Completed
Push — master ( bd4c23...b341c0 )
by Filipe
10:29
created

RouteBuilder   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 139
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Importance

Changes 0
Metric Value
wmc 14
lcom 1
cbo 5
dl 0
loc 139
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 1
A build() 0 6 1
A register() 0 5 1
A getParsedData() 0 19 3
A getYmlFileContent() 0 10 2
A setDefaults() 0 9 3
A addRoutes() 0 10 3
1
<?php
2
3
/**
4
 * This file is part of slick/mvc package
5
 *
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 */
9
10
namespace Slick\Mvc\Http\Router;
11
12
use Aura\Router\Map;
13
use Aura\Router\RouterContainer;
14
use Slick\Mvc\Exception\RoutesFileNotFoundException;
15
use Slick\Mvc\Exception\RoutesFileParserException;
16
use Slick\Mvc\Http\Router\Builder\FactoryInterface;
17
use Symfony\Component\Yaml\Exception\ParseException;
18
use Symfony\Component\Yaml\Parser;
19
20
/**
21
 * RouteBuilder
22
 *
23
 * @package Slick\Mvc\Http\Router
24
 * @author  Filipe Silva <[email protected]>
25
 */
26
class RouteBuilder implements RouteBuilderInterface
27
{
28
    /**
29
     * @var string
30
     */
31
    private $routesFile;
32
33
    /**
34
     * @var Parser
35
     */
36
    private $parser;
37
38
    /**
39
     * @var FactoryInterface
40
     */
41
    private $routeFactory;
42
43
    /**
44
     * @var array
45
     */
46
    private $parsedData;
47
48
    /**
49
     * Creates a route builder
50
     *
51
     * @param string           $routesFile
52
     * @param Parser           $parser
53
     * @param FactoryInterface $routeFactory
54
     */
55
    public function __construct(
56
        $routesFile,
57
        Parser $parser,
58
        FactoryInterface $routeFactory
59
    ) {
60
        $this->routesFile = $routesFile;
61
        $this->parser = $parser;
62
        $this->routeFactory = $routeFactory;
63
    }
64
65
    /**
66
     * Map builder handler
67
     *
68
     * @see http://auraphp.com/packages/3.x/Router/custom-maps.html#1-4-5
69
     *
70
     * @param Map $map
71
     *
72
     * @return RouteBuilder|RouteBuilderInterface
73
     */
74
    public function build(Map $map)
75
    {
76
        $this->setDefaults($map);
77
        $this->addRoutes($map);
78
        return $this;
79
    }
80
81
    /**
82
     * Registers the callback for map creations
83
     *
84
     * @param RouterContainer $container
85
     * @return self|RouteBuilderInterface
86
     */
87
    public function register(RouterContainer $container)
88
    {
89
        $container->setMapBuilder([$this, 'build']);
90
        return $this;
91
    }
92
93
    /**
94
     * Get YML parsed data array
95
     *
96
     * @return array
97
     */
98
    private function getParsedData()
99
    {
100
        if (is_array($this->parsedData)) {
101
            return $this->parsedData;
102
        }
103
        
104
        $content = $this->getYmlFileContent();
105
        try {
106
            $parsedData = $this->parser->parse($content);
107
        } catch (ParseException $caught) {
108
            throw new RoutesFileParserException(
109
                $caught->getMessage(),
110
                0,
111
                $caught
112
            );
113
        }
114
        $this->parsedData = $parsedData;
115
        return $parsedData;
116
    }
117
118
    /**
119
     * Get contents form YML file
120
     *
121
     * @return string
122
     */
123
    private function getYmlFileContent()
124
    {
125
        if (!is_file($this->routesFile)) {
126
            throw new RoutesFileNotFoundException(
127
                "The routes file is not found on your system."
128
            );
129
        }
130
131
        return file_get_contents($this->routesFile);
132
    }
133
134
    /**
135
     * Set map defaults
136
     *
137
     * @param Map $map
138
     */
139
    private function setDefaults(Map $map)
140
    {
141
        $defaults = ['tokens', 'defaults', 'host', 'accepts'];
142
        foreach ($this->getParsedData() as $name => $value) {
0 ignored issues
show
Bug introduced by
The expression $this->getParsedData() of type array|null|object<Symfon...string|object<stdClass> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
143
            if (in_array($name, $defaults)) {
144
                $map->$name($value);
145
            }
146
        }
147
    }
148
149
    /**
150
     * Add routes to the provided route map
151
     *
152
     * @param Map $map
153
     */
154
    private function addRoutes(Map $map)
155
    {
156
        $data = $this->getParsedData();
157
        $routes = (array_key_exists('routes', $data))
158
            ? $data['routes']
159
            : [];
160
        foreach ($routes as $name => $definition) {
161
            $this->routeFactory->parse($name, $definition, $map);
162
        }
163
    }
164
}