Skip to content

Commit 8122e3d

Browse files
committed
More validators
1 parent 6afa376 commit 8122e3d

File tree

13 files changed

+320
-114
lines changed

13 files changed

+320
-114
lines changed

Tests/Fixtures/Definition/Strings.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
namespace Tests\Fixtures\Definition;
4+
5+
abstract class Strings extends \PHPFUI\ORM\Record
6+
{
7+
public static bool $autoIncrement = false;
8+
9+
public static array $fields = [
10+
'starts_with' => ['sqltype', 'string', 50, false, '', false, ],
11+
'ends_with' => ['sqltype', 'string', 50, false, '', false, ],
12+
'contains' => ['sqltype', 'string', 50, false, '', false, ],
13+
'istarts_with' => ['sqltype', 'string', 50, false, '', false, ],
14+
'iends_with' => ['sqltype', 'string', 50, false, '', false, ],
15+
'icontains' => ['sqltype', 'string', 50, false, '', false, ],
16+
];
17+
18+
public static string $primaryKey = '';
19+
20+
public static string $table = '';
21+
}

Tests/Fixtures/Record/Definition/Order.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,13 @@ abstract class Order extends \PHPFUI\ORM\Record
3939
/** @var array<string, array<mixed>> */
4040
protected static array $fields = [
4141
// MYSQL_TYPE, PHP_TYPE, LENGTH, KEY, ALLOWS_NULL, DEFAULT
42-
'customer_id' => ['integer', 'int', 0, false, true, NULL, ],
43-
'employee_id' => ['integer', 'int', 0, false, true, NULL, ],
42+
'customer_id' => ['integer', 'int', 0, false, true, null, ],
43+
'employee_id' => ['integer', 'int', 0, false, true, null, ],
4444
'notes' => ['longtext', 'string', 4294967295, false, true, 'NULL', ],
4545
'order_date' => ['datetime', 'string', 20, false, false, ],
4646
'order_id' => ['integer', 'int', 0, true, false, ],
4747
'order_status_id' => ['integer', 'int', 0, false, true, 0, ],
48-
'order_tax_status_id' => ['integer', 'int', 0, false, true, NULL, ],
48+
'order_tax_status_id' => ['integer', 'int', 0, false, true, null, ],
4949
'paid_date' => ['datetime', 'string', 20, false, true, 'NULL', ],
5050
'payment_type' => ['varchar(50)', 'string', 50, false, true, 'NULL', ],
5151
'ship_address' => ['longtext', 'string', 4294967295, false, true, 'NULL', ],
@@ -55,7 +55,7 @@ abstract class Order extends \PHPFUI\ORM\Record
5555
'ship_state_province' => ['varchar(50)', 'string', 50, false, true, 'NULL', ],
5656
'ship_zip_postal_code' => ['varchar(50)', 'string', 50, false, true, 'NULL', ],
5757
'shipped_date' => ['datetime', 'string', 20, false, true, 'NULL', ],
58-
'shipper_id' => ['integer', 'int', 0, false, true, NULL, ],
58+
'shipper_id' => ['integer', 'int', 0, false, true, null, ],
5959
'shipping_fee' => ['decimal(19,4)', 'float', 19, false, true, 0, ],
6060
'tax_rate' => ['double', 'float', 0, false, true, 0, ],
6161
'taxes' => ['decimal(19,4)', 'float', 19, false, true, 0, ],

Tests/Fixtures/Record/Definition/OrderDetail.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,12 @@ abstract class OrderDetail extends \PHPFUI\ORM\Record
3131
// MYSQL_TYPE, PHP_TYPE, LENGTH, KEY, ALLOWS_NULL, DEFAULT
3232
'date_allocated' => ['datetime', 'string', 20, false, true, 'NULL', ],
3333
'discount' => ['double', 'float', 0, false, false, 0, ],
34-
'inventory_transaction_id' => ['integer', 'int', 0, false, true, NULL, ],
34+
'inventory_transaction_id' => ['integer', 'int', 0, false, true, null, ],
3535
'order_detail_id' => ['integer', 'int', 0, true, false, ],
36-
'order_detail_status_id' => ['integer', 'int', 0, false, true, NULL, ],
36+
'order_detail_status_id' => ['integer', 'int', 0, false, true, null, ],
3737
'order_id' => ['integer', 'int', 0, false, false, ],
38-
'product_id' => ['integer', 'int', 0, false, true, NULL, ],
39-
'purchase_order_id' => ['integer', 'int', 0, false, true, NULL, ],
38+
'product_id' => ['integer', 'int', 0, false, true, null, ],
39+
'purchase_order_id' => ['integer', 'int', 0, false, true, null, ],
4040
'quantity' => ['decimal(18,4)', 'float', 18, false, false, 0, ],
4141
'unit_price' => ['decimal(19,4)', 'float', 19, false, true, 0, ],
4242
];

