Skip to content

Commit

Permalink
Workflow v3 transitions (joomla#61)
Browse files Browse the repository at this point in the history
* Remove condition from workflow component

* Load Workflow plugins on transition generation

* First commit for the publishing plugin

* Prevent saving of publishing state if workflow + plugin is active and the function is supported

* Only enhance transition form, if plugin is supported

* Add options field for transition plugins
Fix support check for workflow publishing plugin

* Set transition default values when creating a new workflow

* Make publishing plugin support name generic

* Allow to kill transition execution

* Add missing variable assignment to kill transitions

* Prevent state change on publish events

* Implement finished version of the publishing plugin which now changes states of items
Fix wrong contexts

* Update the workflow model interface to respect all methods
Secure controller execution for runTransition

* Implement frontend transition with the new plugin method
  • Loading branch information
bembelimen authored Apr 21, 2020
1 parent 479e4d7 commit 12ca6b2
Show file tree
Hide file tree
Showing 24 changed files with 637 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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`),
Expand All @@ -114,18 +115,18 @@ 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
--

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);

--
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ protected function prepareTable($table)
*/
public function publish(&$pks, $value = 1)
{
$this->importWorkflowPlugins();
$this->workflowBeforeStageChange();

return parent::publish($pks, $value);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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'))
Expand Down Expand Up @@ -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)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand Down Expand Up @@ -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.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"}'
]
];

Expand Down Expand Up @@ -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();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -51,6 +54,8 @@
</div>
<?php echo HTMLHelper::_('uitab.endTab'); ?>

<?php echo LayoutHelper::render('joomla.edit.params', $this); ?>

<?php echo HTMLHelper::_('uitab.addTab', 'myTab', 'permissions', Text::_('COM_WORKFLOW_RULES_TAB')); ?>
<fieldset id="fieldset-rules" class="options-form">
<legend><?php echo Text::_('COM_WORKFLOW_RULES_TAB'); ?></legend>
Expand Down
12 changes: 12 additions & 0 deletions administrator/language/en-GB/plg_workflow_publishing.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
; 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"
PLG_WORKFLOW_PUBLISHING_CHANGE_STATE_NOT_ALLOWED="You're not allowed to change the publishing state of this item. Please use a workflow transition."
7 changes: 7 additions & 0 deletions administrator/language/en-GB/plg_workflow_publishing.sys.ini
Original file line number Diff line number Diff line change
@@ -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"
17 changes: 11 additions & 6 deletions components/com_content/forms/article.xml
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,17 @@
/>

<field
name="transition"
type="transition"
extension="com_content"
addfieldprefix="Joomla\Component\Workflow\Administrator\Field"
label="COM_CONTENT_STATE"
>
name="state"
type="list"
label="JSTATUS"
class="custom-select-color-state"
size="1"
default="1"
>
<option value="1">JPUBLISHED</option>
<option value="0">JUNPUBLISHED</option>
<option value="2">JARCHIVED</option>
<option value="-2">JTRASHED</option>
</field>

<field
Expand Down
6 changes: 3 additions & 3 deletions components/com_content/tmpl/form/edit.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@
<?php echo LayoutHelper::render('joomla.edit.params', $this); ?>

<?php echo HTMLHelper::_('uitab.addTab', $this->tab_name, 'publishing', Text::_('COM_CONTENT_PUBLISHING')); ?>

<?php echo $this->form->renderField('transition'); ?>
<?php echo $this->form->renderField('state'); ?>
<?php echo $this->form->renderField('catid'); ?>
<?php echo $this->form->renderField('tags'); ?>
<?php echo $this->form->renderField('note'); ?>
Expand All @@ -108,9 +111,6 @@
<?php if ($params->get('show_publishing_options', 1) == 1) : ?>
<?php echo $this->form->renderField('created_by_alias'); ?>
<?php endif; ?>
<?php if ((int) $this->item->id > 0) : ?>
<?php echo $this->form->renderField('transition'); ?>
<?php endif; ?>
<?php if ($this->item->params->get('access-change')) : ?>
<?php echo $this->form->renderField('featured'); ?>
<?php if ($params->get('show_publishing_options', 1) == 1) : ?>
Expand Down
11 changes: 6 additions & 5 deletions installation/sql/mysql/base.sql
Original file line number Diff line number Diff line change
Expand Up @@ -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`),
Expand All @@ -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);
11 changes: 6 additions & 5 deletions installation/sql/postgresql/base.sql
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand All @@ -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);
10 changes: 10 additions & 0 deletions libraries/src/MVC/Controller/AdminController.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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');

Expand All @@ -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);
Expand Down
Loading

0 comments on commit 12ca6b2

Please sign in to comment.