diff --git a/src/Umbraco.Core/Persistence/Dtos/ContentVersionCultureVariationDto.cs b/src/Umbraco.Core/Persistence/Dtos/ContentVersionCultureVariationDto.cs
index a4e51b913e..27107b0afc 100644
--- a/src/Umbraco.Core/Persistence/Dtos/ContentVersionCultureVariationDto.cs
+++ b/src/Umbraco.Core/Persistence/Dtos/ContentVersionCultureVariationDto.cs
@@ -42,7 +42,8 @@ namespace Umbraco.Core.Persistence.Dtos
[NullSetting(NullSetting = NullSettings.Null)]
public int? PublishedUserId { get => _publishedUserId == 0 ? null : _publishedUserId; set => _publishedUserId = value; } //return null if zero
- [Column("edited")]
- public bool Edited { get; set; }
+ // fixme: I've commented this out, it's never used, need to review
+ //[Column("edited")]
+ //public bool Edited { get; set; }
}
}
diff --git a/src/Umbraco.Core/Persistence/NPocoSqlExtensions.cs b/src/Umbraco.Core/Persistence/NPocoSqlExtensions.cs
index 0d3faa0d68..61f46683d8 100644
--- a/src/Umbraco.Core/Persistence/NPocoSqlExtensions.cs
+++ b/src/Umbraco.Core/Persistence/NPocoSqlExtensions.cs
@@ -76,26 +76,7 @@ namespace Umbraco.Core.Persistence
var (s, a) = sql.SqlContext.Visit(predicate, alias);
return sql.Where(s, a);
}
-
- ///
- /// Appends an AND clause to a WHERE Sql statement.
- ///
- /// The type of the Dto.
- /// The Sql statement.
- /// A predicate to transform and append to the Sql statement.
- /// An optional alias for the table.
- /// The Sql statement.
- ///
- /// Chaining .Where(...).Where(...) in NPoco works because it merges the two WHERE statements,
- /// however if the first statement is not an explicit WHERE statement, chaining fails and two WHERE
- /// statements appear in the resulting Sql. This allows for adding an AND clause without problems.
- ///
- public static Sql AndWhere(this Sql sql, Expression> predicate, string alias = null)
- {
- var (s, a) = sql.SqlContext.Visit(predicate, alias);
- return sql.Append("AND (" + s + ")", a);
- }
-
+
///
/// Appends a WHERE clause to the Sql statement.
///
diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/EntityRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/EntityRepository.cs
index 70fca3fd34..74ecb23071 100644
--- a/src/Umbraco.Core/Persistence/Repositories/Implement/EntityRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/Implement/EntityRepository.cs
@@ -9,6 +9,7 @@ using Umbraco.Core.Persistence.Dtos;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Scoping;
using static Umbraco.Core.Persistence.NPocoSqlExtensions.Statics;
+using Umbraco.Core.Persistence.SqlSyntax;
namespace Umbraco.Core.Persistence.Repositories.Implement
{
@@ -34,6 +35,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
protected IUmbracoDatabase Database => _scopeAccessor.AmbientScope.Database;
protected Sql Sql() => _scopeAccessor.AmbientScope.SqlContext.Sql();
+ protected ISqlSyntaxProvider SqlSyntax => _scopeAccessor.AmbientScope.SqlContext.SqlSyntax;
#region Repository
@@ -57,83 +59,13 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
//fixme - we should be able to do sql = sql.OrderBy(x => Alias(x.NodeId, "NodeId")); but we can't because the OrderBy extension don't support Alias currently
sql = sql.OrderBy("NodeId");
- //IEnumerable result;
- //
- //if (isMedia)
- //{
- // //Treat media differently for now, as an Entity it will be returned with ALL of it's properties in the AdditionalData bag!
- // var pagedResult = UnitOfWork.Database.Page(pageIndex + 1, pageSize, pagedSql);
-
- // var ids = pagedResult.Items.Select(x => (int)x.id).InGroupsOf(2000);
- // var entities = pagedResult.Items.Select(BuildEntityFromDynamic).Cast().ToList();
-
- // //Now we need to merge in the property data since we need paging and we can't do this the way that the big media query was working before
- // foreach (var idGroup in ids)
- // {
- // var propSql = GetPropertySql(Constants.ObjectTypes.Media)
- // .WhereIn(x => x.NodeId, idGroup)
- // .OrderBy(x => x.NodeId);
-
- // //This does NOT fetch all data into memory in a list, this will read
- // // over the records as a data reader, this is much better for performance and memory,
- // // but it means that during the reading of this data set, nothing else can be read
- // // from SQL server otherwise we'll get an exception.
- // var allPropertyData = UnitOfWork.Database.Query(propSql);
-
- // //keep track of the current property data item being enumerated
- // var propertyDataSetEnumerator = allPropertyData.GetEnumerator();
- // var hasCurrent = false; // initially there is no enumerator.Current
-
- // try
- // {
- // //This must be sorted by node id (which is done by SQL) because this is how we are sorting the query to lookup property types above,
- // // which allows us to more efficiently iterate over the large data set of property values.
- // foreach (var entity in entities)
- // {
- // // assemble the dtos for this def
- // // use the available enumerator.Current if any else move to next
- // while (hasCurrent || propertyDataSetEnumerator.MoveNext())
- // {
- // if (propertyDataSetEnumerator.Current.nodeId == entity.Id)
- // {
- // hasCurrent = false; // enumerator.Current is not available
-
- // //the property data goes into the additional data
- // entity.AdditionalData[propertyDataSetEnumerator.Current.propertyTypeAlias] = new UmbracoEntity.EntityProperty
- // {
- // PropertyEditorAlias = propertyDataSetEnumerator.Current.propertyEditorAlias,
- // Value = StringExtensions.IsNullOrWhiteSpace(propertyDataSetEnumerator.Current.textValue)
- // ? propertyDataSetEnumerator.Current.varcharValue
- // : StringExtensions.ConvertToJsonIfPossible(propertyDataSetEnumerator.Current.textValue)
- // };
- // }
- // else
- // {
- // hasCurrent = true; // enumerator.Current is available for another def
- // break; // no more propertyDataDto for this def
- // }
- // }
- // }
- // }
- // finally
- // {
- // propertyDataSetEnumerator.Dispose();
- // }
- // }
-
- // result = entities;
- //}
- //else
- //{
- // var pagedResult = UnitOfWork.Database.Page(pageIndex + 1, pageSize, pagedSql);
- // result = pagedResult.Items.Select(BuildEntityFromDynamic).Cast().ToList();
- //}
var page = Database.Page(pageIndex + 1, pageSize, sql);
var dtos = page.Items;
var entities = dtos.Select(x => BuildEntity(isContent, isMedia, x)).ToArray();
-
- //TODO: For isContent will we need to build up the variation info?
+
+ if (isContent)
+ BuildVariantInfo(entities);
if (isMedia)
BuildProperties(entities, dtos);
@@ -158,7 +90,8 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
ddto => ddto.VariationInfo,
ddto => ddto.VersionId,
sql);
- return dtos.Count == 0 ? null : BuildDocumentEntity(dtos[0]);
+
+ return dtos.Count == 0 ? null : BuildVariantInfo(BuildDocumentEntity(dtos[0]))[0];
}
var dto = Database.FirstOrDefault(sql);
@@ -220,9 +153,10 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
dto => dto.VariationInfo,
dto => dto.VersionId,
sql);
+
return cdtos.Count == 0
? Enumerable.Empty()
- : cdtos.Select(BuildDocumentEntity).ToArray();
+ : BuildVariantInfo(cdtos.Select(BuildDocumentEntity).ToArray()).ToList();
}
var dtos = Database.Fetch(sql);
@@ -323,7 +257,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
private void BuildProperties(EntitySlim[] entities, List dtos)
{
- var versionIds = dtos.Select(x => x.VersionId).Distinct().ToArray();
+ var versionIds = dtos.Select(x => x.VersionId).Distinct().ToList();
var pdtos = Database.FetchByGroups(versionIds, 2000, GetPropertyData);
var xentity = entities.ToDictionary(x => x.Id, x => x); // nodeId -> entity
@@ -346,10 +280,54 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
entity.AdditionalData[pdto.PropertyTypeDto.Alias] = new EntitySlim.PropertySlim(pdto.PropertyTypeDto.DataTypeDto.EditorAlias, value);
}
+ private void BuildVariantInfo(EntitySlim[] entities)
+ {
+ BuildVariantInfo((DocumentEntitySlim[])entities);
+ }
+
+ private DocumentEntitySlim[] BuildVariantInfo(params DocumentEntitySlim[] entities)
+ {
+ if (entities.Any(x => x.Variations.VariesByCulture()))
+ {
+ //each EntitySlim at this stage is an DocumentEntitySlim
+
+ var dtos = Database.FetchByGroups(entities.Select(x => x.Id), 2000, GetVariantPublishedInfo)
+ .GroupBy(x => x.NodeId)
+ .ToDictionary(x => x.Key, x => (IEnumerable)x);
+
+ foreach (var e in entities.OfType().Where(x => x.Variations.VariesByCulture()).OrderBy(x => x.Id))
+ {
+ //fixme: how do i get this info? Seems that requires another query since that is how I think it's done in the DocumentRepository
+ //e.EditedCultures =
+ e.PublishedCultures = dtos[e.Id].Where(x => x.VersionPublished).Select(x => x.IsoCode).Distinct().ToList();
+ }
+ }
+
+ return entities;
+ }
+
#endregion
#region Sql
+ private Sql GetVariantPublishedInfo(IEnumerable ids)
+ {
+ var sql = Sql();
+ sql
+ .Select(x => x.NodeId, x => Alias(x.Id, "versionId"), x => Alias(x.Current, "versionCurrent"))
+ .AndSelect(x => Alias(x.Id, "versionCultureId"))
+ .AndSelect(x => x.IsoCode)
+ .AndSelect(x => Alias(x.Published, "versionPublished"))
+ .From()
+ .InnerJoin().On(x => x.NodeId, x => x.NodeId)
+ .InnerJoin().On(x => x.Id, x => x.VersionId)
+ .InnerJoin().On(x => x.Id, x => x.Id)
+ .InnerJoin().On(x => x.LanguageId, x => x.Id)
+ .Where(x => x.NodeObjectType == Constants.ObjectTypes.Document)
+ .WhereIn(x => x.NodeId, ids)
+ .Where($"{SqlSyntax.GetFieldName(x => x.Current)} = 1 OR {SqlSyntax.GetFieldName(x => x.Published)} = 1");
+ return sql;
+ }
// gets the full sql for a given object type and a given unique id
protected Sql GetFullSqlForEntityType(bool isContent, bool isMedia, Guid objectType, Guid uniqueId)
{
@@ -371,24 +349,6 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
return AddGroupBy(isContent, isMedia, sql);
}
- // fixme kill this nonsense
- //// gets the SELECT + FROM + WHERE sql
- //// to get all property data for all items of the specified object type
- //private Sql GetPropertySql(Guid objectType)
- //{
- // return Sql()
- // .Select(x => x.VersionId, x => x.TextValue, x => x.VarcharValue)
- // .AndSelect(x => x.NodeId)
- // .AndSelect(x => x.PropertyEditorAlias)
- // .AndSelect(x => Alias(x.Alias, "propertyTypeAlias"))
- // .From()
- // .InnerJoin().On((left, right) => left.VersionId == right.Id)
- // .InnerJoin().On((left, right) => left.NodeId == right.NodeId)
- // .InnerJoin().On(dto => dto.PropertyTypeId, dto => dto.Id)
- // .InnerJoin().On(dto => dto.DataTypeId, dto => dto.DataTypeId)
- // .Where(x => x.NodeObjectType == objectType);
- //}
-
private Sql GetPropertyData(int versionId)
{
return Sql()
@@ -410,89 +370,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
.OrderBy(x => x.VersionId);
}
- // fixme - wtf is this?
- //private Sql GetFullSqlForMedia(Sql entitySql, Action> filter = null)
- //{
- // //this will add any varcharValue property to the output which can be added to the additional properties
-
- // var sql = GetPropertySql(Constants.ObjectTypes.Media);
-
- // filter?.Invoke(sql);
-
- // // We're going to create a query to query against the entity SQL
- // // because we cannot group by nText columns and we have a COUNT in the entitySql we cannot simply left join
- // // the entitySql query, we have to join the wrapped query to get the ntext in the result
-
- // var wrappedSql = Sql()
- // .Append("SELECT * FROM (")
- // .Append(entitySql)
- // .Append(") tmpTbl LEFT JOIN (")
- // .Append(sql)
- // .Append(") as property ON id = property.nodeId")
- // .OrderBy("sortOrder, id");
-
- // return wrappedSql;
- //}
-
-
- ///
- /// The DTO used to fetch results for a content item with its variation info
- ///
- private class ContentEntityDto : BaseDto
- {
- public ContentVariation Variations { get; set; }
-
- [ResultColumn, Reference(ReferenceType.Many)]
- public List VariationInfo { get; set; }
-
- public bool Published { get; set; }
- public bool Edited { get; set; }
- }
-
- ///
- /// The DTO used in the 1:M result for content variation info
- ///
- private class ContentEntityVariationInfoDto
- {
- [Column("versionCultureId")]
- public int VersionCultureId { get; set; }
- [Column("versionCultureLangId")]
- public int LanguageId { get; set; }
- [Column("versionCultureName")]
- public string Name { get; set; }
- [Column("versionCultureEdited")]
- public bool Edited { get; set; }
- }
-
- // ReSharper disable once ClassNeverInstantiated.Local
- ///
- /// the DTO corresponding to fields selected by GetBase
- ///
- private class BaseDto
- {
- // ReSharper disable UnusedAutoPropertyAccessor.Local
- // ReSharper disable UnusedMember.Local
- public int NodeId { get; set; }
- public bool Trashed { get; set; }
- public int ParentId { get; set; }
- public int? UserId { get; set; }
- public int Level { get; set; }
- public string Path { get; set; }
- public int SortOrder { get; set; }
- public Guid UniqueId { get; set; }
- public string Text { get; set; }
- public Guid NodeObjectType { get; set; }
- public DateTime CreateDate { get; set; }
- public int Children { get; set; }
- public int VersionId { get; set; }
- public string Alias { get; set; }
- public string Icon { get; set; }
- public string Thumbnail { get; set; }
- public bool IsContainer { get; set; }
-
- // ReSharper restore UnusedAutoPropertyAccessor.Local
- // ReSharper restore UnusedMember.Local
- }
+
// gets the base SELECT + FROM [+ filter] sql
// always from the 'current' content version
@@ -524,8 +402,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
.AndSelect(
x => Alias(x.Id, "versionCultureId"),
x => Alias(x.LanguageId, "versionCultureLangId"),
- x => Alias(x.Name, "versionCultureName"),
- x => Alias(x.Edited, "versionCultureEdited"));
+ x => Alias(x.Name, "versionCultureName"));
}
}
@@ -537,7 +414,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
sql
.InnerJoin().On((left, right) => left.NodeId == right.NodeId && right.Current)
.InnerJoin().On((left, right) => left.NodeId == right.NodeId)
- .LeftJoin().On((left, right) => left.ContentTypeId == right.NodeId);
+ .InnerJoin().On((left, right) => left.ContentTypeId == right.NodeId);
}
if (isContent)
@@ -652,184 +529,73 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
public string TextValue { get; set; }
}
- // fixme kill
+
///
- /// This is a special relator in that it is not returning a DTO but a real resolved entity and that it accepts
- /// a dynamic instance.
+ /// The DTO used to fetch results for a content item with its variation info
///
- ///
- /// We're doing this because when we query the db, we want to use dynamic so that it returns all available fields not just the ones
- /// defined on the entity so we can them to additional data
- ///
- //internal class UmbracoEntityRelator
- //{
- // internal UmbracoEntity Current;
+ private class ContentEntityDto : BaseDto
+ {
+ public ContentVariation Variations { get; set; }
- // public IEnumerable MapAll(IEnumerable input)
- // {
- // UmbracoEntity entity;
+ [ResultColumn, Reference(ReferenceType.Many)]
+ public List VariationInfo { get; set; }
- // foreach (var x in input)
- // {
- // entity = Map(x);
- // if (entity != null) yield return entity;
- // }
+ public bool Published { get; set; }
+ public bool Edited { get; set; }
+ }
- // entity = Map((dynamic) null);
- // if (entity != null) yield return entity;
- // }
+ private class VariationPublishInfoDto
+ {
+ public int NodeId { get; set; }
+ public int VersionId { get; set; }
+ public bool VersionCurrent { get; set; }
+ public string IsoCode { get; set; }
+ public int VersionCultureId { get; set; }
+ public bool VersionPublished { get; set; }
+ }
- // // must be called one last time with null in order to return the last one!
- // public UmbracoEntity Map(dynamic a)
- // {
- // // Terminating call. Since we can return null from this function
- // // we need to be ready for NPoco to callback later with null
- // // parameters
- // if (a == null)
- // return Current;
+ ///
+ /// The DTO used in the 1:M result for content variation info
+ ///
+ private class ContentEntityVariationInfoDto
+ {
+ [Column("versionCultureId")]
+ public int VersionCultureId { get; set; }
+ [Column("versionCultureLangId")]
+ public int LanguageId { get; set; }
+ [Column("versionCultureName")]
+ public string Name { get; set; }
+ }
- // string pPropertyEditorAlias = a.propertyEditorAlias;
- // var pExists = pPropertyEditorAlias != null;
- // string pPropertyAlias = a.propertyTypeAlias;
- // string pTextValue = a.textValue;
- // string pNVarcharValue = a.varcharValue;
-
- // // Is this the same UmbracoEntity as the current one we're processing
- // if (Current != null && Current.Key == a.uniqueID)
- // {
- // if (pExists && pPropertyAlias.IsNullOrWhiteSpace() == false)
- // {
- // // Add this UmbracoProperty to the current additional data
- // Current.AdditionalData[pPropertyAlias] = new UmbracoEntity.EntityProperty
- // {
- // PropertyEditorAlias = pPropertyEditorAlias,
- // Value = pTextValue.IsNullOrWhiteSpace()
- // ? pNVarcharValue
- // : pTextValue.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 = BuildEntityFromDynamic(a);
-
- // if (pExists && pPropertyAlias.IsNullOrWhiteSpace() == false)
- // {
- // //add the property/create the prop list if null
- // Current.AdditionalData[pPropertyAlias] = new UmbracoEntity.EntityProperty
- // {
- // PropertyEditorAlias = pPropertyEditorAlias,
- // Value = pTextValue.IsNullOrWhiteSpace()
- // ? pNVarcharValue
- // : pTextValue.ConvertToJsonIfPossible()
- // };
- // }
-
- // // Return the now populated previous UmbracoEntity (or null if first time through)
- // return prev;
- // }
- //}
-
- // fixme need to review what's below
- // comes from 7.6, similar to what's in VersionableRepositoryBase
- // not sure it really makes sense...
-
- //private class EntityDefinitionCollection : KeyedCollection
- //{
- // protected override int GetKeyForItem(EntityDefinition item)
- // {
- // return item.Id;
- // }
-
- // ///
- // /// if this key already exists if it does then we need to check
- // /// if the existing item is 'older' than the new item and if that is the case we'll replace the older one
- // ///
- // ///
- // ///
- // public bool AddOrUpdate(EntityDefinition item)
- // {
- // if (Dictionary == null)
- // {
- // Add(item);
- // return true;
- // }
-
- // var key = GetKeyForItem(item);
- // if (TryGetValue(key, out EntityDefinition found))
- // {
- // //it already exists and it's older so we need to replace it
- // if (item.VersionId > found.VersionId)
- // {
- // var currIndex = Items.IndexOf(found);
- // if (currIndex == -1)
- // throw new IndexOutOfRangeException("Could not find the item in the list: " + found.Id);
-
- // //replace the current one with the newer one
- // SetItem(currIndex, item);
- // return true;
- // }
- // //could not add or update
- // return false;
- // }
-
- // Add(item);
- // return true;
- // }
-
- // private bool TryGetValue(int key, out EntityDefinition val)
- // {
- // if (Dictionary != null) return Dictionary.TryGetValue(key, out val);
-
- // val = null;
- // return false;
- // }
- //}
-
- // fixme wtf is this, why dynamics here, this is horrible !!
- //private class EntityDefinition
- //{
- // private readonly dynamic _entity;
- // private readonly bool _isContent;
- // private readonly bool _isMedia;
-
- // public EntityDefinition(dynamic entity, bool isContent, bool isMedia)
- // {
- // _entity = entity;
- // _isContent = isContent;
- // _isMedia = isMedia;
- // }
-
- // public IUmbracoEntity BuildFromDynamic()
- // {
- // return BuildEntityFromDynamic(_entity);
- // }
-
- // public int Id => _entity.id;
-
- // public int VersionId
- // {
- // get
- // {
- // if (_isContent || _isMedia)
- // {
- // return _entity.versionId;
- // }
- // return _entity.id;
- // }
- // }
- //}
+ // ReSharper disable once ClassNeverInstantiated.Local
+ ///
+ /// the DTO corresponding to fields selected by GetBase
+ ///
+ private class BaseDto
+ {
+ // ReSharper disable UnusedAutoPropertyAccessor.Local
+ // ReSharper disable UnusedMember.Local
+ public int NodeId { get; set; }
+ public bool Trashed { get; set; }
+ public int ParentId { get; set; }
+ public int? UserId { get; set; }
+ public int Level { get; set; }
+ public string Path { get; set; }
+ public int SortOrder { get; set; }
+ public Guid UniqueId { get; set; }
+ public string Text { get; set; }
+ public Guid NodeObjectType { get; set; }
+ public DateTime CreateDate { get; set; }
+ public int Children { get; set; }
+ public int VersionId { get; set; }
+ public string Alias { get; set; }
+ public string Icon { get; set; }
+ public string Thumbnail { get; set; }
+ public bool IsContainer { get; set; }
+ // ReSharper restore UnusedAutoPropertyAccessor.Local
+ // ReSharper restore UnusedMember.Local
+ }
#endregion
#region Factory
@@ -914,21 +680,15 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
//fill in the variant info
if (dto.Variations.VariesByCulture() && dto.VariationInfo != null && dto.VariationInfo.Count > 0)
{
+ //fixme: Currently require making a 2nd query to fill in publish status information for variants
+
var variantInfo = new Dictionary(StringComparer.InvariantCultureIgnoreCase);
foreach (var info in dto.VariationInfo)
{
var isoCode = _langRepository.GetIsoCodeById(info.LanguageId);
if (isoCode != null)
variantInfo[isoCode] = info.Name;
-
- if (dto.Published)
- {
- publishedCultures.Add(isoCode);
- if (info.Edited)
- {
- editedCultures.Add(isoCode);
- }
- }
+
}
entity.CultureNames = variantInfo;
entity.Variations = dto.Variations;
diff --git a/src/Umbraco.Web/Trees/ContentTreeController.cs b/src/Umbraco.Web/Trees/ContentTreeController.cs
index 33a347d3d4..878a277177 100644
--- a/src/Umbraco.Web/Trees/ContentTreeController.cs
+++ b/src/Umbraco.Web/Trees/ContentTreeController.cs
@@ -47,10 +47,10 @@ namespace Umbraco.Web.Trees
///
protected override TreeNode GetSingleTreeNode(IEntitySlim entity, string parentId, FormDataCollection queryStrings)
{
- var langId = queryStrings?["culture"];
+ var culture = queryStrings?["culture"];
var allowedUserOptions = GetAllowedUserMenuItemsForNode(entity);
- if (CanUserAccessNode(entity, allowedUserOptions, langId))
+ if (CanUserAccessNode(entity, allowedUserOptions, culture))
{
//Special check to see if it ia a container, if so then we'll hide children.
var isContainer = entity.IsContainer; // && (queryStrings.Get("isDialog") != "true");
@@ -74,11 +74,21 @@ namespace Umbraco.Web.Trees
{
var documentEntity = (IDocumentEntitySlim) entity;
- //fixme we need these statuses per variant but to do that we need to fix the issues listed in IDocumentEntitySlim
- if (!documentEntity.Published)
- node.SetNotPublishedStyle();
- //if (documentEntity.Edited)
- // node.SetHasUnpublishedVersionStyle();
+ if (!documentEntity.Variations.VariesByCulture())
+ {
+ if (!documentEntity.Published)
+ node.SetNotPublishedStyle();
+ if (documentEntity.Edited)
+ node.SetHasUnpublishedVersionStyle();
+ }
+ else
+ {
+ if (!culture.IsNullOrWhiteSpace())
+ {
+ if (!documentEntity.PublishedCultures.Contains(culture))
+ node.SetNotPublishedStyle();
+ }
+ }
node.AdditionalData.Add("contentType", documentEntity.ContentTypeAlias);
}