From 651b4a348ae8d5c31b1d8591b31dbdfbbe14f27b Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 3 Oct 2018 14:27:48 +0200 Subject: [PATCH] gets unpublish working --- .../Events/QueuingEventDispatcherBase.cs | 2 +- src/Umbraco.Core/Models/AuditType.cs | 2 +- .../Services/Implement/ContentService.cs | 26 +++---- .../Cache/CacheRefresherComponentTests.cs | 2 +- .../Integration/ContentEventsTests.cs | 4 +- .../Scoping/ScopeEventDispatcherTests.cs | 6 +- .../Services/ContentServiceTests.cs | 2 +- .../components/content/edit.controller.js | 69 ++--------------- .../content/umbcontentnodeinfo.directive.js | 2 +- .../mocks/services/localization.mocks.js | 2 +- .../src/common/resources/content.resource.js | 13 ++-- .../services/contenteditinghelper.service.js | 10 +-- .../src/views/content/overlays/publish.html | 4 +- .../content/overlays/unpublish.controller.js | 18 ++--- .../src/views/content/overlays/unpublish.html | 4 +- .../listview/listview.controller.js | 2 +- src/Umbraco.Web.UI/Umbraco/config/lang/cs.xml | 2 +- src/Umbraco.Web.UI/Umbraco/config/lang/da.xml | 6 +- src/Umbraco.Web.UI/Umbraco/config/lang/de.xml | 2 +- src/Umbraco.Web.UI/Umbraco/config/lang/en.xml | 6 +- .../Umbraco/config/lang/en_us.xml | 9 ++- src/Umbraco.Web.UI/Umbraco/config/lang/es.xml | 2 +- src/Umbraco.Web.UI/Umbraco/config/lang/fr.xml | 4 +- src/Umbraco.Web.UI/Umbraco/config/lang/he.xml | 2 +- src/Umbraco.Web.UI/Umbraco/config/lang/it.xml | 2 +- src/Umbraco.Web.UI/Umbraco/config/lang/ja.xml | 2 +- src/Umbraco.Web.UI/Umbraco/config/lang/ko.xml | 2 +- src/Umbraco.Web.UI/Umbraco/config/lang/nb.xml | 2 +- src/Umbraco.Web.UI/Umbraco/config/lang/nl.xml | 2 +- src/Umbraco.Web.UI/Umbraco/config/lang/pl.xml | 2 +- src/Umbraco.Web.UI/Umbraco/config/lang/pt.xml | 2 +- src/Umbraco.Web.UI/Umbraco/config/lang/ru.xml | 2 +- src/Umbraco.Web.UI/Umbraco/config/lang/sv.xml | 2 +- src/Umbraco.Web.UI/Umbraco/config/lang/tr.xml | 2 +- src/Umbraco.Web.UI/Umbraco/config/lang/zh.xml | 2 +- .../Umbraco/config/lang/zh_tw.xml | 2 +- src/Umbraco.Web.UI/umbraco/config/lang/nb.xml | 2 +- .../umbraco/config/lang/zh_tw.xml | 2 +- .../Cache/CacheRefresherComponent.cs | 2 +- .../Components/NotificationsComponent.cs | 4 +- src/Umbraco.Web/Editors/ContentController.cs | 74 ++++++++++++++----- .../Models/ContentEditing/UnpublishContent.cs | 22 ++++++ .../Mapping/ContentSavedStateResolver.cs | 8 +- src/Umbraco.Web/Umbraco.Web.csproj | 3 +- .../_Legacy/Actions/ActionUnPublish.cs | 6 +- 45 files changed, 180 insertions(+), 168 deletions(-) create mode 100644 src/Umbraco.Web/Models/ContentEditing/UnpublishContent.cs diff --git a/src/Umbraco.Core/Events/QueuingEventDispatcherBase.cs b/src/Umbraco.Core/Events/QueuingEventDispatcherBase.cs index 0283ac372e..4c38c0b2ec 100644 --- a/src/Umbraco.Core/Events/QueuingEventDispatcherBase.cs +++ b/src/Umbraco.Core/Events/QueuingEventDispatcherBase.cs @@ -307,7 +307,7 @@ namespace Umbraco.Core.Events // fixme see notes above // delete event args does NOT superceedes 'unpublished' event - if (argType.IsGenericType && argType.GetGenericTypeDefinition() == typeof(PublishEventArgs<>) && infos.EventDefinition.EventName == "UnPublished") + if (argType.IsGenericType && argType.GetGenericTypeDefinition() == typeof(PublishEventArgs<>) && infos.EventDefinition.EventName == "Unpublished") return false; // found occurences, need to determine if this event args is superceded diff --git a/src/Umbraco.Core/Models/AuditType.cs b/src/Umbraco.Core/Models/AuditType.cs index da2c8e5d8e..a5ae34a89d 100644 --- a/src/Umbraco.Core/Models/AuditType.cs +++ b/src/Umbraco.Core/Models/AuditType.cs @@ -32,7 +32,7 @@ /// /// Used when nodes are unpublished /// - UnPublish, + Unpublish, /// /// Used when nodes are moved /// diff --git a/src/Umbraco.Core/Services/Implement/ContentService.cs b/src/Umbraco.Core/Services/Implement/ContentService.cs index 18dcf6beac..10784e12d6 100644 --- a/src/Umbraco.Core/Services/Implement/ContentService.cs +++ b/src/Umbraco.Core/Services/Implement/ContentService.cs @@ -988,14 +988,14 @@ namespace Umbraco.Core.Services.Implement UnpublishResultType result; if (culture == "*" || culture == null) { - Audit(AuditType.UnPublish, "Unpublished by user", userId, content.Id); + Audit(AuditType.Unpublish, "Unpublished by user", userId, content.Id); result = UnpublishResultType.Success; } else { - Audit(AuditType.UnPublish, $"Culture \"{culture}\" unpublished by user", userId, content.Id); + Audit(AuditType.Unpublish, $"Culture \"{culture}\" unpublished by user", userId, content.Id); if (!content.Published) - Audit(AuditType.UnPublish, $"Unpublished (culture \"{culture}\" is mandatory) by user", userId, content.Id); + Audit(AuditType.Unpublish, $"Unpublished (culture \"{culture}\" is mandatory) by user", userId, content.Id); result = content.Published ? UnpublishResultType.SuccessCulture : UnpublishResultType.SuccessMandatoryCulture; } scope.Complete(); @@ -1120,9 +1120,9 @@ namespace Umbraco.Core.Services.Implement if (unpublishResult.Success) // and succeeded, trigger events { // events and audit - scope.Events.Dispatch(UnPublished, this, new PublishEventArgs(content, false, false), "UnPublished"); + scope.Events.Dispatch(Unpublished, this, new PublishEventArgs(content, false, false), "Unpublished"); scope.Events.Dispatch(TreeChanged, this, new TreeChange(content, TreeChangeTypes.RefreshBranch).ToEventArgs()); - Audit(AuditType.UnPublish, "Unpublished by user", userId, content.Id); + Audit(AuditType.Unpublish, "Unpublished by user", userId, content.Id); scope.Complete(); return new PublishResult(PublishResultType.Success, evtMsgs, content); } @@ -1348,10 +1348,10 @@ namespace Umbraco.Core.Services.Implement scope.WriteLock(Constants.Locks.ContentTree); // if it's not trashed yet, and published, we should unpublish - // but... UnPublishing event makes no sense (not going to cancel?) and no need to save + // but... Unpublishing event makes no sense (not going to cancel?) and no need to save // just raise the event if (content.Trashed == false && content.Published) - scope.Events.Dispatch(UnPublished, this, new PublishEventArgs(content, false, false), nameof(UnPublished)); + scope.Events.Dispatch(Unpublished, this, new PublishEventArgs(content, false, false), nameof(Unpublished)); DeleteLocked(scope, content); @@ -2098,12 +2098,12 @@ namespace Umbraco.Core.Services.Implement /// /// Occurs before unpublish /// - public static event TypedEventHandler> UnPublishing; + public static event TypedEventHandler> Unpublishing; /// /// Occurs after unpublish /// - public static event TypedEventHandler> UnPublished; + public static event TypedEventHandler> Unpublished; /// /// Occurs after change. @@ -2197,8 +2197,8 @@ namespace Umbraco.Core.Services.Implement // ensures that a document can be unpublished internal UnpublishResult StrategyCanUnpublish(IScope scope, IContent content, int userId, EventMessages evtMsgs) { - // raise UnPublishing event - if (scope.Events.DispatchCancelable(UnPublishing, this, new PublishEventArgs(content, evtMsgs))) + // raise Unpublishing event + if (scope.Events.DispatchCancelable(Unpublishing, this, new PublishEventArgs(content, evtMsgs))) { Logger.Info("Document {ContentName} (id={ContentId}) cannot be unpublished: unpublishing was cancelled.", content.Name, content.Id); return new UnpublishResult(UnpublishResultType.FailedCancelledByEvent, evtMsgs, content); @@ -2282,10 +2282,10 @@ namespace Umbraco.Core.Services.Implement foreach (var content in contents.OrderByDescending(x => x.ParentId)) { // if it's not trashed yet, and published, we should unpublish - // but... UnPublishing event makes no sense (not going to cancel?) and no need to save + // but... Unpublishing event makes no sense (not going to cancel?) and no need to save // just raise the event if (content.Trashed == false && content.Published) - scope.Events.Dispatch(UnPublished, this, new PublishEventArgs(content, false, false), nameof(UnPublished)); + scope.Events.Dispatch(Unpublished, this, new PublishEventArgs(content, false, false), nameof(Unpublished)); // if current content has children, move them to trash var c = content; diff --git a/src/Umbraco.Tests/Cache/CacheRefresherComponentTests.cs b/src/Umbraco.Tests/Cache/CacheRefresherComponentTests.cs index e79b26cd1d..0616b4098f 100644 --- a/src/Umbraco.Tests/Cache/CacheRefresherComponentTests.cs +++ b/src/Umbraco.Tests/Cache/CacheRefresherComponentTests.cs @@ -99,7 +99,7 @@ namespace Umbraco.Tests.Cache new EventDefinition>(null, serviceContext.ContentService, new MoveEventArgs(new MoveEventInfo(null, "", -1)), "Trashed"), new EventDefinition(null, serviceContext.ContentService, new RecycleBinEventArgs(Guid.NewGuid())), new EventDefinition>(null, serviceContext.ContentService, new PublishEventArgs(Enumerable.Empty()), "Published"), - new EventDefinition>(null, serviceContext.ContentService, new PublishEventArgs(Enumerable.Empty()), "UnPublished"), + new EventDefinition>(null, serviceContext.ContentService, new PublishEventArgs(Enumerable.Empty()), "Unpublished"), new EventDefinition>(null, serviceContext.PublicAccessService, new SaveEventArgs(Enumerable.Empty())), new EventDefinition>(null, serviceContext.PublicAccessService, new DeleteEventArgs(Enumerable.Empty())), diff --git a/src/Umbraco.Tests/Integration/ContentEventsTests.cs b/src/Umbraco.Tests/Integration/ContentEventsTests.cs index 03539d2273..4ca63e9e96 100644 --- a/src/Umbraco.Tests/Integration/ContentEventsTests.cs +++ b/src/Umbraco.Tests/Integration/ContentEventsTests.cs @@ -463,7 +463,7 @@ namespace Umbraco.Tests.Integration #endregion - #region Save, Publish & UnPublish single content + #region Save, Publish & Unpublish single content [Test] public void SaveUnpublishedContent() @@ -721,7 +721,7 @@ namespace Umbraco.Tests.Integration #endregion - #region Publish & UnPublish branch + #region Publish & Unpublish branch [Test] public void UnpublishContentBranch() diff --git a/src/Umbraco.Tests/Scoping/ScopeEventDispatcherTests.cs b/src/Umbraco.Tests/Scoping/ScopeEventDispatcherTests.cs index 842fe50e04..4d49747004 100644 --- a/src/Umbraco.Tests/Scoping/ScopeEventDispatcherTests.cs +++ b/src/Umbraco.Tests/Scoping/ScopeEventDispatcherTests.cs @@ -169,7 +169,7 @@ namespace Umbraco.Tests.Scoping [Test] public void SupersededEvents2() { - Test_UnPublished += OnDoThingFail; + Test_Unpublished += OnDoThingFail; Test_Deleted += OnDoThingFail; var contentService = Mock.Of(); @@ -178,7 +178,7 @@ namespace Umbraco.Tests.Scoping var scopeProvider = _testObjects.GetScopeProvider(Mock.Of()); using (var scope = scopeProvider.CreateScope(eventDispatcher: new PassiveEventDispatcher())) { - scope.Events.Dispatch(Test_UnPublished, contentService, new PublishEventArgs(new [] { content }), "UnPublished"); + scope.Events.Dispatch(Test_Unpublished, contentService, new PublishEventArgs(new [] { content }), "Unpublished"); scope.Events.Dispatch(Test_Deleted, contentService, new DeleteEventArgs(new [] { content }), "Deleted"); // see U4-10764 @@ -395,7 +395,7 @@ namespace Umbraco.Tests.Scoping public static event TypedEventHandler> DoThing3; - public static event TypedEventHandler> Test_UnPublished; + public static event TypedEventHandler> Test_Unpublished; public static event TypedEventHandler> Test_Deleted; public class TestEventArgs : CancellableObjectEventArgs diff --git a/src/Umbraco.Tests/Services/ContentServiceTests.cs b/src/Umbraco.Tests/Services/ContentServiceTests.cs index 640eaae0ef..e9d855535b 100644 --- a/src/Umbraco.Tests/Services/ContentServiceTests.cs +++ b/src/Umbraco.Tests/Services/ContentServiceTests.cs @@ -1208,7 +1208,7 @@ namespace Umbraco.Tests.Services } [Test] - public void Can_UnPublish_Content() + public void Can_Unpublish_Content() { // Arrange var contentService = ServiceContext.ContentService; diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js index 0154894031..2ed9944efd 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js @@ -177,7 +177,7 @@ methods: { saveAndPublish: $scope.saveAndPublish, sendToPublish: $scope.sendToPublish, - unPublish: $scope.unPublish + unpublish: $scope.unpublish } }); @@ -334,7 +334,7 @@ }); } - $scope.unPublish = function() { + $scope.unpublish = function() { clearNotifications($scope.content); if (formHelper.submitForm({ scope: $scope, action: "unpublish", skipValidation: true })) { var dialog = { @@ -342,23 +342,18 @@ view: "views/content/overlays/unpublish.html", variants: $scope.content.variants, //set a model property for the dialog skipFormValidation: true, //when submitting the overlay form, skip any client side validation - submitButtonLabelKey: "content_unPublish", + submitButtonLabelKey: "content_unpublish", submit: function (model) { model.submitButtonState = "busy"; - var selectedVariants = _.filter(model.variants, function(variant) { return variant.unpublish; }); + var selectedVariants = _.filter(model.variants, function(variant) { return variant.save; }); var culturesForUnpublishing = _.map(selectedVariants, function(variant) { return variant.language.culture; }); - /* TODO: the end point need to handle an array of cultures - contentResource.unPublish($scope.content.id, culture) + contentResource.unpublish($scope.content.id, culturesForUnpublishing) .then(function (data) { formHelper.resetForm({ scope: $scope }); - contentEditingHelper.handleSuccessfulSave({ - scope: $scope, - savedContent: data, - rebindCallback: contentEditingHelper.reBindChangedProperties($scope.content, data) - }); + contentEditingHelper.reBindChangedProperties($scope.content, data); init($scope.content); syncTreeNode($scope.content, data.path); $scope.page.buttonGroupState = "success"; @@ -367,7 +362,7 @@ }, function (err) { $scope.page.buttonGroupState = 'error'; }); - */ + }, close: function () { @@ -377,55 +372,7 @@ overlayService.open(dialog); } }; - - /* - $scope.unPublish = function () { - - //if there's any variants than we need to set the language and include the variants to publish - var culture = null; - if ($scope.content.variants.length > 0) { - _.each($scope.content.variants, - function (d) { - //set the culture if this is active - if (d.active === true) { - culture = d.language.culture; - } - }); - } - - if (formHelper.submitForm({ scope: $scope, skipValidation: true })) { - - $scope.page.buttonGroupState = "busy"; - - eventsService.emit("content.unpublishing", { content: $scope.content }); - - contentResource.unPublish($scope.content.id, culture) - .then(function (data) { - - formHelper.resetForm({ scope: $scope }); - - contentEditingHelper.handleSuccessfulSave({ - scope: $scope, - savedContent: data, - rebindCallback: contentEditingHelper.reBindChangedProperties($scope.content, data) - }); - - init($scope.content); - - syncTreeNode($scope.content, data.path); - - $scope.page.buttonGroupState = "success"; - - eventsService.emit("content.unpublished", { content: $scope.content }); - - }, function (err) { - $scope.page.buttonGroupState = 'error'; - }); - } - - }; - */ - + $scope.sendToPublish = function () { clearNotifications($scope.content); if (showSaveOrPublishDialog()) { diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbcontentnodeinfo.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbcontentnodeinfo.directive.js index 74b806fceb..4831ecea8c 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbcontentnodeinfo.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbcontentnodeinfo.directive.js @@ -186,7 +186,7 @@ case "Publish": item.logTypeColor = "success"; break; - case "UnPublish": + case "Unpublish": case "Delete": item.logTypeColor = "danger"; break; diff --git a/src/Umbraco.Web.UI.Client/src/common/mocks/services/localization.mocks.js b/src/Umbraco.Web.UI.Client/src/common/mocks/services/localization.mocks.js index 615a7aeec9..409ec24d51 100644 --- a/src/Umbraco.Web.UI.Client/src/common/mocks/services/localization.mocks.js +++ b/src/Umbraco.Web.UI.Client/src/common/mocks/services/localization.mocks.js @@ -145,7 +145,7 @@ angular.module('umbraco.mocks'). "content_statistics": "Statistics", "content_titleOptional": "Title (optional)", "content_type": "Type", - "content_unPublish": "Unpublish", + "content_unpublish": "Unpublish", "content_updateDate": "Last edited", "content_updateDateDesc": "Date/time this document was created", "content_uploadClear": "Remove file", diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/content.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/content.resource.js index 073682b59f..721cd4da57 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/content.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/content.resource.js @@ -206,7 +206,7 @@ function contentResource($q, $http, umbDataFormatter, umbRequestHelper) { /** * @ngdoc method - * @name umbraco.resources.contentResource#unPublish + * @name umbraco.resources.contentResource#unpublish * @methodOf umbraco.resources.contentResource * * @description @@ -214,7 +214,7 @@ function contentResource($q, $http, umbDataFormatter, umbRequestHelper) { * * ##usage *
-          * contentResource.unPublish(1234)
+          * contentResource.unpublish(1234)
           *    .then(function() {
           *        alert("node was unpulished");
           *    }, function(err){
@@ -225,21 +225,20 @@ function contentResource($q, $http, umbDataFormatter, umbRequestHelper) {
           * @returns {Promise} resourcePromise object.
           *
           */
-        unPublish: function (id, culture) {
+        unpublish: function (id, cultures) {
             if (!id) {
                 throw "id cannot be null";
             }
 
-            if (!culture) {
-                culture = null;
+            if (!cultures) {
+                cultures = [];
             }
 
             return umbRequestHelper.resourcePromise(
                 $http.post(
                     umbRequestHelper.getApiUrl(
                         "contentApiBaseUrl",
-                        "PostUnPublish",
-                        { id: id, culture: culture })),
+                        "PostUnpublish"), { id: id, cultures: cultures }),
                 'Failed to publish content with id ' + id);
         },
         /**
diff --git a/src/Umbraco.Web.UI.Client/src/common/services/contenteditinghelper.service.js b/src/Umbraco.Web.UI.Client/src/common/services/contenteditinghelper.service.js
index 87fe71c0fb..ba2df1a68a 100644
--- a/src/Umbraco.Web.UI.Client/src/common/services/contenteditinghelper.service.js
+++ b/src/Umbraco.Web.UI.Client/src/common/services/contenteditinghelper.service.js
@@ -146,7 +146,7 @@ function contentEditingHelper(fileManager, $q, $location, $routeParams, notifica
             if (!args.methods) {
                 throw "args.methods is not defined";
             }
-            if (!args.methods.saveAndPublish || !args.methods.sendToPublish || !args.methods.unPublish) {
+            if (!args.methods.saveAndPublish || !args.methods.sendToPublish || !args.methods.unpublish) {
                 throw "args.methods does not contain all required defined methods";
             }
 
@@ -183,8 +183,8 @@ function contentEditingHelper(fileManager, $q, $location, $routeParams, notifica
                         //unpublish
                         return {
                             letter: ch,
-                            labelKey: "content_unPublish",
-                            handler: args.methods.unPublish,
+                            labelKey: "content_unpublish",
+                            handler: args.methods.unpublish,
                             hotKey: "ctrl+u",
                             hotKeyWhenHidden: true,
                             alias: "unpublish",
@@ -403,8 +403,8 @@ function contentEditingHelper(fileManager, $q, $location, $routeParams, notifica
                 case "Z":
                     return {
                         letter: ch,
-                        labelKey: "content_unPublish",
-                        handler: "unPublish"
+                        labelKey: "content_unpublish",
+                        handler: "unpublish"
                     };
 
                 default:
diff --git a/src/Umbraco.Web.UI.Client/src/views/content/overlays/publish.html b/src/Umbraco.Web.UI.Client/src/views/content/overlays/publish.html
index 92ed6c354c..c7855651ec 100644
--- a/src/Umbraco.Web.UI.Client/src/views/content/overlays/publish.html
+++ b/src/Umbraco.Web.UI.Client/src/views/content/overlays/publish.html
@@ -23,11 +23,11 @@
                     
- + + -
diff --git a/src/Umbraco.Web.UI.Client/src/views/content/overlays/unpublish.controller.js b/src/Umbraco.Web.UI.Client/src/views/content/overlays/unpublish.controller.js index 51b734124b..8c43778a87 100644 --- a/src/Umbraco.Web.UI.Client/src/views/content/overlays/unpublish.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/content/overlays/unpublish.controller.js @@ -16,7 +16,7 @@ // set dialog title if (!$scope.model.title) { - localizationService.localize("content_unPublish").then(function (value) { + localizationService.localize("content_unpublish").then(function (value) { $scope.model.title = value; }); } @@ -34,7 +34,7 @@ if (active) { //ensure that the current one is selected - active.unpublish = true; + active.save = true; } // autoselect other variants if needed @@ -47,20 +47,20 @@ // disable submit button if nothing is selected var firstSelected = _.find(vm.variants, function (v) { - return v.unpublish; + return v.save; }); $scope.model.disableSubmitButton = !firstSelected; //disable submit button if there is none selected // if a mandatory variant is selected we want to selet all other variants // and disable selection for the others - if(selectedVariant.unpublish && selectedVariant.language.isMandatory) { + if(selectedVariant.save && selectedVariant.language.isMandatory) { angular.forEach(vm.variants, function(variant){ - if(!variant.unpublish && publishedVariantFilter(variant)) { + if(!variant.save && publishedVariantFilter(variant)) { // keep track of the variants we automaically select // so we can remove the selection again autoSelectedVariants.push(variant.language.culture); - variant.unpublish = true; + variant.save = true; } variant.disabled = true; }); @@ -73,13 +73,13 @@ // if a mandatory variant is deselected we want to deselet all the variants // that was automatically selected so it goes back to the state before the mandatory language was selected. // We also want to enable all checkboxes again - if(!selectedVariant.unpublish && selectedVariant.language.isMandatory) { + if(!selectedVariant.save && selectedVariant.language.isMandatory) { angular.forEach(vm.variants, function(variant){ // check if variant was auto selected, then deselect if(_.contains(autoSelectedVariants, variant.language.culture)) { - variant.unpublish = false; + variant.save = false; }; variant.disabled = false; @@ -106,7 +106,7 @@ //when this dialog is closed, remove all unpublish and disabled flags $scope.$on('$destroy', function () { for (var i = 0; i < vm.variants.length; i++) { - vm.variants[i].unpublish = false; + vm.variants[i].save = false; vm.variants[i].disabled = false; } }); diff --git a/src/Umbraco.Web.UI.Client/src/views/content/overlays/unpublish.html b/src/Umbraco.Web.UI.Client/src/views/content/overlays/unpublish.html index eea04cc630..4b32aa67d1 100644 --- a/src/Umbraco.Web.UI.Client/src/views/content/overlays/unpublish.html +++ b/src/Umbraco.Web.UI.Client/src/views/content/overlays/unpublish.html @@ -19,7 +19,7 @@ -
\ No newline at end of file +
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js index 7ef6c117f2..2f845abd27 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js @@ -411,7 +411,7 @@ function listViewController($scope, $routeParams, $injector, $timeout, currentUs $scope.unpublish = function () { applySelected( - function (selected, index) { return contentResource.unPublish(getIdCallback(selected[index])); }, + function (selected, index) { return contentResource.unpublish(getIdCallback(selected[index])); }, function (count, total) { var key = (total === 1 ? "bulk_unpublishedItemOfItem" : "bulk_unpublishedItemOfItems"); return localizationService.localize(key, [count, total]); diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/cs.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/cs.xml index f9d7fc616e..3471203e76 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/cs.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/cs.xml @@ -147,7 +147,7 @@ Statistika Titulek (volitelně) Typ - Nepublikovat + Nepublikovat Naposledy změněno Datum/čas poslední změny dokumentu Odebrat soubor(y) diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/da.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/da.xml index 85c5a16b06..e0dd0973f6 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/da.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/da.xml @@ -154,7 +154,7 @@ Flyttet Gemt Slettet - Afpubliceret + Afpubliceret Indhold tilbagerullet Sendt til udgivelse Sendt til oversættelse @@ -229,7 +229,7 @@ Titel (valgfri) Alternativ tekst (valgfri) Type - Afpublicér + Afpublicér Afpubliceret Sidst redigeret Tidspunkt for seneste redigering @@ -1619,4 +1619,4 @@ Mange hilsner fra Umbraco robotten Der findes ikke nogen "Genopret" relation for dette dokument/medie. Brug "Flyt" muligheden fra menuen for at flytte det manuelt. Det dokument/medie du ønsker at genoprette under ('%0%') er i skraldespanden. Brug "Flyt" muligheden fra menuen for at flytte det manuelt. - \ No newline at end of file + diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/de.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/de.xml index 9bc0eee3f0..c701e439ea 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/de.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/de.xml @@ -153,7 +153,7 @@ Titel (optional) Alternativtext (optional) Typ - Veröffentlichung widerrufen + Veröffentlichung widerrufen Zuletzt bearbeitet am Letzter Änderungszeitpunkt des Dokuments Datei entfernen diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml index 22a7db7e0c..5b8dc0982c 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml @@ -146,7 +146,7 @@ Viewing for Delete Content performed by user - UnPublish performed by user + Unpublish performed by user Save and Publish performed by user Save Content performed by user Move Content performed by user @@ -159,7 +159,7 @@ Move Save Delete - Unpublish + Unpublish Rollback Send To Publish Send To Translation @@ -238,7 +238,7 @@ Title (optional) Alternative text (optional) Type - Unpublish + Unpublish Unpublished Last edited Date/time this document was edited diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml index 89b34501ef..c2a84cd326 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml @@ -149,7 +149,7 @@ Viewing for Delete Content performed by user - UnPublish performed by user + Unpublish performed by user Save and Publish performed by user Save Content performed by user Move Content performed by user @@ -162,7 +162,7 @@ Move Save Delete - Unpublish + Unpublish Rollback Send To Publish Send To Translation @@ -243,7 +243,7 @@ Title (optional) Alternative text (optional) Type - Unpublish + Unpublish Draft Not created Last edited @@ -1438,7 +1438,8 @@ To manage your website, simply open the Umbraco back office and start adding con Template saved Template saved without any errors! Content unpublished - Content variation %0% unpublished + Content variation %0% unpublished + The mandatory language '%0%' was unpublished. All languages for this content item are now unpublished. Partial view saved Partial view saved without any errors! Partial view not saved diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/es.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/es.xml index e96a33f6f7..dda74e00ed 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/es.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/es.xml @@ -203,7 +203,7 @@ Título (opcional) Texto alternativo (opcional) Tipo - Ocultar + Ocultar Última actualización Fecha/hora este documento fue modificado Eliminar archivo diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/fr.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/fr.xml index 487c5bd3aa..6a1f9a58e7 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/fr.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/fr.xml @@ -159,7 +159,7 @@ Déplacement Sauvegarde Suppression - Dépublication + Dépublication Récupération Envoi pour publication Envoi pour traduction @@ -234,7 +234,7 @@ Titre (optionnel) Texte alternatif (optionnel) Type - Dépublier + Dépublier Dépublié Dernière édition Date/heure à laquelle ce document a été édité diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/he.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/he.xml index 6b8b90ab33..911e0f4131 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/he.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/he.xml @@ -105,7 +105,7 @@ סטטיסטיקות כותרת (לא חובה) סוג - ממתין לפירסום + ממתין לפירסום נערך לאחרונה הסר קובץ קשר למסמך diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/it.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/it.xml index 31977e4c06..1f661000b6 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/it.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/it.xml @@ -108,7 +108,7 @@ Statistiche Titolo (opzionale) Tipo - Non pubblicare + Non pubblicare Ultima modifica Rimuovi il file Link al documento diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/ja.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/ja.xml index 7c1b48d9d3..d3a4a5c27a 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/ja.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/ja.xml @@ -155,7 +155,7 @@ タイトル (オプション) 代替テキスト (オプション) - 非公開 + 非公開 最終更新日時 このドキュメントが最後に更新された日時 ファイルの消去 diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/ko.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/ko.xml index a36593e410..a7ab31efc6 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/ko.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/ko.xml @@ -104,7 +104,7 @@ 통계 제목(옵션) 유형 - 발행취소 + 발행취소 마지막 수정일 파일 삭제 문서에 링크 diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/nb.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/nb.xml index e3b58903d1..235177c712 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/nb.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/nb.xml @@ -151,7 +151,7 @@ Tittel (valgfri) Alternativ tekst (valgfri) Type - Avpubliser + Avpubliser Sist endret Tidspunkt for siste endring Fjern fil diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/nl.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/nl.xml index dd13662fea..72d4afbeca 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/nl.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/nl.xml @@ -165,7 +165,7 @@ Titel (optioneel) Alternatieve tekst (optioneel) Type - Depubliceren + Depubliceren Laatst gewijzigd Date/time this document was edited Bestand(en) verwijderen diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/pl.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/pl.xml index d660880628..5f679a994a 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/pl.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/pl.xml @@ -204,7 +204,7 @@ Tytuł (opcjonalny) Alternatywny tekst (opcjonalny) Typ - Cofnij publikację + Cofnij publikację Ostatnio edytowany Data/czas edycji dokumentu Usuń plik(i) diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/pt.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/pt.xml index 31da65be7b..a62b51f76f 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/pt.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/pt.xml @@ -104,7 +104,7 @@ Estatísticas Título (opcional) Tipo - Des-Publicar + Des-Publicar Última edição Remover arquivo Link ao documento diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/ru.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/ru.xml index 657d286537..6cdfa16fcd 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/ru.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/ru.xml @@ -277,7 +277,7 @@ Цель Заголовок (необязательно) Тип - Скрыть + Скрыть Распубликовано Распубликовать Последняя правка diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/sv.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/sv.xml index 08beb0ccfd..83e1405560 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/sv.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/sv.xml @@ -158,7 +158,7 @@ Mål Titel (valfritt) Typ - Avpublicera + Avpublicera Avpubliceras Senast redigerad Datum/tid detta dokument ändrats diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/tr.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/tr.xml index 3963eb1e23..a69300dbfb 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/tr.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/tr.xml @@ -161,7 +161,7 @@ Başlık (isteğe bağlı) Alternatif metin (isteğe bağlı) tip - Yayından + Yayından Son düzenleme Bu belgenin düzenlendiği tarih / zaman Dosya(ları) kaldırın diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/zh.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/zh.xml index 3c5c0d99cf..64ad3eab1c 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/zh.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/zh.xml @@ -164,7 +164,7 @@ 标题(可选) Alternative text (optional) 类型 - 取消发布 + 取消发布 最近编辑 编辑此文档的日期/时间 移除文件 diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/zh_tw.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/zh_tw.xml index 37c3dec60e..a4c6fc7de5 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/zh_tw.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/zh_tw.xml @@ -161,7 +161,7 @@ 標題(可選) 其他說明文字(可選) 類型 - 取消發佈 + 取消發佈 最近編輯 本文件修改時間 移除文件 diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/nb.xml b/src/Umbraco.Web.UI/umbraco/config/lang/nb.xml index e3b58903d1..235177c712 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/nb.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/nb.xml @@ -151,7 +151,7 @@ Tittel (valgfri) Alternativ tekst (valgfri) Type - Avpubliser + Avpubliser Sist endret Tidspunkt for siste endring Fjern fil diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/zh_tw.xml b/src/Umbraco.Web.UI/umbraco/config/lang/zh_tw.xml index 37c3dec60e..a4c6fc7de5 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/zh_tw.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/zh_tw.xml @@ -161,7 +161,7 @@ 標題(可選) 其他說明文字(可選) 類型 - 取消發佈 + 取消發佈 最近編輯 本文件修改時間 移除文件 diff --git a/src/Umbraco.Web/Cache/CacheRefresherComponent.cs b/src/Umbraco.Web/Cache/CacheRefresherComponent.cs index 2ee0ff5f84..2a427a8cc8 100644 --- a/src/Umbraco.Web/Cache/CacheRefresherComponent.cs +++ b/src/Umbraco.Web/Cache/CacheRefresherComponent.cs @@ -310,7 +310,7 @@ namespace Umbraco.Web.Cache private void ContentService_Trashed(IContentService sender, MoveEventArgs e) { } private void ContentService_EmptiedRecycleBin(IContentService sender, RecycleBinEventArgs e) { } private void ContentService_Published(IContentService sender, PublishEventArgs e) { } - private void ContentService_UnPublished(IContentService sender, PublishEventArgs e) { } + private void ContentService_Unpublished(IContentService sender, PublishEventArgs e) { } //private void ContentService_SavedBlueprint(IContentService sender, SaveEventArgs e) //{ diff --git a/src/Umbraco.Web/Components/NotificationsComponent.cs b/src/Umbraco.Web/Components/NotificationsComponent.cs index 8bf03055e3..27fc604d29 100644 --- a/src/Umbraco.Web/Components/NotificationsComponent.cs +++ b/src/Umbraco.Web/Components/NotificationsComponent.cs @@ -57,10 +57,10 @@ namespace Umbraco.Web.Components }; //Send notifications for the unpublish action - ContentService.UnPublished += (sender, args) => + ContentService.Unpublished += (sender, args) => { foreach (var content in args.PublishedEntities) - notificationService.SendNotification(content, ActionUnPublish.Instance); + notificationService.SendNotification(content, ActionUnpublish.Instance); }; } } diff --git a/src/Umbraco.Web/Editors/ContentController.cs b/src/Umbraco.Web/Editors/ContentController.cs index 040d45f90a..88abeeb70c 100644 --- a/src/Umbraco.Web/Editors/ContentController.cs +++ b/src/Umbraco.Web/Editors/ContentController.cs @@ -1125,39 +1125,75 @@ namespace Umbraco.Web.Editors /// /// Unpublishes a node with a given Id and returns the unpublished entity /// - /// The content id to unpublish - /// The culture variant for the content id to unpublish, if none specified will unpublish all variants of the content + /// The content and variants to unpublish /// - [EnsureUserPermissionForContent("id", 'U')] + [EnsureUserPermissionForContent("model.Id", 'U')] [OutgoingEditorModelEvent] - public ContentItemDisplay PostUnPublish(int id, string culture = null) + public ContentItemDisplay PostUnpublish(UnpublishContent model) { - var foundContent = GetObjectFromRequest(() => Services.ContentService.GetById(id)); + var foundContent = GetObjectFromRequest(() => Services.ContentService.GetById(model.Id)); if (foundContent == null) - HandleContentNotFound(id); + HandleContentNotFound(model.Id); - var unpublishResult = Services.ContentService.Unpublish(foundContent, culture: culture, userId: Security.GetUserId().ResultOr(0)); - - var content = MapToDisplay(foundContent); - - if (!unpublishResult.Success) + var languageCount = _allLangs.Value.Count(); + if (model.Cultures.Length == 0 || model.Cultures.Length == languageCount) { - AddCancelMessage(content); - throw new HttpResponseException(Request.CreateValidationErrorResponse(content)); + //this means that the entire content item will be unpublished + var unpublishResult = Services.ContentService.Unpublish(foundContent, userId: Security.GetUserId().ResultOr(0)); + + var content = MapToDisplay(foundContent); + + if (!unpublishResult.Success) + { + AddCancelMessage(content); + throw new HttpResponseException(Request.CreateValidationErrorResponse(content)); + } + else + { + content.AddSuccessNotification( + Services.TextService.Localize("content/unpublish"), + Services.TextService.Localize("speechBubbles/contentUnpublished")); + return content; + } } else { - //fixme should have a better localized method for when we have the UnpublishResultType.SuccessMandatoryCulture status + //we only want to unpublish some of the variants + var results = new Dictionary(); + foreach(var c in model.Cultures) + { + var result = Services.ContentService.Unpublish(foundContent, culture: c, userId: Security.GetUserId().ResultOr(0)); + results[c] = result; + if (result.Result == UnpublishResultType.SuccessMandatoryCulture) + { + //if this happens, it means they are all unpublished, we don't need to continue + break; + } + } - content.AddSuccessNotification( - Services.TextService.Localize("content/unPublish"), - unpublishResult.Result == UnpublishResultType.SuccessCulture - ? Services.TextService.Localize("speechBubbles/contentVariationUnpublished", new[] { culture }) - : Services.TextService.Localize("speechBubbles/contentUnpublished")); + var content = MapToDisplay(foundContent); + //check for this status and return the correct message + if (results.Any(x => x.Value.Result == UnpublishResultType.SuccessMandatoryCulture)) + { + content.AddSuccessNotification( + Services.TextService.Localize("content/unpublish"), + Services.TextService.Localize("speechBubbles/contentMandatoryCultureUnpublished")); + return content; + } + + //otherwise add a message for each one unpublished + foreach (var r in results) + { + content.AddSuccessNotification( + Services.TextService.Localize("content/unpublish"), + Services.TextService.Localize("speechBubbles/contentCultureUnpublished", new[] { _allLangs.Value[r.Key].CultureName })); + } return content; + } + } public ContentDomainsAndCulture GetCultureAndDomains(int id) diff --git a/src/Umbraco.Web/Models/ContentEditing/UnpublishContent.cs b/src/Umbraco.Web/Models/ContentEditing/UnpublishContent.cs new file mode 100644 index 0000000000..22cb43f467 --- /dev/null +++ b/src/Umbraco.Web/Models/ContentEditing/UnpublishContent.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; +using System.Text; +using System.Threading.Tasks; + +namespace Umbraco.Web.Models.ContentEditing +{ + /// + /// Used to unpublish content and variants + /// + [DataContract(Name = "unpublish", Namespace = "")] + public class UnpublishContent + { + [DataMember(Name = "id")] + public int Id { get; set; } + + [DataMember(Name = "cultures")] + public string[] Cultures { get; set; } + } +} diff --git a/src/Umbraco.Web/Models/Mapping/ContentSavedStateResolver.cs b/src/Umbraco.Web/Models/Mapping/ContentSavedStateResolver.cs index 4f721999de..2b0395b2c6 100644 --- a/src/Umbraco.Web/Models/Mapping/ContentSavedStateResolver.cs +++ b/src/Umbraco.Web/Models/Mapping/ContentSavedStateResolver.cs @@ -33,6 +33,7 @@ namespace Umbraco.Web.Models.Mapping { PublishedState publishedState; bool isEdited; + bool isCreated; if (source.ContentType.VariesByCulture()) { @@ -50,6 +51,7 @@ namespace Umbraco.Web.Models.Mapping : PublishedState.Unpublished; isEdited = source.IsCultureEdited(culture); + isCreated = source.Id > 0 && source.IsCultureAvailable(culture); } else { @@ -58,10 +60,14 @@ namespace Umbraco.Web.Models.Mapping : PublishedState.Published; isEdited = source.Edited; + isCreated = source.Id > 0; } + if (!isCreated) + return ContentSavedState.NotCreated; + if (publishedState == PublishedState.Unpublished) - return isEdited && source.Id > 0 ? ContentSavedState.Draft : ContentSavedState.NotCreated; + return ContentSavedState.Draft; if (publishedState == PublishedState.Published) return isEdited ? ContentSavedState.PublishedPendingChanges : ContentSavedState.Published; diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 219bf3a99d..3e6db493bf 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -147,6 +147,7 @@ + @@ -562,7 +563,7 @@ - + diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionUnPublish.cs b/src/Umbraco.Web/_Legacy/Actions/ActionUnPublish.cs index 97ced79dc2..93d1da2046 100644 --- a/src/Umbraco.Web/_Legacy/Actions/ActionUnPublish.cs +++ b/src/Umbraco.Web/_Legacy/Actions/ActionUnPublish.cs @@ -8,14 +8,14 @@ namespace Umbraco.Web._Legacy.Actions /// /// This action is invoked when a document is being unpublished /// - public class ActionUnPublish : IAction + public class ActionUnpublish : IAction { //create singleton #pragma warning disable 612,618 - private static readonly ActionUnPublish m_instance = new ActionUnPublish(); + private static readonly ActionUnpublish m_instance = new ActionUnpublish(); #pragma warning restore 612,618 - public static ActionUnPublish Instance + public static ActionUnpublish Instance { get { return m_instance; } }