From 81f83873c7ddd739594c29cefbd261d34aa201d6 Mon Sep 17 00:00:00 2001 From: bembelimen Date: Sat, 14 Mar 2020 17:36:39 +0100 Subject: [PATCH 01/14] Remove condition from workflow component --- .../sql/updates/mysql/4.0.0-2018-05-15.sql | 11 +++---- .../updates/postgresql/4.0.0-2018-05-15.sql | 11 +++---- .../com_workflow/forms/filter_stages.xml | 10 ------ .../components/com_workflow/forms/stage.xml | 7 ---- .../com_workflow/src/Model/StagesModel.php | 12 +------ .../src/Model/TransitionsModel.php | 4 +-- .../com_workflow/src/Model/WorkflowModel.php | 5 --- .../com_workflow/src/Model/WorkflowsModel.php | 2 +- .../com_workflow/src/View/Stages/HtmlView.php | 5 --- .../com_workflow/tmpl/stage/edit.php | 1 - .../com_workflow/tmpl/stages/default.php | 20 +----------- .../com_workflow/tmpl/transitions/default.php | 32 ------------------- installation/sql/mysql/joomla.sql | 11 +++---- installation/sql/postgresql/joomla.sql | 11 +++---- 14 files changed, 24 insertions(+), 118 deletions(-) diff --git a/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-05-15.sql b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-05-15.sql index 7bbedc437e6d4..69ac6bf9d5671 100644 --- a/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-05-15.sql +++ b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-05-15.sql @@ -64,7 +64,6 @@ CREATE TABLE IF NOT EXISTS `#__workflow_stages` ( `published` tinyint(1) NOT NULL DEFAULT 0, `title` varchar(255) NOT NULL, `description` text NOT NULL, - `condition` int(10) DEFAULT 0, `default` tinyint(1) NOT NULL DEFAULT 0, `checked_out_time` datetime, `checked_out` int(10) NOT NULL DEFAULT 0, @@ -80,11 +79,11 @@ CREATE TABLE IF NOT EXISTS `#__workflow_stages` ( -- Dumping data for table `#__workflow_stages` -- -INSERT INTO `#__workflow_stages` (`id`, `asset_id`, `ordering`, `workflow_id`, `published`, `title`, `description`, `condition`, `default`, `checked_out_time`, `checked_out`) VALUES -(1, 0, 1, 1, 1, 'JUNPUBLISHED', '', 0, 1, NULL, 0), -(2, 0, 2, 1, 1, 'JPUBLISHED', '', 1, 0, NULL, 0), -(3, 0, 3, 1, 1, 'JTRASHED', '', -2, 0, NULL, 0), -(4, 0, 4, 1, 1, 'JARCHIVED', '', 2, 0, NULL, 0); +INSERT INTO `#__workflow_stages` (`id`, `asset_id`, `ordering`, `workflow_id`, `published`, `title`, `description`, `default`, `checked_out_time`, `checked_out`) VALUES +(1, 0, 1, 1, 1, 'JUNPUBLISHED', '', 1, NULL, 0), +(2, 0, 2, 1, 1, 'JPUBLISHED', '', 0, NULL, 0), +(3, 0, 3, 1, 1, 'JTRASHED', '', 0, NULL, 0), +(4, 0, 4, 1, 1, 'JARCHIVED', '', 0, NULL, 0); -- -- Table structure for table `#__workflow_transitions` diff --git a/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-05-15.sql b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-05-15.sql index a41ff39e4f764..652805aecf746 100644 --- a/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-05-15.sql +++ b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-05-15.sql @@ -64,7 +64,6 @@ CREATE TABLE IF NOT EXISTS "#__workflow_stages" ( "published" smallint NOT NULL DEFAULT 0, "title" varchar(255) NOT NULL, "description" text NOT NULL, - "condition" bigint DEFAULT 0 NOT NULL, "default" smallint NOT NULL DEFAULT 0, "checked_out_time" timestamp without time zone, "checked_out" bigint DEFAULT 0 NOT NULL, @@ -80,11 +79,11 @@ CREATE INDEX "#__workflow_stages_idx_checked_out" ON "#__workflow_stages" ("chec -- Dumping data for table "#__workflow_stages" -- -INSERT INTO "#__workflow_stages" ("id", "asset_id", "ordering", "workflow_id", "published", "title", "description", "condition", "default", "checked_out_time", "checked_out") VALUES -(1, 0, 1, 1, 1, 'JUNPUBLISHED', '', 0, 1, NULL, 0), -(2, 0, 2, 1, 1, 'JPUBLISHED', '', 1, 0, NULL, 0), -(3, 0, 3, 1, 1, 'JTRASHED', '', -2, 0, NULL, 0), -(4, 0, 4, 1, 1, 'JARCHIVED', '', 2, 0, NULL, 0); +INSERT INTO "#__workflow_stages" ("id", "asset_id", "ordering", "workflow_id", "published", "title", "description", "default", "checked_out_time", "checked_out") VALUES +(1, 0, 1, 1, 1, 'JUNPUBLISHED', '', 1, NULL, 0), +(2, 0, 2, 1, 1, 'JPUBLISHED', '', 0, NULL, 0), +(3, 0, 3, 1, 1, 'JTRASHED', '', 0, NULL, 0), +(4, 0, 4, 1, 1, 'JARCHIVED', '', 0, NULL, 0); -- -- Table structure for table "#__workflow_transitions" diff --git a/administrator/components/com_workflow/forms/filter_stages.xml b/administrator/components/com_workflow/forms/filter_stages.xml index bf9da05b14531..830e16abaf336 100644 --- a/administrator/components/com_workflow/forms/filter_stages.xml +++ b/administrator/components/com_workflow/forms/filter_stages.xml @@ -17,14 +17,6 @@ > - - - @@ -43,8 +35,6 @@ - - diff --git a/administrator/components/com_workflow/forms/stage.xml b/administrator/components/com_workflow/forms/stage.xml index af53ea3f2606d..407b1c485aa0a 100644 --- a/administrator/components/com_workflow/forms/stage.xml +++ b/administrator/components/com_workflow/forms/stage.xml @@ -24,13 +24,6 @@ rows="3" cols="60" /> -
diff --git a/administrator/components/com_workflow/src/Model/StagesModel.php b/administrator/components/com_workflow/src/Model/StagesModel.php index 85f9da4441937..27a46555f2162 100644 --- a/administrator/components/com_workflow/src/Model/StagesModel.php +++ b/administrator/components/com_workflow/src/Model/StagesModel.php @@ -37,7 +37,6 @@ public function __construct($config = array()) 'id', 's.id', 'title', 's.title', 'ordering','s.ordering', - 'condition','s.condition', 'published', 's.published' ); } @@ -134,7 +133,6 @@ public function getListQuery() 's.id', 's.title', 's.ordering', - 's.condition', 's.default', 's.published', 's.checked_out', @@ -153,21 +151,13 @@ public function getListQuery() $query->where($db->quoteName('s.workflow_id') . ' = ' . $workflowID); } - $condition = $this->getState('filter.condition'); - - // Filter by condition - if (is_numeric($condition)) - { - $query->where($db->quoteName('s.condition') . ' = ' . (int) $db->escape($condition)); - } - // Join over the users for the checked out user. $query->select($db->quoteName('uc.name', 'editor')) ->join('LEFT', $db->quoteName('#__users', 'uc'), $db->quoteName('uc.id') . ' = ' . $db->quoteName('s.checked_out')); $status = (string) $this->getState('filter.published'); - // Filter by condition + // Filter by publish state if (is_numeric($status)) { $query->where($db->quoteName('s.published') . ' = ' . (int) $status); diff --git a/administrator/components/com_workflow/src/Model/TransitionsModel.php b/administrator/components/com_workflow/src/Model/TransitionsModel.php index 37672982485ea..587d2f5c313fb 100644 --- a/administrator/components/com_workflow/src/Model/TransitionsModel.php +++ b/administrator/components/com_workflow/src/Model/TransitionsModel.php @@ -146,9 +146,7 @@ public function getListQuery() ); $select[] = $db->quoteName('f_stage.title', 'from_stage'); - $select[] = $db->quoteName('f_stage.condition', 'from_condition'); $select[] = $db->quoteName('t_stage.title', 'to_stage'); - $select[] = $db->quoteName('t_stage.condition', 'to_condition'); $joinTo = $db->quoteName('#__workflow_stages', 't_stage') . ' ON ' . $db->quoteName('t_stage.id') . ' = ' . $db->quoteName('t.to_stage_id'); @@ -172,7 +170,7 @@ public function getListQuery() $status = $this->getState('filter.published'); - // Filter by condition + // Filter by status if (is_numeric($status)) { $query->where($db->quoteName('t.published') . ' = ' . (int) $status); diff --git a/administrator/components/com_workflow/src/Model/WorkflowModel.php b/administrator/components/com_workflow/src/Model/WorkflowModel.php index a588e9a5ff7d8..2a75d94ed3751 100644 --- a/administrator/components/com_workflow/src/Model/WorkflowModel.php +++ b/administrator/components/com_workflow/src/Model/WorkflowModel.php @@ -113,23 +113,19 @@ public function save($data) $stages = [ [ 'title' => 'JUNPUBLISHED', - 'condition' => Workflow::CONDITION_UNPUBLISHED, 'default' => 1, 'transition' => 'Unpublish' ], [ 'title' => 'JPUBLISHED', - 'condition' => Workflow::CONDITION_PUBLISHED, 'transition' => 'Publish' ], [ 'title' => 'JTRASHED', - 'condition' => Workflow::CONDITION_TRASHED, 'transition' => 'Trash' ], [ 'title' => 'JARCHIVED', - 'condition' => Workflow::CONDITION_ARCHIVED, 'transition' => 'Archive' ] ]; @@ -144,7 +140,6 @@ public function save($data) $table->id = 0; $table->title = $stage['title']; $table->workflow_id = $workflow_id; - $table->condition = $stage['condition']; $table->published = 1; $table->default = (int) !empty($stage['default']); $table->description = ''; diff --git a/administrator/components/com_workflow/src/Model/WorkflowsModel.php b/administrator/components/com_workflow/src/Model/WorkflowsModel.php index 779c9260a51dc..5473a1840d2c2 100644 --- a/administrator/components/com_workflow/src/Model/WorkflowsModel.php +++ b/administrator/components/com_workflow/src/Model/WorkflowsModel.php @@ -217,7 +217,7 @@ public function getListQuery() $status = (string) $this->getState('filter.published'); - // Filter by condition + // Filter by status if (is_numeric($status)) { $query->where($db->quoteName('w.published') . ' = ' . (int) $status); diff --git a/administrator/components/com_workflow/src/View/Stages/HtmlView.php b/administrator/components/com_workflow/src/View/Stages/HtmlView.php index 7614fd95cd5ef..4b0e8c6fcfd57 100644 --- a/administrator/components/com_workflow/src/View/Stages/HtmlView.php +++ b/administrator/components/com_workflow/src/View/Stages/HtmlView.php @@ -130,11 +130,6 @@ public function display($tpl = null) { $extension = Factory::getApplication()->input->getCmd('extension'); $workflow = new Workflow(['extension' => $extension]); - - foreach ($this->stages as $i => $item) - { - $item->condition = $workflow->getConditionName((int) $item->condition); - } } $this->addToolbar(); diff --git a/administrator/components/com_workflow/tmpl/stage/edit.php b/administrator/components/com_workflow/tmpl/stage/edit.php index 220038f1a04d4..f8bc54f05fa7b 100644 --- a/administrator/components/com_workflow/tmpl/stage/edit.php +++ b/administrator/components/com_workflow/tmpl/stage/edit.php @@ -39,7 +39,6 @@
- form->renderField('condition'); ?> form->renderField('description'); ?>
diff --git a/administrator/components/com_workflow/tmpl/stages/default.php b/administrator/components/com_workflow/tmpl/stages/default.php index 7bb3b46c7719c..9ea5bb8ae8e52 100644 --- a/administrator/components/com_workflow/tmpl/stages/default.php +++ b/administrator/components/com_workflow/tmpl/stages/default.php @@ -67,7 +67,7 @@ - + @@ -75,9 +75,6 @@ - - - @@ -133,21 +130,6 @@
escape(Text::_($item->description)); ?>
- - condition == 'JARCHIVED'): - $icon = 'icon-archive'; - elseif ($item->condition == 'JTRASHED'): - $icon = 'icon-trash'; - elseif ($item->condition == 'JPUBLISHED'): - $icon = 'icon-publish'; - elseif ($item->condition == 'JUNPUBLISHED'): - $icon = 'icon-unpublish'; - endif; - ?> - - condition); ?> - id; ?> diff --git a/administrator/components/com_workflow/tmpl/transitions/default.php b/administrator/components/com_workflow/tmpl/transitions/default.php index af7d6107a2b3e..1873e827b5796 100644 --- a/administrator/components/com_workflow/tmpl/transitions/default.php +++ b/administrator/components/com_workflow/tmpl/transitions/default.php @@ -133,42 +133,10 @@ from_stage_id < 0): ?> - from_condition == Workflow::CONDITION_ARCHIVED): - $icon = 'icon-archive'; - $condition = Text::_('JARCHIVED'); - elseif ($item->from_condition == Workflow::CONDITION_TRASHED): - $icon = 'icon-trash'; - $condition = Text::_('JTRASHED'); - elseif ($item->from_condition == Workflow::CONDITION_PUBLISHED): - $icon = 'icon-publish'; - $condition = Text::_('JPUBLISHED'); - elseif ($item->from_condition == Workflow::CONDITION_UNPUBLISHED): - $icon = 'icon-unpublish'; - $condition = Text::_('JUNPUBLISHED'); - endif; ?> - - escape(Text::_($item->from_stage)); ?> - to_condition == Workflow::CONDITION_ARCHIVED): - $icon = 'icon-archive'; - $condition = Text::_('JARCHIVED'); - elseif ($item->to_condition == Workflow::CONDITION_TRASHED): - $icon = 'icon-trash'; - $condition = Text::_('JTRASHED'); - elseif ($item->to_condition == Workflow::CONDITION_PUBLISHED): - $icon = 'icon-publish'; - $condition = Text::_('JPUBLISHED'); - elseif ($item->to_condition == Workflow::CONDITION_UNPUBLISHED): - $icon = 'icon-unpublish'; - $condition = Text::_('JUNPUBLISHED'); - endif; ?> - - escape(Text::_($item->to_stage)); ?> diff --git a/installation/sql/mysql/joomla.sql b/installation/sql/mysql/joomla.sql index 2836697b0edce..7c2d266639def 100644 --- a/installation/sql/mysql/joomla.sql +++ b/installation/sql/mysql/joomla.sql @@ -2369,7 +2369,6 @@ CREATE TABLE IF NOT EXISTS `#__workflow_stages` ( `published` tinyint(1) NOT NULL DEFAULT 0, `title` varchar(255) NOT NULL, `description` text NOT NULL, - `condition` int(10) DEFAULT 0, `default` tinyint(1) NOT NULL DEFAULT 0, `checked_out_time` datetime, `checked_out` int(10) NOT NULL DEFAULT 0, @@ -2385,11 +2384,11 @@ CREATE TABLE IF NOT EXISTS `#__workflow_stages` ( -- Dumping data for table `#__workflow_stages` -- -INSERT INTO `#__workflow_stages` (`id`, `asset_id`, `ordering`, `workflow_id`, `published`, `title`, `description`, `condition`, `default`, `checked_out_time`, `checked_out`) VALUES -(1, 57, 1, 1, 1, 'JUNPUBLISHED', '', 0, 1, NULL, 0), -(2, 58, 2, 1, 1, 'JPUBLISHED', '', 1, 0, NULL, 0), -(3, 59, 3, 1, 1, 'JTRASHED', '', -2, 0, NULL, 0), -(4, 60, 4, 1, 1, 'JARCHIVED', '', 2, 0, NULL, 0); +INSERT INTO `#__workflow_stages` (`id`, `asset_id`, `ordering`, `workflow_id`, `published`, `title`, `description`, `default`, `checked_out_time`, `checked_out`) VALUES +(1, 57, 1, 1, 1, 'JUNPUBLISHED', '', 1, NULL, 0), +(2, 58, 2, 1, 1, 'JPUBLISHED', '', 0, NULL, 0), +(3, 59, 3, 1, 1, 'JTRASHED', '', 0, NULL, 0), +(4, 60, 4, 1, 1, 'JARCHIVED', '', 0, NULL, 0); -- -- Table structure for table `#__workflow_transitions` diff --git a/installation/sql/postgresql/joomla.sql b/installation/sql/postgresql/joomla.sql index 28cba57814a00..9a5b441404e79 100644 --- a/installation/sql/postgresql/joomla.sql +++ b/installation/sql/postgresql/joomla.sql @@ -2371,7 +2371,6 @@ CREATE TABLE IF NOT EXISTS "#__workflow_stages" ( "published" smallint NOT NULL DEFAULT 0, "title" varchar(255) NOT NULL, "description" text NOT NULL, - "condition" bigint DEFAULT 0 NOT NULL, "default" smallint NOT NULL DEFAULT 0, "checked_out_time" timestamp without time zone, "checked_out" bigint DEFAULT 0 NOT NULL, @@ -2387,11 +2386,11 @@ CREATE INDEX "#__workflow_stages_idx_checked_out" ON "#__workflow_stages" ("chec -- Dumping data for table "#__workflow_stages" -- -INSERT INTO "#__workflow_stages" ("id", "asset_id", "ordering", "workflow_id", "published", "title", "description", "condition", "default", "checked_out_time", "checked_out") VALUES -(1, 0, 1, 1, 1, 'JUNPUBLISHED', '', 0, 1, NULL, 0), -(2, 0, 2, 1, 1, 'JPUBLISHED', '', 1, 0, NULL, 0), -(3, 0, 3, 1, 1, 'JTRASHED', '', -2, 0, NULL, 0), -(4, 0, 4, 1, 1, 'JARCHIVED', '', 2, 0, NULL, 0); +INSERT INTO "#__workflow_stages" ("id", "asset_id", "ordering", "workflow_id", "published", "title", "description", "default", "checked_out_time", "checked_out") VALUES +(1, 0, 1, 1, 1, 'JUNPUBLISHED', '', 1, NULL, 0), +(2, 0, 2, 1, 1, 'JPUBLISHED', '', 0, NULL, 0), +(3, 0, 3, 1, 1, 'JTRASHED', '', 0, NULL, 0), +(4, 0, 4, 1, 1, 'JARCHIVED', '', 0, NULL, 0); SELECT setval('#__workflow_stages_id_seq', 5, false); -- From dc947de7cd04ae68debe631645076d7202fc1563 Mon Sep 17 00:00:00 2001 From: bembelimen Date: Sat, 14 Mar 2020 21:18:14 +0100 Subject: [PATCH 02/14] Load Workflow plugins on transition generation --- .../src/Model/TransitionModel.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/administrator/components/com_workflow/src/Model/TransitionModel.php b/administrator/components/com_workflow/src/Model/TransitionModel.php index e0c2b3a453502..54759f45385d2 100644 --- a/administrator/components/com_workflow/src/Model/TransitionModel.php +++ b/administrator/components/com_workflow/src/Model/TransitionModel.php @@ -12,6 +12,7 @@ defined('_JEXEC') or die; use Joomla\CMS\Factory; +use Joomla\CMS\Form\Form; use Joomla\CMS\Language\Text; use Joomla\CMS\MVC\Model\AdminModel; use Joomla\String\StringHelper; @@ -285,4 +286,22 @@ protected function loadFormData() return $data; } + + /** + * Trigger the form preparation for the workflow group + * + * @param Form $form A Form object. + * @param mixed $data The data expected for the form. + * @param string $group The name of the plugin group to import (defaults to "content"). + * + * @return void + * + * @see FormField + * @since 4.0.0 + * @throws \Exception if there is an error in the form event. + */ + protected function preprocessForm(Form $form, $data, $group = 'workflow') + { + parent::preprocessForm($form, $data, $group); + } } From dbefa0122e2f6d5ba4b2669c7a17183b010bf8f3 Mon Sep 17 00:00:00 2001 From: bembelimen Date: Sun, 29 Mar 2020 20:45:18 +0200 Subject: [PATCH 03/14] First commit for the publishing plugin --- .../sql/updates/mysql/4.0.0-2018-05-15.sql | 3 +- .../src/Model/TransitionModel.php | 23 +++ .../src/Table/TransitionTable.php | 10 ++ .../com_workflow/tmpl/transition/edit.php | 5 + .../en-GB/plg_workflow_publishing.ini | 11 ++ .../en-GB/plg_workflow_publishing.sys.ini | 7 + libraries/src/Form/Field/TransitionField.php | 8 - .../publishing/forms/workflow_publishing.xml | 19 +++ plugins/workflow/publishing/publishing.php | 158 ++++++++++++++++++ 9 files changed, 235 insertions(+), 9 deletions(-) create mode 100644 administrator/language/en-GB/plg_workflow_publishing.ini create mode 100644 administrator/language/en-GB/plg_workflow_publishing.sys.ini create mode 100644 plugins/workflow/publishing/forms/workflow_publishing.xml create mode 100644 plugins/workflow/publishing/publishing.php diff --git a/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-05-15.sql b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-05-15.sql index 69ac6bf9d5671..9196ee734db7c 100644 --- a/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-05-15.sql +++ b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-05-15.sql @@ -125,7 +125,8 @@ INSERT INTO `#__workflow_transitions` (`id`, `asset_id`, `published`, `ordering` -- INSERT INTO `#__extensions` (`package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `checked_out`, `checked_out_time`, `ordering`, `state`) VALUES -(0, 'com_workflow', 'component', 'com_workflow', '', 1, 1, 0, 0, '', '{}', 0, '0000-00-00 00:00:00', 0, 0); +(0, 'com_workflow', 'component', 'com_workflow', '', 1, 1, 0, 0, '', '{}', 0, NULL, 0, 0), +(0, 'plg_workflow_publishing', 'plugin', 'publishing', 'workflow', 0, 1, 1, 0, '', '{}', 0, NULL, 0, 0); -- -- Creating Associations for existing content diff --git a/administrator/components/com_workflow/src/Model/TransitionModel.php b/administrator/components/com_workflow/src/Model/TransitionModel.php index 54759f45385d2..d9ee3560b4456 100644 --- a/administrator/components/com_workflow/src/Model/TransitionModel.php +++ b/administrator/components/com_workflow/src/Model/TransitionModel.php @@ -15,6 +15,7 @@ use Joomla\CMS\Form\Form; use Joomla\CMS\Language\Text; use Joomla\CMS\MVC\Model\AdminModel; +use Joomla\Registry\Registry; use Joomla\String\StringHelper; /** @@ -111,6 +112,28 @@ protected function canEditState($record) return $user->authorise('core.edit.state', $extension); } + /** + * Method to get a single record. + * + * @param integer $pk The id of the primary key. + * + * @return CMSObject|boolean Object on success, false on failure. + * + * @since 4.0.0 + */ + public function getItem($pk = null) + { + $item = parent::getItem($pk); + + if (property_exists($item, 'options')) + { + $registry = new Registry($item->options); + $item->options = $registry->toArray(); + } + + return $item; + } + /** * Method to save the form data. * diff --git a/administrator/components/com_workflow/src/Table/TransitionTable.php b/administrator/components/com_workflow/src/Table/TransitionTable.php index 43f2f1d238351..eff94fc3faf8a 100644 --- a/administrator/components/com_workflow/src/Table/TransitionTable.php +++ b/administrator/components/com_workflow/src/Table/TransitionTable.php @@ -30,6 +30,16 @@ class TransitionTable extends Table */ protected $_supportNullValue = true; + /** + * An array of key names to be json encoded in the bind function + * + * @var array + * @since 4.0.0 + */ + protected $_jsonEncode = [ + 'options' + ]; + /** * Constructor * diff --git a/administrator/components/com_workflow/tmpl/transition/edit.php b/administrator/components/com_workflow/tmpl/transition/edit.php index 215b26b435cd0..857e8749d7b7a 100644 --- a/administrator/components/com_workflow/tmpl/transition/edit.php +++ b/administrator/components/com_workflow/tmpl/transition/edit.php @@ -17,6 +17,9 @@ HTMLHelper::_('behavior.formvalidator'); HTMLHelper::_('behavior.keepalive'); +$this->ignore_fieldsets = ['params', 'transition', 'permissions']; +$this->useCoreUI = true; + // In case of modal $isModal = $this->input->get('layout') === 'modal'; $layout = $isModal ? 'modal' : 'edit'; @@ -51,6 +54,8 @@
+ +
diff --git a/administrator/language/en-GB/plg_workflow_publishing.ini b/administrator/language/en-GB/plg_workflow_publishing.ini new file mode 100644 index 0000000000000..a7a1fcaca0ec2 --- /dev/null +++ b/administrator/language/en-GB/plg_workflow_publishing.ini @@ -0,0 +1,11 @@ +; Joomla! Project +; Copyright (C) 2005 - 2019 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_WORKFLOW_PUBLISHING="Workflow - Publishing" +PLG_WORKFLOW_PUBLISHING_XML_DESCRIPTION="Add publishing options to the workflow transitions for your items" +PLG_WORKFLOW_PUBLISHING_TRANSITION_OPTIONS_LABEL="Transition Options" +PLG_WORKFLOW_PUBLISHING_TRANSITION_OPTIONS_PUBLISHING_LABEL="Publishing state" +PLG_WORKFLOW_PUBLISHING_TRANSITION_OPTIONS_PUBLISHING_DESC="Define the state an item should be set, when executing this transition" +PLG_WORKFLOW_PUBLISHING_TRANSITION_OPTIONS_PUBLISHING_DO_NO_CHANGE="- Do not change" diff --git a/administrator/language/en-GB/plg_workflow_publishing.sys.ini b/administrator/language/en-GB/plg_workflow_publishing.sys.ini new file mode 100644 index 0000000000000..8f09ca95bbbf7 --- /dev/null +++ b/administrator/language/en-GB/plg_workflow_publishing.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2019 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_WORKFLOW_PUBLISHING="Workflow - Publishing" +PLG_WORKFLOW_PUBLISHING_XML_DESCRIPTION="Add publishing options to the workflow transitions for your items" diff --git a/libraries/src/Form/Field/TransitionField.php b/libraries/src/Form/Field/TransitionField.php index f478e54af9de2..2e63abc5f3098 100644 --- a/libraries/src/Form/Field/TransitionField.php +++ b/libraries/src/Form/Field/TransitionField.php @@ -112,7 +112,6 @@ protected function getOptions() [ $db->quoteName('t.id', 'value'), $db->quoteName('t.title', 'text'), - $db->quoteName('s.condition'), ] ) ->from( @@ -157,13 +156,6 @@ function ($item) use ($user, $extension) Factory::getLanguage()->load('com_workflow', JPATH_ADMINISTRATOR); $workflow = new Workflow(['extension' => $this->extension]); - - foreach ($items as $item) - { - $conditionName = $workflow->getConditionName((int) $item->condition); - - $item->text .= ' [' . Text::_($conditionName) . ']'; - } } // Get workflow stage title diff --git a/plugins/workflow/publishing/forms/workflow_publishing.xml b/plugins/workflow/publishing/forms/workflow_publishing.xml new file mode 100644 index 0000000000000..2cbc62a1dfe05 --- /dev/null +++ b/plugins/workflow/publishing/forms/workflow_publishing.xml @@ -0,0 +1,19 @@ + +
+ +
+ + + +
+
+
diff --git a/plugins/workflow/publishing/publishing.php b/plugins/workflow/publishing/publishing.php new file mode 100644 index 0000000000000..47f175b98e83e --- /dev/null +++ b/plugins/workflow/publishing/publishing.php @@ -0,0 +1,158 @@ +getName(); + + // Extend the transition form + if ($context == 'com_workflow.transition') + { + return $this->enhanceTransitionForm($form, $data); + } + + return $this->enhanceItemForm($form, $data); + } + + /** + * Add different parameter options to the transition view, we need when executing the transition + * + * @param Form $form The form + * @param stdClass $data The data + * + * @return boolean + * + * @since __DEPLOY_VERSION__ + */ + protected function enhanceTransitionForm(Form $form, $data) + { + Form::addFormPath(__DIR__ . '/forms'); + + $form->loadFile('workflow_publishing'); + + $model = $this->app->bootComponent('com_workflow') + ->getMVCFactory()->createModel('Workflow', 'Administrator', ['ignore_request' => true]); + + $workflow_id = !empty($data->workflow_id) ? (int) $data->workflow_id : (int) $form->getValue('workflow_id'); + + if (empty($workflow_id)) + { + $workflow_id = $this->app->input->getInt('workflow_id'); + } + + if ($workflow_id) + { + $workflow = $model->getItem($workflow_id); + + $form->setFieldAttribute('publishing', 'extension', $workflow->extension, 'options'); + } + else + { + $form->setFieldAttribute('publishing', 'disabled', 'true', 'options'); + } + + return true; + } + + /** + * Disable certain fields in the item form view, when we want to take over this function in the transition + * Check also for the workflow implementation and if the field exists + * + * @param Form $form The form + * @param stdClass $data The data + * + * @return boolean + * + * @since __DEPLOY_VERSION__ + */ + protected function enhanceItemForm(Form $form, $data) + { + $context = $form->getName(); + + $parts = explode('.', $context); + + // We need at least the extension + view for loading the fields + if (count($parts) < 2) + { + return true; + } + + $component = $this->app->bootComponent($parts[0]); + + if (!$component instanceof WorkflowServiceInterface) + { + return true; + } + + $model = $component->getMVCFactory()->createModel($parts[1], $this->app->getName(), ['ignore_request' => true]); + + if (!$model instanceof DatabaseModelInterface) + { + return true; + } + + $table = $model->getTable(); + + if (!$table instanceof TableInterface || !$table->hasField('published')) + { + return true; + } + + $form->setFieldAttribute($table->getColumnAlias('published'), 'disabled', 'true'); + + return true; + } +} From 851fe5fd9dccaa89298cc4e4f8da8903a3404ca5 Mon Sep 17 00:00:00 2001 From: bembelimen Date: Tue, 21 Apr 2020 02:59:04 +0200 Subject: [PATCH 04/14] Prevent saving of publishing state if workflow + plugin is active and the function is supported --- .../en-GB/plg_workflow_publishing.ini | 1 + plugins/workflow/publishing/publishing.php | 82 ++++++++++++++++--- 2 files changed, 70 insertions(+), 13 deletions(-) diff --git a/administrator/language/en-GB/plg_workflow_publishing.ini b/administrator/language/en-GB/plg_workflow_publishing.ini index a7a1fcaca0ec2..7a00405ac42f9 100644 --- a/administrator/language/en-GB/plg_workflow_publishing.ini +++ b/administrator/language/en-GB/plg_workflow_publishing.ini @@ -9,3 +9,4 @@ PLG_WORKFLOW_PUBLISHING_TRANSITION_OPTIONS_LABEL="Transition Options" PLG_WORKFLOW_PUBLISHING_TRANSITION_OPTIONS_PUBLISHING_LABEL="Publishing state" PLG_WORKFLOW_PUBLISHING_TRANSITION_OPTIONS_PUBLISHING_DESC="Define the state an item should be set, when executing this transition" PLG_WORKFLOW_PUBLISHING_TRANSITION_OPTIONS_PUBLISHING_DO_NO_CHANGE="- Do not change" +PLG_WORKFLOW_PUBLISHING_SAVE_NOT_ALLOWED="You're not allowed to change the publishing state of this item. Please use a workflow transition." diff --git a/plugins/workflow/publishing/publishing.php b/plugins/workflow/publishing/publishing.php index 47f175b98e83e..79cb29419b596 100644 --- a/plugins/workflow/publishing/publishing.php +++ b/plugins/workflow/publishing/publishing.php @@ -10,16 +10,12 @@ defined('_JEXEC') or die; use Joomla\CMS\Application\CMSApplicationInterface; -use Joomla\CMS\Factory; use Joomla\CMS\Form\Form; -use Joomla\CMS\Language\Multilanguage; +use Joomla\CMS\Language\Text; use Joomla\CMS\MVC\Model\DatabaseModelInterface; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Table\TableInterface; -use Joomla\CMS\Workflow\Workflow; use Joomla\CMS\Workflow\WorkflowServiceInterface; -use Joomla\Component\Fields\Administrator\Helper\FieldsHelper; -use Joomla\Registry\Registry; /** * Workflow Publishing Plugin @@ -122,37 +118,97 @@ protected function enhanceItemForm(Form $form, $data) { $context = $form->getName(); + if (!$this->isSupported($context)) + { + return true; + } + $parts = explode('.', $context); - // We need at least the extension + view for loading the fields - if (count($parts) < 2) + $table = $this->app->bootComponent($parts[0]) + ->getMVCFactory()->createModel($parts[1], $this->app->getName(), ['ignore_request' => true]) + ->getTable(); + + $form->setFieldAttribute($table->getColumnAlias('published'), 'disabled', 'true'); + + return true; + } + + /** + * The save event. + * + * @param string $context The context + * @param object $table The item + * @param boolean $isNew Is new item + * @param array $data The validated data + * + * @return boolean + * + * @since 4.0.0 + */ + public function onContentBeforeSave($context, TableInterface $table, $isNew, $data) + { + if (!$this->isSupported($context)) { return true; } + $keyName = $table->getColumnAlias('published'); + + // Check for the old value + $article = clone $table; + + $article->load($table->id); + + // We don't allow the change of the state when we use the workflow + // As we're setting the field to disabled, no value should be there at all + if (isset($data[$keyName])) + { + $table->setError(Text::_('PLG_WORKFLOW_PUBLISHING_SAVE_NOT_ALLOWED')); + + return false; + } + + return true; + } + + /** + * Check if the current plugin should execute workflow related activities + * + * @param type $context + * @return boolean + */ + protected function isSupported($context) + { + $parts = explode('.', $context); + + // We need at least the extension + view for loading the table fields + if (count($parts) < 2) + { + return false; + } + $component = $this->app->bootComponent($parts[0]); - if (!$component instanceof WorkflowServiceInterface) + if (!$component instanceof WorkflowServiceInterface || !$component->supportFunctionality('joomla.state')) { - return true; + return false; } $model = $component->getMVCFactory()->createModel($parts[1], $this->app->getName(), ['ignore_request' => true]); if (!$model instanceof DatabaseModelInterface) { - return true; + return false; } $table = $model->getTable(); if (!$table instanceof TableInterface || !$table->hasField('published')) { - return true; + return false; } - $form->setFieldAttribute($table->getColumnAlias('published'), 'disabled', 'true'); - return true; } } From 47bb0b566c90ddb53aaa2a42723027808a09938a Mon Sep 17 00:00:00 2001 From: bembelimen Date: Tue, 21 Apr 2020 03:57:13 +0200 Subject: [PATCH 05/14] Only enhance transition form, if plugin is supported --- plugins/workflow/publishing/publishing.php | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/plugins/workflow/publishing/publishing.php b/plugins/workflow/publishing/publishing.php index 79cb29419b596..a185b64f9c3d6 100644 --- a/plugins/workflow/publishing/publishing.php +++ b/plugins/workflow/publishing/publishing.php @@ -75,10 +75,6 @@ public function onContentPrepareForm(Form $form, $data) */ protected function enhanceTransitionForm(Form $form, $data) { - Form::addFormPath(__DIR__ . '/forms'); - - $form->loadFile('workflow_publishing'); - $model = $this->app->bootComponent('com_workflow') ->getMVCFactory()->createModel('Workflow', 'Administrator', ['ignore_request' => true]); @@ -89,10 +85,19 @@ protected function enhanceTransitionForm(Form $form, $data) $workflow_id = $this->app->input->getInt('workflow_id'); } - if ($workflow_id) + $workflow = $model->getItem($workflow_id); + + if (!$this->isSupported($workflow->context)) { - $workflow = $model->getItem($workflow_id); + return true; + } + + Form::addFormPath(__DIR__ . '/forms'); + $form->loadFile('workflow_publishing'); + + if ($workflow_id) + { $form->setFieldAttribute('publishing', 'extension', $workflow->extension, 'options'); } else From 0a6e5c4a598a5ac83c4bda07d331c3e1f054360d Mon Sep 17 00:00:00 2001 From: bembelimen Date: Tue, 21 Apr 2020 04:12:04 +0200 Subject: [PATCH 06/14] Add options field for transition plugins Fix support check for workflow publishing plugin --- .../com_admin/sql/updates/mysql/4.0.0-2018-05-15.sql | 11 ++++++----- .../sql/updates/postgresql/4.0.0-2018-05-15.sql | 11 ++++++----- installation/sql/mysql/base.sql | 11 ++++++----- installation/sql/postgresql/base.sql | 11 ++++++----- plugins/workflow/publishing/publishing.php | 4 ++-- 5 files changed, 26 insertions(+), 22 deletions(-) diff --git a/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-05-15.sql b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-05-15.sql index c8853c76e0d1b..ceef7055ca38e 100644 --- a/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-05-15.sql +++ b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-05-15.sql @@ -99,6 +99,7 @@ CREATE TABLE IF NOT EXISTS `#__workflow_transitions` ( `description` text NOT NULL, `from_stage_id` int(10) NOT NULL, `to_stage_id` int(10) NOT NULL, + `options` text NOT NULL, `checked_out_time` datetime, `checked_out` int(10) NOT NULL DEFAULT 0, PRIMARY KEY (`id`), @@ -114,11 +115,11 @@ CREATE TABLE IF NOT EXISTS `#__workflow_transitions` ( -- Dumping data for table `#__workflow_transitions` -- -INSERT INTO `#__workflow_transitions` (`id`, `asset_id`, `published`, `ordering`, `workflow_id`, `title`, `description`, `from_stage_id`, `to_stage_id`, `checked_out_time`, `checked_out`) VALUES -(1, 0, 1, 1, 1, 'Unpublish', '', -1, 1, NULL, 0), -(2, 0, 1, 2, 1, 'Publish', '', -1, 2, NULL, 0), -(3, 0, 1, 3, 1, 'Trash', '', -1, 3, NULL, 0), -(4, 0, 1, 4, 1, 'Archive', '', -1, 4, NULL, 0); +INSERT INTO `#__workflow_transitions` (`id`, `asset_id`, `published`, `ordering`, `workflow_id`, `title`, `description`, `from_stage_id`, `to_stage_id`, `options`, `checked_out_time`, `checked_out`) VALUES +(1, 0, 1, 1, 1, 'Unpublish', '', -1, 1, '{"publishing":"0"}', NULL, 0), +(2, 0, 1, 2, 1, 'Publish', '', -1, 2, '{"publishing":"1"}', NULL, 0), +(3, 0, 1, 3, 1, 'Trash', '', -1, 3, '{"publishing":"-2"}', NULL, 0), +(4, 0, 1, 4, 1, 'Archive', '', -1, 4, '{"publishing":"2"}', NULL, 0); -- -- Creating extension entry diff --git a/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-05-15.sql b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-05-15.sql index 5863ecfb92fd1..107b73c480fb2 100644 --- a/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-05-15.sql +++ b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-05-15.sql @@ -99,6 +99,7 @@ CREATE TABLE IF NOT EXISTS "#__workflow_transitions" ( "description" text NOT NULL, "from_stage_id" bigint DEFAULT 0 NOT NULL, "to_stage_id" bigint DEFAULT 0 NOT NULL, + "options" text NOT NULL, "checked_out_time" timestamp without time zone, "checked_out" bigint DEFAULT 0 NOT NULL, PRIMARY KEY ("id") @@ -110,11 +111,11 @@ CREATE INDEX "#__workflow_transitions_idx_to_stage_id" ON "#__workflow_transitio CREATE INDEX "#__workflow_transitions_idx_workflow_id" ON "#__workflow_transitions" ("workflow_id"); CREATE INDEX "#__workflow_transitions_idx_checked_out" ON "#__workflow_transitions" ("checked_out"); -INSERT INTO "#__workflow_transitions" ("id", "asset_id", "published", "ordering", "workflow_id", "title", "description", "from_stage_id", "to_stage_id", "checked_out_time", "checked_out") VALUES -(1, 0, 1, 1, 1, 'Unpublish', '', -1, 1, NULL, 0), -(2, 0, 1, 2, 1, 'Publish', '', -1, 2, NULL, 0), -(3, 0, 1, 3, 1, 'Trash', '', -1, 3, NULL, 0), -(4, 0, 1, 4, 1, 'Archive', '', -1, 4, NULL, 0); +INSERT INTO "#__workflow_transitions" ("id", "asset_id", "published", "ordering", "workflow_id", "title", "description", "from_stage_id", "to_stage_id", "options", "checked_out_time", "checked_out") VALUES +(1, 0, 1, 1, 1, 'Unpublish', '', -1, 1, '{"publishing":"0"}', NULL, 0), +(2, 0, 1, 2, 1, 'Publish', '', -1, 2, '{"publishing":"1"}', NULL, 0), +(3, 0, 1, 3, 1, 'Trash', '', -1, 3, '{"publishing":"-2"}', NULL, 0), +(4, 0, 1, 4, 1, 'Archive', '', -1, '{"publishing":"2"}', 4, NULL, 0); -- -- Creating extension entry diff --git a/installation/sql/mysql/base.sql b/installation/sql/mysql/base.sql index 1c080e7de83bc..00668b0b5317c 100644 --- a/installation/sql/mysql/base.sql +++ b/installation/sql/mysql/base.sql @@ -1155,6 +1155,7 @@ CREATE TABLE IF NOT EXISTS `#__workflow_transitions` ( `description` text NOT NULL, `from_stage_id` int(10) NOT NULL, `to_stage_id` int(10) NOT NULL, + `options` text NOT NULL, `checked_out_time` datetime, `checked_out` int(10) NOT NULL DEFAULT 0, PRIMARY KEY (`id`), @@ -1170,8 +1171,8 @@ CREATE TABLE IF NOT EXISTS `#__workflow_transitions` ( -- Dumping data for table `#__workflow_transitions` -- -INSERT INTO `#__workflow_transitions` (`id`, `asset_id`, `published`, `ordering`, `workflow_id`, `title`, `description`, `from_stage_id`, `to_stage_id`, `checked_out_time`, `checked_out`) VALUES -(1, 61, 1, 1, 1, 'Unpublish', '', -1, 1, NULL, 0), -(2, 62, 1, 2, 1, 'Publish', '', -1, 2, NULL, 0), -(3, 63, 1, 3, 1, 'Trash', '', -1, 3, NULL, 0), -(4, 64, 1, 4, 1, 'Archive', '', -1, 4, NULL, 0); +INSERT INTO `#__workflow_transitions` (`id`, `asset_id`, `published`, `ordering`, `workflow_id`, `title`, `description`, `from_stage_id`, `to_stage_id`, `options`, `checked_out_time`, `checked_out`) VALUES +(1, 61, 1, 1, 1, 'Unpublish', '', -1, 1, '{"publishing":"0"}', NULL, 0), +(2, 62, 1, 2, 1, 'Publish', '', -1, 2, '{"publishing":"1"}', NULL, 0), +(3, 63, 1, 3, 1, 'Trash', '', -1, 3, '{"publishing":"-2"}', NULL, 0), +(4, 64, 1, 4, 1, 'Archive', '', -1, 4, '{"publishing":"2"}', NULL, 0); diff --git a/installation/sql/postgresql/base.sql b/installation/sql/postgresql/base.sql index 9430393facce9..851940353c965 100644 --- a/installation/sql/postgresql/base.sql +++ b/installation/sql/postgresql/base.sql @@ -1163,6 +1163,7 @@ CREATE TABLE IF NOT EXISTS "#__workflow_transitions" ( "description" text NOT NULL, "from_stage_id" bigint DEFAULT 0 NOT NULL, "to_stage_id" bigint DEFAULT 0 NOT NULL, + "options" text NOT NULL, "checked_out_time" timestamp without time zone, "checked_out" bigint DEFAULT 0 NOT NULL, PRIMARY KEY ("id") @@ -1174,10 +1175,10 @@ CREATE INDEX "#__workflow_transitions_idx_to_stage_id" ON "#__workflow_transitio CREATE INDEX "#__workflow_transitions_idx_workflow_id" ON "#__workflow_transitions" ("workflow_id"); CREATE INDEX "#__workflow_transitions_idx_checked_out" ON "#__workflow_transitions" ("checked_out"); -INSERT INTO "#__workflow_transitions" ("id", "asset_id", "published", "ordering", "workflow_id", "title", "description", "from_stage_id", "to_stage_id", "checked_out_time", "checked_out") VALUES -(1, 61, 1, 1, 1, 'Unpublish', '', -1, 1, NULL, 0), -(2, 62, 1, 2, 1, 'Publish', '', -1, 2, NULL, 0), -(3, 63, 1, 3, 1, 'Trash', '', -1, 3, NULL, 0), -(4, 64, 1, 4, 1, 'Archive', '', -1, 4, NULL, 0); +INSERT INTO "#__workflow_transitions" ("id", "asset_id", "published", "ordering", "workflow_id", "title", "description", "from_stage_id", "to_stage_id", "options", "checked_out_time", "checked_out") VALUES +(1, 61, 1, 1, 1, 'Unpublish', '', -1, 1, '{"publishing":"0"}', NULL, 0), +(2, 62, 1, 2, 1, 'Publish', '', -1, 2, '{"publishing":"1"}', NULL, 0), +(3, 63, 1, 3, 1, 'Trash', '', -1, 3, '{"publishing":"-2"}', NULL, 0), +(4, 64, 1, 4, 1, 'Archive', '', -1, 4, '{"publishing":"2"}', NULL, 0); SELECT setval('#__workflow_transitions_id_seq', 5, false); \ No newline at end of file diff --git a/plugins/workflow/publishing/publishing.php b/plugins/workflow/publishing/publishing.php index a185b64f9c3d6..ba9ae8ccf77ff 100644 --- a/plugins/workflow/publishing/publishing.php +++ b/plugins/workflow/publishing/publishing.php @@ -87,7 +87,7 @@ protected function enhanceTransitionForm(Form $form, $data) $workflow = $model->getItem($workflow_id); - if (!$this->isSupported($workflow->context)) + if (!$this->isSupported($workflow->extension)) { return true; } @@ -195,7 +195,7 @@ protected function isSupported($context) $component = $this->app->bootComponent($parts[0]); - if (!$component instanceof WorkflowServiceInterface || !$component->supportFunctionality('joomla.state')) + if (!$component instanceof WorkflowServiceInterface || !$component->supportFunctionality('joomla.state', $context)) { return false; } From dab5c8dc7e5ef90a4631e3014eaead26a99c287e Mon Sep 17 00:00:00 2001 From: bembelimen Date: Tue, 21 Apr 2020 04:15:36 +0200 Subject: [PATCH 07/14] Set transition default values when creating a new workflow --- .../com_workflow/src/Model/WorkflowModel.php | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/administrator/components/com_workflow/src/Model/WorkflowModel.php b/administrator/components/com_workflow/src/Model/WorkflowModel.php index a500e53761920..6f20b66ac57a4 100644 --- a/administrator/components/com_workflow/src/Model/WorkflowModel.php +++ b/administrator/components/com_workflow/src/Model/WorkflowModel.php @@ -114,19 +114,23 @@ public function save($data) [ 'title' => 'JUNPUBLISHED', 'default' => 1, - 'transition' => 'Unpublish' + 'transition' => 'Unpublish', + 'options' => '{"publishing":"0"}' ], [ 'title' => 'JPUBLISHED', - 'transition' => 'Publish' + 'transition' => 'Publish', + 'options' => '{"publishing":"1"}' ], [ 'title' => 'JTRASHED', - 'transition' => 'Trash' + 'transition' => 'Trash', + 'options' => '{"publishing":"-2"}' ], [ 'title' => 'JARCHIVED', - 'transition' => 'Archive' + 'transition' => 'Archive', + 'options' => '{"publishing":"2"}' ] ]; @@ -155,6 +159,7 @@ public function save($data) $transition->published = 1; $transition->from_stage_id = -1; $transition->to_stage_id = (int) $table->id; + $transition->options = $stage['options']; $transition->store(); } From f906e6708c89bce4e7aded5b7fdbda95d2a0f2ba Mon Sep 17 00:00:00 2001 From: bembelimen Date: Tue, 21 Apr 2020 04:17:48 +0200 Subject: [PATCH 08/14] Make publishing plugin support name generic --- plugins/workflow/publishing/publishing.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/plugins/workflow/publishing/publishing.php b/plugins/workflow/publishing/publishing.php index ba9ae8ccf77ff..995cc998b7336 100644 --- a/plugins/workflow/publishing/publishing.php +++ b/plugins/workflow/publishing/publishing.php @@ -40,6 +40,14 @@ class PlgWorkflowPublishing extends CMSPlugin */ protected $app; + /** + * The name of the supported name to check against + * + * @var string + * @since __DEPLOY_VERSION__ + */ + protected $supportname = 'joomla.state'; + /** * The form event. * @@ -195,7 +203,7 @@ protected function isSupported($context) $component = $this->app->bootComponent($parts[0]); - if (!$component instanceof WorkflowServiceInterface || !$component->supportFunctionality('joomla.state', $context)) + if (!$component instanceof WorkflowServiceInterface || !$component->supportFunctionality($this->supportname, $context)) { return false; } From 941f3079aa77e096e22ab6d1a46d8bd30bfd3e9c Mon Sep 17 00:00:00 2001 From: bembelimen Date: Tue, 21 Apr 2020 04:31:59 +0200 Subject: [PATCH 09/14] Allow to kill transition execution --- libraries/src/Workflow/Workflow.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libraries/src/Workflow/Workflow.php b/libraries/src/Workflow/Workflow.php index 5d4e7cc6dac1a..b49d243ab26a8 100644 --- a/libraries/src/Workflow/Workflow.php +++ b/libraries/src/Workflow/Workflow.php @@ -208,6 +208,11 @@ public function executeTransition(array $pks, int $transition_id): bool ] ); + if (\in_array(false, $result, true)) + { + return false; + } + $success = $this->updateAssociations($pks, (int) $transition->to_stage_id); if ($success) From 087d9b3867ba9ec1d48ea1efe3e10245bb8ac02c Mon Sep 17 00:00:00 2001 From: bembelimen Date: Tue, 21 Apr 2020 04:33:19 +0200 Subject: [PATCH 10/14] Add missing variable assignment to kill transitions --- libraries/src/Workflow/Workflow.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/src/Workflow/Workflow.php b/libraries/src/Workflow/Workflow.php index b49d243ab26a8..322c40fd6a3f8 100644 --- a/libraries/src/Workflow/Workflow.php +++ b/libraries/src/Workflow/Workflow.php @@ -198,7 +198,7 @@ public function executeTransition(array $pks, int $transition_id): bool $app = Factory::getApplication(); - $app->triggerEvent( + $result = $app->triggerEvent( 'onWorkflowBeforeTransition', [ 'pks' => $pks, From a564cb958bc83061141c5a3a72433396b454a9df Mon Sep 17 00:00:00 2001 From: bembelimen Date: Tue, 21 Apr 2020 04:42:39 +0200 Subject: [PATCH 11/14] Prevent state change on publish events --- .../en-GB/plg_workflow_publishing.ini | 2 +- libraries/src/Workflow/Workflow.php | 9 ++++---- plugins/workflow/publishing/publishing.php | 22 ++++++++++++++++++- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/administrator/language/en-GB/plg_workflow_publishing.ini b/administrator/language/en-GB/plg_workflow_publishing.ini index 7a00405ac42f9..ba30a4cd2228f 100644 --- a/administrator/language/en-GB/plg_workflow_publishing.ini +++ b/administrator/language/en-GB/plg_workflow_publishing.ini @@ -9,4 +9,4 @@ PLG_WORKFLOW_PUBLISHING_TRANSITION_OPTIONS_LABEL="Transition Options" PLG_WORKFLOW_PUBLISHING_TRANSITION_OPTIONS_PUBLISHING_LABEL="Publishing state" PLG_WORKFLOW_PUBLISHING_TRANSITION_OPTIONS_PUBLISHING_DESC="Define the state an item should be set, when executing this transition" PLG_WORKFLOW_PUBLISHING_TRANSITION_OPTIONS_PUBLISHING_DO_NO_CHANGE="- Do not change" -PLG_WORKFLOW_PUBLISHING_SAVE_NOT_ALLOWED="You're not allowed to change the publishing state of this item. Please use a workflow transition." +PLG_WORKFLOW_PUBLISHING_CHANGE_STATE_NOT_ALLOWED="You're not allowed to change the publishing state of this item. Please use a workflow transition." diff --git a/libraries/src/Workflow/Workflow.php b/libraries/src/Workflow/Workflow.php index 322c40fd6a3f8..c4b9b3d6acfc2 100644 --- a/libraries/src/Workflow/Workflow.php +++ b/libraries/src/Workflow/Workflow.php @@ -12,6 +12,7 @@ use Joomla\CMS\Extension\ComponentInterface; use Joomla\CMS\Factory; +use Joomla\CMS\Plugin\PluginHelper; use Joomla\Database\ParameterType; use Joomla\Utilities\ArrayHelper; @@ -198,12 +199,13 @@ public function executeTransition(array $pks, int $transition_id): bool $app = Factory::getApplication(); + PluginHelper::importPlugin('workflow'); + $result = $app->triggerEvent( 'onWorkflowBeforeTransition', [ + 'context' => $this->extension, 'pks' => $pks, - 'extension' => $this->extension, - 'user' => $app->getIdentity(), 'transition' => $transition, ] ); @@ -220,9 +222,8 @@ public function executeTransition(array $pks, int $transition_id): bool $app->triggerEvent( 'onWorkflowAfterTransition', [ + 'context' => $this->extension, 'pks' => $pks, - 'extension' => $this->extension, - 'user' => $app->getIdentity(), 'transition' => $transition, ] ); diff --git a/plugins/workflow/publishing/publishing.php b/plugins/workflow/publishing/publishing.php index 995cc998b7336..1f340e152b673 100644 --- a/plugins/workflow/publishing/publishing.php +++ b/plugins/workflow/publishing/publishing.php @@ -147,6 +147,26 @@ protected function enhanceItemForm(Form $form, $data) return true; } + /** + * Change State of an item. Used to disable state change + * + * @param string $context The context + * @param array $pks IDs of the items + * @param int $value The value to change to + * @return boolean + */ + public function onContentBeforeChangeState($context, $pks, $value) + { + if (!$this->isSupported($context)) + { + return true; + } + + $this->app->enqueueMessage(Text::_('PLG_WORKFLOW_PUBLISHING_CHANGE_STATE_NOT_ALLOWED'), 'error'); + + return false; + } + /** * The save event. * @@ -177,7 +197,7 @@ public function onContentBeforeSave($context, TableInterface $table, $isNew, $da // As we're setting the field to disabled, no value should be there at all if (isset($data[$keyName])) { - $table->setError(Text::_('PLG_WORKFLOW_PUBLISHING_SAVE_NOT_ALLOWED')); + $this->app->enqueueMessage(Text::_('PLG_WORKFLOW_PUBLISHING_CHANGE_STATE_NOT_ALLOWED'), 'error'); return false; } From c1e5439ee6be383b8f3e51b3cb82dfdbb284f00d Mon Sep 17 00:00:00 2001 From: bembelimen Date: Tue, 21 Apr 2020 23:37:08 +0200 Subject: [PATCH 12/14] Implement finished version of the publishing plugin which now changes states of items Fix wrong contexts --- .../com_content/src/Model/ArticleModel.php | 2 +- .../com_content/src/Model/ArticlesModel.php | 4 +- .../src/MVC/Model/WorkflowBehaviorTrait.php | 12 ++- libraries/src/Workflow/Workflow.php | 11 ++- plugins/content/joomla/joomla.php | 2 +- plugins/workflow/publishing/publishing.php | 84 ++++++++++++++++++- 6 files changed, 106 insertions(+), 9 deletions(-) diff --git a/administrator/components/com_content/src/Model/ArticleModel.php b/administrator/components/com_content/src/Model/ArticleModel.php index aef54df5bc842..3904c7205ef46 100644 --- a/administrator/components/com_content/src/Model/ArticleModel.php +++ b/administrator/components/com_content/src/Model/ArticleModel.php @@ -346,7 +346,7 @@ protected function prepareTable($table) */ public function publish(&$pks, $value = 1) { - $this->importWorkflowPlugins(); + $this->workflowBeforeStageChange(); return parent::publish($pks, $value); } diff --git a/administrator/components/com_content/src/Model/ArticlesModel.php b/administrator/components/com_content/src/Model/ArticlesModel.php index dc90f2cc40d48..5b6ffd6cec026 100644 --- a/administrator/components/com_content/src/Model/ArticlesModel.php +++ b/administrator/components/com_content/src/Model/ArticlesModel.php @@ -252,7 +252,7 @@ protected function getListQuery() ] ) ->from($db->quoteName('#__content', 'a')) - ->where($db->quoteName('wa.extension') . ' = ' . $db->quote('com_content')) + ->where($db->quoteName('wa.extension') . ' = ' . $db->quote('com_content.article')) ->join('LEFT', $db->quoteName('#__languages', 'l'), $db->quoteName('l.lang_code') . ' = ' . $db->quoteName('a.language')) ->join('LEFT', $db->quoteName('#__content_frontpage', 'fp'), $db->quoteName('fp.content_id') . ' = ' . $db->quoteName('a.id')) ->join('LEFT', $db->quoteName('#__users', 'uc'), $db->quoteName('uc.id') . ' = ' . $db->quoteName('a.checked_out')) @@ -597,7 +597,7 @@ public function getTransitions() $transitions = $db->setQuery($query)->loadAssocList(); - $workflow = new Workflow(['extension' => 'com_content']); + $workflow = new Workflow(['extension' => 'com_content.article']); foreach ($transitions as $key => $transition) { diff --git a/libraries/src/MVC/Model/WorkflowBehaviorTrait.php b/libraries/src/MVC/Model/WorkflowBehaviorTrait.php index d79c79cde259c..2f9f5e62374be 100644 --- a/libraries/src/MVC/Model/WorkflowBehaviorTrait.php +++ b/libraries/src/MVC/Model/WorkflowBehaviorTrait.php @@ -61,7 +61,7 @@ public function setUpWorkflow($extension) $this->section = array_shift($parts); } - $this->workflow = new Workflow(['extension' => $this->extension]); + $this->workflow = new Workflow(['extension' => $extension]); $params = ComponentHelper::getParams($this->extension); @@ -110,6 +110,16 @@ public function workflowPreprocessForm(Form $form, $data) $this->importWorkflowPlugins(); } + public function workflowBeforeStageChange() + { + if (!$this->workflowEnabled) + { + return; + } + + $this->importWorkflowPlugins(); + } + /** * Preparation of workflow data/plugins * diff --git a/libraries/src/Workflow/Workflow.php b/libraries/src/Workflow/Workflow.php index c4b9b3d6acfc2..7004c3647fbf5 100644 --- a/libraries/src/Workflow/Workflow.php +++ b/libraries/src/Workflow/Workflow.php @@ -14,6 +14,7 @@ use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Database\ParameterType; +use Joomla\Registry\Registry; use Joomla\Utilities\ArrayHelper; /** @@ -172,19 +173,23 @@ public function executeTransition(array $pks, int $transition_id): bool $db->quoteName('t.id'), $db->quoteName('t.to_stage_id'), $db->quoteName('t.from_stage_id'), + $db->quoteName('t.options'), ] ) ->from($db->quoteName('#__workflow_transitions', 't')) ->join('LEFT', $db->quoteName('#__workflow_stages', 's'), $db->quoteName('s.id') . ' = ' . $db->quoteName('t.to_stage_id')) ->where($db->quoteName('t.id') . ' = :id') + ->where($db->quoteName('t.published') . ' = 1') ->bind(':id', $transition_id, ParameterType::INTEGER); - if (!empty($this->options['published'])) + $transition = $db->setQuery($query)->loadObject(); + + if (empty($transition->id)) { - $query->where($db->quoteName('t.published') . ' = 1'); + return false; } - $transition = $db->setQuery($query)->loadObject(); + $transition->options = new Registry($transition->options); // Check if the items can execute this transition foreach ($pks as $pk) diff --git a/plugins/content/joomla/joomla.php b/plugins/content/joomla/joomla.php index 55c21cbc57d2c..1c2ed441993b1 100644 --- a/plugins/content/joomla/joomla.php +++ b/plugins/content/joomla/joomla.php @@ -655,7 +655,7 @@ public function onContentChangeState($context, $pks, $value) $article = new ArticleTable($db); - $workflow = new Workflow(['extension' => 'com_content']); + $workflow = new Workflow(['extension' => 'com_content.article']); foreach ($pks as $pk) { diff --git a/plugins/workflow/publishing/publishing.php b/plugins/workflow/publishing/publishing.php index 1f340e152b673..321bf46a5870d 100644 --- a/plugins/workflow/publishing/publishing.php +++ b/plugins/workflow/publishing/publishing.php @@ -147,6 +147,81 @@ protected function enhanceItemForm(Form $form, $data) return true; } + /** + * Check if we can execute the transition + * + * @param string $context The context + * @param array $pks IDs of the items + * @param object $transition The value to change to + * + * @return boolean + */ + public function onWorkflowBeforeTransition($context, $pks, $transition) + { + if (!$this->isSupported($context) || !is_numeric($transition->options->get('publishing'))) + { + return true; + } + + $value = (int) $transition->options->get('publishing'); + + // Here it becomes tricky. We would like to use the component models publish method, so we will + // Execute the normal "onContentBeforeChangeState" plugins. But they could cancel the execution, + // So we have to precheck and cancel the whole transition stuff if not allowed. + $this->app->set('plgWorkflowPublishing.' . $context, $pks); + + $result = $this->app->triggerEvent('onContentBeforeChangeState', [$context, $pks, $value]); + + // Release whitelist, the job is done + $this->app->set('plgWorkflowPublishing.' . $context, []); + + if (\in_array(false, $result, true)) + { + return false; + } + + return true; + } + + /** + * Change State of an item. Used to disable state change + * + * @param string $context The context + * @param array $pks IDs of the items + * @param object $transition The value to change to + * + * @return boolean + */ + public function onWorkflowAfterTransition($context, $pks, $transition) + { + if (!$this->isSupported($context)) + { + return true; + } + + $parts = explode('.', $context); + + // We need at least the extension + view for loading the table fields + if (count($parts) < 2) + { + return false; + } + + $component = $this->app->bootComponent($parts[0]); + + $value = (int) $transition->options->get('publishing'); + + $options = [ + 'ignore_request' => true, + // We already have triggered onContentBeforeChangeState, so use our own + 'event_before_change_state' => 'onWorkflowBeforeChangeState' + ]; + + $model = $component->getMVCFactory()->createModel($parts[1], $this->app->getName(), $options); + + return $model->publish($pks, $value); + } + /** * Change State of an item. Used to disable state change * @@ -162,6 +237,13 @@ public function onContentBeforeChangeState($context, $pks, $value) return true; } + // We have whitelisted the pks, so we're the one who triggered + // With onWorkflowBeforeTransition => free pass + if ($this->app->get('plgWorkflowPublishing.' . $context) === $pks) + { + return true; + } + $this->app->enqueueMessage(Text::_('PLG_WORKFLOW_PUBLISHING_CHANGE_STATE_NOT_ALLOWED'), 'error'); return false; @@ -230,7 +312,7 @@ protected function isSupported($context) $model = $component->getMVCFactory()->createModel($parts[1], $this->app->getName(), ['ignore_request' => true]); - if (!$model instanceof DatabaseModelInterface) + if (!$model instanceof DatabaseModelInterface || !method_exists($model, 'publish')) { return false; } From 116559c9c97854243b7615e60972ea169709edce Mon Sep 17 00:00:00 2001 From: bembelimen Date: Wed, 22 Apr 2020 00:02:16 +0200 Subject: [PATCH 13/14] Update the workflow model interface to respect all methods Secure controller execution for runTransition --- .../src/MVC/Controller/AdminController.php | 10 ++++++ .../src/MVC/Model/WorkflowBehaviorTrait.php | 15 +++++++-- .../src/MVC/Model/WorkflowModelInterface.php | 32 +++++++++++++++++++ 3 files changed, 55 insertions(+), 2 deletions(-) diff --git a/libraries/src/MVC/Controller/AdminController.php b/libraries/src/MVC/Controller/AdminController.php index a094b1a576ff6..e43451c7f6af0 100644 --- a/libraries/src/MVC/Controller/AdminController.php +++ b/libraries/src/MVC/Controller/AdminController.php @@ -16,6 +16,7 @@ use Joomla\CMS\Language\Text; use Joomla\CMS\MVC\Factory\MVCFactoryInterface; use Joomla\CMS\MVC\Model\BaseDatabaseModel; +use Joomla\CMS\MVC\Model\WorkflowModelInterface; use Joomla\CMS\Router\Route; use Joomla\Input\Input; use Joomla\Utilities\ArrayHelper; @@ -430,6 +431,9 @@ public function saveOrderAjax() */ public function runTransition() { + // Check for request forgeries + $this->checkToken(); + // Get the input $pks = $this->input->post->get('cid', array(), 'array'); @@ -444,6 +448,12 @@ public function runTransition() // Get the model $model = $this->getModel(); + + if (!$model instanceof WorkflowModelInterface) + { + return false; + } + $return = $model->executeTransition($pk, $transitionId); $redirect = Route::_('index.php?option=' . $this->option . '&view=' . $this->view_list . $this->getRedirectToListAppend(), false); diff --git a/libraries/src/MVC/Model/WorkflowBehaviorTrait.php b/libraries/src/MVC/Model/WorkflowBehaviorTrait.php index 2f9f5e62374be..9c07e9a657fe7 100644 --- a/libraries/src/MVC/Model/WorkflowBehaviorTrait.php +++ b/libraries/src/MVC/Model/WorkflowBehaviorTrait.php @@ -48,7 +48,11 @@ trait WorkflowBehaviorTrait /** * Set Up the workflow * - * @param string $extension The option and section separated by . + * @param string $extension The option and section separated by. + * + * @return void + * + * @since 4.0.0 */ public function setUpWorkflow($extension) { @@ -110,6 +114,13 @@ public function workflowPreprocessForm(Form $form, $data) $this->importWorkflowPlugins(); } + /** + * Let plugins access stage change events + * + * @return void + * + * @since 4.0.0 + */ public function workflowBeforeStageChange() { if (!$this->workflowEnabled) @@ -183,7 +194,7 @@ public function workflowAfterSave($data) * * @since 4.0.0 */ - public function executeTransition(int $pk, int $transition_id): bool + public function executeTransition(int $pk, int $transition_id) { $result = $this->workflow->executeTransition([$pk], $transition_id); diff --git a/libraries/src/MVC/Model/WorkflowModelInterface.php b/libraries/src/MVC/Model/WorkflowModelInterface.php index a2bb76279c972..9e9d4586c95db 100644 --- a/libraries/src/MVC/Model/WorkflowModelInterface.php +++ b/libraries/src/MVC/Model/WorkflowModelInterface.php @@ -19,6 +19,17 @@ */ interface WorkflowModelInterface { + /** + * Set Up the workflow + * + * @param string $extension The option and section separated by. + * + * @return void + * + * @since 4.0.0 + */ + public function setUpWorkflow($extension); + /** * Method to allow derived classes to preprocess the form. * @@ -33,6 +44,15 @@ interface WorkflowModelInterface */ public function workflowPreprocessForm(Form $form, $data); + /** + * Let plugins access stage change events + * + * @return void + * + * @since 4.0.0 + */ + public function workflowBeforeStageChange(); + /** * Preparation of workflow data/plugins * @@ -51,6 +71,18 @@ public function workflowBeforeSave(); */ public function workflowAfterSave($data); + /** + * Runs transition for item. + * + * @param integer $pk Id of article + * @param integer $transition_id Id of transition + * + * @return boolean + * + * @since 4.0.0 + */ + public function executeTransition(int $pk, int $transition_id); + /** * Method to get state variables. * From bb0c22a52c3dc680a9177fcf8ae4da0538b3faf2 Mon Sep 17 00:00:00 2001 From: bembelimen Date: Wed, 22 Apr 2020 00:58:33 +0200 Subject: [PATCH 14/14] Implement frontend transition with the new plugin method --- .../src/Extension/ContentComponent.php | 28 +++++++++++ components/com_content/forms/article.xml | 17 ++++--- components/com_content/tmpl/form/edit.php | 6 +-- .../src/Workflow/WorkflowServiceInterface.php | 18 +++++++ .../src/Workflow/WorkflowServiceTrait.php | 49 ++++++++++++++++--- plugins/workflow/publishing/publishing.php | 17 +++++-- 6 files changed, 114 insertions(+), 21 deletions(-) diff --git a/administrator/components/com_content/src/Extension/ContentComponent.php b/administrator/components/com_content/src/Extension/ContentComponent.php index 552e5077b1eda..b0a05e63b1382 100644 --- a/administrator/components/com_content/src/Extension/ContentComponent.php +++ b/administrator/components/com_content/src/Extension/ContentComponent.php @@ -199,6 +199,34 @@ public function getWorkflowTableBySection(?string $section = null): string return '#__content'; } + /** + * Returns the model name, based on the context + * + * @param string $context The context of the workflow + * + * @return bool + */ + public function getModelName($context): string + { + $parts = explode('.', $context); + + if (count($parts) < 2) + { + return ''; + } + + array_shift($parts); + + $modelname = array_shift($parts); + + if ($modelname === 'article' && Factory::getApplication()->isClient('site')) + { + return 'Form'; + } + + return ucfirst($modelname); + } + /** * Method to filter transitions by given id of state. * diff --git a/components/com_content/forms/article.xml b/components/com_content/forms/article.xml index d28790a36b7be..4e97bb032b630 100644 --- a/components/com_content/forms/article.xml +++ b/components/com_content/forms/article.xml @@ -55,12 +55,17 @@ /> + name="state" + type="list" + label="JSTATUS" + class="custom-select-color-state" + size="1" + default="1" + > + + + + tab_name, 'publishing', Text::_('COM_CONTENT_PUBLISHING')); ?> + + form->renderField('transition'); ?> + form->renderField('state'); ?> form->renderField('catid'); ?> form->renderField('tags'); ?> form->renderField('note'); ?> @@ -108,9 +111,6 @@ get('show_publishing_options', 1) == 1) : ?> form->renderField('created_by_alias'); ?> - item->id > 0) : ?> - form->renderField('transition'); ?> - item->params->get('access-change')) : ?> form->renderField('featured'); ?> get('show_publishing_options', 1) == 1) : ?> diff --git a/libraries/src/Workflow/WorkflowServiceInterface.php b/libraries/src/Workflow/WorkflowServiceInterface.php index abb81000168c8..83227f8a1f1b8 100644 --- a/libraries/src/Workflow/WorkflowServiceInterface.php +++ b/libraries/src/Workflow/WorkflowServiceInterface.php @@ -28,6 +28,24 @@ interface WorkflowServiceInterface { */ public function supportFunctionality($functionality, $context): bool; + /** + * Returns the model name, based on the context + * + * @param string $context The context of the workflow + * + * @return bool + */ + public function getModelName($context): string; + + /** + * Check if the workflow is active + * + * @param string $context The context of the workflow + * + * @return bool + */ + public function isWorkflowActive($context): bool; + /** * Method to filter transitions by given id of state. * diff --git a/libraries/src/Workflow/WorkflowServiceTrait.php b/libraries/src/Workflow/WorkflowServiceTrait.php index 7841729b21544..475771c9507ab 100644 --- a/libraries/src/Workflow/WorkflowServiceTrait.php +++ b/libraries/src/Workflow/WorkflowServiceTrait.php @@ -36,8 +36,8 @@ abstract function getMVCFactory(); * * @return bool */ - public function supportFunctionality($functionality, $context): bool { - + public function supportFunctionality($functionality, $context): bool + { if (empty($this->supportedFunctionality[$functionality])) { return false; @@ -51,6 +51,27 @@ public function supportFunctionality($functionality, $context): bool { return in_array($context, $this->supportedFunctionality[$functionality]); } + /** + * Returns the model name, based on the context + * + * @param string $context The context of the workflow + * + * @return bool + */ + public function getModelName($context) : string + { + $parts = explode('.', $context); + + if (count($parts) < 2) + { + return ''; + } + + array_shift($parts); + + return ucfirst(array_shift($parts)); + } + /** * Returns an array of possible conditions for the component. * @@ -60,13 +81,20 @@ public function supportFunctionality($functionality, $context): bool { * * @since 4.0.0 */ - public static function getConditions(string $extension): array { - + public static function getConditions(string $extension): array + { return \defined('self::CONDITION_NAMES') ? self::CONDITION_NAMES : Workflow::CONDITION_NAMES; } - public function isWorkflowActive($context): bool { - + /** + * Check if the workflow is active + * + * @param string $context The context of the workflow + * + * @return bool + */ + public function isWorkflowActive($context): bool + { $parts = explode('.', $context); $config = ComponentHelper::getParams($parts[0]); @@ -75,9 +103,16 @@ public function isWorkflowActive($context): bool { return false; } + $modelName = $this->getModelName($context); + + if (empty($modelName)) + { + return false; + } + $component = $this->getMVCFactory(); $appName = Factory::getApplication()->getName(); - $model = $component->createModel($parts[1], $appName, ['ignore_request' => true]); + $model = $component->createModel($modelName, $appName, ['ignore_request' => true]); return $model instanceof WorkflowModelInterface; } diff --git a/plugins/workflow/publishing/publishing.php b/plugins/workflow/publishing/publishing.php index 321bf46a5870d..b8e8ba3513905 100644 --- a/plugins/workflow/publishing/publishing.php +++ b/plugins/workflow/publishing/publishing.php @@ -138,8 +138,11 @@ protected function enhanceItemForm(Form $form, $data) $parts = explode('.', $context); - $table = $this->app->bootComponent($parts[0]) - ->getMVCFactory()->createModel($parts[1], $this->app->getName(), ['ignore_request' => true]) + $component = $this->app->bootComponent($parts[0]); + + $modelName = $component->getModelName($context); + + $table = $component->getMVCFactory()->createModel($modelName, $this->app->getName(), ['ignore_request' => true]) ->getTable(); $form->setFieldAttribute($table->getColumnAlias('published'), 'disabled', 'true'); @@ -217,7 +220,9 @@ public function onWorkflowAfterTransition($context, $pks, $transition) 'event_before_change_state' => 'onWorkflowBeforeChangeState' ]; - $model = $component->getMVCFactory()->createModel($parts[1], $this->app->getName(), $options); + $modelName = $component->getModelName($context); + + $model = $component->getMVCFactory()->createModel($modelName, $this->app->getName(), $options); return $model->publish($pks, $value); } @@ -305,12 +310,14 @@ protected function isSupported($context) $component = $this->app->bootComponent($parts[0]); - if (!$component instanceof WorkflowServiceInterface || !$component->supportFunctionality($this->supportname, $context)) + if (!$component instanceof WorkflowServiceInterface || !$component->isWorkflowActive($context) || !$component->supportFunctionality($this->supportname, $context)) { return false; } - $model = $component->getMVCFactory()->createModel($parts[1], $this->app->getName(), ['ignore_request' => true]); + $modelName = $component->getModelName($context); + + $model = $component->getMVCFactory()->createModel($modelName, $this->app->getName(), ['ignore_request' => true]); if (!$model instanceof DatabaseModelInterface || !method_exists($model, 'publish')) {