//todo: only ever called with both contexts the same
        public async Task <IEnumerable <IQuery <object?> > > GetRelationshipCommands(
            IDescribeRelationshipsContext context)
        {
            var currentList = new List <ContentItemRelationship>();

            //todo: coupling between GetRelationships and NodeAndNestedOutgoingRelationshipsQuery
            var allRelationships = await GetRelationships(context, currentList, context);

            var uniqueCommands = allRelationships.Select(z => z.RelationshipPathString).GroupBy(x => x).Select(g => g.First());

            List <IQuery <object?> > commandsToReturn = uniqueCommands
                                                        .Select(c => new NodeAndNestedOutgoingRelationshipsQuery(c !)).Cast <IQuery <object?> >().ToList();

            //todo: for occupation and skill, we need to filter out nodes that have just the skos__Concept and Resource labels (and others)
            // but allow other nodes that have a skos__Concept label, such as occupations and skills
            // (or filter on relationships, whitelist whatever)
            //todo: add a setting to graphsyncsettings for the filtering (for now we'll set incoming to 0 for occs & skills)
            var graphSyncPartSettings = context.SyncNameProvider.GetGraphSyncPartSettings(context.ContentItem.ContentType);

            commandsToReturn.Add(new SubgraphQuery(
                                     context.SourceNodeLabels,
                                     context.SourceNodeIdPropertyName,
                                     context.SourceNodeId,
                                     SubgraphQuery.RelationshipFilterIncoming,
                                     graphSyncPartSettings.VisualiserIncomingRelationshipsPathLength ?? 1));

            return(commandsToReturn);
        }
        public async Task AddRelationship(JObject contentItemField, IDescribeRelationshipsContext parentContext)
        {
            var describeContentItemHelper = _serviceProvider.GetRequiredService <IDescribeContentItemHelper>();

            ContentPickerFieldSettings contentPickerFieldSettings =
                parentContext.ContentPartFieldDefinition !.GetSettings <ContentPickerFieldSettings>();

            JArray?contentItemIdsJArray = (JArray?)contentItemField[ContentItemIdsKey];

            if (contentItemIdsJArray?.HasValues == true)
            {
                string relationshipType = await RelationshipTypeContentPicker(contentPickerFieldSettings, parentContext.SyncNameProvider);

                var sourceNodeLabels = await parentContext.SyncNameProvider.NodeLabels(parentContext.ContentItem.ContentType);

                string pickedContentType            = contentPickerFieldSettings.DisplayedContentTypes[0];
                IEnumerable <string> destNodeLabels = await parentContext.SyncNameProvider.NodeLabels(pickedContentType);

                parentContext.AvailableRelationships.Add(new ContentItemRelationship(sourceNodeLabels, relationshipType, destNodeLabels));

                //todo: do we need each child, or can we just have a hashset of types
                foreach (var nestedItem in contentItemIdsJArray)
                {
                    await describeContentItemHelper.BuildRelationships(nestedItem.Value <string>(), parentContext);
                }
            }
        }
        //todo: move any cypher generation into a query
        private static async Task <IEnumerable <ContentItemRelationship> > GetRelationships(
            IDescribeRelationshipsContext context,
            List <ContentItemRelationship> currentList,
            IDescribeRelationshipsContext parentContext)
        {
            foreach (var child in context.AvailableRelationships)
            {
                if (child == null)
                {
                    continue;
                }

                var parentRelationship = parentContext.AvailableRelationships.FirstOrDefault(x => x.Destination.All(child.Source.Contains));

                if (parentRelationship != null && !string.IsNullOrEmpty(parentRelationship.RelationshipPathString))
                {
                    var relationshipString = $"{parentRelationship.RelationshipPathString}-[r{context.CurrentDepth}:{child.Relationship}]-(d{context.CurrentDepth}:{string.Join(":", child.Destination!)})";
                    child.RelationshipPathString = relationshipString;
                }
                else
                {
                    child.RelationshipPathString = $@"match (s:{string.Join(":", context.SourceNodeLabels)} {{{context.SourceNodeIdPropertyName}: '{context.SourceNodeId}'}})-[r{0}:{child.Relationship}]-(d{0}:{string.Join(":", child.Destination!)})";
                }
            }

            currentList.AddRange(context.AvailableRelationships);

            foreach (var childContext in context.ChildContexts)
            {
                await GetRelationships((IDescribeRelationshipsContext)childContext, currentList, context);
            }

            return(currentList);
        }
