Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Murray Roke 503 posts 966 karma points c-trib
    Sep 01, 2011 @ 05:48
    Murray Roke
    0

    Email Notification OnPublish Catch 22

    Hi

    I'm implementing a mechanism where website visitors (not members, not admins) can ask to be sent an email when new node is published.

    The correct time to send the email notification is I believe on the event:

    umbraco.content.AfterClearDocumentCache += ...

    Because the node must be published and updated in the document cache before I can call NiceUrl.

    However I also want to update a flag to say I've sent the email, and the correct place to set that flag is I believe on the event:

    Document.BeforePublish += ...

    The reason I need to do it here, is if I do it AfterPublish the property in the UI admin form is not updated, and the user can hit publish again and it will send the email all over again.

    I can think of a couple of ugly solutions I could try, such as:

    • putting the flag in the request.context.items
    • Do everything BeforePublish and send the nodeID in the email and having a redirect rule on the site to push them to the correct url.

    But if anyone has  a better idea, or input on which of the above will work better, let me know.

    Cheers.

    Murray.

  • Sebastiaan Janssen 5060 posts 15522 karma points MVP admin hq
    Sep 01, 2011 @ 08:55
    Sebastiaan Janssen
    0

    I do it simply like this: If an e-mail needs to be sent, the editor sets a checkbox to true, during afterpublish the e-mail gets sent AND the checkbox gets set to false again. This is a save event, not a publish event, therefore you don't get into a loop.

  • Murray Roke 503 posts 966 karma points c-trib
    Sep 01, 2011 @ 09:02
    Murray Roke
    0

    from my experience any property value you set in the AfterPublish Event  will not show in the UI on postback. If you reload from the tree, you will see the change, but you will not see the change on postback, when you click save and publish from the tool bar.

  • Sebastiaan Janssen 5060 posts 15522 karma points MVP admin hq
    Sep 01, 2011 @ 09:12
    Sebastiaan Janssen
    0

    Yep, which is why I save the url in the context items and refresh the page afterwards, so all the way at the end of my eventhandler I do this:

     

    if (((Page)HttpContext.Current.Handler).Items.Contains("RedirectUrl")) {
                    ((Page)HttpContext.Current.Handler).Items.Remove("RedirectUrl");
    } ((Page)HttpContext.Current.Handler).Items.Add("RedirectUrl", HttpContext.Current.Request.Url.ToString()); ((Page)HttpContext.Current.Handler).PreRender += PreRender;

    And the in the PreRender handler I refresh the page:

    private static void PreRender(object sender, EventArgs e)
    {
       if (((Page)HttpContext.Current.Handler).Items.Contains("RedirectUrl") && !string.IsNullOrEmpty((string)((Page)HttpContext.Current.Handler).Items["RedirectUrl"])) {              
    HttpContext.Current.Response.Redirect((string)((Page)HttpContext.Current.Handler).Items["RedirectUrl"]);
    } }

    Yes, this is an awkward little hack, but it has worked very well for me so far. :)

     

  • Murray Roke 503 posts 966 karma points c-trib
    Sep 01, 2011 @ 09:20
    Murray Roke
    0

    yep, I did an awkward hack too, so you may like it:-)

    My requirements are slightly different in that sending an email is the default behaviour

    public ApplicationInitializer()
    {
        Document.BeforePublish += FlagForNotifications;
        Document.AfterPublish += NotifySubscribers;
    }
    
    private static void FlagForNotifications(Document sender, umbraco.cms.businesslogic.PublishEventArgs e)
    {
        //Note: this code is probably not suitable for a multi-web-server setup.
        var prop = sender.getProperty("notifacationEmailSent");
        if (prop.Value is int && (int)prop.Value == 1)
            return;
    
        prop.Value = 1;
        HttpContext.Current.Items["SendNotification"] = true;
    }
    
    private static void NotifySubscribers(Document sender, umbraco.cms.businesslogic.PublishEventArgs e)
    {
        if (HttpContext.Current.Items["SendNotification"] == null)
            return;
    
        umbraco.library.UpdateDocumentCache(sender.Id);
    
        var notifier = new EmailNotifier()
        {
            DocumentTitle = sender.Text,
            DocumentUrl = umbraco.library.NiceUrl(sender.Id),
            CategoryIds = sender.GetPropertyAsNodeCollection("categories").Where(n => n.NodeTypeAlias == "CategoryComponent").Select(n => n.Id).ToArray(),
            BaseUrl = HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority),
            MailConfig = HttpContext.Current.Server.MapPath("/Mail.config"),
            HttpContext = HttpContext.Current,
            NodeId = sender.Id
        };
    
        Log.Add(LogTypes.Publish, sender.Id, string.Format("Starting thread to send email notifications for '{0}'", sender.Text));
    
        var start = new ThreadStart(notifier.Execute);
        var t = new Thread(start) { Priority = ThreadPriority.Lowest };
        t.Start();
    }
    

    For some reason AfterClearDocumentCache wasn't working for me, but this does the trick.

Please Sign in or register to post replies

Write your reply to:

Draft