Tests/Fixtures/Record/Definition/Product.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,14 @@ abstract class Product extends \PHPFUI\ORM\Record
3232
'description' => ['longtext', 'string', 4294967295, false, true, 'NULL', ],
3333
'discontinued' => ['integer', 'int', 0, false, false, 0, ],
3434
'list_price' => ['decimal(19,4)', 'float', 19, false, false, 0, ],
35-
'minimum_reorder_quantity' => ['integer', 'int', 0, false, true, NULL, ],
35+
'minimum_reorder_quantity' => ['integer', 'int', 0, false, true, null, ],
3636
'product_code' => ['varchar(25)', 'string', 25, false, true, 'NULL', ],
3737
'product_id' => ['integer', 'int', 0, true, false, ],
3838
'product_name' => ['varchar(50)', 'string', 50, false, true, 'NULL', ],
3939
'quantity_per_unit' => ['varchar(50)', 'string', 50, false, true, 'NULL', ],
40-
'reorder_level' => ['integer', 'int', 0, false, true, NULL, ],
40+
'reorder_level' => ['integer', 'int', 0, false, true, null, ],
4141
'standard_cost' => ['decimal(19,4)', 'float', 19, false, true, 0, ],
42-
'target_level' => ['integer', 'int', 0, false, true, NULL, ],
42+
'target_level' => ['integer', 'int', 0, false, true, null, ],
4343
];
4444

4545
/** @var array<string, true> */

Tests/Fixtures/Record/Strings.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
namespace Tests\Fixtures\Record;
4+
5+
class Strings extends \Tests\Fixtures\Definition\Strings
6+
{
7+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
namespace Tests\Fixtures\Record\Validation;
4+
5+
/**
6+
* Autogenerated. File will not be changed by oneOffScripts\generateValidators.php. Delete and rerun if you want.
7+
*/
8+
class Product extends \PHPFUI\ORM\Validator
9+
{
10+
/** @var array<string, string[]> */
11+
public static array $validators = [
12+
'category' => ['maxlength'],
13+
'description' => ['maxlength'],
14+
'discontinued' => ['required', 'integer'],
15+
'list_price' => ['required', 'number'],
16+
'minimum_reorder_quantity' => ['integer'],
17+
'product_code' => ['maxlength', 'unique'],
18+
'product_id' => ['required', 'integer'],
19+
'product_name' => ['maxlength'],
20+
'quantity_per_unit' => ['maxlength'],
21+
'reorder_level' => ['integer'],
22+
'standard_cost' => ['number'],
23+
'target_level' => ['integer'],
24+
];
25+
}

Tests/Fixtures/Validation/Strings.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
namespace Tests\Fixtures\Validation;
4+
5+
class Strings extends \PHPFUI\ORM\Validator
6+
{
7+
public static array $validators = [
8+
'starts_with' => ['starts_with:a,b,c'],
9+
'ends_with' => ['ends_with:a,b,c'],
10+
'contains' => ['contains:a,b,c'],
11+
'istarts_with' => ['istarts_with:a,b,c'],
12+
'iends_with' => ['iends_with:a,b,c'],
13+
'icontains' => ['icontains:a,b,c'],
14+
];
15+
}

Tests/Unit/ValidationTest.php

Lines changed: 45 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -653,25 +653,21 @@ public function testMonthDayYear() : void
653653
$this->assertContains('2-30-20 is not a valid date (M-D-Y)', $errors['month_day_year']);
654654
}
655655

