Skip to content

Commit

Permalink
Merge pull request #28 from siggi-k/openapiSchema
Browse files Browse the repository at this point in the history
DbModel with openapiSchema
  • Loading branch information
cebe authored Sep 13, 2024
2 parents 16862ad + 9497bf4 commit 2db7968
Show file tree
Hide file tree
Showing 79 changed files with 564 additions and 38 deletions.
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

0 comments on commit 2db7968

Please sign in to comment.