From 182d41046402bf1c267d1c8d036b06bbae41416e Mon Sep 17 00:00:00 2001 From: YatharthVyas Date: Thu, 22 Jul 2021 23:51:36 +0530 Subject: [PATCH 01/65] filter workflow associations --- administrator/components/com_content/src/Model/ArticlesModel.php | 1 + 1 file changed, 1 insertion(+) diff --git a/administrator/components/com_content/src/Model/ArticlesModel.php b/administrator/components/com_content/src/Model/ArticlesModel.php index e9b8e02a02a..de20a22ff6e 100644 --- a/administrator/components/com_content/src/Model/ArticlesModel.php +++ b/administrator/components/com_content/src/Model/ArticlesModel.php @@ -301,6 +301,7 @@ protected function getListQuery() ->join('LEFT', $db->quoteName('#__categories', 'parent'), $db->quoteName('parent.id') . ' = ' . $db->quoteName('c.parent_id')) ->join('LEFT', $db->quoteName('#__users', 'ua'), $db->quoteName('ua.id') . ' = ' . $db->quoteName('a.created_by')) ->join('INNER', $db->quoteName('#__workflow_associations', 'wa'), $db->quoteName('wa.item_id') . ' = ' . $db->quoteName('a.id')) + ->where($db->quoteName('wa.extension') . ' = "com_content.article"') ->join('INNER', $db->quoteName('#__workflow_stages', 'ws'), $db->quoteName('ws.id') . ' = ' . $db->quoteName('wa.stage_id')) ->join('INNER', $db->quoteName('#__workflows', 'w'), $db->quoteName('w.id') . ' = ' . $db->quoteName('ws.workflow_id')); From 07e59927d50405f39f7d156df913d210557663a9 Mon Sep 17 00:00:00 2001 From: YatharthVyas Date: Thu, 22 Jul 2021 23:52:04 +0530 Subject: [PATCH 02/65] add module workflow menu tab --- administrator/components/com_menus/presets/default.xml | 8 ++++++++ administrator/components/com_menus/presets/system.xml | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/administrator/components/com_menus/presets/default.xml b/administrator/components/com_menus/presets/default.xml index e68f878989d..707f009bd0f 100644 --- a/administrator/components/com_menus/presets/default.xml +++ b/administrator/components/com_menus/presets/default.xml @@ -99,6 +99,14 @@ link="index.php?option=com_modules&view=modules&client_id=1" quicktask="index.php?option=com_modules&view=select&client_id=1" /> + + + + Date: Thu, 22 Jul 2021 23:52:20 +0530 Subject: [PATCH 03/65] language constants --- administrator/language/en-GB/com_modules.ini | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/administrator/language/en-GB/com_modules.ini b/administrator/language/en-GB/com_modules.ini index 0958eb86ac8..f90beb48302 100644 --- a/administrator/language/en-GB/com_modules.ini +++ b/administrator/language/en-GB/com_modules.ini @@ -21,6 +21,7 @@ COM_MODULES_BATCH_TIP="If choosing to copy a module, any other actions selected COM_MODULES_CHANGE_POSITION_BUTTON="Select" COM_MODULES_CHANGE_POSITION_TITLE="Change" COM_MODULES_COLLAPSE="Collapse" +COM_MODULES_CONFIG_INTEGRATION_SETTINGS_DESC="These settings determine how the Modules Component will integrate with other extensions." COM_MODULES_CONFIGURATION="Module: Options" COM_MODULES_CUSTOM_OUTPUT="Custom Output" COM_MODULES_CUSTOM_POSITION="Active Positions" @@ -87,6 +88,7 @@ COM_MODULES_MENU_ITEM_ALIAS="Alias" COM_MODULES_MENU_ITEM_HEADING="Heading" COM_MODULES_MENU_ITEM_SEPARATOR="Separator" COM_MODULES_MENU_ITEM_URL="URL" +COM_MODULES_MENU_WORKFLOW="Modules Workflows" COM_MODULES_MODULE="Module" COM_MODULES_MODULE_ASSIGN="Module Assignment" COM_MODULES_MODULE_DESCRIPTION="Module Description" @@ -190,6 +192,10 @@ COM_MODULES_SUBITEMS="Sub-items" COM_MODULES_TABLE_CAPTION="Table of Modules" COM_MODULES_TYPE_CHOOSE="Select a Module Type" COM_MODULES_TYPE_OR_SELECT_POSITION="Type or Select a Position" +COM_MODULES_WORKFLOW="Workflow" +COM_MODULES_WORKFLOW_NOT_FOUND="No default workflow available, please define one or contact an administrator." +COM_MODULES_WORKFLOW_TRANSITION_NOT_ALLOWED="You're not allowed to execute this transition" +COM_MODULES_WORKFLOWS="Workflows" COM_MODULES_XML_DESCRIPTION="Component for module management in the Administrator Backend." ; Alternate language strings for the rules form field From 964805b731cb7eb43e6fca7c1c89059659530abc Mon Sep 17 00:00:00 2001 From: YatharthVyas Date: Thu, 22 Jul 2021 23:52:47 +0530 Subject: [PATCH 04/65] modules access perms xml --- .../components/com_modules/access.xml | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/administrator/components/com_modules/access.xml b/administrator/components/com_modules/access.xml index f8bfed5ca83..9797341f947 100644 --- a/administrator/components/com_modules/access.xml +++ b/administrator/components/com_modules/access.xml @@ -7,6 +7,8 @@ + +
@@ -15,4 +17,23 @@
+
+ + + + + + +
+
+ + + + +
+
+ + + +
\ No newline at end of file From 833b07fd009aa19071be6f390f9ed54c765f897a Mon Sep 17 00:00:00 2001 From: YatharthVyas Date: Thu, 22 Jul 2021 23:53:06 +0530 Subject: [PATCH 05/65] show integrations tag in options --- .../components/com_modules/config.xml | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/administrator/components/com_modules/config.xml b/administrator/components/com_modules/config.xml index 2cb76164c13..96d9044bb15 100644 --- a/administrator/components/com_modules/config.xml +++ b/administrator/components/com_modules/config.xml @@ -52,4 +52,26 @@ section="component" /> + +
+
+ + + + +
+
From a9b75c0c857ea886f02fb343b4d5d6f0eaf89f0e Mon Sep 17 00:00:00 2001 From: YatharthVyas Date: Thu, 22 Jul 2021 23:53:49 +0530 Subject: [PATCH 06/65] filter by stage --- .../components/com_modules/forms/filter_modules.xml | 10 ++++++++++ .../com_modules/forms/filter_modulesadmin.xml | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/administrator/components/com_modules/forms/filter_modules.xml b/administrator/components/com_modules/forms/filter_modules.xml index 6adc9ec4377..e60a68da459 100644 --- a/administrator/components/com_modules/forms/filter_modules.xml +++ b/administrator/components/com_modules/forms/filter_modules.xml @@ -58,6 +58,16 @@ + + + + + + Date: Thu, 22 Jul 2021 23:54:18 +0530 Subject: [PATCH 07/65] show workflows field in a new tab in com_modules --- .../components/com_modules/forms/module.xml | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/administrator/components/com_modules/forms/module.xml b/administrator/components/com_modules/forms/module.xml index f25e8adde46..836b0122034 100644 --- a/administrator/components/com_modules/forms/module.xml +++ b/administrator/components/com_modules/forms/module.xml @@ -155,4 +155,25 @@ validate="rules" /> + + +
+ +
+
From 07fcb40390c793b6ae90f4ac76cfc04ba117107d Mon Sep 17 00:00:00 2001 From: YatharthVyas Date: Thu, 22 Jul 2021 23:55:01 +0530 Subject: [PATCH 08/65] functions used by workflow plugins --- .../src/Extension/ModulesComponent.php | 56 ++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/administrator/components/com_modules/src/Extension/ModulesComponent.php b/administrator/components/com_modules/src/Extension/ModulesComponent.php index 167c8b8ff60..5941a144180 100644 --- a/administrator/components/com_modules/src/Extension/ModulesComponent.php +++ b/administrator/components/com_modules/src/Extension/ModulesComponent.php @@ -11,9 +11,13 @@ \defined('JPATH_PLATFORM') or die; +use Joomla\CMS\Factory; use Joomla\CMS\Extension\BootableExtensionInterface; use Joomla\CMS\Extension\MVCComponent; use Joomla\CMS\HTML\HTMLRegistryAwareTrait; +use Joomla\CMS\Language\Text; +use Joomla\CMS\Workflow\WorkflowServiceInterface; +use Joomla\CMS\Workflow\WorkflowServiceTrait; use Joomla\Component\Modules\Administrator\Service\HTML\Modules; use Psr\Container\ContainerInterface; @@ -22,9 +26,11 @@ * * @since 4.0.0 */ -class ModulesComponent extends MVCComponent implements BootableExtensionInterface +class ModulesComponent extends MVCComponent implements BootableExtensionInterface, +WorkflowServiceInterface { use HTMLRegistryAwareTrait; + use WorkflowServiceTrait; /** * Booting the extension. This is the function to set up the environment of the extension like @@ -43,4 +49,52 @@ public function boot(ContainerInterface $container) { $this->getRegistry()->register('modules', new Modules); } + + /** + * Returns valid contexts + * + * @return array + * + * @since __DEPLOY_VERSION__ + */ + public function getWorkflowContexts(): array + { + Factory::getLanguage()->load('com_modules', JPATH_ADMINISTRATOR); + + $contexts = array( + 'com_modules.module' => Text::_('COM_MODULES') + ); + + return $contexts; + } + + /** + * Returns a table name for the state association + * + * @param string $section An optional section to separate different areas in the component + * + * @return string + * + * @since __DEPLOY_VERSION__ + */ + public function getWorkflowTableBySection(?string $section = null): string + { + return '#__modules'; + } + + /** + * Method to filter transitions by given id of state. + * + * @param array $transitions The Transitions to filter + * @param int $pk Id of the state + * + * @return array + * + * @since __DEPLOY_VERSION__ + */ + public function filterTransitions(array $transitions, int $pk): array + { + return ModuleHelper::filterTransitions($transitions, $pk); + } + } From 688e0f3512f1a42edd67c77c5160e6d2c00ce768 Mon Sep 17 00:00:00 2001 From: YatharthVyas Date: Thu, 22 Jul 2021 23:58:57 +0530 Subject: [PATCH 09/65] workflows in modules helper --- .../com_modules/src/Helper/ModulesHelper.php | 127 ++++++++++++++++++ 1 file changed, 127 insertions(+) diff --git a/administrator/components/com_modules/src/Helper/ModulesHelper.php b/administrator/components/com_modules/src/Helper/ModulesHelper.php index 6657d2f1b98..ab6a6fc60aa 100644 --- a/administrator/components/com_modules/src/Helper/ModulesHelper.php +++ b/administrator/components/com_modules/src/Helper/ModulesHelper.php @@ -323,4 +323,131 @@ public static function createOptionGroup($label = '', $options = array()) return $group; } + + /** + * Method to filter transitions by given id of state + * + * @param array $transitions Array of transitions + * @param int $pk Id of state + * @param int $workflowId Id of the workflow + * + * @return array + * + * @since __DEPLOY_VERSION__ + */ + public static function filterTransitions(array $transitions, int $pk, int $workflowId = 0): array + { + return array_values( + array_filter( + $transitions, + function ($var) use ($pk, $workflowId) + { + return in_array($var['from_stage_id'], [-1, $pk]) && $workflowId == $var['workflow_id']; + } + ) + ); + } + + /** + * Prepares a form + * + * @param Form $form The form to change + * @param array|object $data The form data + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public static function onPrepareForm(Form $form, $data) + { + $db = Factory::getDbo(); + + $data = (array) $data; + + // Make workflows translatable + Factory::getLanguage()->load('com_workflow', JPATH_ADMINISTRATOR); + + $form->setFieldAttribute('workflow_id', 'default', 'inherit'); + + $query = $db->getQuery(true); + + $query->select($db->quoteName('title')) + ->from($db->quoteName('#__workflows')) + ->where( + [ + $db->quoteName('default') . ' = 1', + $db->quoteName('published') . ' = 1', + ] + ); + + $defaulttitle = $db->setQuery($query)->loadResult(); + + $option = Text::_('COM_WORKFLOW_INHERIT_WORKFLOW_NEW'); + + if (!empty($data['id'])) + { + $category = new Category($db); + + $categories = $category->getPath((int) $data['id']); + + // Remove the current category, because we search for inheritance from parent. + array_pop($categories); + + $option = Text::sprintf('COM_WORKFLOW_INHERIT_WORKFLOW', Text::_($defaulttitle)); + + if (!empty($categories)) + { + $categories = array_reverse($categories); + + $query = $db->getQuery(true); + + $query->select($db->quoteName('title')) + ->from($db->quoteName('#__workflows')) + ->where( + [ + $db->quoteName('id') . ' = :workflowId', + $db->quoteName('published') . ' = 1', + ] + ) + ->bind(':workflowId', $workflow_id, ParameterType::INTEGER); + + $db->setQuery($query); + + foreach ($categories as $cat) + { + $cat->params = new Registry($cat->params); + + $workflow_id = $cat->params->get('workflow_id'); + + if ($workflow_id == 'inherit') + { + continue; + } + elseif ($workflow_id == 'use_default') + { + break; + } + elseif ($workflow_id = (int) $workflow_id) + { + $title = $db->loadResult(); + + if (!is_null($title)) + { + $option = Text::sprintf('COM_WORKFLOW_INHERIT_WORKFLOW', Text::_($title)); + + break; + } + } + } + } + } + + $field = $form->getField('workflow_id', 'params'); + + $field->addOption($option, ['value' => 'inherit']); + + $field->addOption(Text::sprintf('COM_WORKFLOW_USE_DEFAULT_WORKFLOW', Text::_($defaulttitle)), ['value' => 'use_default']); + + $field->addOption('- ' . Text::_('COM_MODULE_WORKFLOWS') . ' -', ['disabled' => 'true']); + } } From c353e355ef4f7ce0d5638a3047049119617eacf6 Mon Sep 17 00:00:00 2001 From: YatharthVyas Date: Fri, 23 Jul 2021 00:00:20 +0530 Subject: [PATCH 10/65] call workflow events on save and delete --- .../com_modules/src/Model/ModuleModel.php | 45 ++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/administrator/components/com_modules/src/Model/ModuleModel.php b/administrator/components/com_modules/src/Model/ModuleModel.php index f0634bbd374..63be9b81595 100644 --- a/administrator/components/com_modules/src/Model/ModuleModel.php +++ b/administrator/components/com_modules/src/Model/ModuleModel.php @@ -19,10 +19,13 @@ use Joomla\CMS\Helper\ModuleHelper; use Joomla\CMS\Language\Text; use Joomla\CMS\MVC\Model\AdminModel; +use Joomla\CMS\MVC\Model\WorkflowBehaviorTrait; +use Joomla\CMS\MVC\Model\WorkflowModelInterface; use Joomla\CMS\Object\CMSObject; use Joomla\CMS\Plugin\PluginHelper; use Joomla\CMS\Router\Route; use Joomla\CMS\Table\Table; +use Joomla\CMS\Workflow\Workflow; use Joomla\Database\ParameterType; use Joomla\Registry\Registry; use Joomla\String\StringHelper; @@ -33,8 +36,10 @@ * * @since 1.6 */ -class ModuleModel extends AdminModel +class ModuleModel extends AdminModel implements WorkflowModelInterface { + use WorkflowBehaviorTrait; + /** * The type alias for this content type. * @@ -100,6 +105,8 @@ public function __construct($config = array()) ); parent::__construct($config); + + $this->setUpWorkflow('com_modules.module'); } /** @@ -389,6 +396,8 @@ public function delete(&$pks) // Clear module cache parent::cleanCache($table->module); + + $this->workflow->deleteAssociation($pks); } else { @@ -840,6 +849,17 @@ public function getTable($type = 'Module', $prefix = 'JTable', $config = array() */ protected function prepareTable($table) { + // Set the publish date to now + if ($table->state == Workflow::CONDITION_PUBLISHED && (int) $table->publish_up == 0) + { + $table->publish_up = Factory::getDate()->toSql(); + } + + if ($table->state == Workflow::CONDITION_PUBLISHED && intval($table->publish_down) == 0) + { + $table->publish_down = null; + } + $table->title = htmlspecialchars_decode($table->title, ENT_QUOTES); $table->position = trim($table->position); } @@ -900,6 +920,8 @@ protected function preprocessForm(Form $form, $data, $group = 'content') Form::addFormPath(JPATH_ADMINISTRATOR . '/components/com_modules/models/forms'); $form->loadFile('advanced', false); + $this->workflowPreprocessForm($form, $data); + // Trigger the default form events. parent::preprocessForm($form, $data, $group); } @@ -1005,6 +1027,8 @@ public function save($data) return false; } + $this->workflowBeforeSave(); + // Process the menu link mappings. $assignment = $data['assignment'] ?? 0; @@ -1129,6 +1153,8 @@ public function save($data) // Clean module cache parent::cleanCache($table->module); + $this->workflowAfterSave($data); + return true; } @@ -1163,4 +1189,21 @@ protected function cleanCache($group = null, $clientId = 0) { parent::cleanCache('com_modules'); } + + /** + * Method to change the published state of one or more records. + * + * @param array &$pks A list of the primary keys to change. + * @param integer $value The value of the published state. + * + * @return boolean True on success. + * + * @since __DEPLOY_VERSION__ + */ + public function publish(&$pks, $value = 1) + { + $this->workflowBeforeStageChange(); + + return parent::publish($pks, $value); + } } From 42c5a02cebecf24aa0817e7fb1f474a1a78e4b03 Mon Sep 17 00:00:00 2001 From: YatharthVyas Date: Fri, 23 Jul 2021 00:01:42 +0530 Subject: [PATCH 11/65] include workflows in modules query --- .../com_modules/src/Model/ModulesModel.php | 169 +++++++++++++++++- 1 file changed, 168 insertions(+), 1 deletion(-) diff --git a/administrator/components/com_modules/src/Model/ModulesModel.php b/administrator/components/com_modules/src/Model/ModulesModel.php index aa337ba202a..87e4a44bbb1 100644 --- a/administrator/components/com_modules/src/Model/ModulesModel.php +++ b/administrator/components/com_modules/src/Model/ModulesModel.php @@ -229,6 +229,37 @@ protected function _getList($query, $limitstart = 0, $limit = 0) return $result; } + /** + * Get the filter form + * + * @param array $data data + * @param boolean $loadData load current data + * + * @return Form|null The \JForm object or null if the form can't be found + * + * @since __DEPLOY_VERSION__ + */ + public function getFilterForm($data = array(), $loadData = true) + { + $form = parent::getFilterForm($data, $loadData); + + $params = ComponentHelper::getParams('com_modules'); + + if (!$params->get('workflow_enabled')) + { + $form->removeField('stage', 'filter'); + } + else + { + $ordering = $form->getField('fullordering', 'list'); + + $ordering->addOption('JSTAGE_ASC', ['value' => 'ws.title ASC']); + $ordering->addOption('JSTAGE_DESC', ['value' => 'ws.title DESC']); + } + + return $form; + } + /** * Translate a list of objects * @@ -278,6 +309,7 @@ protected function getListQuery() // Create a new query object. $db = $this->getDbo(); $query = $db->getQuery(true); + $params = ComponentHelper::getParams('com_modules'); // Select the required fields. $query->select( @@ -312,6 +344,24 @@ protected function getListQuery() $query->select($db->quoteName('e.name', 'name')) ->join('LEFT', $db->quoteName('#__extensions', 'e') . ' ON ' . $db->quoteName('e.element') . ' = ' . $db->quoteName('a.module')); + // Join over the workflows association + $query->select($db->quoteName('wa.stage_id', 'stage_id')) + ->join('INNER', $db->quoteName('#__workflow_associations', 'wa'), $db->quoteName('wa.item_id') . ' = ' . $db->quoteName('a.id')) + ->where($db->quoteName('wa.extension') . ' = "com_modules.module"'); + + // Join over the workflows stage + $query->select( + [ + $db->quoteName('ws.title', 'stage_title'), + $db->quoteName('ws.workflow_id', 'workflow_id') + ] + ) + ->join('INNER', $db->quoteName('#__workflow_stages', 'ws'), $db->quoteName('ws.id') . ' = ' . $db->quoteName('wa.stage_id')); + + // Join over the workflows + $query->select($db->quoteName('w.title', 'workflow_title')) + ->join('INNER', $db->quoteName('#__workflows', 'w'), $db->quoteName('w.id') . ' = ' . $db->quoteName('ws.workflow_id')); + // Group (careful with PostgreSQL) $query->group( 'a.id, a.title, a.note, a.position, a.module, a.language, a.checked_out, ' @@ -344,6 +394,16 @@ protected function getListQuery() ->bind(':access', $access, ParameterType::INTEGER); } + // Filter by stage + $workflowStage = (string) $this->getState('filter.stage'); + + if ($params->get('workflow_enabled') && is_numeric($workflowStage)) + { + $workflowStage = (int) $workflowStage; + $query->where($db->quoteName('wa.stage_id') . ' = :stage') + ->bind(':stage', $workflowStage, ParameterType::INTEGER); + } + // Filter by published state. $state = $this->getState('filter.state'); @@ -353,7 +413,7 @@ protected function getListQuery() $query->where($db->quoteName('a.published') . ' = :state') ->bind(':state', $state, ParameterType::INTEGER); } - elseif ($state === '') + elseif (!is_numeric($workflowStage)) { $query->whereIn($db->quoteName('a.published'), [0, 1]); } @@ -461,6 +521,113 @@ protected function getListQuery() return $query; } + /** + * Method to get all transitions at once for all articles + * + * @return array|boolean + * + * @since __DEPLOY_VERSION__ + */ + public function getTransitions() + { + // Get a storage key. + $store = $this->getStoreId('getTransitions'); + + // Try to load the data from internal storage. + if (isset($this->cache[$store])) + { + return $this->cache[$store]; + } + + $db = $this->getDbo(); + $user = Factory::getUser(); + + $items = $this->getItems(); + + if ($items === false) + { + return false; + } + + $stage_ids = ArrayHelper::getColumn($items, 'stage_id'); + $stage_ids = ArrayHelper::toInteger($stage_ids); + $stage_ids = array_values(array_unique(array_filter($stage_ids))); + + $workflow_ids = ArrayHelper::getColumn($items, 'workflow_id'); + $workflow_ids = ArrayHelper::toInteger($workflow_ids); + $workflow_ids = array_values(array_unique(array_filter($workflow_ids))); + + $this->cache[$store] = array(); + + try + { + if (count($stage_ids) || count($workflow_ids)) + { + Factory::getLanguage()->load('com_workflow', JPATH_ADMINISTRATOR); + + $query = $db->getQuery(true); + + $query ->select( + [ + $db->quoteName('t.id', 'value'), + $db->quoteName('t.title', 'text'), + $db->quoteName('t.from_stage_id'), + $db->quoteName('t.to_stage_id'), + $db->quoteName('s.id', 'stage_id'), + $db->quoteName('s.title', 'stage_title'), + $db->quoteName('t.workflow_id'), + ] + ) + ->from($db->quoteName('#__workflow_transitions', 't')) + ->innerJoin( + $db->quoteName('#__workflow_stages', 's'), + $db->quoteName('t.to_stage_id') . ' = ' . $db->quoteName('s.id') + ) + ->where( + [ + $db->quoteName('t.published') . ' = 1', + $db->quoteName('s.published') . ' = 1', + ] + ) + ->order($db->quoteName('t.ordering')); + + $where = []; + + if (count($stage_ids)) + { + $where[] = $db->quoteName('t.from_stage_id') . ' IN (' . implode(',', $query->bindArray($stage_ids)) . ')'; + } + + if (count($workflow_ids)) + { + $where[] = '(' . $db->quoteName('t.from_stage_id') . ' = -1 AND ' . $db->quoteName('t.workflow_id') . ' IN (' . implode(',', $query->bindArray($workflow_ids)) . '))'; + } + + $query->where('((' . implode(') OR (', $where) . '))'); + + $transitions = $db->setQuery($query)->loadAssocList(); + + foreach ($transitions as $key => $transition) + { + if (!$user->authorise('core.execute.transition', 'com_modules.transition.' . (int) $transition['value'])) + { + unset($transitions[$key]); + } + } + + $this->cache[$store] = $transitions; + } + } + catch (\RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + return $this->cache[$store]; + } + /** * Manipulate the query to be used to evaluate if this is an Empty State to provide specific conditions for this extension. * From 4743efb4d7e29960fbaaa41e3684fe9aee729f29 Mon Sep 17 00:00:00 2001 From: YatharthVyas Date: Fri, 23 Jul 2021 00:02:32 +0530 Subject: [PATCH 12/65] call workflow plugin --- .../components/com_modules/src/View/Modules/HtmlView.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/administrator/components/com_modules/src/View/Modules/HtmlView.php b/administrator/components/com_modules/src/View/Modules/HtmlView.php index 9a30391068e..e8cbf202ee5 100644 --- a/administrator/components/com_modules/src/View/Modules/HtmlView.php +++ b/administrator/components/com_modules/src/View/Modules/HtmlView.php @@ -12,12 +12,14 @@ \defined('_JEXEC') or die; use Joomla\CMS\Factory; +use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Helper\ContentHelper; use Joomla\CMS\Helper\ModuleHelper; use Joomla\CMS\Language\Multilanguage; use Joomla\CMS\Language\Text; use Joomla\CMS\MVC\View\GenericDataException; use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView; +use Joomla\CMS\Plugin\PluginHelper; use Joomla\CMS\Toolbar\Toolbar; use Joomla\CMS\Toolbar\ToolbarHelper; @@ -97,6 +99,13 @@ public function display($tpl = null) $this->setLayout('emptystate'); } + if (ComponentHelper::getParams('com_modules')->get('workflow_enabled')) + { + PluginHelper::importPlugin('workflow'); + + $this->transitions = $this->get('Transitions'); + } + /** * The code below make sure the remembered position will be available from filter dropdown even if there are no * modules available for this position. This will make the UI less confusing for users in case there is only one From fe456fb77546a3a4114e02adbb2b7a8e01e93f8d Mon Sep 17 00:00:00 2001 From: YatharthVyas Date: Fri, 23 Jul 2021 00:03:05 +0530 Subject: [PATCH 13/65] display workflow field in batch_body --- .../com_modules/tmpl/modules/default_batch_body.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/administrator/components/com_modules/tmpl/modules/default_batch_body.php b/administrator/components/com_modules/tmpl/modules/default_batch_body.php index 2a52e9c45f6..ee7764d870a 100644 --- a/administrator/components/com_modules/tmpl/modules/default_batch_body.php +++ b/administrator/components/com_modules/tmpl/modules/default_batch_body.php @@ -9,6 +9,8 @@ defined('_JEXEC') or die; +use Joomla\CMS\Component\ComponentHelper; +use Joomla\CMS\Factory; use Joomla\CMS\Helper\ModuleHelper; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; @@ -17,6 +19,10 @@ $clientId = $this->state->get('client_id'); +$params = ComponentHelper::getParams('com_content'); + +$user = Factory::getUser(); + // Show only Module Positions of published Templates $published = 1; $positions = HTMLHelper::_('modules.positions', $clientId, $published); @@ -59,6 +65,13 @@ + authorise('core.admin', 'com_modules') && $params->get('workflow_enabled')) : ?> +
+
+ 'com_modules']); ?> +
+
+
= 0) : ?> From 6ef70a3b3d572c1a00e5633f194708e298f2bcfa Mon Sep 17 00:00:00 2001 From: YatharthVyas Date: Fri, 23 Jul 2021 00:17:46 +0530 Subject: [PATCH 14/65] fix the language constant for sidebar --- administrator/components/com_menus/presets/default.xml | 2 +- administrator/components/com_menus/presets/system.xml | 2 +- administrator/language/en-GB/com_modules.ini | 1 - administrator/language/en-GB/mod_menu.ini | 1 + 4 files changed, 3 insertions(+), 3 deletions(-) diff --git a/administrator/components/com_menus/presets/default.xml b/administrator/components/com_menus/presets/default.xml index 707f009bd0f..c5d29977ff6 100644 --- a/administrator/components/com_menus/presets/default.xml +++ b/administrator/components/com_menus/presets/default.xml @@ -101,7 +101,7 @@ /> Date: Fri, 23 Jul 2021 16:35:13 +0530 Subject: [PATCH 15/65] display workflow in all modules view --- .../com_modules/tmpl/modules/default.php | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/administrator/components/com_modules/tmpl/modules/default.php b/administrator/components/com_modules/tmpl/modules/default.php index bd95ae2d29c..ccbcdf7eeb6 100644 --- a/administrator/components/com_modules/tmpl/modules/default.php +++ b/administrator/components/com_modules/tmpl/modules/default.php @@ -9,6 +9,9 @@ defined('_JEXEC') or die; +use Joomla\CMS\Button\PublishedButton; +use Joomla\CMS\Button\TransitionButton; +use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Factory; use Joomla\CMS\Helper\ModuleHelper; use Joomla\CMS\HTML\HTMLHelper; @@ -17,6 +20,8 @@ use Joomla\CMS\Layout\LayoutHelper; use Joomla\CMS\Router\Route; use Joomla\CMS\Session\Session; +use Joomla\Component\Content\Administrator\Helper\ContentHelper; +use Joomla\Utilities\ArrayHelper; HTMLHelper::_('behavior.multiselect'); @@ -31,6 +36,38 @@ $saveOrderingUrl = 'index.php?option=com_modules&task=modules.saveOrderAjax&tmpl=component&' . Session::getFormToken() . '=1'; HTMLHelper::_('draggablelist.draggable'); } + +$workflow_enabled = ComponentHelper::getParams('com_modules')->get('workflow_enabled'); +$workflow_state = false; + +if ($workflow_enabled) : + +// @todo move the script to a file +$js = <<document->getWebAssetManager(); + +$wa->getRegistry()->addExtensionRegistryFile('com_workflow'); +$wa->useScript('com_workflow.admin-items-workflow-buttons') + ->addInlineScript($js, [], ['type' => 'module']); + +$workflow_state = Factory::getApplication()->bootComponent('com_content')->isFunctionalityUsed('core.state', 'com_content.article'); +$workflow_featured = Factory::getApplication()->bootComponent('com_content')->isFunctionalityUsed('core.featured', 'com_content.article'); + +endif; ?>
@@ -50,6 +87,11 @@ + + + + + @@ -91,6 +133,10 @@ $canEdit = $user->authorise('core.edit', 'com_modules.module.' . $item->id); $canCheckin = $user->authorise('core.manage', 'com_checkin') || $item->checked_out == $user->get('id')|| is_null($item->checked_out); $canChange = $user->authorise('core.edit.state', 'com_modules.module.' . $item->id) && $canCheckin; + $transitions = ContentHelper::filterTransitions($this->transitions, (int) $item->stage_id, (int) $item->workflow_id); + + $transition_ids = ArrayHelper::getColumn($transitions, 'value'); + $transition_ids = ArrayHelper::toInteger($transition_ids); ?> @@ -115,6 +161,32 @@ + + + $transitions, + 'title' => Text::_($item->stage_title), + 'tip_content' => Text::sprintf('JWORKFLOW', Text::_($item->workflow_title)), + 'id' => 'workflow-' . $item->id + ]; + + echo (new TransitionButton($options)) + ->render(0, $i); + ?> + + + 'modules.', + 'disabled' => $workflow_state || !$canChange, + 'id' => 'state-' . $item->id + ]; + + echo (new PublishedButton)->render((int) $item->state, $i, $options, $item->publish_up, $item->publish_down); + ?> + + enabled > 0) : ?> @@ -126,6 +198,7 @@ +
checked_out) : ?> @@ -209,6 +282,11 @@ $this->loadTemplate('batch_body') ); ?> + + + + + From 3c642db96cd9c6f12d8ea0758890a4436412c107 Mon Sep 17 00:00:00 2001 From: YatharthVyas Date: Fri, 23 Jul 2021 16:35:48 +0530 Subject: [PATCH 16/65] installation sql --- installation/sql/mysql/base.sql | 21 +++++++++++++++++---- installation/sql/postgresql/base.sql | 21 +++++++++++++++++---- 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/installation/sql/mysql/base.sql b/installation/sql/mysql/base.sql index 795e0b55b8b..0c64b6ca1f2 100644 --- a/installation/sql/mysql/base.sql +++ b/installation/sql/mysql/base.sql @@ -105,7 +105,12 @@ INSERT INTO `#__assets` (`id`, `parent_id`, `lft`, `rgt`, `level`, `name`, `titl (85, 18, 120, 121, 2, 'com_modules.module.108', 'Privacy Status', '{}'), (86, 18, 122, 123, 2, 'com_modules.module.96', 'Popular Articles', '{}'), (87, 18, 124, 125, 2, 'com_modules.module.97', 'Recently Added Articles', '{}'), -(88, 18, 126, 127, 2, 'com_modules.module.98', 'Logged-in Users', '{}'); +(88, 18, 126, 127, 2, 'com_modules.module.98', 'Logged-in Users', '{}'), +(89, 8, 128, 129, 2, 'com_modules.workflow.1', 'COM_WORKFLOW_BASIC_WORKFLOW', '{}'), +(90, 18, 130, 131, 3, 'com_modules.state.1', 'COM_WORKFLOW_BASIC_STAGE', '{}'), +(91, 18, 132, 133, 3, 'com_modules.transition.1', 'Publish', '{}'), +(92, 18, 134, 135, 3, 'com_modules.transition.2', 'Unpublish', '{}'), +(93, 18, 136, 137, 3, 'com_modules.transition.3', 'Trash', '{}'); -- -------------------------------------------------------- @@ -1077,7 +1082,8 @@ CREATE TABLE IF NOT EXISTS `#__workflows` ( -- INSERT INTO `#__workflows` (`id`, `asset_id`, `published`, `title`, `description`, `extension`, `default`, `ordering`, `created`, `created_by`, `modified`, `modified_by`) VALUES -(1, 56, 1, 'COM_WORKFLOW_BASIC_WORKFLOW', '', 'com_content.article', 1, 1, CURRENT_TIMESTAMP(), 42, CURRENT_TIMESTAMP(), 42); +(1, 56, 1, 'COM_WORKFLOW_BASIC_WORKFLOW', '', 'com_content.article', 1, 1, CURRENT_TIMESTAMP(), 42, CURRENT_TIMESTAMP(), 42), +(2, 89, 1, 'COM_WORKFLOW_BASIC_WORKFLOW', '', 'com_modules.module', 1, 1, CURRENT_TIMESTAMP(), 42, CURRENT_TIMESTAMP(), 42); -- -------------------------------------------------------- @@ -1126,7 +1132,8 @@ CREATE TABLE IF NOT EXISTS `#__workflow_stages` ( -- INSERT INTO `#__workflow_stages` (`id`, `asset_id`, `ordering`, `workflow_id`, `published`, `title`, `description`, `default`) VALUES -(1, 0, 1, 1, 1, 'COM_WORKFLOW_BASIC_STAGE', '', 1); +(1, 0, 1, 1, 1, 'COM_WORKFLOW_BASIC_STAGE', '', 1), +(2, 18, 1, 2, 1, 'COM_WORKFLOW_BASIC_STAGE', '', 1); -- -------------------------------------------------------- @@ -1167,4 +1174,10 @@ INSERT INTO `#__workflow_transitions` (`id`, `asset_id`, `published`, `ordering` (4, 61, 1, 4, 1, 'Archive', '', -1, 1, '{"publishing":"2"}'), (5, 62, 1, 5, 1, 'Feature', '', -1, 1, '{"featuring":"1"}'), (6, 63, 1, 6, 1, 'Unfeature', '', -1, 1, '{"featuring":"0"}'), -(7, 64, 1, 7, 1, 'Publish & Feature', '', -1, 1, '{"publishing":"1","featuring":"1"}'); +(7, 64, 1, 7, 1, 'Publish & Feature', '', -1, 1, '{"publishing":"1","featuring":"1"}'), +(8, 92, 1, 1, 2, 'Unpublish', '', -1, 1, '{"publishing":"0"}'), +(9, 91, 1, 2, 2, 'Publish', '', -1, 1, '{"publishing":"1"}'), +(10, 93, 1, 3, 2, 'Trash', '', -1, 1, '{"publishing":"-2"}'); + +INSERT INTO `#__workflow_associations` (`item_id`, `stage_id`, `extension`) +SELECT `id`, 2, 'com_modules.module' FROM `#__modules`; \ No newline at end of file diff --git a/installation/sql/postgresql/base.sql b/installation/sql/postgresql/base.sql index f50279c8447..a86b70cac04 100644 --- a/installation/sql/postgresql/base.sql +++ b/installation/sql/postgresql/base.sql @@ -111,7 +111,12 @@ INSERT INTO "#__assets" ("id", "parent_id", "lft", "rgt", "level", "name", "titl (85, 18, 120, 121, 2, 'com_modules.module.108', 'Privacy Status', '{}'), (86, 18, 122, 123, 2, 'com_modules.module.96', 'Popular Articles', '{}'), (87, 18, 124, 125, 2, 'com_modules.module.97', 'Recently Added Articles', '{}'), -(88, 18, 126, 127, 2, 'com_modules.module.98', 'Logged-in Users', '{}'); +(88, 18, 126, 127, 2, 'com_modules.module.98', 'Logged-in Users', '{}'), +(89, 8, 128, 129, 2, 'com_modules.workflow.1', 'COM_WORKFLOW_BASIC_WORKFLOW', '{}'), +(90, 18, 130, 131, 3, 'com_modules.state.1', 'COM_WORKFLOW_BASIC_STAGE', '{}'), +(91, 18, 132, 133, 3, 'com_modules.transition.1', 'Publish', '{}'), +(92, 18, 134, 135, 3, 'com_modules.transition.2', 'Unpublish', '{}'), +(93, 18, 136, 137, 3, 'com_modules.transition.3', 'Trash', '{}'); SELECT setval('#__assets_id_seq', 89, false); @@ -1099,7 +1104,8 @@ CREATE INDEX "#__workflows_idx_modified_by" ON "#__workflows" ("modified_by"); CREATE INDEX "#__workflows_idx_checked_out" ON "#__workflows" ("checked_out"); INSERT INTO "#__workflows" ("id", "asset_id", "published", "title", "description", "extension", "default", "ordering", "created", "created_by", "modified", "modified_by") VALUES -(1, 56, 1, 'COM_WORKFLOW_BASIC_WORKFLOW', '', 'com_content.article', 1, 1, CURRENT_TIMESTAMP, 42, CURRENT_TIMESTAMP, 42); +(1, 56, 1, 'COM_WORKFLOW_BASIC_WORKFLOW', '', 'com_content.article', 1, 1, CURRENT_TIMESTAMP, 42, CURRENT_TIMESTAMP, 42), +(2, 89, 1, 'COM_WORKFLOW_BASIC_WORKFLOW', '', 'com_modules.module', 1, 1, CURRENT_TIMESTAMP, 42, CURRENT_TIMESTAMP, 42); SELECT setval('#__workflows_id_seq', 2, false); @@ -1149,7 +1155,8 @@ CREATE INDEX "#__workflow_stages_idx_checked_out" ON "#__workflow_stages" ("chec -- INSERT INTO "#__workflow_stages" ("id", "asset_id", "ordering", "workflow_id", "published", "title", "description", "default") VALUES -(1, 57, 1, 1, 1, 'COM_WORKFLOW_BASIC_STAGE', '', 1); +(1, 57, 1, 1, 1, 'COM_WORKFLOW_BASIC_STAGE', '', 1), +(2, 90, 1, 2, 1, 'COM_WORKFLOW_BASIC_STAGE', '', 1); SELECT setval('#__workflow_stages_id_seq', 2, false); @@ -1186,6 +1193,12 @@ INSERT INTO "#__workflow_transitions" ("id", "asset_id", "published", "ordering" (4, 61, 1, 4, 1, 'Archive', '', -1, 1, '{"publishing":"2"}'), (5, 62, 1, 5, 1, 'Feature', '', -1, 1, '{"featuring":"1"}'), (6, 63, 1, 6, 1, 'Unfeature', '', -1, 1, '{"featuring":"0"}'), -(7, 64, 1, 7, 1, 'Publish & Feature', '', -1, 1, '{"publishing":"1","featuring":"1"}'); +(7, 64, 1, 7, 1, 'Publish & Feature', '', -1, 1, '{"publishing":"1","featuring":"1"}'), +(8, 92, 1, 1, 2, 'Unpublish', '', -1, 1, '{"publishing":"0"}'), +(9, 91, 1, 2, 2, 'Publish', '', -1, 1, '{"publishing":"1"}'), +(10, 93, 1, 3, 2, 'Trash', '', -1, 1, '{"publishing":"-2"}'); SELECT setval('#__workflow_transitions_id_seq', 8, false); + +INSERT INTO `#__workflow_associations` (`item_id`, `stage_id`, `extension`) +SELECT `id`, 2, 'com_modules.module' FROM `#__modules`; \ No newline at end of file From 3e974bc9fa228c1c5c132491039f56da25889d9c Mon Sep 17 00:00:00 2001 From: YatharthVyas Date: Sat, 24 Jul 2021 10:31:31 +0530 Subject: [PATCH 17/65] misc workflow bug fixes in modules view --- .../com_modules/tmpl/modules/default.php | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/administrator/components/com_modules/tmpl/modules/default.php b/administrator/components/com_modules/tmpl/modules/default.php index ccbcdf7eeb6..0975fbf93a3 100644 --- a/administrator/components/com_modules/tmpl/modules/default.php +++ b/administrator/components/com_modules/tmpl/modules/default.php @@ -64,8 +64,8 @@ $wa->useScript('com_workflow.admin-items-workflow-buttons') ->addInlineScript($js, [], ['type' => 'module']); -$workflow_state = Factory::getApplication()->bootComponent('com_content')->isFunctionalityUsed('core.state', 'com_content.article'); -$workflow_featured = Factory::getApplication()->bootComponent('com_content')->isFunctionalityUsed('core.featured', 'com_content.article'); +$workflow_state = Factory::getApplication()->bootComponent('com_content')->isFunctionalityUsed('core.state', 'com_modules.module'); +$workflow_featured = Factory::getApplication()->bootComponent('com_content')->isFunctionalityUsed('core.featured', 'com_modules.module'); endif; ?> @@ -133,10 +133,13 @@ $canEdit = $user->authorise('core.edit', 'com_modules.module.' . $item->id); $canCheckin = $user->authorise('core.manage', 'com_checkin') || $item->checked_out == $user->get('id')|| is_null($item->checked_out); $canChange = $user->authorise('core.edit.state', 'com_modules.module.' . $item->id) && $canCheckin; - $transitions = ContentHelper::filterTransitions($this->transitions, (int) $item->stage_id, (int) $item->workflow_id); + if ($workflow_enabled) + { + $transitions = ContentHelper::filterTransitions($this->transitions, (int) $item->stage_id, (int) $item->workflow_id); - $transition_ids = ArrayHelper::getColumn($transitions, 'value'); - $transition_ids = ArrayHelper::toInteger($transition_ids); + $transition_ids = ArrayHelper::getColumn($transitions, 'value'); + $transition_ids = ArrayHelper::toInteger($transition_ids); + } ?> @@ -162,13 +165,14 @@ - + $transitions, 'title' => Text::_($item->stage_title), 'tip_content' => Text::sprintf('JWORKFLOW', Text::_($item->workflow_title)), - 'id' => 'workflow-' . $item->id + 'id' => 'workflow-' . $item->id, + 'task' => 'modules.runTransition' ]; echo (new TransitionButton($options)) @@ -183,7 +187,7 @@ 'id' => 'state-' . $item->id ]; - echo (new PublishedButton)->render((int) $item->state, $i, $options, $item->publish_up, $item->publish_down); + echo (new PublishedButton)->render((int) $item->published, $i, $options, $item->publish_up, $item->publish_down); ?> From 656100326a33861c331bf72d1a9404cc05c9e908 Mon Sep 17 00:00:00 2001 From: YatharthVyas Date: Sat, 24 Jul 2021 10:52:22 +0530 Subject: [PATCH 18/65] merge PR https://github.com/joomla/joomla-cms/pull/34882 --- administrator/components/com_content/tmpl/articles/default.php | 3 ++- administrator/components/com_content/tmpl/featured/default.php | 3 ++- layouts/joomla/button/transition-button.php | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/administrator/components/com_content/tmpl/articles/default.php b/administrator/components/com_content/tmpl/articles/default.php index 062d2ff8782..d3fa1fb904e 100644 --- a/administrator/components/com_content/tmpl/articles/default.php +++ b/administrator/components/com_content/tmpl/articles/default.php @@ -221,7 +221,8 @@ 'transitions' => $transitions, 'title' => Text::_($item->stage_title), 'tip_content' => Text::sprintf('JWORKFLOW', Text::_($item->workflow_title)), - 'id' => 'workflow-' . $item->id + 'id' => 'workflow-' . $item->id, + 'task' => 'articles.runTransition' ]; echo (new TransitionButton($options)) diff --git a/administrator/components/com_content/tmpl/featured/default.php b/administrator/components/com_content/tmpl/featured/default.php index 52624114666..3ddeeff4e65 100644 --- a/administrator/components/com_content/tmpl/featured/default.php +++ b/administrator/components/com_content/tmpl/featured/default.php @@ -227,7 +227,8 @@ 'transitions' => $transitions, 'title' => Text::_($item->stage_title), 'tip_content' => Text::sprintf('JWORKFLOW', Text::_($item->workflow_title)), - 'id' => 'workflow-' . $item->id + 'id' => 'workflow-' . $item->id, + 'task' => 'articles.runTransition' ]; echo (new TransitionButton($options)) diff --git a/layouts/joomla/button/transition-button.php b/layouts/joomla/button/transition-button.php index 965973c6e6f..0ee490f82ee 100644 --- a/layouts/joomla/button/transition-button.php +++ b/layouts/joomla/button/transition-button.php @@ -27,6 +27,7 @@ $tipTitle = $options['tip_title']; $tipContent = $options['tip_content']; $checkboxName = $options['checkbox_name']; +$task = $options['task']; ?>