CrudHateoasExtension::_buildViewLinks()   C
last analyzed

Complexity

Conditions 11
Paths 24

Size

Total Lines 82

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 44
CRAP Score 15.8956

Importance

Changes 0
Metric Value
cc 11
nc 24
nop 1
dl 0
loc 82
rs 6.246
c 0
b 0
f 0
ccs 44
cts 67
cp 0.6566
crap 15.8956

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Copyright 2016 - 2018, Cake Development Corporation (http://cakedc.com)
4
 *
5
 * Licensed under The MIT License
6
 * Redistributions of files must retain the above copyright notice.
7
 *
8
 * @copyright Copyright 2016 - 2018, Cake Development Corporation (http://cakedc.com)
9
 * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
10
 */
11
12
namespace CakeDC\Api\Service\Action\Extension;
13
14
use CakeDC\Api\Service\Action\Action;
15
use CakeDC\Api\Service\Action\CrudAction;
16
use CakeDC\Api\Service\Action\ExtensionRegistry;
17
use CakeDC\Api\Service\Utility\ReverseRouting;
18
use Cake\Event\Event;
19
use Cake\Event\EventListenerInterface;
20
use Cake\Utility\Inflector;
21
22
/**
23
 * Class CrudHateoasExtension
24
 *
25
 * @package CakeDC\Api\Service\Action\Extension
26
 */
27
class CrudHateoasExtension extends Extension implements EventListenerInterface
28
{
29
30
    /**
31
     * @var ReverseRouting
32
     */
33
    protected $_reverseRouter;
34
35
    /**
36
     * CrudHateous Extension constructor.
37
     *
38
     * @param ExtensionRegistry $registry An ExtensionRegistry instance.
39
     * @param array $config Configuration.
40
     */
41 4
    public function __construct(ExtensionRegistry $registry, array $config = [])
42
    {
43 4
        parent::__construct($registry, $config);
44 4
        $this->_reverseRouter = new ReverseRouting();
45 4
    }
46
47
    /**
48
     * Returns a list of events this object is implementing. When the class is registered
49
     * in an event manager, each individual method will be associated with the respective event.
50
     *
51
     * @return array
52
     */
53 4
    public function implementedEvents()
54
    {
55
        return [
56 4
            'Action.afterProcess' => 'afterAction',
57 4
        ];
58
    }
59
60
    /**
61
     * After action callback.
62
     *
63
     * @param Event $event An Event instance.
64
     * @return void
65
     */
66 4
    public function afterAction(Event $event)
67
    {
68 4
        $action = $event->getSubject();
69 4
        $result = $action->getService()->getResult();
70 4
        $actionName = $action->getName();
71 4
        $links = [];
72
        //$route = $action->route();
73 4
        if ($actionName == 'view') {
74 2
            $links = $this->_buildViewLinks($action);
0 ignored issues
show
Documentation introduced by
$action is of type object|null, but the function expects a object<CakeDC\Api\Service\Action\Action>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
75 2
        }
76 4
        if ($actionName == 'index') {
77 2
            $links = $this->_buildIndexLinks($action);
0 ignored issues
show
Documentation introduced by
$action is of type object|null, but the function expects a object<CakeDC\Api\Service\Action\Action>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
78 2
        }
79
80 4
        $parent = $action->getService()->getParentService();
81
82 4
        if ($parent !== null) {
83 2
            $result = $parent->getResult();
84 2
        }
85 4
        $result->appendPayload('links', $links);
86 4
    }
87
88
    /**
89
     * Builds index action links.
90
     *
91
     * @param Action $action An Action instance.
92
     * @return array
93
     */
94 2
    protected function _buildIndexLinks(Action $action)
95
    {
96 2
        $links = [];
97 2
        $indexRoute = $action->getRoute();
98 2
        $parent = $action->getService()->getParentService();
99 2
        $path = $this->_reverseRouter->indexPath($action);
100
101 2
        $links[] = $this->_reverseRouter->link('self', $path, $indexRoute['_method']);
102 2
        $links[] = $this->_reverseRouter->link($action->getService()->getName() . ':add', $path, 'POST');
103
104 2
        if ($parent !== null) {
105 1
            $parentName = $parent->getName() . ':view';
106 1
            $path = $this->_reverseRouter->parentViewPath($parentName, $action, 'view');
107 1
            $links[] = $this->_reverseRouter->link($parentName, $path, 'GET');
108 1
        }
109
110 2
        return $links;
111
    }
112
113
    /**
114
     * Builds view action links.
115
     *
116
     * @param Action $action An Action instance.
117
     * @return array
118
     */
119 2
    protected function _buildViewLinks(Action $action)
120
    {
121 2
        $links = [];
122 2
        $viewRoute = $action->getRoute();
123 2
        $service = $action->getService();
124 2
        $parent = $action->getService()->getParentService();
125 2
        $path = null;
126 2
        if ($parent !== null) {
127 1
            $parentRoutes = $parent->routes();
128 1
            $currentRoute = $this->_reverseRouter->findRoute($viewRoute, $parentRoutes);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $currentRoute is correct as $this->_reverseRouter->f...ewRoute, $parentRoutes) (which targets CakeDC\Api\Service\Utili...rseRouting::findRoute()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
129 1
            if ($currentRoute !== null) {
130 1
                unset($viewRoute['id']);
131 1
                $path = $parent->routeReverse($viewRoute);
132 1
                array_pop($viewRoute['pass']);
133
134 1
                $indexName = $service->getName() . ':index';
135 1
                $indexPath = $this->_reverseRouter->parentViewPath($indexName, $action, 'index');
136 1
            }
137 1
        } else {
138 1
            unset($viewRoute['id']);
139 1
            $path = $service->routeReverse($viewRoute);
140 1
            array_pop($viewRoute['pass']);
141
142 1
            $indexName = $service->getName() . ':index';
143 1
            $route = collection($service->routes())
144
                ->filter(function ($item) use ($indexName) {
145 1
                    return $item->getName() == $indexName;
146 1
                })
147 1
                ->first();
148 1
            $indexPath = $service->routeReverse($route->defaults);
149
        }
150
151 2
        $links[] = $this->_reverseRouter->link('self', $path, $viewRoute['_method']);
152 2
        $links[] = $this->_reverseRouter->link($action->getService()->getName() . ':edit', $path, 'PUT');
153 2
        $links[] = $this->_reverseRouter->link($action->getService()->getName() . ':delete', $path, 'DELETE');
154 2
        if (!empty($indexPath)) {
155 2
            $links[] = $this->_reverseRouter->link($action->getService()->getName() . ':index', $indexPath, 'GET');
156 2
        }
157
158 2
        if ($parent === null && $action instanceof CrudAction) {
159 1
            $table = $action->getTable();
160 1
            $hasMany = $table->associations()->getByType('HasMany');
161 1
            foreach ($hasMany as $assoc) {
162
                $target = $assoc->getTarget();
163
                $alias = $target->getAlias();
164
165
                $targetClass = get_class($target);
166
                list(, $className) = namespaceSplit($targetClass);
167
                $className = preg_replace('/(.*)Table$/', '\1', $className);
168
                if ($className === '') {
169
                    $className = $alias;
170
                }
171
                $serviceName = strtolower($className);
172
173
                $indexName = $serviceName . ':index';
174
                $route = collection($service->routes())
175
                    ->filter(function ($item) use ($indexName) {
176
                        return $item->getName() == $indexName;
177
                    })
178
                    ->first();
179
180
                $currentId = Inflector::singularize(Inflector::underscore($service->getName())) . '_id';
181
                $defaults = !empty($route->defaults) ? $route->defaults : [];
182
183
                if (isset($route)) {
184
                    $viewRoute = $action->getRoute();
185
                    $defaults[$currentId] = $viewRoute['id'];
186
                    $indexPath = $service->routeReverse($defaults);
187
188
                    $links[] = $this->_reverseRouter->link($serviceName . ':index', $indexPath, 'GET');
189
                }
190 1
            }
191 1
        }
192
193 2
        if ($parent !== null) {
194 1
            $parentName = $parent->getName() . ':view';
195 1
            $path = $this->_reverseRouter->parentViewPath($parentName, $action, 'view');
196 1
            $links[] = $this->_reverseRouter->link($parentName, $path, 'GET');
197 1
        }
198
199 2
        return $links;
200
    }
201
}
202