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 ceef7055ca38e..dc847730c5a74 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 @@ -127,7 +127,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, NULL, 0, 0), -(0, 'plg_workflow_publishing', 'plugin', 'publishing', 'workflow', 0, 1, 1, 0, '', '{}', 0, NULL, 0, 0); +(0, 'plg_workflow_publishing', 'plugin', 'publishing', 'workflow', 0, 1, 1, 0, '', '{}', 0, NULL, 0, 0), +(0, 'plg_workflow_featuring', 'plugin', 'featuring', 'workflow', 0, 1, 1, 0, '', '{}', 0, NULL, 0, 0); -- -- Creating Associations for existing content 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 107b73c480fb2..e873e2c2c32c3 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 @@ -123,7 +123,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, '1970-01-01 00:00:00', 0, 0), -(0, 'plg_workflow_publishing', 'plugin', 'publishing', 'workflow', 0, 1, 1, 0, '', '{}', 0, NULL, 0, 0); +(0, 'plg_workflow_publishing', 'plugin', 'publishing', 'workflow', 0, 1, 1, 0, '', '{}', 0, NULL, 0, 0), +(0, 'plg_workflow_featuring', 'plugin', 'featuring', 'workflow', 0, 1, 1, 0, '', '{}', 0, NULL, 0, 0); -- -- Creating Associations for existing content diff --git a/administrator/components/com_content/src/Extension/ContentComponent.php b/administrator/components/com_content/src/Extension/ContentComponent.php index 06265cd471be8..01ad75352eb1c 100644 --- a/administrator/components/com_content/src/Extension/ContentComponent.php +++ b/administrator/components/com_content/src/Extension/ContentComponent.php @@ -53,6 +53,14 @@ class ContentComponent extends MVCComponent implements CategoryServiceTrait::getStateColumnForSection insteadof TagServiceTrait; } + /** @var array Supported functionality */ + protected $supportedFunctionality = [ + 'core.featured' => [ + 'com_content.articles' + ], + 'joomla.state' => true, + ]; + /** * The trashed condition * diff --git a/administrator/components/com_content/src/Model/ArticleModel.php b/administrator/components/com_content/src/Model/ArticleModel.php index 47af27fced737..bba8b0e34cead 100644 --- a/administrator/components/com_content/src/Model/ArticleModel.php +++ b/administrator/components/com_content/src/Model/ArticleModel.php @@ -73,10 +73,49 @@ class ArticleModel extends AdminModel implements WorkflowModelInterface */ protected $associationsContext = 'com_content.item'; + /** + * The event to trigger before changing featured status one or more items. + * + * @var string + * @since 4.0 + */ + protected $event_before_change_featured = null; + + /** + * The event to trigger after changing featured status one or more items. + * + * @var string + * @since 4.0 + */ + protected $event_after_change_featured = null; + + /** + * Constructor. + * + * @param array $config An array of configuration options (name, state, dbo, table_path, ignore_request). + * @param MVCFactoryInterface $factory The factory. + * @param FormFactoryInterface $formFactory The form factory. + * + * @since 1.6 + * @throws \Exception + */ public function __construct($config = array(), MVCFactoryInterface $factory = null, FormFactoryInterface $formFactory = null) { + $config['events_map'] = $config['events_map'] ?? []; + + $config['events_map'] = array_merge( + ['featured' => 'content'], + $config['events_map'] + ); + parent::__construct($config, $factory, $formFactory); + // Set the featured status change events + $this->event_before_change_featured = $config['event_before_change_featured'] ?? $this->event_before_change_featured; + $this->event_before_change_featured = $this->event_before_change_featured ?? 'onContentBeforeChangeFeatured'; + $this->event_after_change_featured = $config['event_after_change_featured'] ?? $this->event_after_change_featured; + $this->event_after_change_featured = $this->event_after_change_featured ?? 'onContentAfterChangeFeatured'; + $this->setUpWorkflow('com_content.article'); } @@ -825,9 +864,15 @@ public function save($data) public function featured($pks, $value = 0, $featuredUp = null, $featuredDown = null) { // Sanitize the ids. - $pks = (array) $pks; - $pks = ArrayHelper::toInteger($pks); - $value = (int) $value; + $pks = (array) $pks; + $pks = ArrayHelper::toInteger($pks); + $value = (int) $value; + $context = $this->option . '.' . $this->name; + + $this->workflowBeforeStageChange(); + + // Include the plugins for the change of state event. + PluginHelper::importPlugin($this->events_map['featured']); // Convert empty strings to null for the query. if ($featuredUp === '') @@ -849,6 +894,16 @@ public function featured($pks, $value = 0, $featuredUp = null, $featuredDown = n $table = $this->getTable('Featured', 'Administrator'); + // Trigger the before change state event. + $result = Factory::getApplication()->triggerEvent($this->event_before_change_featured, array($context, $pks, $value)); + + if (\in_array(false, $result, true)) + { + $this->setError($table->getError()); + + return false; + } + try { $db = $this->getDbo(); @@ -942,6 +997,16 @@ public function featured($pks, $value = 0, $featuredUp = null, $featuredDown = n $table->reorder(); + // Trigger the change state event. + $result = Factory::getApplication()->triggerEvent($this->event_after_change_featured, array($context, $pks, $value)); + + if (\in_array(false, $result, true)) + { + $this->setError($table->getError()); + + return false; + } + $this->cleanCache(); return true; diff --git a/administrator/components/com_content/tmpl/articles/default.php b/administrator/components/com_content/tmpl/articles/default.php index fa443112a0afc..12cda5c5d8360 100644 --- a/administrator/components/com_content/tmpl/articles/default.php +++ b/administrator/components/com_content/tmpl/articles/default.php @@ -205,6 +205,10 @@ 'disabled' => !$canChange ]; + if ($workflow_enabled) : + $options['disabled'] = true; + endif; + echo (new FeaturedButton) ->render((int) $item->featured, $i, $options, $item->featured_up, $item->featured_down); ?> diff --git a/administrator/components/com_content/tmpl/featured/default.php b/administrator/components/com_content/tmpl/featured/default.php index 8e9e7b54e790f..6d993dcca50eb 100644 --- a/administrator/components/com_content/tmpl/featured/default.php +++ b/administrator/components/com_content/tmpl/featured/default.php @@ -197,6 +197,10 @@ 'disabled' => !$canChange ]; + if ($workflow_enabled) : + $options['disabled'] = true; + endif; + echo (new FeaturedButton) ->render((int) $item->featured, $i, $options, $item->featured_up, $item->featured_down); ?> diff --git a/administrator/language/en-GB/plg_workflow_featuring.ini b/administrator/language/en-GB/plg_workflow_featuring.ini new file mode 100644 index 0000000000000..f7c2303092ab4 --- /dev/null +++ b/administrator/language/en-GB/plg_workflow_featuring.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_FEATURING="Workflow - Featuring" +PLG_WORKFLOW_FEATURING_XML_DESCRIPTION="Add featuring actions to the workflow transitions for your items" +PLG_WORKFLOW_FEATURING_TRANSITION_ACTIONS_FEATURING_LABEL="Featuring state" +PLG_WORKFLOW_FEATURING_TRANSITION_ACTIONS_FEATURING_DESC="Define the featured state an item should be set, when executing this transition" +PLG_WORKFLOW_FEATURING_CHANGE_STATE_NOT_ALLOWED="You're not allowed to change the featured state of this item. Please use a workflow transition." +PLG_WORKFLOW_FEATURING_FEATURED="Featured: %s" diff --git a/administrator/language/en-GB/plg_workflow_featuring.sys.ini b/administrator/language/en-GB/plg_workflow_featuring.sys.ini new file mode 100644 index 0000000000000..a80d79cb2fe80 --- /dev/null +++ b/administrator/language/en-GB/plg_workflow_featuring.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_FEATURING="Workflow - Featuring" +PLG_WORKFLOW_FEATURING_XML_DESCRIPTION="Add featuring options to the workflow transitions for your items" diff --git a/installation/sql/mysql/base.sql b/installation/sql/mysql/base.sql index fe10e567000d5..86880b10e7530 100644 --- a/installation/sql/mysql/base.sql +++ b/installation/sql/mysql/base.sql @@ -358,7 +358,8 @@ INSERT INTO `#__extensions` (`package_id`, `name`, `type`, `element`, `folder`, (0, 'plg_media-action_rotate', 'plugin', 'rotate', 'media-action', 0, 1, 1, 0, 1, '', '{}', 0, NULL, 0, 0), (0, 'plg_system_accessibility', 'plugin', 'accessibility', 'system', 0, 0, 1, 0, 1, '', '{}', 0, NULL, 0, 0), (0, 'plg_system_webauthn', 'plugin', 'webauthn', 'system', 0, 1, 1, 0, 1, '', '{}', 0, NULL, 0, 0), -(0, 'plg_workflow_publishing', 'plugin', 'publishing', 'workflow', 0, 1, 1, 0, 1, '', '{}', 0, NULL, 0, 0); +(0, 'plg_workflow_publishing', 'plugin', 'publishing', 'workflow', 0, 1, 1, 0, 1, '', '{}', 0, NULL, 0, 0), +(0, 'plg_workflow_featuring', 'plugin', 'featuring', 'workflow', 0, 1, 1, 0, 1, '', '{}', 0, NULL, 0, 0); -- Templates INSERT INTO `#__extensions` (`package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `locked`, `manifest_cache`, `params`, `checked_out`, `checked_out_time`, `ordering`, `state`) VALUES diff --git a/installation/sql/postgresql/base.sql b/installation/sql/postgresql/base.sql index aaf7e5f222378..3655d76239a2b 100644 --- a/installation/sql/postgresql/base.sql +++ b/installation/sql/postgresql/base.sql @@ -364,7 +364,8 @@ INSERT INTO "#__extensions" ("package_id", "name", "type", "element", "folder", (0, 'plg_media-action_rotate', 'plugin', 'rotate', 'media-action', 0, 1, 1, 0, 1, '', '{}', 0, NULL, 0, 0), (0, 'plg_system_accessibility', 'plugin', 'accessibility', 'system', 0, 0, 1, 0, 1, '', '{}', 0, NULL, 0, 0), (0, 'plg_system_webauthn', 'plugin', 'webauthn', 'system', 0, 1, 1, 0, 1, '', '{}', 0, NULL, 0, 0), -(0, 'plg_workflow_publishing', 'plugin', 'publishing', 'workflow', 0, 1, 1, 0, 1, '', '{}', 0, NULL, 0, 0); +(0, 'plg_workflow_publishing', 'plugin', 'publishing', 'workflow', 0, 1, 1, 0, 1, '', '{}', 0, NULL, 0, 0), +(0, 'plg_workflow_featuring', 'plugin', 'featuring', 'workflow', 0, 1, 1, 0, 1, '', '{}', 0, NULL, 0, 0); -- Templates INSERT INTO "#__extensions" ("package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "locked", "manifest_cache", "params", "checked_out", "checked_out_time", "ordering", "state") VALUES @@ -1181,4 +1182,4 @@ INSERT INTO "#__workflow_transitions" ("id", "asset_id", "published", "ordering" (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 +SELECT setval('#__workflow_transitions_id_seq', 5, false); diff --git a/libraries/src/Workflow/WorkflowServiceTrait.php b/libraries/src/Workflow/WorkflowServiceTrait.php index 20c3cc6eae4a8..66f8dd0435a6a 100644 --- a/libraries/src/Workflow/WorkflowServiceTrait.php +++ b/libraries/src/Workflow/WorkflowServiceTrait.php @@ -31,14 +31,17 @@ trait WorkflowServiceTrait */ abstract public function getMVCFactory(): MVCFactoryInterface; - /** @var array Supported functionality */ - protected $supportedFunctionality = [ - 'joomla.state' => true, - 'joomla.featured' => true, - ]; - /** - * Check if the functionality is supported by the context + * Check if the functionality is supported by the component + * The variable $supportFunctionality has the following structure + * [ + * 'core.featured' => [ + * 'com_content.article', + * ], + * 'core.state' => [ + * 'com_content.article', + * ], + * ] * * @param string $functionality The functionality * @param string $context The context of the functionality @@ -57,7 +60,7 @@ public function supportFunctionality($functionality, $context): bool return true; } - return in_array($context, $this->supportedFunctionality[$functionality]); + return in_array($context, $this->supportedFunctionality[$functionality], true); } /** diff --git a/plugins/workflow/featuring/featuring.php b/plugins/workflow/featuring/featuring.php new file mode 100644 index 0000000000000..e2216352b9b3f --- /dev/null +++ b/plugins/workflow/featuring/featuring.php @@ -0,0 +1,424 @@ +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) + { + $model = $this->app->bootComponent('com_workflow') + ->getMVCFactory()->createModel('Workflow', 'Administrator', ['ignore_request' => true]); + + $workflow_id = (int) ($data->workflow_id ?? $form->getValue('workflow_id')); + + if (empty($workflow_id)) + { + $workflow_id = (int) $this->app->input->getInt('workflow_id'); + } + + $workflow = $model->getItem($workflow_id); + + if (!$this->isSupported($workflow->extension)) + { + return true; + } + + $form->loadFile(__DIR__ . '/forms/action.xml'); + + 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(); + + if (!$this->isSupported($context)) + { + return true; + } + + $parts = explode('.', $context); + + $component = $this->app->bootComponent($parts[0]); + + $modelName = $component->getModelName($context); + + $table = $component->getMVCFactory()->createModel($modelName, $this->app->getName(), ['ignore_request' => true]) + ->getTable(); + + $fieldname = $table->getColumnAlias('featured'); + + $options = $form->getField($fieldname)->options; + + $value = isset($data->$fieldname) ? $data->$fieldname : $form->getValue($fieldname, null, 0); + + $text = '-'; + + $textclass = 'body'; + + switch ($value) + { + case 1: + $textclass = 'success'; + break; + + case 0: + case -2: + $textclass = 'danger'; + } + + if (!empty($options)) + { + foreach ($options as $option) + { + if ($option->value == $value) + { + $text = $option->text; + + break; + } + } + } + + $form->setFieldAttribute($fieldname, 'type', 'spacer'); + + $form->setFieldAttribute($fieldname, 'label', Text::sprintf('PLG_WORKFLOW_FEATURING_FEATURED', '' . htmlentities($text, ENT_COMPAT, 'UTF-8') . '')); + + return true; + } + + /** + * Manipulate the generic list view + * + * @param string $context + * @param ViewInterface $view + * @param string $result + */ + public function onAfterDisplay(string $context, ViewInterface $view, string $result) + { + $parts = explode('.', $context); + + if ($parts < 2) + { + return true; + } + + $app = Factory::getApplication(); + + // We need the single model context for checking for workflow + $singularsection = Inflector::singularize($parts[1]); + + $newcontext = $parts[0] . '.' . $singularsection; + + if (!$app->isClient('administrator') || !$this->isSupported($newcontext)) + { + return true; + } + + // List of releated batch functions we need to hide + $states = ['featured', 'unfeatured']; + + $js = " + document.addEventListener('DOMContentLoaded', function() + { + var dropdown = document.getElementById('toolbar-dropdown-status-group'); + + if (!dropdown) + { + reuturn; + } + + " . \json_encode($states) . ".forEach((action) => { + var button = document.getElementById('status-group-children-' + action); + + if (button) + { + button.classList.add('d-none'); + } + }); + + }); + "; + + $app->getDocument()->addScriptDeclaration($js); + + 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('featuring'))) + { + return true; + } + + $value = (int) $transition->options->get('featuring'); + + /** + * Here it becomes tricky. We would like to use the component models featured method, so we will + * Execute the normal "onContentBeforeChangeFeatured" plugins. But they could cancel the execution, + * So we have to precheck and cancel the whole transition stuff if not allowed. + */ + $this->app->set('plgWorkflowFeaturing.' . $context, $pks); + + $result = $this->app->triggerEvent('onContentBeforeChangeFeatured', [$context, $pks, $value]); + + // Release whitelist, the job is done + $this->app->set('plgWorkflowFeaturing.' . $context, []); + + if (\in_array(false, $result, true)) + { + return false; + } + + return true; + } + + /** + * Change Feature State of an item. Used to disable feature 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('featuring'); + + $options = [ + 'ignore_request' => true, + // We already have triggered onContentBeforeChangeFeatured, so use our own + 'event_before_change_featured' => 'onWorkflowBeforeChangeFeatured' + ]; + + $modelName = $component->getModelName($context); + + $model = $component->getMVCFactory()->createModel($modelName, $this->app->getName(), $options); + + return $model->featured($pks, $value); + } + + /** + * Change Feature State of an item. Used to disable Feature 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 onContentBeforeChangeFeatured(string $context, array $pks, int $value): bool + { + if (!$this->isSupported($context)) + { + return true; + } + + // We have whitelisted the pks, so we're the one who triggered + // With onWorkflowBeforeTransition => free pass + if ($this->app->get('plgWorkflowFeaturing.' . $context) === $pks) + { + return true; + } + + throw new Exception(Text::_('PLG_WORKFLOW_FEATURING_CHANGE_STATE_NOT_ALLOWED')); + } + + /** + * 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('featured'); + + // Check for the old value + $article = clone $table; + + $article->load($table->id); + + // We don't allow the change of the feature 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])) + { + $this->app->enqueueMessage(Text::_('PLG_WORKFLOW_FEATURING_CHANGE_STATE_NOT_ALLOWED'), 'error'); + + return false; + } + + return true; + } + + /** + * Check if the current plugin should execute workflow related activities + * + * @param string $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 + || !$component->isWorkflowActive($context) + || !$component->supportFunctionality($this->supportFunctionality, $context)) + { + return false; + } + + $modelName = $component->getModelName($context); + + $model = $component->getMVCFactory()->createModel($modelName, $this->app->getName(), ['ignore_request' => true]); + + if (!$model instanceof DatabaseModelInterface || !method_exists($model, 'featured')) + { + return false; + } + + $table = $model->getTable(); + + if (!$table instanceof TableInterface || !$table->hasField('featured')) + { + return false; + } + + return true; + } +} diff --git a/plugins/workflow/featuring/featuring.xml b/plugins/workflow/featuring/featuring.xml new file mode 100644 index 0000000000000..39ab3f4e2e31f --- /dev/null +++ b/plugins/workflow/featuring/featuring.xml @@ -0,0 +1,27 @@ + + + plg_workflow_featuring + Joomla! Project + March 2020 + Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 4.0.0 + PLG_WORKFLOW_FEATURING_XML_DESCRIPTION + + featuring.php + + + plg_workflow_featuring.ini + plg_workflow_featuring.sys.ini + + + +
+ +
+
+
+ +
diff --git a/plugins/workflow/featuring/forms/action.xml b/plugins/workflow/featuring/forms/action.xml new file mode 100644 index 0000000000000..02d9e95b0e676 --- /dev/null +++ b/plugins/workflow/featuring/forms/action.xml @@ -0,0 +1,18 @@ + +
+ +
+ + + + + +
+
+
diff --git a/plugins/workflow/publishing/forms/workflow_publishing.xml b/plugins/workflow/publishing/forms/workflow_publishing.xml index 7b52b390883ca..2cc0f2e24156c 100644 --- a/plugins/workflow/publishing/forms/workflow_publishing.xml +++ b/plugins/workflow/publishing/forms/workflow_publishing.xml @@ -12,7 +12,7 @@ default="" hide_all="true" > - + diff --git a/plugins/workflow/publishing/publishing.xml b/plugins/workflow/publishing/publishing.xml index d2bbfb5f0f909..6aa683603d94d 100644 --- a/plugins/workflow/publishing/publishing.xml +++ b/plugins/workflow/publishing/publishing.xml @@ -13,8 +13,8 @@ publishing.php - en-GB.plg_workflow_publishing.ini - en-GB.plg_workflow_publishing.sys.ini + plg_workflow_publishing.ini + plg_workflow_publishing.sys.ini