Passed
Push — master ( e876c1...0991d4 )
by Fran
03:32
created

Router::extractDomain()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 5

Importance

Changes 0
Metric Value
cc 5
eloc 8
nc 5
nop 1
dl 0
loc 15
ccs 8
cts 8
cp 1
crap 5
rs 8.8571
c 0
b 0
f 0
1
<?php
2
namespace PSFS\base;
3
4
use PSFS\base\config\Config;
5
use PSFS\base\dto\JsonResponse;
6
use PSFS\base\exception\AccessDeniedException;
7
use PSFS\base\exception\ConfigException;
8
use PSFS\base\exception\RouterException;
9
use PSFS\base\types\helpers\AdminHelper;
10
use PSFS\base\types\helpers\GeneratorHelper;
11
use PSFS\base\types\helpers\I18nHelper;
12
use PSFS\base\types\helpers\RequestHelper;
13
use PSFS\base\types\helpers\RouterHelper;
14
use PSFS\base\types\helpers\SecurityHelper;
15
use PSFS\base\types\traits\SingletonTrait;
16
use PSFS\controller\base\Admin;
17
use PSFS\services\AdminServices;
18
use Symfony\Component\Finder\Finder;
19
20
21
/**
22
 * Class Router
23
 * @package PSFS
24
 */
