Passed
Push — master ( 21c73c...dfa0e8 )
by Fran
04:26
created

Router::debugLoad()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 6
nc 1
nop 0
dl 0
loc 7
ccs 7
cts 7
cp 1
crap 1
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace PSFS\base;
4
5
use PSFS\base\config\Config;
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\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
28
    use SingletonTrait;
29
30
    protected $routing;
31
    protected $slugs;
32
    private $domains;
33
    /**
34
     * @var Finder $finder
35
     */
36
    private $finder;
37
    /**
38
     * @var \PSFS\base\Cache $cache
39
     */
40
    private $cache;
41
    /**
42
     * @var bool headersSent
43
     */
44
    protected $headersSent = false;
45
    /**
46
     * @var int
47
     */
48
    protected $cacheType = Cache::JSON;
49
50
    /**
51
     * Constructor Router
52
     * @throws ConfigException
53
     */
54 6
    public function __construct()
55
    {
56 6
        $this->finder = new Finder();
57 6
        $this->cache = Cache::getInstance();
58 6
        $this->init();
59 6
    }
60
61
    /**
62
     * Inicializador Router
63
     * @throws ConfigException
64
     */
65 1
    public function init()
66
    {
67 1
        if(Cache::canUseMemcache()) {
68
            $this->cacheType = Cache::MEMCACHE;
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
        $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 130 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...
72 1
        if (empty($this->routing) || Config::getInstance()->getDebugMode()) {
73 1
            $this->debugLoad();
74
        }
75 1
    }
76
77
    /**
78
     * Load routes and domains and store them
79
     */
80 1
    private function debugLoad() {
81 1
        Logger::log('Begin routes load', LOG_DEBUG);
82 1
        $this->hydrateRouting();
83 1
        $this->simpatize();
84 1
        $this->checkExternalModules(false);
85 1
        Logger::log('End routes load', LOG_DEBUG);
86 1
    }
87
88
    /**
89
     * Método que deriva un error HTTP de página no encontrada
90
     *
91
     * @param \Exception $e
92
     *
93
     * @return string HTML
0 ignored issues
show
Documentation introduced by
Should the return type not be string|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
94
     */
95
    public function httpNotFound(\Exception $e = NULL)
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...
96
    {
97
        Logger::log('Throw not found exception');
98
        if (NULL === $e) {
99
            Logger::log('Not found page throwed without previous exception', LOG_WARNING);
100
            $e = new \Exception(_('Page not found'), 404);
101
        }
102
        $template = Template::getInstance()->setStatus($e->getCode());
103
        if (preg_match('/json/i', Request::getInstance()->getServer('CONTENT_TYPE'))) {
104
            return $template->output(json_encode(array(
105
                "success" => FALSE,
106
                "error" => $e->getMessage(),
107
            )), 'application/json');
108
        } else {
109
            return $template->render('error.html.twig', array(
110
                'exception' => $e,
111
                'trace' => $e->getTraceAsString(),
112
                'error_page' => TRUE,
113
            ));
114
        }
115
    }
116
117
    /**
118
     * Método que devuelve las rutas
119
     * @return string|null
120
     */
121
    public function getSlugs()
122
    {
123
        return $this->slugs;
124
    }
125
126
    /**
127
     * @return mixed
128
     */
129 1
    public function getRoutes() {
130 1
        return $this->routing;
131
    }
132
133
    /**
134
     * Method that extract all routes in the platform
135
     * @return array
136
     */
137
    public function getAllRoutes()
138
    {
139
        $routes = [];
140
        foreach ($this->getRoutes() as $path => $route) {
141
            if (array_key_exists('slug', $route)) {
142
                $routes[$route['slug']] = $path;
143
            }
144
        }
145
        return $routes;
146
    }
147
148
    /**
149
     * Método que calcula el objeto a enrutar
150
     *
151
     * @param string|null $route
152
     *
153
     * @throws \Exception
154
     * @return string HTML
0 ignored issues
show
Documentation introduced by
Should the return type not be string|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
155
     */
156
    public function execute($route)
157
    {
158
        Logger::log('Executing the request');
159
        try {
160
            //Check CORS for requests
161
            RequestHelper::checkCORS();
162
            // Checks restricted access
163
            SecurityHelper::checkRestrictedAccess($route);
164
            //Search action and execute
165
            $this->searchAction($route);
166
        } catch (AccessDeniedException $e) {
167
            Logger::log(_('Solicitamos credenciales de acceso a zona restringida'));
168
            return Admin::staticAdminLogon($route);
169
        } catch (RouterException $r) {
170
            Logger::log($r->getMessage(), LOG_WARNING);
171
        } catch (\Exception $e) {
172
            Logger::log($e->getMessage(), LOG_ERR);
173
            throw $e;
174
        }
175
176
        throw new RouterException(_("Página no encontrada"), 404);
177
    }
178
179
    /**
180
     * Método que busca el componente que ejecuta la ruta
181
     *
182
     * @param string $route
183
     *
184
     * @throws \PSFS\base\exception\RouterException
185
     */
186
    protected function searchAction($route)
187
    {
188
        Logger::log('Searching action to execute: ' . $route, LOG_INFO);
189
        //Revisamos si tenemos la ruta registrada
190
        $parts = parse_url($route);
191
        $path = (array_key_exists('path', $parts)) ? $parts['path'] : $route;
192
        $httpRequest = Request::getInstance()->getMethod();
193
        foreach ($this->routing as $pattern => $action) {
194
            list($httpMethod, $routePattern) = RouterHelper::extractHttpRoute($pattern);
195
            $matched = RouterHelper::matchRoutePattern($routePattern, $path);
196
            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...
197
                $get = RouterHelper::extractComponents($route, $routePattern);
198
                /** @var $class \PSFS\base\types\Controller */
199
                $class = RouterHelper::getClassToCall($action);
200
                try {
201
                    $this->executeCachedRoute($route, $action, $class, $get);
202
                } catch (\Exception $e) {
203
                    Logger::log($e->getMessage(), LOG_ERR);
204
                    throw new RouterException($e->getMessage(), 404, $e);
205
                }
206
            }
207
        }
208
        throw new RouterException(_("Ruta no encontrada"));
209
    }
