public override async Task AddSyncComponents(JObject content, IGraphMergeContext context) { context.MergeNodeCommand.AddProperty <string>(TermContentTypePropertyName, content); _embeddedContentItemsGraphSyncer.IsNonLeafEmbeddedTerm = false; await _embeddedContentItemsGraphSyncer.AddSyncComponents((JArray?)content[ContainerName], context); }
public Task AddSyncComponents(JObject contentItemField, IGraphMergeContext context) { //todo requires 'picked' part has a graph sync part // add to docs & handle picked part not having graph sync part or throw exception return(AddSyncComponents(context, (JArray?)contentItemField[ContentItemIdsKey])); }
public override async Task AddSyncComponents(JObject content, IGraphMergeContext context) { using var _ = context.SyncNameProvider.PushPropertyNameTransform(_sitemapPropertyNameTransform); //todo: helper for these? JValue?value = (JValue?)content[OverrideSitemapConfigPropertyName]; if (value != null && value.Type != JTokenType.Null) //first bool? { context.MergeNodeCommand.Properties.Add(await context.SyncNameProvider.PropertyName(OverrideSitemapConfigPropertyName), value.As <bool>()); } //todo: we want the change frequency value lowercase (as the sitemap xml format wants it lowercase), // but we probably want enums to serialise using normal casing, so can Enum.Parse etc. // add flag to any enum helpers, such as EnumContentPropertyMatchesNodeProperty value = (JValue?)content[ChangeFrequencyPropertyName]; if (value != null && value.Type != JTokenType.Null) { context.MergeNodeCommand.Properties.Add(await context.SyncNameProvider.PropertyName(ChangeFrequencyPropertyName), ((ChangeFrequency)value.As <int>()).ToString().ToLowerInvariant()); } value = (JValue?)content[PriorityPropertyName]; if (value != null && value.Type != JTokenType.Null) { context.MergeNodeCommand.Properties.Add(await context.SyncNameProvider.PropertyName(PriorityPropertyName), value.As <int>()); } value = (JValue?)content[ExcludePropertyName]; if (value != null && value.Type != JTokenType.Null) { context.MergeNodeCommand.Properties.Add(await context.SyncNameProvider.PropertyName(ExcludePropertyName), value.As <bool>()); } }
public async Task AddSyncComponentsDetaching(IGraphMergeContext context) { var taxonomyFieldSettings = context.ContentPartFieldDefinition !.GetSettings <TaxonomyFieldSettings>(); //todo: factor out common code //todo: check for null ContentItem?taxonomyContentItem = await context.ContentItemVersion.GetContentItem( context.ContentManager, taxonomyFieldSettings.TaxonomyContentItemId); JObject taxonomyPartContent = taxonomyContentItem !.Content[nameof(TaxonomyPart)]; string termContentType = taxonomyPartContent[TermContentType] !.Value <string>(); string termRelationshipType = TermRelationshipType(termContentType); //todo: split into stefull and stateless and put both in the context // then can stop stateful contenttype being reset IEnumerable <string> destNodeLabels = await context.SyncNameProvider.NodeLabels(termContentType); context.ReplaceRelationshipsCommand.RemoveAnyRelationshipsTo( termRelationshipType, destNodeLabels); string taxonomyRelationshipType = TaxonomyRelationshipType(taxonomyContentItem); destNodeLabels = await context.SyncNameProvider.NodeLabels(taxonomyContentItem.ContentType); context.ReplaceRelationshipsCommand.RemoveAnyRelationshipsTo( taxonomyRelationshipType, destNodeLabels); }
public override async Task AddSyncComponents(JObject content, IGraphMergeContext context) { // prefix field property names, so there's no possibility of a clash with the eponymous fields property names using var _ = context.SyncNameProvider.PushPropertyNameTransform(_publishLaterFieldsPropertyNameTransform); context.MergeNodeCommand.AddProperty <DateTime>( await context.SyncNameProvider.PropertyName(ScheduledPublishUtcPropertyName), content, ScheduledPublishUtcPropertyName); }
private async Task <List <CommandRelationship> > GetRequiredRelationshipsAndOptionallySync( JArray?contentItems, IGraphMergeContext context, IAllowSync?allowSync = null) { ContentItem[] embeddedContentItems = ConvertToContentItems(contentItems); List <CommandRelationship> requiredRelationships = new List <CommandRelationship>(); int relationshipOrdinal = 0; foreach (ContentItem contentItem in embeddedContentItems) { IMergeGraphSyncer?mergeGraphSyncer; if (allowSync == null) { // we're actually syncing, not checking if it's allowed mergeGraphSyncer = await context.MergeGraphSyncer.SyncEmbedded(contentItem); } else { mergeGraphSyncer = GetNewMergeGraphSyncer(); IAllowSync embeddedAllowSync = await mergeGraphSyncer.SyncAllowed(context.GraphReplicaSet, contentItem, context.ContentManager, context); allowSync.AddRelated(embeddedAllowSync); if (embeddedAllowSync.Result != AllowSyncResult.Allowed) { continue; } } //todo: check embedded items with no graphsyncpart attached if (mergeGraphSyncer == null) { continue; } IMergeNodeCommand containedContentMergeNodeCommand = mergeGraphSyncer.MergeNodeCommand; containedContentMergeNodeCommand.CheckIsValid(); string relationshipType = await RelationshipType(contentItem.ContentType); var properties = await GetRelationshipProperties(contentItem, relationshipOrdinal, context.SyncNameProvider); ++relationshipOrdinal; requiredRelationships.Add(new CommandRelationship( relationshipType, await TwoWayIncomingRelationshipType(contentItem.ContentType), properties, containedContentMergeNodeCommand.NodeLabels, containedContentMergeNodeCommand.IdPropertyName !, Enumerable.Repeat(containedContentMergeNodeCommand.Properties[containedContentMergeNodeCommand.IdPropertyName !], 1)));
private async Task AddSyncComponents(IGraphMergeContext context, JArray?contentItemIdsJArray = null) { ContentPickerFieldSettings contentPickerFieldSettings = context.ContentPartFieldDefinition !.GetSettings <ContentPickerFieldSettings>(); //todo: use pickedContentSyncNameProvider in RelationshipTypeContentPicker? string relationshipType = await RelationshipTypeContentPicker(contentPickerFieldSettings, context.SyncNameProvider); //todo: support multiple pickable content types string pickedContentType = contentPickerFieldSettings.DisplayedContentTypes[0]; ISyncNameProvider pickedContentSyncNameProvider = _serviceProvider.GetSyncNameProvider(pickedContentType); IEnumerable <string> destNodeLabels = await pickedContentSyncNameProvider.NodeLabels(); if (contentItemIdsJArray?.HasValues != true) { context.ReplaceRelationshipsCommand.RemoveAnyRelationshipsTo( relationshipType, destNodeLabels); return; } ContentItem[] foundDestinationContentItems = await GetContentItemsFromIds( contentItemIdsJArray, context.ContentManager, context.ContentItemVersion); if (context.ContentItemVersion.GraphReplicaSetName == GraphReplicaSetNames.Preview && foundDestinationContentItems.Count() != contentItemIdsJArray.Count) { throw new GraphSyncException( $"Missing picked content items. Looked for {string.Join(",", contentItemIdsJArray.Values<string?>())}. Found {string.Join(",", foundDestinationContentItems.Select(i => i.ContentItemId))}. Current merge node command: {context.MergeNodeCommand}."); } // if we're syncing to the published graph, some items may be draft only, // so it's valid to have less found content items than are picked //todo: we could also check when publishing and take into account how many we expect not to find as they are draft only IEnumerable <object> foundDestinationNodeIds = foundDestinationContentItems.Select(ci => GetNodeId(ci !, pickedContentSyncNameProvider, context.ContentItemVersion)); long ordinal = 0; foreach (var item in foundDestinationNodeIds) { context.ReplaceRelationshipsCommand.AddRelationshipsTo( relationshipType, ContentPickerRelationshipProperties.Concat(new[] { new KeyValuePair <string, object>("Ordinal", ordinal++) }), destNodeLabels, pickedContentSyncNameProvider.IdPropertyName(), item); } }
public override async Task AddSyncComponents(JObject content, IGraphMergeContext context) { //todo: make concurrent? await base.AddSyncComponents(content, context); // FlowPart allows part definition level fields, but values are on each FlowPart instance // prefix flow field property names, so there's no possibility of a clash with the eponymous fields property names using var _ = context.SyncNameProvider.PushPropertyNameTransform(_flowFieldsPropertyNameTransform); await _contentFieldsGraphSyncer.AddSyncComponents(content, context); }
public override Task AddSyncComponents(JObject content, IGraphMergeContext context) { string?title = context.MergeNodeCommand.AddProperty <string>(NodeTitlePropertyName, content, _contentTitlePropertyName); if (title == null) { context.MergeNodeCommand.Properties.Add(NodeTitlePropertyName, context.ContentItem.DisplayText); } return(Task.CompletedTask); }
public override async Task AddSyncComponents(JObject content, IGraphMergeContext context) { // prefix field property names, so there's no possibility of a clash with the eponymous fields property names using var _ = context.SyncNameProvider.PushPropertyNameTransform(_htmlBodyFieldsPropertyNameTransform); JValue?htmlValue = (JValue?)content[HtmlPropertyName]; if (htmlValue != null && htmlValue.Type != JTokenType.Null) { context.MergeNodeCommand.Properties.Add(await context.SyncNameProvider.PropertyName(HtmlPropertyName), htmlValue.As <string>()); } }
public async Task AddSyncComponents(JObject contentItemField, IGraphMergeContext context) { string nodePropertyName = await context.SyncNameProvider.PropertyName(context.ContentPartFieldDefinition !.Name); if (SyncMultilineToArray(context.ContentPartFieldDefinition)) { context.MergeNodeCommand.AddArrayPropertyFromMultilineString( nodePropertyName, contentItemField, ContentKey); return; } context.MergeNodeCommand.AddProperty <string>(nodePropertyName, contentItemField, ContentKey); }
public async Task AddSyncComponents(JObject contentItemField, IGraphMergeContext context) { JValue?value = (JValue?)contentItemField[ContentKey]; if (value == null || value.Type == JTokenType.Null) { return; } context.MergeNodeCommand.Properties.Add( await context.SyncNameProvider.PropertyName(context.ContentPartFieldDefinition !.Name), value.As <string>()); }
public override async Task AllowSync( JArray?contentItems, IGraphMergeContext context, IAllowSync allowSync) { IAllowSync baseAllowSync = new AllowSync(); await base.AllowSync(contentItems, context, baseAllowSync); var baseBlockersWithoutIncomingTaxonomyBlocker = baseAllowSync.SyncBlockers.Where(sb => sb.ContentType != "Taxonomy"); if (baseBlockersWithoutIncomingTaxonomyBlocker.Any()) { allowSync.AddSyncBlockers(baseBlockersWithoutIncomingTaxonomyBlocker); } }
public async Task AddSyncComponents(JObject contentItemField, IGraphMergeContext context) { string basePropertyName = await context.SyncNameProvider.PropertyName(context.ContentPartFieldDefinition !.Name); JValue?value = (JValue?)contentItemField[UrlFieldKey]; if (value != null && value.Type != JTokenType.Null) { context.MergeNodeCommand.Properties.Add($"{basePropertyName}{LinkUrlPostfix}", value.As <string>()); } value = (JValue?)contentItemField[TextFieldKey]; if (value != null && value.Type != JTokenType.Null) { context.MergeNodeCommand.Properties.Add($"{basePropertyName}{LinkTextPostfix}", value.As <string>()); } }
public override async Task AddSyncComponents(JObject content, IGraphMergeContext context) { using var _ = context.SyncNameProvider.PushPropertyNameTransform(_pageLocationPropertyNameTransform); context.MergeNodeCommand.AddProperty <string>(await context.SyncNameProvider.PropertyName(UrlNamePropertyName), content, UrlNamePropertyName); context.MergeNodeCommand.AddProperty <string>(await context.SyncNameProvider.PropertyName(FullUrlPropertyName), content, FullUrlPropertyName); var settings = context.ContentTypePartDefinition.GetSettings <PageLocationPartSettings>(); //TODO : if this setting changes, do we need to also check/remove these properties from the node? if (settings.DisplayRedirectLocationsAndDefaultPageForLocation) { context.MergeNodeCommand.AddProperty <bool>(await context.SyncNameProvider.PropertyName(DefaultPageForLocationPropertyName), content, DefaultPageForLocationPropertyName); context.MergeNodeCommand.AddArrayPropertyFromMultilineString( await context.SyncNameProvider.PropertyName(RedirectLocationsPropertyName), content, RedirectLocationsPropertyName); } }
public async Task AddSyncComponents(JObject contentItemField, IGraphMergeContext context) { JValue?value = (JValue?)contentItemField?[ContentKey]; if (value == null || value.Type == JTokenType.Null) { return; } var fieldSettings = context.ContentPartFieldDefinition !.GetSettings <NumericFieldSettings>(); string propertyName = await context.SyncNameProvider.PropertyName(context.ContentPartFieldDefinition !.Name); if (fieldSettings.Scale == 0) { context.MergeNodeCommand.Properties.Add(propertyName, (int)value); } else { context.MergeNodeCommand.Properties.Add(propertyName, (decimal)value); } }
public override async Task AddSyncComponents(JObject content, IGraphMergeContext context) { string?taxonomyContentItemId = (string?)content[TaxonomyContentItemId]; if (taxonomyContentItemId == null) { throw new GraphSyncException($"{PartName} is missing {TaxonomyContentItemId}."); } //todo: check for null ContentItem?contentItem = await context.ContentItemVersion.GetContentItem(context.ContentManager, taxonomyContentItemId); ISyncNameProvider termSyncNameProvider = _serviceProvider.GetSyncNameProvider(contentItem !.ContentType); //todo: override/extension that takes a contentitem context.ReplaceRelationshipsCommand.AddRelationshipsTo( //todo: go through syncNameProvider $"has{contentItem.ContentType}", null, await termSyncNameProvider.NodeLabels(), termSyncNameProvider.IdPropertyName(), termSyncNameProvider.GetNodeIdPropertyValue(contentItem.Content.GraphSyncPart, context.ContentItemVersion)); }
public override Task AddSyncComponents(JObject graphLookupContent, IGraphMergeContext context) { var settings = context.ContentTypePartDefinition.GetSettings <GraphLookupPartSettings>(); JArray?nodes = (JArray?)graphLookupContent[NodesPropertyName]; if (nodes == null || nodes.Count == 0) { return(Task.CompletedTask); } if (settings.PropertyName != null) { context.MergeNodeCommand.Properties.Add(settings.PropertyName, GetId(nodes.First())); } if (settings.RelationshipType != null) { //todo: settings should contains destnodelabels context.ReplaceRelationshipsCommand.AddRelationshipsTo( settings.RelationshipType !, null, new[] { settings.NodeLabel ! },
public override Task AddSyncComponentsDetaching(IGraphMergeContext context) { return(_embeddedContentItemsGraphSyncer.AddSyncComponentsDetaching(context)); }
public virtual async Task AllowSync( JArray?contentItems, IGraphMergeContext context, IAllowSync allowSync) { _logger.LogDebug("Do embedded items allow sync?"); List <CommandRelationship> requiredRelationships = await GetRequiredRelationshipsAndOptionallySync(contentItems, context, allowSync); INodeAndOutRelationshipsAndTheirInRelationships?existing = (await context.GraphReplicaSet.Run( new NodeAndOutRelationshipsAndTheirInRelationshipsQuery( context.ReplaceRelationshipsCommand.SourceNodeLabels, context.ReplaceRelationshipsCommand.SourceIdPropertyName !, context.ReplaceRelationshipsCommand.SourceIdPropertyValue !))) .FirstOrDefault(); if (existing?.OutgoingRelationships.Any() != true) { // nothing to do here, node is being newly created or existing node has no relationships return; } (string[] embeddableContentTypes, IEnumerable <string> relationshipTypes) = await GetEmbeddableContentTypesAndRelationshipTypes(context); existing = new NodeAndOutRelationshipsAndTheirInRelationships( existing.SourceNode, existing.OutgoingRelationships .Where(or => embeddableContentTypes.Contains( context.SyncNameProvider.GetContentTypeFromNodeLabels( or.outgoingRelationship.DestinationNode.Labels)) && relationshipTypes.Contains(or.outgoingRelationship.Relationship.Type))); IEnumerable <CommandRelationship> existingRelationshipsForEmbeddableContentTypes = existing.ToCommandRelationships(context.SyncNameProvider); _removingRelationships = GetRemovingRelationships( existingRelationshipsForEmbeddableContentTypes, requiredRelationships, context.SyncNameProvider); if (!_removingRelationships.Any()) { // nothing to do here, not removing any relationships return; } foreach (var removingRelationship in _removingRelationships) { foreach (object destinationNodeIdPropertyValue in removingRelationship.DestinationNodeIdPropertyValues) { var existingForRemoving = existing.OutgoingRelationships .Where(er => er.outgoingRelationship.DestinationNode.Properties[ context.SyncNameProvider.IdPropertyName( context.SyncNameProvider.GetContentTypeFromNodeLabels( er.outgoingRelationship.DestinationNode.Labels))] == destinationNodeIdPropertyValue); var nonTwoWayIncomingRelationshipsToEmbeddedItems = existingForRemoving .SelectMany(or => or.incomingRelationships) //todo: null or throws? .Where(ir => !ir.Relationship.Properties.ContainsKey( NodeWithOutgoingRelationshipsCommand.TwoWayRelationshipPropertyName)); allowSync.AddSyncBlockers( nonTwoWayIncomingRelationshipsToEmbeddedItems.Select(r => { string contentType = context.SyncNameProvider.GetContentTypeFromNodeLabels(r.DestinationNode.Labels); return(new SyncBlocker( contentType, r.DestinationNode.Properties[context.SyncNameProvider.IdPropertyName(contentType)], (string?)r.DestinationNode.Properties[TitlePartGraphSyncer.NodeTitlePropertyName])); })); } } }
public override Task AllowSync(JObject content, IGraphMergeContext context, IAllowSync allowSync) { return(Task.WhenAll( base.AllowSync(content, context, allowSync), _contentFieldsGraphSyncer.AllowSync(content, context, allowSync))); }
public async Task AddSyncComponents(JObject contentItemField, IGraphMergeContext context) { //todo: share code with contentpickerfield? //todo: better error message to user if taxonomy is missing //todo: check for null ContentItem?taxonomyContentItem = await GetTaxonomyContentItem( contentItemField, context.ContentItemVersion, context.ContentManager); JObject taxonomyPartContent = taxonomyContentItem !.Content[nameof(TaxonomyPart)]; string termContentType = taxonomyPartContent[TermContentType] !.Value <string>(); string termRelationshipType = TermRelationshipType(termContentType); //todo requires 'picked' part has a graph sync part // add to docs & handle picked part not having graph sync part or throw exception JArray?contentItemIdsJArray = (JArray?)contentItemField[TermContentItemIds]; if (contentItemIdsJArray == null || !contentItemIdsJArray.HasValues) { return; //todo: } IEnumerable <string> contentItemIds = contentItemIdsJArray.Select(jtoken => jtoken.ToObject <string>() !); ISyncNameProvider relatedSyncNameProvider = _serviceProvider.GetSyncNameProvider(termContentType); var flattenedTermsContentItems = GetFlattenedTermsContentItems(taxonomyPartContent); IEnumerable <object> foundDestinationNodeIds = contentItemIds.Select(tid => GetNodeId(tid, flattenedTermsContentItems, relatedSyncNameProvider, context.ContentItemVersion) !); IEnumerable <string> destNodeLabels = await relatedSyncNameProvider.NodeLabels(); context.ReplaceRelationshipsCommand.AddRelationshipsTo( termRelationshipType, null, destNodeLabels, relatedSyncNameProvider !.IdPropertyName(), foundDestinationNodeIds.ToArray()); // add relationship to taxonomy string taxonomyRelationshipType = TaxonomyRelationshipType(taxonomyContentItem); relatedSyncNameProvider.ContentType = taxonomyContentItem.ContentType; destNodeLabels = await relatedSyncNameProvider.NodeLabels(); object taxonomyIdValue = relatedSyncNameProvider.GetNodeIdPropertyValue( taxonomyContentItem.Content[nameof(GraphSyncPart)], context.ContentItemVersion); context.ReplaceRelationshipsCommand.AddRelationshipsTo( taxonomyRelationshipType, null, destNodeLabels, relatedSyncNameProvider !.IdPropertyName(), taxonomyIdValue); // add tagnames //using var _ = s yncNameProvider.PushPropertyNameTransform(_taxonomyPropertyNameTransform); //todo: this is there sometimes, but not others (Tag editor is selected and/or non-unique?) // find out when it should be there: need to know to know how to validate it //context.MergeNodeCommand.AddArrayProperty<string>(TaxonomyTermsNodePropertyName, contentItemField, TagNames); //todo: need to store location as string, e.g. "/contact-us" // could alter flatten to also include parent and work backwards // or do a search, recording the path }
public override Task AddSyncComponents(JObject content, IGraphMergeContext context) { return(_contentFieldsGraphSyncer.AddSyncComponents(content, context)); }
public Task AddSyncComponentsDetaching(IGraphMergeContext context) { return(AddSyncComponents(context)); }
public override async Task AllowSync(JObject content, IGraphMergeContext context, IAllowSync allowSync) { await _contentFieldsGraphSyncer.AllowSync(content, context, allowSync); }
public override async Task AddSyncComponents(JObject content, IGraphMergeContext context) { await _contentFieldsGraphSyncer.AddSyncComponents(content, context); }
public override Task AddSyncComponents(JObject content, IGraphMergeContext context) { context.MergeNodeCommand.AddProperty <string>(NodeAliasPropertyName, content, _contentAliasPropertyName); return(Task.CompletedTask); }
public async Task AddSyncComponentsForNonLeafEmbeddedTerm(JObject content, IGraphMergeContext context) { _embeddedContentItemsGraphSyncer.IsNonLeafEmbeddedTerm = true; await _embeddedContentItemsGraphSyncer.AddSyncComponents((JArray?)content[ContainerName], context); }
public async Task AddSyncComponents(JObject contentItemField, IGraphMergeContext context) { string nodePropertyName = await context.SyncNameProvider.PropertyName(context.ContentPartFieldDefinition !.Name); context.MergeNodeCommand.AddProperty <bool>(nodePropertyName, contentItemField, ContentKey); }
public async Task AddSyncComponentsDetaching(IGraphMergeContext context) { await AddSyncComponents(context); }