_item = $item; $this->manager = Yii::$app->authManager; if ($item !== null) { $this->name = $item->name; $this->type = $item->type; $this->description = $item->description; $this->ruleName = $item->ruleName; $this->data = $item->data === null ? null : Json::encode($item->data); } parent::__construct($config); } /** * @inheritdoc */ public function rules(): array { return [ [['name', 'description', 'data', 'ruleName'], 'trim'], [['name', 'type'], 'required'], ['ruleName', 'checkRule'], ['name', 'validateName', 'when' => function () { return $this->getIsNewRecord() || ($this->_item->name != $this->name); }], ['type', 'integer'], [['description', 'data', 'ruleName'], 'default'], ['name', 'string', 'max' => 64], ]; } /** * Validate item name */ public function validateName() { $value = $this->name; if ($this->manager->getRole($value) !== null || $this->manager->getPermission($value) !== null) { $message = Yii::t('yii', '{attribute} "{value}" has already been taken.'); $params = [ 'attribute' => $this->getAttributeLabel('name'), 'value' => $value, ]; $this->addError('name', Yii::$app->getI18n()->format($message, $params, Yii::$app->language)); } } /** * Check for rule */ public function checkRule() { $name = $this->ruleName; if (!$this->manager->getRule($name)) { try { $rule = Yii::createObject($name); if ($rule instanceof Rule) { $rule->name = $name; $this->manager->add($rule); } else { $this->addError('ruleName', Yii::t('yii2mod.rbac', 'Invalid rule "{value}"', ['value' => $name])); } } catch (\Exception $exc) { $this->addError('ruleName', Yii::t('yii2mod.rbac', 'Rule "{value}" does not exists', ['value' => $name])); } } } /** * @inheritdoc */ public function attributeLabels(): array { return [ 'name' => Yii::t('yii2mod.rbac', 'Name'), 'type' => Yii::t('yii2mod.rbac', 'Type'), 'description' => Yii::t('yii2mod.rbac', 'Description'), 'ruleName' => Yii::t('yii2mod.rbac', 'Rule Name'), 'data' => Yii::t('yii2mod.rbac', 'Data'), ]; } /** * Check if is new record. * * @return bool */ public function getIsNewRecord(): bool { return $this->_item === null; } /** * Find role * * @param string $id * * @return null|\self */ public static function find(string $id) { $item = Yii::$app->authManager->getRole($id); if ($item !== null) { return new self($item); } return null; } /** * Save role to [[\yii\rbac\authManager]] * * @return bool */ public function save(): bool { if ($this->validate()) { if ($this->_item === null) { if ($this->type == Item::TYPE_ROLE) { $this->_item = $this->manager->createRole($this->name); } else { $this->_item = $this->manager->createPermission($this->name); } $isNew = true; $oldName = false; } else { $isNew = false; $oldName = $this->_item->name; } $this->_item->name = $this->name; $this->_item->description = $this->description; $this->_item->ruleName = $this->ruleName; $this->_item->data = Json::decode($this->data); if ($isNew) { $this->manager->add($this->_item); } else { $this->manager->update($oldName, $this->_item); } return true; } return false; } /** * Add child to Item * * @param array $items * * @return bool */ public function addChildren(array $items): bool { if ($this->_item) { foreach ($items as $name) { $child = $this->manager->getPermission($name); if (empty($child) && $this->type == Item::TYPE_ROLE) { $child = $this->manager->getRole($name); } $this->manager->addChild($this->_item, $child); } } return true; } /** * Remove child from an item * * @param array $items * * @return bool */ public function removeChildren(array $items): bool { if ($this->_item !== null) { foreach ($items as $name) { $child = $this->manager->getPermission($name); if (empty($child) && $this->type == Item::TYPE_ROLE) { $child = $this->manager->getRole($name); } $this->manager->removeChild($this->_item, $child); } } return true; } /** * Get all available and assigned roles, permission and routes * * @return array */ public function getItems(): array { $available = []; $assigned = []; if ($this->type == Item::TYPE_ROLE) { foreach (array_keys($this->manager->getRoles()) as $name) { $available[$name] = 'role'; } } foreach (array_keys($this->manager->getPermissions()) as $name) { $available[$name] = $name[0] == '/' ? 'route' : 'permission'; } foreach ($this->manager->getChildren($this->_item->name) as $item) { $assigned[$item->name] = $item->type == 1 ? 'role' : ($item->name[0] == '/' ? 'route' : 'permission'); unset($available[$item->name]); } unset($available[$this->name]); return [ 'available' => $available, 'assigned' => $assigned, ]; } /** * @return null|Item */ public function getItem() { return $this->_item; } /** * Get type name * * @param mixed $type * * @return string|array */ public static function getTypeName($type = null) { $result = [ Item::TYPE_PERMISSION => 'Permission', Item::TYPE_ROLE => 'Role', ]; if ($type === null) { return $result; } return $result[$type]; } }