protected function getRestrictionsByAttributes(Collection $attributesCollection, Options $options): array
{
$restrictionData = [];
$userDepartmentIDs = $this->getUserDepartmentIDs($attributesCollection->getUserId());
$permissionEntityTypes = $attributesCollection->getAllowedEntityTypes();
foreach ($permissionEntityTypes as $permissionEntityType)
{
$entityAttributes = $attributesCollection->getByEntityType($permissionEntityType);
if (empty($entityAttributes))
{
continue;
}
$permissionSets = [];
foreach ($entityAttributes as $attributes)
{
if (empty($attributes))
{
continue;
}
$permissionSet = [
'USER_ID' => 0,
'DEPARTMENT_IDS' => [],
'PROGRESS_STEPS' => [],
'OPENED' => false,
];
for ($i = 0, $length = count($attributes); $i < $length; $i++)
{
$attributeValue = $attributes[$i];
$parsedAttributeValue = '';
if (
$this->controller->hasProgressSteps()
&& $this->controller->tryParseProgressStep($attributeValue, $parsedAttributeValue)
&& $parsedAttributeValue != ''
)
{
$permissionSet['PROGRESS_STEPS'][] = $parsedAttributeValue;
}
elseif ($attributeValue === 'O')
{
$permissionSet['OPENED'] = true;
}
elseif ($this->tryParseUser($attributeValue, $parsedAttributeValue) && $parsedAttributeValue > 0)
{
$permissionSet['USER_ID'] = (int)$parsedAttributeValue;
}
elseif ($this->tryParseDepartment($attributeValue, $parsedAttributeValue) && $parsedAttributeValue > 0)
{
$permissionSet['DEPARTMENT_IDS'][] = (int)$parsedAttributeValue;
}
}
$permissionSets[] = $permissionSet;
if ($permissionSet['OPENED']) // if opened are allowed, also my and my department are allowed
{
$permissionSets[] = [
'USER_ID' => $attributesCollection->getUserId(),
'DEPARTMENT_IDS' => [],
'PROGRESS_STEPS' => $permissionSet['PROGRESS_STEPS'],
'OPENED' => false,
];
if (!empty($userDepartmentIDs))
{
$permissionSets[] = [
'USER_ID' => 0,
'DEPARTMENT_IDS' => $userDepartmentIDs,
'PROGRESS_STEPS' => $permissionSet['PROGRESS_STEPS'],
'OPENED' => false,
];
}
}
}
$permissionFurl = [];
foreach ($permissionSets as $permissionSet)
{
$userID = $permissionSet['USER_ID'];
$departmentIDs = $permissionSet['DEPARTMENT_IDS'];
$isOpened = $permissionSet['OPENED'];
if (!empty($departmentIDs))
{
sort($departmentIDs, SORT_NUMERIC);
}
$hash = md5(
'U:' . $userID
. 'D:' . (!empty($departmentIDs) ? implode(',', $departmentIDs) : '-')
. 'O:' . ($isOpened ? 'Y' : 'N'));
if (!isset($permissionFurl[$hash]))
{
$permissionFurl[$hash] = $permissionSet;
}
elseif (!empty($permissionSet['PROGRESS_STEPS']))
{
$permissionFurl[$hash]['PROGRESS_STEPS'] = array_merge(
$permissionFurl[$hash]['PROGRESS_STEPS'],
array_diff(
$permissionSet['PROGRESS_STEPS'],
$permissionFurl[$hash]['PROGRESS_STEPS']
)
);
}
}
$permissionSets = array_values($permissionFurl);
$restrictionData[$permissionEntityType] = [];
foreach ($permissionSets as $permissionSet)
{
$hash = '-';
$progressSteps = $permissionSet['PROGRESS_STEPS'];
if (!empty($progressSteps))
{
sort($progressSteps, SORT_STRING);
$hash = md5(implode(',', $permissionSet['PROGRESS_STEPS']));
}
if (!isset($restrictionData[$permissionEntityType][$hash]))
{
$restriction = ['PROGRESS_STEPS' => $progressSteps];
}
else
{
$restriction = $restrictionData[$permissionEntityType][$hash];
}
if ($permissionSet['OPENED'])
{
$restriction['OPENED'] = true;
}
$userID = $permissionSet['USER_ID'];
if ($userID > 0)
{
if (!isset($restriction['USER_IDS']))
{
$restriction['USER_IDS'] = [];
}
if (!in_array($userID, $restriction['USER_IDS'], true))
{
$restriction['USER_IDS'][] = $userID;
}
}
if (!empty($permissionSet['DEPARTMENT_IDS']))
{
if (!isset($restriction['USER_IDS']))
{
$restriction['USER_IDS'] = [];
}
$restriction['USER_IDS'] = array_unique(
array_merge(
$restriction['USER_IDS'],
$this->getDepartmentsUsers($permissionSet['DEPARTMENT_IDS'])
)
);
}
$restrictionData[$permissionEntityType][$hash] = $restriction;
}
}
$canSkipCategoryRestrictions = false;
if ($options->canSkipCheckOtherEntityTypes())
{
$canSkipCategoryRestrictions = $attributesCollection->areAllEntityTypesAllowed();
if ($canSkipCategoryRestrictions)
{
foreach ($restrictionData as $restrictions)
{
if (empty($restrictions))
{
continue;
}
foreach ($restrictions as $restriction)
{
if (
!(
count($restriction) === 1
&& isset($restriction['PROGRESS_STEPS'])
&& empty($this->getProgressSteps($permissionEntityType, $restriction))
)
)
{
$canSkipCategoryRestrictions = false;
break;
}
}
}
}
}
$restrictionMap = [];
foreach ($restrictionData as $permissionEntityType => $restrictions)
{
if (empty($restrictions))
{
if (!isset($restrictionMap['-']))
{
$restrictionMap['-'] = [];
}
$this->addTypeAndCategoryToRestrictionMap(
$restrictionMap['-'],
$permissionEntityType,
$canSkipCategoryRestrictions
);
continue;
}
foreach ($restrictions as $restriction)
{
$isProcessed = false;
$progressSteps = $this->getProgressSteps($permissionEntityType, $restriction);
$userIDs = isset($restriction['USER_IDS']) ? $restriction['USER_IDS'] : [];
if (!empty($userIDs))
{
sort($userIDs, SORT_NUMERIC);
$hash = md5(
(!empty($progressSteps) ? $permissionEntityType . ':' . implode(',', $progressSteps) : '-')
. 'U:' . (!empty($userIDs) ? implode(',', $userIDs) : '-')
);
if (!isset($restrictionMap[$hash]))
{
$restrictionMap[$hash] = [
'PROGRESS_STEPS' => $progressSteps,
'USER_IDS' => $userIDs,
];
}
$this->addTypeAndCategoryToRestrictionMap(
$restrictionMap[$hash],
$permissionEntityType
);
$isProcessed = true;
}
$isOpened = isset($restriction['OPENED']) && $restriction['OPENED'];
if ($isOpened)
{
$hash = md5(
(!empty($progressSteps) ? $permissionEntityType . ':' . implode(',', $progressSteps) : '-')
. 'O:' . ($isOpened ? 'Y' : 'N')
);
if (!isset($restrictionMap[$hash]))
{
$restrictionMap[$hash] = [
'PROGRESS_STEPS' => $progressSteps,
'OPENED' => true,
];
}
$this->addTypeAndCategoryToRestrictionMap(
$restrictionMap[$hash],
$permissionEntityType
);
$isProcessed = true;
}
if (!$isProcessed)
{
$hash = md5(
!empty($progressSteps) ? $permissionEntityType . ':' . implode(',', $progressSteps) : '-'
);
if (!isset($restrictionMap[$hash]))
{
$restrictionMap[$hash] = [
'PROGRESS_STEPS' => $progressSteps,
];
}
$this->addTypeAndCategoryToRestrictionMap(
$restrictionMap[$hash],
$permissionEntityType,
$canSkipCategoryRestrictions
);
}
}
}
return $restrictionMap;
}