656-
// public function testUnique() : void
657-
// {
658-
// $crud = new \Tests\Fixtures\Record\Unique();
659-
// $validator = new \Tests\Fixtures\Validation\Unique($crud);
660-
//
661-
// // empty test
662-
// $validator->validate();
663-
// $this->assertEmpty($validator->getErrors());
664-
//
665-
// // valid tests
666-
// $crud->unique = '';
667-
// $validator->validate();
668-
// $this->assertEmpty($validator->getErrors());
669-
//
670-
// // invalid tests
671-
// $crud->unique = '';
672-
// $validator->validate();
673-
// $this->assertNotEmpty($validator->getErrors());
674-
// }
656+
public function testUnique() : void
657+
{
658+
$crud = new \Tests\Fixtures\Record\Product(90);
659+
$this->assertEquals('NWTCFV-90', $crud->product_code);
660+
$validator = new \Tests\Fixtures\Record\Validation\Product($crud);
661+
// empty test
662+
$validator->validate();
663+
$this->assertEmpty($validator->getErrors());
664+
$crud->product_code = 'NWTCFV-91';
665+
$validator->validate();
666+
$errors = $validator->getErrors();
667+
// fwrite(STDERR, print_r($errors, true));
668+
$this->assertCount(1, $errors);
669+
$this->assertContains('NWTCFV-91 is not unique', $errors['product_code']);
670+
}
675671

676672
public function testMonthYear() : void
677673
{
@@ -819,6 +815,36 @@ public function testRequired() : void
819815
$this->assertNotEmpty($validator->getErrors());
820816
}
821817