Exemplo n.º 4
0
        public async Task AddRelationship(JObject contentItemField, IDescribeRelationshipsContext parentContext)
        {
            //todo: check for null
            ContentItem?taxonomyContentItem = await GetTaxonomyContentItem(
                contentItemField,
                parentContext.ContentItemVersion,
                parentContext.ContentManager);

            JObject taxonomyPartContent = taxonomyContentItem !.Content[nameof(TaxonomyPart)];
            string  termContentType     = taxonomyPartContent[TermContentType] !.Value <string>();

            string termRelationshipType = TermRelationshipType(termContentType);

            //todo: auto collect all taxonomy terms? or go through build relationships?

            const int maxDepthFromHere = 0;

            var sourceNodeLabels = await parentContext.SyncNameProvider.NodeLabels(parentContext.ContentItem.ContentType);

            // gets auto-added to parent. better way though?
#pragma warning disable S1848
            new DescribeRelationshipsContext(
                parentContext.SourceNodeIdPropertyName, parentContext.SourceNodeId, parentContext.SourceNodeLabels,
                parentContext.ContentItem, maxDepthFromHere, parentContext.SyncNameProvider, parentContext.ContentManager,
                parentContext.ContentItemVersion, parentContext, parentContext.ServiceProvider)
            {
                AvailableRelationships = new List <ContentItemRelationship>
                {
                    new ContentItemRelationship(
                        sourceNodeLabels,
                        termRelationshipType,
                        await parentContext.SyncNameProvider.NodeLabels(termContentType))
                }
            };

            string taxonomyRelationshipType = TaxonomyRelationshipType(taxonomyContentItem);

            new DescribeRelationshipsContext(
                parentContext.SourceNodeIdPropertyName, parentContext.SourceNodeId, parentContext.SourceNodeLabels,
                parentContext.ContentItem, maxDepthFromHere, parentContext.SyncNameProvider, parentContext.ContentManager,
                parentContext.ContentItemVersion, parentContext, parentContext.ServiceProvider)
            {
                AvailableRelationships = new List <ContentItemRelationship>
                {
                    new ContentItemRelationship(
                        sourceNodeLabels,
                        taxonomyRelationshipType,
                        await parentContext.SyncNameProvider.NodeLabels(taxonomyContentItem.ContentType))
                }
            };

#pragma warning restore S1848
        }
        public async Task AddRelationship(JObject content, IDescribeRelationshipsContext context)
        {
            foreach (var contentFieldGraphSyncer in _contentFieldGraphSyncer)
            {
                IEnumerable <ContentPartFieldDefinition> contentPartFieldDefinitions =
                    context.ContentTypePartDefinition.PartDefinition.Fields
                    .Where(fd => fd.FieldDefinition.Name == contentFieldGraphSyncer.FieldTypeName);

                foreach (ContentPartFieldDefinition contentPartFieldDefinition in contentPartFieldDefinitions)
                {
                    JObject?contentItemField = (JObject?)content[contentPartFieldDefinition.Name];
                    if (contentItemField == null)
                    {
                        continue;
                    }

                    context.SetContentPartFieldDefinition(contentPartFieldDefinition);

                    await contentFieldGraphSyncer.AddRelationship(contentItemField, context);
                }

                context.SetContentPartFieldDefinition(default);
        public async Task <IDescribeRelationshipsContext?> BuildRelationships(
            string contentItemId,
            IDescribeRelationshipsContext context)
        {
            ContentItem?contentItem = await context.ContentItemVersion.GetContentItem(_contentManager, contentItemId);

            if (contentItem == null)
            {
                throw new GraphSyncException($"ContentItem with id {contentItemId} not found.");
            }

            //todo: overload () that accepts context (non root)?
            //todo: child context is same as parent. do we require all of these?
            return(await BuildRelationships(
                       contentItem,
                       context.SourceNodeIdPropertyName,
                       context.SourceNodeId,
                       context.SourceNodeLabels,
                       context.SyncNameProvider,
                       context.ContentManager,
                       context.ContentItemVersion,
                       context,
                       context.ServiceProvider));
        }
Exemplo n.º 7
0
 public override async Task AddRelationship(JObject content, IDescribeRelationshipsContext context)
 {
     await _contentFieldsGraphSyncer.AddRelationship(content, context);
 }
Exemplo n.º 8
0
 public override Task AddRelationship(JObject content, IDescribeRelationshipsContext context)
 {
     return(_contentFieldsGraphSyncer.AddRelationship(content, context));
 }
 public override Task AddRelationship(JObject content, IDescribeRelationshipsContext context)
 {
     return(_embeddedContentItemsGraphSyncer.AddRelationship((JArray?)content[ContainerName], context));
 }
Exemplo n.º 10
0
 public virtual Task AddRelationship(JObject content, IDescribeRelationshipsContext context)
 {
     return(Task.CompletedTask);
 }