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

codeigniter4 / CodeIgniter4 / 25458229238

06 May 2026 08:05PM UTC coverage: 88.308% (+0.03%) from 88.274%
25458229238

Pull #10158

github

web-flow
Merge 8f3ba7ad6 into f300ca0e1
Pull Request #10158: feat: add typed FormRequest accessors

87 of 96 new or added lines in 5 files covered. (90.63%)

123 existing lines in 4 files now uncovered.

23640 of 26770 relevant lines covered (88.31%)

218.13 hits per line

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

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

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

132
        $config ??= config(Cache::class);
2,136✔
133

134
        return CacheFactory::getHandler($config);
2,136✔
135
    }
136

137
    /**
138
     * The locks service provides atomic locks backed by supported cache handlers.
139
     */
140
    public static function locks(?CacheInterface $cache = null, bool $getShared = true): LockManager
141
    {
142
        if ($getShared) {
4✔
143
            return static::getSharedInstance('locks', $cache);
1✔
144
        }
145

146
        $cache ??= AppServices::get('cache');
4✔
147

148
        return new LockManager($cache);
4✔
149
    }
150

151
    /**
152
     * The CLI Request class provides for ways to interact with
153
     * a command line request.
154
     *
155
     * @return CLIRequest
156
     *
157
     * @internal
158
     */
159
    public static function clirequest(?App $config = null, bool $getShared = true)
160
    {
161
        if ($getShared) {
10✔
162
            return static::getSharedInstance('clirequest', $config);
5✔
163
        }
164

165
        $config ??= config(App::class);
10✔
166

167
        return new CLIRequest($config);
10✔
168
    }
169

170
    /**
171
     * CodeIgniter, the core of the framework.
172
     *
173
     * @return CodeIgniter
174
     */
175
    public static function codeigniter(?App $config = null, bool $getShared = true)
176
    {
177
        if ($getShared) {
2✔
178
            return static::getSharedInstance('codeigniter', $config);
×
179
        }
180

181
        $config ??= config(App::class);
2✔
182

183
        return new CodeIgniter($config);
2✔
184
    }
185

186
    /**
187
     * The commands utility for running and working with CLI commands.
188
     *
189
     * @return Commands
190
     */
191
    public static function commands(bool $getShared = true)
192
    {
193
        if ($getShared) {
57✔
194
            return static::getSharedInstance('commands');
55✔
195
        }
196

197
        return new Commands();
57✔
198
    }
199

200
    /**
201
     * Content Security Policy
202
     *
203
     * @return ContentSecurityPolicy
204
     */
205
    public static function csp(?CSPConfig $config = null, bool $getShared = true)
206
    {
207
        if ($getShared) {
108✔
208
            return static::getSharedInstance('csp', $config);
106✔
209
        }
210

211
        $config ??= config(ContentSecurityPolicyConfig::class);
108✔
212

213
        return new ContentSecurityPolicy($config);
108✔
214
    }
215

216
    /**
217
     * The CURL Request class acts as a simple HTTP client for interacting
218
     * with other servers, typically through APIs.
219
     *
220
     * @todo v4.8.0 Remove $config parameter since unused
221
     *
222
     * @return CURLRequest
223
     */
224
    public static function curlrequest(array $options = [], ?ResponseInterface $response = null, ?App $config = null, bool $getShared = true)
225
    {
226
        if ($getShared) {
5✔
227
            return static::getSharedInstance('curlrequest', $options, $response, $config);
3✔
228
        }
229

230
        $config ??= config(App::class);
5✔
231
        $response ??= new Response();
5✔
232

233
        return new CURLRequest(
5✔
234
            $config,
5✔
235
            new URI($options['baseURI'] ?? null),
5✔
236
            $response,
5✔
237
            $options,
5✔
238
        );
5✔
239
    }
240

241
    /**
242
     * The Email class allows you to send email via mail, sendmail, SMTP.
243
     *
244
     * @param array|EmailConfig|null $config
245
     *
246
     * @return Email
247
     */
248
    public static function email($config = null, bool $getShared = true)
249
    {
250
        if ($getShared) {
5✔
251
            return static::getSharedInstance('email', $config);
1✔
252
        }
253

254
        if (empty($config) || (! is_array($config) && ! $config instanceof EmailConfig)) {
4✔
255
            $config = config(EmailConfig::class);
3✔
256
        }
257

258
        return new Email($config);
4✔
259
    }
260