25
class Router
26
{
27
    use SingletonTrait;
28
29
    protected $routing;
30
    protected $slugs;
31
    private $domains = [];
32
    /**
33
     * @var Finder $finder
34
     */
35
    private $finder;
36
    /**
37
     * @var \PSFS\base\Cache $cache
38
     */
39
    private $cache;
40
    /**
41
     * @var bool headersSent
42
     */
43
    protected $headersSent = false;
44
    /**
45
     * @var int
46
     */
47
    protected $cacheType = Cache::JSON;
48
    /**
49
     * @var bool
50
     */
51
    protected $loaded = false;
52
53
    /**
54
     * Constructor Router
55
     * @throws ConfigException
56
     */
57 1
    public function __construct()
58
    {
59 1
        $this->finder = new Finder();
60 1
        $this->cache = Cache::getInstance();
61 1
        $this->init();
62 1
    }
63
64
    /**
65
     * Inicializador Router
66
     * @throws ConfigException
67
     */
68 1
    public function init()
69
    {
70 1
        list($this->routing, $this->slugs) = $this->cache->getDataFromFile(CONFIG_DIR . DIRECTORY_SEPARATOR . "urls.json", $this->cacheType, TRUE);
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 147 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
71 1
        if (empty($this->routing) || Config::getInstance()->getDebugMode()) {
72 1
            $this->debugLoad();
73
        } else {
74
            $this->domains = $this->cache->getDataFromFile(CONFIG_DIR . DIRECTORY_SEPARATOR . "domains.json", $this->cacheType, TRUE);
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 134 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
75
        }
76 1
        $this->checkExternalModules(false);
77 1
        $this->setLoaded(true);
78 1
    }
79
80
    /**
81
     * Load routes and domains and store them
82
     */
83 1
    private function debugLoad() {
84 1
        Logger::log('Begin routes load', LOG_DEBUG);
85 1
        $this->hydrateRouting();
86 1
        $this->simpatize();
87 1
        Logger::log('End routes load', LOG_DEBUG);
88 1
    }
89
90
    /**
91
     * Método que deriva un error HTTP de página no encontrada
92
     *
93
     * @param \Exception $e
0 ignored issues
show
Documentation introduced by
Should the type for parameter $e not be null|\Exception?

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...
94
     * @param boolean $isJson
95
     *
96
     * @return string HTML
97
     */
98
    public function httpNotFound(\Exception $e = NULL, $isJson = false)
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $e. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
99
    {
100
        Logger::log('Throw not found exception');
101
        if (NULL === $e) {
102
            Logger::log('Not found page throwed without previous exception', LOG_WARNING);
103
            $e = new \Exception(_('Page not found'), 404);
104
        }
105
        $template = Template::getInstance()->setStatus($e->getCode());
106
        if (preg_match('/json/i', Request::getInstance()->getServer('CONTENT_TYPE')) || $isJson) {
107
            $response = new JsonResponse(null, false, 0, 0, $e->getMessage());
0 ignored issues
show
Documentation introduced by
null is of type null, but the function expects a array.

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...
108
            return $template->output(json_encode($response), 'application/json');
109
        } else {
110
            $not_found_rouote = Config::getParam('route.404');
111
            if(null !== $not_found_rouote) {
112
                Request::getInstance()->redirect($this->getRoute($not_found_rouote, true));
113
            } else {
114
                return $template->render('error.html.twig', array(
115
                    'exception' => $e,
116
                    'trace' => $e->getTraceAsString(),
117
                    'error_page' => TRUE,
118
                ));
119
            }
120
        }
121
    }
122
123
    /**
124
     * Método que devuelve las rutas
125
     * @return string|null
126
     */
127 1
    public function getSlugs()
128
    {
129 1
        return $this->slugs;
130
    }
131
132
    /**
133
     * @return mixed
134
     */
135 2
    public function getRoutes() {
136 2
        return $this->routing;
137
    }
138
139
    /**
140
     * Method that extract all routes in the platform
141
     * @return array
142
     */
143 1
    public function getAllRoutes()
144
    {
145 1
        $routes = [];
146 1
        foreach ($this->getRoutes() as $path => $route) {
147 1
            if (array_key_exists('slug', $route)) {
148 1
                $routes[$route['slug']] = $path;
149
            }
150
        }
151 1
        return $routes;
152
    }
153
154
    /**
155
     * Método que calcula el objeto a enrutar
156
     *
157
     * @param string|null $route
158
     *
159
     * @throws \Exception
160
     * @return string HTML
161
     */
162 1
    public function execute($route)
163
    {
164 1
        Logger::log('Executing the request');
165
        try {
166
            //Search action and execute
167 1
            $this->searchAction($route);
168 1
        } catch (AccessDeniedException $e) {
169
            Logger::log(_('Solicitamos credenciales de acceso a zona restringida'));
170
            return Admin::staticAdminLogon($route);
171 1
        } catch (RouterException $r) {
172 1
            Logger::log($r->getMessage(), LOG_WARNING);
173
        } catch (\Exception $e) {
174
            Logger::log($e->getMessage(), LOG_ERR);
175
            throw $e;
176
        }
177
178 1
        throw new RouterException(_("Página no encontrada"), 404);
179
    }
180
181
    /**
182
     * Método que busca el componente que ejecuta la ruta
183
     *
184
     * @param string $route
185
     *
186
     * @throws \PSFS\base\exception\RouterException
187
     */
188 1
    protected function searchAction($route)
189
    {
190 1
        Logger::log('Searching action to execute: ' . $route, LOG_INFO);
191
        //Revisamos si tenemos la ruta registrada
192 1
        $parts = parse_url($route);
193 1
        $path = (array_key_exists('path', $parts)) ? $parts['path'] : $route;
194 1
        $httpRequest = Request::getInstance()->getMethod();
195 1
        foreach ($this->routing as $pattern => $action) {
196 1
            list($httpMethod, $routePattern) = RouterHelper::extractHttpRoute($pattern);
197 1
            $matched = RouterHelper::matchRoutePattern($routePattern, $path);
198 1
            if ($matched && ($httpMethod === "ALL" || $httpRequest === $httpMethod) && RouterHelper::compareSlashes($routePattern, $path)) {
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 140 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
199
                // Checks restricted access
200
                SecurityHelper::checkRestrictedAccess($route);
201
                $get = RouterHelper::extractComponents($route, $routePattern);
202
                /** @var $class \PSFS\base\types\Controller */
203
                $class = RouterHelper::getClassToCall($action);
204
                try {
205
                    if($this->checkRequirements($action, $get)) {
206
                        $this->executeCachedRoute($route, $action, $class, $get);
207
                    } else {
208
                        throw new RouterException(_('La ruta no es válida'), 400);
209
                    }
210
                } catch (\Exception $e) {
211
                    Logger::log($e->getMessage(), LOG_ERR);
212
                    throw new \RuntimeException($e->getMessage(), 404, $e);
213
                }
214
            }
215
        }
216 1
        throw new RouterException(_("Ruta no encontrada"));
217
    }
218
219
    /**
220
     * @param array $action
221
     * @param array $params
222
     * @return bool
223
     */
224
    private function checkRequirements(array $action, array $params = []) {
225
        $valid = true;
226
        if(!empty($action['requirements'])) {
227
            if(!empty($params)) {
228
                $checked = 0;
229
                foreach(array_keys($params) as $key) {
230
                    if(in_array($key, $action['requirements'])) {
231
                        $checked++;
232
                    }
233
                }
234
                $valid = count($action['requirements']) == $checked;
235
            } else {
236
                $valid = false;
237
            }
238
        }
239
        return $valid;
240
    }
241
242
    /**
243
     * Método que manda las cabeceras de autenticación
244
     * @return string HTML
245
     */
246
    protected function sentAuthHeader()
247
    {
248
        return AdminServices::getInstance()->setAdminHeaders();
249
    }
250
251
    /**
252
     * @return string|null
253
     */
254 1
    private function getExternalModules() {
255 1
        $externalModules = Config::getParam('modules.extend', '');
256 1
        if(Config::getParam('psfs.auth', false)) {
257
            $externalModules .= ',psfs/auth';
258
        }
259 1
        return $externalModules;
260
    }
261
262
    /**
263
     * Method that check if the proyect has sub project to include
264
     * @param boolean $hydrateRoute
265
     */
266 1
    private function checkExternalModules($hydrateRoute = true)
267
    {
268 1
        $externalModules = $this->getExternalModules();
269 1
        if (strlen($externalModules)) {
270
            $externalModules = explode(',', $externalModules);
271
            foreach ($externalModules as &$module) {
272
                $module = $this->loadExternalModule($hydrateRoute, $module);
273
            }
274
        }
275 1
    }
276
277
    /**
278
     * Method that gather all the routes in the project
279
     */
280 1
    private function generateRouting()
281
    {
282 1
        $base = SOURCE_DIR;
283 1
        $modulesPath = realpath(CORE_DIR);
284 1
        $this->routing = $this->inspectDir($base, "PSFS", array());
285 1
        $this->checkExternalModules();
286 1
        if (file_exists($modulesPath)) {
287
            $modules = $this->finder->directories()->in($modulesPath)->depth(0);
288
            foreach ($modules as $modulePath) {
289
                $module = $modulePath->getBasename();
290
                $this->routing = $this->inspectDir($modulesPath . DIRECTORY_SEPARATOR . $module, $module, $this->routing);
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 122 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
291
            }
292
        }
293 1
        $this->cache->storeData(CONFIG_DIR . DIRECTORY_SEPARATOR . "domains.json", $this->domains, Cache::JSON, TRUE);
294 1
    }
295
296
    /**
297
     * Método que regenera el fichero de rutas
298
     * @throws ConfigException
299
     */
300 1
    public function hydrateRouting()
301
    {
302 1
        $this->generateRouting();
303 1
        $home = Config::getInstance()->get('home.action');
304 1
        if (NULL !== $home || $home !== '') {
305 1
            $home_params = NULL;
306 1
            foreach ($this->routing as $pattern => $params) {
307 1
                list($method, $route) = RouterHelper::extractHttpRoute($pattern);
308 1
                if (preg_match("/" . preg_quote($route, "/") . "$/i", "/" . $home)) {
309
                    $home_params = $params;
310
                }
311
            }
312 1
            if (NULL !== $home_params) {
313
                $this->routing['/'] = $home_params;
314
            }
315
        }
316 1
    }
317
318
    /**
319
     * Método que inspecciona los directorios en busca de clases que registren rutas
320
     *
321
     * @param string $origen
322
     * @param string $namespace
323
     * @param array $routing
324
     *
325
     * @return array
326
     * @throws ConfigException
327
     */
328 1
    private function inspectDir($origen, $namespace = 'PSFS', $routing = [])
329
    {
330 1
        $files = $this->finder->files()->in($origen)->path('/(controller|api)/i')->depth(1)->name("*.php");
331 1
        foreach ($files as $file) {
332 1
            $filename = str_replace("/", '\\', str_replace($origen, '', $file->getPathname()));
333 1
            $routing = $this->addRouting($namespace . str_replace('.php', '', $filename), $routing, $namespace);
334
        }
335 1
        $this->finder = new Finder();
336
337 1
        return $routing;
338
    }
339
340
    /**
341
     * Checks that a namespace exists
342
     * @param string $namespace
343
     * @return bool
344
     */
345 1
    public static function exists($namespace)
346
    {
347 1
        return (class_exists($namespace) || interface_exists($namespace) || trait_exists($namespace));
348
    }
349
350
    /**
351
     * Método que añade nuevas rutas al array de referencia
352
     *
353
     * @param string $namespace
354
     * @param array $routing
355
     * @param string $module
356
     *
357
     * @return array
358
     * @throws ConfigException
359
     */
360 1
    private function addRouting($namespace, &$routing, $module = 'PSFS')
361
    {
362 1
        if (self::exists($namespace)) {
363 1
            $reflection = new \ReflectionClass($namespace);
364 1
            if (FALSE === $reflection->isAbstract() && FALSE === $reflection->isInterface()) {
365 1
                $this->extractDomain($reflection);
366 1
                $classComments = $reflection->getDocComment();
367 1
                preg_match('/@api\ (.*)\n/im', $classComments, $apiPath);
368 1
                $api = '';
369 1
                if (count($apiPath)) {
370
                    $api = array_key_exists(1, $apiPath) ? $apiPath[1] : $api;
371
                }
372 1
                foreach ($reflection->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) {
373 1
                    if (preg_match('/@route\ /i', $method->getDocComment())) {
374 1
                        list($route, $info) = RouterHelper::extractRouteInfo($method, str_replace('\\', '', $api), str_replace('\\', '', $module));
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 147 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
375
376 1
                        if (null !== $route && null !== $info) {
377 1
                            $info['class'] = $namespace;
378 1
                            $routing[$route] = $info;
379
                        }
380
                    }
381
                }
382
            }
383
        }
384
385 1
        return $routing;
386
    }
387
388
    /**
389
     * Método que extrae de la ReflectionClass los datos necesarios para componer los dominios en los templates
390
     *
391
     * @param \ReflectionClass $class
392
     *
393
     * @return Router
394
     * @throws ConfigException
395
     */
396 1
    protected function extractDomain(\ReflectionClass $class)
397
    {
398
        //Calculamos los dominios para las plantillas
399 1
        if ($class->hasConstant("DOMAIN") && !$class->isAbstract()) {
400 1
            if (!$this->domains) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->domains of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
401 1
                $this->domains = [];
402
            }
403 1
            $domain = "@" . $class->getConstant("DOMAIN") . "/";
404 1
            if (!array_key_exists($domain, $this->domains)) {
405 1
                $this->domains[$domain] = RouterHelper::extractDomainInfo($class, $domain);
406
            }
407
        }
408
409 1
        return $this;
410
    }
