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"
```
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" ```