Copied to clipboard

Flag this post as spam?

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


  • Matthew Jarvis 129 posts 129 karma points
    Jun 20, 2011 @ 16:05
    Matthew Jarvis
    0

    Relations API guru wanted

    Hi,

    Have added a Relations class on my site courtesy of the source code found following an Umbraco TV demo.

     

    using System;
    using System.Collections.Generic;
    using System.Text;

    using umbraco.BusinessLogic;
    using umbraco.cms.businesslogic.web;
    using umbraco.cms.businesslogic.relation;
    using umbraco.cms.businesslogic.property;
    using umbraco.cms.businesslogic;

    namespace EventSamples
    {

    //This class inhirites from ApplicationBase and is therefore automaticly instantiated on application_start.
    //All events are hooked-up using the constructor
    public class Relations : ApplicationBase
    {
    //Constructor
    public Relations()
    {
    //subscribe to the afterpublish events
    Document.AfterPublish += new Document.PublishEventHandler(Document_AfterPublish);
    }

    /// <summary>
    /// Executes after document publishing
    /// </summary>
    /// <param name="sender">The sender (a documet object).</param>
    /// <param name="e">The <see cref="umbraco.cms.businesslogic.PublishEventArgs"/> instance containing the event data.</param>
    void Document_AfterPublish(Document sender, umbraco.cms.businesslogic.PublishEventArgs e)
    {
    // if the parent doesn't already have been related
    bool hasCopy = false;
    if (sender.Relations.Length > 0 && sender.Level > 1)
    {
    foreach (Relation r in sender.Parent.Relations)
    {
    if (r.RelType.Alias == "relateDocumentOnCopy")
    {
    hasCopy = true;
    break;
    }
    }
    }

    // if the parent documentObject have a relation
    if (!hasCopy && sender.Level > 1)
    {
    Document parent = new Document(sender.Parent.Id);
    if (parent.Relations.Length > 0)
    {
    foreach (Relation r in parent.Relations)
    {
    if (r.RelType.Alias == "relateDocumentOnCopy")
    {
    sender.Copy(r.Child.Id, sender.User, true);
    }
    }
    }
    }

    }
    }

    }

     

    This class works great for my current set up where a Welsh language version of my site is created following the copying of the English Version.

    What I wondered, is it possible to include within the above code a delete script to accompany what is currently being achieved e.g when an English page is deleted, any relation within the Welsh version is also deleted.

    Many Thanks

    Matt

  • Tim 1193 posts 2675 karma points MVP 4x c-trib
    Jun 21, 2011 @ 15:49
    Tim
    0

    Hi Matt,

    Should be doable! You need to hook into the AfterMoveToTrash event on the document. You should be able to use something like the following on the event I think (haven't tested this though!). Note, I'm not sure if this will delete it or move it to the recycle bin.

     

                    if(sender.Relations.Length>0)
                   
    {
                       
    foreach(Relation r in sender.Relations)
                       
    {
                           
    if(r.RelType.Alias=="relateDocumentOnCopy")
                           
    {
                                sender
    .delete();
                           
    }
                       
    }
                   
    }

     

  • Matthew Jarvis 129 posts 129 karma points
    Jun 21, 2011 @ 16:51
    Matthew Jarvis
    0

    Thanks for getting back Tim, have added in the bit of code as suggested so it now looks like this

    using System;
    using System.Collections.Generic;
    using System.Text;

    using umbraco.BusinessLogic;
    using umbraco.cms.businesslogic.web;
    using umbraco.cms.businesslogic.relation;
    using umbraco.cms.businesslogic.property;
    using umbraco.cms.businesslogic;

    namespace EventSamples
    {

        //This class inhirites from ApplicationBase and is therefore automaticly instantiated on application_start.
        //All events are hooked-up using the constructor
        public class Relations : ApplicationBase
        {
            //Constructor
            public Relations()
            {
                //subscribe to the afterpublish events
                Document.AfterPublish += new Document.PublishEventHandler(Document_AfterPublish);
            }

            /// <summary>
            /// Executes after document publishing
            /// </summary>
            /// <param name="sender">The sender (a documet object).</param>
            /// <param name="e">The <see cref="umbraco.cms.businesslogic.PublishEventArgs"/> instance containing the event data.</param>
            void Document_AfterPublish(Document sender, umbraco.cms.businesslogic.PublishEventArgs e)
            {
                // if the parent doesn't already have been related
                bool hasCopy = false;
                if (sender.Relations.Length > 0 && sender.Level > 1)
                {
                    foreach (Relation r in sender.Parent.Relations)
                    {
                        if (r.RelType.Alias == "relateDocumentOnCopy")
                        {
                            hasCopy = true;
                            break;
                        }
                    }
                }

                // if the parent documentObject have a relation
                if (!hasCopy && sender.Level > 1)
                {
                    Document parent = new Document(sender.Parent.Id);
                    if (parent.Relations.Length > 0)
                    {
                        foreach (Relation r in parent.Relations)
                        {
                            if (r.RelType.Alias == "relateDocumentOnCopy")
                            {
                                sender.Copy(r.Child.Id, sender.User, true);
                            }
                        }
                    }
                }

                //Automatically Delete
                if (sender.Relations.Length > 0)
                {
                    foreach (Relation r in sender.Relations)
                    {
                        if (r.RelType.Alias == "relateDocumentOnCopy")
                        {
                            sender.delete();
                        }
                    }
                }




            }
        }

    }

     

    It appears now though that since adding in the deletion part that the site now acts strange.

    Previously a creation in the English site would auto create an equivalent also in the Welsh site.  Now however a creation in the English site gets automatically moved to the Welsh site so moves the page not duplicate.

    Any ideas?

  • Tim 1193 posts 2675 karma points MVP 4x c-trib
    Jun 22, 2011 @ 23:44
    Tim
    0

    Hiya,

    You've got the code in the wrong place! You need to subscribe to the AfterMoveToTrash event for the delete code!

    Try this code instead (I think it should work, not 100% though, as I haven't had time to test it):

    using System;
    using System.Collections.Generic;
    using System.Text;

    using umbraco.BusinessLogic;
    using umbraco.cms.businesslogic.web;
    using umbraco.cms.businesslogic.relation;
    using umbraco.cms.businesslogic.property;
    using umbraco.cms.businesslogic;

    namespace EventSamples
    {

        //This class inhirites from ApplicationBase and is therefore automaticly instantiated on application_start.
        //All events are hooked-up using the constructor
        public class Relations : ApplicationBase
        {
            //Constructor
            public Relations()
            {
                //subscribe to the afterpublish events
                Document.AfterPublish += new Document.PublishEventHandler(Document_AfterPublish);

                Document.AfterMoveToTrash += newDocument.MoveToTrashEventHandler(Document_AfterMoveToTrash);
            }

            void Document_AfterMoveToTrash(Document sender,MoveToTrashEventArgs e)
            {
                if (sender.Relations.Length > 0)
                {
                    foreach (Relation r in sender.Relations)
                    {
                        if (r.RelType.Alias == "relateDocumentOnCopy")
                        {
                            r.delete();
                        }
                    }
                }
            }

            /// <summary>
            /// Executes after document publishing
            /// </summary>
            /// <param name="sender">The sender (a documet object).</param>
            /// <param name="e">The <see cref="umbraco.cms.businesslogic.PublishEventArgs"/> instance containing the event data.</param>
            void Document_AfterPublish(Document sender, umbraco.cms.businesslogic.PublishEventArgs e)
            {
                // if the parent doesn't already have been related
                bool hasCopy = false;
                if (sender.Relations.Length > 0 && sender.Level > 1)
                {
                    foreach (Relation r in sender.Parent.Relations)
                    {
                        if (r.RelType.Alias == "relateDocumentOnCopy")
                        {
                            hasCopy = true;
                            break;
                        }
                    }
                }

                // if the parent documentObject have a relation
                if (!hasCopy && sender.Level > 1)
                {
                    Document parent = new Document(sender.Parent.Id);
                    if (parent.Relations.Length > 0)
                    {
                        foreach (Relation r in parent.Relations)
                        {
                            if (r.RelType.Alias == "relateDocumentOnCopy")
                            {
                                sender.Copy(r.Child.Id, sender.User, true);
                            }
                        }
                    }
                }
            }
        }

    }

  • Matthew Jarvis 129 posts 129 karma points
    Jun 23, 2011 @ 10:02
    Matthew Jarvis
    0

    Thanks Tim, the code you supplied (bar a few errors relating to capital letters which were throwing server errors) is now implementing the copy fucntion correctly as per my original code but the delete function is still not kicking in.  Looks pretty close, tried a few tweaks in the hope of it working but not getting anywhere.

    If you have chance to look at it again that would be great.

    Cheers

    Matt

  • Tim 1193 posts 2675 karma points MVP 4x c-trib
    Jun 23, 2011 @ 10:22
    Tim
    0

    Hmmmmm, I think we're actually deleting the relationship rather than the actual related item. I need to dig around in the relationships API when I get in from work, I'll let you know what I find!

    :)

  • Tim 1193 posts 2675 karma points MVP 4x c-trib
    Jun 25, 2011 @ 15:29
    Tim
    0

    I found the link to Hendy's excellent blog post on using the relationship API! http://blog.hendyracher.co.uk/umbraco-relation-api/

    :)

    There's also some helper methods in uComponents for working with relationships too: http://ucomponents.codeplex.com/wikipage?title=uQuery

    Hope that helps!

Please Sign in or register to post replies

Write your reply to:

Draft