Completed
Push — master ( 8927df...f70445 )
by Abdelrahman
02:05
created

src/Http/Controllers/AuthorizedController.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
/*
4
 * NOTICE OF LICENSE
5
 *
6
 * Part of the Rinvex Fort Package.
7
 *
8
 * This source file is subject to The MIT License (MIT)
9
 * that is bundled with this package in the LICENSE file.
10
 *
11
 * Package: Rinvex Fort Package
12
 * License: The MIT License (MIT)
13
 * Link:    https://rinvex.com
14
 */
15
16
namespace Rinvex\Fort\Http\Controllers;
17
18
use ReflectionClass;
19
use ReflectionMethod;
20
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
21
22
class AuthorizedController extends AuthenticatedController
23
{
24
    use AuthorizesRequests;
25
26
    /**
27
     * Resource Ability Map.
28
     *
29
     * Array of resource ability map.
30
     *
31
     * @var array
32
     */
33
    protected $resourceAbilityMap = [];
34
35
    /**
36
     * Resource action whitelist.
37
     *
38
     * Array of resource actions to skip mapping to abilities automatically.
39
     *
40
     * @var array
41
     */
42
    protected $resourceActionWhitelist = [];
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $resourceActionWhitelist exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
43
44
    /**
45
     * Create a new manage persistence controller instance.
46
     *
47
     * @throws \Rinvex\Fort\Exceptions\AuthorizationException
48
     */
49
    public function __construct()
50
    {
51
        parent::__construct();
52
53
        if (property_exists(static::class, 'resource')) {
54
            $this->authorizeResource($this->resource);
55
        } else {
56
            // At this stage, sessions still not loaded yet, and `AuthorizationException`
57
            // depends on seesions to flash redirection error msg, so delegate to a middleware
58
            $this->middleware('can:null');
59
        }
60
    }
61
62
    /**
63
     * Authorize a resource action based on the incoming request.
64
     *
65
     * @param  string                        $resource
66
     * @param  string|null                   $parameter
67
     * @param  array                         $options
68
     * @param  \Illuminate\Http\Request|null $request
69
     *
70
     * @return void
71
     */
72
    public function authorizeResource($resource, $parameter = null, array $options = [], $request = null)
73
    {
74
        $middleware = [];
75
        $parameter  = $parameter ?: $resource;
76
77
        // Prepare middleware
78
        foreach ($this->mapResourceAbilities() as $method => $ability) {
79
            $middleware["can:{$ability}-{$resource},{$parameter}"][] = $method;
80
        }
81
82
        // Attach middleware
83
        foreach ($middleware as $middlewareName => $methods) {
84
            $this->middleware($middlewareName, $options)->only($methods);
85
        }
86
    }
87
88
    /**
89
     * Map resource actions to resource abilities.
90
     *
91
     * @return array
92
     */
93
    protected function mapResourceAbilities()
94
    {
95
        // Reflect calling controller
96
        $controller = new ReflectionClass(static::class);
97
98
        // Get public methods and filter magic methods
99
        $methods = array_filter($controller->getMethods(ReflectionMethod::IS_PUBLIC), function ($item) use ($controller) {
100
            return $item->class == $controller->name && substr($item->name, 0, 2) != '__' && ! in_array($item->name, $this->resourceActionWhitelist);
101
        });
102
103
        // Get controller actions
104
        $actions = array_combine($items = array_map(function ($action) {
105
            return $action->name;
106
        }, $methods), $items);
107
108
        // Map resource actions to resourse abilities
109
        array_walk($actions, function ($value, $key) use (&$actions) {
110
            $actions[$key] = array_get($this->resourceAbilityMap(), $key, $value);
111
        });
112
113
        return $actions;
114
    }
115
116
    /**
117
     * Get the map of resource methods to ability names.
118
     *
119
     * @return array
120
     */
121
    protected function resourceAbilityMap()
122
    {
123
        return $this->resourceAbilityMap + [
124
            'show'  => 'view',
125
            'index' => 'list',
126
            'store' => 'create',
127
            'copy'  => 'create',
128
            'edit'  => 'update',
129
        ];
130
    }
131
}
132