Copied to clipboard

Flag this post as spam?

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


  • Bjarne Fyrstenborg 1281 posts 3991 karma points MVP 7x c-trib
    Jul 05, 2016 @ 11:10
    Bjarne Fyrstenborg
    0

    Create relation between content node and member

    I have some different members with additional properties like first name, last name, phone and company (using MNTP to pick a "Company" content node).

    On Company document type I also have a properties using nuPickers relation labels. However when some members have picked a company, then it doesn't seem to create a relation in database - even a have a Relation type between Content and Member) - and therefore nuPickers doesn't display the relations.

    enter image description here

    Shouldn't it create the relation between content and member in this case?

    If I replace MNTP with nuPickers.XmlPrefetchListPicker then it does create the relation, although it saved an object instead of just a node id.

    enter image description here

    I am used Umbraco 7.4.3 and nuPickers 1.5.3

    /Bjarne

  • Hendy Racher 863 posts 3849 karma points MVP 2x admin c-trib
    Jul 05, 2016 @ 13:10
    Hendy Racher
    0

    Hi Bjarne,

    When using the MNTP to pick a company on a member, what are you using to create the relationship ?

  • Bjarne Fyrstenborg 1281 posts 3991 karma points MVP 7x c-trib
    Jul 05, 2016 @ 13:25
    Bjarne Fyrstenborg
    0

    Hi Hendy

    Nothing else than using MNTP and having an relation types configurated, but I guess it does create the relation then out of the box like when using the picker in nuPickers.

    I have and old site in one of the latest releases of Umbraco v4, where the editors can pick different "quotes" or "references" for each page and then I a similar "custom label" property - so it was using MNTP in uComponents.

    As I remember I only had the configurate it from backoffice and set up the relation type for that Document (content) to Document (content) relation.

  • Bjarne Fyrstenborg 1281 posts 3991 karma points MVP 7x c-trib
    Jul 24, 2016 @ 15:07
    Bjarne Fyrstenborg
    0

    Hi Hendy

    In a old Umbraco 4.11.1 site using uComponents 5.3.0, where I had created an "Relate Page And Quote" relation.

    enter image description here

    I also created data types "Quote Picker" using MNTP and "Pages with Quotes" using uComponents: Relation Labels

    enter image description here

    enter image description here

    When pages using "Quote Picker" had picked any quotes, then on the quote itself you could see on which pages it had been picked.

    enter image description here enter image description here

    When I am doing something similar with a content node and member using nuPickers, it doesn't seem to create the relation using MNTP - but it does create one when using the other pickers in nuPickers.

    /Bjarne

  • Bjarne Fyrstenborg 1281 posts 3991 karma points MVP 7x c-trib
    Aug 02, 2016 @ 22:04
    Bjarne Fyrstenborg
    0

    Should nuPickers also create relation, when using MNTP like it does for the other pickers? https://github.com/uComponents/nuPickers/blob/0c8891cd94b6e073adc95cdf10d3203f6bce7881/source/nuPickers/Shared/RelationMapping/RelationMappingEvent.cs

    In uComponents it did create the relation, when using MNTP as in the example mentioned before, where MNTP was in core.

    /Bjarne

  • Bjarne Fyrstenborg 1281 posts 3991 karma points MVP 7x c-trib
    Aug 07, 2016 @ 16:18
    Bjarne Fyrstenborg
    0

    I have managed to solve it in this way similar to how nuPickers handle it with its different pickers. However when picking a company while create a member and hitting save, it seems it doesn't create the relation - first when I save the member again (after it has been created).

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Umbraco.Core;
    using Umbraco.Core.Events;
    using Umbraco.Core.Models;
    using Umbraco.Core.Services;
    
    namespace My.Library.Events
    {
        /// <summary>
        /// server side event to update relations on change of any member
        /// </summary>
        public class RelationMappingEvent : ApplicationEventHandler
        {
            // inspired from nuPickers: https://github.com/uComponents/nuPickers/tree/master/source/nuPickers/Shared/RelationMapping
    
            protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
            {
                MemberService.Saved += this.MemberService_Saved;
    
                // NOTE: all relations to an id are automatically deleted when emptying the recycle bin
            }
    
            private void MemberService_Saved(IMemberService sender, SaveEventArgs<IMember> e)
            {
                this.Saved((IService)sender, e.SavedEntities);
            }
    
            /// <summary>
            /// combined event for member 
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="savedEntities"></param>
            private void Saved(IService sender, IEnumerable<IContentBase> savedEntities)
            {
                foreach (IContentBase savedEntity in savedEntities)
                {
                    // for each property
                    foreach (PropertyType propertyType in savedEntity.PropertyTypes.Where(p => p.Alias == "umbracoMemberCompany"))
                    {
                        List<int> pickedIds = new List<int>();
                        int memberId = savedEntity.Id;
                        var mntpValues = savedEntity.GetValue(propertyType.Alias);
                        if(mntpValues != null)
                        {
                            pickedIds = mntpValues.ToString().Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToList();
                        }
    
                        UpdateCompanyRelations(memberId, "relateCompanyToMember", pickedIds);
                    }
                }
            }
    
            private void SetCompanyRelation(int contentId, int memberId)
            {
                var rs = ApplicationContext.Current.Services.RelationService;
                var areRelated = rs.AreRelated(contentId, memberId, "relateCompanyToMember");
    
                if (!areRelated)
                {
                    //create relation between document (company node) and member
                    var relType = rs.GetRelationTypeByAlias("relateCompanyToMember");
                    var r = new Relation(contentId, memberId, relType);
                    r.Comment = string.Format("Relate document id {0} to member id {1} ", contentId, memberId);
                    rs.Save(r);
                }
            }
    
            /// <summary>
            /// 
            /// </summary>
            /// <param name="contextId">the id of the content, media or member item</param>
            /// <param name="propertyAlias">the property alias of the picker using relation mapping</param>
            /// <param name="relationTypeAlias">the alias of the relation type to use</param>
            /// <param name="pickedIds">the ids of all picked items that are to be related to the contextId</param>
            private void UpdateCompanyRelations(int contextId, string relationTypeAlias, List<int> pickedIds)
            {
                IRelationType relationType = ApplicationContext.Current.Services.RelationService.GetRelationTypeByAlias(relationTypeAlias);
    
                if (relationType != null)
                {
                    // get all relations of this type
                    List<IRelation> relations = ApplicationContext.Current.Services.RelationService.GetAllRelationsByRelationType(relationType.Id).ToList();
    
                    // filter down potential relations, by relation type direction
                    if (relationType.IsBidirectional)
                    {
                        relations = relations.Where(x => x.ChildId == contextId || x.ParentId == contextId).ToList();
                    }
                    else
                    {
                        relations = relations.Where(x => x.ChildId == contextId).ToList();
                    }
    
                    // check current context is of the correct object type (as according to the relation type)
                    if (ApplicationContext.Current.Services.EntityService.GetObjectType(contextId) == UmbracoObjectTypesExtensions.GetUmbracoObjectType(relationType.ChildObjectType))
                    {
                        // for each picked item 
                        foreach (int pickedId in pickedIds)
                        {
                            // check picked item context if of the correct object type (as according to the relation type)
                            if (ApplicationContext.Current.Services.EntityService.GetObjectType(pickedId) == UmbracoObjectTypesExtensions.GetUmbracoObjectType(relationType.ParentObjectType))
                            {
                                // create relation for each picked company
                                SetCompanyRelation(pickedId, contextId);
                            }
                        }
                    }
    
                    // delete any relations that not are in picked ids
                    if (relations.Any())
                    {
                        foreach (IRelation relation in relations)
                        {
                            if(pickedIds == null || !pickedIds.Contains(relation.ChildId))
                            {
                                ApplicationContext.Current.Services.RelationService.Delete(relation);
                            }
                        }
                    }
                }
            }
        }
    }
    

    /Bjarne

  • Hendy Racher 863 posts 3849 karma points MVP 2x admin c-trib
    Aug 08, 2016 @ 18:36
    Hendy Racher
    0

    Hi Bjarne,

    Yes, you are correct. uComponents had a data-type which would 'watch' another picker and wire it up to relations, but this changed in nuPickers - now each picker can update relations directly. (Perhaps this change wasn't so sensible ? but it does avoid creating two data-types).

    My guess on your current issue, could be that the relation isn't created on first save, as there isn't yet an id for the member being created ?

    HTH, Hendy

  • Bjarne Fyrstenborg 1281 posts 3991 karma points MVP 7x c-trib
    Aug 09, 2016 @ 06:17
    Bjarne Fyrstenborg
    0

    Hi Hendy

    Okay, so in uComponents it seems it always "watch" MNTP after it was included in core of Umbraco.

    With nuPickers it only map these relations for its own pickers.

    So for now it seems I have to create the relation myself like in the code posted.

    Yes, that might be the issues.. not sure if there is a way to ensure the relation is created on first save too?

    Update: savedEntity does have an contentTypeId and id

    enter image description here

    Before it reach UpdateCompanyRelations the memberId is saved in int memberId = savedEntity.Id;

    And the picked node id exists, when it reach this property.

    enter image description here

    Hmm, but it did seem to create the relation this time on save.

    enter image description here

    /Bjarne

  • keilo 568 posts 1023 karma points
    Aug 20, 2016 @ 13:41
    keilo
    0

    I came across this page after looking for how to make use of the Relations mapping in v7 for Members, with similar use case in https://our.umbraco.org/projects/backoffice-extensions/media-content-usage/

    I have created RelationShips from Content to Member and Member to Content.

    Using MNTP by default, doesnt seem to capture the relations, like Bjarne pointed out (had to learn it the hard way...)

    Apparently the tutorials/documentation on the net relates to pre v7 for successfull use cases.

    For my use case, I'm trying to repliacete the usability of https://our.umbraco.org/projects/backoffice-extensions/media-content-usage/ but for Members instead of Media.

    So when I visit a Member, I would like to see the list of Content Nodes (hyperlinks to content nodes).

    Since data is already populated, and MNTP used, I cant change to NuPickers directly I think.

    Is there a simpler way of using the code posted above, but adopt for Content with specific MemberType("Subscriber") ?

    ...like:

    ContentNode -> MNTP member picker

    and when a member page visited, i can see the links of content nodes

Please Sign in or register to post replies

Write your reply to:

Draft