1
votes

I'm creating an Umbraco website that allows members to upload photos.

I was asked to create a page that lists only members that have uploaded photos. Photos are stored as Media and have an associated Member Picker property. I tried to formulate a way to get the list of members based on this field, but everything I can come up with seems like it would be very inefficient as the site grows.

I decided to create an additional property called 'Number of Photos' on the member. When they upload a photo, the number increments. It works great until we get a spammer that starts uploading garbage. When the photo is deleted in the Media section, it does not automatically decrement the 'Number of Photos' for the member. Enter Umbraco's ApplicationEventHandler:

using System.Web;
using umbraco.cms.businesslogic;
using umbraco.cms.businesslogic.media;
using umbraco.cms.businesslogic.member;
using Umbraco.Core;

namespace Umbraco.Extensions.EventHandlers
{
    public class RegisterEvents : ApplicationEventHandler
    {
        protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
        {
            Media.AfterMoveToTrash += Media_AfterMoveToTrash;

        }

        private void Media_AfterMoveToTrash(Media sender, MoveToTrashEventArgs e)
        {
            // Reset photo count for user
            if (sender.getProperty("member") != null)
            { 
                int memberId = int.Parse(sender.getProperty("member").Value.ToString());
                var member = new Member(memberId);
                int numPhotos = 0;
                int.TryParse(member.getProperty("numberOfPhotos").Value.ToString(), out numPhotos);
                if (numPhotos > 0)
                    numPhotos--;
                member.getProperty("numberOfPhotos").Value = numPhotos;
                member.Save();
            }
        }
    }
}

ApplicationStarted fires properly. The problem I'm having is that the Media.AfterMoveToTrash event never fires. I've also tried Media.AfterDelete without avail.

I'm not sure it makes a difference, but I'm running Umbraco as a web site not an MVC project. All the custom code (surface controllers, models, and this event handler) is in the App_Code directory.

2

2 Answers

3
votes

As already stated, use MediaEvents. The following is taken from the Umbraco website.

using Umbraco.Core;
using Umbraco.Core.Events;
using Umbraco.Core.Models;
using Umbraco.Core.Services;

namespace My.Namespace
{
    public class MyEventHandler : ApplicationEventHandler
    {
        public MyEventHandler()
        {
            MediaService.Saved += MediaServiceSaved;
        }

        void MediaServiceSaved(IMediaService sender, SaveEventArgs e)
        {
            foreach (var mediaItem in e.SavedEntities)
            {
                // Do whatever you want with each entity
            }
        }
    }
}

Update: if you're using newer versions of Umbraco (e.g. approximately v7.3.0) you should use:

MediaService.Saved += MediaServiceSaved
-1
votes

Also you can use this:

public class UmbracoActionsHandler : IApplicationStartupHandler
    {
        public UmbracoActionsHandler()
        {
            Media.AfterMoveToTrash += Media_AfterMoveToTrash;
        }

        void Media_AfterMoveToTrash(Media sender, umbraco.cms.businesslogic.MoveToTrashEventArgs e)
        {
            ......
        }
    }