2019-01-21 10:55:48 +01:00
|
|
|
|
using Umbraco.Core.Services;
|
|
|
|
|
|
|
|
|
|
|
|
namespace Umbraco.Web.Editors
|
2019-01-04 12:31:58 +01:00
|
|
|
|
{
|
2019-01-18 09:31:38 +01:00
|
|
|
|
using System;
|
2019-01-16 16:21:19 +01:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.IO;
|
|
|
|
|
|
using System.Linq;
|
2019-01-18 09:31:38 +01:00
|
|
|
|
using System.Net;
|
|
|
|
|
|
using System.Net.Http;
|
|
|
|
|
|
using System.Web.Http;
|
2019-01-16 16:21:19 +01:00
|
|
|
|
|
2019-01-18 09:31:38 +01:00
|
|
|
|
using Umbraco.Core;
|
2019-01-16 16:21:19 +01:00
|
|
|
|
using Umbraco.Core.IO;
|
2019-01-18 09:31:38 +01:00
|
|
|
|
using Umbraco.Core.Logging;
|
|
|
|
|
|
using Umbraco.Core.Models;
|
2019-01-16 16:37:33 +01:00
|
|
|
|
using Umbraco.Web.Composing;
|
2019-01-18 09:31:38 +01:00
|
|
|
|
using Umbraco.Web.Models.ContentEditing;
|
|
|
|
|
|
using Umbraco.Web.Mvc;
|
2019-01-18 15:02:18 +01:00
|
|
|
|
using Umbraco.Web.UI;
|
2019-01-18 09:31:38 +01:00
|
|
|
|
using Umbraco.Web.WebApi;
|
|
|
|
|
|
using Umbraco.Web.WebApi.Filters;
|
|
|
|
|
|
|
|
|
|
|
|
using Constants = Umbraco.Core.Constants;
|
2019-01-16 16:21:19 +01:00
|
|
|
|
|
2019-01-04 12:31:58 +01:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// The API controller used for editing dictionary items
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
[PluginController("UmbracoApi")]
|
|
|
|
|
|
[UmbracoTreeAuthorize(Constants.Trees.Macros)]
|
|
|
|
|
|
public class MacrosController : BackOfficeNotificationsController
|
|
|
|
|
|
{
|
2019-01-21 10:55:48 +01:00
|
|
|
|
private readonly IMacroService _macroService;
|
|
|
|
|
|
|
|
|
|
|
|
public MacrosController(IMacroService macroService)
|
|
|
|
|
|
{
|
|
|
|
|
|
_macroService = macroService;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-01-04 12:31:58 +01:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Creates a new macro
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="name">
|
|
|
|
|
|
/// The name.
|
|
|
|
|
|
/// </param>
|
|
|
|
|
|
/// <returns>
|
|
|
|
|
|
/// The <see cref="HttpResponseMessage"/>.
|
|
|
|
|
|
/// </returns>
|
|
|
|
|
|
[HttpPost]
|
|
|
|
|
|
public HttpResponseMessage Create(string name)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(name))
|
2019-01-18 09:31:38 +01:00
|
|
|
|
{
|
|
|
|
|
|
return this.ReturnErrorResponse("Name can not be empty");
|
|
|
|
|
|
}
|
2019-01-04 12:31:58 +01:00
|
|
|
|
|
|
|
|
|
|
var alias = name.ToSafeAlias();
|
|
|
|
|
|
|
2019-01-21 10:55:48 +01:00
|
|
|
|
if (_macroService.GetByAlias(alias) != null)
|
2019-01-04 12:31:58 +01:00
|
|
|
|
{
|
2019-01-18 15:02:18 +01:00
|
|
|
|
return this.ReturnErrorResponse("Macro with this alias already exists");
|
2019-01-04 12:31:58 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
2019-01-18 09:31:38 +01:00
|
|
|
|
var macro = new Macro
|
2019-01-18 15:02:18 +01:00
|
|
|
|
{
|
|
|
|
|
|
Alias = alias,
|
|
|
|
|
|
Name = name,
|
|
|
|
|
|
MacroSource = string.Empty,
|
|
|
|
|
|
MacroType = MacroTypes.PartialView
|
|
|
|
|
|
};
|
2019-01-04 12:31:58 +01:00
|
|
|
|
|
2019-01-21 10:55:48 +01:00
|
|
|
|
_macroService.Save(macro, this.Security.CurrentUser.Id);
|
2019-01-04 12:31:58 +01:00
|
|
|
|
|
2019-01-18 09:31:38 +01:00
|
|
|
|
return this.Request.CreateResponse(HttpStatusCode.OK, macro.Id);
|
2019-01-04 12:31:58 +01:00
|
|
|
|
}
|
|
|
|
|
|
catch (Exception exception)
|
|
|
|
|
|
{
|
2019-01-18 09:31:38 +01:00
|
|
|
|
return this.ReturnErrorResponse("Error creating macro", true, exception);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
[HttpGet]
|
2019-01-18 15:02:18 +01:00
|
|
|
|
public HttpResponseMessage 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 this.ReturnErrorResponse($"Macro with id {id} does not exist");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var macroDisplay = new MacroDisplay
|
2019-01-18 15:02:18 +01:00
|
|
|
|
{
|
|
|
|
|
|
Alias = macro.Alias,
|
|
|
|
|
|
Id = macro.Id,
|
|
|
|
|
|
Key = macro.Key,
|
|
|
|
|
|
Name = macro.Name,
|
|
|
|
|
|
CacheByPage = macro.CacheByPage,
|
|
|
|
|
|
CacheByUser = macro.CacheByMember,
|
|
|
|
|
|
CachePeriod = macro.CacheDuration,
|
|
|
|
|
|
View = macro.MacroSource,
|
|
|
|
|
|
RenderInEditor = !macro.DontRender,
|
|
|
|
|
|
UseInEditor = macro.UseInEditor,
|
|
|
|
|
|
Path = $"-1,{macro.Id}"
|
|
|
|
|
|
};
|
2019-01-18 09:31:38 +01:00
|
|
|
|
|
|
|
|
|
|
var parameters = new List<MacroParameterDisplay>();
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var param in macro.Properties.Values.OrderBy(x => x.SortOrder))
|
|
|
|
|
|
{
|
|
|
|
|
|
parameters.Add(new MacroParameterDisplay
|
2019-01-18 15:02:18 +01:00
|
|
|
|
{
|
|
|
|
|
|
Editor = param.EditorAlias,
|
|
|
|
|
|
Key = param.Alias,
|
|
|
|
|
|
Label = param.Name,
|
|
|
|
|
|
Id = param.Id
|
|
|
|
|
|
});
|
2019-01-16 16:21:19 +01:00
|
|
|
|
}
|
2019-01-18 09:31:38 +01:00
|
|
|
|
|
|
|
|
|
|
macroDisplay.Parameters = parameters;
|
|
|
|
|
|
|
|
|
|
|
|
return this.Request.CreateResponse(HttpStatusCode.OK, macroDisplay);
|
2019-01-16 16:21:19 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2019-01-21 10:44:11 +01:00
|
|
|
|
|
|
|
|
|
|
[HttpPost]
|
|
|
|
|
|
public HttpResponseMessage DeleteById(int id)
|
|
|
|
|
|
{
|
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 this.ReturnErrorResponse($"Macro with id {id} does not exist");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-01-21 10:55:48 +01:00
|
|
|
|
_macroService.Delete(macro);
|
2019-01-21 10:44:11 +01:00
|
|
|
|
|
|
|
|
|
|
return Request.CreateResponse(HttpStatusCode.OK);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-01-18 15:02:18 +01:00
|
|
|
|
[HttpPost]
|
|
|
|
|
|
public HttpResponseMessage Save(MacroDisplay macroDisplay)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (macroDisplay == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
return this.ReturnErrorResponse($"No macro data found in request");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-01-21 10:55:48 +01:00
|
|
|
|
var macro = _macroService.GetById(int.Parse(macroDisplay.Id.ToString()));
|
2019-01-18 15:02:18 +01:00
|
|
|
|
|
|
|
|
|
|
if (macro == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
return this.ReturnErrorResponse($"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);
|
2019-01-18 15:02:18 +01:00
|
|
|
|
|
|
|
|
|
|
if (macroByAlias != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
return this.ReturnErrorResponse("Macro with this alias already exists");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
macro.MacroType = MacroTypes.PartialView;
|
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)));
|
2019-01-18 15:02:18 +01:00
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
2019-01-21 10:55:48 +01:00
|
|
|
|
_macroService.Save(macro, this.Security.CurrentUser.Id);
|
2019-01-18 15:02:18 +01:00
|
|
|
|
|
|
|
|
|
|
macroDisplay.Notifications.Clear();
|
|
|
|
|
|
|
|
|
|
|
|
macroDisplay.Notifications.Add(new Models.ContentEditing.Notification("Success", "Macro saved", SpeechBubbleIcon.Success));
|
|
|
|
|
|
|
|
|
|
|
|
return this.Request.CreateResponse(HttpStatusCode.OK, macroDisplay);
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception exception)
|
|
|
|
|
|
{
|
|
|
|
|
|
return this.ReturnErrorResponse("Error creating macro", true, exception);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-01-16 16:21:19 +01:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Gets a list of available macro partials
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns>
|
|
|
|
|
|
/// The <see cref="HttpResponseMessage"/>.
|
|
|
|
|
|
/// </returns>
|
|
|
|
|
|
public HttpResponseMessage GetPartialViews()
|
|
|
|
|
|
{
|
|
|
|
|
|
var views = new List<string>();
|
|
|
|
|
|
|
|
|
|
|
|
views.AddRange(this.FindPartialViewsFiles());
|
|
|
|
|
|
|
|
|
|
|
|
return this.Request.CreateResponse(HttpStatusCode.OK, views);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-01-16 16:37:33 +01:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Gets the available parameter editors
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns>
|
|
|
|
|
|
/// The <see cref="HttpResponseMessage"/>.
|
|
|
|
|
|
/// </returns>
|
|
|
|
|
|
public HttpResponseMessage GetParameterEditors()
|
|
|
|
|
|
{
|
|
|
|
|
|
return this.Request.CreateResponse(HttpStatusCode.OK, Current.ParameterEditors);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-01-18 09:31:38 +01:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Returns a error response and optionally logs it
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="message">
|
|
|
|
|
|
/// The error message.
|
|
|
|
|
|
/// </param>
|
|
|
|
|
|
/// <param name="logError">
|
|
|
|
|
|
/// Value to indicate if the error needs to be logged
|
|
|
|
|
|
/// </param>
|
|
|
|
|
|
/// <param name="exception">
|
|
|
|
|
|
/// The exception to log
|
|
|
|
|
|
/// </param>
|
|
|
|
|
|
/// <returns>
|
|
|
|
|
|
/// The <see cref="HttpResponseMessage"/>.
|
|
|
|
|
|
/// </returns>
|
|
|
|
|
|
private HttpResponseMessage ReturnErrorResponse(string message, bool logError = false, Exception exception = null)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (logError && exception != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
this.Logger.Error<MacrosController>(exception, message);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return this.Request.CreateNotificationValidationErrorResponse(message);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-01-16 16:21:19 +01:00
|
|
|
|
/// <summary>
|
2019-01-21 09:10:08 +01:00
|
|
|
|
/// Finds all the macro partials
|
2019-01-16 16:21:19 +01:00
|
|
|
|
/// </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()
|
|
|
|
|
|
{
|
|
|
|
|
|
var partialsDir = IOHelper.MapPath(SystemDirectories.MacroPartials);
|
|
|
|
|
|
|
|
|
|
|
|
return this.FindPartialViewFilesInFolder(
|
|
|
|
|
|
partialsDir,
|
|
|
|
|
|
partialsDir,
|
|
|
|
|
|
SystemDirectories.MacroPartials);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Finds partial view files in app plugin folders.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns>
|
|
|
|
|
|
/// The <see cref="IEnumerable"/>.
|
|
|
|
|
|
/// </returns>
|
|
|
|
|
|
private IEnumerable<string> FindPartialViewFilesInPluginFolders()
|
|
|
|
|
|
{
|
|
|
|
|
|
var files = new List<string>();
|
|
|
|
|
|
|
|
|
|
|
|
var appPluginsFolder = new DirectoryInfo(IOHelper.MapPath(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, 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);
|
2019-01-18 15:02:18 +01:00
|
|
|
|
|
2019-01-16 16:21:19 +01:00
|
|
|
|
foreach (var dir in dirInfo.GetDirectories())
|
|
|
|
|
|
{
|
|
|
|
|
|
files.AddRange(this.FindPartialViewFilesInFolder(orgPath, path + "/" + dir.Name, prefixVirtualPath));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var fileInfo = dirInfo.GetFiles("*.*");
|
|
|
|
|
|
|
|
|
|
|
|
files.AddRange(
|
|
|
|
|
|
fileInfo.Select(file =>
|
|
|
|
|
|
prefixVirtualPath.TrimEnd('/') + "/" + (path.Replace(orgPath, string.Empty).Trim('/') + "/" + file.Name).Trim('/')));
|
|
|
|
|
|
|
|
|
|
|
|
return files;
|
2019-01-04 12:31:58 +01:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|