diff --git a/system/Autoloader/Autoloader.php b/system/Autoloader/Autoloader.php
index 28c183f1..b338027c 100644
--- a/system/Autoloader/Autoloader.php
+++ b/system/Autoloader/Autoloader.php
@@ -19,7 +19,6 @@
use Config\Autoload;
use Config\Kint as KintConfig;
use Config\Modules;
-use Config\Services;
use InvalidArgumentException;
use Kint;
use Kint\Renderer\CliRenderer;
@@ -367,6 +366,9 @@ public function sanitizeFilename(string $filename): string
return $cleanFilename;
}
+ /**
+ * @param array{only?: list
, exclude?: list} $composerPackages
+ */
private function loadComposerNamespaces(ClassLoader $composer, array $composerPackages): void
{
$namespacePaths = $composer->getPrefixesPsr4();
@@ -380,7 +382,7 @@ private function loadComposerNamespaces(ClassLoader $composer, array $composerPa
}
}
- if (! method_exists(InstalledVersions::class, 'getAllRawData')) {
+ if (! method_exists(InstalledVersions::class, 'getAllRawData')) { // @phpstan-ignore function.alreadyNarrowedType
throw new RuntimeException(
'Your Composer version is too old.'
. ' Please update Composer (run `composer self-update`) to v2.0.14 or later'
@@ -537,7 +539,7 @@ private function configureKint(): void
Kint::$plugins = $config->plugins;
}
- $csp = Services::csp();
+ $csp = service('csp');
if ($csp->enabled()) {
RichRenderer::$js_nonce = $csp->getScriptNonce();
RichRenderer::$css_nonce = $csp->getStyleNonce();
diff --git a/system/Autoloader/FileLocator.php b/system/Autoloader/FileLocator.php
index 14b9a136..8e2564e0 100644
--- a/system/Autoloader/FileLocator.php
+++ b/system/Autoloader/FileLocator.php
@@ -145,10 +145,11 @@ public function getClassname(string $file): string
if ((isset($tokens[$i - 2][1]) && ($tokens[$i - 2][1] === 'phpnamespace' || $tokens[$i - 2][1] === 'namespace')) || ($dlm && $tokens[$i - 1][0] === T_NS_SEPARATOR && $token[0] === T_STRING)) {
if (! $dlm) {
- $namespace = 0;
+ $namespace = '';
}
+
if (isset($token[1])) {
- $namespace = $namespace ? $namespace . '\\' . $token[1] : $token[1];
+ $namespace = $namespace !== '' ? $namespace . '\\' . $token[1] : $token[1];
$dlm = true;
}
} elseif ($dlm && ($token[0] !== T_NS_SEPARATOR) && ($token[0] !== T_STRING)) {
@@ -194,8 +195,9 @@ public function search(string $path, string $ext = 'php', bool $prioritizeApp =
foreach ($this->getNamespaces() as $namespace) {
if (isset($namespace['path']) && is_file($namespace['path'] . $path)) {
- $fullPath = $namespace['path'] . $path;
- $fullPath = realpath($fullPath) ?: $fullPath;
+ $fullPath = $namespace['path'] . $path;
+ $resolvedPath = realpath($fullPath);
+ $fullPath = $resolvedPath !== false ? $resolvedPath : $fullPath;
if ($prioritizeApp) {
$foundPaths[] = $fullPath;
@@ -272,14 +274,16 @@ protected function getNamespaces()
*/
public function findQualifiedNameFromPath(string $path)
{
- $path = realpath($path) ?: $path;
+ $resolvedPath = realpath($path);
+ $path = $resolvedPath !== false ? $resolvedPath : $path;
if (! is_file($path)) {
return false;
}
foreach ($this->getNamespaces() as $namespace) {
- $namespace['path'] = realpath($namespace['path']) ?: $namespace['path'];
+ $resolvedNamespacePath = realpath($namespace['path']);
+ $namespace['path'] = $resolvedNamespacePath !== false ? $resolvedNamespacePath : $namespace['path'];
if ($namespace['path'] === '') {
continue;
@@ -331,8 +335,9 @@ public function listFiles(string $path): array
helper('filesystem');
foreach ($this->getNamespaces() as $namespace) {
- $fullPath = $namespace['path'] . $path;
- $fullPath = realpath($fullPath) ?: $fullPath;
+ $fullPath = $namespace['path'] . $path;
+ $resolvedPath = realpath($fullPath);
+ $fullPath = $resolvedPath !== false ? $resolvedPath : $fullPath;
if (! is_dir($fullPath)) {
continue;
@@ -365,8 +370,9 @@ public function listNamespaceFiles(string $prefix, string $path): array
// autoloader->getNamespace($prefix) returns an array of paths for that namespace
foreach ($this->autoloader->getNamespace($prefix) as $namespacePath) {
- $fullPath = rtrim($namespacePath, '/') . '/' . $path;
- $fullPath = realpath($fullPath) ?: $fullPath;
+ $fullPath = rtrim($namespacePath, '/') . '/' . $path;
+ $resolvedPath = realpath($fullPath);
+ $fullPath = $resolvedPath !== false ? $resolvedPath : $fullPath;
if (! is_dir($fullPath)) {
continue;
@@ -392,8 +398,9 @@ public function listNamespaceFiles(string $prefix, string $path): array
*/
protected function legacyLocate(string $file, ?string $folder = null)
{
- $path = APPPATH . ($folder === null ? $file : $folder . '/' . $file);
- $path = realpath($path) ?: $path;
+ $path = APPPATH . ($folder === null ? $file : $folder . '/' . $file);
+ $resolvedPath = realpath($path);
+ $path = $resolvedPath !== false ? $resolvedPath : $path;
if (is_file($path)) {
return $path;
diff --git a/system/Autoloader/FileLocatorCached.php b/system/Autoloader/FileLocatorCached.php
index adf45330..8b173994 100644
--- a/system/Autoloader/FileLocatorCached.php
+++ b/system/Autoloader/FileLocatorCached.php
@@ -36,6 +36,8 @@ final class FileLocatorCached implements FileLocatorInterface
* [
* 'search' => [$path => $foundPaths],
* ]
+ *
+ * @var array>
*/
private array $cache = [];
@@ -114,6 +116,9 @@ public function getClassname(string $file): string
return $classname;
}
+ /**
+ * @return list
+ */
public function search(string $path, string $ext = 'php', bool $prioritizeApp = true): array
{
if (isset($this->cache['search'][$path][$ext][$prioritizeApp])) {
diff --git a/system/Autoloader/FileLocatorInterface.php b/system/Autoloader/FileLocatorInterface.php
index 3f7355a8..3a1112dd 100644
--- a/system/Autoloader/FileLocatorInterface.php
+++ b/system/Autoloader/FileLocatorInterface.php
@@ -53,6 +53,8 @@ public function getClassname(string $file): string;
* 'app/Modules/foo/Config/Routes.php',
* 'app/Modules/bar/Config/Routes.php',
* ]
+ *
+ * @return list
*/
public function search(string $path, string $ext = 'php', bool $prioritizeApp = true): array;
diff --git a/system/BaseModel.php b/system/BaseModel.php
index 2b364bdc..05c5459d 100644
--- a/system/BaseModel.php
+++ b/system/BaseModel.php
@@ -26,7 +26,6 @@
use CodeIgniter\Pager\Pager;
use CodeIgniter\Validation\ValidationInterface;
use Config\Feature;
-use Config\Services;
use InvalidArgumentException;
use ReflectionClass;
use ReflectionException;
@@ -47,7 +46,7 @@
* - process various callbacks
* - allow intermingling calls to the db connection
*
- * @phpstan-type row_array array
+ * @phpstan-type row_array array
* @phpstan-type event_data_beforeinsert array{data: row_array}
* @phpstan-type event_data_afterinsert array{id: int|string, data: row_array, result: bool}
* @phpstan-type event_data_beforefind array{id?: int|string, method: string, singleton: bool, limit?: int, offset?: int}
@@ -571,8 +570,8 @@ abstract public function countAllResults(bool $reset = true, bool $test = false)
* Loops over records in batches, allowing you to operate on them.
* This method works only with dbCalls.
*
- * @param int $size Size
- * @param Closure $userFunc Callback Function
+ * @param int $size Size
+ * @param Closure(array|object): mixed $userFunc Callback Function
*
* @return void
*
@@ -640,7 +639,7 @@ public function findColumn(string $columnName)
$resultSet = $this->doFindColumn($columnName);
- return $resultSet ? array_column($resultSet, $columnName) : null;
+ return $resultSet !== null ? array_column($resultSet, $columnName) : null;
}
/**
@@ -1138,7 +1137,7 @@ public function delete($id = null, bool $purge = false)
throw new InvalidArgumentException('delete(): argument #1 ($id) should not be boolean.');
}
- if ($id && (is_numeric($id) || is_string($id))) {
+ if (! in_array($id, [null, 0, '0'], true) && (is_numeric($id) || is_string($id))) {
$id = [$id];
}
@@ -1251,7 +1250,7 @@ public function errors(bool $forceDB = false)
}
// Do we have validation errors?
- if (! $forceDB && ! $this->skipValidation && ($errors = $this->validation->getErrors())) {
+ if (! $forceDB && ! $this->skipValidation && ($errors = $this->validation->getErrors()) !== []) {
return $errors;
}
@@ -1609,7 +1608,7 @@ public function getValidationRules(array $options = []): array
protected function ensureValidation(): void
{
if ($this->validation === null) {
- $this->validation = Services::validation(null, false);
+ $this->validation = service('validation', null, false);
}
}
@@ -1800,8 +1799,6 @@ protected function objectToRawArray($object, bool $onlyChanged = true, bool $rec
// Loop over each property,
// saving the name/value in a new array we can return.
foreach ($props as $prop) {
- // Must make protected values accessible.
- $prop->setAccessible(true);
$properties[$prop->getName()] = $prop->getValue($object);
}
}
diff --git a/system/Boot.php b/system/Boot.php
index 54468a5c..4b2d20ca 100644
--- a/system/Boot.php
+++ b/system/Boot.php
@@ -196,7 +196,16 @@ protected static function definePathConstants(Paths $paths): void
// The path to the writable directory.
if (! defined('WRITEPATH')) {
- define('WRITEPATH', realpath(rtrim($paths->writableDirectory, '\\/ ')) . DIRECTORY_SEPARATOR);
+ $writePath = realpath(rtrim($paths->writableDirectory, '\\/ '));
+
+ if ($writePath === false) {
+ header('HTTP/1.1 503 Service Unavailable.', true, 503);
+ echo 'The WRITEPATH is not set correctly.';
+
+ // EXIT_ERROR is not yet defined
+ exit(1);
+ }
+ define('WRITEPATH', $writePath . DIRECTORY_SEPARATOR);
}
// The path to the tests directory
@@ -246,12 +255,12 @@ protected static function loadAutoloader(): void
protected static function autoloadHelpers(): void
{
- Services::autoloader()->loadHelpers();
+ service('autoloader')->loadHelpers();
}
protected static function setExceptionHandler(): void
{
- Services::exceptions()->initialize();
+ service('exceptions')->initialize();
}
protected static function checkMissingExtensions(): void
@@ -290,7 +299,7 @@ protected static function checkMissingExtensions(): void
protected static function initializeKint(): void
{
- Services::autoloader()->initializeKint(CI_DEBUG);
+ service('autoloader')->initializeKint(CI_DEBUG);
}
protected static function loadConfigCache(): FactoriesCache
@@ -308,7 +317,7 @@ protected static function loadConfigCache(): FactoriesCache
*/
protected static function initializeCodeIgniter(): CodeIgniter
{
- $app = Config\Services::codeigniter();
+ $app = service('codeigniter');
$app->initialize();
$context = is_cli() ? 'php-cli' : 'web';
$app->setContext($context);
diff --git a/system/CLI/CLI.php b/system/CLI/CLI.php
index bfe1511e..0b5b01b1 100644
--- a/system/CLI/CLI.php
+++ b/system/CLI/CLI.php
@@ -14,7 +14,6 @@
namespace CodeIgniter\CLI;
use CodeIgniter\CLI\Exceptions\CLIException;
-use Config\Services;
use InvalidArgumentException;
use Throwable;
@@ -226,12 +225,12 @@ public static function prompt(string $field, $options = null, $validation = null
$extraOutput = '';
$default = '';
- if ($validation && ! is_array($validation) && ! is_string($validation)) {
+ if (isset($validation) && ! is_array($validation) && ! is_string($validation)) {
throw new InvalidArgumentException('$rules can only be of type string|array');
}
if (! is_array($validation)) {
- $validation = $validation ? explode('|', $validation) : [];
+ $validation = ($validation !== null) ? explode('|', $validation) : [];
}
if (is_string($options)) {
@@ -349,7 +348,7 @@ public static function promptByMultipleKeys(string $text, array $options): array
// return the prompt again if $input contain(s) non-numeric character, except a comma.
// And if max from $options less than max from input,
// it means user tried to access null value in $options
- if (! $pattern || $maxOptions < $maxInput) {
+ if ($pattern === 0 || $maxOptions < $maxInput) {
static::error('Please select correctly.');
CLI::newLine();
@@ -416,7 +415,7 @@ protected static function validate(string $field, string $value, $rules): bool
{
$label = $field;
$field = 'temp';
- $validation = Services::validation(null, false);
+ $validation = service('validation', null, false);
$validation->setRules([
$field => [
'label' => $label,
@@ -442,7 +441,7 @@ protected static function validate(string $field, string $value, $rules): bool
*/
public static function print(string $text = '', ?string $foreground = null, ?string $background = null)
{
- if ($foreground || $background) {
+ if ((string) $foreground !== '' || (string) $background !== '') {
$text = static::color($text, $foreground, $background);
}
@@ -458,7 +457,7 @@ public static function print(string $text = '', ?string $foreground = null, ?str
*/
public static function write(string $text = '', ?string $foreground = null, ?string $background = null)
{
- if ($foreground || $background) {
+ if ((string) $foreground !== '' || (string) $background !== '') {
$text = static::color($text, $foreground, $background);
}
@@ -481,7 +480,7 @@ public static function error(string $text, string $foreground = 'light_red', ?st
$stdout = static::$isColored;
static::$isColored = static::hasColorSupport(STDERR);
- if ($foreground || $background) {
+ if ($foreground !== '' || (string) $background !== '') {
$text = static::color($text, $foreground, $background);
}
@@ -514,7 +513,7 @@ public static function beep(int $num = 1)
*/
public static function wait(int $seconds, bool $countdown = false)
{
- if ($countdown === true) {
+ if ($countdown) {
$time = $seconds;
while ($time > 0) {
@@ -590,7 +589,7 @@ public static function color(string $text, string $foreground, ?string $backgrou
throw CLIException::forInvalidColor('foreground', $foreground);
}
- if ($background !== null && ! array_key_exists($background, static::$background_colors)) {
+ if ((string) $background !== '' && ! array_key_exists($background, static::$background_colors)) {
throw CLIException::forInvalidColor('background', $background);
}
@@ -638,7 +637,7 @@ private static function getColoredText(string $text, string $foreground, ?string
{
$string = "\033[" . static::$foreground_colors[$foreground] . 'm';
- if ($background !== null) {
+ if ((string) $background !== '') {
$string .= "\033[" . static::$background_colors[$background] . 'm';
}
@@ -655,7 +654,7 @@ private static function getColoredText(string $text, string $foreground, ?string
*/
public static function strlen(?string $string): int
{
- if ($string === null) {
+ if ((string) $string === '') {
return 0;
}
@@ -769,7 +768,7 @@ public static function generateDimensions()
// Look for the next lines ending in ": "
// Searching for "Columns:" or "Lines:" will fail on non-English locales
- if ($return === 0 && $output && preg_match('/:\s*(\d+)\n[^:]+:\s*(\d+)\n/', implode("\n", $output), $matches)) {
+ if ($return === 0 && $output !== [] && preg_match('/:\s*(\d+)\n[^:]+:\s*(\d+)\n/', implode("\n", $output), $matches)) {
static::$height = (int) $matches[1];
static::$width = (int) $matches[2];
}
@@ -836,7 +835,7 @@ public static function showProgress($thisStep = 1, int $totalSteps = 10)
*/
public static function wrap(?string $string = null, int $max = 0, int $padLeft = 0): string
{
- if ($string === null || $string === '') {
+ if ((string) $string === '') {
return '';
}
diff --git a/system/Cache/Handlers/BaseHandler.php b/system/Cache/Handlers/BaseHandler.php
index 43d316f8..2e35864f 100644
--- a/system/Cache/Handlers/BaseHandler.php
+++ b/system/Cache/Handlers/BaseHandler.php
@@ -67,7 +67,7 @@ public static function validateKey($key, $prefix = ''): string
}
$reserved = config(Cache::class)->reservedCharacters ?? self::RESERVED_CHARACTERS;
- if ($reserved && strpbrk($key, $reserved) !== false) {
+ if ($reserved !== '' && strpbrk($key, $reserved) !== false) {
throw new InvalidArgumentException('Cache key contains reserved characters ' . $reserved);
}
diff --git a/system/Cache/Handlers/FileHandler.php b/system/Cache/Handlers/FileHandler.php
index cf45a654..525616a7 100644
--- a/system/Cache/Handlers/FileHandler.php
+++ b/system/Cache/Handlers/FileHandler.php
@@ -308,7 +308,7 @@ protected function deleteFiles(string $path, bool $delDir = false, bool $htdocs
if ($filename !== '.' && $filename !== '..') {
if (is_dir($path . DIRECTORY_SEPARATOR . $filename) && $filename[0] !== '.') {
$this->deleteFiles($path . DIRECTORY_SEPARATOR . $filename, $delDir, $htdocs, $_level + 1);
- } elseif ($htdocs !== true || ! preg_match('/^(\.htaccess|index\.(html|htm|php)|web\.config)$/i', $filename)) {
+ } elseif (! $htdocs || preg_match('/^(\.htaccess|index\.(html|htm|php)|web\.config)$/i', $filename) !== 1) {
@unlink($path . DIRECTORY_SEPARATOR . $filename);
}
}
@@ -316,7 +316,7 @@ protected function deleteFiles(string $path, bool $delDir = false, bool $htdocs
closedir($currentDir);
- return ($delDir === true && $_level > 0) ? @rmdir($path) : true;
+ return ($delDir && $_level > 0) ? @rmdir($path) : true;
}
/**
@@ -337,13 +337,13 @@ protected function getDirFileInfo(string $sourceDir, bool $topLevelOnly = true,
$relativePath = $sourceDir;
if ($fp = @opendir($sourceDir)) {
- // reset the array and make sure $source_dir has a trailing slash on the initial call
+ // reset the array and make sure $sourceDir has a trailing slash on the initial call
if ($_recursion === false) {
$_filedata = [];
$sourceDir = rtrim(realpath($sourceDir) ?: $sourceDir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
}
- // Used to be foreach (scandir($source_dir, 1) as $file), but scandir() is simply not as fast
+ // Used to be foreach (scandir($sourceDir, 1) as $file), but scandir() is simply not as fast
while (false !== ($file = readdir($fp))) {
if (is_dir($sourceDir . $file) && $file[0] !== '.' && $topLevelOnly === false) {
$this->getDirFileInfo($sourceDir . $file . DIRECTORY_SEPARATOR, $topLevelOnly, true);
diff --git a/system/Cache/Handlers/PredisHandler.php b/system/Cache/Handlers/PredisHandler.php
index 59e35aa4..fc018503 100644
--- a/system/Cache/Handlers/PredisHandler.php
+++ b/system/Cache/Handlers/PredisHandler.php
@@ -19,6 +19,7 @@
use Exception;
use Predis\Client;
use Predis\Collection\Iterator\Keyspace;
+use Predis\Response\Status;
/**
* Predis cache handler
@@ -121,7 +122,7 @@ public function save(string $key, $value, int $ttl = 60)
return false;
}
- if (! $this->redis->hmset($key, ['__ci_type' => $dataType, '__ci_value' => $value])) {
+ if (! $this->redis->hmset($key, ['__ci_type' => $dataType, '__ci_value' => $value]) instanceof Status) {
return false;
}
diff --git a/system/Cache/Handlers/RedisHandler.php b/system/Cache/Handlers/RedisHandler.php
index 22f4e435..6cd43506 100644
--- a/system/Cache/Handlers/RedisHandler.php
+++ b/system/Cache/Handlers/RedisHandler.php
@@ -108,7 +108,7 @@ public function initialize()
public function get(string $key)
{
$key = static::validateKey($key, $this->prefix);
- $data = $this->redis->hMGet($key, ['__ci_type', '__ci_value']);
+ $data = $this->redis->hMget($key, ['__ci_type', '__ci_value']);
if (! isset($data['__ci_type'], $data['__ci_value']) || $data['__ci_value'] === false) {
return null;
@@ -147,7 +147,7 @@ public function save(string $key, $value, int $ttl = 60)
return false;
}
- if (! $this->redis->hMSet($key, ['__ci_type' => $dataType, '__ci_value' => $value])) {
+ if (! $this->redis->hMset($key, ['__ci_type' => $dataType, '__ci_value' => $value])) {
return false;
}
diff --git a/system/CodeIgniter.php b/system/CodeIgniter.php
index 48fbc9d7..af1ef4ed 100644
--- a/system/CodeIgniter.php
+++ b/system/CodeIgniter.php
@@ -56,7 +56,7 @@ class CodeIgniter
/**
* The current version of CodeIgniter Framework
*/
- public const CI_VERSION = '4.5.5';
+ public const CI_VERSION = '4.5.6';
/**
* App startup time.
@@ -819,7 +819,7 @@ protected function tryToRouteIt(?RouteCollectionInterface $routes = null)
{
$this->benchmark->start('routing');
- if ($routes === null) {
+ if (! $routes instanceof RouteCollectionInterface) {
$routes = service('routes')->loadRoutes();
}
diff --git a/system/Commands/ListCommands.php b/system/Commands/ListCommands.php
index 3411b103..8761e2bb 100644
--- a/system/Commands/ListCommands.php
+++ b/system/Commands/ListCommands.php
@@ -71,6 +71,8 @@ class ListCommands extends BaseCommand
/**
* Displays the help for the spark cli script itself.
+ *
+ * @return int
*/
public function run(array $params)
{
@@ -78,7 +80,7 @@ public function run(array $params)
ksort($commands);
// Check for 'simple' format
- return array_key_exists('simple', $params) || CLI::getOption('simple')
+ return array_key_exists('simple', $params) || CLI::getOption('simple') === true
? $this->listSimple($commands)
: $this->listFull($commands);
}
@@ -86,7 +88,7 @@ public function run(array $params)
/**
* Lists the commands with accompanying info.
*
- * @return void
+ * @return int
*/
protected function listFull(array $commands)
{
@@ -124,17 +126,21 @@ protected function listFull(array $commands)
CLI::newLine();
}
}
+
+ return EXIT_SUCCESS;
}
/**
* Lists the commands only.
*
- * @return void
+ * @return int
*/
protected function listSimple(array $commands)
{
foreach (array_keys($commands) as $title) {
CLI::write($title);
}
+
+ return EXIT_SUCCESS;
}
}
diff --git a/system/Commands/Server/Serve.php b/system/Commands/Server/Serve.php
index 82e58998..594e4e58 100644
--- a/system/Commands/Server/Serve.php
+++ b/system/Commands/Server/Serve.php
@@ -110,7 +110,7 @@ public function run(array $params)
// to ensure our environment is set and it simulates basic mod_rewrite.
passthru($php . ' -S ' . $host . ':' . $port . ' -t ' . $docroot . ' ' . $rewrite, $status);
- if ($status && $this->portOffset < $this->tries) {
+ if ($status !== EXIT_SUCCESS && $this->portOffset < $this->tries) {
$this->portOffset++;
$this->run($params);
diff --git a/system/Commands/Utilities/Routes.php b/system/Commands/Utilities/Routes.php
index 9adcc1bc..a0f81f6b 100644
--- a/system/Commands/Utilities/Routes.php
+++ b/system/Commands/Utilities/Routes.php
@@ -86,7 +86,7 @@ public function run(array $params)
$host = $params['host'] ?? null;
// Set HTTP_HOST
- if ($host) {
+ if ($host !== null) {
$request = service('request');
$_SERVER = $request->getServer();
$_SERVER['HTTP_HOST'] = $host;
@@ -96,7 +96,7 @@ public function run(array $params)
$collection = service('routes')->loadRoutes();
// Reset HTTP_HOST
- if ($host) {
+ if ($host !== null) {
unset($_SERVER['HTTP_HOST']);
}
@@ -139,7 +139,9 @@ public function run(array $params)
$autoRoutes = $autoRouteCollector->get();
// Check for Module Routes.
- if ($routingConfig = config(Routing::class)) {
+ $routingConfig = config(Routing::class);
+
+ if ($routingConfig instanceof Routing) {
foreach ($routingConfig->moduleRoutes as $uri => $namespace) {
$autoRouteCollector = new AutoRouteCollectorImproved(
$namespace,
@@ -188,7 +190,7 @@ public function run(array $params)
usort($tbody, static fn ($handler1, $handler2) => strcmp($handler1[3], $handler2[3]));
}
- if ($host) {
+ if ($host !== null) {
CLI::write('Host: ' . $host);
}
diff --git a/system/Commands/Utilities/Routes/AutoRouterImproved/AutoRouteCollector.php b/system/Commands/Utilities/Routes/AutoRouterImproved/AutoRouteCollector.php
index 57996934..f6a4f371 100644
--- a/system/Commands/Utilities/Routes/AutoRouterImproved/AutoRouteCollector.php
+++ b/system/Commands/Utilities/Routes/AutoRouterImproved/AutoRouteCollector.php
@@ -36,7 +36,7 @@ public function __construct(
private readonly string $defaultMethod,
private readonly array $httpMethods,
private readonly array $protectedControllers,
- private string $prefix = ''
+ private readonly string $prefix = ''
) {
}
@@ -122,8 +122,10 @@ private function addFilters($routes)
$filtersShortest = $filterCollector->get($route['method'], $routePath . $sampleUri);
// Get common array elements
- $filters['before'] = array_intersect($filtersLongest['before'], $filtersShortest['before']);
- $filters['after'] = array_intersect($filtersLongest['after'], $filtersShortest['after']);
+ $filters = [
+ 'before' => array_intersect($filtersLongest['before'], $filtersShortest['before']),
+ 'after' => array_intersect($filtersLongest['after'], $filtersShortest['after']),
+ ];
$route['before'] = implode(' ', array_map(class_basename(...), $filters['before']));
$route['after'] = implode(' ', array_map(class_basename(...), $filters['after']));
diff --git a/system/Commands/Utilities/Routes/AutoRouterImproved/ControllerMethodReader.php b/system/Commands/Utilities/Routes/AutoRouterImproved/ControllerMethodReader.php
index e08a16ff..2755a389 100644
--- a/system/Commands/Utilities/Routes/AutoRouterImproved/ControllerMethodReader.php
+++ b/system/Commands/Utilities/Routes/AutoRouterImproved/ControllerMethodReader.php
@@ -221,7 +221,7 @@ private function getRouteForDefaultController(
if ($classShortname === $defaultController) {
$pattern = '#' . preg_quote(lcfirst($defaultController), '#') . '\z#';
$routeWithoutController = rtrim(preg_replace($pattern, '', $uriByClass), '/');
- $routeWithoutController = $routeWithoutController ?: '/';
+ $routeWithoutController = $routeWithoutController !== '' && $routeWithoutController !== '0' ? $routeWithoutController : '/';
[$params, $routeParams] = $this->getParameters($method);
diff --git a/system/Commands/Utilities/Routes/ControllerMethodReader.php b/system/Commands/Utilities/Routes/ControllerMethodReader.php
index c443b669..b40a832b 100644
--- a/system/Commands/Utilities/Routes/ControllerMethodReader.php
+++ b/system/Commands/Utilities/Routes/ControllerMethodReader.php
@@ -161,7 +161,7 @@ private function getRouteWithoutController(
$pattern = '#' . preg_quote(lcfirst($defaultController), '#') . '\z#';
$routeWithoutController = rtrim(preg_replace($pattern, '', $uriByClass), '/');
- $routeWithoutController = $routeWithoutController ?: '/';
+ $routeWithoutController = $routeWithoutController !== '' && $routeWithoutController !== '0' ? $routeWithoutController : '/';
return [[
'route' => $routeWithoutController,
diff --git a/system/Commands/Utilities/Routes/FilterCollector.php b/system/Commands/Utilities/Routes/FilterCollector.php
index 002a529b..b646dcb2 100644
--- a/system/Commands/Utilities/Routes/FilterCollector.php
+++ b/system/Commands/Utilities/Routes/FilterCollector.php
@@ -13,7 +13,6 @@
namespace CodeIgniter\Commands\Utilities\Routes;
-use CodeIgniter\Config\Services;
use CodeIgniter\Filters\Filters;
use CodeIgniter\HTTP\Method;
use CodeIgniter\HTTP\Request;
@@ -68,7 +67,7 @@ public function get(string $method, string $uri): array
];
}
- $request = Services::incomingrequest(null, false);
+ $request = service('incomingrequest', null, false);
$request->setMethod($method);
$router = $this->createRouter($request);
@@ -86,7 +85,7 @@ public function get(string $method, string $uri): array
*/
public function getRequiredFilters(): array
{
- $request = Services::incomingrequest(null, false);
+ $request = service('incomingrequest', null, false);
$request->setMethod(Method::GET);
$router = $this->createRouter($request);
diff --git a/system/Common.php b/system/Common.php
index dcc9487c..b647c9d2 100644
--- a/system/Common.php
+++ b/system/Common.php
@@ -441,7 +441,7 @@ function esc($data, string $context = 'html', ?string $encoding = null)
$escaper = new Escaper($encoding);
}
- if ($encoding && $escaper->getEncoding() !== $encoding) {
+ if ($encoding !== null && $escaper->getEncoding() !== $encoding) {
$escaper = new Escaper($encoding);
}
@@ -580,8 +580,8 @@ function helper($filenames): void
foreach ($filenames as $filename) {
// Store our system and application helper
// versions so that we can control the load ordering.
- $systemHelper = null;
- $appHelper = null;
+ $systemHelper = '';
+ $appHelper = '';
$localIncludes = [];
if (! str_contains($filename, '_helper')) {
@@ -598,7 +598,7 @@ function helper($filenames): void
if (str_contains($filename, '\\')) {
$path = $loader->locateFile($filename, 'Helpers');
- if (empty($path)) {
+ if ($path !== '') {
throw FileNotFoundException::forFileNotFound($filename);
}
@@ -620,7 +620,7 @@ function helper($filenames): void
}
// App-level helpers should override all others
- if (! empty($appHelper)) {
+ if ($appHelper !== '') {
$includes[] = $appHelper;
$loaded[] = $filename;
}
@@ -629,7 +629,7 @@ function helper($filenames): void
$includes = [...$includes, ...$localIncludes];
// And the system default one should be added in last.
- if (! empty($systemHelper)) {
+ if ($systemHelper !== '') {
$includes[] = $systemHelper;
$loaded[] = $filename;
}
@@ -739,13 +739,13 @@ function lang(string $line, array $args = [], ?string $locale = null)
// Get active locale
$activeLocale = $language->getLocale();
- if ($locale && $locale !== $activeLocale) {
+ if ((string) $locale !== '' && $locale !== $activeLocale) {
$language->setLocale($locale);
}
$lines = $language->getLine($line, $args);
- if ($locale && $locale !== $activeLocale) {
+ if ((string) $locale !== '' && $locale !== $activeLocale) {
// Reset to active locale
$language->setLocale($activeLocale);
}
@@ -849,7 +849,7 @@ function redirect(?string $route = null): RedirectResponse
{
$response = service('redirectresponse');
- if ($route !== null) {
+ if ((string) $route !== '') {
return $response->route($route);
}
@@ -869,7 +869,7 @@ function _solidus(?DocTypes $docTypesConfig = null): string
{
static $docTypes = null;
- if ($docTypesConfig !== null) {
+ if ($docTypesConfig instanceof DocTypes) {
$docTypes = $docTypesConfig;
}
@@ -1092,7 +1092,7 @@ function stringify_attributes($attributes, bool $js = false): string
{
$atts = '';
- if (empty($attributes)) {
+ if ($attributes === '' || $attributes === [] || $attributes === null) {
return $atts;
}
diff --git a/system/Config/DotEnv.php b/system/Config/DotEnv.php
index db7152fd..d4a7d9e8 100644
--- a/system/Config/DotEnv.php
+++ b/system/Config/DotEnv.php
@@ -94,7 +94,7 @@ public function parse(): ?array
*/
protected function setVariable(string $name, string $value = '')
{
- if (! getenv($name, true)) {
+ if (getenv($name, true) === false) {
putenv("{$name}={$value}");
}
diff --git a/system/Config/Factories.php b/system/Config/Factories.php
index d98664a2..b845d582 100644
--- a/system/Config/Factories.php
+++ b/system/Config/Factories.php
@@ -37,7 +37,7 @@ final class Factories
*
* @var array>
*/
- private static $options = [];
+ private static array $options = [];
/**
* Explicit options for the Config
@@ -65,7 +65,7 @@ final class Factories
*
* @var array>
*/
- private static $aliases = [];
+ private static array $aliases = [];
/**
* Store for instances of any component that
@@ -78,7 +78,7 @@ final class Factories
*
* @var array>
*/
- private static $instances = [];
+ private static array $instances = [];
/**
* Whether the component instances are updated?
@@ -87,7 +87,7 @@ final class Factories
*
* @internal For caching only
*/
- private static $updated = [];
+ private static array $updated = [];
/**
* Define the class to load. You can *override* the concrete class.
@@ -162,7 +162,7 @@ public static function __callStatic(string $component, array $arguments)
}
// Try to locate the class
- if (! $class = self::locateClass($options, $alias)) {
+ if (($class = self::locateClass($options, $alias)) === null) {
return null;
}
@@ -213,7 +213,7 @@ private static function getDefinedInstance(array $options, string $alias, array
}
// Try to locate the class
- if (! $class = self::locateClass($options, $alias)) {
+ if (($class = self::locateClass($options, $alias)) === null) {
return null;
}
@@ -310,7 +310,7 @@ class_exists($alias, false)
}
// No namespace? Search for it
// Check all namespaces, prioritizing App and modules
- elseif (! $files = $locator->search($options['path'] . DIRECTORY_SEPARATOR . $alias)) {
+ elseif (($files = $locator->search($options['path'] . DIRECTORY_SEPARATOR . $alias)) === []) {
return null;
}
diff --git a/system/Config/Services.php b/system/Config/Services.php
index e37b1278..aa8c180a 100644
--- a/system/Config/Services.php
+++ b/system/Config/Services.php
@@ -202,7 +202,7 @@ public static function csp(?CSPConfig $config = null, bool $getShared = true)
*/
public static function curlrequest(array $options = [], ?ResponseInterface $response = null, ?App $config = null, bool $getShared = true)
{
- if ($getShared === true) {
+ if ($getShared) {
return static::getSharedInstance('curlrequest', $options, $response, $config);
}
@@ -211,7 +211,7 @@ public static function curlrequest(array $options = [], ?ResponseInterface $resp
return new CURLRequest(
$config,
- new URI($options['base_uri'] ?? null),
+ new URI($options['baseURI'] ?? null),
$response,
$options
);
@@ -230,7 +230,7 @@ public static function email($config = null, bool $getShared = true)
return static::getSharedInstance('email', $config);
}
- if (empty($config) || ! (is_array($config) || $config instanceof EmailConfig)) {
+ if (empty($config) || (! is_array($config) && ! $config instanceof EmailConfig)) {
$config = config(EmailConfig::class);
}
@@ -345,7 +345,7 @@ public static function image(?string $handler = null, ?Images $config = null, bo
$config ??= config(Images::class);
assert($config instanceof Images);
- $handler = $handler ?: $config->defaultHandler;
+ $handler = $handler !== null && $handler !== '' && $handler !== '0' ? $handler : $config->defaultHandler;
$class = $config->handlers[$handler];
return new $class($config);
@@ -385,7 +385,7 @@ public static function language(?string $locale = null, bool $getShared = true)
}
// Use '?:' for empty string check
- $locale = $locale ?: $requestLocale;
+ $locale = $locale !== null && $locale !== '' && $locale !== '0' ? $locale : $requestLocale;
return new Language($locale);
}
@@ -484,7 +484,7 @@ public static function parser(?string $viewPath = null, ?ViewConfig $config = nu
return static::getSharedInstance('parser', $viewPath, $config);
}
- $viewPath = $viewPath ?: (new Paths())->viewDirectory;
+ $viewPath = $viewPath !== null && $viewPath !== '' && $viewPath !== '0' ? $viewPath : (new Paths())->viewDirectory;
$config ??= config(ViewConfig::class);
return new Parser($config, $viewPath, AppServices::get('locator'), CI_DEBUG, AppServices::get('logger'));
@@ -503,7 +503,7 @@ public static function renderer(?string $viewPath = null, ?ViewConfig $config =
return static::getSharedInstance('renderer', $viewPath, $config);
}
- $viewPath = $viewPath ?: (new Paths())->viewDirectory;
+ $viewPath = $viewPath !== null && $viewPath !== '' && $viewPath !== '0' ? $viewPath : (new Paths())->viewDirectory;
$config ??= config(ViewConfig::class);
return new View($config, $viewPath, AppServices::get('locator'), CI_DEBUG, AppServices::get('logger'));
@@ -705,7 +705,7 @@ public static function session(?SessionConfig $config = null, bool $getShared =
// See https://www.php.net/manual/en/function.session-cache-limiter.php.
// The headers are not managed by CI's Response class.
// So, we remove CI's default Cache-Control header.
- AppServices::response()->removeHeader('Cache-Control');
+ AppServices::get('response')->removeHeader('Cache-Control');
$session->start();
}
diff --git a/system/Controller.php b/system/Controller.php
index fc0c41bf..9c6e7ee3 100644
--- a/system/Controller.php
+++ b/system/Controller.php
@@ -15,6 +15,7 @@
use CodeIgniter\HTTP\CLIRequest;
use CodeIgniter\HTTP\Exceptions\HTTPException;
+use CodeIgniter\HTTP\Exceptions\RedirectException;
use CodeIgniter\HTTP\IncomingRequest;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
@@ -77,7 +78,7 @@ class Controller
*
* @return void
*
- * @throws HTTPException
+ * @throws HTTPException|RedirectException
*/
public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
{
@@ -105,7 +106,7 @@ public function initController(RequestInterface $request, ResponseInterface $res
*
* @return void
*
- * @throws HTTPException
+ * @throws HTTPException|RedirectException
*/
protected function forceHTTPS(int $duration = 31_536_000)
{
diff --git a/system/Cookie/Cookie.php b/system/Cookie/Cookie.php
index 01b10db1..d75cce26 100644
--- a/system/Cookie/Cookie.php
+++ b/system/Cookie/Cookie.php
@@ -482,7 +482,7 @@ public function withNeverExpiring()
*/
public function withPath(?string $path)
{
- $path = $path ?: self::$defaults['path'];
+ $path = $path !== null && $path !== '' && $path !== '0' ? $path : self::$defaults['path'];
$this->validatePrefix($this->prefix, $this->secure, $path, $this->domain);
$cookie = clone $this;
diff --git a/system/Database/BaseBuilder.php b/system/Database/BaseBuilder.php
index 9d5a02db..e738a331 100644
--- a/system/Database/BaseBuilder.php
+++ b/system/Database/BaseBuilder.php
@@ -579,7 +579,7 @@ public function distinct(bool $val = true)
*/
public function from($from, bool $overwrite = false): self
{
- if ($overwrite === true) {
+ if ($overwrite) {
$this->QBFrom = [];
$this->db->setAliasedTables([]);
}
@@ -769,7 +769,7 @@ protected function whereHaving(string $qbKey, $key, $value = null, string $type
foreach ($keyValue as $k => $v) {
$prefix = empty($this->{$qbKey}) ? $this->groupGetType('') : $this->groupGetType($type);
- if ($rawSqlOnly === true) {
+ if ($rawSqlOnly) {
$k = '';
$op = '';
} elseif ($v !== null) {
@@ -836,7 +836,7 @@ protected function whereHaving(string $qbKey, $key, $value = null, string $type
* Generates a WHERE field IN('item', 'item') SQL query,
* joined with 'AND' if appropriate.
*
- * @param array|BaseBuilder|Closure|string $values The values searched on, or anonymous function with subquery
+ * @param array|BaseBuilder|(Closure(BaseBuilder): BaseBuilder)|null $values The values searched on, or anonymous function with subquery
*
* @return $this
*/
@@ -849,7 +849,7 @@ public function whereIn(?string $key = null, $values = null, ?bool $escape = nul
* Generates a WHERE field IN('item', 'item') SQL query,
* joined with 'OR' if appropriate.
*
- * @param array|BaseBuilder|Closure|string $values The values searched on, or anonymous function with subquery
+ * @param array|BaseBuilder|(Closure(BaseBuilder): BaseBuilder)|null $values The values searched on, or anonymous function with subquery
*
* @return $this
*/
@@ -862,7 +862,7 @@ public function orWhereIn(?string $key = null, $values = null, ?bool $escape = n
* Generates a WHERE field NOT IN('item', 'item') SQL query,
* joined with 'AND' if appropriate.
*
- * @param array|BaseBuilder|Closure|string $values The values searched on, or anonymous function with subquery
+ * @param array|BaseBuilder|(Closure(BaseBuilder): BaseBuilder)|null $values The values searched on, or anonymous function with subquery
*
* @return $this
*/
@@ -875,7 +875,7 @@ public function whereNotIn(?string $key = null, $values = null, ?bool $escape =
* Generates a WHERE field NOT IN('item', 'item') SQL query,
* joined with 'OR' if appropriate.
*
- * @param array|BaseBuilder|Closure|string $values The values searched on, or anonymous function with subquery
+ * @param array|BaseBuilder|(Closure(BaseBuilder): BaseBuilder)|null $values The values searched on, or anonymous function with subquery
*
* @return $this
*/
@@ -888,7 +888,7 @@ public function orWhereNotIn(?string $key = null, $values = null, ?bool $escape
* Generates a HAVING field IN('item', 'item') SQL query,
* joined with 'AND' if appropriate.
*
- * @param array|BaseBuilder|Closure|string $values The values searched on, or anonymous function with subquery
+ * @param array|BaseBuilder|(Closure(BaseBuilder): BaseBuilder)|null $values The values searched on, or anonymous function with subquery
*
* @return $this
*/
@@ -901,7 +901,7 @@ public function havingIn(?string $key = null, $values = null, ?bool $escape = nu
* Generates a HAVING field IN('item', 'item') SQL query,
* joined with 'OR' if appropriate.
*
- * @param array|BaseBuilder|Closure|string $values The values searched on, or anonymous function with subquery
+ * @param array|BaseBuilder|(Closure(BaseBuilder): BaseBuilder)|null $values The values searched on, or anonymous function with subquery
*
* @return $this
*/
@@ -914,7 +914,7 @@ public function orHavingIn(?string $key = null, $values = null, ?bool $escape =
* Generates a HAVING field NOT IN('item', 'item') SQL query,
* joined with 'AND' if appropriate.
*
- * @param array|BaseBuilder|Closure|string $values The values searched on, or anonymous function with subquery
+ * @param array|BaseBuilder|(Closure(BaseBuilder):BaseBuilder)|null $values The values searched on, or anonymous function with subquery
*
* @return $this
*/
@@ -927,7 +927,7 @@ public function havingNotIn(?string $key = null, $values = null, ?bool $escape =
* Generates a HAVING field NOT IN('item', 'item') SQL query,
* joined with 'OR' if appropriate.
*
- * @param array|BaseBuilder|Closure|string $values The values searched on, or anonymous function with subquery
+ * @param array|BaseBuilder|(Closure(BaseBuilder): BaseBuilder)|null $values The values searched on, or anonymous function with subquery
*
* @return $this
*/
@@ -942,8 +942,8 @@ public function orHavingNotIn(?string $key = null, $values = null, ?bool $escape
* @used-by whereNotIn()
* @used-by orWhereNotIn()
*
- * @param non-empty-string|null $key
- * @param array|BaseBuilder|Closure|null $values The values searched on, or anonymous function with subquery
+ * @param non-empty-string|null $key
+ * @param array|BaseBuilder|(Closure(BaseBuilder): BaseBuilder)|null $values The values searched on, or anonymous function with subquery
*
* @return $this
*
@@ -1150,8 +1150,8 @@ protected function _like($field, string $match = '', string $type = 'AND ', stri
$keyValue = ! is_array($field) ? [$field => $match] : $field;
foreach ($keyValue as $k => $v) {
- if ($insensitiveSearch === true) {
- $v = strtolower($v);
+ if ($insensitiveSearch) {
+ $v = mb_strtolower($v, 'UTF-8');
}
$prefix = empty($this->{$clause}) ? $this->groupGetType('') : $this->groupGetType($type);
@@ -1187,7 +1187,7 @@ protected function _like($field, string $match = '', string $type = 'AND ', stri
*/
protected function _like_statement(?string $prefix, string $column, ?string $not, string $bind, bool $insensitiveSearch = false): string
{
- if ($insensitiveSearch === true) {
+ if ($insensitiveSearch) {
return "{$prefix} LOWER(" . $this->db->escapeIdentifiers($column) . ") {$not} LIKE :{$bind}:";
}
@@ -1197,7 +1197,7 @@ protected function _like_statement(?string $prefix, string $column, ?string $not
/**
* Add UNION statement
*
- * @param BaseBuilder|Closure $union
+ * @param BaseBuilder|Closure(BaseBuilder): BaseBuilder $union
*
* @return $this
*/
@@ -1209,7 +1209,7 @@ public function union($union)
/**
* Add UNION ALL statement
*
- * @param BaseBuilder|Closure $union
+ * @param BaseBuilder|Closure(BaseBuilder): BaseBuilder $union
*
* @return $this
*/
@@ -1222,7 +1222,7 @@ public function unionAll($union)
* @used-by union()
* @used-by unionAll()
*
- * @param BaseBuilder|Closure $union
+ * @param BaseBuilder|Closure(BaseBuilder): BaseBuilder $union
*
* @return $this
*/
@@ -1599,7 +1599,7 @@ public function getCompiledSelect(bool $reset = true): string
{
$select = $this->compileSelect();
- if ($reset === true) {
+ if ($reset) {
$this->resetSelect();
}
@@ -1643,7 +1643,7 @@ public function get(?int $limit = null, int $offset = 0, bool $reset = true)
? $this->getCompiledSelect($reset)
: $this->db->query($this->compileSelect(), $this->binds, false);
- if ($reset === true) {
+ if ($reset) {
$this->resetSelect();
// Clear our binds so we don't eat up memory
@@ -1678,7 +1678,7 @@ public function countAll(bool $reset = true)
$query = $query->getRow();
- if ($reset === true) {
+ if ($reset) {
$this->resetSelect();
}
@@ -1727,7 +1727,7 @@ public function countAllResults(bool $reset = true)
$result = $this->db->query($sql, $this->binds, false);
- if ($reset === true) {
+ if ($reset) {
$this->resetSelect();
} elseif (! isset($this->QBOrderBy)) {
$this->QBOrderBy = $orderBy;
@@ -1736,7 +1736,7 @@ public function countAllResults(bool $reset = true)
// Restore the LIMIT setting
$this->QBLimit = $limit;
- $row = ! $result instanceof ResultInterface ? null : $result->getRow();
+ $row = $result instanceof ResultInterface ? $result->getRow() : null;
if (empty($row)) {
return 0;
@@ -1781,7 +1781,7 @@ public function getWhere($where = null, ?int $limit = null, ?int $offset = 0, bo
? $this->getCompiledSelect($reset)
: $this->db->query($this->compileSelect(), $this->binds, false);
- if ($reset === true) {
+ if ($reset) {
$this->resetSelect();
// Clear our binds so we don't eat up memory
@@ -2297,7 +2297,7 @@ public function getCompiledInsert(bool $reset = true)
array_values($this->QBSet)
);
- if ($reset === true) {
+ if ($reset) {
$this->resetWrite();
}
@@ -2466,7 +2466,7 @@ public function getCompiledUpdate(bool $reset = true)
$sql = $this->_update($this->QBFrom[0], $this->QBSet);
- if ($reset === true) {
+ if ($reset) {
$this->resetWrite();
}
@@ -3167,11 +3167,11 @@ protected function compileWhereHaving(string $qbKey): string
$op = $this->getOperator($condition);
if (
$op === false
- || ! preg_match(
+ || preg_match(
'/^(\(?)(.*)(' . preg_quote($op, '/') . ')\s*(.*(?connID) {
@@ -610,7 +610,7 @@ abstract protected function execute(string $sql);
*/
public function query(string $sql, $binds = null, bool $setEscapeFlags = true, string $queryClass = '')
{
- $queryClass = $queryClass ?: $this->queryClass;
+ $queryClass = $queryClass !== '' && $queryClass !== '0' ? $queryClass : $this->queryClass;
if (empty($this->connID)) {
$this->initialize();
@@ -684,7 +684,7 @@ public function query(string $sql, $binds = null, bool $setEscapeFlags = true, s
// Let others do something with this query.
Events::trigger('DBQuery', $query);
- if ($exception !== null) {
+ if ($exception instanceof DatabaseException) {
throw new DatabaseException(
$exception->getMessage(),
$exception->getCode(),
@@ -846,9 +846,9 @@ public function transBegin(bool $testMode = false): bool
}
// Reset the transaction failure flag.
- // If the $test_mode flag is set to TRUE transactions will be rolled back
+ // If the $testMode flag is set to TRUE transactions will be rolled back
// even if the queries produce a successful result.
- $this->transFailure = ($testMode === true);
+ $this->transFailure = $testMode;
if ($this->_transBegin()) {
$this->transDepth++;
@@ -959,6 +959,8 @@ public function newQuery(): BaseBuilder
* ->get();
* })
*
+ * @param Closure(BaseConnection): mixed $func
+ *
* @return BasePreparedQuery|null
*/
public function prepare(Closure $func, array $options = [])
@@ -1124,7 +1126,7 @@ public function protectIdentifiers($item, bool $prefixSingle = false, ?bool $pro
$item = preg_replace('/^' . $this->swapPre . '(\S+?)/', $this->DBPrefix . '\\1', $item);
}
// Do we prefix an item with no segments?
- elseif ($prefixSingle === true && ! str_starts_with($item, $this->DBPrefix)) {
+ elseif ($prefixSingle && ! str_starts_with($item, $this->DBPrefix)) {
$item = $this->DBPrefix . $item;
}
}
@@ -1147,7 +1149,7 @@ private function protectDotItem(string $item, string $alias, bool $protectIdenti
// NOTE: The ! empty() condition prevents this method
// from breaking when QB isn't enabled.
if (! empty($this->aliasedTables) && in_array($parts[0], $this->aliasedTables, true)) {
- if ($protectIdentifiers === true) {
+ if ($protectIdentifiers) {
foreach ($parts as $key => $val) {
if (! in_array($val, $this->reservedIdentifiers, true)) {
$parts[$key] = $this->escapeIdentifiers($val);
@@ -1198,7 +1200,7 @@ private function protectDotItem(string $item, string $alias, bool $protectIdenti
$item = implode('.', $parts);
}
- if ($protectIdentifiers === true) {
+ if ($protectIdentifiers) {
$item = $this->escapeIdentifiers($item);
}
@@ -1372,7 +1374,7 @@ public function escapeString($str, bool $like = false)
$str = $this->_escapeString($str);
// escape LIKE condition wildcards
- if ($like === true) {
+ if ($like) {
return str_replace(
[
$this->likeEscapeChar,
@@ -1501,7 +1503,7 @@ public function listTables(bool $constrainByPrefix = false)
*/
public function tableExists(string $tableName, bool $cached = true): bool
{
- if ($cached === true) {
+ if ($cached) {
return in_array($this->protectIdentifiers($tableName, true, false, false), $this->listTables(), true);
}
diff --git a/system/Database/BasePreparedQuery.php b/system/Database/BasePreparedQuery.php
index 8c4f252c..6ba2f6eb 100644
--- a/system/Database/BasePreparedQuery.php
+++ b/system/Database/BasePreparedQuery.php
@@ -259,4 +259,12 @@ public function getErrorMessage(): string
{
return $this->errorString;
}
+
+ /**
+ * Whether the input contain binary data.
+ */
+ protected function isBinary(string $input): bool
+ {
+ return mb_detect_encoding($input, 'UTF-8', true) === false;
+ }
}
diff --git a/system/Database/Database.php b/system/Database/Database.php
index 23b6cd0f..e09dcdd2 100644
--- a/system/Database/Database.php
+++ b/system/Database/Database.php
@@ -96,7 +96,7 @@ protected function parseDSN(array $params): array
{
$dsn = parse_url($params['DSN']);
- if (! $dsn) {
+ if ($dsn === 0 || $dsn === '' || $dsn === '0' || $dsn === [] || $dsn === false || $dsn === null) {
throw new InvalidArgumentException('Your DSN connection string is invalid.');
}
diff --git a/system/Database/Forge.php b/system/Database/Forge.php
index 595cd615..fc9aa54e 100644
--- a/system/Database/Forge.php
+++ b/system/Database/Forge.php
@@ -32,9 +32,9 @@ class Forge
protected $db;
/**
- * List of fields.
+ * List of fields in the form `[name => attributes]`
*
- * @var array [name => attributes]
+ * @var array|string>
*/
protected $fields = [];
@@ -449,12 +449,12 @@ public function addForeignKey(
*/
public function dropKey(string $table, string $keyName, bool $prefixKeyName = true): bool
{
- $keyName = $this->db->escapeIdentifiers(($prefixKeyName === true ? $this->db->DBPrefix : '') . $keyName);
+ $keyName = $this->db->escapeIdentifiers(($prefixKeyName ? $this->db->DBPrefix : '') . $keyName);
$table = $this->db->escapeIdentifiers($this->db->DBPrefix . $table);
$dropKeyAsConstraint = $this->dropKeyAsConstraint($table, $keyName);
- if ($dropKeyAsConstraint === true) {
+ if ($dropKeyAsConstraint) {
$sql = sprintf(
$this->dropConstraintStr,
$table,
@@ -559,7 +559,7 @@ public function createTable(string $table, bool $ifNotExists = false, array $att
}
// If table exists lets stop here
- if ($ifNotExists === true && $this->db->tableExists($table, false)) {
+ if ($ifNotExists && $this->db->tableExists($table, false)) {
$this->reset();
return true;
@@ -573,7 +573,7 @@ public function createTable(string $table, bool $ifNotExists = false, array $att
}
// Most databases don't support creating indexes from within the CREATE TABLE statement
- if (! empty($this->keys)) {
+ if ($this->keys !== []) {
for ($i = 0, $sqls = $this->_processIndexes($table), $c = count($sqls); $i < $c; $i++) {
$this->db->query($sqls[$i]);
}
@@ -650,7 +650,7 @@ public function dropTable(string $tableName, bool $ifExists = false, bool $casca
return false;
}
- if ($this->db->DBPrefix && str_starts_with($tableName, $this->db->DBPrefix)) {
+ if ($this->db->DBPrefix !== '' && str_starts_with($tableName, $this->db->DBPrefix)) {
$tableName = substr($tableName, strlen($this->db->DBPrefix));
}
@@ -895,7 +895,7 @@ protected function _processFields(bool $createTable = false): array
$attributes = array_change_key_case($attributes, CASE_UPPER);
- if ($createTable === true && empty($attributes['TYPE'])) {
+ if ($createTable && empty($attributes['TYPE'])) {
continue;
}
@@ -942,7 +942,7 @@ protected function _processFields(bool $createTable = false): array
} else {
$field['null'] = ' NOT ' . $this->null;
}
- } elseif ($createTable === true) {
+ } elseif ($createTable) {
$field['null'] = ' NOT ' . $this->null;
}
@@ -1085,7 +1085,7 @@ protected function _processPrimaryKeys(string $table, bool $asQuery = false): st
}
if (isset($this->primaryKeys['fields']) && $this->primaryKeys['fields'] !== []) {
- if ($asQuery === true) {
+ if ($asQuery) {
$sql .= 'ALTER TABLE ' . $this->db->escapeIdentifiers($this->db->DBPrefix . $table) . ' ADD ';
} else {
$sql .= ",\n\t";
@@ -1108,10 +1108,12 @@ public function processIndexes(string $table): bool
$fk = $this->foreignKeys;
if ($this->fields === []) {
- $this->fields = array_flip(array_map(
- static fn ($columnName) => $columnName->name,
- $this->db->getFieldData($this->db->DBPrefix . $table)
- ));
+ $fieldData = $this->db->getFieldData($this->db->DBPrefix . $table);
+
+ $this->fields = array_combine(
+ array_map(static fn ($columnName) => $columnName->name, $fieldData),
+ array_fill(0, count($fieldData), [])
+ );
}
$fields = $this->fields;
@@ -1229,7 +1231,7 @@ protected function _processForeignKeys(string $table, bool $asQuery = false): ar
$referenceTableFilled = $this->db->escapeIdentifiers($this->db->DBPrefix . $fkey['referenceTable']);
$referenceFieldFilled = implode(', ', $this->db->escapeIdentifiers($fkey['referenceField']));
- if ($asQuery === true) {
+ if ($asQuery) {
$sqls[$index] .= 'ALTER TABLE ' . $this->db->escapeIdentifiers($this->db->DBPrefix . $table) . ' ADD ';
} else {
$sqls[$index] .= ",\n\t";
diff --git a/system/Database/Migration.php b/system/Database/Migration.php
index 4386b744..ca9e5e0c 100644
--- a/system/Database/Migration.php
+++ b/system/Database/Migration.php
@@ -45,7 +45,7 @@ public function __construct(?Forge $forge = null)
{
if (isset($this->DBGroup)) {
$this->forge = Database::forge($this->DBGroup);
- } elseif ($forge !== null) {
+ } elseif ($forge instanceof Forge) {
$this->forge = $forge;
} else {
$this->forge = Database::forge(config(Database::class)->defaultGroup);
diff --git a/system/Database/MigrationRunner.php b/system/Database/MigrationRunner.php
index 055b8ba6..13919c78 100644
--- a/system/Database/MigrationRunner.php
+++ b/system/Database/MigrationRunner.php
@@ -19,7 +19,6 @@
use CodeIgniter\I18n\Time;
use Config\Database;
use Config\Migrations as MigrationsConfig;
-use Config\Services;
use RuntimeException;
use stdClass;
@@ -390,7 +389,7 @@ public function force(string $path, string $namespace, ?string $group = null)
*/
public function findMigrations(): array
{
- $namespaces = $this->namespace ? [$this->namespace] : array_keys(Services::autoloader()->getNamespace());
+ $namespaces = $this->namespace !== null ? [$this->namespace] : array_keys(service('autoloader')->getNamespace());
$migrations = [];
foreach ($namespaces as $namespace) {
@@ -415,7 +414,7 @@ public function findMigrations(): array
public function findNamespaceMigrations(string $namespace): array
{
$migrations = [];
- $locator = Services::locator(true);
+ $locator = service('locator', true);
if (! empty($this->path)) {
helper('filesystem');
@@ -451,11 +450,11 @@ protected function migrationFromFile(string $path, string $namespace)
$filename = basename($path, '.php');
- if (! preg_match($this->regex, $filename)) {
+ if (preg_match($this->regex, $filename) !== 1) {
return false;
}
- $locator = Services::locator(true);
+ $locator = service('locator', true);
$migration = new stdClass();
@@ -525,7 +524,7 @@ protected function getMigrationNumber(string $migration): string
{
preg_match($this->regex, $migration, $matches);
- return count($matches) ? $matches[1] : '0';
+ return $matches !== [] ? $matches[1] : '0';
}
/**
@@ -540,7 +539,7 @@ protected function getMigrationName(string $migration): string
{
preg_match($this->regex, $migration, $matches);
- return count($matches) ? $matches[2] : '';
+ return $matches !== [] ? $matches[2] : '';
}
/**
@@ -646,7 +645,7 @@ public function getHistory(string $group = 'default'): array
}
// If a namespace was specified then use it
- if ($this->namespace) {
+ if ($this->namespace !== null) {
$builder->where('namespace', $this->namespace);
}
@@ -701,7 +700,7 @@ public function getLastBatch(): int
->get()
->getResultObject();
- $batch = is_array($batch) && count($batch)
+ $batch = is_array($batch) && $batch !== []
? end($batch)->batch
: 0;
@@ -726,7 +725,7 @@ public function getBatchStart(int $batch): string
->get()
->getResultObject();
- return count($migration) ? $migration[0]->version : '0';
+ return $migration !== [] ? $migration[0]->version : '0';
}
/**
diff --git a/system/Database/MySQLi/Connection.php b/system/Database/MySQLi/Connection.php
index 068dfba5..f98f51fb 100644
--- a/system/Database/MySQLi/Connection.php
+++ b/system/Database/MySQLi/Connection.php
@@ -57,7 +57,7 @@ class Connection extends BaseConnection
/**
* MySQLi object
*
- * Has to be preserved without being assigned to $conn_id.
+ * Has to be preserved without being assigned to $connId.
*
* @var false|mysqli
*/
@@ -96,7 +96,7 @@ public function connect(bool $persistent = false)
$port = null;
$socket = $this->hostname;
} else {
- $hostname = ($persistent === true) ? 'p:' . $this->hostname : $this->hostname;
+ $hostname = $persistent ? 'p:' . $this->hostname : $this->hostname;
$port = empty($this->port) ? null : $this->port;
$socket = '';
}
@@ -193,7 +193,7 @@ public function connect(bool $persistent = false)
$clientFlags
)) {
// Prior to version 5.7.3, MySQL silently downgrades to an unencrypted connection if SSL setup fails
- if (($clientFlags & MYSQLI_CLIENT_SSL) && version_compare($this->mysqli->client_info, 'mysqlnd 5.7.3', '<=')
+ if (($clientFlags & MYSQLI_CLIENT_SSL) !== 0 && version_compare($this->mysqli->client_info, 'mysqlnd 5.7.3', '<=')
&& empty($this->mysqli->query("SHOW STATUS LIKE 'ssl_cipher'")->fetch_object()->Value)
) {
$this->mysqli->close();
@@ -297,7 +297,7 @@ public function getVersion(): string
/**
* Executes the query against the database.
*
- * @return false|mysqli_result;
+ * @return false|mysqli_result
*/
protected function execute(string $sql)
{
@@ -395,11 +395,11 @@ protected function _listTables(bool $prefixLimit = false, ?string $tableName = n
{
$sql = 'SHOW TABLES FROM ' . $this->escapeIdentifier($this->database);
- if ($tableName !== null) {
+ if ((string) $tableName !== '') {
return $sql . ' LIKE ' . $this->escape($tableName);
}
- if ($prefixLimit !== false && $this->DBPrefix !== '') {
+ if ($prefixLimit && $this->DBPrefix !== '') {
return $sql . " LIKE '" . $this->escapeLikeStringDirect($this->DBPrefix) . "%'";
}
@@ -462,7 +462,9 @@ protected function _indexData(string $table): array
throw new DatabaseException(lang('Database.failGetIndexData'));
}
- if (! $indexes = $query->getResultArray()) {
+ $indexes = $query->getResultArray();
+
+ if ($indexes === []) {
return [];
}
diff --git a/system/Database/MySQLi/Forge.php b/system/Database/MySQLi/Forge.php
index 132bde12..c47ff4de 100644
--- a/system/Database/MySQLi/Forge.php
+++ b/system/Database/MySQLi/Forge.php
@@ -116,11 +116,11 @@ protected function _createTableAttributes(array $attributes): string
}
}
- if ($this->db->charset !== '' && ! strpos($sql, 'CHARACTER SET') && ! strpos($sql, 'CHARSET')) {
+ if ($this->db->charset !== '' && ! str_contains($sql, 'CHARACTER SET') && ! str_contains($sql, 'CHARSET')) {
$sql .= ' DEFAULT CHARACTER SET = ' . $this->db->escapeString($this->db->charset);
}
- if ($this->db->DBCollat !== '' && ! strpos($sql, 'COLLATE')) {
+ if ($this->db->DBCollat !== '' && ! str_contains($sql, 'COLLATE')) {
$sql .= ' COLLATE = ' . $this->db->escapeString($this->db->DBCollat);
}
@@ -222,7 +222,7 @@ protected function _processIndexes(string $table, bool $asQuery = false): array
implode('_', $this->keys[$i]['fields']) :
$this->keys[$i]['keyName']);
- if ($asQuery === true) {
+ if ($asQuery) {
$sqls[$index] = 'ALTER TABLE ' . $this->db->escapeIdentifiers($table) . " ADD {$unique}KEY "
. $keyName
. ' (' . implode(', ', $this->db->escapeIdentifiers($this->keys[$i]['fields'])) . ')';
diff --git a/system/Database/MySQLi/PreparedQuery.php b/system/Database/MySQLi/PreparedQuery.php
index e9a6c6d1..34eedc25 100644
--- a/system/Database/MySQLi/PreparedQuery.php
+++ b/system/Database/MySQLi/PreparedQuery.php
@@ -66,15 +66,19 @@ public function _execute(array $data): bool
throw new BadMethodCallException('You must call prepare before trying to execute a prepared statement.');
}
- // First off -bind the parameters
- $bindTypes = '';
+ // First off - bind the parameters
+ $bindTypes = '';
+ $binaryData = [];
// Determine the type string
- foreach ($data as $item) {
+ foreach ($data as $key => $item) {
if (is_int($item)) {
$bindTypes .= 'i';
} elseif (is_numeric($item)) {
$bindTypes .= 'd';
+ } elseif (is_string($item) && $this->isBinary($item)) {
+ $bindTypes .= 'b';
+ $binaryData[$key] = $item;
} else {
$bindTypes .= 's';
}
@@ -83,6 +87,11 @@ public function _execute(array $data): bool
// Bind it
$this->statement->bind_param($bindTypes, ...$data);
+ // Stream binary data
+ foreach ($binaryData as $key => $value) {
+ $this->statement->send_long_data($key, $value);
+ }
+
try {
return $this->statement->execute();
} catch (mysqli_sql_exception $e) {
diff --git a/system/Database/OCI8/Builder.php b/system/Database/OCI8/Builder.php
index 4423a524..24a6bb53 100644
--- a/system/Database/OCI8/Builder.php
+++ b/system/Database/OCI8/Builder.php
@@ -109,12 +109,12 @@ protected function _replace(string $table, array $keys, array $values): string
{
$fieldNames = array_map(static fn ($columnName) => trim($columnName, '"'), $keys);
- $uniqueIndexes = array_filter($this->db->getIndexData($table), static function ($index) use ($fieldNames) {
+ $uniqueIndexes = array_filter($this->db->getIndexData($table), static function ($index) use ($fieldNames): bool {
$hasAllFields = count(array_intersect($index->fields, $fieldNames)) === count($index->fields);
return ($index->type === 'PRIMARY') && $hasAllFields;
});
- $replaceableFields = array_filter($keys, static function ($columnName) use ($uniqueIndexes) {
+ $replaceableFields = array_filter($keys, static function ($columnName) use ($uniqueIndexes): bool {
foreach ($uniqueIndexes as $index) {
if (in_array(trim($columnName, '"'), $index->fields, true)) {
return false;
@@ -344,7 +344,7 @@ protected function _upsertBatch(string $table, array $keys, array $values): stri
if (empty($constraints)) {
$fieldNames = array_map(static fn ($columnName) => trim($columnName, '"'), $keys);
- $uniqueIndexes = array_filter($this->db->getIndexData($table), static function ($index) use ($fieldNames) {
+ $uniqueIndexes = array_filter($this->db->getIndexData($table), static function ($index) use ($fieldNames): bool {
$hasAllFields = count(array_intersect($index->fields, $fieldNames)) === count($index->fields);
return ($index->type === 'PRIMARY' || $index->type === 'UNIQUE') && $hasAllFields;
diff --git a/system/Database/OCI8/Connection.php b/system/Database/OCI8/Connection.php
index 2b870b75..c59d588c 100644
--- a/system/Database/OCI8/Connection.php
+++ b/system/Database/OCI8/Connection.php
@@ -274,7 +274,7 @@ protected function _listTables(bool $prefixLimit = false, ?string $tableName = n
return $sql . ' WHERE "TABLE_NAME" LIKE ' . $this->escape($tableName);
}
- if ($prefixLimit !== false && $this->DBPrefix !== '') {
+ if ($prefixLimit && $this->DBPrefix !== '') {
return $sql . ' WHERE "TABLE_NAME" LIKE \'' . $this->escapeLikeString($this->DBPrefix) . "%' "
. sprintf($this->likeEscapeStr, $this->likeEscapeChar);
}
diff --git a/system/Database/OCI8/Forge.php b/system/Database/OCI8/Forge.php
index 5a10363b..7d81cff8 100644
--- a/system/Database/OCI8/Forge.php
+++ b/system/Database/OCI8/Forge.php
@@ -135,7 +135,7 @@ protected function _alterTable(string $alterType, string $table, $processedField
$wantToAddNull = ! str_contains($processedFields[$i]['null'], ' NOT');
$currentNullable = $nullableMap[$processedFields[$i]['name']];
- if ($wantToAddNull === true && $currentNullable === true) {
+ if ($wantToAddNull && $currentNullable === true) {
$processedFields[$i]['null'] = '';
} elseif ($processedFields[$i]['null'] === '' && $currentNullable === false) {
// Nullable by default
@@ -293,7 +293,7 @@ protected function _dropTable(string $table, bool $ifExists, bool $cascade)
{
$sql = parent::_dropTable($table, $ifExists, $cascade);
- if ($sql !== true && $cascade === true) {
+ if ($sql !== true && $cascade) {
$sql .= ' CASCADE CONSTRAINTS PURGE';
} elseif ($sql !== true) {
$sql .= ' PURGE';
diff --git a/system/Database/OCI8/PreparedQuery.php b/system/Database/OCI8/PreparedQuery.php
index c267f806..e1577642 100644
--- a/system/Database/OCI8/PreparedQuery.php
+++ b/system/Database/OCI8/PreparedQuery.php
@@ -16,6 +16,7 @@
use BadMethodCallException;
use CodeIgniter\Database\BasePreparedQuery;
use CodeIgniter\Database\Exceptions\DatabaseException;
+use OCILob;
/**
* Prepared query for OCI8
@@ -73,12 +74,24 @@ public function _execute(array $data): bool
throw new BadMethodCallException('You must call prepare before trying to execute a prepared statement.');
}
+ $binaryData = null;
+
foreach (array_keys($data) as $key) {
- oci_bind_by_name($this->statement, ':' . $key, $data[$key]);
+ if (is_string($data[$key]) && $this->isBinary($data[$key])) {
+ $binaryData = oci_new_descriptor($this->db->connID, OCI_D_LOB);
+ $binaryData->writeTemporary($data[$key], OCI_TEMP_BLOB);
+ oci_bind_by_name($this->statement, ':' . $key, $binaryData, -1, OCI_B_BLOB);
+ } else {
+ oci_bind_by_name($this->statement, ':' . $key, $data[$key]);
+ }
}
$result = oci_execute($this->statement, $this->db->commitMode);
+ if ($binaryData instanceof OCILob) {
+ $binaryData->free();
+ }
+
if ($result && $this->lastInsertTableName !== '') {
$this->db->lastInsertedTableName = $this->lastInsertTableName;
}
@@ -113,7 +126,7 @@ public function parameterize(string $sql): string
// Track our current value
$count = 0;
- return preg_replace_callback('/\?/', static function ($matches) use (&$count) {
+ return preg_replace_callback('/\?/', static function ($matches) use (&$count): string {
return ':' . ($count++);
}, $sql);
}
diff --git a/system/Database/Postgre/Builder.php b/system/Database/Postgre/Builder.php
index 0d2dce09..faae0eda 100644
--- a/system/Database/Postgre/Builder.php
+++ b/system/Database/Postgre/Builder.php
@@ -293,7 +293,7 @@ protected function _truncate(string $table): string
*/
protected function _like_statement(?string $prefix, string $column, ?string $not, string $bind, bool $insensitiveSearch = false): string
{
- $op = $insensitiveSearch === true ? 'ILIKE' : 'LIKE';
+ $op = $insensitiveSearch ? 'ILIKE' : 'LIKE';
return "{$prefix} {$column} {$not} {$op} :{$bind}:";
}
@@ -368,7 +368,7 @@ protected function _updateBatch(string $table, array $keys, array $values): stri
$sql .= 'WHERE ' . implode(
' AND ',
array_map(
- static function ($key, $value) use ($table, $alias, $that) {
+ static function ($key, $value) use ($table, $alias, $that): string|RawSql {
if ($value instanceof RawSql && is_string($key)) {
return $table . '.' . $key . ' = ' . $value;
}
@@ -463,7 +463,7 @@ protected function _upsertBatch(string $table, array $keys, array $values): stri
$constraints = $this->QBOptions['constraints'] ?? [];
if (empty($constraints)) {
- $allIndexes = array_filter($this->db->getIndexData($table), static function ($index) use ($fieldNames) {
+ $allIndexes = array_filter($this->db->getIndexData($table), static function ($index) use ($fieldNames): bool {
$hasAllFields = count(array_intersect($index->fields, $fieldNames)) === count($index->fields);
return ($index->type === 'UNIQUE' || $index->type === 'PRIMARY') && $hasAllFields;
@@ -575,7 +575,7 @@ protected function _deleteBatch(string $table, array $keys, array $values): stri
$sql .= 'WHERE ' . implode(
' AND ',
array_map(
- static function ($key, $value) use ($table, $alias, $that) {
+ static function ($key, $value) use ($table, $alias, $that): RawSql|string {
if ($value instanceof RawSql) {
return $value;
}
diff --git a/system/Database/Postgre/Connection.php b/system/Database/Postgre/Connection.php
index ec886dbd..4ce2b076 100644
--- a/system/Database/Postgre/Connection.php
+++ b/system/Database/Postgre/Connection.php
@@ -74,11 +74,11 @@ public function connect(bool $persistent = false)
$this->convertDSN();
}
- $this->connID = $persistent === true ? pg_pconnect($this->DSN) : pg_connect($this->DSN);
+ $this->connID = $persistent ? pg_pconnect($this->DSN) : pg_connect($this->DSN);
if ($this->connID !== false) {
if (
- $persistent === true
+ $persistent
&& pg_connection_status($this->connID) === PGSQL_CONNECTION_BAD
&& pg_ping($this->connID) === false
) {
@@ -149,8 +149,9 @@ private function convertDSN()
*/
public function reconnect()
{
- if (pg_ping($this->connID) === false) {
- $this->connID = false;
+ if ($this->connID === false || pg_ping($this->connID) === false) {
+ $this->close();
+ $this->initialize();
}
}
@@ -289,7 +290,7 @@ protected function _listTables(bool $prefixLimit = false, ?string $tableName = n
return $sql . ' AND "table_name" LIKE ' . $this->escape($tableName);
}
- if ($prefixLimit !== false && $this->DBPrefix !== '') {
+ if ($prefixLimit && $this->DBPrefix !== '') {
return $sql . ' AND "table_name" LIKE \''
. $this->escapeLikeString($this->DBPrefix) . "%' "
. sprintf($this->likeEscapeStr, $this->likeEscapeChar);
@@ -462,7 +463,7 @@ public function error(): array
{
return [
'code' => '',
- 'message' => pg_last_error($this->connID) ?: '',
+ 'message' => pg_last_error($this->connID),
];
}
diff --git a/system/Database/Postgre/Forge.php b/system/Database/Postgre/Forge.php
index 7a61bed5..704f3e57 100644
--- a/system/Database/Postgre/Forge.php
+++ b/system/Database/Postgre/Forge.php
@@ -118,7 +118,7 @@ protected function _alterTable(string $alterType, string $table, $processedField
$nullable = false;
}
$sqls[] = $sql . ' ALTER COLUMN ' . $this->db->escapeIdentifiers($field['name'])
- . ($nullable === true ? ' DROP' : ' SET') . ' NOT NULL';
+ . ($nullable ? ' DROP' : ' SET') . ' NOT NULL';
if (! empty($field['new_name'])) {
$sqls[] = $sql . ' RENAME COLUMN ' . $this->db->escapeIdentifiers($field['name'])
@@ -173,6 +173,10 @@ protected function _attributeType(array &$attributes)
$attributes['TYPE'] = 'TIMESTAMP';
break;
+ case 'BLOB':
+ $attributes['TYPE'] = 'BYTEA';
+ break;
+
default:
break;
}
@@ -195,7 +199,7 @@ protected function _dropTable(string $table, bool $ifExists, bool $cascade): str
{
$sql = parent::_dropTable($table, $ifExists, $cascade);
- if ($cascade === true) {
+ if ($cascade) {
$sql .= ' CASCADE';
}
diff --git a/system/Database/Postgre/PreparedQuery.php b/system/Database/Postgre/PreparedQuery.php
index fbea6ac1..c55d5d8c 100644
--- a/system/Database/Postgre/PreparedQuery.php
+++ b/system/Database/Postgre/PreparedQuery.php
@@ -87,6 +87,12 @@ public function _execute(array $data): bool
throw new BadMethodCallException('You must call prepare before trying to execute a prepared statement.');
}
+ foreach ($data as &$item) {
+ if (is_string($item) && $this->isBinary($item)) {
+ $item = pg_escape_bytea($this->db->connID, $item);
+ }
+ }
+
$this->result = pg_execute($this->db->connID, $this->name, $data);
return (bool) $this->result;
@@ -119,7 +125,7 @@ public function parameterize(string $sql): string
// Track our current value
$count = 0;
- return preg_replace_callback('/\?/', static function () use (&$count) {
+ return preg_replace_callback('/\?/', static function () use (&$count): string {
$count++;
return "\${$count}";
diff --git a/system/Database/SQLSRV/Builder.php b/system/Database/SQLSRV/Builder.php
index a6d0b8e8..c1272cdc 100644
--- a/system/Database/SQLSRV/Builder.php
+++ b/system/Database/SQLSRV/Builder.php
@@ -518,7 +518,7 @@ public function countAll(bool $reset = true)
$query = $query->getRow();
- if ($reset === true) {
+ if ($reset) {
$this->resetSelect();
}
@@ -699,7 +699,7 @@ protected function _upsertBatch(string $table, array $keys, array $values): stri
if (empty($constraints)) {
$tableIndexes = $this->db->getIndexData($table);
- $uniqueIndexes = array_filter($tableIndexes, static function ($index) use ($fieldNames) {
+ $uniqueIndexes = array_filter($tableIndexes, static function ($index) use ($fieldNames): bool {
$hasAllFields = count(array_intersect($index->fields, $fieldNames)) === count($index->fields);
return $index->type === 'PRIMARY' && $hasAllFields;
@@ -707,7 +707,7 @@ protected function _upsertBatch(string $table, array $keys, array $values): stri
// if no primary found then look for unique - since indexes have no order
if ($uniqueIndexes === []) {
- $uniqueIndexes = array_filter($tableIndexes, static function ($index) use ($fieldNames) {
+ $uniqueIndexes = array_filter($tableIndexes, static function ($index) use ($fieldNames): bool {
$hasAllFields = count(array_intersect($index->fields, $fieldNames)) === count($index->fields);
return $index->type === 'UNIQUE' && $hasAllFields;
diff --git a/system/Database/SQLSRV/Connection.php b/system/Database/SQLSRV/Connection.php
index 7e008e27..8ded4cd0 100644
--- a/system/Database/SQLSRV/Connection.php
+++ b/system/Database/SQLSRV/Connection.php
@@ -215,7 +215,7 @@ protected function _listTables(bool $prefixLimit = false, ?string $tableName = n
return $sql .= ' AND [TABLE_NAME] LIKE ' . $this->escape($tableName);
}
- if ($prefixLimit === true && $this->DBPrefix !== '') {
+ if ($prefixLimit && $this->DBPrefix !== '') {
$sql .= " AND [TABLE_NAME] LIKE '" . $this->escapeLikeString($this->DBPrefix) . "%' "
. sprintf($this->likeEscapeStr, $this->likeEscapeChar);
}
@@ -368,7 +368,11 @@ protected function _fieldData(string $table): array
$retVal[$i]->max_length = $query[$i]->CHARACTER_MAXIMUM_LENGTH > 0
? $query[$i]->CHARACTER_MAXIMUM_LENGTH
- : $query[$i]->NUMERIC_PRECISION;
+ : (
+ $query[$i]->CHARACTER_MAXIMUM_LENGTH === -1
+ ? 'max'
+ : $query[$i]->NUMERIC_PRECISION
+ );
$retVal[$i]->nullable = $query[$i]->IS_NULLABLE !== 'NO';
$retVal[$i]->default = $query[$i]->COLUMN_DEFAULT;
diff --git a/system/Database/SQLSRV/Forge.php b/system/Database/SQLSRV/Forge.php
index cae4eda2..df3d55c7 100644
--- a/system/Database/SQLSRV/Forge.php
+++ b/system/Database/SQLSRV/Forge.php
@@ -212,10 +212,10 @@ protected function _alterTable(string $alterType, string $table, $processedField
$sql = <<db->escapeIdentifiers($field['name'])
- . " {$field['type']}{$field['length']} " . ($nullable === true ? '' : 'NOT') . ' NULL';
+ . " {$field['type']}{$field['length']} " . ($nullable ? '' : 'NOT') . ' NULL';
if (! empty($field['comment'])) {
$sqls[] = 'EXEC sys.sp_addextendedproperty '
@@ -397,6 +397,11 @@ protected function _attributeType(array &$attributes)
$attributes['TYPE'] = 'BIT';
break;
+ case 'BLOB':
+ $attributes['TYPE'] = 'VARBINARY';
+ $attributes['CONSTRAINT'] ??= 'MAX';
+ break;
+
default:
break;
}
diff --git a/system/Database/SQLSRV/PreparedQuery.php b/system/Database/SQLSRV/PreparedQuery.php
index f3a4a14c..42555592 100644
--- a/system/Database/SQLSRV/PreparedQuery.php
+++ b/system/Database/SQLSRV/PreparedQuery.php
@@ -59,7 +59,7 @@ public function _prepare(string $sql, array $options = []): PreparedQuery
// Prepare parameters for the query
$queryString = $this->getQueryString();
- $parameters = $this->parameterize($queryString);
+ $parameters = $this->parameterize($queryString, $options);
// Prepare the query
$this->statement = sqlsrv_prepare($this->db->connID, $sql, $parameters);
@@ -120,8 +120,10 @@ protected function _close(): bool
/**
* Handle parameters.
+ *
+ * @param array $options
*/
- protected function parameterize(string $queryString): array
+ protected function parameterize(string $queryString, array $options): array
{
$numberOfVariables = substr_count($queryString, '?');
@@ -129,7 +131,11 @@ protected function parameterize(string $queryString): array
for ($c = 0; $c < $numberOfVariables; $c++) {
$this->parameters[$c] = null;
- $params[] = &$this->parameters[$c];
+ if (isset($options[$c])) {
+ $params[] = [&$this->parameters[$c], SQLSRV_PARAM_IN, $options[$c]];
+ } else {
+ $params[] = &$this->parameters[$c];
+ }
}
return $params;
diff --git a/system/Database/SQLite3/Builder.php b/system/Database/SQLite3/Builder.php
index a59270bb..15fc2529 100644
--- a/system/Database/SQLite3/Builder.php
+++ b/system/Database/SQLite3/Builder.php
@@ -145,7 +145,7 @@ protected function _upsertBatch(string $table, array $keys, array $values): stri
if (empty($constraints)) {
$fieldNames = array_map(static fn ($columnName) => trim($columnName, '`'), $keys);
- $allIndexes = array_filter($this->db->getIndexData($table), static function ($index) use ($fieldNames) {
+ $allIndexes = array_filter($this->db->getIndexData($table), static function ($index) use ($fieldNames): bool {
$hasAllFields = count(array_intersect($index->fields, $fieldNames)) === count($index->fields);
return ($index->type === 'PRIMARY' || $index->type === 'UNIQUE') && $hasAllFields;
diff --git a/system/Database/SQLite3/Connection.php b/system/Database/SQLite3/Connection.php
index 9945d41d..577e4b24 100644
--- a/system/Database/SQLite3/Connection.php
+++ b/system/Database/SQLite3/Connection.php
@@ -89,7 +89,7 @@ public function connect(bool $persistent = false)
$this->database = WRITEPATH . $this->database;
}
- $sqlite = (! $this->password)
+ $sqlite = (! isset($this->password) || $this->password !== '')
? new SQLite3($this->database)
: new SQLite3($this->database, SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE, $this->password);
@@ -194,7 +194,7 @@ protected function _escapeString(string $str): string
*/
protected function _listTables(bool $prefixLimit = false, ?string $tableName = null): string
{
- if ($tableName !== null) {
+ if ((string) $tableName !== '') {
return 'SELECT "NAME" FROM "SQLITE_MASTER" WHERE "TYPE" = \'table\''
. ' AND "NAME" NOT LIKE \'sqlite!_%\' ESCAPE \'!\''
. ' AND "NAME" LIKE ' . $this->escape($tableName);
@@ -202,7 +202,7 @@ protected function _listTables(bool $prefixLimit = false, ?string $tableName = n
return 'SELECT "NAME" FROM "SQLITE_MASTER" WHERE "TYPE" = \'table\''
. ' AND "NAME" NOT LIKE \'sqlite!_%\' ESCAPE \'!\''
- . (($prefixLimit !== false && $this->DBPrefix !== '')
+ . (($prefixLimit && $this->DBPrefix !== '')
? ' AND "NAME" LIKE \'' . $this->escapeLikeString($this->DBPrefix) . '%\' ' . sprintf($this->likeEscapeStr, $this->likeEscapeChar)
: '');
}
@@ -359,7 +359,7 @@ protected function _indexData(string $table): array
*/
protected function _foreignKeyData(string $table): array
{
- if ($this->supportsForeignKeys() !== true) {
+ if (! $this->supportsForeignKeys()) {
return [];
}
diff --git a/system/Database/SQLite3/PreparedQuery.php b/system/Database/SQLite3/PreparedQuery.php
index 21dc4c2f..0e15b5d6 100644
--- a/system/Database/SQLite3/PreparedQuery.php
+++ b/system/Database/SQLite3/PreparedQuery.php
@@ -75,6 +75,8 @@ public function _execute(array $data): bool
$bindType = SQLITE3_INTEGER;
} elseif (is_float($item)) {
$bindType = SQLITE3_FLOAT;
+ } elseif (is_string($item) && $this->isBinary($item)) {
+ $bindType = SQLITE3_BLOB;
} else {
$bindType = SQLITE3_TEXT;
}
diff --git a/system/Database/Seeder.php b/system/Database/Seeder.php
index be7cfcdf..c70a34b4 100644
--- a/system/Database/Seeder.php
+++ b/system/Database/Seeder.php
@@ -105,7 +105,7 @@ public function __construct(Database $config, ?BaseConnection $db = null)
*/
public static function faker(): ?Generator
{
- if (self::$faker === null && class_exists(Factory::class)) {
+ if (! self::$faker instanceof Generator && class_exists(Factory::class)) {
self::$faker = Factory::create();
}
diff --git a/system/Debug/Exceptions.php b/system/Debug/Exceptions.php
index e5f7ecb0..aa353732 100644
--- a/system/Debug/Exceptions.php
+++ b/system/Debug/Exceptions.php
@@ -22,7 +22,6 @@
use CodeIgniter\HTTP\ResponseInterface;
use Config\Exceptions as ExceptionsConfig;
use Config\Paths;
-use Config\Services;
use ErrorException;
use Psr\Log\LogLevel;
use Throwable;
@@ -126,7 +125,7 @@ public function exceptionHandler(Throwable $exception)
[$statusCode, $exitCode] = $this->determineCodes($exception);
- $this->request = Services::request();
+ $this->request = service('request');
if ($this->config->log === true && ! in_array($statusCode, $this->config->ignoreCodes, true)) {
$uri = $this->request->getPath() === '' ? '/' : $this->request->getPath();
@@ -155,7 +154,7 @@ public function exceptionHandler(Throwable $exception)
}
}
- $this->response = Services::response();
+ $this->response = service('response');
if (method_exists($this->config, 'handler')) {
// Use new ExceptionHandler
diff --git a/system/Debug/Toolbar.php b/system/Debug/Toolbar.php
index 9f20f987..b939e208 100644
--- a/system/Debug/Toolbar.php
+++ b/system/Debug/Toolbar.php
@@ -25,7 +25,6 @@
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use CodeIgniter\I18n\Time;
-use Config\Services;
use Config\Toolbar as ToolbarConfig;
use Kint\Kint;
@@ -386,7 +385,7 @@ public function prepare(?RequestInterface $request = null, ?ResponseInterface $r
return;
}
- $toolbar = Services::toolbar(config(ToolbarConfig::class));
+ $toolbar = service('toolbar', config(ToolbarConfig::class));
$stats = $app->getPerformanceStats();
$data = $toolbar->run(
$stats['startTime'],
@@ -529,7 +528,7 @@ protected function format(string $data, string $format = 'html'): string
case 'html':
$data['styles'] = [];
extract($data);
- $parser = Services::parser($this->config->viewsPath, null, false);
+ $parser = service('parser', $this->config->viewsPath, null, false);
ob_start();
include $this->config->viewsPath . 'toolbar.tpl.php';
$output = ob_get_clean();
diff --git a/system/Debug/Toolbar/Collectors/Database.php b/system/Debug/Toolbar/Collectors/Database.php
index ee9f829b..1a923a35 100644
--- a/system/Debug/Toolbar/Collectors/Database.php
+++ b/system/Debug/Toolbar/Collectors/Database.php
@@ -148,7 +148,7 @@ protected function formatTimelineData(): array
public function display(): array
{
$data = [];
- $data['queries'] = array_map(static function (array $query) {
+ $data['queries'] = array_map(static function (array $query): array {
$isDuplicate = $query['duplicate'] === true;
$firstNonSystemLine = '';
diff --git a/system/Debug/Toolbar/Collectors/Logs.php b/system/Debug/Toolbar/Collectors/Logs.php
index 2194526c..f36dfb1d 100644
--- a/system/Debug/Toolbar/Collectors/Logs.php
+++ b/system/Debug/Toolbar/Collectors/Logs.php
@@ -13,8 +13,6 @@
namespace CodeIgniter\Debug\Toolbar\Collectors;
-use Config\Services;
-
/**
* Loags collector
*/
@@ -92,6 +90,6 @@ protected function collectLogs()
return $this->data;
}
- return $this->data = Services::logger(true)->logCache ?? [];
+ return $this->data = service('logger', true)->logCache ?? [];
}
}
diff --git a/system/Debug/Toolbar/Collectors/Routes.php b/system/Debug/Toolbar/Collectors/Routes.php
index b6862dce..561399fb 100644
--- a/system/Debug/Toolbar/Collectors/Routes.php
+++ b/system/Debug/Toolbar/Collectors/Routes.php
@@ -14,7 +14,6 @@
namespace CodeIgniter\Debug\Toolbar\Collectors;
use CodeIgniter\Router\DefinedRouteCollector;
-use Config\Services;
use ReflectionException;
use ReflectionFunction;
use ReflectionMethod;
@@ -74,8 +73,8 @@ class Routes extends BaseCollector
*/
public function display(): array
{
- $rawRoutes = Services::routes(true);
- $router = Services::router(null, null, true);
+ $rawRoutes = service('routes', true);
+ $router = service('router', null, null, true);
// Get our parameters
// Closure routes
@@ -153,7 +152,7 @@ public function display(): array
*/
public function getBadgeValue(): int
{
- $rawRoutes = Services::routes(true);
+ $rawRoutes = service('routes', true);
return count($rawRoutes->getRoutes());
}
diff --git a/system/Debug/Toolbar/Collectors/Timers.php b/system/Debug/Toolbar/Collectors/Timers.php
index 163c9f57..d450cc5c 100644
--- a/system/Debug/Toolbar/Collectors/Timers.php
+++ b/system/Debug/Toolbar/Collectors/Timers.php
@@ -13,8 +13,6 @@
namespace CodeIgniter\Debug\Toolbar\Collectors;
-use Config\Services;
-
/**
* Timers collector
*/
@@ -52,7 +50,7 @@ protected function formatTimelineData(): array
{
$data = [];
- $benchmark = Services::timer(true);
+ $benchmark = service('timer', true);
$rows = $benchmark->getTimers(6);
foreach ($rows as $name => $info) {
diff --git a/system/Email/Email.php b/system/Email/Email.php
index b82779eb..5d420cc2 100644
--- a/system/Email/Email.php
+++ b/system/Email/Email.php
@@ -485,7 +485,7 @@ public function setFrom($from, $name = '', $returnPath = null)
if ($this->validate) {
$this->validateEmail($this->stringToArray($from));
- if ($returnPath) {
+ if ($returnPath !== null) {
$this->validateEmail($this->stringToArray($returnPath));
}
}
@@ -495,7 +495,7 @@ public function setFrom($from, $name = '', $returnPath = null)
if ($name !== '') {
// only use Q encoding if there are characters that would require it
- if (! preg_match('/[\200-\377]/', $name)) {
+ if (preg_match('/[\200-\377]/', $name) !== 1) {
$name = '"' . addcslashes($name, "\0..\37\177'\"\\") . '"';
} else {
$name = $this->prepQEncoding($name);
@@ -532,7 +532,7 @@ public function setReplyTo($replyto, $name = '')
$this->tmpArchive['replyName'] = $name;
// only use Q encoding if there are characters that would require it
- if (! preg_match('/[\200-\377]/', $name)) {
+ if (preg_match('/[\200-\377]/', $name) !== 1) {
$name = '"' . addcslashes($name, "\0..\37\177'\"\\") . '"';
} else {
$name = $this->prepQEncoding($name);
@@ -1233,7 +1233,9 @@ protected function buildMessage()
$this->headerStr .= $hdr;
}
- static::strlen($body) && $body .= $this->newline . $this->newline;
+ if (static::strlen($body) > 0) {
+ $body .= $this->newline . $this->newline;
+ }
$body .= $this->getMimeMessage() . $this->newline . $this->newline
. '--' . $lastBoundary . $this->newline
diff --git a/system/Encryption/Handlers/OpenSSLHandler.php b/system/Encryption/Handlers/OpenSSLHandler.php
index f3b62c64..9745160b 100644
--- a/system/Encryption/Handlers/OpenSSLHandler.php
+++ b/system/Encryption/Handlers/OpenSSLHandler.php
@@ -82,7 +82,7 @@ class OpenSSLHandler extends BaseHandler
public function encrypt($data, $params = null)
{
// Allow key override
- if ($params) {
+ if ($params !== null) {
$this->key = is_array($params) && isset($params['key']) ? $params['key'] : $params;
}
@@ -118,7 +118,7 @@ public function encrypt($data, $params = null)
public function decrypt($data, $params = null)
{
// Allow key override
- if ($params) {
+ if ($params !== null) {
$this->key = is_array($params) && isset($params['key']) ? $params['key'] : $params;
}
diff --git a/system/Encryption/Handlers/SodiumHandler.php b/system/Encryption/Handlers/SodiumHandler.php
index b6c74da7..c74f2a5f 100644
--- a/system/Encryption/Handlers/SodiumHandler.php
+++ b/system/Encryption/Handlers/SodiumHandler.php
@@ -26,7 +26,7 @@ class SodiumHandler extends BaseHandler
/**
* Starter key
*
- * @var string
+ * @var string|null Null is used for buffer cleanup.
*/
protected $key = '';
diff --git a/system/Events/Events.php b/system/Events/Events.php
index a06bd790..ad8efed6 100644
--- a/system/Events/Events.php
+++ b/system/Events/Events.php
@@ -84,7 +84,7 @@ public static function initialize()
$files = service('locator')->search('Config/Events.php');
}
- $files = array_filter(array_map(static function (string $file) {
+ $files = array_filter(array_map(static function (string $file): false|string {
if (is_file($file)) {
return realpath($file) ?: $file;
}
diff --git a/system/Exceptions/DownloadException.php b/system/Exceptions/DownloadException.php
index df78127d..8ed2ba48 100644
--- a/system/Exceptions/DownloadException.php
+++ b/system/Exceptions/DownloadException.php
@@ -47,6 +47,8 @@ public static function forNotFoundDownloadSource()
}
/**
+ * @deprecated Since v4.5.6
+ *
* @return static
*/
public static function forCannotSetCache()
diff --git a/system/Exceptions/PageNotFoundException.php b/system/Exceptions/PageNotFoundException.php
index b1af079e..1a3b27a7 100644
--- a/system/Exceptions/PageNotFoundException.php
+++ b/system/Exceptions/PageNotFoundException.php
@@ -13,7 +13,6 @@
namespace CodeIgniter\Exceptions;
-use Config\Services;
use OutOfBoundsException;
class PageNotFoundException extends OutOfBoundsException implements ExceptionInterface, HTTPExceptionInterface
@@ -78,7 +77,7 @@ public static function forLocaleNotSupported(string $locale)
*/
private static function lang(string $line, array $args = []): string
{
- $lang = Services::language(null, false);
+ $lang = service('language', null, false);
return $lang->getLine($line, $args);
}
diff --git a/system/Filters/Filters.php b/system/Filters/Filters.php
index 1255e0c4..fd252fe1 100644
--- a/system/Filters/Filters.php
+++ b/system/Filters/Filters.php
@@ -557,7 +557,7 @@ public function enableFilters(array $names, string $when = 'before')
*/
public function getArguments(?string $key = null)
{
- return $key === null ? $this->arguments : $this->arguments[$key];
+ return ((string) $key === '') ? $this->arguments : $this->arguments[$key];
}
// --------------------------------------------------------------------
@@ -674,7 +674,7 @@ protected function processMethods()
*/
protected function processFilters(?string $uri = null)
{
- if (! isset($this->config->filters) || ! $this->config->filters) {
+ if (! isset($this->config->filters) || $this->config->filters === []) {
return;
}
diff --git a/system/Filters/Honeypot.php b/system/Filters/Honeypot.php
index c2fb98c6..cdff293a 100644
--- a/system/Filters/Honeypot.php
+++ b/system/Filters/Honeypot.php
@@ -17,7 +17,6 @@
use CodeIgniter\HTTP\IncomingRequest;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
-use Config\Services;
/**
* Honeypot filter
@@ -40,7 +39,7 @@ public function before(RequestInterface $request, $arguments = null)
return;
}
- if (Services::honeypot()->hasContent($request)) {
+ if (service('honeypot')->hasContent($request)) {
throw HoneypotException::isBot();
}
}
diff --git a/system/HTTP/CLIRequest.php b/system/HTTP/CLIRequest.php
index 0b2c5737..fbc5165e 100644
--- a/system/HTTP/CLIRequest.php
+++ b/system/HTTP/CLIRequest.php
@@ -95,9 +95,7 @@ public function __construct(App $config)
*/
public function getPath(): string
{
- $path = implode('/', $this->segments);
-
- return ($path === '') ? '' : $path;
+ return implode('/', $this->segments);
}
/**
diff --git a/system/HTTP/CURLRequest.php b/system/HTTP/CURLRequest.php
index 9da231c1..90157e4e 100644
--- a/system/HTTP/CURLRequest.php
+++ b/system/HTTP/CURLRequest.php
@@ -389,7 +389,7 @@ public function send(string $method, string $url)
$output = substr($output, strpos($output, $breakString) + 4);
}
- if (str_starts_with($output, 'HTTP/1.1 200 Connection established')) {
+ if (preg_match('/HTTP\/\d\.\d 200 Connection established/i', $output)) {
$output = substr($output, strpos($output, $breakString) + 4);
}
diff --git a/system/HTTP/ContentSecurityPolicy.php b/system/HTTP/ContentSecurityPolicy.php
index 7582bc46..a6a2b26a 100644
--- a/system/HTTP/ContentSecurityPolicy.php
+++ b/system/HTTP/ContentSecurityPolicy.php
@@ -356,9 +356,9 @@ public function reportOnly(bool $value = true)
}
/**
- * Adds a new base_uri value. Can be either a URI class or a simple string.
+ * Adds a new baseURI value. Can be either a URI class or a simple string.
*
- * base_uri restricts the URLs that can appear in a page's element.
+ * baseURI restricts the URLs that can appear in a page's element.
*
* @see http://www.w3.org/TR/CSP/#directive-base-uri
*
@@ -713,7 +713,7 @@ protected function generateNonces(ResponseInterface $response)
$pattern = '/(' . preg_quote($this->styleNonceTag, '/')
. '|' . preg_quote($this->scriptNonceTag, '/') . ')/';
- $body = preg_replace_callback($pattern, function ($match) {
+ $body = preg_replace_callback($pattern, function ($match): string {
$nonce = $match[0] === $this->styleNonceTag ? $this->getStyleNonce() : $this->getScriptNonce();
return "nonce=\"{$nonce}\"";
diff --git a/system/HTTP/DownloadResponse.php b/system/HTTP/DownloadResponse.php
index 6b293fbc..a0da2e8c 100644
--- a/system/HTTP/DownloadResponse.php
+++ b/system/HTTP/DownloadResponse.php
@@ -85,7 +85,7 @@ public function __construct(string $filename, bool $setMime)
*/
public function setBinary(string $binary)
{
- if ($this->file !== null) {
+ if ($this->file instanceof File) {
throw DownloadException::forCannotSetBinary();
}
@@ -142,7 +142,7 @@ private function setContentTypeByMimeType(): void
$mime = null;
$charset = '';
- if ($this->setMime === true && ($lastDotPosition = strrpos($this->filename, '.')) !== false) {
+ if ($this->setMime && ($lastDotPosition = strrpos($this->filename, '.')) !== false) {
$mime = Mimes::guessTypeFromExtension(substr($this->filename, $lastDotPosition + 1));
$charset = $this->charset;
}
@@ -242,16 +242,6 @@ public function noCache(): self
return $this;
}
- /**
- * Disables cache configuration.
- *
- * @throws DownloadException
- */
- public function setCache(array $options = [])
- {
- throw DownloadException::forCannotSetCache();
- }
-
/**
* {@inheritDoc}
*
@@ -290,10 +280,8 @@ public function buildHeaders()
$this->setHeader('Content-Disposition', $this->getContentDisposition());
}
- $this->setHeader('Expires-Disposition', '0');
$this->setHeader('Content-Transfer-Encoding', 'binary');
$this->setHeader('Content-Length', (string) $this->getContentLength());
- $this->noCache();
}
/**
@@ -309,7 +297,7 @@ public function sendBody()
return $this->sendBodyByBinary();
}
- if ($this->file !== null) {
+ if ($this->file instanceof File) {
return $this->sendBodyByFilePath();
}
diff --git a/system/HTTP/Exceptions/RedirectException.php b/system/HTTP/Exceptions/RedirectException.php
index 5f2dcd05..3047bf96 100644
--- a/system/HTTP/Exceptions/RedirectException.php
+++ b/system/HTTP/Exceptions/RedirectException.php
@@ -69,7 +69,7 @@ public function __construct($message = '', int $code = 0, ?Throwable $previous =
public function getResponse(): ResponseInterface
{
- if (null === $this->response) {
+ if (! $this->response instanceof ResponseInterface) {
$this->response = service('response')
->redirect(base_url($this->getMessage()), 'auto', $this->getCode());
}
diff --git a/system/HTTP/Files/FileCollection.php b/system/HTTP/Files/FileCollection.php
index 079d5e73..add2c3c0 100644
--- a/system/HTTP/Files/FileCollection.php
+++ b/system/HTTP/Files/FileCollection.php
@@ -253,7 +253,7 @@ protected function getValueDotNotationSyntax(array $index, array $value)
{
$currentIndex = array_shift($index);
- if (isset($currentIndex) && is_array($index) && $index && is_array($value[$currentIndex]) && $value[$currentIndex]) {
+ if (isset($currentIndex) && is_array($index) && $index !== [] && array_key_exists($currentIndex, $value) && is_array($value[$currentIndex])) {
return $this->getValueDotNotationSyntax($index, $value[$currentIndex]);
}
diff --git a/system/HTTP/Files/UploadedFile.php b/system/HTTP/Files/UploadedFile.php
index 78643aa7..c17a9e5a 100644
--- a/system/HTTP/Files/UploadedFile.php
+++ b/system/HTTP/Files/UploadedFile.php
@@ -302,7 +302,9 @@ public function getTempName(): string
*/
public function getExtension(): string
{
- return $this->guessExtension() ?: $this->getClientExtension();
+ $guessExtension = $this->guessExtension();
+
+ return $guessExtension !== '' ? $guessExtension : $this->getClientExtension();
}
/**
diff --git a/system/HTTP/Negotiate.php b/system/HTTP/Negotiate.php
index 67a03a38..33938c8f 100644
--- a/system/HTTP/Negotiate.php
+++ b/system/HTTP/Negotiate.php
@@ -39,7 +39,7 @@ class Negotiate
*/
public function __construct(?RequestInterface $request = null)
{
- if ($request !== null) {
+ if ($request instanceof RequestInterface) {
assert($request instanceof IncomingRequest);
$this->request = $request;
@@ -233,7 +233,7 @@ public function parseHeader(string $header): array
}
// Sort to get the highest results first
- usort($results, static function ($a, $b) {
+ usort($results, static function ($a, $b): int {
if ($a['q'] === $b['q']) {
$aAst = substr_count($a['value'], '*');
$bAst = substr_count($b['value'], '*');
diff --git a/system/HTTP/OutgoingRequest.php b/system/HTTP/OutgoingRequest.php
index 27e473a5..e62f0724 100644
--- a/system/HTTP/OutgoingRequest.php
+++ b/system/HTTP/OutgoingRequest.php
@@ -64,7 +64,7 @@ private function getHostFromUri(URI $uri): string
{
$host = $uri->getHost();
- return $host . ($uri->getPort() ? ':' . $uri->getPort() : '');
+ return $host . ($uri->getPort() > 0 ? ':' . $uri->getPort() : '');
}
/**
diff --git a/system/HTTP/RedirectResponse.php b/system/HTTP/RedirectResponse.php
index 95bfadcd..206b1de0 100644
--- a/system/HTTP/RedirectResponse.php
+++ b/system/HTTP/RedirectResponse.php
@@ -15,7 +15,6 @@
use CodeIgniter\Cookie\CookieStore;
use CodeIgniter\HTTP\Exceptions\HTTPException;
-use Config\Services;
/**
* Handle a redirect response
@@ -116,9 +115,8 @@ private function withErrors(): self
{
$validation = service('validation');
- if ($validation->getErrors()) {
- $session = service('session');
- $session->setFlashdata('_ci_validation_errors', $validation->getErrors());
+ if ($validation->getErrors() !== []) {
+ service('session')->setFlashdata('_ci_validation_errors', $validation->getErrors());
}
return $this;
@@ -148,7 +146,7 @@ public function with(string $key, $message)
*/
public function withCookies()
{
- $this->cookieStore = new CookieStore(Services::response()->getCookies());
+ $this->cookieStore = new CookieStore(service('response')->getCookies());
return $this;
}
@@ -163,7 +161,7 @@ public function withCookies()
*/
public function withHeaders()
{
- foreach (Services::response()->headers() as $name => $value) {
+ foreach (service('response')->headers() as $name => $value) {
if ($value instanceof Header) {
$this->setHeader($name, $value->getValue());
} else {
diff --git a/system/HTTP/RequestTrait.php b/system/HTTP/RequestTrait.php
index 43a4f23a..dfa4b663 100644
--- a/system/HTTP/RequestTrait.php
+++ b/system/HTTP/RequestTrait.php
@@ -59,7 +59,7 @@ trait RequestTrait
*/
public function getIPAddress(): string
{
- if ($this->ipAddress) {
+ if ($this->ipAddress !== '') {
return $this->ipAddress;
}
@@ -249,7 +249,7 @@ public function setGlobal(string $name, $value)
*
* @param string $name Supergrlobal name (lowercase)
* @phpstan-param 'get'|'post'|'request'|'cookie'|'server' $name
- * @param array|string|null $index
+ * @param array|int|string|null $index
* @param int|null $filter Filter constant
* @param array|int|null $flags Options
*
@@ -290,7 +290,7 @@ public function fetchGlobal(string $name, $index = null, ?int $filter = null, $f
}
// Does the index contain array notation?
- if (($count = preg_match_all('/(?:^[^\[]+)|\[[^]]*\]/', $index, $matches)) > 1) {
+ if (is_string($index) && ($count = preg_match_all('/(?:^[^\[]+)|\[[^]]*\]/', $index, $matches)) > 1) {
$value = $this->globals[$name];
for ($i = 0; $i < $count; $i++) {
diff --git a/system/HTTP/Response.php b/system/HTTP/Response.php
index a19fbb5f..ac853c3d 100644
--- a/system/HTTP/Response.php
+++ b/system/HTTP/Response.php
@@ -18,7 +18,6 @@
use CodeIgniter\HTTP\Exceptions\HTTPException;
use Config\App;
use Config\Cookie as CookieConfig;
-use Config\Services;
/**
* Representation of an outgoing, server-side response.
@@ -158,7 +157,7 @@ public function __construct($config) // @phpstan-ignore-line
$this->noCache();
// We need CSP object even if not enabled to avoid calls to non existing methods
- $this->CSP = Services::csp();
+ $this->CSP = service('csp');
$this->cookieStore = new CookieStore([]);
diff --git a/system/HTTP/ResponseInterface.php b/system/HTTP/ResponseInterface.php
index 827eea44..382a2847 100644
--- a/system/HTTP/ResponseInterface.php
+++ b/system/HTTP/ResponseInterface.php
@@ -210,7 +210,7 @@ public function setContentType(string $mime, string $charset = 'UTF-8');
/**
* Converts the $body into JSON and sets the Content Type header.
*
- * @param array|string $body
+ * @param array|object|string $body
*
* @return $this
*/
diff --git a/system/HTTP/ResponseTrait.php b/system/HTTP/ResponseTrait.php
index 45f07d18..eaf60f2b 100644
--- a/system/HTTP/ResponseTrait.php
+++ b/system/HTTP/ResponseTrait.php
@@ -123,18 +123,21 @@ public function setDate(DateTime $date)
*/
public function setLink(PagerInterface $pager)
{
- $links = '';
+ $links = '';
+ $previous = $pager->getPreviousPageURI();
- if ($previous = $pager->getPreviousPageURI()) {
+ if (is_string($previous) && $previous !== '') {
$links .= '<' . $pager->getPageURI($pager->getFirstPage()) . '>; rel="first",';
$links .= '<' . $previous . '>; rel="prev"';
}
- if (($next = $pager->getNextPageURI()) && $previous) {
+ $next = $pager->getNextPageURI();
+
+ if (is_string($next) && $next !== '' && is_string($previous) && $previous !== '') {
$links .= ',';
}
- if ($next) {
+ if (is_string($next) && $next !== '') {
$links .= '<' . $next . '>; rel="next",';
$links .= '<' . $pager->getPageURI($pager->getLastPage()) . '>; rel="last"';
}
@@ -566,7 +569,7 @@ public function getCookieStore()
*/
public function hasCookie(string $name, ?string $value = null, string $prefix = ''): bool
{
- $prefix = $prefix ?: Cookie::setDefaults()['prefix']; // to retain BC
+ $prefix = $prefix !== '' ? $prefix : Cookie::setDefaults()['prefix']; // to retain BC
return $this->cookieStore->has($name, $prefix, $value);
}
@@ -586,7 +589,7 @@ public function getCookie(?string $name = null, string $prefix = '')
}
try {
- $prefix = $prefix ?: Cookie::setDefaults()['prefix']; // to retain BC
+ $prefix = $prefix !== '' ? $prefix : Cookie::setDefaults()['prefix']; // to retain BC
return $this->cookieStore->get($name, $prefix);
} catch (CookieException $e) {
@@ -607,7 +610,7 @@ public function deleteCookie(string $name = '', string $domain = '', string $pat
return $this;
}
- $prefix = $prefix ?: Cookie::setDefaults()['prefix']; // to retain BC
+ $prefix = $prefix !== '' ? $prefix : Cookie::setDefaults()['prefix']; // to retain BC
$prefixed = $prefix . $name;
$store = $this->cookieStore;
diff --git a/system/HTTP/SiteURI.php b/system/HTTP/SiteURI.php
index def61b65..2be70a77 100644
--- a/system/HTTP/SiteURI.php
+++ b/system/HTTP/SiteURI.php
@@ -41,7 +41,7 @@ class SiteURI extends URI
/**
* The Index File.
*/
- private string $indexPage;
+ private readonly string $indexPage;
/**
* List of URI segments in baseURL and indexPage.
@@ -421,7 +421,7 @@ public function siteUrl($relativePath = '', ?string $scheme = null, ?App $config
$relativePath = $this->stringifyRelativePath($relativePath);
// Check current host.
- $host = $config === null ? $this->getHost() : null;
+ $host = $config instanceof App ? null : $this->getHost();
$config ??= config(App::class);
diff --git a/system/HTTP/URI.php b/system/HTTP/URI.php
index efa99cf7..d0d23a3d 100644
--- a/system/HTTP/URI.php
+++ b/system/HTTP/URI.php
@@ -1177,7 +1177,8 @@ protected function parseStr(string $query): array
parse_str($params, $result);
foreach ($result as $key => $value) {
- $return[hex2bin($key)] = $value;
+ // Array key might be int
+ $return[hex2bin((string) $key)] = $value;
}
return $return;
diff --git a/system/HTTP/UserAgent.php b/system/HTTP/UserAgent.php
index 6a510477..ec4d1743 100644
--- a/system/HTTP/UserAgent.php
+++ b/system/HTTP/UserAgent.php
@@ -125,7 +125,7 @@ public function isBrowser(?string $key = null): bool
}
// No need to be specific, it's a browser
- if ($key === null) {
+ if ((string) $key === '') {
return true;
}
@@ -143,7 +143,7 @@ public function isRobot(?string $key = null): bool
}
// No need to be specific, it's a robot
- if ($key === null) {
+ if ((string) $key === '') {
return true;
}
@@ -161,7 +161,7 @@ public function isMobile(?string $key = null): bool
}
// No need to be specific, it's a mobile
- if ($key === null) {
+ if ((string) $key === '') {
return true;
}
@@ -289,7 +289,7 @@ protected function compileData()
*/
protected function setPlatform(): bool
{
- if (is_array($this->config->platforms) && $this->config->platforms) {
+ if (is_array($this->config->platforms) && $this->config->platforms !== []) {
foreach ($this->config->platforms as $key => $val) {
if (preg_match('|' . preg_quote($key, '|') . '|i', $this->agent)) {
$this->platform = $val;
@@ -309,7 +309,7 @@ protected function setPlatform(): bool
*/
protected function setBrowser(): bool
{
- if (is_array($this->config->browsers) && $this->config->browsers) {
+ if (is_array($this->config->browsers) && $this->config->browsers !== []) {
foreach ($this->config->browsers as $key => $val) {
if (preg_match('|' . $key . '.*?([0-9\.]+)|i', $this->agent, $match)) {
$this->isBrowser = true;
@@ -330,7 +330,7 @@ protected function setBrowser(): bool
*/
protected function setRobot(): bool
{
- if (is_array($this->config->robots) && $this->config->robots) {
+ if (is_array($this->config->robots) && $this->config->robots !== []) {
foreach ($this->config->robots as $key => $val) {
if (preg_match('|' . preg_quote($key, '|') . '|i', $this->agent)) {
$this->isRobot = true;
@@ -350,7 +350,7 @@ protected function setRobot(): bool
*/
protected function setMobile(): bool
{
- if (is_array($this->config->mobiles) && $this->config->mobiles) {
+ if (is_array($this->config->mobiles) && $this->config->mobiles !== []) {
foreach ($this->config->mobiles as $key => $val) {
if (false !== (stripos($this->agent, $key))) {
$this->isMobile = true;
diff --git a/system/Helpers/Array/ArrayHelper.php b/system/Helpers/Array/ArrayHelper.php
index 76b8e8ae..4bbd3442 100644
--- a/system/Helpers/Array/ArrayHelper.php
+++ b/system/Helpers/Array/ArrayHelper.php
@@ -307,7 +307,7 @@ public static function recursiveCount(array $array, int $counter = 0): int
*/
public static function sortValuesByNatural(array &$array, $sortByIndex = null): bool
{
- return usort($array, static function ($currentValue, $nextValue) use ($sortByIndex) {
+ return usort($array, static function ($currentValue, $nextValue) use ($sortByIndex): int {
if ($sortByIndex !== null) {
return strnatcmp((string) $currentValue[$sortByIndex], (string) $nextValue[$sortByIndex]);
}
diff --git a/system/Helpers/filesystem_helper.php b/system/Helpers/filesystem_helper.php
index 2b86654c..d5f2d974 100644
--- a/system/Helpers/filesystem_helper.php
+++ b/system/Helpers/filesystem_helper.php
@@ -166,7 +166,7 @@ function delete_files(string $path, bool $delDir = false, bool $htdocs = false,
continue;
}
- if (! $htdocs || ! preg_match('/^(\.htaccess|index\.(html|htm|php)|web\.config)$/i', $filename)) {
+ if (! $htdocs || preg_match('/^(\.htaccess|index\.(html|htm|php)|web\.config)$/i', $filename) !== 1) {
$isDir = $object->isDir();
if ($isDir && $delDir) {
rmdir($object->getPathname());
@@ -260,13 +260,13 @@ function get_dir_file_info(string $sourceDir, bool $topLevelOnly = true, bool $r
try {
$fp = opendir($sourceDir);
- // reset the array and make sure $source_dir has a trailing slash on the initial call
+ // reset the array and make sure $sourceDir has a trailing slash on the initial call
if ($recursion === false) {
$fileData = [];
$sourceDir = rtrim(realpath($sourceDir), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
}
- // Used to be foreach (scandir($source_dir, 1) as $file), but scandir() is simply not as fast
+ // Used to be foreach (scandir($sourceDir, 1) as $file), but scandir() is simply not as fast
while (false !== ($file = readdir($fp))) {
if (is_dir($sourceDir . $file) && $file[0] !== '.' && $topLevelOnly === false) {
get_dir_file_info($sourceDir . $file . DIRECTORY_SEPARATOR, $topLevelOnly, true);
diff --git a/system/Helpers/form_helper.php b/system/Helpers/form_helper.php
index 2e5b9f7c..7e113888 100644
--- a/system/Helpers/form_helper.php
+++ b/system/Helpers/form_helper.php
@@ -62,7 +62,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 = service('filters')->getFilters()['before'];
- if ((in_array('csrf', $before, true) || array_key_exists('csrf', $before)) && str_contains($action, base_url()) && ! stripos($form, 'method="get"')) {
+ if ((in_array('csrf', $before, true) || array_key_exists('csrf', $before)) && str_contains($action, base_url()) && stripos($form, 'method="get"') === false) {
$form .= csrf_field($csrfId ?? null);
}
@@ -582,7 +582,7 @@ function set_select(string $field, string $value = '', bool $default = false): s
}
if ($input === null) {
- return ($default === true) ? ' selected="selected"' : '';
+ return $default ? ' selected="selected"' : '';
}
if (is_array($input)) {
@@ -636,7 +636,7 @@ function set_checkbox(string $field, string $value = '', bool $default = false):
return ($input === $value) ? ' checked="checked"' : '';
}
- return ($default === true) ? ' checked="checked"' : '';
+ return $default ? ' checked="checked"' : '';
}
}
@@ -673,7 +673,7 @@ function set_radio(string $field, string $value = '', bool $default = false): st
return ((string) $input === $value) ? ' checked="checked"' : '';
}
- return ($default === true) ? ' checked="checked"' : '';
+ return $default ? ' checked="checked"' : '';
}
}
@@ -788,7 +788,7 @@ function parse_form_attributes($attributes, array $default): string
if (! is_bool($val)) {
if ($key === 'value') {
$val = esc($val);
- } elseif ($key === 'name' && ! strlen($default['name'])) {
+ } elseif ($key === 'name' && $default['name'] === '') {
continue;
}
$att .= $key . '="' . $val . '"' . ($key === array_key_last($default) ? '' : ' ');
diff --git a/system/Helpers/html_helper.php b/system/Helpers/html_helper.php
index b9e5e5c8..3eb55a6d 100644
--- a/system/Helpers/html_helper.php
+++ b/system/Helpers/html_helper.php
@@ -112,8 +112,8 @@ function img($src = '', bool $indexPage = false, $attributes = ''): string
$img = ' $v) {
- if ($k === 'src' && ! preg_match('#^([a-z]+:)?//#i', $v)) {
- if ($indexPage === true) {
+ if ($k === 'src' && preg_match('#^([a-z]+:)?//#i', $v) !== 1) {
+ if ($indexPage) {
$script .= 'src="' . site_url($v) . '" ';
} else {
$script .= 'src="' . slash_item('baseURL') . $v . '" ';
@@ -252,7 +252,7 @@ function link_tag(
$href = $href['href'] ?? '';
}
- if (! preg_match('#^([a-z]+:)?//#i', $href)) {
+ if (preg_match('#^([a-z]+:)?//#i', $href) !== 1) {
$attributes['href'] = $indexPage ? site_url($href) : slash_item('baseURL') . $href;
} else {
$attributes['href'] = $href;
@@ -302,7 +302,7 @@ function video($src, string $unsupportedMessage = '', string $attributes = '', a
if (_has_protocol($src)) {
$video .= ' src="' . $src . '"';
- } elseif ($indexPage === true) {
+ } elseif ($indexPage) {
$video .= ' src="' . site_url($src) . '"';
} else {
$video .= ' src="' . slash_item('baseURL') . $src . '"';
@@ -349,7 +349,7 @@ function audio($src, string $unsupportedMessage = '', string $attributes = '', a
if (_has_protocol($src)) {
$audio .= ' src="' . $src . '"';
- } elseif ($indexPage === true) {
+ } elseif ($indexPage) {
$audio .= ' src="' . site_url($src) . '"';
} else {
$audio .= ' src="' . slash_item('baseURL') . $src . '"';
@@ -422,7 +422,7 @@ function _media(string $name, array $types = [], string $unsupportedMessage = ''
function source(string $src, string $type = 'unknown', string $attributes = '', bool $indexPage = false): string
{
if (! _has_protocol($src)) {
- $src = $indexPage === true ? site_url($src) : slash_item('baseURL') . $src;
+ $src = $indexPage ? site_url($src) : slash_item('baseURL') . $src;
}
$source = '