UrlRewriterService   A
last analyzed

Complexity

Total Complexity 15

Size/Duplication

Total Lines 106
Duplicated Lines 0 %

Coupling/Cohesion

Dependencies 0

Test Coverage

Coverage 95.12%

Importance

Changes 6
Bugs 3 Features 3
Metric Value
wmc 15
c 6
b 3
f 3
cbo 0
dl 0
loc 106
ccs 39
cts 41
cp 0.9512
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A addRoute() 0 6 1
B getRoute() 0 20 5
A getRoutes() 0 4 1
A addRoutes() 0 8 2
B reverse() 0 28 6
1
<?php
2
/**
3
 * Fwk
4
 *
5
 * Copyright (c) 2011-2014, Julien Ballestracci <[email protected]>.
6
 * All rights reserved.
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 *
11
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
12
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
13
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
14
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
15
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
16
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
17
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
19
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
20
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
21
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
22
 * POSSIBILITY OF SUCH DAMAGE.
23
 *
24
 * PHP Version 5.3
25
 *
26
 * @category   Core
27
 * @package    Fwk\Core
28
 * @subpackage Components
29
 * @author     Julien Ballestracci <[email protected]>
30
 * @copyright  2011-2014 Julien Ballestracci <[email protected]>
31
 * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
32
 * @link       http://www.fwk.pw
33
 */
34
namespace Fwk\Core\Components\UrlRewriter;
35
36
/**
37
 * URL Rewriter Service
38
 *
39
 * @category   Utilities
40
 * @package    Fwk\Core
41
 * @subpackage Components
42
 * @author     Julien Ballestracci <[email protected]>
43
 * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
44
 * @link       http://www.fwk.pw
45
 */
46
class UrlRewriterService
47
{
48
    protected $routes = array();
49
50
    /**
51
     * Adds a route
52
     *
53
     * @param Route $route The Route
54
     *
55
     * @return UrlRewriterService
56
     */
57 7
    public function addRoute(Route $route)
58
    {
59 7
        $this->routes[] = $route;
60
61 7
        return $this;
62
    }
63
64
    /**
65
     *
66
     * @param string $url
67
     *
68
     * @return Route
0 ignored issues
show
Documentation introduced by
Should the return type not be Route|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
69
     */
70 3
    public function getRoute($url)
71
    {
72 3
        foreach ($this->routes as $route) {
73 3
            if ($route->match($url)) {
74 3
                $regex = $route->toRegularExpr();
75 3
                $route2 = clone $route;
76
77 3
                \preg_match_all($regex, $url, $matches);
78
79 3
                foreach ($route2->getParameters() as $param) {
80 2
                    $result = (isset($matches[$param->getName()]) ? $matches[$param->getName()][0] : $param->getDefault());
81 2
                    $param->setValue($result);
82 3
                }
83
84 3
                return $route2;
85
            }
86 1
        }
87
        
88
        return null;
89
    }
90
91
    /**
92
     * Returns all routes
93
     *
94
     * @return array
95
     */
96 1
    public function getRoutes()
97
    {
98 1
        return $this->routes;
99
    }
100
101
    /**
102
     *
103
     * @param array $routes
104
     *
105
     * @return UrlRewriterService
106
     */
107 6
    public function addRoutes(array $routes)
108
    {
109 6
        foreach ($routes as $route) {
110 6
            $this->addRoute($route);
111 6
        }
112
113 6
        return $this;
114
    }
115
116
    /**
117
     *
118
     * @param string $actionName
119
     * @param array  $params
120
     *
121
     * @return string
122
     */
123 2
    public function reverse($actionName, array $params = array(), 
124
        $escapeAmp = false
125
    ) {
126 2
        $possibles = array();
127 2
        foreach ($this->routes as $x => $route) {
128 2
            if ($route->getActionName() != $actionName) {
129 1
                continue;
130
            }
131
132 2
            $idx = 1 + $x;
133 2
            if (count($params) != count($route->getParameters())) {
134 1
                $idx = 99999 + $x;
135 1
            }
136
            
137 2
            $possibles[$idx] = $route;
138 2
        }
139
        
140 2
        ksort($possibles);
141
        
142 2
        foreach ($possibles as $route) {
143 2
            $reverse = $route->getReverse($params, $escapeAmp);
144 2
            if ($reverse !== false) {
145 2
                return $reverse;
146
            }
147 1
        }
148
149
        return false;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return false; (false) is incompatible with the return type documented by Fwk\Core\Components\UrlR...ewriterService::reverse of type string.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
150
    }
151
}
152