From c53586a65cc7104ff2a9d2c0c36033c40faa7fde Mon Sep 17 00:00:00 2001 From: kenjis Date: Sat, 23 Sep 2023 21:11:25 +0900 Subject: [PATCH 01/21] chore: change for upgrade to PHP 8.0 --- rector.php | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/rector.php b/rector.php index 1eaacd12328b..2b928390fca9 100644 --- a/rector.php +++ b/rector.php @@ -37,6 +37,13 @@ use Rector\Php55\Rector\String_\StringClassNameToClassConstantRector; use Rector\Php70\Rector\FuncCall\RandomFunctionRector; use Rector\Php73\Rector\FuncCall\JsonThrowOnErrorRector; +use Rector\Php80\Rector\Class_\AnnotationToAttributeRector; +use Rector\Php80\Rector\Class_\ClassPropertyAssignToConstructorPromotionRector; +use Rector\Php80\Rector\FunctionLike\MixedTypeRector; +use Rector\PHPUnit\AnnotationsToAttributes\Rector\Class_\AnnotationWithValueToAttributeRector; +use Rector\PHPUnit\AnnotationsToAttributes\Rector\Class_\CoversAnnotationWithValueToAttributeRector; +use Rector\PHPUnit\AnnotationsToAttributes\Rector\ClassMethod\DataProviderAnnotationToAttributeRector; +use Rector\PHPUnit\AnnotationsToAttributes\Rector\ClassMethod\DependsAnnotationWithValueToAttributeRector; use Rector\PHPUnit\CodeQuality\Rector\Class_\YieldDataProviderRector; use Rector\PHPUnit\Set\PHPUnitSetList; use Rector\Privatization\Rector\Property\PrivatizeFinalClassPropertyRector; @@ -50,7 +57,7 @@ return static function (RectorConfig $rectorConfig): void { $rectorConfig->sets([ SetList::DEAD_CODE, - LevelSetList::UP_TO_PHP_74, + LevelSetList::UP_TO_PHP_80, PHPUnitSetList::PHPUNIT_CODE_QUALITY, PHPUnitSetList::PHPUNIT_100, ]); @@ -110,6 +117,17 @@ RandomFunctionRector::class, SimplifyRegexPatternRector::class, + + // PHP 8.0 features but cause breaking changes + ClassPropertyAssignToConstructorPromotionRector::class, + MixedTypeRector::class, + + // PHPUnit 10 (requires PHP 8.1) features + DataProviderAnnotationToAttributeRector::class, + DependsAnnotationWithValueToAttributeRector::class, + AnnotationWithValueToAttributeRector::class, + AnnotationToAttributeRector::class, + CoversAnnotationWithValueToAttributeRector::class, ]); // auto import fully qualified class names From 7622d1dc9120f122eff5b3eb30e4c28d36f082c9 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 24 Sep 2023 05:28:48 +0900 Subject: [PATCH 02/21] refactor: upgrade to PHP 8.0 by rector --- app/Views/errors/cli/error_exception.php | 21 ++---- app/Views/errors/html/error_exception.php | 2 +- system/Autoloader/Autoloader.php | 6 +- system/Autoloader/FileLocator.php | 10 +-- system/BaseModel.php | 40 ++++------ system/CLI/CLI.php | 2 +- system/CLI/Commands.php | 2 +- system/CLI/GeneratorTrait.php | 2 +- system/Cache/Handlers/PredisHandler.php | 21 ++---- system/Cache/Handlers/RedisHandler.php | 21 ++---- system/CodeIgniter.php | 4 +- system/Commands/Database/CreateDatabase.php | 2 +- system/Commands/Encryption/GenerateKey.php | 2 +- system/Commands/Utilities/Publish.php | 4 +- .../ControllerMethodReader.php | 2 +- .../Utilities/Routes/FilterFinder.php | 4 +- system/Common.php | 64 ++++++---------- system/ComposerScripts.php | 2 +- system/Config/BaseConfig.php | 4 +- system/Config/DotEnv.php | 8 +- system/Config/Factories.php | 8 +- system/Cookie/Cookie.php | 15 ++-- system/Cookie/CookieStore.php | 2 +- system/Database/BaseBuilder.php | 20 ++--- system/Database/BaseConnection.php | 16 ++-- system/Database/Database.php | 4 +- system/Database/Forge.php | 4 +- system/Database/MigrationRunner.php | 2 +- system/Database/OCI8/Connection.php | 12 +-- system/Database/OCI8/Forge.php | 4 +- system/Database/Postgre/Connection.php | 6 +- system/Database/Query.php | 4 +- system/Database/RawSql.php | 4 +- system/Database/SQLSRV/Builder.php | 6 +- system/Database/SQLSRV/Connection.php | 6 +- system/Database/SQLite3/Connection.php | 2 +- system/Database/SQLite3/Forge.php | 2 +- system/Database/SQLite3/Table.php | 2 +- system/Database/Seeder.php | 2 +- system/Debug/BaseExceptionHandler.php | 8 +- system/Debug/ExceptionHandler.php | 4 +- system/Debug/Exceptions.php | 63 +++++----------- system/Debug/Toolbar.php | 4 +- system/Debug/Toolbar/Collectors/Database.php | 2 +- system/Debug/Toolbar/Collectors/Files.php | 2 +- system/Debug/Toolbar/Collectors/Routes.php | 2 +- system/Email/Email.php | 22 +++--- system/Entity/Cast/ArrayCast.php | 2 +- system/Entity/Entity.php | 4 +- system/Entity/Exceptions/CastException.php | 27 ++----- system/Exceptions/CastException.php | 27 ++----- system/Exceptions/FrameworkException.php | 2 +- system/Files/File.php | 17 ++--- system/Files/FileCollection.php | 4 +- system/Filters/Filters.php | 4 +- system/HTTP/CURLRequest.php | 10 +-- system/HTTP/ContentSecurityPolicy.php | 2 +- system/HTTP/Files/FileCollection.php | 6 +- system/HTTP/Files/UploadedFile.php | 2 +- system/HTTP/Header.php | 4 +- system/HTTP/IncomingRequest.php | 75 ++++++------------- system/HTTP/RedirectResponse.php | 2 +- system/HTTP/RequestTrait.php | 4 +- system/HTTP/ResponseTrait.php | 15 ++-- system/HTTP/SiteURI.php | 3 +- system/HTTP/SiteURIFactory.php | 23 ++---- system/HTTP/URI.php | 23 +++--- system/HTTP/UserAgent.php | 3 +- system/Helpers/filesystem_helper.php | 10 +-- system/Helpers/form_helper.php | 6 +- system/Helpers/html_helper.php | 2 +- system/Helpers/number_helper.php | 4 +- system/Helpers/text_helper.php | 2 +- system/Honeypot/Honeypot.php | 2 +- system/Images/Handlers/BaseHandler.php | 35 +++------ system/Images/Handlers/ImageMagickHandler.php | 35 +++------ system/Language/Language.php | 2 +- system/Log/Handlers/ChromeLoggerHandler.php | 2 +- system/Log/Handlers/FileHandler.php | 2 +- system/Log/Logger.php | 4 +- system/Model.php | 2 +- system/Pager/Pager.php | 2 +- system/Publisher/Publisher.php | 4 +- system/RESTful/BaseResource.php | 2 +- system/Router/AutoRouter.php | 6 +- system/Router/AutoRouterImproved.php | 10 +-- system/Router/RouteCollection.php | 14 ++-- system/Router/Router.php | 10 +-- system/Security/Security.php | 2 +- system/Test/CIUnitTestCase.php | 4 +- system/Test/ControllerTestTrait.php | 2 +- system/Test/DOMParser.php | 6 +- system/Test/DatabaseTestTrait.php | 2 +- system/Test/Fabricator.php | 19 ++--- system/Test/FilterTestTrait.php | 4 +- system/Test/TestLogger.php | 2 +- system/Typography/Typography.php | 8 +- system/Validation/CreditCardRules.php | 2 +- system/Validation/FormatRules.php | 19 ++--- system/Validation/Rules.php | 10 +-- system/Validation/Validation.php | 12 +-- system/View/Cell.php | 8 +- system/View/Cells/Cell.php | 3 +- system/View/Filters.php | 19 ++--- system/View/Parser.php | 10 +-- tests/system/AutoReview/ComposerJsonTest.php | 17 ++--- tests/system/AutoReview/FrameworkCodeTest.php | 4 +- .../system/Commands/CommandGeneratorTest.php | 2 +- tests/system/CommonFunctionsTest.php | 4 +- tests/system/CommonHelperTest.php | 4 +- tests/system/CommonSingleServiceTest.php | 6 +- tests/system/ControllerTest.php | 2 +- tests/system/Database/Live/DeleteTest.php | 2 +- tests/system/Database/Live/GetTest.php | 2 +- .../Database/Live/PreparedQueryTest.php | 2 +- tests/system/Database/Live/UpdateTest.php | 4 +- tests/system/Debug/ExceptionsTest.php | 2 +- .../system/HTTP/ContentSecurityPolicyTest.php | 4 +- tests/system/Models/DeleteModelTest.php | 2 +- 119 files changed, 422 insertions(+), 633 deletions(-) diff --git a/app/Views/errors/cli/error_exception.php b/app/Views/errors/cli/error_exception.php index 98d83b0ed3a6..49bcd89131fb 100644 --- a/app/Views/errors/cli/error_exception.php +++ b/app/Views/errors/cli/error_exception.php @@ -3,7 +3,7 @@ use CodeIgniter\CLI\CLI; // The main Exception -CLI::write('[' . get_class($exception) . ']', 'light_gray', 'red'); +CLI::write('[' . $exception::class . ']', 'light_gray', 'red'); CLI::write($message); CLI::write('at ' . CLI::color(clean_path($exception->getFile()) . ':' . $exception->getLine(), 'green')); CLI::newLine(); @@ -50,20 +50,11 @@ $function .= $padClass . $error['function']; } - $args = implode(', ', array_map(static function ($value) { - switch (true) { - case is_object($value): - return 'Object(' . get_class($value) . ')'; - - case is_array($value): - return count($value) ? '[...]' : '[]'; - - case $value === null: - return 'null'; // return the lowercased version - - default: - return var_export($value, true); - } + $args = implode(', ', array_map(static fn ($value) => match (true) { + is_object($value) => 'Object(' . $value::class . ')', + is_array($value) => count($value) ? '[...]' : '[]', + $value === null => 'null', + default => var_export($value, true), }, array_values($error['args'] ?? []))); $function .= '(' . $args . ')'; diff --git a/app/Views/errors/html/error_exception.php b/app/Views/errors/html/error_exception.php index 29a08d19caa8..98b48b9b6834 100644 --- a/app/Views/errors/html/error_exception.php +++ b/app/Views/errors/html/error_exception.php @@ -115,7 +115,7 @@ getParameters(); } diff --git a/system/Autoloader/Autoloader.php b/system/Autoloader/Autoloader.php index 020dd5b1a4f2..bae6e95c878a 100644 --- a/system/Autoloader/Autoloader.php +++ b/system/Autoloader/Autoloader.php @@ -273,7 +273,7 @@ public function loadClass(string $class): void */ protected function loadInNamespace(string $class) { - if (strpos($class, '\\') === false) { + if (! str_contains($class, '\\')) { return false; } @@ -281,7 +281,7 @@ protected function loadInNamespace(string $class) foreach ($directories as $directory) { $directory = rtrim($directory, '\\/'); - if (strpos($class, $namespace) === 0) { + if (str_starts_with($class, $namespace)) { $filePath = $directory . str_replace('\\', DIRECTORY_SEPARATOR, substr($class, strlen($namespace))) . '.php'; $filename = $this->includeFile($filePath); @@ -415,7 +415,7 @@ private function loadComposerNamespaces(ClassLoader $composer, array $composerPa foreach ($srcPaths as $path) { foreach ($installPaths as $installPath) { - if ($installPath === substr($path, 0, strlen($installPath))) { + if (str_starts_with($path, $installPath)) { $add = true; break 2; } diff --git a/system/Autoloader/FileLocator.php b/system/Autoloader/FileLocator.php index e3821c1df27e..2484eda0860f 100644 --- a/system/Autoloader/FileLocator.php +++ b/system/Autoloader/FileLocator.php @@ -51,12 +51,12 @@ public function locateFile(string $file, ?string $folder = null, string $ext = ' $file = $this->ensureExt($file, $ext); // Clears the folder name if it is at the beginning of the filename - if (! empty($folder) && strpos($file, $folder) === 0) { + if (! empty($folder) && str_starts_with($file, $folder)) { $file = substr($file, strlen($folder . '/')); } // Is not namespaced? Try the application folder. - if (strpos($file, '\\') === false) { + if (! str_contains($file, '\\')) { return $this->legacyLocate($file, $folder); } @@ -101,7 +101,7 @@ public function locateFile(string $file, ?string $folder = null, string $ext = ' // If we have a folder name, then the calling function // expects this file to be within that folder, like 'Views', // or 'libraries'. - if (! empty($folder) && strpos($path . $filename, '/' . $folder . '/') === false) { + if (! empty($folder) && ! str_contains($path . $filename, '/' . $folder . '/')) { $path .= trim($folder, '/') . '/'; } @@ -188,7 +188,7 @@ public function search(string $path, string $ext = 'php', bool $prioritizeApp = if ($prioritizeApp) { $foundPaths[] = $fullPath; - } elseif (strpos($fullPath, APPPATH) === 0) { + } elseif (str_starts_with($fullPath, APPPATH)) { $appPaths[] = $fullPath; } else { $foundPaths[] = $fullPath; @@ -212,7 +212,7 @@ protected function ensureExt(string $path, string $ext): string if ($ext !== '') { $ext = '.' . $ext; - if (substr($path, -strlen($ext)) !== $ext) { + if (! str_ends_with($path, $ext)) { $path .= $ext; } } diff --git a/system/BaseModel.php b/system/BaseModel.php index 7afdf9c1cb4d..14b2680875f7 100644 --- a/system/BaseModel.php +++ b/system/BaseModel.php @@ -577,7 +577,7 @@ public function find($id = null) */ public function findColumn(string $columnName) { - if (strpos($columnName, ',') !== false) { + if (str_contains($columnName, ',')) { throw DataException::forFindColumnHaveMultipleColumns(); } @@ -1313,19 +1313,12 @@ protected function setDate(?int $userData = null) */ protected function intToDate(int $value) { - switch ($this->dateFormat) { - case 'int': - return $value; - - case 'datetime': - return date('Y-m-d H:i:s', $value); - - case 'date': - return date('Y-m-d', $value); - - default: - throw ModelException::forNoDateFormat(static::class); - } + return match ($this->dateFormat) { + 'int' => $value, + 'datetime' => date('Y-m-d H:i:s', $value), + 'date' => date('Y-m-d', $value), + default => throw ModelException::forNoDateFormat(static::class), + }; } /** @@ -1342,19 +1335,12 @@ protected function intToDate(int $value) */ protected function timeToDate(Time $value) { - switch ($this->dateFormat) { - case 'datetime': - return $value->format('Y-m-d H:i:s'); - - case 'date': - return $value->format('Y-m-d'); - - case 'int': - return $value->getTimestamp(); - - default: - return (string) $value; - } + return match ($this->dateFormat) { + 'datetime' => $value->format('Y-m-d H:i:s'), + 'date' => $value->format('Y-m-d'), + 'int' => $value->getTimestamp(), + default => (string) $value, + }; } /** diff --git a/system/CLI/CLI.php b/system/CLI/CLI.php index e2aa363e5851..23d5f05a2b4c 100644 --- a/system/CLI/CLI.php +++ b/system/CLI/CLI.php @@ -590,7 +590,7 @@ public static function color(string $text, string $foreground, ?string $backgrou $newText = ''; // Detect if color method was already in use with this text - if (strpos($text, "\033[0m") !== false) { + if (str_contains($text, "\033[0m")) { $pattern = '/\\033\\[0;.+?\\033\\[0m/u'; preg_match_all($pattern, $text, $matches); diff --git a/system/CLI/Commands.php b/system/CLI/Commands.php index 7cb5351cf3b5..0c9bcabae37d 100644 --- a/system/CLI/Commands.php +++ b/system/CLI/Commands.php @@ -174,7 +174,7 @@ protected function getCommandAlternatives(string $name, array $collection): arra foreach (array_keys($collection) as $commandName) { $lev = levenshtein($name, $commandName); - if ($lev <= strlen($commandName) / 3 || strpos($commandName, $name) !== false) { + if ($lev <= strlen($commandName) / 3 || str_contains($commandName, $name)) { $alternatives[$commandName] = $lev; } } diff --git a/system/CLI/GeneratorTrait.php b/system/CLI/GeneratorTrait.php index c1112ca63481..c2260b4abb71 100644 --- a/system/CLI/GeneratorTrait.php +++ b/system/CLI/GeneratorTrait.php @@ -309,7 +309,7 @@ protected function qualifyClassName(): string '\\' ) . '\\'; - if (strncmp($class, $namespace, strlen($namespace)) === 0) { + if (str_starts_with($class, $namespace)) { return $class; // @codeCoverageIgnore } diff --git a/system/Cache/Handlers/PredisHandler.php b/system/Cache/Handlers/PredisHandler.php index 986d083ebc69..d9b3701517ad 100644 --- a/system/Cache/Handlers/PredisHandler.php +++ b/system/Cache/Handlers/PredisHandler.php @@ -86,22 +86,11 @@ public function get(string $key) return null; } - switch ($data['__ci_type']) { - case 'array': - case 'object': - return unserialize($data['__ci_value']); - - case 'boolean': - case 'integer': - case 'double': // Yes, 'double' is returned and NOT 'float' - case 'string': - case 'NULL': - return settype($data['__ci_value'], $data['__ci_type']) ? $data['__ci_value'] : null; - - case 'resource': - default: - return null; - } + return match ($data['__ci_type']) { + 'array', 'object' => unserialize($data['__ci_value']), + 'boolean', 'integer', 'double', 'string', 'NULL' => settype($data['__ci_value'], $data['__ci_type']) ? $data['__ci_value'] : null, + default => null, + }; } /** diff --git a/system/Cache/Handlers/RedisHandler.php b/system/Cache/Handlers/RedisHandler.php index 953de2dc20be..bbba78eb1b9b 100644 --- a/system/Cache/Handlers/RedisHandler.php +++ b/system/Cache/Handlers/RedisHandler.php @@ -112,22 +112,11 @@ public function get(string $key) return null; } - switch ($data['__ci_type']) { - case 'array': - case 'object': - return unserialize($data['__ci_value']); - - case 'boolean': - case 'integer': - case 'double': // Yes, 'double' is returned and NOT 'float' - case 'string': - case 'NULL': - return settype($data['__ci_value'], $data['__ci_type']) ? $data['__ci_value'] : null; - - case 'resource': - default: - return null; - } + return match ($data['__ci_type']) { + 'array', 'object' => unserialize($data['__ci_value']), + 'boolean', 'integer', 'double', 'string', 'NULL' => settype($data['__ci_value'], $data['__ci_type']) ? $data['__ci_value'] : null, + default => null, + }; } /** diff --git a/system/CodeIgniter.php b/system/CodeIgniter.php index 87a2a55b0caa..c508e8afdcde 100644 --- a/system/CodeIgniter.php +++ b/system/CodeIgniter.php @@ -867,7 +867,7 @@ protected function startController() $this->benchmark->start('controller_constructor'); // Is it routed to a Closure? - if (is_object($this->controller) && (get_class($this->controller) === 'Closure')) { + if (is_object($this->controller) && ($this->controller::class === 'Closure')) { $controller = $this->controller; return $controller(...$this->router->params()); @@ -1038,7 +1038,7 @@ public function storePreviousURL($uri) } // Ignore non-HTML responses - if (strpos($this->response->getHeaderLine('Content-Type'), 'text/html') === false) { + if (! str_contains($this->response->getHeaderLine('Content-Type'), 'text/html')) { return; } diff --git a/system/Commands/Database/CreateDatabase.php b/system/Commands/Database/CreateDatabase.php index d103d97f689a..32643320b00f 100644 --- a/system/Commands/Database/CreateDatabase.php +++ b/system/Commands/Database/CreateDatabase.php @@ -107,7 +107,7 @@ public function run(array $params) $config->{$group}['database'] = $name; if ($name !== ':memory:') { - $dbName = strpos($name, DIRECTORY_SEPARATOR) === false ? WRITEPATH . $name : $name; + $dbName = ! str_contains($name, DIRECTORY_SEPARATOR) ? WRITEPATH . $name : $name; if (is_file($dbName)) { CLI::error("Database \"{$dbName}\" already exists.", 'light_gray', 'red'); diff --git a/system/Commands/Encryption/GenerateKey.php b/system/Commands/Encryption/GenerateKey.php index 419ae6ef3e34..c10a76e81e43 100644 --- a/system/Commands/Encryption/GenerateKey.php +++ b/system/Commands/Encryption/GenerateKey.php @@ -166,7 +166,7 @@ protected function writeNewEncryptionKeyToFile(string $oldKey, string $newKey): $oldFileContents = (string) file_get_contents($envFile); $replacementKey = "\nencryption.key = {$newKey}"; - if (strpos($oldFileContents, 'encryption.key') === false) { + if (! str_contains($oldFileContents, 'encryption.key')) { return file_put_contents($envFile, $replacementKey, FILE_APPEND) !== false; } diff --git a/system/Commands/Utilities/Publish.php b/system/Commands/Utilities/Publish.php index 1e4103c114d8..f1abd7433113 100644 --- a/system/Commands/Utilities/Publish.php +++ b/system/Commands/Utilities/Publish.php @@ -83,13 +83,13 @@ public function run(array $params) foreach ($publishers as $publisher) { if ($publisher->publish()) { CLI::write(lang('Publisher.publishSuccess', [ - get_class($publisher), + $publisher::class, count($publisher->getPublished()), $publisher->getDestination(), ]), 'green'); } else { CLI::error(lang('Publisher.publishFailure', [ - get_class($publisher), + $publisher::class, $publisher->getDestination(), ]), 'light_gray', 'red'); diff --git a/system/Commands/Utilities/Routes/AutoRouterImproved/ControllerMethodReader.php b/system/Commands/Utilities/Routes/AutoRouterImproved/ControllerMethodReader.php index 73da88630d5d..460a4a89ccef 100644 --- a/system/Commands/Utilities/Routes/AutoRouterImproved/ControllerMethodReader.php +++ b/system/Commands/Utilities/Routes/AutoRouterImproved/ControllerMethodReader.php @@ -65,7 +65,7 @@ public function read(string $class, string $defaultController = 'Home', string $ $methodName = $method->getName(); foreach ($this->httpMethods as $httpVerb) { - if (strpos($methodName, strtolower($httpVerb)) === 0) { + if (str_starts_with($methodName, strtolower($httpVerb))) { // Remove HTTP verb prefix. $methodInUri = lcfirst(substr($methodName, strlen($httpVerb))); diff --git a/system/Commands/Utilities/Routes/FilterFinder.php b/system/Commands/Utilities/Routes/FilterFinder.php index cc1f6d2b05f4..8788a164ac88 100644 --- a/system/Commands/Utilities/Routes/FilterFinder.php +++ b/system/Commands/Utilities/Routes/FilterFinder.php @@ -65,12 +65,12 @@ public function find(string $uri): array $this->filters->initialize($uri); return $this->filters->getFilters(); - } catch (RedirectException $e) { + } catch (RedirectException) { return [ 'before' => [], 'after' => [], ]; - } catch (PageNotFoundException $e) { + } catch (PageNotFoundException) { return [ 'before' => [''], 'after' => [''], diff --git a/system/Common.php b/system/Common.php index 0f8aa3e7ad27..66115c819164 100644 --- a/system/Common.php +++ b/system/Common.php @@ -92,29 +92,18 @@ function clean_path(string $path): string // Resolve relative paths try { $path = realpath($path) ?: $path; - } catch (ErrorException|ValueError $e) { + } catch (ErrorException|ValueError) { $path = 'error file path: ' . urlencode($path); } - switch (true) { - case strpos($path, APPPATH) === 0: - return 'APPPATH' . DIRECTORY_SEPARATOR . substr($path, strlen(APPPATH)); - - case strpos($path, SYSTEMPATH) === 0: - return 'SYSTEMPATH' . DIRECTORY_SEPARATOR . substr($path, strlen(SYSTEMPATH)); - - case strpos($path, FCPATH) === 0: - return 'FCPATH' . DIRECTORY_SEPARATOR . substr($path, strlen(FCPATH)); - - case defined('VENDORPATH') && strpos($path, VENDORPATH) === 0: - return 'VENDORPATH' . DIRECTORY_SEPARATOR . substr($path, strlen(VENDORPATH)); - - case strpos($path, ROOTPATH) === 0: - return 'ROOTPATH' . DIRECTORY_SEPARATOR . substr($path, strlen(ROOTPATH)); - - default: - return $path; - } + return match (true) { + str_starts_with($path, APPPATH) => 'APPPATH' . DIRECTORY_SEPARATOR . substr($path, strlen(APPPATH)), + str_starts_with($path, SYSTEMPATH) => 'SYSTEMPATH' . DIRECTORY_SEPARATOR . substr($path, strlen(SYSTEMPATH)), + str_starts_with($path, FCPATH) => 'FCPATH' . DIRECTORY_SEPARATOR . substr($path, strlen(FCPATH)), + defined('VENDORPATH') && str_starts_with($path, VENDORPATH) => 'VENDORPATH' . DIRECTORY_SEPARATOR . substr($path, strlen(VENDORPATH)), + str_starts_with($path, ROOTPATH) => 'ROOTPATH' . DIRECTORY_SEPARATOR . substr($path, strlen(ROOTPATH)), + default => $path, + }; } } @@ -382,22 +371,13 @@ function env(string $key, $default = null) return $default; } - // Handle any boolean values - switch (strtolower($value)) { - case 'true': - return true; - - case 'false': - return false; - - case 'empty': - return ''; - - case 'null': - return null; - } - - return $value; + return match (strtolower($value)) { + 'true' => true, + 'false' => false, + 'empty' => '', + 'null' => null, + default => $value, + }; } } @@ -592,7 +572,7 @@ function helper($filenames): void $appHelper = null; $localIncludes = []; - if (strpos($filename, '_helper') === false) { + if (! str_contains($filename, '_helper')) { $filename .= '_helper'; } @@ -603,7 +583,7 @@ function helper($filenames): void // If the file is namespaced, we'll just grab that // file and not search for any others - if (strpos($filename, '\\') !== false) { + if (str_contains($filename, '\\')) { $path = $loader->locateFile($filename, 'Helpers'); if (empty($path)) { @@ -617,9 +597,9 @@ function helper($filenames): void $paths = $loader->search('Helpers/' . $filename); foreach ($paths as $path) { - if (strpos($path, APPPATH . 'Helpers' . DIRECTORY_SEPARATOR) === 0) { + if (str_starts_with($path, APPPATH . 'Helpers' . DIRECTORY_SEPARATOR)) { $appHelper = $path; - } elseif (strpos($path, SYSTEMPATH . 'Helpers' . DIRECTORY_SEPARATOR) === 0) { + } elseif (str_starts_with($path, SYSTEMPATH . 'Helpers' . DIRECTORY_SEPARATOR)) { $systemHelper = $path; } else { $localIncludes[] = $path; @@ -1209,7 +1189,7 @@ function view_cell(string $library, $params = null, int $ttl = 0, ?string $cache */ function class_basename($class) { - $class = is_object($class) ? get_class($class) : $class; + $class = is_object($class) ? $class::class : $class; return basename(str_replace('\\', '/', $class)); } @@ -1228,7 +1208,7 @@ function class_basename($class) function class_uses_recursive($class) { if (is_object($class)) { - $class = get_class($class); + $class = $class::class; } $results = []; diff --git a/system/ComposerScripts.php b/system/ComposerScripts.php index 021079da468d..a3cda28fe063 100644 --- a/system/ComposerScripts.php +++ b/system/ComposerScripts.php @@ -71,7 +71,7 @@ public static function postUpdate() foreach (self::$dependencies as $key => $dependency) { // Kint may be removed. - if (! is_dir($dependency['from']) && strpos($key, 'kint') === 0) { + if (! is_dir($dependency['from']) && str_starts_with($key, 'kint')) { continue; } diff --git a/system/Config/BaseConfig.php b/system/Config/BaseConfig.php index 216ce81fd5e9..a796438ca0cb 100644 --- a/system/Config/BaseConfig.php +++ b/system/Config/BaseConfig.php @@ -120,10 +120,10 @@ public function __construct() $this->initEnvValue($this->{$property}, $property, $prefix, $shortPrefix); if ($this instanceof Encryption && $property === 'key') { - if (strpos($this->{$property}, 'hex2bin:') === 0) { + if (str_starts_with($this->{$property}, 'hex2bin:')) { // Handle hex2bin prefix $this->{$property} = hex2bin(substr($this->{$property}, 8)); - } elseif (strpos($this->{$property}, 'base64:') === 0) { + } elseif (str_starts_with($this->{$property}, 'base64:')) { // Handle base64 prefix $this->{$property} = base64_decode(substr($this->{$property}, 7), true); } diff --git a/system/Config/DotEnv.php b/system/Config/DotEnv.php index 05ecab900c3e..01c51ebf2f9e 100644 --- a/system/Config/DotEnv.php +++ b/system/Config/DotEnv.php @@ -68,12 +68,12 @@ public function parse(): ?array foreach ($lines as $line) { // Is it a comment? - if (strpos(trim($line), '#') === 0) { + if (str_starts_with(trim($line), '#')) { continue; } // If there is an equal sign, then we know we are assigning a variable. - if (strpos($line, '=') !== false) { + if (str_contains($line, '=')) { [$name, $value] = $this->normaliseVariable($line); $vars[$name] = $value; $this->setVariable($name, $value); @@ -112,7 +112,7 @@ protected function setVariable(string $name, string $value = '') public function normaliseVariable(string $name, string $value = ''): array { // Split our compound string into its parts. - if (strpos($name, '=') !== false) { + if (str_contains($name, '=')) { [$name, $value] = explode('=', $name, 2); } @@ -192,7 +192,7 @@ protected function sanitizeValue(string $value): string */ protected function resolveNestedVariables(string $value): string { - if (strpos($value, '$') !== false) { + if (str_contains($value, '$')) { $value = preg_replace_callback( '/\${([a-zA-Z0-9_\.]+)}/', function ($matchedPatterns) { diff --git a/system/Config/Factories.php b/system/Config/Factories.php index 253cd3f7a7c9..f2a59522af73 100644 --- a/system/Config/Factories.php +++ b/system/Config/Factories.php @@ -316,7 +316,7 @@ class_exists($alias, false) */ private static function isNamespaced(string $alias): bool { - return strpos($alias, '\\') !== false; + return str_contains($alias, '\\'); } /** @@ -334,10 +334,10 @@ private static function verifyPreferApp(array $options, string $alias): bool // Special case for Config since its App namespace is actually \Config if (self::isConfig($options['component'])) { - return strpos($alias, 'Config') === 0; + return str_starts_with($alias, 'Config'); } - return strpos($alias, APP_NAMESPACE) === 0; + return str_starts_with($alias, APP_NAMESPACE); } /** @@ -461,7 +461,7 @@ public static function injectMock(string $component, string $alias, object $inst // Force a configuration to exist for this component self::getOptions($component); - $class = get_class($instance); + $class = $instance::class; self::$instances[$component][$class] = $instance; self::$aliases[$component][$alias] = $class; diff --git a/system/Cookie/Cookie.php b/system/Cookie/Cookie.php index 68a748cb30eb..96248099a02e 100644 --- a/system/Cookie/Cookie.php +++ b/system/Cookie/Cookie.php @@ -19,6 +19,7 @@ use InvalidArgumentException; use LogicException; use ReturnTypeWillChange; +use Stringable; /** * A `Cookie` class represents an immutable HTTP cookie value object. @@ -41,7 +42,7 @@ * @template-implements ArrayAccess * @see \CodeIgniter\Cookie\CookieTest */ -class Cookie implements ArrayAccess, CloneableCookieInterface +class Cookie implements ArrayAccess, CloneableCookieInterface, Stringable { /** * @var string @@ -159,7 +160,6 @@ public static function setDefaults($config = []) // ========================================================================= // CONSTRUCTORS // ========================================================================= - /** * Create a new Cookie instance from a `Set-Cookie` header. * @@ -180,7 +180,7 @@ public static function fromHeaderString(string $cookie, bool $raw = false) unset($part); foreach ($parts as $part) { - if (strpos($part, '=') !== false) { + if (str_contains($part, '=')) { [$attr, $val] = explode('=', $part); } else { $attr = $part; @@ -245,7 +245,6 @@ final public function __construct(string $name, string $value = '', array $optio // ========================================================================= // GETTERS // ========================================================================= - /** * {@inheritDoc} */ @@ -398,7 +397,6 @@ public function getOptions(): array // ========================================================================= // CLONING // ========================================================================= - /** * {@inheritDoc} */ @@ -563,7 +561,6 @@ public function withRaw(bool $raw = true) // ========================================================================= // ARRAY ACCESS FOR BC // ========================================================================= - /** * Whether an offset exists. * @@ -621,7 +618,6 @@ public function offsetUnset($offset): void // ========================================================================= // CONVERTERS // ========================================================================= - /** * {@inheritDoc} */ @@ -723,7 +719,6 @@ protected static function convertExpiresTimestamp($expires = 0): int // ========================================================================= // VALIDATION // ========================================================================= - /** * Validates the cookie name per RFC 2616. * @@ -750,11 +745,11 @@ protected function validateName(string $name, bool $raw): void */ protected function validatePrefix(string $prefix, bool $secure, string $path, string $domain): void { - if (strpos($prefix, '__Secure-') === 0 && ! $secure) { + if (str_starts_with($prefix, '__Secure-') && ! $secure) { throw CookieException::forInvalidSecurePrefix(); } - if (strpos($prefix, '__Host-') === 0 && (! $secure || $domain !== '' || $path !== '/')) { + if (str_starts_with($prefix, '__Host-') && (! $secure || $domain !== '' || $path !== '/')) { throw CookieException::forInvalidHostPrefix(); } } diff --git a/system/Cookie/CookieStore.php b/system/Cookie/CookieStore.php index d893a4add116..867ffcecf976 100644 --- a/system/Cookie/CookieStore.php +++ b/system/Cookie/CookieStore.php @@ -223,7 +223,7 @@ public function getIterator(): Traversable protected function validateCookies(array $cookies): void { foreach ($cookies as $index => $cookie) { - $type = is_object($cookie) ? get_class($cookie) : gettype($cookie); + $type = get_debug_type($cookie); if (! $cookie instanceof Cookie) { throw CookieException::forInvalidCookieInstance([static::class, Cookie::class, $type, $index]); diff --git a/system/Database/BaseBuilder.php b/system/Database/BaseBuilder.php index badf2d35cdfc..5c86942be008 100644 --- a/system/Database/BaseBuilder.php +++ b/system/Database/BaseBuilder.php @@ -310,7 +310,7 @@ public function __construct($tableName, ConnectionInterface $db, ?array $options $this->db = $db; // If it contains `,`, it has multiple tables - if (is_string($tableName) && strpos($tableName, ',') === false) { + if (is_string($tableName) && ! str_contains($tableName, ',')) { $this->tableName = $tableName; // @TODO remove alias if exists } else { $this->tableName = ''; @@ -508,7 +508,7 @@ protected function maxMinAvgSum(string $select = '', string $alias = '', string throw DataException::forEmptyInputGiven('Select'); } - if (strpos($select, ',') !== false) { + if (str_contains($select, ',')) { throw DataException::forInvalidArgument('column name not separated by comma'); } @@ -535,7 +535,7 @@ protected function maxMinAvgSum(string $select = '', string $alias = '', string */ protected function createAliasFromTable(string $item): string { - if (strpos($item, '.') !== false) { + if (str_contains($item, '.')) { $item = explode('.', $item); return end($item); @@ -571,7 +571,7 @@ public function from($from, bool $overwrite = false): self } foreach ((array) $from as $table) { - if (strpos($table, ',') !== false) { + if (str_contains($table, ',')) { $this->from(explode(',', $table)); } else { $table = trim($table); @@ -760,7 +760,7 @@ protected function whereHaving(string $qbKey, $key, $value = null, string $type $op = trim(current($op)); // Does the key end with operator? - if (substr($k, -strlen($op)) === $op) { + if (str_ends_with($k, $op)) { $k = rtrim(substr($k, 0, -strlen($op))); $op = " {$op}"; } else { @@ -2318,7 +2318,7 @@ public function insert($set = null, ?bool $escape = null) */ protected function removeAlias(string $from): string { - if (strpos($from, ' ') !== false) { + if (str_contains($from, ' ')) { // if the alias is written with the AS keyword, remove it $from = preg_replace('/\s+AS\s+/i', ' ', $from); @@ -2966,12 +2966,12 @@ protected function trackAliases($table) // Does the string contain a comma? If so, we need to separate // the string into discreet statements - if (strpos($table, ',') !== false) { + if (str_contains($table, ',')) { return $this->trackAliases(explode(',', $table)); } // if a table alias is used we can recognize it by a space - if (strpos($table, ' ') !== false) { + if (str_contains($table, ' ')) { // if the alias is written with the AS keyword, remove it $table = preg_replace('/\s+AS\s+/i', ' ', $table); @@ -3111,11 +3111,11 @@ protected function compileWhereHaving(string $qbKey): string if (! empty($matches[4])) { $protectIdentifiers = false; - if (strpos($matches[4], '.') !== false) { + if (str_contains($matches[4], '.')) { $protectIdentifiers = true; } - if (strpos($matches[4], ':') === false) { + if (! str_contains($matches[4], ':')) { $matches[4] = $this->db->protectIdentifiers(trim($matches[4]), false, $protectIdentifiers); } diff --git a/system/Database/BaseConnection.php b/system/Database/BaseConnection.php index 6d92965f0b94..fd2c278a084f 100644 --- a/system/Database/BaseConnection.php +++ b/system/Database/BaseConnection.php @@ -1067,7 +1067,7 @@ public function protectIdentifiers($item, bool $prefixSingle = false, ?bool $pro // Break the string apart if it contains periods, then insert the table prefix // in the correct location, assuming the period doesn't indicate that we're dealing // with an alias. While we're at it, we will escape the components - if (strpos($item, '.') !== false) { + if (str_contains($item, '.')) { return $this->protectDotItem($item, $alias, $protectIdentifiers, $fieldExists); } @@ -1079,11 +1079,11 @@ public function protectIdentifiers($item, bool $prefixSingle = false, ?bool $pro // Is there a table prefix? If not, no need to insert it if ($this->DBPrefix !== '') { // Verify table prefix and replace if necessary - if ($this->swapPre !== '' && strpos($item, $this->swapPre) === 0) { + if ($this->swapPre !== '' && str_starts_with($item, $this->swapPre)) { $item = preg_replace('/^' . $this->swapPre . '(\S+?)/', $this->DBPrefix . '\\1', $item); } // Do we prefix an item with no segments? - elseif ($prefixSingle === true && strpos($item, $this->DBPrefix) !== 0) { + elseif ($prefixSingle === true && ! str_starts_with($item, $this->DBPrefix)) { $item = $this->DBPrefix . $item; } } @@ -1145,11 +1145,11 @@ private function protectDotItem(string $item, string $alias, bool $protectIdenti } // Verify table prefix and replace if necessary - if ($this->swapPre !== '' && strpos($parts[$i], $this->swapPre) === 0) { + if ($this->swapPre !== '' && str_starts_with($parts[$i], $this->swapPre)) { $parts[$i] = preg_replace('/^' . $this->swapPre . '(\S+?)/', $this->DBPrefix . '\\1', $parts[$i]); } // We only add the table prefix if it does not already exist - elseif (strpos($parts[$i], $this->DBPrefix) !== 0) { + elseif (! str_starts_with($parts[$i], $this->DBPrefix)) { $parts[$i] = $this->DBPrefix . $parts[$i]; } @@ -1192,7 +1192,7 @@ public function escapeIdentifiers($item) if (ctype_digit($item) || $item[0] === "'" || ($this->escapeChar !== '"' && $item[0] === '"') - || strpos($item, '(') !== false) { + || str_contains($item, '(')) { return $item; } @@ -1212,7 +1212,7 @@ public function escapeIdentifiers($item) foreach ($this->reservedIdentifiers as $id) { /** @psalm-suppress NoValue I don't know why ERROR. */ - if (strpos($item, '.' . $id) !== false) { + if (str_contains($item, '.' . $id)) { return preg_replace( '/' . $this->pregEscapeChar[0] . '?([^' . $this->pregEscapeChar[1] . '\.]+)' . $this->pregEscapeChar[1] . '?\./i', $this->pregEscapeChar[2] . '$1' . $this->pregEscapeChar[3] . '.', @@ -1358,7 +1358,7 @@ public function callFunction(string $functionName, ...$params): bool { $driver = $this->getDriverFunctionPrefix(); - if (strpos($driver, $functionName) === false) { + if (! str_contains($driver, $functionName)) { $functionName = $driver . $functionName; } diff --git a/system/Database/Database.php b/system/Database/Database.php index 2818fe220928..7d8921663faf 100644 --- a/system/Database/Database.php +++ b/system/Database/Database.php @@ -44,7 +44,7 @@ public function load(array $params = [], string $alias = '') throw new InvalidArgumentException('You must supply the parameter: alias.'); } - if (! empty($params['DSN']) && strpos($params['DSN'], '://') !== false) { + if (! empty($params['DSN']) && str_contains($params['DSN'], '://')) { $params = $this->parseDSN($params); } @@ -130,7 +130,7 @@ protected function parseDSN(array $params): array */ protected function initDriver(string $driver, string $class, $argument): object { - $classname = (strpos($driver, '\\') === false) + $classname = (! str_contains($driver, '\\')) ? "CodeIgniter\\Database\\{$driver}\\{$class}" : $driver . '\\' . $class; diff --git a/system/Database/Forge.php b/system/Database/Forge.php index 57e43bf199fe..cb0e21c64911 100644 --- a/system/Database/Forge.php +++ b/system/Database/Forge.php @@ -368,7 +368,7 @@ public function addField($field) ]); $this->addKey('id', true); } else { - if (strpos($field, ' ') === false) { + if (! str_contains($field, ' ')) { throw new InvalidArgumentException('Field information is required for that operation.'); } @@ -624,7 +624,7 @@ public function dropTable(string $tableName, bool $ifExists = false, bool $casca return false; } - if ($this->db->DBPrefix && strpos($tableName, $this->db->DBPrefix) === 0) { + if ($this->db->DBPrefix && str_starts_with($tableName, $this->db->DBPrefix)) { $tableName = substr($tableName, strlen($this->db->DBPrefix)); } diff --git a/system/Database/MigrationRunner.php b/system/Database/MigrationRunner.php index 4b342eeaac39..0beac62fe701 100644 --- a/system/Database/MigrationRunner.php +++ b/system/Database/MigrationRunner.php @@ -447,7 +447,7 @@ public function findNamespaceMigrations(string $namespace): array */ protected function migrationFromFile(string $path, string $namespace) { - if (substr($path, -4) !== '.php') { + if (! str_ends_with($path, '.php')) { return false; } diff --git a/system/Database/OCI8/Connection.php b/system/Database/OCI8/Connection.php index 8cb7e3a4a766..510655f38686 100644 --- a/system/Database/OCI8/Connection.php +++ b/system/Database/OCI8/Connection.php @@ -221,7 +221,7 @@ protected function execute(string $sql) public function parseInsertTableName(string $sql): string { $commentStrippedSql = preg_replace(['/\/\*(.|\n)*?\*\//m', '/--.+/'], '', $sql); - $isInsertQuery = strpos(strtoupper(ltrim($commentStrippedSql)), 'INSERT') === 0; + $isInsertQuery = str_starts_with(strtoupper(ltrim($commentStrippedSql)), 'INSERT'); if (! $isInsertQuery) { return ''; @@ -230,7 +230,7 @@ public function parseInsertTableName(string $sql): string preg_match('/(?is)\b(?:into)\s+("?\w+"?)/', $commentStrippedSql, $match); $tableName = $match[1] ?? ''; - return strpos($tableName, '"') === 0 ? trim($tableName, '"') : strtoupper($tableName); + return str_starts_with($tableName, '"') ? trim($tableName, '"') : strtoupper($tableName); } /** @@ -267,7 +267,7 @@ protected function _listTables(bool $prefixLimit = false, ?string $tableName = n */ protected function _listColumns(string $table = ''): string { - if (strpos($table, '.') !== false) { + if (str_contains($table, '.')) { sscanf($table, '%[^.].%s', $owner, $table); } else { $owner = $this->username; @@ -287,7 +287,7 @@ protected function _listColumns(string $table = ''): string */ protected function _fieldData(string $table): array { - if (strpos($table, '.') !== false) { + if (str_contains($table, '.')) { sscanf($table, '%[^.].%s', $owner, $table); } else { $owner = $this->username; @@ -335,7 +335,7 @@ protected function _fieldData(string $table): array */ protected function _indexData(string $table): array { - if (strpos($table, '.') !== false) { + if (str_contains($table, '.')) { sscanf($table, '%[^.].%s', $owner, $table); } else { $owner = $this->username; @@ -633,7 +633,7 @@ protected function buildDSN() return; } - $isEasyConnectableHostName = $this->hostname !== '' && strpos($this->hostname, '/') === false && strpos($this->hostname, ':') === false; + $isEasyConnectableHostName = $this->hostname !== '' && ! str_contains($this->hostname, '/') && ! str_contains($this->hostname, ':'); $easyConnectablePort = ! empty($this->port) && ctype_digit($this->port) ? ':' . $this->port : ''; $easyConnectableDatabase = $this->database !== '' ? '/' . ltrim($this->database, '/') : ''; diff --git a/system/Database/OCI8/Forge.php b/system/Database/OCI8/Forge.php index 6e1e85f666a1..be2dc2181f0c 100644 --- a/system/Database/OCI8/Forge.php +++ b/system/Database/OCI8/Forge.php @@ -122,7 +122,7 @@ protected function _alterTable(string $alterType, string $table, $field) // so add null constraint is used only when it is different from the current null constraint. // If a not null constraint is added to a column with a not null constraint, // ORA-01442 will occur. - $wantToAddNull = strpos($field[$i]['null'], ' NOT') === false; + $wantToAddNull = ! str_contains($field[$i]['null'], ' NOT'); $currentNullable = $nullableMap[$field[$i]['name']]; if ($wantToAddNull === true && $currentNullable === true) { @@ -188,7 +188,7 @@ protected function _processColumn(array $field): string { $constraint = ''; // @todo: can't cover multi pattern when set type. - if ($field['type'] === 'VARCHAR2' && strpos($field['length'], "('") === 0) { + if ($field['type'] === 'VARCHAR2' && str_starts_with($field['length'], "('")) { $constraint = ' CHECK(' . $this->db->escapeIdentifiers($field['name']) . ' IN ' . $field['length'] . ')'; diff --git a/system/Database/Postgre/Connection.php b/system/Database/Postgre/Connection.php index 56905ec922d2..53fe40ea4ca0 100644 --- a/system/Database/Postgre/Connection.php +++ b/system/Database/Postgre/Connection.php @@ -353,10 +353,10 @@ protected function _indexData(string $table): array $_fields = explode(',', preg_replace('/^.*\((.+?)\)$/', '$1', trim($row->indexdef))); $obj->fields = array_map(static fn ($v) => trim($v), $_fields); - if (strpos($row->indexdef, 'CREATE UNIQUE INDEX pk') === 0) { + if (str_starts_with($row->indexdef, 'CREATE UNIQUE INDEX pk')) { $obj->type = 'PRIMARY'; } else { - $obj->type = (strpos($row->indexdef, 'CREATE UNIQUE') === 0) ? 'UNIQUE' : 'INDEX'; + $obj->type = (str_starts_with($row->indexdef, 'CREATE UNIQUE')) ? 'UNIQUE' : 'INDEX'; } $retVal[$obj->name] = $obj; @@ -493,7 +493,7 @@ protected function buildDSN() } // If UNIX sockets are used, we shouldn't set a port - if (strpos($this->hostname, '/') !== false) { + if (str_contains($this->hostname, '/')) { $this->port = ''; } diff --git a/system/Database/Query.php b/system/Database/Query.php index 897a668f1376..898951e09bce 100644 --- a/system/Database/Query.php +++ b/system/Database/Query.php @@ -11,10 +11,12 @@ namespace CodeIgniter\Database; +use Stringable; + /** * Query builder */ -class Query implements QueryInterface +class Query implements QueryInterface, Stringable { /** * The query string, as provided by the user. diff --git a/system/Database/RawSql.php b/system/Database/RawSql.php index efa97d30736c..e45921d42e7a 100644 --- a/system/Database/RawSql.php +++ b/system/Database/RawSql.php @@ -11,10 +11,12 @@ namespace CodeIgniter\Database; +use Stringable; + /** * @see \CodeIgniter\Database\RawSqlTest */ -class RawSql +class RawSql implements Stringable { /** * @var string Raw SQL string diff --git a/system/Database/SQLSRV/Builder.php b/system/Database/SQLSRV/Builder.php index 5e3e4a73bb11..b2c207f6dc3f 100755 --- a/system/Database/SQLSRV/Builder.php +++ b/system/Database/SQLSRV/Builder.php @@ -69,7 +69,7 @@ protected function _fromTables(): string $from = []; foreach ($this->QBFrom as $value) { - $from[] = strpos($value, '(SELECT') === 0 ? $value : $this->getFullName($value); + $from[] = str_starts_with($value, '(SELECT') ? $value : $this->getFullName($value); } return implode(', ', $from); @@ -280,7 +280,7 @@ private function getFullName(string $table): string { $alias = ''; - if (strpos($table, ' ') !== false) { + if (str_contains($table, ' ')) { $alias = explode(' ', $table); $table = array_shift($alias); $alias = ' ' . implode(' ', $alias); @@ -439,7 +439,7 @@ protected function maxMinAvgSum(string $select = '', string $alias = '', string throw DataException::forEmptyInputGiven('Select'); } - if (strpos($select, ',') !== false) { + if (str_contains($select, ',')) { throw DataException::forInvalidArgument('Column name not separated by comma'); } diff --git a/system/Database/SQLSRV/Connection.php b/system/Database/SQLSRV/Connection.php index f1a9fb0b433a..784f527790a1 100755 --- a/system/Database/SQLSRV/Connection.php +++ b/system/Database/SQLSRV/Connection.php @@ -121,7 +121,7 @@ public function connect(bool $persistent = false) unset($connection['UID'], $connection['PWD']); } - if (strpos($this->hostname, ',') === false && $this->port !== '') { + if (! str_contains($this->hostname, ',') && $this->port !== '') { $this->hostname .= ', ' . $this->port; } @@ -253,10 +253,10 @@ protected function _indexData(string $table): array $_fields = explode(',', trim($row->index_keys)); $obj->fields = array_map(static fn ($v) => trim($v), $_fields); - if (strpos($row->index_description, 'primary key located on') !== false) { + if (str_contains($row->index_description, 'primary key located on')) { $obj->type = 'PRIMARY'; } else { - $obj->type = (strpos($row->index_description, 'nonclustered, unique') !== false) ? 'UNIQUE' : 'INDEX'; + $obj->type = (str_contains($row->index_description, 'nonclustered, unique')) ? 'UNIQUE' : 'INDEX'; } $retVal[$obj->name] = $obj; diff --git a/system/Database/SQLite3/Connection.php b/system/Database/SQLite3/Connection.php index f41c8e4de792..dcebba75a9ab 100644 --- a/system/Database/SQLite3/Connection.php +++ b/system/Database/SQLite3/Connection.php @@ -81,7 +81,7 @@ public function connect(bool $persistent = false) } try { - if ($this->database !== ':memory:' && strpos($this->database, DIRECTORY_SEPARATOR) === false) { + if ($this->database !== ':memory:' && ! str_contains($this->database, DIRECTORY_SEPARATOR)) { $this->database = WRITEPATH . $this->database; } diff --git a/system/Database/SQLite3/Forge.php b/system/Database/SQLite3/Forge.php index b1dcb1dd599b..6487c94bbc4c 100644 --- a/system/Database/SQLite3/Forge.php +++ b/system/Database/SQLite3/Forge.php @@ -143,7 +143,7 @@ protected function _alterTable(string $alterType, string $table, $field) */ protected function _processColumn(array $field): string { - if ($field['type'] === 'TEXT' && strpos($field['length'], "('") === 0) { + if ($field['type'] === 'TEXT' && str_starts_with($field['length'], "('")) { $field['type'] .= ' CHECK(' . $this->db->escapeIdentifiers($field['name']) . ' IN ' . $field['length'] . ')'; } diff --git a/system/Database/SQLite3/Table.php b/system/Database/SQLite3/Table.php index 879437da6f6a..9d3d1034119c 100644 --- a/system/Database/SQLite3/Table.php +++ b/system/Database/SQLite3/Table.php @@ -96,7 +96,7 @@ public function fromTable(string $table) $prefix = $this->db->DBPrefix; - if (! empty($prefix) && strpos($table, $prefix) === 0) { + if (! empty($prefix) && str_starts_with($table, $prefix)) { $table = substr($table, strlen($prefix)); } diff --git a/system/Database/Seeder.php b/system/Database/Seeder.php index 749f6f34d5c7..ebd65e5a0387 100644 --- a/system/Database/Seeder.php +++ b/system/Database/Seeder.php @@ -123,7 +123,7 @@ public function call(string $class) throw new InvalidArgumentException('No seeder was specified.'); } - if (strpos($class, '\\') === false) { + if (! str_contains($class, '\\')) { $path = $this->seedPath . str_replace('.php', '', $class) . '.php'; if (! is_file($path)) { diff --git a/system/Debug/BaseExceptionHandler.php b/system/Debug/BaseExceptionHandler.php index 8b67d2153f9f..fcd6429b07d2 100644 --- a/system/Debug/BaseExceptionHandler.php +++ b/system/Debug/BaseExceptionHandler.php @@ -81,8 +81,8 @@ protected function collectVars(Throwable $exception, int $statusCode): array } return [ - 'title' => get_class($exception), - 'type' => get_class($exception), + 'title' => $exception::class, + 'type' => $exception::class, 'code' => $statusCode, 'message' => $exception->getMessage(), 'file' => $exception->getFile(), @@ -114,7 +114,7 @@ private function maskData($args, array $keysToMask, string $path = '') $explode = explode('/', $keyToMask); $index = end($explode); - if (strpos(strrev($path . '/' . $index), strrev($keyToMask)) === 0) { + if (str_starts_with(strrev($path . '/' . $index), strrev($keyToMask))) { if (is_array($args) && array_key_exists($index, $args)) { $args[$index] = '******************'; } elseif ( @@ -176,7 +176,7 @@ protected static function highlightFile(string $file, int $lineNumber, int $line try { $source = file_get_contents($file); - } catch (Throwable $e) { + } catch (Throwable) { return false; } diff --git a/system/Debug/ExceptionHandler.php b/system/Debug/ExceptionHandler.php index 63449888ffb5..51e85db3013c 100644 --- a/system/Debug/ExceptionHandler.php +++ b/system/Debug/ExceptionHandler.php @@ -54,7 +54,7 @@ public function handle( if ($request instanceof IncomingRequest) { try { $response->setStatusCode($statusCode); - } catch (HTTPException $e) { + } catch (HTTPException) { // Workaround for invalid HTTP status code. $statusCode = 500; $response->setStatusCode($statusCode); @@ -73,7 +73,7 @@ public function handle( ); } - if (strpos($request->getHeaderLine('accept'), 'text/html') === false) { + if (! str_contains($request->getHeaderLine('accept'), 'text/html')) { $data = (ENVIRONMENT === 'development' || ENVIRONMENT === 'testing') ? $this->collectVars($exception, $statusCode) : ''; diff --git a/system/Debug/Exceptions.php b/system/Debug/Exceptions.php index da5ce9373753..0c00db0e40e1 100644 --- a/system/Debug/Exceptions.php +++ b/system/Debug/Exceptions.php @@ -173,7 +173,7 @@ public function exceptionHandler(Throwable $exception) if (! is_cli()) { try { $this->response->setStatusCode($statusCode); - } catch (HTTPException $e) { + } catch (HTTPException) { // Workaround for invalid HTTP status code. $statusCode = 500; $this->response->setStatusCode($statusCode); @@ -183,7 +183,7 @@ public function exceptionHandler(Throwable $exception) header(sprintf('HTTP/%s %s %s', $this->request->getProtocolVersion(), $this->response->getStatusCode(), $this->response->getReasonPhrase()), true, $statusCode); } - if (strpos($this->request->getHeaderLine('accept'), 'text/html') === false) { + if (! str_contains($this->request->getHeaderLine('accept'), 'text/html')) { $this->respond(ENVIRONMENT === 'development' ? $this->collectVars($exception, $statusCode) : '', $statusCode)->send(); exit($exitCode); @@ -241,7 +241,7 @@ public function shutdownHandler() if ($this->exceptionCaughtByExceptionHandler instanceof Throwable) { $message .= "\n【Previous Exception】\n" - . get_class($this->exceptionCaughtByExceptionHandler) . "\n" + . $this->exceptionCaughtByExceptionHandler::class . "\n" . $this->exceptionCaughtByExceptionHandler->getMessage() . "\n" . $this->exceptionCaughtByExceptionHandler->getTraceAsString(); } @@ -353,8 +353,8 @@ protected function collectVars(Throwable $exception, int $statusCode): array } return [ - 'title' => get_class($exception), - 'type' => get_class($exception), + 'title' => $exception::class, + 'type' => $exception::class, 'code' => $statusCode, 'message' => $exception->getMessage(), 'file' => $exception->getFile(), @@ -394,7 +394,7 @@ private function maskData($args, array $keysToMask, string $path = '') $explode = explode('/', $keyToMask); $index = end($explode); - if (strpos(strrev($path . '/' . $index), strrev($keyToMask)) === 0) { + if (str_starts_with(strrev($path . '/' . $index), strrev($keyToMask))) { if (is_array($args) && array_key_exists($index, $args)) { $args[$index] = '******************'; } elseif ( @@ -478,25 +478,13 @@ private function handleDeprecationError(string $message, ?string $file = null, ? */ public static function cleanPath(string $file): string { - switch (true) { - case strpos($file, APPPATH) === 0: - $file = 'APPPATH' . DIRECTORY_SEPARATOR . substr($file, strlen(APPPATH)); - break; - - case strpos($file, SYSTEMPATH) === 0: - $file = 'SYSTEMPATH' . DIRECTORY_SEPARATOR . substr($file, strlen(SYSTEMPATH)); - break; - - case strpos($file, FCPATH) === 0: - $file = 'FCPATH' . DIRECTORY_SEPARATOR . substr($file, strlen(FCPATH)); - break; - - case defined('VENDORPATH') && strpos($file, VENDORPATH) === 0: - $file = 'VENDORPATH' . DIRECTORY_SEPARATOR . substr($file, strlen(VENDORPATH)); - break; - } - - return $file; + return match (true) { + str_starts_with($file, APPPATH) => 'APPPATH' . DIRECTORY_SEPARATOR . substr($file, strlen(APPPATH)), + str_starts_with($file, SYSTEMPATH) => 'SYSTEMPATH' . DIRECTORY_SEPARATOR . substr($file, strlen(SYSTEMPATH)), + str_starts_with($file, FCPATH) => 'FCPATH' . DIRECTORY_SEPARATOR . substr($file, strlen(FCPATH)), + defined('VENDORPATH') && str_starts_with($file, VENDORPATH) => 'VENDORPATH' . DIRECTORY_SEPARATOR . substr($file, strlen(VENDORPATH)), + default => $file, + }; } /** @@ -542,7 +530,7 @@ public static function highlightFile(string $file, int $lineNumber, int $lines = try { $source = file_get_contents($file); - } catch (Throwable $e) { + } catch (Throwable) { return false; } @@ -607,23 +595,12 @@ private static function renderBacktrace(array $backtrace): string $idx = $index; $idx = str_pad((string) ++$idx, 2, ' ', STR_PAD_LEFT); - $args = implode(', ', array_map(static function ($value): string { - switch (true) { - case is_object($value): - return sprintf('Object(%s)', get_class($value)); - - case is_array($value): - return $value !== [] ? '[...]' : '[]'; - - case $value === null: - return 'null'; - - case is_resource($value): - return sprintf('resource (%s)', get_resource_type($value)); - - default: - return var_export($value, true); - } + $args = implode(', ', array_map(static fn ($value): string => match (true) { + is_object($value) => sprintf('Object(%s)', $value::class), + is_array($value) => $value !== [] ? '[...]' : '[]', + $value === null => 'null', + is_resource($value) => sprintf('resource (%s)', get_resource_type($value)), + default => var_export($value, true), }, $frame['args'])); $backtraces[] = sprintf( diff --git a/system/Debug/Toolbar.php b/system/Debug/Toolbar.php index 3f846a36d2e7..3cf0566cca07 100644 --- a/system/Debug/Toolbar.php +++ b/system/Debug/Toolbar.php @@ -408,7 +408,7 @@ public function prepare(?RequestInterface $request = null, ?ResponseInterface $r // Non-HTML formats should not include the debugbar // then we send headers saying where to find the debug data // for this response - if ($request->isAJAX() || strpos($format, 'html') === false) { + if ($request->isAJAX() || ! str_contains($format, 'html')) { $response->setHeader('Debugbar-Time', "{$time}") ->setHeader('Debugbar-Link', site_url("?debugbar_time={$time}")); @@ -431,7 +431,7 @@ public function prepare(?RequestInterface $request = null, ?ResponseInterface $r . $kintScript . PHP_EOL; - if (strpos($response->getBody(), '') !== false) { + if (str_contains($response->getBody(), '')) { $response->setBody( preg_replace( '//', diff --git a/system/Debug/Toolbar/Collectors/Database.php b/system/Debug/Toolbar/Collectors/Database.php index b527f2ed3c95..93178f95d9c2 100644 --- a/system/Debug/Toolbar/Collectors/Database.php +++ b/system/Debug/Toolbar/Collectors/Database.php @@ -161,7 +161,7 @@ public function display(): array } // find the first trace line that does not originate from `system/` - if ($firstNonSystemLine === '' && strpos($line['file'], 'SYSTEMPATH') === false) { + if ($firstNonSystemLine === '' && ! str_contains($line['file'], 'SYSTEMPATH')) { $firstNonSystemLine = $line['file']; } diff --git a/system/Debug/Toolbar/Collectors/Files.php b/system/Debug/Toolbar/Collectors/Files.php index c281906cdd28..4461b4b667d8 100644 --- a/system/Debug/Toolbar/Collectors/Files.php +++ b/system/Debug/Toolbar/Collectors/Files.php @@ -60,7 +60,7 @@ public function display(): array foreach ($rawFiles as $file) { $path = clean_path($file); - if (strpos($path, 'SYSTEMPATH') !== false) { + if (str_contains($path, 'SYSTEMPATH')) { $coreFiles[] = [ 'path' => $path, 'name' => basename($file), diff --git a/system/Debug/Toolbar/Collectors/Routes.php b/system/Debug/Toolbar/Collectors/Routes.php index 46aa91644004..c80ef7948fdf 100644 --- a/system/Debug/Toolbar/Collectors/Routes.php +++ b/system/Debug/Toolbar/Collectors/Routes.php @@ -63,7 +63,7 @@ public function display(): array } else { try { $method = new ReflectionMethod($router->controllerName(), $router->methodName()); - } catch (ReflectionException $e) { + } catch (ReflectionException) { try { // If we're here, the method doesn't exist // and is likely calculated in _remap. diff --git a/system/Email/Email.php b/system/Email/Email.php index 27e5bc83b683..9246da0cd794 100644 --- a/system/Email/Email.php +++ b/system/Email/Email.php @@ -658,7 +658,7 @@ public function setMessage($body) public function attach($file, $disposition = '', $newname = null, $mime = '') { if ($mime === '') { - if (strpos($file, '://') === false && ! is_file($file)) { + if (! str_contains($file, '://') && ! is_file($file)) { $this->setErrorMessage(lang('Email.attachmentMissing', [$file])); return false; @@ -738,7 +738,7 @@ public function setHeader($header, $value) protected function stringToArray($email) { if (! is_array($email)) { - return (strpos($email, ',') !== false) ? preg_split('/[\s,]/', $email, -1, PREG_SPLIT_NO_EMPTY) : (array) trim($email); + return (str_contains($email, ',')) ? preg_split('/[\s,]/', $email, -1, PREG_SPLIT_NO_EMPTY) : (array) trim($email); } return $email; @@ -862,7 +862,7 @@ protected function getEncoding() } foreach ($this->baseCharsets as $charset) { - if (strpos($this->charset, $charset) === 0) { + if (str_starts_with($this->charset, $charset)) { $this->encoding = '7bit'; break; @@ -1011,7 +1011,7 @@ public function wordWrap($str, $charlim = null) $charlim = empty($this->wrapChars) ? 76 : $this->wrapChars; } - if (strpos($str, "\r") !== false) { + if (str_contains($str, "\r")) { $str = str_replace(["\r\n", "\r"], "\n", $str); } @@ -1409,7 +1409,7 @@ protected function prepQuotedPrintable($str) $str = preg_replace(['| +|', '/\x00+/'], [' ', ''], $str); // Standardize newlines - if (strpos($str, "\r") !== false) { + if (str_contains($str, "\r")) { $str = str_replace(["\r\n", "\r"], "\n", $str); } @@ -1661,7 +1661,7 @@ protected function unwrapSpecials() */ protected function removeNLCallback($matches) { - if (strpos($matches[1], "\r") !== false || strpos($matches[1], "\n") !== false) { + if (str_contains($matches[1], "\r") || str_contains($matches[1], "\n")) { $matches[1] = str_replace(["\r\n", "\r", "\n"], '', $matches[1]); } @@ -1842,7 +1842,7 @@ protected function sendWithSmtp() $this->setErrorMessage($reply); $this->SMTPEnd(); - if (strpos($reply, '250') !== 0) { + if (! str_starts_with($reply, '250')) { $this->setErrorMessage(lang('Email.SMTPError', [$reply])); return false; @@ -2014,11 +2014,11 @@ protected function SMTPAuthenticate() $this->sendData('AUTH LOGIN'); $reply = $this->getSMTPData(); - if (strpos($reply, '503') === 0) { // Already authenticated + if (str_starts_with($reply, '503')) { // Already authenticated return true; } - if (strpos($reply, '334') !== 0) { + if (! str_starts_with($reply, '334')) { $this->setErrorMessage(lang('Email.failedSMTPLogin', [$reply])); return false; @@ -2027,7 +2027,7 @@ protected function SMTPAuthenticate() $this->sendData(base64_encode($this->SMTPUser)); $reply = $this->getSMTPData(); - if (strpos($reply, '334') !== 0) { + if (! str_starts_with($reply, '334')) { $this->setErrorMessage(lang('Email.SMTPAuthUsername', [$reply])); return false; @@ -2036,7 +2036,7 @@ protected function SMTPAuthenticate() $this->sendData(base64_encode($this->SMTPPass)); $reply = $this->getSMTPData(); - if (strpos($reply, '235') !== 0) { + if (! str_starts_with($reply, '235')) { $this->setErrorMessage(lang('Email.SMTPAuthPassword', [$reply])); return false; diff --git a/system/Entity/Cast/ArrayCast.php b/system/Entity/Cast/ArrayCast.php index 315f2e582fec..d68d17c187de 100644 --- a/system/Entity/Cast/ArrayCast.php +++ b/system/Entity/Cast/ArrayCast.php @@ -21,7 +21,7 @@ class ArrayCast extends BaseCast */ public static function get($value, array $params = []): array { - if (is_string($value) && (strpos($value, 'a:') === 0 || strpos($value, 's:') === 0)) { + if (is_string($value) && (str_starts_with($value, 'a:') || str_starts_with($value, 's:'))) { $value = unserialize($value); } diff --git a/system/Entity/Entity.php b/system/Entity/Entity.php index 90d3ab46a297..12db7a97a059 100644 --- a/system/Entity/Entity.php +++ b/system/Entity/Entity.php @@ -167,7 +167,7 @@ public function toArray(bool $onlyChanged = false, bool $cast = true, bool $recu { $this->_cast = $cast; - $keys = array_filter(array_keys($this->attributes), static fn ($key) => strpos($key, '_') !== 0); + $keys = array_filter(array_keys($this->attributes), static fn ($key) => ! str_starts_with($key, '_')); if (is_array($this->datamap)) { $keys = array_unique( @@ -368,7 +368,7 @@ protected function castAs($value, string $attribute, string $method = 'get') $isNullable = false; - if (strpos($type, '?') === 0) { + if (str_starts_with($type, '?')) { $isNullable = true; if ($value === null) { diff --git a/system/Entity/Exceptions/CastException.php b/system/Entity/Exceptions/CastException.php index e259447b3f76..4bcb62be8067 100644 --- a/system/Entity/Exceptions/CastException.php +++ b/system/Entity/Exceptions/CastException.php @@ -41,25 +41,14 @@ public static function forInvalidInterface(string $class) */ public static function forInvalidJsonFormat(int $error) { - switch ($error) { - case JSON_ERROR_DEPTH: - return new static(lang('Cast.jsonErrorDepth')); - - case JSON_ERROR_STATE_MISMATCH: - return new static(lang('Cast.jsonErrorStateMismatch')); - - case JSON_ERROR_CTRL_CHAR: - return new static(lang('Cast.jsonErrorCtrlChar')); - - case JSON_ERROR_SYNTAX: - return new static(lang('Cast.jsonErrorSyntax')); - - case JSON_ERROR_UTF8: - return new static(lang('Cast.jsonErrorUtf8')); - - default: - return new static(lang('Cast.jsonErrorUnknown')); - } + return match ($error) { + JSON_ERROR_DEPTH => new static(lang('Cast.jsonErrorDepth')), + JSON_ERROR_STATE_MISMATCH => new static(lang('Cast.jsonErrorStateMismatch')), + JSON_ERROR_CTRL_CHAR => new static(lang('Cast.jsonErrorCtrlChar')), + JSON_ERROR_SYNTAX => new static(lang('Cast.jsonErrorSyntax')), + JSON_ERROR_UTF8 => new static(lang('Cast.jsonErrorUtf8')), + default => new static(lang('Cast.jsonErrorUnknown')), + }; } /** diff --git a/system/Exceptions/CastException.php b/system/Exceptions/CastException.php index 8dfb29543a78..e316f8726d9a 100644 --- a/system/Exceptions/CastException.php +++ b/system/Exceptions/CastException.php @@ -32,24 +32,13 @@ public function getExitCode(): int */ public static function forInvalidJsonFormatException(int $error) { - switch ($error) { - case JSON_ERROR_DEPTH: - return new static(lang('Cast.jsonErrorDepth')); - - case JSON_ERROR_STATE_MISMATCH: - return new static(lang('Cast.jsonErrorStateMismatch')); - - case JSON_ERROR_CTRL_CHAR: - return new static(lang('Cast.jsonErrorCtrlChar')); - - case JSON_ERROR_SYNTAX: - return new static(lang('Cast.jsonErrorSyntax')); - - case JSON_ERROR_UTF8: - return new static(lang('Cast.jsonErrorUtf8')); - - default: - return new static(lang('Cast.jsonErrorUnknown')); - } + return match ($error) { + JSON_ERROR_DEPTH => new static(lang('Cast.jsonErrorDepth')), + JSON_ERROR_STATE_MISMATCH => new static(lang('Cast.jsonErrorStateMismatch')), + JSON_ERROR_CTRL_CHAR => new static(lang('Cast.jsonErrorCtrlChar')), + JSON_ERROR_SYNTAX => new static(lang('Cast.jsonErrorSyntax')), + JSON_ERROR_UTF8 => new static(lang('Cast.jsonErrorUtf8')), + default => new static(lang('Cast.jsonErrorUnknown')), + }; } } diff --git a/system/Exceptions/FrameworkException.php b/system/Exceptions/FrameworkException.php index faf3f1480126..83f9cb2808b6 100644 --- a/system/Exceptions/FrameworkException.php +++ b/system/Exceptions/FrameworkException.php @@ -60,7 +60,7 @@ public static function forCopyError(string $path) */ public static function forMissingExtension(string $extension) { - if (strpos($extension, 'intl') !== false) { + if (str_contains($extension, 'intl')) { // @codeCoverageIgnoreStart $message = sprintf( 'The framework needs the following extension(s) installed and loaded: %s.', diff --git a/system/Files/File.php b/system/Files/File.php index 4e4ee388047e..d0842fb6bb7a 100644 --- a/system/Files/File.php +++ b/system/Files/File.php @@ -74,16 +74,11 @@ public function getSize() */ public function getSizeByUnit(string $unit = 'b') { - switch (strtolower($unit)) { - case 'kb': - return number_format($this->getSize() / 1024, 3); - - case 'mb': - return number_format(($this->getSize() / 1024) / 1024, 3); - - default: - return $this->getSize(); - } + return match (strtolower($unit)) { + 'kb' => number_format($this->getSize() / 1024, 3), + 'mb' => number_format(($this->getSize() / 1024) / 1024, 3), + default => $this->getSize(), + }; } /** @@ -173,7 +168,7 @@ public function getDestination(string $destination, string $delimiter = '_', int $info = pathinfo($destination); $extension = isset($info['extension']) ? '.' . $info['extension'] : ''; - if (strpos($info['filename'], $delimiter) !== false) { + if (str_contains($info['filename'], $delimiter)) { $parts = explode($delimiter, $info['filename']); if (is_numeric(end($parts))) { diff --git a/system/Files/FileCollection.php b/system/Files/FileCollection.php index 87f987eb8f1e..545f8997a3b0 100644 --- a/system/Files/FileCollection.php +++ b/system/Files/FileCollection.php @@ -83,7 +83,7 @@ final protected static function filterFiles(array $files, string $directory): ar { $directory = self::resolveDirectory($directory); - return array_filter($files, static fn (string $value): bool => strpos($value, $directory) === 0); + return array_filter($files, static fn (string $value): bool => str_starts_with($value, $directory)); } /** @@ -180,7 +180,7 @@ public function add($paths, bool $recursive = true) try { // Test for a directory self::resolveDirectory($path); - } catch (FileException $e) { + } catch (FileException) { $this->addFile($path); continue; diff --git a/system/Filters/Filters.php b/system/Filters/Filters.php index 25ca9a9ec5f7..6816e72ab482 100644 --- a/system/Filters/Filters.php +++ b/system/Filters/Filters.php @@ -192,7 +192,7 @@ private function runBefore(array $filterClasses) $class = new $className(); if (! $class instanceof FilterInterface) { - throw FilterException::forIncorrectInterface(get_class($class)); + throw FilterException::forIncorrectInterface($class::class); } $result = $class->before( @@ -485,7 +485,7 @@ private function getCleanName(string $name): array { $arguments = []; - if (strpos($name, ':') !== false) { + if (str_contains($name, ':')) { [$name, $arguments] = explode(':', $name); $arguments = explode(',', $arguments); diff --git a/system/HTTP/CURLRequest.php b/system/HTTP/CURLRequest.php index 35b62ec3486f..a73796af42b4 100644 --- a/system/HTTP/CURLRequest.php +++ b/system/HTTP/CURLRequest.php @@ -323,7 +323,7 @@ protected function parseOptions(array $options) protected function prepareURL(string $url): string { // If it's a full URI, then we have nothing to do here... - if (strpos($url, '://') !== false) { + if (str_contains($url, '://')) { return $url; } @@ -378,16 +378,16 @@ public function send(string $method, string $url) // Set the string we want to break our response from $breakString = "\r\n\r\n"; - if (strpos($output, 'HTTP/1.1 100 Continue') === 0) { + if (str_starts_with($output, 'HTTP/1.1 100 Continue')) { $output = substr($output, strpos($output, $breakString) + 4); } - if (strpos($output, 'HTTP/1.1 200 Connection established') === 0) { + if (str_starts_with($output, 'HTTP/1.1 200 Connection established')) { $output = substr($output, strpos($output, $breakString) + 4); } // If request and response have Digest - if (isset($this->config['auth'][2]) && $this->config['auth'][2] === 'digest' && strpos($output, 'WWW-Authenticate: Digest') !== false) { + if (isset($this->config['auth'][2]) && $this->config['auth'][2] === 'digest' && str_contains($output, 'WWW-Authenticate: Digest')) { $output = substr($output, strpos($output, $breakString) + 4); } @@ -487,7 +487,7 @@ protected function setResponseHeaders(array $headers = []) } else { $this->response->setHeader($title, $value); } - } elseif (strpos($header, 'HTTP') === 0) { + } elseif (str_starts_with($header, 'HTTP')) { preg_match('#^HTTP\/([12](?:\.[01])?) (\d+) (.+)#', $header, $matches); if (isset($matches[1])) { diff --git a/system/HTTP/ContentSecurityPolicy.php b/system/HTTP/ContentSecurityPolicy.php index 6a3caed925b8..82ee286716e7 100644 --- a/system/HTTP/ContentSecurityPolicy.php +++ b/system/HTTP/ContentSecurityPolicy.php @@ -800,7 +800,7 @@ protected function addToHeader(string $name, $values = null) $reportOnly = $this->reportOnly; } - if (strpos($value, 'nonce-') === 0) { + if (str_starts_with($value, 'nonce-')) { $value = "'{$value}'"; } diff --git a/system/HTTP/Files/FileCollection.php b/system/HTTP/Files/FileCollection.php index 7188d357b006..6de5f2d0f80d 100644 --- a/system/HTTP/Files/FileCollection.php +++ b/system/HTTP/Files/FileCollection.php @@ -57,7 +57,7 @@ public function getFile(string $name) $this->populateFiles(); if ($this->hasFile($name)) { - if (strpos($name, '.') !== false) { + if (str_contains($name, '.')) { $name = explode('.', $name); $uploadedFile = $this->getValueDotNotationSyntax($name, $this->files); @@ -84,7 +84,7 @@ public function getFileMultiple(string $name) $this->populateFiles(); if ($this->hasFile($name)) { - if (strpos($name, '.') !== false) { + if (str_contains($name, '.')) { $name = explode('.', $name); $uploadedFile = $this->getValueDotNotationSyntax($name, $this->files); @@ -113,7 +113,7 @@ public function hasFile(string $fileID): bool { $this->populateFiles(); - if (strpos($fileID, '.') !== false) { + if (str_contains($fileID, '.')) { $segments = explode('.', $fileID); $el = $this->files; diff --git a/system/HTTP/Files/UploadedFile.php b/system/HTTP/Files/UploadedFile.php index 70ece748d834..b81881c62cb3 100644 --- a/system/HTTP/Files/UploadedFile.php +++ b/system/HTTP/Files/UploadedFile.php @@ -151,7 +151,7 @@ public function move(string $targetPath, ?string $name = null, bool $overwrite = try { $this->hasMoved = move_uploaded_file($this->path, $destination); - } catch (Exception $e) { + } catch (Exception) { $error = error_get_last(); $message = strip_tags($error['message'] ?? ''); diff --git a/system/HTTP/Header.php b/system/HTTP/Header.php index b152509a1cee..0c27e65dbb33 100644 --- a/system/HTTP/Header.php +++ b/system/HTTP/Header.php @@ -11,6 +11,8 @@ namespace CodeIgniter\HTTP; +use Stringable; + /** * Class Header * @@ -18,7 +20,7 @@ * * @see \CodeIgniter\HTTP\HeaderTest */ -class Header +class Header implements Stringable { /** * The name of the header. diff --git a/system/HTTP/IncomingRequest.php b/system/HTTP/IncomingRequest.php index ee5aa8bd6ca0..be1342a9e94c 100755 --- a/system/HTTP/IncomingRequest.php +++ b/system/HTTP/IncomingRequest.php @@ -158,7 +158,7 @@ public function __construct($config, ?URI $uri = null, $body = 'php://input', ?U $body === 'php://input' // php://input is not available with enctype="multipart/form-data". // See https://www.php.net/manual/en/wrappers.php.php#wrappers.php.input - && strpos($this->getHeaderLine('Content-Type'), 'multipart/form-data') === false + && ! str_contains($this->getHeaderLine('Content-Type'), 'multipart/form-data') && (int) $this->getHeaderLine('Content-Length') <= $this->getPostMaxSize() ) { // Get our body from php://input @@ -191,24 +191,12 @@ private function getPostMaxSize(): int { $postMaxSize = ini_get('post_max_size'); - switch (strtoupper(substr($postMaxSize, -1))) { - case 'G': - $postMaxSize = (int) str_replace('G', '', $postMaxSize) * 1024 ** 3; - break; - - case 'M': - $postMaxSize = (int) str_replace('M', '', $postMaxSize) * 1024 ** 2; - break; - - case 'K': - $postMaxSize = (int) str_replace('K', '', $postMaxSize) * 1024; - break; - - default: - $postMaxSize = (int) $postMaxSize; - } - - return $postMaxSize; + return match (strtoupper(substr($postMaxSize, -1))) { + 'G' => (int) str_replace('G', '', $postMaxSize) * 1024 ** 3, + 'M' => (int) str_replace('M', '', $postMaxSize) * 1024 ** 2, + 'K' => (int) str_replace('K', '', $postMaxSize) * 1024, + default => (int) $postMaxSize, + }; } /** @@ -256,20 +244,11 @@ public function detectPath(string $protocol = ''): string $protocol = 'REQUEST_URI'; } - switch ($protocol) { - case 'REQUEST_URI': - $this->path = $this->parseRequestURI(); - break; - - case 'QUERY_STRING': - $this->path = $this->parseQueryString(); - break; - - case 'PATH_INFO': - default: - $this->path = $this->fetchGlobal('server', $protocol) ?? $this->parseRequestURI(); - break; - } + $this->path = match ($protocol) { + 'REQUEST_URI' => $this->parseRequestURI(), + 'QUERY_STRING' => $this->parseQueryString(), + default => $this->fetchGlobal('server', $protocol) ?? $this->parseRequestURI(), + }; return $this->path; } @@ -317,7 +296,7 @@ protected function parseRequestURI(): string // This section ensures that even on servers that require the URI to contain the query string (Nginx) a correct // URI is found, and also fixes the QUERY_STRING Server var and $_GET array. - if (trim($uri, '/') === '' && strncmp($query, '/', 1) === 0) { + if (trim($uri, '/') === '' && str_starts_with($query, '/')) { $query = explode('?', $query, 2); $uri = $query[0]; $_SERVER['QUERY_STRING'] = $query[1] ?? ''; @@ -350,7 +329,7 @@ protected function parseQueryString(): string return '/'; } - if (strncmp($uri, '/', 1) === 0) { + if (str_starts_with($uri, '/')) { $uri = explode('?', $uri, 2); $_SERVER['QUERY_STRING'] = $uri[1] ?? ''; $uri = $uri[0]; @@ -376,21 +355,13 @@ public function negotiate(string $type, array $supported, bool $strictMatch = fa $this->negotiator = Services::negotiator($this, true); } - switch (strtolower($type)) { - case 'media': - return $this->negotiator->media($supported, $strictMatch); - - case 'charset': - return $this->negotiator->charset($supported); - - case 'encoding': - return $this->negotiator->encoding($supported); - - case 'language': - return $this->negotiator->language($supported); - } - - throw HTTPException::forInvalidNegotiationType($type); + return match (strtolower($type)) { + 'media' => $this->negotiator->media($supported, $strictMatch), + 'charset' => $this->negotiator->charset($supported), + 'encoding' => $this->negotiator->encoding($supported), + 'language' => $this->negotiator->language($supported), + default => throw HTTPException::forInvalidNegotiationType($type), + }; } /** @@ -410,7 +381,7 @@ public function is(string $type): bool } if ($valueUpper === 'JSON') { - return strpos($this->getHeaderLine('Content-Type'), 'application/json') !== false; + return str_contains($this->getHeaderLine('Content-Type'), 'application/json'); } if ($valueUpper === 'AJAX') { @@ -546,7 +517,7 @@ public function getDefaultLocale(): string public function getVar($index = null, $filter = null, $flags = null) { if ( - strpos($this->getHeaderLine('Content-Type'), 'application/json') !== false + str_contains($this->getHeaderLine('Content-Type'), 'application/json') && $this->body !== null ) { return $this->getJsonVar($index, false, $filter, $flags); diff --git a/system/HTTP/RedirectResponse.php b/system/HTTP/RedirectResponse.php index 8efd4c2c51ea..9c406df504cf 100644 --- a/system/HTTP/RedirectResponse.php +++ b/system/HTTP/RedirectResponse.php @@ -35,7 +35,7 @@ public function to(string $uri, ?int $code = null, string $method = 'auto') { // If it appears to be a relative URL, then convert to full URL // for better security. - if (strpos($uri, 'http') !== 0) { + if (! str_starts_with($uri, 'http')) { $uri = site_url($uri); } diff --git a/system/HTTP/RequestTrait.php b/system/HTTP/RequestTrait.php index 6db903ddacec..5609d786b23f 100644 --- a/system/HTTP/RequestTrait.php +++ b/system/HTTP/RequestTrait.php @@ -77,7 +77,7 @@ public function getIPAddress(): string // @TODO Extract all this IP address logic to another class. foreach ($proxyIPs as $proxyIP => $header) { // Check if we have an IP address or a subnet - if (strpos($proxyIP, '/') === false) { + if (! str_contains($proxyIP, '/')) { // An IP address (and not a subnet) is specified. // We can compare right away. if ($proxyIP === $this->ipAddress) { @@ -98,7 +98,7 @@ public function getIPAddress(): string } // If the proxy entry doesn't match the IP protocol - skip it - if (strpos($proxyIP, $separator) === false) { + if (! str_contains($proxyIP, $separator)) { continue; } diff --git a/system/HTTP/ResponseTrait.php b/system/HTTP/ResponseTrait.php index e5e006c776aa..e93d4279a428 100644 --- a/system/HTTP/ResponseTrait.php +++ b/system/HTTP/ResponseTrait.php @@ -447,7 +447,7 @@ public function redirect(string $uri, string $method = 'auto', ?int $code = null if ( $method === 'auto' && isset($_SERVER['SERVER_SOFTWARE']) - && strpos($_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS') !== false + && str_contains($_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS') ) { $method = 'refresh'; } elseif ($method !== 'refresh' && $code === null) { @@ -471,15 +471,10 @@ public function redirect(string $uri, string $method = 'auto', ?int $code = null $code = 302; } - switch ($method) { - case 'refresh': - $this->setHeader('Refresh', '0;url=' . $uri); - break; - - default: - $this->setHeader('Location', $uri); - break; - } + match ($method) { + 'refresh' => $this->setHeader('Refresh', '0;url=' . $uri), + default => $this->setHeader('Location', $uri), + }; $this->setStatusCode($code); diff --git a/system/HTTP/SiteURI.php b/system/HTTP/SiteURI.php index 6d56507314e7..43948ecbf33c 100644 --- a/system/HTTP/SiteURI.php +++ b/system/HTTP/SiteURI.php @@ -15,13 +15,14 @@ use CodeIgniter\Exceptions\ConfigException; use CodeIgniter\HTTP\Exceptions\HTTPException; use Config\App; +use Stringable; /** * URI for the application site * * @see \CodeIgniter\HTTP\SiteURITest */ -class SiteURI extends URI +class SiteURI extends URI implements Stringable { /** * The current baseURL. diff --git a/system/HTTP/SiteURIFactory.php b/system/HTTP/SiteURIFactory.php index 36b9d705b28c..fd4921be913c 100644 --- a/system/HTTP/SiteURIFactory.php +++ b/system/HTTP/SiteURIFactory.php @@ -95,20 +95,11 @@ public function detectRoutePath(string $protocol = ''): string $protocol = $this->appConfig->uriProtocol; } - switch ($protocol) { - case 'REQUEST_URI': - $routePath = $this->parseRequestURI(); - break; - - case 'QUERY_STRING': - $routePath = $this->parseQueryString(); - break; - - case 'PATH_INFO': - default: - $routePath = $this->superglobals->server($protocol) ?? $this->parseRequestURI(); - break; - } + $routePath = match ($protocol) { + 'REQUEST_URI' => $this->parseRequestURI(), + 'QUERY_STRING' => $this->parseQueryString(), + default => $this->superglobals->server($protocol) ?? $this->parseRequestURI(), + }; return ($routePath === '/' || $routePath === '') ? '/' : ltrim($routePath, '/'); } @@ -161,7 +152,7 @@ private function parseRequestURI(): string // This section ensures that even on servers that require the URI to // contain the query string (Nginx) a correct URI is found, and also // fixes the QUERY_STRING Server var and $_GET array. - if (trim($path, '/') === '' && strncmp($query, '/', 1) === 0) { + if (trim($path, '/') === '' && str_starts_with($query, '/')) { $parts = explode('?', $query, 2); $path = $parts[0]; $newQuery = $query[1] ?? ''; @@ -193,7 +184,7 @@ private function parseQueryString(): string return '/'; } - if (strncmp($query, '/', 1) === 0) { + if (str_starts_with($query, '/')) { $parts = explode('?', $query, 2); $path = $parts[0]; $newQuery = $parts[1] ?? ''; diff --git a/system/HTTP/URI.php b/system/HTTP/URI.php index 608f8b75d5ba..7d1913da8229 100644 --- a/system/HTTP/URI.php +++ b/system/HTTP/URI.php @@ -15,13 +15,14 @@ use CodeIgniter\HTTP\Exceptions\HTTPException; use Config\App; use InvalidArgumentException; +use Stringable; /** * Abstraction for a uniform resource identifier (URI). * * @see \CodeIgniter\HTTP\URITest */ -class URI +class URI implements Stringable { /** * Sub-delimiters used in query strings and fragments. @@ -172,7 +173,7 @@ public static function createURIString( } if (isset($path) && $path !== '') { - $uri .= substr($uri, -1, 1) !== '/' + $uri .= ! str_ends_with($uri, '/') ? '/' . ltrim($path, '/') : ltrim($path, '/'); } @@ -228,12 +229,12 @@ public static function removeDotSegments(string $path): string $output = trim($output, '/ '); // Add leading slash if necessary - if (strpos($path, '/') === 0) { + if (str_starts_with($path, '/')) { $output = '/' . $output; } // Add trailing slash if necessary - if ($output !== '/' && substr($path, -1, 1) === '/') { + if ($output !== '/' && str_ends_with($path, '/')) { $output .= '/'; } @@ -652,14 +653,14 @@ private function changeSchemeAndPath(string $scheme, string $path): array $baseUri = new self($config->baseURL); if ( - substr($this->getScheme(), 0, 4) === 'http' + str_starts_with($this->getScheme(), 'http') && $this->getHost() === $baseUri->getHost() ) { // Check for additional segments $basePath = trim($baseUri->getPath(), '/') . '/'; $trimPath = ltrim($path, '/'); - if ($basePath !== '/' && strpos($trimPath, $basePath) !== 0) { + if ($basePath !== '/' && ! str_starts_with($trimPath, $basePath)) { $path = $basePath . $trimPath; } @@ -877,7 +878,7 @@ public function refreshPath() */ public function setQuery(string $query) { - if (strpos($query, '#') !== false) { + if (str_contains($query, '#')) { if ($this->silent) { return $this; } @@ -886,7 +887,7 @@ public function setQuery(string $query) } // Can't have leading ? - if (! empty($query) && strpos($query, '?') === 0) { + if (! empty($query) && str_starts_with($query, '?')) { $query = substr($query, 1); } @@ -1008,10 +1009,10 @@ protected function filterPath(?string $path = null): string $path = self::removeDotSegments($path); // Fix up some leading slash edge cases... - if (strpos($orig, './') === 0) { + if (str_starts_with($orig, './')) { $path = '/' . $path; } - if (strpos($orig, '../') === 0) { + if (str_starts_with($orig, '../')) { $path = '/' . $path; } @@ -1112,7 +1113,7 @@ public function resolveRelativeURI(string $uri) $transformed->setQuery($this->getQuery()); } } else { - if (strpos($relative->getPath(), '/') === 0) { + if (str_starts_with($relative->getPath(), '/')) { $transformed->setPath($relative->getPath()); } else { $transformed->setPath($this->mergePaths($this, $relative)); diff --git a/system/HTTP/UserAgent.php b/system/HTTP/UserAgent.php index 77e7cb4392fc..4461ddc9db93 100644 --- a/system/HTTP/UserAgent.php +++ b/system/HTTP/UserAgent.php @@ -12,13 +12,14 @@ namespace CodeIgniter\HTTP; use Config\UserAgents; +use Stringable; /** * Abstraction for an HTTP user agent * * @see \CodeIgniter\HTTP\UserAgentTest */ -class UserAgent +class UserAgent implements Stringable { /** * Current user-agent diff --git a/system/Helpers/filesystem_helper.php b/system/Helpers/filesystem_helper.php index 47c829bbc3c6..cd46d7dc3721 100644 --- a/system/Helpers/filesystem_helper.php +++ b/system/Helpers/filesystem_helper.php @@ -53,7 +53,7 @@ function directory_map(string $sourceDir, int $directoryDepth = 0, bool $hidden closedir($fp); return $fileData; - } catch (Throwable $e) { + } catch (Throwable) { return []; } } @@ -129,7 +129,7 @@ function write_file(string $path, string $data, string $mode = 'wb'): bool fclose($fp); return is_int($result); - } catch (Throwable $e) { + } catch (Throwable) { return false; } } @@ -178,7 +178,7 @@ function delete_files(string $path, bool $delDir = false, bool $htdocs = false, } return true; - } catch (Throwable $e) { + } catch (Throwable) { return false; } } @@ -227,7 +227,7 @@ function get_filenames( } } } - } catch (Throwable $e) { + } catch (Throwable) { return []; } @@ -277,7 +277,7 @@ function get_dir_file_info(string $sourceDir, bool $topLevelOnly = true, bool $r closedir($fp); return $fileData; - } catch (Throwable $fe) { + } catch (Throwable) { return []; } } diff --git a/system/Helpers/form_helper.php b/system/Helpers/form_helper.php index 7edb05cf1de3..8a86cf690a1e 100644 --- a/system/Helpers/form_helper.php +++ b/system/Helpers/form_helper.php @@ -32,9 +32,9 @@ function form_open(string $action = '', $attributes = [], array $hidden = []): s if (! $action) { $action = current_url(true); } // If an action is not a full URL then turn it into one - elseif (strpos($action, '://') === false) { + elseif (! str_contains($action, '://')) { // If an action has {locale} - if (strpos($action, '{locale}') !== false) { + if (str_contains($action, '{locale}')) { $action = str_replace('{locale}', Services::request()->getLocale(), $action); } @@ -61,7 +61,7 @@ function form_open(string $action = '', $attributes = [], array $hidden = []): s // Add CSRF field if enabled, but leave it out for GET requests and requests to external websites $before = Services::filters()->getFilters()['before']; - if ((in_array('csrf', $before, true) || array_key_exists('csrf', $before)) && strpos($action, base_url()) !== false && ! stripos($form, 'method="get"')) { + if ((in_array('csrf', $before, true) || array_key_exists('csrf', $before)) && str_contains($action, base_url()) && ! stripos($form, 'method="get"')) { $form .= csrf_field($csrfId ?? null); } diff --git a/system/Helpers/html_helper.php b/system/Helpers/html_helper.php index 7a76434d0ea2..e43bf0b2a7d2 100755 --- a/system/Helpers/html_helper.php +++ b/system/Helpers/html_helper.php @@ -108,7 +108,7 @@ function img($src = '', bool $indexPage = false, $attributes = ''): string $img = 'config->container) || strpos($this->config->container, '{template}') === false) { + if (empty($this->config->container) || ! str_contains($this->config->container, '{template}')) { $this->config->container = '
{template}
'; } diff --git a/system/Images/Handlers/BaseHandler.php b/system/Images/Handlers/BaseHandler.php index fef31755aaa3..10884805aae5 100644 --- a/system/Images/Handlers/BaseHandler.php +++ b/system/Images/Handlers/BaseHandler.php @@ -471,31 +471,16 @@ public function reorient(bool $silent = false) { $orientation = $this->getEXIF('Orientation', $silent); - switch ($orientation) { - case 2: - return $this->flip('horizontal'); - - case 3: - return $this->rotate(180); - - case 4: - return $this->rotate(180)->flip('horizontal'); - - case 5: - return $this->rotate(270)->flip('horizontal'); - - case 6: - return $this->rotate(270); - - case 7: - return $this->rotate(90)->flip('horizontal'); - - case 8: - return $this->rotate(90); - - default: - return $this; - } + return match ($orientation) { + 2 => $this->flip('horizontal'), + 3 => $this->rotate(180), + 4 => $this->rotate(180)->flip('horizontal'), + 5 => $this->rotate(270)->flip('horizontal'), + 6 => $this->rotate(270), + 7 => $this->rotate(90)->flip('horizontal'), + 8 => $this->rotate(90), + default => $this, + }; } /** diff --git a/system/Images/Handlers/ImageMagickHandler.php b/system/Images/Handlers/ImageMagickHandler.php index 857a273d5372..839a2e4790cc 100644 --- a/system/Images/Handlers/ImageMagickHandler.php +++ b/system/Images/Handlers/ImageMagickHandler.php @@ -448,30 +448,15 @@ public function reorient(bool $silent = false) { $orientation = $this->getEXIF('Orientation', $silent); - switch ($orientation) { - case 2: - return $this->flip('horizontal'); - - case 3: - return $this->rotate(180); - - case 4: - return $this->rotate(180)->flip('horizontal'); - - case 5: - return $this->rotate(90)->flip('horizontal'); - - case 6: - return $this->rotate(90); - - case 7: - return $this->rotate(270)->flip('horizontal'); - - case 8: - return $this->rotate(270); - - default: - return $this; - } + return match ($orientation) { + 2 => $this->flip('horizontal'), + 3 => $this->rotate(180), + 4 => $this->rotate(180)->flip('horizontal'), + 5 => $this->rotate(90)->flip('horizontal'), + 6 => $this->rotate(90), + 7 => $this->rotate(270)->flip('horizontal'), + 8 => $this->rotate(270), + default => $this, + }; } } diff --git a/system/Language/Language.php b/system/Language/Language.php index 8633f8a2dd9c..8c32a8214480 100644 --- a/system/Language/Language.php +++ b/system/Language/Language.php @@ -93,7 +93,7 @@ public function getLocale(): string public function getLine(string $line, array $args = []) { // if no file is given, just parse the line - if (strpos($line, '.') === false) { + if (! str_contains($line, '.')) { return $this->formatMessage($line, $args); } diff --git a/system/Log/Handlers/ChromeLoggerHandler.php b/system/Log/Handlers/ChromeLoggerHandler.php index b04d6f69238c..983ee274c6fc 100644 --- a/system/Log/Handlers/ChromeLoggerHandler.php +++ b/system/Log/Handlers/ChromeLoggerHandler.php @@ -142,7 +142,7 @@ protected function format($object) // @todo Modify formatting of objects once we can view them in browser. $objectArray = (array) $object; - $objectArray['___class_name'] = get_class($object); + $objectArray['___class_name'] = $object::class; return $objectArray; } diff --git a/system/Log/Handlers/FileHandler.php b/system/Log/Handlers/FileHandler.php index 88e384781a70..7c10d3231503 100644 --- a/system/Log/Handlers/FileHandler.php +++ b/system/Log/Handlers/FileHandler.php @@ -88,7 +88,7 @@ public function handle($level, $message): bool } // Instantiating DateTime with microseconds appended to initial date is needed for proper support of this format - if (strpos($this->dateFormat, 'u') !== false) { + if (str_contains($this->dateFormat, 'u')) { $microtimeFull = microtime(true); $microtimeShort = sprintf('%06d', ($microtimeFull - floor($microtimeFull)) * 1_000_000); $date = new DateTime(date('Y-m-d H:i:s.' . $microtimeShort, (int) $microtimeFull)); diff --git a/system/Log/Logger.php b/system/Log/Logger.php index 2c17ded5f7c9..f23b06cc3be9 100644 --- a/system/Log/Logger.php +++ b/system/Log/Logger.php @@ -339,7 +339,7 @@ protected function interpolate($message, array $context = []) $replace['{env}'] = ENVIRONMENT; // Allow us to log the file/line that we are logging from - if (strpos($message, '{file}') !== false) { + if (str_contains($message, '{file}')) { [$file, $line] = $this->determineFile(); $replace['{file}'] = $file; @@ -347,7 +347,7 @@ protected function interpolate($message, array $context = []) } // Match up environment variables in {env:foo} tags. - if (strpos($message, 'env:') !== false) { + if (str_contains($message, 'env:')) { preg_match('/env:[^}]+/', $message, $matches); foreach ($matches as $str) { diff --git a/system/Model.php b/system/Model.php index b64c8225e17c..84601fb0f074 100644 --- a/system/Model.php +++ b/system/Model.php @@ -504,7 +504,7 @@ protected function doErrors() return []; } - return [get_class($this->db) => $error['message']]; + return [$this->db::class => $error['message']]; } /** diff --git a/system/Pager/Pager.php b/system/Pager/Pager.php index b08cb00410fd..73d45d6a728d 100644 --- a/system/Pager/Pager.php +++ b/system/Pager/Pager.php @@ -425,7 +425,7 @@ protected function calculateCurrentPage(string $group) try { $this->groups[$group]['currentPage'] = (int) $this->groups[$group]['currentUri'] ->setSilent(false)->getSegment($this->segment[$group]); - } catch (HTTPException $e) { + } catch (HTTPException) { $this->groups[$group]['currentPage'] = 1; } } else { diff --git a/system/Publisher/Publisher.php b/system/Publisher/Publisher.php index 589e88381ebe..725c15368354 100644 --- a/system/Publisher/Publisher.php +++ b/system/Publisher/Publisher.php @@ -167,7 +167,7 @@ public function __construct(?string $source = null, ?string $destination = null) // Make sure the destination is allowed foreach (array_keys($this->restrictions) as $directory) { - if (strpos($this->destination, $directory) === 0) { + if (str_starts_with($this->destination, $directory)) { return; } } @@ -470,7 +470,7 @@ private function verifyAllowed(string $from, string $to): void { // Verify this is an allowed file for its destination foreach ($this->restrictions as $directory => $pattern) { - if (strpos($to, $directory) === 0 && self::matchFiles([$to], $pattern) === []) { + if (str_starts_with($to, $directory) && self::matchFiles([$to], $pattern) === []) { throw PublisherException::forFileNotAllowed($from, $directory, $pattern); } } diff --git a/system/RESTful/BaseResource.php b/system/RESTful/BaseResource.php index 1c21f65da860..269014ee8b77 100644 --- a/system/RESTful/BaseResource.php +++ b/system/RESTful/BaseResource.php @@ -69,7 +69,7 @@ public function setModel($which = null) } if (! empty($this->model) && empty($this->modelName)) { - $this->modelName = get_class($this->model); + $this->modelName = $this->model::class; } } } diff --git a/system/Router/AutoRouter.php b/system/Router/AutoRouter.php index 281b8a49732a..ec4622a15867 100644 --- a/system/Router/AutoRouter.php +++ b/system/Router/AutoRouter.php @@ -134,13 +134,13 @@ public function getRoute(string $uri, string $httpVerb): array $handler = strtolower($handler); // Like $routes->cli('hello/(:segment)', 'Home::$1') - if (strpos($handler, '::$') !== false) { + if (str_contains($handler, '::$')) { throw new PageNotFoundException( 'Cannot access CLI Route: ' . $uri ); } - if (strpos($handler, $controller . '::' . $methodName) === 0) { + if (str_starts_with($handler, $controller . '::' . $methodName)) { throw new PageNotFoundException( 'Cannot access CLI Route: ' . $uri ); @@ -166,7 +166,7 @@ public function getRoute(string $uri, string $httpVerb): array // Ensure the controller stores the fully-qualified class name // We have to check for a length over 1, since by default it will be '\' - if (strpos($this->controller, '\\') === false && strlen($this->defaultNamespace) > 1) { + if (! str_contains($this->controller, '\\') && strlen($this->defaultNamespace) > 1) { $this->controller = '\\' . ltrim( str_replace( '/', diff --git a/system/Router/AutoRouterImproved.php b/system/Router/AutoRouterImproved.php index a86e92f0161a..6d26cf38f4f1 100644 --- a/system/Router/AutoRouterImproved.php +++ b/system/Router/AutoRouterImproved.php @@ -344,7 +344,7 @@ public function getRoute(string $uri, string $httpVerb): array // Check parameter count try { $this->checkParameters($uri); - } catch (MethodNotFoundException $e) { + } catch (MethodNotFoundException) { throw PageNotFoundException::forControllerNotFound($this->controller, $this->method); } @@ -411,14 +411,14 @@ private function checkParameters(string $uri): void { try { $refClass = new ReflectionClass($this->controller); - } catch (ReflectionException $e) { + } catch (ReflectionException) { throw PageNotFoundException::forControllerNotFound($this->controller, $this->method); } try { $refMethod = $refClass->getMethod($this->method); $refParams = $refMethod->getParameters(); - } catch (ReflectionException $e) { + } catch (ReflectionException) { throw new MethodNotFoundException(); } @@ -445,7 +445,7 @@ private function checkRemap(): void 'AutoRouterImproved does not support `_remap()` method.' . ' Controller:' . $this->controller ); - } catch (ReflectionException $e) { + } catch (ReflectionException) { // Do nothing. } } @@ -459,7 +459,7 @@ private function checkUnderscore(string $uri): void $paramPos = $this->paramPos ?? count($this->segments); for ($i = 0; $i < $paramPos; $i++) { - if (strpos($this->segments[$i], '_') !== false) { + if (str_contains($this->segments[$i], '_')) { throw new PageNotFoundException( 'AutoRouterImproved prohibits access to the URI' . ' containing underscores ("' . $this->segments[$i] . '")' diff --git a/system/Router/RouteCollection.php b/system/Router/RouteCollection.php index 47ac4b63b62e..ea434001cb46 100644 --- a/system/Router/RouteCollection.php +++ b/system/Router/RouteCollection.php @@ -1205,8 +1205,8 @@ public function reverseRoute(string $search, ...$params) // Add the default namespace if needed. $namespace = trim($this->defaultNamespace, '\\') . '\\'; if ( - substr($search, 0, 1) !== '\\' - && substr($search, 0, strlen($namespace)) !== $namespace + ! str_starts_with($search, '\\') + && ! str_starts_with($search, $namespace) ) { $search = $namespace . $search; } @@ -1230,7 +1230,7 @@ public function reverseRoute(string $search, ...$params) // If there's any chance of a match, then it will // be with $search at the beginning of the $to string. - if (strpos($to, $search) !== 0) { + if (! str_starts_with($to, $search)) { continue; } @@ -1352,7 +1352,7 @@ protected function buildReverseRoute(string $from, array $params): string preg_match_all('/\(([^)]+)\)/', $from, $matches); if (empty($matches[0])) { - if (strpos($from, '{locale}') !== false) { + if (str_contains($from, '{locale}')) { $locale = $params[0] ?? null; } @@ -1407,7 +1407,7 @@ protected function buildReverseRoute(string $from, array $params): string */ private function replaceLocale(string $route, ?string $locale = null): string { - if (strpos($route, '{locale}') === false) { + if (! str_contains($route, '{locale}')) { return $route; } @@ -1512,7 +1512,7 @@ protected function create(string $verb, string $from, $to, ?array $options = nul // If is redirect, No processing if (! isset($options['redirect']) && is_string($to)) { // If no namespace found, add the default namespace - if (strpos($to, '\\') === false || strpos($to, '\\') > 0) { + if (! str_contains($to, '\\') || strpos($to, '\\') > 0) { $namespace = $options['namespace'] ?? $this->defaultNamespace; $to = trim($namespace, '\\') . '\\' . $to; } @@ -1651,7 +1651,7 @@ private function determineCurrentSubdomain() // on the URL else parse_url will mis-interpret // 'host' as the 'path'. $url = $this->httpHost; - if (strpos($url, 'http') !== 0) { + if (! str_starts_with($url, 'http')) { $url = 'http://' . $url; } diff --git a/system/Router/Router.php b/system/Router/Router.php index e00031feb2d8..e7b0c087c07d 100644 --- a/system/Router/Router.php +++ b/system/Router/Router.php @@ -406,7 +406,7 @@ protected function checkRoutes(string $uri): bool $matchedKey = $routeKey; // Are we dealing with a locale? - if (strpos($routeKey, '{locale}') !== false) { + if (str_contains($routeKey, '{locale}')) { $routeKey = str_replace('{locale}', '[^/]+', $routeKey); } @@ -428,7 +428,7 @@ protected function checkRoutes(string $uri): bool } // Store our locale so CodeIgniter object can // assign it to the Request. - if (strpos($matchedKey, '{locale}') !== false) { + if (str_contains($matchedKey, '{locale}')) { preg_match( '#^' . str_replace('{locale}', '(?[^/]+)', $matchedKey) . '$#u', $uri, @@ -465,13 +465,13 @@ protected function checkRoutes(string $uri): bool [$controller] = explode('::', $handler); // Checks `/` in controller name - if (strpos($controller, '/') !== false) { + if (str_contains($controller, '/')) { throw RouterException::forInvalidControllerName($handler); } - if (strpos($handler, '$') !== false && strpos($routeKey, '(') !== false) { + if (str_contains($handler, '$') && str_contains($routeKey, '(')) { // Checks dynamic controller - if (strpos($controller, '$') !== false) { + if (str_contains($controller, '$')) { throw RouterException::forDynamicController($handler); } diff --git a/system/Security/Security.php b/system/Security/Security.php index 9c28b82335b0..167f864e2bea 100644 --- a/system/Security/Security.php +++ b/system/Security/Security.php @@ -292,7 +292,7 @@ public function verify(RequestInterface $request) try { $token = ($postedToken !== null && $this->config->tokenRandomize) ? $this->derandomize($postedToken) : $postedToken; - } catch (InvalidArgumentException $e) { + } catch (InvalidArgumentException) { $token = null; } diff --git a/system/Test/CIUnitTestCase.php b/system/Test/CIUnitTestCase.php index 266a22b0161d..40a4da68153e 100644 --- a/system/Test/CIUnitTestCase.php +++ b/system/Test/CIUnitTestCase.php @@ -477,7 +477,7 @@ public function assertCloseEnoughString($expected, $actual, string $message = '' $difference = abs($expected - $actual); $this->assertLessThanOrEqual($tolerance, $difference, $message); - } catch (Exception $e) { + } catch (Exception) { return false; } } @@ -515,7 +515,7 @@ protected function getHeaderEmitted(string $header, bool $ignoreCase = false, st foreach (xdebug_get_headers() as $emittedHeader) { $found = $ignoreCase ? (stripos($emittedHeader, $header) === 0) - : (strpos($emittedHeader, $header) === 0); + : (str_starts_with($emittedHeader, $header)); if ($found) { return $emittedHeader; diff --git a/system/Test/ControllerTestTrait.php b/system/Test/ControllerTestTrait.php index a99b899eaf63..25a8416d17d6 100644 --- a/system/Test/ControllerTestTrait.php +++ b/system/Test/ControllerTestTrait.php @@ -202,7 +202,7 @@ public function execute(string $method, ...$params) // getStatusCode() throws for empty codes try { $response->getStatusCode(); - } catch (HTTPException $e) { + } catch (HTTPException) { // If no code has been set then assume success $response->setStatusCode(200); } diff --git a/system/Test/DOMParser.php b/system/Test/DOMParser.php index 1a2cbb0d61aa..4cc56071670a 100644 --- a/system/Test/DOMParser.php +++ b/system/Test/DOMParser.php @@ -258,11 +258,11 @@ public function parseSelector(string $selector) $attr = null; // ID? - if (strpos($selector, '#') !== false) { + if (str_contains($selector, '#')) { [$tag, $id] = explode('#', $selector); } // Attribute - elseif (strpos($selector, '[') !== false && strpos($selector, ']') !== false) { + elseif (str_contains($selector, '[') && str_contains($selector, ']')) { $open = strpos($selector, '['); $close = strpos($selector, ']'); @@ -280,7 +280,7 @@ public function parseSelector(string $selector) $attr = [$name => trim($value, '] ')]; } // Class? - elseif (strpos($selector, '.') !== false) { + elseif (str_contains($selector, '.')) { [$tag, $class] = explode('.', $selector); } // Otherwise, assume the entire string is our tag diff --git a/system/Test/DatabaseTestTrait.php b/system/Test/DatabaseTestTrait.php index d7b8b02ddaa8..247cc74ee564 100644 --- a/system/Test/DatabaseTestTrait.php +++ b/system/Test/DatabaseTestTrait.php @@ -239,7 +239,7 @@ protected function clearInsertCache() */ public function loadBuilder(string $tableName) { - $builderClass = str_replace('Connection', 'Builder', get_class($this->db)); + $builderClass = str_replace('Connection', 'Builder', $this->db::class); return new $builderClass($tableName, $this->db); } diff --git a/system/Test/Fabricator.php b/system/Test/Fabricator.php index 3a28f281d127..66a685fc8d30 100644 --- a/system/Test/Fabricator.php +++ b/system/Test/Fabricator.php @@ -305,7 +305,7 @@ protected function guessFormatter($field): string $this->faker->getFormatter($field); return $field; - } catch (InvalidArgumentException $e) { + } catch (InvalidArgumentException) { // No match, keep going } @@ -497,18 +497,11 @@ public function create(?int $count = null, bool $mock = false) */ protected function createMock(?int $count = null) { - switch ($this->model->dateFormat) { - case 'datetime': - $datetime = date('Y-m-d H:i:s'); - break; - - case 'date': - $datetime = date('Y-m-d'); - break; - - default: - $datetime = Time::now()->getTimestamp(); - } + $datetime = match ($this->model->dateFormat) { + 'datetime' => date('Y-m-d H:i:s'), + 'date' => date('Y-m-d'), + default => Time::now()->getTimestamp(), + }; // Determine which fields we will need $fields = []; diff --git a/system/Test/FilterTestTrait.php b/system/Test/FilterTestTrait.php index 523717e54679..14bf81db9271 100644 --- a/system/Test/FilterTestTrait.php +++ b/system/Test/FilterTestTrait.php @@ -131,7 +131,7 @@ protected function getFilterCaller($filter, string $position): Closure if (is_string($filter)) { // Check for an alias (no namespace) - if (strpos($filter, '\\') === false) { + if (! str_contains($filter, '\\')) { if (! isset($this->filtersConfig->aliases[$filter])) { throw new RuntimeException("No filter found with alias '{$filter}'"); } @@ -149,7 +149,7 @@ protected function getFilterCaller($filter, string $position): Closure $filter = new $class(); if (! $filter instanceof FilterInterface) { - throw FilterException::forIncorrectInterface(get_class($filter)); + throw FilterException::forIncorrectInterface($filter::class); } $filterInstances[] = $filter; diff --git a/system/Test/TestLogger.php b/system/Test/TestLogger.php index dce1277d98d2..3f453ca5cb0d 100644 --- a/system/Test/TestLogger.php +++ b/system/Test/TestLogger.php @@ -80,7 +80,7 @@ public static function didLog(string $level, $message, bool $useExactComparison continue; } - if (strpos($log['message'], $message) !== false) { + if (str_contains($log['message'], $message)) { return true; } } diff --git a/system/Typography/Typography.php b/system/Typography/Typography.php index fd763cd52e86..1442c2f6e51a 100644 --- a/system/Typography/Typography.php +++ b/system/Typography/Typography.php @@ -82,7 +82,7 @@ public function autoTypography(string $str, bool $reduceLinebreaks = false): str } // Standardize Newlines to make matching easier - if (strpos($str, "\r") !== false) { + if (str_contains($str, "\r")) { $str = str_replace(["\r\n", "\r"], "\n", $str); } @@ -94,7 +94,7 @@ public function autoTypography(string $str, bool $reduceLinebreaks = false): str // HTML comment tags don't conform to patterns of normal tags, so pull them out separately, only if needed $htmlComments = []; - if (strpos($str, '