Completed
Push — feature/bigfix_proxy_httploade... ( 5efe01 )
by Bastian
43:53 queued 29:53
created

MainController::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 19
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 1
Metric Value
dl 0
loc 19
ccs 10
cts 10
cp 1
rs 9.4285
cc 1
eloc 17
nc 1
nop 8
crap 1

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
17
/**
18
 * MainController
19
 *
20
 * @author   List of contributors <https://github.com/libgraviton/graviton/graphs/contributors>
21
 * @license  http://opensource.org/licenses/gpl-license.php GNU Public License
22
 * @link     http://swisscom.ch
23
 */
24
class MainController
25
{
26
    /**
27
     * @var Router
28
     */
29
    private $router;
30
31
    /**
32
     * @var Response
33
     */
34
    private $response;
35
36
    /**
37
     * @var RestUtilsInterface
38
     */
39
    private $restUtils;
40
41
    /**
42
     * @var EngineInterface
43
     */
44
    private $templating;
45
46
    /**
47
     * @var ApiDefinitionLoader
48
     */
49
    private $apiLoader;
50
    
51
    /**
52
     * @var array
53
     */
54
    private $addditionalRoutes;
55
56
    /**
57
     * @var array
58
     */
59
    private $pathWhitelist;
60
61
    /**
62
     * @var array
63
     */
64
    private $proxySourceConfiguration;
65
66
    /**
67
     * @param Router              $router                   router
68
     * @param Response            $response                 prepared response
69
     * @param RestUtilsInterface  $restUtils                rest-utils from GravitonRestBundle
70
     * @param EngineInterface     $templating               templating-engine
71
     * @param ApiDefinitionLoader $apiLoader                loader for third party api definition
72
     * @param array               $additionalRoutes         custom routes
73
     * @param array               $pathWhitelist            serviec path that always get aded to the main page
74
     * @param array               $proxySourceConfiguration Set of sources to be recognized by the controller
75
     */
76 7
    public function __construct(
77
        Router $router,
78
        Response $response,
79
        RestUtilsInterface $restUtils,
80
        EngineInterface $templating,
81
        ApiDefinitionLoader $apiLoader,
82
        $additionalRoutes = array(),
83
        $pathWhitelist = [],
84
        array $proxySourceConfiguration = array()
85
    ) {
86 7
        $this->router = $router;
87 7
        $this->response = $response;
88 7
        $this->restUtils = $restUtils;
89 7
        $this->templating = $templating;
90 7
        $this->apiLoader = $apiLoader;
91 7
        $this->addditionalRoutes = $additionalRoutes;
92 7
        $this->pathWhitelist = $pathWhitelist;
93 7
        $this->proxySourceConfiguration = $proxySourceConfiguration;
94 7
    }
95
96
    /**
97
     * create simple start page.
98
     *
99
     * @return Response $response Response with result or error
100
     */
101 4
    public function indexAction()
102
    {
103 4
        $response = $this->response;
104
105 4
        $mainPage = new \stdClass();
106 4
        $mainPage->message = 'Please look at the Link headers of this response for further information.';
107 4
        $mainPage->services = $this->determineServices(
108 4
            $this->restUtils->getOptionRoutes()
109
        );
110
111 4
        $mainPage->thirdparty = $this->registerThirdPartyServices();
112
113 4
        $response->setContent(json_encode($mainPage));
114 4
        $response->setStatusCode(Response::HTTP_OK);
115 4
        $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 4
        $response->headers->set('Content-Type', 'application/json');
120
121 4
        return $this->render(
122 4
            'GravitonCoreBundle:Main:index.json.twig',
123 4
            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 4
    public function render($view, array $parameters = array(), Response $response = null)
138
    {
139 4
        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 5
    protected function determineServices(array $optionRoutes)
150
    {
151 5
        $sortArr = array();
152 5
        $router = $this->router;
153 5
        foreach ($this->addditionalRoutes as $route) {
154
            // hack because only array keys are used
155 4
            $optionRoutes[$route] = null;
156
        }
157
158 5
        $services = array_map(
159
            function ($routeName) use ($router) {
160 5
                list($app, $bundle, $rest, $document) = explode('.', $routeName);
161 5
                $schemaRoute = implode('.', array($app, $bundle, $rest, $document, 'canonicalSchema'));
162
163
                return array(
164 5
                    '$ref' => $router->generate($routeName, array(), true),
0 ignored issues
show
Documentation introduced by
true is of type boolean, but the function expects a integer.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
165 5
                    'profile' => $router->generate($schemaRoute, array(), true),
0 ignored issues
show
Documentation introduced by
true is of type boolean, but the function expects a integer.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
166
                );
167 5
            },
168
            array_keys($optionRoutes)
169
        );
170
171 5
        foreach ($services as $key => $val) {
172 5
            if ($this->isRelevantForMainPage($val)) {
173 5
                $sortArr[$key] = $val['$ref'];
174
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
175
            } else {
176 5
                unset($services[$key]);
177
            }
178
        }
179 5
        array_multisort($sortArr, SORT_ASC, $services);
180
181 5
        return $services;
182
    }
183
184
    /**
185
     * Prepares the header field containing information about pagination.
186
     *
187
     * @return string
188
     */
189 5
    protected function prepareLinkHeader()
190
    {
191 5
        $links = new LinkHeader(array());
192 5
        $links->add(
193 5
            new LinkHeaderItem(
194 5
                $this->router->generate('graviton.core.rest.app.all', array (), true),
0 ignored issues
show
Documentation introduced by
true is of type boolean, but the function expects a integer.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
195 5
                array ('rel' => 'apps', 'type' => 'application/json')
196
            )
197
        );
198
199 5
        return (string) $links;
200
    }
201
202
    /**
203
     * tells if a service is relevant for the mainpage
204
     *
205
     * @param array $val value of service spec
206
     *
207
     * @return boolean
208
     */
209 5
    private function isRelevantForMainPage($val)
210
    {
211 5
        return (substr($val['$ref'], -1) === '/')
212 5
            || in_array(parse_url($val['$ref'], PHP_URL_PATH), $this->pathWhitelist);
213
    }
214
215
    /**
216
     * Resolves all third party routes and add schema info
217
     *
218
     * @param array $thirdApiRoutes list of all routes from an API
219
     *
220
     * @return array
221
     */
222
    protected function determineThirdPartyServices(array $thirdApiRoutes)
223
    {
224
        $definition = $this->apiLoader;
225
        $mainRoute = $this->router->generate(
226
            'graviton.core.static.main.all',
227
            array(),
228
            true
0 ignored issues
show
Documentation introduced by
true is of type boolean, but the function expects a integer.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
229
        );
230
        $services = array_map(
231
            function ($apiRoute) use ($mainRoute, $definition) {
232
233
                return array (
234
                    '$ref' => $mainRoute.$apiRoute,
235
                    'profile' => $mainRoute."schema/".$apiRoute."/item",
236
                );
237
            },
238
            $thirdApiRoutes
239
        );
240
241
        return $services;
242
    }
243
244
    /**
245
     * Finds configured external apis to be exposed via G2.
246
     *
247
     * @return array
248
     */
249 4
    private function registerThirdPartyServices()
250
    {
251 4
        $services = [];
252
        // getenv()... it's a workaround for run all tests on travis! will be removed!
253 4
        if (array_key_exists('swagger', $this->proxySourceConfiguration)
254 4
            && getenv('USER') !== 'travis'
255 4
            && getenv('HAS_JOSH_K_SEAL_OF_APPROVAL') !== true) {
256
            //@todo: this needs to be refactored in case there are other sources than swagger configuration files
257
            foreach ($this->proxySourceConfiguration['swagger'] as $thirdparty => $option) {
258
                $this->apiLoader->setOption($option);
259
                $services[$thirdparty] = $this->determineThirdPartyServices(
260
                    $this->apiLoader->getAllEndpoints(false, true)
261
                );
262
            }
263
        }
264
265 4
        return $services;
266
    }
267
}
268