Passed
Push — main ( 8b73d6...c69a6f )
by Dimitri
03:18
created

FileLocator::schema()   C

Complexity

Conditions 13
Paths 25

Size

Total Lines 59
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 13
eloc 33
c 0
b 0
f 0
nc 25
nop 1
dl 0
loc 59
rs 6.6166

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * This file is part of Blitz PHP framework.
5
 *
6
 * (c) 2022 Dimitri Sitchet Tomkeu <[email protected]>
7
 *
8
 * For the full copyright and license information, please view
9
 * the LICENSE file that was distributed with this source code.
10
 */
11
12
namespace BlitzPHP\Loader;
13
14
use BlitzPHP\Container\Injector;
15
use BlitzPHP\Container\Services;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, BlitzPHP\Loader\Services. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
16
use BlitzPHP\Contracts\Database\ConnectionInterface;
17
use BlitzPHP\Exceptions\LoadException;
18
use BlitzPHP\Utilities\Helpers;
19
use BlitzPHP\Utilities\String\Text;
20
use Nette\Schema\Expect;
21
use Nette\Schema\Schema;
22
23
class FileLocator
24
{
25
    /**
26
     * Charge un fichier d'aide en mémoire.
27
     * Prend en charge les helpers d'espace de noms, à la fois dans et hors du répertoire 'helpers' d'un répertoire d'espace de noms.
28
     *
29
     * Chargera TOUS les helpers du nom correspondant, dans l'ordre suivant :
30
     *   1. app/Helpers
31
     *   2. {namespace}/Helpers
32
     *   3. system/Helpers
33
     *
34
     * @throws FileNotFoundException
35
     */
36
    public static function helper(array|string $filenames)
37
    {
38
        static $loaded = [];
39
40
        $loader = Services::locator();
41
42
        if (! is_array($filenames)) {
0 ignored issues
show
introduced by
The condition is_array($filenames) is always true.
Loading history...
43
            $filenames = [$filenames];
44
        }
45
46
        // Enregistrez une liste de tous les fichiers à inclure...
47
        $includes = [];
48
49
        foreach ($filenames as $filename) {
50
            // Stockez nos versions d'helpers système et d'application afin que nous puissions contrôler l'ordre de chargement.
51
            $systemHelper  = null;
52
            $appHelper     = null;
53
            $localIncludes = [];
54
55
            // Vérifiez si ce helper a déjà été chargé
56
            if (in_array($filename, $loaded, true)) {
57
                continue;
58
            }
59
60
            // Si le fichier est dans un espace de noms, nous allons simplement saisir ce fichier et ne pas en rechercher d'autres
61
            if (strpos($filename, '\\') !== false) {
62
                $path = $loader->locateFile($filename, 'Helpers');
63
64
                if (empty($path)) {
65
                    throw LoadException::helperNotFound($filename);
66
                }
67
68
                $includes[] = $path;
69
                $loaded[]   = $filename;
70
            } else {
71
                // Pas d'espaces de noms, donc recherchez dans tous les emplacements disponibles
72
                $paths = $loader->search('Helpers/' . $filename);
73
74
                foreach ($paths as $path) {
75
                    if (strpos($path, APP_PATH . 'Helpers' . DS) === 0) {
76
                        $appHelper = $path;
77
                    } elseif (strpos($path, SYST_PATH . 'Helpers' . DS) === 0) {
78
                        $systemHelper = $path;
79
                    } else {
80
                        $localIncludes[] = $path;
81
                        $loaded[]        = $filename;
82
                    }
83
                }
84
85
                // Les helpers au niveau de l'application doivent remplacer tous les autres
86
                if (! empty($appHelper)) {
87
                    $includes[] = $appHelper;
88
                    $loaded[]   = $filename;
89
                }
90
91
                // Tous les fichiers avec espace de noms sont ajoutés ensuite
92
                $includes = [...$includes, ...$localIncludes];
93
94
                // Et celui par défaut du système doit être ajouté en dernier.
95
                if (! empty($systemHelper)) {
96
                    $includes[] = $systemHelper;
97
                    $loaded[]   = $filename;
98
                }
99
            }
100
        }
101
102
        // Incluez maintenant tous les fichiers
103
        foreach ($includes as $path) {
104
            include_once $path;
105
        }
106
    }
107
108
	/**
109
     * Charge un fichier d'aide en mémoire.
110
     * Prend en charge les helpers d'espace de noms, à la fois dans et hors du répertoire 'helpers' d'un répertoire d'espace de noms.
111
     */
112
    public static function schema(string $name): Schema
113
    {
114
        static $loadedSchema = [];
115
116
        $loader = Services::locator();
117
118
		// Stockez nos versions de schame système et d'application afin que nous puissions contrôler l'ordre de chargement.
119
		$systemSchema  = null;
120
		$appSchema     = null;
121
		$vendorSchema  = null;
122
		
123
		// Le fichier de schema qui sera finalement utiliser
124
		$file = null;
125
		
126
		// Vérifiez si ce schama a déjà été chargé
127
		if (in_array($name, $loadedSchema, true)) {
128
            return $loadedSchema[$name];
129
		}
130
131
		// Si le fichier est dans un espace de noms, nous allons simplement saisir ce fichier et ne pas en rechercher d'autres
132
		if (strpos($name, '\\') !== false) {
133
			if (!empty($path = $loader->locateFile($name, 'schemas'))) {
134
				$file = $path;
135
			}
136
		} else {
137
			// Pas d'espaces de noms, donc recherchez dans tous les emplacements disponibles
138
			$paths = $loader->search('schemas/' . $name);
139
140
			foreach ($paths as $path) {
141
				if (strpos($path, CONFIG_PATH . 'schemas' . DS) === 0) {
142
					$appSchema = $path;
143
				} elseif (strpos($path, SYST_PATH . 'Constants' . DS . 'schemas' . DS) === 0) {
144
					$systemSchema = $path;
145
				} else {
146
					$vendorSchema = $path;
147
				}
148
			}
149
150
			// Les schema des vendor sont prioritaire, ensuite vienne ceux de l'application
151
			if (!empty($vendorSchema)) {
0 ignored issues
show
introduced by
The condition empty($vendorSchema) is always false.
Loading history...
152
				$file = $vendorSchema;
153
			} else if (!empty($appSchema)) {
154
				$file = $appSchema;
155
			} else if (!empty($systemSchema)) {
156
				$file = $systemSchema;
157
			}
158
        }
159
160
		if (!empty($file)) {
161
			$schema = require($file);
162
		} else {
163
			$schema = null;
164
		}
165
166
        if (empty($schema) || ! ($schema instanceof Schema)) {
167
            $schema = Expect::mixed();
168
        }
169
170
        return $loadedSchema[$name] = $schema;
171
    }
172
173
    /**
174
     * Cree et renvoie une librairie donnée
175
     *
176
     * @return mixed
177
     */
178
    public static function library(string $library)
179
    {
180
        $library = str_replace(DS, '/', $library);
181
        $library = explode('/', $library);
182
183
        $lib                          = ucfirst(end($library));
184
        $library[count($library) - 1] = $lib;
185
186
        $file  = Helpers::ensureExt(implode(DS, $library), 'php');
187
        $paths = [
188
            SYST_PATH . 'Libraries' . DS . $file,
189
190
            APP_PATH . 'Libraries' . DS . $file,
191
        ];
192
        $file_syst = $file_exist = false;
193
194
        if (file_exists($paths[0])) {
195
            $lib       = "BlitzPhp\\Libraries\\{$lib}";
196
            $file_syst = $file_exist = true;
197
        } elseif (file_exists($paths[1])) {
198
            require_once $paths[1];
199
            $file_exist = true;
200
        }
201
202
        if (true !== $file_exist) {
203
            throw LoadException::libraryNotFound($lib);
204
        }
205
206
        if (true !== $file_syst && ! class_exists($lib)) {
207
            throw LoadException::libraryDontExist($lib);
208
        }
209
210
        return Injector::make($lib);
211
    }
212
213
    /**
214
     * Cree et renvoi un model donné
215
     *
216
     * @template T of \BlitzPHP\Models\BaseModel
217
     *
218
     * @param class-string<T> $model
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<T> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<T>.
Loading history...
219
     *
220
     * @return T
221
     */
222
    public static function model(string $model, ?ConnectionInterface $connection = null)
223
    {
224
        if (! class_exists($model) && ! Text::endsWith($model, 'Model')) {
0 ignored issues
show
Bug introduced by
'Model' of type string is incompatible with the type iterable expected by parameter $needles of BlitzPHP\Utilities\String\Text::endsWith(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

224
        if (! class_exists($model) && ! Text::endsWith($model, /** @scrutinizer ignore-type */ 'Model')) {
Loading history...
225
            $model .= 'Model';
226
        }
227
228
        if (! class_exists($model)) {
229
            $model = str_replace(APP_NAMESPACE . '\\Models\\', '', $model);
230
            $model = APP_NAMESPACE . '\\Models\\' . $model;
231
        }
232
233
        if (! class_exists($model)) {
234
            throw LoadException::modelNotFound($model);
235
        }
236
237
        return Injector::make($model, ['db' => $connection]);
238
    }
239
240
    /**
241
     * Cree et renvoi un controleur donné
242
     *
243
     * @return \dFramework\core\controllers\BaseController
0 ignored issues
show
Bug introduced by
The type dFramework\core\controllers\BaseController was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
244
     */
245
    public static function controller(string $controller)
246
    {
247
        $controller = str_replace(DS, '/', $controller);
248
        $controller = explode('/', $controller);
249
250
        $con                                = ucfirst(end($controller));
251
        $con                                = (! preg_match('#Controller$#', $con)) ? $con . 'Controller' : $con;
252
        $controller[count($controller) - 1] = $con;
253
254
        foreach ($controller as $key => &$value) {
255
            if (preg_match('#^Controllers?$#i', $value)) {
256
                unset($value, $controller[$key]);
257
            }
258
        }
259
260
        $path = CONTROLLER_PATH . Helpers::ensureExt(implode(DS, $controller), 'php');
261
262
        if (! file_exists($path)) {
263
            throw LoadException::controllerNotFound(str_replace('Controller', '', $con), $path);
264
        }
265
266
        require_once $path;
267
268
        $class_namespaced = implode('\\', $controller);
269
270
        if (class_exists($class_namespaced, false)) {
271
            return Injector::make($class_namespaced);
272
        }
273
        if (! class_exists($con, false)) {
274
            throw LoadException::controllerDontExist(str_replace('Controller', '', $con), $path);
275
        }
276
277
        return Injector::make($con);
278
    }
279
280
    /**
281
     * Recupere le nom de base a partir du nom de la classe, namespacé ou non.
282
     */
283
    public static function getBasename(string $name): string
284
    {
285
        // Determine le basename
286
        if ($basename = strrchr($name, '\\')) {
287
            return substr($basename, 1);
288
        }
289
290
        return $name;
291
    }
292
293
    /**
294
     * Verifie si la classe satisfait l'option "preferApp"
295
     *
296
     * @param array  $options directives specifier pqr le composant
297
     * @param string $name    Nom de la classe, namespace optionel
298
     */
299
    protected static function verifyPreferApp(array $options, string $name): bool
300
    {
301
        // Tout element sans restriction passe
302
        if (! $options['preferApp']) {
303
            return true;
304
        }
305
306
        return strpos($name, APP_NAMESPACE) === 0;
307
    }
308
}
309