261
    /**
262
     * The Encryption class provides two-way encryption.
263
     *
264
     * @param bool $getShared
265
     *
266
     * @return EncrypterInterface Encryption handler
267
     */
268
    public static function encrypter(?EncryptionConfig $config = null, $getShared = false)
269
    {
270
        if ($getShared === true) {
7✔
271
            return static::getSharedInstance('encrypter', $config);
1✔
272
        }
273

274
        $config ??= config(EncryptionConfig::class);
7✔
275
        $encryption = new Encryption($config);
7✔
276

277
        return $encryption->initialize($config);
6✔
278
    }
279

280
    /**
281
     * Provides a simple way to determine the current environment
282
     * of the application.
283
     *
284
     * Primarily intended for testing environment-specific branches by
285
     * mocking this service. Mocking it does not modify the `ENVIRONMENT`
286
     * constant. It only affects code paths that resolve and use this service.
287
     */
288
    public static function environment(?string $environment = null, bool $getShared = true): EnvironmentDetector
289
    {
290
        if ($getShared) {
584✔
291
            return static::getSharedInstance('environment', $environment);
582✔
292
        }
293

294
        return new EnvironmentDetector($environment);
584✔
295
    }
296

297
    /**
298
     * The Exceptions class holds the methods that handle:
299
     *
300
     *  - set_exception_handler
301
     *  - set_error_handler
302
     *  - register_shutdown_function
303
     *
304
     * @return Exceptions
305
     */
306
    public static function exceptions(
307
        ?ExceptionsConfig $config = null,
308
        bool $getShared = true,
309
    ) {
310
        if ($getShared) {
4✔
311
            return static::getSharedInstance('exceptions', $config);
1✔
312
        }
313

314
        $config ??= config(ExceptionsConfig::class);
4✔
315

316
        return new Exceptions($config);
4✔
317
    }
318

319
    /**
320
     * Filters allow you to run tasks before and/or after a controller
321
     * is executed. During before filters, the request can be modified,
322
     * and actions taken based on the request, while after filters can
323
     * act on or modify the response itself before it is sent to the client.
324
     *
325
     * @return Filters
326
     */
327
    public static function filters(?FiltersConfig $config = null, bool $getShared = true)
328
    {
329
        if ($getShared) {
147✔
330
            return static::getSharedInstance('filters', $config);
145✔
331
        }
332

333
        $config ??= config(FiltersConfig::class);
147✔
334

335
        return new Filters($config, AppServices::get('request'), AppServices::get('response'));
147✔
336
    }
337

338
    /**
339
     * The Format class is a convenient place to create Formatters.
340
     *
341
     * @return Format
342
     */
343
    public static function format(?FormatConfig $config = null, bool $getShared = true)
344
    {
345
        if ($getShared) {
39✔
346
            return static::getSharedInstance('format', $config);
36✔
347
        }
348

349
        $config ??= config(FormatConfig::class);
39✔
350

351
        return new Format($config);
39✔
352
    }
353

354
    /**
355
     * The Honeypot provides a secret input on forms that bots should NOT
356
     * fill in, providing an additional safeguard when accepting user input.
357
     *
358
     * @return Honeypot
359
     */
360
    public static function honeypot(?HoneypotConfig $config = null, bool $getShared = true)
361
    {
362
        if ($getShared) {
7✔
363
            return static::getSharedInstance('honeypot', $config);
5✔
364
        }
365

366
        $config ??= config(HoneypotConfig::class);
7✔
367

368
        return new Honeypot($config);
7✔
369
    }
370

371
    /**
372
     * Acts as a factory for ImageHandler classes and returns an instance
373
     * of the handler. Used like service('image')->withFile($path)->rotate(90)->save();
374
     *
375
     * @return BaseHandler
376
     */
377
    public static function image(?string $handler = null, ?Images $config = null, bool $getShared = true)
378
    {
379
        if ($getShared) {
90✔
380
            return static::getSharedInstance('image', $handler, $config);
1✔
381
        }
382

383
        $config ??= config(Images::class);
90✔
384
        assert($config instanceof Images);
385

386
        $handler = in_array($handler, [null, '', '0'], true) ? $config->defaultHandler : $handler;
90✔
387
        $class   = $config->handlers[$handler];
90✔
388

389
        return new $class($config);
90✔
390
    }
391

392
    /**
393
     * Returns a typed input data object.
394
     *
395
     * @param array<string, mixed> $data
396
     */
397
    public static function inputdata(array $data = [], bool $getShared = false): InputData
