joomlagerman / joomla

The J!German translation team provides German translation for Joomla!
https://www.jgerman.de
GNU General Public License v2.0
25 stars 46 forks source link

[5.2] Delete user access level - check for levels in use #3234

Closed jgerman-bot closed 1 month ago

jgerman-bot commented 1 month ago

New language relevant PR in upstream repo: https://github.com/joomla/joomla-cms/pull/43223 Here are the upstream changes:

Click to expand the diff! ```diff diff --git a/administrator/components/com_users/src/Model/LevelModel.php b/administrator/components/com_users/src/Model/LevelModel.php index f511143d530a..9164435c26b7 100644 --- a/administrator/components/com_users/src/Model/LevelModel.php +++ b/administrator/components/com_users/src/Model/LevelModel.php @@ -32,10 +32,86 @@ class LevelModel extends AdminModel { /** - * @var array A list of the access levels in use. - * @since 1.6 + * Method to delete one or more access levels. + * + * @param array $pks An array of primary keys. + * + * @return boolean True if successful, false if an error occurs. + * + * @since __DEPLOY_VERSION__ */ - protected $levelsInUse = null; + public function delete(&$pks) + { + $pks = (array) $pks; + $table = $this->getTable(); + + $levelsInUse = []; + + // Iterate the items to delete each one. + foreach ($pks as $i => $pk) { + if ($table->load($pk)) { + // Check if the access level is being used. + $db = $this->getDatabase(); + $query = $db->getQuery(true) + ->select('DISTINCT access'); + + // Get all tables that have the access field + $checkTables = $db->getTableList(); + $prefix = $db->getPrefix(); + + foreach ($checkTables as $checktable) { + // Get all of the columns in the table + $fields = $db->getTableColumns($checktable); + + /** + * We are looking for the access field. If custom tables are using something other + * than the 'access' field they are on their own unfortunately. + * Also make sure the table prefix matches the live db prefix (eg, it is not a "bak_" table) + */ + if (strpos($checktable, $prefix) === 0 && isset($fields['access'])) { + // Lookup the distinct values of the field. + $query->clear('from') + ->from($db->quoteName($checktable)); + $db->setQuery($query); + + try { + $values = $db->loadColumn(); + } catch (\RuntimeException $e) { + $this->setError($e->getMessage()); + + return false; + } + + // Check if the table uses this access level + if (\in_array($pk, $values)) { + // Add the table to the list of tables that use this access level + $levelsInUse[$pk][] = $checktable; + + // Remove the access level from the list of items to delete + unset($pks[$i]); + } + } + } + } + } + + if (!empty($levelsInUse)) { + $app = Factory::getApplication(); + $app->enqueueMessage(Text::_('COM_USERS_ERROR_VIEW_LEVEL_IN_USE'), 'error'); + + foreach ($levelsInUse as $levelId => $usedIn) { + $msg = Text::sprintf('COM_USERS_ERROR_VIEW_LEVEL_IN_USE_DETAILS', $levelId, implode(', ', $usedIn)); + $app->enqueueMessage($msg, 'error'); + } + } + + if (empty($pks)) { + // Nothing left to delete + return true; + } + + return parent::delete($pks); + } /** * Method to test whether a record can be deleted. @@ -65,61 +141,6 @@ protected function canDelete($record) } } - // Check if the access level is being used by any content. - if ($this->levelsInUse === null) { - // Populate the list once. - $this->levelsInUse = []; - - $db = $this->getDatabase(); - $query = $db->getQuery(true) - ->select('DISTINCT access'); - - // Get all the tables and the prefix - $tables = $db->getTableList(); - $prefix = $db->getPrefix(); - - foreach ($tables as $table) { - // Get all of the columns in the table - $fields = $db->getTableColumns($table); - - /** - * We are looking for the access field. If custom tables are using something other - * than the 'access' field they are on their own unfortunately. - * Also make sure the table prefix matches the live db prefix (eg, it is not a "bak_" table) - */ - if (strpos($table, $prefix) === 0 && isset($fields['access'])) { - // Lookup the distinct values of the field. - $query->clear('from') - ->from($db->quoteName($table)); - $db->setQuery($query); - - try { - $values = $db->loadColumn(); - } catch (\RuntimeException $e) { - $this->setError($e->getMessage()); - - return false; - } - - $this->levelsInUse = array_merge($this->levelsInUse, $values); - - // @todo Could assemble an array of the tables used by each view level list those, - // giving the user a clue in the error where to look. - } - } - - // Get uniques. - $this->levelsInUse = array_unique($this->levelsInUse); - - // Ok, after all that we are ready to check the record :) - } - - if (\in_array($record->id, $this->levelsInUse)) { - $this->setError(Text::sprintf('COM_USERS_ERROR_VIEW_LEVEL_IN_USE', $record->id, $record->title)); - - return false; - } - return parent::canDelete($record); } diff --git a/administrator/language/en-GB/com_users.ini b/administrator/language/en-GB/com_users.ini index bc40ad27db63..be813a51a60c 100644 --- a/administrator/language/en-GB/com_users.ini +++ b/administrator/language/en-GB/com_users.ini @@ -104,7 +104,8 @@ COM_USERS_ERROR_LEVELS_NOLEVELS_SELECTED="No View Permission Level(s) selected." COM_USERS_ERROR_NO_ADDITIONS="The selected user(s) are already assigned to the selected group." COM_USERS_ERROR_NOT_IN_GROUP="The selected user(s) are not in the selected group." COM_USERS_ERROR_ONLY_ONE_GROUP="A user must belong to at least one group." -COM_USERS_ERROR_VIEW_LEVEL_IN_USE="You can't delete the view access level '%d:%s' because it is being used by content." +COM_USERS_ERROR_VIEW_LEVEL_IN_USE="You can't delete the view access level(s)" +COM_USERS_ERROR_VIEW_LEVEL_IN_USE_DETAILS="Level with ID %d is being used in the database tables: %s." COM_USERS_FIELDS_USER_FIELDS_TITLE="Users: Fields" COM_USERS_FIELDS_USER_FIELD_ADD_TITLE="Users: New Field" COM_USERS_FIELDS_USER_FIELD_EDIT_TITLE="Users: Edit Field" ```
zero-24 commented 1 month ago

PR #3235