From ebc3c27e898714530bed3becf8a2d6b55e6b3268 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Fri, 26 Jan 2024 15:15:09 +0900
Subject: [PATCH 001/164] test: add test for OCI8 getFieldData()
---
.../Database/Live/OCI8/GetFieldDataTest.php | 110 ++++++++++++++++++
1 file changed, 110 insertions(+)
create mode 100644 tests/system/Database/Live/OCI8/GetFieldDataTest.php
diff --git a/tests/system/Database/Live/OCI8/GetFieldDataTest.php b/tests/system/Database/Live/OCI8/GetFieldDataTest.php
new file mode 100644
index 000000000000..ac9bf1ed8ab9
--- /dev/null
+++ b/tests/system/Database/Live/OCI8/GetFieldDataTest.php
@@ -0,0 +1,110 @@
+
+ *
+ * For the full copyright and license information, please view
+ * the LICENSE file that was distributed with this source code.
+ */
+
+namespace CodeIgniter\Database\Live\OCI8;
+
+use CodeIgniter\Database\Live\AbstractGetFieldDataTest;
+use Config\Database;
+
+/**
+ * @group DatabaseLive
+ *
+ * @internal
+ */
+final class GetFieldDataTest extends AbstractGetFieldDataTest
+{
+ protected function createForge(): void
+ {
+ if ($this->db->DBDriver !== 'OCI8') {
+ $this->markTestSkipped('This test is only for OCI8.');
+ }
+
+ $this->forge = Database::forge($this->db);
+ }
+
+ public function testGetFieldData(): void
+ {
+ $fields = $this->db->getFieldData('test1');
+
+ $data = [];
+
+ foreach ($fields as $obj) {
+ $data[$obj->name] = $obj;
+ }
+
+ $idDefault = $data['id']->default;
+ $this->assertMatchesRegularExpression('/"ORACLE"."ISEQ\$\$_[0-9]+".nextval/', $idDefault);
+
+ $this->assertJsonStringEqualsJsonString(
+ json_encode([
+ (object) [
+ 'name' => 'id',
+ 'type' => 'NUMBER',
+ 'max_length' => '11',
+ 'default' => $idDefault, // The default value is not defined.
+ // 'primary_key' => 1,
+ 'nullable' => false,
+ ],
+ (object) [
+ 'name' => 'text_not_null',
+ 'type' => 'VARCHAR2',
+ 'max_length' => '64',
+ 'default' => null, // The default value is not defined.
+ // 'primary_key' => 0,
+ 'nullable' => false,
+ ],
+ (object) [
+ 'name' => 'text_null',
+ 'type' => 'VARCHAR2',
+ 'max_length' => '64',
+ 'default' => null, // The default value is not defined.
+ // 'primary_key' => 0,
+ 'nullable' => true,
+ ],
+ (object) [
+ 'name' => 'int_default_0',
+ 'type' => 'NUMBER',
+ 'max_length' => '11',
+ 'default' => '0 ', // int 0
+ // 'primary_key' => 0,
+ 'nullable' => false,
+ ],
+ (object) [
+ 'name' => 'text_default_null',
+ 'type' => 'VARCHAR2',
+ 'max_length' => '64',
+ 'default' => 'NULL ', // NULL value
+ // 'primary_key' => 0,
+ 'nullable' => true,
+ ],
+ (object) [
+ 'name' => 'text_default_text_null',
+ 'type' => 'VARCHAR2',
+ 'max_length' => '64',
+ 'default' => "'null' ", // string "null"
+ // 'primary_key' => 0,
+ 'nullable' => false,
+ ],
+ (object) [
+ 'name' => 'text_default_abc',
+ 'type' => 'VARCHAR2',
+ 'max_length' => '64',
+ 'default' => "'abc' ", // string "abc"
+ // 'primary_key' => 0,
+ 'nullable' => false,
+ ],
+ ]),
+ json_encode($fields)
+ );
+ }
+}
From eec7a88e5693b1eeb7ff54240b55303a637ff726 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Fri, 26 Jan 2024 15:16:03 +0900
Subject: [PATCH 002/164] fix: OCI8 getFieldData() returns incorrect `default`
value
---
system/Database/OCI8/Connection.php | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/system/Database/OCI8/Connection.php b/system/Database/OCI8/Connection.php
index 8cb7e3a4a766..58c33536a41c 100644
--- a/system/Database/OCI8/Connection.php
+++ b/system/Database/OCI8/Connection.php
@@ -315,11 +315,7 @@ protected function _fieldData(string $table): array
$retval[$i]->max_length = $length;
- $default = $query[$i]->DATA_DEFAULT;
- if ($default === null && $query[$i]->NULLABLE === 'N') {
- $default = '';
- }
- $retval[$i]->default = $default;
+ $retval[$i]->default = $query[$i]->DATA_DEFAULT;
$retval[$i]->nullable = $query[$i]->NULLABLE === 'Y';
}
From 61bff7e9a271137d2588baeea222b983772ba610 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Fri, 26 Jan 2024 15:45:22 +0900
Subject: [PATCH 003/164] test: update assertion
---
tests/system/Database/Live/ForgeTest.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/system/Database/Live/ForgeTest.php b/tests/system/Database/Live/ForgeTest.php
index 626660ee7246..1cb5c6e4d41b 100644
--- a/tests/system/Database/Live/ForgeTest.php
+++ b/tests/system/Database/Live/ForgeTest.php
@@ -1058,7 +1058,7 @@ public function testAddFields(): void
'name' => 'username',
'type' => 'VARCHAR2',
'max_length' => '255',
- 'default' => '',
+ 'default' => null,
'nullable' => false,
],
2 => [
From 6ee59bd3486d1c4cf9dd9243b8312e1616b37111 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Fri, 26 Jan 2024 15:58:14 +0900
Subject: [PATCH 004/164] fix: SQLite3 getFieldData() returns incorrect
`primary_key` values
The return type is integer, not boolean.
---
system/Database/SQLite3/Connection.php | 2 +-
tests/system/Database/Live/ForgeTest.php | 8 ++++----
.../Database/Live/SQLite3/GetFieldDataTest.php | 14 +++++++-------
3 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/system/Database/SQLite3/Connection.php b/system/Database/SQLite3/Connection.php
index f41c8e4de792..1a682646e83d 100644
--- a/system/Database/SQLite3/Connection.php
+++ b/system/Database/SQLite3/Connection.php
@@ -273,7 +273,7 @@ protected function _fieldData(string $table): array
$retVal[$i]->type = $query[$i]->type;
$retVal[$i]->max_length = null;
$retVal[$i]->default = $query[$i]->dflt_value;
- $retVal[$i]->primary_key = isset($query[$i]->pk) && (bool) $query[$i]->pk;
+ $retVal[$i]->primary_key = $query[$i]->pk ?? false;
$retVal[$i]->nullable = isset($query[$i]->notnull) && ! (bool) $query[$i]->notnull;
}
diff --git a/tests/system/Database/Live/ForgeTest.php b/tests/system/Database/Live/ForgeTest.php
index 626660ee7246..93524a5b39fb 100644
--- a/tests/system/Database/Live/ForgeTest.php
+++ b/tests/system/Database/Live/ForgeTest.php
@@ -986,7 +986,7 @@ public function testAddFields(): void
'type' => 'INTEGER',
'max_length' => null,
'default' => null,
- 'primary_key' => true,
+ 'primary_key' => 1,
'nullable' => true,
],
1 => [
@@ -994,7 +994,7 @@ public function testAddFields(): void
'type' => 'VARCHAR',
'max_length' => null,
'default' => null,
- 'primary_key' => false,
+ 'primary_key' => 0,
'nullable' => false,
],
2 => [
@@ -1002,7 +1002,7 @@ public function testAddFields(): void
'type' => 'VARCHAR',
'max_length' => null,
'default' => null,
- 'primary_key' => false,
+ 'primary_key' => 0,
'nullable' => true,
],
3 => [
@@ -1010,7 +1010,7 @@ public function testAddFields(): void
'type' => 'INTEGER',
'max_length' => null,
'default' => '0',
- 'primary_key' => false,
+ 'primary_key' => 0,
'nullable' => false,
],
];
diff --git a/tests/system/Database/Live/SQLite3/GetFieldDataTest.php b/tests/system/Database/Live/SQLite3/GetFieldDataTest.php
index 70586f10fbdd..621083a061c3 100644
--- a/tests/system/Database/Live/SQLite3/GetFieldDataTest.php
+++ b/tests/system/Database/Live/SQLite3/GetFieldDataTest.php
@@ -47,7 +47,7 @@ public function testGetFieldData(): void
'type' => 'INTEGER',
'max_length' => null,
'default' => null, // The default value is not defined.
- 'primary_key' => true,
+ 'primary_key' => 1,
'nullable' => true,
],
(object) [
@@ -55,7 +55,7 @@ public function testGetFieldData(): void
'type' => 'VARCHAR',
'max_length' => null,
'default' => null, // The default value is not defined.
- 'primary_key' => false,
+ 'primary_key' => 0,
'nullable' => false,
],
(object) [
@@ -63,7 +63,7 @@ public function testGetFieldData(): void
'type' => 'VARCHAR',
'max_length' => null,
'default' => null, // The default value is not defined.
- 'primary_key' => false,
+ 'primary_key' => 0,
'nullable' => true,
],
(object) [
@@ -71,7 +71,7 @@ public function testGetFieldData(): void
'type' => 'INT',
'max_length' => null,
'default' => '0', // int 0
- 'primary_key' => false,
+ 'primary_key' => 0,
'nullable' => false,
],
(object) [
@@ -79,7 +79,7 @@ public function testGetFieldData(): void
'type' => 'VARCHAR',
'max_length' => null,
'default' => 'NULL', // NULL value
- 'primary_key' => false,
+ 'primary_key' => 0,
'nullable' => true,
],
(object) [
@@ -87,7 +87,7 @@ public function testGetFieldData(): void
'type' => 'VARCHAR',
'max_length' => null,
'default' => "'null'", // string "null"
- 'primary_key' => false,
+ 'primary_key' => 0,
'nullable' => false,
],
(object) [
@@ -95,7 +95,7 @@ public function testGetFieldData(): void
'type' => 'VARCHAR',
'max_length' => null,
'default' => "'abc'", // string "abc"
- 'primary_key' => false,
+ 'primary_key' => 0,
'nullable' => false,
],
]),
From 055c5ad8262d1b11882f60a0500a99b2412a83a9 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Fri, 26 Jan 2024 16:04:01 +0900
Subject: [PATCH 005/164] docs: replace MySQL with MySQLi
---
user_guide_src/source/database/metadata.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/user_guide_src/source/database/metadata.rst b/user_guide_src/source/database/metadata.rst
index 607a1025be8b..5a499bad496d 100644
--- a/user_guide_src/source/database/metadata.rst
+++ b/user_guide_src/source/database/metadata.rst
@@ -105,7 +105,7 @@ database:
- name - column name
- type - the type of the column
- max_length - maximum length of the column
-- primary_key - integer ``1`` if the column is a primary key (all integer ``1``, even if there are multiple primary keys), otherwise integer ``0`` (This field is currently only available for MySQL and SQLite3)
+- primary_key - integer ``1`` if the column is a primary key (all integer ``1``, even if there are multiple primary keys), otherwise integer ``0`` (This field is currently only available for MySQLi and SQLite3)
- nullable - boolean ``true`` if the column is nullable, otherwise boolean ``false``
- default - the default value
From c86ddc54340ab8f2e038a2d31554fe6743b4933b Mon Sep 17 00:00:00 2001
From: kenjis
Date: Fri, 26 Jan 2024 16:05:05 +0900
Subject: [PATCH 006/164] docs: decorate text
---
user_guide_src/source/database/metadata.rst | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/user_guide_src/source/database/metadata.rst b/user_guide_src/source/database/metadata.rst
index 5a499bad496d..1845a0440b7a 100644
--- a/user_guide_src/source/database/metadata.rst
+++ b/user_guide_src/source/database/metadata.rst
@@ -102,12 +102,12 @@ supplying the table name:
The following data is available from this function if supported by your
database:
-- name - column name
-- type - the type of the column
-- max_length - maximum length of the column
-- primary_key - integer ``1`` if the column is a primary key (all integer ``1``, even if there are multiple primary keys), otherwise integer ``0`` (This field is currently only available for MySQLi and SQLite3)
-- nullable - boolean ``true`` if the column is nullable, otherwise boolean ``false``
-- default - the default value
+- ``name`` - column name
+- ``type`` - the type of the column
+- ``max_length`` - maximum length of the column
+- ``primary_key`` - integer ``1`` if the column is a primary key (all integer ``1``, even if there are multiple primary keys), otherwise integer ``0`` (This field is currently only available for ``MySQLi`` and ``SQLite3``)
+- ``nullable`` - boolean ``true`` if the column is nullable, otherwise boolean ``false``
+- ``default`` - the default value
.. note:: Since v4.4.0, SQLSRV supported ``nullable``.
From c12aa141bba417f7ef2e88a33f88a8a681771947 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Fri, 26 Jan 2024 16:37:36 +0900
Subject: [PATCH 007/164] test: sort field data
---
.../Database/Live/OCI8/GetFieldDataTest.php | 127 +++++++++---------
1 file changed, 66 insertions(+), 61 deletions(-)
diff --git a/tests/system/Database/Live/OCI8/GetFieldDataTest.php b/tests/system/Database/Live/OCI8/GetFieldDataTest.php
index ac9bf1ed8ab9..fcb585842a0d 100644
--- a/tests/system/Database/Live/OCI8/GetFieldDataTest.php
+++ b/tests/system/Database/Live/OCI8/GetFieldDataTest.php
@@ -45,66 +45,71 @@ public function testGetFieldData(): void
$idDefault = $data['id']->default;
$this->assertMatchesRegularExpression('/"ORACLE"."ISEQ\$\$_[0-9]+".nextval/', $idDefault);
- $this->assertJsonStringEqualsJsonString(
- json_encode([
- (object) [
- 'name' => 'id',
- 'type' => 'NUMBER',
- 'max_length' => '11',
- 'default' => $idDefault, // The default value is not defined.
- // 'primary_key' => 1,
- 'nullable' => false,
- ],
- (object) [
- 'name' => 'text_not_null',
- 'type' => 'VARCHAR2',
- 'max_length' => '64',
- 'default' => null, // The default value is not defined.
- // 'primary_key' => 0,
- 'nullable' => false,
- ],
- (object) [
- 'name' => 'text_null',
- 'type' => 'VARCHAR2',
- 'max_length' => '64',
- 'default' => null, // The default value is not defined.
- // 'primary_key' => 0,
- 'nullable' => true,
- ],
- (object) [
- 'name' => 'int_default_0',
- 'type' => 'NUMBER',
- 'max_length' => '11',
- 'default' => '0 ', // int 0
- // 'primary_key' => 0,
- 'nullable' => false,
- ],
- (object) [
- 'name' => 'text_default_null',
- 'type' => 'VARCHAR2',
- 'max_length' => '64',
- 'default' => 'NULL ', // NULL value
- // 'primary_key' => 0,
- 'nullable' => true,
- ],
- (object) [
- 'name' => 'text_default_text_null',
- 'type' => 'VARCHAR2',
- 'max_length' => '64',
- 'default' => "'null' ", // string "null"
- // 'primary_key' => 0,
- 'nullable' => false,
- ],
- (object) [
- 'name' => 'text_default_abc',
- 'type' => 'VARCHAR2',
- 'max_length' => '64',
- 'default' => "'abc' ", // string "abc"
- // 'primary_key' => 0,
- 'nullable' => false,
- ],
- ]),
- json_encode($fields)
- );
+ $expected = json_decode(json_encode([
+ (object) [
+ 'name' => 'id',
+ 'type' => 'NUMBER',
+ 'max_length' => '11',
+ 'default' => $idDefault, // The default value is not defined.
+ // 'primary_key' => 1,
+ 'nullable' => false,
+ ],
+ (object) [
+ 'name' => 'text_not_null',
+ 'type' => 'VARCHAR2',
+ 'max_length' => '64',
+ 'default' => null, // The default value is not defined.
+ // 'primary_key' => 0,
+ 'nullable' => false,
+ ],
+ (object) [
+ 'name' => 'text_null',
+ 'type' => 'VARCHAR2',
+ 'max_length' => '64',
+ 'default' => null, // The default value is not defined.
+ // 'primary_key' => 0,
+ 'nullable' => true,
+ ],
+ (object) [
+ 'name' => 'int_default_0',
+ 'type' => 'NUMBER',
+ 'max_length' => '11',
+ 'default' => '0 ', // int 0
+ // 'primary_key' => 0,
+ 'nullable' => false,
+ ],
+ (object) [
+ 'name' => 'text_default_null',
+ 'type' => 'VARCHAR2',
+ 'max_length' => '64',
+ 'default' => 'NULL ', // NULL value
+ // 'primary_key' => 0,
+ 'nullable' => true,
+ ],
+ (object) [
+ 'name' => 'text_default_text_null',
+ 'type' => 'VARCHAR2',
+ 'max_length' => '64',
+ 'default' => "'null' ", // string "null"
+ // 'primary_key' => 0,
+ 'nullable' => false,
+ ],
+ (object) [
+ 'name' => 'text_default_abc',
+ 'type' => 'VARCHAR2',
+ 'max_length' => '64',
+ 'default' => "'abc' ", // string "abc"
+ // 'primary_key' => 0,
+ 'nullable' => false,
+ ],
+ ]), true);
+ $names = array_column($expected, 'name');
+ array_multisort($names, SORT_ASC, $expected);
+
+ $fields = json_decode(json_encode($fields), true);
+ $names = array_column($fields, 'name');
+ array_multisort($names, SORT_ASC, $fields);
+
+ $this->assertSame($expected, $fields);
}
}
From cc0e21fb3a939b63dc494112771b27e9b2d0d06f Mon Sep 17 00:00:00 2001
From: "John Paul E. Balandan, CPA"
Date: Fri, 26 Jan 2024 22:32:21 +0800
Subject: [PATCH 008/164] test: refactor ImageMagickHandlerTest
---
.../system/Images/ImageMagickHandlerTest.php | 31 ++++++++++++++-----
1 file changed, 23 insertions(+), 8 deletions(-)
diff --git a/tests/system/Images/ImageMagickHandlerTest.php b/tests/system/Images/ImageMagickHandlerTest.php
index 69a5df6e687c..b313fef96275 100644
--- a/tests/system/Images/ImageMagickHandlerTest.php
+++ b/tests/system/Images/ImageMagickHandlerTest.php
@@ -30,6 +30,8 @@
* @internal
*
* @group Others
+ *
+ * @requires extension imagick
*/
final class ImageMagickHandlerTest extends CIUnitTestCase
{
@@ -40,10 +42,6 @@ final class ImageMagickHandlerTest extends CIUnitTestCase
protected function setUp(): void
{
- if (! extension_loaded('imagick')) {
- $this->markTestSkipped('The ImageMagick extension is not available.');
- }
-
$this->root = WRITEPATH . 'cache/';
// cleanup everything
@@ -55,11 +53,28 @@ protected function setUp(): void
$this->path = $this->origin . 'ci-logo.png';
- $handlerConfig = new Images();
- if (is_file('/usr/bin/convert')) {
- $handlerConfig->libraryPath = '/usr/bin/convert';
+ // get our locally available `convert`
+ $config = new Images();
+ $found = false;
+
+ foreach ([
+ '/usr/bin/convert',
+ trim((string) shell_exec('which convert')),
+ $config->libraryPath,
+ ] as $convert) {
+ if (is_file($convert)) {
+ $config->libraryPath = $convert;
+
+ $found = true;
+ break;
+ }
+ }
+
+ if (! $found) {
+ $this->markTestSkipped('Cannot test imagick as there is no available convert program.');
}
- $this->handler = Services::image('imagick', $handlerConfig, false);
+
+ $this->handler = Services::image('imagick', $config, false);
}
public function testGetVersion(): void
From 4a949b373b06e7855335534d1d842ac0d3b6f3d5 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Sat, 27 Jan 2024 08:42:22 +0900
Subject: [PATCH 009/164] fix: primary_key value
---
system/Database/SQLite3/Connection.php | 13 ++--
.../Live/SQLite3/GetFieldDataTest.php | 59 +++++++++++++++++++
2 files changed, 67 insertions(+), 5 deletions(-)
diff --git a/system/Database/SQLite3/Connection.php b/system/Database/SQLite3/Connection.php
index 1a682646e83d..b4b3b668f8b6 100644
--- a/system/Database/SQLite3/Connection.php
+++ b/system/Database/SQLite3/Connection.php
@@ -269,11 +269,14 @@ protected function _fieldData(string $table): array
for ($i = 0, $c = count($query); $i < $c; $i++) {
$retVal[$i] = new stdClass();
- $retVal[$i]->name = $query[$i]->name;
- $retVal[$i]->type = $query[$i]->type;
- $retVal[$i]->max_length = null;
- $retVal[$i]->default = $query[$i]->dflt_value;
- $retVal[$i]->primary_key = $query[$i]->pk ?? false;
+ $retVal[$i]->name = $query[$i]->name;
+ $retVal[$i]->type = $query[$i]->type;
+ $retVal[$i]->max_length = null;
+ $retVal[$i]->default = $query[$i]->dflt_value;
+ // "pk" (either zero for columns that are not part of the primary key,
+ // or the 1-based index of the column within the primary key).
+ // https://www.sqlite.org/pragma.html#pragma_table_info
+ $retVal[$i]->primary_key = ($query[$i]->pk === 0) ? 0 : 1;
$retVal[$i]->nullable = isset($query[$i]->notnull) && ! (bool) $query[$i]->notnull;
}
diff --git a/tests/system/Database/Live/SQLite3/GetFieldDataTest.php b/tests/system/Database/Live/SQLite3/GetFieldDataTest.php
index 621083a061c3..4b8b9bcd6432 100644
--- a/tests/system/Database/Live/SQLite3/GetFieldDataTest.php
+++ b/tests/system/Database/Live/SQLite3/GetFieldDataTest.php
@@ -102,4 +102,63 @@ public function testGetFieldData(): void
json_encode($fields)
);
}
+
+ protected function createTableCompositePrimaryKey()
+ {
+ $this->forge->dropTable('test1', true);
+
+ $this->forge->addField([
+ 'pk1' => [
+ 'type' => 'VARCHAR',
+ 'constraint' => 64,
+ ],
+ 'pk2' => [
+ 'type' => 'VARCHAR',
+ 'constraint' => 64,
+ ],
+ 'text' => [
+ 'type' => 'VARCHAR',
+ 'constraint' => 64,
+ ],
+ ]);
+ $this->forge->addPrimaryKey(['pk1', 'pk2']);
+ $this->forge->createTable('test1');
+ }
+
+ public function testGetFieldDataCompositePrimaryKey(): void
+ {
+ $this->createTableCompositePrimaryKey();
+
+ $fields = $this->db->getFieldData('test1');
+
+ $this->assertJsonStringEqualsJsonString(
+ json_encode([
+ (object) [
+ 'name' => 'pk1',
+ 'type' => 'VARCHAR',
+ 'max_length' => null,
+ 'default' => null,
+ 'primary_key' => 1,
+ 'nullable' => false,
+ ],
+ (object) [
+ 'name' => 'pk2',
+ 'type' => 'VARCHAR',
+ 'max_length' => null,
+ 'default' => null,
+ 'primary_key' => 1,
+ 'nullable' => false,
+ ],
+ (object) [
+ 'name' => 'text',
+ 'type' => 'VARCHAR',
+ 'max_length' => null,
+ 'default' => null,
+ 'primary_key' => 0,
+ 'nullable' => false,
+ ],
+ ]),
+ json_encode($fields)
+ );
+ }
}
From 742d8f152f302a945820c72641f60cc42f3e23b4 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Sat, 27 Jan 2024 13:07:23 +0900
Subject: [PATCH 010/164] docs: add changelog and upgrade for v4.4.6
---
user_guide_src/source/changelogs/index.rst | 1 +
user_guide_src/source/changelogs/v4.4.6.rst | 35 ++++++++++++
.../source/installation/upgrade_446.rst | 54 +++++++++++++++++++
.../source/installation/upgrading.rst | 1 +
4 files changed, 91 insertions(+)
create mode 100644 user_guide_src/source/changelogs/v4.4.6.rst
create mode 100644 user_guide_src/source/installation/upgrade_446.rst
diff --git a/user_guide_src/source/changelogs/index.rst b/user_guide_src/source/changelogs/index.rst
index a8dc37b18aa6..2409b869c420 100644
--- a/user_guide_src/source/changelogs/index.rst
+++ b/user_guide_src/source/changelogs/index.rst
@@ -12,6 +12,7 @@ See all the changes.
.. toctree::
:titlesonly:
+ v4.4.6
v4.4.5
v4.4.4
v4.4.3
diff --git a/user_guide_src/source/changelogs/v4.4.6.rst b/user_guide_src/source/changelogs/v4.4.6.rst
new file mode 100644
index 000000000000..1fbee1a6eb65
--- /dev/null
+++ b/user_guide_src/source/changelogs/v4.4.6.rst
@@ -0,0 +1,35 @@
+#############
+Version 4.4.6
+#############
+
+Release Date: Unreleased
+
+**4.4.6 release of CodeIgniter4**
+
+.. contents::
+ :local:
+ :depth: 3
+
+********
+BREAKING
+********
+
+***************
+Message Changes
+***************
+
+*******
+Changes
+*******
+
+************
+Deprecations
+************
+
+**********
+Bugs Fixed
+**********
+
+See the repo's
+`CHANGELOG.md `_
+for a complete list of bugs fixed.
diff --git a/user_guide_src/source/installation/upgrade_446.rst b/user_guide_src/source/installation/upgrade_446.rst
new file mode 100644
index 000000000000..a010fb8f7b7e
--- /dev/null
+++ b/user_guide_src/source/installation/upgrade_446.rst
@@ -0,0 +1,54 @@
+#############################
+Upgrading from 4.4.5 to 4.4.6
+#############################
+
+Please refer to the upgrade instructions corresponding to your installation method.
+
+- :ref:`Composer Installation App Starter Upgrading `
+- :ref:`Composer Installation Adding CodeIgniter4 to an Existing Project Upgrading `
+- :ref:`Manual Installation Upgrading `
+
+.. contents::
+ :local:
+ :depth: 2
+
+**********************
+Mandatory File Changes
+**********************
+
+****************
+Breaking Changes
+****************
+
+*********************
+Breaking Enhancements
+*********************
+
+*************
+Project Files
+*************
+
+Some files in the **project space** (root, app, public, writable) received updates. Due to
+these files being outside of the **system** scope they will not be changed without your intervention.
+
+There are some third-party CodeIgniter modules available to assist with merging changes to
+the project space: `Explore on Packagist `_.
+
+Content Changes
+===============
+
+The following files received significant changes (including deprecations or visual adjustments)
+and it is recommended that you merge the updated versions with your application:
+
+Config
+------
+
+- @TODO
+
+All Changes
+===========
+
+This is a list of all files in the **project space** that received changes;
+many will be simple comments or formatting that have no effect on the runtime:
+
+- @TODO
diff --git a/user_guide_src/source/installation/upgrading.rst b/user_guide_src/source/installation/upgrading.rst
index b11fbfc92cfb..2c23fdd025fa 100644
--- a/user_guide_src/source/installation/upgrading.rst
+++ b/user_guide_src/source/installation/upgrading.rst
@@ -16,6 +16,7 @@ See also :doc:`./backward_compatibility_notes`.
backward_compatibility_notes
+ upgrade_446
upgrade_445
upgrade_444
upgrade_443
From 2de7be1686e29574e5afd07779de250b1ca459a5 Mon Sep 17 00:00:00 2001
From: ping-yee <611077101@mail.nknu.edu.tw>
Date: Sat, 27 Jan 2024 13:41:00 +0800
Subject: [PATCH 011/164] fix: fix the repeat status code 100 problem.
---
system/HTTP/CURLRequest.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/system/HTTP/CURLRequest.php b/system/HTTP/CURLRequest.php
index 500b425d2dc5..dfc9ba97f7b2 100644
--- a/system/HTTP/CURLRequest.php
+++ b/system/HTTP/CURLRequest.php
@@ -389,7 +389,7 @@ public function send(string $method, string $url)
// Set the string we want to break our response from
$breakString = "\r\n\r\n";
- if (strpos($output, 'HTTP/1.1 100 Continue') === 0) {
+ while (strpos($output, 'HTTP/1.1 100 Continue') === 0) {
$output = substr($output, strpos($output, $breakString) + 4);
}
From 05052527b06eeb8c37315ee0bee3bc19d596ff20 Mon Sep 17 00:00:00 2001
From: "John Paul E. Balandan, CPA"
Date: Fri, 26 Jan 2024 23:43:25 +0800
Subject: [PATCH 012/164] style: apply new options to `phpdoc_align` fixer
---
system/BaseModel.php | 72 +++++++++++-----------
system/Common.php | 22 +++----
system/Database/BaseConnection.php | 18 +++---
system/Database/BasePreparedQuery.php | 2 +-
system/Database/BaseResult.php | 16 ++---
system/Database/ConnectionInterface.php | 12 ++--
system/Database/Forge.php | 2 +-
system/Database/MySQLi/Forge.php | 2 +-
system/Database/OCI8/Forge.php | 2 +-
system/Database/Postgre/Connection.php | 6 +-
system/Database/Postgre/Forge.php | 2 +-
system/Database/Postgre/PreparedQuery.php | 2 +-
system/Database/PreparedQueryInterface.php | 2 +-
system/Database/ResultInterface.php | 6 +-
system/Database/SQLSRV/Forge.php | 2 +-
system/Database/SQLite3/Forge.php | 4 +-
system/Database/SQLite3/Table.php | 2 +-
system/HTTP/CLIRequest.php | 2 +-
system/HTTP/IncomingRequest.php | 2 +-
system/HTTP/RequestTrait.php | 14 ++---
system/HTTP/SiteURI.php | 8 +--
system/Model.php | 34 +++++-----
system/RESTful/ResourceController.php | 2 +-
system/Traits/ConditionalTrait.php | 16 ++---
system/View/Filters.php | 2 +-
system/View/RendererInterface.php | 10 +--
system/View/View.php | 10 +--
27 files changed, 137 insertions(+), 137 deletions(-)
diff --git a/system/BaseModel.php b/system/BaseModel.php
index 6a6f0dff4dd2..8f04270b20f9 100644
--- a/system/BaseModel.php
+++ b/system/BaseModel.php
@@ -400,7 +400,7 @@ abstract protected function doFirst();
* Inserts data into the current database.
* This method works only with dbCalls.
*
- * @param array $row Row data
+ * @param array $row Row data
* @phpstan-param row_array $row
*
* @return bool
@@ -424,9 +424,9 @@ abstract protected function doInsertBatch(?array $set = null, ?bool $escape = nu
* Updates a single record in the database.
* This method works only with dbCalls.
*
- * @param array|int|string|null $id ID
- * @param array|null $row Row data
- * @phpstan-param row_array|null $row
+ * @param array|int|string|null $id ID
+ * @param array|null $row Row data
+ * @phpstan-param row_array|null $row
*/
abstract protected function doUpdate($id = null, $row = null): bool;
@@ -480,9 +480,9 @@ abstract protected function doOnlyDeleted();
* Compiles a replace and runs the query.
* This method works only with dbCalls.
*
- * @param array|null $row Row data
+ * @param array|null $row Row data
* @phpstan-param row_array|null $row
- * @param bool $returnSQL Set to true to return Query String
+ * @param bool $returnSQL Set to true to return Query String
*
* @return BaseResult|false|Query|string
*/
@@ -511,7 +511,7 @@ abstract protected function idValue($data);
* Public getter to return the id value using the idValue() method.
* For example with SQL this will return $data->$this->primaryKey.
*
- * @param array|object $row Row data
+ * @param array|object $row Row data
* @phpstan-param row_array|object $row
*
* @return array|int|string|null
@@ -552,7 +552,7 @@ abstract public function chunk(int $size, Closure $userFunc);
*
* @param array|int|string|null $id One primary key or an array of primary keys
*
- * @return array|object|null The resulting row of data, or null.
+ * @return array|object|null The resulting row of data, or null.
* @phpstan-return ($id is int|string ? row_array|object|null : list)
*/
public function find($id = null)
@@ -696,7 +696,7 @@ public function first()
* you must ensure that the class will provide access to the class
* variables, even if through a magic method.
*
- * @param array|object $row Row data
+ * @param array|object $row Row data
* @phpstan-param row_array|object $row
*
* @throws ReflectionException
@@ -724,7 +724,7 @@ public function save($row): bool
* This method is called on save to determine if entry have to be updated.
* If this method returns false insert operation will be executed
*
- * @param array|object $row Row data
+ * @param array|object $row Row data
* @phpstan-param row_array|object $row
*/
protected function shouldUpdate($row): bool
@@ -748,11 +748,11 @@ public function getInsertID()
* Inserts data into the database. If an object is provided,
* it will attempt to convert it to an array.
*
- * @param array|object|null $row Row data
+ * @param array|object|null $row Row data
* @phpstan-param row_array|object|null $row
- * @param bool $returnID Whether insert ID should be returned or not.
+ * @param bool $returnID Whether insert ID should be returned or not.
*
- * @return bool|int|string insert ID or true on success. false on failure.
+ * @return bool|int|string insert ID or true on success. false on failure.
* @phpstan-return ($returnID is true ? int|string|false : bool)
*
* @throws ReflectionException
@@ -826,8 +826,8 @@ public function insert($row = null, bool $returnID = true)
/**
* Set datetime to created field.
*
- * @phpstan-param row_array $row
- * @param int|string $date timestamp or datetime string
+ * @phpstan-param row_array $row
+ * @param int|string $date timestamp or datetime string
*/
protected function setCreatedField(array $row, $date): array
{
@@ -841,8 +841,8 @@ protected function setCreatedField(array $row, $date): array
/**
* Set datetime to updated field.
*
- * @phpstan-param row_array $row
- * @param int|string $date timestamp or datetime string
+ * @phpstan-param row_array $row
+ * @param int|string $date timestamp or datetime string
*/
protected function setUpdatedField(array $row, $date): array
{
@@ -856,11 +856,11 @@ protected function setUpdatedField(array $row, $date): array
/**
* Compiles batch insert runs the queries, validating each row prior.
*
- * @param list|null $set an associative array of insert values
+ * @param list|null $set an associative array of insert values
* @phpstan-param list|null $set
- * @param bool|null $escape Whether to escape values
- * @param int $batchSize The size of the batch to run
- * @param bool $testing True means only number of records is returned, false will execute the query
+ * @param bool|null $escape Whether to escape values
+ * @param int $batchSize The size of the batch to run
+ * @param bool $testing True means only number of records is returned, false will execute the query
*
* @return bool|int Number of rows inserted or FALSE on failure
*
@@ -937,8 +937,8 @@ public function insertBatch(?array $set = null, ?bool $escape = null, int $batch
* Updates a single record in the database. If an object is provided,
* it will attempt to convert it into an array.
*
- * @param array|int|string|null $id
- * @param array|object|null $row Row data
+ * @param array|int|string|null $id
+ * @param array|object|null $row Row data
* @phpstan-param row_array|object|null $row
*
* @throws ReflectionException
@@ -999,11 +999,11 @@ public function update($id = null, $row = null): bool
/**
* Compiles an update and runs the query.
*
- * @param list|null $set an associative array of insert values
+ * @param list|null $set an associative array of insert values
* @phpstan-param list|null $set
- * @param string|null $index The where key
- * @param int $batchSize The size of the batch to run
- * @param bool $returnSQL True means SQL is returned, false will execute the query
+ * @param string|null $index The where key
+ * @param int $batchSize The size of the batch to run
+ * @param bool $returnSQL True means SQL is returned, false will execute the query
*
* @return false|int|string[] Number of rows affected or FALSE on failure, SQL array when testMode
*
@@ -1173,9 +1173,9 @@ public function onlyDeleted()
/**
* Compiles a replace and runs the query.
*
- * @param array|null $row Row data
+ * @param array|null $row Row data
* @phpstan-param row_array|null $row
- * @param bool $returnSQL Set to true to return Query String
+ * @param bool $returnSQL Set to true to return Query String
*
* @return BaseResult|false|Query|string
*/
@@ -1279,7 +1279,7 @@ public function protect(bool $protect = true)
* @used-by update() to protect against mass assignment vulnerabilities.
* @used-by updateBatch() to protect against mass assignment vulnerabilities.
*
- * @param array $row Row data
+ * @param array $row Row data
* @phpstan-param row_array $row
*
* @throws DataException
@@ -1310,7 +1310,7 @@ protected function doProtectFields(array $row): array
* @used-by insert() to protect against mass assignment vulnerabilities.
* @used-by insertBatch() to protect against mass assignment vulnerabilities.
*
- * @param array $row Row data
+ * @param array $row Row data
* @phpstan-param row_array $row
*
* @throws DataException
@@ -1505,7 +1505,7 @@ public function cleanRules(bool $choice = false)
* Validate the row data against the validation rules (or the validation group)
* specified in the class property, $validationRules.
*
- * @param array|object $row Row data
+ * @param array|object $row Row data
* @phpstan-param row_array|object $row
*/
public function validate($row): bool
@@ -1575,8 +1575,8 @@ public function getValidationMessages(): array
* currently so that rules don't block updating when only updating
* a partial row.
*
- * @param array $rules Array containing field name and rule
- * @param array $row Row data (@TODO Remove null in param type)
+ * @param array $rules Array containing field name and rule
+ * @param array $row Row data (@TODO Remove null in param type)
* @phpstan-param row_array $row
*/
protected function cleanValidationRules(array $rules, ?array $row = null): array
@@ -1760,9 +1760,9 @@ protected function objectToRawArray($object, bool $onlyChanged = true, bool $rec
/**
* Transform data to array.
*
- * @param array|object|null $row Row data
+ * @param array|object|null $row Row data
* @phpstan-param row_array|object|null $row
- * @param string $type Type of data (insert|update)
+ * @param string $type Type of data (insert|update)
*
* @throws DataException
* @throws InvalidArgumentException
diff --git a/system/Common.php b/system/Common.php
index 690fa3fc5b6a..e5524c039835 100644
--- a/system/Common.php
+++ b/system/Common.php
@@ -64,7 +64,7 @@ function app_timezone(): string
* cache()->save('foo', 'bar');
* $foo = cache('bar');
*
- * @return array|bool|CacheInterface|float|int|object|string|null
+ * @return array|bool|CacheInterface|float|int|object|string|null
* @phpstan-return ($key is null ? CacheInterface : array|bool|float|int|object|string|null)
*/
function cache(?string $key = null)
@@ -207,7 +207,7 @@ function command(string $command)
*
* @param class-string|string $name
*
- * @return ConfigTemplate|null
+ * @return ConfigTemplate|null
* @phpstan-return ($name is class-string ? ConfigTemplate : object|null)
*/
function config(string $name, bool $getShared = true)
@@ -414,11 +414,11 @@ function env(string $key, $default = null)
* If $data is an array, then it loops over it, escaping each
* 'value' of the key/value pairs.
*
- * @param array|string $data
+ * @param array|string $data
* @phpstan-param 'html'|'js'|'css'|'url'|'attr'|'raw' $context
- * @param string|null $encoding Current encoding for escaping.
- * If not UTF-8, we convert strings from this encoding
- * pre-escaping and back to this encoding post-escaping.
+ * @param string|null $encoding Current encoding for escaping.
+ * If not UTF-8, we convert strings from this encoding
+ * pre-escaping and back to this encoding post-escaping.
*
* @return array|string
*
@@ -805,7 +805,7 @@ function log_message(string $level, string $message, array $context = [])
*
* @param class-string|string $name
*
- * @return ModelTemplate|null
+ * @return ModelTemplate|null
* @phpstan-return ($name is class-string ? ModelTemplate : object|null)
*/
function model(string $name, bool $getShared = true, ?ConnectionInterface &$conn = null)
@@ -819,8 +819,8 @@ function model(string $name, bool $getShared = true, ?ConnectionInterface &$conn
* Provides access to "old input" that was set in the session
* during a redirect()->withInput().
*
- * @param string|null $default
- * @param false|string $escape
+ * @param string|null $default
+ * @param false|string $escape
* @phpstan-param false|'attr'|'css'|'html'|'js'|'raw'|'url' $escape
*
* @return array|string|null
@@ -974,7 +974,7 @@ function route_to(string $method, ...$params)
* session()->set('foo', 'bar');
* $foo = session('bar');
*
- * @return array|bool|float|int|object|Session|string|null
+ * @return array|bool|float|int|object|Session|string|null
* @phpstan-return ($val is null ? Session : array|bool|float|int|object|string|null)
*/
function session(?string $val = null)
@@ -1128,7 +1128,7 @@ function stringify_attributes($attributes, bool $js = false): string
* @param non-empty-string|null $name
* @param (callable(): mixed)|null $callable
*
- * @return mixed|Timer
+ * @return mixed|Timer
* @phpstan-return ($name is null ? Timer : ($callable is (callable(): mixed) ? mixed : Timer))
*/
function timer(?string $name = null, ?callable $callable = null)
diff --git a/system/Database/BaseConnection.php b/system/Database/BaseConnection.php
index 1116d3966439..a024d938f386 100644
--- a/system/Database/BaseConnection.php
+++ b/system/Database/BaseConnection.php
@@ -457,7 +457,7 @@ abstract protected function _close();
/**
* Create a persistent database connection.
*
- * @return false|object|resource
+ * @return false|object|resource
* @phpstan-return false|TConnection
*/
public function persistentConnect()
@@ -471,7 +471,7 @@ public function persistentConnect()
* get that connection. If you pass either alias in and only a single
* connection is present, it must return the sole connection.
*
- * @return false|object|resource
+ * @return false|object|resource
* @phpstan-return TConnection
*/
public function getConnection(?string $alias = null)
@@ -547,7 +547,7 @@ public function addTableAlias(string $table)
/**
* Executes the query against the database.
*
- * @return false|object|resource
+ * @return false|object|resource
* @phpstan-return false|TResult
*/
abstract protected function execute(string $sql);
@@ -562,7 +562,7 @@ abstract protected function execute(string $sql);
*
* @param array|string|null $binds
*
- * @return BaseResult|bool|Query BaseResult when “read” type query, bool when “write” type query, Query when prepared query
+ * @return BaseResult|bool|Query BaseResult when “read” type query, bool when “write” type query, Query when prepared query
* @phpstan-return BaseResult|bool|Query
*
* @todo BC set $queryClass default as null in 4.1
@@ -681,7 +681,7 @@ public function query(string $sql, $binds = null, bool $setEscapeFlags = true, s
* is performed, nor are transactions handled. Simply takes a raw
* query string and returns the database-specific result id.
*
- * @return false|object|resource
+ * @return false|object|resource
* @phpstan-return false|TResult
*/
public function simpleQuery(string $sql)
@@ -1006,7 +1006,7 @@ public function getConnectDuration(int $decimals = 6): string
* @param bool $protectIdentifiers Protect table or column names?
* @param bool $fieldExists Supplied $item contains a column name?
*
- * @return array|string
+ * @return array|string
* @phpstan-return ($item is array ? array : string)
*/
public function protectIdentifiers($item, bool $prefixSingle = false, ?bool $protectIdentifiers = null, bool $fieldExists = true)
@@ -1166,7 +1166,7 @@ private function protectDotItem(string $item, string $alias, bool $protectIdenti
*
* @param array|string $item
*
- * @return array|string
+ * @return array|string
* @phpstan-return ($item is array ? array : string)
*/
public function escapeIdentifiers($item)
@@ -1251,7 +1251,7 @@ abstract public function affectedRows(): int;
*
* @param array|bool|float|int|object|string|null $str
*
- * @return array|float|int|string
+ * @return array|float|int|string
* @phpstan-return ($str is array ? array : float|int|string)
*/
public function escape($str)
@@ -1665,7 +1665,7 @@ public function isWriteType($sql): bool
*
* Must return an array with keys 'code' and 'message':
*
- * @return array
+ * @return array
* @phpstan-return array{code: int|string|null, message: string|null}
*/
abstract public function error(): array;
diff --git a/system/Database/BasePreparedQuery.php b/system/Database/BasePreparedQuery.php
index bfc0a608ea05..4e9d816686f9 100644
--- a/system/Database/BasePreparedQuery.php
+++ b/system/Database/BasePreparedQuery.php
@@ -110,7 +110,7 @@ abstract public function _prepare(string $sql, array $options = []);
* Takes a new set of data and runs it against the currently
* prepared query. Upon success, will return a Results object.
*
- * @return bool|ResultInterface
+ * @return bool|ResultInterface
* @phpstan-return bool|ResultInterface
*
* @throws DatabaseException
diff --git a/system/Database/BaseResult.php b/system/Database/BaseResult.php
index b807b0bb7ff0..93bb00e4d350 100644
--- a/system/Database/BaseResult.php
+++ b/system/Database/BaseResult.php
@@ -83,10 +83,10 @@ abstract class BaseResult implements ResultInterface
/**
* Constructor
*
- * @param object|resource $connID
- * @param object|resource $resultID
- * @phpstan-param TConnection $connID
- * @phpstan-param TResult $resultID
+ * @param object|resource $connID
+ * @param object|resource $resultID
+ * @phpstan-param TConnection $connID
+ * @phpstan-param TResult $resultID
*/
public function __construct(&$connID, &$resultID)
{
@@ -209,7 +209,7 @@ public function getResultArray(): array
*
* If no results, an empty array is returned.
*
- * @return array
+ * @return array
* @phpstan-return list
*/
public function getResultObject(): array
@@ -254,11 +254,11 @@ public function getResultObject(): array
*
* If row doesn't exist, returns null.
*
- * @param int|string $n The index of the results to return, or column name.
- * @param string $type The type of result object. 'array', 'object' or class name.
+ * @param int|string $n The index of the results to return, or column name.
+ * @param string $type The type of result object. 'array', 'object' or class name.
* @phpstan-param class-string|'array'|'object' $type
*
- * @return array|object|stdClass|null
+ * @return array|object|stdClass|null
* @phpstan-return ($type is 'object' ? stdClass|null : ($type is 'array' ? array|null : object|null))
*/
public function getRow($n = 0, string $type = 'object')
diff --git a/system/Database/ConnectionInterface.php b/system/Database/ConnectionInterface.php
index 85125eb1ae62..a8493f897ec7 100644
--- a/system/Database/ConnectionInterface.php
+++ b/system/Database/ConnectionInterface.php
@@ -27,7 +27,7 @@ public function initialize();
/**
* Connect to the database.
*
- * @return false|object|resource
+ * @return false|object|resource
* @phpstan-return false|TConnection
*/
public function connect(bool $persistent = false);
@@ -35,7 +35,7 @@ public function connect(bool $persistent = false);
/**
* Create a persistent database connection.
*
- * @return false|object|resource
+ * @return false|object|resource
* @phpstan-return false|TConnection
*/
public function persistentConnect();
@@ -54,7 +54,7 @@ public function reconnect();
* get that connection. If you pass either alias in and only a single
* connection is present, it must return the sole connection.
*
- * @return false|object|resource
+ * @return false|object|resource
* @phpstan-return false|TConnection
*/
public function getConnection(?string $alias = null);
@@ -100,7 +100,7 @@ public function getVersion(): string;
*
* @param array|string|null $binds
*
- * @return BaseResult|bool|Query
+ * @return BaseResult|bool|Query
* @phpstan-return BaseResult|bool|Query
*/
public function query(string $sql, $binds = null);
@@ -110,7 +110,7 @@ public function query(string $sql, $binds = null);
* is performed, nor are transactions handled. Simply takes a raw
* query string and returns the database-specific result id.
*
- * @return false|object|resource
+ * @return false|object|resource
* @phpstan-return false|TResult
*/
public function simpleQuery(string $sql);
@@ -139,7 +139,7 @@ public function getLastQuery();
*
* @param array|bool|float|int|object|string|null $str
*
- * @return array|float|int|string
+ * @return array|float|int|string
* @phpstan-return ($str is array ? array : float|int|string)
*/
public function escape($str);
diff --git a/system/Database/Forge.php b/system/Database/Forge.php
index adbdc208fc47..afc7d1cd6b15 100644
--- a/system/Database/Forge.php
+++ b/system/Database/Forge.php
@@ -831,7 +831,7 @@ public function modifyColumn(string $table, $fields): bool
* @param array|string $processedFields Processed column definitions
* or column names to DROP
*
- * @return false|list|string|null SQL string
+ * @return false|list|string|null SQL string
* @phpstan-return ($alterType is 'DROP' ? string : list|false|null)
*/
protected function _alterTable(string $alterType, string $table, $processedFields)
diff --git a/system/Database/MySQLi/Forge.php b/system/Database/MySQLi/Forge.php
index b1beba2a9dd2..adc6c6cc7267 100644
--- a/system/Database/MySQLi/Forge.php
+++ b/system/Database/MySQLi/Forge.php
@@ -133,7 +133,7 @@ protected function _createTableAttributes(array $attributes): string
* @param array|string $processedFields Processed column definitions
* or column names to DROP
*
- * @return list|string SQL string
+ * @return list|string SQL string
* @phpstan-return ($alterType is 'DROP' ? string : list)
*/
protected function _alterTable(string $alterType, string $table, $processedFields)
diff --git a/system/Database/OCI8/Forge.php b/system/Database/OCI8/Forge.php
index 2735b886cb86..4de36ac91e6d 100644
--- a/system/Database/OCI8/Forge.php
+++ b/system/Database/OCI8/Forge.php
@@ -98,7 +98,7 @@ class Forge extends BaseForge
* @param array|string $processedFields Processed column definitions
* or column names to DROP
*
- * @return list|string SQL string
+ * @return list|string SQL string
* @phpstan-return ($alterType is 'DROP' ? string : list)
*/
protected function _alterTable(string $alterType, string $table, $processedFields)
diff --git a/system/Database/Postgre/Connection.php b/system/Database/Postgre/Connection.php
index 56905ec922d2..c54209453217 100644
--- a/system/Database/Postgre/Connection.php
+++ b/system/Database/Postgre/Connection.php
@@ -55,7 +55,7 @@ class Connection extends BaseConnection
/**
* Connect to the database.
*
- * @return false|resource
+ * @return false|resource
* @phpstan-return false|PgSqlConnection
*/
public function connect(bool $persistent = false)
@@ -178,7 +178,7 @@ public function getVersion(): string
/**
* Executes the query against the database.
*
- * @return false|resource
+ * @return false|resource
* @phpstan-return false|PgSqlResult
*/
protected function execute(string $sql)
@@ -219,7 +219,7 @@ public function affectedRows(): int
*
* @param array|bool|float|int|object|string|null $str
*
- * @return array|float|int|string
+ * @return array|float|int|string
* @phpstan-return ($str is array ? array : float|int|string)
*/
public function escape($str)
diff --git a/system/Database/Postgre/Forge.php b/system/Database/Postgre/Forge.php
index ee7583642684..8af1507c6b2a 100644
--- a/system/Database/Postgre/Forge.php
+++ b/system/Database/Postgre/Forge.php
@@ -84,7 +84,7 @@ protected function _createTableAttributes(array $attributes): string
* @param array|string $processedFields Processed column definitions
* or column names to DROP
*
- * @return false|list|string SQL string or false
+ * @return false|list|string SQL string or false
* @phpstan-return ($alterType is 'DROP' ? string : list|false)
*/
protected function _alterTable(string $alterType, string $table, $processedFields)
diff --git a/system/Database/Postgre/PreparedQuery.php b/system/Database/Postgre/PreparedQuery.php
index fd60793dbe5d..d47b72d639d7 100644
--- a/system/Database/Postgre/PreparedQuery.php
+++ b/system/Database/Postgre/PreparedQuery.php
@@ -93,7 +93,7 @@ public function _execute(array $data): bool
/**
* Returns the result object for the prepared query or false on failure.
*
- * @return resource|null
+ * @return resource|null
* @phpstan-return PgSqlResult|null
*/
public function _getResult()
diff --git a/system/Database/PreparedQueryInterface.php b/system/Database/PreparedQueryInterface.php
index 7b55991835c8..b5d00ef11e19 100644
--- a/system/Database/PreparedQueryInterface.php
+++ b/system/Database/PreparedQueryInterface.php
@@ -24,7 +24,7 @@ interface PreparedQueryInterface
* Takes a new set of data and runs it against the currently
* prepared query. Upon success, will return a Results object.
*
- * @return bool|ResultInterface
+ * @return bool|ResultInterface
* @phpstan-return bool|ResultInterface
*/
public function execute(...$data);
diff --git a/system/Database/ResultInterface.php b/system/Database/ResultInterface.php
index b06de85ad3be..82cb7956b22e 100644
--- a/system/Database/ResultInterface.php
+++ b/system/Database/ResultInterface.php
@@ -57,11 +57,11 @@ public function getResultObject(): array;
*
* If row doesn't exist, returns null.
*
- * @param int|string $n The index of the results to return, or column name.
- * @param string $type The type of result object. 'array', 'object' or class name.
+ * @param int|string $n The index of the results to return, or column name.
+ * @param string $type The type of result object. 'array', 'object' or class name.
* @phpstan-param class-string|'array'|'object' $type
*
- * @return array|object|stdClass|null
+ * @return array|object|stdClass|null
* @phpstan-return ($type is 'object' ? stdClass|null : ($type is 'array' ? array|null : object|null))
*/
public function getRow($n = 0, string $type = 'object');
diff --git a/system/Database/SQLSRV/Forge.php b/system/Database/SQLSRV/Forge.php
index 522d5fa02f54..5dead5b3a308 100755
--- a/system/Database/SQLSRV/Forge.php
+++ b/system/Database/SQLSRV/Forge.php
@@ -129,7 +129,7 @@ protected function _createTableAttributes(array $attributes): string
* @param array|string $processedFields Processed column definitions
* or column names to DROP
*
- * @return false|list|string SQL string or false
+ * @return false|list|string SQL string or false
* @phpstan-return ($alterType is 'DROP' ? string : list|false)
*/
protected function _alterTable(string $alterType, string $table, $processedFields)
diff --git a/system/Database/SQLite3/Forge.php b/system/Database/SQLite3/Forge.php
index d7112c61389f..b02193f5057c 100644
--- a/system/Database/SQLite3/Forge.php
+++ b/system/Database/SQLite3/Forge.php
@@ -112,8 +112,8 @@ public function dropDatabase(string $dbName): bool
* @param array|string $processedFields Processed column definitions
* or column names to DROP
*
- * @return array|string|null
- * @return list|string|null SQL string or null
+ * @return array|string|null
+ * @return list|string|null SQL string or null
* @phpstan-return ($alterType is 'DROP' ? string : list|null)
*/
protected function _alterTable(string $alterType, string $table, $processedFields)
diff --git a/system/Database/SQLite3/Table.php b/system/Database/SQLite3/Table.php
index 620d28464738..ce574033afb0 100644
--- a/system/Database/SQLite3/Table.php
+++ b/system/Database/SQLite3/Table.php
@@ -374,7 +374,7 @@ protected function copyData()
*
* @param array|bool $fields
*
- * @return mixed
+ * @return mixed
* @phpstan-return ($fields is array ? array : mixed)
*/
protected function formatFields($fields)
diff --git a/system/HTTP/CLIRequest.php b/system/HTTP/CLIRequest.php
index 01823dbfc4c5..684b1dbfea15 100644
--- a/system/HTTP/CLIRequest.php
+++ b/system/HTTP/CLIRequest.php
@@ -315,7 +315,7 @@ public function getLocale(): string
/**
* Checks this request type.
*
- * @param string $type HTTP verb or 'json' or 'ajax'
+ * @param string $type HTTP verb or 'json' or 'ajax'
* @phpstan-param string|'get'|'post'|'put'|'delete'|'head'|'patch'|'options'|'json'|'ajax' $type
*/
public function is(string $type): bool
diff --git a/system/HTTP/IncomingRequest.php b/system/HTTP/IncomingRequest.php
index 8bc246f7956d..499fa0b1cf06 100755
--- a/system/HTTP/IncomingRequest.php
+++ b/system/HTTP/IncomingRequest.php
@@ -400,7 +400,7 @@ public function negotiate(string $type, array $supported, bool $strictMatch = fa
/**
* Checks this request type.
*
- * @param string $type HTTP verb or 'json' or 'ajax'
+ * @param string $type HTTP verb or 'json' or 'ajax'
* @phpstan-param string|'get'|'post'|'put'|'delete'|'head'|'patch'|'options'|'json'|'ajax' $type
*/
public function is(string $type): bool
diff --git a/system/HTTP/RequestTrait.php b/system/HTTP/RequestTrait.php
index 6db903ddacec..9c1f4c28a52c 100644
--- a/system/HTTP/RequestTrait.php
+++ b/system/HTTP/RequestTrait.php
@@ -215,9 +215,9 @@ public function getEnv($index = null, $filter = null, $flags = null)
/**
* Allows manually setting the value of PHP global, like $_GET, $_POST, etc.
*
- * @param string $name Supergrlobal name (lowercase)
+ * @param string $name Supergrlobal name (lowercase)
* @phpstan-param 'get'|'post'|'request'|'cookie'|'server' $name
- * @param mixed $value
+ * @param mixed $value
*
* @return $this
*/
@@ -238,11 +238,11 @@ public function setGlobal(string $name, $value)
*
* http://php.net/manual/en/filter.filters.sanitize.php
*
- * @param string $name Supergrlobal name (lowercase)
+ * @param string $name Supergrlobal name (lowercase)
* @phpstan-param 'get'|'post'|'request'|'cookie'|'server' $name
- * @param array|string|null $index
- * @param int|null $filter Filter constant
- * @param array|int|null $flags Options
+ * @param array|string|null $index
+ * @param int|null $filter Filter constant
+ * @param array|int|null $flags Options
*
* @return array|bool|float|int|object|string|null
*/
@@ -332,7 +332,7 @@ public function fetchGlobal(string $name, $index = null, ?int $filter = null, $f
* Saves a copy of the current state of one of several PHP globals,
* so we can retrieve them later.
*
- * @param string $name Superglobal name (lowercase)
+ * @param string $name Superglobal name (lowercase)
* @phpstan-param 'get'|'post'|'request'|'cookie'|'server' $name
*
* @return void
diff --git a/system/HTTP/SiteURI.php b/system/HTTP/SiteURI.php
index 6d56507314e7..b7acfc389f25 100644
--- a/system/HTTP/SiteURI.php
+++ b/system/HTTP/SiteURI.php
@@ -83,10 +83,10 @@ class SiteURI extends URI
private string $routePath;
/**
- * @param string $relativePath URI path relative to baseURL. May include
- * queries or fragments.
- * @param string|null $host Optional current hostname.
- * @param string|null $scheme Optional scheme. 'http' or 'https'.
+ * @param string $relativePath URI path relative to baseURL. May include
+ * queries or fragments.
+ * @param string|null $host Optional current hostname.
+ * @param string|null $scheme Optional scheme. 'http' or 'https'.
* @phpstan-param 'http'|'https'|null $scheme
*/
public function __construct(
diff --git a/system/Model.php b/system/Model.php
index 5dba810c8c59..2596417c12e6 100644
--- a/system/Model.php
+++ b/system/Model.php
@@ -179,7 +179,7 @@ public function setTable(string $table)
* @param bool $singleton Single or multiple results
* @param array|int|string|null $id One primary key or an array of primary keys
*
- * @return array|object|null The resulting row of data, or null.
+ * @return array|object|null The resulting row of data, or null.
* @phpstan-return ($singleton is true ? row_array|null|object : list)
*/
protected function doFind(bool $singleton, $id = null)
@@ -211,7 +211,7 @@ protected function doFind(bool $singleton, $id = null)
*
* @param string $columnName Column Name
*
- * @return array|null The resulting row of data, or null if no data found.
+ * @return array|null The resulting row of data, or null if no data found.
* @phpstan-return list|null
*/
protected function doFindColumn(string $columnName)
@@ -227,7 +227,7 @@ protected function doFindColumn(string $columnName)
* @param int $limit Limit
* @param int $offset Offset
*
- * @return array
+ * @return array
* @phpstan-return list
*/
protected function doFindAll(int $limit = 0, int $offset = 0)
@@ -248,7 +248,7 @@ protected function doFindAll(int $limit = 0, int $offset = 0)
* Query Builder calls into account when determining the result set.
* This method works only with dbCalls.
*
- * @return array|object|null
+ * @return array|object|null
* @phpstan-return row_array|object|null
*/
protected function doFirst()
@@ -274,7 +274,7 @@ protected function doFirst()
* Inserts data into the current table.
* This method works only with dbCalls.
*
- * @param array $row Row data
+ * @param array $row Row data
* @phpstan-param row_array $row
*
* @return bool
@@ -364,9 +364,9 @@ protected function doInsertBatch(?array $set = null, ?bool $escape = null, int $
* Updates a single record in $this->table.
* This method works only with dbCalls.
*
- * @param array|int|string|null $id
- * @param array|null $row Row data
- * @phpstan-param row_array|null $row
+ * @param array|int|string|null $id
+ * @param array|null $row Row data
+ * @phpstan-param row_array|null $row
*/
protected function doUpdate($id = null, $row = null): bool
{
@@ -483,9 +483,9 @@ protected function doOnlyDeleted()
* Compiles a replace into string and runs the query
* This method works only with dbCalls.
*
- * @param array|null $row Data
+ * @param array|null $row Data
* @phpstan-param row_array|null $row
- * @param bool $returnSQL Set to true to return Query String
+ * @param bool $returnSQL Set to true to return Query String
*
* @return BaseResult|false|Query|string
*/
@@ -531,7 +531,7 @@ protected function idValue($data)
/**
* Returns the id value for the data array or object
*
- * @param array|object $row Row data
+ * @param array|object $row Row data
* @phpstan-param row_array|object $row
*
* @return array|int|string|null
@@ -718,11 +718,11 @@ protected function shouldUpdate($row): bool
* Inserts data into the database. If an object is provided,
* it will attempt to convert it to an array.
*
- * @param array|object|null $row
+ * @param array|object|null $row
* @phpstan-param row_array|object|null $row
- * @param bool $returnID Whether insert ID should be returned or not.
+ * @param bool $returnID Whether insert ID should be returned or not.
*
- * @return bool|int|string
+ * @return bool|int|string
* @phpstan-return ($returnID is true ? int|string|false : bool)
*
* @throws ReflectionException
@@ -751,7 +751,7 @@ public function insert($row = null, bool $returnID = true)
* @used-by insert() to protect against mass assignment vulnerabilities.
* @used-by insertBatch() to protect against mass assignment vulnerabilities.
*
- * @param array $row Row data
+ * @param array $row Row data
* @phpstan-param row_array $row
*
* @throws DataException
@@ -784,8 +784,8 @@ protected function doProtectFieldsForInsert(array $row): array
* Updates a single record in the database. If an object is provided,
* it will attempt to convert it into an array.
*
- * @param array|int|string|null $id
- * @param array|object|null $row
+ * @param array|int|string|null $id
+ * @param array|object|null $row
* @phpstan-param row_array|object|null $row
*
* @throws ReflectionException
diff --git a/system/RESTful/ResourceController.php b/system/RESTful/ResourceController.php
index 6ffb602c8bd1..bd0356268142 100644
--- a/system/RESTful/ResourceController.php
+++ b/system/RESTful/ResourceController.php
@@ -104,7 +104,7 @@ public function delete($id = null)
/**
* Set/change the expected response representation for returned objects
*
- * @param string $format json/xml
+ * @param string $format json/xml
* @phpstan-param 'json'|'xml' $format
*
* @return void
diff --git a/system/Traits/ConditionalTrait.php b/system/Traits/ConditionalTrait.php
index 620bdd88508b..5b8273ee78bc 100644
--- a/system/Traits/ConditionalTrait.php
+++ b/system/Traits/ConditionalTrait.php
@@ -18,10 +18,10 @@ trait ConditionalTrait
*
* @template TWhen of mixed
*
- * @phpstan-param TWhen $condition
- * @phpstan-param callable(self, TWhen): mixed $callback
- * @phpstan-param (callable(self): mixed)|null $defaultCallback
- * @param array|bool|float|int|object|resource|string|null $condition
+ * @phpstan-param TWhen $condition
+ * @phpstan-param callable(self, TWhen): mixed $callback
+ * @phpstan-param (callable(self): mixed)|null $defaultCallback
+ * @param array|bool|float|int|object|resource|string|null $condition
*
* @return $this
*/
@@ -41,10 +41,10 @@ public function when($condition, callable $callback, ?callable $defaultCallback
*
* @template TWhenNot of mixed
*
- * @phpstan-param TWhenNot $condition
- * @phpstan-param callable(self, TWhenNot): mixed $callback
- * @phpstan-param (callable(self): mixed)|null $defaultCallback
- * @param array|bool|float|int|object|resource|string|null $condition
+ * @phpstan-param TWhenNot $condition
+ * @phpstan-param callable(self, TWhenNot): mixed $callback
+ * @phpstan-param (callable(self): mixed)|null $defaultCallback
+ * @param array|bool|float|int|object|resource|string|null $condition
*
* @return $this
*/
diff --git a/system/View/Filters.php b/system/View/Filters.php
index fa03a1919a2b..4b89b1265b1c 100644
--- a/system/View/Filters.php
+++ b/system/View/Filters.php
@@ -74,7 +74,7 @@ public static function default($value, string $default): string
/**
* Escapes the given value with our `esc()` helper function.
*
- * @param string $value
+ * @param string $value
* @phpstan-param 'html'|'js'|'css'|'url'|'attr'|'raw' $context
*/
public static function esc($value, string $context = 'html'): string
diff --git a/system/View/RendererInterface.php b/system/View/RendererInterface.php
index a0f093b67326..4bb889743f9f 100644
--- a/system/View/RendererInterface.php
+++ b/system/View/RendererInterface.php
@@ -44,8 +44,8 @@ public function renderString(string $view, ?array $options = null, bool $saveDat
/**
* Sets several pieces of view data at once.
*
- * @param string $context The context to escape it for: html, css, js, url
- * If 'raw', no escaping will happen
+ * @param string $context The context to escape it for: html, css, js, url
+ * If 'raw', no escaping will happen
* @phpstan-param null|'html'|'js'|'css'|'url'|'attr'|'raw' $context
*
* @return RendererInterface
@@ -55,9 +55,9 @@ public function setData(array $data = [], ?string $context = null);
/**
* Sets a single piece of view data.
*
- * @param mixed $value
- * @param string $context The context to escape it for: html, css, js, url
- * If 'raw' no escaping will happen
+ * @param mixed $value
+ * @param string $context The context to escape it for: html, css, js, url
+ * If 'raw' no escaping will happen
* @phpstan-param null|'html'|'js'|'css'|'url'|'attr'|'raw' $context
*
* @return RendererInterface
diff --git a/system/View/View.php b/system/View/View.php
index 2e2823fa2332..8940951a42aa 100644
--- a/system/View/View.php
+++ b/system/View/View.php
@@ -330,8 +330,8 @@ public function excerpt(string $string, int $length = 20): string
/**
* Sets several pieces of view data at once.
*
- * @param string|null $context The context to escape it for: html, css, js, url
- * If null, no escaping will happen
+ * @param string|null $context The context to escape it for: html, css, js, url
+ * If null, no escaping will happen
* @phpstan-param null|'html'|'js'|'css'|'url'|'attr'|'raw' $context
*/
public function setData(array $data = [], ?string $context = null): RendererInterface
@@ -349,9 +349,9 @@ public function setData(array $data = [], ?string $context = null): RendererInte
/**
* Sets a single piece of view data.
*
- * @param mixed $value
- * @param string|null $context The context to escape it for: html, css, js, url
- * If null, no escaping will happen
+ * @param mixed $value
+ * @param string|null $context The context to escape it for: html, css, js, url
+ * If null, no escaping will happen
* @phpstan-param null|'html'|'js'|'css'|'url'|'attr'|'raw' $context
*/
public function setVar(string $name, $value = null, ?string $context = null): RendererInterface
From 917607cd47457718c668bf31437fae6e670c6d29 Mon Sep 17 00:00:00 2001
From: ping-yee <611077101@mail.nknu.edu.tw>
Date: Sun, 28 Jan 2024 17:55:08 +0800
Subject: [PATCH 013/164] test: add the test case for multiple HTTP100.
---
tests/system/HTTP/CURLRequestTest.php | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/tests/system/HTTP/CURLRequestTest.php b/tests/system/HTTP/CURLRequestTest.php
index 4893266e5009..46da73fe736c 100644
--- a/tests/system/HTTP/CURLRequestTest.php
+++ b/tests/system/HTTP/CURLRequestTest.php
@@ -1109,4 +1109,24 @@ public function testUserAgentOption(): void
$this->assertArrayHasKey(CURLOPT_USERAGENT, $options);
$this->assertSame($agent, $options[CURLOPT_USERAGENT]);
}
+
+ public function testMultipleHTTP100(): void
+ {
+ $output = 'HTTP/1.1 100 Continue
+ Mark bundle as not supporting multiuse
+ HTTP/1.1 100 Continue
+ Mark bundle as not supporting multiuse
+ HTTP/1.1 200 OK
+ Server: Werkzeug/2.2.2 Python/3.7.17
+ Date: Sun, 28 Jan 2024 06:05:36 GMT
+ Content-Type: application/json
+ Content-Length: 33
+ Connection: close';
+
+ $this->request->setOutput($output);
+
+ $response = $this->request->request('get', 'http://example.com');
+
+ $this->assertSame(200, $response->getStatusCode());
+ }
}
From 9482b49fb91d945aeecdc2f969e8207f00f4cdb1 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Mon, 29 Jan 2024 11:17:02 +0900
Subject: [PATCH 014/164] docs: add "Set Default Signing" section and refer it
---
contributing/signing.md | 14 +++++++++++++-
contributing/workflow.md | 10 ++++++----
2 files changed, 19 insertions(+), 5 deletions(-)
diff --git a/contributing/signing.md b/contributing/signing.md
index 6626911591d2..21d6b4e98ce3 100644
--- a/contributing/signing.md
+++ b/contributing/signing.md
@@ -47,7 +47,19 @@ The basic steps are
- Provide your GPG key passphrase, as prompted, when you do a commit.
Depending on your IDE, you may have to do your Git commits from your Git
-bash shell to use the **-S** option to force the secure signing.
+bash shell to use the `-S` option to force the secure signing.
+
+## Set Default Signing
+
+We recommend you set git securely sign commits without the `-S` option in
+`git commit`.
+
+You can do it by setting `git config --global commit.gpgsign true` and
+`git config --global user.signingkey 3AC5C34371567BD2` to all local repositories.
+Without the `--global` option, the change is applied to one local repository only.
+
+> [!NOTE]
+> `3AC5C34371567BD2` is your GPG Key ID
## Commit Messages
diff --git a/contributing/workflow.md b/contributing/workflow.md
index 921c49da1791..d91b450499cd 100644
--- a/contributing/workflow.md
+++ b/contributing/workflow.md
@@ -179,6 +179,10 @@ For instance, to commit your work from a debugging session:
Just make sure that your commits in a feature branch are all related.
+> [!NOTE]
+> We recommend to [Set Default Signing](./signing.md#set-default-signing) for
+> secure signing commits without the `-S` option in `git commit`.
+
### GPG-Signing Old Commits
Any developer can forget GPG-signing their commits with the option `-S`, like `git commit -S -m 'Signed GPG'`. In such a case, all you need to do is the following:
@@ -197,10 +201,8 @@ All commits:
> git push --force-with-lease origin your-branch
```
-As a faster alternative, you can still securely sign commits without the `-S` option in `git commit` by setting `git config --global commit.gpgsign true` and `git config --global user.signingkey 3AC5C34371567BD2` to all local repositories. Without the `--global` option, the change is applied to one local repository only.
-
-> **Note**
-> `3AC5C34371567BD2` is your GPG Key ID
+As a faster alternative, you can still securely sign commits without the `-S`
+option in `git commit`. See [Set Default Signing](./signing.md#set-default-signing).
### Changing a Commit Message
From 77557031b0fedf11d42afaf29786db77b7ed9388 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Mon, 29 Jan 2024 11:17:31 +0900
Subject: [PATCH 015/164] docs: fix gramatically error
---
contributing/signing.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/contributing/signing.md b/contributing/signing.md
index 21d6b4e98ce3..949bf18ac955 100644
--- a/contributing/signing.md
+++ b/contributing/signing.md
@@ -29,7 +29,7 @@ Read below to find out how to sign your commits :)
## Secure Signing
-To verify your commits, you will need to setup a GPG key, and attach it
+To verify your commits, you will need to set up a GPG key, and attach it
to your GitHub account.
See the [git tools](https://git-scm.com/book/en/v2/Git-Tools-Signing-Your-Work) page
From f8e1ca7a86fadc56d2cbe2424c68b4e0f4268c80 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Mon, 29 Jan 2024 15:53:26 +0900
Subject: [PATCH 016/164] docs: remove "fzaninotto's"
---
user_guide_src/source/testing/fabricator.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/user_guide_src/source/testing/fabricator.rst b/user_guide_src/source/testing/fabricator.rst
index da621c83b233..750c67a2d7df 100644
--- a/user_guide_src/source/testing/fabricator.rst
+++ b/user_guide_src/source/testing/fabricator.rst
@@ -3,7 +3,7 @@ Generating Test Data
####################
Often you will need sample data for your application to run its tests. The ``Fabricator`` class
-uses fzaninotto's `Faker `_ to turn models into generators
+uses `Faker `_ to turn models into generators
of random data. Use fabricators in your seeds or test cases to stage fake data for your unit tests.
.. contents::
From 0e00cacff3cf81a3d00d518631aa952008a6be4b Mon Sep 17 00:00:00 2001
From: kenjis
Date: Mon, 29 Jan 2024 15:53:46 +0900
Subject: [PATCH 017/164] docs: add empty line
---
user_guide_src/source/testing/fabricator.rst | 1 +
1 file changed, 1 insertion(+)
diff --git a/user_guide_src/source/testing/fabricator.rst b/user_guide_src/source/testing/fabricator.rst
index 750c67a2d7df..e2a4e5910ead 100644
--- a/user_guide_src/source/testing/fabricator.rst
+++ b/user_guide_src/source/testing/fabricator.rst
@@ -56,6 +56,7 @@ method where you can define exactly what the faked data should look like:
Notice in this example how the first three values are equivalent to the formatters from before. However for ``avatar``
we have requested an image size other than the default and ``login`` uses a conditional based on app configuration,
neither of which are possible using the ``$formatters`` parameter.
+
You may want to keep your test data separate from your production models, so it is a good practice to define
a child class in your test support folder:
From 9dbbe1840169d0cb89c23749c0a53c5b53643b24 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Mon, 29 Jan 2024 15:54:42 +0900
Subject: [PATCH 018/164] docs: update sample code
---
.../source/testing/fabricator/005.php | 18 ++++++++++--------
.../source/testing/fabricator/006.php | 3 ++-
.../source/testing/fabricator/008.php | 3 ++-
.../source/testing/fabricator/021.php | 7 +++++--
4 files changed, 19 insertions(+), 12 deletions(-)
diff --git a/user_guide_src/source/testing/fabricator/005.php b/user_guide_src/source/testing/fabricator/005.php
index c61fa527125e..1c233d220b9e 100644
--- a/user_guide_src/source/testing/fabricator/005.php
+++ b/user_guide_src/source/testing/fabricator/005.php
@@ -2,6 +2,8 @@
namespace App\Models;
+use Generator;
+
class UserModel
{
// ...
@@ -9,10 +11,10 @@ class UserModel
public function fake(Generator &$faker)
{
return [
- 'first' => $faker->firstName,
- 'email' => $faker->email,
- 'phone' => $faker->phoneNumber,
- 'avatar' => Faker\Provider\Image::imageUrl(800, 400),
+ 'first' => $faker->firstName(),
+ 'email' => $faker->email(),
+ 'phone' => $faker->phoneNumber(),
+ 'avatar' => \Faker\Provider\Image::imageUrl(800, 400),
'login' => config('Auth')->allowRemembering ? date('Y-m-d') : null,
];
@@ -20,10 +22,10 @@ public function fake(Generator &$faker)
* Or you can return a return type object.
return new User([
- 'first' => $faker->firstName,
- 'email' => $faker->email,
- 'phone' => $faker->phoneNumber,
- 'avatar' => Faker\Provider\Image::imageUrl(800, 400),
+ 'first' => $faker->firstName(),
+ 'email' => $faker->email(),
+ 'phone' => $faker->phoneNumber(),
+ 'avatar' => \Faker\Provider\Image::imageUrl(800, 400),
'login' => config('Auth')->allowRemembering ? date('Y-m-d') : null,
]);
diff --git a/user_guide_src/source/testing/fabricator/006.php b/user_guide_src/source/testing/fabricator/006.php
index 56f34781622c..4cbe439a19a3 100644
--- a/user_guide_src/source/testing/fabricator/006.php
+++ b/user_guide_src/source/testing/fabricator/006.php
@@ -3,10 +3,11 @@
namespace Tests\Support\Models;
use App\Models\UserModel;
+use Faker\Generator;
class UserFabricator extends UserModel
{
- public function fake(&$faker)
+ public function fake(Generator &$faker)
{
// ...
}
diff --git a/user_guide_src/source/testing/fabricator/008.php b/user_guide_src/source/testing/fabricator/008.php
index 1a0d56cf95e2..e39dbe5208cb 100644
--- a/user_guide_src/source/testing/fabricator/008.php
+++ b/user_guide_src/source/testing/fabricator/008.php
@@ -1,7 +1,8 @@
make();
print_r($testUser);
diff --git a/user_guide_src/source/testing/fabricator/021.php b/user_guide_src/source/testing/fabricator/021.php
index 236dd553d492..a7afe497f330 100644
--- a/user_guide_src/source/testing/fabricator/021.php
+++ b/user_guide_src/source/testing/fabricator/021.php
@@ -2,6 +2,9 @@
namespace App\Models;
+use CodeIgniter\Test\Fabricator;
+use Generator;
+
class UserModel
{
protected $table = 'users';
@@ -9,8 +12,8 @@ class UserModel
public function fake(Generator &$faker)
{
return [
- 'first' => $faker->firstName,
- 'email' => $faker->email,
+ 'first' => $faker->firstName(),
+ 'email' => $faker->email(),
'group_id' => mt_rand(1, Fabricator::getCount('groups')),
];
}
From c4b1349b6ed1266ec0302c1567c005e7ad85c15d Mon Sep 17 00:00:00 2001
From: kenjis
Date: Mon, 29 Jan 2024 16:27:16 +0900
Subject: [PATCH 019/164] docs: add how to update PHPStan baseline
---
contributing/pull_request.md | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/contributing/pull_request.md b/contributing/pull_request.md
index 0a863fd39746..c2b71ecf54c9 100644
--- a/contributing/pull_request.md
+++ b/contributing/pull_request.md
@@ -210,12 +210,28 @@ These tools have already been integrated into our CI/CD workflow to minimize una
are expected that their code will pass these two. In your local machine, you can manually run these tools
so that you can fix whatever errors that pop up with your submission.
+#### PHPStan
+
PHPStan is expected to scan the entire framework by running this command in your terminal:
```console
vendor/bin/phpstan analyse
```
+See also:
+- [PHPDocs Basics](https://phpstan.org/writing-php-code/phpdocs-basics)
+- [PHPDoc Types](https://phpstan.org/writing-php-code/phpdoc-types)
+
+If PHPStan errors cannot be resolved by any means, or if the PHPStan error is
+false positive and should be ignored, the baseline can be updated with the following
+command:
+
+```console
+vendor/bin/phpstan analyze --generate-baseline phpstan-baseline.php
+```
+
+#### Rector
+
Rector, on the other hand, can be run on the specific files you modified or added:
```console
From c26775ba6ed0c4c6a0ab6b6e2bd0c48fb55cd399 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Mon, 29 Jan 2024 16:27:36 +0900
Subject: [PATCH 020/164] docs: add `,`
---
contributing/pull_request.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/contributing/pull_request.md b/contributing/pull_request.md
index c2b71ecf54c9..8723bcc5479d 100644
--- a/contributing/pull_request.md
+++ b/contributing/pull_request.md
@@ -79,7 +79,7 @@ and the [PHPUnit website](https://phpunit.de/) for more information.
Source code should be commented using PHPDoc comment blocks. This means
implementation comments to explain potentially confusing sections of
code, and documentation comments before each public or protected
-class/interface/trait, method and variable.
+class/interface/trait, method, and variable.
Do not add PHPDoc comments that are superficial, duplicated, or stating the obvious.
From 589ad8687465e0bc3c741292083d661e68477aa0 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Mon, 29 Jan 2024 16:27:54 +0900
Subject: [PATCH 021/164] docs: add PHPDoc references
---
contributing/pull_request.md | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/contributing/pull_request.md b/contributing/pull_request.md
index 8723bcc5479d..f0950a408283 100644
--- a/contributing/pull_request.md
+++ b/contributing/pull_request.md
@@ -83,8 +83,11 @@ class/interface/trait, method, and variable.
Do not add PHPDoc comments that are superficial, duplicated, or stating the obvious.
-See the [phpDocumentor website](https://phpdoc.org/) for more
-information.
+See the following for more information.
+
+- [PHPDoc reference](https://docs.phpdoc.org/3.0/guide/references/phpdoc/index.html#phpdoc-reference)
+- [PHPDocs Basics](https://phpstan.org/writing-php-code/phpdocs-basics)
+- [PHPDoc Types](https://phpstan.org/writing-php-code/phpdoc-types)
#### Code Comments
From 11f792e0981be17fa8ee86858421c6be4601bb6e Mon Sep 17 00:00:00 2001
From: "John Paul E. Balandan, CPA"
Date: Mon, 29 Jan 2024 23:27:02 +0800
Subject: [PATCH 022/164] docs: fix phpstan errors on TestLogger
---
phpstan-baseline.php | 15 ---------------
system/Test/TestLogger.php | 7 ++++++-
2 files changed, 6 insertions(+), 16 deletions(-)
diff --git a/phpstan-baseline.php b/phpstan-baseline.php
index 22aae16b046e..47f2cce686b4 100644
--- a/phpstan-baseline.php
+++ b/phpstan-baseline.php
@@ -3491,21 +3491,6 @@
'count' => 1,
'path' => __DIR__ . '/system/Test/PhpStreamWrapper.php',
];
-$ignoreErrors[] = [
- 'message' => '#^Method CodeIgniter\\\\Test\\\\TestLogger\\:\\:cleanup\\(\\) has no return type specified\\.$#',
- 'count' => 1,
- 'path' => __DIR__ . '/system/Test/TestLogger.php',
-];
-$ignoreErrors[] = [
- 'message' => '#^Parameter \\#1 \\$level \\(string\\) of method CodeIgniter\\\\Test\\\\TestLogger\\:\\:log\\(\\) should be contravariant with parameter \\$level \\(mixed\\) of method Psr\\\\Log\\\\LoggerInterface\\:\\:log\\(\\)$#',
- 'count' => 1,
- 'path' => __DIR__ . '/system/Test/TestLogger.php',
-];
-$ignoreErrors[] = [
- 'message' => '#^Property CodeIgniter\\\\Test\\\\TestLogger\\:\\:\\$op_logs has no type specified\\.$#',
- 'count' => 1,
- 'path' => __DIR__ . '/system/Test/TestLogger.php',
-];
$ignoreErrors[] = [
'message' => '#^Method CodeIgniter\\\\Test\\\\TestResponse\\:\\:__call\\(\\) should return mixed but return statement is missing\\.$#',
'count' => 1,
diff --git a/system/Test/TestLogger.php b/system/Test/TestLogger.php
index 240f5c6d95b5..fa2f35683ecd 100644
--- a/system/Test/TestLogger.php
+++ b/system/Test/TestLogger.php
@@ -18,13 +18,16 @@
*/
class TestLogger extends Logger
{
+ /**
+ * @var list
+ */
protected static $op_logs = [];
/**
* The log method is overridden so that we can store log history during
* the tests to allow us to check ->assertLogged() methods.
*
- * @param string $level
+ * @param mixed $level
* @param string $message
*/
public function log($level, $message, array $context = []): bool
@@ -92,6 +95,8 @@ public static function didLog(string $level, $message, bool $useExactComparison
*
* @param string $file
*
+ * @return string
+ *
* @deprecated No longer needed as underlying protected method is also deprecated.
*/
public function cleanup($file)
From 0f5da08c17ac82bb4ce1420ed9cc91c9810c5b7f Mon Sep 17 00:00:00 2001
From: kenjis
Date: Mon, 29 Jan 2024 10:07:58 +0900
Subject: [PATCH 023/164] docs: use GitHub markdown Note
---
contributing/styleguide.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/contributing/styleguide.md b/contributing/styleguide.md
index 1b8b499048a2..71c62bde576d 100644
--- a/contributing/styleguide.md
+++ b/contributing/styleguide.md
@@ -3,7 +3,7 @@
This document declares a set of coding conventions and rules to be followed when contributing PHP code
to the CodeIgniter project.
-**Note:**
+> [!NOTE]
> While we would recommend it, there's no requirement that you follow these conventions and rules in your
own projects. Usage is discretionary within your projects but strictly enforceable within the framework.
From aa47487d12152ceff920b1c0d495befe16f0f0cc Mon Sep 17 00:00:00 2001
From: kenjis
Date: Mon, 29 Jan 2024 10:09:49 +0900
Subject: [PATCH 024/164] doc: improve description style and add link to forum
---
contributing/pull_request.md | 26 ++++++++++++++++----------
1 file changed, 16 insertions(+), 10 deletions(-)
diff --git a/contributing/pull_request.md b/contributing/pull_request.md
index f0950a408283..569122fb1485 100644
--- a/contributing/pull_request.md
+++ b/contributing/pull_request.md
@@ -2,17 +2,23 @@
## Contributions
-We expect all contributions to conform to our
-[style guide](https://github.com/codeigniter4/CodeIgniter4/blob/develop/contributing/styleguide.md),
-be commented (inside the PHP source files), be documented (in the
-[user guide](https://codeigniter4.github.io/userguide/)), and unit tested (in
-the [test folder](https://github.com/codeigniter4/CodeIgniter4/tree/develop/tests)).
-
-Note, we expect all code changes or bug-fixes to be accompanied by one or more tests added to our test suite
-to prove the code works. If pull requests are not accompanied by relevant tests, they will likely be closed.
+We expect all contributions to
+- conform to our [style guide](./styleguide.md),
+- be commented (inside the PHP source files),
+- be documented (in the [user guide](https://codeigniter4.github.io/userguide/)),
+- and unit tested (in the [test folder](https://github.com/codeigniter4/CodeIgniter4/tree/develop/tests)).
+
+> [!NOTE]
+> We expect all code changes or bug-fixes to be accompanied by one or more tests
+> added to our test suite to prove the code works.
+
+If pull requests are not accompanied by relevant tests, they will likely be closed.
Since we are a team of volunteers, we don't have any more time to work on the framework than you do. Please
-make it as painless for your contributions to be included as possible. If you need help with getting tests
-running on your local machines, ask for help on the forums. We would be happy to help out.
+make it as painless for your contributions to be included as possible.
+
+If you need help with getting tests running on your local machines, ask for help
+on the [forum](https://forum.codeigniter.com/forumdisplay.php?fid=27). We would
+be happy to help out.
The [Open Source Guide](https://opensource.guide/) is a good first read for those new to contributing to open source!
From 40b7b73793754a9be27ac12976277d2eddbe6d77 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Mon, 29 Jan 2024 10:10:33 +0900
Subject: [PATCH 025/164] docs: remove link that don't make sense
---
contributing/pull_request.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/contributing/pull_request.md b/contributing/pull_request.md
index 569122fb1485..5a7ad10e32a8 100644
--- a/contributing/pull_request.md
+++ b/contributing/pull_request.md
@@ -113,7 +113,7 @@ New classes, methods, parameters, changing default values, changing behavior etc
are all changes that require a change to documentation.
Also, the [Changelog](https://codeigniter4.github.io/CodeIgniter4/changelogs/index.html) must be updated for every change,
-and [PHPDoc](https://github.com/codeigniter4/CodeIgniter4/blob/develop/phpdoc.dist.xml) blocks must be maintained.
+and PHPDoc blocks must be maintained.
See [Writing CodeIgniter Documentation](./documentation.rst).
From 9805314cb83bf2bfdc5b6c4219dfbb231d269e92 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Mon, 29 Jan 2024 10:11:17 +0900
Subject: [PATCH 026/164] docs: add links to user guide directories
---
contributing/pull_request.md | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/contributing/pull_request.md b/contributing/pull_request.md
index 5a7ad10e32a8..5f27415b46ec 100644
--- a/contributing/pull_request.md
+++ b/contributing/pull_request.md
@@ -119,8 +119,10 @@ See [Writing CodeIgniter Documentation](./documentation.rst).
#### Changelog
-The [Changelog](https://codeigniter4.github.io/CodeIgniter4/changelogs/index.html), in the user guide, needs to be kept up-to-date. Not
-all changes will need an entry in it, but the following items should.
+The [Changelog](https://codeigniter4.github.io/CodeIgniter4/changelogs/index.html)
+in the [user guide](https://github.com/codeigniter4/CodeIgniter4/tree/develop/user_guide_src/source/changelogs)
+needs to be kept up-to-date. Not all changes will need an entry in it, but the
+following items should.
- all breaking changes (BCs)
- all enhancements (new features, new classes, new APIs)
@@ -133,7 +135,8 @@ all changes will need an entry in it, but the following items should.
If your PR requires users to do something when they upgrade CodeIgniter, or
changes the Config values,
the [Upgrading Guide](https://codeigniter4.github.io/CodeIgniter4/installation/upgrading.html)
-is also needed.
+in the [installation](https://github.com/codeigniter4/CodeIgniter4/tree/develop/user_guide_src/source/installation)
+folder is also needed.
- Add an instruction what to do when upgrading.
- If you add new properties or changes default values in Config files, add the
From cbbee76b3164ce0822f99bc3b76e90e33900c1d2 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Mon, 29 Jan 2024 10:11:34 +0900
Subject: [PATCH 027/164] docs: add message changes in Changelog
---
contributing/pull_request.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/contributing/pull_request.md b/contributing/pull_request.md
index 5f27415b46ec..5eb373c4e760 100644
--- a/contributing/pull_request.md
+++ b/contributing/pull_request.md
@@ -126,6 +126,7 @@ following items should.
- all breaking changes (BCs)
- all enhancements (new features, new classes, new APIs)
+- message changes
- other behavior changes
- deprecations
- major bug fixes
From 35a1dd8ca79348d03a508bdf245bfa94c2e06f06 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Mon, 29 Jan 2024 10:19:02 +0900
Subject: [PATCH 028/164] docs: update example branch to 4.5
---
contributing/pull_request.md | 4 ++--
contributing/workflow.md | 28 ++++++++++++++--------------
2 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/contributing/pull_request.md b/contributing/pull_request.md
index 5eb373c4e760..665b8c2ce1a3 100644
--- a/contributing/pull_request.md
+++ b/contributing/pull_request.md
@@ -186,7 +186,7 @@ working on your contribution.
All bug fixes should be sent to the __"develop"__ branch, this is where the next bug fix version will be developed.
-PRs with any enhancement should be sent to next minor version branch, e.g. __"4.3"__
+PRs with any enhancement should be sent to next minor version branch, e.g. __"4.5"__
The __"master"__ branch will always contain the latest stable version and is kept clean so a "hotfix" (e.g. an
emergency security patch) can be applied to the "master" branch to create a new version, without worrying
@@ -276,7 +276,7 @@ The best way to contribute is to fork the CodeIgniter4 repository, and "clone" t
- If your PR is for bug fixes:
- `> git switch develop`
- `> git switch -c `
- - If your PR has any enhancement, create new branch from next minor version branch, e.g. __"4.3"__:
+ - If your PR has any enhancement, create new branch from next minor version branch, e.g. __"4.5"__:
- `> git switch `
- `> git switch -c `
7. Fix existing bugs on the [Issue tracker](https://github.com/codeigniter4/CodeIgniter4/issues) after confirming that no one else is working on them.
diff --git a/contributing/workflow.md b/contributing/workflow.md
index d91b450499cd..2cba1db37daf 100644
--- a/contributing/workflow.md
+++ b/contributing/workflow.md
@@ -17,7 +17,7 @@ values for when you try these:
## Branching
- All bug fix PRs should be sent to the __"develop"__ branch, this is where the next bug fix version will be developed.
-- PRs with any enhancement should be sent to next minor version branch, e.g. __"4.3"__
+- PRs with any enhancement should be sent to next minor version branch, e.g. __"4.5"__
The "master" branch will always contain the latest stable
version and is kept clean so a "hotfix" (e.g: an emergency security
@@ -112,7 +112,7 @@ This local branch should be named appropriately, for instance
is optional, and implies a sort of namespacing if used.
- All bug fix PRs should be sent to the __"develop"__ branch, this is where the next bug fix version will be developed.
-- PRs with any enhancement should be sent to next minor version branch, e.g. __"4.3"__
+- PRs with any enhancement should be sent to next minor version branch, e.g. __"4.5"__
For instance, if you send a PR to __"develop"__ branch, make sure you are in the *develop* branch, and create a
new bugfix branch, based on *develop*, for a new feature you are
@@ -124,10 +124,10 @@ creating:
```
If you send a PR with an enhancement, make sure you are in the *next minor version* branch,
-and create a new feature branch, based on, e.g., *4.3*, for a new feature you are creating:
+and create a new feature branch, based on, e.g., __"4.5"__, for a new feature you are creating:
```console
-> git switch 4.3
+> git switch 4.5
> git switch -c new/mind-reader
```
@@ -267,7 +267,7 @@ On GitHub, you propose your changes one feature branch at a time, by
switching to the branch you wish to contribute, and then clicking on
"New pull request".
-Make sure the pull request is for the shared __"develop"__ or next minor version branch, e.g. __"4.3"__, or it
+Make sure the pull request is for the shared __"develop"__ or next minor version branch, e.g. __"4.5"__, or it
may be rejected.
Make sure that the PR title is helpful for the maintainers and other
@@ -308,7 +308,7 @@ And if your PRs have the breaking changes, label the following label:
If you are asked for changes in the review, commit the fix in your branch and push it to GitHub again.
-If the __"develop"__ or next minor version branch, e.g. __"4.3"__, progresses and conflicts arise that prevent merging, or if you are asked to *rebase*,
+If the __"develop"__ or next minor version branch, e.g. __"4.5"__, progresses and conflicts arise that prevent merging, or if you are asked to *rebase*,
do the following:
Synchronize your repository:
@@ -347,7 +347,7 @@ And finally push your local branch to your GitHub repository:
If you have sent a PR to the wrong branch, you need to create a new PR branch.
-When you have the PR branch `feat-abc` and you should have sent the PR to `4.3`,
+When you have the PR branch `feat-abc` and you should have sent the PR to __"4.5"__,
but you created the PR branch from `develop` and sent a PR.
Copy the IDs of any commits you made that you want to keep:
@@ -356,13 +356,13 @@ Copy the IDs of any commits you made that you want to keep:
> git log
```
-Update your `4.3` branch:
+Update your __"4.5"__ branch:
```console
> git fetch upstream
-> git switch 4.3
-> git merge upstream/4.3
-> git push origin 4.3
+> git switch 4.5
+> git merge upstream/4.5
+> git push origin 4.5
```
(Optional) Create a new branch as a backup, just in case:
@@ -371,10 +371,10 @@ Update your `4.3` branch:
> git branch feat-abc.bk feat-abc
```
-Rebase your PR branch from `develop` onto `4.3`:
+Rebase your PR branch from `develop` onto __"4.5"__:
```console
-> git rebase --onto 4.3 develop feat-abc
+> git rebase --onto 4.5 develop feat-abc
```
Force push.
@@ -383,7 +383,7 @@ Force push.
> git push --force-with-lease origin feat-abc
```
-On the GitHub PR page, change the base branch to the correct branch `4.3`.
+On the GitHub PR page, change the base branch to the correct branch __"4.5"__.
## Cleanup
From 4dbc4d04c77f195d521eb0e03073e07c895fbf8e Mon Sep 17 00:00:00 2001
From: kenjis
Date: Mon, 29 Jan 2024 10:35:50 +0900
Subject: [PATCH 029/164] docs: break long lines
---
contributing/pull_request.md | 114 ++++++++++++++++++++++-------------
contributing/workflow.md | 49 ++++++++-------
2 files changed, 101 insertions(+), 62 deletions(-)
diff --git a/contributing/pull_request.md b/contributing/pull_request.md
index 665b8c2ce1a3..d803fd48e6bf 100644
--- a/contributing/pull_request.md
+++ b/contributing/pull_request.md
@@ -13,14 +13,16 @@ We expect all contributions to
> added to our test suite to prove the code works.
If pull requests are not accompanied by relevant tests, they will likely be closed.
-Since we are a team of volunteers, we don't have any more time to work on the framework than you do. Please
-make it as painless for your contributions to be included as possible.
+Since we are a team of volunteers, we don't have any more time to work on the
+framework than you do. Please make it as painless for your contributions to be
+included as possible.
If you need help with getting tests running on your local machines, ask for help
on the [forum](https://forum.codeigniter.com/forumdisplay.php?fid=27). We would
be happy to help out.
-The [Open Source Guide](https://opensource.guide/) is a good first read for those new to contributing to open source!
+The [Open Source Guide](https://opensource.guide/) is a good first read for those
+new to contributing to open source!
## CodeIgniter Internals Overview
@@ -35,7 +37,8 @@ Your Pull Requests (PRs) need to meet our guidelines.
If your Pull Requests fail to pass these guidelines, they will be declined,
and you will need to re-submit when you've made the changes.
-This might sound a bit tough, but it is required for us to maintain the quality of the codebase.
+This might sound a bit tough, but it is required for us to maintain the quality
+of the codebase.
### PHP Style
@@ -44,10 +47,11 @@ This might sound a bit tough, but it is required for us to maintain the quality
All code must conform to our [Style Guide](./styleguide.md), which is
based on PSR-12.
-This makes certain that all submitted code is of the same format
-as the existing code and ensures that the codebase will be as readable as possible.
+This makes certain that all submitted code is of the same format as the existing
+code and ensures that the codebase will be as readable as possible.
-You can fix most of the coding style violations by running this command in your terminal:
+You can fix most of the coding style violations by running this command in your
+terminal:
```console
composer cs-fix
@@ -61,7 +65,8 @@ composer cs
### Unit Testing
-If you are not familiar with Unit Testing, see [the forum thread](https://forum.codeigniter.com/showthread.php?tid=81830).
+If you are not familiar with Unit Testing, see
+[the forum thread](https://forum.codeigniter.com/showthread.php?tid=81830).
Unit testing is expected for all CodeIgniter components. We use PHPUnit,
and run unit tests using GitHub Actions for each PR submitted or changed.
@@ -112,8 +117,8 @@ then you will need to add to the documentation.
New classes, methods, parameters, changing default values, changing behavior etc.
are all changes that require a change to documentation.
-Also, the [Changelog](https://codeigniter4.github.io/CodeIgniter4/changelogs/index.html) must be updated for every change,
-and PHPDoc blocks must be maintained.
+Also, the [Changelog](https://codeigniter4.github.io/CodeIgniter4/changelogs/index.html)
+must be updated for every change, and PHPDoc blocks must be maintained.
See [Writing CodeIgniter Documentation](./documentation.rst).
@@ -141,7 +146,7 @@ folder is also needed.
- Add an instruction what to do when upgrading.
- If you add new properties or changes default values in Config files, add the
-changes in *"Project Files > Content Changes > Config"*.
+ changes in *"Project Files > Content Changes > Config"*.
### CSS
@@ -164,12 +169,19 @@ break with earlier versions of the framework.
#### Breaking Changes
-In general, any change that would disrupt existing uses of the framework is considered a "Breaking Change" (BC) and will not be favorably considered. A few specific examples to pay attention to:
+In general, any change that would disrupt existing uses of the framework is
+considered a "Breaking Change" (BC) and will not be favorably considered. A few
+specific examples to pay attention to:
-1. New classes/properties/constants in `system` are acceptable, but anything in the `app` directory that will be used in `system` should be backwards-compatible.
-2. Any changes to non-private methods must be backwards-compatible with the original definition.
-3. Deleting non-private properties or methods without prior deprecation notices is frowned upon and will likely be closed.
-4. Deleting or renaming public classes and interfaces, as well as those not marked as `@internal`, without prior deprecation notices or not providing fallback solutions will also not be favorably considered.
+1. New classes/properties/constants in `system` are acceptable, but anything in
+ the `app` directory that will be used in `system` should be backwards-compatible.
+2. Any changes to non-private methods must be backwards-compatible with the original
+ definition.
+3. Deleting non-private properties or methods without prior deprecation notices
+ is frowned upon and will likely be closed.
+4. Deleting or renaming public classes and interfaces, as well as those not marked
+ as `@internal`, without prior deprecation notices or not providing fallback
+ solutions will also not be favorably considered.
### Mergeability
@@ -184,30 +196,35 @@ working on your contribution.
### Branching
-All bug fixes should be sent to the __"develop"__ branch, this is where the next bug fix version will be developed.
+All bug fixes should be sent to the __"develop"__ branch, this is where the next
+bug fix version will be developed.
PRs with any enhancement should be sent to next minor version branch, e.g. __"4.5"__
-The __"master"__ branch will always contain the latest stable version and is kept clean so a "hotfix" (e.g. an
-emergency security patch) can be applied to the "master" branch to create a new version, without worrying
-about other features holding it up. Any sent to the "master" branch will be closed automatically.
+The __"master"__ branch will always contain the latest stable version and is kept
+clean so a "hotfix" (e.g. an emergency security patch) can be applied to the
+"master" branch to create a new version, without worrying about other features
+holding it up. Any sent to the "master" branch will be closed automatically.
If you have multiple changes to submit,
please place all changes into their own branch on your fork.
-**One thing at a time:** A pull request should only contain one change. That does not mean only one commit,
-but one change - however many commits it took. The reason for this is that if you change X and Y,
-but send a pull request for both at the same time, we might really want X but disagree with Y,
-meaning we cannot merge the request. Using the Git-Flow branching model you can create new
-branches for both of these features and send two requests.
+**One thing at a time:** A pull request should only contain one change. That does
+not mean only one commit, but one change - however many commits it took. The reason
+for this is that if you change X and Y, but send a pull request for both at the
+same time, we might really want X but disagree with Y, meaning we cannot merge
+the request. Using the Git-Flow branching model you can create new branches for
+both of these features and send two requests.
-A reminder: **please use separate branches for each of your PRs** - it will make it easier for you to keep
-changes separate from each other and from whatever else you are doing with your repository!
+A reminder: **please use separate branches for each of your PRs** - it will make
+it easier for you to keep changes separate from each other and from whatever else
+you are doing with your repository!
### Signing
You must [GPG-sign](./signing.md) your work, certifying that you either wrote the work or
-otherwise have the right to pass it on to an open-source project. See [Developer's Certificate of Origin](./DCO.md).
+otherwise have the right to pass it on to an open-source project. See
+[Developer's Certificate of Origin](./DCO.md).
This is *not* just a "signed-off-by" commit, but instead, a digitally signed one.
@@ -215,17 +232,20 @@ See [Contribution signing](./signing.md) for details.
### Static Analysis on PHP code
-We cannot, at all times, guarantee that all PHP code submitted on pull requests to be working well without
-actually running the code. For this reason, we make use of two static analysis tools, [PHPStan][1]
-and [Rector][2] to do the analysis for us.
+We cannot, at all times, guarantee that all PHP code submitted on pull requests
+to be working well without actually running the code. For this reason, we make
+use of two static analysis tools, [PHPStan][1] and [Rector][2] to do the analysis
+for us.
-These tools have already been integrated into our CI/CD workflow to minimize unannounced bugs. Pull requests
-are expected that their code will pass these two. In your local machine, you can manually run these tools
-so that you can fix whatever errors that pop up with your submission.
+These tools have already been integrated into our CI/CD workflow to minimize
+unannounced bugs. Pull requests are expected that their code will pass these two.
+In your local machine, you can manually run these tools so that you can fix
+whatever errors that pop up with your submission.
#### PHPStan
-PHPStan is expected to scan the entire framework by running this command in your terminal:
+PHPStan is expected to scan the entire framework by running this command in your
+terminal:
```console
vendor/bin/phpstan analyse
@@ -262,7 +282,10 @@ vendor/bin/rector process path/to/file
## How-to Guide
-The best way to contribute is to fork the CodeIgniter4 repository, and "clone" that to your development area. That sounds like some jargon, but "forking" on GitHub means "making a copy of that repo to your account" and "cloning" means "copying that code to your environment so you can work on it".
+The best way to contribute is to fork the CodeIgniter4 repository, and "clone"
+that to your development area. That sounds like some jargon, but "forking" on
+GitHub means "making a copy of that repo to your account" and "cloning" means
+"copying that code to your environment so you can work on it".
1. Set up Git ([Windows](https://git-scm.com/download/win), [Mac](https://git-scm.com/download/mac), & [Linux](https://git-scm.com/download/linux)).
2. Go to the [CodeIgniter4 repository](https://github.com/codeigniter4/CodeIgniter4).
@@ -279,13 +302,18 @@ The best way to contribute is to fork the CodeIgniter4 repository, and "clone" t
- If your PR has any enhancement, create new branch from next minor version branch, e.g. __"4.5"__:
- `> git switch `
- `> git switch -c `
-7. Fix existing bugs on the [Issue tracker](https://github.com/codeigniter4/CodeIgniter4/issues) after confirming that no one else is working on them.
+7. Fix existing bugs on the [Issue tracker](https://github.com/codeigniter4/CodeIgniter4/issues) after confirming that no one
+ else is working on them.
8. [Commit](https://help.github.com/en/desktop/contributing-to-projects/committing-and-reviewing-changes-to-your-project) the changed files in your contribution branch.
- `> git commit`
- - Commit messages are expected to be descriptive of why and what you changed specifically. Commit messages like "Fixes #1234" would be asked by the reviewer to be revised. [Atomic commit](https://en.wikipedia.org/wiki/Atomic_commit#Atomic_commit_convention) is recommended. See [Contribution Workflow](./workflow.md#commit-messages) for details.
+ - Commit messages are expected to be descriptive of why and what you changed
+ specifically. Commit messages like "Fixes #1234" would be asked by the reviewer
+ to be revised. [Atomic commit](https://en.wikipedia.org/wiki/Atomic_commit#Atomic_commit_convention) is recommended. See
+ [Contribution Workflow](./workflow.md#commit-messages) for details.
9. If you have touched PHP code, run static analysis.
- `> composer analyze`
-10. Run unit tests on the specific file you modified. If there are no existing tests yet, please create one.
+10. Run unit tests on the specific file you modified. If there are no existing
+ tests yet, please create one.
- `> vendor/bin/phpunit tests/system/path/to/file/you/modified`
- Make sure the tests pass to have a higher chance of merging.
11. [Push](https://docs.github.com/en/github/using-git/pushing-commits-to-a-remote-repository) your contribution branch to your fork.
@@ -295,9 +323,13 @@ The best way to contribute is to fork the CodeIgniter4 repository, and "clone" t
See [Contribution workflow](./workflow.md) for Git workflow details.
-The codebase maintainers will now be alerted to the submission and someone from the team will respond. If your change fails to meet the guidelines, it will be rejected or feedback will be provided to help you improve it.
+The codebase maintainers will now be alerted to the submission and someone from
+the team will respond. If your change fails to meet the guidelines, it will be
+rejected or feedback will be provided to help you improve it.
-Once the maintainer handling your pull request is satisfied with it, they will approve the pull request and merge it into the "develop" branch. Your patch will now be part of the next release!
+Once the maintainer handling your pull request is satisfied with it, they will
+approve the pull request and merge it into the "develop" branch. Your patch will
+now be part of the next release!
## Translating System Messages
diff --git a/contributing/workflow.md b/contributing/workflow.md
index 2cba1db37daf..eb8024053754 100644
--- a/contributing/workflow.md
+++ b/contributing/workflow.md
@@ -16,7 +16,8 @@ values for when you try these:
## Branching
-- All bug fix PRs should be sent to the __"develop"__ branch, this is where the next bug fix version will be developed.
+- All bug fix PRs should be sent to the __"develop"__ branch, this is where the
+ next bug fix version will be developed.
- PRs with any enhancement should be sent to next minor version branch, e.g. __"4.5"__
The "master" branch will always contain the latest stable
@@ -111,20 +112,22 @@ This local branch should be named appropriately, for instance
"fix/problem123" or "new/mind-reader". The slashes in these branch names
is optional, and implies a sort of namespacing if used.
-- All bug fix PRs should be sent to the __"develop"__ branch, this is where the next bug fix version will be developed.
+- All bug fix PRs should be sent to the __"develop"__ branch, this is where the
+ next bug fix version will be developed.
- PRs with any enhancement should be sent to next minor version branch, e.g. __"4.5"__
-For instance, if you send a PR to __"develop"__ branch, make sure you are in the *develop* branch, and create a
-new bugfix branch, based on *develop*, for a new feature you are
-creating:
+For instance, if you send a PR to __"develop"__ branch, make sure you are in the
+*develop* branch, and create a new bugfix branch, based on *develop*, for a new
+feature you are creating:
```console
> git switch develop
> git switch -c fix/problem123
```
-If you send a PR with an enhancement, make sure you are in the *next minor version* branch,
-and create a new feature branch, based on, e.g., __"4.5"__, for a new feature you are creating:
+If you send a PR with an enhancement, make sure you are in the *next minor version*
+branch, and create a new feature branch, based on, e.g., __"4.5"__, for a new
+feature you are creating:
```console
> git switch 4.5
@@ -151,14 +154,14 @@ There are some references for writing good commit messages:
If there are intermediate commits that are not meaningful to the overall PR,
such as "Fix error on style guide", "Fix phpstan error", "Fix mistake in code",
-and other related commits, you can squash your commits so that we can have a clean commit history.
-But it is not a must.
+and other related commits, you can squash your commits so that we can have a
+clean commit history. But it is not a must.
### Commit Messages
-Commit messages are important. They communicate the intent of a specific change, concisely.
-They make it easier to review code, and to find out why a change was made
-if the code history is examined later.
+Commit messages are important. They communicate the intent of a specific change,
+concisely. They make it easier to review code, and to find out why a change was
+made if the code history is examined later.
The audience for your commit messages will be the codebase maintainers,
any code reviewers, and debuggers trying to figure out when a bug might
@@ -166,8 +169,9 @@ have been introduced.
Make your commit messages meaningful.
-Commit messages are expected to be descriptive of **why** and what you changed specifically.
-Commit messages like "Fixes #1234" would be asked by the reviewer to be revised.
+Commit messages are expected to be descriptive of **why** and what you changed
+specifically. Commit messages like "Fixes #1234" would be asked by the reviewer
+to be revised.
You can have as many commits in a branch as you need to "get it right".
For instance, to commit your work from a debugging session:
@@ -185,7 +189,8 @@ Just make sure that your commits in a feature branch are all related.
### GPG-Signing Old Commits
-Any developer can forget GPG-signing their commits with the option `-S`, like `git commit -S -m 'Signed GPG'`. In such a case, all you need to do is the following:
+Any developer can forget GPG-signing their commits with the option `-S`, like
+`git commit -S -m 'Signed GPG'`. In such a case, all you need to do is the following:
Latest commit only:
```console
@@ -267,16 +272,16 @@ On GitHub, you propose your changes one feature branch at a time, by
switching to the branch you wish to contribute, and then clicking on
"New pull request".
-Make sure the pull request is for the shared __"develop"__ or next minor version branch, e.g. __"4.5"__, or it
-may be rejected.
+Make sure the pull request is for the shared __"develop"__ or next minor version
+branch, e.g. __"4.5"__, or it may be rejected.
Make sure that the PR title is helpful for the maintainers and other
developers. Add any comments appropriate, for instance asking for
review.
> **Note**
-> If you do not provide a title or description for your PR, the odds of it being summarily rejected
-rise astronomically.
+> If you do not provide a title or description for your PR, the odds of it being
+> summarily rejected rise astronomically.
When your PR is submitted, a continuous integration task will be
triggered, running all the unit tests as well as any other checking we
@@ -306,9 +311,11 @@ And if your PRs have the breaking changes, label the following label:
## Updating Your Branch
-If you are asked for changes in the review, commit the fix in your branch and push it to GitHub again.
+If you are asked for changes in the review, commit the fix in your branch and
+push it to GitHub again.
-If the __"develop"__ or next minor version branch, e.g. __"4.5"__, progresses and conflicts arise that prevent merging, or if you are asked to *rebase*,
+If the __"develop"__ or next minor version branch, e.g. __"4.5"__, progresses
+and conflicts arise that prevent merging, or if you are asked to *rebase*,
do the following:
Synchronize your repository:
From 146927326852ca5441073be78214b5e0f7329b0e Mon Sep 17 00:00:00 2001
From: kenjis
Date: Mon, 29 Jan 2024 10:37:04 +0900
Subject: [PATCH 030/164] docs: use GitHub markdown Note
---
contributing/styleguide.md | 2 +-
contributing/workflow.md | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/contributing/styleguide.md b/contributing/styleguide.md
index 71c62bde576d..95e68bb37ddb 100644
--- a/contributing/styleguide.md
+++ b/contributing/styleguide.md
@@ -200,7 +200,7 @@ conditions MUST always be at the beginning or at the end of the line, not a mix
- The conditional operator, also known simply as the ternary operator, MUST be preceded and followed by at least one space around both the `?` and `:` characters.
- When the middle operand of the conditional operator is omitted, the operator MUST follow the same style rules as other binary comparison operators.
-**Note:**
+> [!NOTE]
> All the preceding rules are quoted from PSR-12. You may visit its website to view the code block samples.
## Custom Conventions
diff --git a/contributing/workflow.md b/contributing/workflow.md
index eb8024053754..da1f53d4743c 100644
--- a/contributing/workflow.md
+++ b/contributing/workflow.md
@@ -240,7 +240,7 @@ are working in.
At some point, you will decide that your feature branch is complete, or
that it could benefit from a review by fellow developers.
-> **Note**
+> [!NOTE]
> Remember to sync your local repo with the shared one before pushing!
It is a lot easier to resolve conflicts at this stage.
@@ -279,7 +279,7 @@ Make sure that the PR title is helpful for the maintainers and other
developers. Add any comments appropriate, for instance asking for
review.
-> **Note**
+> [!NOTE]
> If you do not provide a title or description for your PR, the odds of it being
> summarily rejected rise astronomically.
From c334bac50fa864faf026b3701ee4789856b62be3 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Mon, 29 Jan 2024 10:47:51 +0900
Subject: [PATCH 031/164] docs: change section title
---
contributing/pull_request.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/contributing/pull_request.md b/contributing/pull_request.md
index d803fd48e6bf..d5acb8afb82d 100644
--- a/contributing/pull_request.md
+++ b/contributing/pull_request.md
@@ -104,7 +104,7 @@ See the following for more information.
Do not add comments that are superficial, duplicated, or stating the obvious.
-### Documentation
+### User Guide
The User Guide is an essential component of the CodeIgniter framework.
From 3be1f954fd813fe73895d3bc05d7583e5669c688 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Mon, 29 Jan 2024 10:49:45 +0900
Subject: [PATCH 032/164] docs: use GitHub markdown IMPORTANT
---
contributing/pull_request.md | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/contributing/pull_request.md b/contributing/pull_request.md
index d5acb8afb82d..f0fd6b8df495 100644
--- a/contributing/pull_request.md
+++ b/contributing/pull_request.md
@@ -216,9 +216,10 @@ same time, we might really want X but disagree with Y, meaning we cannot merge
the request. Using the Git-Flow branching model you can create new branches for
both of these features and send two requests.
-A reminder: **please use separate branches for each of your PRs** - it will make
-it easier for you to keep changes separate from each other and from whatever else
-you are doing with your repository!
+> [!IMPORTANT]
+> **Please use separate branches for each of your PRs** - it will make it easier
+> for you to keep changes separate from each other and from whatever else you are
+> doing with your repository!
### Signing
From d117b8a83030aa48710f1f49c7c19e438e669eb0 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Mon, 29 Jan 2024 10:50:29 +0900
Subject: [PATCH 033/164] docs: change NOTE to IMPORTANT
---
contributing/pull_request.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/contributing/pull_request.md b/contributing/pull_request.md
index f0fd6b8df495..38f32d40c1be 100644
--- a/contributing/pull_request.md
+++ b/contributing/pull_request.md
@@ -8,7 +8,7 @@ We expect all contributions to
- be documented (in the [user guide](https://codeigniter4.github.io/userguide/)),
- and unit tested (in the [test folder](https://github.com/codeigniter4/CodeIgniter4/tree/develop/tests)).
-> [!NOTE]
+> [!IMPORTANT]
> We expect all code changes or bug-fixes to be accompanied by one or more tests
> added to our test suite to prove the code works.
From aa6978e886345180cb7219bb505a2bc87637bfc3 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Tue, 30 Jan 2024 12:58:39 +0900
Subject: [PATCH 034/164] fix: change order of properties in stdClass returned
by getFieldData() to the same for all DB drivers
---
system/Database/OCI8/Connection.php | 2 +-
system/Database/Postgre/Connection.php | 2 +-
system/Database/SQLSRV/Connection.php | 6 ++--
system/Database/SQLite3/Connection.php | 2 +-
tests/system/Database/Live/ForgeTest.php | 32 +++++++++----------
.../Database/Live/OCI8/GetFieldDataTest.php | 14 ++++----
user_guide_src/source/database/metadata.rst | 2 +-
7 files changed, 30 insertions(+), 30 deletions(-)
diff --git a/system/Database/OCI8/Connection.php b/system/Database/OCI8/Connection.php
index 58c33536a41c..5d239f171733 100644
--- a/system/Database/OCI8/Connection.php
+++ b/system/Database/OCI8/Connection.php
@@ -315,8 +315,8 @@ protected function _fieldData(string $table): array
$retval[$i]->max_length = $length;
- $retval[$i]->default = $query[$i]->DATA_DEFAULT;
$retval[$i]->nullable = $query[$i]->NULLABLE === 'Y';
+ $retval[$i]->default = $query[$i]->DATA_DEFAULT;
}
return $retval;
diff --git a/system/Database/Postgre/Connection.php b/system/Database/Postgre/Connection.php
index c54209453217..64c24adb0244 100644
--- a/system/Database/Postgre/Connection.php
+++ b/system/Database/Postgre/Connection.php
@@ -318,9 +318,9 @@ protected function _fieldData(string $table): array
$retVal[$i]->name = $query[$i]->column_name;
$retVal[$i]->type = $query[$i]->data_type;
+ $retVal[$i]->max_length = $query[$i]->character_maximum_length > 0 ? $query[$i]->character_maximum_length : $query[$i]->numeric_precision;
$retVal[$i]->nullable = $query[$i]->is_nullable === 'YES';
$retVal[$i]->default = $query[$i]->column_default;
- $retVal[$i]->max_length = $query[$i]->character_maximum_length > 0 ? $query[$i]->character_maximum_length : $query[$i]->numeric_precision;
}
return $retVal;
diff --git a/system/Database/SQLSRV/Connection.php b/system/Database/SQLSRV/Connection.php
index bd9a22e94975..aa45a4ba0a24 100755
--- a/system/Database/SQLSRV/Connection.php
+++ b/system/Database/SQLSRV/Connection.php
@@ -357,15 +357,15 @@ protected function _fieldData(string $table): array
for ($i = 0, $c = count($query); $i < $c; $i++) {
$retVal[$i] = new stdClass();
- $retVal[$i]->name = $query[$i]->COLUMN_NAME;
- $retVal[$i]->type = $query[$i]->DATA_TYPE;
- $retVal[$i]->default = $query[$i]->COLUMN_DEFAULT;
+ $retVal[$i]->name = $query[$i]->COLUMN_NAME;
+ $retVal[$i]->type = $query[$i]->DATA_TYPE;
$retVal[$i]->max_length = $query[$i]->CHARACTER_MAXIMUM_LENGTH > 0
? $query[$i]->CHARACTER_MAXIMUM_LENGTH
: $query[$i]->NUMERIC_PRECISION;
$retVal[$i]->nullable = $query[$i]->IS_NULLABLE !== 'NO';
+ $retVal[$i]->default = $query[$i]->COLUMN_DEFAULT;
}
return $retVal;
diff --git a/system/Database/SQLite3/Connection.php b/system/Database/SQLite3/Connection.php
index b4b3b668f8b6..18760699a391 100644
--- a/system/Database/SQLite3/Connection.php
+++ b/system/Database/SQLite3/Connection.php
@@ -272,12 +272,12 @@ protected function _fieldData(string $table): array
$retVal[$i]->name = $query[$i]->name;
$retVal[$i]->type = $query[$i]->type;
$retVal[$i]->max_length = null;
+ $retVal[$i]->nullable = isset($query[$i]->notnull) && ! (bool) $query[$i]->notnull;
$retVal[$i]->default = $query[$i]->dflt_value;
// "pk" (either zero for columns that are not part of the primary key,
// or the 1-based index of the column within the primary key).
// https://www.sqlite.org/pragma.html#pragma_table_info
$retVal[$i]->primary_key = ($query[$i]->pk === 0) ? 0 : 1;
- $retVal[$i]->nullable = isset($query[$i]->notnull) && ! (bool) $query[$i]->notnull;
}
return $retVal;
diff --git a/tests/system/Database/Live/ForgeTest.php b/tests/system/Database/Live/ForgeTest.php
index f8a695396c9b..f75ed57f4560 100644
--- a/tests/system/Database/Live/ForgeTest.php
+++ b/tests/system/Database/Live/ForgeTest.php
@@ -953,30 +953,30 @@ public function testAddFields(): void
0 => [
'name' => 'id',
'type' => 'integer',
+ 'max_length' => '32',
'nullable' => false,
'default' => "nextval('db_forge_test_fields_id_seq'::regclass)",
- 'max_length' => '32',
],
1 => [
'name' => 'username',
'type' => 'character varying',
+ 'max_length' => '255',
'nullable' => false,
'default' => null,
- 'max_length' => '255',
],
2 => [
'name' => 'name',
'type' => 'character varying',
+ 'max_length' => '255',
'nullable' => true,
'default' => null,
- 'max_length' => '255',
],
3 => [
'name' => 'active',
'type' => 'integer',
+ 'max_length' => '32',
'nullable' => false,
'default' => '0',
- 'max_length' => '32',
],
];
} elseif ($this->db->DBDriver === 'SQLite3') {
@@ -985,33 +985,33 @@ public function testAddFields(): void
'name' => 'id',
'type' => 'INTEGER',
'max_length' => null,
+ 'nullable' => true,
'default' => null,
'primary_key' => 1,
- 'nullable' => true,
],
1 => [
'name' => 'username',
'type' => 'VARCHAR',
'max_length' => null,
+ 'nullable' => false,
'default' => null,
'primary_key' => 0,
- 'nullable' => false,
],
2 => [
'name' => 'name',
'type' => 'VARCHAR',
'max_length' => null,
+ 'nullable' => true,
'default' => null,
'primary_key' => 0,
- 'nullable' => true,
],
3 => [
'name' => 'active',
'type' => 'INTEGER',
'max_length' => null,
+ 'nullable' => false,
'default' => '0',
'primary_key' => 0,
- 'nullable' => false,
],
];
} elseif ($this->db->DBDriver === 'SQLSRV') {
@@ -1019,30 +1019,30 @@ public function testAddFields(): void
0 => [
'name' => 'id',
'type' => 'int',
- 'default' => null,
'max_length' => 10,
'nullable' => false,
+ 'default' => null,
],
1 => [
'name' => 'username',
'type' => 'varchar',
- 'default' => null,
'max_length' => 255,
'nullable' => false,
+ 'default' => null,
],
2 => [
'name' => 'name',
'type' => 'varchar',
- 'default' => null,
'max_length' => 255,
'nullable' => true,
+ 'default' => null,
],
3 => [
'name' => 'active',
'type' => 'int',
- 'default' => '((0))', // Why?
'max_length' => 10,
'nullable' => false,
+ 'default' => '((0))', // Why?
],
];
} elseif ($this->db->DBDriver === 'OCI8') {
@@ -1051,29 +1051,29 @@ public function testAddFields(): void
'name' => 'id',
'type' => 'NUMBER',
'max_length' => '11',
- 'default' => '"ORACLE"."ISEQ$$_80229".nextval', // Sequence id may change
'nullable' => false,
+ 'default' => '"ORACLE"."ISEQ$$_80229".nextval', // Sequence id may change
],
1 => [
'name' => 'username',
'type' => 'VARCHAR2',
'max_length' => '255',
- 'default' => null,
'nullable' => false,
+ 'default' => null,
],
2 => [
'name' => 'name',
'type' => 'VARCHAR2',
'max_length' => '255',
- 'default' => null,
'nullable' => true,
+ 'default' => null,
],
3 => [
'name' => 'active',
'type' => 'NUMBER',
'max_length' => '11',
- 'default' => '0 ', // Why?
'nullable' => false,
+ 'default' => '0 ', // Why?
],
];
diff --git a/tests/system/Database/Live/OCI8/GetFieldDataTest.php b/tests/system/Database/Live/OCI8/GetFieldDataTest.php
index fcb585842a0d..28763a11f3ee 100644
--- a/tests/system/Database/Live/OCI8/GetFieldDataTest.php
+++ b/tests/system/Database/Live/OCI8/GetFieldDataTest.php
@@ -50,57 +50,57 @@ public function testGetFieldData(): void
'name' => 'id',
'type' => 'NUMBER',
'max_length' => '11',
+ 'nullable' => false,
'default' => $idDefault, // The default value is not defined.
// 'primary_key' => 1,
- 'nullable' => false,
],
(object) [
'name' => 'text_not_null',
'type' => 'VARCHAR2',
'max_length' => '64',
+ 'nullable' => false,
'default' => null, // The default value is not defined.
// 'primary_key' => 0,
- 'nullable' => false,
],
(object) [
'name' => 'text_null',
'type' => 'VARCHAR2',
'max_length' => '64',
+ 'nullable' => true,
'default' => null, // The default value is not defined.
// 'primary_key' => 0,
- 'nullable' => true,
],
(object) [
'name' => 'int_default_0',
'type' => 'NUMBER',
'max_length' => '11',
+ 'nullable' => false,
'default' => '0 ', // int 0
// 'primary_key' => 0,
- 'nullable' => false,
],
(object) [
'name' => 'text_default_null',
'type' => 'VARCHAR2',
'max_length' => '64',
+ 'nullable' => true,
'default' => 'NULL ', // NULL value
// 'primary_key' => 0,
- 'nullable' => true,
],
(object) [
'name' => 'text_default_text_null',
'type' => 'VARCHAR2',
'max_length' => '64',
+ 'nullable' => false,
'default' => "'null' ", // string "null"
// 'primary_key' => 0,
- 'nullable' => false,
],
(object) [
'name' => 'text_default_abc',
'type' => 'VARCHAR2',
'max_length' => '64',
+ 'nullable' => false,
'default' => "'abc' ", // string "abc"
// 'primary_key' => 0,
- 'nullable' => false,
],
]), true);
$names = array_column($expected, 'name');
diff --git a/user_guide_src/source/database/metadata.rst b/user_guide_src/source/database/metadata.rst
index 1845a0440b7a..da68a356c9df 100644
--- a/user_guide_src/source/database/metadata.rst
+++ b/user_guide_src/source/database/metadata.rst
@@ -105,9 +105,9 @@ database:
- ``name`` - column name
- ``type`` - the type of the column
- ``max_length`` - maximum length of the column
-- ``primary_key`` - integer ``1`` if the column is a primary key (all integer ``1``, even if there are multiple primary keys), otherwise integer ``0`` (This field is currently only available for ``MySQLi`` and ``SQLite3``)
- ``nullable`` - boolean ``true`` if the column is nullable, otherwise boolean ``false``
- ``default`` - the default value
+- ``primary_key`` - integer ``1`` if the column is a primary key (all integer ``1``, even if there are multiple primary keys), otherwise integer ``0`` (This field is currently only available for ``MySQLi`` and ``SQLite3``)
.. note:: Since v4.4.0, SQLSRV supported ``nullable``.
From dcd94511c4a009f2f2816458f587d29393a44db5 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Tue, 30 Jan 2024 14:28:33 +0900
Subject: [PATCH 035/164] docs: fix Generator -> Faker\Generator
---
user_guide_src/source/testing/fabricator/005.php | 2 +-
user_guide_src/source/testing/fabricator/021.php | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/user_guide_src/source/testing/fabricator/005.php b/user_guide_src/source/testing/fabricator/005.php
index 1c233d220b9e..5a601cebc050 100644
--- a/user_guide_src/source/testing/fabricator/005.php
+++ b/user_guide_src/source/testing/fabricator/005.php
@@ -2,7 +2,7 @@
namespace App\Models;
-use Generator;
+use Faker\Generator;
class UserModel
{
diff --git a/user_guide_src/source/testing/fabricator/021.php b/user_guide_src/source/testing/fabricator/021.php
index a7afe497f330..af6297f53946 100644
--- a/user_guide_src/source/testing/fabricator/021.php
+++ b/user_guide_src/source/testing/fabricator/021.php
@@ -3,7 +3,7 @@
namespace App\Models;
use CodeIgniter\Test\Fabricator;
-use Generator;
+use Faker\Generator;
class UserModel
{
From a567d72cee856dcd57cad042302c9f40fce2ba8d Mon Sep 17 00:00:00 2001
From: kenjis
Date: Fri, 26 Jan 2024 13:18:03 +0900
Subject: [PATCH 036/164] test: add assertions
---
tests/system/Database/Live/ForgeTest.php | 28 ++++++++++++++++++++++--
1 file changed, 26 insertions(+), 2 deletions(-)
diff --git a/tests/system/Database/Live/ForgeTest.php b/tests/system/Database/Live/ForgeTest.php
index f8a695396c9b..a0e3c9cc7c81 100644
--- a/tests/system/Database/Live/ForgeTest.php
+++ b/tests/system/Database/Live/ForgeTest.php
@@ -1289,8 +1289,18 @@ public function testModifyColumnRename(): void
'unsigned' => false,
'auto_increment' => true,
],
+ 'int' => [
+ 'type' => 'INT',
+ 'constraint' => 10,
+ 'null' => false,
+ ],
+ 'varchar' => [
+ 'type' => 'VARCHAR',
+ 'constraint' => 7,
+ 'null' => false,
+ ],
'name' => [
- 'type' => 'varchar',
+ 'type' => 'VARCHAR',
'constraint' => 255,
'null' => true,
],
@@ -1304,7 +1314,7 @@ public function testModifyColumnRename(): void
$this->forge->modifyColumn('forge_test_three', [
'name' => [
'name' => 'altered',
- 'type' => 'varchar',
+ 'type' => 'VARCHAR',
'constraint' => 255,
'null' => true,
],
@@ -1312,9 +1322,23 @@ public function testModifyColumnRename(): void
$this->db->resetDataCache();
+ $fieldData = $this->db->getFieldData('forge_test_three');
+ $fields = [];
+
+ foreach ($fieldData as $obj) {
+ $fields[$obj->name] = $obj;
+ }
+
$this->assertFalse($this->db->fieldExists('name', 'forge_test_three'));
$this->assertTrue($this->db->fieldExists('altered', 'forge_test_three'));
+ $this->assertTrue($fields['altered']->nullable);
+ $this->assertFalse($fields['int']->nullable);
+ $this->assertFalse($fields['varchar']->nullable);
+ $this->assertNull($fields['altered']->default);
+ $this->assertNull($fields['int']->default);
+ $this->assertNull($fields['varchar']->default);
+
$this->forge->dropTable('forge_test_three', true);
}
From b47e87848d048c0f77383e5cd47acef586fbffae Mon Sep 17 00:00:00 2001
From: kenjis
Date: Fri, 26 Jan 2024 13:18:48 +0900
Subject: [PATCH 037/164] fix: SQLite3 Forge::modifyColumn() messes up table
---
system/Database/SQLite3/Forge.php | 15 ++++++++++++++-
system/Database/SQLite3/Table.php | 10 ++++++++++
2 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/system/Database/SQLite3/Forge.php b/system/Database/SQLite3/Forge.php
index b02193f5057c..c3d8e12f1935 100644
--- a/system/Database/SQLite3/Forge.php
+++ b/system/Database/SQLite3/Forge.php
@@ -131,9 +131,22 @@ protected function _alterTable(string $alterType, string $table, $processedField
return ''; // Why empty string?
case 'CHANGE':
+ $fieldsToModify = [];
+
+ foreach ($processedFields as $processedField) {
+ $name = $processedField['name'];
+ $newName = $processedField['new_name'];
+
+ $field = $this->fields[$name];
+ $field['name'] = $name;
+ $field['new_name'] = $newName;
+
+ $fieldsToModify[] = $field;
+ }
+
(new Table($this->db, $this))
->fromTable($table)
- ->modifyColumn($processedFields) // @TODO Bug: should be NOT processed fields
+ ->modifyColumn($fieldsToModify)
->run();
return null; // Why null?
diff --git a/system/Database/SQLite3/Table.php b/system/Database/SQLite3/Table.php
index ce574033afb0..725090dbcedc 100644
--- a/system/Database/SQLite3/Table.php
+++ b/system/Database/SQLite3/Table.php
@@ -392,6 +392,16 @@ protected function formatFields($fields)
'null' => $field->nullable,
];
+ if ($field->default === null) {
+ // `null` means that the default value is not defined.
+ unset($return[$field->name]['default']);
+ } elseif ($field->default === 'NULL') {
+ // 'NULL' means that the default value is NULL.
+ $return[$field->name]['default'] = null;
+ } else {
+ $return[$field->name]['default'] = trim($field->default, "'");
+ }
+
if ($field->primary_key) {
$this->keys['primary'] = [
'fields' => [$field->name],
From 8d0a5e57e6477d45c58cd76f7c1ae0c20b3243bd Mon Sep 17 00:00:00 2001
From: kenjis
Date: Fri, 26 Jan 2024 13:56:18 +0900
Subject: [PATCH 038/164] test: update assertions for fromTable()
---
tests/system/Database/Live/SQLite3/AlterTableTest.php | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/tests/system/Database/Live/SQLite3/AlterTableTest.php b/tests/system/Database/Live/SQLite3/AlterTableTest.php
index 4a06a8ada091..a738484009c1 100644
--- a/tests/system/Database/Live/SQLite3/AlterTableTest.php
+++ b/tests/system/Database/Live/SQLite3/AlterTableTest.php
@@ -89,17 +89,17 @@ public function testFromTableFillsDetails(): void
$this->assertCount(5, $fields);
$this->assertArrayHasKey('id', $fields);
- $this->assertNull($fields['id']['default']);
+ $this->assertArrayNotHasKey('default', $fields['id']);
$this->assertTrue($fields['id']['null']);
$this->assertSame('integer', strtolower($fields['id']['type']));
$this->assertArrayHasKey('name', $fields);
- $this->assertNull($fields['name']['default']);
+ $this->assertArrayNotHasKey('default', $fields['name']);
$this->assertFalse($fields['name']['null']);
$this->assertSame('varchar', strtolower($fields['name']['type']));
$this->assertArrayHasKey('email', $fields);
- $this->assertNull($fields['email']['default']);
+ $this->assertArrayNotHasKey('default', $fields['email']);
$this->assertTrue($fields['email']['null']);
$this->assertSame('varchar', strtolower($fields['email']['type']));
From c28c0c3d9cc1b743c35d51f7632cf4463a4aa4de Mon Sep 17 00:00:00 2001
From: kenjis
Date: Fri, 26 Jan 2024 14:25:53 +0900
Subject: [PATCH 039/164] fix: make default NULL when modifying column
---
system/Database/SQLite3/Forge.php | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/system/Database/SQLite3/Forge.php b/system/Database/SQLite3/Forge.php
index c3d8e12f1935..4be650e03155 100644
--- a/system/Database/SQLite3/Forge.php
+++ b/system/Database/SQLite3/Forge.php
@@ -141,6 +141,12 @@ protected function _alterTable(string $alterType, string $table, $processedField
$field['name'] = $name;
$field['new_name'] = $newName;
+ // Unlike when creating a table, if `null` is not specified,
+ // the column will be `NULL`, not `NOT NULL`.
+ if ($processedField['null'] === '') {
+ $field['null'] = true;
+ }
+
$fieldsToModify[] = $field;
}
From eafb2d2e21329747eaab34ea62a2ec082d1fae68 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Tue, 30 Jan 2024 09:28:28 +0900
Subject: [PATCH 040/164] test: add test for SQLite3 Forge::modifyColumn()
---
.../Live/SQLite3/ForgeModifyColumnTest.php | 113 ++++++++++++++++++
1 file changed, 113 insertions(+)
create mode 100644 tests/system/Database/Live/SQLite3/ForgeModifyColumnTest.php
diff --git a/tests/system/Database/Live/SQLite3/ForgeModifyColumnTest.php b/tests/system/Database/Live/SQLite3/ForgeModifyColumnTest.php
new file mode 100644
index 000000000000..7905dcd7d684
--- /dev/null
+++ b/tests/system/Database/Live/SQLite3/ForgeModifyColumnTest.php
@@ -0,0 +1,113 @@
+
+ *
+ * For the full copyright and license information, please view
+ * the LICENSE file that was distributed with this source code.
+ */
+
+namespace CodeIgniter\Database\Live\SQLite3;
+
+use CodeIgniter\Database\Forge;
+use CodeIgniter\Test\CIUnitTestCase;
+use Config\Database;
+
+/**
+ * @group DatabaseLive
+ *
+ * @internal
+ */
+final class ForgeModifyColumnTest extends CIUnitTestCase
+{
+ private Forge $forge;
+
+ protected function setUp(): void
+ {
+ parent::setUp();
+
+ $this->db = Database::connect($this->DBGroup);
+
+ if ($this->db->DBDriver !== 'SQLite3') {
+ $this->markTestSkipped('This test is only for SQLite3.');
+ }
+
+ $this->forge = Database::forge($this->DBGroup);
+ }
+
+ public function testModifyColumnRename(): void
+ {
+ $this->forge->dropTable('forge_test_three', true);
+
+ $this->forge->addField([
+ 'id' => [
+ 'type' => 'INTEGER',
+ 'constraint' => 11,
+ 'auto_increment' => true,
+ ],
+ 'int' => [
+ 'type' => 'INT',
+ 'constraint' => 10,
+ 'null' => false,
+ 'default' => 0,
+ ],
+ 'varchar' => [
+ 'type' => 'VARCHAR',
+ 'constraint' => 7,
+ 'null' => false,
+ ],
+ 'decimal' => [
+ 'type' => 'DECIMAL',
+ 'constraint' => '10,5',
+ 'default' => 0.1,
+ ],
+ 'name' => [
+ 'type' => 'VARCHAR',
+ 'constraint' => 255,
+ 'null' => true,
+ ],
+ ]);
+
+ $this->forge->addKey('id', true);
+ $this->forge->createTable('forge_test_three');
+
+ $this->assertTrue($this->db->fieldExists('name', 'forge_test_three'));
+
+ $this->forge->modifyColumn('forge_test_three', [
+ 'name' => [
+ 'name' => 'altered',
+ 'type' => 'VARCHAR',
+ 'constraint' => 255,
+ 'null' => true,
+ ],
+ ]);
+
+ $this->db->resetDataCache();
+
+ $fieldData = $this->db->getFieldData('forge_test_three');
+ $fields = [];
+
+ foreach ($fieldData as $obj) {
+ $fields[$obj->name] = $obj;
+ }
+
+ $this->assertFalse($this->db->fieldExists('name', 'forge_test_three'));
+ $this->assertTrue($this->db->fieldExists('altered', 'forge_test_three'));
+
+ $this->assertFalse($fields['int']->nullable);
+ $this->assertSame('0', $fields['int']->default);
+
+ $this->assertFalse($fields['varchar']->nullable);
+ $this->assertNull($fields['varchar']->default);
+
+ $this->assertFalse($fields['decimal']->nullable);
+ $this->assertSame('0.1', $fields['decimal']->default);
+
+ $this->assertTrue($fields['altered']->nullable);
+ $this->assertNull($fields['altered']->default);
+
+ $this->forge->dropTable('forge_test_three', true);
+ }
+}
From 26f786f723c1768f9f251459a33d9e5fa32d6f00 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Tue, 30 Jan 2024 09:29:13 +0900
Subject: [PATCH 041/164] fix: SQLite3 Forge::modifyColumn() changes numeric
default value
See https://github.com/codeigniter4/CodeIgniter4/pull/8457#issuecomment-1915547675
---
system/Database/SQLite3/Table.php | 34 ++++++++++++++++++++++++++++++-
1 file changed, 33 insertions(+), 1 deletion(-)
diff --git a/system/Database/SQLite3/Table.php b/system/Database/SQLite3/Table.php
index 725090dbcedc..47e6d1a7097e 100644
--- a/system/Database/SQLite3/Table.php
+++ b/system/Database/SQLite3/Table.php
@@ -399,7 +399,15 @@ protected function formatFields($fields)
// 'NULL' means that the default value is NULL.
$return[$field->name]['default'] = null;
} else {
- $return[$field->name]['default'] = trim($field->default, "'");
+ $default = trim($field->default, "'");
+
+ if ($this->isIntegerType($field->type)) {
+ $default = (int) $default;
+ } elseif ($this->isNumericType($field->type)) {
+ $default = (float) $default;
+ }
+
+ $return[$field->name]['default'] = $default;
}
if ($field->primary_key) {
@@ -413,6 +421,30 @@ protected function formatFields($fields)
return $return;
}
+ /**
+ * Is INTEGER type?
+ *
+ * @param string $type SQLite data type (case-insensitive)
+ *
+ * @see https://www.sqlite.org/datatype3.html
+ */
+ private function isIntegerType(string $type): bool
+ {
+ return strpos(strtoupper($type), 'INT') !== false;
+ }
+
+ /**
+ * Is NUMERIC type?
+ *
+ * @param string $type SQLite data type (case-insensitive)
+ *
+ * @see https://www.sqlite.org/datatype3.html
+ */
+ private function isNumericType(string $type): bool
+ {
+ return in_array(strtoupper($type), ['NUMERIC', 'DECIMAL'], true);
+ }
+
/**
* Converts keys retrieved from the database to
* the format needed to create later.
From 8d30df7fedc12be0014f4a5a3f749bd8e58d4a51 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Tue, 30 Jan 2024 09:36:12 +0900
Subject: [PATCH 042/164] test: use variable $table
---
.../Live/SQLite3/ForgeModifyColumnTest.php | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/tests/system/Database/Live/SQLite3/ForgeModifyColumnTest.php b/tests/system/Database/Live/SQLite3/ForgeModifyColumnTest.php
index 7905dcd7d684..1237cb6da28e 100644
--- a/tests/system/Database/Live/SQLite3/ForgeModifyColumnTest.php
+++ b/tests/system/Database/Live/SQLite3/ForgeModifyColumnTest.php
@@ -39,7 +39,9 @@ protected function setUp(): void
public function testModifyColumnRename(): void
{
- $this->forge->dropTable('forge_test_three', true);
+ $table = 'forge_test_three';
+
+ $this->forge->dropTable($table, true);
$this->forge->addField([
'id' => [
@@ -71,11 +73,11 @@ public function testModifyColumnRename(): void
]);
$this->forge->addKey('id', true);
- $this->forge->createTable('forge_test_three');
+ $this->forge->createTable($table);
- $this->assertTrue($this->db->fieldExists('name', 'forge_test_three'));
+ $this->assertTrue($this->db->fieldExists('name', $table));
- $this->forge->modifyColumn('forge_test_three', [
+ $this->forge->modifyColumn($table, [
'name' => [
'name' => 'altered',
'type' => 'VARCHAR',
@@ -86,15 +88,15 @@ public function testModifyColumnRename(): void
$this->db->resetDataCache();
- $fieldData = $this->db->getFieldData('forge_test_three');
+ $fieldData = $this->db->getFieldData($table);
$fields = [];
foreach ($fieldData as $obj) {
$fields[$obj->name] = $obj;
}
- $this->assertFalse($this->db->fieldExists('name', 'forge_test_three'));
- $this->assertTrue($this->db->fieldExists('altered', 'forge_test_three'));
+ $this->assertFalse($this->db->fieldExists('name', $table));
+ $this->assertTrue($this->db->fieldExists('altered', $table));
$this->assertFalse($fields['int']->nullable);
$this->assertSame('0', $fields['int']->default);
@@ -108,6 +110,6 @@ public function testModifyColumnRename(): void
$this->assertTrue($fields['altered']->nullable);
$this->assertNull($fields['altered']->default);
- $this->forge->dropTable('forge_test_three', true);
+ $this->forge->dropTable($table, true);
}
}
From 3e2d71560c42ea36e5899d36527976ee2081589b Mon Sep 17 00:00:00 2001
From: kenjis
Date: Tue, 30 Jan 2024 18:52:53 +0900
Subject: [PATCH 043/164] docs: add note to query->getFieldData()
---
user_guide_src/source/database/metadata.rst | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/user_guide_src/source/database/metadata.rst b/user_guide_src/source/database/metadata.rst
index 1845a0440b7a..2de5abc0e063 100644
--- a/user_guide_src/source/database/metadata.rst
+++ b/user_guide_src/source/database/metadata.rst
@@ -94,11 +94,6 @@ Usage example:
.. literalinclude:: metadata/006.php
-If you have run a query already you can use the result object instead of
-supplying the table name:
-
-.. literalinclude:: metadata/007.php
-
The following data is available from this function if supported by your
database:
@@ -111,6 +106,17 @@ database:
.. note:: Since v4.4.0, SQLSRV supported ``nullable``.
+$query->getFieldData()
+----------------------
+
+If you have run a query already you can use the result object instead of
+supplying the table name:
+
+.. literalinclude:: metadata/007.php
+
+.. note:: The data returned is different from the data from ``$db->getFieldData()``.
+ If you cannot get the data you need, use ``$db->getFieldData()``.
+
List the Indexes in a Table
===========================
From e234370301881408d0716fae3df6e424378f3891 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Tue, 30 Jan 2024 15:50:49 +0000
Subject: [PATCH 044/164] chore(deps-dev): update rector/rector requirement
from 0.19.2 to 0.19.5
Updates the requirements on [rector/rector](https://github.com/rectorphp/rector) to permit the latest version.
- [Release notes](https://github.com/rectorphp/rector/releases)
- [Commits](https://github.com/rectorphp/rector/compare/0.19.2...0.19.5)
---
updated-dependencies:
- dependency-name: rector/rector
dependency-type: direct:development
...
Signed-off-by: dependabot[bot]
---
composer.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/composer.json b/composer.json
index 82c97606b4c8..8ce1815a81b1 100644
--- a/composer.json
+++ b/composer.json
@@ -34,7 +34,7 @@
"phpunit/phpcov": "^8.2",
"phpunit/phpunit": "^9.1",
"predis/predis": "^1.1 || ^2.0",
- "rector/rector": "0.19.2",
+ "rector/rector": "0.19.5",
"vimeo/psalm": "^5.0"
},
"replace": {
From f95f9970fbe148c0fae22203e67183eb4ab91690 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Wed, 31 Jan 2024 09:08:25 +0900
Subject: [PATCH 045/164] docs: update description for 404 Override
---
user_guide_src/source/incoming/routing.rst | 14 +++++++++-----
user_guide_src/source/incoming/routing/051.php | 9 ---------
user_guide_src/source/incoming/routing/069.php | 10 ++++++++++
3 files changed, 19 insertions(+), 14 deletions(-)
create mode 100644 user_guide_src/source/incoming/routing/069.php
diff --git a/user_guide_src/source/incoming/routing.rst b/user_guide_src/source/incoming/routing.rst
index c9bd1e9eeb39..a9aa28602822 100644
--- a/user_guide_src/source/incoming/routing.rst
+++ b/user_guide_src/source/incoming/routing.rst
@@ -667,15 +667,19 @@ to only those defined by you, by setting the ``$autoRoute`` property to false:
404 Override
============
-When a page is not found that matches the current URI, the system will show a generic 404 view. You can change
-what happens by specifying an action to happen with the ``set404Override()`` method. The value can be either
-a valid class/method pair, just like you would show in any route, or a Closure:
+When a page is not found that matches the current URI, the system will show a
+generic 404 view. Using the ``$override404`` property within the routing config
+file, you can define controller class/method for 404 routes.
.. literalinclude:: routing/051.php
-Using the ``$override404`` property within the routing config file, you can use closures. Defining the override in the Routing file is restricted to class/method pairs.
+You can also change what happens by specifying an action to happen with the
+``set404Override()`` method in Routes config file. The value can be either a
+valid class/method pair, or a Closure:
-.. note:: The ``set404Override()`` method does not change the Response status code to ``404``.
+.. literalinclude:: routing/069.php
+
+.. note:: The 404 Override feature does not change the Response status code to ``404``.
If you don't set the status code in the controller you set, the default status code ``200``
will be returned. See :php:meth:`CodeIgniter\\HTTP\\Response::setStatusCode()` for
information on how to set the status code.
diff --git a/user_guide_src/source/incoming/routing/051.php b/user_guide_src/source/incoming/routing/051.php
index 8c598c400b03..33852c87e021 100644
--- a/user_guide_src/source/incoming/routing/051.php
+++ b/user_guide_src/source/incoming/routing/051.php
@@ -10,12 +10,3 @@ class Routing extends BaseRouting
public ?string $override404 = 'App\Errors::show404';
// ...
}
-
-// In app/Config/Routes.php
-// Would execute the show404 method of the App\Errors class
-$routes->set404Override('App\Errors::show404');
-
-// Will display a custom view
-$routes->set404Override(static function () {
- echo view('my_errors/not_found.html');
-});
diff --git a/user_guide_src/source/incoming/routing/069.php b/user_guide_src/source/incoming/routing/069.php
new file mode 100644
index 000000000000..991aa5c57b74
--- /dev/null
+++ b/user_guide_src/source/incoming/routing/069.php
@@ -0,0 +1,10 @@
+set404Override('App\Errors::show404');
+
+// Will display a custom view
+$routes->set404Override(static function () {
+ echo view('my_errors/not_found.html');
+});
From 55a2932171631e9eb37128843b49a8326bf3955a Mon Sep 17 00:00:00 2001
From: kenjis
Date: Tue, 30 Jan 2024 10:03:05 +0900
Subject: [PATCH 046/164] test: rename test method name
---
tests/system/Database/Live/AbstractGetFieldDataTest.php | 2 +-
tests/system/Database/Live/MySQLi/GetFieldDataTest.php | 2 +-
tests/system/Database/Live/OCI8/GetFieldDataTest.php | 2 +-
tests/system/Database/Live/Postgre/GetFieldDataTest.php | 2 +-
tests/system/Database/Live/SQLSRV/GetFieldDataTest.php | 2 +-
tests/system/Database/Live/SQLite3/GetFieldDataTest.php | 2 +-
6 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/tests/system/Database/Live/AbstractGetFieldDataTest.php b/tests/system/Database/Live/AbstractGetFieldDataTest.php
index 570061cac3e3..d7484607c928 100644
--- a/tests/system/Database/Live/AbstractGetFieldDataTest.php
+++ b/tests/system/Database/Live/AbstractGetFieldDataTest.php
@@ -91,5 +91,5 @@ protected function createTable()
$this->forge->createTable('test1');
}
- abstract public function testGetFieldData(): void;
+ abstract public function testGetFieldDataDefault(): void;
}
diff --git a/tests/system/Database/Live/MySQLi/GetFieldDataTest.php b/tests/system/Database/Live/MySQLi/GetFieldDataTest.php
index aacc7fa84b99..7d7e4012fa38 100644
--- a/tests/system/Database/Live/MySQLi/GetFieldDataTest.php
+++ b/tests/system/Database/Live/MySQLi/GetFieldDataTest.php
@@ -46,7 +46,7 @@ private function isOldMySQL(): bool
);
}
- public function testGetFieldData(): void
+ public function testGetFieldDataDefault(): void
{
$fields = $this->db->getFieldData('test1');
diff --git a/tests/system/Database/Live/OCI8/GetFieldDataTest.php b/tests/system/Database/Live/OCI8/GetFieldDataTest.php
index 28763a11f3ee..0fd789c6d387 100644
--- a/tests/system/Database/Live/OCI8/GetFieldDataTest.php
+++ b/tests/system/Database/Live/OCI8/GetFieldDataTest.php
@@ -32,7 +32,7 @@ protected function createForge(): void
$this->forge = Database::forge($this->db);
}
- public function testGetFieldData(): void
+ public function testGetFieldDataDefault(): void
{
$fields = $this->db->getFieldData('test1');
diff --git a/tests/system/Database/Live/Postgre/GetFieldDataTest.php b/tests/system/Database/Live/Postgre/GetFieldDataTest.php
index 64caac6126b3..ad62a7a38cb5 100644
--- a/tests/system/Database/Live/Postgre/GetFieldDataTest.php
+++ b/tests/system/Database/Live/Postgre/GetFieldDataTest.php
@@ -32,7 +32,7 @@ protected function createForge(): void
$this->forge = Database::forge($this->db);
}
- public function testGetFieldData(): void
+ public function testGetFieldDataDefault(): void
{
$fields = $this->db->getFieldData('test1');
diff --git a/tests/system/Database/Live/SQLSRV/GetFieldDataTest.php b/tests/system/Database/Live/SQLSRV/GetFieldDataTest.php
index 07a41cd1467e..80af8543fffe 100644
--- a/tests/system/Database/Live/SQLSRV/GetFieldDataTest.php
+++ b/tests/system/Database/Live/SQLSRV/GetFieldDataTest.php
@@ -32,7 +32,7 @@ protected function createForge(): void
$this->forge = Database::forge($this->db);
}
- public function testGetFieldData(): void
+ public function testGetFieldDataDefault(): void
{
$fields = $this->db->getFieldData('test1');
diff --git a/tests/system/Database/Live/SQLite3/GetFieldDataTest.php b/tests/system/Database/Live/SQLite3/GetFieldDataTest.php
index 4b8b9bcd6432..9febf7bba45d 100644
--- a/tests/system/Database/Live/SQLite3/GetFieldDataTest.php
+++ b/tests/system/Database/Live/SQLite3/GetFieldDataTest.php
@@ -36,7 +36,7 @@ protected function createForge(): void
$this->forge = Database::forge($config);
}
- public function testGetFieldData(): void
+ public function testGetFieldDataDefault(): void
{
$fields = $this->db->getFieldData('test1');
From 53d592ad0e1c6db996f9adf5da47b35db75431d0 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Tue, 30 Jan 2024 10:07:51 +0900
Subject: [PATCH 047/164] test: add property $table
---
tests/system/Database/Live/AbstractGetFieldDataTest.php | 7 ++++---
tests/system/Database/Live/MySQLi/GetFieldDataTest.php | 2 +-
tests/system/Database/Live/OCI8/GetFieldDataTest.php | 2 +-
tests/system/Database/Live/SQLSRV/GetFieldDataTest.php | 2 +-
tests/system/Database/Live/SQLite3/GetFieldDataTest.php | 8 ++++----
5 files changed, 11 insertions(+), 10 deletions(-)
diff --git a/tests/system/Database/Live/AbstractGetFieldDataTest.php b/tests/system/Database/Live/AbstractGetFieldDataTest.php
index d7484607c928..ebea3cbcd47d 100644
--- a/tests/system/Database/Live/AbstractGetFieldDataTest.php
+++ b/tests/system/Database/Live/AbstractGetFieldDataTest.php
@@ -26,6 +26,7 @@ abstract class AbstractGetFieldDataTest extends CIUnitTestCase
protected $db;
protected Forge $forge;
+ protected string $table = 'test1';
protected function setUp(): void
{
@@ -46,12 +47,12 @@ protected function tearDown(): void
{
parent::tearDown();
- $this->forge->dropTable('test1', true);
+ $this->forge->dropTable($this->table, true);
}
protected function createTable()
{
- $this->forge->dropTable('test1', true);
+ $this->forge->dropTable($this->table, true);
$this->forge->addField([
'id' => [
@@ -88,7 +89,7 @@ protected function createTable()
],
]);
$this->forge->addKey('id', true);
- $this->forge->createTable('test1');
+ $this->forge->createTable($this->table);
}
abstract public function testGetFieldDataDefault(): void;
diff --git a/tests/system/Database/Live/MySQLi/GetFieldDataTest.php b/tests/system/Database/Live/MySQLi/GetFieldDataTest.php
index 7d7e4012fa38..547d45eace91 100644
--- a/tests/system/Database/Live/MySQLi/GetFieldDataTest.php
+++ b/tests/system/Database/Live/MySQLi/GetFieldDataTest.php
@@ -48,7 +48,7 @@ private function isOldMySQL(): bool
public function testGetFieldDataDefault(): void
{
- $fields = $this->db->getFieldData('test1');
+ $fields = $this->db->getFieldData($this->table);
$this->assertJsonStringEqualsJsonString(
json_encode([
diff --git a/tests/system/Database/Live/OCI8/GetFieldDataTest.php b/tests/system/Database/Live/OCI8/GetFieldDataTest.php
index 0fd789c6d387..a6dc3156b248 100644
--- a/tests/system/Database/Live/OCI8/GetFieldDataTest.php
+++ b/tests/system/Database/Live/OCI8/GetFieldDataTest.php
@@ -34,7 +34,7 @@ protected function createForge(): void
public function testGetFieldDataDefault(): void
{
- $fields = $this->db->getFieldData('test1');
+ $fields = $this->db->getFieldData($this->table);
$data = [];
diff --git a/tests/system/Database/Live/SQLSRV/GetFieldDataTest.php b/tests/system/Database/Live/SQLSRV/GetFieldDataTest.php
index 80af8543fffe..60d60577130c 100644
--- a/tests/system/Database/Live/SQLSRV/GetFieldDataTest.php
+++ b/tests/system/Database/Live/SQLSRV/GetFieldDataTest.php
@@ -34,7 +34,7 @@ protected function createForge(): void
public function testGetFieldDataDefault(): void
{
- $fields = $this->db->getFieldData('test1');
+ $fields = $this->db->getFieldData($this->table);
$this->assertJsonStringEqualsJsonString(
json_encode([
diff --git a/tests/system/Database/Live/SQLite3/GetFieldDataTest.php b/tests/system/Database/Live/SQLite3/GetFieldDataTest.php
index 9febf7bba45d..69cc9e01b7b2 100644
--- a/tests/system/Database/Live/SQLite3/GetFieldDataTest.php
+++ b/tests/system/Database/Live/SQLite3/GetFieldDataTest.php
@@ -38,7 +38,7 @@ protected function createForge(): void
public function testGetFieldDataDefault(): void
{
- $fields = $this->db->getFieldData('test1');
+ $fields = $this->db->getFieldData($this->table);
$this->assertJsonStringEqualsJsonString(
json_encode([
@@ -105,7 +105,7 @@ public function testGetFieldDataDefault(): void
protected function createTableCompositePrimaryKey()
{
- $this->forge->dropTable('test1', true);
+ $this->forge->dropTable($this->table, true);
$this->forge->addField([
'pk1' => [
@@ -122,14 +122,14 @@ protected function createTableCompositePrimaryKey()
],
]);
$this->forge->addPrimaryKey(['pk1', 'pk2']);
- $this->forge->createTable('test1');
+ $this->forge->createTable($this->table);
}
public function testGetFieldDataCompositePrimaryKey(): void
{
$this->createTableCompositePrimaryKey();
- $fields = $this->db->getFieldData('test1');
+ $fields = $this->db->getFieldData($this->table);
$this->assertJsonStringEqualsJsonString(
json_encode([
From 956e815858835e2d573a444a15c3293e13cab62b Mon Sep 17 00:00:00 2001
From: kenjis
Date: Tue, 30 Jan 2024 10:10:19 +0900
Subject: [PATCH 048/164] test: rename method name
---
tests/system/Database/Live/AbstractGetFieldDataTest.php | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tests/system/Database/Live/AbstractGetFieldDataTest.php b/tests/system/Database/Live/AbstractGetFieldDataTest.php
index ebea3cbcd47d..9d9eb89474e6 100644
--- a/tests/system/Database/Live/AbstractGetFieldDataTest.php
+++ b/tests/system/Database/Live/AbstractGetFieldDataTest.php
@@ -35,7 +35,7 @@ protected function setUp(): void
$this->db = Database::connect($this->DBGroup);
$this->createForge();
- $this->createTable();
+ $this->createTableForDefault();
}
/**
@@ -50,7 +50,7 @@ protected function tearDown(): void
$this->forge->dropTable($this->table, true);
}
- protected function createTable()
+ protected function createTableForDefault()
{
$this->forge->dropTable($this->table, true);
From a444ab1c45ab06a933066e502bdf36fe0be488bd Mon Sep 17 00:00:00 2001
From: kenjis
Date: Tue, 30 Jan 2024 10:12:43 +0900
Subject: [PATCH 049/164] test: move $this->createTableForDefault() to child
classes
---
tests/system/Database/Live/AbstractGetFieldDataTest.php | 1 -
tests/system/Database/Live/MySQLi/GetFieldDataTest.php | 2 ++
tests/system/Database/Live/OCI8/GetFieldDataTest.php | 2 ++
tests/system/Database/Live/Postgre/GetFieldDataTest.php | 2 ++
tests/system/Database/Live/SQLSRV/GetFieldDataTest.php | 2 ++
tests/system/Database/Live/SQLite3/GetFieldDataTest.php | 2 ++
6 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/tests/system/Database/Live/AbstractGetFieldDataTest.php b/tests/system/Database/Live/AbstractGetFieldDataTest.php
index 9d9eb89474e6..d52e3cf5adb1 100644
--- a/tests/system/Database/Live/AbstractGetFieldDataTest.php
+++ b/tests/system/Database/Live/AbstractGetFieldDataTest.php
@@ -35,7 +35,6 @@ protected function setUp(): void
$this->db = Database::connect($this->DBGroup);
$this->createForge();
- $this->createTableForDefault();
}
/**
diff --git a/tests/system/Database/Live/MySQLi/GetFieldDataTest.php b/tests/system/Database/Live/MySQLi/GetFieldDataTest.php
index 547d45eace91..f48bc325a59a 100644
--- a/tests/system/Database/Live/MySQLi/GetFieldDataTest.php
+++ b/tests/system/Database/Live/MySQLi/GetFieldDataTest.php
@@ -48,6 +48,8 @@ private function isOldMySQL(): bool
public function testGetFieldDataDefault(): void
{
+ $this->createTableForDefault();
+
$fields = $this->db->getFieldData($this->table);
$this->assertJsonStringEqualsJsonString(
diff --git a/tests/system/Database/Live/OCI8/GetFieldDataTest.php b/tests/system/Database/Live/OCI8/GetFieldDataTest.php
index a6dc3156b248..ea733ea8b2ff 100644
--- a/tests/system/Database/Live/OCI8/GetFieldDataTest.php
+++ b/tests/system/Database/Live/OCI8/GetFieldDataTest.php
@@ -34,6 +34,8 @@ protected function createForge(): void
public function testGetFieldDataDefault(): void
{
+ $this->createTableForDefault();
+
$fields = $this->db->getFieldData($this->table);
$data = [];
diff --git a/tests/system/Database/Live/Postgre/GetFieldDataTest.php b/tests/system/Database/Live/Postgre/GetFieldDataTest.php
index ad62a7a38cb5..e891918343db 100644
--- a/tests/system/Database/Live/Postgre/GetFieldDataTest.php
+++ b/tests/system/Database/Live/Postgre/GetFieldDataTest.php
@@ -34,6 +34,8 @@ protected function createForge(): void
public function testGetFieldDataDefault(): void
{
+ $this->createTableForDefault();
+
$fields = $this->db->getFieldData('test1');
$this->assertJsonStringEqualsJsonString(
diff --git a/tests/system/Database/Live/SQLSRV/GetFieldDataTest.php b/tests/system/Database/Live/SQLSRV/GetFieldDataTest.php
index 60d60577130c..b2b37741f27a 100644
--- a/tests/system/Database/Live/SQLSRV/GetFieldDataTest.php
+++ b/tests/system/Database/Live/SQLSRV/GetFieldDataTest.php
@@ -34,6 +34,8 @@ protected function createForge(): void
public function testGetFieldDataDefault(): void
{
+ $this->createTableForDefault();
+
$fields = $this->db->getFieldData($this->table);
$this->assertJsonStringEqualsJsonString(
diff --git a/tests/system/Database/Live/SQLite3/GetFieldDataTest.php b/tests/system/Database/Live/SQLite3/GetFieldDataTest.php
index 69cc9e01b7b2..00bc08e2cffd 100644
--- a/tests/system/Database/Live/SQLite3/GetFieldDataTest.php
+++ b/tests/system/Database/Live/SQLite3/GetFieldDataTest.php
@@ -38,6 +38,8 @@ protected function createForge(): void
public function testGetFieldDataDefault(): void
{
+ $this->createTableForDefault();
+
$fields = $this->db->getFieldData($this->table);
$this->assertJsonStringEqualsJsonString(
From c271e1fb3b180d6b94150c86f2e17543ef321c38 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Tue, 30 Jan 2024 10:53:09 +0900
Subject: [PATCH 050/164] test: add assertSameFieldData()
---
.../Live/AbstractGetFieldDataTest.php | 13 ++
.../Database/Live/MySQLi/GetFieldDataTest.php | 120 ++++++------
.../Database/Live/OCI8/GetFieldDataTest.php | 13 +-
.../Live/Postgre/GetFieldDataTest.php | 120 ++++++------
.../Database/Live/SQLSRV/GetFieldDataTest.php | 120 ++++++------
.../Live/SQLite3/GetFieldDataTest.php | 176 +++++++++---------
6 files changed, 279 insertions(+), 283 deletions(-)
diff --git a/tests/system/Database/Live/AbstractGetFieldDataTest.php b/tests/system/Database/Live/AbstractGetFieldDataTest.php
index d52e3cf5adb1..859c37718902 100644
--- a/tests/system/Database/Live/AbstractGetFieldDataTest.php
+++ b/tests/system/Database/Live/AbstractGetFieldDataTest.php
@@ -92,4 +92,17 @@ protected function createTableForDefault()
}
abstract public function testGetFieldDataDefault(): void;
+
+ protected function assertSameFieldData(array $expected, array $actual)
+ {
+ $expected = json_decode(json_encode($expected), true);
+ $names = array_column($expected, 'name');
+ array_multisort($names, SORT_ASC, $expected);
+
+ $fields = json_decode(json_encode($actual), true);
+ $names = array_column($fields, 'name');
+ array_multisort($names, SORT_ASC, $fields);
+
+ $this->assertSame($expected, $fields);
+ }
}
diff --git a/tests/system/Database/Live/MySQLi/GetFieldDataTest.php b/tests/system/Database/Live/MySQLi/GetFieldDataTest.php
index f48bc325a59a..f5c9a0761ea4 100644
--- a/tests/system/Database/Live/MySQLi/GetFieldDataTest.php
+++ b/tests/system/Database/Live/MySQLi/GetFieldDataTest.php
@@ -52,66 +52,64 @@ public function testGetFieldDataDefault(): void
$fields = $this->db->getFieldData($this->table);
- $this->assertJsonStringEqualsJsonString(
- json_encode([
- (object) [
- 'name' => 'id',
- 'type' => 'int',
- 'max_length' => $this->isOldMySQL() ? 11 : null,
- 'default' => null, // The default value is not defined.
- 'primary_key' => 1,
- 'nullable' => false,
- ],
- (object) [
- 'name' => 'text_not_null',
- 'type' => 'varchar',
- 'max_length' => 64,
- 'default' => null, // The default value is not defined.
- 'primary_key' => 0,
- 'nullable' => false,
- ],
- (object) [
- 'name' => 'text_null',
- 'type' => 'varchar',
- 'max_length' => 64,
- 'default' => null, // The default value is not defined.
- 'primary_key' => 0,
- 'nullable' => true,
- ],
- (object) [
- 'name' => 'int_default_0',
- 'type' => 'int',
- 'max_length' => $this->isOldMySQL() ? 11 : null,
- 'default' => '0', // int 0
- 'primary_key' => 0,
- 'nullable' => false,
- ],
- (object) [
- 'name' => 'text_default_null',
- 'type' => 'varchar',
- 'max_length' => 64,
- 'default' => null, // NULL value
- 'primary_key' => 0,
- 'nullable' => true,
- ],
- (object) [
- 'name' => 'text_default_text_null',
- 'type' => 'varchar',
- 'max_length' => 64,
- 'default' => 'null', // string "null"
- 'primary_key' => 0,
- 'nullable' => false,
- ],
- (object) [
- 'name' => 'text_default_abc',
- 'type' => 'varchar',
- 'max_length' => 64,
- 'default' => 'abc', // string "abc"
- 'primary_key' => 0,
- 'nullable' => false,
- ],
- ]),
- json_encode($fields)
- );
+ $expected = [
+ (object) [
+ 'name' => 'id',
+ 'type' => 'int',
+ 'max_length' => $this->isOldMySQL() ? 11 : null,
+ 'nullable' => false,
+ 'default' => null, // The default value is not defined.
+ 'primary_key' => 1,
+ ],
+ (object) [
+ 'name' => 'text_not_null',
+ 'type' => 'varchar',
+ 'max_length' => 64,
+ 'nullable' => false,
+ 'default' => null, // The default value is not defined.
+ 'primary_key' => 0,
+ ],
+ (object) [
+ 'name' => 'text_null',
+ 'type' => 'varchar',
+ 'max_length' => 64,
+ 'nullable' => true,
+ 'default' => null, // The default value is not defined.
+ 'primary_key' => 0,
+ ],
+ (object) [
+ 'name' => 'int_default_0',
+ 'type' => 'int',
+ 'max_length' => $this->isOldMySQL() ? 11 : null,
+ 'nullable' => false,
+ 'default' => '0', // int 0
+ 'primary_key' => 0,
+ ],
+ (object) [
+ 'name' => 'text_default_null',
+ 'type' => 'varchar',
+ 'max_length' => 64,
+ 'nullable' => true,
+ 'default' => null, // NULL value
+ 'primary_key' => 0,
+ ],
+ (object) [
+ 'name' => 'text_default_text_null',
+ 'type' => 'varchar',
+ 'max_length' => 64,
+ 'nullable' => false,
+ 'default' => 'null', // string "null"
+ 'primary_key' => 0,
+ ],
+ (object) [
+ 'name' => 'text_default_abc',
+ 'type' => 'varchar',
+ 'max_length' => 64,
+ 'nullable' => false,
+ 'default' => 'abc', // string "abc"
+ 'primary_key' => 0,
+ ],
+ ];
+ $this->assertSameFieldData($expected, $fields);
}
}
diff --git a/tests/system/Database/Live/OCI8/GetFieldDataTest.php b/tests/system/Database/Live/OCI8/GetFieldDataTest.php
index ea733ea8b2ff..89750fd60bf8 100644
--- a/tests/system/Database/Live/OCI8/GetFieldDataTest.php
+++ b/tests/system/Database/Live/OCI8/GetFieldDataTest.php
@@ -47,7 +47,7 @@ public function testGetFieldDataDefault(): void
$idDefault = $data['id']->default;
$this->assertMatchesRegularExpression('/"ORACLE"."ISEQ\$\$_[0-9]+".nextval/', $idDefault);
- $expected = json_decode(json_encode([
+ $expected = [
(object) [
'name' => 'id',
'type' => 'NUMBER',
@@ -104,14 +104,7 @@ public function testGetFieldDataDefault(): void
'default' => "'abc' ", // string "abc"
// 'primary_key' => 0,
],
- ]), true);
- $names = array_column($expected, 'name');
- array_multisort($names, SORT_ASC, $expected);
-
- $fields = json_decode(json_encode($fields), true);
- $names = array_column($fields, 'name');
- array_multisort($names, SORT_ASC, $fields);
-
- $this->assertSame($expected, $fields);
+ ];
+ $this->assertSameFieldData($expected, $fields);
}
}
diff --git a/tests/system/Database/Live/Postgre/GetFieldDataTest.php b/tests/system/Database/Live/Postgre/GetFieldDataTest.php
index e891918343db..514bb7011c74 100644
--- a/tests/system/Database/Live/Postgre/GetFieldDataTest.php
+++ b/tests/system/Database/Live/Postgre/GetFieldDataTest.php
@@ -38,66 +38,64 @@ public function testGetFieldDataDefault(): void
$fields = $this->db->getFieldData('test1');
- $this->assertJsonStringEqualsJsonString(
- json_encode([
- (object) [
- 'name' => 'id',
- 'type' => 'integer',
- 'max_length' => '32',
- 'default' => "nextval('db_test1_id_seq'::regclass)", // The default value is not defined.
- // 'primary_key' => 1,
- 'nullable' => false,
- ],
- (object) [
- 'name' => 'text_not_null',
- 'type' => 'character varying',
- 'max_length' => '64',
- 'default' => null, // The default value is not defined.
- // 'primary_key' => 0,
- 'nullable' => false,
- ],
- (object) [
- 'name' => 'text_null',
- 'type' => 'character varying',
- 'max_length' => '64',
- 'default' => null, // The default value is not defined.
- // 'primary_key' => 0,
- 'nullable' => true,
- ],
- (object) [
- 'name' => 'int_default_0',
- 'type' => 'integer',
- 'max_length' => '32',
- 'default' => '0', // int 0
- // 'primary_key' => 0,
- 'nullable' => false,
- ],
- (object) [
- 'name' => 'text_default_null',
- 'type' => 'character varying',
- 'max_length' => '64',
- 'default' => 'NULL::character varying', // NULL value
- // 'primary_key' => 0,
- 'nullable' => true,
- ],
- (object) [
- 'name' => 'text_default_text_null',
- 'type' => 'character varying',
- 'max_length' => '64',
- 'default' => "'null'::character varying", // string "null"
- // 'primary_key' => 0,
- 'nullable' => false,
- ],
- (object) [
- 'name' => 'text_default_abc',
- 'type' => 'character varying',
- 'max_length' => '64',
- 'default' => "'abc'::character varying", // string "abc"
- // 'primary_key' => 0,
- 'nullable' => false,
- ],
- ]),
- json_encode($fields)
- );
+ $expected = [
+ (object) [
+ 'name' => 'id',
+ 'type' => 'integer',
+ 'max_length' => '32',
+ 'nullable' => false,
+ // 'primary_key' => 1,
+ 'default' => "nextval('db_test1_id_seq'::regclass)", // The default value is not defined.
+ ],
+ (object) [
+ 'name' => 'text_not_null',
+ 'type' => 'character varying',
+ 'max_length' => '64',
+ 'nullable' => false,
+ // 'primary_key' => 0,
+ 'default' => null, // The default value is not defined.
+ ],
+ (object) [
+ 'name' => 'text_null',
+ 'type' => 'character varying',
+ 'max_length' => '64',
+ 'nullable' => true,
+ // 'primary_key' => 0,
+ 'default' => null, // The default value is not defined.
+ ],
+ (object) [
+ 'name' => 'int_default_0',
+ 'type' => 'integer',
+ 'max_length' => '32',
+ 'nullable' => false,
+ // 'primary_key' => 0,
+ 'default' => '0', // int 0
+ ],
+ (object) [
+ 'name' => 'text_default_null',
+ 'type' => 'character varying',
+ 'max_length' => '64',
+ 'nullable' => true,
+ // 'primary_key' => 0,
+ 'default' => 'NULL::character varying', // NULL value
+ ],
+ (object) [
+ 'name' => 'text_default_text_null',
+ 'type' => 'character varying',
+ 'max_length' => '64',
+ 'nullable' => false,
+ // 'primary_key' => 0,
+ 'default' => "'null'::character varying", // string "null"
+ ],
+ (object) [
+ 'name' => 'text_default_abc',
+ 'type' => 'character varying',
+ 'max_length' => '64',
+ 'nullable' => false,
+ // 'primary_key' => 0,
+ 'default' => "'abc'::character varying", // string "abc"
+ ],
+ ];
+ $this->assertSameFieldData($expected, $fields);
}
}
diff --git a/tests/system/Database/Live/SQLSRV/GetFieldDataTest.php b/tests/system/Database/Live/SQLSRV/GetFieldDataTest.php
index b2b37741f27a..ada673292ddd 100644
--- a/tests/system/Database/Live/SQLSRV/GetFieldDataTest.php
+++ b/tests/system/Database/Live/SQLSRV/GetFieldDataTest.php
@@ -38,66 +38,64 @@ public function testGetFieldDataDefault(): void
$fields = $this->db->getFieldData($this->table);
- $this->assertJsonStringEqualsJsonString(
- json_encode([
- (object) [
- 'name' => 'id',
- 'type' => 'int',
- 'max_length' => 10,
- 'default' => null, // The default value is not defined.
- // 'primary_key' => 1,
- 'nullable' => false,
- ],
- (object) [
- 'name' => 'text_not_null',
- 'type' => 'varchar',
- 'max_length' => 64,
- 'default' => null, // The default value is not defined.
- // 'primary_key' => 0,
- 'nullable' => false,
- ],
- (object) [
- 'name' => 'text_null',
- 'type' => 'varchar',
- 'max_length' => 64,
- 'default' => null, // The default value is not defined.
- // 'primary_key' => 0,
- 'nullable' => true,
- ],
- (object) [
- 'name' => 'int_default_0',
- 'type' => 'int',
- 'max_length' => 10,
- 'default' => '((0))', // int 0
- // 'primary_key' => 0,
- 'nullable' => false,
- ],
- (object) [
- 'name' => 'text_default_null',
- 'type' => 'varchar',
- 'max_length' => 64,
- 'default' => '(NULL)', // NULL value
- // 'primary_key' => 0,
- 'nullable' => true,
- ],
- (object) [
- 'name' => 'text_default_text_null',
- 'type' => 'varchar',
- 'max_length' => 64,
- 'default' => "('null')", // string "null"
- // 'primary_key' => 0,
- 'nullable' => false,
- ],
- (object) [
- 'name' => 'text_default_abc',
- 'type' => 'varchar',
- 'max_length' => 64,
- 'default' => "('abc')", // string "abc"
- // 'primary_key' => 0,
- 'nullable' => false,
- ],
- ]),
- json_encode($fields)
- );
+ $expected = [
+ (object) [
+ 'name' => 'id',
+ 'type' => 'int',
+ 'max_length' => 10,
+ 'nullable' => false,
+ 'default' => null, // The default value is not defined.
+ // 'primary_key' => 1,
+ ],
+ (object) [
+ 'name' => 'text_not_null',
+ 'type' => 'varchar',
+ 'max_length' => 64,
+ 'nullable' => false,
+ 'default' => null, // The default value is not defined.
+ // 'primary_key' => 0,
+ ],
+ (object) [
+ 'name' => 'text_null',
+ 'type' => 'varchar',
+ 'max_length' => 64,
+ 'nullable' => true,
+ 'default' => null, // The default value is not defined.
+ // 'primary_key' => 0,
+ ],
+ (object) [
+ 'name' => 'int_default_0',
+ 'type' => 'int',
+ 'max_length' => 10,
+ 'nullable' => false,
+ 'default' => '((0))', // int 0
+ // 'primary_key' => 0,
+ ],
+ (object) [
+ 'name' => 'text_default_null',
+ 'type' => 'varchar',
+ 'max_length' => 64,
+ 'nullable' => true,
+ 'default' => '(NULL)', // NULL value
+ // 'primary_key' => 0,
+ ],
+ (object) [
+ 'name' => 'text_default_text_null',
+ 'type' => 'varchar',
+ 'max_length' => 64,
+ 'nullable' => false,
+ 'default' => "('null')", // string "null"
+ // 'primary_key' => 0,
+ ],
+ (object) [
+ 'name' => 'text_default_abc',
+ 'type' => 'varchar',
+ 'max_length' => 64,
+ 'nullable' => false,
+ 'default' => "('abc')", // string "abc"
+ // 'primary_key' => 0,
+ ],
+ ];
+ $this->assertSameFieldData($expected, $fields);
}
}
diff --git a/tests/system/Database/Live/SQLite3/GetFieldDataTest.php b/tests/system/Database/Live/SQLite3/GetFieldDataTest.php
index 00bc08e2cffd..2f14d2f60ba4 100644
--- a/tests/system/Database/Live/SQLite3/GetFieldDataTest.php
+++ b/tests/system/Database/Live/SQLite3/GetFieldDataTest.php
@@ -42,67 +42,65 @@ public function testGetFieldDataDefault(): void
$fields = $this->db->getFieldData($this->table);
- $this->assertJsonStringEqualsJsonString(
- json_encode([
- (object) [
- 'name' => 'id',
- 'type' => 'INTEGER',
- 'max_length' => null,
- 'default' => null, // The default value is not defined.
- 'primary_key' => 1,
- 'nullable' => true,
- ],
- (object) [
- 'name' => 'text_not_null',
- 'type' => 'VARCHAR',
- 'max_length' => null,
- 'default' => null, // The default value is not defined.
- 'primary_key' => 0,
- 'nullable' => false,
- ],
- (object) [
- 'name' => 'text_null',
- 'type' => 'VARCHAR',
- 'max_length' => null,
- 'default' => null, // The default value is not defined.
- 'primary_key' => 0,
- 'nullable' => true,
- ],
- (object) [
- 'name' => 'int_default_0',
- 'type' => 'INT',
- 'max_length' => null,
- 'default' => '0', // int 0
- 'primary_key' => 0,
- 'nullable' => false,
- ],
- (object) [
- 'name' => 'text_default_null',
- 'type' => 'VARCHAR',
- 'max_length' => null,
- 'default' => 'NULL', // NULL value
- 'primary_key' => 0,
- 'nullable' => true,
- ],
- (object) [
- 'name' => 'text_default_text_null',
- 'type' => 'VARCHAR',
- 'max_length' => null,
- 'default' => "'null'", // string "null"
- 'primary_key' => 0,
- 'nullable' => false,
- ],
- (object) [
- 'name' => 'text_default_abc',
- 'type' => 'VARCHAR',
- 'max_length' => null,
- 'default' => "'abc'", // string "abc"
- 'primary_key' => 0,
- 'nullable' => false,
- ],
- ]),
- json_encode($fields)
- );
+ $expected = [
+ (object) [
+ 'name' => 'id',
+ 'type' => 'INTEGER',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => null, // The default value is not defined.
+ 'primary_key' => 1,
+ ],
+ (object) [
+ 'name' => 'text_not_null',
+ 'type' => 'VARCHAR',
+ 'max_length' => null,
+ 'nullable' => false,
+ 'default' => null, // The default value is not defined.
+ 'primary_key' => 0,
+ ],
+ (object) [
+ 'name' => 'text_null',
+ 'type' => 'VARCHAR',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => null, // The default value is not defined.
+ 'primary_key' => 0,
+ ],
+ (object) [
+ 'name' => 'int_default_0',
+ 'type' => 'INT',
+ 'max_length' => null,
+ 'nullable' => false,
+ 'default' => '0', // int 0
+ 'primary_key' => 0,
+ ],
+ (object) [
+ 'name' => 'text_default_null',
+ 'type' => 'VARCHAR',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => 'NULL', // NULL value
+ 'primary_key' => 0,
+ ],
+ (object) [
+ 'name' => 'text_default_text_null',
+ 'type' => 'VARCHAR',
+ 'max_length' => null,
+ 'nullable' => false,
+ 'default' => "'null'", // string "null"
+ 'primary_key' => 0,
+ ],
+ (object) [
+ 'name' => 'text_default_abc',
+ 'type' => 'VARCHAR',
+ 'max_length' => null,
+ 'nullable' => false,
+ 'default' => "'abc'", // string "abc"
+ 'primary_key' => 0,
+ ],
+ ];
+ $this->assertSameFieldData($expected, $fields);
}
protected function createTableCompositePrimaryKey()
@@ -133,34 +131,32 @@ public function testGetFieldDataCompositePrimaryKey(): void
$fields = $this->db->getFieldData($this->table);
- $this->assertJsonStringEqualsJsonString(
- json_encode([
- (object) [
- 'name' => 'pk1',
- 'type' => 'VARCHAR',
- 'max_length' => null,
- 'default' => null,
- 'primary_key' => 1,
- 'nullable' => false,
- ],
- (object) [
- 'name' => 'pk2',
- 'type' => 'VARCHAR',
- 'max_length' => null,
- 'default' => null,
- 'primary_key' => 1,
- 'nullable' => false,
- ],
- (object) [
- 'name' => 'text',
- 'type' => 'VARCHAR',
- 'max_length' => null,
- 'default' => null,
- 'primary_key' => 0,
- 'nullable' => false,
- ],
- ]),
- json_encode($fields)
- );
+ $expected = [
+ (object) [
+ 'name' => 'pk1',
+ 'type' => 'VARCHAR',
+ 'max_length' => null,
+ 'nullable' => false,
+ 'default' => null,
+ 'primary_key' => 1,
+ ],
+ (object) [
+ 'name' => 'pk2',
+ 'type' => 'VARCHAR',
+ 'max_length' => null,
+ 'nullable' => false,
+ 'default' => null,
+ 'primary_key' => 1,
+ ],
+ (object) [
+ 'name' => 'text',
+ 'type' => 'VARCHAR',
+ 'max_length' => null,
+ 'nullable' => false,
+ 'default' => null,
+ 'primary_key' => 0,
+ ],
+ ];
+ $this->assertSameFieldData($expected, $fields);
}
}
From 2b8b6617ec078406e22df6c456bd373a3e2ad6e5 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Wed, 31 Jan 2024 11:34:22 +0900
Subject: [PATCH 051/164] docs: fix supported SQL Server version
We are using OFFSET.
SQL Server 2012 also reached the end of life: Jul 12, 2022.
https://learn.microsoft.com/en-us/lifecycle/products/microsoft-sql-server-2012
---
user_guide_src/source/intro/requirements.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/user_guide_src/source/intro/requirements.rst b/user_guide_src/source/intro/requirements.rst
index e025198a8cc0..a21f8b2a9cdc 100644
--- a/user_guide_src/source/intro/requirements.rst
+++ b/user_guide_src/source/intro/requirements.rst
@@ -56,7 +56,7 @@ Currently supported databases are:
- MySQL via the ``MySQLi`` driver (version 5.1 and above only)
- PostgreSQL via the ``Postgre`` driver (version 7.4 and above only)
- SQLite3 via the ``SQLite3`` driver
- - Microsoft SQL Server via the ``SQLSRV`` driver (version 2005 and above only)
+ - Microsoft SQL Server via the ``SQLSRV`` driver (version 2012 and above only)
- Oracle Database via the ``OCI8`` driver (version 12.1 and above only)
Not all of the drivers have been converted/rewritten for CodeIgniter4.
From 60042fba17267e56a8879e80498825c20ed30c87 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Wed, 31 Jan 2024 20:47:33 +0900
Subject: [PATCH 052/164] docs: fix doc comments
I think there is no way to set 404 closure in the constructor.
---
app/Config/Routing.php | 5 ++---
system/Config/Routing.php | 5 ++---
2 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/app/Config/Routing.php b/app/Config/Routing.php
index 8d3c773157cf..c0234da8df91 100644
--- a/app/Config/Routing.php
+++ b/app/Config/Routing.php
@@ -63,13 +63,12 @@ class Routing extends BaseRouting
/**
* Sets the class/method that should be called if routing doesn't
- * find a match. It can be either a closure or the controller/method
- * name exactly like a route is defined: Users::index
+ * find a match. It can be the controller/method name like: Users::index
*
* This setting is passed to the Router class and handled there.
*
* If you want to use a closure, you will have to set it in the
- * class constructor or the routes file by calling:
+ * routes file by calling:
*
* $routes->set404Override(function() {
* // Do something here
diff --git a/system/Config/Routing.php b/system/Config/Routing.php
index e6d25138f8f0..5f5d9db620a4 100644
--- a/system/Config/Routing.php
+++ b/system/Config/Routing.php
@@ -61,13 +61,12 @@ class Routing extends BaseConfig
/**
* Sets the class/method that should be called if routing doesn't
- * find a match. It can be either a closure or the controller/method
- * name exactly like a route is defined: Users::index
+ * find a match. It can be the controller/method name like: Users::index
*
* This setting is passed to the Router class and handled there.
*
* If you want to use a closure, you will have to set it in the
- * class constructor or the routes file by calling:
+ * routes file by calling:
*
* $routes->set404Override(function() {
* // Do something here
From c4de4f97343363c7fc79ec61bae4e50b33e610e1 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Tue, 30 Jan 2024 16:59:06 +0900
Subject: [PATCH 053/164] test: add tests for getFieldData() type
---
.../Live/AbstractGetFieldDataTest.php | 58 ++++++
.../Database/Live/MySQLi/GetFieldDataTest.php | 179 +++++++++++++++++
.../Database/Live/OCI8/GetFieldDataTest.php | 185 +++++++++++++++++-
.../Live/Postgre/GetFieldDataTest.php | 123 ++++++++++++
.../Database/Live/SQLSRV/GetFieldDataTest.php | 130 ++++++++++++
.../Live/SQLite3/GetFieldDataTest.php | 179 +++++++++++++++++
6 files changed, 847 insertions(+), 7 deletions(-)
diff --git a/tests/system/Database/Live/AbstractGetFieldDataTest.php b/tests/system/Database/Live/AbstractGetFieldDataTest.php
index 859c37718902..1dc594094c30 100644
--- a/tests/system/Database/Live/AbstractGetFieldDataTest.php
+++ b/tests/system/Database/Live/AbstractGetFieldDataTest.php
@@ -91,6 +91,64 @@ protected function createTableForDefault()
$this->forge->createTable($this->table);
}
+ protected function createTableForType()
+ {
+ $this->forge->dropTable($this->table, true);
+
+ // missing types:
+ // TINYINT,MEDIUMINT,BIT,YEAR,BINARY,VARBINARY,TINYTEXT,LONGTEXT,
+ // JSON,Spatial data types
+ // `id` must be INTEGER else SQLite3 error on not null for autoincrement field.
+ $fields = [
+ 'id' => ['type' => 'INTEGER', 'constraint' => 20, 'auto_increment' => true],
+ 'type_varchar' => ['type' => 'VARCHAR', 'constraint' => 40, 'null' => true],
+ 'type_char' => ['type' => 'CHAR', 'constraint' => 10, 'null' => true],
+ // TEXT should not be used on SQLSRV. It is deprecated.
+ 'type_text' => ['type' => 'TEXT', 'null' => true],
+ 'type_smallint' => ['type' => 'SMALLINT', 'null' => true],
+ 'type_integer' => ['type' => 'INTEGER', 'null' => true],
+ 'type_float' => ['type' => 'FLOAT', 'null' => true],
+ 'type_numeric' => ['type' => 'NUMERIC', 'constraint' => '18,2', 'null' => true],
+ 'type_date' => ['type' => 'DATE', 'null' => true],
+ 'type_time' => ['type' => 'TIME', 'null' => true],
+ // On SQLSRV `datetime2` is recommended.
+ 'type_datetime' => ['type' => 'DATETIME', 'null' => true],
+ 'type_timestamp' => ['type' => 'TIMESTAMP', 'null' => true],
+ 'type_bigint' => ['type' => 'BIGINT', 'null' => true],
+ 'type_real' => ['type' => 'REAL', 'null' => true],
+ 'type_enum' => ['type' => 'ENUM', 'constraint' => ['appel', 'pears'], 'null' => true],
+ 'type_set' => ['type' => 'SET', 'constraint' => ['one', 'two'], 'null' => true],
+ 'type_mediumtext' => ['type' => 'MEDIUMTEXT', 'null' => true],
+ 'type_double' => ['type' => 'DOUBLE', 'null' => true],
+ 'type_decimal' => ['type' => 'DECIMAL', 'constraint' => '18,4', 'null' => true],
+ 'type_blob' => ['type' => 'BLOB', 'null' => true],
+ 'type_boolean' => ['type' => 'BOOLEAN', 'null' => true],
+ ];
+
+ if ($this->db->DBDriver === 'Postgre') {
+ unset(
+ $fields['type_enum'],
+ $fields['type_set'],
+ $fields['type_mediumtext'],
+ $fields['type_double'],
+ $fields['type_blob']
+ );
+ }
+
+ if ($this->db->DBDriver === 'SQLSRV') {
+ unset(
+ $fields['type_set'],
+ $fields['type_mediumtext'],
+ $fields['type_double'],
+ $fields['type_blob']
+ );
+ }
+
+ $this->forge->addField($fields);
+ $this->forge->addKey('id', true);
+ $this->forge->createTable($this->table);
+ }
+
abstract public function testGetFieldDataDefault(): void;
protected function assertSameFieldData(array $expected, array $actual)
diff --git a/tests/system/Database/Live/MySQLi/GetFieldDataTest.php b/tests/system/Database/Live/MySQLi/GetFieldDataTest.php
index f5c9a0761ea4..93c1bddc9183 100644
--- a/tests/system/Database/Live/MySQLi/GetFieldDataTest.php
+++ b/tests/system/Database/Live/MySQLi/GetFieldDataTest.php
@@ -112,4 +112,183 @@ public function testGetFieldDataDefault(): void
];
$this->assertSameFieldData($expected, $fields);
}
+
+ public function testGetFieldDataType(): void
+ {
+ $this->createTableForType();
+
+ $fields = $this->db->getFieldData($this->table);
+
+ $expected = [
+ 0 => (object) [
+ 'name' => 'id',
+ 'type' => 'int',
+ 'max_length' => $this->isOldMySQL() ? 20 : null,
+ 'nullable' => false,
+ 'default' => null,
+ 'primary_key' => 1,
+ ],
+ 1 => (object) [
+ 'name' => 'type_varchar',
+ 'type' => 'varchar',
+ 'max_length' => 40,
+ 'nullable' => true,
+ 'default' => null,
+ 'primary_key' => 0,
+ ],
+ 2 => (object) [
+ 'name' => 'type_char',
+ 'type' => 'char',
+ 'max_length' => 10,
+ 'nullable' => true,
+ 'default' => null,
+ 'primary_key' => 0,
+ ],
+ 3 => (object) [
+ 'name' => 'type_text',
+ 'type' => 'text',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => null,
+ 'primary_key' => 0,
+ ],
+ 4 => (object) [
+ 'name' => 'type_smallint',
+ 'type' => 'smallint',
+ 'max_length' => $this->isOldMySQL() ? 6 : null,
+ 'nullable' => true,
+ 'default' => null,
+ 'primary_key' => 0,
+ ],
+ 5 => (object) [
+ 'name' => 'type_integer',
+ 'type' => 'int',
+ 'max_length' => $this->isOldMySQL() ? 11 : null,
+ 'nullable' => true,
+ 'default' => null,
+ 'primary_key' => 0,
+ ],
+ 6 => (object) [
+ 'name' => 'type_float',
+ 'type' => 'float',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => null,
+ 'primary_key' => 0,
+ ],
+ 7 => (object) [
+ 'name' => 'type_numeric',
+ 'type' => 'decimal',
+ 'max_length' => 18,
+ 'nullable' => true,
+ 'default' => null,
+ 'primary_key' => 0,
+ ],
+ 8 => (object) [
+ 'name' => 'type_date',
+ 'type' => 'date',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => null,
+ 'primary_key' => 0,
+ ],
+ 9 => (object) [
+ 'name' => 'type_time',
+ 'type' => 'time',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => null,
+ 'primary_key' => 0,
+ ],
+ 10 => (object) [
+ 'name' => 'type_datetime',
+ 'type' => 'datetime',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => null,
+ 'primary_key' => 0,
+ ],
+ 11 => (object) [
+ 'name' => 'type_timestamp',
+ 'type' => 'timestamp',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => null,
+ 'primary_key' => 0,
+ ],
+ 12 => (object) [
+ 'name' => 'type_bigint',
+ 'type' => 'bigint',
+ 'max_length' => $this->isOldMySQL() ? 20 : null,
+ 'nullable' => true,
+ 'default' => null,
+ 'primary_key' => 0,
+ ],
+ 13 => (object) [
+ 'name' => 'type_real',
+ 'type' => 'double',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => null,
+ 'primary_key' => 0,
+ ],
+ 14 => (object) [
+ 'name' => 'type_enum',
+ 'type' => 'enum',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => null,
+ 'primary_key' => 0,
+ ],
+ 15 => (object) [
+ 'name' => 'type_set',
+ 'type' => 'set',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => null,
+ 'primary_key' => 0,
+ ],
+ 16 => (object) [
+ 'name' => 'type_mediumtext',
+ 'type' => 'mediumtext',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => null,
+ 'primary_key' => 0,
+ ],
+ 17 => (object) [
+ 'name' => 'type_double',
+ 'type' => 'double',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => null,
+ 'primary_key' => 0,
+ ],
+ 18 => (object) [
+ 'name' => 'type_decimal',
+ 'type' => 'decimal',
+ 'max_length' => 18,
+ 'nullable' => true,
+ 'default' => null,
+ 'primary_key' => 0,
+ ],
+ 19 => (object) [
+ 'name' => 'type_blob',
+ 'type' => 'blob',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => null,
+ 'primary_key' => 0,
+ ],
+ 20 => (object) [
+ 'name' => 'type_boolean',
+ 'type' => 'tinyint',
+ 'max_length' => 1,
+ 'nullable' => true,
+ 'default' => null,
+ 'primary_key' => 0,
+ ],
+ ];
+ $this->assertSameFieldData($expected, $fields);
+ }
}
diff --git a/tests/system/Database/Live/OCI8/GetFieldDataTest.php b/tests/system/Database/Live/OCI8/GetFieldDataTest.php
index 89750fd60bf8..ec985252214f 100644
--- a/tests/system/Database/Live/OCI8/GetFieldDataTest.php
+++ b/tests/system/Database/Live/OCI8/GetFieldDataTest.php
@@ -15,6 +15,8 @@
use CodeIgniter\Database\Live\AbstractGetFieldDataTest;
use Config\Database;
+use LogicException;
+use stdClass;
/**
* @group DatabaseLive
@@ -32,19 +34,30 @@ protected function createForge(): void
$this->forge = Database::forge($this->db);
}
+ private function getFieldMetaData(string $column, string $table): stdClass
+ {
+ $fields = $this->db->getFieldData($table);
+
+ $name = array_search(
+ $column,
+ array_column($fields, 'name'),
+ true
+ );
+
+ if ($name === false) {
+ throw new LogicException('Field not found: ' . $column);
+ }
+
+ return $fields[$name];
+ }
+
public function testGetFieldDataDefault(): void
{
$this->createTableForDefault();
$fields = $this->db->getFieldData($this->table);
- $data = [];
-
- foreach ($fields as $obj) {
- $data[$obj->name] = $obj;
- }
-
- $idDefault = $data['id']->default;
+ $idDefault = $this->getFieldMetaData('id', $this->table)->default;
$this->assertMatchesRegularExpression('/"ORACLE"."ISEQ\$\$_[0-9]+".nextval/', $idDefault);
$expected = [
@@ -107,4 +120,162 @@ public function testGetFieldDataDefault(): void
];
$this->assertSameFieldData($expected, $fields);
}
+
+ public function testGetFieldDataType(): void
+ {
+ $this->createTableForType();
+
+ $fields = $this->db->getFieldData($this->table);
+
+ $expected = [
+ 0 => (object) [
+ 'name' => 'id',
+ 'type' => 'NUMBER',
+ 'max_length' => '20',
+ 'nullable' => false,
+ 'default' => $this->getFieldMetaData('id', $this->table)->default,
+ ],
+ 1 => (object) [
+ 'name' => 'type_varchar',
+ 'type' => 'VARCHAR2',
+ 'max_length' => '40',
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 2 => (object) [
+ 'name' => 'type_char',
+ 'type' => 'CHAR',
+ 'max_length' => '10',
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 3 => (object) [
+ 'name' => 'type_text',
+ 'type' => 'VARCHAR2',
+ 'max_length' => '4000',
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 4 => (object) [
+ 'name' => 'type_smallint',
+ 'type' => 'NUMBER',
+ 'max_length' => '5',
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 5 => (object) [
+ 'name' => 'type_integer',
+ 'type' => 'NUMBER',
+ 'max_length' => '11',
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 6 => (object) [
+ 'name' => 'type_float',
+ 'type' => 'FLOAT',
+ 'max_length' => '126',
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 7 => (object) [
+ 'name' => 'type_numeric',
+ 'type' => 'NUMBER',
+ 'max_length' => '18',
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 8 => (object) [
+ 'name' => 'type_date',
+ 'type' => 'DATE',
+ 'max_length' => '7',
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 9 => (object) [
+ 'name' => 'type_time',
+ 'type' => 'DATE',
+ 'max_length' => '7',
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 10 => (object) [
+ 'name' => 'type_datetime',
+ 'type' => 'DATE',
+ 'max_length' => '7',
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 11 => (object) [
+ 'name' => 'type_timestamp',
+ 'type' => 'TIMESTAMP(6)',
+ 'max_length' => '11',
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 12 => (object) [
+ 'name' => 'type_bigint',
+ 'type' => 'NUMBER',
+ 'max_length' => '19',
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 13 => (object) [
+ 'name' => 'type_real',
+ 'type' => 'FLOAT',
+ 'max_length' => '63',
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 14 => (object) [
+ 'name' => 'type_enum',
+ 'type' => 'VARCHAR2',
+ 'max_length' => '5',
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 15 => (object) [
+ 'name' => 'type_set',
+ 'type' => 'VARCHAR2',
+ 'max_length' => '3',
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 16 => (object) [
+ 'name' => 'type_mediumtext',
+ 'type' => 'VARCHAR2',
+ 'max_length' => '4000',
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 17 => (object) [
+ 'name' => 'type_double',
+ 'type' => 'FLOAT',
+ 'max_length' => '126',
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 18 => (object) [
+ 'name' => 'type_decimal',
+ 'type' => 'NUMBER',
+ 'max_length' => '18',
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 19 => (object) [
+ 'name' => 'type_blob',
+ 'type' => 'BLOB',
+ 'max_length' => '4000',
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 20 => (object) [
+ 'name' => 'type_boolean',
+ 'type' => 'NUMBER',
+ 'max_length' => '1',
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ ];
+ $this->assertSameFieldData($expected, $fields);
+ }
}
diff --git a/tests/system/Database/Live/Postgre/GetFieldDataTest.php b/tests/system/Database/Live/Postgre/GetFieldDataTest.php
index 514bb7011c74..7ff4d57b5bce 100644
--- a/tests/system/Database/Live/Postgre/GetFieldDataTest.php
+++ b/tests/system/Database/Live/Postgre/GetFieldDataTest.php
@@ -98,4 +98,127 @@ public function testGetFieldDataDefault(): void
];
$this->assertSameFieldData($expected, $fields);
}
+
+ public function testGetFieldDataType(): void
+ {
+ $this->createTableForType();
+
+ $fields = $this->db->getFieldData($this->table);
+
+ $expected = [
+ 0 => (object) [
+ 'name' => 'id',
+ 'type' => 'integer',
+ 'max_length' => '32',
+ 'nullable' => false,
+ 'default' => 'nextval(\'db_test1_id_seq\'::regclass)',
+ ],
+ 1 => (object) [
+ 'name' => 'type_varchar',
+ 'type' => 'character varying',
+ 'max_length' => '40',
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 2 => (object) [
+ 'name' => 'type_char',
+ 'type' => 'character',
+ 'max_length' => '10',
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 3 => (object) [
+ 'name' => 'type_text',
+ 'type' => 'text',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 4 => (object) [
+ 'name' => 'type_smallint',
+ 'type' => 'smallint',
+ 'max_length' => '16',
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 5 => (object) [
+ 'name' => 'type_integer',
+ 'type' => 'integer',
+ 'max_length' => '32',
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 6 => (object) [
+ 'name' => 'type_float',
+ 'type' => 'double precision',
+ 'max_length' => '53',
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 7 => (object) [
+ 'name' => 'type_numeric',
+ 'type' => 'numeric',
+ 'max_length' => '18',
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 8 => (object) [
+ 'name' => 'type_date',
+ 'type' => 'date',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 9 => (object) [
+ 'name' => 'type_time',
+ 'type' => 'time without time zone',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 10 => (object) [
+ 'name' => 'type_datetime',
+ 'type' => 'timestamp without time zone',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 11 => (object) [
+ 'name' => 'type_timestamp',
+ 'type' => 'timestamp without time zone',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 12 => (object) [
+ 'name' => 'type_bigint',
+ 'type' => 'bigint',
+ 'max_length' => '64',
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 13 => (object) [
+ 'name' => 'type_real',
+ 'type' => 'real',
+ 'max_length' => '24',
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 14 => (object) [
+ 'name' => 'type_decimal',
+ 'type' => 'numeric',
+ 'max_length' => '18',
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 15 => (object) [
+ 'name' => 'type_boolean',
+ 'type' => 'boolean',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ ];
+ $this->assertSameFieldData($expected, $fields);
+ }
}
diff --git a/tests/system/Database/Live/SQLSRV/GetFieldDataTest.php b/tests/system/Database/Live/SQLSRV/GetFieldDataTest.php
index ada673292ddd..e6f924a28aba 100644
--- a/tests/system/Database/Live/SQLSRV/GetFieldDataTest.php
+++ b/tests/system/Database/Live/SQLSRV/GetFieldDataTest.php
@@ -98,4 +98,134 @@ public function testGetFieldDataDefault(): void
];
$this->assertSameFieldData($expected, $fields);
}
+
+ public function testGetFieldDataType(): void
+ {
+ $this->createTableForType();
+
+ $fields = $this->db->getFieldData($this->table);
+
+ $expected = [
+ 0 => (object) [
+ 'name' => 'id',
+ 'type' => 'int',
+ 'max_length' => 10,
+ 'nullable' => false,
+ 'default' => null,
+ ],
+ 1 => (object) [
+ 'name' => 'type_varchar',
+ 'type' => 'varchar',
+ 'max_length' => 40,
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 2 => (object) [
+ 'name' => 'type_char',
+ 'type' => 'char',
+ 'max_length' => 10,
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 3 => (object) [
+ 'name' => 'type_text',
+ 'type' => 'text',
+ 'max_length' => 2_147_483_647,
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 4 => (object) [
+ 'name' => 'type_smallint',
+ 'type' => 'smallint',
+ 'max_length' => 5,
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 5 => (object) [
+ 'name' => 'type_integer',
+ 'type' => 'int',
+ 'max_length' => 10,
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 6 => (object) [
+ 'name' => 'type_float',
+ 'type' => 'float',
+ 'max_length' => 53,
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 7 => (object) [
+ 'name' => 'type_numeric',
+ 'type' => 'numeric',
+ 'max_length' => 18,
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 8 => (object) [
+ 'name' => 'type_date',
+ 'type' => 'date',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 9 => (object) [
+ 'name' => 'type_time',
+ 'type' => 'time',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 10 => (object) [
+ 'name' => 'type_datetime',
+ 'type' => 'datetime',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 11 => (object) [
+ 'name' => 'type_timestamp',
+ 'type' => 'datetime',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 12 => (object) [
+ 'name' => 'type_bigint',
+ 'type' => 'bigint',
+ 'max_length' => 19,
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 13 => (object) [
+ 'name' => 'type_real',
+ 'type' => 'real',
+ 'max_length' => 24,
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 14 => (object) [
+ 'name' => 'type_enum',
+ 'type' => 'text',
+ 'max_length' => 2_147_483_647,
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 15 => (object) [
+ 'name' => 'type_decimal',
+ 'type' => 'decimal',
+ 'max_length' => 18,
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ 16 => (object) [
+ 'name' => 'type_boolean',
+ 'type' => 'bit',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => null,
+ ],
+ ];
+ $this->assertSameFieldData($expected, $fields);
+ }
}
diff --git a/tests/system/Database/Live/SQLite3/GetFieldDataTest.php b/tests/system/Database/Live/SQLite3/GetFieldDataTest.php
index 2f14d2f60ba4..319706a90e53 100644
--- a/tests/system/Database/Live/SQLite3/GetFieldDataTest.php
+++ b/tests/system/Database/Live/SQLite3/GetFieldDataTest.php
@@ -159,4 +159,183 @@ public function testGetFieldDataCompositePrimaryKey(): void
];
$this->assertSameFieldData($expected, $fields);
}
+
+ public function testGetFieldDataType(): void
+ {
+ $this->createTableForType();
+
+ $fields = $this->db->getFieldData($this->table);
+
+ $expected = [
+ 0 => (object) [
+ 'name' => 'id',
+ 'type' => 'INTEGER',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => null,
+ 'primary_key' => 1,
+ ],
+ 1 => (object) [
+ 'name' => 'type_varchar',
+ 'type' => 'VARCHAR',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => null,
+ 'primary_key' => 0,
+ ],
+ 2 => (object) [
+ 'name' => 'type_char',
+ 'type' => 'CHAR',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => null,
+ 'primary_key' => 0,
+ ],
+ 3 => (object) [
+ 'name' => 'type_text',
+ 'type' => 'TEXT',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => null,
+ 'primary_key' => 0,
+ ],
+ 4 => (object) [
+ 'name' => 'type_smallint',
+ 'type' => 'SMALLINT',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => null,
+ 'primary_key' => 0,
+ ],
+ 5 => (object) [
+ 'name' => 'type_integer',
+ 'type' => 'INTEGER',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => null,
+ 'primary_key' => 0,
+ ],
+ 6 => (object) [
+ 'name' => 'type_float',
+ 'type' => 'FLOAT',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => null,
+ 'primary_key' => 0,
+ ],
+ 7 => (object) [
+ 'name' => 'type_numeric',
+ 'type' => 'NUMERIC',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => null,
+ 'primary_key' => 0,
+ ],
+ 8 => (object) [
+ 'name' => 'type_date',
+ 'type' => 'DATE',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => null,
+ 'primary_key' => 0,
+ ],
+ 9 => (object) [
+ 'name' => 'type_time',
+ 'type' => 'TIME',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => null,
+ 'primary_key' => 0,
+ ],
+ 10 => (object) [
+ 'name' => 'type_datetime',
+ 'type' => 'DATETIME',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => null,
+ 'primary_key' => 0,
+ ],
+ 11 => (object) [
+ 'name' => 'type_timestamp',
+ 'type' => 'TIMESTAMP',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => null,
+ 'primary_key' => 0,
+ ],
+ 12 => (object) [
+ 'name' => 'type_bigint',
+ 'type' => 'BIGINT',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => null,
+ 'primary_key' => 0,
+ ],
+ 13 => (object) [
+ 'name' => 'type_real',
+ 'type' => 'REAL',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => null,
+ 'primary_key' => 0,
+ ],
+ 14 => (object) [
+ 'name' => 'type_enum',
+ 'type' => 'TEXT',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => null,
+ 'primary_key' => 0,
+ ],
+ 15 => (object) [
+ 'name' => 'type_set',
+ 'type' => 'TEXT',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => null,
+ 'primary_key' => 0,
+ ],
+ 16 => (object) [
+ 'name' => 'type_mediumtext',
+ 'type' => 'MEDIUMTEXT',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => null,
+ 'primary_key' => 0,
+ ],
+ 17 => (object) [
+ 'name' => 'type_double',
+ 'type' => 'DOUBLE',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => null,
+ 'primary_key' => 0,
+ ],
+ 18 => (object) [
+ 'name' => 'type_decimal',
+ 'type' => 'DECIMAL',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => null,
+ 'primary_key' => 0,
+ ],
+ 19 => (object) [
+ 'name' => 'type_blob',
+ 'type' => 'BLOB',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => null,
+ 'primary_key' => 0,
+ ],
+ 20 => (object) [
+ 'name' => 'type_boolean',
+ 'type' => 'INT',
+ 'max_length' => null,
+ 'nullable' => true,
+ 'default' => null,
+ 'primary_key' => 0,
+ ],
+ ];
+ $this->assertSameFieldData($expected, $fields);
+ }
}
From 3438fe3ccd0a9897d7c4c1e335f63e3281633fe5 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Thu, 1 Feb 2024 11:29:47 +0900
Subject: [PATCH 054/164] docs: decroate variables
---
user_guide_src/source/testing/feature.rst | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/user_guide_src/source/testing/feature.rst b/user_guide_src/source/testing/feature.rst
index f113eab68cce..e958011d524d 100644
--- a/user_guide_src/source/testing/feature.rst
+++ b/user_guide_src/source/testing/feature.rst
@@ -29,12 +29,12 @@ Requesting a Page
Essentially, feature tests simply allows you to call an endpoint on your application and get the results back.
To do this, you use the ``call()`` method.
-1. The first parameter is the HTTP method to use (most frequently either GET or POST).
+1. The first parameter is the HTTP method to use (most frequently either ``GET`` or ``POST``).
2. The second parameter is the URI path on your site to test.
3. The third parameter ``$params`` accepts an array that is used to populate the
superglobal variables for the HTTP verb you are using. So, a method of **GET**
- would have the **$_GET** variable populated, while a **POST** request would
- have the **$_POST** array populated. The ``$params`` is also used in
+ would have the ``$_GET`` variable populated, while a **POST** request would
+ have the ``$_POST`` array populated. The ``$params`` is also used in
:ref:`feature-formatting-the-request`.
.. note:: The ``$params`` array does not make sense for every HTTP verb, but is
From fd7c8e2248eb88a4ebf6ddd29587ba50223dfbd0 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Thu, 1 Feb 2024 11:30:18 +0900
Subject: [PATCH 055/164] docs: add `:lines: 2-`
---
user_guide_src/source/testing/feature.rst | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/user_guide_src/source/testing/feature.rst b/user_guide_src/source/testing/feature.rst
index e958011d524d..00100f8a7885 100644
--- a/user_guide_src/source/testing/feature.rst
+++ b/user_guide_src/source/testing/feature.rst
@@ -41,6 +41,7 @@ To do this, you use the ``call()`` method.
included for consistency.
.. literalinclude:: feature/002.php
+ :lines: 2-
Shorthand Methods
-----------------
@@ -48,6 +49,7 @@ Shorthand Methods
Shorthand methods for each of the HTTP verbs exist to ease typing and make things clearer:
.. literalinclude:: feature/003.php
+ :lines: 2-
Setting Different Routes
------------------------
@@ -56,6 +58,7 @@ You can use a custom collection of routes by passing an array of "routes" into t
override any existing routes in the system:
.. literalinclude:: feature/004.php
+ :lines: 2-
Each of the "routes" is a 3 element array containing the HTTP verb (or "add" for all),
the URI to match, and the routing destination.
@@ -68,6 +71,7 @@ of key/value pairs that should exist within the ``$_SESSION`` variable when this
that the current values of ``$_SESSION`` should be used. This is handy for testing authentication and more.
.. literalinclude:: feature/005.php
+ :lines: 2-
Setting Headers
---------------
@@ -76,6 +80,7 @@ You can set header values with the ``withHeaders()`` method. This takes an array
passed as a header into the call:
.. literalinclude:: feature/006.php
+ :lines: 2-
Bypassing Events
----------------
@@ -84,6 +89,7 @@ Events are handy to use in your application, but can be problematic during testi
to send out emails. You can tell the system to skip any event handling with the ``skipEvents()`` method:
.. literalinclude:: feature/007.php
+ :lines: 2-
.. _feature-formatting-the-request:
@@ -100,6 +106,7 @@ body of the request in the given format.
This will also set the `Content-Type` header for your request accordingly.
.. literalinclude:: feature/008.php
+ :lines: 2-
.. _feature-setting-the-body:
From de8d9085f0ff6db36058a930ea63c88129955468 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Thu, 1 Feb 2024 11:30:33 +0900
Subject: [PATCH 056/164] docs: fix sample code
---
user_guide_src/source/testing/feature/001.php | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/user_guide_src/source/testing/feature/001.php b/user_guide_src/source/testing/feature/001.php
index 0ab640465052..9884535d41f2 100644
--- a/user_guide_src/source/testing/feature/001.php
+++ b/user_guide_src/source/testing/feature/001.php
@@ -1,11 +1,12 @@
Date: Thu, 1 Feb 2024 11:36:09 +0900
Subject: [PATCH 057/164] docs: fix section order in testing
"Mocking" is about PHPUnit testing.
---
user_guide_src/source/testing/index.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/user_guide_src/source/testing/index.rst b/user_guide_src/source/testing/index.rst
index 949a68b99b51..0e4ddf996171 100644
--- a/user_guide_src/source/testing/index.rst
+++ b/user_guide_src/source/testing/index.rst
@@ -14,6 +14,6 @@ The following sections should get you quickly testing your applications.
Controller Testing
HTTP Testing
response
+ Mocking
benchmark
debugging
- Mocking
From 0a5adfc460de541124790cc14cab6e55772e17f9 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Thu, 1 Feb 2024 10:44:18 +0900
Subject: [PATCH 058/164] docs: update description for CI apps
Appstarter and Zip installation provide phpunit.xml.dist for applications.
---
user_guide_src/source/testing/overview.rst | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/user_guide_src/source/testing/overview.rst b/user_guide_src/source/testing/overview.rst
index 6cd60c100e73..2b447ee1d5d1 100644
--- a/user_guide_src/source/testing/overview.rst
+++ b/user_guide_src/source/testing/overview.rst
@@ -60,12 +60,11 @@ Testing Your Application
PHPUnit Configuration
=====================
-The framework has a ``phpunit.xml.dist`` file in the project root. This controls unit
-testing of the framework itself. If you provide your own ``phpunit.xml``, it will
-over-ride this.
+In your CodeIgniter project root, there is the ``phpunit.xml.dist`` file. This
+controls unit testing of your application. If you provide your own ``phpunit.xml``,
+it will over-ride this.
-Your ``phpunit.xml`` should exclude the ``system`` folder, as well as any ``vendor`` or
-``ThirdParty`` folders, if you are unit testing your application.
+By default, test files are placed under the **tests** directory in the project root.
The Test Class
==============
From 6afe975df5b8dbfcab9449aee324c0597d1e60d0 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Thu, 1 Feb 2024 10:47:49 +0900
Subject: [PATCH 059/164] docs: update description for test file locations
---
user_guide_src/source/testing/overview.rst | 18 +++++++++++++-----
user_guide_src/source/testing/overview/002.php | 2 +-
user_guide_src/source/testing/overview/003.php | 2 +-
3 files changed, 15 insertions(+), 7 deletions(-)
diff --git a/user_guide_src/source/testing/overview.rst b/user_guide_src/source/testing/overview.rst
index 2b447ee1d5d1..6e2c957f34da 100644
--- a/user_guide_src/source/testing/overview.rst
+++ b/user_guide_src/source/testing/overview.rst
@@ -69,14 +69,22 @@ By default, test files are placed under the **tests** directory in the project r
The Test Class
==============
-In order to take advantage of the additional tools provided, your tests must extend ``CIUnitTestCase``. All tests
-are expected to be located in the **tests/app** directory by default.
+In order to take advantage of the additional tools provided, your tests must extend
+``CIUnitTestCase``.
-To test a new library, **Foo**, you would create a new file at **tests/app/Libraries/FooTest.php**:
+There are no rules for how test files must be placed. However, we recommend that
+you establish placement rules in advance so that you can quickly understand where
+the test files are located.
+
+In this document, we will place the test files corresponding to the classes in
+the **app** directory in the **tests/app** directory. To test a new library,
+**app/Libraries/Foo.php**, you would create a new file at
+**tests/app/Libraries/FooTest.php**:
.. literalinclude:: overview/001.php
-To test one of your models, you might end up with something like this in **tests/app/Models/OneOfMyModelsTest.php**:
+To test one of your models, **app/Models/UserMode.php**, you might end up with
+something like this in **tests/app/Models/UserModelTest.php**:
.. literalinclude:: overview/002.php
@@ -103,7 +111,7 @@ to help with staging and clean up::
The static methods ``setUpBeforeClass()`` and ``tearDownAfterClass()`` run before and after the entire test case, whereas the protected methods ``setUp()`` and ``tearDown()`` run
between each test.
-If you implement any of these special functions make sure you run their
+If you implement any of these special functions, make sure you run their
parent as well so extended test cases do not interfere with staging:
.. literalinclude:: overview/003.php
diff --git a/user_guide_src/source/testing/overview/002.php b/user_guide_src/source/testing/overview/002.php
index eca8ef906203..db746b62a3b1 100644
--- a/user_guide_src/source/testing/overview/002.php
+++ b/user_guide_src/source/testing/overview/002.php
@@ -4,7 +4,7 @@
use CodeIgniter\Test\CIUnitTestCase;
-class OneOfMyModelsTest extends CIUnitTestCase
+class UserModelTest extends CIUnitTestCase
{
public function testFooNotBar()
{
diff --git a/user_guide_src/source/testing/overview/003.php b/user_guide_src/source/testing/overview/003.php
index fe9f163246b1..ee39231cb382 100644
--- a/user_guide_src/source/testing/overview/003.php
+++ b/user_guide_src/source/testing/overview/003.php
@@ -4,7 +4,7 @@
use CodeIgniter\Test\CIUnitTestCase;
-final class OneOfMyModelsTest extends CIUnitTestCase
+final class UserModelTest extends CIUnitTestCase
{
protected function setUp(): void
{
From 0d2cf34ab1ced2534b3592b2f7c16040389babe7 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Thu, 1 Feb 2024 10:52:47 +0900
Subject: [PATCH 060/164] docs: update sample code style
---
user_guide_src/source/testing/overview/016.php | 7 +++++--
user_guide_src/source/testing/overview/017.php | 3 ++-
2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/user_guide_src/source/testing/overview/016.php b/user_guide_src/source/testing/overview/016.php
index d3a769d8379c..8598a4a7a3c5 100644
--- a/user_guide_src/source/testing/overview/016.php
+++ b/user_guide_src/source/testing/overview/016.php
@@ -1,5 +1,8 @@
getMockBuilder('CodeIgniter\HTTP\CURLRequest')
- ->setMethods(['request'])
+ $curlrequest = $this->getMockBuilder(CURLRequest::class)
+ ->onlyMethods(['request'])
->getMock();
Services::injectMock('curlrequest', $curlrequest);
diff --git a/user_guide_src/source/testing/overview/017.php b/user_guide_src/source/testing/overview/017.php
index f5e436377383..d989ed7e7da1 100644
--- a/user_guide_src/source/testing/overview/017.php
+++ b/user_guide_src/source/testing/overview/017.php
@@ -2,6 +2,7 @@
namespace Tests;
+use App\Models\UserModel;
use CodeIgniter\Config\Factories;
use CodeIgniter\Test\CIUnitTestCase;
use Tests\Support\Mock\MockUserModel;
@@ -13,6 +14,6 @@ protected function setUp(): void
parent::setUp();
$model = new MockUserModel();
- Factories::injectMock('models', 'App\Models\UserModel', $model);
+ Factories::injectMock('models', UserModel::class, $model);
}
}
From 7d20c89bddb25ff4665b84b8eaf8971207c47a5f Mon Sep 17 00:00:00 2001
From: kenjis
Date: Thu, 1 Feb 2024 10:53:22 +0900
Subject: [PATCH 061/164] docs: add `namespace Tests;` to sample code
---
user_guide_src/source/testing/overview/018.php | 2 ++
user_guide_src/source/testing/overview/019.php | 2 ++
user_guide_src/source/testing/overview/020.php | 2 ++
3 files changed, 6 insertions(+)
diff --git a/user_guide_src/source/testing/overview/018.php b/user_guide_src/source/testing/overview/018.php
index 09f1f4e42f2d..cddef79a9ef2 100644
--- a/user_guide_src/source/testing/overview/018.php
+++ b/user_guide_src/source/testing/overview/018.php
@@ -1,5 +1,7 @@
Date: Fri, 2 Feb 2024 09:17:07 +0900
Subject: [PATCH 062/164] docs: change to FQCN
---
user_guide_src/source/testing/overview.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/user_guide_src/source/testing/overview.rst b/user_guide_src/source/testing/overview.rst
index 6e2c957f34da..b625e95671a4 100644
--- a/user_guide_src/source/testing/overview.rst
+++ b/user_guide_src/source/testing/overview.rst
@@ -70,7 +70,7 @@ The Test Class
==============
In order to take advantage of the additional tools provided, your tests must extend
-``CIUnitTestCase``.
+``CodeIgniter\Test\CIUnitTestCase``.
There are no rules for how test files must be placed. However, we recommend that
you establish placement rules in advance so that you can quickly understand where
From 05962e9682ccaebd4ac83897234ecdee0c604e0b Mon Sep 17 00:00:00 2001
From: kenjis
Date: Fri, 2 Feb 2024 10:46:54 +0900
Subject: [PATCH 063/164] docs: replace integer with int
---
system/Log/Logger.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/system/Log/Logger.php b/system/Log/Logger.php
index e5f482cb63d2..2246fc8c2017 100644
--- a/system/Log/Logger.php
+++ b/system/Log/Logger.php
@@ -37,7 +37,7 @@ class Logger implements LoggerInterface
* Used by the logThreshold Config setting to define
* which errors to show.
*
- * @var array
+ * @var array
*/
protected $logLevels = [
'emergency' => 1,
From e7213285d5067f45fdd4afd1a9a640faf0b3d618 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Thu, 1 Feb 2024 11:10:44 +0900
Subject: [PATCH 064/164] docs: fix sample code in testing/controllers
`namespace CodeIgniter` should not be used in app testing.
---
user_guide_src/source/testing/controllers/001.php | 4 ++--
user_guide_src/source/testing/controllers/002.php | 6 +++---
user_guide_src/source/testing/controllers/011.php | 4 ++--
user_guide_src/source/testing/controllers/012.php | 4 ++--
user_guide_src/source/testing/controllers/014.php | 4 ++--
5 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/user_guide_src/source/testing/controllers/001.php b/user_guide_src/source/testing/controllers/001.php
index 9162fa0aeabd..ae51187f949d 100644
--- a/user_guide_src/source/testing/controllers/001.php
+++ b/user_guide_src/source/testing/controllers/001.php
@@ -1,12 +1,12 @@
withURI('http://example.com/categories')
- ->controller(\App\Controllers\ForumController::class)
+ ->controller(ForumController::class)
->execute('showCategories');
$this->assertTrue($result->isOK());
diff --git a/user_guide_src/source/testing/controllers/011.php b/user_guide_src/source/testing/controllers/011.php
index f2ab558b8da2..e53aa42c8768 100644
--- a/user_guide_src/source/testing/controllers/011.php
+++ b/user_guide_src/source/testing/controllers/011.php
@@ -1,11 +1,11 @@
Date: Fri, 2 Feb 2024 09:46:31 +0900
Subject: [PATCH 065/164] docs: fix test classname
---
user_guide_src/source/testing/controllers/002.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/user_guide_src/source/testing/controllers/002.php b/user_guide_src/source/testing/controllers/002.php
index 31bdc3dd90a5..13701910f5e8 100644
--- a/user_guide_src/source/testing/controllers/002.php
+++ b/user_guide_src/source/testing/controllers/002.php
@@ -6,7 +6,7 @@
use CodeIgniter\Test\ControllerTestTrait;
use CodeIgniter\Test\DatabaseTestTrait;
-class FooControllerTest extends CIUnitTestCase
+class ForumControllerTest extends CIUnitTestCase
{
use ControllerTestTrait;
use DatabaseTestTrait;
From eb889179a6720901185b2d868721daea77c274d8 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Fri, 2 Feb 2024 16:41:57 +0900
Subject: [PATCH 066/164] docs: fix incorrect @return type
---
system/Database/BaseResult.php | 10 ++++++++--
system/Database/ResultInterface.php | 10 ++++++++--
2 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/system/Database/BaseResult.php b/system/Database/BaseResult.php
index 93bb00e4d350..124e19e06fcf 100644
--- a/system/Database/BaseResult.php
+++ b/system/Database/BaseResult.php
@@ -292,9 +292,15 @@ public function getRow($n = 0, string $type = 'object')
/**
* Returns a row as a custom class instance.
*
- * If row doesn't exists, returns null.
+ * If the row doesn't exist, returns null.
*
- * @return array|null
+ * @template T of object
+ *
+ * @param int $n The row number of the results
+ * @phpstan-param class-string $className
+ *
+ * @return object|null
+ * @phpstan-return T|null
*/
public function getCustomRowObject(int $n, string $className)
{
diff --git a/system/Database/ResultInterface.php b/system/Database/ResultInterface.php
index 82cb7956b22e..49dd49edca4f 100644
--- a/system/Database/ResultInterface.php
+++ b/system/Database/ResultInterface.php
@@ -69,9 +69,15 @@ public function getRow($n = 0, string $type = 'object');
/**
* Returns a row as a custom class instance.
*
- * If row doesn't exists, returns null.
+ * If the row doesn't exist, returns null.
*
- * @return array|null
+ * @template T of object
+ *
+ * @param int $n The row number of the results
+ * @phpstan-param class-string $className
+ *
+ * @return object|null
+ * @phpstan-return T|null
*/
public function getCustomRowObject(int $n, string $className);
From 59b5d125a07ad832964a3c4699830a3b439b7c22 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Fri, 2 Feb 2024 16:58:27 +0900
Subject: [PATCH 067/164] docs: fix incorrect sample code
---
user_guide_src/source/database/results/016.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/user_guide_src/source/database/results/016.php b/user_guide_src/source/database/results/016.php
index f6d0e2325ce6..b3356729d39f 100644
--- a/user_guide_src/source/database/results/016.php
+++ b/user_guide_src/source/database/results/016.php
@@ -1,3 +1,3 @@
getCustomRowObject(0, \App\Entities\User::class);
+$row = $query->getRow(0, \App\Entities\User::class);
From 6d971afa905f07efc242c57f7010464834428569 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Fri, 2 Feb 2024 17:05:06 +0900
Subject: [PATCH 068/164] docs: improve doc comments
---
system/Database/BaseResult.php | 14 ++++++++------
system/Database/ResultInterface.php | 14 ++++++++------
2 files changed, 16 insertions(+), 12 deletions(-)
diff --git a/system/Database/BaseResult.php b/system/Database/BaseResult.php
index 124e19e06fcf..d7b32218322b 100644
--- a/system/Database/BaseResult.php
+++ b/system/Database/BaseResult.php
@@ -252,14 +252,16 @@ public function getResultObject(): array
* Wrapper object to return a row as either an array, an object, or
* a custom class.
*
- * If row doesn't exist, returns null.
+ * If the row doesn't exist, returns null.
+ *
+ * @template T of object
*
- * @param int|string $n The index of the results to return, or column name.
- * @param string $type The type of result object. 'array', 'object' or class name.
- * @phpstan-param class-string|'array'|'object' $type
+ * @param int|string $n The index of the results to return, or column name.
+ * @param string $type The type of result object. 'array', 'object' or class name.
+ * @phpstan-param class-string|'array'|'object' $type
*
* @return array|object|stdClass|null
- * @phpstan-return ($type is 'object' ? stdClass|null : ($type is 'array' ? array|null : object|null))
+ * @phpstan-return ($type is 'object' ? stdClass|null : ($type is 'array' ? array|null : T|null))
*/
public function getRow($n = 0, string $type = 'object')
{
@@ -296,7 +298,7 @@ public function getRow($n = 0, string $type = 'object')
*
* @template T of object
*
- * @param int $n The row number of the results
+ * @param int $n The index of the results to return.
* @phpstan-param class-string $className
*
* @return object|null
diff --git a/system/Database/ResultInterface.php b/system/Database/ResultInterface.php
index 49dd49edca4f..ea5f0de2800f 100644
--- a/system/Database/ResultInterface.php
+++ b/system/Database/ResultInterface.php
@@ -55,14 +55,16 @@ public function getResultObject(): array;
* Wrapper object to return a row as either an array, an object, or
* a custom class.
*
- * If row doesn't exist, returns null.
+ * If the row doesn't exist, returns null.
+ *
+ * @template T of object
*
- * @param int|string $n The index of the results to return, or column name.
- * @param string $type The type of result object. 'array', 'object' or class name.
- * @phpstan-param class-string|'array'|'object' $type
+ * @param int|string $n The index of the results to return, or column name.
+ * @param string $type The type of result object. 'array', 'object' or class name.
+ * @phpstan-param class-string|'array'|'object' $type
*
* @return array|object|stdClass|null
- * @phpstan-return ($type is 'object' ? stdClass|null : ($type is 'array' ? array|null : object|null))
+ * @phpstan-return ($type is 'object' ? stdClass|null : ($type is 'array' ? array|null : T|null))
*/
public function getRow($n = 0, string $type = 'object');
@@ -73,7 +75,7 @@ public function getRow($n = 0, string $type = 'object');
*
* @template T of object
*
- * @param int $n The row number of the results
+ * @param int $n The index of the results to return.
* @phpstan-param class-string $className
*
* @return object|null
From bf05e2ed790e4630658059a647ad47b0537f0d94 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Sat, 3 Feb 2024 09:22:45 +0900
Subject: [PATCH 069/164] docs: fix wrong @param in Email
---
system/Email/Email.php | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/system/Email/Email.php b/system/Email/Email.php
index 42835c3d404e..183ac945047c 100644
--- a/system/Email/Email.php
+++ b/system/Email/Email.php
@@ -1665,7 +1665,9 @@ protected function unwrapSpecials()
/**
* Strip line-breaks via callback
*
- * @param string $matches
+ * @used-by unwrapSpecials()
+ *
+ * @param list $matches
*
* @return string
*/
From f5c3df56704394c6ddacfd793ee94d9c02c1bb3f Mon Sep 17 00:00:00 2001
From: kenjis
Date: Sat, 3 Feb 2024 09:46:55 +0900
Subject: [PATCH 070/164] docs: add signature for Closure in Router
---
phpstan-baseline.php | 110 ---------------------
system/Router/AutoRouter.php | 3 +-
system/Router/RouteCollection.php | 29 +++---
system/Router/RouteCollectionInterface.php | 9 +-
system/Router/Router.php | 7 +-
system/Router/RouterInterface.php | 5 +-
6 files changed, 29 insertions(+), 134 deletions(-)
diff --git a/phpstan-baseline.php b/phpstan-baseline.php
index 47f2cce686b4..cc669afb1e74 100644
--- a/phpstan-baseline.php
+++ b/phpstan-baseline.php
@@ -2491,11 +2491,6 @@
'count' => 1,
'path' => __DIR__ . '/system/Router/AutoRouter.php',
];
-$ignoreErrors[] = [
- 'message' => '#^Property CodeIgniter\\\\Router\\\\AutoRouter\\:\\:\\$cliRoutes type has no signature specified for Closure\\.$#',
- 'count' => 1,
- 'path' => __DIR__ . '/system/Router/AutoRouter.php',
-];
$ignoreErrors[] = [
'message' => '#^Short ternary operator is not allowed\\. Use null coalesce operator if applicable or consider using long ternary\\.$#',
'count' => 1,
@@ -2516,81 +2511,16 @@
'count' => 6,
'path' => __DIR__ . '/system/Router/RouteCollection.php',
];
-$ignoreErrors[] = [
- 'message' => '#^Method CodeIgniter\\\\Router\\\\RouteCollection\\:\\:add\\(\\) has parameter \\$to with no signature specified for Closure\\.$#',
- 'count' => 1,
- 'path' => __DIR__ . '/system/Router/RouteCollection.php',
-];
-$ignoreErrors[] = [
- 'message' => '#^Method CodeIgniter\\\\Router\\\\RouteCollection\\:\\:cli\\(\\) has parameter \\$to with no signature specified for Closure\\.$#',
- 'count' => 1,
- 'path' => __DIR__ . '/system/Router/RouteCollection.php',
-];
-$ignoreErrors[] = [
- 'message' => '#^Method CodeIgniter\\\\Router\\\\RouteCollection\\:\\:create\\(\\) has parameter \\$to with no signature specified for Closure\\.$#',
- 'count' => 1,
- 'path' => __DIR__ . '/system/Router/RouteCollection.php',
-];
-$ignoreErrors[] = [
- 'message' => '#^Method CodeIgniter\\\\Router\\\\RouteCollection\\:\\:delete\\(\\) has parameter \\$to with no signature specified for Closure\\.$#',
- 'count' => 1,
- 'path' => __DIR__ . '/system/Router/RouteCollection.php',
-];
$ignoreErrors[] = [
'message' => '#^Method CodeIgniter\\\\Router\\\\RouteCollection\\:\\:environment\\(\\) has parameter \\$callback with no signature specified for Closure\\.$#',
'count' => 1,
'path' => __DIR__ . '/system/Router/RouteCollection.php',
];
-$ignoreErrors[] = [
- 'message' => '#^Method CodeIgniter\\\\Router\\\\RouteCollection\\:\\:get\\(\\) has parameter \\$to with no signature specified for Closure\\.$#',
- 'count' => 1,
- 'path' => __DIR__ . '/system/Router/RouteCollection.php',
-];
-$ignoreErrors[] = [
- 'message' => '#^Method CodeIgniter\\\\Router\\\\RouteCollection\\:\\:get404Override\\(\\) return type has no signature specified for Closure\\.$#',
- 'count' => 1,
- 'path' => __DIR__ . '/system/Router/RouteCollection.php',
-];
-$ignoreErrors[] = [
- 'message' => '#^Method CodeIgniter\\\\Router\\\\RouteCollection\\:\\:getControllerName\\(\\) has parameter \\$handler with no signature specified for Closure\\.$#',
- 'count' => 1,
- 'path' => __DIR__ . '/system/Router/RouteCollection.php',
-];
$ignoreErrors[] = [
'message' => '#^Method CodeIgniter\\\\Router\\\\RouteCollection\\:\\:group\\(\\) has parameter \\$params with no signature specified for callable\\.$#',
'count' => 1,
'path' => __DIR__ . '/system/Router/RouteCollection.php',
];
-$ignoreErrors[] = [
- 'message' => '#^Method CodeIgniter\\\\Router\\\\RouteCollection\\:\\:head\\(\\) has parameter \\$to with no signature specified for Closure\\.$#',
- 'count' => 1,
- 'path' => __DIR__ . '/system/Router/RouteCollection.php',
-];
-$ignoreErrors[] = [
- 'message' => '#^Method CodeIgniter\\\\Router\\\\RouteCollection\\:\\:match\\(\\) has parameter \\$to with no signature specified for Closure\\.$#',
- 'count' => 1,
- 'path' => __DIR__ . '/system/Router/RouteCollection.php',
-];
-$ignoreErrors[] = [
- 'message' => '#^Method CodeIgniter\\\\Router\\\\RouteCollection\\:\\:options\\(\\) has parameter \\$to with no signature specified for Closure\\.$#',
- 'count' => 1,
- 'path' => __DIR__ . '/system/Router/RouteCollection.php',
-];
-$ignoreErrors[] = [
- 'message' => '#^Method CodeIgniter\\\\Router\\\\RouteCollection\\:\\:patch\\(\\) has parameter \\$to with no signature specified for Closure\\.$#',
- 'count' => 1,
- 'path' => __DIR__ . '/system/Router/RouteCollection.php',
-];
-$ignoreErrors[] = [
- 'message' => '#^Method CodeIgniter\\\\Router\\\\RouteCollection\\:\\:post\\(\\) has parameter \\$to with no signature specified for Closure\\.$#',
- 'count' => 1,
- 'path' => __DIR__ . '/system/Router/RouteCollection.php',
-];
-$ignoreErrors[] = [
- 'message' => '#^Method CodeIgniter\\\\Router\\\\RouteCollection\\:\\:put\\(\\) has parameter \\$to with no signature specified for Closure\\.$#',
- 'count' => 1,
- 'path' => __DIR__ . '/system/Router/RouteCollection.php',
-];
$ignoreErrors[] = [
'message' => '#^Method CodeIgniter\\\\Router\\\\RouteCollection\\:\\:set404Override\\(\\) has parameter \\$callable with no signature specified for callable\\.$#',
'count' => 1,
@@ -2611,21 +2541,6 @@
'count' => 1,
'path' => __DIR__ . '/system/Router/RouteCollection.php',
];
-$ignoreErrors[] = [
- 'message' => '#^Property CodeIgniter\\\\Router\\\\RouteCollection\\:\\:\\$override404 type has no signature specified for Closure\\.$#',
- 'count' => 1,
- 'path' => __DIR__ . '/system/Router/RouteCollection.php',
-];
-$ignoreErrors[] = [
- 'message' => '#^Method CodeIgniter\\\\Router\\\\RouteCollectionInterface\\:\\:add\\(\\) has parameter \\$to with no signature specified for Closure\\.$#',
- 'count' => 1,
- 'path' => __DIR__ . '/system/Router/RouteCollectionInterface.php',
-];
-$ignoreErrors[] = [
- 'message' => '#^Method CodeIgniter\\\\Router\\\\RouteCollectionInterface\\:\\:get404Override\\(\\) return type has no signature specified for Closure\\.$#',
- 'count' => 1,
- 'path' => __DIR__ . '/system/Router/RouteCollectionInterface.php',
-];
$ignoreErrors[] = [
'message' => '#^Method CodeIgniter\\\\Router\\\\RouteCollectionInterface\\:\\:set404Override\\(\\) has parameter \\$callable with no signature specified for callable\\.$#',
'count' => 1,
@@ -2681,41 +2596,16 @@
'count' => 1,
'path' => __DIR__ . '/system/Router/Router.php',
];
-$ignoreErrors[] = [
- 'message' => '#^Method CodeIgniter\\\\Router\\\\Router\\:\\:controllerName\\(\\) return type has no signature specified for Closure\\.$#',
- 'count' => 1,
- 'path' => __DIR__ . '/system/Router/Router.php',
-];
$ignoreErrors[] = [
'message' => '#^Method CodeIgniter\\\\Router\\\\Router\\:\\:get404Override\\(\\) has no return type specified\\.$#',
'count' => 1,
'path' => __DIR__ . '/system/Router/Router.php',
];
-$ignoreErrors[] = [
- 'message' => '#^Method CodeIgniter\\\\Router\\\\Router\\:\\:handle\\(\\) return type has no signature specified for Closure\\.$#',
- 'count' => 1,
- 'path' => __DIR__ . '/system/Router/Router.php',
-];
$ignoreErrors[] = [
'message' => '#^Method CodeIgniter\\\\Router\\\\Router\\:\\:setMatchedRoute\\(\\) has parameter \\$handler with no signature specified for callable\\.$#',
'count' => 1,
'path' => __DIR__ . '/system/Router/Router.php',
];
-$ignoreErrors[] = [
- 'message' => '#^Property CodeIgniter\\\\Router\\\\Router\\:\\:\\$controller type has no signature specified for Closure\\.$#',
- 'count' => 1,
- 'path' => __DIR__ . '/system/Router/Router.php',
-];
-$ignoreErrors[] = [
- 'message' => '#^Method CodeIgniter\\\\Router\\\\RouterInterface\\:\\:controllerName\\(\\) return type has no signature specified for Closure\\.$#',
- 'count' => 1,
- 'path' => __DIR__ . '/system/Router/RouterInterface.php',
-];
-$ignoreErrors[] = [
- 'message' => '#^Method CodeIgniter\\\\Router\\\\RouterInterface\\:\\:handle\\(\\) return type has no signature specified for Closure\\.$#',
- 'count' => 1,
- 'path' => __DIR__ . '/system/Router/RouterInterface.php',
-];
$ignoreErrors[] = [
'message' => '#^Method CodeIgniter\\\\Session\\\\Exceptions\\\\SessionException\\:\\:forEmptySavepath\\(\\) has no return type specified\\.$#',
'count' => 1,
diff --git a/system/Router/AutoRouter.php b/system/Router/AutoRouter.php
index 87a5b3ac3bc1..d7516afb0a15 100644
--- a/system/Router/AutoRouter.php
+++ b/system/Router/AutoRouter.php
@@ -13,6 +13,7 @@
use Closure;
use CodeIgniter\Exceptions\PageNotFoundException;
+use CodeIgniter\HTTP\ResponseInterface;
/**
* Router for Auto-Routing
@@ -22,7 +23,7 @@ final class AutoRouter implements AutoRouterInterface
/**
* List of CLI routes that do not contain '*' routes.
*
- * @var array [routeKey => handler]
+ * @var array [routeKey => handler]
*/
private array $cliRoutes;
diff --git a/system/Router/RouteCollection.php b/system/Router/RouteCollection.php
index 4407c1076f3d..8df31c9073bb 100644
--- a/system/Router/RouteCollection.php
+++ b/system/Router/RouteCollection.php
@@ -13,6 +13,7 @@
use Closure;
use CodeIgniter\Autoloader\FileLocator;
+use CodeIgniter\HTTP\ResponseInterface;
use CodeIgniter\Router\Exceptions\RouterException;
use Config\App;
use Config\Modules;
@@ -87,7 +88,7 @@ class RouteCollection implements RouteCollectionInterface
* A callable that will be shown
* when the route cannot be matched.
*
- * @var Closure|string
+ * @var (Closure(string): (ResponseInterface|string|void))|string
*/
protected $override404;
@@ -497,7 +498,7 @@ public function set404Override($callable = null): RouteCollectionInterface
* Returns the 404 Override setting, which can be null, a closure
* or the controller/string.
*
- * @return Closure|string|null
+ * @return (Closure(string): (ResponseInterface|string|void))|string|null
*/
public function get404Override()
{
@@ -658,7 +659,7 @@ public function map(array $routes = [], ?array $options = null): RouteCollection
* Example:
* $routes->add('news', 'Posts::index');
*
- * @param array|Closure|string $to
+ * @param array|(Closure(mixed...): (ResponseInterface|string|void))|string $to
*/
public function add(string $from, $to, ?array $options = null): RouteCollectionInterface
{
@@ -992,7 +993,7 @@ public function presenter(string $name, ?array $options = null): RouteCollection
* Example:
* $route->match( ['get', 'post'], 'users/(:num)', 'users/$1);
*
- * @param array|Closure|string $to
+ * @param array|(Closure(mixed...): (ResponseInterface|string|void))|string $to
*/
public function match(array $verbs = [], string $from = '', $to = '', ?array $options = null): RouteCollectionInterface
{
@@ -1012,7 +1013,7 @@ public function match(array $verbs = [], string $from = '', $to = '', ?array $op
/**
* Specifies a route that is only available to GET requests.
*
- * @param array|Closure|string $to
+ * @param array|(Closure(mixed...): (ResponseInterface|string|void))|string $to
*/
public function get(string $from, $to, ?array $options = null): RouteCollectionInterface
{
@@ -1024,7 +1025,7 @@ public function get(string $from, $to, ?array $options = null): RouteCollectionI
/**
* Specifies a route that is only available to POST requests.
*
- * @param array|Closure|string $to
+ * @param array|(Closure(mixed...): (ResponseInterface|string|void))|string $to
*/
public function post(string $from, $to, ?array $options = null): RouteCollectionInterface
{
@@ -1036,7 +1037,7 @@ public function post(string $from, $to, ?array $options = null): RouteCollection
/**
* Specifies a route that is only available to PUT requests.
*
- * @param array|Closure|string $to
+ * @param array|(Closure(mixed...): (ResponseInterface|string|void))|string $to
*/
public function put(string $from, $to, ?array $options = null): RouteCollectionInterface
{
@@ -1048,7 +1049,7 @@ public function put(string $from, $to, ?array $options = null): RouteCollectionI
/**
* Specifies a route that is only available to DELETE requests.
*
- * @param array|Closure|string $to
+ * @param array|(Closure(mixed...): (ResponseInterface|string|void))|string $to
*/
public function delete(string $from, $to, ?array $options = null): RouteCollectionInterface
{
@@ -1060,7 +1061,7 @@ public function delete(string $from, $to, ?array $options = null): RouteCollecti
/**
* Specifies a route that is only available to HEAD requests.
*
- * @param array|Closure|string $to
+ * @param array|(Closure(mixed...): (ResponseInterface|string|void))|string $to
*/
public function head(string $from, $to, ?array $options = null): RouteCollectionInterface
{
@@ -1072,7 +1073,7 @@ public function head(string $from, $to, ?array $options = null): RouteCollection
/**
* Specifies a route that is only available to PATCH requests.
*
- * @param array|Closure|string $to
+ * @param array|(Closure(mixed...): (ResponseInterface|string|void))|string $to
*/
public function patch(string $from, $to, ?array $options = null): RouteCollectionInterface
{
@@ -1084,7 +1085,7 @@ public function patch(string $from, $to, ?array $options = null): RouteCollectio
/**
* Specifies a route that is only available to OPTIONS requests.
*
- * @param array|Closure|string $to
+ * @param array|(Closure(mixed...): (ResponseInterface|string|void))|string $to
*/
public function options(string $from, $to, ?array $options = null): RouteCollectionInterface
{
@@ -1096,7 +1097,7 @@ public function options(string $from, $to, ?array $options = null): RouteCollect
/**
* Specifies a route that is only available to command-line requests.
*
- * @param array|Closure|string $to
+ * @param array|(Closure(mixed...): (ResponseInterface|string|void))|string $to
*/
public function cli(string $from, $to, ?array $options = null): RouteCollectionInterface
{
@@ -1416,7 +1417,7 @@ private function replaceLocale(string $route, ?string $locale = null): string
* the request method(s) that this route will work for. They can be separated
* by a pipe character "|" if there is more than one.
*
- * @param array|Closure|string $to
+ * @param array|(Closure(mixed...): (ResponseInterface|string|void))|string $to
*
* @return void
*/
@@ -1767,7 +1768,7 @@ public function getRegisteredControllers(?string $verb = '*'): array
}
/**
- * @param Closure|string $handler Handler
+ * @param (Closure(mixed...): (ResponseInterface|string|void))|string $handler Handler
*
* @return string|null Controller classname
*/
diff --git a/system/Router/RouteCollectionInterface.php b/system/Router/RouteCollectionInterface.php
index 00f1d4c8bdc2..c9c8610009fc 100644
--- a/system/Router/RouteCollectionInterface.php
+++ b/system/Router/RouteCollectionInterface.php
@@ -12,6 +12,7 @@
namespace CodeIgniter\Router;
use Closure;
+use CodeIgniter\HTTP\ResponseInterface;
/**
* Interface RouteCollectionInterface
@@ -28,9 +29,9 @@ interface RouteCollectionInterface
/**
* Adds a single route to the collection.
*
- * @param string $from The route path (with placeholders or regex)
- * @param array|Closure|string $to The route handler
- * @param array|null $options The route options
+ * @param string $from The route path (with placeholders or regex)
+ * @param array|(Closure(mixed...): (ResponseInterface|string|void))|string $to The route handler
+ * @param array|null $options The route options
*
* @return RouteCollectionInterface
*/
@@ -111,7 +112,7 @@ public function set404Override($callable = null): self;
* Returns the 404 Override setting, which can be null, a closure
* or the controller/string.
*
- * @return Closure|string|null
+ * @return (Closure(string): (ResponseInterface|string|void))|string|null
*/
public function get404Override();
diff --git a/system/Router/Router.php b/system/Router/Router.php
index 723c292cb931..634f3e61a035 100644
--- a/system/Router/Router.php
+++ b/system/Router/Router.php
@@ -15,6 +15,7 @@
use CodeIgniter\Exceptions\PageNotFoundException;
use CodeIgniter\HTTP\Exceptions\RedirectException;
use CodeIgniter\HTTP\Request;
+use CodeIgniter\HTTP\ResponseInterface;
use CodeIgniter\Router\Exceptions\RouterException;
use Config\App;
use Config\Feature;
@@ -44,7 +45,7 @@ class Router implements RouterInterface
/**
* The name of the controller class.
*
- * @var Closure|string
+ * @var (Closure(mixed...): (ResponseInterface|string|void))|string
*/
protected $controller;
@@ -163,7 +164,7 @@ public function __construct(RouteCollectionInterface $routes, ?Request $request
*
* @param string|null $uri URI path relative to baseURL
*
- * @return Closure|string Controller classname or Closure
+ * @return (Closure(mixed...): (ResponseInterface|string|void))|string Controller classname or Closure
*
* @throws PageNotFoundException
* @throws RedirectException
@@ -237,7 +238,7 @@ public function getFilters(): array
/**
* Returns the name of the matched controller.
*
- * @return Closure|string Controller classname or Closure
+ * @return (Closure(mixed...): (ResponseInterface|string|void))|string Controller classname or Closure
*/
public function controllerName()
{
diff --git a/system/Router/RouterInterface.php b/system/Router/RouterInterface.php
index ffed59ca8aac..ccdef3d6d9be 100644
--- a/system/Router/RouterInterface.php
+++ b/system/Router/RouterInterface.php
@@ -13,6 +13,7 @@
use Closure;
use CodeIgniter\HTTP\Request;
+use CodeIgniter\HTTP\ResponseInterface;
/**
* Expected behavior of a Router.
@@ -29,14 +30,14 @@ public function __construct(RouteCollectionInterface $routes, ?Request $request
*
* @param string|null $uri URI path relative to baseURL
*
- * @return Closure|string Controller classname or Closure
+ * @return (Closure(mixed...): (ResponseInterface|string|void))|string Controller classname or Closure
*/
public function handle(?string $uri = null);
/**
* Returns the name of the matched controller.
*
- * @return Closure|string Controller classname or Closure
+ * @return (Closure(mixed...): (ResponseInterface|string|void))|string Controller classname or Closure
*/
public function controllerName();
From 267d6c075474c76e62f64207b29bca716817557a Mon Sep 17 00:00:00 2001
From: kenjis
Date: Sat, 3 Feb 2024 09:24:21 +0900
Subject: [PATCH 071/164] docs: add () to methods for consistency
---
system/Database/BaseBuilder.php | 8 ++++----
system/Database/Postgre/Builder.php | 2 +-
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/system/Database/BaseBuilder.php b/system/Database/BaseBuilder.php
index 48302ab26fc7..bc005f48f407 100644
--- a/system/Database/BaseBuilder.php
+++ b/system/Database/BaseBuilder.php
@@ -1968,7 +1968,7 @@ public function upsertBatch($set = null, ?bool $escape = null, int $batchSize =
/**
* Generates a platform-specific upsertBatch string from the supplied data
*
- * @used-by batchExecute
+ * @used-by batchExecute()
*
* @param string $table Protected table name
* @param list $keys QBKeys
@@ -2195,7 +2195,7 @@ public function insertBatch($set = null, ?bool $escape = null, int $batchSize =
/**
* Generates a platform-specific insert string from the supplied data.
*
- * @used-by batchExecute
+ * @used-by batchExecute()
*
* @param string $table Protected table name
* @param list $keys QBKeys
@@ -2563,7 +2563,7 @@ public function updateBatch($set = null, $constraints = null, int $batchSize = 1
/**
* Generates a platform-specific batch update string from the supplied data
*
- * @used-by batchExecute
+ * @used-by batchExecute()
*
* @param string $table Protected table name
* @param list $keys QBKeys
@@ -2825,7 +2825,7 @@ public function deleteBatch($set = null, $constraints = null, int $batchSize = 1
/**
* Generates a platform-specific batch update string from the supplied data
*
- * @used-by batchExecute
+ * @used-by batchExecute()
*
* @param string $table Protected table name
* @param list $keys QBKeys
diff --git a/system/Database/Postgre/Builder.php b/system/Database/Postgre/Builder.php
index 3749d8383237..8bd008f20916 100644
--- a/system/Database/Postgre/Builder.php
+++ b/system/Database/Postgre/Builder.php
@@ -315,7 +315,7 @@ public function join(string $table, $cond, string $type = '', ?bool $escape = nu
/**
* Generates a platform-specific batch update string from the supplied data
*
- * @used-by batchExecute
+ * @used-by batchExecute()
*
* @param string $table Protected table name
* @param list $keys QBKeys
From 5cb67248e54f7ed2f979c08292cce253c25cda95 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Sat, 3 Feb 2024 10:06:56 +0900
Subject: [PATCH 072/164] test: use array_sort_by_multiple_keys()
---
.../Live/AbstractGetFieldDataTest.php | 19 ++++++++++++-------
1 file changed, 12 insertions(+), 7 deletions(-)
diff --git a/tests/system/Database/Live/AbstractGetFieldDataTest.php b/tests/system/Database/Live/AbstractGetFieldDataTest.php
index 859c37718902..8bd05b6f5046 100644
--- a/tests/system/Database/Live/AbstractGetFieldDataTest.php
+++ b/tests/system/Database/Live/AbstractGetFieldDataTest.php
@@ -28,6 +28,13 @@ abstract class AbstractGetFieldDataTest extends CIUnitTestCase
protected Forge $forge;
protected string $table = 'test1';
+ public static function setUpBeforeClass(): void
+ {
+ parent::setUpBeforeClass();
+
+ helper('array');
+ }
+
protected function setUp(): void
{
parent::setUp();
@@ -95,14 +102,12 @@ abstract public function testGetFieldDataDefault(): void;
protected function assertSameFieldData(array $expected, array $actual)
{
- $expected = json_decode(json_encode($expected), true);
- $names = array_column($expected, 'name');
- array_multisort($names, SORT_ASC, $expected);
+ $expectedArray = json_decode(json_encode($expected), true);
+ array_sort_by_multiple_keys($expectedArray, ['name' => SORT_ASC]);
- $fields = json_decode(json_encode($actual), true);
- $names = array_column($fields, 'name');
- array_multisort($names, SORT_ASC, $fields);
+ $fieldsArray = json_decode(json_encode($actual), true);
+ array_sort_by_multiple_keys($fieldsArray, ['name' => SORT_ASC]);
- $this->assertSame($expected, $fields);
+ $this->assertSame($expectedArray, $fieldsArray);
}
}
From 16317db0a72ef62d8cf19b6a9efbd2c04020f519 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Sat, 3 Feb 2024 10:24:02 +0900
Subject: [PATCH 073/164] docs: add `:lines: 2-`
---
user_guide_src/source/helpers/array_helper.rst | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/user_guide_src/source/helpers/array_helper.rst b/user_guide_src/source/helpers/array_helper.rst
index 730dae957222..24d22156cd37 100644
--- a/user_guide_src/source/helpers/array_helper.rst
+++ b/user_guide_src/source/helpers/array_helper.rst
@@ -15,6 +15,7 @@ Loading this Helper
This helper is loaded using the following code:
.. literalinclude:: array_helper/001.php
+ :lines: 2-
Available Functions
===================
@@ -32,21 +33,25 @@ The following functions are available:
and allows the use of a the '*' wildcard. Given the following array:
.. literalinclude:: array_helper/002.php
+ :lines: 2-
We can locate the value of 'fizz' by using the search string "foo.buzz.fizz". Likewise, the value
of baz can be found with "foo.bar.baz":
.. literalinclude:: array_helper/003.php
+ :lines: 2-
You can use the asterisk as a wildcard to replace any of the segments. When found, it will search through all
of the child nodes until it finds it. This is handy if you don't know the values, or if your values
have a numeric index:
.. literalinclude:: array_helper/004.php
+ :lines: 2-
If the array key contains a dot, then the key can be escaped with a backslash:
.. literalinclude:: array_helper/005.php
+ :lines: 2-
.. note:: Prior to v4.2.0, ``dot_array_search('foo.bar.baz', ['foo' => ['bar' => 23]])`` returned ``23``
due to a bug. v4.2.0 and later returns ``null``.
@@ -73,17 +78,20 @@ The following functions are available:
from, e.g., the ``find()`` function of a model:
.. literalinclude:: array_helper/006.php
+ :lines: 2-
Now sort this array by two keys. Note that the method supports the dot-notation
to access values in deeper array levels, but does not support wildcards:
.. literalinclude:: array_helper/007.php
+ :lines: 2-
The ``$players`` array is now sorted by the 'order' value in each players'
'team' subarray. If this value is equal for several players, these players
will be ordered by their 'position'. The resulting array is:
.. literalinclude:: array_helper/008.php
+ :lines: 2-
In the same way, the method can also handle an array of objects. In the example
above it is further possible that each 'player' is represented by an array,
@@ -101,16 +109,19 @@ The following functions are available:
as separators for the keys.
.. literalinclude:: array_helper/009.php
+ :lines: 2-
On inspection, ``$flattened`` is equal to:
.. literalinclude:: array_helper/010.php
+ :lines: 2-
Users may use the ``$id`` parameter on their own, but are not required to do so.
The function uses this parameter internally to track the flattened keys. If users
will be supplying an initial ``$id``, it will be prepended to all keys.
.. literalinclude:: array_helper/011.php
+ :lines: 2-
.. php:function:: array_group_by(array $array, array $indexes[, bool $includeEmpty = false]): array
@@ -128,10 +139,13 @@ The following functions are available:
.. literalinclude:: array_helper/012.php
We want to group them first by "gender", then by "hr.department" (max depth = 2).
+ :lines: 2-
First the result when excluding empty values:
.. literalinclude:: array_helper/013.php
-
+ :lines: 2-
+
And here the same code, but this time we want to include empty values:
.. literalinclude:: array_helper/014.php
+ :lines: 2-
From 11d006621b47f789cae95c2cbfd0587bf89b41bc Mon Sep 17 00:00:00 2001
From: kenjis
Date: Sat, 3 Feb 2024 10:24:30 +0900
Subject: [PATCH 074/164] docs: decorate text
---
.../source/helpers/array_helper.rst | 24 +++++++++----------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/user_guide_src/source/helpers/array_helper.rst b/user_guide_src/source/helpers/array_helper.rst
index 24d22156cd37..8a9c795d335f 100644
--- a/user_guide_src/source/helpers/array_helper.rst
+++ b/user_guide_src/source/helpers/array_helper.rst
@@ -30,25 +30,25 @@ The following functions are available:
:rtype: mixed
This method allows you to use dot-notation to search through an array for a specific-key,
- and allows the use of a the '*' wildcard. Given the following array:
+ and allows the use of a the ``*`` wildcard. Given the following array:
.. literalinclude:: array_helper/002.php
:lines: 2-
- We can locate the value of 'fizz' by using the search string "foo.buzz.fizz". Likewise, the value
- of baz can be found with "foo.bar.baz":
+ We can locate the value of ``fizz`` by using the search string ``foo.buzz.fizz``. Likewise, the value
+ of ``baz`` can be found with ``foo.bar.baz``:
.. literalinclude:: array_helper/003.php
:lines: 2-
- You can use the asterisk as a wildcard to replace any of the segments. When found, it will search through all
+ You can use the asterisk (``*``) as a wildcard to replace any of the segments. When found, it will search through all
of the child nodes until it finds it. This is handy if you don't know the values, or if your values
have a numeric index:
.. literalinclude:: array_helper/004.php
:lines: 2-
- If the array key contains a dot, then the key can be escaped with a backslash:
+ If the array key contains a dot (``.``), then the key can be escaped with a backslash (``\``):
.. literalinclude:: array_helper/005.php
:lines: 2-
@@ -86,16 +86,16 @@ The following functions are available:
.. literalinclude:: array_helper/007.php
:lines: 2-
- The ``$players`` array is now sorted by the 'order' value in each players'
- 'team' subarray. If this value is equal for several players, these players
- will be ordered by their 'position'. The resulting array is:
+ The ``$players`` array is now sorted by the ``order`` value in each players'
+ ``team`` subarray. If this value is equal for several players, these players
+ will be ordered by their ``position``. The resulting array is:
.. literalinclude:: array_helper/008.php
:lines: 2-
In the same way, the method can also handle an array of objects. In the example
- above it is further possible that each 'player' is represented by an array,
- while the 'teams' are objects. The method will detect the type of elements in
+ above it is further possible that each ``player`` is represented by an array,
+ while the ``teams`` are objects. The method will detect the type of elements in
each nesting level and handle it accordingly.
.. php:function:: array_flatten_with_dots(iterable $array[, string $id = '']): array
@@ -137,9 +137,9 @@ The following functions are available:
The example shows some data (i.e. loaded from an API) with nested arrays.
.. literalinclude:: array_helper/012.php
-
- We want to group them first by "gender", then by "hr.department" (max depth = 2).
:lines: 2-
+
+ We want to group them first by ``gender``, then by ``hr.department`` (max depth = 2).
First the result when excluding empty values:
.. literalinclude:: array_helper/013.php
From 826f163bae32e8d11a8fa331233fae9b1c37d7be Mon Sep 17 00:00:00 2001
From: kenjis
Date: Sat, 3 Feb 2024 17:30:23 +0900
Subject: [PATCH 075/164] docs: update starter/tests/README.md
You can set up test database with .env.
Now we provide only CIUnitTestCase.
---
admin/starter/tests/README.md | 22 +++++++++-------------
1 file changed, 9 insertions(+), 13 deletions(-)
diff --git a/admin/starter/tests/README.md b/admin/starter/tests/README.md
index 473d0f8c140e..ad4c74d97a24 100644
--- a/admin/starter/tests/README.md
+++ b/admin/starter/tests/README.md
@@ -14,7 +14,7 @@ use to test your application. Those details can be found in the documentation.
## Requirements
It is recommended to use the latest version of PHPUnit. At the time of this
-writing we are running version 9.x. Support for this has been built into the
+writing, we are running version 9.x. Support for this has been built into the
**composer.json** file that ships with CodeIgniter and can easily be installed
via [Composer](https://getcomposer.org/) if you don't already have it installed globally.
@@ -35,7 +35,7 @@ for code coverage to be calculated successfully. After installing `XDebug`, you
A number of the tests use a running database.
In order to set up the database edit the details for the `tests` group in
-**app/Config/Database.php** or **phpunit.xml**.
+**app/Config/Database.php** or **.env**.
Make sure that you provide a database engine that is currently running on your machine.
More details on a test database setup are in the
[Testing Your Database](https://codeigniter4.github.io/userguide/testing/database.html) section of the documentation.
@@ -92,12 +92,11 @@ HTML code coverage reports.
## Test Cases
Every test needs a *test case*, or class that your tests extend. CodeIgniter 4
-provides a few that you may use directly:
-* `CodeIgniter\Test\CIUnitTestCase` - for basic tests with no other service needs
-* `CodeIgniter\Test\DatabaseTestTrait` - for tests that need database access
+provides one class that you may use directly:
+* `CodeIgniter\Test\CIUnitTestCase`
-Most of the time you will want to write your own test cases to hold functions and services
-common to your test suites.
+Most of the time you will want to write your own test cases that extend `CIUnitTestCase`
+to hold functions and services common to your test suites.
## Creating Tests
@@ -112,11 +111,8 @@ Review the links above and always pay attention to your code coverage.
### Database Tests
-Tests can include migrating, seeding, and testing against a mock or live1 database.
+Tests can include migrating, seeding, and testing against a mock or live database.
Be sure to modify the test case (or create your own) to point to your seed and migrations
and include any additional steps to be run before tests in the `setUp()` method.
-
-1 Note: If you are using database tests that require a live database connection
-you will need to rename **phpunit.xml.dist** to **phpunit.xml**, uncomment the database
-configuration lines and add your connection details. Prevent **phpunit.xml** from being
-tracked in your repo by adding it to **.gitignore**.
+See [Testing Your Database](https://codeigniter4.github.io/userguide/testing/database.html)
+for details.
From d81b63d6e7c38e3f55ba9df4d48868ba0e0170eb Mon Sep 17 00:00:00 2001
From: kenjis
Date: Sun, 4 Feb 2024 09:11:40 +0900
Subject: [PATCH 076/164] docs: improve description for Environment Variables
as Replacements for Data
---
user_guide_src/source/general/configuration.rst | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/user_guide_src/source/general/configuration.rst b/user_guide_src/source/general/configuration.rst
index 45ecce84108d..f7d6c2d78d34 100644
--- a/user_guide_src/source/general/configuration.rst
+++ b/user_guide_src/source/general/configuration.rst
@@ -222,14 +222,15 @@ Since v4.1.5, you can also write with underscores::
Environment Variables as Replacements for Data
==============================================
-It is very important to always remember that environment variables contained in your **.env** are
-**only replacements for existing data**.
+It is very important to always remember that environment variables contained in
+your **.env** are **only replacements for existing scalar values**.
-Simply put, you can change only the property value that exists in the Config class
-by setting it in your **.env**.
+Simply put, you can change only the property's scalar value that exists in the
+Config class by setting it in your **.env**.
-You cannot add a property that is not defined in the Config class, nor can you
-change it to an array if the value of the defined property is a scalar.
+ 1. You cannot add a property that is not defined in the Config class.
+ 2. You cannot change a scalar value in a property to an array.
+ 3. You cannot add an element to an existing array.
For example, you cannot just put ``app.myNewConfig = foo`` in your **.env** and
expect your ``Config\App`` to magically have that property and value at run time.
From 400d171ebdb398a3b8f406cb1475ba4edc865adf Mon Sep 17 00:00:00 2001
From: Abdul Malik Ikhsan
Date: Sun, 4 Feb 2024 08:12:25 +0700
Subject: [PATCH 077/164] Reduce jobsize on rector config
---
rector.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/rector.php b/rector.php
index b1520c38e10a..6ee2738f2618 100644
--- a/rector.php
+++ b/rector.php
@@ -59,7 +59,7 @@
PHPUnitSetList::PHPUNIT_100,
]);
- $rectorConfig->parallel(120, 8, 15);
+ $rectorConfig->parallel(120, 8, 10);
// paths to refactor; solid alternative to CLI arguments
$rectorConfig->paths([__DIR__ . '/app', __DIR__ . '/system', __DIR__ . '/tests', __DIR__ . '/utils']);
From b0e1bf7d148acf7c9b8a21345ba72604ab7b384b Mon Sep 17 00:00:00 2001
From: kenjis
Date: Sun, 4 Feb 2024 17:31:31 +0900
Subject: [PATCH 078/164] docs: add protocol-relative link to PHPDocs
---
system/HTTP/SiteURI.php | 14 +++++++++-----
system/Helpers/url_helper.php | 14 +++++++++-----
2 files changed, 18 insertions(+), 10 deletions(-)
diff --git a/system/HTTP/SiteURI.php b/system/HTTP/SiteURI.php
index b7acfc389f25..8daa5ab2c0cd 100644
--- a/system/HTTP/SiteURI.php
+++ b/system/HTTP/SiteURI.php
@@ -369,8 +369,10 @@ protected function applyParts(array $parts): void
/**
* For base_url() helper.
*
- * @param array|string $relativePath URI string or array of URI segments
- * @param string|null $scheme URI scheme. E.g., http, ftp
+ * @param array|string $relativePath URI string or array of URI segments.
+ * @param string|null $scheme URI scheme. E.g., http, ftp. If empty
+ * string '' is set, a protocol-relative
+ * link is returned.
*/
public function baseUrl($relativePath = '', ?string $scheme = null): string
{
@@ -406,9 +408,11 @@ private function stringifyRelativePath($relativePath): string
/**
* For site_url() helper.
*
- * @param array|string $relativePath URI string or array of URI segments
- * @param string|null $scheme URI scheme. E.g., http, ftp
- * @param App|null $config Alternate configuration to use
+ * @param array|string $relativePath URI string or array of URI segments.
+ * @param string|null $scheme URI scheme. E.g., http, ftp. If empty
+ * string '' is set, a protocol-relative
+ * link is returned.
+ * @param App|null $config Alternate configuration to use.
*/
public function siteUrl($relativePath = '', ?string $scheme = null, ?App $config = null): string
{
diff --git a/system/Helpers/url_helper.php b/system/Helpers/url_helper.php
index 8099558aa343..f992eac391f8 100644
--- a/system/Helpers/url_helper.php
+++ b/system/Helpers/url_helper.php
@@ -23,9 +23,11 @@
/**
* Returns a site URL as defined by the App config.
*
- * @param array|string $relativePath URI string or array of URI segments
- * @param string|null $scheme URI scheme. E.g., http, ftp
- * @param App|null $config Alternate configuration to use
+ * @param array|string $relativePath URI string or array of URI segments.
+ * @param string|null $scheme URI scheme. E.g., http, ftp. If empty
+ * string '' is set, a protocol-relative
+ * link is returned.
+ * @param App|null $config Alternate configuration to use.
*/
function site_url($relativePath = '', ?string $scheme = null, ?App $config = null): string
{
@@ -42,8 +44,10 @@ function site_url($relativePath = '', ?string $scheme = null, ?App $config = nul
* Returns the base URL as defined by the App config.
* Base URLs are trimmed site URLs without the index page.
*
- * @param array|string $relativePath URI string or array of URI segments
- * @param string|null $scheme URI scheme. E.g., http, ftp
+ * @param array|string $relativePath URI string or array of URI segments.
+ * @param string|null $scheme URI scheme. E.g., http, ftp. If empty
+ * string '' is set, a protocol-relative
+ * link is returned.
*/
function base_url($relativePath = '', ?string $scheme = null): string
{
From c2cbf05638c3734c86d85595c2f6d075838a257e Mon Sep 17 00:00:00 2001
From: kenjis
Date: Sun, 4 Feb 2024 17:32:06 +0900
Subject: [PATCH 079/164] docs: add about missing protocol-relative link
---
user_guide_src/source/helpers/url_helper.rst | 15 ++++++++++-----
user_guide_src/source/helpers/url_helper/004.php | 1 +
user_guide_src/source/helpers/url_helper/026.php | 4 ++++
3 files changed, 15 insertions(+), 5 deletions(-)
create mode 100644 user_guide_src/source/helpers/url_helper/026.php
diff --git a/user_guide_src/source/helpers/url_helper.rst b/user_guide_src/source/helpers/url_helper.rst
index eec0c7067d54..6dcd67ae9994 100644
--- a/user_guide_src/source/helpers/url_helper.rst
+++ b/user_guide_src/source/helpers/url_helper.rst
@@ -20,9 +20,9 @@ The following functions are available:
.. php:function:: site_url([$uri = ''[, $protocol = null[, $altConfig = null]]])
- :param array|string $uri: URI string or array of URI segments
- :param string $protocol: Protocol, e.g., 'http' or 'https'
- :param \\Config\\App $altConfig: Alternate configuration to use
+ :param array|string $uri: URI string or array of URI segments.
+ :param string $protocol: Protocol, e.g., 'http' or 'https'. If empty string '' is set, a protocol-relative link is returned.
+ :param \\Config\\App $altConfig: Alternate configuration to use.
:returns: Site URL
:rtype: string
@@ -56,8 +56,8 @@ The following functions are available:
.. php:function:: base_url([$uri = ''[, $protocol = null]])
- :param array|string $uri: URI string or array of URI segments
- :param string $protocol: Protocol, e.g., 'http' or 'https'
+ :param array|string $uri: URI string or array of URI segments.
+ :param string $protocol: Protocol, e.g., 'http' or 'https'. If empty string '' is set, a protocol-relative link is returned.
:returns: Base URL
:rtype: string
@@ -83,6 +83,11 @@ The following functions are available:
The above example would return something like:
**http://example.com/blog/post/123**
+ If you pass an empty string ``''`` as the second parameter, it returns
+ the protocol-relative link:
+
+ .. literalinclude:: url_helper/026.php
+
This is useful because unlike :php:func:`site_url()`, you can supply a
string to a file, such as an image or stylesheet. For example:
diff --git a/user_guide_src/source/helpers/url_helper/004.php b/user_guide_src/source/helpers/url_helper/004.php
index e820085b3c59..8bc5192b803e 100644
--- a/user_guide_src/source/helpers/url_helper/004.php
+++ b/user_guide_src/source/helpers/url_helper/004.php
@@ -1,3 +1,4 @@
Date: Mon, 5 Feb 2024 11:37:21 +0900
Subject: [PATCH 080/164] docs: modify sentences slightly
---
user_guide_src/source/models/entities.rst | 2 +-
user_guide_src/source/models/entities/018.php | 2 +-
user_guide_src/source/models/entities/020.php | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/user_guide_src/source/models/entities.rst b/user_guide_src/source/models/entities.rst
index 072d41e85793..6e683dcafe0b 100644
--- a/user_guide_src/source/models/entities.rst
+++ b/user_guide_src/source/models/entities.rst
@@ -309,7 +309,7 @@ like ``type[param1, param2]``.
.. literalinclude:: entities/021.php
-.. note:: If the casting type is marked as nullable ``?bool`` and the passed value is not null, then the parameter with
+.. note:: If the casting type is marked as nullable like ``?bool`` and the passed value is not null, then the parameter with
the value ``nullable`` will be passed to the casting type handler.
If casting type has predefined parameters, then ``nullable`` will be added to the end of the list.
diff --git a/user_guide_src/source/models/entities/018.php b/user_guide_src/source/models/entities/018.php
index 2bb8750affe1..1469f5627138 100644
--- a/user_guide_src/source/models/entities/018.php
+++ b/user_guide_src/source/models/entities/018.php
@@ -6,7 +6,7 @@
class MyEntity extends Entity
{
- // Specifying the type for the field
+ // Specify the type for the field
protected $casts = [
'key' => 'base64',
];
diff --git a/user_guide_src/source/models/entities/020.php b/user_guide_src/source/models/entities/020.php
index 7d3708b044d8..bedf6d12f947 100644
--- a/user_guide_src/source/models/entities/020.php
+++ b/user_guide_src/source/models/entities/020.php
@@ -6,7 +6,7 @@
class MyEntity extends Entity
{
- // Defining a type with parameters
+ // Define a type with parameters
protected $casts = [
'some_attribute' => 'class[App\SomeClass, param2, param3]',
];
From 1f34ccf2622c5b0ae1f727da4d539e03ef0f48df Mon Sep 17 00:00:00 2001
From: kenjis
Date: Mon, 5 Feb 2024 15:11:37 +0900
Subject: [PATCH 081/164] docs: add link to detailed page
---
user_guide_src/source/installation/running.rst | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/user_guide_src/source/installation/running.rst b/user_guide_src/source/installation/running.rst
index 2538cfee2d9a..b9992ed7950a 100644
--- a/user_guide_src/source/installation/running.rst
+++ b/user_guide_src/source/installation/running.rst
@@ -49,9 +49,10 @@ Open the **app/Config/App.php** file with a text editor.
Configure Database Connection Settings
======================================
-If you intend to use a database, open the
-**app/Config/Database.php** file with a text editor and set your
-database settings. Alternately, these could be set in your **.env** file.
+If you intend to use a database, open the **app/Config/Database.php** file with
+a text editor and set your database settings. Alternately, these could be set in
+your **.env** file. See :ref:`Database Configuration `
+for details.
Set to Development Mode
=======================
From 464ebb80b70577f8a0098b8935f95aca81ba9c05 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Mon, 5 Feb 2024 15:23:29 +0900
Subject: [PATCH 082/164] docs: update @var type
---
app/Config/App.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/Config/App.php b/app/Config/App.php
index 6ae678625e7b..c2ac69fcccd1 100644
--- a/app/Config/App.php
+++ b/app/Config/App.php
@@ -94,7 +94,7 @@ class App extends BaseConfig
*
* IncomingRequest::setLocale() also uses this list.
*
- * @var string[]
+ * @var list
*/
public array $supportedLocales = ['en'];
From 857e14ee2e793c98bd731545c6d3d588cad19714 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Mon, 5 Feb 2024 15:23:57 +0900
Subject: [PATCH 083/164] docs: add "E.g.,"
---
app/Config/App.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/Config/App.php b/app/Config/App.php
index c2ac69fcccd1..34f19813563e 100644
--- a/app/Config/App.php
+++ b/app/Config/App.php
@@ -14,7 +14,7 @@ class App extends BaseConfig
* URL to your CodeIgniter root. Typically, this will be your base URL,
* WITH a trailing slash:
*
- * http://example.com/
+ * E.g., http://example.com/
*/
public string $baseURL = 'http://localhost:8080/';
From 1bbb26c003f881cb078a823a0c489f05dd3ca9c4 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Mon, 5 Feb 2024 15:24:52 +0900
Subject: [PATCH 084/164] docs: add ","
---
app/Config/App.php | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/app/Config/App.php b/app/Config/App.php
index 34f19813563e..1afe256ad323 100644
--- a/app/Config/App.php
+++ b/app/Config/App.php
@@ -36,9 +36,9 @@ class App extends BaseConfig
* Index File
* --------------------------------------------------------------------------
*
- * Typically this will be your index.php file, unless you've renamed it to
- * something else. If you are using mod_rewrite to remove the page set this
- * variable so that it is blank.
+ * Typically, this will be your `index.php` file, unless you've renamed it to
+ * something else. If you have configured your web server to remove this file
+ * from your site URIs, set this variable to an empty string.
*/
public string $indexPage = 'index.php';
From 4c03c9355f9ad0b74933944502f2ad7b30c32664 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Mon, 5 Feb 2024 15:25:23 +0900
Subject: [PATCH 085/164] docs: break long lines
---
app/Config/App.php | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/app/Config/App.php b/app/Config/App.php
index 1afe256ad323..3d7b971ab89f 100644
--- a/app/Config/App.php
+++ b/app/Config/App.php
@@ -22,10 +22,10 @@ class App extends BaseConfig
* Allowed Hostnames in the Site URL other than the hostname in the baseURL.
* If you want to accept multiple Hostnames, set this.
*
- * E.g. When your site URL ($baseURL) is 'http://example.com/', and your site
- * also accepts 'http://media.example.com/' and
- * 'http://accounts.example.com/':
- * ['media.example.com', 'accounts.example.com']
+ * E.g.,
+ * When your site URL ($baseURL) is 'http://example.com/', and your site
+ * also accepts 'http://media.example.com/' and 'http://accounts.example.com/':
+ * ['media.example.com', 'accounts.example.com']
*
* @var list
*/
@@ -106,7 +106,8 @@ class App extends BaseConfig
* The default timezone that will be used in your application to display
* dates with the date helper, and can be retrieved through app_timezone()
*
- * @see https://www.php.net/manual/en/timezones.php for list of timezones supported by PHP.
+ * @see https://www.php.net/manual/en/timezones.php for list of timezones
+ * supported by PHP.
*/
public string $appTimezone = 'UTC';
From e32d1d2f44fad1b737d6157192ce31fa84127503 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Mon, 5 Feb 2024 15:25:43 +0900
Subject: [PATCH 086/164] docs: remove duplicate space
---
app/Config/App.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/Config/App.php b/app/Config/App.php
index 3d7b971ab89f..8883d061f05f 100644
--- a/app/Config/App.php
+++ b/app/Config/App.php
@@ -48,7 +48,7 @@ class App extends BaseConfig
* --------------------------------------------------------------------------
*
* This item determines which server global should be used to retrieve the
- * URI string. The default setting of 'REQUEST_URI' works for most servers.
+ * URI string. The default setting of 'REQUEST_URI' works for most servers.
* If your links do not seem to work, try one of the other delicious flavors:
*
* 'REQUEST_URI' Uses $_SERVER['REQUEST_URI']
From 61bf6fd8c3069feed384a61c509bee0ad82c5812 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Mon, 5 Feb 2024 15:26:03 +0900
Subject: [PATCH 087/164] docs: add keyword "HSTS"
---
app/Config/App.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/Config/App.php b/app/Config/App.php
index 8883d061f05f..1a359ed3a49e 100644
--- a/app/Config/App.php
+++ b/app/Config/App.php
@@ -131,7 +131,7 @@ class App extends BaseConfig
* If true, this will force every request made to this application to be
* made via a secure connection (HTTPS). If the incoming request is not
* secure, the user will be redirected to a secure version of the page
- * and the HTTP Strict Transport Security header will be set.
+ * and the HTTP Strict Transport Security (HSTS) header will be set.
*/
public bool $forceGlobalSecureRequests = false;
From bf1057ee5c7ef8e47500a945bebc87b3b2898d0d Mon Sep 17 00:00:00 2001
From: kenjis
Date: Mon, 5 Feb 2024 15:27:44 +0900
Subject: [PATCH 088/164] docs: improve readability
---
app/Config/App.php | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/app/Config/App.php b/app/Config/App.php
index 1a359ed3a49e..21b4df205286 100644
--- a/app/Config/App.php
+++ b/app/Config/App.php
@@ -51,9 +51,9 @@ class App extends BaseConfig
* URI string. The default setting of 'REQUEST_URI' works for most servers.
* If your links do not seem to work, try one of the other delicious flavors:
*
- * 'REQUEST_URI' Uses $_SERVER['REQUEST_URI']
- * 'QUERY_STRING' Uses $_SERVER['QUERY_STRING']
- * 'PATH_INFO' Uses $_SERVER['PATH_INFO']
+ * 'REQUEST_URI': Uses $_SERVER['REQUEST_URI']
+ * 'QUERY_STRING': Uses $_SERVER['QUERY_STRING']
+ * 'PATH_INFO': Uses $_SERVER['PATH_INFO']
*
* WARNING: If you set this to 'PATH_INFO', URIs will always be URL-decoded!
*/
From 01f616a304950cbbc08b4bdeb63c5009b2d0fc9f Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 5 Feb 2024 15:53:10 +0000
Subject: [PATCH 089/164] chore(deps-dev): update rector/rector requirement
from 0.19.5 to 0.19.8
Updates the requirements on [rector/rector](https://github.com/rectorphp/rector) to permit the latest version.
- [Release notes](https://github.com/rectorphp/rector/releases)
- [Commits](https://github.com/rectorphp/rector/compare/0.19.5...0.19.8)
---
updated-dependencies:
- dependency-name: rector/rector
dependency-type: direct:development
...
Signed-off-by: dependabot[bot]
---
composer.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/composer.json b/composer.json
index 8ce1815a81b1..9d0cbb8487ba 100644
--- a/composer.json
+++ b/composer.json
@@ -34,7 +34,7 @@
"phpunit/phpcov": "^8.2",
"phpunit/phpunit": "^9.1",
"predis/predis": "^1.1 || ^2.0",
- "rector/rector": "0.19.5",
+ "rector/rector": "0.19.8",
"vimeo/psalm": "^5.0"
},
"replace": {
From 23a34dfd43eb53c791b4d0ffa4117e341e2f9236 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Tue, 6 Feb 2024 10:53:22 +0900
Subject: [PATCH 090/164] chore: allow to use @property-read and
@property-write
---
.php-cs-fixer.dist.php | 30 +++++++++++++++++++++++++++++-
1 file changed, 29 insertions(+), 1 deletion(-)
diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php
index 3653cf1349c2..6a86ebe205e5 100644
--- a/.php-cs-fixer.dist.php
+++ b/.php-cs-fixer.dist.php
@@ -43,7 +43,35 @@
__DIR__ . '/spark',
]);
-$overrides = [];
+$overrides = [
+ 'phpdoc_no_alias_tag' => [
+ 'replacements' => [
+ 'type' => 'var',
+ 'link' => 'see',
+ ],
+ ],
+ 'phpdoc_align' => [
+ 'align' => 'vertical',
+ 'spacing' => 1,
+ 'tags' => [
+ 'method',
+ 'param',
+ 'phpstan-assert',
+ 'phpstan-assert-if-true',
+ 'phpstan-assert-if-false',
+ 'phpstan-param',
+ 'phpstan-property',
+ 'phpstan-return',
+ 'property',
+ 'property-read',
+ 'property-write',
+ 'return',
+ 'throws',
+ 'type',
+ 'var',
+ ],
+ ],
+];
$options = [
'cacheFile' => 'build/.php-cs-fixer.cache',
From 1ed7245a41feae39cd2b50d05a7d3b35b1f75a0b Mon Sep 17 00:00:00 2001
From: kenjis
Date: Tue, 6 Feb 2024 10:54:03 +0900
Subject: [PATCH 091/164] docs: add/update @property
---
phpstan-baseline.php | 10 -----
system/Database/BaseConnection.php | 54 ++++++++++++-------------
system/Database/ConnectionInterface.php | 3 ++
3 files changed, 30 insertions(+), 37 deletions(-)
diff --git a/phpstan-baseline.php b/phpstan-baseline.php
index cc669afb1e74..3b79f9639943 100644
--- a/phpstan-baseline.php
+++ b/phpstan-baseline.php
@@ -1026,16 +1026,6 @@
'count' => 1,
'path' => __DIR__ . '/system/Database/Config.php',
];
-$ignoreErrors[] = [
- 'message' => '#^Access to an undefined property CodeIgniter\\\\Database\\\\ConnectionInterface\\:\\:\\$DBDriver\\.$#',
- 'count' => 2,
- 'path' => __DIR__ . '/system/Database/Database.php',
-];
-$ignoreErrors[] = [
- 'message' => '#^Access to an undefined property CodeIgniter\\\\Database\\\\ConnectionInterface\\:\\:\\$connID\\.$#',
- 'count' => 2,
- 'path' => __DIR__ . '/system/Database/Database.php',
-];
$ignoreErrors[] = [
'message' => '#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#',
'count' => 2,
diff --git a/system/Database/BaseConnection.php b/system/Database/BaseConnection.php
index a024d938f386..4e34e0fdb699 100644
--- a/system/Database/BaseConnection.php
+++ b/system/Database/BaseConnection.php
@@ -18,33 +18,33 @@
use Throwable;
/**
- * @property array $aliasedTables
- * @property string $charset
- * @property bool $compress
- * @property float $connectDuration
- * @property float $connectTime
- * @property string $database
- * @property string $DBCollat
- * @property bool $DBDebug
- * @property string $DBDriver
- * @property string $DBPrefix
- * @property string $DSN
- * @property array|bool $encrypt
- * @property array $failover
- * @property string $hostname
- * @property Query $lastQuery
- * @property string $password
- * @property bool $pConnect
- * @property int|string $port
- * @property bool $pretend
- * @property string $queryClass
- * @property array $reservedIdentifiers
- * @property bool $strictOn
- * @property string $subdriver
- * @property string $swapPre
- * @property int $transDepth
- * @property bool $transFailure
- * @property bool $transStatus
+ * @property-read array $aliasedTables
+ * @property-read string $charset
+ * @property-read bool $compress
+ * @property-read float $connectDuration
+ * @property-read float $connectTime
+ * @property-read string $database
+ * @property-read string $DBCollat
+ * @property-read bool $DBDebug
+ * @property-read string $DBDriver
+ * @property-read string $DBPrefix
+ * @property-read string $DSN
+ * @property-read array|bool $encrypt
+ * @property-read array $failover
+ * @property-read string $hostname
+ * @property-read Query $lastQuery
+ * @property-read string $password
+ * @property-read bool $pConnect
+ * @property-read int|string $port
+ * @property-read bool $pretend
+ * @property-read string $queryClass
+ * @property-read array $reservedIdentifiers
+ * @property-read bool $strictOn
+ * @property-read string $subdriver
+ * @property-read string $swapPre
+ * @property-read int $transDepth
+ * @property-read bool $transFailure
+ * @property-read bool $transStatus
*
* @template TConnection
* @template TResult
diff --git a/system/Database/ConnectionInterface.php b/system/Database/ConnectionInterface.php
index a8493f897ec7..ed45933734a2 100644
--- a/system/Database/ConnectionInterface.php
+++ b/system/Database/ConnectionInterface.php
@@ -14,6 +14,9 @@
/**
* @template TConnection
* @template TResult
+ *
+ * @property false|object|resource $connID
+ * @property-read string $DBDriver
*/
interface ConnectionInterface
{
From 069e9c644afae2617bd7e5688c59b7e725edd5b1 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Tue, 6 Feb 2024 15:42:10 +0000
Subject: [PATCH 092/164] chore(deps-dev): update rector/rector requirement
from 0.19.8 to 1.0.0
Updates the requirements on [rector/rector](https://github.com/rectorphp/rector) to permit the latest version.
- [Release notes](https://github.com/rectorphp/rector/releases)
- [Commits](https://github.com/rectorphp/rector/compare/0.19.8...1.0.0)
---
updated-dependencies:
- dependency-name: rector/rector
dependency-type: direct:development
...
Signed-off-by: dependabot[bot]
---
composer.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/composer.json b/composer.json
index 9d0cbb8487ba..6a7ab7714cba 100644
--- a/composer.json
+++ b/composer.json
@@ -34,7 +34,7 @@
"phpunit/phpcov": "^8.2",
"phpunit/phpunit": "^9.1",
"predis/predis": "^1.1 || ^2.0",
- "rector/rector": "0.19.8",
+ "rector/rector": "1.0.0",
"vimeo/psalm": "^5.0"
},
"replace": {
From 6d3ffc0c484648c230f639b406e1a62a9bd635d0 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Wed, 7 Feb 2024 09:08:17 +0900
Subject: [PATCH 093/164] docs: add links to view() function
---
user_guide_src/source/outgoing/views.rst | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/user_guide_src/source/outgoing/views.rst b/user_guide_src/source/outgoing/views.rst
index 70bbadcc7504..fabd811de87a 100644
--- a/user_guide_src/source/outgoing/views.rst
+++ b/user_guide_src/source/outgoing/views.rst
@@ -37,7 +37,8 @@ Then save the file in your **app/Views** directory.
Displaying a View
=================
-To load and display a particular view file you will use the following code in your controller:
+To load and display a particular view file you will use the :php:func:`view()`
+function like following code in your controller:
.. literalinclude:: views/001.php
:lines: 2-
@@ -64,8 +65,10 @@ If you visit your site, you should see your new view. The URL was similar to thi
Loading Multiple Views
======================
-CodeIgniter will intelligently handle multiple calls to ``view()`` from within a controller. If more than one
-call happens they will be appended together. For example, you may wish to have a header view, a menu view, a
+CodeIgniter will intelligently handle multiple calls to :php:func:`view()` from
+within a controller. If more than one call happens they will be appended together.
+
+For example, you may wish to have a header view, a menu view, a
content view, and a footer view. That might look something like this:
.. literalinclude:: views/003.php
@@ -101,8 +104,8 @@ example, you could load the **blog_view.php** file from **example/blog/Views** b
Caching Views
=============
-You can cache a view with the ``view()`` function by passing a ``cache`` option with the number of seconds to cache
-the view for, in the third parameter:
+You can cache a view with the :php:func:`view()` function by passing a ``cache``
+option with the number of seconds to cache the view for, in the third parameter:
.. literalinclude:: views/006.php
:lines: 2-
@@ -116,7 +119,9 @@ along ``cache_name`` and the cache ID you wish to use:
Adding Dynamic Data to the View
===============================
-Data is passed from the controller to the view by way of an array in the second parameter of the ``view()`` function.
+Data is passed from the controller to the view by way of an array in the second
+parameter of the :php:func:`view()` function.
+
Here's an example:
.. literalinclude:: views/008.php
@@ -142,8 +147,9 @@ Then load the page at the URL you've been using and you should see the variables
The saveData Option
-------------------
-The data passed in is retained for subsequent calls to ``view()``. If you call the function multiple times
-in a single request, you will not have to pass the desired data to each ``view()``.
+The data passed in is retained for subsequent calls to :php:func:`view()`. If you
+call the function multiple times in a single request, you will not have to pass
+the desired data to each ``view()``.
But this might not keep any data from "bleeding" into
other views, potentially causing issues. If you would prefer to clean the data after one call, you can pass the ``saveData`` option
From 97660696cf72248b1e1c3ff9c7961bfd75aaa70f Mon Sep 17 00:00:00 2001
From: kenjis
Date: Wed, 7 Feb 2024 09:08:49 +0900
Subject: [PATCH 094/164] docs: add link to view_renderer
---
user_guide_src/source/general/common_functions.rst | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/user_guide_src/source/general/common_functions.rst b/user_guide_src/source/general/common_functions.rst
index 75d2cbebd13c..bebf3cb3eaad 100755
--- a/user_guide_src/source/general/common_functions.rst
+++ b/user_guide_src/source/general/common_functions.rst
@@ -197,7 +197,8 @@ Service Accessors
.. literalinclude:: common_functions/004.php
- For more details, see the :doc:`Views ` page.
+ For more details, see the :doc:`Views <../outgoing/views>` and
+ :doc:`../outgoing/view_renderer` page.
.. php:function:: view_cell($library[, $params = null[, $ttl = 0[, $cacheName = null]]])
From 0cec717cab690ef6f985ed651af7f627369156aa Mon Sep 17 00:00:00 2001
From: kenjis
Date: Wed, 7 Feb 2024 09:09:18 +0900
Subject: [PATCH 095/164] docs: make description more precise
---
.../source/outgoing/view_renderer.rst | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/user_guide_src/source/outgoing/view_renderer.rst b/user_guide_src/source/outgoing/view_renderer.rst
index 618a90c4a516..06e15a809e00 100644
--- a/user_guide_src/source/outgoing/view_renderer.rst
+++ b/user_guide_src/source/outgoing/view_renderer.rst
@@ -116,11 +116,18 @@ View Renderer Options
Several options can be passed to the ``render()`` or ``renderString()`` methods:
-- ``cache`` - the time in seconds, to save a view's results; ignored for renderString()
-- ``cache_name`` - the ID used to save/retrieve a cached view result; defaults to the viewpath; ignored for ``renderString()``
-- ``saveData`` - true if the view data parameters should be retained for subsequent calls
-
-.. note:: ``saveData()`` as defined by the interface must be a boolean, but implementing
+- ``$options``
+
+ - ``cache`` - the time in seconds, to save a view's results; ignored for
+ ``renderString()``.
+ - ``cache_name`` - the ID used to save/retrieve a cached view result; defaults
+ to the ``$viewPath``; ignored for ``renderString()``.
+ - ``debug`` - can be set to false to disable the addition of debug code for
+ :ref:`Debug Toolbar `.
+- ``$saveData`` - true if the view data parameters should be retained for
+ subsequent calls.
+
+.. note:: ``$saveData`` as defined by the interface must be a boolean, but implementing
classes (like ``View`` below) may extend this to include ``null`` values.
***************
From 28721e78f12961d9c4bbaa18795383cf7c63029d Mon Sep 17 00:00:00 2001
From: kenjis
Date: Wed, 7 Feb 2024 09:14:59 +0900
Subject: [PATCH 096/164] docs: add missing null to @param
---
system/View/RendererInterface.php | 30 ++++++++++++++----------------
1 file changed, 14 insertions(+), 16 deletions(-)
diff --git a/system/View/RendererInterface.php b/system/View/RendererInterface.php
index 4bb889743f9f..ba2ee7df802f 100644
--- a/system/View/RendererInterface.php
+++ b/system/View/RendererInterface.php
@@ -22,10 +22,10 @@ interface RendererInterface
* Builds the output based upon a file name and any
* data that has already been set.
*
- * @param array $options Reserved for 3rd-party uses since
- * it might be needed to pass additional info
- * to other template engines.
- * @param bool $saveData Whether to save data for subsequent calls
+ * @param array|null $options Reserved for 3rd-party uses since
+ * it might be needed to pass additional info
+ * to other template engines.
+ * @param bool $saveData Whether to save data for subsequent calls
*/
public function render(string $view, ?array $options = null, bool $saveData = false): string;
@@ -33,20 +33,19 @@ public function render(string $view, ?array $options = null, bool $saveData = fa
* Builds the output based upon a string and any
* data that has already been set.
*
- * @param string $view The view contents
- * @param array $options Reserved for 3rd-party uses since
- * it might be needed to pass additional info
- * to other template engines.
- * @param bool $saveData Whether to save data for subsequent calls
+ * @param string $view The view contents
+ * @param array|null $options Reserved for 3rd-party uses since
+ * it might be needed to pass additional info
+ * to other template engines.
+ * @param bool $saveData Whether to save data for subsequent calls
*/
public function renderString(string $view, ?array $options = null, bool $saveData = false): string;
/**
* Sets several pieces of view data at once.
*
- * @param string $context The context to escape it for: html, css, js, url
- * If 'raw', no escaping will happen
- * @phpstan-param null|'html'|'js'|'css'|'url'|'attr'|'raw' $context
+ * @param string|null $context The context to escape it for: html, css, js, url
+ * If 'raw', no escaping will happen
*
* @return RendererInterface
*/
@@ -55,10 +54,9 @@ public function setData(array $data = [], ?string $context = null);
/**
* Sets a single piece of view data.
*
- * @param mixed $value
- * @param string $context The context to escape it for: html, css, js, url
- * If 'raw' no escaping will happen
- * @phpstan-param null|'html'|'js'|'css'|'url'|'attr'|'raw' $context
+ * @param mixed $value
+ * @param string|null $context The context to escape it for: html, css, js, url
+ * If 'raw' no escaping will happen
*
* @return RendererInterface
*/
From d434b8fd2597506b51901a8d4f757694a1fb4fd3 Mon Sep 17 00:00:00 2001
From: kenjis
Date: Wed, 7 Feb 2024 10:01:22 +0900
Subject: [PATCH 097/164] docs: update doc comments
---
system/View/Parser.php | 5 +++--
system/View/RendererInterface.php | 12 +++++++-----
system/View/View.php | 8 ++++----
3 files changed, 14 insertions(+), 11 deletions(-)
diff --git a/system/View/Parser.php b/system/View/Parser.php
index 87f0e96bdce9..ff5656a53863 100644
--- a/system/View/Parser.php
+++ b/system/View/Parser.php
@@ -185,8 +185,9 @@ public function renderString(string $template, ?array $options = null, ?bool $sa
* so that the variable is correctly handled within the
* parsing itself, and contexts (including raw) are respected.
*
- * @param non-empty-string|null $context The context to escape it for: html, css, js, url, raw
- * If 'raw', no escaping will happen
+ * @param non-empty-string|null $context The context to escape it for.
+ * If 'raw', no escaping will happen.
+ * @phpstan-param null|'html'|'js'|'css'|'url'|'attr'|'raw' $context
*/
public function setData(array $data = [], ?string $context = null): RendererInterface
{
diff --git a/system/View/RendererInterface.php b/system/View/RendererInterface.php
index ba2ee7df802f..c4edeb9550f4 100644
--- a/system/View/RendererInterface.php
+++ b/system/View/RendererInterface.php
@@ -44,8 +44,9 @@ public function renderString(string $view, ?array $options = null, bool $saveDat
/**
* Sets several pieces of view data at once.
*
- * @param string|null $context The context to escape it for: html, css, js, url
- * If 'raw', no escaping will happen
+ * @param non-empty-string|null $context The context to escape it for.
+ * If 'raw', no escaping will happen.
+ * @phpstan-param null|'html'|'js'|'css'|'url'|'attr'|'raw' $context
*
* @return RendererInterface
*/
@@ -54,9 +55,10 @@ public function setData(array $data = [], ?string $context = null);
/**
* Sets a single piece of view data.
*
- * @param mixed $value
- * @param string|null $context The context to escape it for: html, css, js, url
- * If 'raw' no escaping will happen
+ * @param mixed $value
+ * @param non-empty-string|null $context The context to escape it for.
+ * If 'raw', no escaping will happen.
+ * @phpstan-param null|'html'|'js'|'css'|'url'|'attr'|'raw' $context
*
* @return RendererInterface
*/
diff --git a/system/View/View.php b/system/View/View.php
index 8940951a42aa..ad5c38de9b2f 100644
--- a/system/View/View.php
+++ b/system/View/View.php
@@ -330,8 +330,8 @@ public function excerpt(string $string, int $length = 20): string
/**
* Sets several pieces of view data at once.
*
- * @param string|null $context The context to escape it for: html, css, js, url
- * If null, no escaping will happen
+ * @param non-empty-string|null $context The context to escape it for.
+ * If 'raw', no escaping will happen.
* @phpstan-param null|'html'|'js'|'css'|'url'|'attr'|'raw' $context
*/
public function setData(array $data = [], ?string $context = null): RendererInterface
@@ -350,8 +350,8 @@ public function setData(array $data = [], ?string $context = null): RendererInte
* Sets a single piece of view data.
*
* @param mixed $value
- * @param string|null $context The context to escape it for: html, css, js, url
- * If null, no escaping will happen
+ * @param non-empty-string|null $context The context to escape it for.
+ * If 'raw', no escaping will happen.
* @phpstan-param null|'html'|'js'|'css'|'url'|'attr'|'raw' $context
*/
public function setVar(string $name, $value = null, ?string $context = null): RendererInterface
From c060e01de2e542054f741bd5e80dccfb85c55ebd Mon Sep 17 00:00:00 2001
From: kenjis
Date: Wed, 7 Feb 2024 11:03:42 +0900
Subject: [PATCH 098/164] fix: Postgre updateBatch() breaks `char` type data
---
system/Database/Postgre/Builder.php | 11 ++++++++++-
tests/system/Database/Live/UpdateTest.php | 6 +++++-
2 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/system/Database/Postgre/Builder.php b/system/Database/Postgre/Builder.php
index 8bd008f20916..40d751b71e67 100644
--- a/system/Database/Postgre/Builder.php
+++ b/system/Database/Postgre/Builder.php
@@ -431,7 +431,16 @@ private function getFieldType(string $table, string $fieldName): ?string
$this->QBOptions['fieldTypes'][$table] = [];
foreach ($this->db->getFieldData($table) as $field) {
- $this->QBOptions['fieldTypes'][$table][$field->name] = $field->type;
+ $type = $field->type;
+
+ // If `character` (or `char`) lacks a specifier, it is equivalent
+ // to `character(1)`.
+ // See https://www.postgresql.org/docs/current/datatype-character.html
+ if ($field->type === 'character') {
+ $type = $field->type . '(' . $field->max_length . ')';
+ }
+
+ $this->QBOptions['fieldTypes'][$table][$field->name] = $type;
}
}
diff --git a/tests/system/Database/Live/UpdateTest.php b/tests/system/Database/Live/UpdateTest.php
index f8b0ced088db..fe270ac53da8 100644
--- a/tests/system/Database/Live/UpdateTest.php
+++ b/tests/system/Database/Live/UpdateTest.php
@@ -125,7 +125,7 @@ public function testUpdateBatch(string $constraints, array $data, array $expecte
for ($i = 1; $i < 4; $i++) {
$builder->insert([
'type_varchar' => 'test' . $i,
- 'type_char' => 'char',
+ 'type_char' => 'char' . $i,
'type_text' => 'text',
'type_smallint' => 32767,
'type_integer' => 2_147_483_647,
@@ -159,6 +159,7 @@ public static function provideUpdateBatch(): iterable
[
[
'type_varchar' => 'test1', // Key
+ 'type_char' => 'updated',
'type_text' => 'updated',
'type_smallint' => 9999,
'type_integer' => 9_999_999,
@@ -170,6 +171,7 @@ public static function provideUpdateBatch(): iterable
],
[
'type_varchar' => 'test2', // Key
+ 'type_char' => 'updated',
'type_text' => 'updated',
'type_smallint' => 9999,
'type_integer' => 9_999_999,
@@ -183,6 +185,7 @@ public static function provideUpdateBatch(): iterable
[
[
'type_varchar' => 'test1',
+ 'type_char' => 'updated',
'type_text' => 'updated',
'type_smallint' => 9999,
'type_integer' => 9_999_999,
@@ -193,6 +196,7 @@ public static function provideUpdateBatch(): iterable
],
[
'type_varchar' => 'test2',
+ 'type_char' => 'updated',
'type_text' => 'updated',
'type_smallint' => 9999,
'type_integer' => 9_999_999,
From 345eb4a005383f5d3deabb7624fcbdee2b89e546 Mon Sep 17 00:00:00 2001
From: Denny Septian Panggabean
Date: Fri, 9 Feb 2024 09:43:45 +0700
Subject: [PATCH 099/164] refactor: possible one liner in Helper
---
system/Helpers/array_helper.php | 7 +-----
system/Helpers/filesystem_helper.php | 8 +-----
system/Helpers/form_helper.php | 8 +-----
system/Helpers/html_helper.php | 37 ++++------------------------
system/Helpers/text_helper.php | 12 ++-------
5 files changed, 10 insertions(+), 62 deletions(-)
diff --git a/system/Helpers/array_helper.php b/system/Helpers/array_helper.php
index b8bd1a4d956f..4c7f7f4b51e8 100644
--- a/system/Helpers/array_helper.php
+++ b/system/Helpers/array_helper.php
@@ -72,12 +72,7 @@ function _array_search_dot(array $indexes, array $array)
$answer = array_filter($answer, static fn ($value) => $value !== null);
if ($answer !== []) {
- if (count($answer) === 1) {
- // If array only has one element, we return that element for BC.
- return current($answer);
- }
-
- return $answer;
+ return count($answer) === 1 ? current($answer) : $answer;
}
return null;
diff --git a/system/Helpers/filesystem_helper.php b/system/Helpers/filesystem_helper.php
index 4e0e8b1532e9..dc64ce18a986 100644
--- a/system/Helpers/filesystem_helper.php
+++ b/system/Helpers/filesystem_helper.php
@@ -218,13 +218,7 @@ function get_filenames(
}
if ($includeDir || ! $object->isDir()) {
- if ($includePath === false) {
- $files[] = $basename;
- } elseif ($includePath === null) {
- $files[] = str_replace($sourceDir, '', $name);
- } else {
- $files[] = $name;
- }
+ $files[] = $includePath === false ? $basename : ($includePath === null ? str_replace($sourceDir, '', $name) : $name);
}
}
} catch (Throwable $e) {
diff --git a/system/Helpers/form_helper.php b/system/Helpers/form_helper.php
index d3abd7e247b0..cd3f874b28f9 100644
--- a/system/Helpers/form_helper.php
+++ b/system/Helpers/form_helper.php
@@ -656,13 +656,7 @@ function set_radio(string $field, string $value = '', bool $default = false): st
$postInput = $request->getPost($field);
- if ($oldInput !== null) {
- $input = $oldInput;
- } elseif ($postInput !== null) {
- $input = $postInput;
- } else {
- $input = $default;
- }
+ $input = $oldInput !== null ? $oldInput : ($postInput !== null ? $postInput : $default);
if (is_array($input)) {
// Note: in_array('', array(0)) returns TRUE, do not use it
diff --git a/system/Helpers/html_helper.php b/system/Helpers/html_helper.php
index 075dcd510b43..8fd4231dc975 100755
--- a/system/Helpers/html_helper.php
+++ b/system/Helpers/html_helper.php
@@ -66,14 +66,7 @@ function _list(string $type = 'ul', $list = [], $attributes = '', int $depth = 0
foreach ($list as $key => $val) {
$out .= str_repeat(' ', $depth + 2) . '