From 844616ef291ca07b726c1aaca552e16aadc3ceeb Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 5 Sep 2023 00:46:08 +0000 Subject: [PATCH] Release v4.4.1 --- app/Config/Autoload.php | 2 + app/Config/DocTypes.php | 3 ++ app/Config/Email.php | 6 ++- app/Config/ForeignCharacters.php | 3 ++ app/Config/Mimes.php | 2 + app/Config/Modules.php | 2 + system/CLI/CLI.php | 2 +- system/Cache/Handlers/BaseHandler.php | 3 ++ system/Cache/Handlers/DummyHandler.php | 2 + system/Cache/Handlers/FileHandler.php | 2 + system/Cache/Handlers/MemcachedHandler.php | 2 + system/Cache/Handlers/PredisHandler.php | 2 + system/Cache/Handlers/RedisHandler.php | 2 + system/Cache/Handlers/WincacheHandler.php | 2 + system/CodeIgniter.php | 6 ++- system/Common.php | 14 +++++- system/Config/Factories.php | 50 +++++++++++++++---- system/Config/Services.php | 2 +- system/Database/BaseBuilder.php | 1 - system/Database/Migration.php | 4 -- system/Database/Query.php | 2 - system/Debug/Toolbar.php | 3 -- system/Debug/Toolbar/Views/toolbar.css | 19 +++---- system/Email/Email.php | 10 +++- .../Exceptions/EncryptionException.php | 2 - system/Entity/Entity.php | 2 +- system/Format/Exceptions/FormatException.php | 2 +- system/HTTP/URI.php | 2 - system/HTTP/UserAgent.php | 6 --- system/Images/Handlers/BaseHandler.php | 2 - system/Images/ImageHandlerInterface.php | 2 +- system/Log/Handlers/ChromeLoggerHandler.php | 2 - system/Pager/Pager.php | 2 - system/Router/RouteCollection.php | 47 ++++++++++------- system/Router/RouteCollectionInterface.php | 7 +-- system/Test/DOMParser.php | 5 -- system/Test/FeatureTestCase.php | 2 - system/Test/FeatureTestTrait.php | 11 +++- system/Typography/Typography.php | 5 +- system/Validation/CreditCardRules.php | 2 - system/Validation/FormatRules.php | 10 ---- system/Validation/Rules.php | 4 -- 42 files changed, 156 insertions(+), 105 deletions(-) diff --git a/app/Config/Autoload.php b/app/Config/Autoload.php index e9ee6613..22f05ecd 100644 --- a/app/Config/Autoload.php +++ b/app/Config/Autoload.php @@ -17,6 +17,8 @@ * * NOTE: This class is required prior to Autoloader instantiation, * and does not extend BaseConfig. + * + * @immutable */ class Autoload extends AutoloadConfig { diff --git a/app/Config/DocTypes.php b/app/Config/DocTypes.php index 788d68fd..7e8aaacf 100755 --- a/app/Config/DocTypes.php +++ b/app/Config/DocTypes.php @@ -2,6 +2,9 @@ namespace Config; +/** + * @immutable + */ class DocTypes { /** diff --git a/app/Config/Email.php b/app/Config/Email.php index 01350186..01b805a5 100644 --- a/app/Config/Email.php +++ b/app/Config/Email.php @@ -56,7 +56,11 @@ class Email extends BaseConfig public bool $SMTPKeepAlive = false; /** - * SMTP Encryption. Either tls or ssl + * SMTP Encryption. + * + * @var string '', 'tls' or 'ssl'. 'tls' will issue a STARTTLS command + * to the server. 'ssl' means implicit SSL. Connection on port + * 465 should set this to ''. */ public string $SMTPCrypto = 'tls'; diff --git a/app/Config/ForeignCharacters.php b/app/Config/ForeignCharacters.php index 174ddb16..f1a95725 100644 --- a/app/Config/ForeignCharacters.php +++ b/app/Config/ForeignCharacters.php @@ -4,6 +4,9 @@ use CodeIgniter\Config\ForeignCharacters as BaseForeignCharacters; +/** + * @immutable + */ class ForeignCharacters extends BaseForeignCharacters { } diff --git a/app/Config/Mimes.php b/app/Config/Mimes.php index 99d28e5f..d02df1ab 100644 --- a/app/Config/Mimes.php +++ b/app/Config/Mimes.php @@ -15,6 +15,8 @@ * * When working with mime types, please make sure you have the ´fileinfo´ * extension enabled to reliably detect the media types. + * + * @immutable */ class Mimes { diff --git a/app/Config/Modules.php b/app/Config/Modules.php index 54079e77..f84580c8 100644 --- a/app/Config/Modules.php +++ b/app/Config/Modules.php @@ -9,6 +9,8 @@ * * NOTE: This class is required prior to Autoloader instantiation, * and does not extend BaseConfig. + * + * @immutable */ class Modules extends BaseModules { diff --git a/system/CLI/CLI.php b/system/CLI/CLI.php index 044f9dbb..112a662d 100644 --- a/system/CLI/CLI.php +++ b/system/CLI/CLI.php @@ -177,7 +177,7 @@ public static function init() * Named options must be in the following formats: * php index.php user -v --v -name=John --name=John * - * @param string $prefix + * @param string $prefix You may specify a string with which to prompt the user. */ public static function input(?string $prefix = null): string { diff --git a/system/Cache/Handlers/BaseHandler.php b/system/Cache/Handlers/BaseHandler.php index 9f700370..74a4482c 100644 --- a/system/Cache/Handlers/BaseHandler.php +++ b/system/Cache/Handlers/BaseHandler.php @@ -77,6 +77,7 @@ public static function validateKey($key, $prefix = ''): string * @param string $key Cache item name * @param int $ttl Time to live * @param Closure $callback Callback return value + * @phpstan-param Closure(): mixed $callback * * @return array|bool|float|int|object|string|null */ @@ -98,6 +99,8 @@ public function remember(string $key, int $ttl, Closure $callback) * * @param string $pattern Cache items glob-style pattern * + * @return int|never + * * @throws Exception */ public function deleteMatching(string $pattern) diff --git a/system/Cache/Handlers/DummyHandler.php b/system/Cache/Handlers/DummyHandler.php index fd4f1b50..4349db4f 100644 --- a/system/Cache/Handlers/DummyHandler.php +++ b/system/Cache/Handlers/DummyHandler.php @@ -59,6 +59,8 @@ public function delete(string $key) /** * {@inheritDoc} + * + * @return int */ public function deleteMatching(string $pattern) { diff --git a/system/Cache/Handlers/FileHandler.php b/system/Cache/Handlers/FileHandler.php index 524ee8e4..aea0a605 100644 --- a/system/Cache/Handlers/FileHandler.php +++ b/system/Cache/Handlers/FileHandler.php @@ -127,6 +127,8 @@ public function delete(string $key) /** * {@inheritDoc} + * + * @return int */ public function deleteMatching(string $pattern) { diff --git a/system/Cache/Handlers/MemcachedHandler.php b/system/Cache/Handlers/MemcachedHandler.php index f38a5411..a998ad30 100644 --- a/system/Cache/Handlers/MemcachedHandler.php +++ b/system/Cache/Handlers/MemcachedHandler.php @@ -188,6 +188,8 @@ public function delete(string $key) /** * {@inheritDoc} + * + * @return never */ public function deleteMatching(string $pattern) { diff --git a/system/Cache/Handlers/PredisHandler.php b/system/Cache/Handlers/PredisHandler.php index ab4fb1ff..e549a742 100644 --- a/system/Cache/Handlers/PredisHandler.php +++ b/system/Cache/Handlers/PredisHandler.php @@ -150,6 +150,8 @@ public function delete(string $key) /** * {@inheritDoc} + * + * @return int */ public function deleteMatching(string $pattern) { diff --git a/system/Cache/Handlers/RedisHandler.php b/system/Cache/Handlers/RedisHandler.php index adb9a581..d86d9f98 100644 --- a/system/Cache/Handlers/RedisHandler.php +++ b/system/Cache/Handlers/RedisHandler.php @@ -176,6 +176,8 @@ public function delete(string $key) /** * {@inheritDoc} + * + * @return int */ public function deleteMatching(string $pattern) { diff --git a/system/Cache/Handlers/WincacheHandler.php b/system/Cache/Handlers/WincacheHandler.php index c5f0f084..b1ea45de 100644 --- a/system/Cache/Handlers/WincacheHandler.php +++ b/system/Cache/Handlers/WincacheHandler.php @@ -73,6 +73,8 @@ public function delete(string $key) /** * {@inheritDoc} + * + * @return never */ public function deleteMatching(string $pattern) { diff --git a/system/CodeIgniter.php b/system/CodeIgniter.php index cc6d3f67..6ef3ab82 100644 --- a/system/CodeIgniter.php +++ b/system/CodeIgniter.php @@ -52,7 +52,7 @@ class CodeIgniter /** * The current version of CodeIgniter Framework */ - public const CI_VERSION = '4.4.0'; + public const CI_VERSION = '4.4.1'; /** * App startup time. @@ -468,6 +468,8 @@ protected function handleRequest(?RouteCollectionInterface $routes, Cache $cache // If a ResponseInterface instance is returned then send it back to the client and stop if ($possibleResponse instanceof ResponseInterface) { + $this->outputBufferingEnd(); + return $possibleResponse; } @@ -701,6 +703,8 @@ public function displayCache(Cache $config) * Tells the app that the final output should be cached. * * @deprecated 4.4.0 Moved to ResponseCache::setTtl(). to No longer used. + * + * @return void */ public static function cache(int $time) { diff --git a/system/Common.php b/system/Common.php index ff9ca929..c964e10e 100644 --- a/system/Common.php +++ b/system/Common.php @@ -886,11 +886,21 @@ function redirect(?string $route = null): RedirectResponse /** * Generates the solidus character (`/`) depending on the HTML5 compatibility flag in `Config\DocTypes` * + * @param DocTypes|null $docTypesConfig New config. For testing purpose only. + * * @internal */ - function _solidus(): string + function _solidus(?DocTypes $docTypesConfig = null): string { - if (config(DocTypes::class)->html5 ?? false) { + static $docTypes = null; + + if ($docTypesConfig !== null) { + $docTypes = $docTypesConfig; + } + + $docTypes ??= new DocTypes(); + + if ($docTypes->html5 ?? false) { return ''; } diff --git a/system/Config/Factories.php b/system/Config/Factories.php index 0eb6d244..6db25549 100644 --- a/system/Config/Factories.php +++ b/system/Config/Factories.php @@ -118,6 +118,7 @@ public static function define(string $component, string $alias, string $classnam self::getOptions($component); self::$aliases[$component][$alias] = $classname; + self::$updated[$component] = true; } /** @@ -142,6 +143,7 @@ public static function __callStatic(string $component, array $arguments) return new $class(...$arguments); } + // Try to locate the class if ($class = self::locateClass($options, $alias)) { return new $class(...$arguments); } @@ -160,14 +162,8 @@ public static function __callStatic(string $component, array $arguments) return null; } - self::$instances[$options['component']][$class] = new $class(...$arguments); - self::$aliases[$options['component']][$alias] = $class; - self::$updated[$options['component']] = true; - - // If a short classname is specified, also register FQCN to share the instance. - if (! isset(self::$aliases[$options['component']][$class])) { - self::$aliases[$options['component']][$class] = $class; - } + self::createInstance($options['component'], $class, $arguments); + self::setAlias($options['component'], $alias, $class); return self::$instances[$options['component']][$class]; } @@ -179,6 +175,7 @@ public static function __callStatic(string $component, array $arguments) */ private static function getDefinedInstance(array $options, string $alias, array $arguments) { + // The alias is already defined. if (isset(self::$aliases[$options['component']][$alias])) { $class = self::$aliases[$options['component']][$alias]; @@ -189,15 +186,50 @@ private static function getDefinedInstance(array $options, string $alias, array return self::$instances[$options['component']][$class]; } - self::$instances[$options['component']][$class] = new $class(...$arguments); + self::createInstance($options['component'], $class, $arguments); return self::$instances[$options['component']][$class]; } } + // Try to locate the class + if (! $class = self::locateClass($options, $alias)) { + return null; + } + + // Check for an existing instance for the class + if (isset(self::$instances[$options['component']][$class])) { + self::setAlias($options['component'], $alias, $class); + + return self::$instances[$options['component']][$class]; + } + return null; } + /** + * Creates the shared instance. + */ + private static function createInstance(string $component, string $class, array $arguments): void + { + self::$instances[$component][$class] = new $class(...$arguments); + self::$updated[$component] = true; + } + + /** + * Sets alias + */ + private static function setAlias(string $component, string $alias, string $class): void + { + self::$aliases[$component][$alias] = $class; + self::$updated[$component] = true; + + // If a short classname is specified, also register FQCN to share the instance. + if (! isset(self::$aliases[$component][$class]) && ! self::isNamespaced($alias)) { + self::$aliases[$component][$class] = $class; + } + } + /** * Is the component Config? * diff --git a/system/Config/Services.php b/system/Config/Services.php index 2a4596bf..720bb3c4 100644 --- a/system/Config/Services.php +++ b/system/Config/Services.php @@ -781,7 +781,7 @@ public static function toolbar(?ToolbarConfig $config = null, bool $getShared = /** * The URI class provides a way to model and manipulate URIs. * - * @param string $uri + * @param string|null $uri The URI string * * @return URI The current URI if $uri is null. */ diff --git a/system/Database/BaseBuilder.php b/system/Database/BaseBuilder.php index 07486cff..30202032 100644 --- a/system/Database/BaseBuilder.php +++ b/system/Database/BaseBuilder.php @@ -706,7 +706,6 @@ public function where($key, $value = null, ?bool $escape = null) * * @param array|RawSql|string $key * @param mixed $value - * @param bool $escape * * @return $this */ diff --git a/system/Database/Migration.php b/system/Database/Migration.php index 0f1ab2c7..1616830f 100644 --- a/system/Database/Migration.php +++ b/system/Database/Migration.php @@ -41,8 +41,6 @@ abstract class Migration /** * Constructor. - * - * @param Forge $forge */ public function __construct(?Forge $forge = null) { @@ -53,8 +51,6 @@ public function __construct(?Forge $forge = null) /** * Returns the database group name this migration uses. - * - * @return string */ public function getDBGroup(): ?string { diff --git a/system/Database/Query.php b/system/Database/Query.php index 702575ca..a78190a2 100644 --- a/system/Database/Query.php +++ b/system/Database/Query.php @@ -167,8 +167,6 @@ public function getQuery(): string * for it's start and end values. If no end value is present, will * use the current time to determine total duration. * - * @param float $end - * * @return $this */ public function setDuration(float $start, ?float $end = null) diff --git a/system/Debug/Toolbar.php b/system/Debug/Toolbar.php index d20125b9..19a67b45 100644 --- a/system/Debug/Toolbar.php +++ b/system/Debug/Toolbar.php @@ -346,9 +346,6 @@ protected function roundTo(float $number, int $increments = 5): float /** * Prepare for debugging.. * - * @param RequestInterface $request - * @param ResponseInterface $response - * * @return void */ public function prepare(?RequestInterface $request = null, ?ResponseInterface $response = null) diff --git a/system/Debug/Toolbar/Views/toolbar.css b/system/Debug/Toolbar/Views/toolbar.css index 38bab087..8a302b40 100644 --- a/system/Debug/Toolbar/Views/toolbar.css +++ b/system/Debug/Toolbar/Views/toolbar.css @@ -140,6 +140,14 @@ white-space: nowrap; z-index: 10000; } +#debug-bar .toolbar .rotate { + animation: toolbar-rotate 9s linear infinite; +} +@keyframes toolbar-rotate { + to { + transform: rotate(360deg); + } +} #debug-bar.fixed-top { bottom: auto; top: 0; @@ -796,14 +804,3 @@ .debug-bar-noverflow { overflow: hidden; } - -/* ENDLESS ROTATE */ -.rotate { - animation: rotate 9s linear infinite; -} - -@keyframes rotate { - to { - transform: rotate(360deg); - } -} diff --git a/system/Email/Email.php b/system/Email/Email.php index d962042d..b2f6874c 100644 --- a/system/Email/Email.php +++ b/system/Email/Email.php @@ -113,7 +113,9 @@ class Email /** * SMTP Encryption * - * @var string Empty, 'tls' or 'ssl' + * @var string '', 'tls' or 'ssl'. 'tls' will issue a STARTTLS command + * to the server. 'ssl' means implicit SSL. Connection on port + * 465 should set this to ''. */ public $SMTPCrypto = ''; @@ -1868,9 +1870,13 @@ protected function SMTPConnect() $ssl = ''; + // Connection to port 465 should use implicit TLS (without STARTTLS) + // as per RFC 8314. if ($this->SMTPPort === 465) { $ssl = 'tls://'; - } elseif ($this->SMTPCrypto === 'ssl') { + } + // But if $SMTPCrypto is set to `ssl`, SSL can be used. + if ($this->SMTPCrypto === 'ssl') { $ssl = 'ssl://'; } diff --git a/system/Encryption/Exceptions/EncryptionException.php b/system/Encryption/Exceptions/EncryptionException.php index d226fd5d..41a96b69 100644 --- a/system/Encryption/Exceptions/EncryptionException.php +++ b/system/Encryption/Exceptions/EncryptionException.php @@ -45,8 +45,6 @@ public static function forNoHandlerAvailable(string $handler) /** * Thrown when the handler requested is unknown. * - * @param string $driver - * * @return static */ public static function forUnKnownHandler(?string $driver = null) diff --git a/system/Entity/Entity.php b/system/Entity/Entity.php index 0481cc35..dd4f54c9 100644 --- a/system/Entity/Entity.php +++ b/system/Entity/Entity.php @@ -136,7 +136,7 @@ public function __construct(?array $data = null) * properties, using any `setCamelCasedProperty()` methods * that may or may not exist. * - * @param array $data + * @param array $data * * @return $this */ diff --git a/system/Format/Exceptions/FormatException.php b/system/Format/Exceptions/FormatException.php index cfe39d3b..55c36d3d 100644 --- a/system/Format/Exceptions/FormatException.php +++ b/system/Format/Exceptions/FormatException.php @@ -36,7 +36,7 @@ public static function forInvalidFormatter(string $class) * Thrown in JSONFormatter when the json_encode produces * an error code other than JSON_ERROR_NONE and JSON_ERROR_RECURSION. * - * @param string $error + * @param string $error The error message * * @return static */ diff --git a/system/HTTP/URI.php b/system/HTTP/URI.php index fb9d780c..a149c410 100644 --- a/system/HTTP/URI.php +++ b/system/HTTP/URI.php @@ -778,8 +778,6 @@ public function setHost(string $str) /** * Sets the port portion of the URI. * - * @param int $port - * * @return $this * * @TODO PSR-7: Should be `withPort($port)`. diff --git a/system/HTTP/UserAgent.php b/system/HTTP/UserAgent.php index 1ccc2109..02797b2d 100644 --- a/system/HTTP/UserAgent.php +++ b/system/HTTP/UserAgent.php @@ -112,8 +112,6 @@ public function __construct(?UserAgents $config = null) /** * Is Browser - * - * @param string $key */ public function isBrowser(?string $key = null): bool { @@ -132,8 +130,6 @@ public function isBrowser(?string $key = null): bool /** * Is Robot - * - * @param string $key */ public function isRobot(?string $key = null): bool { @@ -152,8 +148,6 @@ public function isRobot(?string $key = null): bool /** * Is Mobile - * - * @param string $key */ public function isMobile(?string $key = null): bool { diff --git a/system/Images/Handlers/BaseHandler.php b/system/Images/Handlers/BaseHandler.php index 134c7c6c..cf23fd0f 100644 --- a/system/Images/Handlers/BaseHandler.php +++ b/system/Images/Handlers/BaseHandler.php @@ -549,8 +549,6 @@ public function getEXIF(?string $key = null, bool $silent = false) * - bottom * - bottom-right * - * @param int $height - * * @return BaseHandler */ public function fit(int $width, ?int $height = null, string $position = 'center') diff --git a/system/Images/ImageHandlerInterface.php b/system/Images/ImageHandlerInterface.php index 2b924720..1c3593a9 100644 --- a/system/Images/ImageHandlerInterface.php +++ b/system/Images/ImageHandlerInterface.php @@ -132,7 +132,7 @@ public function text(string $text, array $options = []); * $image->resize(100, 200, true) * ->save($target); * - * @param string $target + * @param string|null $target The path to save the file to. * * @return bool */ diff --git a/system/Log/Handlers/ChromeLoggerHandler.php b/system/Log/Handlers/ChromeLoggerHandler.php index 9ce30a82..3354e5fb 100644 --- a/system/Log/Handlers/ChromeLoggerHandler.php +++ b/system/Log/Handlers/ChromeLoggerHandler.php @@ -149,8 +149,6 @@ protected function format($object) /** * Attaches the header and the content to the passed in request object. * - * @param ResponseInterface $response - * * @return void */ public function sendLogs(?ResponseInterface &$response = null) diff --git a/system/Pager/Pager.php b/system/Pager/Pager.php index 2c666e2c..3a9f5a77 100644 --- a/system/Pager/Pager.php +++ b/system/Pager/Pager.php @@ -387,8 +387,6 @@ public function only(array $queries): self /** * Ensures that an array exists for the group specified. * - * @param int $perPage - * * @return void */ protected function ensureGroup(string $group, ?int $perPage = null) diff --git a/system/Router/RouteCollection.php b/system/Router/RouteCollection.php index 82c6a6dd..83832801 100644 --- a/system/Router/RouteCollection.php +++ b/system/Router/RouteCollection.php @@ -28,7 +28,9 @@ class RouteCollection implements RouteCollectionInterface { /** * The namespace to be added to any Controllers. - * Defaults to the global namespaces (\) + * Defaults to the global namespaces (\). + * + * This must have a trailing backslash (\). * * @var string */ @@ -288,7 +290,7 @@ public function __construct(FileLocator $locator, Modules $moduleConfig, Routing $this->httpHost = Services::request()->getServer('HTTP_HOST'); // Setup based on config file. Let routes file override. - $this->defaultNamespace = $routing->defaultNamespace; + $this->defaultNamespace = rtrim($routing->defaultNamespace, '\\') . '\\'; $this->defaultController = $routing->defaultController; $this->defaultMethod = $routing->defaultMethod; $this->translateURIDashes = $routing->translateURIDashes; @@ -1149,11 +1151,13 @@ public function environment(string $env, Closure $callback): RouteCollectionInte public function reverseRoute(string $search, ...$params) { // Named routes get higher priority. - foreach ($this->routesNames as $collection) { + foreach ($this->routesNames as $verb => $collection) { if (array_key_exists($search, $collection)) { $routeKey = $collection[$search]; - return $this->buildReverseRoute($routeKey, $params); + $from = $this->routes[$verb][$routeKey]['from']; + + return $this->buildReverseRoute($from, $params); } } @@ -1169,8 +1173,9 @@ public function reverseRoute(string $search, ...$params) // If it's not a named route, then loop over // all routes to find a match. foreach ($this->routes as $collection) { - foreach ($collection as $routeKey => $route) { - $to = $route['handler']; + foreach ($collection as $route) { + $to = $route['handler']; + $from = $route['from']; // ignore closures if (! is_string($to)) { @@ -1194,7 +1199,7 @@ public function reverseRoute(string $search, ...$params) continue; } - return $this->buildReverseRoute($routeKey, $params); + return $this->buildReverseRoute($from, $params); } } @@ -1309,21 +1314,21 @@ protected function fillRouteParams(string $from, ?array $params = null): string * @param array $params One or more parameters to be passed to the route. * The last parameter allows you to set the locale. */ - protected function buildReverseRoute(string $routeKey, array $params): string + protected function buildReverseRoute(string $from, array $params): string { $locale = null; // Find all of our back-references in the original route - preg_match_all('/\(([^)]+)\)/', $routeKey, $matches); + preg_match_all('/\(([^)]+)\)/', $from, $matches); if (empty($matches[0])) { - if (strpos($routeKey, '{locale}') !== false) { + if (strpos($from, '{locale}') !== false) { $locale = $params[0] ?? null; } - $routeKey = $this->replaceLocale($routeKey, $locale); + $from = $this->replaceLocale($from, $locale); - return '/' . ltrim($routeKey, '/'); + return '/' . ltrim($from, '/'); } // Locale is passed? @@ -1334,25 +1339,31 @@ protected function buildReverseRoute(string $routeKey, array $params): string // Build our resulting string, inserting the $params in // the appropriate places. - foreach ($matches[0] as $index => $pattern) { + foreach ($matches[0] as $index => $placeholder) { if (! isset($params[$index])) { throw new InvalidArgumentException( - 'Missing argument for "' . $pattern . '" in route "' . $routeKey . '".' + 'Missing argument for "' . $placeholder . '" in route "' . $from . '".' ); } + + // Remove `(:` and `)` when $placeholder is a placeholder. + $placeholderName = substr($placeholder, 2, -1); + // or maybe $placeholder is not a placeholder, but a regex. + $pattern = $this->placeholders[$placeholderName] ?? $placeholder; + if (! preg_match('#^' . $pattern . '$#u', $params[$index])) { throw RouterException::forInvalidParameterType(); } // Ensure that the param we're inserting matches // the expected param type. - $pos = strpos($routeKey, $pattern); - $routeKey = substr_replace($routeKey, $params[$index], $pos, strlen($pattern)); + $pos = strpos($from, $placeholder); + $from = substr_replace($from, $params[$index], $pos, strlen($placeholder)); } - $routeKey = $this->replaceLocale($routeKey, $locale); + $from = $this->replaceLocale($from, $locale); - return '/' . ltrim($routeKey, '/'); + return '/' . ltrim($from, '/'); } /** diff --git a/system/Router/RouteCollectionInterface.php b/system/Router/RouteCollectionInterface.php index 0ca43523..00f1d4c8 100644 --- a/system/Router/RouteCollectionInterface.php +++ b/system/Router/RouteCollectionInterface.php @@ -28,8 +28,9 @@ interface RouteCollectionInterface /** * Adds a single route to the collection. * - * @param array|Closure|string $to - * @param array $options + * @param string $from The route path (with placeholders or regex) + * @param array|Closure|string $to The route handler + * @param array|null $options The route options * * @return RouteCollectionInterface */ @@ -44,7 +45,7 @@ public function add(string $from, $to, ?array $options = null); * multiple placeholders added at once. * * @param array|string $placeholder - * @param string $pattern + * @param string|null $pattern The regex pattern * * @return RouteCollectionInterface */ diff --git a/system/Test/DOMParser.php b/system/Test/DOMParser.php index 5ab12e44..54762643 100644 --- a/system/Test/DOMParser.php +++ b/system/Test/DOMParser.php @@ -101,9 +101,6 @@ public function withFile(string $path) /** * Checks to see if the text is found within the result. - * - * @param string $search - * @param string $element */ public function see(?string $search = null, ?string $element = null): bool { @@ -121,8 +118,6 @@ public function see(?string $search = null, ?string $element = null): bool /** * Checks to see if the text is NOT found within the result. - * - * @param string $search */ public function dontSee(?string $search = null, ?string $element = null): bool { diff --git a/system/Test/FeatureTestCase.php b/system/Test/FeatureTestCase.php index 371e302c..02835391 100644 --- a/system/Test/FeatureTestCase.php +++ b/system/Test/FeatureTestCase.php @@ -51,8 +51,6 @@ class FeatureTestCase extends CIUnitTestCase * ['get', 'home', 'Home::index'] * ] * - * @param array $routes - * * @return $this */ protected function withRoutes(?array $routes = null) diff --git a/system/Test/FeatureTestTrait.php b/system/Test/FeatureTestTrait.php index b117a1d8..23e56990 100644 --- a/system/Test/FeatureTestTrait.php +++ b/system/Test/FeatureTestTrait.php @@ -39,7 +39,7 @@ trait FeatureTestTrait * ['get', 'home', 'Home::index'] * ] * - * @param array $routes + * @param array|null $routes Array to set routes * * @return $this */ @@ -51,7 +51,11 @@ protected function withRoutes(?array $routes = null) $collection->resetRoutes(); foreach ($routes as $route) { - $collection->{$route[0]}($route[1], $route[2]); + if (isset($route[3])) { + $collection->{$route[0]}($route[1], $route[2], $route[3]); + } else { + $collection->{$route[0]}($route[1], $route[2]); + } } } @@ -292,6 +296,9 @@ protected function setupRequest(string $method, ?string $path = null): IncomingR if ($config->forceGlobalSecureRequests) { $_SERVER['HTTPS'] = 'test'; + $server = $request->getServer(); + $server['HTTPS'] = 'test'; + $request->setGlobal('server', $server); } return $request; diff --git a/system/Typography/Typography.php b/system/Typography/Typography.php index 1ca7a56f..fb05b68f 100644 --- a/system/Typography/Typography.php +++ b/system/Typography/Typography.php @@ -323,10 +323,11 @@ protected function protectCharacters(array $match): string */ public function nl2brExceptPre(string $str): string { - $newstr = ''; + $newstr = ''; + $docTypes = new DocTypes(); for ($ex = explode('pre>', $str), $ct = count($ex), $i = 0; $i < $ct; $i++) { - $xhtml = ! (config(DocTypes::class)->html5 ?? false); + $xhtml = ! ($docTypes->html5 ?? false); $newstr .= (($i % 2) === 0) ? nl2br($ex[$i], $xhtml) : $ex[$i]; if ($ct - 1 !== $i) { diff --git a/system/Validation/CreditCardRules.php b/system/Validation/CreditCardRules.php index 9e18f4ef..8b0e3842 100644 --- a/system/Validation/CreditCardRules.php +++ b/system/Validation/CreditCardRules.php @@ -236,8 +236,6 @@ public function valid_cc_number(?string $ccNumber, string $type): bool /** * Checks the given number to see if the number passing a Luhn check. - * - * @param string $number */ protected function isValidLuhn(?string $number = null): bool { diff --git a/system/Validation/FormatRules.php b/system/Validation/FormatRules.php index bc4301c2..485b9efe 100644 --- a/system/Validation/FormatRules.php +++ b/system/Validation/FormatRules.php @@ -176,8 +176,6 @@ public function regex_match(?string $str, string $pattern): bool * timezone_identifiers_list function. * * @see http://php.net/manual/en/datetimezone.listidentifiers.php - * - * @param string $str */ public function timezone(?string $str = null): bool { @@ -189,8 +187,6 @@ public function timezone(?string $str = null): bool * * Tests a string for characters outside of the Base64 alphabet * as defined by RFC 2045 http://www.faqs.org/rfcs/rfc2045 - * - * @param string $str */ public function valid_base64(?string $str = null): bool { @@ -203,8 +199,6 @@ public function valid_base64(?string $str = null): bool /** * Valid JSON - * - * @param string $str */ public function valid_json(?string $str = null): bool { @@ -215,8 +209,6 @@ public function valid_json(?string $str = null): bool /** * Checks for a correctly formatted email address - * - * @param string $str */ public function valid_email(?string $str = null): bool { @@ -233,8 +225,6 @@ public function valid_email(?string $str = null): bool * * Example: * valid_emails[one@example.com,two@example.com] - * - * @param string $str */ public function valid_emails(?string $str = null): bool { diff --git a/system/Validation/Rules.php b/system/Validation/Rules.php index 1bb2c243..e85b7443 100644 --- a/system/Validation/Rules.php +++ b/system/Validation/Rules.php @@ -204,8 +204,6 @@ public function min_length(?string $str, string $val): bool /** * Does not equal the static value provided. - * - * @param string $str */ public function not_equals(?string $str, string $val): bool { @@ -214,8 +212,6 @@ public function not_equals(?string $str, string $val): bool /** * Value should not be within an array of values. - * - * @param string $value */ public function not_in_list(?string $value, string $list): bool {