Skip to content

Commit

Permalink
Add option to use Laravel's cache or not
Browse files Browse the repository at this point in the history
- Add option to use Laravel's cache #201.
- Reduce cache payload size.
  • Loading branch information
santigarcor committed Sep 29, 2017
1 parent a8bbdd0 commit 227c89d
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 6 deletions.
29 changes: 28 additions & 1 deletion src/Helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

namespace Laratrust;

use Illuminate\Support\Facades\Config;
use InvalidArgumentException;
use Illuminate\Support\Facades\Config;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphPivot;

class Helper
{
Expand Down Expand Up @@ -138,4 +140,29 @@ public static function checkOrSet($option, $array, $possibleValues)

return $array;
}

/**
* Creates a model from an array filled with the class data.
*
* @param string $class
* @param string|\Illuminate\Database\Eloquent\Model $data
* @return \Illuminate\Database\Eloquent\Model
*/
public static function hidrateModel($class, $data)
{
if ($data instanceof Model) {
return $data;
}

$model = (new $class)
->setAttribute('id', $data['id'])
->setAttribute('name', $data['name']);

$model->setRelation(
'pivot',
MorphPivot::fromRawAttributes($model, $data['pivot'], 'pivot_table')
);

return $model;
}
}
8 changes: 7 additions & 1 deletion src/Traits/LaratrustRoleTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,12 @@ public function cachedPermissions()
{
$cacheKey = 'laratrust_permissions_for_role_' . $this->getKey();

return Cache::remember($cacheKey, Config::get('cache.ttl', 60), function () {
if (! Config::get('laratrust.use_cache')) {
return $this->permissions()->get();
}

return Cache::remember($cacheKey, Config::get('cache.ttl', 60), function () {
return $this->permissions()->get()->toArray();
});
}

Expand Down Expand Up @@ -132,6 +136,8 @@ public function hasPermission($permission, $requireAll = false)
}

foreach ($this->cachedPermissions() as $perm) {
$perm = Helper::hidrateModel(Config::get('laratrust.models.permission'), $perm);

if (str_is($permission, $perm->name)) {
return true;
}
Expand Down
21 changes: 17 additions & 4 deletions src/Traits/LaratrustUserTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,12 @@ public function cachedRoles()
{
$cacheKey = 'laratrust_roles_for_user_' . $this->getKey();

return Cache::remember($cacheKey, Config::get('cache.ttl', 60), function () {
if (! Config::get('laratrust.use_cache')) {
return $this->roles()->get();
}

return Cache::remember($cacheKey, Config::get('cache.ttl', 60), function () {
return $this->roles()->get()->toArray();
});
}

Expand All @@ -78,8 +82,12 @@ public function cachedPermissions()
{
$cacheKey = 'laratrust_permissions_for_user_' . $this->getKey();

return Cache::remember($cacheKey, Config::get('cache.ttl', 60), function () {
if (! Config::get('laratrust.use_cache')) {
return $this->permissions()->get();
}

return Cache::remember($cacheKey, Config::get('cache.ttl', 60), function () {
return $this->permissions()->get()->toArray();
});
}

Expand Down Expand Up @@ -164,6 +172,8 @@ public function hasRole($name, $team = null, $requireAll = false)
$team = Helper::fetchTeam($team);

foreach ($this->cachedRoles() as $role) {
$role = Helper::hidrateModel(Config::get('laratrust.models.role'), $role);

if ($role->name == $name && Helper::isInSameTeam($role, $team)) {
return true;
}
Expand Down Expand Up @@ -235,13 +245,17 @@ public function hasPermission($permission, $team = null, $requireAll = false)
$team = Helper::fetchTeam($team);

foreach ($this->cachedPermissions() as $perm) {
$perm = Helper::hidrateModel(Config::get('laratrust.models.permission'), $perm);

if (Helper::isInSameTeam($perm, $team)
&& str_is($permission, $perm->name)) {
return true;
}
}

foreach ($this->cachedRoles() as $role) {
$role = Helper::hidrateModel(Config::get('laratrust.models.role'), $role);

if (Helper::isInSameTeam($role, $team)
&& $role->hasPermission($permission)
) {
Expand Down Expand Up @@ -667,13 +681,12 @@ public function canAndOwns($permission, $thing, $options = [])
public function allPermissions()
{
$roles = $this->roles()->with('permissions')->get();
$permissions = $this->cachedPermissions();

$roles = $roles->flatMap(function ($role) {
return $role->permissions;
});

return $permissions->merge($roles)->unique('name');
return $this->permissions->merge($roles)->unique('name');
}

/**
Expand Down
10 changes: 10 additions & 0 deletions src/config/laratrust.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,16 @@
*/
'use_morph_map' => false,

/*
|--------------------------------------------------------------------------
| Use cache in the package
|--------------------------------------------------------------------------
|
| Defines if Laratrust will use Laravel's Cache to cache the roles and permissions.
|
*/
'use_cache' => false,

/*
|--------------------------------------------------------------------------
| Use teams feature in the package
Expand Down
86 changes: 86 additions & 0 deletions tests/LaratrustCacheTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<?php

namespace Laratrust\Test;

use Mockery as m;
use Laratrust\Tests\Models\Role;
use Laratrust\Tests\Models\Team;
use Laratrust\Tests\Models\User;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Config;
use Laratrust\Tests\LaratrustTestCase;
use Laratrust\Tests\Models\Permission;
use Laratrust\Tests\Models\OwnableObject;

class LaratrustCacheTest extends LaratrustTestCase
{
protected $user;

public function setUp()
{
parent::setUp();

$this->migrate();
}

public function testUserCanDisableTheRolesAndPermissionsCaching()
{
/*
|------------------------------------------------------------
| Set
|------------------------------------------------------------
*/
$team = Team::create(['name' => 'team_a']);
$user = User::create(['name' => 'test', 'email' => 'test@test.com']);
$role = Role::create(['name' => 'role_a'])
->attachPermissions([
Permission::create(['name' => 'permission_a']),
Permission::create(['name' => 'permission_b']),
Permission::create(['name' => 'permission_c']),
]);

$user->roles()->attach($role->id);

$user->permissions()->attach([
Permission::create(['name' => 'permission_d'])->id => ['team_id' => $team->id ],
Permission::create(['name' => 'permission_e'])->id => ['team_id' => $team->id],
]);

/*
|------------------------------------------------------------
| User Assertion
|------------------------------------------------------------
*/
// With cache
$this->app['config']->set('laratrust.use_cache', true);
$this->assertInternalType('array', $user->cachedRoles());
$this->assertEquals($user->roles()->get()->toArray(), $user->cachedRoles());

$this->assertInternalType('array', $user->cachedPermissions());
$this->assertEquals($user->permissions()->get()->toArray(), $user->cachedPermissions());

// Without cache
$this->app['config']->set('laratrust.use_cache', false);
$this->assertInstanceOf('Illuminate\Support\Collection', $user->cachedRoles());
$this->assertEquals($user->roles()->get(), $user->cachedRoles());

$this->assertInstanceOf('Illuminate\Support\Collection', $user->cachedPermissions());
$this->assertEquals($user->permissions()->get(), $user->cachedPermissions());

/*
|------------------------------------------------------------
| Role Assertion
|------------------------------------------------------------
*/
// With cache
$this->app['config']->set('laratrust.use_cache', true);
$this->assertInternalType('array', $role->cachedPermissions());
$this->assertEquals($role->permissions()->get()->toArray(), $role->cachedPermissions());

// Without cache
$this->app['config']->set('laratrust.use_cache', false);
$this->assertInstanceOf('Illuminate\Support\Collection', $role->cachedPermissions());
$this->assertEquals($role->permissions()->get(), $role->cachedPermissions());
}
}

0 comments on commit 227c89d

Please sign in to comment.