public void Can_Serialize_Without_Error() { var ss = new SerializationService(new JsonNetSerializer()); var item = new UmbracoEntity() { Id = 3, ContentTypeAlias = "test1", CreatorId = 4, Key = Guid.NewGuid(), UpdateDate = DateTime.Now, CreateDate = DateTime.Now, Name = "Test", ParentId = 5, SortOrder = 6, Path = "-1,23", Level = 7, ContentTypeIcon = "icon", ContentTypeThumbnail = "thumb", HasChildren = true, HasPendingChanges = true, IsDraft = true, IsPublished = true, NodeObjectTypeId = Guid.NewGuid() }; item.AdditionalData.Add("test1", 3); item.AdditionalData.Add("test2", "valuie"); var result = ss.ToStream(item); var json = result.ResultStream.ToJsonString(); Debug.Print(json); }
public void Can_Deep_Clone() { var item = new UmbracoEntity() { Id = 3, ContentTypeAlias = "test1", CreatorId = 4, Key = Guid.NewGuid(), UpdateDate = DateTime.Now, CreateDate = DateTime.Now, Name = "Test", ParentId = 5, SortOrder = 6, Path = "-1,23", Level = 7, ContentTypeIcon = "icon", ContentTypeThumbnail = "thumb", HasChildren = true, HasPendingChanges = true, IsDraft = true, IsPublished = true, NodeObjectTypeId = Guid.NewGuid() }; item.AdditionalData.Add("test1", 3); item.AdditionalData.Add("test2", "valuie"); var clone = (UmbracoEntity)item.DeepClone(); Assert.AreNotSame(clone, item); Assert.AreEqual(clone, item); Assert.AreEqual(clone.CreateDate, item.CreateDate); Assert.AreEqual(clone.ContentTypeAlias, item.ContentTypeAlias); Assert.AreEqual(clone.CreatorId, item.CreatorId); Assert.AreEqual(clone.Id, item.Id); Assert.AreEqual(clone.Key, item.Key); Assert.AreEqual(clone.Level, item.Level); Assert.AreEqual(clone.Name, item.Name); Assert.AreEqual(clone.ParentId, item.ParentId); Assert.AreEqual(clone.SortOrder, item.SortOrder); Assert.AreEqual(clone.Path, item.Path); Assert.AreEqual(clone.ContentTypeIcon, item.ContentTypeIcon); Assert.AreEqual(clone.ContentTypeThumbnail, item.ContentTypeThumbnail); Assert.AreEqual(clone.HasChildren, item.HasChildren); Assert.AreEqual(clone.HasPendingChanges, item.HasPendingChanges); Assert.AreEqual(clone.IsDraft, item.IsDraft); Assert.AreEqual(clone.IsPublished, item.IsPublished); Assert.AreEqual(clone.NodeObjectTypeId, item.NodeObjectTypeId); Assert.AreEqual(clone.UpdateDate, item.UpdateDate); Assert.AreEqual(clone.AdditionalData.Count, item.AdditionalData.Count); Assert.AreEqual(clone.AdditionalData, item.AdditionalData); //This double verifies by reflection var allProps = clone.GetType().GetProperties(); foreach (var propertyInfo in allProps) { Assert.AreEqual(propertyInfo.GetValue(clone, null), propertyInfo.GetValue(item, null)); } }
/// <summary> /// Creates an XmlTreeNode based on the passed in UmbracoEntity /// </summary> /// <param name="dd"></param> /// <param name="allowedUserOptions"></param> /// <returns></returns> internal XmlTreeNode CreateNode(UmbracoEntity dd, List <IAction> allowedUserOptions) { XmlTreeNode node = XmlTreeNode.Create(this); SetMenuAttribute(ref node, allowedUserOptions); node.NodeID = dd.Id.ToString(); node.Text = dd.Name; SetNonPublishedAttribute(ref node, dd); SetProtectedAttribute(ref node, dd); SetActionAttribute(ref node, dd); SetSourcesAttributes(ref node, dd); if (dd.ContentTypeIcon != null) { node.Icon = dd.ContentTypeIcon; node.OpenIcon = dd.ContentTypeIcon; } if (dd.IsPublished == false) { node.Style.DimNode(); } if (dd.HasPendingChanges) { node.Style.HighlightNode(); } return(node); }
public void Ensure_Path_Throws_Without_Id() { var entity = new UmbracoEntity(); //no id assigned Assert.Throws <InvalidOperationException>(() => entity.EnsureValidPath(Mock.Of <ILogger>(), umbracoEntity => new UmbracoEntity(), umbracoEntity => { })); }
/// <summary> /// Helper method to create tree nodes and automatically generate the json url + UDI /// </summary> /// <param name="entity"></param> /// <param name="entityObjectType"></param> /// <param name="parentId"></param> /// <param name="queryStrings"></param> /// <param name="hasChildren"></param> /// <returns></returns> public TreeNode CreateTreeNode(UmbracoEntity entity, Guid entityObjectType, string parentId, FormDataCollection queryStrings, bool hasChildren) { var treeNode = CreateTreeNode(entity.Id.ToInvariantString(), parentId, queryStrings, entity.Name, entity.ContentTypeIcon); treeNode.Udi = Udi.Create(UmbracoObjectTypesExtensions.GetUdiType(entityObjectType), entity.Key); treeNode.HasChildren = hasChildren; return(treeNode); }
/// <summary> /// Determins if the user has access to view the node/document /// </summary> /// <param name="doc">The Document to check permissions against</param> /// <param name="allowedUserOptions">A list of IActions that the user has permissions to execute on the current document</param> /// <remarks>By default the user must have Browse permissions to see the node in the Content tree</remarks> /// <returns></returns> internal virtual bool CanUserAccessNode(UmbracoEntity doc, List <IAction> allowedUserOptions) { if (allowedUserOptions.Contains(ActionBrowse.Instance)) { return(true); } return(false); }
/// <summary> /// Figure out what extra properties we have that are not on the IUmbracoEntity and add them to additional data /// </summary> /// <param name="entity"></param> /// <param name="originalEntityProperties"></param> internal void AddAdditionalData(UmbracoEntity entity, IDictionary <string, object> originalEntityProperties) { foreach (var k in originalEntityProperties.Keys .Select(x => new { orig = x, title = x.ToCleanString(CleanStringType.PascalCase | CleanStringType.Ascii | CleanStringType.ConvertCase) }) .Where(x => EntityProperties.Value.InvariantContains(x.title) == false)) { entity.AdditionalData[k.title] = originalEntityProperties[k.orig]; } }
public void Ensure_Path_Throws_Without_Parent() { var entity = new UmbracoEntity { Id = 1234 }; //no parent found Assert.Throws <NullReferenceException>(() => entity.EnsureValidPath(Mock.Of <ILogger>(), umbracoEntity => null, umbracoEntity => { })); }
public void Ensure_Path_Entity_Valid_Recursive_Parent() { var parentA = new UmbracoEntity { Id = 999, ParentId = -1 }; var parentB = new UmbracoEntity { Id = 888, ParentId = 999 }; var parentC = new UmbracoEntity { Id = 777, ParentId = 888 }; var entity = new UmbracoEntity { Id = 1234, ParentId = 777 }; Func <IUmbracoEntity, IUmbracoEntity> getParent = umbracoEntity => { switch (umbracoEntity.ParentId) { case 999: return(parentA); case 888: return(parentB); case 777: return(parentC); case 1234: return(entity); default: return(null); } }; //this will recursively fix all paths entity.EnsureValidPath(Mock.Of <ILogger>(), getParent, umbracoEntity => { }); Assert.AreEqual("-1,999", parentA.Path); Assert.AreEqual("-1,999,888", parentB.Path); Assert.AreEqual("-1,999,888,777", parentC.Path); Assert.AreEqual("-1,999,888,777,1234", entity.Path); }
internal UmbracoEntity Map(dynamic a, UmbracoPropertyDto p) { // Terminating call. Since we can return null from this function // we need to be ready for PetaPoco to callback later with null // parameters if (a == null) { return(Current); } // Is this the same UmbracoEntity as the current one we're processing if (Current != null && Current.Key == a.uniqueID) { if (p != null && p.PropertyAlias.IsNullOrWhiteSpace() == false) { // Add this UmbracoProperty to the current additional data Current.AdditionalData[p.PropertyAlias] = new UmbracoEntity.EntityProperty { PropertyEditorAlias = p.PropertyEditorAlias, Value = p.NTextValue.IsNullOrWhiteSpace() ? p.NVarcharValue : p.NTextValue.ConvertToJsonIfPossible() }; } // Return null to indicate we're not done with this UmbracoEntity yet return(null); } // This is a different UmbracoEntity to the current one, or this is the // first time through and we don't have a Tab yet // Save the current UmbracoEntityDto var prev = Current; // Setup the new current UmbracoEntity Current = _factory.BuildEntityFromDynamic(a); if (p != null && p.PropertyAlias.IsNullOrWhiteSpace() == false) { //add the property/create the prop list if null Current.AdditionalData[p.PropertyAlias] = new UmbracoEntity.EntityProperty { PropertyEditorAlias = p.PropertyEditorAlias, Value = p.NTextValue.IsNullOrWhiteSpace() ? p.NVarcharValue : p.NTextValue.ConvertToJsonIfPossible() }; } // Return the now populated previous UmbracoEntity (or null if first time through) return(prev); }
internal void SetProtectedAttribute(ref XmlTreeNode treeElement, UmbracoEntity dd) { if (Access.IsProtected(dd.Id, dd.Path)) { treeElement.IsProtected = true; } else { treeElement.IsProtected = false; } }
public void UmbracoEntity_Can_Be_Initialized_From_Dynamic() { var boolIsTrue = true; ulong ulongIsTrue = 1; // because MySql might return ulong var trashedWithBool = new UmbracoEntity((dynamic)boolIsTrue); var trashedWithInt = new UmbracoEntity((dynamic)ulongIsTrue); Assert.IsTrue(trashedWithBool.Trashed); Assert.IsTrue(trashedWithInt.Trashed); }
/// <summary> /// Builds a string of actions that the user is able to perform on the current document. /// The list of actions is subject to the user's rights assigned to the document and also /// is dependant on the type of node. /// </summary> /// <param name="dd"></param> /// <returns></returns> internal List <IAction> GetUserActionsForNode(UmbracoEntity dd) { List <IAction> actions = umbraco.BusinessLogic.Actions.Action.FromString(CurrentUser.GetPermissions(dd.Path)); // A user is allowed to delete their own stuff if (dd.CreatorId == CurrentUser.Id && actions.Contains(ActionDelete.Instance) == false) { actions.Add(ActionDelete.Instance); } return(actions); }
internal void AddAdditionalData(UmbracoEntity entity, IDictionary <string, object> originalEntityProperties) { var entityProps = typeof(IUmbracoEntity).GetPublicProperties().Select(x => x.Name).ToArray(); //figure out what extra properties we have that are not on the IUmbracoEntity and add them to additional data foreach (var k in originalEntityProperties.Keys .Select(x => new { orig = x, title = x.ToCleanString(CleanStringType.PascalCase | CleanStringType.Ascii | CleanStringType.ConvertCase) }) .Where(x => entityProps.InvariantContains(x.title) == false)) { entity.AdditionalData[k.title] = originalEntityProperties[k.orig]; } }
/// <summary> /// NOTE: New implementation of the legacy GetLinkValue. This is however a bit quirky as a media item can have multiple "Linkable DataTypes". /// Returns the value for a link in WYSIWYG mode, by default only media items that have a /// DataTypeUploadField are linkable, however, a custom tree can be created which overrides /// this method, or another GUID for a custom data type can be added to the LinkableMediaDataTypes /// list on application startup. /// </summary> /// <param name="entity"></param> /// <returns></returns> internal virtual string GetLinkValue(UmbracoEntity entity) { foreach (var property in entity.UmbracoProperties) { if (LinkableMediaDataTypes.Contains(property.DataTypeControlId) && string.IsNullOrEmpty(property.Value) == false) { return(property.Value); } } return(""); }
internal void SetNonPublishedAttribute(ref XmlTreeNode treeElement, UmbracoEntity dd) { treeElement.NotPublished = false; if (dd.IsPublished) { treeElement.NotPublished = dd.HasPendingChanges; } else { treeElement.NotPublished = true; } }
internal UmbracoEntity BuildEntityFromDynamic(dynamic d) { var asDictionary = (IDictionary <string, object>)d; var entity = new UmbracoEntity(d.trashed); try { entity.DisableChangeTracking(); entity.CreateDate = d.createDate; entity.CreatorId = d.nodeUser == null ? 0 : d.nodeUser; entity.Id = d.id; entity.Key = d.uniqueID; entity.Level = d.level; entity.Name = d.text; entity.NodeObjectTypeId = d.nodeObjectType; entity.ParentId = d.parentID; entity.Path = d.path; entity.SortOrder = d.sortOrder; entity.HasChildren = d.children > 0; entity.ContentTypeAlias = asDictionary.ContainsKey("alias") ? (d.alias ?? string.Empty) : string.Empty; entity.ContentTypeIcon = asDictionary.ContainsKey("icon") ? (d.icon ?? string.Empty) : string.Empty; entity.ContentTypeThumbnail = asDictionary.ContainsKey("thumbnail") ? (d.thumbnail ?? string.Empty) : string.Empty; var publishedVersion = default(Guid); //some content items don't have a published/newest version if (asDictionary.ContainsKey("publishedVersion") && asDictionary["publishedVersion"] != null) { Guid.TryParse(d.publishedVersion.ToString(), out publishedVersion); } var newestVersion = default(Guid); if (asDictionary.ContainsKey("newestVersion") && d.newestVersion != null) { Guid.TryParse(d.newestVersion.ToString(), out newestVersion); } entity.IsPublished = publishedVersion != default(Guid) || (newestVersion != default(Guid) && publishedVersion == newestVersion); entity.IsDraft = newestVersion != default(Guid) && (publishedVersion == default(Guid) || publishedVersion != newestVersion); entity.HasPendingChanges = (publishedVersion != default(Guid) && newestVersion != default(Guid)) && publishedVersion != newestVersion; //Now we can assign the additional data! AddAdditionalData(entity, asDictionary); return(entity); } finally { entity.EnableChangeTracking(); } }
public void Ensure_Path_Entity_At_Root() { var entity = new UmbracoEntity { Id = 1234, ParentId = -1 }; entity.EnsureValidPath(Mock.Of <ILogger>(), umbracoEntity => null, umbracoEntity => { }); //works because it's under the root Assert.AreEqual("-1,1234", entity.Path); }
/// <summary> /// Creates the link for the current UmbracoEntity /// </summary> /// <param name="dd"></param> /// <returns></returns> internal string CreateNodeLink(UmbracoEntity dd) { string nodeLink = library.NiceUrl(dd.Id); if (nodeLink == "") { nodeLink = "/" + dd.Id; if (GlobalSettings.UseDirectoryUrls == false) { nodeLink += ".aspx"; } } return(nodeLink); }
public void Ensure_Path_Entity_Valid_Parent() { var entity = new UmbracoEntity { Id = 1234, ParentId = 888 }; entity.EnsureValidPath(Mock.Of <ILogger>(), umbracoEntity => umbracoEntity.ParentId == 888 ? new UmbracoEntity { Id = 888, Path = "-1,888" } : null, umbracoEntity => { }); //works because the parent was found Assert.AreEqual("-1,888,1234", entity.Path); }
public static void RenderContentStartNodes(int userId, TreeControllerBase sender, TreeNodesRenderingEventArgs e) { StartNodeCollection startNodes = StartNodeRepository.GetCachedStartNodesByUserId(userId, sender.ApplicationContext, sender.DatabaseContext); if (startNodes.Content == null) { return; } if (startNodes.Content.Any()) { // Remove default start nodes e.Nodes.Clear(); IEnumerable <IUmbracoEntity> startNodesEntities = sender.Services.EntityService.GetAll(Umbraco.Core.Models.UmbracoObjectTypes.Document, startNodes.Content); // Feels like a lot of duct tape. A lot taken from: // https://github.com/umbraco/Umbraco-CMS/blob/5397f2c53acbdeb0805e1fe39fda938f571d295a/src/Umbraco.Web/Trees/ContentTreeController.cs#L75 foreach (IUmbracoEntity startNodeEntity in startNodesEntities) { UmbracoEntity entity = (UmbracoEntity)startNodeEntity; // Not as safe as the approach in core // https://github.com/umbraco/Umbraco-CMS/blob/5397f2c53acbdeb0805e1fe39fda938f571d295a/src/Umbraco.Core/Models/UmbracoEntityExtensions.cs#L34 bool isContainer = (entity.AdditionalData.ContainsKey("IsContainer") && entity.AdditionalData["IsContainer"].ToString() == "True"); TreeNode node = sender.CreateTreeNode( startNodeEntity.Id.ToInvariantString(), "-1", e.QueryStrings, startNodeEntity.Name, entity.ContentTypeIcon, entity.HasChildren && (isContainer == false) ); AddQueryStringsToAdditionalData(node, e.QueryStrings); if (e.QueryStrings.Get("isDialog") == "true") { node.RoutePath = "#"; } // TODO: How should we order nodes? e.Nodes.Add(node); } } }
public static void RenderMediaStartNodes(int userId, TreeControllerBase sender, TreeNodesRenderingEventArgs e) { StartNodeCollection startNodes = StartNodeRepository.GetCachedStartNodesByUserId(userId, sender.ApplicationContext, sender.DatabaseContext); if (startNodes.Media == null) { return; } if (startNodes.Media.Any()) { // Remove default start nodes e.Nodes.Clear(); IEnumerable <IUmbracoEntity> startNodesEntities = sender.Services.EntityService.GetAll(Umbraco.Core.Models.UmbracoObjectTypes.Media, startNodes.Media); foreach (IUmbracoEntity startNodeEntity in startNodesEntities) { UmbracoEntity entity = (UmbracoEntity)startNodeEntity; bool isContainer = (entity.AdditionalData.ContainsKey("IsContainer") && entity.AdditionalData["IsContainer"].ToString() == "True"); TreeNode node = sender.CreateTreeNode( startNodeEntity.Id.ToInvariantString(), "-1", e.QueryStrings, startNodeEntity.Name, entity.ContentTypeIcon, entity.HasChildren && (isContainer == false) ); node.AdditionalData.Add("contentType", entity.ContentTypeAlias); if (isContainer) { node.SetContainerStyle(); node.AdditionalData.Add("isContainer", true); } // TODO: How should we order nodes? e.Nodes.Add(node); } } }
/// <summary> /// NOTE: New implementation of the legacy GetLinkValue. This is however a bit quirky as a media item can have multiple "Linkable DataTypes". /// Returns the value for a link in WYSIWYG mode, by default only media items that have a /// DataTypeUploadField are linkable, however, a custom tree can be created which overrides /// this method, or another GUID for a custom data type can be added to the LinkableMediaDataTypes /// list on application startup. /// </summary> /// <param name="entity"></param> /// <returns></returns> internal virtual string GetLinkValue(UmbracoEntity entity) { foreach (var property in entity.AdditionalData .Select(x => x.Value as UmbracoEntity.EntityProperty) .Where(x => x != null)) { //required for backwards compatibility with v7 with changing the GUID -> alias var controlId = LegacyPropertyEditorIdToAliasConverter.GetLegacyIdFromAlias(property.PropertyEditorAlias, LegacyPropertyEditorIdToAliasConverter.NotFoundLegacyIdResponseBehavior.ReturnNull); if (controlId != null) { if (LinkableMediaDataTypes.Contains(controlId.Value) && string.IsNullOrEmpty((string)property.Value) == false) { return(property.Value.ToString()); } } } return(""); }
public EntityRepository.UmbracoEntityDto BuildDto(UmbracoEntity entity) { var node = new EntityRepository.UmbracoEntityDto { CreateDate = entity.CreateDate, Level = short.Parse(entity.Level.ToString(CultureInfo.InvariantCulture)), NodeId = entity.Id, NodeObjectType = entity.NodeObjectTypeId, ParentId = entity.ParentId, Path = entity.Path, SortOrder = entity.SortOrder, Text = entity.Name, Trashed = entity.Trashed, UniqueId = entity.Key, UserId = entity.CreatorId }; return(node); }
public UmbracoEntity BuildEntity(EntityRepository.UmbracoEntityDto dto) { var entity = new UmbracoEntity(dto.Trashed) { CreateDate = dto.CreateDate, CreatorId = dto.UserId.Value, Id = dto.NodeId, Key = dto.UniqueId, Level = dto.Level, Name = dto.Text, NodeObjectTypeId = dto.NodeObjectType.Value, ParentId = dto.ParentId, Path = dto.Path, SortOrder = dto.SortOrder, HasChildren = dto.Children > 0, ContentTypeAlias = dto.Alias ?? string.Empty, ContentTypeIcon = dto.Icon ?? string.Empty, ContentTypeThumbnail = dto.Thumbnail ?? string.Empty, }; entity.IsPublished = dto.PublishedVersion != default(Guid) || (dto.NewestVersion != default(Guid) && dto.PublishedVersion == dto.NewestVersion); entity.IsDraft = dto.NewestVersion != default(Guid) && (dto.PublishedVersion == default(Guid) || dto.PublishedVersion != dto.NewestVersion); entity.HasPendingChanges = (dto.PublishedVersion != default(Guid) && dto.NewestVersion != default(Guid)) && dto.PublishedVersion != dto.NewestVersion; if (dto.UmbracoPropertyDtos != null) { foreach (var propertyDto in dto.UmbracoPropertyDtos) { entity.AdditionalData[propertyDto.PropertyAlias] = new UmbracoEntity.EntityProperty { PropertyEditorAlias = propertyDto.PropertyEditorAlias, Value = propertyDto.NTextValue.IsNullOrWhiteSpace() ? propertyDto.NVarcharValue : propertyDto.NTextValue.ConvertToJsonIfPossible() }; } } return(entity); }
public void Validate_Path() { var entity = new UmbracoEntity(); //it's empty with no id so we need to allow it Assert.IsTrue(entity.ValidatePath()); entity.Id = 1234; //it has an id but no path, so we can't allow it Assert.IsFalse(entity.ValidatePath()); entity.Path = "-1"; //invalid path Assert.IsFalse(entity.ValidatePath()); entity.Path = string.Concat("-1,", entity.Id); //valid path Assert.IsTrue(entity.ValidatePath()); }
internal void SetActionAttribute(ref XmlTreeNode treeElement, UmbracoEntity dd) { // Check for dialog behaviour if (this.DialogMode == TreeDialogModes.fulllink) { string nodeLink = CreateNodeLink(dd); treeElement.Action = String.Format("javascript:openContent('{0}');", nodeLink); } else if (this.DialogMode == TreeDialogModes.locallink) { string nodeLink = string.Format("{{localLink:{0}}}", dd.Id); string nodeText = dd.Name.Replace("'", "\\'"); // try to make a niceurl too string niceUrl = umbraco.library.NiceUrl(dd.Id).Replace("'", "\\'");; if (niceUrl != "#" || niceUrl != "") { nodeLink += "|" + niceUrl + "|" + HttpContext.Current.Server.HtmlEncode(nodeText); } else { nodeLink += "||" + HttpContext.Current.Server.HtmlEncode(nodeText); } treeElement.Action = String.Format("javascript:openContent('{0}');", nodeLink); } else if (this.DialogMode == TreeDialogModes.id || this.DialogMode == TreeDialogModes.none) { treeElement.Action = String.Format("javascript:openContent('{0}');", dd.Id.ToString(CultureInfo.InvariantCulture)); } else if (this.IsDialog == false || (this.DialogMode == TreeDialogModes.id)) { if (CurrentUser.GetPermissions(dd.Path).Contains(ActionUpdate.Instance.Letter.ToString(CultureInfo.InvariantCulture))) { treeElement.Action = String.Format("javascript:openContent({0});", dd.Id); } } }
internal virtual string GetLinkValue(UmbracoEntity entity) => string.Empty;
internal void SetSourcesAttributes(ref XmlTreeNode treeElement, UmbracoEntity dd) { treeElement.HasChildren = dd.HasChildren; treeElement.Source = IsDialog == false?GetTreeServiceUrl(dd.Id) : GetTreeDialogUrl(dd.Id); }