398
    {
399
        if ($getShared) {
3✔
NEW
400
            return static::getSharedInstance('inputdata', $data);
×
401
        }
402

403
        return new InputData($data);
3✔
404
    }
405

406
    /**
407
     * The Iterator class provides a simple way of looping over a function
408
     * and timing the results and memory usage. Used when debugging and
409
     * optimizing applications.
410
     *
411
     * @return Iterator
412
     */
413
    public static function iterator(bool $getShared = true)
414
    {
415
        if ($getShared) {
3✔
416
            return static::getSharedInstance('iterator');
1✔
417
        }
418

419
        return new Iterator();
3✔
420
    }
421

422
    /**
423
     * Responsible for loading the language string translations.
424
     *
425
     * @return Language
426
     */
427
    public static function language(?string $locale = null, bool $getShared = true)
428
    {
429
        if ($getShared) {
522✔
430
            return static::getSharedInstance('language', $locale)->setLocale($locale);
511✔
431
        }
432

433
        if (AppServices::get('request') instanceof IncomingRequest) {
521✔
434
            $requestLocale = AppServices::get('request')->getLocale();
520✔
435
        } else {
436
            $requestLocale = Locale::getDefault();
1✔
437
        }
438

439
        // Use '?:' for empty string check
440
        $locale = in_array($locale, [null, '', '0'], true) ? $requestLocale : $locale;
521✔
441

442
        return new Language($locale);
521✔
443
    }
444

445
    /**
446
     * The Logger class is a PSR-3 compatible Logging class that supports
447
     * multiple handlers that process the actual logging.
448
     *
449
     * @return Logger
450
     */
451
    public static function logger(bool $getShared = true)
452
    {
453
        if ($getShared) {
353✔
454
            return static::getSharedInstance('logger');
351✔
455
        }
456

457
        return new Logger(config(LoggerConfig::class));
351✔
458
    }
459

460
    /**
461
     * Return the appropriate Migration runner.
462
     *
463
     * @return MigrationRunner
464
     */
465
    public static function migrations(?Migrations $config = null, ?ConnectionInterface $db = null, bool $getShared = true)
466
    {
467
        if ($getShared) {
864✔
468
            return static::getSharedInstance('migrations', $config, $db);
2✔
469
        }
470

471
        $config ??= config(Migrations::class);
864✔
472

473
        return new MigrationRunner($config, $db);
864✔
474
    }
475

476
    /**
477
     * The Negotiate class provides the content negotiation features for
478
     * working the request to determine correct language, encoding, charset,
479
     * and more.
480
     *
481
     * @return Negotiate
482
     */
483
    public static function negotiator(?RequestInterface $request = null, bool $getShared = true)
484
    {
485
        if ($getShared) {
11✔
486
            return static::getSharedInstance('negotiator', $request);
9✔
487
        }
488

489
        $request ??= AppServices::get('request');
5✔
490

491
        return new Negotiate($request);
5✔
492
    }
493

494
    /**
495
     * Return the ResponseCache.
496
     *
497
     * @return ResponseCache
498
     */
499
    public static function responsecache(?Cache $config = null, ?CacheInterface $cache = null, bool $getShared = true)
500
    {
501
        if ($getShared) {
7,652✔
502
            return static::getSharedInstance('responsecache', $config, $cache);
7,652✔
503
        }
504

505
        $config ??= config(Cache::class);
2,135✔
506
        $cache ??= AppServices::get('cache');
2,135✔
507

508
        return new ResponseCache($config, $cache);
2,135✔
509
    }
510

511
    /**
512
     * Return the appropriate pagination handler.
513
     *
514
     * @return Pager
515
     */
516
    public static function pager(?PagerConfig $config = null, ?RendererInterface $view = null, bool $getShared = true)
517
    {
518
        if ($getShared) {
12✔
519
            return static::getSharedInstance('pager', $config, $view);
10✔
520
        }
521

522
        $config ??= config(PagerConfig::class);
12✔
523
        $view ??= AppServices::renderer(null, null, false);
12✔
524

525
        return new Pager($config, $view);
12✔
526
    }
527

528
    /**
529
     * The Parser is a simple template parser.
530
     *
531
     * @return Parser
532
     */
533
    public static function parser(?string $viewPath = null, ?ViewConfig $config = null, bool $getShared = true)