411
412
    /**
413
     * Método que genera las urls amigables para usar dentro del framework
414
     * @return Router
415
     */
416 1
    public function simpatize()
417
    {
418 1
        $translationFileName = "translations" . DIRECTORY_SEPARATOR . "routes_translations.php";
419 1
        $absoluteTranslationFileName = CACHE_DIR . DIRECTORY_SEPARATOR . $translationFileName;
420 1
        $this->generateSlugs($absoluteTranslationFileName);
421 1
        GeneratorHelper::createDir(CONFIG_DIR);
422 1
        Cache::getInstance()->storeData(CONFIG_DIR . DIRECTORY_SEPARATOR . "urls.json", array($this->routing, $this->slugs), Cache::JSON, TRUE);
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 144 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
423
424 1
        return $this;
425
    }
426
427
    /**
428
     * Método que devuelve una ruta del framework
429
     *
430
     * @param string $slug
431
     * @param boolean $absolute
432
     * @param array $params
433
     *
434
     * @return string|null
435
     * @throws RouterException
436
     */
437 1
    public function getRoute($slug = '', $absolute = FALSE, $params = [])
438
    {
439 1
        if (strlen($slug) === 0) {
440
            return ($absolute) ? Request::getInstance()->getRootUrl() . '/' : '/';
441
        }
442 1
        if (!is_array($this->slugs) || !array_key_exists($slug, $this->slugs)) {
443
            throw new RouterException(_("No existe la ruta especificada"));
444
        }
445 1
        $url = ($absolute) ? Request::getInstance()->getRootUrl() . $this->slugs[$slug] : $this->slugs[$slug];
446 1
        if (!empty($params)) foreach ($params as $key => $value) {
447
            $url = str_replace("{" . $key . "}", $value, $url);
448 1
        } elseif (!empty($this->routing[$this->slugs[$slug]]["default"])) {
449 1
            $url = ($absolute) ? Request::getInstance()->getRootUrl() . $this->routing[$this->slugs[$slug]]["default"] : $this->routing[$this->slugs[$slug]]["default"];
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 168 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
450
        }
451
452 1
        return preg_replace('/(GET|POST|PUT|DELETE|ALL)\#\|\#/', '', $url);
453
    }