210
211
    /**
212
     * Método que manda las cabeceras de autenticación
213
     * @return string HTML
0 ignored issues
show
Documentation introduced by
Should the return type not be string|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
214
     */
215
    protected function sentAuthHeader()
216
    {
217
        return AdminServices::getInstance()->setAdminHeaders();
218
    }
219
220
    /**
221
     * Method that check if the proyect has sub project to include
222
     * @param boolean $hydrateRoute
223
     */
224 1
    private function checkExternalModules($hydrateRoute = true)
225
    {
226 1
        $externalModules = Config::getParam('modules.extend');
227 1
        if (null !== $externalModules) {
228
            $externalModules = explode(',', $externalModules);
229
            foreach ($externalModules as &$module) {
230
                $module = preg_replace('/(\\\|\/)/', DIRECTORY_SEPARATOR, $module);
231
                $externalModulePath = VENDOR_DIR . DIRECTORY_SEPARATOR . $module . DIRECTORY_SEPARATOR . 'src';
232
                if (file_exists($externalModulePath)) {
233
                    $externalModule = $this->finder->directories()->in($externalModulePath)->depth(0);
234
                    if (!empty($externalModule)) {
235
                        foreach ($externalModule as $modulePath) {
236
                            $extModule = $modulePath->getBasename();
237
                            $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 152 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...
238
                            if (file_exists($moduleAutoloader)) {
239
                                @include $moduleAutoloader;
240
                                if ($hydrateRoute) {
241
                                    $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 162 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...
242
                                }
243
                            }
244
                        }
245
                    }
246
                }
247
            }
248
        }
249 1
    }
250
251
    /**
252
     * Method that gather all the routes in the project
253
     */
254 1
    private function generateRouting()
255
    {
256 1
        $base = SOURCE_DIR;
257 1
        $modulesPath = realpath(CORE_DIR);
258 1
        $this->routing = $this->inspectDir($base, "PSFS", array());
259 1
        if (file_exists($modulesPath)) {
260
            $modules = $this->finder->directories()->in($modulesPath)->depth(0);
261
            foreach ($modules as $modulePath) {
262
                $module = $modulePath->getBasename();
263
                $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...
264
            }
265
        }
266 1
        $this->checkExternalModules();
267 1
        $this->cache->storeData(CONFIG_DIR . DIRECTORY_SEPARATOR . "domains.json", $this->domains, Cache::JSON, TRUE);
268 1
    }
269
270
    /**
271
     * Método que regenera el fichero de rutas
272
     * @throws ConfigException
273
     */
274 1
    public function hydrateRouting()
275
    {
276 1
        $this->generateRouting();
277 1
        $home = Config::getInstance()->get('home_action');
278 1
        if (NULL !== $home || $home !== '') {
279 1
            $home_params = NULL;
280 1
            foreach ($this->routing as $pattern => $params) {
281 1
                list($method, $route) = RouterHelper::extractHttpRoute($pattern);
282 1
                if (preg_match("/" . preg_quote($route, "/") . "$/i", "/" . $home)) {
283 1
                    $home_params = $params;
284
                }
285
            }
286 1
            if (NULL !== $home_params) {
287
                $this->routing['/'] = $home_params;
288
            }
289
        }
290 1
    }
