Services::responsecache()   A
last analyzed

Complexity

Conditions 3
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 3
nc 2
nop 1
dl 0
loc 7
ccs 0
cts 2
cp 0
crap 12
rs 10
c 1
b 0
f 0
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\Container;
13
14
use BlitzPHP\Autoloader\Autoloader;
15
use BlitzPHP\Autoloader\Locator;
16
use BlitzPHP\Autoloader\LocatorCached;
17
use BlitzPHP\Cache\Cache;
18
use BlitzPHP\Cache\Handlers\FileVarExportHandler;
19
use BlitzPHP\Cache\ResponseCache;
20
use BlitzPHP\Config\Config;
21
use BlitzPHP\Contracts\Autoloader\LocatorInterface;
22
use BlitzPHP\Contracts\Cache\CacheInterface;
23
use BlitzPHP\Contracts\Container\ContainerInterface;
24
use BlitzPHP\Contracts\Database\ConnectionResolverInterface;
25
use BlitzPHP\Contracts\Event\EventManagerInterface;
26
use BlitzPHP\Contracts\Mail\MailerInterface;
27
use BlitzPHP\Contracts\Router\RouteCollectionInterface;
28
use BlitzPHP\Contracts\Router\RouterInterface;
29
use BlitzPHP\Contracts\Security\EncrypterInterface;
30
use BlitzPHP\Contracts\Security\HasherInterface;
31
use BlitzPHP\Contracts\Session\CookieManagerInterface;
32
use BlitzPHP\Contracts\Session\SessionInterface;
33
use BlitzPHP\Debug\Logger;
34
use BlitzPHP\Debug\Timer;
35
use BlitzPHP\Debug\Toolbar;
36
use BlitzPHP\Event\EventManager;
37
use BlitzPHP\Filesystem\Filesystem;
38
use BlitzPHP\Filesystem\FilesystemManager;
39
use BlitzPHP\Http\Negotiator;
40
use BlitzPHP\Http\Redirection;
41
use BlitzPHP\Http\Request;
42
use BlitzPHP\Http\Response;
43
use BlitzPHP\Http\ResponseEmitter;
44
use BlitzPHP\Http\ServerRequest;
45
use BlitzPHP\Http\ServerRequestFactory;
46
use BlitzPHP\Http\Uri;
47
use BlitzPHP\Http\UrlGenerator;
48
use BlitzPHP\Mail\Mail;
49
use BlitzPHP\Router\RouteCollection;
50
use BlitzPHP\Router\Router;
51
use BlitzPHP\Security\Encryption\Encryption;
52
use BlitzPHP\Security\Hashing\Hasher;
53
use BlitzPHP\Session\Cookie\Cookie;
54
use BlitzPHP\Session\Cookie\CookieManager;
55
use BlitzPHP\Session\Handlers\Database as DatabaseSessionHandler;
56
use BlitzPHP\Session\Handlers\Database\MySQL as MySQLSessionHandler;
57
use BlitzPHP\Session\Handlers\Database\Postgre as PostgreSessionHandler;
58
use BlitzPHP\Session\Store;
59
use BlitzPHP\Translator\Translate;
60
use BlitzPHP\Utilities\Helpers;
61
use BlitzPHP\Utilities\String\Text;
62
use BlitzPHP\View\Components\ComponentLoader;
63
use BlitzPHP\View\View;
64
use Psr\Http\Message\UriInterface;
65
use Psr\Log\LoggerInterface;
66
use stdClass;
67
68
/**
69
 * Service
70
 *
71
 * Les services sont simplement d'autres classes/bibliothèques que le système utilise
72
 * pour faire son travail. Ceci est utilisé par BlitzPHP pour permettre au coeur du
73
 * framework à échanger facilement sans affecter l'utilisation à l'intérieur
74
 * le reste de votre application.
75
 *
76
 * Ceci est utilisé à la place d'un conteneur d'injection de dépendance principalement
77
 * en raison de sa simplicité, qui permet un meilleur entretien à long terme
78
 * des applications construites sur BlitzPHP. Un effet secondaire bonus
79
 * est que les IDE sont capables de déterminer quelle classe vous appelez
80
 * alors qu'avec les conteneurs DI, il n'y a généralement aucun moyen pour eux de le faire.
81
 */
