public function getJunctionPermissions($Where, $JunctionTable = null, $LimitToSuffix = '', $Options = array())
{
$Namespaces = $this->GetAllowedPermissionNamespaces();
$RoleID = val('RoleID', $Where, null);
$JunctionID = val('JunctionID', $Where, null);
$limitToDefault = val('LimitToDefault', $Options);
$SQL = $this->SQL;
// Load all of the default junction permissions.
$SQL->select('*')->from('Permission p')->where('p.RoleID', 0);
if (is_null($JunctionTable)) {
$SQL->where('p.JunctionTable is not null');
} else {
$SQL->where('p.JunctionTable', $JunctionTable);
}
// Get the disabled permissions.
$DisabledPermissions = c('Garden.Permissions.Disabled');
if (is_array($DisabledPermissions)) {
$DisabledWhere = array();
foreach ($DisabledPermissions as $TableName => $Disabled) {
if ($Disabled) {
$DisabledWhere[] = $TableName;
}
}
if (count($DisabledWhere) > 0) {
$SQL->whereNotIn('JunctionTable', $DisabledWhere);
}
}
$Data = $SQL->get()->resultArray();
$Result = array();
foreach ($Data as $Row) {
$JunctionTable = $Row['JunctionTable'];
$JunctionColumn = $Row['JunctionColumn'];
unset($Row['PermissionID'], $Row['RoleID'], $Row['JunctionTable'], $Row['JunctionColumn'], $Row['JunctionID']);
// If the junction column is not the primary key then we must figure out and limit the permissions.
if ($limitToDefault === false && $JunctionColumn != $JunctionTable . 'ID') {
$JuncIDs = $SQL->Distinct(true)->select("p.{$JunctionTable}ID")->select("c.{$JunctionColumn}")->select('p.Name')->from("{$JunctionTable} c")->join("{$JunctionTable} p", "c.{$JunctionColumn} = p.{$JunctionTable}ID", 'left')->get()->resultArray();
foreach ($JuncIDs as &$JuncRow) {
if (!$JuncRow[$JunctionTable . 'ID']) {
$JuncRow[$JunctionTable . 'ID'] = -1;
}
}
}
if (!empty($RoleID) || !empty($JunctionID)) {
// Figure out which columns to select.
foreach ($Row as $PermissionName => $Value) {
if (!($Value & 2)) {
continue;
// permission not applicable to this junction table
}
if (!empty($LimitToSuffix) && substr($PermissionName, -strlen($LimitToSuffix)) != $LimitToSuffix) {
continue;
// permission not in $LimitToSuffix
}
if ($index = strpos($PermissionName, '.')) {
if (!in_array(substr($PermissionName, 0, $index), $Namespaces) && !in_array(substr($PermissionName, 0, strrpos($PermissionName, '.')), $Namespaces)) {
continue;
// permission not in allowed namespaces
}
}
// If we are viewing the permissions by junction table (ex. Category) then set the default value when a permission row doesn't exist.
if (!$RoleID && $JunctionColumn != $JunctionTable . 'ID' && val('AddDefaults', $Options)) {
$DefaultValue = $Value & 1 ? 1 : 0;
} else {
$DefaultValue = 0;
}
$SQL->select("p.`{$PermissionName}`, {$DefaultValue}", 'coalesce', $PermissionName);
}
if (!empty($RoleID)) {
$roleIDs = (array) $RoleID;
if (count($roleIDs) === 1) {
$roleOn = 'p.RoleID = ' . $this->SQL->Database->connection()->quote(reset($roleIDs));
} else {
$roleIDs = array_map(array($this->SQL->Database->connection(), 'quote'), $roleIDs);
$roleOn = 'p.RoleID in (' . implode(',', $roleIDs) . ')';
}
// Get the permissions for the junction table.
$SQL->select('junc.Name')->select('junc.' . $JunctionColumn, '', 'JunctionID')->from($JunctionTable . ' junc')->join('Permission p', "p.JunctionID = junc.{$JunctionColumn} and {$roleOn}", 'left')->orderBy('junc.Sort')->orderBy('junc.Name');
if ($limitToDefault) {
$SQL->where("junc.{$JunctionTable}ID", -1);
} elseif (isset($JuncIDs)) {
$SQL->whereIn("junc.{$JunctionTable}ID", array_column($JuncIDs, "{$JunctionTable}ID"));
}
$JuncData = $SQL->get()->resultArray();
} elseif (!empty($JunctionID)) {
// Here we are getting permissions for all roles.
$JuncData = $SQL->select('r.RoleID, r.Name, r.CanSession')->from('Role r')->join('Permission p', "p.RoleID = r.RoleID and p.JunctionTable = '{$JunctionTable}' and p.JunctionColumn = '{$JunctionColumn}' and p.JunctionID = {$JunctionID}", 'left')->orderBy('r.Sort, r.Name')->get()->resultArray();
}
} else {
$JuncData = [];
}
// Add all of the necessary information back to the result.
foreach ($JuncData as $JuncRow) {
$JuncRow['JunctionTable'] = $JunctionTable;
$JuncRow['JunctionColumn'] = $JunctionColumn;
if (!is_null($JunctionID)) {
$JuncRow['JunctionID'] = $JunctionID;
}
if ($JuncRow['JunctionID'] < 0) {
$JuncRow['Name'] = sprintf(t('Default %s Permissions'), t('Permission.' . $JunctionTable, $JunctionTable));
}
if (array_key_exists('CanSession', $JuncRow)) {
if (!$JuncRow['CanSession']) {
// Remove view permissions.
foreach ($JuncRow as $PermissionName => $Value) {
if (strpos($PermissionName, '.') !== false && strpos($PermissionName, '.View') === false) {
unset($JuncRow[$PermissionName]);
}
}
}
unset($JuncRow['CanSession']);
}
if (!$RoleID && !$JunctionID && array_key_exists(0, $Data)) {
// Set all of the default permissions for a new role.
foreach ($JuncRow as $PermissionName => $Value) {
if (val($PermissionName, $Data[0], 0) & 1) {
$JuncRow[$PermissionName] = 1;
}
}
}
$Result[] = $JuncRow;
}
}
return $Result;
}