chore: update codeigniter to 4.5.1 + other dependencies to latest

This commit is contained in:
Yassine Doghri 2024-04-23 08:57:21 +00:00
parent 303a900f66
commit f9a939471d
57 changed files with 2840 additions and 2406 deletions

1
.gitignore vendored
View File

@ -132,7 +132,6 @@ tmp/
/results/ /results/
/phpunit*.xml /phpunit*.xml
/.phpunit.*.cache
# js package manager # js package manager
yarn.lock yarn.lock

View File

@ -1,6 +1,2 @@
<IfModule authz_core_module> <IfModule authz_core_module> Require all denied </IfModule>
Require all denied <IfModule !authz_core_module> Deny from all </IfModule>
</IfModule>
<IfModule !authz_core_module>
Deny from all
</IfModule>

View File

@ -61,6 +61,30 @@ class App extends BaseConfig
*/ */
public string $uriProtocol = 'REQUEST_URI'; public string $uriProtocol = 'REQUEST_URI';
/*
*--------------------------------------------------------------------------
* Allowed URL Characters
*--------------------------------------------------------------------------
*
* This lets you specify which characters are permitted within your URLs.
* When someone tries to submit a URL with disallowed characters they will
* get a warning message.
*
* As a security measure you are STRONGLY encouraged to restrict URLs to
* as few characters as possible.
*
* By default, only these are allowed: `a-z 0-9~%.:_-`
*
* Set an empty string to allow all characters -- but only if you are insane.
*
* The configured value is actually a regular expression character group
* and it will be used as: '/\A[<permittedURIChars>]+\z/iu'
*
* DO NOT CHANGE THIS UNLESS YOU FULLY UNDERSTAND THE REPERCUSSIONS!!
*
*/
public string $permittedURIChars = 'a-z 0-9~%.:_\-';
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Default Locale * Default Locale

View File

@ -29,23 +29,17 @@ class Autoload extends AutoloadConfig
* their location on the file system. These are used by the autoloader * their location on the file system. These are used by the autoloader
* to locate files the first time they have been instantiated. * to locate files the first time they have been instantiated.
* *
* The '/app' and '/system' directories are already mapped for you. * The 'Config' (APPPATH . 'Config') and 'CodeIgniter' (SYSTEMPATH) are
* you may change the name of the 'App' namespace if you wish, * already mapped for you.
*
* You may change the name of the 'App' namespace if you wish,
* but this should be done prior to creating any namespaced classes, * but this should be done prior to creating any namespaced classes,
* else you will need to modify all of those classes for this to work. * else you will need to modify all of those classes for this to work.
* *
* Prototype:
*
* $psr4 = [
* 'CodeIgniter' => SYSTEMPATH,
* 'App' => APPPATH
* ];
*
* @var array<string, list<string>|string> * @var array<string, list<string>|string>
*/ */
public $psr4 = [ public $psr4 = [
APP_NAMESPACE => APPPATH, APP_NAMESPACE => APPPATH,
'Config' => APPPATH . 'Config/',
'Modules' => ROOTPATH . 'modules/', 'Modules' => ROOTPATH . 'modules/',
'Modules\Admin' => ROOTPATH . 'modules/Admin/', 'Modules\Admin' => ROOTPATH . 'modules/Admin/',
'Modules\Analytics' => ROOTPATH . 'modules/Analytics/', 'Modules\Analytics' => ROOTPATH . 'modules/Analytics/',

View File

@ -11,8 +11,10 @@ declare(strict_types=1);
* *
* If you set 'display_errors' to '1', CI4's detailed error report will show. * If you set 'display_errors' to '1', CI4's detailed error report will show.
*/ */
error_reporting(E_ALL & ~E_DEPRECATED);
// If you want to suppress more types of errors.
// error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT & ~E_USER_NOTICE & ~E_USER_DEPRECATED);
ini_set('display_errors', '0'); ini_set('display_errors', '0');
error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT & ~E_USER_NOTICE & ~E_USER_DEPRECATED);
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------

View File

@ -48,25 +48,6 @@ class Cache extends BaseConfig
*/ */
public string $storePath = WRITEPATH . 'cache/'; public string $storePath = WRITEPATH . 'cache/';
/**
* --------------------------------------------------------------------------
* Cache Include Query String
* --------------------------------------------------------------------------
*
* Whether to take the URL query string into consideration when generating
* output cache files. Valid options are:
*
* false = Disabled
* true = Enabled, take all query parameters into account.
* Please be aware that this may result in numerous cache
* files generated for the same page over and over again.
* ['q'] = Enabled, but only take into account the specified list
* of query parameters.
*
* @var boolean|string[]
*/
public bool | array $cacheQueryString = false;
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Key Prefix * Key Prefix
@ -170,4 +151,23 @@ class Cache extends BaseConfig
'redis' => RedisHandler::class, 'redis' => RedisHandler::class,
'wincache' => WincacheHandler::class, 'wincache' => WincacheHandler::class,
]; ];
/**
* --------------------------------------------------------------------------
* Web Page Caching: Cache Include Query String
* --------------------------------------------------------------------------
*
* Whether to take the URL query string into consideration when generating
* output cache files. Valid options are:
*
* false = Disabled
* true = Enabled, take all query parameters into account.
* Please be aware that this may result in numerous cache
* files generated for the same page over and over again.
* ['q'] = Enabled, but only take into account the specified list
* of query parameters.
*
* @var bool|list<string>
*/
public $cacheQueryString = false;
} }

View File

@ -35,28 +35,28 @@ class ContentSecurityPolicy extends BaseConfig
/** /**
* Will default to self if not overridden * Will default to self if not overridden
* *
* @var string|string[]|null * @var list<string>|string|null
*/ */
public string | array | null $defaultSrc = null; public string | array | null $defaultSrc = null;
/** /**
* Lists allowed scripts' URLs. * Lists allowed scripts' URLs.
* *
* @var string|string[] * @var list<string>|string
*/ */
public string | array $scriptSrc = 'self'; public string | array $scriptSrc = 'self';
/** /**
* Lists allowed stylesheets' URLs. * Lists allowed stylesheets' URLs.
* *
* @var string|string[] * @var list<string>|string
*/ */
public string | array $styleSrc = 'self'; public string | array $styleSrc = 'self';
/** /**
* Defines the origins from which images can be loaded. * Defines the origins from which images can be loaded.
* *
* @var string|string[] * @var list<string>|string
*/ */
public string | array $imageSrc = 'self'; public string | array $imageSrc = 'self';
@ -65,35 +65,35 @@ class ContentSecurityPolicy extends BaseConfig
* *
* Will default to self if not overridden * Will default to self if not overridden
* *
* @var string|string[]|null * @var list<string>|string|null
*/ */
public string | array | null $baseURI = null; public string | array | null $baseURI = null;
/** /**
* Lists the URLs for workers and embedded frame contents * Lists the URLs for workers and embedded frame contents
* *
* @var string|string[] * @var list<string>|string
*/ */
public string | array $childSrc = 'self'; public string | array $childSrc = 'self';
/** /**
* Limits the origins that you can connect to (via XHR, WebSockets, and EventSource). * Limits the origins that you can connect to (via XHR, WebSockets, and EventSource).
* *
* @var string|string[] * @var list<string>|string
*/ */
public string | array $connectSrc = 'self'; public string | array $connectSrc = 'self';
/** /**
* Specifies the origins that can serve web fonts. * Specifies the origins that can serve web fonts.
* *
* @var string|string[] * @var list<string>|string
*/ */
public string | array $fontSrc; public string | array $fontSrc;
/** /**
* Lists valid endpoints for submission from `<form>` tags. * Lists valid endpoints for submission from `<form>` tags.
* *
* @var string|string[] * @var list<string>|string
*/ */
public string | array $formAction = 'self'; public string | array $formAction = 'self';
@ -102,47 +102,47 @@ class ContentSecurityPolicy extends BaseConfig
* `<embed>`, and `<applet>` tags. This directive can't be used in `<meta>` tags and applies only to non-HTML * `<embed>`, and `<applet>` tags. This directive can't be used in `<meta>` tags and applies only to non-HTML
* resources. * resources.
* *
* @var string|string[]|null * @var list<string>|string|null
*/ */
public string | array | null $frameAncestors = null; public string | array | null $frameAncestors = null;
/** /**
* The frame-src directive restricts the URLs which may be loaded into nested browsing contexts. * The frame-src directive restricts the URLs which may be loaded into nested browsing contexts.
* *
* @var string[]|string|null * @var list<string>|string|null
*/ */
public string | array | null $frameSrc = null; public string | array | null $frameSrc = null;
/** /**
* Restricts the origins allowed to deliver video and audio. * Restricts the origins allowed to deliver video and audio.
* *
* @var string|string[]|null * @var list<string>|string|null
*/ */
public string | array | null $mediaSrc = null; public string | array | null $mediaSrc = null;
/** /**
* Allows control over Flash and other plugins. * Allows control over Flash and other plugins.
* *
* @var string|string[] * @var list<string>|string
*/ */
public string | array $objectSrc = 'self'; public string | array $objectSrc = 'self';
/** /**
* @var string|string[]|null * @var list<string>|string|null
*/ */
public string | array | null $manifestSrc = null; public string | array | null $manifestSrc = null;
/** /**
* Limits the kinds of plugins a page may invoke. * Limits the kinds of plugins a page may invoke.
* *
* @var string|string[]|null * @var list<string>|string|null
*/ */
public string | array | null $pluginTypes = null; public string | array | null $pluginTypes = null;
/** /**
* List of actions allowed. * List of actions allowed.
* *
* @var string|string[]|null * @var list<string>|string|null
*/ */
public string | array | null $sandbox = null; public string | array | null $sandbox = null;

105
app/Config/Cors.php Normal file
View File

@ -0,0 +1,105 @@
<?php
namespace Config;
use CodeIgniter\Config\BaseConfig;
/**
* Cross-Origin Resource Sharing (CORS) Configuration
*
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
*/
class Cors extends BaseConfig
{
/**
* The default CORS configuration.
*
* @var array{
* allowedOrigins: list<string>,
* allowedOriginsPatterns: list<string>,
* supportsCredentials: bool,
* allowedHeaders: list<string>,
* exposedHeaders: list<string>,
* allowedMethods: list<string>,
* maxAge: int,
* }
*/
public array $default = [
/**
* Origins for the `Access-Control-Allow-Origin` header.
*
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
*
* E.g.:
* - ['http://localhost:8080']
* - ['https://www.example.com']
*/
'allowedOrigins' => [],
/**
* Origin regex patterns for the `Access-Control-Allow-Origin` header.
*
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
*
* NOTE: A pattern specified here is part of a regular expression. It will
* be actually `#\A<pattern>\z#`.
*
* E.g.:
* - ['https://\w+\.example\.com']
*/
'allowedOriginsPatterns' => [],
/**
* Weather to send the `Access-Control-Allow-Credentials` header.
*
* The Access-Control-Allow-Credentials response header tells browsers whether
* the server allows cross-origin HTTP requests to include credentials.
*
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials
*/
'supportsCredentials' => false,
/**
* Set headers to allow.
*
* The Access-Control-Allow-Headers response header is used in response to
* a preflight request which includes the Access-Control-Request-Headers to
* indicate which HTTP headers can be used during the actual request.
*
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers
*/
'allowedHeaders' => [],
/**
* Set headers to expose.
*
* The Access-Control-Expose-Headers response header allows a server to
* indicate which response headers should be made available to scripts running
* in the browser, in response to a cross-origin request.
*
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers
*/
'exposedHeaders' => [],
/**
* Set methods to allow.
*
* The Access-Control-Allow-Methods response header specifies one or more
* methods allowed when accessing a resource in response to a preflight
* request.
*
* E.g.:
* - ['GET', 'POST', 'PUT', 'DELETE']
*
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methods
*/
'allowedMethods' => [],
/**
* Set how many seconds the results of a preflight request can be cached.
*
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age
*/
'maxAge' => 7200,
];
}

View File

@ -45,6 +45,11 @@ class Database extends Config
'failover' => [], 'failover' => [],
'port' => 3306, 'port' => 3306,
'numberNative' => false, 'numberNative' => false,
'dateFormat' => [
'date' => 'Y-m-d',
'datetime' => 'Y-m-d H:i:s',
'time' => 'H:i:s',
],
]; ];
/** /**
@ -64,7 +69,7 @@ class Database extends Config
'pConnect' => false, 'pConnect' => false,
'DBDebug' => true, 'DBDebug' => true,
'charset' => 'utf8', 'charset' => 'utf8',
'DBCollat' => 'utf8_general_ci', 'DBCollat' => '',
'swapPre' => '', 'swapPre' => '',
'encrypt' => false, 'encrypt' => false,
'compress' => false, 'compress' => false,
@ -73,6 +78,11 @@ class Database extends Config
'port' => 3306, 'port' => 3306,
'foreignKeys' => true, 'foreignKeys' => true,
'busyTimeout' => 1000, 'busyTimeout' => 1000,
'dateFormat' => [
'date' => 'Y-m-d',
'datetime' => 'Y-m-d H:i:s',
'time' => 'H:i:s',
],
]; ];
//-------------------------------------------------------------------- //--------------------------------------------------------------------

View File

@ -33,7 +33,7 @@ class Exceptions extends BaseConfig
* Any status codes here will NOT be logged if logging is turned on. * Any status codes here will NOT be logged if logging is turned on.
* By default, only 404 (Page Not Found) exceptions are ignored. * By default, only 404 (Page Not Found) exceptions are ignored.
* *
* @var int[] * @var list<int>
*/ */
public array $ignoreCodes = [404]; public array $ignoreCodes = [404];
@ -56,7 +56,7 @@ class Exceptions extends BaseConfig
* In order to specify 2 levels, use "/" to separate. * In order to specify 2 levels, use "/" to separate.
* ex. ['server', 'setup/password', 'secret_token'] * ex. ['server', 'setup/password', 'secret_token']
* *
* @var string[] * @var list<string>
*/ */
public array $sensitiveDataInTrace = []; public array $sensitiveDataInTrace = [];

View File

@ -11,22 +11,21 @@ use CodeIgniter\Config\BaseConfig;
*/ */
class Feature extends BaseConfig class Feature extends BaseConfig
{ {
/**
* Enable multiple filters for a route or not.
*
* If you enable this:
* - CodeIgniter\CodeIgniter::handleRequest() uses:
* - CodeIgniter\Filters\Filters::enableFilters(), instead of enableFilter()
* - CodeIgniter\CodeIgniter::tryToRouteIt() uses:
* - CodeIgniter\Router\Router::getFilters(), instead of getFilter()
* - CodeIgniter\Router\Router::handle() uses:
* - property $filtersInfo, instead of $filterInfo
* - CodeIgniter\Router\RouteCollection::getFiltersForRoute(), instead of getFilterForRoute()
*/
public bool $multipleFilters = false;
/** /**
* Use improved new auto routing instead of the default legacy version. * Use improved new auto routing instead of the default legacy version.
*/ */
public bool $autoRoutesImproved = false; public bool $autoRoutesImproved = false;
/**
* Use filter execution order in 4.4 or before.
*/
public bool $oldFilterOrder = false;
/**
* The behavior of `limit(0)` in Query Builder.
*
* If true, `limit(0)` returns all records. (the behavior of 4.4.x or before in version 4.x.)
* If false, `limit(0)` returns no records. (the behavior of 3.1.9 or later in version 3.x.)
*/
public bool $limitZeroAsAll = true;
} }

View File

@ -8,8 +8,11 @@ use App\Filters\AllowCorsFilter;
use CodeIgniter\Config\BaseConfig; use CodeIgniter\Config\BaseConfig;
use CodeIgniter\Filters\CSRF; use CodeIgniter\Filters\CSRF;
use CodeIgniter\Filters\DebugToolbar; use CodeIgniter\Filters\DebugToolbar;
use CodeIgniter\Filters\ForceHTTPS;
use CodeIgniter\Filters\Honeypot; use CodeIgniter\Filters\Honeypot;
use CodeIgniter\Filters\InvalidChars; use CodeIgniter\Filters\InvalidChars;
use CodeIgniter\Filters\PageCache;
use CodeIgniter\Filters\PerformanceMetrics;
use CodeIgniter\Filters\SecureHeaders; use CodeIgniter\Filters\SecureHeaders;
use Modules\Auth\Filters\PermissionFilter; use Modules\Auth\Filters\PermissionFilter;
@ -18,8 +21,10 @@ class Filters extends BaseConfig
/** /**
* Configures aliases for Filter classes to make reading things nicer and simpler. * Configures aliases for Filter classes to make reading things nicer and simpler.
* *
* @var array<string, class-string|list<class-string>> [filter_name => classname] * @var array<string, class-string|list<class-string>>
* or [filter_name => [classname1, classname2, ...]] *
* [filter_name => classname]
* or [filter_name => [classname1, classname2, ...]]
*/ */
public array $aliases = [ public array $aliases = [
'csrf' => CSRF::class, 'csrf' => CSRF::class,
@ -28,12 +33,41 @@ class Filters extends BaseConfig
'invalidchars' => InvalidChars::class, 'invalidchars' => InvalidChars::class,
'secureheaders' => SecureHeaders::class, 'secureheaders' => SecureHeaders::class,
'allow-cors' => AllowCorsFilter::class, 'allow-cors' => AllowCorsFilter::class,
'cors' => Cors::class,
'forcehttps' => ForceHTTPS::class,
'pagecache' => PageCache::class,
'performance' => PerformanceMetrics::class,
];
/**
* List of special required filters.
*
* The filters listed here are special. They are applied before and after
* other kinds of filters, and always applied even if a route does not exist.
*
* Filters set by default provide framework functionality. If removed,
* those functions will no longer work.
*
* @see https://codeigniter.com/user_guide/incoming/filters.html#provided-filters
*
* @var array{before: list<string>, after: list<string>}
*/
public array $required = [
'before' => [
'forcehttps', // Force Global Secure Requests
'pagecache', // Web Page Caching
],
'after' => [
'pagecache', // Web Page Caching
'performance', // Performance Metrics
'toolbar', // Debug Toolbar
],
]; ];
/** /**
* List of filter aliases that are always applied before and after every request. * List of filter aliases that are always applied before and after every request.
* *
* @var array<string, array<string, array<string, string>>>|array<string, list<string>> * @var array<string, array<string, array<string, string|array<string>>>>>|array<string, list<string>>
*/ */
public array $globals = [ public array $globals = [
'before' => [ 'before' => [
@ -44,7 +78,6 @@ class Filters extends BaseConfig
// 'invalidchars', // 'invalidchars',
], ],
'after' => [ 'after' => [
'toolbar',
// 'honeypot', // 'honeypot',
// 'secureheaders', // 'secureheaders',
], ],
@ -53,12 +86,12 @@ class Filters extends BaseConfig
/** /**
* List of filter aliases that works on a particular HTTP method (GET, POST, etc.). * List of filter aliases that works on a particular HTTP method (GET, POST, etc.).
* *
* Example: 'post' => ['foo', 'bar'] * Example: 'POST' => ['foo', 'bar']
* *
* If you use this, you should disable auto-routing because auto-routing permits any HTTP method to access a * If you use this, you should disable auto-routing because auto-routing permits any HTTP method to access a
* controller. Accessing the controller with a method you dont expect could bypass the filter. * controller. Accessing the controller with a method you dont expect could bypass the filter.
* *
* @var array<string, string[]> * @var array<string, list<string>>
*/ */
public array $methods = []; public array $methods = [];
@ -67,7 +100,7 @@ class Filters extends BaseConfig
* *
* Example: 'isLoggedIn' => ['before' => ['account/*', 'profiles/*']] * Example: 'isLoggedIn' => ['before' => ['account/*', 'profiles/*']]
* *
* @var array<string, array<string, string[]>> * @var array<string, array<string, list<string>>>
*/ */
public array $filters = []; public array $filters = [];

View File

@ -24,7 +24,7 @@ class Format extends BaseConfig
* These formats are only checked when the data passed to the respond() * These formats are only checked when the data passed to the respond()
* method is an array. * method is an array.
* *
* @var string[] * @var list<string>
*/ */
public array $supportedResponseFormats = [ public array $supportedResponseFormats = [
'application/json', 'application/json',

View File

@ -28,8 +28,10 @@ class Generators extends BaseConfig
* @var array<string, string> * @var array<string, string>
*/ */
public array $views = [ public array $views = [
'make:cell' => 'CodeIgniter\Commands\Generators\Views\cell.tpl.php', 'make:cell' => [
'make:cell_view' => 'CodeIgniter\Commands\Generators\Views\cell_view.tpl.php', 'class' => 'CodeIgniter\Commands\Generators\Views\cell.tpl.php',
'view' => 'CodeIgniter\Commands\Generators\Views\cell_view.tpl.php',
],
'make:command' => 'CodeIgniter\Commands\Generators\Views\command.tpl.php', 'make:command' => 'CodeIgniter\Commands\Generators\Views\command.tpl.php',
'make:config' => 'CodeIgniter\Commands\Generators\Views\config.tpl.php', 'make:config' => 'CodeIgniter\Commands\Generators\Views\config.tpl.php',
'make:controller' => 'CodeIgniter\Commands\Generators\Views\controller.tpl.php', 'make:controller' => 'CodeIgniter\Commands\Generators\Views\controller.tpl.php',

View File

@ -4,7 +4,6 @@ declare(strict_types=1);
namespace Config; namespace Config;
use CodeIgniter\Config\BaseConfig;
use Kint\Parser\ConstructablePluginInterface; use Kint\Parser\ConstructablePluginInterface;
use Kint\Renderer\AbstractRenderer; use Kint\Renderer\AbstractRenderer;
use Kint\Renderer\Rich\TabPluginInterface; use Kint\Renderer\Rich\TabPluginInterface;
@ -20,7 +19,7 @@ use Kint\Renderer\Rich\ValuePluginInterface;
* *
* @see https://kint-php.github.io/kint/ for details on these settings. * @see https://kint-php.github.io/kint/ for details on these settings.
*/ */
class Kint extends BaseConfig class Kint
{ {
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------

View File

@ -38,7 +38,7 @@ class Logger extends BaseConfig
* For a live site you'll usually enable Critical or higher (3) to be logged otherwise * For a live site you'll usually enable Critical or higher (3) to be logged otherwise
* your log files will fill up very fast. * your log files will fill up very fast.
* *
* @var int|int[] * @var int|list<int>
*/ */
public int | array $threshold = (ENVIRONMENT === 'production') ? 4 : 9; public int | array $threshold = (ENVIRONMENT === 'production') ? 4 : 9;
@ -75,7 +75,7 @@ class Logger extends BaseConfig
* Handlers are executed in the order defined in this array, starting with * Handlers are executed in the order defined in this array, starting with
* the handler on top and continuing down. * the handler on top and continuing down.
* *
* @var array<string, mixed> * @var array<class-string, array<string, int|list<string>|string>>
*/ */
public array $handlers = [ public array $handlers = [
/* /*

View File

@ -22,7 +22,7 @@ class Mimes
/** /**
* Map of extensions to mime types. * Map of extensions to mime types.
* *
* @var array<string, string|string[]> * @var array<string, list<string>|string>
*/ */
public static $mimes = [ public static $mimes = [
'hqx' => [ 'hqx' => [

32
app/Config/Optimize.php Normal file
View File

@ -0,0 +1,32 @@
<?php
namespace Config;
/**
* Optimization Configuration.
*
* NOTE: This class does not extend BaseConfig for performance reasons.
* So you cannot replace the property values with Environment Variables.
*
* @immutable
*/
class Optimize
{
/**
* --------------------------------------------------------------------------
* Config Caching
* --------------------------------------------------------------------------
*
* @see https://codeigniter.com/user_guide/concepts/factories.html#config-caching
*/
public bool $configCacheEnabled = false;
/**
* --------------------------------------------------------------------------
* Config Caching
* --------------------------------------------------------------------------
*
* @see https://codeigniter.com/user_guide/concepts/autoloader.html#file-locator-caching
*/
public bool $locatorCacheEnabled = false;
}

View File

@ -12,13 +12,14 @@ use CodeIgniter\Config\Routing as BaseRouting;
class Routing extends BaseRouting class Routing extends BaseRouting
{ {
/** /**
* For Defined Routes.
* An array of files that contain route definitions. * An array of files that contain route definitions.
* Route files are read in order, with the first match * Route files are read in order, with the first match
* found taking precedence. * found taking precedence.
* *
* Default: APPPATH . 'Config/Routes.php' * Default: APPPATH . 'Config/Routes.php'
* *
* @var string[] * @var list<string>
*/ */
public array $routeFiles = [ public array $routeFiles = [
APPPATH . 'Config/Routes.php', APPPATH . 'Config/Routes.php',
@ -34,6 +35,7 @@ class Routing extends BaseRouting
]; ];
/** /**
* For Defined Routes and Auto Routing.
* The default namespace to use for Controllers when no other * The default namespace to use for Controllers when no other
* namespace has been specified. * namespace has been specified.
* *
@ -42,6 +44,7 @@ class Routing extends BaseRouting
public string $defaultNamespace = 'App\Controllers'; public string $defaultNamespace = 'App\Controllers';
/** /**
* For Auto Routing.
* The default controller to use when no other controller has been * The default controller to use when no other controller has been
* specified. * specified.
* *
@ -50,6 +53,7 @@ class Routing extends BaseRouting
public string $defaultController = 'HomeController'; public string $defaultController = 'HomeController';
/** /**
* For Defined Routes and Auto Routing.
* The default method to call on the controller when no other * The default method to call on the controller when no other
* method has been set in the route. * method has been set in the route.
* *
@ -58,7 +62,8 @@ class Routing extends BaseRouting
public string $defaultMethod = 'index'; public string $defaultMethod = 'index';
/** /**
* Whether to translate dashes in URIs to underscores. * For Auto Routing.
* Whether to translate dashes in URIs for controller/method to underscores.
* Primarily useful when using the auto-routing. * Primarily useful when using the auto-routing.
* *
* Default: false * Default: false
@ -94,6 +99,7 @@ class Routing extends BaseRouting
public bool $autoRoute = false; public bool $autoRoute = false;
/** /**
* For Defined Routes.
* If TRUE, will enable the use of the 'prioritize' option * If TRUE, will enable the use of the 'prioritize' option
* when defining routes. * when defining routes.
* *
@ -102,7 +108,16 @@ class Routing extends BaseRouting
public bool $prioritize = false; public bool $prioritize = false;
/** /**
* Map of URI segments and namespaces. For Auto Routing (Improved). * For Defined Routes.
* If TRUE, matched multiple URI segments will be passed as one parameter.
*
* Default: false
*/
public bool $multipleSegmentsOneParam = false;
/**
* For Auto Routing (Improved).
* Map of URI segments and namespaces.
* *
* The key is the first URI segment. The value is the controller namespace. * The key is the first URI segment. The value is the controller namespace.
* E.g., * E.g.,
@ -113,4 +128,15 @@ class Routing extends BaseRouting
* @var array<string, string> [ uri_segment => namespace ] * @var array<string, string> [ uri_segment => namespace ]
*/ */
public array $moduleRoutes = []; public array $moduleRoutes = [];
/**
* For Auto Routing (Improved).
* Whether to translate dashes in URIs for controller/method to CamelCase.
* E.g., blog-controller -> BlogController
*
* If you enable this, $translateURIDashes is ignored.
*
* Default: false
*/
public bool $translateUriToCamelCase = false;
} }

View File

@ -80,9 +80,9 @@ class Security extends BaseConfig
* CSRF Redirect * CSRF Redirect
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* *
* Redirect to previous page with error on failure. * @see https://codeigniter4.github.io/userguide/libraries/security.html#redirection-on-failure
*/ */
public bool $redirect = false; public bool $redirect = (ENVIRONMENT === 'production');
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------

View File

@ -101,4 +101,29 @@ class Session extends BaseConfig
* DB Group for the database session. * DB Group for the database session.
*/ */
public ?string $DBGroup = null; public ?string $DBGroup = null;
/**
* --------------------------------------------------------------------------
* Lock Retry Interval (microseconds)
* --------------------------------------------------------------------------
*
* This is used for RedisHandler.
*
* Time (microseconds) to wait if lock cannot be acquired.
* The default is 100,000 microseconds (= 0.1 seconds).
*/
public int $lockRetryInterval = 100_000;
/**
* --------------------------------------------------------------------------
* Lock Max Retries
* --------------------------------------------------------------------------
*
* This is used for RedisHandler.
*
* Maximum number of lock acquisition attempts.
* The default is 300 times. That is lock timeout is about 30 (0.1 * 300)
* seconds.
*/
public int $lockMaxRetries = 300;
} }

View File

@ -33,7 +33,7 @@ class Toolbar extends BaseConfig
* List of toolbar collectors that will be called when Debug Toolbar * List of toolbar collectors that will be called when Debug Toolbar
* fires up and collects data from. * fires up and collects data from.
* *
* @var string[] * @var list<class-string>
*/ */
public array $collectors = [ public array $collectors = [
Timers::class, Timers::class,
@ -51,7 +51,7 @@ class Toolbar extends BaseConfig
* Collect Var Data * Collect Var Data
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* *
* If set to false var data from the views will not be colleted. Useful to * If set to false var data from the views will not be collected. Useful to
* avoid high memory usage when there are lots of data passed to the view. * avoid high memory usage when there are lots of data passed to the view.
*/ */
public bool $collectVarData = true; public bool $collectVarData = true;
@ -102,7 +102,7 @@ class Toolbar extends BaseConfig
* *
* NOTE: The ROOTPATH will be prepended to all values. * NOTE: The ROOTPATH will be prepended to all values.
* *
* @var string[] * @var list<string>
*/ */
public array $watchedDirectories = ['app', 'modules', 'themes']; public array $watchedDirectories = ['app', 'modules', 'themes'];
@ -114,7 +114,7 @@ class Toolbar extends BaseConfig
* Contains an array of file extensions that will be watched for changes and * Contains an array of file extensions that will be watched for changes and
* used to determine if the hot-reload feature should reload the page or not. * used to determine if the hot-reload feature should reload the page or not.
* *
* @var string[] * @var list<string>
*/ */
public array $watchedExtensions = ['php', 'css', 'js', 'html', 'svg', 'json', 'env']; public array $watchedExtensions = ['php', 'css', 'js', 'html', 'svg', 'json', 'env'];
} }

View File

@ -16,7 +16,7 @@ class Validation extends BaseConfig
/** /**
* Stores the classes that contain the rules that are available. * Stores the classes that contain the rules that are available.
* *
* @var string[] * @var list<string>
*/ */
public array $ruleSets = [ public array $ruleSets = [
Rules::class, Rules::class,

View File

@ -9,8 +9,8 @@ use CodeIgniter\View\ViewDecoratorInterface;
use ViewComponents\Decorator; use ViewComponents\Decorator;
/** /**
* @phpstan-type ParserCallable (callable(mixed): mixed) * @phpstan-type parser_callable (callable(mixed): mixed)
* @phpstan-type ParserCallableString (callable(mixed): mixed)&string * @phpstan-type parser_callable_string (callable(mixed): mixed)&string
*/ */
class View extends BaseView class View extends BaseView
{ {
@ -31,8 +31,8 @@ class View extends BaseView
* *
* Examples: { title|esc(js) } { created_on|date(Y-m-d)|esc(attr) } * Examples: { title|esc(js) } { created_on|date(Y-m-d)|esc(attr) }
* *
* @var array<string, string> * @var array<string, string>
* @phpstan-var array<string, ParserCallableString> * @phpstan-var array<string, parser_callable_string>
*/ */
public $filters = []; public $filters = [];
@ -40,8 +40,8 @@ class View extends BaseView
* Parser Plugins provide a way to extend the functionality provided by the core Parser by creating aliases that * Parser Plugins provide a way to extend the functionality provided by the core Parser by creating aliases that
* will be replaced with any callable. Can be single or tag pair. * will be replaced with any callable. Can be single or tag pair.
* *
* @var array<string, array<string>|callable|string> * @var array<string, callable|list<string>|string>
* @phpstan-var array<string, array<ParserCallableString>|ParserCallableString|ParserCallable> * @phpstan-var array<string, list<parser_callable_string>|parser_callable_string|parser_callable>
*/ */
public $plugins = []; public $plugins = [];
@ -51,7 +51,7 @@ class View extends BaseView
* *
* All classes must implement CodeIgniter\View\ViewDecoratorInterface * All classes must implement CodeIgniter\View\ViewDecoratorInterface
* *
* @var class-string<ViewDecoratorInterface>[] * @var list<class-string<ViewDecoratorInterface>>
*/ */
public array $decorators = [Decorator::class]; public array $decorators = [Decorator::class];
} }

View File

@ -41,7 +41,7 @@ abstract class BaseController extends Controller
* class instantiation. These helpers will be available * class instantiation. These helpers will be available
* to all other controllers that extend BaseController. * to all other controllers that extend BaseController.
* *
* @var string[] * @var list<string>
*/ */
protected $helpers = []; protected $helpers = [];

View File

@ -40,7 +40,7 @@ class EpisodeAudioController extends Controller
* An array of helpers to be loaded automatically upon class instantiation. These helpers will be available to all * An array of helpers to be loaded automatically upon class instantiation. These helpers will be available to all
* other controllers that extend Analytics. * other controllers that extend Analytics.
* *
* @var string[] * @var list<string>
*/ */
protected $helpers = ['analytics']; protected $helpers = ['analytics'];

View File

@ -26,7 +26,7 @@ class CategoryModel extends Model
protected $primaryKey = 'id'; protected $primaryKey = 'id';
/** /**
* @var string[] * @var list<string>
*/ */
protected $allowedFields = ['parent_id', 'code', 'apple_category', 'google_category']; protected $allowedFields = ['parent_id', 'code', 'apple_category', 'google_category'];

View File

@ -33,7 +33,7 @@ class ClipModel extends Model
protected $primaryKey = 'id'; protected $primaryKey = 'id';
/** /**
* @var string[] * @var list<string>
*/ */
protected $allowedFields = [ protected $allowedFields = [
'id', 'id',

View File

@ -40,7 +40,7 @@ class EpisodeCommentModel extends UuidModel
protected $uuidFields = ['id', 'in_reply_to_id']; protected $uuidFields = ['id', 'in_reply_to_id'];
/** /**
* @var string[] * @var list<string>
*/ */
protected $allowedFields = [ protected $allowedFields = [
'id', 'id',
@ -57,7 +57,7 @@ class EpisodeCommentModel extends UuidModel
]; ];
/** /**
* @var string[] * @var list<string>
*/ */
protected $beforeInsert = ['setCommentId']; protected $beforeInsert = ['setCommentId'];

View File

@ -62,7 +62,7 @@ class EpisodeModel extends UuidModel
protected $table = 'episodes'; protected $table = 'episodes';
/** /**
* @var string[] * @var list<string>
*/ */
protected $allowedFields = [ protected $allowedFields = [
'id', 'id',
@ -127,17 +127,17 @@ class EpisodeModel extends UuidModel
]; ];
/** /**
* @var string[] * @var list<string>
*/ */
protected $afterInsert = ['writeEnclosureMetadata', 'clearCache']; protected $afterInsert = ['writeEnclosureMetadata', 'clearCache'];
/** /**
* @var string[] * @var list<string>
*/ */
protected $afterUpdate = ['clearCache', 'writeEnclosureMetadata']; protected $afterUpdate = ['clearCache', 'writeEnclosureMetadata'];
/** /**
* @var string[] * @var list<string>
*/ */
protected $beforeDelete = ['clearCache']; protected $beforeDelete = ['clearCache'];

View File

@ -26,7 +26,7 @@ class LanguageModel extends Model
protected $primaryKey = 'id'; protected $primaryKey = 'id';
/** /**
* @var string[] * @var list<string>
*/ */
protected $allowedFields = ['code', 'native_name']; protected $allowedFields = ['code', 'native_name'];

View File

@ -31,7 +31,7 @@ class LikeModel extends UuidModel
protected $uuidFields = ['comment_id']; protected $uuidFields = ['comment_id'];
/** /**
* @var string[] * @var list<string>
*/ */
protected $allowedFields = ['actor_id', 'comment_id']; protected $allowedFields = ['actor_id', 'comment_id'];

View File

@ -26,7 +26,7 @@ class PageModel extends Model
protected $primaryKey = 'id'; protected $primaryKey = 'id';
/** /**
* @var string[] * @var list<string>
*/ */
protected $allowedFields = ['id', 'title', 'slug', 'content_markdown', 'content_html']; protected $allowedFields = ['id', 'title', 'slug', 'content_markdown', 'content_html'];
@ -55,19 +55,19 @@ class PageModel extends Model
]; ];
/** /**
* @var string[] * @var list<string>
*/ */
protected $afterInsert = ['clearCache']; protected $afterInsert = ['clearCache'];
/** /**
* Before update because slug or title might change * Before update because slug or title might change
* *
* @var string[] * @var list<string>
*/ */
protected $beforeUpdate = ['clearCache']; protected $beforeUpdate = ['clearCache'];
/** /**
* @var string[] * @var list<string>
*/ */
protected $beforeDelete = ['clearCache']; protected $beforeDelete = ['clearCache'];

View File

@ -26,7 +26,7 @@ class PersonModel extends Model
protected $primaryKey = 'id'; protected $primaryKey = 'id';
/** /**
* @var string[] * @var list<string>
*/ */
protected $allowedFields = [ protected $allowedFields = [
'id', 'id',
@ -64,19 +64,19 @@ class PersonModel extends Model
]; ];
/** /**
* @var string[] * @var list<string>
*/ */
protected $afterInsert = ['clearCache']; protected $afterInsert = ['clearCache'];
/** /**
* clear cache before update if by any chance, the person name changes, so will the person link * clear cache before update if by any chance, the person name changes, so will the person link
* *
* @var string[] * @var list<string>
*/ */
protected $beforeUpdate = ['clearCache']; protected $beforeUpdate = ['clearCache'];
/** /**
* @var string[] * @var list<string>
*/ */
protected $beforeDelete = ['clearCache']; protected $beforeDelete = ['clearCache'];

View File

@ -30,7 +30,7 @@ class PodcastModel extends Model
protected $primaryKey = 'id'; protected $primaryKey = 'id';
/** /**
* @var string[] * @var list<string>
*/ */
protected $allowedFields = [ protected $allowedFields = [
'id', 'id',
@ -104,29 +104,29 @@ class PodcastModel extends Model
]; ];
/** /**
* @var string[] * @var list<string>
*/ */
protected $beforeInsert = ['setPodcastGUID', 'createPodcastActor']; protected $beforeInsert = ['setPodcastGUID', 'createPodcastActor'];
/** /**
* @var string[] * @var list<string>
*/ */
protected $afterInsert = ['setActorAvatar']; protected $afterInsert = ['setActorAvatar'];
/** /**
* @var string[] * @var list<string>
*/ */
protected $afterUpdate = ['updatePodcastActor']; protected $afterUpdate = ['updatePodcastActor'];
/** /**
* clear cache before update if by any chance, the podcast name changes, so will the podcast link * clear cache before update if by any chance, the podcast name changes, so will the podcast link
* *
* @var string[] * @var list<string>
*/ */
protected $beforeUpdate = ['clearCache']; protected $beforeUpdate = ['clearCache'];
/** /**
* @var string[] * @var list<string>
*/ */
protected $beforeDelete = ['clearCache']; protected $beforeDelete = ['clearCache'];

View File

@ -5,7 +5,7 @@ declare(strict_types=1);
use CodeIgniter\CLI\CLI; use CodeIgniter\CLI\CLI;
// The main Exception // The main Exception
CLI::write('[' . get_class($exception) . ']', 'light_gray', 'red'); CLI::write('[' . $exception::class . ']', 'light_gray', 'red');
CLI::write($message); CLI::write($message);
CLI::write('at ' . CLI::color(clean_path($exception->getFile()) . ':' . $exception->getLine(), 'green')); CLI::write('at ' . CLI::color(clean_path($exception->getFile()) . ':' . $exception->getLine(), 'green'));
CLI::newLine(); CLI::newLine();
@ -16,7 +16,7 @@ while ($prevException = $last->getPrevious()) {
$last = $prevException; $last = $prevException;
CLI::write(' Caused by:'); CLI::write(' Caused by:');
CLI::write(' [' . get_class($prevException) . ']', 'red'); CLI::write(' [' . $prevException::class . ']', 'red');
CLI::write(' ' . $prevException->getMessage()); CLI::write(' ' . $prevException->getMessage());
CLI::write(' at ' . CLI::color(clean_path($prevException->getFile()) . ':' . $prevException->getLine(), 'green')); CLI::write(' at ' . CLI::color(clean_path($prevException->getFile()) . ':' . $prevException->getLine(), 'green'));
CLI::newLine(); CLI::newLine();
@ -52,20 +52,11 @@ if (defined('SHOW_DEBUG_BACKTRACE') && SHOW_DEBUG_BACKTRACE) {
$function .= $padClass . $error['function']; $function .= $padClass . $error['function'];
} }
$args = implode(', ', array_map(static function ($value) { $args = implode(', ', array_map(static fn ($value) => match (true) {
switch (true) { is_object($value) => 'Object(' . $value::class . ')',
case is_object($value): is_array($value) => count($value) ? '[...]' : '[]',
return 'Object(' . get_class($value) . ')'; $value === null => 'null', // return the lowercased version
default => var_export($value, true),
case is_array($value):
return count($value) ? '[...]' : '[]';
case $value === null:
return 'null'; // return the lowercased version
default:
return var_export($value, true);
}
}, array_values($error['args'] ?? []))); }, array_values($error['args'] ?? [])));
$function .= '(' . $args . ')'; $function .= '(' . $args . ')';

View File

@ -18,62 +18,69 @@ body {
margin: 0; margin: 0;
padding: 0; padding: 0;
} }
h1 { h1 {
font-weight: lighter; font-weight: lighter;
letter-spacing: 0.8;
font-size: 3rem; font-size: 3rem;
color: var(--dark-text-color); color: var(--dark-text-color);
margin: 0; margin: 0;
} }
h1.headline { h1.headline {
margin-top: 20%; margin-top: 20%;
font-size: 5rem; font-size: 5rem;
} }
.text-center { .text-center {
text-align: center; text-align: center;
} }
p.lead { p.lead {
font-size: 1.6rem; font-size: 1.6rem;
} }
.container { .container {
max-width: 75rem; max-width: 75rem;
margin: 0 auto; margin: 0 auto;
padding: 1rem; padding: 1rem;
} }
.header { .header {
background: var(--light-bg-color); background: var(--light-bg-color);
color: var(--dark-text-color); color: var(--dark-text-color);
} }
.header .container { .header .container {
padding: 1rem 1.75rem 1.75rem 1.75rem; padding: 1rem;
} }
.header h1 { .header h1 {
font-size: 2.5rem; font-size: 2.5rem;
font-weight: 500; font-weight: 500;
} }
.header p { .header p {
font-size: 1.2rem; font-size: 1.2rem;
margin: 0; margin: 0;
line-height: 2.5; line-height: 2.5;
} }
.header a { .header a {
color: var(--brand-primary-color); color: var(--brand-primary-color);
margin-left: 2rem; margin-left: 2rem;
display: none; display: none;
text-decoration: none; text-decoration: none;
} }
.header:hover a { .header:hover a {
display: inline; display: inline;
} }
.footer { .environment {
background: var(--dark-bg-color); background: var(--dark-bg-color);
color: var(--light-text-color); color: var(--light-text-color);
}
.footer .container {
border-top: 1px solid #e7e7e7;
margin-top: 1rem;
text-align: center; text-align: center;
padding: 0.2rem;
} }
.source { .source {
@ -86,17 +93,21 @@ p.lead {
margin: 0; margin: 0;
overflow-x: scroll; overflow-x: scroll;
} }
.source span.line { .source span.line {
line-height: 1.4; line-height: 1.4;
} }
.source span.line .number { .source span.line .number {
color: #666; color: #666;
} }
.source .line .highlight { .source .line .highlight {
display: block; display: block;
background: var(--dark-text-color); background: var(--dark-text-color);
color: var(--light-text-color); color: var(--light-text-color);
} }
.source span.highlight .number { .source span.highlight .number {
color: #fff; color: #fff;
} }
@ -108,37 +119,44 @@ p.lead {
padding: 0; padding: 0;
margin-bottom: -1px; margin-bottom: -1px;
} }
.tabs li { .tabs li {
display: inline; display: inline;
} }
.tabs a:link, .tabs a:link,
.tabs a:visited { .tabs a:visited {
padding: 0rem 1rem; padding: 0 1rem;
line-height: 2.7; line-height: 2.7;
text-decoration: none; text-decoration: none;
color: var(--dark-text-color); color: var(--dark-text-color);
background: var(--light-bg-color); background: var(--light-bg-color);
border: 1px solid rgba(0, 0, 0, 0.15); border: 1px solid rgb(0 0 0 / 15%);
border-bottom: 0; border-bottom: 0;
border-top-left-radius: 5px; border-top-left-radius: 5px;
border-top-right-radius: 5px; border-top-right-radius: 5px;
display: inline-block; display: inline-block;
} }
.tabs a:hover { .tabs a:hover {
background: var(--light-bg-color); background: var(--light-bg-color);
border-color: rgba(0, 0, 0, 0.15); border-color: rgb(0 0 0 / 15%);
} }
.tabs a.active { .tabs a.active {
background: var(--main-bg-color); background: var(--main-bg-color);
color: var(--main-text-color); color: var(--main-text-color);
} }
.tab-content { .tab-content {
background: var(--main-bg-color); background: var(--main-bg-color);
border: 1px solid rgba(0, 0, 0, 0.15); border: 1px solid rgb(0 0 0 / 15%);
} }
.content { .content {
padding: 1rem; padding: 1rem;
} }
.hide { .hide {
display: none; display: none;
} }
@ -153,26 +171,26 @@ p.lead {
border-radius: 5px; border-radius: 5px;
color: #31708f; color: #31708f;
} }
ul,
ol {
line-height: 1.8;
}
table { table {
width: 100%; width: 100%;
overflow: hidden; overflow: hidden;
} }
th { th {
text-align: left; text-align: left;
border-bottom: 1px solid #e7e7e7; border-bottom: 1px solid #e7e7e7;
padding-bottom: 0.5rem; padding-bottom: 0.5rem;
} }
td { td {
padding: 0.2rem 0.5rem 0.2rem 0; padding: 0.2rem 0.5rem 0.2rem 0;
} }
tr:hover td { tr:hover td {
background: #f1f1f1; background: #f1f1f1;
} }
td pre { td pre {
white-space: pre-wrap; white-space: pre-wrap;
} }
@ -180,20 +198,25 @@ td pre {
.trace a { .trace a {
color: inherit; color: inherit;
} }
.trace table { .trace table {
width: auto; width: auto;
} }
.trace tr td:first-child { .trace tr td:first-child {
min-width: 5em; min-width: 5em;
font-weight: bold; font-weight: bold;
} }
.trace td { .trace td {
background: var(--light-bg-color); background: var(--light-bg-color);
padding: 0 1rem; padding: 0 1rem;
} }
.trace td pre { .trace td pre {
margin: 0; margin: 0;
} }
.args { .args {
display: none; display: none;
} }

View File

@ -3,6 +3,7 @@
declare(strict_types=1); declare(strict_types=1);
use CodeIgniter\CodeIgniter; use CodeIgniter\CodeIgniter;
use CodeIgniter\HTTP\Header;
use Config\Services; use Config\Services;
$errorId = uniqid('error', true); $errorId = uniqid('error', true);
@ -26,6 +27,12 @@ $errorId = uniqid('error', true);
<!-- Header --> <!-- Header -->
<div class="header"> <div class="header">
<div class="environment">
Displayed at <?= esc(date('H:i:sa')) ?> &mdash;
PHP: <?= esc(PHP_VERSION) ?> &mdash;
CodeIgniter: <?= esc(CodeIgniter::CI_VERSION) ?> --
Environment: <?= ENVIRONMENT ?>
</div>
<div class="container"> <div class="container">
<h1><?= esc($title), esc($exception->getCode() ? ' #' . $exception->getCode() : '') ?></h1> <h1><?= esc($title), esc($exception->getCode() ? ' #' . $exception->getCode() : '') ?></h1>
<p> <p>
@ -57,10 +64,10 @@ while ($prevException = $last->getPrevious()) {
<pre> <pre>
Caused by: Caused by:
<?= esc(get_class($prevException)), esc($prevException->getCode() ? ' #' . $prevException->getCode() : '') ?> <?= esc($prevException::class), esc($prevException->getCode() ? ' #' . $prevException->getCode() : '') ?>
<?= nl2br(esc($prevException->getMessage())) ?> <?= nl2br(esc($prevException->getMessage())) ?>
<a href="https://www.duckduckgo.com/?q=<?= urlencode(get_class($prevException) . ' ' . preg_replace('#\'.*\'|".*"#Us', '', $prevException->getMessage())) ?>" <a href="https://www.duckduckgo.com/?q=<?= urlencode($prevException::class . ' ' . preg_replace('#\'.*\'|".*"#Us', '', $prevException->getMessage())) ?>"
rel="noreferrer" target="_blank">search &rarr;</a> rel="noreferrer" target="_blank">search &rarr;</a>
<?= esc(clean_path($prevException->getFile()) . ':' . $prevException->getLine()) ?> <?= esc(clean_path($prevException->getFile()) . ':' . $prevException->getLine()) ?>
</pre> </pre>
@ -117,7 +124,7 @@ while ($prevException = $last->getPrevious()) {
<?php <?php
$params = null; $params = null;
// Reflection by name is not available for closure function // Reflection by name is not available for closure function
if (substr($row['function'], -1) !== '}') { if (! str_ends_with($row['function'], '}')) {
$mirror = isset($row['class']) ? new ReflectionMethod($row['class'], $row['function']) : new ReflectionFunction($row['function']); $mirror = isset($row['class']) ? new ReflectionMethod($row['class'], $row['function']) : new ReflectionFunction($row['function']);
$params = $mirror->getParameters(); $params = $mirror->getParameters();
} }
@ -231,7 +238,7 @@ while ($prevException = $last->getPrevious()) {
</tr> </tr>
<tr> <tr>
<td>HTTP Method</td> <td>HTTP Method</td>
<td><?= esc(strtoupper($request->getMethod())) ?></td> <td><?= esc($request->getMethod()) ?></td>
</tr> </tr>
<tr> <tr>
<td>IP Address</td> <td>IP Address</td>
@ -315,22 +322,22 @@ while ($prevException = $last->getPrevious()) {
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<?php foreach ($headers as $value) : ?> <?php foreach ($headers as $name => $value) : ?>
<?php <tr>
if (empty($value)) { <td><?= esc($name, 'html') ?></td>
continue; <td>
} <?php
if ($value instanceof Header) {
if (! is_array($value)) { echo esc($value->getValueLine(), 'html');
$value = [$value]; } else {
} ?> foreach ($value as $i => $header) {
<?php foreach ($value as $h) : ?> echo ' (' . $i + 1 . ') ' . esc($header->getValueLine(), 'html');
<tr> }
<td><?= esc($h->getName(), 'html') ?></td> }
<td><?= esc($h->getValueLine(), 'html') ?></td> ?>
</tr> </td>
<?php endforeach; ?> </tr>
<?php endforeach; ?> <?php endforeach; ?>
</tbody> </tbody>
</table> </table>
@ -352,8 +359,6 @@ $response->setStatusCode(http_response_code());
<?php $headers = $response->headers(); ?> <?php $headers = $response->headers(); ?>
<?php if (! empty($headers)) : ?> <?php if (! empty($headers)) : ?>
<?php natsort($headers) ?>
<h3>Headers</h3> <h3>Headers</h3>
<table> <table>
@ -364,12 +369,22 @@ $response->setStatusCode(http_response_code());
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<?php foreach (array_keys($headers) as $name) : ?> <?php foreach ($headers as $name => $value) : ?>
<tr> <tr>
<td><?= esc($name, 'html') ?></td> <td><?= esc($name, 'html') ?></td>
<td><?= esc($response->getHeaderLine($name), 'html') ?></td> <td>
<?php
if ($value instanceof Header) {
echo esc($response->getHeaderLine($name), 'html');
} else {
foreach ($value as $i => $header) {
echo ' (' . $i + 1 . ') ' . esc($header->getValueLine(), 'html');
}
}
?>
</td>
</tr> </tr>
<?php endforeach; ?> <?php endforeach; ?>
</tbody> </tbody>
</table> </table>
@ -414,18 +429,5 @@ $response->setStatusCode(http_response_code());
</div> <!-- /container --> </div> <!-- /container -->
<?php endif; ?> <?php endif; ?>
<div class="footer">
<div class="container">
<p>
Displayed at <?= esc(date('H:i:sa')) ?> &mdash;
PHP: <?= esc(PHP_VERSION) ?> &mdash;
CodeIgniter: <?= esc(CodeIgniter::CI_VERSION) ?> --
Environment: <?= ENVIRONMENT ?>
</p>
</div>
</div>
</body> </body>
</html> </html>

View File

@ -9,38 +9,41 @@
"php": "^8.1", "php": "^8.1",
"adaures/ipcat-php": "^v1.0.0", "adaures/ipcat-php": "^v1.0.0",
"adaures/podcast-persons-taxonomy": "^v1.0.1", "adaures/podcast-persons-taxonomy": "^v1.0.1",
"aws/aws-sdk-php": "^3.300.8", "aws/aws-sdk-php": "^3.305.1",
"chrisjean/php-ico": "^1.0.4", "chrisjean/php-ico": "^1.0.4",
"cocur/slugify": "^v4.5.1", "cocur/slugify": "^v4.5.1",
"codeigniter4/framework": "v4.4.6", "codeigniter4/framework": "v4.5.1",
"codeigniter4/settings": "v2.2.0", "codeigniter4/settings": "v2.2.0",
"codeigniter4/shield": "v1.0.1", "codeigniter4/shield": "v1.0.3",
"codeigniter4/tasks": "dev-develop", "codeigniter4/tasks": "dev-develop",
"geoip2/geoip2": "v3.0.0", "geoip2/geoip2": "v3.0.0",
"james-heinrich/getid3": "^2.0.0-beta5", "james-heinrich/getid3": "^2.0.0-beta5",
"league/commonmark": "^2.4.2", "league/commonmark": "^2.4.2",
"league/html-to-markdown": "5.1.1", "league/html-to-markdown": "5.1.1",
"melbahja/seo": "^v2.1.1", "melbahja/seo": "^v2.1.1",
"michalsn/codeigniter4-uuid": "v1.0.2", "michalsn/codeigniter4-uuid": "v1.1.0",
"mpratt/embera": "^2.0.36", "mpratt/embera": "^2.0.38",
"opawg/user-agents-v2-php": "dev-main", "opawg/user-agents-v2-php": "dev-main",
"phpseclib/phpseclib": "~2.0.47", "phpseclib/phpseclib": "~2.0.47",
"vlucas/phpdotenv": "v5.6.0", "vlucas/phpdotenv": "v5.6.0",
"whichbrowser/parser": "^v2.1.7", "whichbrowser/parser": "^v2.1.8",
"yassinedoghri/podcast-feed": "dev-main" "yassinedoghri/podcast-feed": "dev-main"
}, },
"require-dev": { "require-dev": {
"captainhook/captainhook": "^5.21.2", "captainhook/captainhook": "^5.23.0",
"codeigniter/phpstan-codeigniter": "v1.4.3", "codeigniter/phpstan-codeigniter": "v1.4.3",
"mikey179/vfsstream": "^v1.6.11", "mikey179/vfsstream": "^v1.6.11",
"phpstan/extension-installer": "^1.3.1", "phpstan/extension-installer": "^1.3.1",
"phpstan/phpstan": "^1.10.59", "phpstan/phpstan": "^1.10.67",
"phpunit/phpunit": "^10.5.11", "phpunit/phpunit": "^10.5.20",
"rector/rector": "^1.0.1", "rector/rector": "^1.0.4",
"symplify/coding-standard": "^12.0.7", "symplify/coding-standard": "^12.0.7",
"symplify/easy-coding-standard": "^12.0.13" "symplify/easy-coding-standard": "^12.0.13"
}, },
"autoload": { "autoload": {
"psr-4": {
"App\\": "app/"
},
"exclude-from-classmap": [ "exclude-from-classmap": [
"**/Database/Migrations/**" "**/Database/Migrations/**"
] ]

436
composer.lock generated

File diff suppressed because it is too large Load Diff

80
env
View File

@ -30,12 +30,15 @@
# DATABASE # DATABASE
#-------------------------------------------------------------------- #--------------------------------------------------------------------
# If you use MySQLi as tests, first update the values of Config\Database::$tests.
# database.default.hostname = localhost # database.default.hostname = localhost
# database.default.database = ci4 # database.default.database = ci4
# database.default.username = root # database.default.username = root
# database.default.password = root # database.default.password = root
# database.default.DBDriver = MySQLi # database.default.DBDriver = MySQLi
# database.default.DBPrefix = # database.default.DBPrefix =
# database.tests.charset = utf8mb4
# database.tests.DBCollat = utf8mb4_general_ci
# database.default.port = 3306 # database.default.port = 3306
# database.tests.hostname = localhost # database.tests.hostname = localhost
@ -46,98 +49,21 @@
# database.tests.DBPrefix = # database.tests.DBPrefix =
# database.tests.port = 3306 # database.tests.port = 3306
#--------------------------------------------------------------------
# CONTENT SECURITY POLICY
#--------------------------------------------------------------------
# contentsecuritypolicy.reportOnly = false
# contentsecuritypolicy.defaultSrc = 'none'
# contentsecuritypolicy.scriptSrc = 'self'
# contentsecuritypolicy.styleSrc = 'self'
# contentsecuritypolicy.imageSrc = 'self'
# contentsecuritypolicy.baseURI = null
# contentsecuritypolicy.childSrc = null
# contentsecuritypolicy.connectSrc = 'self'
# contentsecuritypolicy.fontSrc = null
# contentsecuritypolicy.formAction = null
# contentsecuritypolicy.frameAncestors = null
# contentsecuritypolicy.frameSrc = null
# contentsecuritypolicy.mediaSrc = null
# contentsecuritypolicy.objectSrc = null
# contentsecuritypolicy.pluginTypes = null
# contentsecuritypolicy.reportURI = null
# contentsecuritypolicy.sandbox = false
# contentsecuritypolicy.upgradeInsecureRequests = false
# contentsecuritypolicy.styleNonceTag = '{csp-style-nonce}'
# contentsecuritypolicy.scriptNonceTag = '{csp-script-nonce}'
# contentsecuritypolicy.autoNonce = true
#--------------------------------------------------------------------
# COOKIE
#--------------------------------------------------------------------
# cookie.prefix = ''
# cookie.expires = 0
# cookie.path = '/'
# cookie.domain = ''
# cookie.secure = false
# cookie.httponly = false
# cookie.samesite = 'Lax'
# cookie.raw = false
#-------------------------------------------------------------------- #--------------------------------------------------------------------
# ENCRYPTION # ENCRYPTION
#-------------------------------------------------------------------- #--------------------------------------------------------------------
# encryption.key = # encryption.key =
# encryption.driver = OpenSSL
# encryption.blockSize = 16
# encryption.digest = SHA512
#--------------------------------------------------------------------
# HONEYPOT
#--------------------------------------------------------------------
# honeypot.hidden = 'true'
# honeypot.label = 'Fill This Field'
# honeypot.name = 'honeypot'
# honeypot.template = '<label>{label}</label><input type="text" name="{name}" value=""/>'
# honeypot.container = '<div style="display:none">{template}</div>'
#--------------------------------------------------------------------
# SECURITY
#--------------------------------------------------------------------
# security.csrfProtection = 'cookie'
# security.tokenRandomize = false
# security.tokenName = 'csrf_token_name'
# security.headerName = 'X-CSRF-TOKEN'
# security.cookieName = 'csrf_cookie_name'
# security.expires = 7200
# security.regenerate = true
# security.redirect = false
# security.samesite = 'Lax'
#-------------------------------------------------------------------- #--------------------------------------------------------------------
# SESSION # SESSION
#-------------------------------------------------------------------- #--------------------------------------------------------------------
# session.driver = 'CodeIgniter\Session\Handlers\FileHandler' # session.driver = 'CodeIgniter\Session\Handlers\FileHandler'
# session.cookieName = 'ci_session'
# session.expiration = 7200
# session.savePath = null # session.savePath = null
# session.matchIP = false
# session.timeToUpdate = 300
# session.regenerateDestroy = false
#-------------------------------------------------------------------- #--------------------------------------------------------------------
# LOGGER # LOGGER
#-------------------------------------------------------------------- #--------------------------------------------------------------------
# logger.threshold = 4 # logger.threshold = 4
#--------------------------------------------------------------------
# CURLRequest
#--------------------------------------------------------------------
# curlrequest.shareOptions = false

View File

@ -30,16 +30,16 @@
"dependencies": { "dependencies": {
"@amcharts/amcharts4": "^4.10.38", "@amcharts/amcharts4": "^4.10.38",
"@amcharts/amcharts4-geodata": "^4.1.28", "@amcharts/amcharts4-geodata": "^4.1.28",
"@codemirror/commands": "^6.3.3", "@codemirror/commands": "^6.5.0",
"@codemirror/lang-xml": "^6.0.2", "@codemirror/lang-xml": "^6.1.0",
"@codemirror/language": "^6.10.1", "@codemirror/language": "^6.10.1",
"@codemirror/state": "^6.4.1", "@codemirror/state": "^6.4.1",
"@codemirror/view": "^6.24.1", "@codemirror/view": "^6.26.3",
"@floating-ui/dom": "^1.6.3", "@floating-ui/dom": "^1.6.3",
"@github/clipboard-copy-element": "^1.3.0", "@github/clipboard-copy-element": "^1.3.0",
"@github/hotkey": "^3.1.0", "@github/hotkey": "^3.1.0",
"@github/markdown-toolbar-element": "^2.2.1", "@github/markdown-toolbar-element": "^2.2.3",
"@github/relative-time-element": "^4.3.1", "@github/relative-time-element": "^4.4.0",
"@tailwindcss/nesting": "0.0.0-insiders.565cd3e", "@tailwindcss/nesting": "0.0.0-insiders.565cd3e",
"@vime/core": "^5.4.1", "@vime/core": "^5.4.1",
"choices.js": "^10.2.0", "choices.js": "^10.2.0",
@ -47,28 +47,28 @@
"flatpickr": "^4.6.13", "flatpickr": "^4.6.13",
"leaflet": "^1.9.4", "leaflet": "^1.9.4",
"leaflet.markercluster": "^1.5.3", "leaflet.markercluster": "^1.5.3",
"lit": "^3.1.2", "lit": "^3.1.3",
"marked": "^12.0.0", "marked": "^12.0.2",
"wavesurfer.js": "^7.7.3", "wavesurfer.js": "^7.7.11",
"xml-formatter": "^3.6.2" "xml-formatter": "^3.6.2"
}, },
"devDependencies": { "devDependencies": {
"@commitlint/cli": "^19.0.3", "@commitlint/cli": "^19.3.0",
"@commitlint/config-conventional": "^19.0.3", "@commitlint/config-conventional": "^19.2.2",
"@csstools/css-tokenizer": "^2.2.3", "@csstools/css-tokenizer": "^2.2.4",
"@semantic-release/changelog": "^6.0.3", "@semantic-release/changelog": "^6.0.3",
"@semantic-release/exec": "^6.0.3", "@semantic-release/exec": "^6.0.3",
"@semantic-release/git": "^10.0.1", "@semantic-release/git": "^10.0.1",
"@semantic-release/gitlab": "^13.0.3", "@semantic-release/gitlab": "^13.0.3",
"@tailwindcss/forms": "^0.5.7", "@tailwindcss/forms": "^0.5.7",
"@tailwindcss/typography": "^0.5.10", "@tailwindcss/typography": "^0.5.12",
"@types/leaflet": "^1.9.8", "@types/leaflet": "^1.9.12",
"@typescript-eslint/eslint-plugin": "^7.1.0", "@typescript-eslint/eslint-plugin": "^7.7.1",
"@typescript-eslint/parser": "^7.1.0", "@typescript-eslint/parser": "^7.7.1",
"all-contributors-cli": "^6.26.1", "all-contributors-cli": "^6.26.1",
"commitizen": "^4.3.0", "commitizen": "^4.3.0",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"cssnano": "^6.0.3", "cssnano": "^6.1.2",
"cz-conventional-changelog": "^3.3.0", "cz-conventional-changelog": "^3.3.0",
"eslint": "^8.57.0", "eslint": "^8.57.0",
"eslint-config-prettier": "^9.1.0", "eslint-config-prettier": "^9.1.0",
@ -76,25 +76,25 @@
"husky": "^9.0.11", "husky": "^9.0.11",
"is-ci": "^3.0.1", "is-ci": "^3.0.1",
"lint-staged": "^15.2.2", "lint-staged": "^15.2.2",
"postcss": "^8.4.35", "postcss": "^8.4.38",
"postcss-import": "^16.0.1", "postcss-import": "^16.1.0",
"postcss-nesting": "^12.0.4", "postcss-nesting": "^12.1.2",
"postcss-preset-env": "^9.4.0", "postcss-preset-env": "^9.5.9",
"postcss-reporter": "^7.1.0", "postcss-reporter": "^7.1.0",
"prettier": "3.2.5", "prettier": "3.2.5",
"prettier-plugin-organize-imports": "^3.2.4", "prettier-plugin-organize-imports": "^3.2.4",
"semantic-release": "^23.0.2", "semantic-release": "^23.0.8",
"stylelint": "^16.2.1", "stylelint": "^16.4.0",
"stylelint-config-standard": "^36.0.0", "stylelint-config-standard": "^36.0.0",
"svgo": "^3.2.0", "svgo": "^3.2.0",
"tailwindcss": "^3.4.1", "tailwindcss": "^3.4.3",
"typescript": "^5.3.3", "typescript": "^5.4.5",
"vite": "^5.1.4", "vite": "^5.2.10",
"vite-plugin-pwa": "^0.19.2", "vite-plugin-pwa": "^0.19.8",
"workbox-build": "^7.0.0", "workbox-build": "^7.1.0",
"workbox-core": "^7.0.0", "workbox-core": "^7.1.0",
"workbox-routing": "^7.0.0", "workbox-routing": "^7.1.0",
"workbox-strategies": "^7.0.0" "workbox-strategies": "^7.1.0"
}, },
"lint-staged": { "lint-staged": {
"*.{js,ts,css,md,json}": "prettier --write", "*.{js,ts,css,md,json}": "prettier --write",

View File

@ -1,6 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?> <phpunit
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" bootstrap="vendor/codeigniter4/framework/system/Test/bootstrap.php" backupGlobals="false" colors="true" stopOnError="false" stopOnFailure="false" stopOnIncomplete="false" stopOnSkipped="false" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.2/phpunit.xsd" cacheDirectory=".phpunit.cache"> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<coverage includeUncoveredFiles="true"> xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd"
bootstrap="vendor/codeigniter4/framework/system/Test/bootstrap.php"
backupGlobals="false"
beStrictAboutOutputDuringTests="true"
colors="true"
columns="max"
failOnRisky="true"
failOnWarning="true"
cacheDirectory="build/.phpunit.cache">
<coverage
includeUncoveredFiles="true"
pathCoverage="false"
ignoreDeprecatedCodeUnits="true"
disableCodeCoverageIgnore="true">
<report> <report>
<clover outputFile="build/logs/clover.xml"/> <clover outputFile="build/logs/clover.xml"/>
<html outputDirectory="build/logs/html"/> <html outputDirectory="build/logs/html"/>
@ -18,6 +31,15 @@
<testdoxText outputFile="build/logs/testdox.txt"/> <testdoxText outputFile="build/logs/testdox.txt"/>
<junit outputFile="build/logs/logfile.xml"/> <junit outputFile="build/logs/logfile.xml"/>
</logging> </logging>
<source>
<include>
<directory suffix=".php">./app</directory>
</include>
<exclude>
<directory suffix=".php">./app/Views</directory>
<file>./app/Config/Routes.php</file>
</exclude>
</source>
<php> <php>
<server name="app.baseURL" value="http://example.com/"/> <server name="app.baseURL" value="http://example.com/"/>
<!-- Directory containing phpunit.xml --> <!-- Directory containing phpunit.xml -->
@ -35,13 +57,4 @@
<env name="database.tests.DBPrefix" value="tests_"/> <env name="database.tests.DBPrefix" value="tests_"/>
<env name="restapi.enabled" value="true"/> <env name="restapi.enabled" value="true"/>
</php> </php>
<source>
<include>
<directory suffix=".php">./app</directory>
</include>
<exclude>
<directory suffix=".php">./app/Views</directory>
<file>./app/Config/Routes.php</file>
</exclude>
</source>
</phpunit> </phpunit>

File diff suppressed because it is too large Load Diff

View File

@ -51,7 +51,7 @@ class preload
*/ */
private array $paths = [ private array $paths = [
[ [
'include' => __DIR__ . '/vendor/codeigniter4/framework/system', 'include' => __DIR__ . '/vendor/codeigniter4/framework/system', // Change this path if using manual installation
'exclude' => [ 'exclude' => [
// Not needed if you don't use them. // Not needed if you don't use them.
'/system/Database/OCI8/', '/system/Database/OCI8/',

View File

@ -45,5 +45,5 @@ Options -Indexes
</IfModule> </IfModule>
# Disable server signature start # Disable server signature start
ServerSignature Off ServerSignature Off
# Disable server signature end # Disable server signature end

View File

@ -2,11 +2,15 @@
declare(strict_types=1); declare(strict_types=1);
use CodeIgniter\Config\DotEnv; use CodeIgniter\Boot;
use Config\Paths; use Config\Paths;
use Config\Services;
// Check PHP version. /*
*---------------------------------------------------------------
* CHECK PHP VERSION
*---------------------------------------------------------------
*/
$minPhpVersion = '8.1'; // If you update this, don't forget to update `spark`. $minPhpVersion = '8.1'; // If you update this, don't forget to update `spark`.
if (version_compare(PHP_VERSION, $minPhpVersion, '<')) { if (version_compare(PHP_VERSION, $minPhpVersion, '<')) {
$message = sprintf( $message = sprintf(
@ -15,9 +19,18 @@ if (version_compare(PHP_VERSION, $minPhpVersion, '<')) {
PHP_VERSION PHP_VERSION
); );
exit($message); header('HTTP/1.1 503 Service Unavailable.', true, 503);
echo $message;
exit(1);
} }
/*
*---------------------------------------------------------------
* SET THE CURRENT DIRECTORY
*---------------------------------------------------------------
*/
// Path to the front controller (this file) // Path to the front controller (this file)
define('FCPATH', __DIR__ . DIRECTORY_SEPARATOR); define('FCPATH', __DIR__ . DIRECTORY_SEPARATOR);
@ -35,59 +48,14 @@ if (getcwd() . DIRECTORY_SEPARATOR !== FCPATH) {
* and fires up an environment-specific bootstrapping. * and fires up an environment-specific bootstrapping.
*/ */
// Load our paths config file // LOAD OUR PATHS CONFIG FILE
// This is the line that might need to be changed, depending on your folder structure. // This is the line that might need to be changed, depending on your folder structure.
require FCPATH . '../app/Config/Paths.php'; require FCPATH . '../app/Config/Paths.php';
// ^^^ Change this line if you move your application folder // ^^^ Change this line if you move your application folder
$paths = new Paths(); $paths = new Paths();
// Location of the framework bootstrap file. // LOAD THE FRAMEWORK BOOTSTRAP FILE
require rtrim($paths->systemDirectory, '\\/ ') . DIRECTORY_SEPARATOR . 'bootstrap.php'; require $paths->systemDirectory . '/Boot.php';
// Load environment settings from .env files into $_SERVER and $_ENV exit(Boot::bootWeb($paths));
require_once SYSTEMPATH . 'Config/DotEnv.php';
(new DotEnv(ROOTPATH))->load();
// Define ENVIRONMENT
if (! defined('ENVIRONMENT')) {
define('ENVIRONMENT', env('CI_ENVIRONMENT', 'production'));
}
// Load Config Cache
// $factoriesCache = new \CodeIgniter\Cache\FactoriesCache();
// $factoriesCache->load('config');
// ^^^ Uncomment these lines if you want to use Config Caching.
/*
* ---------------------------------------------------------------
* GRAB OUR CODEIGNITER INSTANCE
* ---------------------------------------------------------------
*
* The CodeIgniter class contains the core functionality to make
* the application run, and does all the dirty work to get
* the pieces all working together.
*/
$app = Services::codeigniter();
$app->initialize();
$context = is_cli() ? 'php-cli' : 'web';
$app->setContext($context);
/*
*---------------------------------------------------------------
* LAUNCH THE APPLICATION
*---------------------------------------------------------------
* Now that everything is set up, it's time to actually fire
* up the engines and make this app do its thang.
*/
$app->run();
// Save Config Cache
// $factoriesCache->save('config');
// ^^^ Uncomment this line if you want to use Config Caching.
// Exits the application, setting the exit code for CLI-based applications
// that might be watching.
exit(EXIT_SUCCESS);

62
spark
View File

@ -12,13 +12,16 @@
/* /*
* -------------------------------------------------------------------- * --------------------------------------------------------------------
* CodeIgniter command-line tools * CODEIGNITER COMMAND-LINE TOOLS
* -------------------------------------------------------------------- * --------------------------------------------------------------------
* The main entry point into the CLI system and allows you to run * The main entry point into the CLI system and allows you to run
* commands and perform maintenance on your application. * commands and perform maintenance on your application.
* */
* Because CodeIgniter can handle CLI requests as just another web request
* this class mainly acts as a passthru to the framework itself. /*
*---------------------------------------------------------------
* CHECK SERVER API
*---------------------------------------------------------------
*/ */
// Refuse to run when called from php-cgi // Refuse to run when called from php-cgi
@ -26,7 +29,12 @@ if (strpos(PHP_SAPI, 'cgi') === 0) {
exit("The cli tool is not supported when running php-cgi. It needs php-cli to function!\n\n"); exit("The cli tool is not supported when running php-cgi. It needs php-cli to function!\n\n");
} }
// Check PHP version. /*
*---------------------------------------------------------------
* CHECK PHP VERSION
*---------------------------------------------------------------
*/
$minPhpVersion = '8.1'; // If you update this, don't forget to update `public/index.php`. $minPhpVersion = '8.1'; // If you update this, don't forget to update `public/index.php`.
if (version_compare(PHP_VERSION, $minPhpVersion, '<')) { if (version_compare(PHP_VERSION, $minPhpVersion, '<')) {
$message = sprintf( $message = sprintf(
@ -42,12 +50,11 @@ if (version_compare(PHP_VERSION, $minPhpVersion, '<')) {
error_reporting(E_ALL); error_reporting(E_ALL);
ini_set('display_errors', '1'); ini_set('display_errors', '1');
/** /*
* @var bool *---------------------------------------------------------------
* * SET THE CURRENT DIRECTORY
* @deprecated No longer in use. `CodeIgniter` has `$context` property. *---------------------------------------------------------------
*/ */
define('SPARKED', true);
// Path to the front controller // Path to the front controller
define('FCPATH', __DIR__ . DIRECTORY_SEPARATOR . 'public' . DIRECTORY_SEPARATOR); define('FCPATH', __DIR__ . DIRECTORY_SEPARATOR . 'public' . DIRECTORY_SEPARATOR);
@ -64,41 +71,14 @@ chdir(FCPATH);
* and fires up an environment-specific bootstrapping. * and fires up an environment-specific bootstrapping.
*/ */
// Load our paths config file // LOAD OUR PATHS CONFIG FILE
// This is the line that might need to be changed, depending on your folder structure. // This is the line that might need to be changed, depending on your folder structure.
require FCPATH . '../app/Config/Paths.php'; require FCPATH . '../app/Config/Paths.php';
// ^^^ Change this line if you move your application folder // ^^^ Change this line if you move your application folder
$paths = new Config\Paths(); $paths = new Config\Paths();
// Location of the framework bootstrap file. // LOAD THE FRAMEWORK BOOTSTRAP FILE
require rtrim($paths->systemDirectory, '\\/ ') . DIRECTORY_SEPARATOR . 'bootstrap.php'; require $paths->systemDirectory . '/Boot.php';
// Load environment settings from .env files into $_SERVER and $_ENV exit(CodeIgniter\Boot::bootSpark($paths));
require_once SYSTEMPATH . 'Config/DotEnv.php';
(new CodeIgniter\Config\DotEnv(ROOTPATH))->load();
// Define ENVIRONMENT
if (! defined('ENVIRONMENT')) {
define('ENVIRONMENT', env('CI_ENVIRONMENT', 'production'));
}
// Grab our CodeIgniter
$app = Config\Services::codeigniter();
$app->initialize();
// Grab our Console
$console = new CodeIgniter\CLI\Console();
// Show basic information before we do anything else.
if (is_int($suppress = array_search('--no-header', $_SERVER['argv'], true))) {
unset($_SERVER['argv'][$suppress]); // @codeCoverageIgnore
$suppress = true;
}
$console->showHeader($suppress);
// fire off the command in the main framework.
$exit = $console->run();
exit(is_int($exit) ? $exit : EXIT_SUCCESS);

6
tests/.htaccess Normal file
View File

@ -0,0 +1,6 @@
<IfModule authz_core_module>
Require all denied
</IfModule>
<IfModule !authz_core_module>
Deny from all
</IfModule>

View File

@ -29,7 +29,7 @@ class ExampleModel extends Model
protected $useSoftDeletes = false; protected $useSoftDeletes = false;
/** /**
* @var string[] * @var list<string>
*/ */
protected $allowedFields = ['name', 'uid', 'class', 'icon', 'summary']; protected $allowedFields = ['name', 'uid', 'class', 'icon', 'summary'];
@ -39,12 +39,12 @@ class ExampleModel extends Model
protected $useTimestamps = true; protected $useTimestamps = true;
/** /**
* @var mixed[] * @var array<string, array<string, array<string, string>|string>|string>|string
*/ */
protected $validationRules = []; protected $validationRules = [];
/** /**
* @var mixed[] * @var array<string, array<string, string>>
*/ */
protected $validationMessages = []; protected $validationMessages = [];

View File

@ -4,6 +4,7 @@ declare(strict_types=1);
namespace Tests\Database; namespace Tests\Database;
use CodeIgniter\Database\Seeder;
use CodeIgniter\Test\CIUnitTestCase; use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\DatabaseTestTrait; use CodeIgniter\Test\DatabaseTestTrait;
use Tests\Support\Database\Seeds\ExampleSeeder; use Tests\Support\Database\Seeds\ExampleSeeder;
@ -14,7 +15,7 @@ class ExampleDatabaseTest extends CIUnitTestCase
use DatabaseTestTrait; use DatabaseTestTrait;
/** /**
* @var string * @var class-string<Seeder>|list<class-string<Seeder>>
*/ */
protected $seed = ExampleSeeder::class; protected $seed = ExampleSeeder::class;

9
tests/index.html Normal file
View File

@ -0,0 +1,9 @@
<!doctype html>
<html>
<head>
<title>403 Forbidden</title>
</head>
<body>
<p>Directory access is forbidden.</p>
</body>
</html>

View File

@ -5,6 +5,7 @@ declare(strict_types=1);
namespace modules\Api\Rest\V1; namespace modules\Api\Rest\V1;
use App\Database\Seeds\FakeSinglePodcastApiSeeder; use App\Database\Seeds\FakeSinglePodcastApiSeeder;
use CodeIgniter\Database\Seeder;
use CodeIgniter\Test\CIUnitTestCase; use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\DatabaseTestTrait; use CodeIgniter\Test\DatabaseTestTrait;
use CodeIgniter\Test\FeatureTestTrait; use CodeIgniter\Test\FeatureTestTrait;
@ -31,9 +32,9 @@ class EpisodeTest extends CIUnitTestCase
protected $namespace; protected $namespace;
/** /**
* @var string * @var class-string<Seeder>|list<class-string<Seeder>>
*/ */
protected $seed = 'FakeSinglePodcastApiSeeder'; protected $seed = FakeSinglePodcastApiSeeder::class;
/** /**
* @var string * @var string

View File

@ -5,6 +5,7 @@ declare(strict_types=1);
namespace modules\Api\Rest\V1; namespace modules\Api\Rest\V1;
use App\Database\Seeds\FakeSinglePodcastApiSeeder; use App\Database\Seeds\FakeSinglePodcastApiSeeder;
use CodeIgniter\Database\Seeder;
use CodeIgniter\Test\CIUnitTestCase; use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\DatabaseTestTrait; use CodeIgniter\Test\DatabaseTestTrait;
use CodeIgniter\Test\FeatureTestTrait; use CodeIgniter\Test\FeatureTestTrait;
@ -31,9 +32,9 @@ class PodcastTest extends CIUnitTestCase
protected $namespace; protected $namespace;
/** /**
* @var string * @var class-string<Seeder>|list<class-string<Seeder>>
*/ */
protected $seed = 'FakeSinglePodcastApiSeeder'; protected $seed = FakeSinglePodcastApiSeeder::class;
/** /**
* @var string * @var string

View File

@ -1,6 +1,6 @@
<IfModule authz_core_module> <IfModule authz_core_module>
Require all denied Require all denied
</IfModule> </IfModule>
<IfModule !authz_core_module> <IfModule !authz_core_module>
Deny from all Deny from all
</IfModule> </IfModule>

9
writable/index.html Normal file
View File

@ -0,0 +1,9 @@
<!doctype html>
<html>
<head>
<title>403 Forbidden</title>
</head>
<body>
<p>Directory access is forbidden.</p>
</body>
</html>