Completed
Pull Request — develop (#337)
by Bastian
06:24
created

MainController::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 15
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 1
Metric Value
dl 0
loc 15
ccs 8
cts 8
cp 1
rs 9.4286
cc 1
eloc 13
nc 1
nop 6
crap 1
1
<?php
2
/**
3
 * controller for start page
4
 */
5
6
namespace Graviton\CoreBundle\Controller;
7
8
use Symfony\Component\HttpFoundation\Response;
9
use Symfony\Component\Routing\Router;
10
use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface;
11
use Graviton\RestBundle\HttpFoundation\LinkHeader;
12
use Graviton\RestBundle\HttpFoundation\LinkHeaderItem;
13
use Graviton\RestBundle\Service\RestUtilsInterface;
14
15
/**
16
 * MainController
17
 *
18
 * @author   List of contributors <https://github.com/libgraviton/graviton/graphs/contributors>
19
 * @license  http://opensource.org/licenses/gpl-license.php GNU Public License
20
 * @link     http://swisscom.ch
21
 */
22
class MainController
23
{
24
    /**
25
     * @var Router
26
     */
27
    private $router;
28
29
    /**
30
     * @var Response
31
     */
32
    private $response;
33
34
    /**
35
     * @var RestUtilsInterface
36
     */
37
    private $restUtils;
38
39
    /**
40
     * @var EngineInterface
41
     */
42
    private $templating;
43
44
    /**
45
     * @var array
46
     */
47
    private $addditionalRoutes;
48
49
    /**
50
     * @var array
51
     */
52
    private $pathWhitelist;
53
54
    /**
55
     * @param Router             $router           router
56
     * @param Response           $response         prepared response
57
     * @param RestUtilsInterface $restUtils        rest-utils from GravitonRestBundle
58
     * @param EngineInterface    $templating       templating-engine
59
     * @param array              $additionalRoutes custom routes
60
     * @param array              $pathWhitelist    serviec path that always get aded to the main page
61
     *
62
     */
63 7
    public function __construct(
64
        Router $router,
65
        Response $response,
66
        RestUtilsInterface $restUtils,
67
        EngineInterface $templating,
68
        $additionalRoutes = array(),
69
        $pathWhitelist = []
70
    ) {
71 7
        $this->router = $router;
72 7
        $this->response = $response;
73 7
        $this->restUtils = $restUtils;
74 7
        $this->templating = $templating;
75 7
        $this->addditionalRoutes = $additionalRoutes;
76 7
        $this->pathWhitelist = $pathWhitelist;
77 7
    }
78
79
    /**
80
     * create simple start page.
81
     *
82
     * @return Response $response Response with result or error
83
     */
84 4
    public function indexAction()
85
    {
86 4
        $response = $this->response;
87
88 4
        $mainPage = new \stdClass;
89 4
        $mainPage->message = 'Please look at the Link headers of this response for further information.';
90 4
        $mainPage->services = $this->determineServices(
91 4
            $this->restUtils->getOptionRoutes()
92 4
        );
93
94 4
        $response->setContent(json_encode($mainPage));
95 4
        $response->setStatusCode(Response::HTTP_OK);
96 4
        $response->headers->set('Link', $this->prepareLinkHeader());
97
98
        // todo: make sure, that the correct content type is set.
99
        // todo: this should be covered by a kernel.response event listener?
100 4
        $response->headers->set('Content-Type', 'application/json');
101
102 4
        return $this->render(
103 4
            'GravitonCoreBundle:Main:index.json.twig',
104 4
            array('response' => $response->getContent()),
105
            $response
106 4
        );
107
    }
108
109
    /**
110
     * Determines what service endpoints are available.
111
     *
112
     * @param array $optionRoutes List of routing options.
113
     *
114
     * @return array
115
     */
116 5
    protected function determineServices(array $optionRoutes)
117
    {
118 5
        $sortArr = array();
119 5
        $router = $this->router;
120 5
        foreach ($this->addditionalRoutes as $route) {
121
            // hack because only array keys are used
122 4
            $optionRoutes[$route] = null;
123 5
        }
124
125 5
        $services = array_map(
126 5
            function ($routeName) use ($router) {
127 5
                list($app, $bundle, $rest, $document) = explode('.', $routeName);
128 5
                $schemaRoute = implode('.', array($app, $bundle, $rest, $document, 'canonicalSchema'));
129
130
                return array(
131 5
                    '$ref' => $router->generate($routeName, array(), true),
132 5
                    'profile' => $router->generate($schemaRoute, array(), true),
133 5
                );
134 5
            },
135 5
            array_keys($optionRoutes)
136 5
        );
137
138 5
        foreach ($services as $key => $val) {
139 5
            if ($this->isRelevantForMainPage($val)) {
140 5
                $sortArr[$key] = $val['$ref'];
141
142 5
            } else {
143 4
                unset($services[$key]);
144
            }
145 5
        }
146 5
        array_multisort($sortArr, SORT_ASC, $services);
147
148 5
        return $services;
149
    }
150
151
    /**
152
     * Prepares the header field containing information about pagination.
153
     *
154
     * @return string
155
     */
156 5
    protected function prepareLinkHeader()
157
    {
158 5
        $links = new LinkHeader(array());
159 5
        $links->add(
160 5
            new LinkHeaderItem(
161 5
                $this->router->generate('graviton.core.rest.app.all', array(), true),
162
                array(
163 5
                    'rel'  => 'apps',
164
                    'type' => 'application/json'
165 5
                )
166 5
            )
167 5
        );
168
169 5
        return (string) $links;
170
    }
171
172
    /**
173
     * tells if a service is relevant for the mainpage
174
     *
175
     * @param array $val value of service spec
176
     *
177
     * @return boolean
178
     */
179 5
    private function isRelevantForMainPage($val)
180
    {
181 5
        return (substr($val['$ref'], -1) === '/')
182 5
            || in_array(parse_url($val['$ref'], PHP_URL_PATH), $this->pathWhitelist);
183
    }
184
185
    /**
186
     * Renders a view.
187
     *
188
     * @param string   $view       The view name
189
     * @param array    $parameters An array of parameters to pass to the view
190
     * @param Response $response   A response instance
191
     *
192
     * @return Response A Response instance
193
     */
194 4
    public function render($view, array $parameters = array(), Response $response = null)
195
    {
196 4
        return $this->templating->renderResponse($view, $parameters, $response);
197
    }
198
}
199