Improved permission regen performance by factor of 4

Worked around slower eloquent access to speed up permission generation.
This commit is contained in:
Dan Brown 2016-04-30 17:16:06 +01:00
parent 9a31b83b2a
commit 59367b3417
16 changed files with 49 additions and 60 deletions

View File

@ -2,8 +2,6 @@
namespace BookStack;
use Illuminate\Database\Eloquent\Model;
/**
* @property string key
* @property \User user

View File

@ -2,8 +2,6 @@
namespace BookStack;
use Illuminate\Database\Eloquent\Model;
class EmailConfirmation extends Model
{
protected $fillable = ['user_id', 'token'];

View File

@ -82,8 +82,7 @@ abstract class Entity extends Ownable
*/
public function hasActiveRestriction($role_id, $action)
{
return $this->restricted && $this->restrictions()
->where('role_id', '=', $role_id)->where('action', '=', $action)->count() > 0;
return $this->getRawAttribute('restricted') && $this->hasRestriction($role_id, $action);
}
/**

View File

@ -1,8 +1,4 @@
<?php
namespace BookStack;
use Illuminate\Database\Eloquent\Model;
<?php namespace BookStack;
class EntityPermission extends Model
{

19
app/Model.php Normal file
View File

@ -0,0 +1,19 @@
<?php namespace BookStack;
use Illuminate\Database\Eloquent\Model as EloquentModel;
class Model extends EloquentModel
{
/**
* Provides public access to get the raw attribute value from the model.
* Used in areas where no mutations are required but performance is critical.
* @param $key
* @return mixed
*/
public function getRawAttribute($key)
{
return parent::getAttributeFromArray($key);
}
}

View File

@ -1,6 +1,5 @@
<?php namespace BookStack;
use Illuminate\Database\Eloquent\Model;
abstract class Ownable extends Model
{

View File

@ -1,8 +1,5 @@
<?php
<?php namespace BookStack;
namespace BookStack;
use Illuminate\Database\Eloquent\Model;
class Page extends Entity
{

View File

@ -1,6 +1,5 @@
<?php namespace BookStack;
use Illuminate\Database\Eloquent\Model;
class PageRevision extends Model
{

View File

@ -1,6 +1,5 @@
<?php namespace BookStack;
use Illuminate\Database\Eloquent\Model;
class Permission extends Model
{

View File

@ -1,8 +1,5 @@
<?php
<?php namespace BookStack;
namespace BookStack;
use Illuminate\Database\Eloquent\Model;
class Restriction extends Model
{

View File

@ -1,8 +1,5 @@
<?php
<?php namespace BookStack;
namespace BookStack;
use Illuminate\Database\Eloquent\Model;
class Role extends Model
{
@ -36,11 +33,16 @@ class Role extends Model
/**
* Check if this role has a permission.
* @param $permission
* @param $permissionName
* @return bool
*/
public function hasPermission($permission)
public function hasPermission($permissionName)
{
return $this->permissions->pluck('name')->contains($permission);
$permissions = $this->getRelationValue('permissions');
foreach ($permissions as $permission) {
if ($permission->getRawAttribute('name') === $permissionName) return true;
}
return false;
}
/**

View File

@ -54,21 +54,21 @@ class RestrictionService
$this->entityPermission->truncate();
// Get all roles (Should be the most limited dimension)
$roles = $this->role->load('permissions')->all();
$roles = $this->role->with('permissions')->get();
// Chunk through all books
$this->book->chunk(500, function ($books) use ($roles) {
$this->book->with('restrictions')->chunk(500, function ($books) use ($roles) {
$this->createManyEntityPermissions($books, $roles);
});
// Chunk through all chapters
$this->chapter->with('book')->chunk(500, function ($books) use ($roles) {
$this->createManyEntityPermissions($books, $roles);
$this->chapter->with('book', 'restrictions')->chunk(500, function ($chapters) use ($roles) {
$this->createManyEntityPermissions($chapters, $roles);
});
// Chunk through all pages
$this->page->with('book', 'chapter')->chunk(500, function ($books) use ($roles) {
$this->createManyEntityPermissions($books, $roles);
$this->page->with('book', 'chapter', 'restrictions')->chunk(500, function ($pages) use ($roles) {
$this->createManyEntityPermissions($pages, $roles);
});
}
@ -78,7 +78,7 @@ class RestrictionService
*/
public function buildEntityPermissionsForEntity(Entity $entity)
{
$roles = $this->role->load('permissions')->all();
$roles = $this->role->with('permissions')->get();
$entities = collect([$entity]);
if ($entity->isA('book')) {
@ -103,17 +103,17 @@ class RestrictionService
$this->deleteManyEntityPermissionsForRoles($roles);
// Chunk through all books
$this->book->chunk(500, function ($books) use ($roles) {
$this->book->with('restrictions')->chunk(500, function ($books) use ($roles) {
$this->createManyEntityPermissions($books, $roles);
});
// Chunk through all chapters
$this->chapter->with('book')->chunk(500, function ($books) use ($roles) {
$this->chapter->with('book', 'restrictions')->chunk(500, function ($books) use ($roles) {
$this->createManyEntityPermissions($books, $roles);
});
// Chunk through all pages
$this->page->with('book', 'chapter')->chunk(500, function ($books) use ($roles) {
$this->page->with('book', 'chapter', 'restrictions')->chunk(500, function ($books) use ($roles) {
$this->createManyEntityPermissions($books, $roles);
});
}
@ -272,13 +272,13 @@ class RestrictionService
{
$entityClass = get_class($entity);
return [
'role_id' => $role->id,
'entity_id' => $entity->id,
'role_id' => $role->getRawAttribute('id'),
'entity_id' => $entity->getRawAttribute('id'),
'entity_type' => $entityClass,
'action' => $action,
'has_permission' => $permissionAll,
'has_permission_own' => $permissionOwn,
'created_by' => $entity->created_by
'created_by' => $entity->getRawAttribute('created_by')
];
}

View File

@ -1,8 +1,4 @@
<?php
namespace BookStack;
use Illuminate\Database\Eloquent\Model;
<?php namespace BookStack;
class Setting extends Model
{

View File

@ -1,8 +1,5 @@
<?php
<?php namespace BookStack;
namespace BookStack;
use Illuminate\Database\Eloquent\Model;
class SocialAccount extends Model
{

View File

@ -1,9 +1,6 @@
<?php
namespace BookStack;
<?php namespace BookStack;
use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;

View File

@ -1,8 +1,4 @@
<?php
namespace BookStack;
use Illuminate\Database\Eloquent\Model;
<?php namespace BookStack;
class View extends Model
{