454
455
    /**
456
     * Método que devuelve las rutas de administración
457
     * @deprecated
458
     * @return array
459
     */
460
    public function getAdminRoutes()
461
    {
462
        return AdminHelper::getAdminRoutes($this->routing);
463
    }
464
465
    /**
466
     * Método que devuelve le controlador del admin
467
     * @deprecated
468
     * @return Admin
469
     */
470
    public function getAdmin()
471
    {
472
        return Admin::getInstance();
473
    }
474
475
    /**
476
     * Método que extrae los dominios
477
     * @return array
478
     */
479 1
    public function getDomains()
480
    {
481 1
        return $this->domains ?: [];
482
    }
483
484
    /**
485
     * Método que ejecuta una acción del framework y revisa si lo tenemos cacheado ya o no
486
     *
487
     * @param string $route
488
     * @param array|null $action
489
     * @param types\Controller $class
490
     * @param array $params
0 ignored issues
show
Documentation introduced by
Should the type for parameter $params not be array|null? Also, consider making the array more specific, something like array<String>, or String[].

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. In addition it looks for parameters that have the generic type array and suggests a stricter type like array<String>.

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

Loading history...
491
     */
492
    protected function executeCachedRoute($route, $action, $class, $params = NULL)
493
    {
494
        Logger::log('Executing route ' . $route, LOG_INFO);
495
        $action['params'] = array_merge($action['params'], $params, Request::getInstance()->getQueryParams());
496
        Security::getInstance()->setSessionKey("__CACHE__", $action);
497
        $cache = Cache::needCache();
498
        $execute = TRUE;
499
        if (FALSE !== $cache && Config::getInstance()->getDebugMode() === FALSE && $action['http'] === 'GET') {
500
            list($path, $cacheDataName) = $this->cache->getRequestCacheHash();
501
            $cachedData = $this->cache->readFromCache("json" . DIRECTORY_SEPARATOR . $path . $cacheDataName,
502
                $cache, null);
0 ignored issues
show
Bug introduced by
It seems like $cache defined by \PSFS\base\Cache::needCache() on line 497 can also be of type boolean; however, PSFS\base\Cache::readFromCache() does only seem to accept integer, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
503
            if (NULL !== $cachedData) {
504
                $headers = $this->cache->readFromCache("json" . DIRECTORY_SEPARATOR . $path . $cacheDataName . ".headers",
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 122 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
505
                    $cache, null, Cache::JSON);
0 ignored issues
show
Bug introduced by
It seems like $cache defined by \PSFS\base\Cache::needCache() on line 497 can also be of type boolean; however, PSFS\base\Cache::readFromCache() does only seem to accept integer, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
506
                Template::getInstance()->renderCache($cachedData, $headers);
507
                $execute = FALSE;
508
            }
509
        }
510
        if ($execute) {
511
            Logger::log(_('Start executing action'), LOG_DEBUG);
512
            if (false === call_user_func_array(array($class, $action['method']), $params)) {
513
                Logger::log(_('An error ocurred trying to execute the action'), LOG_ERR, [error_get_last()]);
514
            }
515
        }
516
    }