82
class Services
83
{
84
    /**
85
     * Cache des instances des services demander comme instance "partagee".
86
     * La cle est le FQCN du service.
87
     */
88
    protected static array $instances = [];
89
90
    /**
91
     * Objets simulés à tester qui sont renvoyés s'ils existent.
92
     */
93
    protected static array $mocks = [];
94
95
    /**
96
     * Cache d'autres classe de que nous avons trouver via la methode cacheService.
97
     */
98
    protected static array $services = [];
99
100
    /**
101
     * Avons-nous déjà découvert d'autres Services ?
102
     */
103
    protected static bool $discovered = false;
104
105
    /**
106
     * Un cache des noms de classes de services trouvés.
107
     *
108
     * @var list<string>
0 ignored issues
show
Bug introduced by
The type BlitzPHP\Container\list 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...
109
     */
110
    private static array $serviceNames = [];
111
112
    /**
113
     * La classe Autoloader permet de charger les fichiers simplement.
114
     */
115
    public static function autoloader(bool $shared = true): Autoloader
116
    {
117
        if (true === $shared && isset(static::$instances[Autoloader::class])) {
118 68
            return static::$instances[Autoloader::class];
119
        }
120
121 2
        $config  = static::config()->get('autoload');
122 2
        $helpers = array_merge(['url'], ($config['helpers'] ?? []));
123
124 2
        return static::$instances[Autoloader::class] = new Autoloader(/** @scrutinizer ignore-type */ $config, $helpers);
125
    }
126
127
    /**
128
     * La classe de cache fournit un moyen simple de stocker et de récupérer
129
     * données complexes pour plus tard
130
     *
131
     * @return Cache
132
     */
133
    public static function cache(?array $config = null, bool $shared = true): CacheInterface
134
    {
135
        if ($config === null || $config === []) {
136 4
            $config = static::config()->get('cache');
137
        }
138
139
        if (true === $shared && isset(static::$instances[Cache::class])) {
140 4
            $instance = static::$instances[Cache::class];
141
            if (empty(func_get_args()[0])) {
142 4
                return $instance;
143
            }
144
145 2
            return $instance->setConfig($config);
146
        }
147
148 2
        return static::$instances[Cache::class] = new Cache($config);
149
    }
150
151
    /**
152
     * Les composants sont destinées à vous permettre d'insérer du HTML dans la vue
153
     * qui a été généré par n'importe quel appel dans le système.
154
     */
155
    public static function componentLoader(bool $shared = true): ComponentLoader
156
    {
157
        if (true === $shared && isset(static::$instances[ComponentLoader::class])) {
158
            return static::$instances[ComponentLoader::class];
159
        }
160
161
        return static::$instances[ComponentLoader::class] = new ComponentLoader(static::cache());
162
    }
163
164
    /**
165
     * La clase Config offre une api fluide por gerer les configurations de l'application
166
     */
167
    public static function config(bool $shared = true): Config
168
    {
169
        if (true === $shared && isset(static::$instances[Config::class])) {
170 210
            return static::$instances[Config::class];
171
        }
172
173
        return static::$instances[Config::class] = new Config();
174
    }
175
176
    /**
177
     * Conteneur d'injection de dependances
178
     *
179
     * @return Container
180
     */
181
    public static function container(bool $shared = true): ContainerInterface
182
    {
183
        if (true === $shared && isset(static::$instances[Container::class])) {
184 81
            return static::$instances[Container::class];
185
        }
186
187
        return static::$instances[Container::class] = new Container();
188
    }
189
190
    /**
191
     * Gestionnaire de cookies
192
     *
193
     * @return CookieManager
194
     */
195
    public static function cookie(bool $shared = true): CookieManagerInterface
196
    {
197
        if (true === $shared && isset(static::$instances[CookieManager::class])) {
198 2
            return static::$instances[CookieManager::class];
199
        }
200
201 2
        $config = (object) static::config()->get('cookie');
202
203
        return static::$instances[CookieManager::class] = (new CookieManager())->setDefaultPathAndDomain(
204
            $config->path ?: '/',
205
            $config->domain ?: '',
206
            $config->secure ?: false,
207
            $config->httponly ?: true,
208
            $config->samesite ?: 'Lax'
209 2
        );
210
    }
211
212
    /**
213
     * Émetteur de réponse au client
214
     */
215
    public static function emitter(bool $shared = true): ResponseEmitter
216
    {
217
        if (true === $shared && isset(static::$instances[ResponseEmitter::class])) {
218 2
            return static::$instances[ResponseEmitter::class];
219
        }
220
221 2
        return static::$instances[ResponseEmitter::class] = new ResponseEmitter();
222
    }
223
224
    /**
225
     * La classe Encryption fournit un cryptage bidirectionnel.
226
     *
227
     * @return Encryption
228
     */
229
    public static function encrypter(?array $config = null, bool $shared = false): EncrypterInterface
230
    {
231
        if (true === $shared && isset(static::$instances[Encryption::class])) {
232 2
            return static::$instances[Encryption::class];
233
        }
234
235 4
        $config ??= config('encryption');
236 4
        $config     = (object) $config;
237 4
        $encryption = new Encryption($config);
238 4
        $encryption->initialize($config);
239
240 4
        return static::$instances[Encryption::class] = $encryption;
241
    }
242
243
    /**
244
     * Gestionnaire d'evenement
245
     *
246
     * @return EventManager
247
     */
248
    public static function event(bool $shared = true): EventManagerInterface
249
    {
250
        if (true === $shared && isset(static::$instances[EventManager::class])) {
251 3
            return static::$instances[EventManager::class];
252
        }
253
254
        return static::$instances[EventManager::class] = new EventManager();
255
    }
256
257
    /**
258
     * System de gestion de fichier
259
     */
260
    public static function fs(bool $shared = true): Filesystem
261
    {
262
        if (true === $shared && isset(static::$instances[Filesystem::class])) {
263 24
            return static::$instances[Filesystem::class];
264
        }
265
266 2
        return static::$instances[Filesystem::class] = new Filesystem();
267
    }
268
269
    /**
270
     * La classe Encryption fournit un cryptage bidirectionnel.
271
     *
272
     * @return Hasher
273
     */
274
    public static function hashing(?array $config = null, bool $shared = true): HasherInterface
275
    {
276
        if (true === $shared && isset(static::$instances[Hasher::class])) {
277 4
            return static::$instances[Hasher::class];
278
        }
279
280 2
        $config ??= config('hashing');
281 2
        $config = (object) $config;
282 2
        $hasher = new Hasher($config);
283 2
        $hasher->initialize($config);
284
285 2
        return static::$instances[Hasher::class] = $hasher;
286
    }
287
288
    /**
289
     * Responsable du chargement des traductions des chaînes de langue.
290
     *
291
     * @deprecated 0.9 use translators instead
292
     */
293
    public static function language(?string $locale = null, bool $shared = true): Translate
294
    {
295
        return static::translator($locale, $shared);
296
    }
297
298
    /**
299
     * Le file locator fournit des methodes utilitaire pour chercher les fichiers non-classes dans les dossiers de namespace.
300
     * C'est une excelente methode pour charger les 'vues', 'helpers', et 'libraries'.
301
     */
302
    public static function locator(bool $shared = true): LocatorInterface
303
    {
304
        if ($shared) {
305
            if (! isset(static::$instances[Locator::class])) {
306 131
                $locator = new Locator(static::autoloader());
307
                if (true === config('optimize.locator_cache_enabled', false)) {
0 ignored issues
show
introduced by
The condition true === config('optimiz..._cache_enabled', false) is always false.
Loading history...
308
                    static::$instances[Locator::class] = new LocatorCached($locator, new FileVarExportHandler(FRAMEWORK_STORAGE_PATH . 'cache'));
309
                } else {
310
                    static::$instances[Locator::class] = $locator;
311
                }
312
            }
313
314 131
            return static::$instances[Locator::class];
315
        }
316
317
        return static::$instances[Locator::class] = new Locator(static::autoloader());
318
    }
319
320
    /**
321
     * La classe Logger est une classe Logging compatible PSR-3 qui prend en charge
322
     * plusieurs gestionnaires qui traitent la journalisation réelle.
323
     *
324
     * @return Logger
325
     */
326
    public static function logger(bool $shared = true): LoggerInterface
327
    {
328
        if ($shared && isset(static::$instances[Logger::class])) {
329 43
            return static::$instances[Logger::class];
330
        }
331
332
        return static::$instances[Logger::class] = new Logger();
333
    }
334
335
    /**
336
     * La classe de mail vous permet d'envoyer par courrier électronique via mail, sendmail, SMTP.
337
     *
338
     * @return Mail
339
     */
340
    public static function mail(?array $config = null, bool $shared = true): MailerInterface
341
    {
342
        if ($config === null || $config === []) {
343
            $config = static::config()->get('mail');
344
        }
345
346
        if (true === $shared && isset(static::$instances[Mail::class])) {
347
            /** @var Mail $instance */
348
            $instance = static::$instances[Mail::class];
349
            if (empty(func_get_args()[0])) {
350
                return $instance;
351
            }
352
353
            return $instance->merge($config);
354
        }
355
356
        return static::$instances[Mail::class] = new Mail($config);
357
    }
358
359
    /**
360
     * La classe Input générale modélise une requête HTTP.
361
     */
362
    public static function negotiator(?ServerRequest $request = null, bool $shared = true): Negotiator
363
    {
364
        if ($request === null) {
365
            $request = static::request(true);
366
        }
367
368
        if (true === $shared && isset(static::$instances[Negotiator::class])) {
369
            $instance = static::$instances[Negotiator::class];
370
            if (empty(func_get_args()[0])) {
371
                return $instance;
372
            }
373
374
            return $instance->setRequest($request);
375
        }
376
377
        return static::$instances[Negotiator::class] = new Negotiator($request);
378
    }
379
380
    /**
381
     * La classe des redirections HTTP
382
     */
383
    public static function redirection(bool $shared = true): Redirection
384
    {
385
        if (true === $shared && isset(static::$instances[Redirection::class])) {
386
            return static::$instances[Redirection::class];
387
        }
388
389
        return static::$instances[Redirection::class] = new Redirection(static::factory(UrlGenerator::class));
390
    }
391
392
    /**
393
     * La classe Resquest modélise une reqûete HTTP.
394
     */
395
    public static function request(bool $shared = true): Request
396
    {
397
        if (true === $shared && isset(static::$instances[Request::class])) {
398 45
            return static::$instances[Request::class];
399
        }
400
401 2
        return static::$instances[Request::class] = ServerRequestFactory::fromGlobals();
402
    }
403
404
    /**
405
     * La classe Response modélise une réponse HTTP.
406
     */
407
    public static function response(bool $shared = true): Response
408
    {
409
        if (true === $shared && isset(static::$instances[Response::class])) {
410 6
            return static::$instances[Response::class];
411
        }
412
413 1
        return static::$instances[Response::class] = new Response();
414
    }
415
416
    /**
417
     * CacheResponse
418
     */
419
    public static function responsecache(bool $shared = true): ResponseCache
420
    {
421
        if (true === $shared && isset(static::$instances[ResponseCache::class])) {
422
            return static::$instances[ResponseCache::class];
423
        }
424
425
        return static::$instances[ResponseCache::class] = new ResponseCache(static::cache(), /** @scrutinizer ignore-type */ static::config()->get('cache.cache_query_string'));
426
    }
427
428
    /**
429
     * Le service Routes est une classe qui permet de construire facilement une collection de routes.
430
     *
431
     * @return RouteCollection
432
     */
433
    public static function routes(bool $shared = true): RouteCollectionInterface
434
    {
435
        if (true === $shared && isset(static::$instances[RouteCollection::class])) {
436 4
            return static::$instances[RouteCollection::class];
437
        }
438
439 10
        return static::$instances[RouteCollection::class] = new RouteCollection(static::locator(), (object) static::config()->get('routing'));
440
    }
441
442
    /**
443
     * La classe Router utilise le tableau de routes d'une RouteCollection et détermine
444
     * le contrôleur et la méthode corrects à exécuter.
445
     *
446
     * @return Router
447
     */
448
    public static function router(?RouteCollection $routes = null, ?ServerRequest $request = null, bool $shared = true): RouterInterface
449
    {
450
        if (true === $shared && isset(static::$instances[Router::class])) {
451 12
            return static::$instances[Router::class];
452
        }
453
454
        if ($routes === null) {
455 12
            $routes = static::routes(true);
456
        }
457
        if ($request === null) {
458 2
            $request = static::request(true);
459
        }
460
461 12
        return static::$instances[Router::class] = new Router($routes, $request);
462
    }
463
464
    /**
465
     * Retourne le gestionnaire de session.
466
     *
467
     * @return Store
468
     */
469
    public static function session(bool $shared = true): SessionInterface
470
    {
471
        if (true === $shared && isset(static::$instances[Store::class])) {
472 12
            return static::$instances[Store::class];
473
        }
474
475 21
        $config = static::config()->get('session');
476 21
        $db     = null;
477
478
        if (Text::contains($config['handler'], [DatabaseSessionHandler::class, 'database'])) {
479 21
            $group = $config['group'] ?? static::config()->get('database.connection');
480
            $db    = static::singleton(ConnectionResolverInterface::class)->connection($group);
481
482
            $driver = $db->getPlatform();
483
484
            if (Text::contains($driver, ['mysql', MySQLSessionHandler::class])) {
485
                $config['handler'] = MySQLSessionHandler::class;
486
            } elseif (Text::contains($driver, ['postgre', PostgreSessionHandler::class])) {
487
                $config['handler'] = PostgreSessionHandler::class;
488
            }
489
        }
490
491 21
        Cookie::setDefaults($cookies = /** @scrutinizer ignore-type */ static::config()->get('cookie'));
0 ignored issues
show
Bug introduced by
It seems like $cookies = static::config()->get('cookie') can also be of type null; however, parameter $options of BlitzPHP\Session\Cookie\Cookie::setDefaults() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

491
        Cookie::setDefaults(/** @scrutinizer ignore-type */ $cookies = /** @scrutinizer ignore-type */ static::config()->get('cookie'));
Loading history...
492 21
        $session = new Store((array) $config, (array) $cookies, Helpers::ipAddress());
493 21
        $session->setLogger(static::logger());
494 21
        $session->setDatabase($db);
495
496
        if (session_status() === PHP_SESSION_NONE) {
497 21
            $session->start();
498
        }
499
500 21
        return static::$instances[Store::class] = $session;
501
    }
502
503
    /**
504
     * System de gestion de fichier par disque
505
     */
506
    public static function storage(bool $shared = true): FilesystemManager
507
    {
508
        if ($shared && isset(static::$instances[FilesystemManager::class])) {
509 2
            return static::$instances[FilesystemManager::class];
510
        }
511
512 2
        return static::$instances[FilesystemManager::class] = new FilesystemManager(/** @scrutinizer ignore-type */ static::config()->get('filesystems'));
513
    }
514
515
    /**
516
     * La classe Timer fournit un moyen simple d'évaluer des parties de votre application.
517
     */
518
    public static function timer(bool $shared = true): Timer
519
    {
520
        if (true === $shared && isset(static::$instances[Timer::class])) {
521
            return static::$instances[Timer::class];
522
        }
523
524
        return static::$instances[Timer::class] = new Timer();
525
    }
526
527
    /**
528
     * Renvoie la barre d'outils de débogage.
529
     */
530
    public static function toolbar(?stdClass $config = null, bool $shared = true): Toolbar
531
    {
532
        if ($shared && isset(static::$instances[Toolbar::class])) {
533
            return static::$instances[Toolbar::class];
534
        }
535
536
        $config ??= (object) static::config()->get('toolbar');
537
538
        return static::$instances[Toolbar::class] = new Toolbar($config);
539
    }
540
541
    /**
542
     * Responsable du chargement des traductions des chaînes de langue.
543
     */
544
    public static function translator(?string $locale = null, bool $shared = true): Translate
545
    {
546
        if (null === $locale || $locale === '' || $locale === '0') {
547 64
            $locale = is_cli() ? static::config()->get('app.language') : static::request()->getLocale();
548
        }
549
550
        if (true === $shared && isset(static::$instances[Translate::class])) {
551 64
            return static::$instances[Translate::class]->setLocale($locale);
552
        }
553
554 2
        return static::$instances[Translate::class] = new Translate($locale, static::locator());
555
    }
556
557
    /**
558
     * La classe URI fournit un moyen de modéliser et de manipuler les URI.
559
     *
560
     * @return Uri
561
     */
562
    public static function uri(?string $uri = null, bool $shared = true): UriInterface
563
    {
564
        if (true === $shared && isset(static::$instances[Uri::class])) {
565
            return static::$instances[Uri::class]->setURI($uri);
566
        }
567
568
        return static::$instances[Uri::class] = new Uri($uri);
569
    }
570
571
    /**
572
     * La classe Renderer est la classe qui affiche réellement un fichier à l'utilisateur.
573
     * La classe View par défaut dans BlitzPHP est intentionnellement simple, mais
574
     * le service peut facilement être remplacé par un moteur de modèle si l'utilisateur en a besoin.
575
     */
576
    public static function viewer(bool $shared = true): View
577
    {
578
        if (true === $shared && isset(static::$instances[View::class])) {
579 2
            return static::$instances[View::class];
580
        }
581
582 2
        return static::$instances[View::class] = new View();
583
    }
584
585
    /**
586
     * Offre la possibilité d'effectuer des appels insensibles à la casse des noms de service.
587
     *
588
     * @return mixed
589
     */
590
    public static function __callStatic(string $name, array $arguments)
591
    {
592
        if (null === $service = static::serviceExists($name)) {
593 24
            return static::discoverServices($name, $arguments);
594
        }
595
596 2
        return $service::$name(...$arguments);
597
    }
598
599
    /**
600
     * Vérifiez si le service demandé est défini et renvoyez la classe déclarante.
601
     * Renvoie null s'il n'est pas trouvé.
602
     */
603
    public static function serviceExists(string $name): ?string
604
    {
605 26
        static::cacheServices();
606 26
        $services = array_merge(self::$serviceNames, [self::class]);
607 26
        $name     = strtolower($name);
608
609
        foreach ($services as $service) {
610
            if (method_exists($service, $name)) {
611 2
                return $service;
612
            }
613
        }
614
615 24
        return null;
616
    }
617
618
    /**
619
     * Essaie d'obtenir un service à partir du conteneur
620
     *
621
     * @return mixed
622
     */
623
    protected static function discoverServices(string $name, array $arguments)
624
    {
625
        if (true !== array_pop($arguments)) {
626 24
            return static::factory($name, $arguments);
627
        }
628
629
        return static::singleton($name, ...$arguments);
630
    }
631
632
    protected static function cacheServices(): void
633
    {
634
        if (! static::$discovered) {
635 26
            $locator = static::locator();
636
            $files   = $locator->search('Config/Services');
637
638
            // Obtenez des instances de toutes les classes de service et mettez-les en cache localement.
639
            foreach ($files as $file) {
640
                if (false === $classname = $locator->findQualifiedNameFromPath($file)) {
641
                    continue;
642
                }
643
                if (self::class !== $classname) {
644
                    self::$serviceNames[] = $classname;
645
                    static::$services[]   = new $classname();
646
                }
647
            }
648
649
            static::$discovered = true;
650
        }
651
    }
652
653
    /**
654
     * Injecter une seule instance de la classe donnée
655
     *
656
     * @return mixed
657
     */
658
    public static function singleton(string $name)
659
    {
660
        $arguments = func_get_args();
661
        $name      = array_shift($arguments);
662
663
        if (empty(static::$instances[$name])) {
664
            static::$instances[$name] = $arguments !== [] ? static::factory($name, $arguments) : static::container()->get($name);
665
        }
666
667
        return static::$instances[$name];
668
    }
669
670
    /**
671
     * Injecter une nouvelle instance de la classe donnée
672
     *
673
     * @return mixed
674
     */
675
    public static function factory(string $name, array $arguments = [])
676
    {
677 28
        return static::container()->make($name, $arguments);
678
    }
679
680
    /**
681
     * Définissez un objet ou une valeur dans le conteneur.
682
     *
683
     * @param string $name  Nom de l'entrée
684
     * @param mixed  $value utilisez les aides à la définition pour définir les objets
685
     */
686
    public static function set(string $name, $value)
687
    {
688 48
        static::$instances[$name] = $value;
689 48
        static::container()->set($name, $value);
690
    }
691
692
    /**
693
     * Injectez un objet fictif pour les tests.
694
     *
695
     * @testTag disponible uniquement pour le code de test
696
     */
697
    public static function injectMock(string $name, object $mock): void
698
    {
699 3
        static::$mocks[strtolower($name)] = $mock;
700
    }
701
702
    /**
703
     * Réinitialisez les instances partagées et les simulations pour les tests.
704
     *
705
     * @testTag disponible uniquement pour le code de test
706
     */
707
    public static function reset(bool $initAutoloader = true): void
708
    {
709
        static::$mocks     = [];
710
        static::$instances = [];
711
712
        if ($initAutoloader) {
713
            static::autoloader()->initialize();
714
        }
715
    }
716
717
    /**
718
     * Réinitialise toutes les instances fictives et partagées pour un seul service.
719
     *
720
     * @testTag disponible uniquement pour le code de test
721
     */
722
    public static function resetSingle(string ...$name)
723
    {
724
        foreach ($name as $n) {
725
            unset(static::$mocks[$n], static::$instances[$n]);
726
            $n = strtolower($n);
727
            unset(static::$mocks[$n], static::$instances[$n]);
728
        }
729
    }
730
}
731