Passed
Push — develop ( 28e0ad...7b5dfd )
by Brent
03:35
created

DevController::run()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 14
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 10
nc 6
nop 1
dl 0
loc 14
rs 9.2
c 0
b 0
f 0
1
<?php
2
3
namespace Brendt\Stitcher\Application;
4
5
use Brendt\Stitcher\App;
6
use Brendt\Stitcher\Exception\StitcherException;
7
use Brendt\Stitcher\Factory\AdapterFactory;
8
use Brendt\Stitcher\Stitcher;
9
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
10
use Symfony\Component\Routing\Matcher\UrlMatcher;
11
use Symfony\Component\Routing\RequestContext;
12
use Symfony\Component\Routing\Route;
13
use Symfony\Component\Routing\RouteCollection;
14
15
/**
16
 * The developer controller is used to render pages on the fly (on an HTTP request). This controller enables a
17
 * developer make code changes and see those changes real-time without re-compiling the whole site.
18
 */
19
class DevController
20
{
21
22
    /**
23
     * @var Stitcher
24
     */
25
    protected $stitcher;
26
27
    /**
28
     * Create a new developer controller with optional configuration path and -file.
29
     *
30
     * @param string $path
31
     * @param string $name
32
     */
33
    public function __construct($path = './', $name = 'config.dev.yml') {
34
        $path = rtrim($path, '/');
35
        $name = ltrim($name, '/');
36
37
        $this->stitcher = App::init("{$path}/{$name}")::get('stitcher');
38
    }
39
40
    /**
41
     * Run the developer controller. This function will read the request URL and dispatch the according route.
42
     *
43
     * @param string $url
44
     *
45
     * @return string
46
     */
47
    public function run($url = null) {
48
        if ($url === null) {
49
            $request = explode('?', $_SERVER['REQUEST_URI']);
50
            $url = reset($request);
51
        }
52
53
        try {
54
            return $this->getPage($url);
55
        } catch (StitcherException $e) {
56
            return $e->getMessage();
57
        } catch (ResourceNotFoundException $e) {
58
            return "404";
59
        }
60
    }
61
62
    /**
63
     * Create the route container
64
     *
65
     * @return \Symfony\Component\Routing\RouteCollection
66
     */
67
    protected function createRouteCollection() {
68
        $routeCollection = new RouteCollection();
69
        $site = $this->stitcher->loadSite();
70
71
        foreach ($site as $page) {
72
            $route = $page->getId();
73
74
            $routeCollection->add($route, new Route($route));
75
76
            if ($page->getAdapterConfig(AdapterFactory::PAGINATION_ADAPTER)) {
77
                $paginationRoute = $route . '/page-{page}';
78
                $routeCollection->add($paginationRoute, new Route($paginationRoute));
79
            }
80
        }
81
82
        return $routeCollection;
83
    }
84
85
    /**
86
     * @param $url
87
     *
88
     * @return mixed
89
     */
90
    protected function getPage($url) {
91
        $routeCollection = $this->createRouteCollection();
92
        $matcher = new UrlMatcher($routeCollection, new RequestContext());
93
        $routeResult = $matcher->match($url);
94
        $route = $routeResult['_route'];
95
96
        $id = isset($routeResult['id']) ? $routeResult['id'] : null;
97
98
        if (isset($routeResult['page'])) {
99
            $route = str_replace('/page-{page}', '', $route);
100
            $id = $routeResult['page'];
101
        }
102
103
        $blanket = $this->stitcher->stitch($route, $id);
104
105
        if (isset($blanket[$route])) {
106
            return $blanket[$route];
107
        }
108
109
        if (isset($blanket[$url])) {
110
            return $blanket[$url];
111
        }
112
113
        throw new ResourceNotFoundException();
114
    }
115
116
}
117