Merge remote-tracking branch 'origin/temp8' into temp8-258-empty-trees-arrow
This commit is contained in:
@@ -1,35 +0,0 @@
|
||||
using System;
|
||||
using Umbraco.Core.Exceptions;
|
||||
|
||||
namespace Umbraco.Core.CodeAnnotations
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
|
||||
internal class ActionMetadataAttribute : Attribute
|
||||
{
|
||||
public string Category { get; }
|
||||
public string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Constructor used to assign a Category, since no name is assigned it will try to be translated from the language files based on the action's alias
|
||||
/// </summary>
|
||||
/// <param name="category"></param>
|
||||
public ActionMetadataAttribute(string category)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(category)) throw new ArgumentNullOrEmptyException(nameof(category));
|
||||
Category = category;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor used to assign an explicit name and category
|
||||
/// </summary>
|
||||
/// <param name="category"></param>
|
||||
/// <param name="name"></param>
|
||||
public ActionMetadataAttribute(string category, string name)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(category)) throw new ArgumentNullOrEmptyException(nameof(category));
|
||||
if (string.IsNullOrWhiteSpace(name)) throw new ArgumentNullOrEmptyException(nameof(name));
|
||||
Category = category;
|
||||
Name = name;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -37,101 +37,6 @@ namespace Umbraco.Core
|
||||
return dirty.WasPropertyDirty("Published") && entity.Published;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of the current contents ancestors, not including the content itself.
|
||||
/// </summary>
|
||||
/// <param name="content">Current content</param>
|
||||
/// <param name="contentService"></param>
|
||||
/// <returns>An enumerable list of <see cref="IContent"/> objects</returns>
|
||||
public static IEnumerable<IContent> Ancestors(this IContent content, IContentService contentService)
|
||||
{
|
||||
return contentService.GetAncestors(content);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of the current contents children.
|
||||
/// </summary>
|
||||
/// <param name="content">Current content</param>
|
||||
/// <param name="contentService"></param>
|
||||
/// <returns>An enumerable list of <see cref="IContent"/> objects</returns>
|
||||
public static IEnumerable<IContent> Children(this IContent content, IContentService contentService)
|
||||
{
|
||||
return contentService.GetChildren(content.Id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of the current contents descendants, not including the content itself.
|
||||
/// </summary>
|
||||
/// <param name="content">Current content</param>
|
||||
/// <param name="contentService"></param>
|
||||
/// <returns>An enumerable list of <see cref="IContent"/> objects</returns>
|
||||
public static IEnumerable<IContent> Descendants(this IContent content, IContentService contentService)
|
||||
{
|
||||
return contentService.GetDescendants(content);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the parent of the current content.
|
||||
/// </summary>
|
||||
/// <param name="content">Current content</param>
|
||||
/// <param name="contentService"></param>
|
||||
/// <returns>An <see cref="IContent"/> object</returns>
|
||||
public static IContent Parent(this IContent content, IContentService contentService)
|
||||
{
|
||||
return contentService.GetById(content.ParentId);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IMedia
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of the current medias ancestors, not including the media itself.
|
||||
/// </summary>
|
||||
/// <param name="media">Current media</param>
|
||||
/// <param name="mediaService"></param>
|
||||
/// <returns>An enumerable list of <see cref="IMedia"/> objects</returns>
|
||||
public static IEnumerable<IMedia> Ancestors(this IMedia media, IMediaService mediaService)
|
||||
{
|
||||
return mediaService.GetAncestors(media);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of the current medias children.
|
||||
/// </summary>
|
||||
/// <param name="media">Current media</param>
|
||||
/// <param name="mediaService"></param>
|
||||
/// <returns>An enumerable list of <see cref="IMedia"/> objects</returns>
|
||||
public static IEnumerable<IMedia> Children(this IMedia media, IMediaService mediaService)
|
||||
{
|
||||
return mediaService.GetChildren(media.Id);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of the current medias descendants, not including the media itself.
|
||||
/// </summary>
|
||||
/// <param name="media">Current media</param>
|
||||
/// <param name="mediaService"></param>
|
||||
/// <returns>An enumerable list of <see cref="IMedia"/> objects</returns>
|
||||
public static IEnumerable<IMedia> Descendants(this IMedia media, IMediaService mediaService)
|
||||
{
|
||||
return mediaService.GetDescendants(media);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns the parent of the current media.
|
||||
/// </summary>
|
||||
/// <param name="media">Current media</param>
|
||||
/// <param name="mediaService"></param>
|
||||
/// <returns>An <see cref="IMedia"/> object</returns>
|
||||
public static IMedia Parent(this IMedia media, IMediaService mediaService)
|
||||
{
|
||||
return mediaService.GetById(media.ParentId);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
@@ -179,29 +84,7 @@ namespace Umbraco.Core
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the children for the content base item
|
||||
/// </summary>
|
||||
/// <param name="content"></param>
|
||||
/// <param name="services"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// This is a bit of a hack because we need to type check!
|
||||
/// </remarks>
|
||||
internal static IEnumerable<IContentBase> Children(IContentBase content, ServiceContext services)
|
||||
{
|
||||
if (content is IContent)
|
||||
{
|
||||
return services.ContentService.GetChildren(content.Id);
|
||||
}
|
||||
if (content is IMedia)
|
||||
{
|
||||
return services.MediaService.GetChildren(content.Id);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns properties that do not belong to a group
|
||||
/// </summary>
|
||||
|
||||
@@ -99,7 +99,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
private string VariantNameSqlExpression
|
||||
=> SqlContext.VisitDto<ContentVersionCultureVariationDto, NodeDto>((ccv, node) => ccv.Name ?? node.Text, "ccv").Sql;
|
||||
|
||||
protected virtual Sql<ISqlContext> GetBaseQuery(QueryType queryType, bool current)
|
||||
protected Sql<ISqlContext> GetBaseQuery(QueryType queryType, bool current)
|
||||
{
|
||||
var sql = SqlContext.Sql();
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace Umbraco.Core.Services
|
||||
IEnumerable<IUrlSegmentProvider> urlSegmentProviders,
|
||||
IContent content,
|
||||
bool published,
|
||||
bool withDescendants = false) // fixme take care of usage!
|
||||
bool withDescendants = false) //fixme take care of usage! only used for the packager
|
||||
{
|
||||
if (contentService == null) throw new ArgumentNullException(nameof(contentService));
|
||||
if (dataTypeService == null) throw new ArgumentNullException(nameof(dataTypeService));
|
||||
@@ -58,9 +58,15 @@ namespace Umbraco.Core.Services
|
||||
|
||||
if (withDescendants)
|
||||
{
|
||||
var descendants = contentService.GetDescendants(content).ToArray();
|
||||
var currentChildren = descendants.Where(x => x.ParentId == content.Id);
|
||||
SerializeDescendants(contentService, dataTypeService, userService, localizationService, urlSegmentProviders, descendants, currentChildren, xml, published);
|
||||
const int pageSize = 500;
|
||||
var page = 0;
|
||||
var total = long.MaxValue;
|
||||
while(page * pageSize < total)
|
||||
{
|
||||
var children = contentService.GetPagedChildren(content.Id, page++, pageSize, out total);
|
||||
SerializeChildren(contentService, dataTypeService, userService, localizationService, urlSegmentProviders, children, xml, published);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return xml;
|
||||
@@ -103,9 +109,14 @@ namespace Umbraco.Core.Services
|
||||
|
||||
if (withDescendants)
|
||||
{
|
||||
var descendants = mediaService.GetDescendants(media).ToArray();
|
||||
var currentChildren = descendants.Where(x => x.ParentId == media.Id);
|
||||
SerializeDescendants(mediaService, dataTypeService, userService, localizationService, urlSegmentProviders, descendants, currentChildren, xml);
|
||||
const int pageSize = 500;
|
||||
var page = 0;
|
||||
var total = long.MaxValue;
|
||||
while (page * pageSize < total)
|
||||
{
|
||||
var children = mediaService.GetPagedChildren(media.Id, page++, pageSize, out total);
|
||||
SerializeChildren(mediaService, dataTypeService, userService, localizationService, urlSegmentProviders, children, xml);
|
||||
}
|
||||
}
|
||||
|
||||
return xml;
|
||||
@@ -451,7 +462,7 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
|
||||
// exports an IContent item descendants.
|
||||
private static void SerializeDescendants(IContentService contentService, IDataTypeService dataTypeService, IUserService userService, ILocalizationService localizationService, IEnumerable<IUrlSegmentProvider> urlSegmentProviders, IContent[] originalDescendants, IEnumerable<IContent> children, XElement xml, bool published)
|
||||
private static void SerializeChildren(IContentService contentService, IDataTypeService dataTypeService, IUserService userService, ILocalizationService localizationService, IEnumerable<IUrlSegmentProvider> urlSegmentProviders, IEnumerable<IContent> children, XElement xml, bool published)
|
||||
{
|
||||
foreach (var child in children)
|
||||
{
|
||||
@@ -459,17 +470,20 @@ namespace Umbraco.Core.Services
|
||||
var childXml = Serialize(contentService, dataTypeService, userService, localizationService, urlSegmentProviders, child, published);
|
||||
xml.Add(childXml);
|
||||
|
||||
// capture id (out of closure) and get the grandChildren (children of the child)
|
||||
var parentId = child.Id;
|
||||
var grandChildren = originalDescendants.Where(x => x.ParentId == parentId);
|
||||
|
||||
// recurse
|
||||
SerializeDescendants(contentService, dataTypeService, userService, localizationService, urlSegmentProviders, originalDescendants, grandChildren, childXml, published);
|
||||
const int pageSize = 500;
|
||||
var page = 0;
|
||||
var total = long.MaxValue;
|
||||
while(page * pageSize < total)
|
||||
{
|
||||
var grandChildren = contentService.GetPagedChildren(child.Id, page++, pageSize, out total);
|
||||
// recurse
|
||||
SerializeChildren(contentService, dataTypeService, userService, localizationService, urlSegmentProviders, grandChildren, childXml, published);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// exports an IMedia item descendants.
|
||||
private static void SerializeDescendants(IMediaService mediaService, IDataTypeService dataTypeService, IUserService userService, ILocalizationService localizationService, IEnumerable<IUrlSegmentProvider> urlSegmentProviders, IMedia[] originalDescendants, IEnumerable<IMedia> children, XElement xml)
|
||||
private static void SerializeChildren(IMediaService mediaService, IDataTypeService dataTypeService, IUserService userService, ILocalizationService localizationService, IEnumerable<IUrlSegmentProvider> urlSegmentProviders, IEnumerable<IMedia> children, XElement xml)
|
||||
{
|
||||
foreach (var child in children)
|
||||
{
|
||||
@@ -477,12 +491,15 @@ namespace Umbraco.Core.Services
|
||||
var childXml = Serialize(mediaService, dataTypeService, userService, localizationService, urlSegmentProviders, child);
|
||||
xml.Add(childXml);
|
||||
|
||||
// capture id (out of closure) and get the grandChildren (children of the child)
|
||||
var parentId = child.Id;
|
||||
var grandChildren = originalDescendants.Where(x => x.ParentId == parentId);
|
||||
|
||||
// recurse
|
||||
SerializeDescendants(mediaService, dataTypeService, userService, localizationService, urlSegmentProviders, originalDescendants, grandChildren, childXml);
|
||||
const int pageSize = 500;
|
||||
var page = 0;
|
||||
var total = long.MaxValue;
|
||||
while (page * pageSize < total)
|
||||
{
|
||||
var grandChildren = mediaService.GetPagedChildren(child.Id, page++, pageSize, out total);
|
||||
// recurse
|
||||
SerializeChildren(mediaService, dataTypeService, userService, localizationService, urlSegmentProviders, grandChildren, childXml);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,26 +78,11 @@ namespace Umbraco.Core.Services
|
||||
/// </summary>
|
||||
IEnumerable<IContent> GetByIds(IEnumerable<Guid> ids);
|
||||
|
||||
/// <summary>
|
||||
/// Gets documents of a given document type.
|
||||
/// </summary>
|
||||
IEnumerable<IContent> GetByType(int documentTypeId);
|
||||
|
||||
/// <summary>
|
||||
/// Gets documents at a given level.
|
||||
/// </summary>
|
||||
IEnumerable<IContent> GetByLevel(int level);
|
||||
|
||||
/// <summary>
|
||||
/// Gets child documents of a given parent.
|
||||
/// </summary>
|
||||
IEnumerable<IContent> GetChildren(int parentId);
|
||||
|
||||
/// <summary>
|
||||
/// Gets child documents of a document, (partially) matching a name.
|
||||
/// </summary>
|
||||
IEnumerable<IContent> GetChildren(int parentId, string name);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the parent of a document.
|
||||
/// </summary>
|
||||
@@ -118,16 +103,6 @@ namespace Umbraco.Core.Services
|
||||
/// </summary>
|
||||
IEnumerable<IContent> GetAncestors(IContent content);
|
||||
|
||||
/// <summary>
|
||||
/// Gets descendant documents of a document.
|
||||
/// </summary>
|
||||
IEnumerable<IContent> GetDescendants(int id);
|
||||
|
||||
/// <summary>
|
||||
/// Gets descendant documents of a document.
|
||||
/// </summary>
|
||||
IEnumerable<IContent> GetDescendants(IContent content);
|
||||
|
||||
/// <summary>
|
||||
/// Gets all versions of a document.
|
||||
/// </summary>
|
||||
@@ -169,19 +144,8 @@ namespace Umbraco.Core.Services
|
||||
/// <summary>
|
||||
/// Gets documents in the recycle bin.
|
||||
/// </summary>
|
||||
IEnumerable<IContent> GetContentInRecycleBin();
|
||||
|
||||
/// <summary>
|
||||
/// Gets child documents of a parent.
|
||||
/// </summary>
|
||||
/// <param name="id">The parent identifier.</param>
|
||||
/// <param name="pageIndex">The page number.</param>
|
||||
/// <param name="pageSize">The page size.</param>
|
||||
/// <param name="totalRecords">Total number of documents.</param>
|
||||
/// <param name="filter">Search text filter.</param>
|
||||
/// <param name="ordering">Ordering infos.</param>
|
||||
IEnumerable<IContent> GetPagedChildren(int id, long pageIndex, int pageSize, out long totalRecords,
|
||||
string filter = null, Ordering ordering = null);
|
||||
IEnumerable<IContent> GetPagedContentInRecycleBin(long pageIndex, int pageSize, out long totalRecords,
|
||||
IQuery<IContent> filter = null, Ordering ordering = null);
|
||||
|
||||
/// <summary>
|
||||
/// Gets child documents of a parent.
|
||||
@@ -193,20 +157,7 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="filter">Query filter.</param>
|
||||
/// <param name="ordering">Ordering infos.</param>
|
||||
IEnumerable<IContent> GetPagedChildren(int id, long pageIndex, int pageSize, out long totalRecords,
|
||||
IQuery<IContent> filter, Ordering ordering = null);
|
||||
|
||||
/// <summary>
|
||||
/// Gets descendant documents of a given parent.
|
||||
/// </summary>
|
||||
/// <param name="id">The parent identifier.</param>
|
||||
/// <param name="pageIndex">The page number.</param>
|
||||
/// <param name="pageSize">The page size.</param>
|
||||
/// <param name="totalRecords">Total number of documents.</param>
|
||||
/// <param name="orderBy">A field to order by.</param>
|
||||
/// <param name="orderDirection">The ordering direction.</param>
|
||||
/// <param name="filter">Search text filter.</param>
|
||||
IEnumerable<IContent> GetPagedDescendants(int id, long pageIndex, int pageSize, out long totalRecords,
|
||||
string orderBy = "path", Direction orderDirection = Direction.Ascending, string filter = "");
|
||||
IQuery<IContent> filter = null, Ordering ordering = null);
|
||||
|
||||
/// <summary>
|
||||
/// Gets descendant documents of a given parent.
|
||||
@@ -220,7 +171,31 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="orderBySystemField">A flag indicating whether the ordering field is a system field.</param>
|
||||
/// <param name="filter">Query filter.</param>
|
||||
IEnumerable<IContent> GetPagedDescendants(int id, long pageIndex, int pageSize, out long totalRecords,
|
||||
string orderBy, Direction orderDirection, bool orderBySystemField, IQuery<IContent> filter);
|
||||
IQuery<IContent> filter = null, Ordering ordering = null);
|
||||
|
||||
/// <summary>
|
||||
/// Gets paged documents of a content content
|
||||
/// </summary>
|
||||
/// <param name="contentTypeId">The page number.</param>
|
||||
/// <param name="pageIndex">The page number.</param>
|
||||
/// <param name="pageSize">The page size.</param>
|
||||
/// <param name="totalRecords">Total number of documents.</param>
|
||||
/// <param name="filter">Search text filter.</param>
|
||||
/// <param name="ordering">Ordering infos.</param>
|
||||
IEnumerable<IContent> GetPagedOfType(int contentTypeId, long pageIndex, int pageSize, out long totalRecords,
|
||||
IQuery<IContent> filter, Ordering ordering = null);
|
||||
|
||||
/// <summary>
|
||||
/// Gets paged documents for specified content types
|
||||
/// </summary>
|
||||
/// <param name="contentTypeIds">The page number.</param>
|
||||
/// <param name="pageIndex">The page number.</param>
|
||||
/// <param name="pageSize">The page size.</param>
|
||||
/// <param name="totalRecords">Total number of documents.</param>
|
||||
/// <param name="filter">Search text filter.</param>
|
||||
/// <param name="ordering">Ordering infos.</param>
|
||||
IEnumerable<IContent> GetPagedOfTypes(int[] contentTypeIds, long pageIndex, int pageSize, out long totalRecords,
|
||||
IQuery<IContent> filter, Ordering ordering = null);
|
||||
|
||||
/// <summary>
|
||||
/// Counts documents of a given document type.
|
||||
|
||||
@@ -78,27 +78,6 @@ namespace Umbraco.Core.Services
|
||||
/// <returns><see cref="IMedia"/></returns>
|
||||
IMedia GetById(int id);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of <see cref="IMedia"/> objects by Parent Id
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the Parent to retrieve Children from</param>
|
||||
/// <returns>An Enumerable list of <see cref="IMedia"/> objects</returns>
|
||||
IEnumerable<IMedia> GetChildren(int id);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of <see cref="IMedia"/> objects by Parent Id
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the Parent to retrieve Children from</param>
|
||||
/// <param name="pageIndex">Page number</param>
|
||||
/// <param name="pageSize">Page size</param>
|
||||
/// <param name="totalRecords">Total records query would return without paging</param>
|
||||
/// <param name="orderBy">Field to order by</param>
|
||||
/// <param name="orderDirection">Direction to order by</param>
|
||||
/// <param name="filter">Search text filter</param>
|
||||
/// <returns>An Enumerable list of <see cref="IContent"/> objects</returns>
|
||||
IEnumerable<IMedia> GetPagedChildren(int id, long pageIndex, int pageSize, out long totalRecords,
|
||||
string orderBy = "SortOrder", Direction orderDirection = Direction.Ascending, string filter = "");
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of <see cref="IMedia"/> objects by Parent Id
|
||||
/// </summary>
|
||||
@@ -112,37 +91,7 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="filter"></param>
|
||||
/// <returns>An Enumerable list of <see cref="IContent"/> objects</returns>
|
||||
IEnumerable<IMedia> GetPagedChildren(int id, long pageIndex, int pageSize, out long totalRecords,
|
||||
string orderBy, Direction orderDirection, bool orderBySystemField, IQuery<IMedia> filter);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of <see cref="IMedia"/> objects by Parent Id
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the Parent to retrieve Children from</param>
|
||||
/// <param name="pageIndex">Page number</param>
|
||||
/// <param name="pageSize">Page size</param>
|
||||
/// <param name="totalRecords">Total records query would return without paging</param>
|
||||
/// <param name="orderBy">Field to order by</param>
|
||||
/// <param name="orderDirection">Direction to order by</param>
|
||||
/// <param name="orderBySystemField">Flag to indicate when ordering by system field</param>
|
||||
/// <param name="filter">Search text filter</param>
|
||||
/// <param name="contentTypeFilter">A list of content type Ids to filter the list by</param>
|
||||
/// <returns>An Enumerable list of <see cref="IContent"/> objects</returns>
|
||||
IEnumerable<IMedia> GetPagedChildren(int id, long pageIndex, int pageSize, out long totalRecords,
|
||||
string orderBy, Direction orderDirection, bool orderBySystemField, string filter, int[] contentTypeFilter);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of <see cref="IMedia"/> objects by Parent Id
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the Parent to retrieve Descendants from</param>
|
||||
/// <param name="pageIndex">Page number</param>
|
||||
/// <param name="pageSize">Page size</param>
|
||||
/// <param name="totalRecords">Total records query would return without paging</param>
|
||||
/// <param name="orderBy">Field to order by</param>
|
||||
/// <param name="orderDirection">Direction to order by</param>
|
||||
/// <param name="filter">Search text filter</param>
|
||||
/// <returns>An Enumerable list of <see cref="IContent"/> objects</returns>
|
||||
IEnumerable<IMedia> GetPagedDescendants(int id, long pageIndex, int pageSize, out long totalRecords,
|
||||
string orderBy = "path", Direction orderDirection = Direction.Ascending, string filter = "");
|
||||
IQuery<IMedia> filter = null, Ordering ordering = null);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of <see cref="IMedia"/> objects by Parent Id
|
||||
@@ -157,21 +106,31 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="filter"></param>
|
||||
/// <returns>An Enumerable list of <see cref="IContent"/> objects</returns>
|
||||
IEnumerable<IMedia> GetPagedDescendants(int id, long pageIndex, int pageSize, out long totalRecords,
|
||||
string orderBy, Direction orderDirection, bool orderBySystemField, IQuery<IMedia> filter);
|
||||
IQuery<IMedia> filter = null, Ordering ordering = null);
|
||||
|
||||
/// <summary>
|
||||
/// Gets descendants of a <see cref="IMedia"/> object by its Id
|
||||
/// Gets paged documents of a content content
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the Parent to retrieve descendants from</param>
|
||||
/// <returns>An Enumerable flat list of <see cref="IMedia"/> objects</returns>
|
||||
IEnumerable<IMedia> GetDescendants(int id);
|
||||
/// <param name="contentTypeId">The page number.</param>
|
||||
/// <param name="pageIndex">The page number.</param>
|
||||
/// <param name="pageSize">The page size.</param>
|
||||
/// <param name="totalRecords">Total number of documents.</param>
|
||||
/// <param name="filter">Search text filter.</param>
|
||||
/// <param name="ordering">Ordering infos.</param>
|
||||
IEnumerable<IMedia> GetPagedOfType(int contentTypeId, long pageIndex, int pageSize, out long totalRecords,
|
||||
IQuery<IMedia> filter = null, Ordering ordering = null);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of <see cref="IMedia"/> objects by the Id of the <see cref="IContentType"/>
|
||||
/// Gets paged documents for specified content types
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the <see cref="IMediaType"/></param>
|
||||
/// <returns>An Enumerable list of <see cref="IMedia"/> objects</returns>
|
||||
IEnumerable<IMedia> GetMediaOfMediaType(int id);
|
||||
/// <param name="contentTypeIds">The page number.</param>
|
||||
/// <param name="pageIndex">The page number.</param>
|
||||
/// <param name="pageSize">The page size.</param>
|
||||
/// <param name="totalRecords">Total number of documents.</param>
|
||||
/// <param name="filter">Search text filter.</param>
|
||||
/// <param name="ordering">Ordering infos.</param>
|
||||
IEnumerable<IMedia> GetPagedOfTypes(int[] contentTypeIds, long pageIndex, int pageSize, out long totalRecords,
|
||||
IQuery<IMedia> filter = null, Ordering ordering = null);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of <see cref="IMedia"/> objects, which reside at the first level / root
|
||||
@@ -183,7 +142,8 @@ namespace Umbraco.Core.Services
|
||||
/// Gets a collection of an <see cref="IMedia"/> objects, which resides in the Recycle Bin
|
||||
/// </summary>
|
||||
/// <returns>An Enumerable list of <see cref="IMedia"/> objects</returns>
|
||||
IEnumerable<IMedia> GetMediaInRecycleBin();
|
||||
IEnumerable<IMedia> GetPagedMediaInRecycleBin(long pageIndex, int pageSize, out long totalRecords,
|
||||
IQuery<IMedia> filter = null, Ordering ordering = null);
|
||||
|
||||
/// <summary>
|
||||
/// Moves an <see cref="IMedia"/> object to a new location
|
||||
@@ -321,13 +281,6 @@ namespace Umbraco.Core.Services
|
||||
/// <returns>An Enumerable list of <see cref="IMedia"/> objects</returns>
|
||||
IEnumerable<IMedia> GetAncestors(IMedia media);
|
||||
|
||||
/// <summary>
|
||||
/// Gets descendants of a <see cref="IMedia"/> object by its Id
|
||||
/// </summary>
|
||||
/// <param name="media">The Parent <see cref="IMedia"/> object to retrieve descendants from</param>
|
||||
/// <returns>An Enumerable flat list of <see cref="IMedia"/> objects</returns>
|
||||
IEnumerable<IMedia> GetDescendants(IMedia media);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the parent of the current media as an <see cref="IMedia"/> item.
|
||||
/// </summary>
|
||||
|
||||
@@ -405,28 +405,40 @@ namespace Umbraco.Core.Services.Implement
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of <see cref="IContent"/> objects by the Id of the <see cref="IContentType"/>
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the <see cref="IContentType"/></param>
|
||||
/// <returns>An Enumerable list of <see cref="IContent"/> objects</returns>
|
||||
public IEnumerable<IContent> GetByType(int id)
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<IContent> GetPagedOfType(int contentTypeId, long pageIndex, int pageSize, out long totalRecords
|
||||
, IQuery<IContent> filter = null, Ordering ordering = null)
|
||||
{
|
||||
if(pageIndex < 0) throw new ArgumentOutOfRangeException(nameof(pageIndex));
|
||||
if (pageSize <= 0) throw new ArgumentOutOfRangeException(nameof(pageSize));
|
||||
|
||||
if (ordering == null)
|
||||
ordering = Ordering.By("sortOrder");
|
||||
|
||||
using (var scope = ScopeProvider.CreateScope(autoComplete: true))
|
||||
{
|
||||
scope.ReadLock(Constants.Locks.ContentTree);
|
||||
var query = Query<IContent>().Where(x => x.ContentTypeId == id);
|
||||
return _documentRepository.Get(query);
|
||||
return _documentRepository.GetPage(
|
||||
Query<IContent>().Where(x => x.ContentTypeId == contentTypeId),
|
||||
pageIndex, pageSize, out totalRecords, filter, ordering);
|
||||
}
|
||||
}
|
||||
|
||||
internal IEnumerable<IContent> GetPublishedContentOfContentType(int id)
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<IContent> GetPagedOfTypes(int[] contentTypeIds, long pageIndex, int pageSize, out long totalRecords, IQuery<IContent> filter, Ordering ordering = null)
|
||||
{
|
||||
if (pageIndex < 0) throw new ArgumentOutOfRangeException(nameof(pageIndex));
|
||||
if (pageSize <= 0) throw new ArgumentOutOfRangeException(nameof(pageSize));
|
||||
|
||||
if (ordering == null)
|
||||
ordering = Ordering.By("sortOrder");
|
||||
|
||||
using (var scope = ScopeProvider.CreateScope(autoComplete: true))
|
||||
{
|
||||
scope.ReadLock(Constants.Locks.ContentTree);
|
||||
var query = Query<IContent>().Where(x => x.ContentTypeId == id);
|
||||
return _documentRepository.Get(query);
|
||||
return _documentRepository.GetPage(
|
||||
Query<IContent>().Where(x => contentTypeIds.Contains(x.ContentTypeId)),
|
||||
pageIndex, pageSize, out totalRecords, filter, ordering);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -536,21 +548,6 @@ namespace Umbraco.Core.Services.Implement
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of <see cref="IContent"/> objects by Parent Id
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the Parent to retrieve Children from</param>
|
||||
/// <returns>An Enumerable list of <see cref="IContent"/> objects</returns>
|
||||
public IEnumerable<IContent> GetChildren(int id)
|
||||
{
|
||||
using (var scope = ScopeProvider.CreateScope(autoComplete: true))
|
||||
{
|
||||
scope.ReadLock(Constants.Locks.ContentTree);
|
||||
var query = Query<IContent>().Where(x => x.ParentId == id);
|
||||
return _documentRepository.Get(query).OrderBy(x => x.SortOrder);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of published <see cref="IContent"/> objects by Parent Id
|
||||
/// </summary>
|
||||
@@ -568,18 +565,7 @@ namespace Umbraco.Core.Services.Implement
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<IContent> GetPagedChildren(int id, long pageIndex, int pageSize, out long totalChildren,
|
||||
string filter = null, Ordering ordering = null)
|
||||
{
|
||||
var filterQuery = filter.IsNullOrWhiteSpace()
|
||||
? null
|
||||
: Query<IContent>().Where(x => x.Name.Contains(filter));
|
||||
|
||||
return GetPagedChildren(id, pageIndex, pageSize, out totalChildren, filterQuery, ordering);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<IContent> GetPagedChildren(int id, long pageIndex, int pageSize, out long totalChildren,
|
||||
IQuery<IContent> filter, Ordering ordering = null)
|
||||
IQuery<IContent> filter = null, Ordering ordering = null)
|
||||
{
|
||||
if (pageIndex < 0) throw new ArgumentOutOfRangeException(nameof(pageIndex));
|
||||
if (pageSize <= 0) throw new ArgumentOutOfRangeException(nameof(pageSize));
|
||||
@@ -597,27 +583,16 @@ namespace Umbraco.Core.Services.Implement
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<IContent> GetPagedDescendants(int id, long pageIndex, int pageSize, out long totalChildren, string orderBy = "Path", Direction orderDirection = Direction.Ascending, string filter = "")
|
||||
public IEnumerable<IContent> GetPagedDescendants(int id, long pageIndex, int pageSize, out long totalChildren,
|
||||
IQuery<IContent> filter = null, Ordering ordering = null)
|
||||
{
|
||||
var filterQuery = filter.IsNullOrWhiteSpace()
|
||||
? null
|
||||
: Query<IContent>().Where(x => x.Name.Contains(filter));
|
||||
|
||||
return GetPagedDescendants(id, pageIndex, pageSize, out totalChildren, orderBy, orderDirection, true, filterQuery);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<IContent> GetPagedDescendants(int id, long pageIndex, int pageSize, out long totalChildren, string orderBy, Direction orderDirection, bool orderBySystemField, IQuery<IContent> filter)
|
||||
{
|
||||
if (pageIndex < 0) throw new ArgumentOutOfRangeException(nameof(pageIndex));
|
||||
if (pageSize <= 0) throw new ArgumentOutOfRangeException(nameof(pageSize));
|
||||
if (ordering == null)
|
||||
ordering = Ordering.By("Path");
|
||||
|
||||
using (var scope = ScopeProvider.CreateScope(autoComplete: true))
|
||||
{
|
||||
scope.ReadLock(Constants.Locks.ContentTree);
|
||||
|
||||
var query = Query<IContent>();
|
||||
|
||||
//if the id is System Root, then just get all
|
||||
if (id != Constants.System.Root)
|
||||
{
|
||||
@@ -627,65 +602,24 @@ namespace Umbraco.Core.Services.Implement
|
||||
totalChildren = 0;
|
||||
return Enumerable.Empty<IContent>();
|
||||
}
|
||||
query.Where(x => x.Path.SqlStartsWith($"{contentPath[0].Path},", TextColumnType.NVarchar));
|
||||
return GetPagedDescendantsLocked(contentPath[0].Path, pageIndex, pageSize, out totalChildren, filter, ordering);
|
||||
}
|
||||
|
||||
return _documentRepository.GetPage(query, pageIndex, pageSize, out totalChildren, filter, Ordering.By(orderBy, orderDirection, isCustomField: !orderBySystemField));
|
||||
return GetPagedDescendantsLocked(null, pageIndex, pageSize, out totalChildren, filter, ordering);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of <see cref="IContent"/> objects by its name or partial name
|
||||
/// </summary>
|
||||
/// <param name="parentId">Id of the Parent to retrieve Children from</param>
|
||||
/// <param name="name">Full or partial name of the children</param>
|
||||
/// <returns>An Enumerable list of <see cref="IContent"/> objects</returns>
|
||||
public IEnumerable<IContent> GetChildren(int parentId, string name)
|
||||
private IEnumerable<IContent> GetPagedDescendantsLocked(string contentPath, long pageIndex, int pageSize, out long totalChildren,
|
||||
IQuery<IContent> filter, Ordering ordering)
|
||||
{
|
||||
using (var scope = ScopeProvider.CreateScope(autoComplete: true))
|
||||
{
|
||||
scope.ReadLock(Constants.Locks.ContentTree);
|
||||
var query = Query<IContent>().Where(x => x.ParentId == parentId && x.Name.Contains(name));
|
||||
return _documentRepository.Get(query);
|
||||
}
|
||||
}
|
||||
if (pageIndex < 0) throw new ArgumentOutOfRangeException(nameof(pageIndex));
|
||||
if (pageSize <= 0) throw new ArgumentOutOfRangeException(nameof(pageSize));
|
||||
if (ordering == null) throw new ArgumentNullException(nameof(ordering));
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of <see cref="IContent"/> objects by Parent Id
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the Parent to retrieve Descendants from</param>
|
||||
/// <returns>An Enumerable list of <see cref="IContent"/> objects</returns>
|
||||
public IEnumerable<IContent> GetDescendants(int id)
|
||||
{
|
||||
using (var scope = ScopeProvider.CreateScope(autoComplete: true))
|
||||
{
|
||||
scope.ReadLock(Constants.Locks.ContentTree);
|
||||
var content = GetById(id);
|
||||
if (content == null)
|
||||
{
|
||||
scope.Complete(); // else causes rollback
|
||||
return Enumerable.Empty<IContent>();
|
||||
}
|
||||
var pathMatch = content.Path + ",";
|
||||
var query = Query<IContent>().Where(x => x.Id != content.Id && x.Path.StartsWith(pathMatch));
|
||||
return _documentRepository.Get(query);
|
||||
}
|
||||
}
|
||||
var query = Query<IContent>();
|
||||
if (!contentPath.IsNullOrWhiteSpace())
|
||||
query.Where(x => x.Path.SqlStartsWith($"{contentPath},", TextColumnType.NVarchar));
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of <see cref="IContent"/> objects by Parent Id
|
||||
/// </summary>
|
||||
/// <param name="content"><see cref="IContent"/> item to retrieve Descendants from</param>
|
||||
/// <returns>An Enumerable list of <see cref="IContent"/> objects</returns>
|
||||
public IEnumerable<IContent> GetDescendants(IContent content)
|
||||
{
|
||||
using (var scope = ScopeProvider.CreateScope(autoComplete: true))
|
||||
{
|
||||
scope.ReadLock(Constants.Locks.ContentTree);
|
||||
var pathMatch = content.Path + ",";
|
||||
var query = Query<IContent>().Where(x => x.Id != content.Id && x.Path.StartsWith(pathMatch));
|
||||
return _documentRepository.Get(query);
|
||||
}
|
||||
return _documentRepository.GetPage(query, pageIndex, pageSize, out totalChildren, filter, ordering);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -772,13 +706,17 @@ namespace Umbraco.Core.Services.Implement
|
||||
/// Gets a collection of an <see cref="IContent"/> objects, which resides in the Recycle Bin
|
||||
/// </summary>
|
||||
/// <returns>An Enumerable list of <see cref="IContent"/> objects</returns>
|
||||
public IEnumerable<IContent> GetContentInRecycleBin()
|
||||
public IEnumerable<IContent> GetPagedContentInRecycleBin(long pageIndex, int pageSize, out long totalRecords,
|
||||
IQuery<IContent> filter = null, Ordering ordering = null)
|
||||
{
|
||||
using (var scope = ScopeProvider.CreateScope(autoComplete: true))
|
||||
{
|
||||
if (ordering == null)
|
||||
ordering = Ordering.By("Path");
|
||||
|
||||
scope.ReadLock(Constants.Locks.ContentTree);
|
||||
var query = Query<IContent>().Where(x => x.Path.StartsWith(Constants.System.RecycleBinContentPathPrefix));
|
||||
return _documentRepository.Get(query);
|
||||
return _documentRepository.GetPage(query, pageIndex, pageSize, out totalRecords, filter, ordering);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -871,7 +809,7 @@ namespace Umbraco.Core.Services.Implement
|
||||
var langs = string.Join(", ", _languageRepository.GetMany()
|
||||
.Where(x => culturesChanging.InvariantContains(x.IsoCode))
|
||||
.Select(x => x.CultureName));
|
||||
Audit(AuditType.SaveVariant, userId, content.Id, $"Saved languagues: {langs}", langs);
|
||||
Audit(AuditType.SaveVariant, userId, content.Id, $"Saved languages: {langs}", langs);
|
||||
}
|
||||
else
|
||||
Audit(AuditType.Save, userId, content.Id);
|
||||
@@ -1355,27 +1293,35 @@ namespace Umbraco.Core.Services.Implement
|
||||
// if one fails, abort its branch
|
||||
var exclude = new HashSet<int>();
|
||||
|
||||
//fixme: should be paged to not overwhelm the database (timeouts)
|
||||
foreach (var d in GetDescendants(document))
|
||||
const int pageSize = 500;
|
||||
var page = 0;
|
||||
var total = long.MaxValue;
|
||||
while (page * pageSize < total)
|
||||
{
|
||||
// if parent is excluded, exclude document and ignore
|
||||
// if not forcing, and not publishing, exclude document and ignore
|
||||
if (exclude.Contains(d.ParentId) || !force && !d.Published)
|
||||
var descendants = GetPagedDescendants(document.Id, page++, pageSize, out total);
|
||||
|
||||
foreach (var d in descendants)
|
||||
{
|
||||
// if parent is excluded, exclude document and ignore
|
||||
// if not forcing, and not publishing, exclude document and ignore
|
||||
if (exclude.Contains(d.ParentId) || !force && !d.Published)
|
||||
{
|
||||
exclude.Add(d.Id);
|
||||
continue;
|
||||
}
|
||||
|
||||
// no need to check path here,
|
||||
// 1. because we know the parent is path-published (we just published it)
|
||||
// 2. because it would not work as nothing's been written out to the db until the uow completes
|
||||
result = SaveAndPublishBranchOne(scope, d, editing, publishCultures, false, publishedDocuments, evtMsgs, userId);
|
||||
results.Add(result);
|
||||
if (result.Success) continue;
|
||||
|
||||
// abort branch
|
||||
exclude.Add(d.Id);
|
||||
continue;
|
||||
}
|
||||
|
||||
// no need to check path here,
|
||||
// 1. because we know the parent is path-published (we just published it)
|
||||
// 2. because it would not work as nothing's been written out to the db until the uow completes
|
||||
result = SaveAndPublishBranchOne(scope, d, editing, publishCultures, false, publishedDocuments, evtMsgs, userId);
|
||||
results.Add(result);
|
||||
if (result.Success) continue;
|
||||
|
||||
// abort branch
|
||||
exclude.Add(d.Id);
|
||||
}
|
||||
|
||||
|
||||
scope.Events.Dispatch(TreeChanged, this, new TreeChange<IContent>(document, TreeChangeTypes.RefreshBranch).ToEventArgs());
|
||||
scope.Events.Dispatch(Published, this, new PublishEventArgs<IContent>(publishedDocuments, false, false), "Published");
|
||||
@@ -1458,25 +1404,8 @@ namespace Umbraco.Core.Services.Implement
|
||||
|
||||
private void DeleteLocked(IScope scope, IContent content)
|
||||
{
|
||||
// then recursively delete descendants, bottom-up
|
||||
// just repository.Delete + an event
|
||||
var stack = new Stack<IContent>();
|
||||
stack.Push(content);
|
||||
var level = 1;
|
||||
while (stack.Count > 0)
|
||||
void DoDelete(IContent c)
|
||||
{
|
||||
var c = stack.Peek();
|
||||
IContent[] cc;
|
||||
if (c.Level == level)
|
||||
while ((cc = c.Children(this).ToArray()).Length > 0)
|
||||
{
|
||||
foreach (var ci in cc)
|
||||
stack.Push(ci);
|
||||
c = cc[cc.Length - 1];
|
||||
}
|
||||
c = stack.Pop();
|
||||
level = c.Level;
|
||||
|
||||
_documentRepository.Delete(c);
|
||||
var args = new DeleteEventArgs<IContent>(c, false); // raise event & get flagged files
|
||||
scope.Events.Dispatch(Deleted, this, args, nameof(Deleted));
|
||||
@@ -1485,6 +1414,18 @@ namespace Umbraco.Core.Services.Implement
|
||||
_mediaFileSystem.DeleteFiles(args.MediaFilesToDelete, // remove flagged files
|
||||
(file, e) => Logger.Error<ContentService>(e, "An error occurred while deleting file attached to nodes: {File}", file));
|
||||
}
|
||||
|
||||
const int pageSize = 500;
|
||||
var page = 0;
|
||||
var total = long.MaxValue;
|
||||
while (page * pageSize < total)
|
||||
{
|
||||
//get descendants - ordered from deepest to shallowest
|
||||
var descendants = GetPagedDescendants(content.Id, page, pageSize, out total, ordering: Ordering.By("Path", Direction.Descending));
|
||||
foreach (var c in descendants)
|
||||
DoDelete(c);
|
||||
}
|
||||
DoDelete(content);
|
||||
}
|
||||
|
||||
//TODO:
|
||||
@@ -1694,8 +1635,8 @@ namespace Umbraco.Core.Services.Implement
|
||||
|
||||
moves.Add(Tuple.Create(content, content.Path)); // capture original path
|
||||
|
||||
// get before moving, in case uow is immediate
|
||||
var descendants = GetDescendants(content);
|
||||
//need to store the original path to lookup descendants based on it below
|
||||
var originalPath = content.Path;
|
||||
|
||||
// these will be updated by the repo because we changed parentId
|
||||
//content.Path = (parent == null ? "-1" : parent.Path) + "," + content.Id;
|
||||
@@ -1708,22 +1649,28 @@ namespace Umbraco.Core.Services.Implement
|
||||
//paths[content.Id] = content.Path;
|
||||
paths[content.Id] = (parent == null ? (parentId == Constants.System.RecycleBinContent ? "-1,-20" : "-1") : parent.Path) + "," + content.Id;
|
||||
|
||||
foreach (var descendant in descendants)
|
||||
const int pageSize = 500;
|
||||
var page = 0;
|
||||
var total = long.MaxValue;
|
||||
while(page * pageSize < total)
|
||||
{
|
||||
moves.Add(Tuple.Create(descendant, descendant.Path)); // capture original path
|
||||
var descendants = GetPagedDescendantsLocked(originalPath, page++, pageSize, out total, null, Ordering.By("Path", Direction.Ascending));
|
||||
foreach (var descendant in descendants)
|
||||
{
|
||||
moves.Add(Tuple.Create(descendant, descendant.Path)); // capture original path
|
||||
|
||||
// update path and level since we do not update parentId
|
||||
if (paths.ContainsKey(descendant.ParentId) == false)
|
||||
Console.WriteLine("oops on " + descendant.ParentId + " for " + content.Path + " " + parent?.Path);
|
||||
descendant.Path = paths[descendant.Id] = paths[descendant.ParentId] + "," + descendant.Id;
|
||||
Console.WriteLine("path " + descendant.Id + " = " + paths[descendant.Id]);
|
||||
descendant.Level += levelDelta;
|
||||
PerformMoveContentLocked(descendant, userId, trash);
|
||||
// update path and level since we do not update parentId
|
||||
descendant.Path = paths[descendant.Id] = paths[descendant.ParentId] + "," + descendant.Id;
|
||||
descendant.Level += levelDelta;
|
||||
PerformMoveContentLocked(descendant, userId, trash);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void PerformMoveContentLocked(IContent content, int userId, bool? trash)
|
||||
{
|
||||
//fixme no casting
|
||||
if (trash.HasValue) ((ContentBase) content).Trashed = trash.Value;
|
||||
content.WriterId = userId;
|
||||
_documentRepository.Save(content);
|
||||
@@ -1852,29 +1799,36 @@ namespace Umbraco.Core.Services.Implement
|
||||
|
||||
if (recursive) // process descendants
|
||||
{
|
||||
foreach (var descendant in GetDescendants(content))
|
||||
const int pageSize = 500;
|
||||
var page = 0;
|
||||
var total = long.MaxValue;
|
||||
while(page * pageSize < total)
|
||||
{
|
||||
// if parent has not been copied, skip, else gets its copy id
|
||||
if (idmap.TryGetValue(descendant.ParentId, out parentId) == false) continue;
|
||||
var descendants = GetPagedDescendants(content.Id, page++, pageSize, out total);
|
||||
foreach (var descendant in descendants)
|
||||
{
|
||||
// if parent has not been copied, skip, else gets its copy id
|
||||
if (idmap.TryGetValue(descendant.ParentId, out parentId) == false) continue;
|
||||
|
||||
var descendantCopy = descendant.DeepCloneWithResetIdentities();
|
||||
descendantCopy.ParentId = parentId;
|
||||
var descendantCopy = descendant.DeepCloneWithResetIdentities();
|
||||
descendantCopy.ParentId = parentId;
|
||||
|
||||
if (scope.Events.DispatchCancelable(Copying, this, new CopyEventArgs<IContent>(descendant, descendantCopy, parentId)))
|
||||
continue;
|
||||
if (scope.Events.DispatchCancelable(Copying, this, new CopyEventArgs<IContent>(descendant, descendantCopy, parentId)))
|
||||
continue;
|
||||
|
||||
// a copy is not published (but not really unpublishing either)
|
||||
// update the create author and last edit author
|
||||
if (descendantCopy.Published)
|
||||
((Content) descendantCopy).Published = false;
|
||||
descendantCopy.CreatorId = userId;
|
||||
descendantCopy.WriterId = userId;
|
||||
// a copy is not published (but not really unpublishing either)
|
||||
// update the create author and last edit author
|
||||
if (descendantCopy.Published)
|
||||
((Content)descendantCopy).Published = false;
|
||||
descendantCopy.CreatorId = userId;
|
||||
descendantCopy.WriterId = userId;
|
||||
|
||||
// save and flush (see above)
|
||||
_documentRepository.Save(descendantCopy);
|
||||
// save and flush (see above)
|
||||
_documentRepository.Save(descendantCopy);
|
||||
|
||||
copies.Add(Tuple.Create(descendant, descendantCopy));
|
||||
idmap[descendant.Id] = descendantCopy.Id;
|
||||
copies.Add(Tuple.Create(descendant, descendantCopy));
|
||||
idmap[descendant.Id] = descendantCopy.Id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -364,18 +364,39 @@ namespace Umbraco.Core.Services.Implement
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of <see cref="IMedia"/> objects by the Id of the <see cref="IMediaType"/>
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the <see cref="IMediaType"/></param>
|
||||
/// <returns>An Enumerable list of <see cref="IMedia"/> objects</returns>
|
||||
public IEnumerable<IMedia> GetMediaOfMediaType(int id)
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<IMedia> GetPagedOfType(int contentTypeId, long pageIndex, int pageSize, out long totalRecords, IQuery<IMedia> filter = null, Ordering ordering = null)
|
||||
{
|
||||
if (pageIndex < 0) throw new ArgumentOutOfRangeException(nameof(pageIndex));
|
||||
if (pageSize <= 0) throw new ArgumentOutOfRangeException(nameof(pageSize));
|
||||
|
||||
if (ordering == null)
|
||||
ordering = Ordering.By("sortOrder");
|
||||
|
||||
using (var scope = ScopeProvider.CreateScope(autoComplete: true))
|
||||
{
|
||||
scope.ReadLock(Constants.Locks.MediaTree);
|
||||
var query = Query<IMedia>().Where(x => x.ContentTypeId == id);
|
||||
return _mediaRepository.Get(query);
|
||||
scope.ReadLock(Constants.Locks.ContentTree);
|
||||
return _mediaRepository.GetPage(
|
||||
Query<IMedia>().Where(x => x.ContentTypeId == contentTypeId),
|
||||
pageIndex, pageSize, out totalRecords, filter, ordering);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<IMedia> GetPagedOfTypes(int[] contentTypeIds, long pageIndex, int pageSize, out long totalRecords, IQuery<IMedia> filter = null, Ordering ordering = null)
|
||||
{
|
||||
if (pageIndex < 0) throw new ArgumentOutOfRangeException(nameof(pageIndex));
|
||||
if (pageSize <= 0) throw new ArgumentOutOfRangeException(nameof(pageSize));
|
||||
|
||||
if (ordering == null)
|
||||
ordering = Ordering.By("sortOrder");
|
||||
|
||||
using (var scope = ScopeProvider.CreateScope(autoComplete: true))
|
||||
{
|
||||
scope.ReadLock(Constants.Locks.ContentTree);
|
||||
return _mediaRepository.GetPage(
|
||||
Query<IMedia>().Where(x => contentTypeIds.Contains(x.ContentTypeId)),
|
||||
pageIndex, pageSize, out totalRecords, filter, ordering);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -460,149 +481,36 @@ namespace Umbraco.Core.Services.Implement
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of <see cref="IMedia"/> objects by Parent Id
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the Parent to retrieve Children from</param>
|
||||
/// <returns>An Enumerable list of <see cref="IMedia"/> objects</returns>
|
||||
public IEnumerable<IMedia> GetChildren(int id)
|
||||
{
|
||||
using (var scope = ScopeProvider.CreateScope(autoComplete: true))
|
||||
{
|
||||
scope.ReadLock(Constants.Locks.MediaTree);
|
||||
var query = Query<IMedia>().Where(x => x.ParentId == id);
|
||||
return _mediaRepository.Get(query).OrderBy(x => x.SortOrder);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of <see cref="IMedia"/> objects by Parent Id
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the Parent to retrieve Children from</param>
|
||||
/// <param name="pageIndex">Page index (zero based)</param>
|
||||
/// <param name="pageSize">Page size</param>
|
||||
/// <param name="totalChildren">Total records query would return without paging</param>
|
||||
/// <param name="orderBy">Field to order by</param>
|
||||
/// <param name="orderDirection">Direction to order by</param>
|
||||
/// <param name="filter">Search text filter</param>
|
||||
/// <returns>An Enumerable list of <see cref="IMedia"/> objects</returns>
|
||||
public IEnumerable<IMedia> GetPagedChildren(int id, long pageIndex, int pageSize, out long totalChildren, string orderBy, Direction orderDirection, string filter = "")
|
||||
{
|
||||
var filterQuery = filter.IsNullOrWhiteSpace()
|
||||
? null
|
||||
: Query<IMedia>().Where(x => x.Name.Contains(filter));
|
||||
|
||||
return GetPagedChildren(id, pageIndex, pageSize, out totalChildren, orderBy, orderDirection, true, filterQuery);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of <see cref="IMedia"/> objects by Parent Id
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the Parent to retrieve Children from</param>
|
||||
/// <param name="pageIndex">Page index (zero based)</param>
|
||||
/// <param name="pageSize">Page size</param>
|
||||
/// <param name="totalChildren">Total records query would return without paging</param>
|
||||
/// <param name="orderBy">Field to order by</param>
|
||||
/// <param name="orderDirection">Direction to order by</param>
|
||||
/// <param name="orderBySystemField">Flag to indicate when ordering by system field</param>
|
||||
/// <param name="filter"></param>
|
||||
/// <returns>An Enumerable list of <see cref="IMedia"/> objects</returns>
|
||||
public IEnumerable<IMedia> GetPagedChildren(int id, long pageIndex, int pageSize, out long totalChildren, string orderBy, Direction orderDirection, bool orderBySystemField, IQuery<IMedia> filter)
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<IMedia> GetPagedChildren(int id, long pageIndex, int pageSize, out long totalChildren,
|
||||
IQuery<IMedia> filter = null, Ordering ordering = null)
|
||||
{
|
||||
if (pageIndex < 0) throw new ArgumentOutOfRangeException(nameof(pageIndex));
|
||||
if (pageSize <= 0) throw new ArgumentOutOfRangeException(nameof(pageSize));
|
||||
|
||||
if (ordering == null)
|
||||
ordering = Ordering.By("sortOrder");
|
||||
|
||||
using (var scope = ScopeProvider.CreateScope(autoComplete: true))
|
||||
{
|
||||
scope.ReadLock(Constants.Locks.MediaTree);
|
||||
|
||||
var query = Query<IMedia>().Where(x => x.ParentId == id);
|
||||
return _mediaRepository.GetPage(query, pageIndex, pageSize, out totalChildren, filter, Ordering.By(orderBy, orderDirection, isCustomField: !orderBySystemField));
|
||||
return _mediaRepository.GetPage(query, pageIndex, pageSize, out totalChildren, filter, ordering);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of <see cref="IMedia"/> objects by Parent Id
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the Parent to retrieve Children from</param>
|
||||
/// <param name="pageIndex">Page number</param>
|
||||
/// <param name="pageSize">Page size</param>
|
||||
/// <param name="totalChildren">Total records query would return without paging</param>
|
||||
/// <param name="orderBy">Field to order by</param>
|
||||
/// <param name="orderDirection">Direction to order by</param>
|
||||
/// <param name="orderBySystemField">Flag to indicate when ordering by system field</param>
|
||||
/// <param name="filter">Search text filter</param>
|
||||
/// <param name="contentTypeFilter">A list of content type Ids to filter the list by</param>
|
||||
/// <returns>An Enumerable list of <see cref="IContent"/> objects</returns>
|
||||
public IEnumerable<IMedia> GetPagedChildren(int id, long pageIndex, int pageSize, out long totalChildren, string orderBy, Direction orderDirection, bool orderBySystemField, string filter, int[] contentTypeFilter)
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<IMedia> GetPagedDescendants(int id, long pageIndex, int pageSize, out long totalChildren,
|
||||
IQuery<IMedia> filter = null, Ordering ordering = null)
|
||||
{
|
||||
if (pageIndex < 0) throw new ArgumentOutOfRangeException(nameof(pageIndex));
|
||||
if (pageSize <= 0) throw new ArgumentOutOfRangeException(nameof(pageSize));
|
||||
if (ordering == null)
|
||||
ordering = Ordering.By("Path");
|
||||
|
||||
using (var scope = ScopeProvider.CreateScope(autoComplete: true))
|
||||
{
|
||||
scope.ReadLock(Constants.Locks.MediaTree);
|
||||
|
||||
var query = Query<IMedia>();
|
||||
// always check for a parent - else it will also get decendants (and then you should use the GetPagedDescendants method)
|
||||
|
||||
query.Where(x => x.ParentId == id);
|
||||
|
||||
if (contentTypeFilter != null && contentTypeFilter.Length > 0)
|
||||
{
|
||||
query.Where(x => contentTypeFilter.Contains(x.ContentTypeId));
|
||||
}
|
||||
|
||||
var filterQuery = filter.IsNullOrWhiteSpace()
|
||||
? null
|
||||
: Query<IMedia>().Where(x => x.Name.Contains(filter));
|
||||
return _mediaRepository.GetPage(query, pageIndex, pageSize, out totalChildren, filterQuery, Ordering.By(orderBy, orderDirection, isCustomField: !orderBySystemField));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of <see cref="IMedia"/> objects by Parent Id
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the Parent to retrieve Descendants from</param>
|
||||
/// <param name="pageIndex">Page number</param>
|
||||
/// <param name="pageSize">Page size</param>
|
||||
/// <param name="totalChildren">Total records query would return without paging</param>
|
||||
/// <param name="orderBy">Field to order by</param>
|
||||
/// <param name="orderDirection">Direction to order by</param>
|
||||
/// <param name="filter">Search text filter</param>
|
||||
/// <returns>An Enumerable list of <see cref="IMedia"/> objects</returns>
|
||||
public IEnumerable<IMedia> GetPagedDescendants(int id, long pageIndex, int pageSize, out long totalChildren, string orderBy = "Path", Direction orderDirection = Direction.Ascending, string filter = "")
|
||||
{
|
||||
var filterQuery = filter.IsNullOrWhiteSpace()
|
||||
? null
|
||||
: Query<IMedia>().Where(x => x.Name.Contains(filter));
|
||||
|
||||
return GetPagedDescendants(id, pageIndex, pageSize, out totalChildren, orderBy, orderDirection, true, filterQuery);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of <see cref="IMedia"/> objects by Parent Id
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the Parent to retrieve Descendants from</param>
|
||||
/// <param name="pageIndex">Page number</param>
|
||||
/// <param name="pageSize">Page size</param>
|
||||
/// <param name="totalChildren">Total records query would return without paging</param>
|
||||
/// <param name="orderBy">Field to order by</param>
|
||||
/// <param name="orderDirection">Direction to order by</param>
|
||||
/// <param name="orderBySystemField">Flag to indicate when ordering by system field</param>
|
||||
/// <param name="filter"></param>
|
||||
/// <returns>An Enumerable list of <see cref="IMedia"/> objects</returns>
|
||||
public IEnumerable<IMedia> GetPagedDescendants(int id, long pageIndex, int pageSize, out long totalChildren, string orderBy, Direction orderDirection, bool orderBySystemField, IQuery<IMedia> filter)
|
||||
{
|
||||
if (pageIndex < 0) throw new ArgumentOutOfRangeException(nameof(pageIndex));
|
||||
if (pageSize <= 0) throw new ArgumentOutOfRangeException(nameof(pageSize));
|
||||
|
||||
using (var scope = ScopeProvider.CreateScope(autoComplete: true))
|
||||
{
|
||||
scope.ReadLock(Constants.Locks.MediaTree);
|
||||
|
||||
var query = Query<IMedia>();
|
||||
|
||||
//if the id is System Root, then just get all
|
||||
if (id != Constants.System.Root)
|
||||
{
|
||||
@@ -612,47 +520,24 @@ namespace Umbraco.Core.Services.Implement
|
||||
totalChildren = 0;
|
||||
return Enumerable.Empty<IMedia>();
|
||||
}
|
||||
query.Where(x => x.Path.SqlStartsWith(mediaPath[0].Path + ",", TextColumnType.NVarchar));
|
||||
return GetPagedDescendantsLocked(mediaPath[0].Path, pageIndex, pageSize, out totalChildren, filter, ordering);
|
||||
}
|
||||
|
||||
return _mediaRepository.GetPage(query, pageIndex, pageSize, out totalChildren, filter, Ordering.By(orderBy, orderDirection, isCustomField: !orderBySystemField));
|
||||
return GetPagedDescendantsLocked(null, pageIndex, pageSize, out totalChildren, filter, ordering);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets descendants of a <see cref="IMedia"/> object by its Id
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the Parent to retrieve descendants from</param>
|
||||
/// <returns>An Enumerable flat list of <see cref="IMedia"/> objects</returns>
|
||||
public IEnumerable<IMedia> GetDescendants(int id)
|
||||
private IEnumerable<IMedia> GetPagedDescendantsLocked(string mediaPath, long pageIndex, int pageSize, out long totalChildren,
|
||||
IQuery<IMedia> filter, Ordering ordering)
|
||||
{
|
||||
using (var scope = ScopeProvider.CreateScope(autoComplete: true))
|
||||
{
|
||||
scope.ReadLock(Constants.Locks.MediaTree);
|
||||
var media = GetById(id);
|
||||
if (media == null)
|
||||
return Enumerable.Empty<IMedia>();
|
||||
if (pageIndex < 0) throw new ArgumentOutOfRangeException(nameof(pageIndex));
|
||||
if (pageSize <= 0) throw new ArgumentOutOfRangeException(nameof(pageSize));
|
||||
if (ordering == null) throw new ArgumentNullException(nameof(ordering));
|
||||
|
||||
var pathMatch = media.Path + ",";
|
||||
var query = Query<IMedia>().Where(x => x.Id != media.Id && x.Path.StartsWith(pathMatch));
|
||||
return _mediaRepository.Get(query);
|
||||
}
|
||||
}
|
||||
var query = Query<IMedia>();
|
||||
if (!mediaPath.IsNullOrWhiteSpace())
|
||||
query.Where(x => x.Path.SqlStartsWith(mediaPath + ",", TextColumnType.NVarchar));
|
||||
|
||||
/// <summary>
|
||||
/// Gets descendants of a <see cref="IMedia"/> object by its Id
|
||||
/// </summary>
|
||||
/// <param name="media">The Parent <see cref="IMedia"/> object to retrieve descendants from</param>
|
||||
/// <returns>An Enumerable flat list of <see cref="IMedia"/> objects</returns>
|
||||
public IEnumerable<IMedia> GetDescendants(IMedia media)
|
||||
{
|
||||
using (var scope = ScopeProvider.CreateScope(autoComplete: true))
|
||||
{
|
||||
scope.ReadLock(Constants.Locks.MediaTree);
|
||||
var pathMatch = media.Path + ",";
|
||||
var query = Query<IMedia>().Where(x => x.Id != media.Id && x.Path.StartsWith(pathMatch));
|
||||
return _mediaRepository.Get(query);
|
||||
}
|
||||
return _mediaRepository.GetPage(query, pageIndex, pageSize, out totalChildren, filter, ordering);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -694,17 +579,18 @@ namespace Umbraco.Core.Services.Implement
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of an <see cref="IMedia"/> objects, which resides in the Recycle Bin
|
||||
/// </summary>
|
||||
/// <returns>An Enumerable list of <see cref="IMedia"/> objects</returns>
|
||||
public IEnumerable<IMedia> GetMediaInRecycleBin()
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<IMedia> GetPagedMediaInRecycleBin(long pageIndex, int pageSize, out long totalRecords,
|
||||
IQuery<IMedia> filter = null, Ordering ordering = null)
|
||||
{
|
||||
using (var scope = ScopeProvider.CreateScope(autoComplete: true))
|
||||
{
|
||||
if (ordering == null)
|
||||
ordering = Ordering.By("Path");
|
||||
|
||||
scope.ReadLock(Constants.Locks.MediaTree);
|
||||
var query = Query<IMedia>().Where(x => x.Path.StartsWith(Constants.System.RecycleBinMediaPathPrefix));
|
||||
return _mediaRepository.Get(query);
|
||||
return _mediaRepository.GetPage(query, pageIndex, pageSize, out totalRecords, filter, ordering);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -865,25 +751,8 @@ namespace Umbraco.Core.Services.Implement
|
||||
|
||||
private void DeleteLocked(IScope scope, IMedia media)
|
||||
{
|
||||
// then recursively delete descendants, bottom-up
|
||||
// just repository.Delete + an event
|
||||
var stack = new Stack<IMedia>();
|
||||
stack.Push(media);
|
||||
var level = 1;
|
||||
while (stack.Count > 0)
|
||||
void DoDelete(IMedia c)
|
||||
{
|
||||
var c = stack.Peek();
|
||||
IMedia[] cc;
|
||||
if (c.Level == level)
|
||||
while ((cc = c.Children(this).ToArray()).Length > 0)
|
||||
{
|
||||
foreach (var ci in cc)
|
||||
stack.Push(ci);
|
||||
c = cc[cc.Length - 1];
|
||||
}
|
||||
c = stack.Pop();
|
||||
level = c.Level;
|
||||
|
||||
_mediaRepository.Delete(c);
|
||||
var args = new DeleteEventArgs<IMedia>(c, false); // raise event & get flagged files
|
||||
scope.Events.Dispatch(Deleted, this, args);
|
||||
@@ -891,6 +760,18 @@ namespace Umbraco.Core.Services.Implement
|
||||
_mediaFileSystem.DeleteFiles(args.MediaFilesToDelete, // remove flagged files
|
||||
(file, e) => Logger.Error<MediaService>(e, "An error occurred while deleting file attached to nodes: {File}", file));
|
||||
}
|
||||
|
||||
const int pageSize = 500;
|
||||
var page = 0;
|
||||
var total = long.MaxValue;
|
||||
while(page * pageSize < total)
|
||||
{
|
||||
//get descendants - ordered from deepest to shallowest
|
||||
var descendants = GetPagedDescendants(media.Id, page, pageSize, out total, ordering: Ordering.By("Path", Direction.Descending));
|
||||
foreach (var c in descendants)
|
||||
DoDelete(c);
|
||||
}
|
||||
DoDelete(media);
|
||||
}
|
||||
|
||||
//TODO:
|
||||
@@ -1100,8 +981,8 @@ namespace Umbraco.Core.Services.Implement
|
||||
|
||||
moves.Add(Tuple.Create(media, media.Path)); // capture original path
|
||||
|
||||
// get before moving, in case uow is immediate
|
||||
var descendants = GetDescendants(media);
|
||||
//need to store the original path to lookup descendants based on it below
|
||||
var originalPath = media.Path;
|
||||
|
||||
// these will be updated by the repo because we changed parentId
|
||||
//media.Path = (parent == null ? "-1" : parent.Path) + "," + media.Id;
|
||||
@@ -1114,14 +995,21 @@ namespace Umbraco.Core.Services.Implement
|
||||
//paths[media.Id] = media.Path;
|
||||
paths[media.Id] = (parent == null ? (parentId == Constants.System.RecycleBinMedia ? "-1,-21" : "-1") : parent.Path) + "," + media.Id;
|
||||
|
||||
foreach (var descendant in descendants)
|
||||
const int pageSize = 500;
|
||||
var page = 0;
|
||||
var total = long.MaxValue;
|
||||
while (page * pageSize < total)
|
||||
{
|
||||
moves.Add(Tuple.Create(descendant, descendant.Path)); // capture original path
|
||||
var descendants = GetPagedDescendantsLocked(originalPath, page++, pageSize, out total, null, Ordering.By("Path", Direction.Ascending));
|
||||
foreach (var descendant in descendants)
|
||||
{
|
||||
moves.Add(Tuple.Create(descendant, descendant.Path)); // capture original path
|
||||
|
||||
// update path and level since we do not update parentId
|
||||
descendant.Path = paths[descendant.Id] = paths[descendant.ParentId] + "," + descendant.Id;
|
||||
descendant.Level += levelDelta;
|
||||
PerformMoveMediaLocked(descendant, userId, trash);
|
||||
// update path and level since we do not update parentId
|
||||
descendant.Path = paths[descendant.Id] = paths[descendant.ParentId] + "," + descendant.Id;
|
||||
descendant.Level += levelDelta;
|
||||
PerformMoveMediaLocked(descendant, userId, trash);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -393,12 +393,14 @@ namespace Umbraco.Core.Services.Implement
|
||||
|
||||
// fixme get rid of string filter?
|
||||
|
||||
public IEnumerable<IMember> GetAll(long pageIndex, int pageSize, out long totalRecords, string orderBy, Direction orderDirection, string memberTypeAlias = null, string filter = "")
|
||||
public IEnumerable<IMember> GetAll(long pageIndex, int pageSize, out long totalRecords,
|
||||
string orderBy, Direction orderDirection, string memberTypeAlias = null, string filter = "")
|
||||
{
|
||||
return GetAll(pageIndex, pageSize, out totalRecords, orderBy, orderDirection, true, memberTypeAlias, filter);
|
||||
}
|
||||
|
||||
public IEnumerable<IMember> GetAll(long pageIndex, int pageSize, out long totalRecords, string orderBy, Direction orderDirection, bool orderBySystemField, string memberTypeAlias, string filter)
|
||||
public IEnumerable<IMember> GetAll(long pageIndex, int pageSize, out long totalRecords,
|
||||
string orderBy, Direction orderDirection, bool orderBySystemField, string memberTypeAlias, string filter)
|
||||
{
|
||||
using (var scope = ScopeProvider.CreateScope(autoComplete: true))
|
||||
{
|
||||
|
||||
@@ -143,7 +143,6 @@
|
||||
<Compile Include="Cache\SingleItemsOnlyRepositoryCachePolicy.cs" />
|
||||
<Compile Include="Cache\StaticCacheProvider.cs" />
|
||||
<Compile Include="Cache\TypedCacheRefresherBase.cs" />
|
||||
<Compile Include="CodeAnnotations\ActionMetadataAttribute.cs" />
|
||||
<Compile Include="CodeAnnotations\FriendlyNameAttribute.cs" />
|
||||
<Compile Include="CodeAnnotations\UmbracoObjectTypeAttribute.cs" />
|
||||
<Compile Include="CodeAnnotations\UmbracoUdiTypeAttribute.cs" />
|
||||
|
||||
@@ -258,7 +258,8 @@ namespace Umbraco.Examine
|
||||
else
|
||||
{
|
||||
//add the published filter
|
||||
descendants = ContentService.GetPagedDescendants(contentParentId, pageIndex, pageSize, out total, "Path", Direction.Ascending, true, _publishedQuery);
|
||||
descendants = ContentService.GetPagedDescendants(contentParentId, pageIndex, pageSize, out total,
|
||||
_publishedQuery, Ordering.By("Path", Direction.Ascending));
|
||||
}
|
||||
|
||||
//if specific types are declared we need to post filter them
|
||||
|
||||
@@ -418,7 +418,7 @@ namespace Umbraco.Examine
|
||||
//icon
|
||||
if (e.IndexItem.ValueSet.Values.TryGetValue("icon", out var icon) && e.IndexItem.ValueSet.Values.ContainsKey(IconFieldName) == false)
|
||||
{
|
||||
e.IndexItem.ValueSet.Values[IconFieldName] = new List<object> { icon };
|
||||
e.IndexItem.ValueSet.Values[IconFieldName] = icon;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -175,13 +175,17 @@ namespace Umbraco.Examine
|
||||
if (e.IndexItem.ValueSet.Values.TryGetValue("key", out var key) && e.IndexItem.ValueSet.Values.ContainsKey("__key") == false)
|
||||
{
|
||||
//double __ prefix means it will be indexed as culture invariant
|
||||
e.IndexItem.ValueSet.Values["__key"] = new List<object> { key };
|
||||
e.IndexItem.ValueSet.Values["__key"] = key;
|
||||
}
|
||||
|
||||
if (e.IndexItem.ValueSet.Values.TryGetValue("email", out var email) && e.IndexItem.ValueSet.Values.ContainsKey("_searchEmail") == false)
|
||||
{
|
||||
//will be indexed as full text (the default anaylyzer)
|
||||
e.IndexItem.ValueSet.Values["_searchEmail"] = new List<object> { email?.ToString().Replace(".", " ").Replace("@", " ") };
|
||||
if (email.Count > 0)
|
||||
{
|
||||
//will be indexed as full text (the default anaylyzer)
|
||||
e.IndexItem.ValueSet.Values["_searchEmail"] = new List<object> { email[0]?.ToString().Replace(".", " ").Replace("@", " ") };
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Web;
|
||||
using Umbraco.Web.UI.Pages;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
namespace Umbraco.Tests.Composing
|
||||
{
|
||||
[TestFixture]
|
||||
public class ActionCollectionTests : ComposingTestBase
|
||||
{
|
||||
[Test]
|
||||
public void ActionCollectionBuilderWorks()
|
||||
{
|
||||
var collectionBuilder = new ActionCollectionBuilder();
|
||||
collectionBuilder.SetProducer(() => TypeLoader.GetActions());
|
||||
|
||||
var actions = collectionBuilder.CreateCollection();
|
||||
Assert.AreEqual(2, actions.Count());
|
||||
|
||||
// order is unspecified, but both must be there
|
||||
var hasAction1 = actions.ElementAt(0) is SingletonAction || actions.ElementAt(1) is SingletonAction;
|
||||
var hasAction2 = actions.ElementAt(0) is NonSingletonAction || actions.ElementAt(1) is NonSingletonAction;
|
||||
Assert.IsTrue(hasAction1);
|
||||
Assert.IsTrue(hasAction2);
|
||||
|
||||
var singletonAction = (SingletonAction) (actions.ElementAt(0) is SingletonAction ? actions.ElementAt(0) : actions.ElementAt(1));
|
||||
|
||||
// ensure it is a singleton
|
||||
Assert.AreSame(SingletonAction.Instance, singletonAction);
|
||||
}
|
||||
|
||||
#region Test Objects
|
||||
|
||||
public class SingletonAction : IAction
|
||||
{
|
||||
public static SingletonAction Instance { get; } = new SingletonAction();
|
||||
|
||||
public char Letter => 'I';
|
||||
|
||||
public string JsFunctionName => $"{ClientTools.Scripts.GetAppActions}.actionAssignDomain()";
|
||||
|
||||
public string JsSource => null;
|
||||
|
||||
public string Alias => "assignDomain";
|
||||
|
||||
public string Icon => ".sprDomain";
|
||||
|
||||
public bool ShowInNotifier => false;
|
||||
|
||||
public bool CanBePermissionAssigned => true;
|
||||
|
||||
public bool OpensDialog => true;
|
||||
}
|
||||
|
||||
public class NonSingletonAction : IAction
|
||||
{
|
||||
public char Letter => 'Q';
|
||||
|
||||
public string JsFunctionName => $"{ClientTools.Scripts.GetAppActions}.actionAssignDomain()";
|
||||
|
||||
public string JsSource => null;
|
||||
|
||||
public string Alias => "asfasdf";
|
||||
|
||||
public string Icon => ".sprDomain";
|
||||
|
||||
public bool ShowInNotifier => false;
|
||||
|
||||
public bool CanBePermissionAssigned => true;
|
||||
|
||||
public bool OpensDialog => true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -268,13 +268,6 @@ AnotherContentFinder
|
||||
Assert.AreEqual(2, foundTypes1.Count());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Resolves_Actions()
|
||||
{
|
||||
var actions = _typeLoader.GetActions();
|
||||
Assert.AreEqual(33, actions.Count());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetDataEditors()
|
||||
{
|
||||
|
||||
@@ -459,7 +459,7 @@ namespace Umbraco.Tests.Integration
|
||||
#region Utils
|
||||
|
||||
private IEnumerable<IContent> Children(IContent content)
|
||||
=> ServiceContext.ContentService.GetChildren(content.Id);
|
||||
=> ServiceContext.ContentService.GetPagedChildren(content.Id, 0, int.MaxValue, out var total);
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -846,22 +846,18 @@ namespace Umbraco.Tests.Integration
|
||||
|
||||
// force:true => all nodes are republished, refreshing all nodes - but only with changes - published w/out changes are not repub
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1.Id}.u+p", _events[i++].ToString());
|
||||
|
||||
//Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[0].Id}.p+p", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[1].Id}.u+p", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[2].Id}.p+p", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[3].Id}.u+p", _events[i++].ToString());
|
||||
|
||||
// remember: ordered by level, sortOrder
|
||||
//Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content2C[0].Id}.p+p", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content3C[0].Id}.u+p", _events[i++].ToString());
|
||||
//Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content4C[0].Id}.p+p", _events[i++].ToString());
|
||||
//Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content5C[0].Id}.p+p", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content2C[1].Id}.u+p", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[1].Id}.u+p", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content3C[0].Id}.u+p", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content3C[1].Id}.u+p", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[2].Id}.p+p", _events[i++].ToString());
|
||||
//Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content4C[0].Id}.p+p", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content4C[1].Id}.u+p", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[3].Id}.u+p", _events[i++].ToString());
|
||||
//Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content5C[0].Id}.p+p", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content5C[1].Id}.u+p", _events[i++].ToString());
|
||||
|
||||
Assert.AreEqual($"{m:000}: ContentCacheRefresher/RefreshBranch/{content1.Id}", _events[i++].ToString()); // repub content1
|
||||
}
|
||||
|
||||
@@ -1073,17 +1069,18 @@ namespace Umbraco.Tests.Integration
|
||||
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1.Id}.p=m", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[0].Id}.p=m", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[1].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[2].Id}.p=m", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[3].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content2C[0].Id}.p=m", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content3C[0].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content4C[0].Id}.p=m", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content5C[0].Id}.p=m", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content2C[1].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[1].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content3C[0].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content3C[1].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[2].Id}.p=m", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content4C[0].Id}.p=m", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content4C[1].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[3].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content5C[0].Id}.p=m", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m:000}: ContentRepository/Refresh/{content5C[1].Id}.u=u", _events[i++].ToString());
|
||||
|
||||
m++;
|
||||
Assert.AreEqual($"{m:000}: ContentCacheRefresher/RefreshBranch/{content1.Id}", _events[i].ToString());
|
||||
}
|
||||
@@ -1706,16 +1703,16 @@ namespace Umbraco.Tests.Integration
|
||||
var content5C = Children(content1C[3]).ToArray();
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1.Id}.p=m", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[0].Id}.p=m", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[1].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[2].Id}.p=m", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[3].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content2C[0].Id}.p=m", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content3C[0].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content4C[0].Id}.p=m", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content5C[0].Id}.p=m", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content2C[1].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[1].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content3C[0].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content3C[1].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[2].Id}.p=m", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content4C[0].Id}.p=m", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content4C[1].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[3].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content5C[0].Id}.p=m", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m:000}: ContentRepository/Refresh/{content5C[1].Id}.u=u", _events[i++].ToString());
|
||||
m++;
|
||||
Assert.AreEqual($"{m:000}: ContentCacheRefresher/RefreshBranch/{content1.Id}", _events[i++].ToString());
|
||||
@@ -1759,16 +1756,16 @@ namespace Umbraco.Tests.Integration
|
||||
var content5C = Children(content1C[3]).ToArray();
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1.Id}.p=p", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[0].Id}.p=p", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[1].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[2].Id}.p=p", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[3].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content2C[0].Id}.p=p", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content3C[0].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content4C[0].Id}.p=p", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content5C[0].Id}.p=m", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content2C[1].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[1].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content3C[0].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content3C[1].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[2].Id}.p=p", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content4C[0].Id}.p=p", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content4C[1].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[3].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content5C[0].Id}.p=m", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m:000}: ContentRepository/Refresh/{content5C[1].Id}.u=u", _events[i++].ToString());
|
||||
m++;
|
||||
Assert.AreEqual($"{m:000}: ContentCacheRefresher/RefreshBranch/{content1.Id}", _events[i++].ToString());
|
||||
@@ -1816,16 +1813,16 @@ namespace Umbraco.Tests.Integration
|
||||
var content5C = Children(content1C[3]).ToArray();
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1.Id}.p=m", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[0].Id}.p=m", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[1].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[2].Id}.p=m", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[3].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content2C[0].Id}.p=m", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content3C[0].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content4C[0].Id}.p=m", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content5C[0].Id}.p=m", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content2C[1].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[1].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content3C[0].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content3C[1].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[2].Id}.p=m", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content4C[0].Id}.p=m", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content4C[1].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[3].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content5C[0].Id}.p=m", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m:000}: ContentRepository/Refresh/{content5C[1].Id}.u=u", _events[i++].ToString());
|
||||
m++;
|
||||
Assert.AreEqual($"{m:000}: ContentCacheRefresher/RefreshBranch/{content1.Id}", _events[i++].ToString());
|
||||
@@ -1871,16 +1868,16 @@ namespace Umbraco.Tests.Integration
|
||||
var content5C = Children(content1C[3]).ToArray();
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1.Id}.p=p", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[0].Id}.p=p", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[1].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[2].Id}.p=p", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[3].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content2C[0].Id}.p=p", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content3C[0].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content4C[0].Id}.p=p", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content5C[0].Id}.p=m", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content2C[1].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[1].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content3C[0].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content3C[1].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[2].Id}.p=p", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content4C[0].Id}.p=p", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content4C[1].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[3].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content5C[0].Id}.p=m", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m:000}: ContentRepository/Refresh/{content5C[1].Id}.u=u", _events[i++].ToString());
|
||||
m++;
|
||||
Assert.AreEqual($"{m:000}: ContentCacheRefresher/RefreshBranch/{content1.Id}", _events[i++].ToString());
|
||||
@@ -1925,16 +1922,16 @@ namespace Umbraco.Tests.Integration
|
||||
var content5C = Children(content1C[3]).ToArray();
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1.Id}.p=p", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[0].Id}.p=p", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[1].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[2].Id}.p=p", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[3].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content2C[0].Id}.p=p", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content3C[0].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content4C[0].Id}.p=p", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content5C[0].Id}.p=m", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content2C[1].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[1].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content3C[0].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content3C[1].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[2].Id}.p=p", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content4C[0].Id}.p=p", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content4C[1].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[3].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content5C[0].Id}.p=m", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m:000}: ContentRepository/Refresh/{content5C[1].Id}.u=u", _events[i++].ToString());
|
||||
m++;
|
||||
Assert.AreEqual($"{m:000}: ContentCacheRefresher/RefreshBranch/{content1.Id}", _events[i++].ToString());
|
||||
@@ -1984,16 +1981,16 @@ namespace Umbraco.Tests.Integration
|
||||
var content5C = Children(content1C[3]).ToArray();
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1.Id}.p=p", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[0].Id}.p=p", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[1].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[2].Id}.p=p", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[3].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content2C[0].Id}.p=p", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content3C[0].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content4C[0].Id}.p=p", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content5C[0].Id}.p=m", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content2C[1].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[1].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content3C[0].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content3C[1].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[2].Id}.p=p", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content4C[0].Id}.p=p", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content4C[1].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content1C[3].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{content5C[0].Id}.p=m", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m:000}: ContentRepository/Refresh/{content5C[1].Id}.u=u", _events[i++].ToString());
|
||||
m++;
|
||||
Assert.AreEqual($"{m:000}: ContentCacheRefresher/RefreshBranch/{content1.Id}", _events[i++].ToString());
|
||||
@@ -2098,16 +2095,16 @@ namespace Umbraco.Tests.Integration
|
||||
var m = 0;
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{copy.Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{copyC[0].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{copyC[1].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{copyC[2].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{copyC[3].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{copy2C[0].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{copy3C[0].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{copy4C[0].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{copy5C[0].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{copy2C[1].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{copyC[1].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{copy3C[0].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{copy3C[1].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{copyC[2].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{copy4C[0].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{copy4C[1].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{copyC[3].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m++:000}: ContentRepository/Refresh/{copy5C[0].Id}.u=u", _events[i++].ToString());
|
||||
Assert.AreEqual($"{m:000}: ContentRepository/Refresh/{copy5C[1].Id}.u=u", _events[i++].ToString());
|
||||
m++;
|
||||
Assert.AreEqual($"{m:000}: ContentCacheRefresher/RefreshBranch/{copy.Id}", _events[i].ToString());
|
||||
|
||||
@@ -125,10 +125,6 @@ namespace Umbraco.Tests.Persistence.NPocoTests
|
||||
|
||||
contentService.GetByLevel(2);
|
||||
|
||||
contentService.GetChildren(id1);
|
||||
|
||||
contentService.GetDescendants(id2);
|
||||
|
||||
contentService.GetVersions(id3);
|
||||
|
||||
contentService.GetRootContent();
|
||||
@@ -137,8 +133,6 @@ namespace Umbraco.Tests.Persistence.NPocoTests
|
||||
|
||||
contentService.GetContentForRelease();
|
||||
|
||||
contentService.GetContentInRecycleBin();
|
||||
|
||||
((ContentService)contentService).GetPublishedDescendants(new Content("Test", -1, new ContentType(-1))
|
||||
{
|
||||
Id = id1,
|
||||
|
||||
@@ -105,7 +105,7 @@ namespace Umbraco.Tests.Services
|
||||
total.AddRange(ServiceContext.ContentService.GetRootContent());
|
||||
foreach (var content in total.ToArray())
|
||||
{
|
||||
total.AddRange(ServiceContext.ContentService.GetDescendants(content));
|
||||
total.AddRange(ServiceContext.ContentService.GetPagedDescendants(content.Id, 0, int.MaxValue, out var _));
|
||||
}
|
||||
TestProfiler.Disable();
|
||||
Current.Logger.Info<ContentServicePerformanceTest>("Returned " + total.Count + " items");
|
||||
|
||||
@@ -35,7 +35,10 @@ namespace Umbraco.Tests.Services
|
||||
/// as well as configuration.
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
[UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest, PublishedRepositoryEvents = true, WithApplication = true)]
|
||||
[UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest,
|
||||
PublishedRepositoryEvents = true,
|
||||
WithApplication = true,
|
||||
Logger = UmbracoTestOptions.Logger.Console)]
|
||||
public class ContentServiceTests : TestWithSomeContentBase
|
||||
{
|
||||
//TODO Add test to verify there is only ONE newest document/content in {Constants.DatabaseSchema.Tables.Document} table after updating.
|
||||
@@ -1038,37 +1041,6 @@ namespace Umbraco.Tests.Services
|
||||
Assert.That(contents.Count(), Is.GreaterThanOrEqualTo(2));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Get_Children_Of_Content_Id()
|
||||
{
|
||||
// Arrange
|
||||
var contentService = ServiceContext.ContentService;
|
||||
|
||||
// Act
|
||||
var contents = contentService.GetChildren(NodeDto.NodeIdSeed + 2).ToList();
|
||||
|
||||
// Assert
|
||||
Assert.That(contents, Is.Not.Null);
|
||||
Assert.That(contents.Any(), Is.True);
|
||||
Assert.That(contents.Count(), Is.GreaterThanOrEqualTo(2));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Get_Descendents_Of_Content()
|
||||
{
|
||||
// Arrange
|
||||
var contentService = ServiceContext.ContentService;
|
||||
var hierarchy = CreateContentHierarchy();
|
||||
contentService.Save(hierarchy, 0);
|
||||
|
||||
// Act
|
||||
var contents = contentService.GetDescendants(NodeDto.NodeIdSeed + 2).ToList();
|
||||
|
||||
// Assert
|
||||
Assert.That(contents, Is.Not.Null);
|
||||
Assert.That(contents.Any(), Is.True);
|
||||
Assert.That(contents.Count(), Is.EqualTo(52));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Get_All_Versions_Of_Content()
|
||||
@@ -1200,7 +1172,7 @@ namespace Umbraco.Tests.Services
|
||||
var contentService = ServiceContext.ContentService;
|
||||
|
||||
// Act
|
||||
var contents = contentService.GetContentInRecycleBin().ToList();
|
||||
var contents = contentService.GetPagedContentInRecycleBin(0, int.MaxValue, out var _).ToList();
|
||||
|
||||
// Assert
|
||||
Assert.That(contents, Is.Not.Null);
|
||||
@@ -1240,7 +1212,7 @@ namespace Umbraco.Tests.Services
|
||||
{
|
||||
// Arrange
|
||||
|
||||
var langUk = new Language("en-UK") { IsDefault = true };
|
||||
var langUk = new Language("en-GB") { IsDefault = true };
|
||||
var langFr = new Language("fr-FR");
|
||||
|
||||
ServiceContext.LocalizationService.Save(langFr);
|
||||
@@ -1476,8 +1448,16 @@ namespace Umbraco.Tests.Services
|
||||
var parent = contentService.GetById(parentId);
|
||||
|
||||
Console.WriteLine(" " + parent.Id);
|
||||
foreach (var x in contentService.GetDescendants(parent))
|
||||
Console.WriteLine(" ".Substring(0, x.Level) + x.Id);
|
||||
const int pageSize = 500;
|
||||
var page = 0;
|
||||
var total = long.MaxValue;
|
||||
while(page * pageSize < total)
|
||||
{
|
||||
var descendants = contentService.GetPagedDescendants(parent.Id, page++, pageSize, out total);
|
||||
foreach (var x in descendants)
|
||||
Console.WriteLine(" ".Substring(0, x.Level) + x.Id);
|
||||
}
|
||||
|
||||
Console.WriteLine();
|
||||
|
||||
// publish parent & its branch
|
||||
@@ -1492,7 +1472,7 @@ namespace Umbraco.Tests.Services
|
||||
Assert.IsTrue(parentPublished.All(x => x.Success));
|
||||
Assert.IsTrue(parent.Published);
|
||||
|
||||
var children = contentService.GetChildren(parentId);
|
||||
var children = contentService.GetPagedChildren(parentId, 0, 500, out var totalChildren); //we only want the first so page size, etc.. is abitrary
|
||||
|
||||
// children are published including ... that was released 5 mins ago
|
||||
Assert.IsTrue(children.First(x => x.Id == NodeDto.NodeIdSeed + 4).Published);
|
||||
@@ -1738,7 +1718,7 @@ namespace Umbraco.Tests.Services
|
||||
// Act
|
||||
contentService.DeleteOfType(contentType.Id);
|
||||
var rootContent = contentService.GetRootContent();
|
||||
var contents = contentService.GetByType(contentType.Id);
|
||||
var contents = contentService.GetPagedOfType(contentType.Id, 0, int.MaxValue, out var _, null);
|
||||
|
||||
// Assert
|
||||
Assert.That(rootContent.Any(), Is.False);
|
||||
@@ -1785,7 +1765,13 @@ namespace Umbraco.Tests.Services
|
||||
contentService.Save(subsubpage, 0);
|
||||
|
||||
var content = contentService.GetById(NodeDto.NodeIdSeed + 2);
|
||||
var descendants = contentService.GetDescendants(content).ToList();
|
||||
const int pageSize = 500;
|
||||
var page = 0;
|
||||
var total = long.MaxValue;
|
||||
var descendants = new List<IContent>();
|
||||
while(page * pageSize < total)
|
||||
descendants.AddRange(contentService.GetPagedDescendants(content.Id, page++, pageSize, out total));
|
||||
|
||||
Assert.AreNotEqual(-20, content.ParentId);
|
||||
Assert.IsFalse(content.Trashed);
|
||||
Assert.AreEqual(3, descendants.Count);
|
||||
@@ -1793,7 +1779,11 @@ namespace Umbraco.Tests.Services
|
||||
Assert.IsFalse(descendants.Any(x => x.Trashed));
|
||||
|
||||
contentService.MoveToRecycleBin(content, 0);
|
||||
descendants = contentService.GetDescendants(content).ToList();
|
||||
|
||||
descendants.Clear();
|
||||
page = 0;
|
||||
while (page * pageSize < total)
|
||||
descendants.AddRange(contentService.GetPagedDescendants(content.Id, page++, pageSize, out total));
|
||||
|
||||
Assert.AreEqual(-20, content.ParentId);
|
||||
Assert.IsTrue(content.Trashed);
|
||||
@@ -1802,7 +1792,7 @@ namespace Umbraco.Tests.Services
|
||||
Assert.True(descendants.All(x => x.Trashed));
|
||||
|
||||
contentService.EmptyRecycleBin();
|
||||
var trashed = contentService.GetContentInRecycleBin();
|
||||
var trashed = contentService.GetPagedContentInRecycleBin(0, int.MaxValue, out var _).ToList();
|
||||
Assert.IsEmpty(trashed);
|
||||
}
|
||||
|
||||
@@ -1814,7 +1804,7 @@ namespace Umbraco.Tests.Services
|
||||
|
||||
// Act
|
||||
contentService.EmptyRecycleBin();
|
||||
var contents = contentService.GetContentInRecycleBin();
|
||||
var contents = contentService.GetPagedContentInRecycleBin(0, int.MaxValue, out var _).ToList();
|
||||
|
||||
// Assert
|
||||
Assert.That(contents.Any(), Is.False);
|
||||
@@ -1883,8 +1873,13 @@ namespace Umbraco.Tests.Services
|
||||
ServiceContext.ContentService.Save(childPage3);
|
||||
|
||||
//Verify that the children have the inherited permissions
|
||||
var descendants = ServiceContext.ContentService.GetDescendants(parentPage).ToArray();
|
||||
Assert.AreEqual(3, descendants.Length);
|
||||
var descendants = new List<IContent>();
|
||||
const int pageSize = 500;
|
||||
var page = 0;
|
||||
var total = long.MaxValue;
|
||||
while(page * pageSize < total)
|
||||
descendants.AddRange(ServiceContext.ContentService.GetPagedDescendants(parentPage.Id, page++, pageSize, out total));
|
||||
Assert.AreEqual(3, descendants.Count);
|
||||
|
||||
foreach (var descendant in descendants)
|
||||
{
|
||||
@@ -1902,8 +1897,11 @@ namespace Umbraco.Tests.Services
|
||||
//Now copy, what should happen is the child pages will now have permissions inherited from the new parent
|
||||
var copy = ServiceContext.ContentService.Copy(childPage1, parentPage2.Id, false, true);
|
||||
|
||||
descendants = ServiceContext.ContentService.GetDescendants(parentPage2).ToArray();
|
||||
Assert.AreEqual(3, descendants.Length);
|
||||
descendants.Clear();
|
||||
page = 0;
|
||||
while (page * pageSize < total)
|
||||
descendants.AddRange(ServiceContext.ContentService.GetPagedDescendants(parentPage2.Id, page++, pageSize, out total));
|
||||
Assert.AreEqual(3, descendants.Count);
|
||||
|
||||
foreach (var descendant in descendants)
|
||||
{
|
||||
@@ -1984,7 +1982,7 @@ namespace Umbraco.Tests.Services
|
||||
// Act
|
||||
ServiceContext.ContentService.MoveToRecycleBin(content1);
|
||||
ServiceContext.ContentService.EmptyRecycleBin();
|
||||
var contents = ServiceContext.ContentService.GetContentInRecycleBin();
|
||||
var contents = ServiceContext.ContentService.GetPagedContentInRecycleBin(0, int.MaxValue, out var _).ToList();
|
||||
|
||||
// Assert
|
||||
Assert.That(contents.Any(), Is.False);
|
||||
@@ -2035,7 +2033,7 @@ namespace Umbraco.Tests.Services
|
||||
var contentService = ServiceContext.ContentService;
|
||||
var temp = contentService.GetById(NodeDto.NodeIdSeed + 2);
|
||||
Assert.AreEqual("Home", temp.Name);
|
||||
Assert.AreEqual(2, temp.Children(contentService).Count());
|
||||
Assert.AreEqual(2, contentService.CountChildren(temp.Id));
|
||||
|
||||
// Act
|
||||
var copy = contentService.Copy(temp, temp.ParentId, false, true, 0);
|
||||
@@ -2045,10 +2043,10 @@ namespace Umbraco.Tests.Services
|
||||
Assert.That(copy, Is.Not.Null);
|
||||
Assert.That(copy.Id, Is.Not.EqualTo(content.Id));
|
||||
Assert.AreNotSame(content, copy);
|
||||
Assert.AreEqual(2, copy.Children(contentService).Count());
|
||||
Assert.AreEqual(2, contentService.CountChildren(copy.Id));
|
||||
|
||||
var child = contentService.GetById(NodeDto.NodeIdSeed + 3);
|
||||
var childCopy = copy.Children(contentService).First();
|
||||
var childCopy = contentService.GetPagedChildren(copy.Id, 0, 500, out var total).First();
|
||||
Assert.AreEqual(childCopy.Name, child.Name);
|
||||
Assert.AreNotEqual(childCopy.Id, child.Id);
|
||||
Assert.AreNotEqual(childCopy.Key, child.Key);
|
||||
@@ -2061,7 +2059,7 @@ namespace Umbraco.Tests.Services
|
||||
var contentService = ServiceContext.ContentService;
|
||||
var temp = contentService.GetById(NodeDto.NodeIdSeed + 2);
|
||||
Assert.AreEqual("Home", temp.Name);
|
||||
Assert.AreEqual(2, temp.Children(contentService).Count());
|
||||
Assert.AreEqual(2, contentService.CountChildren(temp.Id));
|
||||
|
||||
// Act
|
||||
var copy = contentService.Copy(temp, temp.ParentId, false, false, 0);
|
||||
@@ -2071,7 +2069,7 @@ namespace Umbraco.Tests.Services
|
||||
Assert.That(copy, Is.Not.Null);
|
||||
Assert.That(copy.Id, Is.Not.EqualTo(content.Id));
|
||||
Assert.AreNotSame(content, copy);
|
||||
Assert.AreEqual(0, copy.Children(contentService).Count());
|
||||
Assert.AreEqual(0, contentService.CountChildren(copy.Id));
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -2780,7 +2778,7 @@ namespace Umbraco.Tests.Services
|
||||
{
|
||||
var languageService = ServiceContext.LocalizationService;
|
||||
|
||||
var langUk = new Language("en-UK") { IsDefault = true };
|
||||
var langUk = new Language("en-GB") { IsDefault = true };
|
||||
var langFr = new Language("fr-FR");
|
||||
|
||||
languageService.Save(langFr);
|
||||
@@ -2815,7 +2813,7 @@ namespace Umbraco.Tests.Services
|
||||
{
|
||||
var languageService = ServiceContext.LocalizationService;
|
||||
|
||||
var langUk = new Language("en-UK") { IsDefault = true };
|
||||
var langUk = new Language("en-GB") { IsDefault = true };
|
||||
var langFr = new Language("fr-FR");
|
||||
|
||||
languageService.Save(langFr);
|
||||
@@ -2852,7 +2850,7 @@ namespace Umbraco.Tests.Services
|
||||
{
|
||||
var languageService = ServiceContext.LocalizationService;
|
||||
|
||||
var langUk = new Language("en-UK") { IsDefault = true };
|
||||
var langUk = new Language("en-GB") { IsDefault = true };
|
||||
var langFr = new Language("fr-FR");
|
||||
var langDa = new Language("da-DK");
|
||||
|
||||
@@ -2944,7 +2942,7 @@ namespace Umbraco.Tests.Services
|
||||
private void WriteList(List<IContent> list)
|
||||
{
|
||||
foreach (var content in list)
|
||||
Console.WriteLine("[{0}] {1} {2} {3} {4}", content.Id, content.Name, content.GetCultureName("en-UK"), content.GetCultureName("fr-FR"), content.GetCultureName("da-DK"));
|
||||
Console.WriteLine("[{0}] {1} {2} {3} {4}", content.Id, content.Name, content.GetCultureName("en-GB"), content.GetCultureName("fr-FR"), content.GetCultureName("da-DK"));
|
||||
Console.WriteLine("-");
|
||||
}
|
||||
|
||||
@@ -2956,7 +2954,7 @@ namespace Umbraco.Tests.Services
|
||||
//var langFr = new Language("fr-FR") { IsDefaultVariantLanguage = true };
|
||||
var langXx = new Language("pt-PT") { IsDefault = true };
|
||||
var langFr = new Language("fr-FR");
|
||||
var langUk = new Language("en-UK");
|
||||
var langUk = new Language("en-GB");
|
||||
var langDe = new Language("de-DE");
|
||||
|
||||
languageService.Save(langFr);
|
||||
|
||||
@@ -69,11 +69,15 @@ namespace Umbraco.Tests.Services
|
||||
}
|
||||
|
||||
long total;
|
||||
var result = ServiceContext.MediaService.GetPagedChildren(-1, 0, 11, out total, "SortOrder", Direction.Ascending, true, null, new[] { mediaType1.Id, mediaType2.Id });
|
||||
var result = ServiceContext.MediaService.GetPagedChildren(-1, 0, 11, out total,
|
||||
SqlContext.Query<IMedia>().Where(x => new[] { mediaType1.Id, mediaType2.Id }.Contains(x.ContentTypeId)),
|
||||
Ordering.By("SortOrder", Direction.Ascending));
|
||||
Assert.AreEqual(11, result.Count());
|
||||
Assert.AreEqual(20, total);
|
||||
|
||||
result = ServiceContext.MediaService.GetPagedChildren(-1, 1, 11, out total, "SortOrder", Direction.Ascending, true, null, new[] { mediaType1.Id, mediaType2.Id });
|
||||
result = ServiceContext.MediaService.GetPagedChildren(-1, 1, 11, out total,
|
||||
SqlContext.Query<IMedia>().Where(x => new[] { mediaType1.Id, mediaType2.Id }.Contains(x.ContentTypeId)),
|
||||
Ordering.By("SortOrder", Direction.Ascending));
|
||||
Assert.AreEqual(9, result.Count());
|
||||
Assert.AreEqual(20, total);
|
||||
}
|
||||
|
||||
@@ -108,40 +108,6 @@ namespace Umbraco.Tests.Services
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Get_All_Published_Content_Of_Type()
|
||||
{
|
||||
var result = PrimeDbWithLotsOfContent();
|
||||
var contentSvc = (ContentService)ServiceContext.ContentService;
|
||||
|
||||
var countOfPublished = result.Count(x => x.Published);
|
||||
var contentTypeId = result.First().ContentTypeId;
|
||||
|
||||
var proflog = GetTestProfilingLogger();
|
||||
using (proflog.DebugDuration<PerformanceTests>("Getting published content of type normally"))
|
||||
{
|
||||
//do this 10x!
|
||||
for (var i = 0; i < 10; i++)
|
||||
{
|
||||
|
||||
//get all content items that are published of this type
|
||||
var published = contentSvc.GetByType(contentTypeId).Where(content => content.Published);
|
||||
Assert.AreEqual(countOfPublished, published.Count(x => x.ContentTypeId == contentTypeId));
|
||||
}
|
||||
}
|
||||
|
||||
using (proflog.DebugDuration<PerformanceTests>("Getting published content of type optimized"))
|
||||
{
|
||||
|
||||
//do this 10x!
|
||||
for (var i = 0; i < 10; i++)
|
||||
{
|
||||
//get all content items that are published of this type
|
||||
var published = contentSvc.GetPublishedContentOfContentType(contentTypeId);
|
||||
Assert.AreEqual(countOfPublished, published.Count(x => x.ContentTypeId == contentTypeId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Truncate_Insert_Vs_Update_Insert()
|
||||
|
||||
@@ -14,7 +14,8 @@ using Umbraco.Core.Persistence.Querying;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Services.Implement;
|
||||
using Umbraco.Tests.Testing;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
using Umbraco.Web.Actions;
|
||||
|
||||
|
||||
namespace Umbraco.Tests.Services
|
||||
{
|
||||
@@ -70,12 +71,12 @@ namespace Umbraco.Tests.Services
|
||||
MockedContent.CreateSimpleContent(contentType)
|
||||
};
|
||||
ServiceContext.ContentService.Save(content);
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionBrowse.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionDelete.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionMove.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[1], ActionBrowse.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[1], ActionDelete.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[2], ActionBrowse.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionBrowse.ActionLetter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionDelete.ActionLetter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionMove.ActionLetter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[1], ActionBrowse.ActionLetter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[1], ActionDelete.ActionLetter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[2], ActionBrowse.ActionLetter, new int[] { userGroup.Id });
|
||||
|
||||
// Act
|
||||
var permissions = userService.GetPermissions(user, content[0].Id, content[1].Id, content[2].Id).ToArray();
|
||||
@@ -103,12 +104,12 @@ namespace Umbraco.Tests.Services
|
||||
MockedContent.CreateSimpleContent(contentType)
|
||||
};
|
||||
ServiceContext.ContentService.Save(content);
|
||||
ServiceContext.ContentService.SetPermission(content.ElementAt(0), ActionBrowse.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content.ElementAt(0), ActionDelete.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content.ElementAt(0), ActionMove.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content.ElementAt(1), ActionBrowse.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content.ElementAt(1), ActionDelete.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content.ElementAt(2), ActionBrowse.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content.ElementAt(0), ActionBrowse.ActionLetter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content.ElementAt(0), ActionDelete.ActionLetter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content.ElementAt(0), ActionMove.ActionLetter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content.ElementAt(1), ActionBrowse.ActionLetter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content.ElementAt(1), ActionDelete.ActionLetter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content.ElementAt(2), ActionBrowse.ActionLetter, new int[] { userGroup.Id });
|
||||
|
||||
// Act
|
||||
var permissions = userService.GetPermissions(userGroup, false, content[0].Id, content[1].Id, content[2].Id).ToArray();
|
||||
@@ -136,11 +137,11 @@ namespace Umbraco.Tests.Services
|
||||
MockedContent.CreateSimpleContent(contentType)
|
||||
};
|
||||
ServiceContext.ContentService.Save(content);
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionBrowse.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionDelete.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionMove.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[1], ActionBrowse.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[1], ActionDelete.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionBrowse.ActionLetter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionDelete.ActionLetter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionMove.ActionLetter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[1], ActionBrowse.ActionLetter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[1], ActionDelete.ActionLetter, new int[] { userGroup.Id });
|
||||
|
||||
// Act
|
||||
var permissions = userService.GetPermissions(userGroup, true, content[0].Id, content[1].Id, content[2].Id)
|
||||
@@ -180,12 +181,12 @@ namespace Umbraco.Tests.Services
|
||||
};
|
||||
ServiceContext.ContentService.Save(content);
|
||||
//assign permissions - we aren't assigning anything explicit for group3 and nothing explicit for content[2] /w group2
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionBrowse.Instance.Letter, new int[] { userGroup1.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionDelete.Instance.Letter, new int[] { userGroup1.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionMove.Instance.Letter, new int[] { userGroup2.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[1], ActionBrowse.Instance.Letter, new int[] { userGroup1.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[1], ActionDelete.Instance.Letter, new int[] { userGroup2.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[2], ActionDelete.Instance.Letter, new int[] { userGroup1.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionBrowse.ActionLetter, new int[] { userGroup1.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionDelete.ActionLetter, new int[] { userGroup1.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionMove.ActionLetter, new int[] { userGroup2.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[1], ActionBrowse.ActionLetter, new int[] { userGroup1.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[1], ActionDelete.ActionLetter, new int[] { userGroup2.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[2], ActionDelete.ActionLetter, new int[] { userGroup1.Id });
|
||||
|
||||
// Act
|
||||
//we don't pass in any nodes so it will return all of them
|
||||
@@ -249,12 +250,12 @@ namespace Umbraco.Tests.Services
|
||||
MockedContent.CreateSimpleContent(contentType)
|
||||
};
|
||||
ServiceContext.ContentService.Save(content);
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionBrowse.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionDelete.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionMove.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[1], ActionBrowse.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[1], ActionDelete.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[2], ActionDelete.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionBrowse.ActionLetter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionDelete.ActionLetter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[0], ActionMove.ActionLetter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[1], ActionBrowse.ActionLetter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[1], ActionDelete.ActionLetter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(content[2], ActionDelete.ActionLetter, new int[] { userGroup.Id });
|
||||
|
||||
// Act
|
||||
//we don't pass in any nodes so it will return all of them
|
||||
@@ -412,11 +413,11 @@ namespace Umbraco.Tests.Services
|
||||
var child2 = MockedContent.CreateSimpleContent(contentType, "child2", child1);
|
||||
ServiceContext.ContentService.Save(child2);
|
||||
|
||||
ServiceContext.ContentService.SetPermission(parent, ActionBrowse.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(parent, ActionDelete.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(parent, ActionMove.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(parent, ActionBrowse.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(parent, ActionDelete.Instance.Letter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(parent, ActionBrowse.ActionLetter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(parent, ActionDelete.ActionLetter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(parent, ActionMove.ActionLetter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(parent, ActionBrowse.ActionLetter, new int[] { userGroup.Id });
|
||||
ServiceContext.ContentService.SetPermission(parent, ActionDelete.ActionLetter, new int[] { userGroup.Id });
|
||||
|
||||
// Act
|
||||
var permissions = userService.GetPermissionsForPath(userGroup, child2.Path);
|
||||
|
||||
@@ -36,9 +36,10 @@ using Umbraco.Web;
|
||||
using Umbraco.Web.Services;
|
||||
using Umbraco.Examine;
|
||||
using Umbraco.Tests.Testing.Objects.Accessors;
|
||||
using Umbraco.Web.Actions;
|
||||
using Umbraco.Web.Composing.CompositionRoots;
|
||||
using Umbraco.Web.ContentApps;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
using Current = Umbraco.Core.Composing.Current;
|
||||
using Umbraco.Web.Routing;
|
||||
|
||||
@@ -205,9 +206,7 @@ namespace Umbraco.Tests.Testing
|
||||
Container.RegisterSingleton(f => runtimeStateMock.Object);
|
||||
|
||||
// ah...
|
||||
Container.RegisterCollectionBuilder<ActionCollectionBuilder>()
|
||||
.SetProducer(Enumerable.Empty<Type>);
|
||||
|
||||
Container.RegisterCollectionBuilder<ActionCollectionBuilder>();
|
||||
Container.RegisterCollectionBuilder<PropertyValueConverterCollectionBuilder>();
|
||||
Container.RegisterSingleton<IPublishedContentTypeFactory, PublishedContentTypeFactory>();
|
||||
|
||||
|
||||
@@ -406,7 +406,6 @@
|
||||
<Compile Include="Persistence\Repositories\StylesheetRepositoryTest.cs" />
|
||||
<Compile Include="PublishedContent\PublishedContentMoreTests.cs" />
|
||||
<Compile Include="Publishing\PublishingStrategyTests.cs" />
|
||||
<Compile Include="Composing\ActionCollectionTests.cs" />
|
||||
<Compile Include="TestHelpers\Entities\MockedMember.cs" />
|
||||
<Compile Include="TestHelpers\Entities\MockedUser.cs" />
|
||||
<Compile Include="TestHelpers\Stubs\TestProfiler.cs" />
|
||||
|
||||
@@ -71,11 +71,7 @@ namespace Umbraco.Tests.UmbracoExamine
|
||||
|
||||
contentService = Mock.Of<IContentService>(
|
||||
x => x.GetPagedDescendants(
|
||||
It.IsAny<int>(), It.IsAny<long>(), It.IsAny<int>(), out longTotalRecs, It.IsAny<string>(), It.IsAny<Direction>(), It.IsAny<string>())
|
||||
==
|
||||
allRecs
|
||||
&& x.GetPagedDescendants(
|
||||
It.IsAny<int>(), It.IsAny<long>(), It.IsAny<int>(), out longTotalRecs, It.IsAny<string>(), It.IsAny<Direction>(), It.IsAny<bool>(), It.IsAny<IQuery<IContent>>())
|
||||
It.IsAny<int>(), It.IsAny<long>(), It.IsAny<int>(), out longTotalRecs, It.IsAny<IQuery<IContent>>(), It.IsAny<Ordering>())
|
||||
==
|
||||
allRecs);
|
||||
}
|
||||
@@ -116,12 +112,7 @@ namespace Umbraco.Tests.UmbracoExamine
|
||||
|
||||
mediaServiceMock
|
||||
.Setup(x => x.GetPagedDescendants(
|
||||
It.IsAny<int>(), It.IsAny<long>(), It.IsAny<int>(), out totalRecs, It.IsAny<string>(), It.IsAny<Direction>(), It.IsAny<string>())
|
||||
).Returns(() => allRecs);
|
||||
|
||||
mediaServiceMock
|
||||
.Setup(x => x.GetPagedDescendants(
|
||||
It.IsAny<int>(), It.IsAny<long>(), It.IsAny<int>(), out totalRecs, It.IsAny<string>(), It.IsAny<Direction>(), It.IsAny<bool>(), It.IsAny<IQuery<IMedia>>())
|
||||
It.IsAny<int>(), It.IsAny<long>(), It.IsAny<int>(), out totalRecs, It.IsAny<IQuery<IMedia>>(), It.IsAny<Ordering>())
|
||||
).Returns(() => allRecs);
|
||||
|
||||
//mediaServiceMock.Setup(service => service.GetPagedXmlEntries(It.IsAny<string>(), It.IsAny<long>(), It.IsAny<int>(), out longTotalRecs))
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace Umbraco.Tests.UmbracoExamine
|
||||
.ToArray();
|
||||
var contentService = Mock.Of<IContentService>(
|
||||
x => x.GetPagedDescendants(
|
||||
It.IsAny<int>(), It.IsAny<long>(), It.IsAny<int>(), out totalRecs, It.IsAny<string>(), It.IsAny<Direction>(), It.IsAny<bool>(), It.IsAny<IQuery<IContent>>())
|
||||
It.IsAny<int>(), It.IsAny<long>(), It.IsAny<int>(), out totalRecs, It.IsAny<IQuery<IContent>>(), It.IsAny<Ordering>())
|
||||
==
|
||||
allRecs);
|
||||
|
||||
|
||||
@@ -22,20 +22,5 @@ namespace Umbraco.Tests.Web.Controllers
|
||||
};
|
||||
|
||||
|
||||
[TestCaseSource("TestLegacyJsActionPaths")]
|
||||
public void Separates_Legacy_JsActions_By_Block_Or_Url(object[] jsActions)
|
||||
{
|
||||
var jsBlocks =
|
||||
BackOfficeController.GetLegacyActionJsForActions(BackOfficeController.LegacyJsActionType.JsBlock,
|
||||
jsActions.Select(n => n.ToString()));
|
||||
|
||||
var jsUrls =
|
||||
BackOfficeController.GetLegacyActionJsForActions(BackOfficeController.LegacyJsActionType.JsUrl,
|
||||
jsActions.Select(n => n.ToString()));
|
||||
|
||||
Assert.That(jsBlocks.Count() == 4);
|
||||
Assert.That(jsUrls.Count() == 3);
|
||||
Assert.That(jsUrls.Last().StartsWith("~/") == false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ using Umbraco.Web;
|
||||
using Umbraco.Web.Editors;
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
using Umbraco.Web.PublishedCache;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
using Task = System.Threading.Tasks.Task;
|
||||
using Umbraco.Core.Dictionary;
|
||||
using Umbraco.Web.PropertyEditors;
|
||||
@@ -30,6 +30,7 @@ using System;
|
||||
using Umbraco.Web.WebApi;
|
||||
using Umbraco.Web.Trees;
|
||||
using System.Globalization;
|
||||
using Umbraco.Web.Actions;
|
||||
|
||||
namespace Umbraco.Tests.Web.Controllers
|
||||
{
|
||||
@@ -53,10 +54,10 @@ namespace Umbraco.Tests.Web.Controllers
|
||||
{
|
||||
new EntityPermission(0, 123, new[]
|
||||
{
|
||||
ActionBrowse.Instance.Letter.ToString(),
|
||||
ActionUpdate.Instance.Letter.ToString(),
|
||||
ActionPublish.Instance.Letter.ToString(),
|
||||
ActionNew.Instance.Letter.ToString()
|
||||
ActionBrowse.ActionLetter.ToString(),
|
||||
ActionUpdate.ActionLetter.ToString(),
|
||||
ActionPublish.ActionLetter.ToString(),
|
||||
ActionNew.ActionLetter.ToString()
|
||||
}),
|
||||
})));
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ Umbraco.Sys.registerNamespace("Umbraco.Application");
|
||||
* Returns the root angular scope
|
||||
*/
|
||||
function getRootScope() {
|
||||
return angular.element(document.getElementById("umbracoMainPageBody")).scope();
|
||||
return top.$("#umbracoMainPageBody").scope();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -46,7 +46,7 @@ Umbraco.Sys.registerNamespace("Umbraco.Application");
|
||||
* Returns the root angular injector
|
||||
*/
|
||||
function getRootInjector() {
|
||||
return angular.element(document.getElementById("umbracoMainPageBody")).injector();
|
||||
return top.$("#umbracoMainPageBody").injector();
|
||||
}
|
||||
|
||||
|
||||
@@ -327,7 +327,7 @@ Umbraco.Sys.registerNamespace("Umbraco.Application");
|
||||
//add the callback to the jquery data for the modal so we can call it on close to support the legacy way dialogs worked.
|
||||
dialog.element.data("modalCb", onCloseCallback);
|
||||
//add the close triggers
|
||||
if (angular.isArray(closeTriggers)) {
|
||||
if (top.angular.isArray(closeTriggers)) {
|
||||
for (var i = 0; i < closeTriggers.length; i++) {
|
||||
var e = dialog.find(closeTriggers[i]);
|
||||
if (e.length > 0) {
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
* </pre>
|
||||
**/
|
||||
|
||||
function contentResource($q, $http, umbDataFormatter, umbRequestHelper) {
|
||||
function contentResource($q, $http, $routeParams, umbDataFormatter, umbRequestHelper) {
|
||||
|
||||
/** internal method process the saving of data and post processing the result */
|
||||
function saveContentItem(content, action, files, restApiUrl, showNotifications) {
|
||||
@@ -607,7 +607,10 @@ function contentResource($q, $http, umbDataFormatter, umbRequestHelper) {
|
||||
else if (options.orderDirection === "desc") {
|
||||
options.orderDirection = "Descending";
|
||||
}
|
||||
|
||||
if (!options.cultureName) {
|
||||
// must send a culture to the content API to handle variant data correctly
|
||||
options.cultureName = $routeParams.mculture;
|
||||
}
|
||||
//converts the value to a js bool
|
||||
function toBool(v) {
|
||||
if (angular.isNumber(v)) {
|
||||
|
||||
@@ -402,21 +402,34 @@ function treeService($q, treeResource, iconHelper, notificationsService, eventsS
|
||||
throw "Cannot get a descendant node from a section container node without a treeAlias specified";
|
||||
}
|
||||
|
||||
//if it is a section container, we need to find the tree to be searched
|
||||
if (treeNode.isContainer) {
|
||||
var foundRoot = null;
|
||||
for (var c = 0; c < treeNode.children.length; c++) {
|
||||
if (this.getTreeAlias(treeNode.children[c]) === treeAlias) {
|
||||
foundRoot = treeNode.children[c];
|
||||
break;
|
||||
//the treeNode passed in could be a section container, or it could be a section group
|
||||
//in either case we need to go through the children until we can find the actual tree root with the treeAlias
|
||||
var self = this;
|
||||
function getTreeRoot(tn) {
|
||||
//if it is a section container, we need to find the tree to be searched
|
||||
if (tn.isContainer) {
|
||||
for (var c = 0; c < tn.children.length; c++) {
|
||||
if (tn.children[c].isContainer) {
|
||||
//recurse
|
||||
return getTreeRoot(tn.children[c]);
|
||||
}
|
||||
else if (self.getTreeAlias(tn.children[c]) === treeAlias) {
|
||||
return tn.children[c];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (!foundRoot) {
|
||||
throw "Could not find a tree in the current section with alias " + treeAlias;
|
||||
else {
|
||||
return tn;
|
||||
}
|
||||
treeNode = foundRoot;
|
||||
}
|
||||
|
||||
var foundRoot = getTreeRoot(treeNode);
|
||||
if (!foundRoot) {
|
||||
throw "Could not find a tree in the current section with alias " + treeAlias;
|
||||
}
|
||||
treeNode = foundRoot;
|
||||
|
||||
//check this node
|
||||
if (treeNode.id === id) {
|
||||
return treeNode;
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* @ngdoc controller
|
||||
* @name Umbraco.Dialogs.LegacyDeleteController
|
||||
* @function
|
||||
*
|
||||
* @description
|
||||
* The controller for deleting content
|
||||
*/
|
||||
function LegacyDeleteController($scope, legacyResource, treeService, navigationService) {
|
||||
|
||||
$scope.performDelete = function () {
|
||||
|
||||
//mark it for deletion (used in the UI)
|
||||
$scope.currentNode.loading = true;
|
||||
|
||||
legacyResource.deleteItem({
|
||||
nodeId: $scope.currentNode.id,
|
||||
nodeType: $scope.currentNode.nodeType,
|
||||
alias: $scope.currentNode.name
|
||||
}).then(function () {
|
||||
$scope.currentNode.loading = false;
|
||||
//TODO: Need to sync tree, etc...
|
||||
treeService.removeNode($scope.currentNode);
|
||||
navigationService.hideMenu();
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
$scope.cancel = function () {
|
||||
navigationService.hideDialog();
|
||||
};
|
||||
}
|
||||
|
||||
angular.module("umbraco").controller("Umbraco.Dialogs.LegacyDeleteController", LegacyDeleteController);
|
||||
@@ -0,0 +1,14 @@
|
||||
<div class="umb-dialog" ng-controller="Umbraco.Dialogs.LegacyDeleteController">
|
||||
<div class="umb-dialog-body" >
|
||||
|
||||
<div class="umb-pane">
|
||||
<p>
|
||||
<localize key="defaultdialogs_confirmdelete">Are you sure you want to delete</localize> <strong>{{currentNode.name}}</strong> ?
|
||||
</p>
|
||||
|
||||
|
||||
<umb-confirm on-confirm="performDelete" on-cancel="cancel">
|
||||
</umb-confirm>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -324,8 +324,6 @@
|
||||
<Content Include="Umbraco\Developer\RelationTypes\Images\Refresh.gif" />
|
||||
<Content Include="Umbraco\Developer\RelationTypes\NewRelationType.aspx" />
|
||||
<Content Include="Umbraco\Developer\RelationTypes\RelationTypesWebService.asmx" />
|
||||
<Content Include="Umbraco\Developer\RelationTypes\TreeMenu\ActionDeleteRelationType.js" />
|
||||
<Content Include="Umbraco\Developer\RelationTypes\TreeMenu\ActionNewRelationType.js" />
|
||||
<Content Include="Umbraco\Dialogs\ChangeDocType.aspx">
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Content>
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
function actionDeleteRelationType(relationTypeId, relationTypeName) {
|
||||
|
||||
if (confirm('Are you sure you want to delete "' + relationTypeName + '"?')) {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "developer/RelationTypes/RelationTypesWebService.asmx/DeleteRelationType",
|
||||
data: "{ 'relationTypeId' : '" + relationTypeId + "' }",
|
||||
contentType: "application/json; charset=utf-8",
|
||||
dataType: "json",
|
||||
success: function (data) {
|
||||
UmbClientMgr.mainTree().refreshTree('relationTypes');
|
||||
UmbClientMgr.appActions().openDashboard('developer');
|
||||
},
|
||||
error: function (data) { }
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
function actionNewRelationType() {
|
||||
UmbClientMgr.openModalWindow('developer/RelationTypes/NewRelationType.aspx', 'Create New RelationType', true, 400, 300, 0, 0);
|
||||
}
|
||||
@@ -113,7 +113,8 @@ namespace Umbraco.Web.UI.Umbraco.Dialogs
|
||||
|
||||
private IEnumerable<IContentType> RemoveInvalidByChildrenDocumentTypesFromAlternatives(IEnumerable<IContentType> documentTypes)
|
||||
{
|
||||
var docTypeIdsOfChildren = _content.Children(Services.ContentService)
|
||||
//fixme Should do proper paging here ... when this is refactored we will
|
||||
var docTypeIdsOfChildren = Services.ContentService.GetPagedChildren(_content.Id, 0, int.MaxValue, out var total)
|
||||
.Select(x => x.ContentType.Id)
|
||||
.Distinct()
|
||||
.ToList();
|
||||
|
||||
21
src/Umbraco.Web/Actions/ActionAssignDomain.cs
Normal file
21
src/Umbraco.Web/Actions/ActionAssignDomain.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Actions
|
||||
{
|
||||
/// <summary>
|
||||
/// This action is invoked when a domain is being assigned to a document
|
||||
/// </summary>
|
||||
public class ActionAssignDomain : IAction
|
||||
{
|
||||
public const char ActionLetter = 'I';
|
||||
|
||||
public char Letter => ActionLetter;
|
||||
public string Alias => "assignDomain";
|
||||
public string Category => Constants.Conventions.PermissionCategories.AdministrationCategory;
|
||||
public string Icon => "home";
|
||||
public bool ShowInNotifier => false;
|
||||
public bool CanBePermissionAssigned => true;
|
||||
}
|
||||
}
|
||||
27
src/Umbraco.Web/Actions/ActionBrowse.cs
Normal file
27
src/Umbraco.Web/Actions/ActionBrowse.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Actions
|
||||
{
|
||||
/// <summary>
|
||||
/// This action is used as a security constraint that grants a user the ability to view nodes in a tree
|
||||
/// that has permissions applied to it.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This action should not be invoked. It is used as the minimum required permission to view nodes in the content tree. By
|
||||
/// granting a user this permission, the user is able to see the node in the tree but not edit the document. This may be used by other trees
|
||||
/// that support permissions in the future.
|
||||
/// </remarks>
|
||||
public class ActionBrowse : IAction
|
||||
{
|
||||
public const char ActionLetter = 'F';
|
||||
|
||||
public char Letter => ActionLetter;
|
||||
public bool ShowInNotifier => false;
|
||||
public bool CanBePermissionAssigned => true;
|
||||
public string Icon => "";
|
||||
public string Alias => "browse";
|
||||
public string Category => Constants.Conventions.PermissionCategories.ContentCategory;
|
||||
}
|
||||
}
|
||||
20
src/Umbraco.Web/Actions/ActionChangeDocType.cs
Normal file
20
src/Umbraco.Web/Actions/ActionChangeDocType.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
using Umbraco.Web.UI.Pages;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Actions
|
||||
{
|
||||
/// <summary>
|
||||
/// This action is invoked when the document type of a piece of content is changed
|
||||
/// </summary>
|
||||
public class ActionChangeDocType : IAction
|
||||
{
|
||||
public char Letter => '7';
|
||||
public string Alias => "changeDocType";
|
||||
public string Category => Constants.Conventions.PermissionCategories.AdministrationCategory;
|
||||
public string Icon => "axis-rotation-2";
|
||||
public bool ShowInNotifier => true;
|
||||
public bool CanBePermissionAssigned => true;
|
||||
}
|
||||
}
|
||||
@@ -3,8 +3,10 @@ using System.Globalization;
|
||||
using System.Linq;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
|
||||
namespace Umbraco.Web._Legacy.Actions
|
||||
|
||||
namespace Umbraco.Web.Actions
|
||||
{
|
||||
public class ActionCollection : BuilderCollectionBase<IAction>
|
||||
{
|
||||
@@ -15,7 +17,7 @@ namespace Umbraco.Web._Legacy.Actions
|
||||
internal T GetAction<T>()
|
||||
where T : IAction
|
||||
{
|
||||
return this.OfType<T>().SingleOrDefault();
|
||||
return this.OfType<T>().FirstOrDefault();
|
||||
}
|
||||
|
||||
internal IEnumerable<IAction> GetByLetters(IEnumerable<string> letters)
|
||||
@@ -25,5 +27,15 @@ namespace Umbraco.Web._Legacy.Actions
|
||||
.WhereNotNull()
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
internal IReadOnlyList<IAction> FromEntityPermission(EntityPermission entityPermission)
|
||||
{
|
||||
return entityPermission.AssignedPermissions
|
||||
.Where(x => x.Length == 1)
|
||||
.Select(x => x.ToCharArray()[0])
|
||||
.SelectMany(c => this.Where(x => x.Letter == c))
|
||||
.Where(action => action != null)
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
31
src/Umbraco.Web/Actions/ActionCollectionBuilder.cs
Normal file
31
src/Umbraco.Web/Actions/ActionCollectionBuilder.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using LightInject;
|
||||
using Umbraco.Core.Composing;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Actions
|
||||
{
|
||||
internal class ActionCollectionBuilder : LazyCollectionBuilderBase<ActionCollectionBuilder, ActionCollection, IAction>
|
||||
{
|
||||
public ActionCollectionBuilder(IServiceContainer container)
|
||||
: base(container)
|
||||
{ }
|
||||
|
||||
protected override ActionCollectionBuilder This => this;
|
||||
|
||||
protected override IEnumerable<IAction> CreateItems(params object[] args)
|
||||
{
|
||||
var items = base.CreateItems(args).ToList();
|
||||
//validate the items, no actions should exist that do not either expose notifications or permissions
|
||||
var invalid = items.Where(x => !x.CanBePermissionAssigned && !x.ShowInNotifier).ToList();
|
||||
if (invalid.Count > 0)
|
||||
{
|
||||
throw new InvalidOperationException($"Invalid actions '{string.Join(", ", invalid.Select(x => x.Alias))}'. All {typeof(IAction)} implementations must be true for either {nameof(IAction.CanBePermissionAssigned)} or {nameof(IAction.ShowInNotifier)}");
|
||||
}
|
||||
return items;
|
||||
}
|
||||
}
|
||||
}
|
||||
20
src/Umbraco.Web/Actions/ActionCopy.cs
Normal file
20
src/Umbraco.Web/Actions/ActionCopy.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
using Umbraco.Web.UI.Pages;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Actions
|
||||
{
|
||||
/// <summary>
|
||||
/// This action is invoked when copying a document, media, member
|
||||
/// </summary>
|
||||
public class ActionCopy : IAction
|
||||
{
|
||||
public char Letter => 'O';
|
||||
public string Alias => "copy";
|
||||
public string Category => Constants.Conventions.PermissionCategories.StructureCategory;
|
||||
public string Icon => "documents";
|
||||
public bool ShowInNotifier => true;
|
||||
public bool CanBePermissionAssigned => true;
|
||||
}
|
||||
}
|
||||
16
src/Umbraco.Web/Actions/ActionCreateBlueprintFromContent.cs
Normal file
16
src/Umbraco.Web/Actions/ActionCreateBlueprintFromContent.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Actions
|
||||
{
|
||||
public class ActionCreateBlueprintFromContent : IAction
|
||||
{
|
||||
public char Letter => 'ï';
|
||||
public bool ShowInNotifier => false;
|
||||
public bool CanBePermissionAssigned => true;
|
||||
public string Icon => "blueprint";
|
||||
public string Alias => "createblueprint";
|
||||
public string Category => Constants.Conventions.PermissionCategories.ContentCategory;
|
||||
}
|
||||
}
|
||||
23
src/Umbraco.Web/Actions/ActionDelete.cs
Normal file
23
src/Umbraco.Web/Actions/ActionDelete.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
using Umbraco.Web.UI.Pages;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Actions
|
||||
{
|
||||
/// <summary>
|
||||
/// This action is invoked when a document, media, member is deleted
|
||||
/// </summary>
|
||||
public class ActionDelete : IAction
|
||||
{
|
||||
public const string ActionAlias = "delete";
|
||||
public const char ActionLetter = 'D';
|
||||
|
||||
public char Letter => ActionLetter;
|
||||
public string Alias => ActionAlias;
|
||||
public string Category => Constants.Conventions.PermissionCategories.ContentCategory;
|
||||
public string Icon => "delete";
|
||||
public bool ShowInNotifier => true;
|
||||
public bool CanBePermissionAssigned => true;
|
||||
}
|
||||
}
|
||||
22
src/Umbraco.Web/Actions/ActionMove.cs
Normal file
22
src/Umbraco.Web/Actions/ActionMove.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
using Umbraco.Web.UI.Pages;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Actions
|
||||
{
|
||||
/// <summary>
|
||||
/// This action is invoked upon creation of a document, media, member
|
||||
/// </summary>
|
||||
public class ActionMove : IAction
|
||||
{
|
||||
public const char ActionLetter = 'M';
|
||||
|
||||
public char Letter => ActionLetter;
|
||||
public string Alias => "move";
|
||||
public string Category => Constants.Conventions.PermissionCategories.StructureCategory;
|
||||
public string Icon => "enter";
|
||||
public bool ShowInNotifier => true;
|
||||
public bool CanBePermissionAssigned => true;
|
||||
}
|
||||
}
|
||||
23
src/Umbraco.Web/Actions/ActionNew.cs
Normal file
23
src/Umbraco.Web/Actions/ActionNew.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
using Umbraco.Web.UI.Pages;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Actions
|
||||
{
|
||||
/// <summary>
|
||||
/// This action is invoked upon creation of a document
|
||||
/// </summary>
|
||||
public class ActionNew : IAction
|
||||
{
|
||||
public const string ActionAlias = "create";
|
||||
public const char ActionLetter = 'C';
|
||||
|
||||
public char Letter => ActionLetter;
|
||||
public string Alias => ActionAlias;
|
||||
public string Icon => "add";
|
||||
public bool ShowInNotifier => true;
|
||||
public bool CanBePermissionAssigned => true;
|
||||
public string Category => Constants.Conventions.PermissionCategories.ContentCategory;
|
||||
}
|
||||
}
|
||||
20
src/Umbraco.Web/Actions/ActionProtect.cs
Normal file
20
src/Umbraco.Web/Actions/ActionProtect.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
using Umbraco.Web.UI.Pages;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Actions
|
||||
{
|
||||
/// <summary>
|
||||
/// This action is invoked when a document is protected or unprotected
|
||||
/// </summary>
|
||||
public class ActionProtect : IAction
|
||||
{
|
||||
public char Letter => 'P';
|
||||
public string Alias => "protect";
|
||||
public string Category => Constants.Conventions.PermissionCategories.AdministrationCategory;
|
||||
public string Icon => "lock";
|
||||
public bool ShowInNotifier => true;
|
||||
public bool CanBePermissionAssigned => true;
|
||||
}
|
||||
}
|
||||
21
src/Umbraco.Web/Actions/ActionPublish.cs
Normal file
21
src/Umbraco.Web/Actions/ActionPublish.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Actions
|
||||
{
|
||||
/// <summary>
|
||||
/// This action is invoked when a document is being published
|
||||
/// </summary>
|
||||
public class ActionPublish : IAction
|
||||
{
|
||||
public const char ActionLetter = 'U';
|
||||
|
||||
public char Letter => ActionLetter;
|
||||
public string Alias => "publish";
|
||||
public string Category => Constants.Conventions.PermissionCategories.ContentCategory;
|
||||
public string Icon => string.Empty;
|
||||
public bool ShowInNotifier => true;
|
||||
public bool CanBePermissionAssigned => true;
|
||||
}
|
||||
}
|
||||
20
src/Umbraco.Web/Actions/ActionRestore.cs
Normal file
20
src/Umbraco.Web/Actions/ActionRestore.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
|
||||
|
||||
namespace Umbraco.Web.Actions
|
||||
{
|
||||
/// <summary>
|
||||
/// This action is invoked when the content/media item is to be restored from the recycle bin
|
||||
/// </summary>
|
||||
public class ActionRestore : IAction
|
||||
{
|
||||
public const string ActionAlias = "restore";
|
||||
|
||||
public char Letter => 'V';
|
||||
public string Alias => ActionAlias;
|
||||
public string Category => null;
|
||||
public string Icon => "undo";
|
||||
public bool ShowInNotifier => true;
|
||||
public bool CanBePermissionAssigned => false;
|
||||
|
||||
}
|
||||
}
|
||||
20
src/Umbraco.Web/Actions/ActionRights.cs
Normal file
20
src/Umbraco.Web/Actions/ActionRights.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
using Umbraco.Web.UI.Pages;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Actions
|
||||
{
|
||||
/// <summary>
|
||||
/// This action is invoked when rights are changed on a document
|
||||
/// </summary>
|
||||
public class ActionRights : IAction
|
||||
{
|
||||
public char Letter => 'R';
|
||||
public string Alias => "rights";
|
||||
public string Category => Constants.Conventions.PermissionCategories.ContentCategory;
|
||||
public string Icon => "vcard";
|
||||
public bool ShowInNotifier => true;
|
||||
public bool CanBePermissionAssigned => true;
|
||||
}
|
||||
}
|
||||
22
src/Umbraco.Web/Actions/ActionRollback.cs
Normal file
22
src/Umbraco.Web/Actions/ActionRollback.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
using Umbraco.Web.UI.Pages;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Actions
|
||||
{
|
||||
/// <summary>
|
||||
/// This action is invoked when copying a document is being rolled back
|
||||
/// </summary>
|
||||
public class ActionRollback : IAction
|
||||
{
|
||||
public const char ActionLetter = 'K';
|
||||
|
||||
public char Letter => ActionLetter;
|
||||
public string Alias => "rollback";
|
||||
public string Category => Constants.Conventions.PermissionCategories.AdministrationCategory;
|
||||
public string Icon => "undo";
|
||||
public bool ShowInNotifier => true;
|
||||
public bool CanBePermissionAssigned => true;
|
||||
}
|
||||
}
|
||||
19
src/Umbraco.Web/Actions/ActionSort.cs
Normal file
19
src/Umbraco.Web/Actions/ActionSort.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Actions
|
||||
{
|
||||
/// <summary>
|
||||
/// This action is invoked when children to a document, media, member is being sorted
|
||||
/// </summary>
|
||||
public class ActionSort : IAction
|
||||
{
|
||||
public char Letter => 'S';
|
||||
public string Alias => "sort";
|
||||
public string Category => Constants.Conventions.PermissionCategories.StructureCategory;
|
||||
public string Icon => "navigation-vertical";
|
||||
public bool ShowInNotifier => true;
|
||||
public bool CanBePermissionAssigned => true;
|
||||
}
|
||||
}
|
||||
22
src/Umbraco.Web/Actions/ActionToPublish.cs
Normal file
22
src/Umbraco.Web/Actions/ActionToPublish.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
using Umbraco.Web.UI.Pages;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Actions
|
||||
{
|
||||
/// <summary>
|
||||
/// This action is invoked when children to a document is being sent to published (by an editor without publishrights)
|
||||
/// </summary>
|
||||
public class ActionToPublish : IAction
|
||||
{
|
||||
public const char ActionLetter = 'H';
|
||||
|
||||
public char Letter => ActionLetter;
|
||||
public string Alias => "sendtopublish";
|
||||
public string Category => Constants.Conventions.PermissionCategories.ContentCategory;
|
||||
public string Icon => "outbox";
|
||||
public bool ShowInNotifier => true;
|
||||
public bool CanBePermissionAssigned => true;
|
||||
}
|
||||
}
|
||||
21
src/Umbraco.Web/Actions/ActionUnpublish.cs
Normal file
21
src/Umbraco.Web/Actions/ActionUnpublish.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Actions
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// This action is invoked when a document is being unpublished
|
||||
/// </summary>
|
||||
public class ActionUnpublish : IAction
|
||||
{
|
||||
public char Letter => 'Z';
|
||||
public string Alias => "unpublish";
|
||||
public string Category => Constants.Conventions.PermissionCategories.ContentCategory;
|
||||
public string Icon => "circle-dotted";
|
||||
public bool ShowInNotifier => false;
|
||||
public bool CanBePermissionAssigned => true;
|
||||
}
|
||||
|
||||
}
|
||||
22
src/Umbraco.Web/Actions/ActionUpdate.cs
Normal file
22
src/Umbraco.Web/Actions/ActionUpdate.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
using Umbraco.Web.UI.Pages;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Actions
|
||||
{
|
||||
/// <summary>
|
||||
/// This action is invoked when copying a document or media
|
||||
/// </summary>
|
||||
public class ActionUpdate : IAction
|
||||
{
|
||||
public const char ActionLetter = 'A';
|
||||
|
||||
public char Letter => ActionLetter;
|
||||
public string Alias => "update";
|
||||
public string Category => Constants.Conventions.PermissionCategories.ContentCategory;
|
||||
public string Icon => "save";
|
||||
public bool ShowInNotifier => true;
|
||||
public bool CanBePermissionAssigned => true;
|
||||
}
|
||||
}
|
||||
46
src/Umbraco.Web/Actions/IAction.cs
Normal file
46
src/Umbraco.Web/Actions/IAction.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
using Umbraco.Core.Composing;
|
||||
|
||||
namespace Umbraco.Web.Actions
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a back office action that can be permission assigned or subscribed to for notifications
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If an IAction returns false for both ShowInNotifier and CanBePermissionAssigned then the IAction should not exist
|
||||
/// </remarks>
|
||||
public interface IAction : IDiscoverable
|
||||
{
|
||||
/// <summary>
|
||||
/// The letter used to assign a permission (must be unique)
|
||||
/// </summary>
|
||||
char Letter { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether to allow subscribing to notifications for this action
|
||||
/// </summary>
|
||||
bool ShowInNotifier { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether to allow assigning permissions based on this action
|
||||
/// </summary>
|
||||
bool CanBePermissionAssigned { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The icon to display for this action
|
||||
/// </summary>
|
||||
string Icon { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The alias for this action (must be unique)
|
||||
/// </summary>
|
||||
string Alias { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The category used for this action
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Used in the UI when assigning permissions
|
||||
/// </remarks>
|
||||
string Category { get; }
|
||||
}
|
||||
}
|
||||
@@ -5,23 +5,24 @@ using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Entities;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Services.Implement;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
using Umbraco.Web.Actions;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Components
|
||||
{
|
||||
[RuntimeLevel(MinLevel = RuntimeLevel.Run)]
|
||||
public sealed class NotificationsComponent : UmbracoComponentBase, IUmbracoCoreComponent
|
||||
{
|
||||
public void Initialize(INotificationService notificationService)
|
||||
public void Initialize(INotificationService notificationService, ActionCollection actions)
|
||||
{
|
||||
ContentService.SentToPublish += (sender, args) =>
|
||||
notificationService.SendNotification(args.Entity, ActionToPublish.Instance);
|
||||
notificationService.SendNotification(args.Entity, actions.GetAction<ActionToPublish>());
|
||||
|
||||
//Send notifications for the published action
|
||||
ContentService.Published += (sender, args) =>
|
||||
{
|
||||
foreach (var content in args.PublishedEntities)
|
||||
notificationService.SendNotification(content, ActionPublish.Instance);
|
||||
notificationService.SendNotification(content, actions.GetAction<ActionToPublish>());
|
||||
};
|
||||
|
||||
//Send notifications for the update and created actions
|
||||
@@ -45,22 +46,22 @@ namespace Umbraco.Web.Components
|
||||
updatedEntities.Add(entity);
|
||||
}
|
||||
}
|
||||
notificationService.SendNotification(newEntities, ActionNew.Instance);
|
||||
notificationService.SendNotification(updatedEntities, ActionUpdate.Instance);
|
||||
notificationService.SendNotification(newEntities, actions.GetAction<ActionNew>());
|
||||
notificationService.SendNotification(updatedEntities, actions.GetAction<ActionUpdate>());
|
||||
};
|
||||
|
||||
//Send notifications for the delete action
|
||||
ContentService.Deleted += (sender, args) =>
|
||||
{
|
||||
foreach (var content in args.DeletedEntities)
|
||||
notificationService.SendNotification(content, ActionDelete.Instance);
|
||||
notificationService.SendNotification(content, actions.GetAction<ActionDelete>());
|
||||
};
|
||||
|
||||
//Send notifications for the unpublish action
|
||||
ContentService.Unpublished += (sender, args) =>
|
||||
{
|
||||
foreach (var content in args.PublishedEntities)
|
||||
notificationService.SendNotification(content, ActionUnpublish.Instance);
|
||||
notificationService.SendNotification(content, actions.GetAction<ActionUnpublish>());
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Strings;
|
||||
using Umbraco.Core.Sync;
|
||||
using Umbraco.Core._Legacy.PackageActions;
|
||||
using Umbraco.Web.Actions;
|
||||
using Umbraco.Web.Cache;
|
||||
using Umbraco.Web.Editors;
|
||||
using Umbraco.Web.HealthCheck;
|
||||
@@ -27,7 +28,7 @@ using Umbraco.Web.Mvc;
|
||||
using Umbraco.Web.PublishedCache;
|
||||
using Umbraco.Web.Routing;
|
||||
using Umbraco.Web.WebApi;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
using CoreCurrent = Umbraco.Core.Composing.Current;
|
||||
|
||||
namespace Umbraco.Web.Composing
|
||||
|
||||
@@ -3,14 +3,15 @@ using LightInject;
|
||||
using Umbraco.Core.Composing;
|
||||
using Current = Umbraco.Web.Composing.Current;
|
||||
using Umbraco.Core.Macros;
|
||||
using Umbraco.Web.Actions;
|
||||
using Umbraco.Web.Editors;
|
||||
using Umbraco.Web.HealthCheck;
|
||||
using Umbraco.Web.Media;
|
||||
using Umbraco.Web.Mvc;
|
||||
using Umbraco.Web.PublishedCache;
|
||||
using Umbraco.Web.Routing;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
using Umbraco.Web.ContentApps;
|
||||
using Umbraco.Web.Features;
|
||||
|
||||
// the namespace here is intentional - although defined in Umbraco.Web assembly,
|
||||
// this class should be visible when using Umbraco.Core.Components, alongside
|
||||
@@ -58,6 +59,9 @@ namespace Umbraco.Core.Components
|
||||
internal static EditorValidatorCollectionBuilder EditorValidators(this Composition composition)
|
||||
=> composition.Container.GetInstance<EditorValidatorCollectionBuilder>();
|
||||
|
||||
public static UmbracoFeatures Features(this Composition composition)
|
||||
=> composition.Container.GetInstance<UmbracoFeatures>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the filtered controller factories collection builder.
|
||||
/// </summary>
|
||||
|
||||
@@ -3,18 +3,15 @@ using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.UI;
|
||||
using LightInject;
|
||||
using Microsoft.AspNet.Identity;
|
||||
using Microsoft.AspNet.Identity.Owin;
|
||||
using Microsoft.Owin.Security;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Configuration;
|
||||
@@ -22,18 +19,13 @@ using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Manifest;
|
||||
using Umbraco.Core.Models.Identity;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
using Umbraco.Core.Security;
|
||||
using Umbraco.Web.Models;
|
||||
using Umbraco.Web.Mvc;
|
||||
|
||||
using Umbraco.Web.Trees;
|
||||
using Umbraco.Web.UI.JavaScript;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Web.Features;
|
||||
using Umbraco.Web.Security;
|
||||
using Action = Umbraco.Web._Legacy.Actions.Action;
|
||||
using Constants = Umbraco.Core.Constants;
|
||||
using JArray = Newtonsoft.Json.Linq.JArray;
|
||||
|
||||
@@ -197,11 +189,8 @@ namespace Umbraco.Web.Editors
|
||||
{
|
||||
var initJs = new JsInitialization(_manifestParser);
|
||||
var initCss = new CssInitialization(_manifestParser);
|
||||
|
||||
//get the legacy ActionJs file references to append as well
|
||||
var legacyActionJsRef = GetLegacyActionJs(LegacyJsActionType.JsUrl);
|
||||
|
||||
var files = initJs.OptimizeBackOfficeScriptFiles(HttpContext, JsInitialization.GetDefaultInitialization(), legacyActionJsRef);
|
||||
|
||||
var files = initJs.OptimizeBackOfficeScriptFiles(HttpContext, JsInitialization.GetDefaultInitialization());
|
||||
var result = JsInitialization.GetJavascriptInitialization(HttpContext, files, "umbraco");
|
||||
result += initCss.GetStylesheetInitialization(HttpContext);
|
||||
|
||||
@@ -519,50 +508,7 @@ namespace Umbraco.Web.Editors
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
internal static IEnumerable<string> GetLegacyActionJsForActions(LegacyJsActionType type, IEnumerable<string> values)
|
||||
{
|
||||
var blockList = new List<string>();
|
||||
var urlList = new List<string>();
|
||||
foreach (var jsFile in values)
|
||||
{
|
||||
var isJsPath = jsFile.DetectIsJavaScriptPath();
|
||||
if (isJsPath.Success)
|
||||
|
||||
{
|
||||
urlList.Add(isJsPath.Result);
|
||||
}
|
||||
else
|
||||
{
|
||||
blockList.Add(isJsPath.Result);
|
||||
}
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case LegacyJsActionType.JsBlock:
|
||||
return blockList;
|
||||
case LegacyJsActionType.JsUrl:
|
||||
return urlList;
|
||||
}
|
||||
|
||||
return blockList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Renders out all JavaScript references that have been declared in IActions
|
||||
/// </summary>
|
||||
private static IEnumerable<string> GetLegacyActionJs(LegacyJsActionType type)
|
||||
{
|
||||
return GetLegacyActionJsForActions(type, Action.GetJavaScriptFileReferences());
|
||||
}
|
||||
|
||||
internal enum LegacyJsActionType
|
||||
{
|
||||
JsBlock,
|
||||
JsUrl
|
||||
}
|
||||
|
||||
|
||||
private ActionResult RedirectToLocal(string returnUrl)
|
||||
{
|
||||
if (Url.IsLocalUrl(returnUrl))
|
||||
|
||||
@@ -30,10 +30,11 @@ using Umbraco.Core.Models.Validation;
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Web.Models;
|
||||
using Umbraco.Web.WebServices;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
using Constants = Umbraco.Core.Constants;
|
||||
using Language = Umbraco.Web.Models.ContentEditing.Language;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Web.Actions;
|
||||
using Umbraco.Web.ContentApps;
|
||||
using Umbraco.Web.Editors.Binders;
|
||||
using Umbraco.Web.Editors.Filters;
|
||||
@@ -456,7 +457,7 @@ namespace Umbraco.Web.Editors
|
||||
public PagedResult<ContentItemBasic<ContentPropertyBasic>> GetChildren(
|
||||
int id,
|
||||
string includeProperties,
|
||||
int pageNumber = 0, //TODO: This should be '1' as it's not the index
|
||||
int pageNumber = 0,
|
||||
int pageSize = 0,
|
||||
string orderBy = "SortOrder",
|
||||
Direction orderDirection = Direction.Ascending,
|
||||
@@ -483,7 +484,8 @@ namespace Umbraco.Web.Editors
|
||||
}
|
||||
else
|
||||
{
|
||||
children = Services.ContentService.GetChildren(id).ToList();
|
||||
//better to not use this without paging where possible, currently only the sort dialog does
|
||||
children = Services.ContentService.GetPagedChildren(id, 0, int.MaxValue, out var total).ToList();
|
||||
totalChildren = children.Count;
|
||||
}
|
||||
|
||||
@@ -931,14 +933,14 @@ namespace Umbraco.Web.Editors
|
||||
var errMsg = Services.TextService.Localize(localizationKey, new[] { _allLangs.Value[culture].CultureName });
|
||||
ModelState.AddModelError(key, errMsg);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Publishes a document with a given ID
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// The CanAccessContentAuthorize attribute will deny access to this method if the current user
|
||||
/// The EnsureUserPermissionForContent attribute will deny access to this method if the current user
|
||||
/// does not have Publish access to this node.
|
||||
/// </remarks>
|
||||
///
|
||||
@@ -1076,7 +1078,7 @@ namespace Umbraco.Web.Editors
|
||||
|
||||
if (sorted.ParentId > 0)
|
||||
{
|
||||
Services.NotificationService.SendNotification(contentService.GetById(sorted.ParentId), ActionSort.Instance, UmbracoContext, Services.TextService, GlobalSettings);
|
||||
Services.NotificationService.SendNotification(contentService.GetById(sorted.ParentId), Current.Actions.GetAction<ActionSort>(), UmbracoContext, Services.TextService, GlobalSettings);
|
||||
}
|
||||
|
||||
return Request.CreateResponse(HttpStatusCode.OK);
|
||||
@@ -1223,7 +1225,7 @@ namespace Umbraco.Web.Editors
|
||||
|
||||
var permission = Services.UserService.GetPermissions(Security.CurrentUser, node.Path);
|
||||
|
||||
if (permission.AssignedPermissions.Contains(ActionAssignDomain.Instance.Letter.ToString(), StringComparer.Ordinal) == false)
|
||||
if (permission.AssignedPermissions.Contains(ActionAssignDomain.ActionLetter.ToString(), StringComparer.Ordinal) == false)
|
||||
{
|
||||
var response = Request.CreateResponse(HttpStatusCode.BadRequest);
|
||||
response.Content = new StringContent("You do not have permission to assign domains on that node.");
|
||||
@@ -1317,7 +1319,7 @@ namespace Umbraco.Web.Editors
|
||||
xnames.Add(xcontent.Name);
|
||||
if (xcontent.ParentId < -1)
|
||||
xnames.Add("Recycle Bin");
|
||||
xcontent = xcontent.Parent(Services.ContentService);
|
||||
xcontent = Services.ContentService.GetParent(xcontent);
|
||||
}
|
||||
xnames.Reverse();
|
||||
domainModel.Other = "/" + string.Join("/", xnames);
|
||||
@@ -1760,6 +1762,7 @@ namespace Umbraco.Web.Editors
|
||||
: content.Variants.FirstOrDefault(x => x.Language.IsoCode == culture);
|
||||
}
|
||||
|
||||
[EnsureUserPermissionForContent("contentId", ActionRollback.ActionLetter)]
|
||||
[HttpPost]
|
||||
public HttpResponseMessage PostRollbackContent(int contentId, int versionId, string culture = "*")
|
||||
{
|
||||
|
||||
@@ -9,11 +9,12 @@ using Umbraco.Core;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Actions;
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
using Umbraco.Web.Security;
|
||||
using Umbraco.Web.WebApi;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Editors.Filters
|
||||
{
|
||||
@@ -94,24 +95,24 @@ namespace Umbraco.Web.Editors.Filters
|
||||
switch (contentItem.Action)
|
||||
{
|
||||
case ContentSaveAction.Save:
|
||||
permissionToCheck.Add(ActionUpdate.Instance.Letter);
|
||||
permissionToCheck.Add(ActionUpdate.ActionLetter);
|
||||
contentToCheck = contentItem.PersistedContent;
|
||||
contentIdToCheck = contentToCheck.Id;
|
||||
break;
|
||||
case ContentSaveAction.Publish:
|
||||
permissionToCheck.Add(ActionPublish.Instance.Letter);
|
||||
permissionToCheck.Add(ActionPublish.ActionLetter);
|
||||
contentToCheck = contentItem.PersistedContent;
|
||||
contentIdToCheck = contentToCheck.Id;
|
||||
break;
|
||||
case ContentSaveAction.SendPublish:
|
||||
permissionToCheck.Add(ActionToPublish.Instance.Letter);
|
||||
permissionToCheck.Add(ActionToPublish.ActionLetter);
|
||||
contentToCheck = contentItem.PersistedContent;
|
||||
contentIdToCheck = contentToCheck.Id;
|
||||
break;
|
||||
case ContentSaveAction.SaveNew:
|
||||
//Save new requires ActionNew
|
||||
|
||||
permissionToCheck.Add(ActionNew.Instance.Letter);
|
||||
permissionToCheck.Add(ActionNew.ActionLetter);
|
||||
|
||||
if (contentItem.ParentId != Constants.System.Root)
|
||||
{
|
||||
@@ -126,8 +127,8 @@ namespace Umbraco.Web.Editors.Filters
|
||||
case ContentSaveAction.SendPublishNew:
|
||||
//Send new requires both ActionToPublish AND ActionNew
|
||||
|
||||
permissionToCheck.Add(ActionNew.Instance.Letter);
|
||||
permissionToCheck.Add(ActionToPublish.Instance.Letter);
|
||||
permissionToCheck.Add(ActionNew.ActionLetter);
|
||||
permissionToCheck.Add(ActionToPublish.ActionLetter);
|
||||
if (contentItem.ParentId != Constants.System.Root)
|
||||
{
|
||||
contentToCheck = _contentService.GetById(contentItem.ParentId);
|
||||
@@ -142,8 +143,8 @@ namespace Umbraco.Web.Editors.Filters
|
||||
//Publish new requires both ActionNew AND ActionPublish
|
||||
//TODO: Shoudn't publish also require ActionUpdate since it will definitely perform an update to publish but maybe that's just implied
|
||||
|
||||
permissionToCheck.Add(ActionNew.Instance.Letter);
|
||||
permissionToCheck.Add(ActionPublish.Instance.Letter);
|
||||
permissionToCheck.Add(ActionNew.ActionLetter);
|
||||
permissionToCheck.Add(ActionPublish.ActionLetter);
|
||||
|
||||
if (contentItem.ParentId != Constants.System.Root)
|
||||
{
|
||||
|
||||
@@ -209,7 +209,10 @@ namespace Umbraco.Web.Editors
|
||||
}
|
||||
|
||||
long total;
|
||||
var children = Services.MediaService.GetPagedChildren(id, pageNumber - 1, pageSize, out total, "Name", Direction.Ascending, true, null, folderTypes.ToArray());
|
||||
var children = Services.MediaService.GetPagedChildren(id, pageNumber - 1, pageSize, out total,
|
||||
//lookup these content types
|
||||
SqlContext.Query<IMedia>().Where(x => folderTypes.Contains(x.ContentTypeId)),
|
||||
Ordering.By("Name", Direction.Ascending));
|
||||
|
||||
return new PagedResult<ContentItemBasic<ContentPropertyBasic>>(total, pageNumber, pageSize)
|
||||
{
|
||||
@@ -271,7 +274,7 @@ namespace Umbraco.Web.Editors
|
||||
// else proceed as usual
|
||||
|
||||
long totalChildren;
|
||||
IMedia[] children;
|
||||
List<IMedia> children;
|
||||
if (pageNumber > 0 && pageSize > 0)
|
||||
{
|
||||
IQuery<IMedia> queryFilter = null;
|
||||
@@ -286,13 +289,14 @@ namespace Umbraco.Web.Editors
|
||||
.GetPagedChildren(
|
||||
id, (pageNumber - 1), pageSize,
|
||||
out totalChildren,
|
||||
orderBy, orderDirection, orderBySystemField,
|
||||
queryFilter).ToArray();
|
||||
queryFilter,
|
||||
Ordering.By(orderBy, orderDirection, isCustomField: !orderBySystemField)).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
children = Services.MediaService.GetChildren(id).ToArray();
|
||||
totalChildren = children.Length;
|
||||
//better to not use this without paging where possible, currently only the sort dialog does
|
||||
children = Services.MediaService.GetPagedChildren(id, 0, int.MaxValue, out var total).ToList();
|
||||
totalChildren = children.Count;
|
||||
}
|
||||
|
||||
if (totalChildren == 0)
|
||||
@@ -663,7 +667,8 @@ namespace Umbraco.Web.Editors
|
||||
" returned null");
|
||||
|
||||
//look for matching folder
|
||||
folderMediaItem = mediaRoot.Children(Services.MediaService).FirstOrDefault(x => x.Name == folderName && x.ContentType.Alias == Constants.Conventions.MediaTypes.Folder);
|
||||
folderMediaItem = FindInChildren(mediaRoot.Id, folderName, Constants.Conventions.MediaTypes.Folder);
|
||||
|
||||
if (folderMediaItem == null)
|
||||
{
|
||||
//if null, create a folder
|
||||
@@ -753,6 +758,21 @@ namespace Umbraco.Web.Editors
|
||||
return Request.CreateResponse(HttpStatusCode.OK, tempFiles);
|
||||
}
|
||||
|
||||
private IMedia FindInChildren(int mediaId, string nameToFind, string contentTypeAlias)
|
||||
{
|
||||
const int pageSize = 500;
|
||||
var page = 0;
|
||||
var total = long.MaxValue;
|
||||
while (page * pageSize < total)
|
||||
{
|
||||
var children = Services.MediaService.GetPagedChildren(mediaId, page, pageSize, out total,
|
||||
SqlContext.Query<IMedia>().Where(x => x.Name == nameToFind));
|
||||
foreach (var c in children)
|
||||
return c; //return first one if any are found
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Given a parent id which could be a GUID, UDI or an INT, this will resolve the INT
|
||||
/// </summary>
|
||||
|
||||
@@ -6,8 +6,9 @@ using Umbraco.Core;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Actions;
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Models.Mapping
|
||||
{
|
||||
@@ -37,13 +38,11 @@ namespace Umbraco.Web.Models.Mapping
|
||||
private Permission GetPermission(IAction action, IUserGroup source)
|
||||
{
|
||||
var result = new Permission();
|
||||
var attribute = action.GetType().GetCustomAttribute<ActionMetadataAttribute>(false);
|
||||
result.Category = attribute == null
|
||||
|
||||
result.Category = action.Category.IsNullOrWhiteSpace()
|
||||
? _textService.Localize($"actionCategories/{Constants.Conventions.PermissionCategories.OtherCategory}")
|
||||
: _textService.Localize($"actionCategories/{attribute.Category}");
|
||||
result.Name = attribute == null || attribute.Name.IsNullOrWhiteSpace()
|
||||
? _textService.Localize($"actions/{action.Alias}")
|
||||
: attribute.Name;
|
||||
: _textService.Localize($"actionCategories/{action.Category}");
|
||||
result.Name = _textService.Localize($"actions/{action.Alias}");
|
||||
result.Description = _textService.Localize($"actionDescriptions/{action.Alias}");
|
||||
result.Icon = action.Icon;
|
||||
result.Checked = source.Permissions != null && source.Permissions.Contains(action.Letter.ToString(CultureInfo.InvariantCulture));
|
||||
|
||||
@@ -11,7 +11,8 @@ using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Entities;
|
||||
using Umbraco.Core.Security;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
using Umbraco.Web.Actions;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Models.Mapping
|
||||
{
|
||||
|
||||
@@ -1,41 +1,55 @@
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Services;
|
||||
|
||||
namespace Umbraco.Web.Models.Trees
|
||||
{
|
||||
/// <summary>
|
||||
/// A menu item that represents some JS that needs to execute when the menu item is clicked.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// These types of menu items are rare but they do exist. Things like refresh node simply execute
|
||||
/// JS and don't launch a dialog.
|
||||
///
|
||||
/// Each action menu item describes what angular service that it's method exists in and what the method name is.
|
||||
///
|
||||
/// An action menu item must describe the angular service name for which it's method exists. It may also define what the
|
||||
/// method name is that will be called in this service but if one is not specified then we will assume the method name is the
|
||||
/// same as the Type name of the current action menu class.
|
||||
/// </remarks>
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// A menu item that represents some JS that needs to execute when the menu item is clicked.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// These types of menu items are rare but they do exist. Things like refresh node simply execute
|
||||
/// JS and don't launch a dialog.
|
||||
/// Each action menu item describes what angular service that it's method exists in and what the method name is.
|
||||
/// An action menu item must describe the angular service name for which it's method exists. It may also define what the
|
||||
/// method name is that will be called in this service but if one is not specified then we will assume the method name is the
|
||||
/// same as the Type name of the current action menu class.
|
||||
/// </remarks>
|
||||
public abstract class ActionMenuItem : MenuItem
|
||||
{
|
||||
protected ActionMenuItem()
|
||||
: base()
|
||||
{
|
||||
var attribute = GetType().GetCustomAttribute<ActionMenuItemAttribute>(false);
|
||||
if (attribute == null)
|
||||
{
|
||||
throw new InvalidOperationException("All " + typeof (ActionMenuItem).FullName + " instances must be attributed with " + typeof (ActionMenuItemAttribute).FullName);
|
||||
}
|
||||
/// <summary>
|
||||
/// The angular service name containing the <see cref="AngularServiceMethodName"/>
|
||||
/// </summary>
|
||||
public abstract string AngularServiceName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The angular service method name to call for this menu item
|
||||
/// </summary>
|
||||
public virtual string AngularServiceMethodName { get; } = null;
|
||||
|
||||
protected ActionMenuItem(string alias, string name) : base(alias, name)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
protected ActionMenuItem(string alias, ILocalizedTextService textService) : base(alias, textService)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
private void Initialize()
|
||||
{
|
||||
//add the current type to the metadata
|
||||
if (attribute.MethodName.IsNullOrWhiteSpace())
|
||||
if (AngularServiceMethodName.IsNullOrWhiteSpace())
|
||||
{
|
||||
//if no method name is supplied we will assume that the menu action is the type name of the current menu class
|
||||
AdditionalData.Add("jsAction", string.Format("{0}.{1}", attribute.ServiceName, this.GetType().Name));
|
||||
ExecuteJsMethod($"{AngularServiceName}.{this.GetType().Name}");
|
||||
}
|
||||
else
|
||||
{
|
||||
AdditionalData.Add("jsAction", string.Format("{0}.{1}", attribute.ServiceName, attribute.MethodName));
|
||||
ExecuteJsMethod($"{AngularServiceName}.{AngularServiceMethodName}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
using System;
|
||||
using Umbraco.Core.Exceptions;
|
||||
|
||||
namespace Umbraco.Web.Models.Trees
|
||||
{
|
||||
/// <summary>
|
||||
/// The attribute to assign to any ActionMenuItem objects.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public sealed class ActionMenuItemAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// This constructor defines both the angular service and method name to use
|
||||
/// </summary>
|
||||
/// <param name="serviceName"></param>
|
||||
/// <param name="methodName"></param>
|
||||
public ActionMenuItemAttribute(string serviceName, string methodName)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(serviceName)) throw new ArgumentNullOrEmptyException(nameof(serviceName));
|
||||
if (string.IsNullOrWhiteSpace(methodName)) throw new ArgumentNullOrEmptyException(nameof(methodName));
|
||||
MethodName = methodName;
|
||||
ServiceName = serviceName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This constructor will assume that the method name equals the type name of the action menu class
|
||||
/// </summary>
|
||||
/// <param name="serviceName"></param>
|
||||
public ActionMenuItemAttribute(string serviceName)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(serviceName)) throw new ArgumentNullOrEmptyException(nameof(serviceName));
|
||||
MethodName = "";
|
||||
ServiceName = serviceName;
|
||||
}
|
||||
|
||||
public string MethodName { get; }
|
||||
public string ServiceName { get; }
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,27 @@
|
||||
namespace Umbraco.Web.Models.Trees
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Actions;
|
||||
|
||||
namespace Umbraco.Web.Models.Trees
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the refresh node menu item
|
||||
/// </summary>
|
||||
[ActionMenuItem("umbracoMenuActions")]
|
||||
public sealed class CreateChildEntity : ActionMenuItem
|
||||
{
|
||||
public override string AngularServiceName => "umbracoMenuActions";
|
||||
|
||||
public CreateChildEntity(string name, bool seperatorBefore = false)
|
||||
: base(ActionNew.ActionAlias, name)
|
||||
{
|
||||
Icon = "add"; Name = name;
|
||||
SeperatorBefore = seperatorBefore;
|
||||
}
|
||||
|
||||
public CreateChildEntity(ILocalizedTextService textService, bool seperatorBefore = false)
|
||||
: base(ActionNew.ActionAlias, textService)
|
||||
{
|
||||
Icon = "add";
|
||||
SeperatorBefore = seperatorBefore;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
namespace Umbraco.Web.Models.Trees
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the disable user menu item
|
||||
/// </summary>
|
||||
[ActionMenuItem("umbracoMenuActions")]
|
||||
public sealed class DisableUser : ActionMenuItem
|
||||
{
|
||||
public DisableUser()
|
||||
{
|
||||
Alias = "disable";
|
||||
Icon = "remove";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,17 @@
|
||||
namespace Umbraco.Web.Models.Trees
|
||||
using Umbraco.Core.Services;
|
||||
|
||||
namespace Umbraco.Web.Models.Trees
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the export member menu item
|
||||
/// </summary>
|
||||
[ActionMenuItem("umbracoMenuActions")]
|
||||
public sealed class ExportMember : ActionMenuItem
|
||||
{ }
|
||||
{
|
||||
public override string AngularServiceName => "umbracoMenuActions";
|
||||
|
||||
public ExportMember(ILocalizedTextService textService) : base("export", textService)
|
||||
{
|
||||
Icon = "download-alt";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,8 +5,9 @@ using System.Collections.Generic;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models.Entities;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Actions;
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Models.Trees
|
||||
{
|
||||
@@ -30,15 +31,27 @@ namespace Umbraco.Web.Models.Trees
|
||||
Name = name;
|
||||
}
|
||||
|
||||
public MenuItem(IAction legacyMenu, string name = "")
|
||||
|
||||
public MenuItem(string alias, ILocalizedTextService textService)
|
||||
: this()
|
||||
{
|
||||
Name = name.IsNullOrWhiteSpace() ? legacyMenu.Alias : name;
|
||||
Alias = legacyMenu.Alias;
|
||||
Alias = alias;
|
||||
Name = textService.Localize($"actions/{Alias}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a menu item based on an <see cref="IAction"/> definition
|
||||
/// </summary>
|
||||
/// <param name="action"></param>
|
||||
/// <param name="name"></param>
|
||||
public MenuItem(IAction action, string name = "")
|
||||
: this()
|
||||
{
|
||||
Name = name.IsNullOrWhiteSpace() ? action.Alias : name;
|
||||
Alias = action.Alias;
|
||||
SeperatorBefore = false;
|
||||
Icon = legacyMenu.Icon;
|
||||
Action = legacyMenu;
|
||||
OpensDialog = legacyMenu.OpensDialog;
|
||||
Icon = action.Icon;
|
||||
Action = action;
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -73,6 +86,9 @@ namespace Umbraco.Web.Models.Trees
|
||||
[DataMember(Name = "cssclass")]
|
||||
public string Icon { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Used in the UI to inform the user that the menu item will open a dialog/confirmation
|
||||
/// </summary>
|
||||
[DataMember(Name = "opensDialog")]
|
||||
public bool OpensDialog { get; set; }
|
||||
|
||||
@@ -128,7 +144,7 @@ namespace Umbraco.Web.Models.Trees
|
||||
/// Adds the required meta data to the menu item so that angular knows to attempt to call the Js method.
|
||||
/// </summary>
|
||||
/// <param name="jsToExecute"></param>
|
||||
public void ExecuteLegacyJs(string jsToExecute)
|
||||
public void ExecuteJsMethod(string jsToExecute)
|
||||
{
|
||||
SetJsAction(jsToExecute);
|
||||
}
|
||||
@@ -206,7 +222,7 @@ namespace Umbraco.Web.Models.Trees
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Actions;
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Models.Trees
|
||||
{
|
||||
@@ -24,7 +26,7 @@ namespace Umbraco.Web.Models.Trees
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a menu item
|
||||
/// Adds a menu item based on a <see cref="IAction"/>
|
||||
/// </summary>
|
||||
/// <param name="action"></param>
|
||||
/// <param name="name">The text to display for the menu item, will default to the IAction alias if not specified</param>
|
||||
@@ -32,78 +34,20 @@ namespace Umbraco.Web.Models.Trees
|
||||
{
|
||||
var item = new MenuItem(action, name);
|
||||
|
||||
DetectLegacyActionMenu(action.GetType(), item);
|
||||
|
||||
Add(item);
|
||||
return item;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a menu item
|
||||
/// </summary>
|
||||
/// <typeparam name="TMenuItem"></typeparam>
|
||||
/// <typeparam name="TAction"></typeparam>
|
||||
/// <param name="hasSeparator"></param>
|
||||
/// <param name="name">The text to display for the menu item, will default to the IAction alias if not specified</param>
|
||||
/// <param name="additionalData"></param>
|
||||
/// <returns></returns>
|
||||
public TMenuItem Add<TMenuItem, TAction>(string name, bool hasSeparator = false, IDictionary<string, object> additionalData = null)
|
||||
where TAction : IAction
|
||||
where TMenuItem : MenuItem, new()
|
||||
{
|
||||
var item = CreateMenuItem<TAction>(name, hasSeparator, additionalData);
|
||||
if (item == null) return null;
|
||||
|
||||
var customMenuItem = new TMenuItem
|
||||
{
|
||||
Name = item.Name,
|
||||
Alias = item.Alias,
|
||||
SeperatorBefore = hasSeparator,
|
||||
Icon = item.Icon,
|
||||
Action = item.Action
|
||||
};
|
||||
|
||||
Add(customMenuItem);
|
||||
|
||||
return customMenuItem;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a menu item
|
||||
/// </summary>
|
||||
/// <param name="name">The text to display for the menu item, will default to the IAction alias if not specified</param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public MenuItem Add<T>(string name)
|
||||
where T : IAction
|
||||
{
|
||||
return Add<T>(name, false, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a menu item with a key value pair which is merged to the AdditionalData bag
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="name">The text to display for the menu item, will default to the IAction alias if not specified</param>
|
||||
/// <param name="hasSeparator"></param>
|
||||
public MenuItem Add<T>(string name, string key, string value, bool hasSeparator = false)
|
||||
where T : IAction
|
||||
{
|
||||
return Add<T>(name, hasSeparator, new Dictionary<string, object> { { key, value } });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a menu item with a dictionary which is merged to the AdditionalData bag
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="hasSeparator"></param>
|
||||
/// /// <param name="name">The text to display for the menu item, will default to the IAction alias if not specified</param>
|
||||
/// <param name="additionalData"></param>
|
||||
public MenuItem Add<T>(string name, bool hasSeparator = false, IDictionary<string, object> additionalData = null)
|
||||
/// <param name="name">The text to display for the menu item, will default to the IAction alias if not specified</param>
|
||||
public MenuItem Add<T>(string name, bool hasSeparator = false)
|
||||
where T : IAction
|
||||
{
|
||||
var item = CreateMenuItem<T>(name, hasSeparator, additionalData);
|
||||
var item = CreateMenuItem<T>(name, hasSeparator);
|
||||
if (item != null)
|
||||
{
|
||||
Add(item);
|
||||
@@ -113,69 +57,51 @@ namespace Umbraco.Web.Models.Trees
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// Adds a menu item with a dictionary which is merged to the AdditionalData bag
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="hasSeparator"></param>
|
||||
/// <param name="name">The text to display for the menu item, will default to the IAction alias if not specified</param>
|
||||
/// <param name="additionalData"></param>
|
||||
/// <returns></returns>
|
||||
internal MenuItem CreateMenuItem<T>(string name, bool hasSeparator = false, IDictionary<string, object> additionalData = null)
|
||||
/// <param name="textService">The <see cref="ILocalizedTextService"/> used to localize the action name based on it's alias</param>
|
||||
/// <param name="opensDialog"></param>
|
||||
public MenuItem Add<T>(ILocalizedTextService textService, bool hasSeparator = false, bool opensDialog = false)
|
||||
where T : IAction
|
||||
{
|
||||
var item = Current.Actions.GetAction<T>();
|
||||
var item = CreateMenuItem<T>(textService, hasSeparator);
|
||||
if (item != null)
|
||||
{
|
||||
var menuItem = new MenuItem(item, name)
|
||||
{
|
||||
SeperatorBefore = hasSeparator
|
||||
};
|
||||
|
||||
if (additionalData != null)
|
||||
{
|
||||
foreach (var i in additionalData)
|
||||
{
|
||||
menuItem.AdditionalData[i.Key] = i.Value;
|
||||
}
|
||||
}
|
||||
|
||||
DetectLegacyActionMenu(typeof(T), menuItem);
|
||||
|
||||
//TODO: Once we implement 'real' menu items, not just IActions we can implement this since
|
||||
// people may need to pass specific data to their menu items
|
||||
|
||||
////validate the data in the meta data bag
|
||||
//item.ValidateRequiredData(AdditionalData);
|
||||
|
||||
return menuItem;
|
||||
Add(item);
|
||||
return item;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the IAction type passed in is attributed with LegacyActionMenuItemAttribute and if so
|
||||
/// ensures that the correct action metadata is added.
|
||||
/// </summary>
|
||||
/// <param name="actionType"></param>
|
||||
/// <param name="menuItem"></param>
|
||||
private void DetectLegacyActionMenu(Type actionType, MenuItem menuItem)
|
||||
|
||||
internal MenuItem CreateMenuItem<T>(string name, bool hasSeparator = false)
|
||||
where T : IAction
|
||||
{
|
||||
//This checks for legacy IActions that have the LegacyActionMenuItemAttribute which is a legacy hack
|
||||
// to make old IAction actions work in v7 by mapping to the JS used by the new menu items
|
||||
var attribute = actionType.GetCustomAttribute<LegacyActionMenuItemAttribute>(false);
|
||||
if (attribute != null)
|
||||
var item = Current.Actions.GetAction<T>();
|
||||
if (item == null) return null;
|
||||
var menuItem = new MenuItem(item, name)
|
||||
{
|
||||
//add the current type to the metadata
|
||||
if (attribute.MethodName.IsNullOrWhiteSpace())
|
||||
{
|
||||
//if no method name is supplied we will assume that the menu action is the type name of the current menu class
|
||||
menuItem.AdditionalData.Add(MenuItem.JsActionKey, string.Format("{0}.{1}", attribute.ServiceName, this.GetType().Name));
|
||||
}
|
||||
else
|
||||
{
|
||||
menuItem.AdditionalData.Add(MenuItem.JsActionKey, string.Format("{0}.{1}", attribute.ServiceName, attribute.MethodName));
|
||||
}
|
||||
}
|
||||
SeperatorBefore = hasSeparator
|
||||
};
|
||||
|
||||
return menuItem;
|
||||
}
|
||||
|
||||
internal MenuItem CreateMenuItem<T>(ILocalizedTextService textService, bool hasSeparator = false, bool opensDialog = false)
|
||||
where T : IAction
|
||||
{
|
||||
var item = Current.Actions.GetAction<T>();
|
||||
if (item == null) return null;
|
||||
|
||||
var menuItem = new MenuItem(item, textService.Localize($"actions/{item.Alias}"))
|
||||
{
|
||||
SeperatorBefore = hasSeparator,
|
||||
OpensDialog = opensDialog
|
||||
};
|
||||
|
||||
return menuItem;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,27 @@
|
||||
namespace Umbraco.Web.Models.Trees
|
||||
using Umbraco.Core.Services;
|
||||
|
||||
namespace Umbraco.Web.Models.Trees
|
||||
{
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Represents the refresh node menu item
|
||||
/// </summary>
|
||||
[ActionMenuItem("umbracoMenuActions")]
|
||||
public sealed class RefreshNode : ActionMenuItem
|
||||
{
|
||||
public override string AngularServiceName => "umbracoMenuActions";
|
||||
|
||||
public RefreshNode(string name, bool seperatorBefore = false)
|
||||
: base("refreshNode", name)
|
||||
{
|
||||
Icon = "refresh";
|
||||
SeperatorBefore = seperatorBefore;
|
||||
}
|
||||
|
||||
public RefreshNode(ILocalizedTextService textService, bool seperatorBefore = false)
|
||||
: base("refreshNode", textService)
|
||||
{
|
||||
Icon = "refresh";
|
||||
SeperatorBefore = seperatorBefore;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,9 +6,10 @@ using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models.Entities;
|
||||
using Umbraco.Web.Actions;
|
||||
using Umbraco.Web.Composing;
|
||||
|
||||
namespace Umbraco.Web
|
||||
|
||||
@@ -129,7 +129,7 @@ namespace Umbraco.Web.Routing
|
||||
var parent = content;
|
||||
do
|
||||
{
|
||||
parent = parent.ParentId > 0 ? parent.Parent(contentService) : null;
|
||||
parent = parent.ParentId > 0 ? contentService.GetParent(parent) : null;
|
||||
}
|
||||
while (parent != null && parent.Published && (!parent.ContentType.VariesByCulture() || parent.IsCulturePublished(culture)));
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ using Umbraco.Core.PropertyEditors.ValueConverters;
|
||||
using Umbraco.Core.Runtime;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Examine;
|
||||
using Umbraco.Web.Actions;
|
||||
using Umbraco.Web.Cache;
|
||||
using Umbraco.Web.Composing.CompositionRoots;
|
||||
using Umbraco.Web.ContentApps;
|
||||
@@ -53,7 +54,7 @@ using Umbraco.Web.Tour;
|
||||
using Umbraco.Web.Trees;
|
||||
using Umbraco.Web.UI.JavaScript;
|
||||
using Umbraco.Web.WebApi;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
using Current = Umbraco.Web.Composing.Current;
|
||||
|
||||
namespace Umbraco.Web.Runtime
|
||||
@@ -139,7 +140,7 @@ namespace Umbraco.Web.Runtime
|
||||
Current.DefaultRenderMvcControllerType = typeof(RenderMvcController); // fixme WRONG!
|
||||
|
||||
composition.Container.RegisterCollectionBuilder<ActionCollectionBuilder>()
|
||||
.SetProducer(() => typeLoader.GetActions());
|
||||
.Add(() => typeLoader.GetTypes<IAction>());
|
||||
|
||||
var surfaceControllerTypes = new SurfaceControllerTypeCollection(typeLoader.GetSurfaceControllers());
|
||||
composition.Container.RegisterInstance(surfaceControllerTypes);
|
||||
|
||||
@@ -26,6 +26,7 @@ using Umbraco.Web.Cache;
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Web.PropertyEditors;
|
||||
using Umbraco.Examine;
|
||||
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
|
||||
|
||||
namespace Umbraco.Web.Search
|
||||
{
|
||||
@@ -102,13 +103,10 @@ namespace Umbraco.Web.Search
|
||||
// bind to distributed cache events - this ensures that this logic occurs on ALL servers
|
||||
// that are taking part in a load balanced environment.
|
||||
ContentCacheRefresher.CacheUpdated += ContentCacheRefresherUpdated;
|
||||
ContentTypeCacheRefresher.CacheUpdated += ContentTypeCacheRefresherUpdated; ;
|
||||
MediaCacheRefresher.CacheUpdated += MediaCacheRefresherUpdated;
|
||||
MemberCacheRefresher.CacheUpdated += MemberCacheRefresherUpdated;
|
||||
|
||||
// fixme - content type?
|
||||
// events handling removed in ef013f9d3b945d0a48a306ff1afbd49c10c3fff8
|
||||
// because, could not make sense of it?
|
||||
|
||||
EnsureUnlocked(profilingLogger.Logger, examineManager);
|
||||
|
||||
RebuildIndexesOnStartup(profilingLogger.Logger);
|
||||
@@ -307,16 +305,191 @@ namespace Umbraco.Web.Search
|
||||
// branch
|
||||
if (payload.ChangeTypes.HasType(TreeChangeTypes.RefreshBranch))
|
||||
{
|
||||
var descendants = mediaService.GetDescendants(media);
|
||||
foreach (var descendant in descendants)
|
||||
const int pageSize = 500;
|
||||
var page = 0;
|
||||
var total = long.MaxValue;
|
||||
while (page * pageSize < total)
|
||||
{
|
||||
ReIndexForMedia(descendant, descendant.Trashed == false);
|
||||
var descendants = mediaService.GetPagedDescendants(media.Id, page++, pageSize, out total);
|
||||
foreach (var descendant in descendants)
|
||||
{
|
||||
ReIndexForMedia(descendant, descendant.Trashed == false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates indexes based on content type changes
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="args"></param>
|
||||
private void ContentTypeCacheRefresherUpdated(ContentTypeCacheRefresher sender, CacheRefresherEventArgs args)
|
||||
{
|
||||
if (Suspendable.ExamineEvents.CanIndex == false)
|
||||
return;
|
||||
|
||||
if (args.MessageType != MessageType.RefreshByPayload)
|
||||
throw new NotSupportedException();
|
||||
|
||||
var changedIds = new Dictionary<string, (List<int> removedIds, List<int> refreshedIds, List<int> otherIds)>();
|
||||
|
||||
foreach (var payload in (ContentTypeCacheRefresher.JsonPayload[])args.MessageObject)
|
||||
{
|
||||
if (!changedIds.TryGetValue(payload.ItemType, out var idLists))
|
||||
{
|
||||
idLists = (removedIds: new List<int>(), refreshedIds: new List<int>(), otherIds: new List<int>());
|
||||
changedIds.Add(payload.ItemType, idLists);
|
||||
}
|
||||
|
||||
if (payload.ChangeTypes.HasType(ContentTypeChangeTypes.Remove))
|
||||
idLists.removedIds.Add(payload.Id);
|
||||
else if (payload.ChangeTypes.HasType(ContentTypeChangeTypes.RefreshMain))
|
||||
idLists.refreshedIds.Add(payload.Id);
|
||||
else if (payload.ChangeTypes.HasType(ContentTypeChangeTypes.RefreshOther))
|
||||
idLists.otherIds.Add(payload.Id);
|
||||
}
|
||||
|
||||
const int pageSize = 500;
|
||||
|
||||
foreach(var ci in changedIds)
|
||||
{
|
||||
if (ci.Value.refreshedIds.Count > 0 || ci.Value.otherIds.Count > 0)
|
||||
{
|
||||
switch(ci.Key)
|
||||
{
|
||||
case var itemType when itemType == typeof(IContentType).Name:
|
||||
RefreshContentOfContentTypes(ci.Value.refreshedIds.Concat(ci.Value.otherIds).Distinct().ToArray());
|
||||
break;
|
||||
case var itemType when itemType == typeof(IMediaType).Name:
|
||||
RefreshMediaOfMediaTypes(ci.Value.refreshedIds.Concat(ci.Value.otherIds).Distinct().ToArray());
|
||||
break;
|
||||
case var itemType when itemType == typeof(IMemberType).Name:
|
||||
RefreshMemberOfMemberTypes(ci.Value.refreshedIds.Concat(ci.Value.otherIds).Distinct().ToArray());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//Delete all content of this content/media/member type that is in any content indexer by looking up matched examine docs
|
||||
foreach (var id in ci.Value.removedIds)
|
||||
{
|
||||
foreach (var index in _examineManager.IndexProviders.Values.OfType<UmbracoExamineIndexer>())
|
||||
{
|
||||
var searcher = index.GetSearcher();
|
||||
|
||||
var page = 0;
|
||||
var total = long.MaxValue;
|
||||
while (page * pageSize < total)
|
||||
{
|
||||
//paging with examine, see https://shazwazza.com/post/paging-with-examine/
|
||||
var results = searcher.Search(
|
||||
searcher.CreateCriteria().Field("nodeType", id).Compile(),
|
||||
maxResults: pageSize * (page + 1));
|
||||
total = results.TotalItemCount;
|
||||
var paged = results.Skip(page * pageSize);
|
||||
|
||||
foreach (var item in paged)
|
||||
if (int.TryParse(item.Id, out var contentId))
|
||||
DeleteIndexForEntity(contentId, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshMemberOfMemberTypes(int[] memberTypeIds)
|
||||
{
|
||||
const int pageSize = 500;
|
||||
|
||||
var memberTypes = _services.MemberTypeService.GetAll(memberTypeIds);
|
||||
foreach(var memberType in memberTypes)
|
||||
{
|
||||
var page = 0;
|
||||
var total = long.MaxValue;
|
||||
while (page * pageSize < total)
|
||||
{
|
||||
var memberToRefresh = _services.MemberService.GetAll(
|
||||
page++, pageSize, out total, "LoginName", Direction.Ascending,
|
||||
memberType.Alias);
|
||||
|
||||
foreach (var c in memberToRefresh)
|
||||
{
|
||||
ReIndexForMember(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshMediaOfMediaTypes(int[] mediaTypeIds)
|
||||
{
|
||||
const int pageSize = 500;
|
||||
var page = 0;
|
||||
var total = long.MaxValue;
|
||||
while (page * pageSize < total)
|
||||
{
|
||||
var mediaToRefresh = _services.MediaService.GetPagedOfTypes(
|
||||
//Re-index all content of these types
|
||||
mediaTypeIds,
|
||||
page++, pageSize, out total, null,
|
||||
Ordering.By("Path", Direction.Ascending));
|
||||
|
||||
foreach (var c in mediaToRefresh)
|
||||
{
|
||||
ReIndexForMedia(c, c.Trashed == false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshContentOfContentTypes(int[] contentTypeIds)
|
||||
{
|
||||
const int pageSize = 500;
|
||||
var page = 0;
|
||||
var total = long.MaxValue;
|
||||
while (page * pageSize < total)
|
||||
{
|
||||
var contentToRefresh = _services.ContentService.GetPagedOfTypes(
|
||||
//Re-index all content of these types
|
||||
contentTypeIds,
|
||||
page++, pageSize, out total, null,
|
||||
//order by shallowest to deepest, this allows us to check it's published state without checking every item
|
||||
Ordering.By("Path", Direction.Ascending));
|
||||
|
||||
//track which Ids have their paths are published
|
||||
var publishChecked = new Dictionary<int, bool>();
|
||||
|
||||
foreach (var c in contentToRefresh)
|
||||
{
|
||||
IContent published = null;
|
||||
if (c.Published)
|
||||
{
|
||||
if (publishChecked.TryGetValue(c.ParentId, out var isPublished))
|
||||
{
|
||||
//if the parent's published path has already been verified then this is published
|
||||
if (isPublished)
|
||||
published = c;
|
||||
}
|
||||
else
|
||||
{
|
||||
//nothing by parent id, so query the service and cache the result for the next child to check against
|
||||
isPublished = _services.ContentService.IsPathPublished(c);
|
||||
publishChecked[c.Id] = isPublished;
|
||||
if (isPublished)
|
||||
published = c;
|
||||
}
|
||||
}
|
||||
|
||||
ReIndexForContent(c, published);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates indexes based on content changes
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="args"></param>
|
||||
private void ContentCacheRefresherUpdated(ContentCacheRefresher sender, CacheRefresherEventArgs args)
|
||||
{
|
||||
if (Suspendable.ExamineEvents.CanIndex == false)
|
||||
@@ -340,6 +513,8 @@ namespace Umbraco.Web.Search
|
||||
// ExamineEvents does not support RefreshAll
|
||||
// just ignore that payload
|
||||
// so what?!
|
||||
|
||||
//fixme: Rebuild the index at this point?
|
||||
}
|
||||
else // RefreshNode or RefreshBranch (maybe trashed)
|
||||
{
|
||||
@@ -355,7 +530,7 @@ namespace Umbraco.Web.Search
|
||||
}
|
||||
|
||||
IContent published = null;
|
||||
if (content.Published && ((ContentService)contentService).IsPathPublished(content))
|
||||
if (content.Published && contentService.IsPathPublished(content))
|
||||
published = content;
|
||||
|
||||
// just that content
|
||||
@@ -365,19 +540,28 @@ namespace Umbraco.Web.Search
|
||||
if (payload.ChangeTypes.HasType(TreeChangeTypes.RefreshBranch))
|
||||
{
|
||||
var masked = published == null ? null : new List<int>();
|
||||
var descendants = contentService.GetDescendants(content);
|
||||
foreach (var descendant in descendants)
|
||||
const int pageSize = 500;
|
||||
var page = 0;
|
||||
var total = long.MaxValue;
|
||||
while(page * pageSize < total)
|
||||
{
|
||||
published = null;
|
||||
if (masked != null) // else everything is masked
|
||||
{
|
||||
if (masked.Contains(descendant.ParentId) || !descendant.Published)
|
||||
masked.Add(descendant.Id);
|
||||
else
|
||||
published = descendant;
|
||||
}
|
||||
var descendants = contentService.GetPagedDescendants(content.Id, page++, pageSize, out total,
|
||||
//order by shallowest to deepest, this allows us to check it's published state without checking every item
|
||||
ordering: Ordering.By("Path", Direction.Ascending));
|
||||
|
||||
ReIndexForContent(descendant, published);
|
||||
foreach (var descendant in descendants)
|
||||
{
|
||||
published = null;
|
||||
if (masked != null) // else everything is masked
|
||||
{
|
||||
if (masked.Contains(descendant.ParentId) || !descendant.Published)
|
||||
masked.Add(descendant.Id);
|
||||
else
|
||||
published = descendant;
|
||||
}
|
||||
|
||||
ReIndexForContent(descendant, published);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,10 +4,11 @@ using Umbraco.Core;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Entities;
|
||||
using Umbraco.Web.Actions;
|
||||
using Umbraco.Web.Models.Trees;
|
||||
using Umbraco.Web.Mvc;
|
||||
using Umbraco.Web.WebApi.Filters;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
using Constants = Umbraco.Core.Constants;
|
||||
|
||||
namespace Umbraco.Web.Trees
|
||||
@@ -95,9 +96,8 @@ namespace Umbraco.Web.Trees
|
||||
if (id == Constants.System.Root.ToInvariantString())
|
||||
{
|
||||
// root actions
|
||||
menu.Items.Add<ActionNew>(Services.TextService.Localize($"actions/{ActionNew.Instance.Alias}"));
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize(
|
||||
$"actions/{ActionRefresh.Instance.Alias}"), true);
|
||||
menu.Items.Add<ActionNew>(Services.TextService, opensDialog: true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
return menu;
|
||||
}
|
||||
var cte = Services.EntityService.Get(int.Parse(id), UmbracoObjectTypes.DocumentType);
|
||||
@@ -105,15 +105,15 @@ namespace Umbraco.Web.Trees
|
||||
if (cte != null)
|
||||
{
|
||||
var ct = Services.ContentTypeService.Get(cte.Id);
|
||||
var createItem = menu.Items.Add<ActionCreateBlueprintFromContent>(Services.TextService.Localize($"actions/{ActionCreateBlueprintFromContent.Instance.Alias}"));
|
||||
var createItem = menu.Items.Add<ActionCreateBlueprintFromContent>(Services.TextService, opensDialog: true);
|
||||
createItem.NavigateToRoute("/settings/contentBlueprints/edit/-1?create=true&doctype=" + ct.Alias);
|
||||
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize($"actions/{ActionRefresh.Instance.Alias}"), true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
menu.Items.Add<ActionDelete>(Services.TextService.Localize($"actions/{ActionDelete.Instance.Alias}"));
|
||||
menu.Items.Add<ActionDelete>(Services.TextService, opensDialog: true);
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
@@ -8,11 +8,12 @@ using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Entities;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Actions;
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Web.Models.Trees;
|
||||
using Umbraco.Web.Mvc;
|
||||
using Umbraco.Web.WebApi.Filters;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
using Umbraco.Web.Search;
|
||||
using Constants = Umbraco.Core.Constants;
|
||||
@@ -114,23 +115,21 @@ namespace Umbraco.Web.Trees
|
||||
// if the user's start node is not the root then the only menu item to display is refresh
|
||||
if (UserStartNodes.Contains(Constants.System.Root) == false)
|
||||
{
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(
|
||||
Services.TextService.Localize(string.Concat("actions/", ActionRefresh.Instance.Alias)),
|
||||
true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
return menu;
|
||||
}
|
||||
|
||||
//set the default to create
|
||||
menu.DefaultMenuAlias = ActionNew.Instance.Alias;
|
||||
menu.DefaultMenuAlias = ActionNew.ActionAlias;
|
||||
|
||||
// we need to get the default permissions as you can't set permissions on the very root node
|
||||
var permission = Services.UserService.GetPermissions(Security.CurrentUser, Constants.System.Root).First();
|
||||
var nodeActions = global::Umbraco.Web._Legacy.Actions.Action.FromEntityPermission(permission)
|
||||
var nodeActions = Current.Actions.FromEntityPermission(permission)
|
||||
.Select(x => new MenuItem(x));
|
||||
|
||||
//these two are the standard items
|
||||
menu.Items.Add<ActionNew>(Services.TextService.Localize("actions", ActionNew.Instance.Alias));
|
||||
menu.Items.Add<ActionSort>(Services.TextService.Localize("actions", ActionSort.Instance.Alias), true);
|
||||
menu.Items.Add<ActionNew>(Services.TextService, opensDialog: true);
|
||||
menu.Items.Add<ActionSort>(Services.TextService, true);
|
||||
|
||||
//filter the standard items
|
||||
FilterUserAllowedMenuItems(menu, nodeActions);
|
||||
@@ -143,7 +142,7 @@ namespace Umbraco.Web.Trees
|
||||
// add default actions for *all* users
|
||||
// fixme - temp disable RePublish as the page itself (republish.aspx) has been temp disabled
|
||||
//menu.Items.Add<ActionRePublish>(Services.TextService.Localize("actions", ActionRePublish.Instance.Alias)).ConvertLegacyMenuItem(null, "content", "content");
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
|
||||
return menu;
|
||||
}
|
||||
@@ -165,9 +164,7 @@ namespace Umbraco.Web.Trees
|
||||
if (Security.CurrentUser.HasPathAccess(item, Services.EntityService, RecycleBinId) == false)
|
||||
{
|
||||
var menu = new MenuItemCollection();
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(
|
||||
Services.TextService.Localize(string.Concat("actions/", ActionRefresh.Instance.Alias)),
|
||||
true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
return menu;
|
||||
}
|
||||
|
||||
@@ -182,7 +179,7 @@ namespace Umbraco.Web.Trees
|
||||
else
|
||||
{
|
||||
//set the default to create
|
||||
nodeMenu.DefaultMenuAlias = ActionNew.Instance.Alias;
|
||||
nodeMenu.DefaultMenuAlias = ActionNew.ActionAlias;
|
||||
}
|
||||
|
||||
var allowedMenuItems = GetAllowedUserMenuItemsForNode(item);
|
||||
@@ -228,25 +225,25 @@ namespace Umbraco.Web.Trees
|
||||
protected MenuItemCollection GetAllNodeMenuItems(IUmbracoEntity item)
|
||||
{
|
||||
var menu = new MenuItemCollection();
|
||||
AddActionNode<ActionNew>(item, menu);
|
||||
AddActionNode<ActionDelete>(item, menu);
|
||||
|
||||
AddActionNode<ActionCreateBlueprintFromContent>(item, menu);
|
||||
|
||||
//need to ensure some of these are converted to the legacy system - until we upgrade them all to be angularized.
|
||||
AddActionNode<ActionMove>(item, menu, true);
|
||||
AddActionNode<ActionCopy>(item, menu);
|
||||
|
||||
AddActionNode<ActionNew>(item, menu, opensDialog: true);
|
||||
AddActionNode<ActionDelete>(item, menu, opensDialog: true);
|
||||
AddActionNode<ActionCreateBlueprintFromContent>(item, menu, opensDialog: true);
|
||||
AddActionNode<ActionMove>(item, menu, true, opensDialog: true);
|
||||
AddActionNode<ActionCopy>(item, menu, opensDialog: true);
|
||||
AddActionNode<ActionSort>(item, menu, true);
|
||||
AddActionNode<ActionAssignDomain>(item, menu, opensDialog: true);
|
||||
AddActionNode<ActionRights>(item, menu, opensDialog: true);
|
||||
//fixme - conver this editor to angular
|
||||
AddActionNode<ActionProtect>(item, menu, true, convert: true, opensDialog: true);
|
||||
|
||||
AddActionNode<ActionToPublish>(item, menu, convert: true);
|
||||
AddActionNode<ActionAssignDomain>(item, menu);
|
||||
AddActionNode<ActionRights>(item, menu, convert: true);
|
||||
AddActionNode<ActionProtect>(item, menu, true, true);
|
||||
|
||||
AddActionNode<ActionNotify>(item, menu, true);
|
||||
menu.Items.Add(new MenuItem("notify", Services.TextService)
|
||||
{
|
||||
Icon = "megaphone",
|
||||
SeperatorBefore = true,
|
||||
OpensDialog = true
|
||||
});
|
||||
|
||||
AddActionNode<RefreshNode, ActionRefresh>(item, menu, true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
|
||||
return menu;
|
||||
}
|
||||
@@ -259,10 +256,10 @@ namespace Umbraco.Web.Trees
|
||||
protected MenuItemCollection GetNodeMenuItemsForDeletedContent(IUmbracoEntity item)
|
||||
{
|
||||
var menu = new MenuItemCollection();
|
||||
menu.Items.Add<ActionRestore>(Services.TextService.Localize("actions", ActionRestore.Instance.Alias));
|
||||
menu.Items.Add<ActionDelete>(Services.TextService.Localize("actions", ActionDelete.Instance.Alias));
|
||||
menu.Items.Add<ActionRestore>(Services.TextService, opensDialog: true);
|
||||
menu.Items.Add<ActionDelete>(Services.TextService, opensDialog: true);
|
||||
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
|
||||
return menu;
|
||||
}
|
||||
@@ -306,19 +303,14 @@ namespace Umbraco.Web.Trees
|
||||
entity.Name = "[[" + entity.Id + "]]";
|
||||
}
|
||||
|
||||
private void AddActionNode<TAction>(IUmbracoEntity item, MenuItemCollection menu, bool hasSeparator = false, bool convert = false)
|
||||
//fixme: Remove the need for converting to legacy
|
||||
private void AddActionNode<TAction>(IUmbracoEntity item, MenuItemCollection menu, bool hasSeparator = false, bool convert = false, bool opensDialog = false)
|
||||
where TAction : IAction
|
||||
{
|
||||
//fixme: Inject
|
||||
var menuItem = menu.Items.Add<TAction>(Services.TextService.Localize("actions", Current.Actions.GetAction<TAction>().Alias), hasSeparator);
|
||||
if (convert) menuItem.ConvertLegacyMenuItem(item, "content", "content");
|
||||
}
|
||||
|
||||
private void AddActionNode<TItem, TAction>(IUmbracoEntity item, MenuItemCollection menu, bool hasSeparator = false, bool convert = false)
|
||||
where TItem : MenuItem, new()
|
||||
where TAction : IAction
|
||||
{
|
||||
var menuItem = menu.Items.Add<TItem, TAction>(Services.TextService.Localize("actions", Current.Actions.GetAction<TAction>().Alias), hasSeparator);
|
||||
if (convert) menuItem.ConvertLegacyMenuItem(item, "content", "content");
|
||||
menuItem.OpensDialog = opensDialog;
|
||||
}
|
||||
|
||||
public IEnumerable<SearchResultItem> Search(string query, int pageSize, long pageIndex, out long totalFound, string searchFrom = null)
|
||||
|
||||
@@ -14,7 +14,9 @@ using Umbraco.Web.Models.Trees;
|
||||
using Umbraco.Web.WebApi.Filters;
|
||||
using System.Globalization;
|
||||
using Umbraco.Core.Models.Entities;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
using Umbraco.Web.Actions;
|
||||
using Umbraco.Web.Composing;
|
||||
|
||||
|
||||
namespace Umbraco.Web.Trees
|
||||
{
|
||||
@@ -347,8 +349,12 @@ namespace Umbraco.Web.Trees
|
||||
if (RecycleBinId.ToInvariantString() == id)
|
||||
{
|
||||
var menu = new MenuItemCollection();
|
||||
menu.Items.Add<ActionEmptyTranscan>(Services.TextService.Localize("actions/emptyTrashcan"));
|
||||
menu.Items.Add<ActionRefresh>(Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true);
|
||||
menu.Items.Add(new MenuItem("emptyRecycleBin", Services.TextService)
|
||||
{
|
||||
Icon = "trash",
|
||||
OpensDialog = true
|
||||
});
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
return menu;
|
||||
}
|
||||
|
||||
@@ -381,13 +387,16 @@ namespace Umbraco.Web.Trees
|
||||
internal IEnumerable<MenuItem> GetAllowedUserMenuItemsForNode(IUmbracoEntity dd)
|
||||
{
|
||||
var permission = Services.UserService.GetPermissions(Security.CurrentUser, dd.Path);
|
||||
var actions = global::Umbraco.Web._Legacy.Actions.Action.FromEntityPermission(permission)
|
||||
//fixme: inject
|
||||
var actions = Current.Actions.FromEntityPermission(permission)
|
||||
.ToList();
|
||||
|
||||
var actionDelete = Current.Actions.GetAction<ActionDelete>();
|
||||
|
||||
// A user is allowed to delete their own stuff
|
||||
var tryGetCurrentUserId = Security.GetUserId();
|
||||
if (tryGetCurrentUserId && dd.CreatorId == tryGetCurrentUserId.Result && actions.Contains(ActionDelete.Instance) == false)
|
||||
actions.Add(ActionDelete.Instance);
|
||||
if (tryGetCurrentUserId && dd.CreatorId == tryGetCurrentUserId.Result && actions.Contains(actionDelete) == false)
|
||||
actions.Add(actionDelete);
|
||||
|
||||
return actions.Select(x => new MenuItem(x));
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ using Umbraco.Core;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
using Umbraco.Web.Actions;
|
||||
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
using Umbraco.Web.Models.Trees;
|
||||
using Umbraco.Web.WebApi.Filters;
|
||||
@@ -77,12 +78,18 @@ namespace Umbraco.Web.Trees
|
||||
if (id == Constants.System.Root.ToInvariantString())
|
||||
{
|
||||
//set the default to create
|
||||
menu.DefaultMenuAlias = ActionNew.Instance.Alias;
|
||||
menu.DefaultMenuAlias = ActionNew.ActionAlias;
|
||||
|
||||
// root actions
|
||||
menu.Items.Add<ActionNew>(Services.TextService.Localize(string.Format("actions/{0}", ActionNew.Instance.Alias)));
|
||||
menu.Items.Add<ActionImport>(Services.TextService.Localize(string.Format("actions/{0}", ActionImport.Instance.Alias)), true);
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize(string.Format("actions/{0}", ActionRefresh.Instance.Alias)), true);
|
||||
menu.Items.Add<ActionNew>(Services.TextService, opensDialog: true);
|
||||
menu.Items.Add(new MenuItem("importDocumentType", Services.TextService)
|
||||
{
|
||||
Icon = "page-up",
|
||||
SeperatorBefore = true,
|
||||
OpensDialog = true
|
||||
});
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
@@ -90,11 +97,11 @@ namespace Umbraco.Web.Trees
|
||||
if (container != null)
|
||||
{
|
||||
//set the default to create
|
||||
menu.DefaultMenuAlias = ActionNew.Instance.Alias;
|
||||
menu.DefaultMenuAlias = ActionNew.ActionAlias;
|
||||
|
||||
menu.Items.Add<ActionNew>(Services.TextService.Localize(string.Format("actions/{0}", ActionNew.Instance.Alias)));
|
||||
menu.Items.Add<ActionNew>(Services.TextService, opensDialog: true);
|
||||
|
||||
menu.Items.Add(new MenuItem("rename", Services.TextService.Localize(String.Format("actions/{0}", "rename")))
|
||||
menu.Items.Add(new MenuItem("rename", Services.TextService)
|
||||
{
|
||||
Icon = "icon icon-edit"
|
||||
});
|
||||
@@ -102,11 +109,9 @@ namespace Umbraco.Web.Trees
|
||||
if (container.HasChildren == false)
|
||||
{
|
||||
//can delete doc type
|
||||
menu.Items.Add<ActionDelete>(Services.TextService.Localize(string.Format("actions/{0}", ActionDelete.Instance.Alias)), true);
|
||||
menu.Items.Add<ActionDelete>(Services.TextService, true, opensDialog: true);
|
||||
}
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize(string.Format("actions/{0}", ActionRefresh.Instance.Alias)), true);
|
||||
|
||||
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -115,18 +120,23 @@ namespace Umbraco.Web.Trees
|
||||
|
||||
if (enableInheritedDocumentTypes)
|
||||
{
|
||||
menu.Items.Add<ActionNew>(Services.TextService.Localize(string.Format("actions/{0}", ActionNew.Instance.Alias)));
|
||||
menu.Items.Add<ActionNew>(Services.TextService, opensDialog: true);
|
||||
}
|
||||
//no move action if this is a child doc type
|
||||
if (parent == null)
|
||||
{
|
||||
menu.Items.Add<ActionMove>(Services.TextService.Localize(string.Format("actions/{0}", ActionMove.Instance.Alias)), true);
|
||||
menu.Items.Add<ActionMove>(Services.TextService, true, opensDialog: true);
|
||||
}
|
||||
menu.Items.Add<ActionCopy>(Services.TextService.Localize(string.Format("actions/{0}", ActionCopy.Instance.Alias)));
|
||||
menu.Items.Add<ActionExport>(Services.TextService.Localize(string.Format("actions/{0}", ActionExport.Instance.Alias)), true);
|
||||
menu.Items.Add<ActionDelete>(Services.TextService.Localize(string.Format("actions/{0}", ActionDelete.Instance.Alias)), true);
|
||||
menu.Items.Add<ActionCopy>(Services.TextService, opensDialog: true);
|
||||
menu.Items.Add(new MenuItem("export", Services.TextService)
|
||||
{
|
||||
Icon = "download-alt",
|
||||
SeperatorBefore = true,
|
||||
OpensDialog = true
|
||||
});
|
||||
menu.Items.Add<ActionDelete>(Services.TextService, true, opensDialog: true);
|
||||
if (enableInheritedDocumentTypes)
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize(string.Format("actions/{0}", ActionRefresh.Instance.Alias)), true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
}
|
||||
|
||||
return menu;
|
||||
|
||||
@@ -9,9 +9,10 @@ using Umbraco.Web.Models.Trees;
|
||||
using Umbraco.Web.Mvc;
|
||||
using Umbraco.Web.WebApi.Filters;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Actions;
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
using Umbraco.Web.Search;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
using Constants = Umbraco.Core.Constants;
|
||||
|
||||
namespace Umbraco.Web.Trees
|
||||
@@ -100,11 +101,11 @@ namespace Umbraco.Web.Trees
|
||||
if (id == Constants.System.Root.ToInvariantString())
|
||||
{
|
||||
//set the default to create
|
||||
menu.DefaultMenuAlias = ActionNew.Instance.Alias;
|
||||
menu.DefaultMenuAlias = ActionNew.ActionAlias;
|
||||
|
||||
// root actions
|
||||
menu.Items.Add<ActionNew>(Services.TextService.Localize($"actions/{ActionNew.Instance.Alias}"));
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true);
|
||||
menu.Items.Add<ActionNew>(Services.TextService, opensDialog: true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
return menu;
|
||||
}
|
||||
|
||||
@@ -112,9 +113,9 @@ namespace Umbraco.Web.Trees
|
||||
if (container != null)
|
||||
{
|
||||
//set the default to create
|
||||
menu.DefaultMenuAlias = ActionNew.Instance.Alias;
|
||||
menu.DefaultMenuAlias = ActionNew.ActionAlias;
|
||||
|
||||
menu.Items.Add<ActionNew>(Services.TextService.Localize($"actions/{ActionNew.Instance.Alias}"));
|
||||
menu.Items.Add<ActionNew>(Services.TextService, opensDialog: true);
|
||||
|
||||
menu.Items.Add(new MenuItem("rename", Services.TextService.Localize("actions/rename"))
|
||||
{
|
||||
@@ -124,19 +125,18 @@ namespace Umbraco.Web.Trees
|
||||
if (container.HasChildren == false)
|
||||
{
|
||||
//can delete data type
|
||||
menu.Items.Add<ActionDelete>(Services.TextService.Localize($"actions/{ActionDelete.Instance.Alias}"));
|
||||
menu.Items.Add<ActionDelete>(Services.TextService, opensDialog: true);
|
||||
}
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize(
|
||||
$"actions/{ActionRefresh.Instance.Alias}"), hasSeparator: true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
}
|
||||
else
|
||||
{
|
||||
var nonDeletableSystemDataTypeIds = GetNonDeletableSystemDataTypeIds();
|
||||
|
||||
if (nonDeletableSystemDataTypeIds.Contains(int.Parse(id)) == false)
|
||||
menu.Items.Add<ActionDelete>(Services.TextService.Localize($"actions/{ActionDelete.Instance.Alias}"));
|
||||
menu.Items.Add<ActionDelete>(Services.TextService, opensDialog: true);
|
||||
|
||||
menu.Items.Add<ActionMove>(Services.TextService.Localize($"actions/{ActionMove.Instance.Alias}"), hasSeparator: true);
|
||||
menu.Items.Add<ActionMove>(Services.TextService, hasSeparator: true, opensDialog: true);
|
||||
}
|
||||
|
||||
return menu;
|
||||
|
||||
@@ -3,7 +3,8 @@ using System.Linq;
|
||||
using System.Net.Http.Formatting;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
using Umbraco.Web.Actions;
|
||||
|
||||
using Umbraco.Web.Models.Trees;
|
||||
using Umbraco.Web.WebApi.Filters;
|
||||
|
||||
@@ -95,14 +96,12 @@ namespace Umbraco.Web.Trees
|
||||
{
|
||||
var menu = new MenuItemCollection();
|
||||
|
||||
menu.Items.Add<ActionNew>(Services.TextService.Localize($"actions/{ActionNew.Instance.Alias}"));
|
||||
menu.Items.Add<ActionNew>(Services.TextService, opensDialog: true);
|
||||
|
||||
if (id != Constants.System.Root.ToInvariantString())
|
||||
menu.Items.Add<ActionDelete>(Services.TextService.Localize(
|
||||
$"actions/{ActionDelete.Instance.Alias}"), true);
|
||||
menu.Items.Add<ActionDelete>(Services.TextService, true, opensDialog: true);
|
||||
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize(
|
||||
$"actions/{ActionRefresh.Instance.Alias}"), true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
@@ -7,8 +7,9 @@ using System.Web;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Actions;
|
||||
using Umbraco.Web.Models.Trees;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
using Constants = Umbraco.Core.Constants;
|
||||
|
||||
namespace Umbraco.Web.Trees
|
||||
@@ -87,11 +88,11 @@ namespace Umbraco.Web.Trees
|
||||
var menu = new MenuItemCollection();
|
||||
|
||||
//set the default to create
|
||||
menu.DefaultMenuAlias = ActionNew.Instance.Alias;
|
||||
menu.DefaultMenuAlias = ActionNew.ActionAlias;
|
||||
//create action
|
||||
menu.Items.Add<ActionNew>(Services.TextService.Localize(string.Format("actions/{0}", ActionNew.Instance.Alias)));
|
||||
menu.Items.Add<ActionNew>(Services.TextService, opensDialog: true);
|
||||
//refresh action
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize(string.Format("actions/{0}", ActionRefresh.Instance.Alias)), true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
|
||||
return menu;
|
||||
}
|
||||
@@ -101,9 +102,9 @@ namespace Umbraco.Web.Trees
|
||||
var menu = new MenuItemCollection();
|
||||
|
||||
//set the default to create
|
||||
menu.DefaultMenuAlias = ActionNew.Instance.Alias;
|
||||
menu.DefaultMenuAlias = ActionNew.ActionAlias;
|
||||
//create action
|
||||
menu.Items.Add<ActionNew>(Services.TextService.Localize(string.Format("actions/{0}", ActionNew.Instance.Alias)));
|
||||
menu.Items.Add<ActionNew>(Services.TextService, opensDialog: true);
|
||||
|
||||
var hasChildren = FileSystem.GetFiles(path).Any() || FileSystem.GetDirectories(path).Any();
|
||||
|
||||
@@ -111,11 +112,11 @@ namespace Umbraco.Web.Trees
|
||||
if (hasChildren == false)
|
||||
{
|
||||
//delete action
|
||||
menu.Items.Add<ActionDelete>(Services.TextService.Localize(string.Format("actions/{0}", ActionDelete.Instance.Alias)), true);
|
||||
menu.Items.Add<ActionDelete>(Services.TextService, true, opensDialog: true);
|
||||
}
|
||||
|
||||
//refresh action
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize(string.Format("actions/{0}", ActionRefresh.Instance.Alias)), true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
|
||||
return menu;
|
||||
}
|
||||
@@ -125,7 +126,7 @@ namespace Umbraco.Web.Trees
|
||||
var menu = new MenuItemCollection();
|
||||
|
||||
//if it's not a directory then we only allow to delete the item
|
||||
menu.Items.Add<ActionDelete>(Services.TextService.Localize(string.Format("actions/{0}", ActionDelete.Instance.Alias)));
|
||||
menu.Items.Add<ActionDelete>(Services.TextService, opensDialog: true);
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,8 @@ using System.Web.Http.Routing;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
using Umbraco.Web.Actions;
|
||||
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Web.Models.Trees;
|
||||
|
||||
@@ -17,6 +18,8 @@ namespace Umbraco.Web.Trees
|
||||
/// </summary>
|
||||
internal class LegacyTreeDataConverter
|
||||
{
|
||||
//fixme: remove this whole class when everything is angularized
|
||||
|
||||
/// <summary>
|
||||
/// This will look at the legacy IAction's JsFunctionName and convert it to a confirmation dialog view if possible
|
||||
/// </summary>
|
||||
@@ -24,14 +27,9 @@ namespace Umbraco.Web.Trees
|
||||
/// <returns></returns>
|
||||
internal static Attempt<string> GetLegacyConfirmView(IAction action)
|
||||
{
|
||||
if (action.JsFunctionName.IsNullOrWhiteSpace())
|
||||
switch (action)
|
||||
{
|
||||
return Attempt<string>.Fail();
|
||||
}
|
||||
|
||||
switch (action.JsFunctionName)
|
||||
{
|
||||
case "UmbClientMgr.appActions().actionDelete()":
|
||||
case ActionDelete actionDelete:
|
||||
return Attempt.Succeed(
|
||||
UmbracoConfig.For.GlobalSettings().Path.EnsureEndsWith('/') + "views/common/dialogs/legacydelete.html");
|
||||
}
|
||||
@@ -49,64 +47,18 @@ namespace Umbraco.Web.Trees
|
||||
/// <param name="nodeType"></param>
|
||||
internal static Attempt<LegacyUrlAction> GetUrlAndTitleFromLegacyAction(IAction action, string nodeId, string nodeType, string nodeName, string currentSection)
|
||||
{
|
||||
if (action.JsFunctionName.IsNullOrWhiteSpace())
|
||||
switch (action)
|
||||
{
|
||||
return Attempt<LegacyUrlAction>.Fail();
|
||||
}
|
||||
|
||||
switch (action.JsFunctionName)
|
||||
{
|
||||
case "UmbClientMgr.appActions().actionNew()":
|
||||
case ActionNew actionNew:
|
||||
return Attempt.Succeed(
|
||||
new LegacyUrlAction(
|
||||
"create.aspx?nodeId=" + nodeId + "&nodeType=" + nodeType + "&nodeName=" + nodeName + "&rnd=" + DateTime.UtcNow.Ticks,
|
||||
Current.Services.TextService.Localize("actions/create")));
|
||||
case "UmbClientMgr.appActions().actionNewFolder()":
|
||||
return Attempt.Succeed(
|
||||
new LegacyUrlAction(
|
||||
"createFolder.aspx?nodeId=" + nodeId + "&nodeType=" + nodeType + "&nodeName=" + nodeName + "&rnd=" + DateTime.UtcNow.Ticks,
|
||||
Current.Services.TextService.Localize("actions/create")));
|
||||
case "UmbClientMgr.appActions().actionProtect()":
|
||||
case ActionProtect actionProtect:
|
||||
return Attempt.Succeed(
|
||||
new LegacyUrlAction(
|
||||
"dialogs/protectPage.aspx?mode=cut&nodeId=" + nodeId + "&rnd=" + DateTime.UtcNow.Ticks,
|
||||
Current.Services.TextService.Localize("actions/protect")));
|
||||
case "UmbClientMgr.appActions().actionRollback()":
|
||||
return Attempt.Succeed(
|
||||
new LegacyUrlAction(
|
||||
"dialogs/rollback.aspx?nodeId=" + nodeId + "&rnd=" + DateTime.UtcNow.Ticks,
|
||||
Current.Services.TextService.Localize("actions/rollback")));
|
||||
case "UmbClientMgr.appActions().actionNotify()":
|
||||
return Attempt.Succeed(
|
||||
new LegacyUrlAction(
|
||||
"dialogs/notifications.aspx?id=" + nodeId + "&rnd=" + DateTime.UtcNow.Ticks,
|
||||
Current.Services.TextService.Localize("actions/notify")));
|
||||
case "UmbClientMgr.appActions().actionPublish()":
|
||||
return Attempt.Succeed(
|
||||
new LegacyUrlAction(
|
||||
"dialogs/publish.aspx?id=" + nodeId + "&rnd=" + DateTime.UtcNow.Ticks,
|
||||
Current.Services.TextService.Localize("actions/publish")));
|
||||
case "UmbClientMgr.appActions().actionChangeDocType()":
|
||||
return Attempt.Succeed(
|
||||
new LegacyUrlAction(
|
||||
"dialogs/ChangeDocType.aspx?id=" + nodeId + "&rnd=" + DateTime.UtcNow.Ticks,
|
||||
Current.Services.TextService.Localize("actions/changeDocType")));
|
||||
case "UmbClientMgr.appActions().actionToPublish()":
|
||||
return Attempt.Succeed(
|
||||
new LegacyUrlAction(
|
||||
"dialogs/SendPublish.aspx?id=" + nodeId + "&rnd=" + DateTime.UtcNow.Ticks,
|
||||
Current.Services.TextService.Localize("actions/sendtopublish")));
|
||||
case "UmbClientMgr.appActions().actionRePublish()":
|
||||
return Attempt.Succeed(
|
||||
new LegacyUrlAction(
|
||||
"dialogs/republish.aspx?rnd=" + DateTime.UtcNow.Ticks,
|
||||
Current.Services.TextService.Localize("actions/republish")));
|
||||
case "UmbClientMgr.appActions().actionSendToTranslate()":
|
||||
return Attempt.Succeed(
|
||||
new LegacyUrlAction(
|
||||
"dialogs/sendToTranslation.aspx?id=" + nodeId + "&rnd=" + DateTime.UtcNow.Ticks,
|
||||
Current.Services.TextService.Localize("actions/sendToTranslate")));
|
||||
|
||||
}
|
||||
return Attempt<LegacyUrlAction>.Fail();
|
||||
}
|
||||
|
||||
@@ -8,7 +8,8 @@ using Umbraco.Web.Models.Trees;
|
||||
using Umbraco.Web.Mvc;
|
||||
using Umbraco.Web.WebApi.Filters;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
using Umbraco.Web.Actions;
|
||||
|
||||
using Constants = Umbraco.Core.Constants;
|
||||
|
||||
namespace Umbraco.Web.Trees
|
||||
@@ -58,13 +59,13 @@ namespace Umbraco.Web.Trees
|
||||
if (id == Constants.System.Root.ToInvariantString())
|
||||
{
|
||||
//Create the normal create action
|
||||
menu.Items.Add<ActionNew>(Services.TextService.Localize("actions", ActionNew.Instance.Alias))
|
||||
menu.Items.Add<ActionNew>(Services.TextService, opensDialog: true)
|
||||
//Since we haven't implemented anything for macros in angular, this needs to be converted to
|
||||
//use the legacy format
|
||||
.ConvertLegacyMenuItem(null, "initmacros", queryStrings.GetValue<string>("application"));
|
||||
|
||||
//refresh action
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
|
||||
return menu;
|
||||
}
|
||||
@@ -74,7 +75,7 @@ namespace Umbraco.Web.Trees
|
||||
if (macro == null) return new MenuItemCollection();
|
||||
|
||||
//add delete option for all macros
|
||||
menu.Items.Add<ActionDelete>(Services.TextService.Localize("actions", ActionDelete.Instance.Alias))
|
||||
menu.Items.Add<ActionDelete>(Services.TextService, opensDialog: true)
|
||||
//Since we haven't implemented anything for macros in angular, this needs to be converted to
|
||||
//use the legacy format
|
||||
.ConvertLegacyMenuItem(new EntitySlim
|
||||
|
||||
@@ -8,10 +8,12 @@ using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Entities;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Actions;
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Web.Models.Trees;
|
||||
using Umbraco.Web.Mvc;
|
||||
using Umbraco.Web.WebApi.Filters;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
using Umbraco.Web.Search;
|
||||
using Constants = Umbraco.Core.Constants;
|
||||
@@ -81,28 +83,25 @@ namespace Umbraco.Web.Trees
|
||||
var menu = new MenuItemCollection();
|
||||
|
||||
//set the default
|
||||
menu.DefaultMenuAlias = ActionNew.Instance.Alias;
|
||||
menu.DefaultMenuAlias = ActionNew.ActionAlias;
|
||||
|
||||
if (id == Constants.System.Root.ToInvariantString())
|
||||
{
|
||||
// if the user's start node is not the root then the only menu item to display is refresh
|
||||
if (UserStartNodes.Contains(Constants.System.Root) == false)
|
||||
{
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(
|
||||
Services.TextService.Localize(string.Concat("actions/", ActionRefresh.Instance.Alias)),
|
||||
true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
return menu;
|
||||
}
|
||||
|
||||
// root actions
|
||||
menu.Items.Add<ActionNew>(Services.TextService.Localize("actions", ActionNew.Instance.Alias));
|
||||
menu.Items.Add<ActionSort>(Services.TextService.Localize("actions", ActionSort.Instance.Alias), true);
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true);
|
||||
menu.Items.Add<ActionNew>(Services.TextService, opensDialog: true);
|
||||
menu.Items.Add<ActionSort>(Services.TextService, true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
return menu;
|
||||
}
|
||||
|
||||
int iid;
|
||||
if (int.TryParse(id, out iid) == false)
|
||||
if (int.TryParse(id, out var iid) == false)
|
||||
{
|
||||
throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||
}
|
||||
@@ -115,29 +114,30 @@ namespace Umbraco.Web.Trees
|
||||
//if the user has no path access for this node, all they can do is refresh
|
||||
if (Security.CurrentUser.HasPathAccess(item, Services.EntityService, RecycleBinId) == false)
|
||||
{
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(
|
||||
Services.TextService.Localize(string.Concat("actions/", ActionRefresh.Instance.Alias)),
|
||||
true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
return menu;
|
||||
}
|
||||
|
||||
//return a normal node menu:
|
||||
menu.Items.Add<ActionNew>(Services.TextService.Localize("actions", ActionNew.Instance.Alias));
|
||||
menu.Items.Add<ActionMove>(Services.TextService.Localize("actions", ActionMove.Instance.Alias));
|
||||
menu.Items.Add<ActionDelete>(Services.TextService.Localize("actions", ActionDelete.Instance.Alias));
|
||||
menu.Items.Add<ActionSort>(Services.TextService.Localize("actions", ActionSort.Instance.Alias));
|
||||
menu.Items.Add<ActionRefresh>(Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true);
|
||||
menu.Items.Add<ActionNew>(Services.TextService, opensDialog: true);
|
||||
menu.Items.Add<ActionMove>(Services.TextService, opensDialog: true);
|
||||
menu.Items.Add<ActionDelete>(Services.TextService, opensDialog: true);
|
||||
menu.Items.Add<ActionSort>(Services.TextService);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
|
||||
//if the media item is in the recycle bin, don't have a default menu, just show the regular menu
|
||||
if (item.Path.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries).Contains(RecycleBinId.ToInvariantString()))
|
||||
{
|
||||
menu.DefaultMenuAlias = null;
|
||||
menu.Items.Insert(2, new MenuItem(ActionRestore.Instance, Services.TextService.Localize("actions", ActionRestore.Instance.Alias)));
|
||||
menu.Items.Insert(2, new MenuItem(ActionRestore.ActionAlias, Services.TextService)
|
||||
{
|
||||
OpensDialog = true
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
//set the default to create
|
||||
menu.DefaultMenuAlias = ActionNew.Instance.Alias;
|
||||
menu.DefaultMenuAlias = ActionNew.ActionAlias;
|
||||
}
|
||||
|
||||
return menu;
|
||||
|
||||
@@ -9,8 +9,9 @@ using Umbraco.Core.Models;
|
||||
using Umbraco.Web.Models.Trees;
|
||||
using Umbraco.Web.WebApi.Filters;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Actions;
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
using Umbraco.Web.Search;
|
||||
|
||||
namespace Umbraco.Web.Trees
|
||||
@@ -70,12 +71,11 @@ namespace Umbraco.Web.Trees
|
||||
if (id == Constants.System.Root.ToInvariantString())
|
||||
{
|
||||
//set the default to create
|
||||
menu.DefaultMenuAlias = ActionNew.Instance.Alias;
|
||||
menu.DefaultMenuAlias = ActionNew.ActionAlias;
|
||||
|
||||
// root actions
|
||||
menu.Items.Add<ActionNew>(Services.TextService.Localize($"actions/{ActionNew.Instance.Alias}"));
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize(
|
||||
$"actions/{ActionRefresh.Instance.Alias}"));
|
||||
menu.Items.Add<ActionNew>(Services.TextService, opensDialog: true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService));
|
||||
return menu;
|
||||
}
|
||||
|
||||
@@ -83,9 +83,9 @@ namespace Umbraco.Web.Trees
|
||||
if (container != null)
|
||||
{
|
||||
//set the default to create
|
||||
menu.DefaultMenuAlias = ActionNew.Instance.Alias;
|
||||
menu.DefaultMenuAlias = ActionNew.ActionAlias;
|
||||
|
||||
menu.Items.Add<ActionNew>(Services.TextService.Localize($"actions/{ActionNew.Instance.Alias}"));
|
||||
menu.Items.Add<ActionNew>(Services.TextService, opensDialog: true);
|
||||
|
||||
menu.Items.Add(new MenuItem("rename", Services.TextService.Localize("actions/rename"))
|
||||
{
|
||||
@@ -95,10 +95,9 @@ namespace Umbraco.Web.Trees
|
||||
if (container.HasChildren == false)
|
||||
{
|
||||
//can delete doc type
|
||||
menu.Items.Add<ActionDelete>(Services.TextService.Localize($"actions/{ActionDelete.Instance.Alias}"));
|
||||
menu.Items.Add<ActionDelete>(Services.TextService, opensDialog: true);
|
||||
}
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize(
|
||||
$"actions/{ActionRefresh.Instance.Alias}"), hasSeparator: true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -107,29 +106,28 @@ namespace Umbraco.Web.Trees
|
||||
|
||||
if (enableInheritedMediaTypes)
|
||||
{
|
||||
menu.Items.Add<ActionNew>(Services.TextService.Localize($"actions/{ActionNew.Instance.Alias}"));
|
||||
menu.Items.Add<ActionNew>(Services.TextService, opensDialog: true);
|
||||
|
||||
//no move action if this is a child doc type
|
||||
if (parent == null)
|
||||
{
|
||||
menu.Items.Add<ActionMove>(Services.TextService.Localize($"actions/{ActionMove.Instance.Alias}"), true);
|
||||
menu.Items.Add<ActionMove>(Services.TextService, true, opensDialog: true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
menu.Items.Add<ActionMove>(Services.TextService.Localize($"actions/{ActionMove.Instance.Alias}"));
|
||||
menu.Items.Add<ActionMove>(Services.TextService, opensDialog: true);
|
||||
//no move action if this is a child doc type
|
||||
if (parent == null)
|
||||
{
|
||||
menu.Items.Add<ActionMove>(Services.TextService.Localize($"actions/{ActionMove.Instance.Alias}"), true);
|
||||
menu.Items.Add<ActionMove>(Services.TextService, true, opensDialog: true);
|
||||
}
|
||||
}
|
||||
|
||||
menu.Items.Add<ActionCopy>(Services.TextService.Localize($"actions/{ActionCopy.Instance.Alias}"));
|
||||
menu.Items.Add<ActionDelete>(Services.TextService.Localize($"actions/{ActionDelete.Instance.Alias}"));
|
||||
menu.Items.Add<ActionCopy>(Services.TextService, opensDialog: true);
|
||||
menu.Items.Add<ActionDelete>(Services.TextService, opensDialog: true);
|
||||
if (enableInheritedMediaTypes)
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize(
|
||||
$"actions/{ActionRefresh.Instance.Alias}"), true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
}
|
||||
|
||||
return menu;
|
||||
|
||||
@@ -10,10 +10,11 @@ using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Security;
|
||||
using Umbraco.Web.Actions;
|
||||
using Umbraco.Web.Models.Trees;
|
||||
using Umbraco.Web.Mvc;
|
||||
using Umbraco.Web.WebApi.Filters;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
using Umbraco.Web.Search;
|
||||
using Constants = Umbraco.Core.Constants;
|
||||
@@ -155,36 +156,35 @@ namespace Umbraco.Web.Trees
|
||||
if (_provider.IsUmbracoMembershipProvider())
|
||||
{
|
||||
//set default
|
||||
menu.DefaultMenuAlias = ActionNew.Instance.Alias;
|
||||
menu.DefaultMenuAlias = ActionNew.ActionAlias;
|
||||
|
||||
//Create the normal create action
|
||||
menu.Items.Add<ActionNew>(Services.TextService.Localize("actions", ActionNew.Instance.Alias));
|
||||
menu.Items.Add<ActionNew>(Services.TextService, opensDialog: true);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Create a custom create action - this does not launch a dialog, it just navigates to the create screen
|
||||
// we'll create it based on the ActionNew so it maintains the same icon properties, name, etc...
|
||||
var createMenuItem = new MenuItem(ActionNew.Instance);
|
||||
var createMenuItem = new MenuItem(ActionNew.ActionAlias, Services.TextService)
|
||||
{
|
||||
Icon = "add",
|
||||
OpensDialog = true
|
||||
};
|
||||
//we want to go to this route: /member/member/edit/-1?create=true
|
||||
createMenuItem.NavigateToRoute("/member/member/edit/-1?create=true");
|
||||
menu.Items.Add(createMenuItem);
|
||||
}
|
||||
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
return menu;
|
||||
}
|
||||
|
||||
//add delete option for all members
|
||||
menu.Items.Add<ActionDelete>(Services.TextService.Localize("actions", ActionDelete.Instance.Alias));
|
||||
menu.Items.Add<ActionDelete>(Services.TextService, opensDialog: true);
|
||||
|
||||
if (Security.CurrentUser.HasAccessToSensitiveData())
|
||||
{
|
||||
menu.Items.Add(new ExportMember
|
||||
{
|
||||
Name = Services.TextService.Localize("actions/export"),
|
||||
Icon = "download-alt",
|
||||
Alias = "export"
|
||||
});
|
||||
menu.Items.Add(new ExportMember(Services.TextService));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
using System.Net.Http.Formatting;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
using Umbraco.Web.Actions;
|
||||
|
||||
using Umbraco.Web.Models.Trees;
|
||||
|
||||
namespace Umbraco.Web.Trees
|
||||
@@ -25,14 +26,14 @@ namespace Umbraco.Web.Trees
|
||||
if (id == Constants.System.Root.ToInvariantString())
|
||||
{
|
||||
// root actions
|
||||
menu.Items.Add<CreateChildEntity, ActionNew>(Services.TextService.Localize("actions", ActionNew.Instance.Alias));
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true);
|
||||
menu.Items.Add(new CreateChildEntity(Services.TextService));
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
return menu;
|
||||
}
|
||||
else
|
||||
{
|
||||
//delete member type/group
|
||||
menu.Items.Add<ActionDelete>(Services.TextService.Localize("actions", ActionDelete.Instance.Alias));
|
||||
menu.Items.Add<ActionDelete>(Services.TextService, opensDialog: true);
|
||||
}
|
||||
|
||||
return menu;
|
||||
|
||||
@@ -8,7 +8,8 @@ using Umbraco.Web.WebApi.Filters;
|
||||
using umbraco;
|
||||
using umbraco.cms.businesslogic.packager;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
using Umbraco.Web.Actions;
|
||||
|
||||
using Constants = Umbraco.Core.Constants;
|
||||
|
||||
namespace Umbraco.Web.Trees
|
||||
@@ -83,21 +84,20 @@ namespace Umbraco.Web.Trees
|
||||
// Root actions
|
||||
if (id == "-1")
|
||||
{
|
||||
menu.Items.Add<ActionNew>(Services.TextService.Localize($"actions/{ActionNew.Instance.Alias}"))
|
||||
menu.Items.Add<ActionNew>(Services.TextService, opensDialog: true)
|
||||
.ConvertLegacyMenuItem(null, Constants.Trees.Packages, queryStrings.GetValue<string>("application"));
|
||||
}
|
||||
else if (id == "created")
|
||||
{
|
||||
menu.Items.Add<ActionNew>(Services.TextService.Localize($"actions/{ActionNew.Instance.Alias}"))
|
||||
menu.Items.Add<ActionNew>(Services.TextService, opensDialog: true)
|
||||
.ConvertLegacyMenuItem(null, Constants.Trees.Packages, queryStrings.GetValue<string>("application"));
|
||||
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(
|
||||
Services.TextService.Localize($"actions/{ActionRefresh.Instance.Alias}"), true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
}
|
||||
else
|
||||
{
|
||||
//it's a package node
|
||||
menu.Items.Add<ActionDelete>(Services.TextService.Localize("actions", ActionDelete.Instance.Alias));
|
||||
menu.Items.Add<ActionDelete>(Services.TextService, opensDialog: true);
|
||||
}
|
||||
|
||||
return menu;
|
||||
|
||||
@@ -4,10 +4,11 @@ using System.Net.Http.Formatting;
|
||||
using Umbraco.Web.Models.Trees;
|
||||
using Umbraco.Web.WebApi.Filters;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Entities;
|
||||
using Umbraco.Web.Actions;
|
||||
|
||||
namespace Umbraco.Web.Trees
|
||||
{
|
||||
@@ -24,12 +25,10 @@ namespace Umbraco.Web.Trees
|
||||
if (id == Constants.System.Root.ToInvariantString())
|
||||
{
|
||||
//Create the normal create action
|
||||
menu.Items.Add<ActionNew>(Services.TextService.Localize("actions", ActionNew.Instance.Alias))
|
||||
//Since we haven't implemented anything for relationtypes in angular, this needs to be converted to
|
||||
//use the legacy format
|
||||
.ConvertLegacyMenuItem(null, "initrelationTypes", queryStrings.GetValue<string>("application"));
|
||||
var addMenuItem = menu.Items.Add<ActionNew>(Services.TextService, opensDialog: true);
|
||||
addMenuItem.LaunchDialogUrl("developer/RelationTypes/NewRelationType.aspx", "Create New RelationType");
|
||||
//refresh action
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
|
||||
return menu;
|
||||
}
|
||||
@@ -38,7 +37,7 @@ namespace Umbraco.Web.Trees
|
||||
if (relationType == null) return new MenuItemCollection();
|
||||
|
||||
//add delete option for all macros
|
||||
menu.Items.Add<ActionDelete>(Services.TextService.Localize("actions", ActionDelete.Instance.Alias))
|
||||
menu.Items.Add<ActionDelete>(Services.TextService, opensDialog: true)
|
||||
//Since we haven't implemented anything for relationtypes in angular, this needs to be converted to
|
||||
//use the legacy format
|
||||
.ConvertLegacyMenuItem(new EntitySlim
|
||||
|
||||
@@ -8,12 +8,13 @@ using Umbraco.Core;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Entities;
|
||||
using Umbraco.Web.Actions;
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
using Umbraco.Web.Models.Trees;
|
||||
using Umbraco.Web.Mvc;
|
||||
using Umbraco.Web.Search;
|
||||
using Umbraco.Web.WebApi.Filters;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
using Constants = Umbraco.Core.Constants;
|
||||
|
||||
namespace Umbraco.Web.Trees
|
||||
@@ -69,13 +70,13 @@ namespace Umbraco.Web.Trees
|
||||
var menu = new MenuItemCollection();
|
||||
|
||||
//Create the normal create action
|
||||
var item = menu.Items.Add<ActionNew>(Services.TextService.Localize("actions", ActionNew.Instance.Alias));
|
||||
var item = menu.Items.Add<ActionNew>(Services.TextService, opensDialog: true);
|
||||
item.NavigateToRoute($"{queryStrings.GetValue<string>("application")}/templates/edit/{id}?create=true");
|
||||
|
||||
if (id == Constants.System.Root.ToInvariantString())
|
||||
{
|
||||
//refresh action
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
|
||||
return menu;
|
||||
}
|
||||
@@ -88,11 +89,11 @@ namespace Umbraco.Web.Trees
|
||||
if (template.IsMasterTemplate == false)
|
||||
{
|
||||
//add delete option if it doesn't have children
|
||||
menu.Items.Add<ActionDelete>(Services.TextService.Localize("actions", ActionDelete.Instance.Alias), true);
|
||||
menu.Items.Add<ActionDelete>(Services.TextService, true, opensDialog: true);
|
||||
}
|
||||
|
||||
//add refresh
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
|
||||
|
||||
return menu;
|
||||
|
||||
@@ -3,10 +3,11 @@ using System.Linq;
|
||||
using System.Net.Http.Formatting;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Actions;
|
||||
using Umbraco.Web.Models.Trees;
|
||||
using Umbraco.Web.Mvc;
|
||||
using Umbraco.Web.WebApi.Filters;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
using Constants = Umbraco.Core.Constants;
|
||||
|
||||
namespace Umbraco.Web.Trees
|
||||
@@ -43,7 +44,7 @@ namespace Umbraco.Web.Trees
|
||||
if (id == Constants.System.Root.ToInvariantString())
|
||||
{
|
||||
// root actions
|
||||
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true);
|
||||
menu.Items.Add(new RefreshNode(Services.TextService, true));
|
||||
return menu;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Models.Trees;
|
||||
using Umbraco.Web.Mvc;
|
||||
using Umbraco.Web.WebApi.Filters;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
using Constants = Umbraco.Core.Constants;
|
||||
|
||||
namespace Umbraco.Web.Trees
|
||||
|
||||
@@ -5,7 +5,7 @@ using Umbraco.Web.Mvc;
|
||||
using Umbraco.Web.Trees;
|
||||
using Umbraco.Web.WebApi;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
|
||||
namespace Umbraco.Web
|
||||
{
|
||||
@@ -14,15 +14,6 @@ namespace Umbraco.Web
|
||||
/// </summary>
|
||||
public static class TypeLoaderExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns all available IAction in application
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
internal static IEnumerable<Type> GetActions(this TypeLoader mgr)
|
||||
{
|
||||
return mgr.GetTypes<IAction>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all available TreeApiController's in application that are attribute with TreeAttribute
|
||||
/// </summary>
|
||||
@@ -43,15 +34,5 @@ namespace Umbraco.Web
|
||||
return mgr.GetTypes<UmbracoApiController>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all available ISearchableTrees in application
|
||||
/// </summary>
|
||||
/// <param name="mgr"></param>
|
||||
/// <returns></returns>
|
||||
internal static IEnumerable<Type> GetSearchableTrees(this TypeLoader mgr)
|
||||
{
|
||||
return mgr.GetTypes<ISearchableTree>();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,9 +11,10 @@ using Umbraco.Core.Exceptions;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Entities;
|
||||
using Umbraco.Core.Security;
|
||||
using Umbraco.Web.Actions;
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Web.Security;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
|
||||
namespace Umbraco.Web.UI.Pages
|
||||
{
|
||||
|
||||
@@ -427,7 +427,6 @@
|
||||
<Compile Include="PublishedCache\NuCache\PublishedSnapshot.cs" />
|
||||
<Compile Include="PublishedCache\PublishedElement.cs" />
|
||||
<Compile Include="PublishedCache\PublishedElementPropertyBase.cs" />
|
||||
<Compile Include="Models\Trees\DisableUser.cs" />
|
||||
<Compile Include="PropertyEditors\ValueConverters\ContentPickerValueConverter.cs" />
|
||||
<Compile Include="PublishedCache\PublishedSnapshotServiceBase.cs" />
|
||||
<Compile Include="PublishedCache\IDomainCache.cs" />
|
||||
@@ -530,39 +529,26 @@
|
||||
<Compile Include="Runtime\WebRuntimeComponent.cs" />
|
||||
<Compile Include="Editors\PublishedStatusController.cs" />
|
||||
<Compile Include="Editors\NuCacheStatusController.cs" />
|
||||
<Compile Include="_Legacy\Actions\Action.cs" />
|
||||
<Compile Include="_Legacy\Actions\ActionAssignDomain.cs" />
|
||||
<Compile Include="_Legacy\Actions\ActionBrowse.cs" />
|
||||
<Compile Include="_Legacy\Actions\ActionChangeDocType.cs" />
|
||||
<Compile Include="_Legacy\Actions\ActionCollection.cs" />
|
||||
<Compile Include="_Legacy\Actions\ActionCollectionBuilder.cs" />
|
||||
<Compile Include="_Legacy\Actions\ActionCopy.cs" />
|
||||
<Compile Include="_Legacy\Actions\ActionCreateBlueprintFromContent.cs" />
|
||||
<Compile Include="_Legacy\Actions\ActionDelete.cs" />
|
||||
<Compile Include="_Legacy\Actions\ActionEmptyTranscan.cs" />
|
||||
<Compile Include="_Legacy\Actions\ActionExport.cs" />
|
||||
<Compile Include="_Legacy\Actions\ActionImport.cs" />
|
||||
<Compile Include="_Legacy\Actions\ActionMove.cs" />
|
||||
<Compile Include="_Legacy\Actions\ActionNew.cs" />
|
||||
<Compile Include="_Legacy\Actions\ActionNotify.cs" />
|
||||
<Compile Include="_Legacy\Actions\ActionNull.cs" />
|
||||
<Compile Include="_Legacy\Actions\ActionPackage.cs" />
|
||||
<Compile Include="_Legacy\Actions\ActionPackageCreate.cs" />
|
||||
<Compile Include="_Legacy\Actions\ActionProtect.cs" />
|
||||
<Compile Include="_Legacy\Actions\ActionPublish.cs" />
|
||||
<Compile Include="_Legacy\Actions\ActionRefresh.cs" />
|
||||
<Compile Include="_Legacy\Actions\ActionRePublish.cs" />
|
||||
<Compile Include="_Legacy\Actions\ActionRestore.cs" />
|
||||
<Compile Include="_Legacy\Actions\ActionRights.cs" />
|
||||
<Compile Include="_Legacy\Actions\ActionRollback.cs" />
|
||||
<Compile Include="_Legacy\Actions\ActionSort.cs" />
|
||||
<Compile Include="_Legacy\Actions\ActionToPublish.cs" />
|
||||
<Compile Include="_Legacy\Actions\ActionTranslate.cs" />
|
||||
<Compile Include="_Legacy\Actions\ActionUnpublish.cs" />
|
||||
<Compile Include="_Legacy\Actions\ActionUpdate.cs" />
|
||||
<Compile Include="_Legacy\Actions\ContextMenuSeperator.cs" />
|
||||
<Compile Include="_Legacy\Actions\IAction.cs" />
|
||||
<Compile Include="_Legacy\Actions\LegacyActionMenuItemAttribute.cs" />
|
||||
<Compile Include="Actions\ActionAssignDomain.cs" />
|
||||
<Compile Include="Actions\ActionBrowse.cs" />
|
||||
<Compile Include="Actions\ActionChangeDocType.cs" />
|
||||
<Compile Include="Actions\ActionCollection.cs" />
|
||||
<Compile Include="Actions\ActionCollectionBuilder.cs" />
|
||||
<Compile Include="Actions\ActionCopy.cs" />
|
||||
<Compile Include="Actions\ActionCreateBlueprintFromContent.cs" />
|
||||
<Compile Include="Actions\ActionDelete.cs" />
|
||||
<Compile Include="Actions\ActionMove.cs" />
|
||||
<Compile Include="Actions\ActionNew.cs" />
|
||||
<Compile Include="Actions\ActionProtect.cs" />
|
||||
<Compile Include="Actions\ActionPublish.cs" />
|
||||
<Compile Include="Actions\ActionRestore.cs" />
|
||||
<Compile Include="Actions\ActionRights.cs" />
|
||||
<Compile Include="Actions\ActionRollback.cs" />
|
||||
<Compile Include="Actions\ActionSort.cs" />
|
||||
<Compile Include="Actions\ActionToPublish.cs" />
|
||||
<Compile Include="Actions\ActionUnpublish.cs" />
|
||||
<Compile Include="Actions\ActionUpdate.cs" />
|
||||
<Compile Include="Actions\IAction.cs" />
|
||||
<Compile Include="Models\ContentEditing\EntityBasic.cs" />
|
||||
<Compile Include="Models\Trees\ApplicationAttribute.cs" />
|
||||
<Compile Include="Models\Trees\ApplicationDefinitions.cs" />
|
||||
@@ -947,7 +933,6 @@
|
||||
<Compile Include="PropertyEditors\TrueFalsePropertyEditor.cs" />
|
||||
<Compile Include="Trees\MediaTreeController.cs" />
|
||||
<Compile Include="Models\Trees\ActionMenuItem.cs" />
|
||||
<Compile Include="Models\Trees\ActionMenuItemAttribute.cs" />
|
||||
<Compile Include="Trees\ActionUrlMethod.cs" />
|
||||
<Compile Include="Trees\ContentTreeControllerBase.cs" />
|
||||
<Compile Include="Trees\ISearchableTree.cs" />
|
||||
@@ -1263,12 +1248,6 @@
|
||||
<Compile Include="umbraco.presentation\umbraco\developer\RelationTypes\NewRelationType.aspx.designer.cs">
|
||||
<DependentUpon>NewRelationType.aspx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="umbraco.presentation\umbraco\developer\RelationTypes\RelationTypesWebService.asmx.cs">
|
||||
<DependentUpon>RelationTypesWebService.asmx</DependentUpon>
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="umbraco.presentation\umbraco\developer\RelationTypes\TreeMenu\ActionDeleteRelationType.cs" />
|
||||
<Compile Include="umbraco.presentation\umbraco\developer\RelationTypes\TreeMenu\ActionNewRelationType.cs" />
|
||||
<Compile Include="umbraco.presentation\umbraco\dialogs\insertMasterpageContent.aspx.cs">
|
||||
<DependentUpon>insertMasterpageContent.aspx</DependentUpon>
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
@@ -1372,7 +1351,6 @@
|
||||
<Content Include="umbraco.presentation\umbraco\developer\RelationTypes\NewRelationType.aspx">
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Content>
|
||||
<Content Include="umbraco.presentation\umbraco\developer\RelationTypes\RelationTypesWebService.asmx" />
|
||||
<Content Include="umbraco.presentation\umbraco\dashboard\FeedProxy.aspx" />
|
||||
<Content Include="umbraco.presentation\umbraco\dialogs\insertMasterpageContent.aspx">
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
|
||||
@@ -5,9 +5,10 @@ using System.Web.Http.Filters;
|
||||
using Umbraco.Core.Exceptions;
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Web.Editors;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Web.Actions;
|
||||
|
||||
namespace Umbraco.Web.WebApi.Filters
|
||||
{
|
||||
@@ -39,7 +40,7 @@ namespace Umbraco.Web.WebApi.Filters
|
||||
{
|
||||
if (string.IsNullOrEmpty(paramName)) throw new ArgumentNullOrEmptyException(nameof(paramName));
|
||||
_paramName = paramName;
|
||||
_permissionToCheck = ActionBrowse.Instance.Letter;
|
||||
_permissionToCheck = ActionBrowse.ActionLetter;
|
||||
}
|
||||
|
||||
public EnsureUserPermissionForContentAttribute(string paramName, char permissionToCheck)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user