Completed
Push — master ( b015a1...0e1003 )
by Abdelrahman
49:45
created

AuthorizedController::mapResourceAbilities()   A

Complexity

Conditions 3
Paths 1

Size

Total Lines 22
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 10
nc 1
nop 0
dl 0
loc 22
rs 9.2
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * NOTICE OF LICENSE
5
 *
6
 * Part of the Cortex Foundation Module.
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: Cortex Foundation Module
12
 * License: The MIT License (MIT)
13
 * Link:    https://rinvex.com
14
 */
15
16
declare(strict_types=1);
17
18
namespace Cortex\Foundation\Http\Controllers;
19
20
use ReflectionClass;
21
use ReflectionMethod;
22
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
23
24
class AuthorizedController extends AuthenticatedController
25
{
26
    use AuthorizesRequests;
27
28
    /**
29
     * Resource Ability Map.
30
     * Array of resource ability map.
31
     *
32
     * @var array
33
     */
34
    protected $resourceAbilityMap = [];
35
36
    /**
37
     * Resource action whitelist.
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);
0 ignored issues
show
Bug introduced by
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
            // Since Laravel 5.3 controller constructors executed before middleware to be able to append
59
            // new middleware to the pipeline then all middleware executed together, and sessions started in `StartSession` middleware
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 134 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
60
            $this->middleware('can:null');
61
        }
62
    }
63
64
    /**
65
     * Authorize a resource action based on the incoming request.
66
     *
67
     * @param string                        $resource
68
     * @param string|null                   $parameter
69
     * @param array                         $options
70
     * @param \Illuminate\Http\Request|null $request
71
     *
72
     * @return void
73
     */
74
    public function authorizeResource($resource, $parameter = null, array $options = [], $request = null)
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
75
    {
76
        $middleware = [];
77
        $parameter = $parameter ?: $resource;
78
79
        // Prepare middleware
80
        foreach ($this->mapResourceAbilities() as $method => $ability) {
81
            $middleware["can:{$ability}-{$resource},{$parameter}"][] = $method;
82
        }
83
84
        // Attach middleware
85
        foreach ($middleware as $middlewareName => $methods) {
86
            $this->middleware($middlewareName, $options)->only($methods);
87
        }
88
    }
89
90
    /**
91
     * Map resource actions to resource abilities.
92
     *
93
     * @return array
94
     */
95
    protected function mapResourceAbilities()
96
    {
97
        // Reflect calling controller
98
        $controller = new ReflectionClass(static::class);
99
100
        // Get public methods and filter magic methods
101
        $methods = array_filter($controller->getMethods(ReflectionMethod::IS_PUBLIC), function ($item) use ($controller) {
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 122 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
102
            return $item->class === $controller->name && mb_substr($item->name, 0, 2) !== '__' && ! in_array($item->name, $this->resourceActionWhitelist);
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 154 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
103
        });
104
105
        // Get controller actions
106
        $actions = array_combine($items = array_map(function ($action) {
107
            return $action->name;
108
        }, $methods), $items);
109
110
        // Map resource actions to resourse abilities
111
        array_walk($actions, function ($value, $key) use (&$actions) {
112
            $actions[$key] = array_get($this->resourceAbilityMap(), $key, $value);
113
        });
114
115
        return $actions;
116
    }
117
118
    /**
119
     * Get the map of resource methods to ability names.
120
     *
121
     * @return array
122
     */
123
    protected function resourceAbilityMap()
124
    {
125
        return $this->resourceAbilityMap + [
126
                'index' => 'list',
127
                'store' => 'create',
128
                'edit' => 'update',
129
            ];
130
    }
131
}
132