-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[4.0] Global Delete Trash - New Feature
It has been requested several times that there was a single place where you could go and "empty the trash" for all components. This new component is based on com_checkin At this stage [ ] I am sure the code in the model can be improved [ ] What should the default permissions be or should it be hard coded restricted to super users only like joomlaupdate is ### testing Apply patch and then discover the component You will then find it in the Maintenance section of the system dashboard
- Loading branch information
1 parent
98ddc19
commit a6a6e3b
Showing
11 changed files
with
786 additions
and
0 deletions.
There are no files selected for viewing
122 changes: 122 additions & 0 deletions
122
administrator/components/com_trash/Controller/DisplayController.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
<?php | ||
/** | ||
* @package Joomla.Administrator | ||
* @subpackage com_trash | ||
* | ||
* @copyright Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved. | ||
* @license GNU General Public License version 2 or later; see LICENSE.txt | ||
*/ | ||
|
||
namespace Joomla\Component\Trash\Administrator\Controller; | ||
|
||
defined('_JEXEC') or die; | ||
|
||
use Joomla\CMS\Factory; | ||
use Joomla\CMS\Language\Text; | ||
use Joomla\CMS\MVC\Controller\BaseController; | ||
use Joomla\CMS\Response\JsonResponse; | ||
|
||
/** | ||
* Trash Controller | ||
* | ||
* @since __DEPLOY_VERSION__ | ||
*/ | ||
class DisplayController extends BaseController | ||
{ | ||
/** | ||
* The default view. | ||
* | ||
* @var string | ||
* @since __DEPLOY_VERSION__ | ||
*/ | ||
protected $default_view = 'trash'; | ||
|
||
/** | ||
* Method to display a view. | ||
* | ||
* @param boolean $cachable If true, the view output will be cached | ||
* @param array $urlparams An array of safe URL parameters and their variable types, for valid values see {@link \JFilterInput::clean()}. | ||
* | ||
* @return static A \JControllerLegacy object to support chaining. | ||
*/ | ||
public function display($cachable = false, $urlparams = array()) | ||
{ | ||
return parent::display(); | ||
} | ||
|
||
/** | ||
* Trash a list of items. | ||
* | ||
* @return void | ||
*/ | ||
public function trash() | ||
{ | ||
// Check for request forgeries | ||
$this->checkToken(); | ||
|
||
$ids = $this->input->get('cid', array(), 'array'); | ||
|
||
if (empty($ids)) | ||
{ | ||
$this->app->enqueueMessage(Text::_('JLIB_HTML_PLEASE_MAKE_A_SELECTION_FROM_THE_LIST'), 'warning'); | ||
} | ||
else | ||
{ | ||
// Get the model. | ||
/** @var \Joomla\Component\Trash\Administrator\Model\TrashModel $model */ | ||
$model = $this->getModel('Trash'); | ||
|
||
// Trash the items. | ||
$this->setMessage(Text::plural('COM_TRASH_N_ITEMS_DELETED', $model->trash($ids))); | ||
} | ||
|
||
$this->setRedirect('index.php?option=com_trash'); | ||
} | ||
|
||
/** | ||
* Provide the data for a badge in a menu item via JSON | ||
* | ||
* @return void | ||
* | ||
* @since __DEPLOY_VERSION__ | ||
*/ | ||
public function getMenuBadgeData() | ||
{ | ||
if (!Factory::getUser()->authorise('core.admin', 'com_trash')) | ||
{ | ||
throw new \Exception(Text::_('JGLOBAL_AUTH_ACCESS_DENIED')); | ||
} | ||
|
||
$model = $this->getModel('Trash'); | ||
|
||
$amount = (int) count($model->getItems()); | ||
|
||
echo new JsonResponse($amount); | ||
} | ||
|
||
/** | ||
* Method to get the number of trashed items | ||
* | ||
* @return void | ||
* | ||
* @since __DEPLOY_VERSION__ | ||
*/ | ||
public function getQuickiconContent() | ||
{ | ||
if (!Factory::getUser()->authorise('core.admin', 'com_trash')) | ||
{ | ||
throw new \Exception(Text::_('JGLOBAL_AUTH_ACCESS_DENIED')); | ||
} | ||
|
||
$model = $this->getModel('Trash'); | ||
|
||
$amount = (int) count($model->getItems()); | ||
|
||
$result = []; | ||
|
||
$result['amount'] = $amount; | ||
$result['sronly'] = Text::plural('COM_TRASH_N_QUICKICON_SRONLY', $amount); | ||
|
||
echo new JsonResponse($result); | ||
} | ||
} |
270 changes: 270 additions & 0 deletions
270
administrator/components/com_trash/Model/TrashModel.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,270 @@ | ||
<?php | ||
/** | ||
* @package Joomla.Administrator | ||
* @subpackage com_trash | ||
* | ||
* @copyright Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved. | ||
* @license GNU General Public License version 2 or later; see LICENSE.txt | ||
*/ | ||
|
||
namespace Joomla\Component\Trash\Administrator\Model; | ||
|
||
defined('_JEXEC') or die; | ||
|
||
use Joomla\CMS\Factory; | ||
use Joomla\CMS\MVC\Factory\MVCFactoryInterface; | ||
use Joomla\CMS\MVC\Model\ListModel; | ||
|
||
/** | ||
* Trash Model | ||
* | ||
* @since __DEPLOY_VERSION__ | ||
*/ | ||
class TrashModel extends ListModel | ||
{ | ||
/** | ||
* Count of the total items in trashed state | ||
* | ||
* @var integer | ||
*/ | ||
protected $total; | ||
|
||
/** | ||
* Constructor. | ||
* | ||
* @param array $config An optional associative array of configuration settings. | ||
* @param MVCFactoryInterface $factory The factory. | ||
* | ||
* @see \Joomla\CMS\MVC\Model\BaseDatabaseModel | ||
* @since __DEPLOY_VERSION__ | ||
*/ | ||
public function __construct($config = array(), MVCFactoryInterface $factory = null) | ||
{ | ||
if (empty($config['filter_fields'])) | ||
{ | ||
$config['filter_fields'] = array( | ||
'table', | ||
'count', | ||
); | ||
} | ||
|
||
parent::__construct($config, $factory); | ||
} | ||
|
||
/** | ||
* Method to auto-populate the model state. | ||
* | ||
* Note: Calling getState in this method will result in recursion. | ||
* | ||
* @param string $ordering An optional ordering field. | ||
* @param string $direction An optional direction (asc|desc). | ||
* | ||
* @return void | ||
* | ||
* @since __DEPLOY_VERSION__ | ||
*/ | ||
protected function populateState($ordering = 'table', $direction = 'asc') | ||
{ | ||
// List state information. | ||
parent::populateState($ordering, $direction); | ||
} | ||
|
||
/** | ||
* Deletes items in requested tables | ||
* | ||
* @param array $ids An array of table names. Optional. | ||
* | ||
* @return mixed The database results or 0 | ||
* | ||
* @since __DEPLOY_VERSION__ | ||
*/ | ||
public function trash($ids = array()) | ||
{ | ||
$db = $this->getDbo(); | ||
|
||
if (!is_array($ids)) | ||
{ | ||
return 0; | ||
} | ||
|
||
// This int will hold the trashed item count. | ||
$results = 0; | ||
|
||
$app = Factory::getApplication(); | ||
|
||
foreach ($ids as $tn) | ||
{ | ||
// Make sure we get the right tables based on prefix. | ||
if (stripos($tn, $app->get('dbprefix')) !== 0) | ||
{ | ||
continue; | ||
} | ||
|
||
// Set the column name for the where clause | ||
$fields = $db->getTableColumns($tn); | ||
|
||
if (isset($fields['state'])) | ||
{ | ||
$column = 'state'; | ||
} | ||
elseif (isset($fields['published'])) | ||
{ | ||
$column = 'published'; | ||
} | ||
|
||
$query = $db->getQuery(true) | ||
->delete($db->quoteName($tn)) | ||
->where( $column . ' = -2'); | ||
|
||
$db->setQuery($query); | ||
|
||
if ($db->execute()) | ||
{ | ||
$results = $results + $db->getAffectedRows(); | ||
$app->triggerEvent('onAfterTrash', array($tn)); | ||
} | ||
} | ||
|
||
return $results; | ||
} | ||
|
||
/** | ||
* Get total of tables | ||
* | ||
* @return integer Total to trash tables | ||
* | ||
* @since __DEPLOY_VERSION__ | ||
*/ | ||
public function getTotal() | ||
{ | ||
if (!isset($this->total)) | ||
{ | ||
$this->getItems(); | ||
} | ||
|
||
return $this->total; | ||
} | ||
|
||
/** | ||
* Get tables | ||
* | ||
* @return array Table names as keys and item count as values. | ||
* | ||
* @since __DEPLOY_VERSION__ | ||
*/ | ||
public function getItems() | ||
{ | ||
if (!isset($this->items)) | ||
{ | ||
$db = $this->getDbo(); | ||
$tables = $db->getTableList(); | ||
|
||
// This array will hold table name as key and item count as value. | ||
$results = array(); | ||
|
||
foreach ($tables as $i => $tn) | ||
{ | ||
// Make sure we get the right tables based on prefix. | ||
if (stripos($tn, Factory::getApplication()->get('dbprefix')) !== 0) | ||
{ | ||
unset($tables[$i]); | ||
continue; | ||
} | ||
|
||
if ($this->getState('filter.search') && stripos($tn, $this->getState('filter.search')) === false) | ||
{ | ||
unset($tables[$i]); | ||
continue; | ||
} | ||
|
||
$fields = $db->getTableColumns($tn); | ||
|
||
// only work with the tables that have a state or published column | ||
if (!(isset($fields['state'])) && !(isset($fields['published']))) | ||
{ | ||
unset($tables[$i]); | ||
continue; | ||
} | ||
|
||
} | ||
|
||
foreach ($tables as $tn) | ||
{ | ||
// Set the column name for the where clause | ||
$fields = $db->getTableColumns($tn); | ||
|
||
if (isset($fields['state'])) | ||
{ | ||
$column = 'state'; | ||
} | ||
elseif (isset($fields['published'])) | ||
{ | ||
$column = 'published'; | ||
} | ||
|
||
$query = $db->getQuery(true) | ||
->select('COUNT(*)') | ||
->from($db->quoteName($tn)) | ||
->where( $column . ' = -2'); | ||
|
||
$db->setQuery($query); | ||
|
||
if ($db->execute()) | ||
{ | ||
$results[$tn] = $db->loadResult(); | ||
|
||
// Show only tables with items to trash. | ||
if ((int) $results[$tn] === 0) | ||
{ | ||
unset($results[$tn]); | ||
} | ||
} | ||
else | ||
{ | ||
continue; | ||
} | ||
} | ||
|
||
$this->total = count($results); | ||
|
||
// Order items by table | ||
if ($this->getState('list.ordering') == 'table') | ||
{ | ||
if (strtolower($this->getState('list.direction')) == 'asc') | ||
{ | ||
ksort($results); | ||
} | ||
else | ||
{ | ||
krsort($results); | ||
} | ||
} | ||
// Order items by number of items | ||
else | ||
{ | ||
if (strtolower($this->getState('list.direction')) == 'asc') | ||
{ | ||
asort($results); | ||
} | ||
else | ||
{ | ||
arsort($results); | ||
} | ||
} | ||
|
||
// Pagination | ||
$limit = (int) $this->getState('list.limit'); | ||
|
||
if ($limit !== 0) | ||
{ | ||
$this->items = array_slice($results, $this->getState('list.start'), $limit); | ||
} | ||
else | ||
{ | ||
$this->items = $results; | ||
} | ||
} | ||
|
||
return $this->items; | ||
} | ||
} |
Oops, something went wrong.