diff --git a/src/Umbraco.Web.UI/umbraco/controls/ContentTypeControlNew.ascx b/src/Umbraco.Web.UI/umbraco/controls/ContentTypeControlNew.ascx index 7fc9bbf44c..b803f94494 100644 --- a/src/Umbraco.Web.UI/umbraco/controls/ContentTypeControlNew.ascx +++ b/src/Umbraco.Web.UI/umbraco/controls/ContentTypeControlNew.ascx @@ -105,10 +105,26 @@ }); - jQuery(document).ready(function () { + $(document).ready(function () { + + $("table.tabs-table tr.propertyContent input.sort-order").keydown(function(e) { + // Allow: backspace, delete, tab, escape, enter and . + if ($.inArray(e.keyCode, [46, 8, 9, 27, 13, 190]) !== -1 || + // Allow: Ctrl+A + (e.keyCode == 65 && e.ctrlKey === true) || + // Allow: home, end, left, right + (e.keyCode >= 35 && e.keyCode <= 39)) { + // let it happen, don't do anything + return; + } + // Ensure that it is a number and stop the keypress + if ((e.shiftKey || (e.keyCode < 48 || e.keyCode > 57)) && (e.keyCode < 96 || e.keyCode > 105)) { + e.preventDefault(); + } + }); // Make each tr of the tabs table sortable (prevent dragging of header row, and set up a callback for when row dragged) - jQuery("table.tabs-table tbody").sortable({ + $("table.tabs-table tbody").sortable({ containment: 'parent', cancel: '.propertyHeader, input', tolerance: 'pointer', @@ -119,8 +135,8 @@ // Fired after row dragged; go through each tr and save position to the hidden sort order field function saveOrder() { - jQuery("table.tabs-table tbody tr.propertyContent").each(function (index) { - jQuery("input.sort-order", this).val(index + 1); + $("table.tabs-table tbody tr.propertyContent").each(function (index) { + $("input.sort-order", this).val(index + 1); }); } diff --git a/src/Umbraco.Web.UI/umbraco_client/ui/default.css b/src/Umbraco.Web.UI/umbraco_client/ui/default.css index ecc1163290..576bd0d0ce 100644 --- a/src/Umbraco.Web.UI/umbraco_client/ui/default.css +++ b/src/Umbraco.Web.UI/umbraco_client/ui/default.css @@ -743,7 +743,12 @@ table.tabs-table tr.propertyContent td } table.tabs-table input[type=text] { width: 200px; } table.tabs-table input[type=submit] { text-align: right; } -table.tabs-table tr.propertyContent input.sort-order {display: none;} + +table.tabs-table tr.propertyContent input.sort-order { + width: 20px; + background-color: lightgray; + padding: 0px 5px 0px 5px; +} li.no-properties-on-tab {background: none; background-color: #fff; cursor: default; } diff --git a/src/Umbraco.Web/Strategies/LegacyActionHandlerEventHandler.cs b/src/Umbraco.Web/Strategies/LegacyActionHandlerEventHandler.cs new file mode 100644 index 0000000000..4ab8b25849 --- /dev/null +++ b/src/Umbraco.Web/Strategies/LegacyActionHandlerEventHandler.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using umbraco.BusinessLogic.Actions; +using umbraco.cms.businesslogic.web; +using Umbraco.Core; +using Umbraco.Core.Events; +using Umbraco.Core.Models; +using Umbraco.Core.Publishing; +using Umbraco.Core.Services; + +namespace Umbraco.Web.Strategies +{ + + /// + /// This is used to trigger the legacy ActionHandlers based on events + /// + public sealed class LegacyActionHandlerEventHandler : ApplicationEventHandler + { + //NOTE: this is to fix this currently: http://issues.umbraco.org/issue/U4-1550 + + protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) + { + ContentService.Published += ContentService_Published; + ContentService.UnPublished += ContentService_UnPublished; + } + + static void ContentService_UnPublished(IPublishingStrategy sender, PublishEventArgs e) + { + e.PublishedEntities.ForEach(x => + global::umbraco.BusinessLogic.Actions.Action.RunActionHandlers( + new Document(x), ActionUnPublish.Instance)); + } + + static void ContentService_Published(IPublishingStrategy sender, PublishEventArgs e) + { + e.PublishedEntities.ForEach(x => + global::umbraco.BusinessLogic.Actions.Action.RunActionHandlers( + new Document(x), ActionPublish.Instance)); + } + } +} diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 86c7437ba3..11d70c41b8 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -401,6 +401,7 @@ + diff --git a/src/Umbraco.Web/umbraco.presentation/content.cs b/src/Umbraco.Web/umbraco.presentation/content.cs index 9270e57cc0..ab611bda87 100644 --- a/src/Umbraco.Web/umbraco.presentation/content.cs +++ b/src/Umbraco.Web/umbraco.presentation/content.cs @@ -521,9 +521,7 @@ namespace umbraco var cachedFieldKeyStart = string.Format("{0}{1}_", CacheKeys.ContentItemCacheKey, d.Id); ApplicationContext.Current.ApplicationCache.ClearCacheByKeySearch(cachedFieldKeyStart); - - Action.RunActionHandlers(d, ActionPublish.Instance); - + FireAfterUpdateDocumentCache(d, e); } } @@ -532,6 +530,7 @@ namespace umbraco /// Updates the document cache for multiple documents /// /// The documents. + [Obsolete("This is not used and will be removed from the codebase in future versions")] public virtual void UpdateDocumentCache(List Documents) { // We need to lock content cache here, because we cannot allow other threads @@ -550,11 +549,6 @@ namespace umbraco XmlContentInternal = xmlContentCopy; ClearContextCache(); } - - foreach (Document d in Documents) - { - Action.RunActionHandlers(d, ActionPublish.Instance); - } } /// @@ -635,12 +629,6 @@ namespace umbraco } } - if (x != null) - { - // Run Handler - Action.RunActionHandlers(doc, ActionUnPublish.Instance); - } - //SD: changed to fire event BEFORE running the sitemap!! argh. FireAfterClearDocumentCache(doc, e); diff --git a/src/umbraco.cms/businesslogic/CMSNode.cs b/src/umbraco.cms/businesslogic/CMSNode.cs index 4052d89cc4..5b4381e13d 100644 --- a/src/umbraco.cms/businesslogic/CMSNode.cs +++ b/src/umbraco.cms/businesslogic/CMSNode.cs @@ -377,6 +377,19 @@ namespace umbraco.cms.businesslogic setupNode(); } + /// + /// This is purely for a hackity hack hack hack in order to make the new Document(id, version) constructor work because + /// the Version property needs to be set on the object before setupNode is called, otherwise it never works! this allows + /// inheritors to set default data before setupNode() is called. + /// + /// + /// + internal CMSNode(int id, object[] ctorArgs) + { + _id = id; + PreSetupNode(ctorArgs); + } + /// /// Initializes a new instance of the class. /// @@ -1016,6 +1029,18 @@ order by level,sortOrder"; _entity.Name = txt; } + /// + /// This is purely for a hackity hack hack hack in order to make the new Document(id, version) constructor work because + /// the Version property needs to be set on the object before setupNode is called, otherwise it never works! + /// + /// + internal virtual void PreSetupNode(params object[] ctorArgs) + { + //if people want to override then awesome but then we call setupNode so they need to ensure + // to call base.PreSetupNode + setupNode(); + } + /// /// Sets up the internal data of the CMSNode, used by the various constructors /// diff --git a/src/umbraco.cms/businesslogic/Content.cs b/src/umbraco.cms/businesslogic/Content.cs index f2e52a1287..7dd0c264ae 100644 --- a/src/umbraco.cms/businesslogic/Content.cs +++ b/src/umbraco.cms/businesslogic/Content.cs @@ -39,13 +39,18 @@ namespace umbraco.cms.businesslogic private bool _versionDateInitialized; private string _contentTypeIcon; private ContentType _contentType; - private Properties m_LoadedProperties = null; + private Properties _loadedProperties = null; protected internal IContentBase ContentBase; #endregion #region Constructors - + + protected internal Content(int id, Guid version) + : base(id, new object[] { version }) + { + } + public Content(int id) : base(id) { } protected Content(int id, bool noSetup) : base(id, noSetup) { } @@ -223,7 +228,7 @@ namespace umbraco.cms.businesslogic get { EnsureProperties(); - return m_LoadedProperties; + return _loadedProperties; } } @@ -236,7 +241,7 @@ namespace umbraco.cms.businesslogic get { EnsureProperties(); - return m_LoadedProperties.ToArray(); + return _loadedProperties.ToArray(); } } @@ -288,7 +293,7 @@ namespace umbraco.cms.businesslogic { EnsureProperties(); - return m_LoadedProperties.SingleOrDefault(x => x.PropertyType.Alias == alias); + return _loadedProperties.SingleOrDefault(x => x.PropertyType.Alias == alias); } /// @@ -300,7 +305,7 @@ namespace umbraco.cms.businesslogic { EnsureProperties(); - return m_LoadedProperties.SingleOrDefault(x => x.PropertyType.Id == pt.Id); + return _loadedProperties.SingleOrDefault(x => x.PropertyType.Id == pt.Id); } /// @@ -462,6 +467,21 @@ namespace umbraco.cms.businesslogic #region Protected Methods + /// + /// This is purely for a hackity hack hack hack in order to make the new Document(id, version) constructor work because + /// the Version property needs to be set on the object before setupNode is called, otherwise it never works! + /// + /// + internal override void PreSetupNode(params object[] ctorArgs) + { + //we know that there is one ctor arg and it is a GUID since we are only calling the base + // ctor with this overload for one purpose. + var version = (Guid) ctorArgs[0]; + _version = version; + + base.PreSetupNode(ctorArgs); + } + /// /// Sets up the ContentType property for this content item and sets the addition content properties manually. /// If the ContentType property is not already set, then this will get the ContentType from Cache. @@ -616,7 +636,7 @@ namespace umbraco.cms.businesslogic /// private void ClearLoadedProperties() { - m_LoadedProperties = null; + _loadedProperties = null; } /// @@ -624,7 +644,7 @@ namespace umbraco.cms.businesslogic /// private void EnsureProperties() { - if (m_LoadedProperties == null) + if (_loadedProperties == null) { InitializeProperties(); } @@ -643,13 +663,13 @@ namespace umbraco.cms.businesslogic /// private void InitializeProperties() { - m_LoadedProperties = new Properties(); + _loadedProperties = new Properties(); if (ContentBase != null) { //NOTE: we will not load any properties where HasIdentity = false - this is because if properties are // added to the property collection that aren't persisted we'll get ysods - m_LoadedProperties.AddRange(ContentBase.Properties.Where(x => x.HasIdentity).Select(x => new Property(x))); + _loadedProperties.AddRange(ContentBase.Properties.Where(x => x.HasIdentity).Select(x => new Property(x))); return; } @@ -658,7 +678,7 @@ namespace umbraco.cms.businesslogic //Create anonymous typed list with 2 props, Id and PropertyTypeId of type Int. //This will still be an empty list since the props list is empty. - var propData = m_LoadedProperties.Select(x => new { Id = 0, PropertyTypeId = 0 }).ToList(); + var propData = _loadedProperties.Select(x => new { Id = 0, PropertyTypeId = 0 }).ToList(); string sql = @"select id, propertyTypeId from cmsPropertyData where versionId=@versionId"; @@ -697,7 +717,7 @@ namespace umbraco.cms.businesslogic continue; //this remains from old code... not sure why we would do this? } - m_LoadedProperties.Add(p); + _loadedProperties.Add(p); } } diff --git a/src/umbraco.cms/businesslogic/web/Document.cs b/src/umbraco.cms/businesslogic/web/Document.cs index b95a8402f7..51ecb20967 100644 --- a/src/umbraco.cms/businesslogic/web/Document.cs +++ b/src/umbraco.cms/businesslogic/web/Document.cs @@ -55,9 +55,8 @@ namespace umbraco.cms.businesslogic.web /// The id of the document /// The version of the document public Document(int id, Guid Version) - : base(id) + : base(id, Version) { - this.Version = Version; } ///