diff --git a/Controller/ArticleController.php b/Controller/ArticleController.php
index 47cbc6a73..baeaa6cea 100644
--- a/Controller/ArticleController.php
+++ b/Controller/ArticleController.php
@@ -159,10 +159,12 @@ public function getAction($uuid, Request $request)
*/
public function postAction(Request $request)
{
+ $action = $request->get('action');
$document = $this->getDocumentManager()->create(self::DOCUMENT_TYPE);
$locale = $this->getRequestParameter($request, 'locale', true);
$this->persistDocument($request->request->all(), $document, $locale);
+ $this->handleActionParameter($action, $document, $locale);
$this->getDocumentManager()->flush();
return $this->handleView(
@@ -183,6 +185,7 @@ public function postAction(Request $request)
public function putAction(Request $request, $uuid)
{
$locale = $this->getRequestParameter($request, 'locale', true);
+ $action = $request->get('action');
$document = $this->getDocumentManager()->find(
$uuid,
@@ -196,6 +199,7 @@ public function putAction(Request $request, $uuid)
$this->get('sulu_hash.request_hash_checker')->checkHash($request, $document, $document->getUuid());
$this->persistDocument($request->request->all(), $document, $locale);
+ $this->handleActionParameter($action, $document, $locale);
$this->getDocumentManager()->flush();
return $this->handleView(
@@ -288,4 +292,20 @@ protected function getDocumentManager()
{
return $this->get('sulu_document_manager.document_manager');
}
+
+ /**
+ * Delegates actions by given actionParameter, which can be retrieved from the request.
+ *
+ * @param string $actionParameter
+ * @param object $document
+ * @param string $locale
+ */
+ private function handleActionParameter($actionParameter, $document, $locale)
+ {
+ switch ($actionParameter) {
+ case 'publish':
+ $this->getDocumentManager()->publish($document, $locale);
+ break;
+ }
+ }
}
diff --git a/Document/ArticleDocument.php b/Document/ArticleDocument.php
index 2e79657d2..01bd64b2a 100644
--- a/Document/ArticleDocument.php
+++ b/Document/ArticleDocument.php
@@ -18,6 +18,7 @@
use Sulu\Component\Content\Document\Behavior\LocalizedAuditableBehavior;
use Sulu\Component\Content\Document\Behavior\LocalizedStructureBehavior;
use Sulu\Component\Content\Document\Behavior\StructureBehavior;
+use Sulu\Component\Content\Document\Behavior\WorkflowStageBehavior;
use Sulu\Component\Content\Document\Extension\ExtensionContainer;
use Sulu\Component\Content\Document\Structure\Structure;
use Sulu\Component\Content\Document\Structure\StructureInterface;
@@ -41,7 +42,8 @@ class ArticleDocument implements
LocalizedAuditableBehavior,
DateShardingBehavior,
RoutableInterface,
- ExtensionBehavior
+ ExtensionBehavior,
+ WorkflowStageBehavior
{
/**
* @var string
@@ -125,6 +127,20 @@ class ArticleDocument implements
*/
protected $extensions;
+ /**
+ * Workflow Stage currently Test or Published.
+ *
+ * @var int
+ */
+ protected $workflowStage;
+
+ /**
+ * Is Document is published.
+ *
+ * @var bool
+ */
+ protected $published;
+
public function __construct()
{
$this->structure = new Structure();
@@ -359,4 +375,28 @@ public function setExtension($name, $data)
{
$this->extensions[$name] = $data;
}
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getWorkflowStage()
+ {
+ return $this->workflowStage;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setWorkflowStage($workflowStage)
+ {
+ $this->workflowStage = $workflowStage;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getPublished()
+ {
+ return $this->published;
+ }
}
diff --git a/Resources/config/serializer/Document.ArticleDocument.xml b/Resources/config/serializer/Document.ArticleDocument.xml
index f8fdc096e..4258f37d7 100644
--- a/Resources/config/serializer/Document.ArticleDocument.xml
+++ b/Resources/config/serializer/Document.ArticleDocument.xml
@@ -25,6 +25,7 @@
+
diff --git a/Resources/public/js/components/articles/edit/details/main.js b/Resources/public/js/components/articles/edit/details/main.js
index 9b9f52ddb..7a714391c 100644
--- a/Resources/public/js/components/articles/edit/details/main.js
+++ b/Resources/public/js/components/articles/edit/details/main.js
@@ -46,7 +46,8 @@ define(['underscore', 'jquery', 'config'], function(_, $, Config) {
},
listenForChange: function() {
- this.sandbox.dom.on(this.$el, 'keyup change', _.debounce(this.setDirty.bind(this), 10), '.trigger-save-button');
+ this.sandbox.dom.on(this.$el, 'keyup', _.debounce(this.setDirty.bind(this), 10), 'input, textarea');
+ this.sandbox.dom.on(this.$el, 'change', _.debounce(this.setDirty.bind(this), 10), 'input[type="checkbox"], select');
this.sandbox.on('sulu.content.changed', this.setDirty.bind(this));
},
@@ -55,17 +56,15 @@ define(['underscore', 'jquery', 'config'], function(_, $, Config) {
this.sandbox.emit('sulu.tab.dirty');
},
- save: function() {
+ save: function(action) {
if (!this.sandbox.form.validate(this.formId)) {
return this.sandbox.emit('sulu.tab.dirty', true);
}
var data = this.sandbox.form.getData(this.formId);
data.template = this.template;
- this.sandbox.util.save(this.options.url(), !this.data.id ? 'POST' : 'PUT', data).then(function(data) {
- this.data = data;
- this.sandbox.emit('sulu.tab.saved', data);
- }.bind(this));
+
+ this.sandbox.emit('sulu.articles.save', data, action);
},
render: function() {
@@ -107,9 +106,7 @@ define(['underscore', 'jquery', 'config'], function(_, $, Config) {
},
loadFormTemplate: function(template) {
- if (!!template) {
- this.setDirty();
- } else {
+ if (!template) {
var types = Config.get('sulu_article.types');
template = types[(this.options.type || this.data.type)];
}
diff --git a/Resources/public/js/components/articles/edit/excerpt/main.js b/Resources/public/js/components/articles/edit/excerpt/main.js
index 4e1b4d3c7..b8bbceb94 100644
--- a/Resources/public/js/components/articles/edit/excerpt/main.js
+++ b/Resources/public/js/components/articles/edit/excerpt/main.js
@@ -18,10 +18,7 @@ define([], function() {
var content = this.options.data();
content.ext.excerpt = data;
- this.sandbox.util.save(this.options.url(), !content.id ? 'POST' : 'PUT', content).then(function(data) {
- this.data = data;
- this.sandbox.emit('sulu.tab.saved', data);
- }.bind(this));
+ this.sandbox.emit('sulu.articles.save', data, action);
}
};
});
diff --git a/Resources/public/js/components/articles/edit/main.js b/Resources/public/js/components/articles/edit/main.js
index 8f64c5172..7f714720d 100644
--- a/Resources/public/js/components/articles/edit/main.js
+++ b/Resources/public/js/components/articles/edit/main.js
@@ -7,7 +7,7 @@
* with this source code in the file LICENSE.
*/
-define(['jquery', 'underscore'], function($, _) {
+define(['jquery', 'underscore', 'sulusecurity/services/user-manager'], function($, _, UserManager) {
'use strict';
@@ -23,14 +23,15 @@ define(['jquery', 'underscore'], function($, _) {
},
translations: {
- headline: 'sulu_article.edit.title'
+ headline: 'sulu_article.edit.title',
+ draftLabel: 'sulu-content.draft-label'
}
},
header: function() {
var buttons = {
save: {
- parent: 'saveWithOptions'
+ parent: 'saveWithDraft'
},
template: {
options: {
@@ -76,14 +77,17 @@ define(['jquery', 'underscore'], function($, _) {
this.saveState = 'disabled';
this.bindCustomEvents();
+ this.showDraftLabel();
},
bindCustomEvents: function() {
this.sandbox.on('sulu.header.back', this.toList.bind(this));
- this.sandbox.on('sulu.tab.dirty', this.enableSave.bind(this));
+ this.sandbox.on('sulu.tab.dirty', this.setHeaderBar.bind(this));
this.sandbox.on('sulu.toolbar.save', this.save.bind(this));
this.sandbox.on('sulu.toolbar.delete', this.deleteItem.bind(this));
this.sandbox.on('sulu.tab.data-changed', this.setData.bind(this));
+ this.sandbox.on('sulu.articles.save', this.saveArticle.bind(this));
+ this.sandbox.on('sulu.tab.saved', this.showDraftLabel.bind(this));
this.sandbox.on('sulu.header.language-changed', function(item) {
this.sandbox.sulu.saveUserSetting(this.options.config.settingsKey, item.id);
@@ -120,7 +124,7 @@ define(['jquery', 'underscore'], function($, _) {
save: function(action) {
this.loadingSave();
- this.saveTab().then(function(data) {
+ this.saveTab(action).then(function(data) {
this.afterSave(action, data);
}.bind(this));
},
@@ -129,7 +133,7 @@ define(['jquery', 'underscore'], function($, _) {
this.data = data;
},
- saveTab: function() {
+ saveTab: function(action) {
var promise = $.Deferred();
this.sandbox.once('sulu.tab.saved', function(savedData) {
@@ -138,27 +142,33 @@ define(['jquery', 'underscore'], function($, _) {
promise.resolve(savedData);
}.bind(this));
- this.sandbox.emit('sulu.tab.save');
+ this.sandbox.emit('sulu.tab.save', action);
return promise;
},
- enableSave: function(force) {
- if (!force && this.saveState === 'loading') {
- return;
- }
-
- this.saveState = 'enabled';
- this.sandbox.emit('sulu.header.toolbar.item.enable', 'save', false);
+ saveArticle: function(data, action) {
+ return this.sandbox.util.save(this.getUrl(action), !this.data.id ? 'POST' : 'PUT', data).then(function(data) {
+ this.data = data;
+ this.sandbox.emit('sulu.tab.saved', data);
+ }.bind(this));
},
- disableSave: function(force) {
- if (!force && this.saveState === 'loading') {
- return;
- }
+ setHeaderBar: function(saved) {
+ var saveDraft = !saved,
+ savePublish = !saved,
+ publish = !!saved && !this.data.publishedState;
- this.saveState = 'disabled';
- this.sandbox.emit('sulu.header.toolbar.item.disable', 'save', true);
+ this.setSaveToolbarItems.call(this, 'saveDraft', saveDraft);
+ this.setSaveToolbarItems.call(this, 'savePublish', savePublish);
+ this.setSaveToolbarItems.call(this, 'publish', publish);
+ this.setSaveToolbarItems.call(this, 'save', (!!saveDraft || !!savePublish || !!publish));
+
+ this.saved = saved;
+ },
+
+ setSaveToolbarItems: function(item, value) {
+ this.sandbox.emit('sulu.header.toolbar.item.' + (!!value ? 'enable' : 'disable'), item, false);
},
loadingSave: function() {
@@ -167,7 +177,7 @@ define(['jquery', 'underscore'], function($, _) {
},
afterSave: function(action, data) {
- this.disableSave(true);
+ this.setHeaderBar(true);
this.sandbox.emit('sulu.header.saved', data);
if (action === 'back') {
@@ -179,6 +189,42 @@ define(['jquery', 'underscore'], function($, _) {
}
},
+ showDraftLabel: function() {
+ this.sandbox.emit('sulu.header.tabs.label.hide');
+
+ if (!this.data.id || !!this.data.publishedState) {
+ return;
+ }
+
+ this.setHeaderBar(true);
+
+ UserManager.find(this.data.changer).then(function(response) {
+ this.sandbox.emit(
+ 'sulu.header.tabs.label.show',
+ this.sandbox.util.sprintf(
+ this.sandbox.translate(this.translations.draftLabel),
+ {
+ changed: this.sandbox.date.format(this.data.changed, true),
+ user: response.username
+ }
+ )
+ );
+ }.bind(this));
+ },
+
+ getUrl: function(action) {
+ var url = _.template(this.defaults.templates.url, {
+ id: this.options.id,
+ locale: this.options.locale
+ });
+
+ if (action) {
+ url += '&action=' + action;
+ }
+
+ return url;
+ },
+
loadComponentData: function() {
var promise = $.Deferred();
@@ -188,10 +234,7 @@ define(['jquery', 'underscore'], function($, _) {
return promise;
}
- this.sandbox.util.load(_.template(this.defaults.templates.url, {
- id: this.options.id,
- locale: this.options.locale
- })).done(function(data) {
+ this.sandbox.util.load(this.getUrl()).done(function(data) {
promise.resolve(data);
});
diff --git a/Resources/public/js/components/articles/edit/seo/main.js b/Resources/public/js/components/articles/edit/seo/main.js
index ff0b46a24..54c0d8a59 100644
--- a/Resources/public/js/components/articles/edit/seo/main.js
+++ b/Resources/public/js/components/articles/edit/seo/main.js
@@ -29,10 +29,7 @@ define(function() {
var content = this.options.data();
content.ext.seo = data;
- this.sandbox.util.save(this.options.url(), !content.id ? 'POST' : 'PUT', content).then(function(data) {
- this.data = data;
- this.sandbox.emit('sulu.tab.saved', data);
- }.bind(this));
+ this.sandbox.emit('sulu.articles.save', data, action);
}
};
});