Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
137 changes: 79 additions & 58 deletions administrator/components/com_users/src/Model/LevelModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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);
}

Expand Down
3 changes: 2 additions & 1 deletion administrator/language/en-GB/com_users.ini
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down