Merge with 4.11.8

This commit is contained in:
Shannon Deminick
2013-04-25 14:15:09 -10:00
14 changed files with 316 additions and 94 deletions

View File

@@ -27,6 +27,7 @@ ff3bb24ea0c915878396a6ae27f1ff164e8ac150 Release-6.0.0-beta
1719fbd857f28b376639ac2aa0abada0ef2e7560 Release-6.0.0
e02f5aebb87e3f07d27376647756caa9762931d8 Release-4.11.4
14338b0ab1738fbd8987677ecdb9a73d79fc229d release-4.11.6
ce47176bc6b9298741783e20f1fe2672c811f744 release-4.11.7
b247b35d821144849f551e02da8ba719f91d5fb0 Release-6.0.2
aed55cba29009ad3db48880a7cfb66407ce9805f release-6.0.3
0dee9964687ea51ea797984cf7cce3655d6a6558 release-6.0.4

View File

@@ -21,7 +21,7 @@
}
body
{
font-size: 11px;
font-size: 11px;
width: 100%;
font-family: Trebuchet MS, verdana, arial, Lucida Grande;
text-align: center;
@@ -70,7 +70,7 @@
<asp:Label ID="username" runat="server" AssociatedControlID="lname"></asp:Label>
</td>
<td>
<asp:TextBox ID="lname" Style="padding-left: 3px; background: url(images/gradientBackground.png);
<asp:TextBox AutoCompleteType="None" autocomplete="off" ID="lname" Style="padding-left: 3px; background: url(images/gradientBackground.png);
_background: none; border-right: #999999 1px solid; border-top: #999999 1px solid;
border-left: #999999 1px solid; border-bottom: #999999 1px solid; width: 180px;"
runat="server"></asp:TextBox>
@@ -85,7 +85,7 @@
<asp:Label ID="password" runat="server" AssociatedControlID="passw"></asp:Label>
</td>
<td>
<asp:TextBox ID="passw" Style="padding-left: 3px; background: url(images/gradientBackground.png);
<asp:TextBox AutoCompleteType="None" autocomplete="off" ID="passw" Style="padding-left: 3px; background: url(images/gradientBackground.png);
_background: none; border-right: #999999 1px solid; border-top: #999999 1px solid;
border-left: #999999 1px solid; border-bottom: #999999 1px solid; width: 180px;"
runat="server" TextMode="Password"></asp:TextBox>

View File

@@ -93,7 +93,7 @@
<globalization requestEncoding="UTF-8" responseEncoding="UTF-8" />
<xhtmlConformance mode="Strict" />
<httpRuntime requestValidationMode="2.0" />
<httpRuntime requestValidationMode="2.0" enableVersionHeader="false" />
<pages enableEventValidation="false">
<!-- ASPNETAJAX -->
@@ -232,6 +232,14 @@
<remove fileExtension=".air" />
<mimeMap fileExtension=".air" mimeType="application/vnd.adobe.air-application-installer-package+zip" />
</staticContent>
<!-- Ensure the powered by header is not returned -->
<httpProtocol>
<customHeaders>
<remove name="X-Powered-By"/>
</customHeaders>
</httpProtocol>
</system.webServer>
<system.codedom>

View File

@@ -5,6 +5,7 @@ using System.Linq;
using System.Text;
using System.Web;
using System.Web.Hosting;
using System.Web.Mvc;
using Umbraco.Core;
using Umbraco.Core.Logging;
using Umbraco.Web.Routing;
@@ -17,6 +18,9 @@ namespace Umbraco.Web
/// </summary>
public class UmbracoApplication : UmbracoApplicationBase
{
//don't output the MVC version header (security)
MvcHandler.DisableMvcResponseHeader = true;
protected override IBootManager GetBootManager()
{

View File

@@ -426,6 +426,15 @@ namespace Umbraco.Web
DisposeHttpContextItems(httpContext);
};
//disable asp.net headers (security)
app.PreSendRequestHeaders += (sender, args) =>
{
var httpContext = ((HttpApplication)sender).Context;
httpContext.Response.Headers.Remove("Server");
//this doesn't normally work since IIS sets it but we'll keep it here anyways.
httpContext.Response.Headers.Remove("X-Powered-By");
};
}
public void Dispose()

View File

@@ -63,11 +63,13 @@ namespace umbraco.controls
//the async saving task
private Action<SaveAsyncState> _asyncSaveTask;
//the async delete property task
private Action<GenericPropertyWrapper> _asyncDeleteTask;
override protected void OnInit(EventArgs e)
{
base.OnInit(e);
LoadContentType();
SetupInfoPane();
@@ -78,17 +80,17 @@ namespace umbraco.controls
SetupGenericPropertiesPane();
SetupTabPane();
}
}
protected void Page_Load(object sender, EventArgs e)
{
pp_newTab.Text = ui.Text("newtab", UmbracoEnsuredPage.CurrentUser);
pp_alias.Text = ui.Text("alias", UmbracoEnsuredPage.CurrentUser);
pp_name.Text = ui.Text("name", UmbracoEnsuredPage.CurrentUser);
pp_allowedChildren.Text = ui.Text("allowedchildnodetypes", UmbracoEnsuredPage.CurrentUser);
pp_description.Text = ui.Text("editcontenttype", "description");
pp_icon.Text = ui.Text("icon", UmbracoEnsuredPage.CurrentUser);
pp_thumbnail.Text = ui.Text("editcontenttype", "thumbnail");
pp_newTab.Text = ui.Text("newtab", CurrentUser);
pp_alias.Text = ui.Text("alias", CurrentUser);
pp_name.Text = ui.Text("name", CurrentUser);
pp_allowedChildren.Text = ui.Text("allowedchildnodetypes", CurrentUser);
pp_description.Text = ui.Text("editcontenttype", "description", CurrentUser);
pp_icon.Text = ui.Text("icon", CurrentUser);
pp_thumbnail.Text = ui.Text("editcontenttype", "thumbnail", CurrentUser);
// we'll disable this...
@@ -130,20 +132,24 @@ namespace umbraco.controls
string originalAlias,
string originalName,
string newAlias,
string newName)
string newName
string[] originalPropertyAliases)
{
SaveArgs = saveArgs;
OriginalAlias = originalAlias;
OriginalName = originalName;
_originalAlias = originalAlias;
_originalName = originalName;
NewAlias = newAlias;
_originalPropertyAliases = originalPropertyAliases;
NewName = newName;
}
public SaveClickEventArgs SaveArgs { get; private set; }
public string OriginalAlias { get; private set; }
public string OriginalName { get; private set; }
private readonly string _originalAlias;
private readonly string _originalName;
public string NewAlias { get; private set; }
public string NewName { get; private set; }
private readonly string[] _originalPropertyAliases;
public bool HasAliasChanged()
{
@@ -153,6 +159,23 @@ namespace umbraco.controls
{
return (string.Compare(OriginalName, NewName, StringComparison.OrdinalIgnoreCase) != 0);
}
/// <summary>
/// Returns true if any property has been removed or if any alias has changed
/// </summary>
/// <param name="contentType"></param>
/// <returns></returns>
public bool HasAnyPropertyAliasChanged(ContentType contentType)
{
var newAliases = contentType.PropertyTypes.Select(x => x.Alias).ToArray();
//if any have been removed, return true
if (newAliases.Length < _originalPropertyAliases.Count())
{
return true;
}
//otherwise ensure that all of the original aliases are still existing
return newAliases.ContainsAll(_originalPropertyAliases) == false;
}
}
/// <summary>
@@ -233,7 +256,7 @@ namespace umbraco.controls
var state = new SaveAsyncState(new SaveClickEventArgs("Saved")
{
IconType = BasePage.speechBubbleIcon.success
}, _contentType.Alias, _contentType.Text, txtAlias.Text, txtName.Text);
}, _contentType.Alias, _contentType.Text, txtAlias.Text, txtName.Text, _contentType.PropertyTypes.Select(x => x.Alias).ToArray());
//Add the async operation to the page
Page.RegisterAsyncTask(new PageAsyncTask(BeginAsyncSaveOperation, EndAsyncSaveOperation, HandleAsyncSaveTimeout, state));
@@ -310,13 +333,13 @@ namespace umbraco.controls
_contentType.AllowedChildContentTypeIDs = SaveAllowedChildTypes();
_contentType.AllowAtRoot = allowAtRoot.Checked;
_contentType.Save();
}
// Only if the doctype alias changed, cause a regeneration of the xml cache file since
// the xml element names will need to be updated to reflect the new alias
if (asyncState.HasAliasChanged())
if (asyncState.HasAliasChanged(_contentType) || asyncState.HasAnyPropertyAliasChanged(_contentType))
RegenerateXmlCaches();
Trace.Write("ContentTypeControlNew", "task completing");
@@ -347,6 +370,10 @@ namespace umbraco.controls
{
_contentType = new cms.businesslogic.media.MediaType(docTypeId);
}
else if (Request.Path.ToLowerInvariant().Contains("editmembertype.aspx"))
{
_contentType = new cms.businesslogic.member.MemberType(docTypeId);
}
else
{
_contentType = new ContentType(docTypeId);
@@ -356,10 +383,19 @@ namespace umbraco.controls
/// <summary>
/// Regenerates the XML caches. Used after a document type alias has been changed.
/// </summary>
/// <remarks>
/// We only regenerate any XML cache based on if this is a Document type, not a media type or
/// a member type.
/// </remarks>
private void RegenerateXmlCaches()
{
Document.RePublishAll();
library.RefreshContent();
_contentType.RebuildXmlStructuresForContent();
//special case for DocumentType's
if (_contentType is DocumentType)
{
library.RefreshContent();
}
}
/// <summary>

View File

@@ -251,29 +251,21 @@ namespace umbraco.BasePages
{
get
{
// zb-00004 #29956 : refactor cookies names & handling
if (StateHelper.Cookies.HasCookies && StateHelper.Cookies.UserContext.HasValue)
return StateHelper.Cookies.UserContext.GetValue();
else
{
try
{
string encTicket = StateHelper.Cookies.UserContext.GetValue();
if (!String.IsNullOrEmpty(encTicket))
return FormsAuthentication.Decrypt(encTicket).UserData;
var encTicket = StateHelper.Cookies.UserContext.GetValue();
if (string.IsNullOrEmpty(encTicket) == false)
{
return encTicket.DecryptWithMachineKey();
}
}
catch (HttpException ex)
{
// we swallow this type of exception as it happens if a legacy (pre 4.8.1) cookie is set
}
catch (ArgumentException ex)
{
// we swallow this one because it's 99.99% certaincy is legacy based. We'll still log it, though
LogHelper.Error<BasePage>("An error occurred reading auth cookie value", ex);
}
}
return "";
}
set
@@ -285,25 +277,15 @@ namespace umbraco.BasePages
if (StateHelper.Cookies.UserContext.HasValue)
StateHelper.Cookies.ClearAll();
if (!String.IsNullOrEmpty(value))
{
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1,
value,
DateTime.Now,
DateTime.Now.AddDays(1),
false,
value,
FormsAuthentication.FormsCookiePath);
// Encrypt the ticket.
string encTicket = FormsAuthentication.Encrypt(ticket);
if (string.IsNullOrEmpty(value) == false)
{
// Encrypt the value
var encTicket = value.EncryptWithMachineKey();
// Create new cookie.
StateHelper.Cookies.UserContext.SetValue(value, 1);
} else
StateHelper.Cookies.UserContext.SetValue(encTicket, 1);
}
else
{
StateHelper.Cookies.UserContext.Clear();
}

View File

@@ -454,6 +454,9 @@ namespace umbraco.BusinessLogic
if (GlobalSettings.UseSSL)
cookie.Secure = true;
//ensure http only, this should only be able to be accessed via the server
cookie.HttpOnly = true;
cookie.Expires = expires;
ResponseCookie = cookie;

View File

@@ -4,6 +4,7 @@ using System.Linq;
using System.Xml;
using Umbraco.Core;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using umbraco.cms.businesslogic.property;
using umbraco.DataLayer;
@@ -386,8 +387,7 @@ namespace umbraco.cms.businesslogic
/// <param name="xd"></param>
public virtual void XmlGenerate(XmlDocument xd)
{
XmlNode node = generateXmlWithoutSaving(xd);
SaveXmlDocument(node);
SaveXmlDocument(generateXmlWithoutSaving(xd));
}
public virtual void XmlPopulate(XmlDocument xd, ref XmlNode x, bool Deep)
@@ -398,27 +398,27 @@ namespace umbraco.cms.businesslogic
x.AppendChild(p.ToXml(xd));
// attributes
x.Attributes.Append(xmlHelper.addAttribute(xd, "id", this.Id.ToString()));
x.Attributes.Append(xmlHelper.addAttribute(xd, "version", this.Version.ToString()));
x.Attributes.Append(XmlHelper.AddAttribute(xd, "id", this.Id.ToString()));
x.Attributes.Append(XmlHelper.AddAttribute(xd, "version", this.Version.ToString()));
if (this.Level > 1)
x.Attributes.Append(xmlHelper.addAttribute(xd, "parentID", this.Parent.Id.ToString()));
x.Attributes.Append(XmlHelper.AddAttribute(xd, "parentID", this.Parent.Id.ToString()));
else
x.Attributes.Append(xmlHelper.addAttribute(xd, "parentID", "-1"));
x.Attributes.Append(xmlHelper.addAttribute(xd, "level", this.Level.ToString()));
x.Attributes.Append(xmlHelper.addAttribute(xd, "writerID", this.User.Id.ToString()));
x.Attributes.Append(XmlHelper.AddAttribute(xd, "parentID", "-1"));
x.Attributes.Append(XmlHelper.AddAttribute(xd, "level", this.Level.ToString()));
x.Attributes.Append(XmlHelper.AddAttribute(xd, "writerID", this.User.Id.ToString()));
if (this.ContentType != null)
x.Attributes.Append(xmlHelper.addAttribute(xd, "nodeType", this.ContentType.Id.ToString()));
x.Attributes.Append(xmlHelper.addAttribute(xd, "template", "0"));
x.Attributes.Append(xmlHelper.addAttribute(xd, "sortOrder", this.sortOrder.ToString()));
x.Attributes.Append(xmlHelper.addAttribute(xd, "createDate", this.CreateDateTime.ToString("s")));
x.Attributes.Append(xmlHelper.addAttribute(xd, "updateDate", this.VersionDate.ToString("s")));
x.Attributes.Append(xmlHelper.addAttribute(xd, "nodeName", this.Text));
x.Attributes.Append(XmlHelper.AddAttribute(xd, "nodeType", this.ContentType.Id.ToString()));
x.Attributes.Append(XmlHelper.AddAttribute(xd, "template", "0"));
x.Attributes.Append(XmlHelper.AddAttribute(xd, "sortOrder", this.sortOrder.ToString()));
x.Attributes.Append(XmlHelper.AddAttribute(xd, "createDate", this.CreateDateTime.ToString("s")));
x.Attributes.Append(XmlHelper.AddAttribute(xd, "updateDate", this.VersionDate.ToString("s")));
x.Attributes.Append(XmlHelper.AddAttribute(xd, "nodeName", this.Text));
if (this.Text != null)
x.Attributes.Append(xmlHelper.addAttribute(xd, "urlName", this.Text.Replace(" ", "").ToLower()));
x.Attributes.Append(xmlHelper.addAttribute(xd, "writerName", this.User.Name));
x.Attributes.Append(XmlHelper.AddAttribute(xd, "urlName", this.Text.Replace(" ", "").ToLower()));
x.Attributes.Append(XmlHelper.AddAttribute(xd, "writerName", this.User.Name));
if (this.ContentType != null)
x.Attributes.Append(xmlHelper.addAttribute(xd, "nodeTypeAlias", this.ContentType.Alias));
x.Attributes.Append(xmlHelper.addAttribute(xd, "path", this.Path));
x.Attributes.Append(XmlHelper.AddAttribute(xd, "nodeTypeAlias", this.ContentType.Alias));
x.Attributes.Append(XmlHelper.AddAttribute(xd, "path", this.Path));
if (Deep)
{

View File

@@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.Threading;
using System.Runtime.CompilerServices;
using System.Linq;
using System.Xml;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Rdbms;
@@ -246,6 +247,84 @@ namespace umbraco.cms.businesslogic
#region Public Properties
#region Regenerate Xml Structures
/// <summary>
/// Used to rebuild all of the xml structures for content of the current content type in the cmsContentXml table
/// </summary>
[MethodImpl(MethodImplOptions.Synchronized)]
internal void RebuildXmlStructuresForContent()
{
//Clears all xml structures in the cmsContentXml table for the current content type
ClearXmlStructuresForContent();
foreach (var i in GetContentIdsForContentType())
{
RebuildXmlStructureForContentItem(i);
}
}
/// <summary>
/// Returns all content ids associated with this content type
/// </summary>
/// <returns></returns>
/// <remarks>
/// This will generally just return the content ids associated with this content type but in the case
/// of a DocumentType where we can have inherited types, this will return all content Ids that are of
/// this content type or any descendant types as well.
/// </remarks>
internal virtual IEnumerable<int> GetContentIdsForContentType()
{
var ids = new List<int>();
//get all the content item ids of the current content type
using (var dr = SqlHelper.ExecuteReader(@"SELECT DISTINCT cmsContent.nodeId FROM cmsContent
INNER JOIN cmsContentType ON cmsContent.contentType = cmsContentType.nodeId
WHERE cmsContentType.nodeId = @nodeId",
SqlHelper.CreateParameter("@nodeId", this.Id)))
{
while (dr.Read())
{
ids.Add(dr.GetInt("nodeId"));
}
dr.Close();
}
return ids;
}
/// <summary>
/// Rebuilds the xml structure for the content item by id
/// </summary>
/// <param name="contentId"></param>
/// <remarks>
/// This is not thread safe
/// </remarks>
internal virtual void RebuildXmlStructureForContentItem(int contentId)
{
var xd = new XmlDocument();
try
{
new Content(contentId).XmlGenerate(xd);
}
catch (Exception ee)
{
LogHelper.Error<ContentType>("Error generating xml", ee);
}
}
/// <summary>
/// Clears all xml structures in the cmsContentXml table for the current content type
/// </summary>
internal virtual void ClearXmlStructuresForContent()
{
//Remove all items from the cmsContentXml table that are of this current content type
SqlHelper.ExecuteNonQuery(@"DELETE FROM cmsContentXml WHERE nodeId IN
(SELECT DISTINCT cmsContent.nodeId FROM cmsContent
INNER JOIN cmsContentType ON cmsContent.contentType = cmsContentType.nodeId
WHERE cmsContentType.nodeId = @nodeId)",
SqlHelper.CreateParameter("@nodeId", this.Id));
}
#endregion
/// <summary>
/// The Alias of the ContentType, is used for import/export and more human readable initialization see: GetByAlias
/// method.

View File

@@ -647,16 +647,7 @@ namespace umbraco.cms.businesslogic.member
FireAfterSave(e);
}
}
/// <summary>
/// Generates the xmlrepresentation of a member
/// </summary>
/// <param name="xd"></param>
public override void XmlGenerate(XmlDocument xd)
{
SaveXmlDocument(generateXmlWithoutSaving(xd));
}
/// <summary>
/// Xmlrepresentation of a member
/// </summary>