534
    {
535
        if ($getShared) {
14✔
536
            return static::getSharedInstance('parser', $viewPath, $config);
12✔
537
        }
538

539
        $viewPath = in_array($viewPath, [null, '', '0'], true) ? (new Paths())->viewDirectory : $viewPath;
14✔
540
        $config ??= config(ViewConfig::class);
14✔
541

542
        return new Parser($config, $viewPath, AppServices::get('locator'), CI_DEBUG, AppServices::get('logger'));
14✔
543
    }
544

545
    /**
546
     * The Renderer class is the class that actually displays a file to the user.
547
     * The default View class within CodeIgniter is intentionally simple, but this
548
     * service could easily be replaced by a template engine if the user needed to.
549
     *
550
     * @return View
551
     */
552
    public static function renderer(?string $viewPath = null, ?ViewConfig $config = null, bool $getShared = true)
553
    {
554
        if ($getShared) {
233✔
555
            return static::getSharedInstance('renderer', $viewPath, $config);
219✔
556
        }
557

558
        $viewPath = in_array($viewPath, [null, '', '0'], true) ? (new Paths())->viewDirectory : $viewPath;
233✔
559
        $config ??= config(ViewConfig::class);
233✔
560

561
        return new View($config, $viewPath, AppServices::get('locator'), CI_DEBUG, AppServices::get('logger'));
233✔
562
    }
563

564
    /**
565
     * Returns the current Request object.
566
     *
567
     * createRequest() injects IncomingRequest or CLIRequest.
568
     *
569
     * @return CLIRequest|IncomingRequest
570
     */
571
    public static function request()
572
    {
573
        return static::$instances['request'] ?? static::incomingrequest(getShared: false);
2,948✔
574
    }
575

576
    /**
577
     * Create the current Request object, either IncomingRequest or CLIRequest.
578
     *
579
     * This method is called from CodeIgniter::getRequestObject().
580
     *
581
     * @internal
582
     */
583
    public static function createRequest(App $config, bool $isCli = false): void
584
    {
585
        if ($isCli) {
81✔
586
            $request = AppServices::clirequest($config);
4✔
587
        } else {
588
            $request = AppServices::incomingrequest($config);
77✔
589

590
            // guess at protocol if needed
591
            $request->setProtocolVersion(static::superglobals()->server('SERVER_PROTOCOL', 'HTTP/1.1'));
77✔
592
        }
593

594
        // Inject the request object into Services.
595
        static::$instances['request'] = $request;
81✔
596
    }
597

598
    /**
599
     * The IncomingRequest class models an HTTP request.
600
     *
601
     * @return IncomingRequest
602
     *
603
     * @internal
604
     */
605
    public static function incomingrequest(?App $config = null, bool $getShared = true)
606
    {
607
        if ($getShared) {
2,992✔
608
            return static::getSharedInstance('request', $config);
78✔
609
        }
610

611
        $config ??= config(App::class);
2,992✔
612

613
        return new IncomingRequest(
2,992✔
614
            $config,
2,992✔
615
            AppServices::get('uri'),
2,992✔
616
            'php://input',
2,992✔
617
            new UserAgent(),
2,992✔
618
        );
2,992✔
619
    }
620

621
    /**
622
     * The Response class models an HTTP response.
623
     *
624
     * @todo v4.8.0 Remove $config parameter since unused
625
     *
626
     * @return ResponseInterface
627
     */
628
    public static function response(?App $config = null, bool $getShared = true)
629
    {
630
        if ($getShared) {
387✔
631
            return static::getSharedInstance('response', $config);
343✔
632
        }
633

634
        return new Response();
379✔
635
    }
636

637
    /**
638
     * The Redirect class provides nice way of working with redirects.
639
     *
640
     * @todo v4.8.0 Remove $config parameter since unused
641
     *
642
     * @return RedirectResponse
643
     */
644
    public static function redirectresponse(?App $config = null, bool $getShared = true)
645
    {
646
        if ($getShared) {
18✔
647
            return static::getSharedInstance('redirectresponse', $config);
14✔
648
        }
649

650
        $response = new RedirectResponse();
18✔
651
        $response->setProtocolVersion(AppServices::get('request')->getProtocolVersion());
18✔
652

653
        return $response;
18✔
654
    }
655

656
    /**
657
     * The Routes service is a class that allows for easily building
658
     * a collection of routes.
659
     *
660
     * @return RouteCollection
661
     */
662
    public static function routes(bool $getShared = true)
663
    {
664
        if ($getShared) {
257✔
665
            return static::getSharedInstance('routes');
255✔
666
        }
667

668
        return new RouteCollection(AppServices::get('locator'), new Modules(), config(Routing::class));
257✔
669
    }
