Skip to content
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

DbModel with openapiSchema #28

Merged
merged 13 commits into from
Sep 13, 2024
12 changes: 12 additions & 0 deletions src/generator/ApiGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

namespace cebe\yii2openapi\generator;

use cebe\yii2openapi\lib\items\DbModel;
use yii\db\mysql\Schema as MySqlSchema;
use SamIT\Yii2\MariaDb\Schema as MariaDbSchema;
use yii\db\pgsql\Schema as PgSqlSchema;
Expand Down Expand Up @@ -133,6 +134,17 @@ class ApiGenerator extends Generator
*/
public $excludeModels = [];

/**
* @var array Map for custom dbModels
*
* @see DbModel::$scenarioDefaultDescription with acceptedInputs: {scenarioName}, {scenarioConst}, {modelName}.
* @example
* 'dbModel' => [
* 'scenarioDefaultDescription' => "Scenario {scenarioName}",
* ]
*/
public $dbModel = [];

/**
* @var array Map for custom controller names not based on model name for exclusive cases
* @example
Expand Down
45 changes: 43 additions & 2 deletions src/generator/default/dbmodel.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,18 @@
<?= '<?php' ?>


/**
* This file is generated by Gii, do not change manually!
*/

namespace <?= $namespace ?>;

/**
*<?= empty($model->description) ? '' : str_replace("\n", "\n * ", ' ' . trim($model->description)) ?>
*<?= $model->getModelClassDescription() ?>

*
<?php foreach ($model->dbAttributes() as $attribute): ?>
* @property <?= $attribute->getFormattedDescription() ?>
* @property <?= $attribute->getPropertyAnnotation() ?>

<?php endforeach; ?>
*
Expand All @@ -45,6 +49,16 @@
*/
abstract class <?= $model->getClassName() ?> extends \yii\db\ActiveRecord
{
<?php if($scenarios = $model->getScenarios()):
foreach($scenarios as $scenario): ?>
/**
*<?= $scenario['description'] ?>

*/
public const <?= $scenario['const'] ?> = '<?= $scenario['name'] ?>';

<?php endforeach; ?>
<?php endif ?>
<?php if (count($model->virtualAttributes())):?>
protected $virtualAttributes = ['<?=implode("', '", array_map(function ($attr) {
return $attr->columnName;
Expand All @@ -62,6 +76,33 @@ public static function tableName()
{
return <?= var_export($model->getTableAlias()) ?>;
}
<?php if($scenarios): ?>

/**
* Automatically generated scenarios from the model 'x-scenarios'.
* @return array a list of scenarios and the corresponding active attributes.
*/
public function scenarios()
{
/**
* Each scenario is assigned attributes as in the 'default' scenario.
* The advantage is that the scenario can be used immediately.
* This can be overridden in the child model if needed.
*/
$default = parent::scenarios()[self::SCENARIO_DEFAULT];

return [
<?php foreach($scenarios as $scenario): ?>
self::<?= $scenario['const'] ?> => $default,
<?php endforeach; ?>
/**
* The 'default' scenario and all scenarios mentioned in the rules() using 'on' and 'except'
* are automatically included in the scenarios() function for the model.
*/
...parent::scenarios(),
];
}
<?php endif;?>
<?php if (count($model->virtualAttributes())):?>

public function attributes()
Expand Down
32 changes: 17 additions & 15 deletions src/lib/AttributeResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class AttributeResolver
/**
* @var ComponentSchema
*/
private $schema;
private $componentSchema;

/**
* @var \cebe\yii2openapi\lib\items\JunctionSchemas
Expand All @@ -79,7 +79,7 @@ class AttributeResolver
public function __construct(string $schemaName, ComponentSchema $schema, JunctionSchemas $junctions, ?Config $config = null)
{
$this->schemaName = $schemaName;
$this->schema = $schema;
$this->componentSchema = $schema;
$this->tableName = $schema->resolveTableName($schemaName);
$this->junctions = $junctions;
$this->isJunctionSchema = $junctions->isJunctionSchema($schemaName);
Expand All @@ -94,10 +94,10 @@ public function __construct(string $schemaName, ComponentSchema $schema, Junctio
*/
public function resolve():DbModel
{
foreach ($this->schema->getProperties() as $property) {
foreach ($this->componentSchema->getProperties() as $property) {
/** @var $property \cebe\yii2openapi\lib\openapi\PropertySchema */

$isRequired = $this->schema->isRequiredProperty($property->getName());
$isRequired = $this->componentSchema->isRequiredProperty($property->getName());
$nullableValue = $property->getProperty()->getSerializableData()->nullable ?? null;
if ($nullableValue === false) { // see docs in README regarding NOT NULL, required and nullable
$isRequired = true;
Expand All @@ -113,18 +113,20 @@ public function resolve():DbModel
}
return Yii::createObject(DbModel::class, [
[
'pkName' => $this->schema->getPkName(),
/** @see \cebe\openapi\spec\Schema */
'openapiSchema' => $this->componentSchema->getSchema(),
'pkName' => $this->componentSchema->getPkName(),
'name' => $this->schemaName,
'tableName' => $this->tableName,
'description' => $this->schema->getDescription(),
'description' => $this->componentSchema->getDescription(),
'attributes' => $this->attributes,
'relations' => $this->relations,
'nonDbRelations' => $this->nonDbRelations,
'many2many' => $this->many2many,
'indexes' => $this->prepareIndexes($this->schema->getIndexes()),
'indexes' => $this->prepareIndexes($this->componentSchema->getIndexes()),
//For valid primary keys for junction tables
'junctionCols' => $this->isJunctionSchema ? $this->junctions->junctionCols($this->schemaName) : [],
'isNotDb' => $this->schema->isNonDb(),
'isNotDb' => $this->componentSchema->isNonDb(),
],
]);
}
Expand Down Expand Up @@ -185,7 +187,7 @@ protected function resolveHasMany2ManyTableProperty(PropertySchema $property, bo
'relatedSchemaName' => $junkAttribute['relatedClassName'],
'tableName' => $this->tableName,
'relatedTableName' => $junkAttribute['relatedTableName'],
'pkAttribute' => $this->attributes[$this->schema->getPkName()],
'pkAttribute' => $this->attributes[$this->componentSchema->getPkName()],
'hasViaModel' => true,
'viaModelName' => $viaModel,
'viaRelationName' => Inflector::id2camel($junkRef, '_'),
Expand All @@ -197,7 +199,7 @@ protected function resolveHasMany2ManyTableProperty(PropertySchema $property, bo

$this->relations[Inflector::pluralize($junkRef)] =
Yii::createObject(AttributeRelation::class, [$junkRef, $junkAttribute['junctionTable'], $viaModel])
->asHasMany([$junkAttribute['pairProperty'] . '_id' => $this->schema->getPkName()]);
->asHasMany([$junkAttribute['pairProperty'] . '_id' => $this->componentSchema->getPkName()]);
return;
}

Expand Down Expand Up @@ -328,7 +330,7 @@ protected function resolveProperty(
AttributeRelation::class,
[$property->getName(), $relatedTableName, $relatedClassName]
)
->asHasMany([$foreignPk => $this->schema->getPkName()]);
->asHasMany([$foreignPk => $this->componentSchema->getPkName()]);
return;
}
$relatedClassName = $property->getRefClassName();
Expand All @@ -347,10 +349,10 @@ protected function resolveProperty(
AttributeRelation::class,
[$property->getName(), $relatedTableName, $relatedClassName]
)
->asHasMany([Inflector::camel2id($this->schemaName, '_') . '_id' => $this->schema->getPkName()]);
->asHasMany([Inflector::camel2id($this->schemaName, '_') . '_id' => $this->componentSchema->getPkName()]);
return;
}
if ($this->schema->isNonDb() && $attribute->isReference()) {
if ($this->componentSchema->isNonDb() && $attribute->isReference()) {
$this->attributes[$property->getName()] = $attribute;
return;
}
Expand Down Expand Up @@ -398,7 +400,7 @@ protected function catchManyToMany(
'relatedSchemaName' => $relatedSchemaName,
'tableName' => $this->tableName,
'relatedTableName' => $relatedTableName,
'pkAttribute' => $this->attributes[$this->schema->getPkName()],
'pkAttribute' => $this->attributes[$this->componentSchema->getPkName()],
],
]);
$this->many2many[$propertyName] = $relation;
Expand Down Expand Up @@ -480,7 +482,7 @@ protected function resolvePropertyRef(PropertySchema $property, Attribute $attri
$fkProperty = new PropertySchema(
$property->getRefSchema()->getSchema(),
$property->getName(),
$this->schema
$this->componentSchema
);
[$min, $max] = $fkProperty->guessMinMax();
$attribute->setPhpType($fkProperty->guessPhpType())
Expand Down
11 changes: 11 additions & 0 deletions src/lib/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,17 @@ class Config extends BaseObject
*/
public $excludeModels = [];

/**
* @var array Map for custom dbModels
*
* @see DbModel::$scenarioDefaultDescription with acceptedInputs: {scenarioName}, {scenarioConst}, {modelName}.
* @example
* 'dbModel' => [
* 'scenarioDefaultDescription' => "Scenario {scenarioName}",
* ]
*/
public $dbModel = [];

/**
* @var array Map for custom controller names not based on model name for exclusive cases
* @example
Expand Down
3 changes: 3 additions & 0 deletions src/lib/generators/ModelsGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ public function generate():CodeFiles
}
foreach ($this->models as $model) {
$className = $model->getClassName();
if (!empty($this->config->dbModel['scenarioDefaultDescription'])) {
$model->scenarioDefaultDescription = $this->config->dbModel['scenarioDefaultDescription'];
}
if ($model->isNotDb === false) {
$this->files->add(new CodeFile(
Yii::getAlias("$modelPath/base/$className.php"),
Expand Down
25 changes: 25 additions & 0 deletions src/lib/helpers/FormatHelper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

/**
* @copyright Copyright (c) 2018 Carsten Brandt <[email protected]> and contributors
* @license https://github.com/cebe/yii2-openapi/blob/master/LICENSE
*/

namespace cebe\yii2openapi\lib\helpers;

class FormatHelper
{
/**
* @param string $description
* @param int $spacing
* @return string
*/
public static function getFormattedDescription(string $description, int $spacing = 1): string
{
$descriptionArr = explode("\n", trim($description));
$descriptionArr = array_map(function ($item) {
return $item === '' ? '' : ' ' . $item;
}, $descriptionArr);
return implode("\n".str_repeat(" ", $spacing)."*", $descriptionArr);
}
}
14 changes: 10 additions & 4 deletions src/lib/items/Attribute.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

namespace cebe\yii2openapi\lib\items;

use cebe\yii2openapi\lib\helpers\FormatHelper;
use yii\helpers\VarDumper;
use \Yii;
use cebe\yii2openapi\lib\openapi\PropertySchema;
Expand Down Expand Up @@ -295,11 +296,16 @@ public function getMinLength():?int
return $this->limits['minLength'];
}

public function getFormattedDescription():string
/**
* @return string
*/
public function getPropertyAnnotation(): string
{
$comment = $this->columnName.' '.$this->description;
$type = $this->phpType;
return $type.' $'.str_replace("\n", "\n * ", rtrim($comment));
$annotation = $this->phpType . ' $' . $this->columnName;
if (!empty($this->description)) {
$annotation .= FormatHelper::getFormattedDescription($this->description);
}
return $annotation;
}

public function toColumnSchema():ColumnSchema
Expand Down
Loading
Loading