2019-12-20 17:36:44 +01:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
2018-06-29 19:52:40 +02:00
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using System.Net;
|
|
|
|
|
|
using System.Net.Http;
|
|
|
|
|
|
using System.Web.Http;
|
2019-02-01 15:24:07 +11:00
|
|
|
|
using Umbraco.Core;
|
|
|
|
|
|
using Umbraco.Core.Cache;
|
|
|
|
|
|
using Umbraco.Core.Configuration;
|
2018-06-29 19:52:40 +02:00
|
|
|
|
using Umbraco.Core.IO;
|
2019-02-01 15:24:07 +11:00
|
|
|
|
using Umbraco.Core.Logging;
|
2020-01-20 14:15:54 -08:00
|
|
|
|
using Umbraco.Core.Mapping;
|
2018-06-29 19:52:40 +02:00
|
|
|
|
using Umbraco.Core.Models;
|
2019-02-01 15:24:07 +11:00
|
|
|
|
using Umbraco.Core.Persistence;
|
|
|
|
|
|
using Umbraco.Core.Services;
|
2019-12-20 17:36:44 +01:00
|
|
|
|
using Umbraco.Core.Strings;
|
2018-06-29 19:52:40 +02:00
|
|
|
|
using Umbraco.Web.Models.ContentEditing;
|
|
|
|
|
|
using Umbraco.Web.Mvc;
|
2020-02-14 13:04:49 +01:00
|
|
|
|
using Umbraco.Web.Routing;
|
2018-06-29 19:52:40 +02:00
|
|
|
|
using Umbraco.Web.WebApi.Filters;
|
|
|
|
|
|
using Constants = Umbraco.Core.Constants;
|
|
|
|
|
|
|
|
|
|
|
|
namespace Umbraco.Web.Editors
|
|
|
|
|
|
{
|
|
|
|
|
|
[PluginController("UmbracoApi")]
|
|
|
|
|
|
[UmbracoTreeAuthorize(Constants.Trees.Templates)]
|
|
|
|
|
|
public class TemplateController : BackOfficeNotificationsController
|
|
|
|
|
|
{
|
2020-02-14 13:04:49 +01:00
|
|
|
|
public TemplateController(
|
|
|
|
|
|
IGlobalSettings globalSettings,
|
|
|
|
|
|
IUmbracoContextAccessor umbracoContextAccessor,
|
|
|
|
|
|
ISqlContext sqlContext,
|
|
|
|
|
|
ServiceContext services,
|
|
|
|
|
|
AppCaches appCaches,
|
|
|
|
|
|
IProfilingLogger logger,
|
|
|
|
|
|
IRuntimeState runtimeState,
|
|
|
|
|
|
IShortStringHelper shortStringHelper,
|
|
|
|
|
|
UmbracoMapper umbracoMapper,
|
|
|
|
|
|
IPublishedUrlProvider publishedUrlProvider)
|
2020-03-03 11:59:17 +01:00
|
|
|
|
: base(globalSettings, umbracoContextAccessor, sqlContext, services, appCaches, logger, runtimeState, shortStringHelper, umbracoMapper, publishedUrlProvider)
|
2019-02-01 15:24:07 +11:00
|
|
|
|
{
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-06-29 19:52:40 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Gets data type by alias
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="alias"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public TemplateDisplay GetByAlias(string alias)
|
|
|
|
|
|
{
|
|
|
|
|
|
var template = Services.FileService.GetTemplate(alias);
|
|
|
|
|
|
return template == null ? null : Mapper.Map<ITemplate, TemplateDisplay>(template);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Get all templates
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public IEnumerable<EntityBasic> GetAll()
|
|
|
|
|
|
{
|
|
|
|
|
|
return Services.FileService.GetTemplates().Select(Mapper.Map<ITemplate, EntityBasic>);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Gets the content json for the content id
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="id"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public TemplateDisplay GetById(int id)
|
|
|
|
|
|
{
|
|
|
|
|
|
var template = Services.FileService.GetTemplate(id);
|
|
|
|
|
|
if (template == null)
|
|
|
|
|
|
throw new HttpResponseException(HttpStatusCode.NotFound);
|
|
|
|
|
|
|
|
|
|
|
|
return Mapper.Map<ITemplate, TemplateDisplay>(template);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2019-01-26 10:52:19 -05:00
|
|
|
|
/// Deletes a template with a given ID
|
2018-06-29 19:52:40 +02:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="id"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
[HttpDelete]
|
|
|
|
|
|
[HttpPost]
|
|
|
|
|
|
public HttpResponseMessage DeleteById(int id)
|
|
|
|
|
|
{
|
|
|
|
|
|
var template = Services.FileService.GetTemplate(id);
|
|
|
|
|
|
if (template == null)
|
|
|
|
|
|
throw new HttpResponseException(HttpStatusCode.NotFound);
|
|
|
|
|
|
|
|
|
|
|
|
Services.FileService.DeleteTemplate(template.Alias);
|
|
|
|
|
|
return Request.CreateResponse(HttpStatusCode.OK);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public TemplateDisplay GetScaffold(int id)
|
|
|
|
|
|
{
|
|
|
|
|
|
//empty default
|
2019-12-20 17:36:44 +01:00
|
|
|
|
var dt = new Template(ShortStringHelper, string.Empty, string.Empty);
|
2018-06-29 19:52:40 +02:00
|
|
|
|
dt.Path = "-1";
|
|
|
|
|
|
|
|
|
|
|
|
if (id > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
var master = Services.FileService.GetTemplate(id);
|
|
|
|
|
|
if(master != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
dt.SetMasterTemplate(master);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var content = ViewHelper.GetDefaultFileContent( layoutPageAlias: dt.MasterTemplateAlias );
|
|
|
|
|
|
var scaffold = Mapper.Map<ITemplate, TemplateDisplay>(dt);
|
|
|
|
|
|
|
|
|
|
|
|
scaffold.Content = content + "\r\n\r\n@* the fun starts here *@\r\n\r\n";
|
|
|
|
|
|
return scaffold;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Saves the data type
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="display"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public TemplateDisplay PostSave(TemplateDisplay display)
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
//Checking the submitted is valid with the Required attributes decorated on the ViewModel
|
|
|
|
|
|
if (ModelState.IsValid == false)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (display.Id > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
// update
|
|
|
|
|
|
var template = Services.FileService.GetTemplate(display.Id);
|
|
|
|
|
|
if (template == null)
|
|
|
|
|
|
throw new HttpResponseException(HttpStatusCode.NotFound);
|
|
|
|
|
|
|
|
|
|
|
|
var changeMaster = template.MasterTemplateAlias != display.MasterTemplateAlias;
|
|
|
|
|
|
var changeAlias = template.Alias != display.Alias;
|
|
|
|
|
|
|
|
|
|
|
|
Mapper.Map(display, template);
|
|
|
|
|
|
|
|
|
|
|
|
if (changeMaster)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (string.IsNullOrEmpty(display.MasterTemplateAlias) == false)
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
var master = Services.FileService.GetTemplate(display.MasterTemplateAlias);
|
|
|
|
|
|
if(master == null || master.Id == display.Id)
|
|
|
|
|
|
{
|
|
|
|
|
|
template.SetMasterTemplate(null);
|
|
|
|
|
|
}else
|
|
|
|
|
|
{
|
|
|
|
|
|
template.SetMasterTemplate(master);
|
|
|
|
|
|
|
|
|
|
|
|
//After updating the master - ensure we update the path property if it has any children already assigned
|
|
|
|
|
|
var templateHasChildren = Services.FileService.GetTemplateDescendants(display.Id);
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var childTemplate in templateHasChildren)
|
|
|
|
|
|
{
|
|
|
|
|
|
//template ID to find
|
|
|
|
|
|
var templateIdInPath = "," + display.Id + ",";
|
|
|
|
|
|
|
|
|
|
|
|
if (string.IsNullOrEmpty(childTemplate.Path))
|
|
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-01-14 09:32:32 -05:00
|
|
|
|
//Find position in current comma separate string path (so we get the correct children path)
|
2018-06-29 19:52:40 +02:00
|
|
|
|
var positionInPath = childTemplate.Path.IndexOf(templateIdInPath) + templateIdInPath.Length;
|
|
|
|
|
|
|
|
|
|
|
|
//Get the substring of the child & any children (descendants it may have too)
|
|
|
|
|
|
var childTemplatePath = childTemplate.Path.Substring(positionInPath);
|
|
|
|
|
|
|
|
|
|
|
|
//As we are updating the template to be a child of a master
|
|
|
|
|
|
//Set the path to the master's path + its current template id + the current child path substring
|
|
|
|
|
|
childTemplate.Path = master.Path + "," + display.Id + "," + childTemplatePath;
|
|
|
|
|
|
|
|
|
|
|
|
//Save the children with the updated path
|
|
|
|
|
|
Services.FileService.SaveTemplate(childTemplate);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
//remove the master
|
|
|
|
|
|
template.SetMasterTemplate(null);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Services.FileService.SaveTemplate(template);
|
|
|
|
|
|
|
|
|
|
|
|
if (changeAlias)
|
|
|
|
|
|
{
|
|
|
|
|
|
template = Services.FileService.GetTemplate(template.Id);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Mapper.Map(template, display);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
//create
|
|
|
|
|
|
ITemplate master = null;
|
|
|
|
|
|
if (string.IsNullOrEmpty(display.MasterTemplateAlias) == false)
|
|
|
|
|
|
{
|
|
|
|
|
|
master = Services.FileService.GetTemplate(display.MasterTemplateAlias);
|
|
|
|
|
|
if (master == null)
|
|
|
|
|
|
throw new HttpResponseException(HttpStatusCode.NotFound);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-01-30 17:06:15 +01:00
|
|
|
|
// we need to pass the template name as alias to keep the template file casing consistent with templates created with content
|
|
|
|
|
|
// - see comment in FileService.CreateTemplateForContentType for additional details
|
|
|
|
|
|
var template = Services.FileService.CreateTemplateWithIdentity(display.Name, display.Name, display.Content, master);
|
2018-06-29 19:52:40 +02:00
|
|
|
|
Mapper.Map(template, display);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return display;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|