670

671
    /**
672
     * The Router class uses a RouteCollection's array of routes, and determines
673
     * the correct Controller and Method to execute.
674
     *
675
     * @return Router
676
     */
677
    public static function router(?RouteCollectionInterface $routes = null, ?Request $request = null, bool $getShared = true)
678
    {
679
        if ($getShared) {
115✔
680
            return static::getSharedInstance('router', $routes, $request);
113✔
681
        }
682

683
        $routes ??= AppServices::get('routes');
112✔
684
        $request ??= AppServices::get('request');
112✔
685

686
        return new Router($routes, $request);
112✔
687
    }
688

689
    /**
690
     * The Security class provides a few handy tools for keeping the site
691
     * secure, most notably the CSRF protection tools.
692
     *
693
     * @return Security
694
     */
695
    public static function security(?SecurityConfig $config = null, bool $getShared = true)
696
    {
697
        if ($getShared) {
13✔
698
            return static::getSharedInstance('security', $config);
11✔
699
        }
700

701
        $config ??= config(SecurityConfig::class);
12✔
702

703
        return new Security($config);
12✔
704
    }
705

706
    /**
707
     * Return the session manager.
708
     *
709
     * @return Session
710
     */
711
    public static function session(?SessionConfig $config = null, bool $getShared = true)
712
    {
713
        if ($getShared) {
63✔
714
            return static::getSharedInstance('session', $config);
56✔
715
        }
716

717
        $config ??= config(SessionConfig::class);
62✔
718

719
        $logger = AppServices::get('logger');
62✔
720

721
        $driverName = $config->driver;
62✔
722

723
        if ($driverName === DatabaseHandler::class) {
62✔
724
            $DBGroup = $config->DBGroup ?? config(Database::class)->defaultGroup;
1✔
725

726
            $driverPlatform = Database::connect($DBGroup)->getPlatform();
1✔
727

728
            if ($driverPlatform === 'MySQLi') {
1✔
729
                $driverName = MySQLiHandler::class;
×
730
            } elseif ($driverPlatform === 'Postgre') {
1✔
731
                $driverName = PostgreHandler::class;
×
732
            } else {
733
                throw new InvalidArgumentException(sprintf(
1✔
734
                    'Invalid session database handler "%s" provided. Only "MySQLi" and "Postgre" are supported.',
1✔
735
                    $driverPlatform,
1✔
736
                ));
1✔
737
            }
738
        }
739

740
        if (! class_exists($driverName) || ! is_a($driverName, SessionBaseHandler::class, true)) {
61✔
741
            throw new InvalidArgumentException(sprintf(
3✔
742
                'Invalid session handler "%s" provided.',
3✔
743
                $driverName,
3✔
744
            ));
3✔
745
        }
746

747
        $driver = new $driverName($config, AppServices::get('request')->getIPAddress());
58✔
748
        $driver->setLogger($logger);
58✔
749

750
        $session = new Session($driver, $config);
58✔
751
        $session->setLogger($logger);
58✔
752

753
        if (session_status() === PHP_SESSION_NONE) {
58✔
754
            // PHP Session emits the headers according to `session.cache_limiter`.
755
            // See https://www.php.net/manual/en/function.session-cache-limiter.php.
756
            // The headers are not managed by CI's Response class.
757
            // So, we remove CI's default Cache-Control header.
758
            AppServices::get('response')->removeHeader('Cache-Control');
58✔
759

760
            $session->start();
58✔
761
        }
762

763
        return $session;
58✔
764
    }
765

766
    /**
767
     * The Factory for SiteURI.
768
     *
769
     * @return SiteURIFactory
770
     */
771
    public static function siteurifactory(
772
        ?App $config = null,
773
        ?Superglobals $superglobals = null,
774
        bool $getShared = true,
775
    ) {
776
        if ($getShared) {
22✔
777
            return static::getSharedInstance('siteurifactory', $config, $superglobals);
17✔
778
        }
779

780
        $config ??= config('App');
22✔
781
        $superglobals ??= AppServices::get('superglobals');
22✔
782

783
        return new SiteURIFactory($config, $superglobals);
22✔
784
    }
785

786
    /**
787
     * Superglobals.
788
     *
789
     * @return Superglobals
790
     */
