Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
f64c9ca
Prevent trashing of active items
bembelimen Aug 13, 2018
61d9c0b
Fix wrong method name
bembelimen Aug 13, 2018
6be26a1
Improve translation
bembelimen Aug 13, 2018
b25c0b3
Improve translation
bembelimen Aug 13, 2018
647092d
Merge branch '4.0-dev' of github.com:joomla/joomla-cms into workflow-…
bembelimen Aug 13, 2018
b1eebd6
Reorder xml structure
bembelimen Aug 13, 2018
ab6369e
Remove blank line
bembelimen Aug 13, 2018
0a2cb77
Order use statements
bembelimen Aug 13, 2018
f21b84b
Add point
bembelimen Aug 13, 2018
d4428d7
Merge branch '4.0-dev' into workflow-prevent-trashing
wilsonge Aug 13, 2018
974c564
Merge branch '4.0-dev' into workflow-prevent-trashing
wilsonge Aug 14, 2018
272fcf8
Sniffer satisfaction
bembelimen Aug 14, 2018
fac863e
Sniffer satisfaction
bembelimen Aug 14, 2018
102d260
Merge branch '4.0-dev' into workflow-prevent-trashing
wilsonge Aug 14, 2018
85b4ff1
Merge branch '4.0-dev' of github.com:joomla/joomla-cms into workflow-…
bembelimen Aug 18, 2018
069fc8b
Remove parameter check
bembelimen Aug 18, 2018
899805c
Fix comment
bembelimen Aug 18, 2018
85223e5
Code sniffer
bembelimen Aug 19, 2018
07b7a44
Merge branch '4.0-dev' of github.com:joomla/joomla-cms into workflow-…
bembelimen Aug 20, 2018
9305a49
Merge branch '4.0-dev' into workflow-prevent-trashing
bembelimen Aug 23, 2018
ff70dc6
Merge branch '4.0-dev' into workflow-prevent-trashing
bembelimen Aug 24, 2018
e93e017
Merge branch '4.0-dev' of github.com:joomla/joomla-cms into workflow-…
bembelimen Sep 8, 2018
e762553
Merge branch '4.0-dev' into workflow-prevent-trashing
wilsonge Sep 8, 2018
d9b2b2d
Merge branch '4.0-dev' of github.com:joomla/joomla-cms into workflow-…
bembelimen Sep 9, 2018
e204edf
Merge branch 'workflow-prevent-trashing' of github.com:bembelimen/joo…
bembelimen Sep 9, 2018
22b2446
Fix trashing over edit view
bembelimen Sep 9, 2018
9c066cc
Remove unused string
bembelimen Sep 9, 2018
10d8bc0
Merge branch '4.0-dev' into workflow-prevent-trashing
bembelimen Sep 9, 2018
14fcc14
Merge branch '4.0-dev' of github.com:joomla/joomla-cms into workflow-…
bembelimen Sep 10, 2018
0843fbc
Remove unused "use statement"
bembelimen Sep 10, 2018
4e68625
Merge branch '4.0-dev' into workflow-prevent-trashing
bembelimen Sep 22, 2018
5f31e9f
Merge branch '4.0-dev' of github.com:joomla/joomla-cms into workflow-…
bembelimen Nov 19, 2018
a9b60ff
Merge branch '4.0-dev' into workflow-prevent-trashing
wilsonge Dec 10, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions administrator/language/en-GB/en-GB.com_workflow.ini
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ COM_WORKFLOW_MODIFIED_LABEL="Date Modified"
COM_WORKFLOW_MSG_DELETE_DEFAULT="You are trying to delete the default item."
COM_WORKFLOW_MSG_FROM_TO_STAGE="From Stage and to Stage must have different Names."
COM_WORKFLOW_MSG_DELETE_IS_ASSIGNED="This item is in use by the component."
COM_WORKFLOW_MSG_DELETE_IS_DEFAULT="You can't delete the default item"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add a . at the end

COM_WORKFLOW_MSG_WORKFLOWS_DELETE_ERROR="There was a problem while deleting the item: "
COM_WORKFLOW_NA="N/A"
COM_WORKFLOW_NAME="Name"
Expand Down
4 changes: 2 additions & 2 deletions administrator/language/en-GB/en-GB.plg_content_joomla.ini
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
PLG_CONTENT_JOOMLA="Content - Joomla"
PLG_CONTENT_JOOMLA_FIELD_CHECK_CATEGORIES_DESC="Check that categories are fully empty before they are deleted."
PLG_CONTENT_JOOMLA_FIELD_CHECK_CATEGORIES_LABEL="Check Category Deletion"
PLG_CONTENT_JOOMLA_FIELD_CHECK_STATES_DESC="Check that states are not assigned to an item before they are deleted."
PLG_CONTENT_JOOMLA_FIELD_CHECK_STATES_LABEL="Check States Deletion"
PLG_CONTENT_JOOMLA_FIELD_CHECK_STATES_WORKFLOW_DESC="Check that stages/workflows are not assigned to an item before they are deleted."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename STATES

