Skip to content

Commit 2849e7f

Browse files
committed
Release v4.5.5
1 parent 336e078 commit 2849e7f

24 files changed

+138
-150
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
"kint-php/kint": "^5.0.4",
2424
"mikey179/vfsstream": "^1.6",
2525
"nexusphp/cs-config": "^3.6",
26-
"phpunit/phpunit": "^10.5.16",
26+
"phpunit/phpunit": "^10.5.16 || ^11.2",
2727
"predis/predis": "^1.1 || ^2.0"
2828
},
2929
"suggest": {

preload.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,23 +38,25 @@ class preload
3838
[
3939
'include' => __DIR__ . '/vendor/codeigniter4/framework/system', // Change this path if using manual installation
4040
'exclude' => [
41-
'/system/bootstrap.php',
4241
// Not needed if you don't use them.
4342
'/system/Database/OCI8/',
4443
'/system/Database/Postgre/',
4544
'/system/Database/SQLite3/',
4645
'/system/Database/SQLSRV/',
47-
// Not needed.
46+
// Not needed for web apps.
4847
'/system/Database/Seeder.php',
4948
'/system/Test/',
50-
'/system/Language/',
5149
'/system/CLI/',
5250
'/system/Commands/',
5351
'/system/Publisher/',
5452
'/system/ComposerScripts.php',
53+
// Not Class/Function files.
54+
'/system/Config/Routes.php',
55+
'/system/Language/',
56+
'/system/bootstrap.php',
57+
'/system/rewrite.php',
5558
'/Views/',
5659
// Errors occur.
57-
'/system/Config/Routes.php',
5860
'/system/ThirdParty/',
5961
],
6062
],

system/BaseModel.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -541,7 +541,7 @@ abstract protected function doReplace(?array $row = null, bool $returnSQL = fals
541541
* Grabs the last error(s) that occurred from the Database connection.
542542
* This method works only with dbCalls.
543543
*
544-
* @return array|null
544+
* @return array<string, string>
545545
*/
546546
abstract protected function doErrors();
547547

@@ -1242,7 +1242,7 @@ public function replace(?array $row = null, bool $returnSQL = false)
12421242
*
12431243
* @param bool $forceDB Always grab the db error, not validation
12441244
*
1245-
* @return array<string,string>
1245+
* @return array<string, string>
12461246
*/
12471247
public function errors(bool $forceDB = false)
12481248
{

system/CodeIgniter.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ class CodeIgniter
5656
/**
5757
* The current version of CodeIgniter Framework
5858
*/
59-
public const CI_VERSION = '4.5.4';
59+
public const CI_VERSION = '4.5.5';
6060

6161
/**
6262
* App startup time.

system/Common.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
use CodeIgniter\HTTP\RedirectResponse;
2929
use CodeIgniter\HTTP\RequestInterface;
3030
use CodeIgniter\HTTP\ResponseInterface;
31+
use CodeIgniter\Language\Language;
3132
use CodeIgniter\Model;
3233
use CodeIgniter\Session\Session;
3334
use CodeIgniter\Test\TestLogger;
@@ -732,6 +733,7 @@ function is_windows(?bool $mock = null): bool
732733
*/
733734
function lang(string $line, array $args = [], ?string $locale = null)
734735
{
736+
/** @var Language $language */
735737
$language = service('language');
736738

737739
// Get active locale

system/Database/BaseBuilder.php

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3164,21 +3164,27 @@ protected function compileWhereHaving(string $qbKey): string
31643164
);
31653165

31663166
foreach ($conditions as &$condition) {
3167-
if (($op = $this->getOperator($condition)) === false
3168-
|| ! preg_match('/^(\(?)(.*)(' . preg_quote($op, '/') . ')\s*(.*(?<!\)))?(\)?)$/i', $condition, $matches)
3167+
$op = $this->getOperator($condition);
3168+
if (
3169+
$op === false
3170+
|| ! preg_match(
3171+
'/^(\(?)(.*)(' . preg_quote($op, '/') . ')\s*(.*(?<!\)))?(\)?)$/i',
3172+
$condition,
3173+
$matches
3174+
)
31693175
) {
31703176
continue;
31713177
}
3172-
// $matches = array(
3173-
// 0 => '(test <= foo)', /* the whole thing */
3174-
// 1 => '(', /* optional */
3175-
// 2 => 'test', /* the field name */
3176-
// 3 => ' <= ', /* $op */
3177-
// 4 => 'foo', /* optional, if $op is e.g. 'IS NULL' */
3178-
// 5 => ')' /* optional */
3179-
// );
3180-
3181-
if (! empty($matches[4])) {
3178+
// $matches = [
3179+
// 0 => '(test <= foo)', /* the whole thing */
3180+
// 1 => '(', /* optional */
3181+
// 2 => 'test', /* the field name */
3182+
// 3 => ' <= ', /* $op */
3183+
// 4 => 'foo', /* optional, if $op is e.g. 'IS NULL' */
3184+
// 5 => ')' /* optional */
3185+
// ];
3186+
3187+
if (isset($matches[4]) && $matches[4] !== '') {
31823188
$protectIdentifiers = false;
31833189
if (str_contains($matches[4], '.')) {
31843190
$protectIdentifiers = true;

system/Database/BaseConnection.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -784,9 +784,9 @@ public function transStart(bool $testMode = false): bool
784784
*
785785
* @return $this
786786
*/
787-
public function transException(bool $transExcetion)
787+
public function transException(bool $transException)
788788
{
789-
$this->transException = $transExcetion;
789+
$this->transException = $transException;
790790

791791
return $this;
792792
}

system/Database/Database.php

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313

1414
namespace CodeIgniter\Database;
1515

16+
use CodeIgniter\Exceptions\ConfigException;
17+
use CodeIgniter\Exceptions\CriticalError;
1618
use InvalidArgumentException;
1719

1820
/**
@@ -54,6 +56,8 @@ public function load(array $params = [], string $alias = '')
5456
throw new InvalidArgumentException('You have not selected a database type to connect to.');
5557
}
5658

59+
assert($this->checkDbExtension($params['DBDriver']));
60+
5761
$this->connections[$alias] = $this->initDriver($params['DBDriver'], 'Connection', $params);
5862

5963
return $this->connections[$alias];
@@ -124,9 +128,9 @@ protected function parseDSN(array $params): array
124128
/**
125129
* Creates a database object.
126130
*
127-
* @param string $driver Driver name. FQCN can be used.
128-
* @param string $class 'Connection'|'Forge'|'Utils'
129-
* @param array|object $argument The constructor parameter.
131+
* @param string $driver Driver name. FQCN can be used.
132+
* @param string $class 'Connection'|'Forge'|'Utils'
133+
* @param array|ConnectionInterface $argument The constructor parameter or DB connection
130134
*
131135
* @return BaseConnection|BaseUtils|Forge
132136
*/
@@ -138,4 +142,43 @@ protected function initDriver(string $driver, string $class, $argument): object
138142

139143
return new $classname($argument);
140144
}
145+
146+
/**
147+
* Check the PHP database extension is loaded.
148+
*
149+
* @param string $driver DB driver or FQCN for custom driver
150+
*/
151+
private function checkDbExtension(string $driver): bool
152+
{
153+
if (str_contains($driver, '\\')) {
154+
// Cannot check a fully qualified classname for a custom driver.
155+
return true;
156+
}
157+
158+
$extensionMap = [
159+
// DBDriver => PHP extension
160+
'MySQLi' => 'mysqli',
161+
'SQLite3' => 'sqlite3',
162+
'Postgre' => 'pgsql',
163+
'SQLSRV' => 'sqlsrv',
164+
'OCI8' => 'oci8',
165+
];
166+
167+
$extension = $extensionMap[$driver] ?? '';
168+
169+
if ($extension === '') {
170+
$message = 'Invalid DBDriver name: "' . $driver . '"';
171+
172+
throw new ConfigException($message);
173+
}
174+
175+
if (extension_loaded($extension)) {
176+
return true;
177+
}
178+
179+
$message = 'The required PHP extension "' . $extension . '" is not loaded.'
180+
. ' Install and enable it to use "' . $driver . '" driver.';
181+
182+
throw new CriticalError($message);
183+
}
141184
}

system/Database/Postgre/Builder.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -411,10 +411,8 @@ static function ($key, $value) use ($table, $alias, $that) {
411411
* Returns cast expression.
412412
*
413413
* @TODO move this to BaseBuilder in 4.5.0
414-
*
415-
* @param float|int|string $expression
416414
*/
417-
private function cast($expression, ?string $type): string
415+
private function cast(string $expression, ?string $type): string
418416
{
419417
return ($type === null) ? $expression : 'CAST(' . $expression . ' AS ' . strtoupper($type) . ')';
420418
}

system/Entity/Entity.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ class Entity implements JsonSerializable
106106
/**
107107
* Holds the current values of all class vars.
108108
*
109-
* @var array
109+
* @var array<string, mixed>
110110
*/
111111
protected $attributes = [];
112112

@@ -115,7 +115,7 @@ class Entity implements JsonSerializable
115115
* what's actually been changed and not accidentally write
116116
* nulls where we shouldn't.
117117
*
118-
* @var array
118+
* @var array<string, mixed>
119119
*/
120120
protected $original = [];
121121

system/Filters/CSRF.php

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use CodeIgniter\HTTP\RequestInterface;
1919
use CodeIgniter\HTTP\ResponseInterface;
2020
use CodeIgniter\Security\Exceptions\SecurityException;
21+
use CodeIgniter\Security\Security;
2122

2223
/**
2324
* CSRF filter.
@@ -30,14 +31,7 @@
3031
class CSRF implements FilterInterface
3132
{
3233
/**
33-
* Do whatever processing this filter needs to do.
34-
* By default it should not return anything during
35-
* normal execution. However, when an abnormal state
36-
* is found, it should return an instance of
37-
* CodeIgniter\HTTP\Response. If it does, script
38-
* execution will end and that Response will be
39-
* sent back to the client, allowing for error pages,
40-
* redirects, etc.
34+
* CSRF verification.
4135
*
4236
* @param list<string>|null $arguments
4337
*
@@ -51,6 +45,7 @@ public function before(RequestInterface $request, $arguments = null)
5145
return;
5246
}
5347

48+
/** @var Security $security */
5449
$security = service('security');
5550

5651
try {

system/HTTP/ContentSecurityPolicy.php

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class ContentSecurityPolicy
3131
/**
3232
* CSP directives
3333
*
34-
* @var array<string, string>
34+
* @var array<string, string> [name => property]
3535
*/
3636
protected array $directives = [
3737
'base-uri' => 'baseURI',
@@ -166,7 +166,8 @@ class ContentSecurityPolicy
166166
protected $sandbox = [];
167167

168168
/**
169-
* Used for security enforcement
169+
* A set of endpoints to which csp violation reports will be sent when
170+
* particular behaviors are prevented.
170171
*
171172
* @var string|null
172173
*/
@@ -189,7 +190,7 @@ class ContentSecurityPolicy
189190
/**
190191
* Used for security enforcement
191192
*
192-
* @var array
193+
* @var list<string>
193194
*/
194195
protected $validSources = [
195196
'self',
@@ -242,7 +243,7 @@ class ContentSecurityPolicy
242243

243244
/**
244245
* An array of header info since we have
245-
* to build ourself before passing to Response.
246+
* to build ourselves before passing to Response.
246247
*
247248
* @var array
248249
*/
@@ -594,6 +595,9 @@ public function addPluginType($mime, ?bool $explicitReporting = null)
594595
*
595596
* @see http://www.w3.org/TR/CSP/#directive-report-uri
596597
*
598+
* @param string $uri URL to send reports. Set `''` if you want to remove
599+
* this directive at runtime.
600+
*
597601
* @return $this
598602
*/
599603
public function setReportURI(string $uri)

0 commit comments

Comments
 (0)