/// <summary> /// Updates or adds the content item. If content item already exists, it updates it. /// If content item doesn't exists, it creates new content item (in that case contentItem.Id will be set to newly created id). /// NOTE: Set the ParentId property of this item. /// </summary> /// <param name="contentItem">Content item to update/add</param> /// <param name="userId">User used for add or updating the content</param> /// <param name="publish">If set to <c>true</c> it contentItem will be published as well.</param> public static void Save(DocumentTypeBase contentItem, int userId, bool publish) { if (contentItem.ParentId < 1) { throw new ArgumentException("Parent property cannot be null"); } if (String.IsNullOrEmpty(contentItem.Name)) { throw new Exception("Name property of this content item is not set"); } IContentType contentType = DocumentTypeManager.GetDocumentType(contentItem.GetType()); IContent content; if (contentItem.Id == 0) // content item is new so create Document { content = ContentService.CreateContent(contentItem.Name, contentItem.ParentId, contentType.Alias); } else // content item already exists, so load it { content = ContentService.GetById(contentItem.Id); } var documentTypeProperties = contentItem.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance); SaveProperties(contentItem, contentType, content, documentTypeProperties); if (publish) { ContentService.SaveAndPublish(content, userId); contentItem.Id = content.Id; } }
private void ContentServiceOnCreating(IContentService sender, NewEventArgs <IContent> newEventArgs) { Type typeDocType = DocumentTypeManager.GetDocumentTypeType(newEventArgs.Alias); if (typeDocType != null) { foreach (PropertyInfo propInfo in typeDocType.GetProperties(BindingFlags.Public | BindingFlags.Instance)) { DocumentTypePropertyAttribute propAttr = Util.GetAttribute <DocumentTypePropertyAttribute>(propInfo); if (propAttr == null) { continue; // skip this property - not part of a Document Type } string propertyName; string propertyAlias; ReadPropertyNameAndAlias(propInfo, propAttr, out propertyName, out propertyAlias); if (propAttr.DefaultValue != null) { try { newEventArgs.Entity.SetValue(propertyAlias, propAttr.DefaultValue); } catch (Exception exc) { throw new Exception(string.Format("Cannot set default value ('{0}') for property {1}.{2}. Error: {3}", propAttr.DefaultValue, typeDocType.Name, propInfo.Name, exc.Message), exc); } } } } }
/// <summary> /// Gets all children nodes of a given type from a given node id. /// </summary> /// <typeparam name="T">Strongly typed content item</typeparam> /// <param name="parentId">Parent node id of all children to get</param> /// <param name="deepGet">If true it does deep search for children in the whole content tree starting from node whose id is parentId)</param> public static IEnumerable <T> GetChildren <T>(int parentId, bool deepGet) where T : DocumentTypeBase, new() { Node parentNode = uQuery.GetNode(parentId); string docTypeAlias = DocumentTypeManager.GetDocumentTypeAlias(typeof(T)); IEnumerable <Node> childNodes = null; if (deepGet) { childNodes = parentNode.GetDescendantNodes(); } else { childNodes = parentNode.GetChildNodes(); } foreach (Node childNode in childNodes) { // Check if this childNode is of a given document type and if not deleted if (docTypeAlias == childNode.NodeTypeAlias && !ContentHelper.IsInRecycleBin(childNode.Path)) { var d = ContentHelper.GetByNode <T>(childNode); if (d != null) { yield return(d); } } } }
public virtual T CreateAndPopulateTypedInstance <T>(Node node) where T : DocumentTypeBase { T retVal = null; if (node != null) { Type typeDocType = DocumentTypeManager.GetDocumentTypeType(node.NodeTypeAlias); if (typeDocType == null) { var message = string.Format( "Error processing document with id {0} of type '{1}' - no code for the document type found. ", node.Id, node.NodeTypeAlias); throw new Exception(message); } T typedPage = (T)CreateInstance(typeDocType); if (ContentHelper.PopuplateInstance <T>(node, typeDocType, typedPage)) { retVal = typedPage; } } return(retVal); }
/// <summary> /// The method saves values from the given properties of the valueSource specified to the content of the contentType type /// </summary> /// <param name="valueSource">An object to get property values from. Can be either DocumentTypeBase or mixin object reference</param> /// <param name="contentType">A content type information</param> /// <param name="content">A content to save values to</param> /// <param name="properties">A valueSource properties collection</param> private static void SaveProperties(object valueSource, IContentType contentType, IContent content, IEnumerable <PropertyInfo> properties) { foreach (var propInfo in properties) { try { var mixinAttribute = Util.GetAttribute <MixinPropertyAttribute>(propInfo); if (mixinAttribute != null) { var mixin = propInfo.GetValue(valueSource, null); if (mixin != null) { var mixinType = mixinAttribute.GetMixinType(propInfo); var mixinProperties = mixinType.GetProperties(BindingFlags.Public | BindingFlags.Instance); SaveProperties(mixin, contentType, content, mixinProperties); } continue; } DocumentTypePropertyAttribute propAttr = Util.GetAttribute <DocumentTypePropertyAttribute>(propInfo); if (propAttr == null) { continue; // skip this property - not part of a Document Type } string propertyName; string propertyAlias; DocumentTypeManager.ReadPropertyNameAndAlias(propInfo, propAttr, out propertyName, out propertyAlias); PropertyType property = content.PropertyTypes.FirstOrDefault(p => p.Alias == propertyAlias); if (property == null) { throw new Exception(string.Format("Property '{0}' not found in this node: {1}. Content type: {2}.", propertyAlias, content.Id, contentType.Alias)); } if (PropertyConvertors.ContainsKey(propInfo.PropertyType)) { content.SetValue(propertyAlias, PropertyConvertors[propInfo.PropertyType].ConvertValueWhenWrite(propInfo.GetValue(valueSource, null))); } else { content.SetValue(propertyAlias, propInfo.GetValue(valueSource, null)); } } catch (Exception exc) { throw new Exception(String.Format("Error while saving property: {0}.{1}. Error: {2}, Stack trace: {3}", contentType.Alias, propInfo.Name, exc.Message, exc.StackTrace), exc); } } }
public static void SynchronizeDocumentTypes() { #if DEBUG Stopwatch timer = new Stopwatch(); timer.Start(); #endif DocumentTypeManager docTypeManager = new DocumentTypeManager(); docTypeManager.Synchronize(); #if DEBUG timer.Stop(); StopwatchLogger.AddToLog(string.Format("Total elapsed time for method 'SynchronizeDocumentTypes': {0}ms.", timer.ElapsedMilliseconds)); timer.Restart(); #endif }
/// <summary> /// Gets all ancestor nodes of a given type from a given node id. /// (parent's path back to root) /// </summary> /// <typeparam name="T">Strongly typed content item</typeparam> /// <param name="nodeId">Id of node for which to retrieve node ancestors</param> public static IEnumerable <T> GetAncestors <T>(int nodeId) where T : DocumentTypeBase, new() { Node parentNode = uQuery.GetNode(nodeId); string docTypeAlias = DocumentTypeManager.GetDocumentTypeAlias(typeof(T)); IEnumerable <Node> ancestorNodes = parentNode.GetAncestorNodes(); foreach (Node childNode in ancestorNodes) { // Check if this childNode is of a given document type and if not deleted if (docTypeAlias != childNode.NodeTypeAlias) { continue; } var d = ContentHelper.GetByNode <T>(childNode); if (d != null) { yield return(d); } } }
/// <summary> /// Deletes single document type from Umbraco /// </summary> /// <param name="alias"></param> public static void DeleteDocumentType(string alias) { DocumentTypeManager.DeleteDocumentType(alias); }
/// <summary> /// Gets document type name for the given type /// </summary> /// <typeparam name="T"></typeparam> /// <returns></returns> public static IContentType GetDocumentType <T>() { return(DocumentTypeManager.GetDocumentType(typeof(T))); }
/// <summary> /// Gets document type name for the given type /// </summary> /// <typeparam name="T"></typeparam> /// <returns></returns> public static string GetDocumentTypeName <T>() { return(DocumentTypeManager.GetDocumentType(typeof(T)).Name); }
/// <summary> /// Gets document type alias for the given type /// </summary> /// <typeparam name="T"></typeparam> /// <returns></returns> public static string GetDocumentTypeAlias <T>() where T : DocumentTypeBase { return(DocumentTypeManager.GetDocumentTypeAlias(typeof(T))); }
internal static object GetPropertyValue(Node sourceNode, PropertyInfo propInfo, DocumentTypePropertyAttribute propAttr) { string propertyName; string propertyAlias; object value = null; if (propAttr == null) { propAttr = Util.GetAttribute <DocumentTypePropertyAttribute>(propInfo); } DocumentTypeManager.ReadPropertyNameAndAlias(propInfo, propAttr, out propertyName, out propertyAlias); var property = sourceNode.GetProperty(propertyAlias); if (property == null) { value = null; } else if (propInfo.PropertyType.Equals(typeof(Boolean))) { if (String.IsNullOrEmpty(property.Value) || property.Value == "0") { value = false; } else { value = true; } } else if (propAttr.CustomTypeConverter != null) { value = ((ICustomTypeConvertor)Activator.Current.GetInstance(propAttr.CustomTypeConverter)).ConvertValueWhenRead(property.Value); } else if (ContentHelper.PropertyConvertors.ContainsKey(propInfo.PropertyType)) { // will be transformed later. TODO: move transformation here //value = ContentHelper.GetInnerXml(node.Id.ToString(), propertyAlias); value = PropertyConvertors[propInfo.PropertyType].ConvertValueWhenRead(property.Value); } else if (String.IsNullOrEmpty(property.Value)) { // if property type is string or if it's some custom type, try to get the inner xml of this property within a node. if (propInfo.PropertyType == typeof(string) || ContentHelper.PropertyConvertors.ContainsKey(propInfo.PropertyType)) { value = ContentHelper.GetInnerXml(sourceNode.Id.ToString(), propertyAlias); if (value == null && propInfo.PropertyType == typeof(string)) { value = string.Empty; } } else { value = null; } } else if (propInfo.PropertyType.IsGenericType && propInfo.PropertyType.GetGenericTypeDefinition() == typeof(Nullable <>)) { value = Convert.ChangeType(property.Value, Nullable.GetUnderlyingType(propInfo.PropertyType)); // TODO: If data type is DateTime and is nullable and is less than 1.1.1000 than set it to NULL } else if (propInfo.PropertyType.Equals(typeof(HtmlString))) { value = new HtmlString(property.Value); } else { value = Convert.ChangeType(property.Value, propInfo.PropertyType); } return(value); }
private void SynchronizeMemberTypeProperties(Type typeMemberType, MemberType memberType) { int propertySortOrder = 0; foreach (PropertyInfo propInfo in typeMemberType.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { DocumentTypePropertyAttribute propAttr = Util.GetAttribute <DocumentTypePropertyAttribute>(propInfo); if (propAttr == null) { continue; // skip this property - not part of a document type } // getting name and alias string propertyName; string propertyAlias; DocumentTypeManager.ReadPropertyNameAndAlias(propInfo, propAttr, out propertyName, out propertyAlias); if (HasObsoleteAttribute(propInfo)) { Util.DeletePropertyType(memberType, propertyAlias); continue; } if (propAttr.DefaultValue != null) { _hadDefaultValues = true; // at least one property has a default value } umbraco.cms.businesslogic.datatype.DataTypeDefinition dataTypeDefinition = GetDataTypeDefinition(typeMemberType, propAttr, propInfo); // getting property if already exists, or creating new if it not exists umbraco.cms.businesslogic.propertytype.PropertyType propertyType = memberType.PropertyTypes.FirstOrDefault(p => p.Alias == propertyAlias); if (propertyType == null) // if not exists, create it { memberType.AddPropertyType(dataTypeDefinition, propertyAlias, propertyName); propertyType = memberType.PropertyTypes.FirstOrDefault(p => p.Alias == propertyAlias); } //// Setting up the tab of this property. If tab doesn't exists, create it. if (!string.IsNullOrEmpty(propAttr.TabAsString) && propAttr.TabAsString.ToLower() != DocumentTypeDefaultValues.TabGenericProperties.ToLower()) { // try to find this tab umbraco.cms.businesslogic.propertytype.PropertyTypeGroup pg = memberType.PropertyTypeGroups.FirstOrDefault(x => x.Name == propAttr.TabAsString); if (pg == null) // if found { memberType.AddVirtualTab(propAttr.TabAsString); pg = memberType.PropertyTypeGroups.FirstOrDefault(x => x.Name == propAttr.TabAsString); } if (propAttr.TabOrder.HasValue) { pg.SortOrder = propAttr.TabOrder.Value; } propertyType.PropertyTypeGroup = pg.Id; } propertyType.Name = propertyName; propertyType.Mandatory = propAttr.Mandatory; propertyType.ValidationRegExp = propAttr.ValidationRegExp; propertyType.Description = propAttr.Description; propertyType.SortOrder = propertySortOrder; propertySortOrder++; } }
/// <summary> /// Removes all Umbraco document types that are not defined using uSiteBuilder /// </summary> public static void CleanUpDocumentTypes() { DocumentTypeManager.CleanUpDocumentTypes(); }
//#region [Document type properties synchronization] /// <summary> /// Synchronizes content type properties /// </summary> /// <param name="typeContentType">ContentType type</param> /// <param name="contentType">Umbraco content type</param> /// <param name="hadDefaultValues">set to true if some of properties has default values</param> protected void SynchronizeContentTypeProperties(Type typeContentType, IContentType contentType, DocumentTypeAttribute documentTypeAttribute, out bool hadDefaultValues, bool updateMixins) { // sync the mixins first so that any properties are overwritten by the specific properties on the class if ((documentTypeAttribute.Mixins != null) && (updateMixins == false)) { foreach (Type mixinType in documentTypeAttribute.Mixins) { SynchronizeContentTypeProperties(mixinType, contentType, documentTypeAttribute, out hadDefaultValues, true); } } hadDefaultValues = false; int propertySortOrder = 0; foreach (PropertyInfo propInfo in typeContentType.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { DocumentTypePropertyAttribute propAttr = Util.GetAttribute <DocumentTypePropertyAttribute>(propInfo); if (propAttr == null) { continue; // skip this property - not part of a document type } // Getting name and alias string propertyName; string propertyAlias; DocumentTypeManager.ReadPropertyNameAndAlias(propInfo, propAttr, out propertyName, out propertyAlias); // Remove property if it has Obsolete attribute if (this.RemoveIfObsolete(contentType, propInfo, propertyAlias)) { continue; } if (propAttr.DefaultValue != null) { hadDefaultValues = true; // at least one property has a default value } DataTypeDefinition dataTypeDefinition = GetDataTypeDefinition(typeContentType, propAttr, propInfo); // getting property if already exists, or creating new if it not exists Umbraco.Core.Models.PropertyType propertyType = contentType.PropertyTypes.FirstOrDefault(p => p.Alias == propertyAlias); if (propertyType == null) // if not exists, create it { Util.AddPropertyType(contentType, dataTypeDefinition, propertyAlias, propertyName, propAttr.TabAsString); propertyType = contentType.PropertyTypes.FirstOrDefault(p => p.Alias == propertyAlias); } else { if (propertyType.DataTypeDefinitionId != dataTypeDefinition.Id) { propertyType.DataTypeDefinitionId = dataTypeDefinition.Id; } } // If propertyType is still null, skip it. It means it cannot be added and is probably present in a parent content type. // Reason for inability to create the propertyType must be resolved manually. if (propertyType != null) { // Setting up the tab of this property. If tab doesn't exists, create it. if (!string.IsNullOrEmpty(propAttr.TabAsString) && propAttr.TabAsString.ToLower() != DocumentTypeDefaultValues.TabGenericProperties.ToLower()) { // try to find this tab PropertyGroup pg = contentType.PropertyGroups.FirstOrDefault(x => x.Name == propAttr.TabAsString); if (pg == null) // if found { contentType.AddPropertyGroup(propAttr.TabAsString); pg = contentType.PropertyGroups.FirstOrDefault(x => x.Name == propAttr.TabAsString); } if (propAttr.TabOrder.HasValue) { pg.SortOrder = propAttr.TabOrder.Value; } if (!pg.PropertyTypes.Any(x => x.Alias == propertyType.Alias)) { contentType.MovePropertyType(propertyType.Alias, propAttr.TabAsString); } } else if ((propAttr.TabAsString == string.Empty) || (propAttr.TabAsString.ToLower() == "generic properties")) { // In case when some property exists and needs to be moved to "Generic Properties" tab contentType.MovePropertyType(propertyType.Alias, null); } propertyType.Name = propertyName; propertyType.Mandatory = propAttr.Mandatory; propertyType.ValidationRegExp = propAttr.ValidationRegExp; propertyType.Description = propAttr.Description; propertyType.SortOrder = propertySortOrder; propertySortOrder++; } } }
public static void ReadProperties(Type contentType, Content content, object output) { foreach (PropertyInfo propInfo in contentType.GetProperties(BindingFlags.Public | BindingFlags.Instance)) { DocumentTypePropertyAttribute propAttr = Util.GetAttribute <DocumentTypePropertyAttribute>(propInfo); if (propAttr == null) { continue; // skip this property - not part of a Document Type } string propertyName; string propertyAlias; DocumentTypeManager.ReadPropertyNameAndAlias(propInfo, propAttr, out propertyName, out propertyAlias); umbraco.cms.businesslogic.property.Property property = content.getProperty(propertyAlias); object value = null; try { if (property == null) { value = null; } else if (propInfo.PropertyType.Equals(typeof(System.Boolean))) { if (String.IsNullOrEmpty(Convert.ToString(property.Value)) || Convert.ToString(property.Value) == "0") { value = false; } else { value = true; } } else if (PropertyConvertors.ContainsKey(propInfo.PropertyType)) { value = ContentUtil.GetInnerXml(content.Id.ToString(), propertyAlias); } else if (String.IsNullOrEmpty(Convert.ToString(property.Value))) { // if property type is string or if it's some custom type, try to get the inner xml of this property within a node. if (propInfo.PropertyType == typeof(string) || PropertyConvertors.ContainsKey(propInfo.PropertyType)) { value = ContentUtil.GetInnerXml(content.Id.ToString(), propertyAlias); if (value == null && propInfo.PropertyType == typeof(string)) { value = string.Empty; } } else { value = null; } } else if (propInfo.PropertyType.IsGenericType && propInfo.PropertyType.GetGenericTypeDefinition() == typeof(Nullable <>)) { value = Convert.ChangeType(property.Value, Nullable.GetUnderlyingType(propInfo.PropertyType)); // TODO: If data type is DateTime and is nullable and is less than 1.1.1000 than set it to NULL } else { value = Convert.ChangeType(property.Value, propInfo.PropertyType); } if (PropertyConvertors.ContainsKey(propInfo.PropertyType)) { value = PropertyConvertors[propInfo.PropertyType].ConvertValueWhenRead(value); } propInfo.SetValue(output, value, null); } catch (Exception exc) { throw new Exception(string.Format("Cannot set the value of a document type property {0}.{1} (document type: {2}) to value: '{3}' (value type: {4}). Error: {5}", contentType.Name, propInfo.Name, propInfo.PropertyType.FullName, value, value != null ? value.GetType().FullName : "", exc.Message)); } } }