791
    public static function superglobals(
792
        ?array $server = null,
793
        ?array $get = null,
794
        ?array $post = null,
795
        ?array $cookie = null,
796
        ?array $files = null,
797
        ?array $request = null,
798
        bool $getShared = true,
799
    ) {
800
        if ($getShared) {
1,315✔
801
            return static::getSharedInstance('superglobals', $server, $get, $post, $cookie, $files, $request);
1,313✔
802
        }
803

804
        return new Superglobals($server, $get, $post, $cookie, $files, $request);
780✔
805
    }
806

807
    /**
808
     * The Throttler class provides a simple method for implementing
809
     * rate limiting in your applications.
810
     *
811
     * @return Throttler
812
     */
813
    public static function throttler(bool $getShared = true)
814
    {
815
        if ($getShared) {
4✔
816
            return static::getSharedInstance('throttler');
1✔
817
        }
818

819
        return new Throttler(AppServices::get('cache'));
4✔
820
    }
821

822
    /**
823
     * The Timer class provides a simple way to Benchmark portions of your
824
     * application.
825
     *
826
     * @return Timer
827
     */
828
    public static function timer(bool $getShared = true)
829
    {
830
        if ($getShared) {
119✔
831
            return static::getSharedInstance('timer');
117✔
832
        }
833

834
        return new Timer();
117✔
835
    }
836

837
    /**
838
     * Return the debug toolbar.
839
     *
840
     * @return Toolbar
841
     */
842
    public static function toolbar(?ToolbarConfig $config = null, bool $getShared = true)
843
    {
844
        if ($getShared) {
107✔
845
            return static::getSharedInstance('toolbar', $config);
105✔
846
        }
847

848
        $config ??= config(ToolbarConfig::class);
107✔
849

850
        return new Toolbar($config);
107✔
851
    }
852

853
    /**
854
     * The URI class provides a way to model and manipulate URIs.
855
     *
856
     * @param string|null $uri The URI string
857
     *
858
     * @return URI The current URI if $uri is null.
859
     */
860
    public static function uri(?string $uri = null, bool $getShared = true)
861
    {
862
        if ($getShared) {
×
863
            return static::getSharedInstance('uri', $uri);
×
864
        }
865

866
        if ($uri === null) {
×
867
            $appConfig = config(App::class);
×
868
            $factory   = AppServices::siteurifactory($appConfig, AppServices::get('superglobals'));
×
869

870
            return $factory->createFromGlobals();
×
871
        }
872

873
        return new URI($uri);
×
874
    }
875

876
    /**
877
     * The Validation class provides tools for validating input data.
878
     *
879
     * @return ValidationInterface
880
     */
881
    public static function validation(?ValidationConfig $config = null, bool $getShared = true)
882
    {
883
        if ($getShared) {
151✔
884
            return static::getSharedInstance('validation', $config);
48✔
885
        }
886

887
        $config ??= config(ValidationConfig::class);
151✔
888

889
        return new Validation($config, AppServices::get('renderer'));
151✔
890
    }
891

892
    /**
893
     * Returns a typed validated input object.
894
     *
895
     * @param array<string, mixed> $data
896
     */
897
    public static function validatedinput(array $data = [], bool $getShared = false): ValidatedInput
898
    {
899
        if ($getShared) {
6✔
NEW
900
            return static::getSharedInstance('validatedinput', $data);
×
901
        }
902

903
        return new ValidatedInput($data);
6✔
904
    }
905

906
    /**
907
     * View cells are intended to let you insert HTML into view
908
     * that has been generated by any callable in the system.
909
     *
910
     * @return Cell
911
     */
912
    public static function viewcell(bool $getShared = true)
913
    {
914
        if ($getShared) {
6✔
915
            return static::getSharedInstance('viewcell');
3✔
916
        }
917

918
        return new Cell(AppServices::get('cache'));
6✔
919
    }
920

921
    /**
922
     * The Typography class provides a way to format text in semantically relevant ways.
923
     *
924
     * @return Typography
925
     */
926
    public static function typography(bool $getShared = true)
927
    {
928
        if ($getShared) {
5✔
929
            return static::getSharedInstance('typography');
3✔
930
        }
931

932
        return new Typography();
5✔
933
    }
934

935
    /**
936
     * The Context class provides a way to store and retrieve static data throughout requests.
937
     */
938
    public static function context(bool $getShared = true): Context
939
    {
940
        if ($getShared) {
65✔
941
            return static::getSharedInstance('context');
2✔
942
        }
943

944
        return new Context();
65✔
945
    }
946
}
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