mirror of
https://github.com/codeigniter4/CodeIgniter4.git
synced 2025-02-20 11:44:28 +08:00
Merge remote-tracking branch 'upstream/develop' into 4.5
This commit is contained in:
commit
47675842c4
@ -150,10 +150,6 @@
|
||||
.timer {
|
||||
background-color: $g-orange;
|
||||
}
|
||||
|
||||
.timeline-parent-open td {
|
||||
color: $t-dark;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,9 @@ the official website: <https://sass-lang.com/install>
|
||||
Open your terminal, and navigate to CodeIgniter's root folder. To
|
||||
generate the CSS file, use the following command:
|
||||
|
||||
`sass --no-source-map admin/css/debug-toolbar/toolbar.scss system/Debug/Toolbar/Views/toolbar.css`
|
||||
```console
|
||||
sass --no-source-map admin/css/debug-toolbar/toolbar.scss system/Debug/Toolbar/Views/toolbar.css`
|
||||
```
|
||||
|
||||
Details:
|
||||
- `--no-source-map` is an option which prevents sourcemap files from being generated
|
||||
@ -18,23 +20,4 @@ Details:
|
||||
|
||||
## Color scheme
|
||||
|
||||
**Themes**
|
||||
|
||||
Dark: `#252525` / `rgb(37, 37, 37)`
|
||||
Light: `#FFFFFF` / `rgb(255, 255, 255)`
|
||||
|
||||
**Glossy colors**
|
||||
|
||||
Blue: `#5BC0DE` / `rgb(91, 192, 222)`
|
||||
Gray: `#434343` / `rgb(67, 67, 67)`
|
||||
Green: `#9ACE25` / `rgb(154, 206, 37)`
|
||||
Orange: `#DD8615` / `rgb(221, 134, 21)`
|
||||
Red: `#DD4814` / `rgb(221, 72, 20)`
|
||||
|
||||
**Matt colors**
|
||||
|
||||
Blue: `#D8EAF0` / `rgb(216, 234, 240)`
|
||||
Gray: `#DFDFDF` / `rgb(223, 223, 223)`
|
||||
Green: `#DFF0D8` / `rgb(223, 240, 216)`
|
||||
Orange: `#FDC894` / `rgb(253, 200, 148)`
|
||||
Red: `#EF9090` / `rgb(239, 144, 144)`
|
||||
See [_graphic-charter.scss](../admin/css/debug-toolbar/_graphic-charter.scss).
|
||||
|
@ -532,9 +532,6 @@
|
||||
#debug-bar .timeline .timer {
|
||||
background-color: #DD8615;
|
||||
}
|
||||
#debug-bar .timeline .timeline-parent-open td {
|
||||
color: #252525;
|
||||
}
|
||||
.debug-view.show-view {
|
||||
border-color: #DD8615;
|
||||
}
|
||||
@ -647,9 +644,6 @@
|
||||
#toolbarContainer.dark #debug-bar .timeline .timer {
|
||||
background-color: #DD8615;
|
||||
}
|
||||
#toolbarContainer.dark #debug-bar .timeline .timeline-parent-open td {
|
||||
color: #252525;
|
||||
}
|
||||
#toolbarContainer.dark .debug-view.show-view {
|
||||
border-color: #DD8615;
|
||||
}
|
||||
|
@ -168,12 +168,14 @@ class Validation implements ValidationInterface
|
||||
}
|
||||
|
||||
if (strpos($field, '*') !== false) {
|
||||
$values = array_filter(array_flatten_with_dots($data), static fn ($key) => preg_match(
|
||||
'/^'
|
||||
. str_replace(['\.\*', '\*\.'], ['\..+', '.+\.'], preg_quote($field, '/'))
|
||||
. '$/',
|
||||
$key
|
||||
), ARRAY_FILTER_USE_KEY);
|
||||
$flattenedArray = array_flatten_with_dots($data);
|
||||
|
||||
$values = array_filter(
|
||||
$flattenedArray,
|
||||
static fn ($key) => preg_match(self::getRegex($field), $key),
|
||||
ARRAY_FILTER_USE_KEY
|
||||
);
|
||||
|
||||
// if keys not found
|
||||
$values = $values ?: [$field => null];
|
||||
} else {
|
||||
@ -211,6 +213,20 @@ class Validation implements ValidationInterface
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns regex pattern for key with dot array syntax.
|
||||
*/
|
||||
private static function getRegex(string $field): string
|
||||
{
|
||||
return '/\A'
|
||||
. str_replace(
|
||||
['\.\*', '\*\.'],
|
||||
['\.[^.]+', '[^.]+\.'],
|
||||
preg_quote($field, '/')
|
||||
)
|
||||
. '\z/';
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the validation process, returning true or false determining whether
|
||||
* validation was successful or not.
|
||||
@ -816,9 +832,7 @@ class Validation implements ValidationInterface
|
||||
*/
|
||||
public function hasError(string $field): bool
|
||||
{
|
||||
$pattern = '/^' . str_replace('\.\*', '\..+', preg_quote($field, '/')) . '$/';
|
||||
|
||||
return (bool) preg_grep($pattern, array_keys($this->getErrors()));
|
||||
return (bool) preg_grep(self::getRegex($field), array_keys($this->getErrors()));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -831,10 +845,11 @@ class Validation implements ValidationInterface
|
||||
$field = array_key_first($this->rules);
|
||||
}
|
||||
|
||||
$errors = array_filter($this->getErrors(), static fn ($key) => preg_match(
|
||||
'/^' . str_replace(['\.\*', '\*\.'], ['\..+', '.+\.'], preg_quote($field, '/')) . '$/',
|
||||
$key
|
||||
), ARRAY_FILTER_USE_KEY);
|
||||
$errors = array_filter(
|
||||
$this->getErrors(),
|
||||
static fn ($key) => preg_match(self::getRegex($field), $key),
|
||||
ARRAY_FILTER_USE_KEY
|
||||
);
|
||||
|
||||
return $errors === [] ? '' : implode("\n", $errors);
|
||||
}
|
||||
|
@ -1206,9 +1206,9 @@ class ValidationTest extends CIUnitTestCase
|
||||
$request = new IncomingRequest($config, new URI(), 'php://input', new UserAgent());
|
||||
|
||||
$this->validation->setRules([
|
||||
'id_user.*' => 'numeric',
|
||||
'name_user.*' => 'alpha',
|
||||
'contacts.*.name' => 'required',
|
||||
'id_user.*' => 'numeric',
|
||||
'name_user.*' => 'alpha',
|
||||
'contacts.friends.*.name' => 'required',
|
||||
]);
|
||||
|
||||
$this->validation->withRequest($request->withMethod('post'))->run();
|
||||
@ -1216,7 +1216,7 @@ class ValidationTest extends CIUnitTestCase
|
||||
'id_user.0' => 'The id_user.* field must contain only numbers.',
|
||||
'name_user.0' => 'The name_user.* field may only contain alphabetical characters.',
|
||||
'name_user.2' => 'The name_user.* field may only contain alphabetical characters.',
|
||||
'contacts.friends.0.name' => 'The contacts.*.name field is required.',
|
||||
'contacts.friends.0.name' => 'The contacts.friends.*.name field is required.',
|
||||
], $this->validation->getErrors());
|
||||
|
||||
$this->assertSame(
|
||||
@ -1225,8 +1225,8 @@ class ValidationTest extends CIUnitTestCase
|
||||
$this->validation->getError('name_user.*')
|
||||
);
|
||||
$this->assertSame(
|
||||
'The contacts.*.name field is required.',
|
||||
$this->validation->getError('contacts.*.name')
|
||||
'The contacts.friends.*.name field is required.',
|
||||
$this->validation->getError('contacts.friends.*.name')
|
||||
);
|
||||
}
|
||||
|
||||
@ -1323,17 +1323,17 @@ class ValidationTest extends CIUnitTestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideDotNotationOnIfExistRule
|
||||
* @dataProvider provideIfExistRuleWithAsterisk
|
||||
*
|
||||
* @see https://github.com/codeigniter4/CodeIgniter4/issues/4521
|
||||
*/
|
||||
public function testDotNotationOnIfExistRule(bool $expected, array $rules, array $data): void
|
||||
public function testIfExistRuleWithAsterisk(bool $expected, array $rules, array $data): void
|
||||
{
|
||||
$actual = $this->validation->setRules($rules)->run($data);
|
||||
$this->assertSame($expected, $actual);
|
||||
}
|
||||
|
||||
public static function provideDotNotationOnIfExistRule(): iterable
|
||||
public static function provideIfExistRuleWithAsterisk(): iterable
|
||||
{
|
||||
yield 'dot-on-end-fail' => [
|
||||
false,
|
||||
@ -1708,7 +1708,7 @@ class ValidationTest extends CIUnitTestCase
|
||||
/**
|
||||
* @see https://github.com/codeigniter4/CodeIgniter4/issues/5942
|
||||
*/
|
||||
public function testRequireWithoutWithWildCard(): void
|
||||
public function testRequireWithoutWithAsterisk(): void
|
||||
{
|
||||
$data = [
|
||||
'a' => [
|
||||
@ -1726,4 +1726,50 @@ class ValidationTest extends CIUnitTestCase
|
||||
$this->validation->getError('a.1.c')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see https://github.com/codeigniter4/CodeIgniter4/issues/8128
|
||||
*/
|
||||
public function testRuleWithAsteriskToMultiDimensionalArray(): void
|
||||
{
|
||||
$data = [
|
||||
'contacts' => [
|
||||
'name' => 'Joe Smith',
|
||||
'just' => [
|
||||
'friends' => [
|
||||
[
|
||||
'name' => 'Fred Flinstone',
|
||||
],
|
||||
[
|
||||
'name' => 'Wilma',
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$this->validation->setRules(
|
||||
['contacts.just.friends.*.name' => 'required|max_length[1]']
|
||||
);
|
||||
$this->assertFalse($this->validation->run($data));
|
||||
$this->assertSame(
|
||||
[
|
||||
'contacts.just.friends.0.name' => 'The contacts.just.friends.*.name field cannot exceed 1 characters in length.',
|
||||
'contacts.just.friends.1.name' => 'The contacts.just.friends.*.name field cannot exceed 1 characters in length.',
|
||||
],
|
||||
$this->validation->getErrors()
|
||||
);
|
||||
|
||||
$this->validation->reset();
|
||||
$this->validation->setRules(
|
||||
['contacts.*.name' => 'required|max_length[1]']
|
||||
);
|
||||
$this->assertFalse($this->validation->run($data));
|
||||
$this->assertSame(
|
||||
// The data for `contacts.*.name` does not exist. So it is interpreted
|
||||
// as `null`, and this error message returns.
|
||||
['contacts.*.name' => 'The contacts.*.name field is required.'],
|
||||
$this->validation->getErrors()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,13 @@ Release Date: Unreleased
|
||||
BREAKING
|
||||
********
|
||||
|
||||
Validation with Dot Array Syntax
|
||||
================================
|
||||
|
||||
A validation rule with the wildcard ``*`` now validates only data in correct
|
||||
dimensions as "dot array syntax".
|
||||
See :ref:`Upgrading <upgrade-444-validation-with-dot-array-syntax>` for details.
|
||||
|
||||
***************
|
||||
Message Changes
|
||||
***************
|
||||
|
@ -20,6 +20,25 @@ Mandatory File Changes
|
||||
Breaking Changes
|
||||
****************
|
||||
|
||||
.. _upgrade-444-validation-with-dot-array-syntax:
|
||||
|
||||
Validation with Dot Array Syntax
|
||||
================================
|
||||
|
||||
If you are using :ref:`dot array syntax <validation-dot-array-syntax>` in validation
|
||||
rules, a bug where ``*`` would validate data in incorrect dimensions has been fixed.
|
||||
|
||||
In previous versions, the rule key ``contacts.*.name`` captured data with any
|
||||
level like ``contacts.*.name``, ``contacts.*.*.name``, ``contacts.*.*.*.name``,
|
||||
etc., incorrectly.
|
||||
|
||||
The following code explains details:
|
||||
|
||||
.. literalinclude:: upgrade_444/001.php
|
||||
:lines: 2-
|
||||
|
||||
If you have code that depends on the bug, fix the the rule key.
|
||||
|
||||
*********************
|
||||
Breaking Enhancements
|
||||
*********************
|
||||
|
38
user_guide_src/source/installation/upgrade_444/001.php
Normal file
38
user_guide_src/source/installation/upgrade_444/001.php
Normal file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
use Config\Services;
|
||||
|
||||
$validation = Services::validation();
|
||||
|
||||
$data = [
|
||||
'contacts' => [
|
||||
'name' => 'Joe Smith',
|
||||
'just' => [
|
||||
'friends' => [
|
||||
['name' => 'SATO Taro'],
|
||||
['name' => 'Li Ming'],
|
||||
['name' => 'Heinz Müller'],
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$validation->setRules(
|
||||
['contacts.*.name' => 'required|max_length[8]']
|
||||
);
|
||||
|
||||
$validation->run($data); // false
|
||||
|
||||
d($validation->getErrors());
|
||||
/*
|
||||
Before: Captured `contacts.*.*.*.name` incorrectly.
|
||||
[
|
||||
contacts.just.friends.0.name => "The contacts.*.name field cannot exceed 8 characters in length.",
|
||||
contacts.just.friends.2.name => "The contacts.*.name field cannot exceed 8 characters in length.",
|
||||
]
|
||||
|
||||
After: Captures no data for `contacts.*.name`.
|
||||
[
|
||||
contacts.*.name => string (38) "The contacts.*.name field is required.",
|
||||
]
|
||||
*/
|
@ -325,6 +325,8 @@ To give a labeled error message you can set up as:
|
||||
.. note:: ``setRules()`` will overwrite any rules that were set previously. To add more than one
|
||||
rule to an existing set of rules, use ``setRule()`` multiple times.
|
||||
|
||||
.. _validation-dot-array-syntax:
|
||||
|
||||
Setting Rules for Array Data
|
||||
============================
|
||||
|
||||
@ -339,6 +341,10 @@ You can use the ``*`` wildcard symbol to match any one level of the array:
|
||||
.. literalinclude:: validation/010.php
|
||||
:lines: 2-
|
||||
|
||||
.. note:: Prior to v4.4.4, due to a bug, the wildcard ``*`` validated data in incorrect
|
||||
dimensions. See :ref:`Upgrading <upgrade-444-validation-with-dot-array-syntax>`
|
||||
for details.
|
||||
|
||||
"dot array syntax" can also be useful when you have single dimension array data.
|
||||
For example, data returned by multi select dropdown:
|
||||
|
||||
@ -602,7 +608,7 @@ If you need to retrieve all error messages for failed fields, you can use the ``
|
||||
|
||||
If no errors exist, an empty array will be returned.
|
||||
|
||||
When using a wildcard, the error will point to a specific field, replacing the asterisk with the appropriate key/keys::
|
||||
When using a wildcard (``*``), the error will point to a specific field, replacing the asterisk with the appropriate key/keys::
|
||||
|
||||
// for data
|
||||
'contacts' => [
|
||||
@ -617,10 +623,10 @@ When using a wildcard, the error will point to a specific field, replacing the a
|
||||
]
|
||||
|
||||
// rule
|
||||
'contacts.*.name' => 'required'
|
||||
'contacts.friends.*.name' => 'required'
|
||||
|
||||
// error will be
|
||||
'contacts.friends.1.name' => 'The contacts.*.name field is required.'
|
||||
'contacts.friends.1.name' => 'The contacts.friends.*.name field is required.'
|
||||
|
||||
Getting a Single Error
|
||||
======================
|
||||
@ -864,7 +870,8 @@ alpha_numeric_punct No Fails if field contains anything other than
|
||||
alphanumeric, space, or this limited set of
|
||||
punctuation characters: ``~`` (tilde),
|
||||
``!`` (exclamation), ``#`` (number),
|
||||
``$`` (dollar), ``% (percent), & (ampersand),
|
||||
``$`` (dollar), ``%`` (percent),
|
||||
``&`` (ampersand),
|
||||
``*`` (asterisk), ``-`` (dash),
|
||||
``_`` (underscore), ``+`` (plus),
|
||||
``=`` (equals), ``|`` (vertical bar),
|
||||
|
@ -4,7 +4,7 @@
|
||||
* The data to test:
|
||||
* [
|
||||
* 'contacts' => [
|
||||
* 'name' => 'Joe Smith',
|
||||
* 'name' => 'Joe Smith',
|
||||
* 'friends' => [
|
||||
* [
|
||||
* 'name' => 'Fred Flinstone',
|
||||
@ -21,8 +21,3 @@
|
||||
$validation->setRules([
|
||||
'contacts.name' => 'required|max_length[60]',
|
||||
]);
|
||||
|
||||
// Fred Flintsone & Wilma
|
||||
$validation->setRules([
|
||||
'contacts.friends.name' => 'required|max_length[60]',
|
||||
]);
|
||||
|
@ -2,5 +2,5 @@
|
||||
|
||||
// Fred Flintsone & Wilma
|
||||
$validation->setRules([
|
||||
'contacts.*.name' => 'required|max_length[60]',
|
||||
'contacts.friends.*.name' => 'required|max_length[60]',
|
||||
]);
|
||||
|
Loading…
x
Reference in New Issue
Block a user