818+
public function testStrings() : void
819+
{
820+
$crud = new \Tests\Fixtures\Record\Strings();
821+
$crud->starts_with = 'asdfghjkl';
822+
$crud->ends_with = 'sdfghjklc';
823+
$crud->contains = 'sdfaghjkl';
824+
$crud->istarts_with = 'CSDFGHJKL';
825+
$crud->iends_with = 'SDFGHJKLB';
826+
$crud->icontains = 'SDFCGHJKL';
827+
$validator = new \Tests\Fixtures\Validation\Strings($crud);
828+
$validator->validate();
829+
$this->assertEmpty($validator->getErrors());
830+
831+
$crud->starts_with = 'sdfghjkl';
832+
$crud->ends_with = 'sdfghjkl';
833+
$crud->contains = 'sdfghjkl';
834+
$crud->istarts_with = 'SDFGHJKL';
835+
$crud->iends_with = 'SDFGHJKL';
836+
$crud->icontains = 'SDFGHJKL';
837+
$validator->validate();
838+
$errors = $validator->getErrors();
839+
$this->assertCount(6, $errors);
840+
$this->assertContains('sdfghjkl does not start with one of (a,b,c) of the same case', $errors['starts_with']);
841+
$this->assertContains('sdfghjkl does not end with one of (a,b,c) of the same case', $errors['ends_with']);
842+
$this->assertContains('sdfghjkl does not contain one of (a,b,c) of the same case', $errors['contains']);
843+
$this->assertContains('SDFGHJKL does not start with one of (a,b,c)', $errors['istarts_with']);
844+
$this->assertContains('SDFGHJKL does not end with one of (a,b,c)', $errors['iends_with']);
845+
$this->assertContains('SDFGHJKL does not contain one of (a,b,c)', $errors['icontains']);
846+
}
847+
822848
public function testTime() : void
823849
{
824850
$crud = new \Tests\Fixtures\Record\Time();

docs/7. Validation.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,20 @@ foreach ($validationErrors as $field => $fieldErrors)
3434
| bool | Must be one or zero | None |
3535
| card | Credit card number (LUHN validation) | None |
3636
| color | HTML color (#fff or #fafbfc, '#' is optional) | None |
37+
| contains | Field must contain (case sensitive) | comma separated list of strings |
3738
| cvv | Credit card cvv number | None |
3839
| date | Loosely formatted date (Y-M-D) | None |
3940
| dateISO | Strictly formatted ISO Date (YYYY-MM-DD) | None |
4041
| datetime | Loosely formatted date (Y-M-D) followed by time format | None |
4142
| day_month_year | Loosely formatted date (D-M-Y) | None |
4243
| domain | Valid domain | None |
4344
| email | Valid email | None |
45+
| ends_with | Field must end with (case sensitive) | comma separated list of strings |
4446
| enum | MySQL enum value, case insensitive | comma separated list of identifiers<br>**Example:** enum:Get,Post,Put,Delete |
4547
| enum_exact | MySQL enum value, case sensitive | comma separated list of identifiers<br>**Example:** enum:ssl,tls |
48+
| icontains | Field must contain (case insensitive) | comma separated list of strings |
4649
| integer | Whole number, no fractional part | None |
50+
| istarts_with | Field must start with (case insensitive) | comma separated list of strings |
4751
| maxlength | Length must be greater or equal | Optional length, else MySQL limit |
4852
| maxvalue | Value must be greater or equal | value, required |
4953
| minlength | Must be less than or equal | number, default field size |
@@ -52,6 +56,7 @@ foreach ($validationErrors as $field => $fieldErrors)
5256
| month_year | Loosely formatted Month Year | None |
5357
| number | Floating point number or whole number | None |
5458
| required | Field is required, can't be null or blank, 0 is OK | None |
59+
| starts_with | Field must start with (case sensitive) | comma separated list of strings |
5560
| time | Time (ampm or military), : separators | None |
5661
| unique | Column must be a unique value | See Below |
5762
| url | Valid URL (ftp, http, etc) | None |
@@ -83,7 +88,7 @@ You want the name to be unique for a specific type and division: *unique:type,sh
8388
## Optional Validation
8489
You may need to do additional checks for a specific record type. A second parameter can be passed to the contructor which would represent the original values of the record.
8590

86-
You can also pass an optional method to validate to perform more complex validation. By default, insert, update, and delete are standard methods that are used by the \App\Controller\Record class will use.
91+
You can also pass an optional method to validate to perform more complex validation. If you use an optional method, the validator will not perform the standard validations unless you specifically call the validate() method again without the optional method parameter.
8792

8893
## Multi Validator Example
8994
```php

src/PHPFUI/ORM/Record.php

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -655,12 +655,12 @@ public function setCustomValidator(string $className) : static
655655

656656
public function blankDate(?string $date) : string
657657
{
658-
if ('1000-01-01' < $date)
658+
if ('1000-01-01' > $date)
659659
{
660660
return '';
661661
}
662662

663-
return $date ?? '';
663+
return $date;
664664
}
665665

666666
/**
@@ -829,7 +829,7 @@ private function privateInsert(bool $updateOnDuplicate, string $ignore = '') : i
829829
{
830830
$updateSql = ' on duplicate key update ';
831831
$comma = '';
832-
$inputCount = count($input);
832+
$inputCount = \count($input);
833833

834834
foreach ($this->current as $key => $value)
835835
{
@@ -850,9 +850,10 @@ private function privateInsert(bool $updateOnDuplicate, string $ignore = '') : i
850850
}
851851
}
852852
}
853-
if (count($input) == $inputCount) // nothing to update but primary keys, ignore input
853+
854+
if (\count($input) == $inputCount) // nothing to update but primary keys, ignore input
854855
{
855-
$sql = str_replace('insert into', 'insert ignore into', $sql);
856+
$sql = \str_replace('insert into', 'insert ignore into', $sql);
856857
}
857858
else
858859
{

src/PHPFUI/ORM/Tool/Generate/Base.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ protected function getPrimaryKeys(string $table) : array
2929
if (! $primaryKeys) // look in indicies if no primary, could be a composite primary key
3030
{
3131
$indexes = \PHPFUI\ORM::getIndexes($table);
32+
3233
foreach ($indexes as $index)
3334
{
3435
if ($index->primaryKey)

0 commit comments

Comments
 (0)