291
292
    /**
293
     * Método que inspecciona los directorios en busca de clases que registren rutas
294
     *
295
     * @param string $origen
296
     * @param string $namespace
297
     * @param array $routing
298
     *
299
     * @return array
300
     * @throws ConfigException
301
     */
302 1
    private function inspectDir($origen, $namespace = 'PSFS', $routing = [])
303
    {
304 1
        $files = $this->finder->files()->in($origen)->path('/(controller|api)/i')->depth(1)->name("*.php");
305 1
        foreach ($files as $file) {
306 1
            $filename = str_replace("/", '\\', str_replace($origen, '', $file->getPathname()));
307 1
            $routing = $this->addRouting($namespace . str_replace('.php', '', $filename), $routing, $namespace);
308
        }
309 1
        $this->finder = new Finder();
310
311 1
        return $routing;
312
    }
313
314
    /**
315
     * Checks that a namespace exists
316
     * @param string $namespace
317
     * @return bool
318
     */
319 1
    public static function exists($namespace)
320
    {
321 1
        return (class_exists($namespace) || interface_exists($namespace) || trait_exists($namespace));
322
    }
323
324
    /**
325
     * Método que añade nuevas rutas al array de referencia
326
     *
327
     * @param string $namespace
328
     * @param array $routing
329
     * @param string $module
330
     *
331
     * @return array
332
     * @throws ConfigException
333
     */
334 1
    private function addRouting($namespace, &$routing, $module = 'PSFS')
335
    {
336 1
        if (self::exists($namespace)) {
337 1
            $reflection = new \ReflectionClass($namespace);
338 1
            if (FALSE === $reflection->isAbstract() && FALSE === $reflection->isInterface()) {
339 1
                $this->extractDomain($reflection);
340 1
                $classComments = $reflection->getDocComment();
341 1
                preg_match('/@api\ (.*)\n/im', $classComments, $apiPath);
342 1
                $api = '';
343 1
                if (count($apiPath)) {
344
                    $api = array_key_exists(1, $apiPath) ? $apiPath[1] : $api;
345
                }
346 1
                foreach ($reflection->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) {
347 1
                    if (preg_match('/@route\ /i', $method->getDocComment())) {
348 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...
349
350 1
                        if (null !== $route && null !== $info) {
351 1
                            $info['class'] = $namespace;
352 1
                            $routing[$route] = $info;
353
                        }
354
                    }
355
                }
356
            }
357
        }
358
359 1
        return $routing;
360
    }
361
362
    /**
363
     * Método que extrae de la ReflectionClass los datos necesarios para componer los dominios en los templates
364
     *
365
     * @param \ReflectionClass $class
366
     *
367
     * @return Router
368
     * @throws ConfigException
369
     */
370 1
    protected function extractDomain(\ReflectionClass $class)
371
    {
372
        //Calculamos los dominios para las plantillas
373 1
        if ($class->hasConstant("DOMAIN") && !$class->isAbstract()) {
374 1
            if (!$this->domains) {
375 1
                $this->domains = [];
376
            }
377 1
            $domain = "@" . $class->getConstant("DOMAIN") . "/";
378 1
            if (!array_key_exists($domain, $this->domains)) {
379 1
                $this->domains[$domain] = RouterHelper::extractDomainInfo($class, $domain);
380
            }
381
        }
382
383 1
        return $this;
384
    }
385
386
    /**
387
     * Método que genera las urls amigables para usar dentro del framework
388
     * @return Router
389
     */
390 1
    public function simpatize()
391
    {
392 1
        $translationFileName = "translations" . DIRECTORY_SEPARATOR . "routes_translations.php";
393 1
        $absoluteTranslationFileName = CACHE_DIR . DIRECTORY_SEPARATOR . $translationFileName;
394 1
        $this->generateSlugs($absoluteTranslationFileName);
395 1
        GeneratorHelper::createDir(CONFIG_DIR);
396 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...
397
398 1
        return $this;
399
    }
400
401
    /**
402
     * Método que devuelve una ruta del framework
403
     *
404
     * @param string $slug
405
     * @param boolean $absolute
406
     * @param array $params
407
     *
408
     * @return string|null
409
     * @throws RouterException
410
     */
411 1
    public function getRoute($slug = '', $absolute = FALSE, $params = [])
