* @since 2.0 */ abstract class BaseManager extends Component implements ManagerInterface { /** * @var array a list of role names that are assigned to every user automatically without calling [[assign()]]. */ public $defaultRoles = []; /** * Returns the named auth item. * @param string $name the auth item name. * @return Item the auth item corresponding to the specified name. Null is returned if no such item. */ abstract protected function getItem($name); /** * Returns the items of the specified type. * @param int $type the auth item type (either [[Item::TYPE_ROLE]] or [[Item::TYPE_PERMISSION]] * @return Item[] the auth items of the specified type. */ abstract protected function getItems($type); /** * Adds an auth item to the RBAC system. * @param Item $item the item to add * @return bool whether the auth item is successfully added to the system * @throws \Exception if data validation or saving fails (such as the name of the role or permission is not unique) */ abstract protected function addItem($item); /** * Adds a rule to the RBAC system. * @param Rule $rule the rule to add * @return bool whether the rule is successfully added to the system * @throws \Exception if data validation or saving fails (such as the name of the rule is not unique) */ abstract protected function addRule($rule); /** * Removes an auth item from the RBAC system. * @param Item $item the item to remove * @return bool whether the role or permission is successfully removed * @throws \Exception if data validation or saving fails (such as the name of the role or permission is not unique) */ abstract protected function removeItem($item); /** * Removes a rule from the RBAC system. * @param Rule $rule the rule to remove * @return bool whether the rule is successfully removed * @throws \Exception if data validation or saving fails (such as the name of the rule is not unique) */ abstract protected function removeRule($rule); /** * Updates an auth item in the RBAC system. * @param string $name the name of the item being updated * @param Item $item the updated item * @return bool whether the auth item is successfully updated * @throws \Exception if data validation or saving fails (such as the name of the role or permission is not unique) */ abstract protected function updateItem($name, $item); /** * Updates a rule to the RBAC system. * @param string $name the name of the rule being updated * @param Rule $rule the updated rule * @return bool whether the rule is successfully updated * @throws \Exception if data validation or saving fails (such as the name of the rule is not unique) */ abstract protected function updateRule($name, $rule); /** * @inheritdoc */ public function createRole($name) { $role = new Role(); $role->name = $name; return $role; } /** * @inheritdoc */ public function createPermission($name) { $permission = new Permission(); $permission->name = $name; return $permission; } /** * @inheritdoc */ public function add($object) { if ($object instanceof Item) { if ($object->ruleName && $this->getRule($object->ruleName) === null) { $rule = \Yii::createObject($object->ruleName); $rule->name = $object->ruleName; $this->addRule($rule); } return $this->addItem($object); } elseif ($object instanceof Rule) { return $this->addRule($object); } else { throw new InvalidParamException('Adding unsupported object type.'); } } /** * @inheritdoc */ public function remove($object) { if ($object instanceof Item) { return $this->removeItem($object); } elseif ($object instanceof Rule) { return $this->removeRule($object); } else { throw new InvalidParamException('Removing unsupported object type.'); } } /** * @inheritdoc */ public function update($name, $object) { if ($object instanceof Item) { if ($object->ruleName && $this->getRule($object->ruleName) === null) { $rule = \Yii::createObject($object->ruleName); $rule->name = $object->ruleName; $this->addRule($rule); } return $this->updateItem($name, $object); } elseif ($object instanceof Rule) { return $this->updateRule($name, $object); } else { throw new InvalidParamException('Updating unsupported object type.'); } } /** * @inheritdoc */ public function getRole($name) { $item = $this->getItem($name); return $item instanceof Item && $item->type == Item::TYPE_ROLE ? $item : null; } /** * @inheritdoc */ public function getPermission($name) { $item = $this->getItem($name); return $item instanceof Item && $item->type == Item::TYPE_PERMISSION ? $item : null; } /** * @inheritdoc */ public function getRoles() { return $this->getItems(Item::TYPE_ROLE); } /** * Returns defaultRoles as array of Role objects * @since 2.0.12 * @return Role[] default roles. The array is indexed by the role names */ public function getDefaultRoleInstances() { $result = []; foreach ($this->defaultRoles as $roleName) { $result[$roleName] = $this->createRole($roleName); } return $result; } /** * @inheritdoc */ public function getPermissions() { return $this->getItems(Item::TYPE_PERMISSION); } /** * Executes the rule associated with the specified auth item. * * If the item does not specify a rule, this method will return true. Otherwise, it will * return the value of [[Rule::execute()]]. * * @param string|int $user the user ID. This should be either an integer or a string representing * the unique identifier of a user. See [[\yii\web\User::id]]. * @param Item $item the auth item that needs to execute its rule * @param array $params parameters passed to [[CheckAccessInterface::checkAccess()]] and will be passed to the rule * @return bool the return value of [[Rule::execute()]]. If the auth item does not specify a rule, true will be returned. * @throws InvalidConfigException if the auth item has an invalid rule. */ protected function executeRule($user, $item, $params) { if ($item->ruleName === null) { return true; } $rule = $this->getRule($item->ruleName); if ($rule instanceof Rule) { return $rule->execute($user, $item, $params); } else { throw new InvalidConfigException("Rule not found: {$item->ruleName}"); } } /** * Checks whether array of $assignments is empty and [[defaultRoles]] property is empty as well * * @param Assignment[] $assignments array of user's assignments * @return bool whether array of $assignments is empty and [[defaultRoles]] property is empty as well * @since 2.0.11 */ protected function hasNoAssignments(array $assignments) { return empty($assignments) && empty($this->defaultRoles); } }