Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make possible to create new user role #352

Open
wants to merge 14 commits into
base: 2.5
Choose a base branch
from
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,23 @@ $user = User::find(1);
echo $user->user_login;
```

### Creating Roles

You can also create a new role based on a pre-existent one. For example, to create a role `foo` based on the `editor` role:

```php
$manager = new RoleManager();
$role = $manager->from('editor')->create('foo', [
'edit_pages' => false,
'edit_others_pages' => false,
]);

echo $role['name'];
var_dump($role['capabilities']); // array
```

The new capabilities array you send in the `create()` method will override the `editor` capabilities. You can also add new capabilities as well.

## <a id="auth"></a>Authentication

### Using Laravel
Expand Down
4 changes: 2 additions & 2 deletions src/Model/Option.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,11 @@ public function getValueAttribute()
/**
* @param string $key
* @param mixed $value
* @return Option
* @return Option|\Illuminate\Database\Eloquent\Model
*/
public static function add($key, $value)
{
return static::create([
return static::query()->create([
'option_name' => $key,
'option_value' => is_array($value) ? serialize($value) : $value,
]);
Expand Down
91 changes: 91 additions & 0 deletions src/Services/RoleManager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?php

namespace Corcel\Services;

use Corcel\Model\Option;
use Illuminate\Support\Arr;

/**
* Class RoleManager
*
* @package Corcel\Services
* @author Junior Grossi <juniorgro@gmail.com>
* @todo Update, delete and list roles
*/
class RoleManager
{
/**
* @var string
*/
protected $optionKey = 'wp_user_roles';

/**
* @var array
*/
protected $option = [];

/**
* @var array
*/
protected $capabilities = [];

/**
* Create a new RoleManager instance
*/
public function __construct()
{
$this->option = $this->fetch();
}

/**
* @param string $role
* @return $this
*/
public function from($role)
{
$this->capabilities = Arr::get(
$this->get($role), 'capabilities'
);

return $this;
}

/**
* @param string $role
* @return array
*/
public function get($role)
{
return Arr::get($this->option->value, $role);
}

/**
* @param string $name
* @param array $capabilities
* @return array
*/
public function create($name, array $capabilities)
{
$key = str_slug($name, '_');
$roles = $this->option->value;

$roles[$key] = $role = [
'name' => $name,
'capabilities' => array_merge($this->capabilities, $capabilities),
];

$this->option->option_value = serialize($roles);

return $this->option->save() ? $role : null;
}

/**
* @return Option|\Illuminate\Database\Eloquent\Model|null|static
*/
private function fetch()
{
return Option::query()->where([
'option_name' => $this->optionKey,
])->first();
}
}
82 changes: 82 additions & 0 deletions tests/Unit/Services/RoleManagerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
<?php

namespace Corcel\Tests\Services;

use Corcel\Model\Option;
use Corcel\Services\RoleManager;
use Corcel\Tests\TestCase;

/**
* Class RoleManagerTest
*
* @package Corcel\Tests\Services
* @author Junior Grossi <juniorgro@gmail.com>
*/
class RoleManagerTest extends TestCase
{
/**
* @return void
*/
public function setUp()
{
parent::setUp();
$this->insertDefaultRoles();
}

/**
* @test
*/
public function it_creates_a_new_role_based_on_a_previous_one()
{
(new RoleManager)->from('editor')
->create('foo', [
'edit_pages' => false,
'edit_others_pages' => false,
]);

$role = (new RoleManager)->get('foo');

$this->assertFalse($role['capabilities']['edit_pages']);
$this->assertFalse($role['capabilities']['edit_others_pages']);
$this->assertRoleEquals('foo', $role);
}

/**
* @test
*/
public function it_can_create_a_new_role_without_setting_from()
{
(new RoleManager)->create('foo', [
'edit_pages' => true,
'edit_others_pages' => true,
]);

$role = (new RoleManager)->get('foo');

$this->assertTrue($role['capabilities']['edit_pages']);
$this->assertTrue($role['capabilities']['edit_others_pages']);
$this->assertCount(2, $role['capabilities']);
$this->assertRoleEquals('foo', $role);
}

/**
* @return Option
*/
private function insertDefaultRoles()
{
$roles = unserialize('a:5:{s:13:"administrator";a:2:{s:4:"name";s:13:"Administrator";s:12:"capabilities";a:61:{s:13:"switch_themes";b:1;s:11:"edit_themes";b:1;s:16:"activate_plugins";b:1;s:12:"edit_plugins";b:1;s:10:"edit_users";b:1;s:10:"edit_files";b:1;s:14:"manage_options";b:1;s:17:"moderate_comments";b:1;s:17:"manage_categories";b:1;s:12:"manage_links";b:1;s:12:"upload_files";b:1;s:6:"import";b:1;s:15:"unfiltered_html";b:1;s:10:"edit_posts";b:1;s:17:"edit_others_posts";b:1;s:20:"edit_published_posts";b:1;s:13:"publish_posts";b:1;s:10:"edit_pages";b:1;s:4:"read";b:1;s:8:"level_10";b:1;s:7:"level_9";b:1;s:7:"level_8";b:1;s:7:"level_7";b:1;s:7:"level_6";b:1;s:7:"level_5";b:1;s:7:"level_4";b:1;s:7:"level_3";b:1;s:7:"level_2";b:1;s:7:"level_1";b:1;s:7:"level_0";b:1;s:17:"edit_others_pages";b:1;s:20:"edit_published_pages";b:1;s:13:"publish_pages";b:1;s:12:"delete_pages";b:1;s:19:"delete_others_pages";b:1;s:22:"delete_published_pages";b:1;s:12:"delete_posts";b:1;s:19:"delete_others_posts";b:1;s:22:"delete_published_posts";b:1;s:20:"delete_private_posts";b:1;s:18:"edit_private_posts";b:1;s:18:"read_private_posts";b:1;s:20:"delete_private_pages";b:1;s:18:"edit_private_pages";b:1;s:18:"read_private_pages";b:1;s:12:"delete_users";b:1;s:12:"create_users";b:1;s:17:"unfiltered_upload";b:1;s:14:"edit_dashboard";b:1;s:14:"update_plugins";b:1;s:14:"delete_plugins";b:1;s:15:"install_plugins";b:1;s:13:"update_themes";b:1;s:14:"install_themes";b:1;s:11:"update_core";b:1;s:10:"list_users";b:1;s:12:"remove_users";b:1;s:13:"promote_users";b:1;s:18:"edit_theme_options";b:1;s:13:"delete_themes";b:1;s:6:"export";b:1;}}s:6:"editor";a:2:{s:4:"name";s:6:"Editor";s:12:"capabilities";a:34:{s:17:"moderate_comments";b:1;s:17:"manage_categories";b:1;s:12:"manage_links";b:1;s:12:"upload_files";b:1;s:15:"unfiltered_html";b:1;s:10:"edit_posts";b:1;s:17:"edit_others_posts";b:1;s:20:"edit_published_posts";b:1;s:13:"publish_posts";b:1;s:10:"edit_pages";b:1;s:4:"read";b:1;s:7:"level_7";b:1;s:7:"level_6";b:1;s:7:"level_5";b:1;s:7:"level_4";b:1;s:7:"level_3";b:1;s:7:"level_2";b:1;s:7:"level_1";b:1;s:7:"level_0";b:1;s:17:"edit_others_pages";b:1;s:20:"edit_published_pages";b:1;s:13:"publish_pages";b:1;s:12:"delete_pages";b:1;s:19:"delete_others_pages";b:1;s:22:"delete_published_pages";b:1;s:12:"delete_posts";b:1;s:19:"delete_others_posts";b:1;s:22:"delete_published_posts";b:1;s:20:"delete_private_posts";b:1;s:18:"edit_private_posts";b:1;s:18:"read_private_posts";b:1;s:20:"delete_private_pages";b:1;s:18:"edit_private_pages";b:1;s:18:"read_private_pages";b:1;}}s:6:"author";a:2:{s:4:"name";s:6:"Author";s:12:"capabilities";a:10:{s:12:"upload_files";b:1;s:10:"edit_posts";b:1;s:20:"edit_published_posts";b:1;s:13:"publish_posts";b:1;s:4:"read";b:1;s:7:"level_2";b:1;s:7:"level_1";b:1;s:7:"level_0";b:1;s:12:"delete_posts";b:1;s:22:"delete_published_posts";b:1;}}s:11:"contributor";a:2:{s:4:"name";s:11:"Contributor";s:12:"capabilities";a:5:{s:10:"edit_posts";b:1;s:4:"read";b:1;s:7:"level_1";b:1;s:7:"level_0";b:1;s:12:"delete_posts";b:1;}}s:10:"subscriber";a:2:{s:4:"name";s:10:"Subscriber";s:12:"capabilities";a:2:{s:4:"read";b:1;s:7:"level_0";b:1;}}}');

return Option::add('wp_user_roles', $roles);
}

/**
* @param string $key
* @param array $role
*/
private function assertRoleEquals($key, array $role)
{
$roles = Option::get('wp_user_roles');

$this->assertEquals($roles[$key], $role);
}
}