Skip to content

Resolve: Add validation rules by attribute name or pattern #30 #31

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Nov 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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);
}
}
Loading