View File

@@ -1,5 +1,6 @@
using System;
using System.Xml;
using Umbraco.Core.Logging;
using umbraco.cms.businesslogic.propertytype;
using System.Linq;
using umbraco.BusinessLogic;
@@ -32,6 +33,30 @@ namespace umbraco.cms.businesslogic.member
/// <param name="id">MemberType id</param>
public MemberType(Guid id) : base(id) { }
#region Regenerate Xml Structures
/// <summary>
/// Rebuilds the xml structure for the member item by id
/// </summary>
/// <param name="contentId"></param>
/// <remarks>
/// This is not thread safe
/// </remarks>
internal override void RebuildXmlStructureForContentItem(int contentId)
{
var xd = new XmlDocument();
try
{
new Member(contentId).XmlGenerate(xd);
}
catch (Exception ee)
{
LogHelper.Error<MemberType>("Error generating xml", ee);
}
}
#endregion
#endregion
#region Public Methods

View File

@@ -402,22 +402,26 @@ namespace umbraco.cms.businesslogic.web
var children = ApplicationContext.Current.Services.ContentService.GetChildrenByName(NodeId, searchString);
return children.Select(x => new Document(x)).ToList();
}
[Obsolete("Obsolete, Use Umbraco.Core.Services.ContentService.RePublishAll()", false)]
/// <summary>
/// This will clear out the cmsContentXml table for all Documents (not media or members) and then
/// rebuild the xml for each Docuemtn item and store it in this table.
/// </summary>
/// <remarks>
/// This method is thread safe
/// </remarks>
[MethodImpl(MethodImplOptions.Synchronized)]
[Obsolete("Obsolete, Use Umbraco.Core.Services.ContentService.RePublishAll()", false)]
public static void RePublishAll()
{
XmlDocument xd = new XmlDocument();
var xd = new XmlDocument();
if (!DataLayerHelper.IsEmbeddedDatabase(SqlHelper.ConnectionString))
{
SqlHelper.ExecuteNonQuery("truncate table cmsContentXml");
}
else
{
SqlHelper.ExecuteNonQuery("delete from cmsContentXml");
}
IRecordsReader dr = SqlHelper.ExecuteReader("select nodeId from cmsDocument where published = 1");
//Remove all Documents (not media or members), only Documents are stored in the cmsDocument table
SqlHelper.ExecuteNonQuery(@"DELETE FROM cmsContentXml WHERE nodeId IN
(SELECT DISTINCT cmsContentXml.nodeId FROM cmsContentXml
INNER JOIN cmsDocument ON cmsContentXml.nodeId = cmsDocument.nodeId)");
var dr = SqlHelper.ExecuteReader("select nodeId from cmsDocument where published = 1");
while (dr.Read())
{
@@ -427,7 +431,7 @@ namespace umbraco.cms.businesslogic.web
}
catch (Exception ee)
{
LogHelper.Error<Document>("Error generating xml", ee);
LogHelper.Error<Document>("Error generating xml", ee);
}
}
dr.Close();

View File

@@ -280,6 +280,86 @@ namespace umbraco.cms.businesslogic.web
#region Public Methods
#region Regenerate Xml Structures
/// <summary>
/// This will return all PUBLISHED content Ids that are of this content type or any descendant types as well.
/// </summary>
/// <returns></returns>
internal override IEnumerable<int> GetContentIdsForContentType()
{
var ids = new List<int>();
int? currentContentTypeId = this.Id;
while (currentContentTypeId != null)
{
//get all the content item ids of the current content type
using (var dr = SqlHelper.ExecuteReader(@"SELECT DISTINCT cmsDocument.nodeId FROM cmsDocument
INNER JOIN cmsContent ON cmsContent.nodeId = cmsDocument.nodeId
INNER JOIN cmsContentType ON cmsContent.contentType = cmsContentType.nodeId
WHERE cmsContentType.nodeId = @contentTypeId AND cmsDocument.published = 1",
SqlHelper.CreateParameter("@contentTypeId", currentContentTypeId)))
{
while (dr.Read())
{
ids.Add(dr.GetInt("nodeId"));
}
dr.Close();
}
//lookup the child content type if there is one
currentContentTypeId = SqlHelper.ExecuteScalar<int?>("SELECT nodeId FROM cmsContentType WHERE masterContentType=@contentTypeId",
SqlHelper.CreateParameter("@contentTypeId", currentContentTypeId));
}
return ids;
}
/// <summary>
/// Rebuilds the xml structure for the content item by id
/// </summary>
/// <param name="contentId"></param>
/// <remarks>
/// This is not thread safe
/// </remarks>
internal override void RebuildXmlStructureForContentItem(int contentId)
{
var xd = new XmlDocument();
try
{
new Document(contentId).XmlGenerate(xd);
}
catch (Exception ee)
{
LogHelper.Error<DocumentType>("Error generating xml", ee);
}
}
/// <summary>
/// Clears all xml structures in the cmsContentXml table for the current content type and any of it's descendant types
/// </summary>
/// <remarks>
/// This is not thread safe
/// </remarks>
internal override void ClearXmlStructuresForContent()
{
int? currentContentTypeId = this.Id;
while (currentContentTypeId != null)
{
//Remove all items from the cmsContentXml table that are of this current content type
SqlHelper.ExecuteNonQuery(@"DELETE FROM cmsContentXml WHERE nodeId IN
(SELECT DISTINCT cmsContent.nodeId FROM cmsContent
INNER JOIN cmsContentType ON cmsContent.contentType = cmsContentType.nodeId
WHERE cmsContentType.nodeId = @contentTypeId)",
SqlHelper.CreateParameter("@contentTypeId", currentContentTypeId));
//lookup the child content type if there is one
currentContentTypeId = SqlHelper.ExecuteScalar<int?>("SELECT nodeId FROM cmsContentType WHERE masterContentType=@contentTypeId",
SqlHelper.CreateParameter("@contentTypeId", currentContentTypeId));
}
}
#endregion
[Obsolete("Obsolete, Use RemoveTemplate() on Umbraco.Core.Models.ContentType", false)]
public void RemoveTemplate(int templateId)
{