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 = [];
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);
0 ignored issues
show
The property resource does not seem to exist. Did you mean resourceAbilityMap?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
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