517
518
    /**
519
     * Parse slugs to create translations
520
     *
521
     * @param string $absoluteTranslationFileName
522
     */
523 1
    private function generateSlugs($absoluteTranslationFileName)
524
    {
525 1
        $translations = I18nHelper::generateTranslationsFile($absoluteTranslationFileName);
526 1
        foreach ($this->routing as $key => &$info) {
527 1
            $keyParts = $key;
528 1
            if (FALSE === strstr("#|#", $key)) {
529 1
                $keyParts = explode("#|#", $key);
530 1
                $keyParts = array_key_exists(1, $keyParts) ? $keyParts[1] : '';
531
            }
532 1
            $slug = RouterHelper::slugify($keyParts);
533 1
            if (NULL !== $slug && !array_key_exists($slug, $translations)) {
534 1
                $translations[$slug] = $key;
535 1
                file_put_contents($absoluteTranslationFileName, "\$translations[\"{$slug}\"] = _(\"{$slug}\");\n", FILE_APPEND);
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 128 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
536
            }
537 1
            $this->slugs[$slug] = $key;
538 1
            $info["slug"] = $slug;
539
        }
540 1
    }
541
542
    /**
543
     * @param $hydrateRoute
544
     * @param $modulePath
545
     * @param $externalModulePath
546
     */
