Completed
Pull Request — develop (#512)
by Adrian
16:23 queued 09:34
created

MainController::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 19
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 19
ccs 0
cts 19
cp 0
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 17
nc 1
nop 8
crap 2

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
/**
3
 * controller for start page
4
 */
5
6
namespace Graviton\CoreBundle\Controller;
7
8
use Graviton\ProxyBundle\Service\ApiDefinitionLoader;
9
use Graviton\RestBundle\HttpFoundation\LinkHeader;
10
use Graviton\RestBundle\HttpFoundation\LinkHeaderItem;
11
use Graviton\RestBundle\Service\RestUtilsInterface;
12
use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface;
13
use Symfony\Component\HttpFoundation\Request;
14
use Symfony\Component\HttpFoundation\Response;
15
use Symfony\Component\Routing\Router;
16
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
17
18
/**
19
 * MainController
20
 *
21
 * @author   List of contributors <https://github.com/libgraviton/graviton/graphs/contributors>
22
 * @license  http://opensource.org/licenses/gpl-license.php GNU Public License
23
 * @link     http://swisscom.ch
24
 */
25
class MainController
26
{
27
    /**
28
     * @var Router
29
     */
30
    private $router;
31
32
    /**
33
     * @var Response
34
     */
35
    private $response;
36
37
    /**
38
     * @var RestUtilsInterface
39
     */
40
    private $restUtils;
41
42
    /**
43
     * @var EngineInterface
44
     */
45
    private $templating;
46
47
    /**
48
     * @var ApiDefinitionLoader
49
     */
50
    private $apiLoader;
51
52
    /**
53
     * @var array
54
     */
55
    private $addditionalRoutes;
56
57
    /**
58
     * @var array
59
     */
60
    private $pathWhitelist;
61
62
    /**
63
     * @var array
64
     */
65
    private $proxySourceConfiguration;
66
67
    /**
68
     * @param Router              $router                   router
69
     * @param Response            $response                 prepared response
70
     * @param RestUtilsInterface  $restUtils                rest-utils from GravitonRestBundle
71
     * @param EngineInterface     $templating               templating-engine
72
     * @param ApiDefinitionLoader $apiLoader                loader for third party api definition
73
     * @param array               $additionalRoutes         custom routes
74
     * @param array               $pathWhitelist            serviec path that always get aded to the main page
75
     * @param array               $proxySourceConfiguration Set of sources to be recognized by the controller
76
     */
77
    public function __construct(
78
        Router $router,
79
        Response $response,
80
        RestUtilsInterface $restUtils,
81
        EngineInterface $templating,
82
        ApiDefinitionLoader $apiLoader,
83
        $additionalRoutes = array(),
84
        $pathWhitelist = [],
85
        array $proxySourceConfiguration = array()
86
    ) {
87
        $this->router = $router;
88
        $this->response = $response;
89
        $this->restUtils = $restUtils;
90
        $this->templating = $templating;
91
        $this->apiLoader = $apiLoader;
92
        $this->addditionalRoutes = $additionalRoutes;
93
        $this->pathWhitelist = $pathWhitelist;
94
        $this->proxySourceConfiguration = $proxySourceConfiguration;
95
    }
96
97
    /**
98
     * create simple start page.
99
     *
100
     * @return Response $response Response with result or error
101
     */
102
    public function indexAction()
103
    {
104
        $response = $this->response;
105
106
        $mainPage = new \stdClass();
107
        $mainPage->services = $this->determineServices(
108
            $this->restUtils->getOptionRoutes()
109
        );
110
111
        $mainPage->thirdparty = $this->registerThirdPartyServices();
112
113
        $response->setContent(json_encode($mainPage));
114
        $response->setStatusCode(Response::HTTP_OK);
115
        $response->headers->set('Link', $this->prepareLinkHeader());
116
117
        // todo: make sure, that the correct content type is set.
118
        // todo: this should be covered by a kernel.response event listener?
119
        $response->headers->set('Content-Type', 'application/json');
120
121
        return $this->render(
122
            'GravitonCoreBundle:Main:index.json.twig',
123
            array('response' => $response->getContent()),
124
            $response
125
        );
126
    }
127
128
    /**
129
     * Renders a view.
130
     *
131
     * @param string   $view       The view name
132
     * @param array    $parameters An array of parameters to pass to the view
133
     * @param Response $response   A response instance
0 ignored issues
show
Documentation introduced by
Should the type for parameter $response not be null|Response?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
134
     *
135
     * @return Response A Response instance
136
     */
137
    public function render($view, array $parameters = array(), Response $response = null)
138
    {
139
        return $this->templating->renderResponse($view, $parameters, $response);
140
    }
141
142
    /**
143
     * Determines what service endpoints are available.
144
     *
145
     * @param array $optionRoutes List of routing options.
146
     *
147
     * @return array
148
     */
149
    protected function determineServices(array $optionRoutes)
150
    {
151
        $sortArr = array();
152
        $router = $this->router;
153
        foreach ($this->addditionalRoutes as $route) {
154
            // hack because only array keys are used
155
            $optionRoutes[$route] = null;
156
        }
157
158
        $services = array_map(
159
            function ($routeName) use ($router) {
160
                list($app, $bundle, $rest, $document) = explode('.', $routeName);
161
                $schemaRoute = implode('.', array($app, $bundle, $rest, $document, 'canonicalSchema'));
162
163
                return array(
164
                    '$ref' => $router->generate($routeName, array(), UrlGeneratorInterface::ABSOLUTE_URL),
165
                    'profile' => $router->generate($schemaRoute, array(), UrlGeneratorInterface::ABSOLUTE_URL),
166
                );
167
            },
168
            array_keys($optionRoutes)
169
        );
170
171
        foreach ($services as $key => $val) {
172
            if ($this->isRelevantForMainPage($val) && !in_array($val['$ref'], $sortArr)) {
173
                $sortArr[$key] = $val['$ref'];
174
            } else {
175
                unset($services[$key]);
176
            }
177
        }
178
        array_multisort($sortArr, SORT_ASC, $services);
179
180
        return $services;
181
    }
182
183
    /**
184
     * Prepares the header field containing information about pagination.
185
     *
186
     * @return string
187
     */
188
    protected function prepareLinkHeader()
189
    {
190
        $links = new LinkHeader(array());
191
        $links->add(
192
            new LinkHeaderItem(
193
                $this->router->generate('graviton.core.rest.app.all', array (), UrlGeneratorInterface::ABSOLUTE_URL),
194
                array ('rel' => 'apps', 'type' => 'application/json')
195
            )
196
        );
197
198
        return (string) $links;
199
    }
200
201
    /**
202
     * tells if a service is relevant for the mainpage
203
     *
204
     * @param array $val value of service spec
205
     *
206
     * @return boolean
207
     */
208
    private function isRelevantForMainPage($val)
209
    {
210
        return (substr($val['$ref'], -1) === '/')
211
            || in_array(parse_url($val['$ref'], PHP_URL_PATH), $this->pathWhitelist);
212
    }
213
214
    /**
215
     * Resolves all third party routes and add schema info
216
     *
217
     * @param array $thirdApiRoutes list of all routes from an API
218
     *
219
     * @return array
220
     */
221
    protected function determineThirdPartyServices(array $thirdApiRoutes)
222
    {
223
        $definition = $this->apiLoader;
224
        $mainRoute = $this->router->generate(
225
            'graviton.core.static.main.all',
226
            array(),
227
            UrlGeneratorInterface::ABSOLUTE_URL
228
        );
229
        $services = array_map(
230
            function ($apiRoute) use ($mainRoute, $definition) {
231
232
                return array (
233
                    '$ref' => $mainRoute.$apiRoute,
234
                    'profile' => $mainRoute."schema/".$apiRoute."/item",
235
                );
236
            },
237
            $thirdApiRoutes
238
        );
239
240
        return $services;
241
    }
242
243
    /**
244
     * Finds configured external apis to be exposed via G2.
245
     *
246
     * @return array
247
     */
248
    private function registerThirdPartyServices()
249
    {
250
        $services = [];
251
252
        // getenv()... it's a workaround for run all tests on travis! will be removed!
253
        if (getenv('USER') !== 'travis' && getenv('HAS_JOSH_K_SEAL_OF_APPROVAL') !== true) {
254
            foreach (array_keys($this->proxySourceConfiguration) as $source) {
255
                foreach ($this->proxySourceConfiguration[$source] as $thirdparty => $option) {
256
                    $this->apiLoader->resetDefinitionLoader();
257
                    $this->apiLoader->setOption($option);
258
                    $this->apiLoader->addOptions($this->decideApiAndEndpoint($option));
259
                    $services[$thirdparty] = $this->determineThirdPartyServices(
260
                        $this->apiLoader->getAllEndpoints(false, true)
261
                    );
262
                }
263
            }
264
        }
265
266
        return $services;
267
    }
268
269
    /**
270
     * get API name and endpoint from the url (third party API)
271
     *
272
     * @param array $config Configuration information ['prefix', 'serviceEndpoint']
273
     *
274
     * @return array
275
     */
276
    protected function decideApiAndEndpoint(array $config)
277
    {
278
        if (array_key_exists('serviceEndpoint', $config)) {
279
            return array (
280
                "apiName" => $config['prefix'],
281
                "endpoint" => $config['serviceEndpoint'],
282
            );
283
        }
284
285
        return [];
286
    }
287
}
288