412
    {
413 1
        if (strlen($slug) === 0) {
414
            return ($absolute) ? Request::getInstance()->getRootUrl() . '/' : '/';
415
        }
416 1
        if (!is_array($this->slugs) || !array_key_exists($slug, $this->slugs)) {
417
            throw new RouterException(_("No existe la ruta especificada"));
418
        }
419 1
        $url = ($absolute) ? Request::getInstance()->getRootUrl() . $this->slugs[$slug] : $this->slugs[$slug];
420 1
        if (!empty($params)) foreach ($params as $key => $value) {
421
            $url = str_replace("{" . $key . "}", $value, $url);
422 1
        } elseif (!empty($this->routing[$this->slugs[$slug]]["default"])) {
423 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...
424
        }
425
426 1
        return preg_replace('/(GET|POST|PUT|DELETE|ALL)\#\|\#/', '', $url);
427
    }
428
429
    /**
430
     * Método que devuelve las rutas de administración
431
     * @deprecated
432
     * @return array
433
     */
434
    public function getAdminRoutes()
435
    {
436
        return AdminHelper::getAdminRoutes($this->routing);
437
    }
438
439
    /**
440
     * Método que devuelve le controlador del admin
441
     * @deprecated
442
     * @return Admin
443
     */
444
    public function getAdmin()
445
    {
446
        return Admin::getInstance();
447
    }
448
449
    /**
450
     * Método que extrae los dominios
451
     * @return array
452
     */
453
    public function getDomains()
454
    {
455
        return $this->domains ?: [];
456
    }
457
458
    /**
459
     * Método que ejecuta una acción del framework y revisa si lo tenemos cacheado ya o no
460
     *
461
     * @param string $route
462
     * @param array|null $action
463
     * @param types\Controller $class
464
     * @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...
465
     */
466
    protected function executeCachedRoute($route, $action, $class, $params = NULL)
467
    {
468
        Logger::log('Executing route ' . $route, LOG_INFO);
469
        Security::getInstance()->setSessionKey("__CACHE__", $action);
470
        $cache = Cache::needCache();
471
        $execute = TRUE;
472
        if (FALSE !== $cache && Config::getInstance()->getDebugMode() === FALSE) {
473
            $cacheDataName = $this->cache->getRequestCacheHash();
474
            $tmpDir = substr($cacheDataName, 0, 2) . DIRECTORY_SEPARATOR . substr($cacheDataName, 2, 2) . DIRECTORY_SEPARATOR;
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 126 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...
475
            $cachedData = $this->cache->readFromCache("json" . DIRECTORY_SEPARATOR . $tmpDir . $cacheDataName,
476
                $cache, function () {
0 ignored issues
show
Bug introduced by
It seems like $cache defined by \PSFS\base\Cache::needCache() on line 470 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...
477
                });
478
            if (NULL !== $cachedData) {
479
                $headers = $this->cache->readFromCache("json" . DIRECTORY_SEPARATOR . $tmpDir . $cacheDataName . ".headers",
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 124 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...
480
                    $cache, function () {
0 ignored issues
show
Bug introduced by
It seems like $cache defined by \PSFS\base\Cache::needCache() on line 470 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...
481
                    }, Cache::JSON);
482
                Template::getInstance()->renderCache($cachedData, $headers);
483
                $execute = FALSE;
484
            }
485
        }
486
        if ($execute) {
487
            Logger::log(_('Start executing action'), LOG_DEBUG);
488
            if (false === call_user_func_array(array($class, $action['method']), $params)) {
489
                Logger::log(_('An error ocurred trying to execute the action'), LOG_ERR, [error_get_last()]);
490
            }
491
        }
492
    }
493
494
    /**
495
     * Parse slugs to create translations
496
     *
497
     * @param string $absoluteTranslationFileName
498
     */
499 1
    private function generateSlugs($absoluteTranslationFileName)
500
    {
501 1
        $translations = I18nHelper::generateTranslationsFile($absoluteTranslationFileName);
502 1
        foreach ($this->routing as $key => &$info) {
503 1
            $keyParts = $key;
504 1
            if (FALSE === strstr("#|#", $key)) {
505 1
                $keyParts = explode("#|#", $key);
506 1
                $keyParts = array_key_exists(1, $keyParts) ? $keyParts[1] : '';
507
            }
508 1
            $slug = RouterHelper::slugify($keyParts);
509 1
            if (NULL !== $slug && !array_key_exists($slug, $translations)) {
510 1
                $translations[$slug] = $key;
511 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...
512
            }
513 1
            $this->slugs[$slug] = $key;
514 1
            $info["slug"] = $slug;
515
        }
516 1
    }
517
518
}
519