Skip to content

Commit

Permalink
Merge pull request #31 from php-openapi/30-add-validation-rules-by-at…
Browse files Browse the repository at this point in the history
…tribute-name-or-pattern

Resolve: Add validation rules by attribute name or pattern #30
  • Loading branch information
cebe authored Nov 12, 2024
2 parents 6fbf532 + 42674b7 commit 9666ec1
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 7 deletions.
28 changes: 21 additions & 7 deletions src/lib/ValidationRulesBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@
use cebe\yii2openapi\lib\items\Attribute;
use cebe\yii2openapi\lib\items\DbModel;
use cebe\yii2openapi\lib\items\ValidationRule;
use yii\helpers\VarDumper;
use yii\validators\DateValidator;
use function count;
use function implode;
use function in_array;
Expand Down Expand Up @@ -65,7 +63,7 @@ public function build():array
}
}
foreach ($this->model->attributes as $attribute) {
// column/field/property with name `id` is considered as Primary Key by this library and it is automatically handled by DB/Yii; so remove it from validation `rules()`
// column/field/property with name `id` is considered as Primary Key by this library, and it is automatically handled by DB/Yii; so remove it from validation `rules()`
if (in_array($attribute->columnName, ['id', $this->model->pkName]) ||
in_array($attribute->propertyName, ['id', $this->model->pkName])
) {
Expand Down Expand Up @@ -136,16 +134,32 @@ private function resolveAttributeRules(Attribute $attribute):void

private function addRulesByAttributeName(Attribute $attribute):void
{
//@TODO: probably also patterns for file, image
$patterns = [
'~e?mail~i' => 'email',
'~(url|site|website|href|link)~i' => 'url',

# below patters will only work if `format: binary` (file) is present in OpenAPI spec
# also `string` validation rule will be removed
'~(image|photo|picture)~i' => 'image',
'~(file|pdf|audio|video|document|json|yml|yaml|zip|tar|7z)~i' => 'file',
];
$addRule = function (Attribute $attribute, string $validator): void {
$key = $attribute->columnName . '_' . $validator;
$this->rules[$key] = new ValidationRule([$attribute->columnName], $validator);
};
foreach ($patterns as $pattern => $validator) {
if (empty($attribute->reference) # ignore column name based rules in case of reference/relation # https://github.com/cebe/yii2-openapi/issues/159
&& preg_match($pattern, strtolower($attribute->columnName))) {
$key = $attribute->columnName . '_' . $validator;
$this->rules[$key] = new ValidationRule([$attribute->columnName], $validator);
if (in_array($validator, ['image', 'file'], true)) {
if ($attribute->dbType === 'binary') {
$addRule($attribute, $validator);
// for files, we don't need `string` validation
$key = $attribute->columnName . '_string';
unset($this->rules[$key]);
}
} else {
$addRule($attribute, $validator);
}
return;
}
}
Expand Down Expand Up @@ -223,7 +237,7 @@ private function prepareTypeScope():void
if ($attribute->isReadOnly()) {
continue;
}
// column/field/property with name `id` is considered as Primary Key by this library and it is automatically handled by DB/Yii; so remove it from validation `rules()`
// column/field/property with name `id` is considered as Primary Key by this library, and it is automatically handled by DB/Yii; so remove it from validation `rules()`
if (in_array($attribute->columnName, ['id', $this->model->pkName]) ||
in_array($attribute->propertyName, ['id', $this->model->pkName])
) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

return [
'openApiPath' => '@specs/issue_fix/30_add_validation_rules_by_attribute_name_or_pattern/index.yaml',
'generateUrls' => false,
'generateModels' => true,
'excludeModels' => [
'Error',
],
'generateControllers' => false,
'generateMigrations' => false,
'generateModelFaker' => false, // `generateModels` must be `true` in order to use `generateModelFaker` as `true`
];

Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@

openapi: 3.0.3

info:
title: Add validation rules by attribute name or pattern \#30
version: 1.0.0

components:
schemas:
User:
type: object
required:
- id
- name
properties:
id:
type: integer
readOnly: true
name:
description: name
type: string
maxLength: 128
photo:
type: string
format: binary
profile_photo:
type: string
format: binary
pdf:
type: string
format: binary
a_file:
type: string
format: binary
profile:
type: string

paths:
'/':
get:
operationId: opId
summary: summary
responses:
'200':
description: OK
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace app\models;

class User extends \app\models\base\User
{


}

Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

namespace app\models\base;

/**
*
*
* @property int $id
* @property string $name name
* @property string $photo
* @property string $profile_photo
* @property string $pdf
* @property string $a_file
* @property string $profile
*
*/
abstract class User extends \yii\db\ActiveRecord
{
public static function tableName()
{
return '{{%users}}';
}

public function rules()
{
return [
'trim' => [['name', 'photo', 'profile_photo', 'pdf', 'a_file', 'profile'], 'trim'],
'required' => [['name'], 'required'],
'name_string' => [['name'], 'string', 'max' => 128],
'photo_image' => [['photo'], 'image'],
'profile_photo_image' => [['profile_photo'], 'image'],
'pdf_file' => [['pdf'], 'file'],
'a_file_file' => [['a_file'], 'file'],
'profile_string' => [['profile'], 'string'],
];
}
}
14 changes: 14 additions & 0 deletions tests/unit/IssueFixTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -360,4 +360,18 @@ public function test158BugGiiapiGeneratedRulesEnumWithTrim()
]);
$this->checkFiles($actualFiles, $expectedFiles);
}

// https://github.com/php-openapi/yii2-openapi/issues/30
public function test30AddValidationRulesByAttributeNameOrPattern()
{
$testFile = Yii::getAlias("@specs/issue_fix/30_add_validation_rules_by_attribute_name_or_pattern/index.php");
$this->runGenerator($testFile);
$actualFiles = FileHelper::findFiles(Yii::getAlias('@app'), [
'recursive' => true,
]);
$expectedFiles = FileHelper::findFiles(Yii::getAlias("@specs/issue_fix/30_add_validation_rules_by_attribute_name_or_pattern/mysql"), [
'recursive' => true,
]);
$this->checkFiles($actualFiles, $expectedFiles);
}
}

0 comments on commit 9666ec1

Please sign in to comment.