PLG_CONTENT_JOOMLA_FIELD_CHECK_STATES_WORKFLOW_LABEL="Check Stages/Workflow Deletion"
PLG_CONTENT_JOOMLA_FIELD_EMAIL_NEW_FE_DESC="Email users if 'Send email' is on when there is a new article submitted via the Frontend."
PLG_CONTENT_JOOMLA_FIELD_EMAIL_NEW_FE_LABEL="Email on New Site Article"
PLG_CONTENT_JOOMLA_FIELD_EMAIL_NEW_STAGE_DESC="Email users if 'Send email' is on when there is a status change of an article."
Expand Down
31 changes: 29 additions & 2 deletions libraries/src/MVC/Model/AdminModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,14 @@ abstract class AdminModel extends FormModel
*/
protected $event_before_save = null;

/**
* The event to trigger before changing the published state of the data.
*
* @var string
* @since __DEPLOY_VERSION__
*/
protected $event_before_change_state = null;

/**
* The event to trigger after changing the published state of the data.
*
Expand Down Expand Up @@ -214,6 +222,15 @@ public function __construct($config = array(), MVCFactoryInterface $factory = nu
$this->event_before_save = 'onContentBeforeSave';
}

if (isset($config['event_before_change_state']))
{
$this->event_before_change_state = $config['event_before_change_state'];
}
elseif (empty($this->event_before_change_state))
{
$this->event_before_change_state = 'onContentBeforeChangeState';
}

if (isset($config['event_change_state']))
{
$this->event_change_state = $config['event_change_state'];
Expand Down Expand Up @@ -1004,6 +1021,8 @@ public function publish(&$pks, $value = 1)
$table = $this->getTable();
$pks = (array) $pks;

$context = $this->option . '.' . $this->name;

// Include the plugins for the change of state event.
\JPluginHelper::importPlugin($this->events_map['change_state']);

Expand Down Expand Up @@ -1037,6 +1056,16 @@ public function publish(&$pks, $value = 1)
}
}

// Trigger the change state event.
$result = Factory::getApplication()->triggerEvent($this->event_before_change_state, array($context, $pks, $value));

if (in_array(false, $result, true))
{
$this->setError($table->getError());

return false;
}

// Attempt to change the state of the records.
if (!$table->publish($pks, $value, $user->get('id')))
{
Expand All @@ -1045,8 +1074,6 @@ public function publish(&$pks, $value = 1)
return false;
}

$context = $this->option . '.' . $this->name;

// Trigger the change state event.
$result = Factory::getApplication()->triggerEvent($this->event_change_state, array($context, $pks, $value));

Expand Down
155 changes: 146 additions & 9 deletions plugins/content/joomla/joomla.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
use Joomla\Component\Content\Administrator\Table\ArticleTable;
use Joomla\CMS\Workflow\Workflow;
use Joomla\Utilities\ArrayHelper;
use Joomla\Component\Workflow\Administrator\Table\StageTable;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sort in alpha order. See this PR #21577.

use Joomla\Component\Workflow\Administrator\Table\WorkflowTable;

/**
* Example Content Plugin
Expand Down Expand Up @@ -137,10 +139,35 @@ public function onContentBeforeDelete($context, $data)
return $this->_canDeleteCategories($data);

case 'com_workflow.stage':
return $this->_canDeleteStages($data->id);
return $this->_canDeleteStage($data->id);
}
}

public function onContentBeforeChangeState($context, $pks, $value)
{
if ($value != -2 || !in_array($context, ['com_workflow.workflow', 'com_workflow.stage']))
{
return true;
}

$result = true;

foreach ($pks as $id)
{
switch ($context)
{
case 'com_workflow.workflow':
return $result && $this->_canDeleteWorkflow($id);

case 'com_workflow.stage':
$result = $result && $this->_canDeleteStage($id);
}
}

return $result;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove blank line

}

/**
* Checks if a given category can be deleted
*
Expand Down Expand Up @@ -218,18 +245,18 @@ private function _canDeleteCategories($data)
}

/**
* Checks if a given stage can be deleted
* Checks if a given workflow can be deleted
*
* @param int $pk The stage ID
*
* @return boolean
*
* @since __DEPLOY_VERSION__
*/
private function _canDeleteStages($pk)
private function _canDeleteWorkflow($pk)
{
// Check if this function is enabled.
if (!$this->params->def('check_stages', 1))
if (!$this->params->def('check_states_workflow', 1))
{
return true;
}
Expand All @@ -239,15 +266,27 @@ private function _canDeleteStages($pk)
// Default to true if not a core extension
$result = true;

// Check if this workflow is the default stage
$table = new WorkflowTable($this->db);

$table->load($pk);

if ($table->default)
{
throw new Exception(Text::_('COM_WORKFLOW_MSG_DELETE_IS_DEFAULT'));
}

$tableInfo = [
'com_content' => array('table_name' => '#__content')
];

// Now check to see if this is a known core extension
if (isset($tableInfo[$extension]))
{
$table = $tableInfo[$extension]['table_name'];

// See if this category has any content items
$count = $this->_countItemsFromState($extension, $pk, $tableInfo[$extension]);
$count = $this->_countItemsFromWorkflow($extension, $pk, $table);

// Return false if db error
if ($count === false)
Expand All @@ -259,9 +298,69 @@ private function _canDeleteStages($pk)
// Show error if items are found assigned to the stage
if ($count > 0)
{
$msg = Text::_('COM_WORKFLOW_MSG_DELETE_IS_ASSIGNED');
Factory::getApplication()->enqueueMessage($msg, 'error');
$result = false;
throw new Exception(Text::_('COM_WORKFLOW_MSG_DELETE_IS_ASSIGNED'));
}
}
}

