public function define($PermissionNames, $Type = 'tinyint', $JunctionTable = null, $JunctionColumn = null)
{
$PermissionNames = (array) $PermissionNames;
$Structure = $this->Database->structure();
$Structure->table('Permission');
$DefaultPermissions = array();
$NewColumns = array();
foreach ($PermissionNames as $Key => $Value) {
if (is_numeric($Key)) {
// Only got a permissions name with no default.
$PermissionName = $Value;
$DefaultPermissions[$PermissionName] = 2;
} else {
$PermissionName = $Key;
if ($Value === 0) {
// "Off for all"
$DefaultPermissions[$PermissionName] = 2;
} elseif ($Value === 1) {
// "On for all"
$DefaultPermissions[$PermissionName] = 3;
} elseif (!$Structure->columnExists($Value) && array_key_exists($Value, $PermissionNames)) {
// Mapped to an explicitly-defined permission.
$DefaultPermissions[$PermissionName] = $PermissionNames[$Value] ? 3 : 2;
} else {
// Mapped to another permission for which we don't have the value.
$DefaultPermissions[$PermissionName] = "`{$Value}`";
}
}
if (!$Structure->columnExists($PermissionName)) {
$Default = $DefaultPermissions[$PermissionName];
$NewColumns[$PermissionName] = is_numeric($Default) ? $Default - 2 : $Default;
}
// Define the column.
$Structure->column($PermissionName, $Type, 0);
}
$Structure->set(false, false);
// Detect an initial permission setup by seeing if our placeholder row exists yet.
$DefaultRow = $this->SQL->select('*')->from('Permission')->where('RoleID', 0)->where('JunctionTable is null')->orderBy('RoleID')->limit(1)->get()->firstRow(DATASET_TYPE_ARRAY);
// If this is our initial setup, map missing permissions to off.
// Otherwise we'd be left with placeholders in our final query, which would cause a strict mode failure.
if (!$DefaultRow) {
$DefaultPermissions = array_map(function ($Value) {
// All non-numeric values are converted to "off" flag.
return is_numeric($Value) ? $Value : 2;
}, $DefaultPermissions);
}
// Set the default permissions on the placeholder.
$this->SQL->set($this->_backtick($DefaultPermissions), '', false)->replace('Permission', array(), array('RoleID' => 0, 'JunctionTable' => $JunctionTable, 'JunctionColumn' => $JunctionColumn), true);
// Set the default permissions for new columns on all roles.
if (count($NewColumns) > 0) {
$Where = array('RoleID <>' => 0);
if (!$JunctionTable) {
$Where['JunctionTable'] = null;
} else {
$Where['JunctionTable'] = $JunctionTable;
}
$this->SQL->set($this->_backtick($NewColumns), '', false)->put('Permission', array(), $Where);
}
// Flush permissions cache & loaded schema.
$this->clearPermissions();
if ($this->Schema) {
// Redefine the schema if it has been defined to reflect the permissions that were just added.
$this->Schema = null;
$this->defineSchema();
}
}