/// <summary> /// Deserialize the relations for a relation type. /// </summary> private IEnumerable <uSyncChange> DeserializeRelations(XElement node, IRelationType relationType, SyncSerializerOptions options) { var changes = new List <uSyncChange>(); var existing = relationService .GetAllRelationsByRelationType(relationType.Id) .ToList(); var relations = node.Element("Relations"); // do we do this, or do we remove them all! if (relations == null) { return(Enumerable.Empty <uSyncChange>()); } var newRelations = new List <string>(); foreach (var relationNode in relations.Elements("Relation")) { var parentKey = relationNode.Element("Parent").ValueOrDefault(Guid.Empty); var childKey = relationNode.Element("Child").ValueOrDefault(Guid.Empty); if (parentKey == Guid.Empty || childKey == Guid.Empty) { continue; } var parentItem = entityService.Get(parentKey); var childItem = entityService.Get(childKey); if (parentItem == null || childItem == null) { continue; } if (!existing.Any(x => x.ParentId == parentItem.Id && x.ChildId == childItem.Id)) { // missing from the current list... add it. relationService.Save(new Relation(parentItem.Id, childItem.Id, relationType)); changes.Add(uSyncChange.Create(relationType.Alias, parentItem.Name, childItem.Name)); } newRelations.Add($"{parentItem.Id}_{childItem.Id}"); } if (options.DeleteItems()) { var obsolete = existing.Where(x => !newRelations.Contains($"{x.ParentId}_{x.ChildId}")); foreach (var obsoleteRelation in obsolete) { changes.Add(uSyncChange.Delete(relationType.Alias, obsoleteRelation.ParentId.ToString(), obsoleteRelation.ChildId.ToString())); relationService.Delete(obsoleteRelation); } } return(changes); }
protected override SyncAttempt <IMacro> DeserializeCore(XElement node, SyncSerializerOptions options) { var details = new List <uSyncChange>(); if (node.Element("Name") == null) { throw new ArgumentNullException("XML missing Name parameter"); } var item = default(IMacro); var key = node.GetKey(); var alias = node.GetAlias(); var name = node.Element("Name").ValueOrDefault(string.Empty); var macroSource = node.Element("MacroSource").ValueOrDefault(string.Empty); var macroType = node.Element("MacroType").ValueOrDefault(MacroTypes.PartialView); logger.Debug <MacroSerializer>("Macro by Key [{0}]", key); item = macroService.GetById(key); if (item == null) { logger.Debug <MacroSerializer>("Macro by Alias [{0}]", key); item = macroService.GetByAlias(alias); } if (item == null) { logger.Debug <MacroSerializer>("Creating New [{0}]", key); item = new Macro(alias, name, macroSource, macroType); details.Add(uSyncChange.Create(alias, name, "New Macro")); } if (item.Key != key) { details.AddUpdate("Key", item.Key, key); item.Key = key; } if (item.Name != name) { details.AddUpdate("Name", item.Name, name); item.Name = name; } if (item.Alias != alias) { details.AddUpdate("Alias", item.Alias, alias); item.Alias = alias; } if (item.MacroSource != macroSource) { details.AddUpdate("MacroSource", item.MacroSource, macroSource); item.MacroSource = macroSource; } if (item.MacroType != macroType) { details.AddUpdate("MacroType", item.MacroType, macroType); item.MacroType = macroType; } var useInEditor = node.Element("UseInEditor").ValueOrDefault(false); var dontRender = node.Element("DontRender").ValueOrDefault(false); var cacheByMember = node.Element("CachedByMember").ValueOrDefault(false); var cacheByPage = node.Element("CachedByPage").ValueOrDefault(false); var cacheDuration = node.Element("CachedDuration").ValueOrDefault(0); if (item.UseInEditor != useInEditor) { details.AddUpdate("UseInEditor", item.UseInEditor, useInEditor); item.UseInEditor = useInEditor; } if (item.DontRender != dontRender) { details.AddUpdate("DontRender", item.DontRender, dontRender); item.DontRender = dontRender; } if (item.CacheByMember != cacheByMember) { details.AddUpdate("CacheByMember", item.CacheByMember, cacheByMember); item.CacheByMember = cacheByMember; } if (item.CacheByPage != cacheByPage) { details.AddUpdate("CacheByPage", item.CacheByPage, cacheByPage); item.CacheByPage = cacheByPage; } if (item.CacheDuration != cacheDuration) { details.AddUpdate("CacheByMember", item.CacheDuration, cacheDuration); item.CacheDuration = cacheDuration; } var properties = node.Element("Properties"); if (properties != null && properties.HasElements) { foreach (var propNode in properties.Elements("Property")) { var propertyAlias = propNode.Element("Alias").ValueOrDefault(string.Empty); var editorAlias = propNode.Element("EditorAlias").ValueOrDefault(string.Empty); var propertyName = propNode.Element("Name").ValueOrDefault(string.Empty); var sortOrder = propNode.Element("SortOrder").ValueOrDefault(0); logger.Debug <MacroSerializer>(" > Property {0} {1} {2} {3}", propertyAlias, editorAlias, propertyName, sortOrder); var propPath = $"{alias}: {propertyName}"; if (item.Properties.ContainsKey(propertyAlias)) { logger.Debug <MacroSerializer>(" >> Updating {0}", propertyAlias); item.Properties.UpdateProperty(propertyAlias, propertyName, sortOrder, editorAlias); } else { logger.Debug <MacroSerializer>(" >> Adding {0}", propertyAlias); details.Add(uSyncChange.Create(propPath, "Property", propertyAlias)); item.Properties.Add(new MacroProperty(propertyAlias, propertyName, sortOrder, editorAlias)); } } } if (options.DeleteItems()) { RemoveOrphanProperties(item, properties); } return(SyncAttempt <IMacro> .Succeed(item.Name, item, ChangeType.Import, details)); }
protected IEnumerable <uSyncChange> DeserializeProperties(TObject item, XElement node, SyncSerializerOptions options) { logger.Debug(serializerType, "Deserializing Properties"); var propertiesNode = node?.Element("GenericProperties"); if (propertiesNode == null) { return(Enumerable.Empty <uSyncChange>()); } /// there are something we can't do in the loop, /// so we store them and do them once we've put /// things in. List <string> propertiesToRemove = new List <string>(); Dictionary <string, string> propertiesToMove = new Dictionary <string, string>(); List <uSyncChange> changes = new List <uSyncChange>(); foreach (var propertyNode in propertiesNode.Elements("GenericProperty")) { var alias = propertyNode.Element("Alias").ValueOrDefault(string.Empty); if (string.IsNullOrEmpty(alias)) { continue; } var key = propertyNode.Element("Key").ValueOrDefault(alias.GetHashCode().ToGuid()); var definitionKey = propertyNode.Element("Definition").ValueOrDefault(Guid.Empty); var propertyEditorAlias = propertyNode.Element("Type").ValueOrDefault(string.Empty); logger.Debug(serializerType, " > Property: {0} {1} {2} {3}", alias, key, definitionKey, propertyEditorAlias); bool IsNew = false; var property = GetOrCreateProperty(item, key, alias, definitionKey, propertyEditorAlias, out IsNew); if (property == null) { continue; } if (key != Guid.Empty && property.Key != key) { changes.AddUpdate("Key", property.Key, key, $"{alias}/Key"); property.Key = key; } if (property.Alias != alias) { changes.AddUpdate("Alias", property.Alias, alias, $"{alias}/Alias"); property.Alias = alias; } var name = propertyNode.Element("Name").ValueOrDefault(alias); if (property.Name != name) { changes.AddUpdate("Name", property.Name, name, $"{alias}/Name"); property.Name = name; } var description = propertyNode.Element("Description").ValueOrDefault(string.Empty); if (property.Description != description) { changes.AddUpdate("Description", property.Description, description, $"{alias}/Description"); property.Description = description; } var mandatory = propertyNode.Element("Mandatory").ValueOrDefault(false); if (property.Mandatory != mandatory) { changes.AddUpdate("Mandatory", property.Mandatory, mandatory, $"{alias}/Mandatory"); property.Mandatory = mandatory; } var regEx = propertyNode.Element("Validation").ValueOrDefault(string.Empty); if (property.ValidationRegExp != regEx) { changes.AddUpdate("Validation", property.ValidationRegExp, regEx, $"{alias}/RegEx"); property.ValidationRegExp = propertyNode.Element("Validation").ValueOrDefault(string.Empty); } var sortOrder = propertyNode.Element("SortOrder").ValueOrDefault(0); if (property.SortOrder != sortOrder) { changes.AddUpdate("SortOrder", property.SortOrder, sortOrder, $"{alias}/SortOrder"); property.SortOrder = sortOrder; } // added in v8.6 // reflection is fast but a a quick check of version is faster ! if (UmbracoVersion.LocalVersion.Major > 8 || UmbracoVersion.LocalVersion.Minor >= 6) { changes.AddNotNull(DeserializeNewProperty <string>(property, propertyNode, "MandatoryMessage")); changes.AddNotNull(DeserializeNewProperty <string>(property, propertyNode, "ValidationRegExpMessage")); } if (UmbracoVersion.LocalVersion.Major > 8 || UmbracoVersion.LocalVersion.Minor >= 10) { changes.AddNotNull(DeserializeNewProperty <bool>(property, propertyNode, "LabelOnTop")); } changes.AddRange(DeserializeExtraProperties(item, property, propertyNode)); var tab = propertyNode.Element("Tab").ValueOrDefault(string.Empty); if (IsNew) { changes.AddNew(alias, name, alias); logger.Debug(serializerType, "Property Is new adding to tab."); if (string.IsNullOrWhiteSpace(tab)) { item.AddPropertyType(property); } else { item.AddPropertyType(property, tab); } } else { logger.Debug(serializerType, "Property exists, checking tab location"); // we need to see if this one has moved. if (!string.IsNullOrWhiteSpace(tab)) { var tabGroup = item.PropertyGroups.FirstOrDefault(x => x.Name.InvariantEquals(tab)); if (tabGroup != null) { if (!tabGroup.PropertyTypes.Contains(property.Alias)) { // add to our move list. propertiesToMove[property.Alias] = tab; } } } } } // move things between tabs. changes.AddRange(MoveProperties(item, propertiesToMove)); if (options.DeleteItems()) { // remove what needs to be removed changes.AddRange(RemoveProperties(item, propertiesNode)); } else { logger.Debug(serializerType, "Property Removal disabled by config"); } return(changes); }