julienmonnerie/kirby/src/Cms/Roles.php
2023-06-01 16:54:20 +02:00

152 lines
3.2 KiB
PHP

<?php
namespace Kirby\Cms;
/**
* Extension of the Collection class that
* introduces `Roles::factory()` to convert an
* array of role definitions into a proper
* collection with Role objects. It also has
* a `Roles::load()` method that handles loading
* role definitions from disk.
*
* @package Kirby Cms
* @author Bastian Allgeier <bastian@getkirby.com>
* @link https://getkirby.com
* @copyright Bastian Allgeier
* @license https://getkirby.com/license
*/
class Roles extends Collection
{
/**
* All registered roles methods
*
* @var array
*/
public static $methods = [];
/**
* Returns a filtered list of all
* roles that can be created by the
* current user
*
* @return $this|static
* @throws \Exception
*/
public function canBeChanged()
{
if (App::instance()->user()) {
return $this->filter(function ($role) {
$newUser = new User([
'email' => 'test@getkirby.com',
'role' => $role->id()
]);
return $newUser->permissions()->can('changeRole');
});
}
return $this;
}
/**
* Returns a filtered list of all
* roles that can be created by the
* current user
*
* @return $this|static
* @throws \Exception
*/
public function canBeCreated()
{
if (App::instance()->user()) {
return $this->filter(function ($role) {
$newUser = new User([
'email' => 'test@getkirby.com',
'role' => $role->id()
]);
return $newUser->permissions()->can('create');
});
}
return $this;
}
/**
* @param array $roles
* @param array $inject
* @return static
*/
public static function factory(array $roles, array $inject = [])
{
$collection = new static();
// read all user blueprints
foreach ($roles as $props) {
$role = Role::factory($props, $inject);
$collection->set($role->id(), $role);
}
// always include the admin role
if ($collection->find('admin') === null) {
$collection->set('admin', Role::admin());
}
// return the collection sorted by name
return $collection->sort('name', 'asc');
}
/**
* @param string|null $root
* @param array $inject
* @return static
*/
public static function load(string $root = null, array $inject = [])
{
$kirby = App::instance();
$roles = new static();
// load roles from plugins
foreach ($kirby->extensions('blueprints') as $blueprintName => $blueprint) {
if (substr($blueprintName, 0, 6) !== 'users/') {
continue;
}
// callback option can be return array or blueprint file path
if (is_callable($blueprint) === true) {
$blueprint = $blueprint($kirby);
}
if (is_array($blueprint) === true) {
$role = Role::factory($blueprint, $inject);
} else {
$role = Role::load($blueprint, $inject);
}
$roles->set($role->id(), $role);
}
// load roles from directory
if ($root !== null) {
foreach (glob($root . '/*.yml') as $file) {
$filename = basename($file);
if ($filename === 'default.yml') {
continue;
}
$role = Role::load($file, $inject);
$roles->set($role->id(), $role);
}
}
// always include the admin role
if ($roles->find('admin') === null) {
$roles->set('admin', Role::admin($inject));
}
// return the collection sorted by name
return $roles->sort('name', 'asc');
}
}