Test Setup Failed
Pull Request — master (#50)
by Alex
03:19
created

MetadataControllerTrait::getParameterNames()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 23
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 23
ccs 19
cts 19
cp 1
rs 9.0856
cc 3
eloc 17
nc 3
nop 1
crap 3
1
<?php
2
3
namespace AlgoWeb\PODataLaravel\Controllers;
4
5
use Illuminate\Routing\Controller as BaseController;
6
7
trait MetadataControllerTrait
8
{
9
    /*
10
     * Allowed crud verbs
11
     */
12
    protected $crudVerbs = ['create', 'read', 'update', 'delete'];
13
14
    /*
15
     * Array to record mapping betweeen model-verb combos and names
16
     * First-level key is fully-qualified model name
17
     * (eg Alt\Swedish\Chef\Bork\Bork\Bork)
18
     * Second-level key is CRUD verb
19
     */
20
    protected $mapping;
21
22
    /*
23
     * Given model and verb, get method name and parameter list
24
     *
25
     * @param $modelName
26
     * @param $crudVerb
27
     * @return array
28
     * @throws \Exception
29
     */
30 9
    public function getMethodName($modelName, $crudVerb)
31
    {
32
        // enforce we're actually hooked up to a controller
33 9
        assert($this instanceof BaseController, get_class($this));
34
        // enforce that mapping is actually not empty
35 9
        assert(0 < count($this->mapping), "Mapping array must not be empty");
1 ignored issue
show
Bug introduced by
The property mapping does not seem to exist in Illuminate\Routing\Controller.

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...
36
37 8
        if (!array_key_exists($modelName, $this->mapping)) {
38 1
            throw new \Exception('Metadata mapping for model '.$modelName.' not defined');
39
        }
40
41 7
        if (!in_array(strtolower($crudVerb), $this->crudVerbs)) {
1 ignored issue
show
Bug introduced by
The property crudVerbs does not seem to exist in Illuminate\Routing\Controller.

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...
42 1
            throw new \Exception('CRUD verb '.$crudVerb.' not defined');
43
        }
44
45 6
        $lookup = $this->mapping[$modelName];
46 6
        if (!is_array($lookup)) {
47 1
            throw new \Exception('Metadata mapping for model '.$modelName.' not an array');
48
        }
49
50 5
        if (!array_key_exists($crudVerb, $lookup)) {
51 1
            throw new \Exception('Metadata mapping for CRUD verb '.$crudVerb.' on model '.$modelName.' not defined');
52
        }
53 4
        $result = $lookup[$crudVerb];
54 4 View Code Duplication
        if (!isset($result)) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
55 1
            throw new \Exception('Metadata mapping for CRUD verb '.$crudVerb.' on model '.$modelName.' null');
56
        }
57
58 3 View Code Duplication
        if (!method_exists($this, $result)) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
59 1
            throw new \Exception(
60 1
                'Metadata target for CRUD verb '.$crudVerb.' on model '.$modelName.' does not exist'
61 1
            );
62
        }
63
64 2
        $class = get_class($this);
65 2
        $parmArray = $this->getParameterNames($result);
66
67 2
        return ['method' => $result, 'controller' => $class, 'parameters' => $parmArray];
68
    }
69
70 68
    public function getMappings()
71
    {
72
        // enforce we're actually hooked up to a controller
73 68
        assert($this instanceof BaseController, get_class($this));
74
        // enforce that mapping is actually not empty
75 68
        assert(!empty($this->mapping), "Mapping array must not be empty");
1 ignored issue
show
Bug introduced by
The property mapping does not seem to exist in Illuminate\Routing\Controller.

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...
76
77 68
        $allMappings = [];
78
79
        // check that mapping array is well formed and sane, rather than waiting to stab us with a spatula
80 68
        foreach ($this->mapping as $key => $map) {
81 68
            if (!is_array($map)) {
82 1
                throw new \Exception('Metadata mapping for model '.$key.' not an array');
83
            }
84 68
            foreach ($map as $verb => $method) {
85 68
                if (!in_array(strtolower($verb), $this->crudVerbs)) {
1 ignored issue
show
Bug introduced by
The property crudVerbs does not seem to exist in Illuminate\Routing\Controller.

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...
86 1
                    throw new \Exception('CRUD verb '.$verb.' not defined');
87
                }
88 68
                if (!isset($method)) {
89 1
                    throw new \Exception('Metadata mapping for CRUD verb '.$verb.' on model '.$key.' null');
90
                }
91
92 68
                if (!method_exists($this, $method)) {
93 1
                    throw new \Exception(
94 1
                        'Metadata target for CRUD verb '.$verb.' on model '.$key.' does not exist'
95 1
                    );
96
                }
97 68
                $parmArray = $this->getParameterNames($method);
98 68
                if (!array_key_exists($key, $allMappings)) {
99 68
                    $allMappings[$key] = [];
100 68
                }
101
102 68
                $class = get_class($this);
103 68
                $allMappings[$key][$verb] = ['method' => $method, 'controller' => $class, 'parameters' => $parmArray];
104 68
            }
105 68
        }
106 68
        return $allMappings;
107
    }
108
109
    /**
110
     * @param $result
111
     * @return array
112
     */
113 68
    protected function getParameterNames($result)
114
    {
115 68
        $parmArray = [];
116 68
        $r = new \ReflectionMethod($this, $result);
117 68
        $params = $r->getParameters();
118 68
        foreach ($params as $parm) {
119 68
            $detail = [];
120 68
            $detail['name'] = $parm->name;
121 68
            $classHint = $parm->getClass();
122 68
            $isRequest = false;
123 68
            if (null != $classHint) {
124
                // check to see if this is a request
125 68
                $className = $classHint->name;
126 68
                $class = new $className();
127 68
                $isRequest = $class instanceof \Illuminate\Http\Request;
128 68
                $detail['type'] = $className;
129 68
            }
130
131 68
            $detail['isRequest'] = $isRequest;
132 68
            $parmArray[$parm->name] = $detail;
133
        }
134 68
        return $parmArray;
135 68
    }
136
}
137