547
    private function loadExternalAutoloader(bool $hydrateRoute, \DirectoryIterator $modulePath, $externalModulePath)
548
    {
549
        $extModule = $modulePath->getBasename();
550
        $moduleAutoloader = realpath($externalModulePath . DIRECTORY_SEPARATOR . $extModule . DIRECTORY_SEPARATOR . 'autoload.php');
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 132 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
551
        if (file_exists($moduleAutoloader)) {
552
            @include $moduleAutoloader;
553
            if ($hydrateRoute) {
554
                $this->routing = $this->inspectDir($externalModulePath . DIRECTORY_SEPARATOR . $extModule, '\\' . $extModule, $this->routing);
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 142 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
555
            }
556
        }
557
    }
558
559
    /**
560
     * @param $hydrateRoute
561
     * @param $module
562
     * @return mixed
563
     */
564
    private function loadExternalModule(bool $hydrateRoute, $module)
565
    {
566
        $module = preg_replace('/(\\\|\/)/', DIRECTORY_SEPARATOR, $module);
567
        $externalModulePath = VENDOR_DIR . DIRECTORY_SEPARATOR . $module . DIRECTORY_SEPARATOR . 'src';
568
        if (file_exists($externalModulePath)) {
569
            $externalModule = $this->finder->directories()->in($externalModulePath)->depth(0);
570
            if (!empty($externalModule)) {
571
                foreach ($externalModule as $modulePath) {
572
                    $this->loadExternalAutoloader($hydrateRoute, $modulePath, $externalModulePath);
573
                }
574
            }
575
        }
576
        return $module;
577
    }
578
579
}
580