Passed
Push — master ( 2f61c1...c1f5d7 )
by Dan
04:59
created

RSymfonyAdaptor   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 149
Duplicated Lines 32.21 %

Coupling/Cohesion

Components 1
Dependencies 8

Importance

Changes 0
Metric Value
wmc 13
lcom 1
cbo 8
dl 48
loc 149
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A match() 18 18 2
B getSymfonyRouteCollection() 14 38 4
A createRouterResponse() 16 16 2
A createFastRouteHandler() 0 15 2
A isCached() 0 4 1
A getCachedRoutes() 0 4 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
/**
3
 * This file is part of the PSR Http Framework.
4
 *
5
 * (c) Dan Smith <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
namespace Ds\Router\Adaptor;
11
12
use Ds\Router\Exceptions\RouterException;
13
use Ds\Router\Interfaces\RouteCollectionInterface;
14
use Ds\Router\Interfaces\RouteInterface;
15
use Ds\Router\Interfaces\SerializerInterface;
16
use Ds\Router\RouterResponse;
17
18
19
use Symfony\Component\Routing\Matcher\UrlMatcher;
20
use Symfony\Component\Routing\RequestContext;
21
use Symfony\Component\Routing\RouteCollection;
22
use Symfony\Component\Routing\Route;
23
24
25
/**
26
 * Class RSymfonyAdaptor
27
 *
28
 * @package Ds\Router\Adaptor
29
 * @author  Dan Smith    <[email protected]>
30
 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
31
 * @link    https://github.com/djsmithme/Router
32
 */
33
class RSymfonyAdaptor extends AbstractAdaptor
34
{
35
    protected $locator;
36
    protected $context;
37
38
    protected $defaults = [
39
        'cacheDisabled' => true,
40
        'cacheFile' => __DIR__ . 'r.cache',
41
    ];
42
43
    /**
44
     * FastRouteAdaptor constructor.
45
     *
46
     * @param  SerializerInterface $serializer
47
     * @param  array $options
48
     * @throws RouterException
49
     */
50
    public function __construct(SerializerInterface $serializer, array $options = [])
51
    {
52
        parent::__construct($serializer);
53
54
        $this->options = $options;
55
    }
56
57
    /**
58
     * Return RouterResponse for given route.
59
     *
60
     * @param  RouteCollectionInterface $routes
61
     * @param  string $method
62
     * @param  string $requestTarget
63
     * @return RouterResponse
64
     * @throws \Symfony\Component\Routing\Exception\ResourceNotFoundException
65
     * @throws \Symfony\Component\Routing\Exception\MethodNotAllowedException
66
     */
67 View Code Duplication
    public function match(RouteCollectionInterface $routes, $method, $requestTarget)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
68
    {
69
        $response = ['response'];
70
        $symfonyRoutes = $this->getSymfonyRouteCollection($routes);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $symfonyRoutes is correct as $this->getSymfonyRouteCollection($routes) (which targets Ds\Router\Adaptor\RSymfo...ymfonyRouteCollection()) 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...
71
72
        $context = new RequestContext('/');
73
74
        $matcher = new UrlMatcher($symfonyRoutes, $context);
0 ignored issues
show
Documentation introduced by
$symfonyRoutes is of type null, but the function expects a object<Symfony\Component\Routing\RouteCollection>.

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
76
        $parameters = $matcher->match($requestTarget);
77
        // array('_controller' => 'MyController', '_route' => 'route_name')
0 ignored issues
show
Unused Code Comprehensibility introduced by
63% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
78
79
        if (!isset($parameters['controller'])) {
80
            $response['statusCode'] = 404;
81
        }
82
83
        return $this->createRouterResponse($response);
84
    }
85
86
    public function getSymfonyRouteCollection(RouteCollectionInterface $routes)
87
    {
88
89
        if (!$this->options['cacheDisabled'] && file_exists($this->options['cacheFile'])){
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
90
            //get cached route collection.
91
        }
92
93
        $froute = '/articles/{id:\d+}[/{title}]';
0 ignored issues
show
Unused Code introduced by
$froute is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
94
95
96
        $route = new Route(
97
            '/path',
98
            array('handler' => 'some::string'), // default values
99
            array('month' => '[0-9]{4}-[0-9]{2}'), // requirements
100
            array(), // options
101
            '', // host
102
            array('https','https'), // schemes
103
            array('GET') // methods
104
        );
105
106
107
        $symfonyRoutes = new RouteCollection();
108
109 View Code Duplication
        foreach ($routes as $route) {
0 ignored issues
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...
110
            $symfonyRoutes->add(
111
                \json_encode($route->getNames()),
112
                new Route(
113
                    $route->getPattern(),
114
                    [$route->getHandler()],
115
                    [],
116
                    [],
117
                    [],
0 ignored issues
show
Documentation introduced by
array() is of type array, but the function expects a string.

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...
118
                    [],
119
                    [$route->getMethod()]
120
                )
121
            );
122
        }
123
    }
124
125
    /**
126
     * Unserialize any cached content and return RouterResponse.
127
     *
128
     * @param  $dispatchResponse
129
     * @return RouterResponse
130
     */
131 View Code Duplication
    public function createRouterResponse($dispatchResponse)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
132
    {
133
        if ($dispatchResponse['handler']['type'] === 'object') {
134
            $dispatchResponse['content'] = $this->serializer->unserialize($dispatchResponse['handler']['content']);
135
        } else {
136
            $dispatchResponse['content'] = $dispatchResponse['handler']['content'];
137
        }
138
139
        return new RouterResponse(
140
            $dispatchResponse['statusCode'],
141
            $dispatchResponse['allowedMethods'],
142
            $dispatchResponse['content'],
0 ignored issues
show
Documentation introduced by
$dispatchResponse['content'] is of type object<Closure>, but the function expects a array.

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...
143
            $dispatchResponse['vars'],
144
            $dispatchResponse['handler']['name']
0 ignored issues
show
Unused Code introduced by
The call to RouterResponse::__construct() has too many arguments starting with $dispatchResponse['handler']['name'].

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
145
        );
146
    }
147
148
    public function createFastRouteHandler(RouteInterface $route)
149
    {
150
        $handlerOut = [
151
            'type' => $route->getHandlerType(),
152
            'name' => $route->getNames()
153
        ];
154
155
        if ($route->getHandlerType() === 'object') {
156
            $handlerOut['content'] = $this->serializer->serialize($route->getHandler());
0 ignored issues
show
Bug introduced by
It seems like $route->getHandler() targeting Ds\Router\Interfaces\RouteInterface::getHandler() can also be of type string; however, Ds\Router\Interfaces\Ser...rInterface::serialize() does only seem to accept object<Closure>, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
157
        } else {
158
            $handlerOut['content'] = $route->getHandler();
159
        }
160
161
        return $handlerOut;
162
    }
163
164
    /**
165
     * Check if Cache Enabled and whether too skip adding routes.
166
     *
167
     * @return boolean
168
     */
169
    public function isCached()
170
    {
171
        return false;
172
    }
173
174
    /**
175
     * @inheritdoc
176
     */
177
    public function getCachedRoutes($context = '')
178
    {
179
        // TODO: Implement getCachedRoutes() method.
180
    }
181
}
182