• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

codeigniter4 / CodeIgniter4 / 15248472192

26 May 2025 07:11AM UTC coverage: 84.182% (+0.02%) from 84.163%
15248472192

push

github

web-flow
refactor: fix `notIdentical.alwaysTrue` error (#9579)

* refactor: fix `notIdentical.alwaysTrue` error

* Fix psalm

1 of 1 new or added line in 1 file covered. (100.0%)

4 existing lines in 1 file now uncovered.

20776 of 24680 relevant lines covered (84.18%)

191.57 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.12
/system/Config/Services.php
1
<?php
2

3
declare(strict_types=1);
4

5
/**
6
 * This file is part of CodeIgniter 4 framework.
7
 *
8
 * (c) CodeIgniter Foundation <admin@codeigniter.com>
9
 *
10
 * For the full copyright and license information, please view
11
 * the LICENSE file that was distributed with this source code.
12
 */
13

14
namespace CodeIgniter\Config;
15

16
use CodeIgniter\Cache\CacheFactory;
17
use CodeIgniter\Cache\CacheInterface;
18
use CodeIgniter\Cache\ResponseCache;
19
use CodeIgniter\CLI\Commands;
20
use CodeIgniter\CodeIgniter;
21
use CodeIgniter\Database\ConnectionInterface;
22
use CodeIgniter\Database\MigrationRunner;
23
use CodeIgniter\Debug\Exceptions;
24
use CodeIgniter\Debug\Iterator;
25
use CodeIgniter\Debug\Timer;
26
use CodeIgniter\Debug\Toolbar;
27
use CodeIgniter\Email\Email;
28
use CodeIgniter\Encryption\EncrypterInterface;
29
use CodeIgniter\Encryption\Encryption;
30
use CodeIgniter\Filters\Filters;
31
use CodeIgniter\Format\Format;
32
use CodeIgniter\Honeypot\Honeypot;
33
use CodeIgniter\HTTP\CLIRequest;
34
use CodeIgniter\HTTP\ContentSecurityPolicy;
35
use CodeIgniter\HTTP\CURLRequest;
36
use CodeIgniter\HTTP\IncomingRequest;
37
use CodeIgniter\HTTP\Negotiate;
38
use CodeIgniter\HTTP\RedirectResponse;
39
use CodeIgniter\HTTP\Request;
40
use CodeIgniter\HTTP\RequestInterface;
41
use CodeIgniter\HTTP\Response;
42
use CodeIgniter\HTTP\ResponseInterface;
43
use CodeIgniter\HTTP\SiteURIFactory;
44
use CodeIgniter\HTTP\URI;
45
use CodeIgniter\HTTP\UserAgent;
46
use CodeIgniter\Images\Handlers\BaseHandler;
47
use CodeIgniter\Language\Language;
48
use CodeIgniter\Log\Logger;
49
use CodeIgniter\Pager\Pager;
50
use CodeIgniter\Router\RouteCollection;
51
use CodeIgniter\Router\RouteCollectionInterface;
52
use CodeIgniter\Router\Router;
53
use CodeIgniter\Security\Security;
54
use CodeIgniter\Session\Handlers\BaseHandler as SessionBaseHandler;
55
use CodeIgniter\Session\Handlers\Database\MySQLiHandler;
56
use CodeIgniter\Session\Handlers\Database\PostgreHandler;
57
use CodeIgniter\Session\Handlers\DatabaseHandler;
58
use CodeIgniter\Session\Session;
59
use CodeIgniter\Superglobals;
60
use CodeIgniter\Throttle\Throttler;
61
use CodeIgniter\Typography\Typography;
62
use CodeIgniter\Validation\Validation;
63
use CodeIgniter\Validation\ValidationInterface;
64
use CodeIgniter\View\Cell;
65
use CodeIgniter\View\Parser;
66
use CodeIgniter\View\RendererInterface;
67
use CodeIgniter\View\View;
68
use Config\App;
69
use Config\Cache;
70
use Config\ContentSecurityPolicy as ContentSecurityPolicyConfig;
71
use Config\ContentSecurityPolicy as CSPConfig;
72
use Config\Database;
73
use Config\Email as EmailConfig;
74
use Config\Encryption as EncryptionConfig;
75
use Config\Exceptions as ExceptionsConfig;
76
use Config\Filters as FiltersConfig;
77
use Config\Format as FormatConfig;
78
use Config\Honeypot as HoneypotConfig;
79
use Config\Images;
80
use Config\Logger as LoggerConfig;
81
use Config\Migrations;
82
use Config\Modules;
83
use Config\Pager as PagerConfig;
84
use Config\Paths;
85
use Config\Routing;
86
use Config\Security as SecurityConfig;
87
use Config\Services as AppServices;
88
use Config\Session as SessionConfig;
89
use Config\Toolbar as ToolbarConfig;
90
use Config\Validation as ValidationConfig;
91
use Config\View as ViewConfig;
92
use InvalidArgumentException;
93
use Locale;
94

95
/**
96
 * Services Configuration file.
97
 *
98
 * Services are simply other classes/libraries that the system uses
99
 * to do its job. This is used by CodeIgniter to allow the core of the
100
 * framework to be swapped out easily without affecting the usage within
101
 * the rest of your application.
102
 *
103
 * This is used in place of a Dependency Injection container primarily
104
 * due to its simplicity, which allows a better long-term maintenance
105
 * of the applications built on top of CodeIgniter. A bonus side-effect
106
 * is that IDEs are able to determine what class you are calling
107
 * whereas with DI Containers there usually isn't a way for them to do this.
108
 *
109
 * @see http://blog.ircmaxell.com/2015/11/simple-easy-risk-and-change.html
110
 * @see http://www.infoq.com/presentations/Simple-Made-Easy
111
 * @see \CodeIgniter\Config\ServicesTest
112
 */
113
class Services extends BaseService
114
{
115
    /**
116
     * The cache class provides a simple way to store and retrieve
117
     * complex data for later.
118
     *
119
     * @return CacheInterface
120
     */
121
    public static function cache(?Cache $config = null, bool $getShared = true)
122
    {
123
        if ($getShared) {
1,823✔
124
            return static::getSharedInstance('cache', $config);
1,820✔
125
        }
126

127
        $config ??= config(Cache::class);
1,823✔
128

129
        return CacheFactory::getHandler($config);
1,823✔
130
    }
131

132
    /**
133
     * The CLI Request class provides for ways to interact with
134
     * a command line request.
135
     *
136
     * @return CLIRequest
137
     *
138
     * @internal
139
     */
140
    public static function clirequest(?App $config = null, bool $getShared = true)
141
    {
142
        if ($getShared) {
18✔
143
            return static::getSharedInstance('clirequest', $config);
13✔
144
        }
145

146
        $config ??= config(App::class);
11✔
147

148
        return new CLIRequest($config);
11✔
149
    }
150

151
    /**
152
     * CodeIgniter, the core of the framework.
153
     *
154
     * @return CodeIgniter
155
     */
156
    public static function codeigniter(?App $config = null, bool $getShared = true)
157
    {
158
        if ($getShared) {
2✔
159
            return static::getSharedInstance('codeigniter', $config);
×
160
        }
161

162
        $config ??= config(App::class);
2✔
163

164
        return new CodeIgniter($config);
2✔
165
    }
166

167
    /**
168
     * The commands utility for running and working with CLI commands.
169
     *
170
     * @return Commands
171
     */
172
    public static function commands(bool $getShared = true)
173
    {
174
        if ($getShared) {
56✔
175
            return static::getSharedInstance('commands');
54✔
176
        }
177

178
        return new Commands();
56✔
179
    }
180

181
    /**
182
     * Content Security Policy
183
     *
184
     * @return ContentSecurityPolicy
185
     */
186
    public static function csp(?CSPConfig $config = null, bool $getShared = true)
187
    {
188
        if ($getShared) {
560✔
189
            return static::getSharedInstance('csp', $config);
558✔
190
        }
191

192
        $config ??= config(ContentSecurityPolicyConfig::class);
560✔
193

194
        return new ContentSecurityPolicy($config);
560✔
195
    }
196

197
    /**
198
     * The CURL Request class acts as a simple HTTP client for interacting
199
     * with other servers, typically through APIs.
200
     *
201
     * @return CURLRequest
202
     */
203
    public static function curlrequest(array $options = [], ?ResponseInterface $response = null, ?App $config = null, bool $getShared = true)
204
    {
205
        if ($getShared) {
5✔
206
            return static::getSharedInstance('curlrequest', $options, $response, $config);
3✔
207
        }
208

209
        $config ??= config(App::class);
5✔
210
        $response ??= new Response($config);
5✔
211

212
        return new CURLRequest(
5✔
213
            $config,
5✔
214
            new URI($options['baseURI'] ?? null),
5✔
215
            $response,
5✔
216
            $options,
5✔
217
        );
5✔
218
    }
219

220
    /**
221
     * The Email class allows you to send email via mail, sendmail, SMTP.
222
     *
223
     * @param array|EmailConfig|null $config
224
     *
225
     * @return Email
226
     */
227
    public static function email($config = null, bool $getShared = true)
228
    {
229
        if ($getShared) {
5✔
230
            return static::getSharedInstance('email', $config);
1✔
231
        }
232

233
        if (empty($config) || (! is_array($config) && ! $config instanceof EmailConfig)) {
4✔
234
            $config = config(EmailConfig::class);
3✔
235
        }
236

237
        return new Email($config);
4✔
238
    }
239

240
    /**
241
     * The Encryption class provides two-way encryption.
242
     *
243
     * @param bool $getShared
244
     *
245
     * @return EncrypterInterface Encryption handler
246
     */
247
    public static function encrypter(?EncryptionConfig $config = null, $getShared = false)
248
    {
249
        if ($getShared === true) {
7✔
250
            return static::getSharedInstance('encrypter', $config);
1✔
251
        }
252

253
        $config ??= config(EncryptionConfig::class);
7✔
254
        $encryption = new Encryption($config);
7✔
255

256
        return $encryption->initialize($config);
6✔
257
    }
258

259
    /**
260
     * The Exceptions class holds the methods that handle:
261
     *
262
     *  - set_exception_handler
263
     *  - set_error_handler
264
     *  - register_shutdown_function
265
     *
266
     * @return Exceptions
267
     */
268
    public static function exceptions(
269
        ?ExceptionsConfig $config = null,
270
        bool $getShared = true,
271
    ) {
272
        if ($getShared) {
4✔
273
            return static::getSharedInstance('exceptions', $config);
1✔
274
        }
275

276
        $config ??= config(ExceptionsConfig::class);
4✔
277

278
        return new Exceptions($config);
4✔
279
    }
280

281
    /**
282
     * Filters allow you to run tasks before and/or after a controller
283
     * is executed. During before filters, the request can be modified,
284
     * and actions taken based on the request, while after filters can
285
     * act on or modify the response itself before it is sent to the client.
286
     *
287
     * @return Filters
288
     */
289
    public static function filters(?FiltersConfig $config = null, bool $getShared = true)
290
    {
291
        if ($getShared) {
129✔
292
            return static::getSharedInstance('filters', $config);
127✔
293
        }
294

295
        $config ??= config(FiltersConfig::class);
129✔
296

297
        return new Filters($config, AppServices::get('request'), AppServices::get('response'));
129✔
298
    }
299

300
    /**
301
     * The Format class is a convenient place to create Formatters.
302
     *
303
     * @return Format
304
     */
305
    public static function format(?FormatConfig $config = null, bool $getShared = true)
306
    {
307
        if ($getShared) {
33✔
308
            return static::getSharedInstance('format', $config);
30✔
309
        }
310

311
        $config ??= config(FormatConfig::class);
33✔
312

313
        return new Format($config);
33✔
314
    }
315

316
    /**
317
     * The Honeypot provides a secret input on forms that bots should NOT
318
     * fill in, providing an additional safeguard when accepting user input.
319
     *
320
     * @return Honeypot
321
     */
322
    public static function honeypot(?HoneypotConfig $config = null, bool $getShared = true)
323
    {
324
        if ($getShared) {
7✔
325
            return static::getSharedInstance('honeypot', $config);
5✔
326
        }
327

328
        $config ??= config(HoneypotConfig::class);
7✔
329

330
        return new Honeypot($config);
7✔
331
    }
332

333
    /**
334
     * Acts as a factory for ImageHandler classes and returns an instance
335
     * of the handler. Used like service('image')->withFile($path)->rotate(90)->save();
336
     *
337
     * @return BaseHandler
338
     */
339
    public static function image(?string $handler = null, ?Images $config = null, bool $getShared = true)
340
    {
341
        if ($getShared) {
84✔
342
            return static::getSharedInstance('image', $handler, $config);
1✔
343
        }
344

345
        $config ??= config(Images::class);
84✔
346
        assert($config instanceof Images);
347

348
        $handler = $handler !== null && $handler !== '' && $handler !== '0' ? $handler : $config->defaultHandler;
84✔
349
        $class   = $config->handlers[$handler];
84✔
350

351
        return new $class($config);
84✔
352
    }
353

354
    /**
355
     * The Iterator class provides a simple way of looping over a function
356
     * and timing the results and memory usage. Used when debugging and
357
     * optimizing applications.
358
     *
359
     * @return Iterator
360
     */
361
    public static function iterator(bool $getShared = true)
362
    {
363
        if ($getShared) {
3✔
364
            return static::getSharedInstance('iterator');
1✔
365
        }
366

367
        return new Iterator();
3✔
368
    }
369

370
    /**
371
     * Responsible for loading the language string translations.
372
     *
373
     * @return Language
374
     */
375
    public static function language(?string $locale = null, bool $getShared = true)
376
    {
377
        if ($getShared) {
410✔
378
            return static::getSharedInstance('language', $locale)->setLocale($locale);
397✔
379
        }
380

381
        if (AppServices::get('request') instanceof IncomingRequest) {
409✔
382
            $requestLocale = AppServices::get('request')->getLocale();
408✔
383
        } else {
384
            $requestLocale = Locale::getDefault();
1✔
385
        }
386

387
        // Use '?:' for empty string check
388
        $locale = $locale !== null && $locale !== '' && $locale !== '0' ? $locale : $requestLocale;
409✔
389

390
        return new Language($locale);
409✔
391
    }
392

393
    /**
394
     * The Logger class is a PSR-3 compatible Logging class that supports
395
     * multiple handlers that process the actual logging.
396
     *
397
     * @return Logger
398
     */
399
    public static function logger(bool $getShared = true)
400
    {
401
        if ($getShared) {
307✔
402
            return static::getSharedInstance('logger');
305✔
403
        }
404

405
        return new Logger(config(LoggerConfig::class));
305✔
406
    }
407

408
    /**
409
     * Return the appropriate Migration runner.
410
     *
411
     * @return MigrationRunner
412
     */
413
    public static function migrations(?Migrations $config = null, ?ConnectionInterface $db = null, bool $getShared = true)
414
    {
415
        if ($getShared) {
714✔
416
            return static::getSharedInstance('migrations', $config, $db);
2✔
417
        }
418

419
        $config ??= config(Migrations::class);
714✔
420

421
        return new MigrationRunner($config, $db);
714✔
422
    }
423

424
    /**
425
     * The Negotiate class provides the content negotiation features for
426
     * working the request to determine correct language, encoding, charset,
427
     * and more.
428
     *
429
     * @return Negotiate
430
     */
431
    public static function negotiator(?RequestInterface $request = null, bool $getShared = true)
432
    {
433
        if ($getShared) {
11✔
434
            return static::getSharedInstance('negotiator', $request);
9✔
435
        }
436

437
        $request ??= AppServices::get('request');
5✔
438

439
        return new Negotiate($request);
5✔
440
    }
441

442
    /**
443
     * Return the ResponseCache.
444
     *
445
     * @return ResponseCache
446
     */
447
    public static function responsecache(?Cache $config = null, ?CacheInterface $cache = null, bool $getShared = true)
448
    {
449
        if ($getShared) {
6,616✔
450
            return static::getSharedInstance('responsecache', $config, $cache);
6,616✔
451
        }
452

453
        $config ??= config(Cache::class);
1,822✔
454
        $cache ??= AppServices::get('cache');
1,822✔
455

456
        return new ResponseCache($config, $cache);
1,822✔
457
    }
458

459
    /**
460
     * Return the appropriate pagination handler.
461
     *
462
     * @return Pager
463
     */
464
    public static function pager(?PagerConfig $config = null, ?RendererInterface $view = null, bool $getShared = true)
465
    {
466
        if ($getShared) {
12✔
467
            return static::getSharedInstance('pager', $config, $view);
10✔
468
        }
469

470
        $config ??= config(PagerConfig::class);
12✔
471
        $view ??= AppServices::renderer(null, null, false);
12✔
472

473
        return new Pager($config, $view);
12✔
474
    }
475

476
    /**
477
     * The Parser is a simple template parser.
478
     *
479
     * @return Parser
480
     */
481
    public static function parser(?string $viewPath = null, ?ViewConfig $config = null, bool $getShared = true)
482
    {
483
        if ($getShared) {
14✔
484
            return static::getSharedInstance('parser', $viewPath, $config);
12✔
485
        }
486

487
        $viewPath = $viewPath !== null && $viewPath !== '' && $viewPath !== '0' ? $viewPath : (new Paths())->viewDirectory;
14✔
488
        $config ??= config(ViewConfig::class);
14✔
489

490
        return new Parser($config, $viewPath, AppServices::get('locator'), CI_DEBUG, AppServices::get('logger'));
14✔
491
    }
492

493
    /**
494
     * The Renderer class is the class that actually displays a file to the user.
495
     * The default View class within CodeIgniter is intentionally simple, but this
496
     * service could easily be replaced by a template engine if the user needed to.
497
     *
498
     * @return View
499
     */
500
    public static function renderer(?string $viewPath = null, ?ViewConfig $config = null, bool $getShared = true)
501
    {
502
        if ($getShared) {
201✔
503
            return static::getSharedInstance('renderer', $viewPath, $config);
187✔
504
        }
505

506
        $viewPath = $viewPath !== null && $viewPath !== '' && $viewPath !== '0' ? $viewPath : (new Paths())->viewDirectory;
201✔
507
        $config ??= config(ViewConfig::class);
201✔
508

509
        return new View($config, $viewPath, AppServices::get('locator'), CI_DEBUG, AppServices::get('logger'));
201✔
510
    }
511

512
    /**
513
     * Returns the current Request object.
514
     *
515
     * createRequest() injects IncomingRequest or CLIRequest.
516
     *
517
     * @return CLIRequest|IncomingRequest
518
     *
519
     * @deprecated The parameter $config and $getShared are deprecated.
520
     */
521
    public static function request(?App $config = null, bool $getShared = true)
522
    {
523
        if ($getShared) {
919✔
524
            return static::getSharedInstance('request', $config);
889✔
525
        }
526

527
        // @TODO remove the following code for backward compatibility
528
        return AppServices::incomingrequest($config, $getShared);
918✔
529
    }
530

531
    /**
532
     * Create the current Request object, either IncomingRequest or CLIRequest.
533
     *
534
     * This method is called from CodeIgniter::getRequestObject().
535
     *
536
     * @internal
537
     */
538
    public static function createRequest(App $config, bool $isCli = false): void
539
    {
540
        if ($isCli) {
69✔
541
            $request = AppServices::clirequest($config);
12✔
542
        } else {
543
            $request = AppServices::incomingrequest($config);
57✔
544

545
            // guess at protocol if needed
546
            $request->setProtocolVersion($_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.1');
57✔
547
        }
548

549
        // Inject the request object into Services.
550
        static::$instances['request'] = $request;
69✔
551
    }
552

553
    /**
554
     * The IncomingRequest class models an HTTP request.
555
     *
556
     * @return IncomingRequest
557
     *
558
     * @internal
559
     */
560
    public static function incomingrequest(?App $config = null, bool $getShared = true)
561
    {
562
        if ($getShared) {
970✔
563
            return static::getSharedInstance('request', $config);
57✔
564
        }
565

566
        $config ??= config(App::class);
970✔
567

568
        return new IncomingRequest(
970✔
569
            $config,
970✔
570
            AppServices::get('uri'),
970✔
571
            'php://input',
970✔
572
            new UserAgent(),
970✔
573
        );
970✔
574
    }
575

576
    /**
577
     * The Response class models an HTTP response.
578
     *
579
     * @return ResponseInterface
580
     */
581
    public static function response(?App $config = null, bool $getShared = true)
582
    {
583
        if ($getShared) {
323✔
584
            return static::getSharedInstance('response', $config);
286✔
585
        }
586

587
        $config ??= config(App::class);
318✔
588

589
        return new Response($config);
318✔
590
    }
591

592
    /**
593
     * The Redirect class provides nice way of working with redirects.
594
     *
595
     * @return RedirectResponse
596
     */
597
    public static function redirectresponse(?App $config = null, bool $getShared = true)
598
    {
599
        if ($getShared) {
15✔
600
            return static::getSharedInstance('redirectresponse', $config);
11✔
601
        }
602

603
        $config ??= config(App::class);
15✔
604
        $response = new RedirectResponse($config);
15✔
605
        $response->setProtocolVersion(AppServices::get('request')->getProtocolVersion());
15✔
606

607
        return $response;
15✔
608
    }
609

610
    /**
611
     * The Routes service is a class that allows for easily building
612
     * a collection of routes.
613
     *
614
     * @return RouteCollection
615
     */
616
    public static function routes(bool $getShared = true)
617
    {
618
        if ($getShared) {
211✔
619
            return static::getSharedInstance('routes');
209✔
620
        }
621

622
        return new RouteCollection(AppServices::get('locator'), new Modules(), config(Routing::class));
211✔
623
    }
624

625
    /**
626
     * The Router class uses a RouteCollection's array of routes, and determines
627
     * the correct Controller and Method to execute.
628
     *
629
     * @return Router
630
     */
631
    public static function router(?RouteCollectionInterface $routes = null, ?Request $request = null, bool $getShared = true)
632
    {
633
        if ($getShared) {
91✔
634
            return static::getSharedInstance('router', $routes, $request);
89✔
635
        }
636

637
        $routes ??= AppServices::get('routes');
88✔
638
        $request ??= AppServices::get('request');
88✔
639

640
        return new Router($routes, $request);
88✔
641
    }
642

643
    /**
644
     * The Security class provides a few handy tools for keeping the site
645
     * secure, most notably the CSRF protection tools.
646
     *
647
     * @return Security
648
     */
649
    public static function security(?SecurityConfig $config = null, bool $getShared = true)
650
    {
651
        if ($getShared) {
13✔
652
            return static::getSharedInstance('security', $config);
11✔
653
        }
654

655
        $config ??= config(SecurityConfig::class);
12✔
656

657
        return new Security($config);
12✔
658
    }
659

660
    /**
661
     * Return the session manager.
662
     *
663
     * @return Session
664
     */
665
    public static function session(?SessionConfig $config = null, bool $getShared = true)
666
    {
667
        if ($getShared) {
45✔
668
            return static::getSharedInstance('session', $config);
38✔
669
        }
670

671
        $config ??= config(SessionConfig::class);
44✔
672

673
        $logger = AppServices::get('logger');
44✔
674

675
        $driverName = $config->driver;
44✔
676

677
        if ($driverName === DatabaseHandler::class) {
44✔
678
            $DBGroup = $config->DBGroup ?? config(Database::class)->defaultGroup;
1✔
679

680
            $driverPlatform = Database::connect($DBGroup)->getPlatform();
1✔
681

682
            if ($driverPlatform === 'MySQLi') {
1✔
683
                $driverName = MySQLiHandler::class;
×
684
            } elseif ($driverPlatform === 'Postgre') {
1✔
685
                $driverName = PostgreHandler::class;
×
686
            } else {
687
                throw new InvalidArgumentException(sprintf(
1✔
688
                    'Invalid session database handler "%s" provided. Only "MySQLi" and "Postgre" are supported.',
1✔
689
                    $driverPlatform,
1✔
690
                ));
1✔
691
            }
692
        }
693

694
        if (! class_exists($driverName) || ! is_a($driverName, SessionBaseHandler::class, true)) {
43✔
695
            throw new InvalidArgumentException(sprintf(
3✔
696
                'Invalid session handler "%s" provided.',
3✔
697
                $driverName,
3✔
698
            ));
3✔
699
        }
700

701
        /** @var SessionBaseHandler $driver */
702
        $driver = new $driverName($config, AppServices::get('request')->getIPAddress());
40✔
703
        $driver->setLogger($logger);
40✔
704

705
        $session = new Session($driver, $config);
40✔
706
        $session->setLogger($logger);
40✔
707

708
        if (session_status() === PHP_SESSION_NONE) {
40✔
709
            // PHP Session emits the headers according to `session.cache_limiter`.
710
            // See https://www.php.net/manual/en/function.session-cache-limiter.php.
711
            // The headers are not managed by CI's Response class.
712
            // So, we remove CI's default Cache-Control header.
713
            AppServices::get('response')->removeHeader('Cache-Control');
40✔
714

715
            $session->start();
40✔
716
        }
717

718
        return $session;
40✔
719
    }
720

721
    /**
722
     * The Factory for SiteURI.
723
     *
724
     * @return SiteURIFactory
725
     */
726
    public static function siteurifactory(
727
        ?App $config = null,
728
        ?Superglobals $superglobals = null,
729
        bool $getShared = true,
730
    ) {
731
        if ($getShared) {
22✔
732
            return static::getSharedInstance('siteurifactory', $config, $superglobals);
17✔
733
        }
734

735
        $config ??= config('App');
22✔
736
        $superglobals ??= AppServices::get('superglobals');
22✔
737

738
        return new SiteURIFactory($config, $superglobals);
22✔
739
    }
740

741
    /**
742
     * Superglobals.
743
     *
744
     * @return Superglobals
745
     */
746
    public static function superglobals(
747
        ?array $server = null,
748
        ?array $get = null,
749
        bool $getShared = true,
750
    ) {
751
        if ($getShared) {
900✔
752
            return static::getSharedInstance('superglobals', $server, $get);
898✔
753
        }
754

755
        return new Superglobals($server, $get);
898✔
756
    }
757

758
    /**
759
     * The Throttler class provides a simple method for implementing
760
     * rate limiting in your applications.
761
     *
762
     * @return Throttler
763
     */
764
    public static function throttler(bool $getShared = true)
765
    {
766
        if ($getShared) {
4✔
767
            return static::getSharedInstance('throttler');
1✔
768
        }
769

770
        return new Throttler(AppServices::get('cache'));
4✔
771
    }
772

773
    /**
774
     * The Timer class provides a simple way to Benchmark portions of your
775
     * application.
776
     *
777
     * @return Timer
778
     */
779
    public static function timer(bool $getShared = true)
780
    {
781
        if ($getShared) {
94✔
782
            return static::getSharedInstance('timer');
92✔
783
        }
784

785
        return new Timer();
92✔
786
    }
787

788
    /**
789
     * Return the debug toolbar.
790
     *
791
     * @return Toolbar
792
     */
793
    public static function toolbar(?ToolbarConfig $config = null, bool $getShared = true)
794
    {
795
        if ($getShared) {
85✔
796
            return static::getSharedInstance('toolbar', $config);
83✔
797
        }
798

799
        $config ??= config(ToolbarConfig::class);
85✔
800

801
        return new Toolbar($config);
85✔
802
    }
803

804
    /**
805
     * The URI class provides a way to model and manipulate URIs.
806
     *
807
     * @param string|null $uri The URI string
808
     *
809
     * @return URI The current URI if $uri is null.
810
     */
811
    public static function uri(?string $uri = null, bool $getShared = true)
812
    {
813
        if ($getShared) {
×
814
            return static::getSharedInstance('uri', $uri);
×
815
        }
816

UNCOV
817
        if ($uri === null) {
×
UNCOV
818
            $appConfig = config(App::class);
×
819
            $factory   = AppServices::siteurifactory($appConfig, AppServices::get('superglobals'));
×
820

UNCOV
821
            return $factory->createFromGlobals();
×
822
        }
823

UNCOV
824
        return new URI($uri);
×
825
    }
826

827
    /**
828
     * The Validation class provides tools for validating input data.
829
     *
830
     * @return ValidationInterface
831
     */
832
    public static function validation(?ValidationConfig $config = null, bool $getShared = true)
833
    {
834
        if ($getShared) {
117✔
835
            return static::getSharedInstance('validation', $config);
21✔
836
        }
837

838
        $config ??= config(ValidationConfig::class);
117✔
839

840
        return new Validation($config, AppServices::get('renderer'));
117✔
841
    }
842

843
    /**
844
     * View cells are intended to let you insert HTML into view
845
     * that has been generated by any callable in the system.
846
     *
847
     * @return Cell
848
     */
849
    public static function viewcell(bool $getShared = true)
850
    {
851
        if ($getShared) {
6✔
852
            return static::getSharedInstance('viewcell');
3✔
853
        }
854

855
        return new Cell(AppServices::get('cache'));
6✔
856
    }
857

858
    /**
859
     * The Typography class provides a way to format text in semantically relevant ways.
860
     *
861
     * @return Typography
862
     */
863
    public static function typography(bool $getShared = true)
864
    {
865
        if ($getShared) {
4✔
866
            return static::getSharedInstance('typography');
2✔
867
        }
868

869
        return new Typography();
4✔
870
    }
871
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc