diff --git a/app/Config/App.php b/app/Config/App.php index 70c2bca24..04768f508 100644 --- a/app/Config/App.php +++ b/app/Config/App.php @@ -49,70 +49,74 @@ class App extends BaseConfig * and path to your installation. However, you should always configure this * explicitly and never rely on auto-guessing, especially in production * environments. - * - * @var string */ - public $baseURL; //Defined in the constructor + public string $baseURL; //Defined in the constructor - /** - * -------------------------------------------------------------------------- - * Index File - * -------------------------------------------------------------------------- - * - * Typically this will be your index.php file, unless you've renamed it to - * something else. If you are using mod_rewrite to remove the page set this - * variable so that it is blank. - * - * @var string - */ - public $indexPage = ''; + /** + * Allowed Hostnames in the Site URL other than the hostname in the baseURL. + * If you want to accept multiple Hostnames, set this. + * + * E.g. When your site URL ($baseURL) is 'http://example.com/', and your site + * also accepts 'http://media.example.com/' and + * 'http://accounts.example.com/': + * ['media.example.com', 'accounts.example.com'] + * + * @var string[] + * @phpstan-var list + */ + public array $allowedHostnames = []; - /** - * -------------------------------------------------------------------------- - * URI PROTOCOL - * -------------------------------------------------------------------------- - * - * This item determines which getServer global should be used to retrieve the - * URI string. The default setting of 'REQUEST_URI' works for most servers. - * If your links do not seem to work, try one of the other delicious flavors: - * - * 'REQUEST_URI' Uses $_SERVER['REQUEST_URI'] - * 'QUERY_STRING' Uses $_SERVER['QUERY_STRING'] - * 'PATH_INFO' Uses $_SERVER['PATH_INFO'] - * - * WARNING: If you set this to 'PATH_INFO', URIs will always be URL-decoded! - * - * @var string - */ - public $uriProtocol = 'REQUEST_URI'; + /** + * -------------------------------------------------------------------------- + * Index File + * -------------------------------------------------------------------------- + * + * Typically this will be your index.php file, unless you've renamed it to + * something else. If you are using mod_rewrite to remove the page set this + * variable so that it is blank. + */ + public string $indexPage = ''; - /** - * -------------------------------------------------------------------------- - * Default Locale - * -------------------------------------------------------------------------- - * - * The Locale roughly represents the language and location that your visitor - * is viewing the site from. It affects the language strings and other - * strings (like currency markers, numbers, etc), that your program - * should run under for this request. - * - * @var string - */ - public $defaultLocale = 'en-US'; + /** + * -------------------------------------------------------------------------- + * URI PROTOCOL + * -------------------------------------------------------------------------- + * + * This item determines which server global should be used to retrieve the + * URI string. The default setting of 'REQUEST_URI' works for most servers. + * If your links do not seem to work, try one of the other delicious flavors: + * + * 'REQUEST_URI' Uses $_SERVER['REQUEST_URI'] + * 'QUERY_STRING' Uses $_SERVER['QUERY_STRING'] + * 'PATH_INFO' Uses $_SERVER['PATH_INFO'] + * + * WARNING: If you set this to 'PATH_INFO', URIs will always be URL-decoded! + */ + public string $uriProtocol = 'REQUEST_URI'; - /** - * -------------------------------------------------------------------------- - * Negotiate Locale - * -------------------------------------------------------------------------- - * - * If true, the current Request object will automatically determine the - * language to use based on the value of the Accept-Language header. - * - * If false, no automatic detection will be performed. - * - * @var bool - */ - public $negotiateLocale = true; + /** + * -------------------------------------------------------------------------- + * Default Locale + * -------------------------------------------------------------------------- + * + * The Locale roughly represents the language and location that your visitor + * is viewing the site from. It affects the language strings and other + * strings (like currency markers, numbers, etc), that your program + * should run under for this request. + */ + public string $defaultLocale = 'en-US'; + + /** + * -------------------------------------------------------------------------- + * Negotiate Locale + * -------------------------------------------------------------------------- + * + * If true, the current Request object will automatically determine the + * language to use based on the value of the Accept-Language header. + * + * If false, no automatic detection will be performed. + */ + public bool $negotiateLocale = true; /** * -------------------------------------------------------------------------- @@ -125,7 +129,7 @@ class App extends BaseConfig * * @var string[] */ - public $supportedLocales = [ + public array $supportedLocales = [ 'ar-EG', 'ar-LB', 'az-AZ', @@ -176,109 +180,103 @@ class App extends BaseConfig * * The default timezone that will be used in your application to display * dates with the date helper, and can be retrieved through app_timezone() - * - * @var string */ - public $appTimezone = 'America/Chicago'; + public string $appTimezone = 'UTC'; - /** - * -------------------------------------------------------------------------- - * Default Character Set - * -------------------------------------------------------------------------- - * - * This determines which character set is used by default in various methods - * that require a character set to be provided. - * - * @see http://php.net/htmlspecialchars for a list of supported charsets. - * - * @var string - */ - public $charset = 'UTF-8'; + /** + * -------------------------------------------------------------------------- + * Default Character Set + * -------------------------------------------------------------------------- + * + * This determines which character set is used by default in various methods + * that require a character set to be provided. + * + * @see http://php.net/htmlspecialchars for a list of supported charsets. + */ + public string $charset = 'UTF-8'; - /** - * -------------------------------------------------------------------------- - * URI PROTOCOL - * -------------------------------------------------------------------------- - * - * If true, this will force every request made to this application to be - * made via a secure connection (HTTPS). If the incoming request is not - * secure, the user will be redirected to a secure version of the page - * and the HTTP Strict Transport Security header will be set. - * - * @var bool - */ - public $forceGlobalSecureRequests = true; + /** + * -------------------------------------------------------------------------- + * URI PROTOCOL + * -------------------------------------------------------------------------- + * + * If true, this will force every request made to this application to be + * made via a secure connection (HTTPS). If the incoming request is not + * secure, the user will be redirected to a secure version of the page + * and the HTTP Strict Transport Security header will be set. + */ + public bool $forceGlobalSecureRequests = false; - /** - * -------------------------------------------------------------------------- - * Session Driver - * -------------------------------------------------------------------------- - * - * The session storage driver to use: - * - `CodeIgniter\Session\Handlers\FileHandler` - * - `CodeIgniter\Session\Handlers\DatabaseHandler` - * - `CodeIgniter\Session\Handlers\MemcachedHandler` - * - `CodeIgniter\Session\Handlers\RedisHandler` - * - * @var string - */ - public $sessionDriver = DatabaseHandler::class; + /** + * -------------------------------------------------------------------------- + * Session Driver + * -------------------------------------------------------------------------- + * + * The session storage driver to use: + * - `CodeIgniter\Session\Handlers\FileHandler` + * - `CodeIgniter\Session\Handlers\DatabaseHandler` + * - `CodeIgniter\Session\Handlers\MemcachedHandler` + * - `CodeIgniter\Session\Handlers\RedisHandler` + * + * @deprecated use Config\Session::$driver instead. + */ + public string $sessionDriver = DatabaseHandler::class; - /** - * -------------------------------------------------------------------------- - * Session Cookie Name - * -------------------------------------------------------------------------- - * - * The session cookie name, must contain only [0-9a-z_-] characters - * - * @var string - */ - public $sessionCookieName = 'ospos_session'; + /** + * -------------------------------------------------------------------------- + * Session Cookie Name + * -------------------------------------------------------------------------- + * + * The session cookie name, must contain only [0-9a-z_-] characters + * + * @deprecated use Config\Session::$cookieName instead. + */ + public string $sessionCookieName = 'ospos_session'; - /** - * -------------------------------------------------------------------------- - * Session Expiration - * -------------------------------------------------------------------------- - * - * The number of SECONDS you want the session to last. - * Setting to 0 (zero) means expire when the browser is closed. - * - * @var int - */ - public $sessionExpiration = 7200; + /** + * -------------------------------------------------------------------------- + * Session Expiration + * -------------------------------------------------------------------------- + * + * The number of SECONDS you want the session to last. + * Setting to 0 (zero) means expire when the browser is closed. + * + * @deprecated use Config\Session::$expiration instead. + */ + public int $sessionExpiration = 7200; - /** - * -------------------------------------------------------------------------- - * Session Save Path - * -------------------------------------------------------------------------- - * - * The location to save sessions to and is driver dependent. - * - * For the 'files' driver, it's a path to a writable directory. - * WARNING: Only absolute paths are supported! - * - * For the 'database' driver, it's a table name. - * Please read up the manual for the format with other session drivers. - * - * IMPORTANT: You are REQUIRED to set a valid save path! - * - * @var string - */ - public $sessionSavePath = 'sessions'; + /** + * -------------------------------------------------------------------------- + * Session Save Path + * -------------------------------------------------------------------------- + * + * The location to save sessions to and is driver dependent. + * + * For the 'files' driver, it's a path to a writable directory. + * WARNING: Only absolute paths are supported! + * + * For the 'database' driver, it's a table name. + * Please read up the manual for the format with other session drivers. + * + * IMPORTANT: You are REQUIRED to set a valid save path! + * + * @deprecated use Config\Session::$savePath instead. + */ + public string $sessionSavePath = 'sessions'; - /** - * -------------------------------------------------------------------------- - * Session Match IP - * -------------------------------------------------------------------------- - * - * Whether to match the user's IP address when reading the session data. - * - * WARNING: If you're using the database driver, don't forget to update - * your session table's PRIMARY KEY when changing this setting. - * - * @var bool - */ - public $sessionMatchIP = true; + /** + * -------------------------------------------------------------------------- + * Session Match IP + * -------------------------------------------------------------------------- + * + * Whether to match the user's IP address when reading the session data. + * + * WARNING: If you're using the database driver, don't forget to update + * your session table's PRIMARY KEY when changing this setting. + * + * @deprecated use Config\Session::$matchIP instead. + */ + public bool $sessionMatchIP = true; /** * -------------------------------------------------------------------------- @@ -287,9 +285,9 @@ class App extends BaseConfig * * How many seconds between CI regenerating the session ID. * - * @var int + * @deprecated use Config\Session::$timeToUpdate instead. */ - public $sessionTimeToUpdate = 300; + public int $sessionTimeToUpdate = 300; /** * -------------------------------------------------------------------------- @@ -300,9 +298,20 @@ class App extends BaseConfig * when auto-regenerating the session ID. When set to FALSE, the data * will be later deleted by the garbage collector. * - * @var bool + * @deprecated use Config\Session::$regenerateDestroy instead. */ - public $sessionRegenerateDestroy = false; + public bool $sessionRegenerateDestroy = false; + + /** + * -------------------------------------------------------------------------- + * Session Database Group + * -------------------------------------------------------------------------- + * + * DB Group for the database session. + * + * @deprecated use Config\Session::$DBGroup instead. + */ + public ?string $sessionDBGroup = null; /** * -------------------------------------------------------------------------- @@ -311,11 +320,9 @@ class App extends BaseConfig * * Set a cookie name prefix if you need to avoid collisions. * - * @var string - * * @deprecated use Config\Cookie::$prefix property instead. */ - public $cookiePrefix; + public string $cookiePrefix = ''; /** * -------------------------------------------------------------------------- @@ -324,11 +331,9 @@ class App extends BaseConfig * * Set to `.your-domain.com` for site-wide cookies. * - * @var string - * * @deprecated use Config\Cookie::$domain property instead. */ - public $cookieDomain; + public string $cookieDomain = ''; /** * -------------------------------------------------------------------------- @@ -337,11 +342,9 @@ class App extends BaseConfig * * Typically will be a forward slash. * - * @var string - * * @deprecated use Config\Cookie::$path property instead. */ - public $cookiePath; + public string $cookiePath = '/'; /** * -------------------------------------------------------------------------- @@ -350,11 +353,9 @@ class App extends BaseConfig * * Cookie will only be set if a secure HTTPS connection exists. * - * @var bool - * * @deprecated use Config\Cookie::$secure property instead. */ - public $cookieSecure; + public bool $cookieSecure = false; /** * -------------------------------------------------------------------------- @@ -363,11 +364,9 @@ class App extends BaseConfig * * Cookie will only be accessible via HTTP(S) (no JavaScript). * - * @var bool - * * @deprecated use Config\Cookie::$httponly property instead. */ - public $cookieHTTPOnly; + public bool $cookieHTTPOnly = true; /** * -------------------------------------------------------------------------- @@ -389,11 +388,9 @@ class App extends BaseConfig * (empty string) means default SameSite attribute set by browsers (`Lax`) * will be set on cookies. If set to `None`, `$cookieSecure` must also be set. * - * @var string|null - * * @deprecated use Config\Cookie::$samesite property instead. */ - public $cookieSameSite = 'Lax'; + public ?string $cookieSameSite = 'Lax'; /** * -------------------------------------------------------------------------- @@ -402,18 +399,21 @@ class App extends BaseConfig * * If your server is behind a reverse proxy, you must whitelist the proxy * IP addresses from which CodeIgniter should trust headers such as - * HTTP_X_FORWARDED_FOR and HTTP_CLIENT_IP in order to properly identify + * X-Forwarded-For or Client-IP in order to properly identify * the visitor's IP address. * - * You can use both an array or a comma-separated list of proxy addresses, - * as well as specifying whole subnets. Here are a few examples: + * You need to set a proxy IP address or IP address with subnets and + * the HTTP header for the client IP address. * - * Comma-separated: '10.0.1.200,192.168.5.0/24' - * Array: ['10.0.1.200', '192.168.5.0/24'] + * Here are some examples: + * [ + * '10.0.1.200' => 'X-Forwarded-For', + * '192.168.5.0/24' => 'X-Real-IP', + * ] * - * @var string|string[] + * @var array */ - public $proxyIPs = ''; + public array $proxyIPs = []; /** * -------------------------------------------------------------------------- @@ -423,10 +423,8 @@ class App extends BaseConfig * The token name. * * @deprecated Use `Config\Security` $tokenName property instead of using this property. - * - * @var string */ - public $CSRFTokenName; + public string $CSRFTokenName = 'csrf_ospos_v4'; /** * -------------------------------------------------------------------------- @@ -436,10 +434,8 @@ class App extends BaseConfig * The header name. * * @deprecated Use `Config\Security` $headerName property instead of using this property. - * - * @var string */ - public $CSRFHeaderName = 'X-CSRF-TOKEN'; + public string $CSRFHeaderName = 'X-CSRF-TOKEN'; /** * -------------------------------------------------------------------------- @@ -449,10 +445,8 @@ class App extends BaseConfig * The cookie name. * * @deprecated Use `Config\Security` $cookieName property instead of using this property. - * - * @var string */ - public $CSRFCookieName; + public string $CSRFCookieName = 'csrf_cookie_ospos_v4'; /** * -------------------------------------------------------------------------- @@ -462,10 +456,8 @@ class App extends BaseConfig * The number in seconds the token should expire. * * @deprecated Use `Config\Security` $expire property instead of using this property. - * - * @var int */ - public $CSRFExpire; + public int $CSRFExpire = 7200; /** * -------------------------------------------------------------------------- @@ -475,10 +467,8 @@ class App extends BaseConfig * Regenerate token on every submission? * * @deprecated Use `Config\Security` $regenerate property instead of using this property. - * - * @var bool */ - public $CSRFRegenerate; + public bool $CSRFRegenerate = true; /** * -------------------------------------------------------------------------- @@ -488,10 +478,8 @@ class App extends BaseConfig * Redirect to previous page with error on failure? * * @deprecated Use `Config\Security` $redirect property instead of using this property. - * - * @var bool */ - public $CSRFRedirect; + public bool $CSRFRedirect = false; /** * -------------------------------------------------------------------------- @@ -509,10 +497,8 @@ class App extends BaseConfig * @see https://portswigger.net/web-security/csrf/samesite-cookies * * @deprecated `Config\Cookie` $samesite property is used. - * - * @var string */ - public $CSRFSameSite; + public string $CSRFSameSite = 'Lax'; /** * -------------------------------------------------------------------------- @@ -529,10 +515,8 @@ class App extends BaseConfig * * @see http://www.html5rocks.com/en/tutorials/security/content-security-policy/ * @see http://www.w3.org/TR/CSP/ - * - * @var bool */ - public $CSPEnabled = false; //TODO: We need to enable this either as part of 3.4.0 release or shortly after. It will be an undertaking to whitelist everything, but it's imperative to block XSS attacks + public bool $CSPEnabled = false; //TODO: We need to enable this either as part of 3.4.0 release or shortly after. It will be an undertaking to whitelist everything, but it's imperative to block XSS attacks public function __construct() { diff --git a/app/Config/Autoload.php b/app/Config/Autoload.php index 9c009b568..d329f9d05 100644 --- a/app/Config/Autoload.php +++ b/app/Config/Autoload.php @@ -31,14 +31,13 @@ class Autoload extends AutoloadConfig * else you will need to modify all of those classes for this to work. * * Prototype: - *``` * $psr4 = [ * 'CodeIgniter' => SYSTEMPATH, - * 'App' => APPPATH + * 'App' => APPPATH * ]; - *``` * - * @var array + * @var array|string> + * @phpstan-var array> */ public $psr4 = [ APP_NAMESPACE => APPPATH, // For custom app namespace @@ -57,11 +56,9 @@ class Autoload extends AutoloadConfig * were being autoloaded through a namespace. * * Prototype: - *``` * $classmap = [ * 'MyClass' => '/path/to/class/file.php' * ]; - *``` * * @var array */ @@ -184,13 +181,26 @@ class Autoload extends AutoloadConfig * or for loading functions. * * Prototype: - * ``` - * $files = [ - * '/path/to/my/file.php', - * ]; - * ``` + * $files = [ + * '/path/to/my/file.php', + * ]; * - * @var array + * @var string[] + * @phpstan-var list */ public $files = []; + + /** + * ------------------------------------------------------------------- + * Helpers + * ------------------------------------------------------------------- + * Prototype: + * $helpers = [ + * 'form', + * ]; + * + * @var string[] + * @phpstan-var list + */ + public $helpers = []; } diff --git a/app/Config/CURLRequest.php b/app/Config/CURLRequest.php index b4c8e5c4f..6c3ed74aa 100644 --- a/app/Config/CURLRequest.php +++ b/app/Config/CURLRequest.php @@ -15,8 +15,6 @@ class CURLRequest extends BaseConfig * * If true, all the options won't be reset between requests. * It may cause an error request with unnecessary headers. - * - * @var bool */ - public $shareOptions = true; + public bool $shareOptions = true; } diff --git a/app/Config/Cache.php b/app/Config/Cache.php index 2d1fea90c..659d9ed6a 100644 --- a/app/Config/Cache.php +++ b/app/Config/Cache.php @@ -19,10 +19,8 @@ class Cache extends BaseConfig * * The name of the preferred handler that should be used. If for some reason * it is not available, the $backupHandler will be used in its place. - * - * @var string */ - public $handler = 'file'; + public string $handler = 'file'; /** * -------------------------------------------------------------------------- @@ -32,10 +30,8 @@ class Cache extends BaseConfig * The name of the handler that will be used in case the first one is * unreachable. Often, 'file' is used here since the filesystem is * always available, though that's not always practical for the app. - * - * @var string */ - public $backupHandler = 'dummy'; + public string $backupHandler = 'dummy'; /** * -------------------------------------------------------------------------- @@ -45,11 +41,9 @@ class Cache extends BaseConfig * The path to where cache files should be stored, if using a file-based * system. * - * @var string - * * @deprecated Use the driver-specific variant under $file */ - public $storePath = WRITEPATH . 'cache/'; + public string $storePath = WRITEPATH . 'cache/'; /** * -------------------------------------------------------------------------- @@ -77,10 +71,8 @@ class Cache extends BaseConfig * * This string is added to all cache item names to help avoid collisions * if you run multiple applications with the same cache engine. - * - * @var string */ - public $prefix = ''; + public string $prefix = ''; /** * -------------------------------------------------------------------------- @@ -92,10 +84,8 @@ class Cache extends BaseConfig * WARNING: This is not used by framework handlers where 60 seconds is * hard-coded, but may be useful to projects and modules. This will replace * the hard-coded value in a future release. - * - * @var int */ - public $ttl = 60; + public int $ttl = 60; /** * -------------------------------------------------------------------------- @@ -106,10 +96,8 @@ class Cache extends BaseConfig * Strings that violate this restriction will cause handlers to throw. * Default: {}()/\@: * Note: The default set is required for PSR-6 compliance. - * - * @var string */ - public $reservedCharacters = '{}()/\@:'; + public string $reservedCharacters = '{}()/\@:'; /** * -------------------------------------------------------------------------- @@ -120,7 +108,7 @@ class Cache extends BaseConfig * * @var array */ - public $file = [ + public array $file = [ 'storePath' => WRITEPATH . 'cache/', 'mode' => 0640, ]; @@ -134,9 +122,9 @@ class Cache extends BaseConfig * * @see https://codeigniter.com/user_guide/libraries/caching.html#memcached * - * @var array + * @var array */ - public $memcached = [ + public array $memcached = [ 'host' => '127.0.0.1', 'port' => 11211, 'weight' => 1, @@ -152,7 +140,7 @@ class Cache extends BaseConfig * * @var array */ - public $redis = [ + public array $redis = [ 'host' => '127.0.0.1', 'password' => null, 'port' => 6379, @@ -170,7 +158,7 @@ class Cache extends BaseConfig * * @var array */ - public $validHandlers = [ + public array $validHandlers = [ 'dummy' => DummyHandler::class, 'file' => FileHandler::class, 'memcached' => MemcachedHandler::class, diff --git a/app/Config/ContentSecurityPolicy.php b/app/Config/ContentSecurityPolicy.php index 0be616301..18612e15c 100644 --- a/app/Config/ContentSecurityPolicy.php +++ b/app/Config/ContentSecurityPolicy.php @@ -21,27 +21,21 @@ class ContentSecurityPolicy extends BaseConfig /** * Default CSP report context - * - * @var bool */ - public $reportOnly = false; + public bool $reportOnly = false; /** * Specifies a URL where a browser will send reports * when a content security policy is violated. - * - * @var string|null */ - public $reportURI; + public ?string $reportURI = null; /** * Instructs user agents to rewrite URL schemes, changing * HTTP to HTTPS. This directive is for websites with * large numbers of old URLs that need to be rewritten. - * - * @var bool */ - public $upgradeInsecureRequests = false; + public bool $upgradeInsecureRequests = false; // ------------------------------------------------------------------------- // Sources allowed @@ -167,22 +161,16 @@ class ContentSecurityPolicy extends BaseConfig /** * Nonce tag for style - * - * @var string */ - public $styleNonceTag = '{csp-style-nonce}'; + public string $styleNonceTag = '{csp-style-nonce}'; /** * Nonce tag for script - * - * @var string */ - public $scriptNonceTag = '{csp-script-nonce}'; + public string $scriptNonceTag = '{csp-script-nonce}'; /** * Replace nonce tag automatically - * - * @var bool */ - public $autoNonce = true; + public bool $autoNonce = true; } diff --git a/app/Config/Cookie.php b/app/Config/Cookie.php index cac698f26..440af5ee8 100644 --- a/app/Config/Cookie.php +++ b/app/Config/Cookie.php @@ -13,10 +13,8 @@ class Cookie extends BaseConfig * -------------------------------------------------------------------------- * * Set a cookie name prefix if you need to avoid collisions. - * - * @var string */ - public $prefix = ''; + public string $prefix = ''; /** * -------------------------------------------------------------------------- @@ -37,10 +35,8 @@ class Cookie extends BaseConfig * -------------------------------------------------------------------------- * * Typically will be a forward slash. - * - * @var string */ - public $path = '/'; + public string $path = '/'; /** * -------------------------------------------------------------------------- @@ -48,10 +44,8 @@ class Cookie extends BaseConfig * -------------------------------------------------------------------------- * * Set to `.your-domain.com` for site-wide cookies. - * - * @var string */ - public $domain = ''; + public string $domain = ''; /** * -------------------------------------------------------------------------- @@ -59,10 +53,8 @@ class Cookie extends BaseConfig * -------------------------------------------------------------------------- * * Cookie will only be set if a secure HTTPS connection exists. - * - * @var bool */ - public $secure = false; + public bool $secure = false; /** * -------------------------------------------------------------------------- @@ -70,10 +62,8 @@ class Cookie extends BaseConfig * -------------------------------------------------------------------------- * * Cookie will only be accessible via HTTP(S) (no JavaScript). - * - * @var bool */ - public $httponly = true; + public bool $httponly = true; /** * -------------------------------------------------------------------------- @@ -94,10 +84,8 @@ class Cookie extends BaseConfig * Defaults to `Lax` for compatibility with modern browsers. Setting `''` * (empty string) means default SameSite attribute set by browsers (`Lax`) * will be set on cookies. If set to `None`, `$secure` must also be set. - * - * @var string */ - public $samesite = 'Lax'; + public string $samesite = 'Lax'; /** * -------------------------------------------------------------------------- @@ -110,17 +98,8 @@ class Cookie extends BaseConfig * If this is set to `true`, cookie names should be compliant of RFC 2616's * list of allowed characters. * - * @var bool - * * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#attributes * @see https://tools.ietf.org/html/rfc2616#section-2.2 */ - public $raw = false; - - function __construct() - { - parent::__construct(); - $config = config('App'); - $this->secure = $config->https_on; - } + public bool $raw = false; } diff --git a/app/Config/Database.php b/app/Config/Database.php index 1e470c2d8..eb0792a7c 100644 --- a/app/Config/Database.php +++ b/app/Config/Database.php @@ -12,25 +12,19 @@ class Database extends Config /** * The directory that holds the Migrations * and Seeds directories. - * - * @var string */ - public $filesPath = APPPATH . 'Database' . DIRECTORY_SEPARATOR; + public string $filesPath = APPPATH . 'Database' . DIRECTORY_SEPARATOR; /** * Lets you choose which connection group to * use if no other is specified. - * - * @var string */ - public $defaultGroup = 'default'; + public string $defaultGroup = 'default'; /** * The default database connection. - * - * @var array */ - public $default = [ + public array $default = [ 'DSN' => '', 'hostname' => 'localhost', 'username' => 'admin', @@ -50,14 +44,11 @@ class Database extends Config 'port' => 3306 ]; - /** * This database connection is used when * running PHPUnit database tests. - * - * @var array */ - public $tests = [ + public array $tests = [ 'DSN' => '', 'hostname' => 'localhost', 'username' => 'admin', @@ -74,7 +65,9 @@ class Database extends Config 'compress' => false, 'strictOn' => false, 'failover' => [], - 'port' => 3306 + 'port' => 3306, + 'foreignKeys' => true, + 'busyTimeout' => 1000, ]; /** @@ -100,7 +93,9 @@ class Database extends Config 'compress' => false, 'strictOn' => false, 'failover' => [], - 'port' => 3306 + 'port' => 3306, + 'foreignKeys' => true, + 'busyTimeout' => 1000, ]; public function __construct() diff --git a/app/Config/DocTypes.php b/app/Config/DocTypes.php index 6f1669368..788d68fdc 100644 --- a/app/Config/DocTypes.php +++ b/app/Config/DocTypes.php @@ -9,7 +9,7 @@ class DocTypes * * @var array */ - public $list = [ + public array $list = [ 'xhtml11' => '', 'xhtml1-strict' => '', 'xhtml1-trans' => '', @@ -30,4 +30,14 @@ class DocTypes 'xhtml-rdfa-1' => '', 'xhtml-rdfa-2' => '', ]; + + /** + * Whether to remove the solidus (`/`) character for void HTML elements (e.g. ``) + * for HTML5 compatibility. + * + * Set to: + * `true` - to be HTML5 compatible + * `false` - to be XHTML compatible + */ + public bool $html5 = true; } diff --git a/app/Config/Email.php b/app/Config/Email.php index 3a42fbe68..1e2b4956a 100644 --- a/app/Config/Email.php +++ b/app/Config/Email.php @@ -6,165 +6,112 @@ use CodeIgniter\Config\BaseConfig; class Email extends BaseConfig { - /** - * @var string - */ - public $fromEmail; - - /** - * @var string - */ - public $fromName; - - /** - * @var string - */ - public $recipients; + public string $fromEmail = ''; + public string $fromName = ''; + public string $recipients = ''; /** * The "user agent" - * - * @var string */ - public $userAgent = 'CodeIgniter'; + public string $userAgent = 'CodeIgniter'; /** * The mail sending protocol: mail, sendmail, smtp - * - * @var string */ - public $protocol = 'mail'; + public string $protocol = 'mail'; /** * The server path to Sendmail. - * - * @var string */ - public $mailPath = '/usr/sbin/sendmail'; + public string $mailPath = '/usr/sbin/sendmail'; /** * SMTP Server Address - * - * @var string */ - public $SMTPHost; + public string $SMTPHost = ''; /** * SMTP Username - * - * @var string */ - public $SMTPUser; + public string $SMTPUser = ''; /** * SMTP Password - * - * @var string */ - public $SMTPPass; + public string $SMTPPass = ''; /** * SMTP Port - * - * @var int */ - public $SMTPPort = 25; + public int $SMTPPort = 25; /** * SMTP Timeout (in seconds) - * - * @var int */ - public $SMTPTimeout = 5; + public int $SMTPTimeout = 5; /** * Enable persistent SMTP connections - * - * @var bool */ - public $SMTPKeepAlive = false; + public bool $SMTPKeepAlive = false; /** * SMTP Encryption. Either tls or ssl - * - * @var string */ - public $SMTPCrypto = 'tls'; + public string $SMTPCrypto = 'tls'; /** * Enable word-wrap - * - * @var bool */ - public $wordWrap = true; + public bool $wordWrap = true; /** * Character count to wrap at - * - * @var int */ - public $wrapChars = 76; + public int $wrapChars = 76; /** * Type of mail, either 'text' or 'html' - * - * @var string */ - public $mailType = 'text'; + public string $mailType = 'html'; /** * Character set (utf-8, iso-8859-1, etc.) - * - * @var string */ - public $charset = 'UTF-8'; + public string $charset = 'UTF-8'; /** * Whether to validate the email address - * - * @var bool */ - public $validate = false; + public bool $validate = false; /** * Email Priority. 1 = highest. 5 = lowest. 3 = normal - * - * @var int */ - public $priority = 3; + public int $priority = 3; /** * Newline character. (Use ā€œ\r\nā€ to comply with RFC 822) - * - * @var string */ - public $CRLF = "\r\n"; + public string $CRLF = "\r\n"; /** * Newline character. (Use ā€œ\r\nā€ to comply with RFC 822) - * - * @var string */ - public $newline = "\r\n"; + public string $newline = "\r\n"; /** * Enable BCC Batch Mode. - * - * @var bool */ - public $BCCBatchMode = false; + public bool $BCCBatchMode = false; /** * Number of emails in each BCC batch - * - * @var int */ - public $BCCBatchSize = 200; + public int $BCCBatchSize = 200; /** * Enable notify message from server - * - * @var bool */ - public $DSN = false; + public bool $DSN = false; } diff --git a/app/Config/Security.php b/app/Config/Security.php index d71a80f8f..f583e74bd 100644 --- a/app/Config/Security.php +++ b/app/Config/Security.php @@ -94,7 +94,7 @@ class Security extends BaseConfig * * @var bool */ - public $redirect = true; + public $redirect = false; /** * -------------------------------------------------------------------------- diff --git a/app/Config/Session.php b/app/Config/Session.php new file mode 100644 index 000000000..012542f63 --- /dev/null +++ b/app/Config/Session.php @@ -0,0 +1,102 @@ + + */ + public string $driver = DatabaseHandler::class; + + /** + * -------------------------------------------------------------------------- + * Session Cookie Name + * -------------------------------------------------------------------------- + * + * The session cookie name, must contain only [0-9a-z_-] characters + */ + public string $cookieName = 'ospos_session'; + + /** + * -------------------------------------------------------------------------- + * Session Expiration + * -------------------------------------------------------------------------- + * + * The number of SECONDS you want the session to last. + * Setting to 0 (zero) means expire when the browser is closed. + */ + public int $expiration = 7200; + + /** + * -------------------------------------------------------------------------- + * Session Save Path + * -------------------------------------------------------------------------- + * + * The location to save sessions to and is driver dependent. + * + * For the 'files' driver, it's a path to a writable directory. + * WARNING: Only absolute paths are supported! + * + * For the 'database' driver, it's a table name. + * Please read up the manual for the format with other session drivers. + * + * IMPORTANT: You are REQUIRED to set a valid save path! + */ + public string $savePath = 'sessions'; + + /** + * -------------------------------------------------------------------------- + * Session Match IP + * -------------------------------------------------------------------------- + * + * Whether to match the user's IP address when reading the session data. + * + * WARNING: If you're using the database driver, don't forget to update + * your session table's PRIMARY KEY when changing this setting. + */ + public bool $matchIP = true; + + /** + * -------------------------------------------------------------------------- + * Session Time to Update + * -------------------------------------------------------------------------- + * + * How many seconds between CI regenerating the session ID. + */ + public int $timeToUpdate = 300; + + /** + * -------------------------------------------------------------------------- + * Session Regenerate Destroy + * -------------------------------------------------------------------------- + * + * Whether to destroy session data associated with the old session ID + * when auto-regenerating the session ID. When set to FALSE, the data + * will be later deleted by the garbage collector. + */ + public bool $regenerateDestroy = false; + + /** + * -------------------------------------------------------------------------- + * Session Database Group + * -------------------------------------------------------------------------- + * + * DB Group for the database session. + */ + public ?string $DBGroup = null; +} diff --git a/preload.php b/preload.php new file mode 100644 index 000000000..63c781c22 --- /dev/null +++ b/preload.php @@ -0,0 +1,113 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +/* + *--------------------------------------------------------------- + * Sample file for Preloading + *--------------------------------------------------------------- + * See https://www.php.net/manual/en/opcache.preloading.php + * + * How to Use: + * 0. Copy this file to your project root folder. + * 1. Set the $paths property of the preload class below. + * 2. Set opcache.preload in php.ini. + * php.ini: + * opcache.preload=/path/to/preload.php + */ + +// Load the paths config file +require __DIR__ . '/app/Config/Paths.php'; + +// Path to the front controller +define('FCPATH', __DIR__ . DIRECTORY_SEPARATOR . 'public' . DIRECTORY_SEPARATOR); + +/** + * See https://www.php.net/manual/en/function.str-contains.php#126277 + */ +if (! function_exists('str_contains')) { + /** + * Polyfill of str_contains() + */ + function str_contains(string $haystack, string $needle): bool + { + return empty($needle) || strpos($haystack, $needle) !== false; + } +} + +class preload +{ + /** + * @var array Paths to preload. + */ + private array $paths = [ + [ + 'include' => __DIR__ . '/vendor/codeigniter4/framework/system', + 'exclude' => [ + // Not needed if you don't use them. + '/system/Database/OCI8/', + '/system/Database/Postgre/', + '/system/Database/SQLSRV/', + // Not needed. + '/system/Database/Seeder.php', + '/system/Test/', + '/system/Language/', + '/system/CLI/', + '/system/Commands/', + '/system/Publisher/', + '/system/ComposerScripts.php', + '/Views/', + // Errors occur. + '/system/Config/Routes.php', + '/system/ThirdParty/', + ], + ], + ]; + + public function __construct() + { + $this->loadAutoloader(); + } + + private function loadAutoloader() + { + $paths = new Config\Paths(); + require rtrim($paths->systemDirectory, '\\/ ') . DIRECTORY_SEPARATOR . 'bootstrap.php'; + } + + /** + * Load PHP files. + */ + public function load() + { + foreach ($this->paths as $path) { + $directory = new RecursiveDirectoryIterator($path['include']); + $fullTree = new RecursiveIteratorIterator($directory); + $phpFiles = new RegexIterator( + $fullTree, + '/.+((? $file) { + foreach ($path['exclude'] as $exclude) { + if (str_contains($file[0], $exclude)) { + continue 2; + } + } + + require_once $file[0]; + echo 'Loaded: ' . $file[0] . "\n"; + } + } + } +} + +(new preload())->load(); diff --git a/public/.htaccess b/public/.htaccess index 2a2f5fab5..6142a5131 100644 --- a/public/.htaccess +++ b/public/.htaccess @@ -1,6 +1,5 @@ # Disable directory browsing -# For security reasons, Option all cannot be overridden. -Options +ExecCGI +Includes +IncludesNOEXEC +SymLinksIfOwnerMatch -Indexes +Options All -Indexes # ---------------------------------------------------------------------- # Rewrite engine @@ -9,12 +8,13 @@ Options +ExecCGI +Includes +IncludesNOEXEC +SymLinksIfOwnerMatch -Indexes # Turning on the rewrite engine is necessary for the following rules and features. # FollowSymLinks must be enabled for this to work. + Options +SymLinksIfOwnerMatch RewriteEngine On # If you installed CodeIgniter in a subfolder, you will need to # change the following line to match the subfolder you need. # http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewritebase - # RewriteBase "/" + # RewriteBase / # Redirect Trailing Slashes... RewriteCond %{REQUEST_FILENAME} !-d diff --git a/spark b/spark index 49a00aa8a..f2ba3f305 100644 --- a/spark +++ b/spark @@ -81,10 +81,9 @@ require_once SYSTEMPATH . 'Config/DotEnv.php'; // Grab our CodeIgniter $app = Config\Services::codeigniter(); $app->initialize(); -$app->setContext('spark'); // Grab our Console -$console = new CodeIgniter\CLI\Console($app); +$console = new CodeIgniter\CLI\Console(); // Show basic information before we do anything else. if (is_int($suppress = array_search('--no-header', $_SERVER['argv'], true))) { @@ -95,8 +94,6 @@ if (is_int($suppress = array_search('--no-header', $_SERVER['argv'], true))) { $console->showHeader($suppress); // fire off the command in the main framework. -$response = $console->run(); +$exit = $console->run(); -if ($response->getStatusCode() >= 300) { - exit($response->getStatusCode()); -} +exit(is_int($exit) ? $exit : EXIT_SUCCESS); diff --git a/tests/README.md b/tests/README.md new file mode 100644 index 000000000..473d0f8c1 --- /dev/null +++ b/tests/README.md @@ -0,0 +1,122 @@ +# Running Application Tests + +This is the quick-start to CodeIgniter testing. Its intent is to describe what +it takes to set up your application and get it ready to run unit tests. +It is not intended to be a full description of the test features that you can +use to test your application. Those details can be found in the documentation. + +## Resources + +* [CodeIgniter 4 User Guide on Testing](https://codeigniter4.github.io/userguide/testing/index.html) +* [PHPUnit docs](https://phpunit.de/documentation.html) +* [Any tutorials on Unit testing in CI4?](https://forum.codeigniter.com/showthread.php?tid=81830) + +## Requirements + +It is recommended to use the latest version of PHPUnit. At the time of this +writing we are running version 9.x. Support for this has been built into the +**composer.json** file that ships with CodeIgniter and can easily be installed +via [Composer](https://getcomposer.org/) if you don't already have it installed globally. + +```console +> composer install +``` + +If running under macOS or Linux, you can create a symbolic link to make running tests a touch nicer. + +```console +> ln -s ./vendor/bin/phpunit ./phpunit +``` + +You also need to install [XDebug](https://xdebug.org/docs/install) in order +for code coverage to be calculated successfully. After installing `XDebug`, you must add `xdebug.mode=coverage` in the **php.ini** file to enable code coverage. + +## Setting Up + +A number of the tests use a running database. +In order to set up the database edit the details for the `tests` group in +**app/Config/Database.php** or **phpunit.xml**. +Make sure that you provide a database engine that is currently running on your machine. +More details on a test database setup are in the +[Testing Your Database](https://codeigniter4.github.io/userguide/testing/database.html) section of the documentation. + +## Running the tests + +The entire test suite can be run by simply typing one command-line command from the main directory. + +```console +> ./phpunit +``` + +If you are using Windows, use the following command. + +```console +> vendor\bin\phpunit +``` + +You can limit tests to those within a single test directory by specifying the +directory name after phpunit. + +```console +> ./phpunit app/Models +``` + +## Generating Code Coverage + +To generate coverage information, including HTML reports you can view in your browser, +you can use the following command: + +```console +> ./phpunit --colors --coverage-text=tests/coverage.txt --coverage-html=tests/coverage/ -d memory_limit=1024m +``` + +This runs all of the tests again collecting information about how many lines, +functions, and files are tested. It also reports the percentage of the code that is covered by tests. +It is collected in two formats: a simple text file that provides an overview as well +as a comprehensive collection of HTML files that show the status of every line of code in the project. + +The text file can be found at **tests/coverage.txt**. +The HTML files can be viewed by opening **tests/coverage/index.html** in your favorite browser. + +## PHPUnit XML Configuration + +The repository has a ``phpunit.xml.dist`` file in the project root that's used for +PHPUnit configuration. This is used to provide a default configuration if you +do not have your own configuration file in the project root. + +The normal practice would be to copy ``phpunit.xml.dist`` to ``phpunit.xml`` +(which is git ignored), and to tailor it as you see fit. +For instance, you might wish to exclude database tests, or automatically generate +HTML code coverage reports. + +## Test Cases + +Every test needs a *test case*, or class that your tests extend. CodeIgniter 4 +provides a few that you may use directly: +* `CodeIgniter\Test\CIUnitTestCase` - for basic tests with no other service needs +* `CodeIgniter\Test\DatabaseTestTrait` - for tests that need database access + +Most of the time you will want to write your own test cases to hold functions and services +common to your test suites. + +## Creating Tests + +All tests go in the **tests/** directory. Each test file is a class that extends a +**Test Case** (see above) and contains methods for the individual tests. These method +names must start with the word "test" and should have descriptive names for precisely what +they are testing: +`testUserCanModifyFile()` `testOutputColorMatchesInput()` `testIsLoggedInFailsWithInvalidUser()` + +Writing tests is an art, and there are many resources available to help learn how. +Review the links above and always pay attention to your code coverage. + +### Database Tests + +Tests can include migrating, seeding, and testing against a mock or live1 database. +Be sure to modify the test case (or create your own) to point to your seed and migrations +and include any additional steps to be run before tests in the `setUp()` method. + +1 Note: If you are using database tests that require a live database connection +you will need to rename **phpunit.xml.dist** to **phpunit.xml**, uncomment the database +configuration lines and add your connection details. Prevent **phpunit.xml** from being +tracked in your repo by adding it to **.gitignore**. diff --git a/tests/helpers/LocaleHelperTest.php b/tests/helpers/LocaleHelperTest.php deleted file mode 100644 index c84042f17..000000000 --- a/tests/helpers/LocaleHelperTest.php +++ /dev/null @@ -1,24 +0,0 @@ -assertEquals(2.22, $decimals); - } - - public function test_format_decimals() - { - $decimals = to_decimals(5, 2); - - $this->assertEquals(5.00, $decimals); - } -} diff --git a/tests/libraries/TokenLibTest.php b/tests/libraries/TokenLibTest.php deleted file mode 100644 index f6655b058..000000000 --- a/tests/libraries/TokenLibTest.php +++ /dev/null @@ -1,76 +0,0 @@ -appconfig = model('Appconfig'); - $this->token_lib = new Token_lib(); - } - - public function test_token_parser() - { - $tokens = Token::get_barcode_tokens(); - - $parsed_tokens = $this->token_lib->parse("0250200000abc", "02{P:2}{W:6}{I:3}", $tokens); - - $this->assertEquals('abc', $parsed_tokens['I']); - $this->assertEquals('50', $parsed_tokens['P']); - $this->assertEquals('200000', $parsed_tokens['W']); - - } - - public function test_barcode_item_number_and_quantity() - { - $this->appconfig->set('barcode_formats', json_encode (["02{I:5}{W:6}"])); - - $item_number = "0250000123456"; - $quantity = 0; - $this->token_lib->parse_barcode($quantity, $price, $item_number); - - $this->assertEquals(123.456, $quantity); - $this->assertEquals("50000", $item_number); - $this->assertEquals(NULL, $price); - } - - public function test_barcode_quantity_and_item_number() - { - $this->appconfig->set('barcode_formats', json_encode (["02{I:6}{W:5}{P:2}"])); - - $item_number = "021234565000110"; - $quantity = 0; - $this->token_lib->parse_barcode($quantity, $price, $item_number); - - - $this->assertEquals(10, $price); - $this->assertEquals(123456, $item_number); - $this->assertEquals(50.001, $quantity); - } - - public function test_no_barcode_format() - { - $this->appconfig->set('barcode_formats', json_encode ([""])); - - $item_number = "021234565000110"; - $quantity = 0; - - $this->token_lib->parse_barcode($quantity, $price, $item_number); - - $this->assertEquals(1, $quantity); - $this->assertEquals(0, $price); - $this->assertEquals("021234565000110", $item_number); - } -} diff --git a/tests/models/RoundingModeTest.php b/tests/models/RoundingModeTest.php deleted file mode 100644 index 180c45e3d..000000000 --- a/tests/models/RoundingModeTest.php +++ /dev/null @@ -1,37 +0,0 @@ -resetInstance(); - $this->rounding_mode = model('enums/Rounding_mode'); - } - - public function test_rounding() - { - // $this->assertEquals(5.20, Rounding_mode::round_number(Rounding_mode::HALF_FIVE, 5.20, 2)); - $this->assertEquals(5.20, Rounding_mode::round_number(Rounding_mode::HALF_FIVE, 5.20, 2)); - $this->assertEquals(5.20, Rounding_mode::round_number(Rounding_mode::HALF_FIVE, 5.21, 2)); - $this->assertEquals(5.20, Rounding_mode::round_number(Rounding_mode::HALF_FIVE, 5.22, 2)); - $this->assertEquals(5.25, Rounding_mode::round_number(Rounding_mode::HALF_FIVE, 5.23, 2)); - $this->assertEquals(5.25, Rounding_mode::round_number(Rounding_mode::HALF_FIVE, 5.24, 2)); - $this->assertEquals(5.25, Rounding_mode::round_number(Rounding_mode::HALF_FIVE, 5.25, 2)); - $this->assertEquals(5.25, Rounding_mode::round_number(Rounding_mode::HALF_FIVE, 5.26, 2)); - $this->assertEquals(5.25, Rounding_mode::round_number(Rounding_mode::HALF_FIVE, 5.27, 2)); - $this->assertEquals(5.30, Rounding_mode::round_number(Rounding_mode::HALF_FIVE, 5.28, 2)); - $this->assertEquals(5.30, Rounding_mode::round_number(Rounding_mode::HALF_FIVE, 5.29, 2)); - } -} -