/// <inheritdoc/> public override bool Set(Address a, object data, Dictionary <string, object> setOptions) { if (a == null) { a = GetAddress(data); } var ci = (ContentItem)GetContainer(a, data); var updatedData = SetRelated(ci.Path, data, (bool)(setOptions.ContainsKey("bypassChecks") ? setOptions["bypassChecks"] : false)); if (updatedData != null) { ci = (ContentItem)GetContainer(a, updatedData); } if (data is ICoreMetadata && !((ICoreMetadata)data).HasMetadata()) { TypeExtender.CopyExtensionData(ci, data); } var created = Repository.Set(new List <object> { ci }, setOptions); return(created[0]); }
protected virtual ContentItem GetNewRecord(Type type, string path) { var newCI = System.Repository.New <ContentItem>(); newCI.Path = path; newCI.DataType = type.FullName; Type extType = System.Extender[type] ?? type; var newContent = Activator.CreateInstance(extType); var address = new Address(type, path); address.SetAddressFields(newContent); if (newContent is ICoreMetadata) { TypeExtender.CopyExtensionData(newCI, newContent); } newContent = System.Events.ProcessEvent("ContentItem.New", this, newContent).Data; newCI.SetContent(System, newContent); // ensure it is created in the current version System.Versions.SetVersion(System.Versions.CurrentVersion, newCI); return(newCI); }
private ContentItem GetContentItem(Address a, object data) { string dataPath = null; string routePath = null; ContentItem contentItem = null; // try and get path from data via attributes Address address = new Address(data); if (address.Count > 0) { dataPath = address.GetAsContentPath(); } // Get requested path if (a != null) { routePath = a.GetAsContentPath(); } // We have path in data and address parameter and they disagree if (dataPath != null && routePath != null && dataPath != routePath) { // Raise event here for when address is changed via changing addressed mapped fields on data System.Events.ProcessEvent("Content.Move", this, Tuple.Create(a, data)); // regenerate path in case event processor changed data address = new Address(data); dataPath = address.GetAsContentPath(); routePath = a.GetAsContentPath(); } string path = dataPath ?? routePath; // if we have an extended content object, we can use the OriginalRecord if must as we have no path, or if the path is the same if (data is ICoreMetadata) { contentItem = (ContentItem)Activator.CreateInstance(System.Extender[typeof(ContentItem)] ?? typeof(ContentItem)); TypeExtender.CopyExtensionData(data, contentItem); contentItem.DataType = data.GetType().UnextendedType().FullName; if (path == null || path == contentItem.Path) { contentItem.SetContent(System, data); return(contentItem); } } // If we get to here, we can't find the path if (path == null) { throw new ArgumentException("Cannot find path of " + data.GetType().FullName); } // Now we have to get the content item from the db so we get the right ids etc var findPath = routePath ?? dataPath; var contentItems = System.Repository.Get <ContentItem>(data.GetType(), iq => iq.Where(ci => ci.Path == findPath)).ToList(); if (contentItems.Count > 1) { throw new Exception("Duplicate content items at " + findPath + " of type " + data.GetType().FullName); } contentItem = contentItems.SingleOrDefault(); // If we can't we build a new one if (contentItem == null) { contentItem = Repository.New <ContentItem>(); contentItem.DataType = data.GetType().FullName; } contentItem.Path = path; contentItem.SetContent(System, data); if (data is ICoreMetadata) { TypeExtender.CopyExtensionData(contentItem, data); } return(contentItem); }
/// <summary> /// Get the content of the item as an object /// </summary> /// <returns>The contained content item</returns> public object GetContent(TypeExtender extender) { Type type = this.ContentType; Type extType = extender[type] ?? type; if (contentObject != null) { return(contentObject); } JObject contentJObject = null; if (string.IsNullOrEmpty(this.Content)) { contentObject = Activator.CreateInstance(extType); if (this.Id != Guid.Empty) // shouldn't normally happen { log.WarnFormat("Reading content from contentitem {0} with no content: {1}", this.Id, Environment.StackTrace); } } else { contentJObject = JObject.Parse(this.Content); var sz = JsonSerializer.Create(GetSerializerSettings(type, this.Id)); contentObject = contentJObject.ToObject(extType, sz); if (contentObject == null) { contentObject = Activator.CreateInstance(extType); } } var summaryMap = GetSummaryProperties(type); // Set the summary property(ies) if record field has data if (!string.IsNullOrEmpty(this.Summary) && summaryMap.Count > 0) { var summType = GetSummaryType(type); var summ = JsonConvert.DeserializeObject(this.Summary, summType, GetSerializerSettings(type, this.Id)); if (summaryMap.ContainsKey("")) { summaryMap[""].SetValue(contentObject, summ); } else { JToken dummy; // We check contentJObject to see if the summary property existed in the serialization of the // content, in which case we don't use the property from the summary. This allows us to safely // change the content classes by adding a property to the summary without losing the data in // that property. Removal of a property from the summary will still cause data loss however. summaryMap.Do(kvp => { if (kvp.Value.CanWrite && kvp.Value.GetCustomAttribute <JsonIgnoreAttribute>() == null && !contentJObject.TryGetValue(kvp.Value.Name, out dummy)) { if (summType.GetProperty(kvp.Key) == null) { throw new Exception("Type " + type.FullName + " has property " + kvp.Key + " incorrectly marked as being on summary type " + summType.FullName); } kvp.Value.SetValue(contentObject, summType.GetProperty(kvp.Key).GetValue(summ)); } }); } } if (this.Title != null) { if (summaryMap.ContainsKey("")) { var summ = summaryMap[""].GetValue(contentObject); // we know it has the property Title as it inherits from Summary summ.GetType().GetProperty("Title").SetValue(summ, this.Title); summaryMap[""].SetValue(contentObject, summ); } else { var titleProp = type.GetProperty("Title"); if (summaryMap.ContainsKey("Title")) { titleProp = summaryMap["Title"]; } if (titleProp != null) { titleProp.SetValue(contentObject, this.Title); } } } // Set up metadata if possible if (typeof(ICoreMetadata).IsAssignableFrom(extType)) { TypeExtender.CopyExtensionData(this, contentObject); } return(contentObject); }