return $result;
}

/**
* Checks if a given stage can be deleted
*
* @param int $pk The stage ID
*
* @return boolean
*
* @since __DEPLOY_VERSION__
*/
private function _canDeleteStage($pk)
{
// Check if this function is enabled.
if (!$this->params->def('check_states_workflow', 1))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need this parameter? Why not just use the com_content enabled parameter (and when it's disabled it should always stop you from deleting a stage)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The category check uses their own parameter, too. So it was a "copy&extend".

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then we need to fix that too :P Like the parameters here need to respect their extensions helper values - not have their own

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So to be clear: it should not be possible to disable this function (beside deactivating the plugin)?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct. If workflows is enabled in the relevant component, then this is enabled

{
return true;
}

$extension = Factory::getApplication()->input->getString('extension');

// Default to true if not a core extension
$result = true;

// Check if this stage is the default stage
$table = new StageTable($this->db);

$table->load($pk);

if ($table->default)
{
throw new Exception(Text::_('COM_WORKFLOW_MSG_DELETE_IS_DEFAULT'));
}

$tableInfo = [
'com_content' => array('table_name' => '#__content')
];

// Now check to see if this is a known core extension
if (isset($tableInfo[$extension]))
{
$table = $tableInfo[$extension]['table_name'];

// See if this state has any content items
$count = $this->_countItemsFromState($extension, $pk, $table);

// Return false if db error
if ($count === false)
{
$result = false;
}
else
{
// Show error if items are found assigned to the stage
if ($count > 0)
{
throw new Exception(Text::_('COM_WORKFLOW_MSG_DELETE_IS_ASSIGNED'));
}
}
}
Expand Down Expand Up @@ -397,6 +496,44 @@ private function _countItemsFromState($extension, $stage_id, $table)
return $count;
}

/**
* Get count of items assigned to a stage
*
* @param string $extension The extension to search for
* @param integer $stage_id ID of the stage to check
* @param string $table The table to search for
*
* @return mixed count of items found or false if db error
*
* @since __DEPLOY_VERSION__
*/
private function _countItemsFromWorkflow($extension, $workflow_id, $table)
{
$query = $this->db->getQuery(true);

$query ->select('COUNT(' . $this->db->quoteName('wa.item_id') . ')')
->from($query->quoteName('#__workflow_associations', 'wa'))
->from($query->quoteName('#__workflow_stages', 's'))
->from($this->db->quoteName($table, 'b'))
->where($this->db->quoteName('wa.stage_id') . ' = ' . $this->db->quoteName('s.id'))
->where($this->db->quoteName('wa.item_id') . ' = ' . $this->db->quoteName('b.id'))
->where($this->db->quoteName('s.workflow_id') . ' = ' . (int) $workflow_id)
->where($this->db->quoteName('wa.extension') . ' = ' . $this->db->quote($extension));

try
{
$count = $this->db->setQuery($query)->loadResult();
}
catch (RuntimeException $e)
{
Factory::getApplication()->enqueueMessage($e->getMessage(), 'error');

return false;
}

return $count;
}

/**
* Change the state in core_content if the stage in a table is changed
*
Expand All @@ -416,7 +553,7 @@ public function onContentChangeState($context, $pks, $value)
{
foreach ($pks as $pk)
{
if (!$this->_canDeleteStates($pk))
if (!$this->_canDeleteStage($pk))
{
return false;
}
Expand Down
6 changes: 3 additions & 3 deletions plugins/content/joomla/joomla.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@
<option value="1">JYES</option>
</field>
<field
name="check_states"
name="check_states_workflow"
type="radio"
class="switcher"
label="PLG_CONTENT_JOOMLA_FIELD_CHECK_STATES_LABEL"
description="PLG_CONTENT_JOOMLA_FIELD_CHECK_STATES_DESC"
label="PLG_CONTENT_JOOMLA_FIELD_CHECK_STATES_WORKFLOW_LABEL"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per Joomla Coding Standards:

The four attributes name, type, label and description should be written in this order and at the top of the element definition.

description="PLG_CONTENT_JOOMLA_FIELD_CHECK_STATES_WORKFLOW_DESC"
default="1"
>
<option value="0">JNO</option>
Expand Down