Files
Umbraco-CMS/src/Umbraco.Web.BackOffice/Controllers/MacrosController.cs

427 lines
15 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
2021-09-14 22:13:39 +02:00
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net.Http;
using Microsoft.AspNetCore.Authorization;
2020-06-03 20:39:54 +02:00
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Hosting;
using Umbraco.Cms.Core.Mapping;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.ContentEditing;
using Umbraco.Cms.Core.PropertyEditors;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Strings;
using Umbraco.Cms.Web.Common.Attributes;
using Umbraco.Cms.Web.Common.Authorization;
using Umbraco.Extensions;
using Constants = Umbraco.Cms.Core.Constants;
2019-01-21 10:55:48 +01:00
namespace Umbraco.Cms.Web.BackOffice.Controllers
{
/// <summary>
/// The API controller used for editing dictionary items
/// </summary>
[PluginController(Constants.Web.Mvc.BackOfficeApiArea)]
[Authorize(Policy = AuthorizationPolicies.TreeAccessMacros)]
[ParameterSwapControllerActionSelector(nameof(GetById), "id", typeof(int), typeof(Guid), typeof(Udi))]
public class MacrosController : BackOfficeNotificationsController
{
private readonly ParameterEditorCollection _parameterEditorCollection;
2019-01-21 10:55:48 +01:00
private readonly IMacroService _macroService;
2020-06-03 20:39:54 +02:00
private readonly IShortStringHelper _shortStringHelper;
private readonly IBackOfficeSecurityAccessor _backofficeSecurityAccessor;
private readonly ILogger<MacrosController> _logger;
2020-06-03 20:39:54 +02:00
private readonly IHostingEnvironment _hostingEnvironment;
Merge remote-tracking branch 'origin/v8/dev' into netcore/dev # Conflicts: # build/NuSpecs/UmbracoCms.Web.nuspec # src/SolutionInfo.cs # src/Umbraco.Core/Cache/MediaCacheRefresher.cs # src/Umbraco.Core/Composing/ComponentCollection.cs # src/Umbraco.Core/Composing/Composers.cs # src/Umbraco.Core/Composing/TypeFinder.cs # src/Umbraco.Core/Composing/TypeLoader.cs # src/Umbraco.Core/Configuration/Grid/GridEditorsConfig.cs # src/Umbraco.Core/Constants-SvgSanitizer.cs # src/Umbraco.Core/ContentApps/ContentAppFactoryCollection.cs # src/Umbraco.Core/Extensions/PublishedContentExtensions.cs # src/Umbraco.Core/Extensions/PublishedPropertyExtension.cs # src/Umbraco.Core/Extensions/StringExtensions.cs # src/Umbraco.Core/HealthChecks/Checks/Security/ExcessiveHeadersCheck.cs # src/Umbraco.Core/HealthChecks/HealthCheckResults.cs # src/Umbraco.Core/IO/FileSystems.cs # src/Umbraco.Core/IO/IOHelper.cs # src/Umbraco.Core/IO/MediaFileSystem.cs # src/Umbraco.Core/IO/PhysicalFileSystem.cs # src/Umbraco.Core/Logging/DebugDiagnosticsLogger.cs # src/Umbraco.Core/Logging/DisposableTimer.cs # src/Umbraco.Core/Logging/ILogger.cs # src/Umbraco.Core/Logging/LogProfiler.cs # src/Umbraco.Core/Logging/OwinLogger.cs # src/Umbraco.Core/Manifest/ManifestWatcher.cs # src/Umbraco.Core/Mapping/UmbracoMapper.cs # src/Umbraco.Core/Media/UploadAutoFillProperties.cs # src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs # src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/PreValueMigratorCollection.cs # src/Umbraco.Core/Models/Mapping/ContentPropertyBasicMapper.cs # src/Umbraco.Core/Models/Mapping/DataTypeMapDefinition.cs # src/Umbraco.Core/Models/Mapping/MacroMapDefinition.cs # src/Umbraco.Core/Models/Member.cs # src/Umbraco.Core/Packaging/PackageActionRunner.cs # src/Umbraco.Core/PropertyEditors/DataValueEditor.cs # src/Umbraco.Core/PropertyEditors/Validators/EyeDropperColorPickerConfigurationEditor.cs # src/Umbraco.Core/PropertyEditors/Validators/EyeDropperColorPickerPropertyEditor.cs # src/Umbraco.Core/Routing/DefaultUrlProvider.cs # src/Umbraco.Core/Runtime/CoreRuntime.cs # src/Umbraco.Core/Runtime/MainDom.cs # src/Umbraco.Core/RuntimeState.cs # src/Umbraco.Core/Scoping/ScopeProvider.cs # src/Umbraco.Core/Sync/DatabaseServerMessenger.cs # src/Umbraco.Core/Templates/HtmlUrlParser.cs # src/Umbraco.Core/UriExtensions.cs # src/Umbraco.Examine.Lucene/UmbracoContentIndex.cs # src/Umbraco.Examine.Lucene/UmbracoExamineIndex.cs # src/Umbraco.Infrastructure/Examine/IndexRebuilder.cs # src/Umbraco.Infrastructure/Manifest/DataEditorConverter.cs # src/Umbraco.Infrastructure/Manifest/ManifestParser.cs # src/Umbraco.Infrastructure/Migrations/Install/DatabaseBuilder.cs # src/Umbraco.Infrastructure/Migrations/Install/DatabaseSchemaCreator.cs # src/Umbraco.Infrastructure/Migrations/MigrationPlan.cs # src/Umbraco.Infrastructure/Migrations/Upgrade/V_8_0_0/DataTypeMigration.cs # src/Umbraco.Infrastructure/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs # src/Umbraco.Infrastructure/Migrations/Upgrade/V_8_0_0/MergeDateAndDateTimePropertyEditor.cs # src/Umbraco.Infrastructure/Migrations/Upgrade/V_8_0_0/RadioAndCheckboxPropertyEditorsMigration.cs # src/Umbraco.Infrastructure/Packaging/PackageDataInstallation.cs # src/Umbraco.Infrastructure/Persistence/Repositories/Implement/ContentRepositoryBase.cs # src/Umbraco.Infrastructure/Persistence/Repositories/Implement/ContentTypeRepository.cs # src/Umbraco.Infrastructure/Persistence/Repositories/Implement/ContentTypeRepositoryBase.cs # src/Umbraco.Infrastructure/Persistence/Repositories/Implement/MediaRepository.cs # src/Umbraco.Infrastructure/Persistence/UmbracoDatabase.cs # src/Umbraco.Infrastructure/Persistence/UmbracoDatabaseFactory.cs # src/Umbraco.Infrastructure/PropertyEditors/BlockEditorPropertyEditor.cs # src/Umbraco.Infrastructure/PropertyEditors/ImageCropperPropertyEditor.cs # src/Umbraco.Infrastructure/PropertyEditors/MultiUrlPickerValueEditor.cs # src/Umbraco.Infrastructure/PropertyEditors/NestedContentPropertyEditor.cs # src/Umbraco.Infrastructure/PropertyEditors/RichTextEditorPastedImages.cs # src/Umbraco.Infrastructure/PropertyEditors/ValueConverters/GridValueConverter.cs # src/Umbraco.Infrastructure/PropertyEditors/ValueConverters/ImageCropperValueConverter.cs # src/Umbraco.Infrastructure/PropertyEditors/ValueConverters/JsonValueConverter.cs # src/Umbraco.Infrastructure/PublishedCache/PublishedContentTypeCache.cs # src/Umbraco.Infrastructure/Runtime/SqlMainDomLock.cs # src/Umbraco.Infrastructure/Scoping/Scope.cs # src/Umbraco.Infrastructure/Search/ExamineNotificationHandler.cs # src/Umbraco.Infrastructure/Services/Implement/ContentService.cs # src/Umbraco.Infrastructure/Services/Implement/LocalizedTextService.cs # src/Umbraco.Infrastructure/Services/Implement/LocalizedTextServiceFileSources.cs # src/Umbraco.Infrastructure/Services/Implement/MediaService.cs # src/Umbraco.Infrastructure/Services/Implement/NotificationService.cs # src/Umbraco.Infrastructure/Sync/ServerMessengerBase.cs # src/Umbraco.ModelsBuilder.Embedded/Compose/ModelsBuilderComposer.cs # src/Umbraco.ModelsBuilder.Embedded/LiveModelsProvider.cs # src/Umbraco.PublishedCache.NuCache/ContentStore.cs # src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentEventsTests.cs # src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Mapping/MappingTests.cs # src/Umbraco.Tests.UnitTests/Umbraco.ModelsBuilder.Embedded/BuilderTests.cs # src/Umbraco.Tests/Composing/TypeLoaderTests.cs # src/Umbraco.Tests/LegacyXmlPublishedCache/DictionaryPublishedContent.cs # src/Umbraco.Tests/LegacyXmlPublishedCache/LegacyBackgroundTask/BackgroundTaskRunner.cs # src/Umbraco.Tests/LegacyXmlPublishedCache/PreviewContent.cs # src/Umbraco.Tests/LegacyXmlPublishedCache/PublishedMediaCache.cs # src/Umbraco.Tests/LegacyXmlPublishedCache/XmlStore.cs # src/Umbraco.Tests/LegacyXmlPublishedCache/XmlStoreFilePersister.cs # src/Umbraco.Tests/Services/ContentServicePerformanceTest.cs # src/Umbraco.Tests/Services/PerformanceTests.cs # src/Umbraco.Tests/TestHelpers/ConsoleLogger.cs # src/Umbraco.Tests/Testing/TestingTests/MockTests.cs # src/Umbraco.Web.BackOffice/Controllers/BackOfficeServerVariables.cs # src/Umbraco.Web.BackOffice/Controllers/ContentController.cs # src/Umbraco.Web.BackOffice/Controllers/DashboardController.cs # src/Umbraco.Web.BackOffice/Controllers/ExamineManagementController.cs # src/Umbraco.Web.BackOffice/HealthChecks/HealthCheckController.cs # src/Umbraco.Web.BackOffice/PropertyEditors/RteEmbedController.cs # src/Umbraco.Web.BackOffice/Services/IconService.cs # src/Umbraco.Web.BackOffice/Trees/ContentTreeControllerBase.cs # src/Umbraco.Web.Common/Extensions/FormCollectionExtensions.cs # src/Umbraco.Web.Common/Install/InstallApiController.cs # src/Umbraco.Web.Common/Macros/MacroRenderer.cs # src/Umbraco.Web.Common/ModelsBuilder/PureLiveModelFactory.cs # src/Umbraco.Web.UI.Client/package-lock.json # src/Umbraco.Web.UI.Client/src/views/memberTypes/copy.controller.js # src/Umbraco.Web.UI.Client/src/views/memberTypes/copy.html # src/Umbraco.Web.UI.NetCore/umbraco/UmbracoBackOffice/Default.cshtml # src/Umbraco.Web.UI.NetCore/umbraco/config/lang/da.xml # src/Umbraco.Web.UI.NetCore/umbraco/config/lang/en.xml # src/Umbraco.Web.UI.NetCore/umbraco/config/lang/en_us.xml # src/Umbraco.Web.UI/config/splashes/noNodes.aspx # src/Umbraco.Web/AspNet/AspNetHttpContextAccessor.cs # src/Umbraco.Web/Cache/DistributedCacheBinder.cs # src/Umbraco.Web/Cache/DistributedCacheBinder_Handlers.cs # src/Umbraco.Web/Editors/AuthenticationController.cs # src/Umbraco.Web/Editors/BackOfficeController.cs # src/Umbraco.Web/Editors/Binders/ContentModelBinderHelper.cs # src/Umbraco.Web/Editors/ContentControllerBase.cs # src/Umbraco.Web/Editors/ContentTypeController.cs # src/Umbraco.Web/Editors/DictionaryController.cs # src/Umbraco.Web/Editors/MemberTypeController.cs # src/Umbraco.Web/Editors/PasswordChanger.cs # src/Umbraco.Web/Editors/RelationTypeController.cs # src/Umbraco.Web/Editors/TinyMceController.cs # src/Umbraco.Web/HealthCheck/Checks/Security/HttpsCheck.cs # src/Umbraco.Web/HtmlHelperRenderExtensions.cs # src/Umbraco.Web/HttpUrlHelperExtensions.cs # src/Umbraco.Web/HybridEventMessagesAccessor.cs # src/Umbraco.Web/ImageCropperTemplateExtensions.cs # src/Umbraco.Web/JavaScript/ClientDependencyConfiguration.cs # src/Umbraco.Web/Mvc/RenderMvcController.cs # src/Umbraco.Web/PublishedCache/NuCache/DataSource/DatabaseDataSource.cs # src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs # src/Umbraco.Web/Routing/ContentFinderByConfigured404.cs # src/Umbraco.Web/Routing/ContentFinderByIdPath.cs # src/Umbraco.Web/Routing/ContentFinderByRedirectUrl.cs # src/Umbraco.Web/Routing/ContentFinderByUrl.cs # src/Umbraco.Web/Routing/ContentFinderByUrlAlias.cs # src/Umbraco.Web/Routing/ContentFinderByUrlAndTemplate.cs # src/Umbraco.Web/Routing/NotFoundHandlerHelper.cs # src/Umbraco.Web/Routing/PublishedRouter.cs # src/Umbraco.Web/Runtime/WebInitialComposer.cs # src/Umbraco.Web/Scheduling/KeepAlive.cs # src/Umbraco.Web/Scheduling/ScheduledPublishing.cs # src/Umbraco.Web/Scheduling/TempFileCleanup.cs # src/Umbraco.Web/Security/MembershipHelper.cs # src/Umbraco.Web/Security/Providers/UmbracoMembershipProvider.cs # src/Umbraco.Web/Trees/MemberTreeController.cs # src/Umbraco.Web/Trees/MemberTypeAndGroupTreeControllerBase.cs # src/Umbraco.Web/Trees/MemberTypeTreeController.cs # src/Umbraco.Web/UmbracoApplicationBase.cs # src/Umbraco.Web/UmbracoInjectedModule.cs # src/Umbraco.Web/UmbracoModule.cs # src/Umbraco.Web/WebApi/AngularJsonMediaTypeFormatter.cs # src/Umbraco.Web/WebApi/Filters/FileUploadCleanupFilterAttribute.cs # src/Umbraco.Web/WebApi/UnhandledExceptionLogger.cs
2021-04-20 19:34:18 +02:00
private readonly IUmbracoMapper _umbracoMapper;
2019-01-21 10:55:48 +01:00
public MacrosController(
ParameterEditorCollection parameterEditorCollection,
2020-06-03 20:39:54 +02:00
IMacroService macroService,
IShortStringHelper shortStringHelper,
IBackOfficeSecurityAccessor backofficeSecurityAccessor,
ILogger<MacrosController> logger,
2020-06-03 20:39:54 +02:00
IHostingEnvironment hostingEnvironment,
IUmbracoMapper umbracoMapper)
2019-01-21 10:55:48 +01:00
{
2020-06-03 20:39:54 +02:00
_parameterEditorCollection = parameterEditorCollection ?? throw new ArgumentNullException(nameof(parameterEditorCollection));
_macroService = macroService ?? throw new ArgumentNullException(nameof(macroService));
_shortStringHelper = shortStringHelper ?? throw new ArgumentNullException(nameof(shortStringHelper));
_backofficeSecurityAccessor = backofficeSecurityAccessor ?? throw new ArgumentNullException(nameof(backofficeSecurityAccessor));
2020-06-03 20:39:54 +02:00
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_hostingEnvironment = hostingEnvironment ?? throw new ArgumentNullException(nameof(hostingEnvironment));
_umbracoMapper = umbracoMapper ?? throw new ArgumentNullException(nameof(umbracoMapper));
2019-01-21 10:55:48 +01:00
}
2020-01-08 19:02:16 +01:00
/// <summary>
/// Creates a new macro
/// </summary>
/// <param name="name">
/// The name.
/// </param>
/// <returns>
2020-06-03 20:39:54 +02:00
/// The id of the created macro
/// </returns>
[HttpPost]
2020-06-03 20:39:54 +02:00
public ActionResult<int> Create(string name)
{
if (string.IsNullOrWhiteSpace(name))
2019-01-18 09:31:38 +01:00
{
return ValidationProblem("Name can not be empty");
2019-01-18 09:31:38 +01:00
}
2020-06-03 20:39:54 +02:00
var alias = name.ToSafeAlias(_shortStringHelper);
2019-01-21 10:55:48 +01:00
if (_macroService.GetByAlias(alias) != null)
{
return ValidationProblem("Macro with this alias already exists");
}
2019-08-29 22:09:25 +01:00
if (name == null || name.Length > 255)
{
return ValidationProblem("Name cannnot be more than 255 characters in length.");
2019-08-29 22:09:25 +01:00
}
try
{
2020-06-03 20:39:54 +02:00
var macro = new Macro(_shortStringHelper)
{
Alias = alias,
Name = name,
MacroSource = string.Empty
};
_macroService.Save(macro, _backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser.Id);
2020-06-03 20:39:54 +02:00
return macro.Id;
}
catch (Exception exception)
{
2020-06-03 20:39:54 +02:00
const string errorMessage = "Error creating macro";
_logger.LogError(exception, errorMessage);
return ValidationProblem(errorMessage);
2019-01-18 09:31:38 +01:00
}
}
[HttpGet]
public ActionResult<MacroDisplay> GetById(int id)
2019-01-18 09:31:38 +01:00
{
2019-01-21 10:55:48 +01:00
var macro = _macroService.GetById(id);
2019-01-18 09:31:38 +01:00
if (macro == null)
{
return ValidationProblem($"Macro with id {id} does not exist");
2019-01-18 09:31:38 +01:00
}
2020-01-08 19:02:16 +01:00
var macroDisplay = MapToDisplay(macro);
2020-06-03 20:39:54 +02:00
return macroDisplay;
2020-01-08 19:02:16 +01:00
}
[HttpGet]
public ActionResult<MacroDisplay> GetById(Guid id)
2020-01-08 19:02:16 +01:00
{
var macro = _macroService.GetById(id);
if (macro == null)
2019-01-18 09:31:38 +01:00
{
return ValidationProblem($"Macro with id {id} does not exist");
}
2019-01-18 09:31:38 +01:00
2020-01-08 19:02:16 +01:00
var macroDisplay = MapToDisplay(macro);
2019-01-18 09:31:38 +01:00
2020-06-03 20:39:54 +02:00
return macroDisplay;
}
2020-01-08 19:02:16 +01:00
[HttpGet]
public ActionResult<MacroDisplay> GetById(Udi id)
2020-01-08 19:02:16 +01:00
{
var guidUdi = id as GuidUdi;
if (guidUdi == null)
return ValidationProblem($"Macro with id {id} does not exist");
2020-01-08 19:02:16 +01:00
var macro = _macroService.GetById(guidUdi.Guid);
if (macro == null)
{
return ValidationProblem($"Macro with id {id} does not exist");
2020-01-08 19:02:16 +01:00
}
var macroDisplay = MapToDisplay(macro);
2020-06-03 20:39:54 +02:00
return macroDisplay;
2020-01-08 19:02:16 +01:00
}
2019-01-21 10:44:11 +01:00
[HttpPost]
public IActionResult DeleteById(int id)
2019-01-21 10:44:11 +01:00
{
2019-01-21 10:55:48 +01:00
var macro = _macroService.GetById(id);
2019-01-21 10:44:11 +01:00
if (macro == null)
{
return ValidationProblem($"Macro with id {id} does not exist");
2019-01-21 10:44:11 +01:00
}
2019-01-21 10:55:48 +01:00
_macroService.Delete(macro);
2019-01-21 10:44:11 +01:00
2020-06-03 20:39:54 +02:00
return Ok();
2019-01-21 10:44:11 +01:00
}
[HttpPost]
public ActionResult<MacroDisplay> Save(MacroDisplay macroDisplay)
{
if (macroDisplay == null)
{
return ValidationProblem("No macro data found in request");
}
2019-08-29 22:09:25 +01:00
if (macroDisplay.Name == null || macroDisplay.Name.Length > 255)
{
return ValidationProblem("Name cannnot be more than 255 characters in length.");
2019-08-29 22:09:25 +01:00
}
2021-09-14 22:13:39 +02:00
var macro = _macroService.GetById(int.Parse(macroDisplay.Id.ToString(), CultureInfo.InvariantCulture));
if (macro == null)
{
return ValidationProblem($"Macro with id {macroDisplay.Id} does not exist");
}
if (macroDisplay.Alias != macro.Alias)
{
2019-01-21 10:55:48 +01:00
var macroByAlias = _macroService.GetByAlias(macroDisplay.Alias);
if (macroByAlias != null)
{
return ValidationProblem("Macro with this alias already exists");
2020-06-03 20:39:54 +02:00
}
}
macro.Alias = macroDisplay.Alias;
macro.Name = macroDisplay.Name;
macro.CacheByMember = macroDisplay.CacheByUser;
macro.CacheByPage = macroDisplay.CacheByPage;
macro.CacheDuration = macroDisplay.CachePeriod;
macro.DontRender = !macroDisplay.RenderInEditor;
macro.UseInEditor = macroDisplay.UseInEditor;
macro.MacroSource = macroDisplay.View;
2019-01-21 09:10:08 +01:00
macro.Properties.ReplaceAll(macroDisplay.Parameters.Select((x,i) => new MacroProperty(x.Key, x.Label, i, x.Editor)));
try
{
_macroService.Save(macro, _backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser.Id);
macroDisplay.Notifications.Clear();
macroDisplay.Notifications.Add(new BackOfficeNotification("Success", "Macro saved", NotificationStyle.Success));
2020-06-03 20:39:54 +02:00
return macroDisplay;
}
catch (Exception exception)
{
2020-06-03 20:39:54 +02:00
const string errorMessage = "Error creating macro";
_logger.LogError(exception, errorMessage);
return ValidationProblem(errorMessage);
}
}
/// <summary>
/// Gets a list of available macro partials
/// </summary>
/// <returns>
/// The <see cref="HttpResponseMessage"/>.
/// </returns>
public IEnumerable<string> GetPartialViews()
{
var views = new List<string>();
views.AddRange(this.FindPartialViewsFiles());
2020-06-03 20:39:54 +02:00
return views;
}
/// <summary>
/// Gets the available parameter editors
/// </summary>
/// <returns>
/// The <see cref="HttpResponseMessage"/>.
/// </returns>
2020-06-03 20:39:54 +02:00
public ParameterEditorCollection GetParameterEditors()
{
2020-06-03 20:39:54 +02:00
return _parameterEditorCollection;
}
/// <summary>
/// Gets the available parameter editors grouped by their group.
/// </summary>
/// <returns>
/// The <see cref="HttpResponseMessage"/>.
/// </returns>
2020-06-03 20:39:54 +02:00
public IDictionary<string, IEnumerable<IDataEditor>> GetGroupedParameterEditors()
{
var parameterEditors = _parameterEditorCollection.ToArray();
var grouped = parameterEditors
.GroupBy(x => x.Group.IsNullOrWhiteSpace() ? "" : x.Group.ToLower())
.OrderBy(x => x.Key)
.ToDictionary(group => group.Key, group => group.OrderBy(d => d.Name).AsEnumerable());
2020-06-03 20:39:54 +02:00
return grouped;
}
/// <summary>
/// Get parameter editor by alias.
/// </summary>
/// <returns>
/// The <see cref="HttpResponseMessage"/>.
/// </returns>
2020-06-03 20:39:54 +02:00
public IDataEditor GetParameterEditorByAlias(string alias)
{
var parameterEditors = _parameterEditorCollection.ToArray();
var parameterEditor = parameterEditors.FirstOrDefault(x => x.Alias.InvariantEquals(alias));
2020-06-03 20:39:54 +02:00
return parameterEditor;
}
2019-01-18 09:31:38 +01:00
/// <summary>
2019-01-21 09:10:08 +01:00
/// Finds all the macro partials
/// </summary>
/// <returns>
/// The <see cref="IEnumerable"/>.
/// </returns>
private IEnumerable<string> FindPartialViewsFiles()
{
var files = new List<string>();
files.AddRange(this.FindPartialViewFilesInViewsFolder());
files.AddRange(this.FindPartialViewFilesInPluginFolders());
return files;
}
/// <summary>
/// Finds all macro partials in the views folder
/// </summary>
/// <returns>
/// The <see cref="IEnumerable"/>.
/// </returns>
private IEnumerable<string> FindPartialViewFilesInViewsFolder()
{
// TODO: This is inconsistent. We have FileSystems.MacroPartialsFileSystem but we basically don't use
// that at all except to render the tree. In the future we may want to use it. This also means that
// we are storing the virtual path of the macro like ~/Views/MacroPartials/Login.cshtml instead of the
// relative path which would work with the FileSystems.MacroPartialsFileSystem, but these are incompatible.
// At some point this should all be made consistent and probably just use FileSystems.MacroPartialsFileSystem.
2020-06-03 20:39:54 +02:00
var partialsDir = _hostingEnvironment.MapPathContentRoot(Constants.SystemDirectories.MacroPartials);
return this.FindPartialViewFilesInFolder(
partialsDir,
partialsDir,
Constants.SystemDirectories.MacroPartials);
}
/// <summary>
/// Finds partial view files in app plugin folders.
/// </summary>
/// <returns>
/// </returns>
private IEnumerable<string> FindPartialViewFilesInPluginFolders()
{
var files = new List<string>();
2020-06-03 20:39:54 +02:00
var appPluginsFolder = new DirectoryInfo(_hostingEnvironment.MapPathContentRoot(Constants.SystemDirectories.AppPlugins));
if (!appPluginsFolder.Exists)
{
return files;
}
foreach (var directory in appPluginsFolder.GetDirectories())
{
var viewsFolder = directory.GetDirectories("Views");
if (viewsFolder.Any())
{
var macroPartials = viewsFolder.First().GetDirectories("MacroPartials");
if (macroPartials.Any())
{
files.AddRange(this.FindPartialViewFilesInFolder(macroPartials.First().FullName, macroPartials.First().FullName, Constants.SystemDirectories.AppPlugins + "/" + directory.Name + "/Views/MacroPartials"));
}
}
}
return files;
}
/// <summary>
/// Finds all partial views in a folder and subfolders
/// </summary>
/// <param name="orgPath">
/// The org path.
/// </param>
/// <param name="path">
/// The path.
/// </param>
/// <param name="prefixVirtualPath">
/// The prefix virtual path.
/// </param>
/// <returns>
/// The <see cref="IEnumerable"/>.
/// </returns>
private IEnumerable<string> FindPartialViewFilesInFolder(string orgPath, string path, string prefixVirtualPath)
{
var files = new List<string>();
var dirInfo = new DirectoryInfo(path);
2020-06-03 20:39:54 +02:00
if (dirInfo.Exists)
{
2020-06-03 20:39:54 +02:00
foreach (var dir in dirInfo.GetDirectories())
{
files.AddRange(this.FindPartialViewFilesInFolder(orgPath, path + "/" + dir.Name, prefixVirtualPath));
}
2020-06-03 20:39:54 +02:00
var fileInfo = dirInfo.GetFiles("*.*");
2020-06-03 20:39:54 +02:00
files.AddRange(
fileInfo.Select(file =>
Merge remote-tracking branch 'origin/v8/dev' into netcore/dev # Conflicts: # build/NuSpecs/UmbracoCms.Core.nuspec # build/NuSpecs/UmbracoCms.Web.nuspec # src/SolutionInfo.cs # src/Umbraco.Core/Cache/CacheKeys.cs # src/Umbraco.Core/Composing/TypeFinder.cs # src/Umbraco.Core/Configuration/GlobalSettings.cs # src/Umbraco.Core/Configuration/GlobalSettingsExtensions.cs # src/Umbraco.Core/Configuration/IGlobalSettings.cs # src/Umbraco.Core/Configuration/UmbracoSettings/ContentElement.cs # src/Umbraco.Core/Configuration/UmbracoSettings/ContentSectionExtensions.cs # src/Umbraco.Core/Constants-AppSettings.cs # src/Umbraco.Core/Editors/UserEditorAuthorizationHelper.cs # src/Umbraco.Core/Extensions/StringExtensions.cs # src/Umbraco.Core/Extensions/UriExtensions.cs # src/Umbraco.Core/IO/IOHelper.cs # src/Umbraco.Core/IO/PhysicalFileSystem.cs # src/Umbraco.Core/Media/Exif/MathEx.cs # src/Umbraco.Core/Media/UploadAutoFillProperties.cs # src/Umbraco.Core/Models/Mapping/UserMapDefinition.cs # src/Umbraco.Core/Models/Membership/User.cs # src/Umbraco.Core/Models/UserExtensions.cs # src/Umbraco.Core/Packaging/PackageDefinitionXmlParser.cs # src/Umbraco.Core/PropertyEditors/ListViewConfiguration.cs # src/Umbraco.Core/PropertyEditors/ValueConverters/MediaPickerValueConverter.cs # src/Umbraco.Core/PropertyEditors/ValueConverters/MultiNodeTreePickerValueConverter.cs # src/Umbraco.Core/Routing/AliasUrlProvider.cs # src/Umbraco.Core/Routing/DefaultUrlProvider.cs # src/Umbraco.Core/Routing/UriUtility.cs # src/Umbraco.Core/Routing/UrlProviderExtensions.cs # src/Umbraco.Core/Runtime/CoreRuntime.cs # src/Umbraco.Core/RuntimeOptions.cs # src/Umbraco.Core/RuntimeState.cs # src/Umbraco.Core/Security/BackOfficeUserStore.cs # src/Umbraco.Core/Security/ContentPermissions.cs # src/Umbraco.Core/Sync/ApplicationUrlHelper.cs # src/Umbraco.Core/Trees/TreeNode.cs # src/Umbraco.Core/Udi.cs # src/Umbraco.Examine.Lucene/BackOfficeExamineSearcher.cs # src/Umbraco.Examine/Umbraco.Examine.csproj # src/Umbraco.Infrastructure/Examine/ContentValueSetValidator.cs # src/Umbraco.Infrastructure/Migrations/Install/DatabaseBuilder.cs # src/Umbraco.Infrastructure/Packaging/PackageDataInstallation.cs # src/Umbraco.Infrastructure/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs # src/Umbraco.Infrastructure/Scoping/Scope.cs # src/Umbraco.Infrastructure/Search/ExamineComponent.cs # src/Umbraco.Infrastructure/Security/IdentityMapDefinition.cs # src/Umbraco.Infrastructure/Services/Implement/ContentService.cs # src/Umbraco.Infrastructure/Services/Implement/MediaService.cs # src/Umbraco.Infrastructure/Services/Implement/NotificationService.cs # src/Umbraco.Persistence.SqlCe/SqlCeSyntaxProvider.cs # src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/LocksTests.cs # src/Umbraco.Tests.UnitTests/Umbraco.Core/Models/UserExtensionsTests.cs # src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Editors/UserEditorAuthorizationHelperTests.cs # src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Examine/UmbracoContentValueSetValidatorTests.cs # src/Umbraco.Tests/Configurations/UmbracoSettings/ContentElementTests.cs # src/Umbraco.Tests/Configurations/UmbracoSettings/umbracoSettings.config # src/Umbraco.Tests/TestHelpers/SettingsForTests.cs # src/Umbraco.Tests/Testing/TestDatabase.cs # src/Umbraco.Tests/Web/Controllers/ContentControllerUnitTests.cs # src/Umbraco.Tests/Web/Controllers/FilterAllowedOutgoingContentAttributeTests.cs # src/Umbraco.Tests/Web/Controllers/MediaControllerUnitTests.cs # src/Umbraco.Web.BackOffice/Controllers/BackOfficeServerVariables.cs # src/Umbraco.Web.BackOffice/Controllers/CodeFileController.cs # src/Umbraco.Web.BackOffice/Controllers/ContentController.cs # src/Umbraco.Web.BackOffice/Controllers/EntityController.cs # src/Umbraco.Web.BackOffice/Controllers/MacrosController.cs # src/Umbraco.Web.BackOffice/Controllers/MediaController.cs # src/Umbraco.Web.BackOffice/Controllers/PackageInstallController.cs # src/Umbraco.Web.BackOffice/Controllers/TourController.cs # src/Umbraco.Web.BackOffice/Controllers/UserGroupEditorAuthorizationHelper.cs # src/Umbraco.Web.BackOffice/Filters/FilterAllowedOutgoingContentAttribute.cs # src/Umbraco.Web.BackOffice/Filters/FilterAllowedOutgoingMediaAttribute.cs # src/Umbraco.Web.BackOffice/Mapping/ContentMapDefinition.cs # src/Umbraco.Web.BackOffice/Services/IconService.cs # src/Umbraco.Web.BackOffice/Trees/ContentTreeController.cs # src/Umbraco.Web.BackOffice/Trees/ContentTreeControllerBase.cs # src/Umbraco.Web.BackOffice/Trees/FileSystemTreeController.cs # src/Umbraco.Web.BackOffice/Trees/MediaTreeController.cs # src/Umbraco.Web.Common/Extensions/FormCollectionExtensions.cs # src/Umbraco.Web.UI.Client/src/common/resources/content.resource.js # src/Umbraco.Web.UI.Client/src/views/content/overlays/publish.html # src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/editors/media.controller.js # src/Umbraco.Web.UI.NetCore/umbraco/config/lang/da.xml # src/Umbraco.Web.UI.NetCore/umbraco/config/lang/en.xml # src/Umbraco.Web.UI.NetCore/umbraco/config/lang/en_us.xml # src/Umbraco.Web.UI/config/umbracoSettings.Release.config # src/Umbraco.Web/Cache/MemberCacheRefresher.cs # src/Umbraco.Web/Composing/ModuleInjector.cs # src/Umbraco.Web/Editors/BackOfficeController.cs # src/Umbraco.Web/Editors/Binders/ContentModelBinderHelper.cs # src/Umbraco.Web/Editors/ContentTypeController.cs # src/Umbraco.Web/Editors/Filters/ContentSaveValidationAttribute.cs # src/Umbraco.Web/Editors/Filters/MediaItemSaveValidationAttribute.cs # src/Umbraco.Web/Editors/Filters/UserGroupAuthorizationAttribute.cs # src/Umbraco.Web/Editors/TinyMceController.cs # src/Umbraco.Web/Editors/UserGroupsController.cs # src/Umbraco.Web/Editors/UsersController.cs # src/Umbraco.Web/ImageCropperTemplateExtensions.cs # src/Umbraco.Web/Logging/WebProfiler.cs # src/Umbraco.Web/Logging/WebProfilerProvider.cs # src/Umbraco.Web/Macros/PublishedContentHashtableConverter.cs # src/Umbraco.Web/Mvc/EnsurePublishedContentRequestAttribute.cs # src/Umbraco.Web/Mvc/JsonNetResult.cs # src/Umbraco.Web/Mvc/MemberAuthorizeAttribute.cs # src/Umbraco.Web/Mvc/RenderRouteHandler.cs # src/Umbraco.Web/PropertyEditors/MediaPickerPropertyEditor.cs # src/Umbraco.Web/PropertyEditors/MultiNodeTreePickerPropertyEditor.cs # src/Umbraco.Web/PublishedCache/NuCache/DataSource/DatabaseDataSource.cs # src/Umbraco.Web/RoutableDocumentFilter.cs # src/Umbraco.Web/Routing/ContentFinderByUrlAlias.cs # src/Umbraco.Web/Routing/NotFoundHandlerHelper.cs # src/Umbraco.Web/Routing/PublishedRouter.cs # src/Umbraco.Web/Runtime/WebInitialComposer.cs # src/Umbraco.Web/Scheduling/KeepAlive.cs # src/Umbraco.Web/Security/AppBuilderExtensions.cs # src/Umbraco.Web/Security/BackOfficeClaimsIdentityFactory.cs # src/Umbraco.Web/Security/Providers/UmbracoMembershipProvider.cs # src/Umbraco.Web/Trees/DictionaryTreeController.cs # src/Umbraco.Web/Trees/LanguageTreeController.cs # src/Umbraco.Web/Trees/LogViewerTreeController.cs # src/Umbraco.Web/Trees/PackagesTreeController.cs # src/Umbraco.Web/UmbracoApplication.cs # src/Umbraco.Web/UmbracoApplicationBase.cs # src/Umbraco.Web/UmbracoInjectedModule.cs # src/Umbraco.Web/WebApi/Filters/AdminUsersAuthorizeAttribute.cs # src/Umbraco.Web/WebApi/Filters/CheckIfUserTicketDataIsStaleAttribute.cs # src/Umbraco.Web/WebApi/Filters/EnsureUserPermissionForContentAttribute.cs # src/Umbraco.Web/WebApi/Filters/EnsureUserPermissionForMediaAttribute.cs # src/Umbraco.Web/WebApi/MemberAuthorizeAttribute.cs
2021-03-05 15:36:27 +01:00
prefixVirtualPath.TrimEnd(Constants.CharArrays.ForwardSlash) + "/" + (path.Replace(orgPath, string.Empty).Trim(Constants.CharArrays.ForwardSlash) + "/" + file.Name).Trim(Constants.CharArrays.ForwardSlash)));
2020-06-03 20:39:54 +02:00
}
return files;
}
2020-01-08 19:02:16 +01:00
/// <summary>
/// Used to map an <see cref="IMacro"/> instance to a <see cref="MacroDisplay"/>
/// </summary>
/// <param name="macro"></param>
/// <returns></returns>
private MacroDisplay MapToDisplay(IMacro macro)
{
2020-06-03 20:39:54 +02:00
var display = _umbracoMapper.Map<MacroDisplay>(macro);
2020-01-08 19:02:16 +01:00
var parameters = macro.Properties.Values
.OrderBy(x => x.SortOrder)
.Select(x => new MacroParameterDisplay()
{
Editor = x.EditorAlias,
Key = x.Alias,
Label = x.Name,
Id = x.Id
});
display.Parameters = parameters;
return display;
}
}
}