Skip to content
This repository was archived by the owner on Jun 4, 2024. It is now read-only.

Commit 55bcb01

Browse files
committed
Add support references to non-db models
1 parent 5f5b3c7 commit 55bcb01

File tree

14 files changed

+270
-3
lines changed

14 files changed

+270
-3
lines changed

src/generator/default/dbmodel.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,14 @@
2929
* @property array|\<?= trim($relationNamespace, '\\') ?>\<?= $relation->getClassName() ?>[] $<?= Inflector::variablize($relation->getName()) ?>
3030
<?php endif?>
3131

32+
<?php endforeach; ?>
33+
<?php foreach ($model->nonDbRelations as $relationName => $relation): ?>
34+
<?php if ($relation->isHasOne()):?>
35+
* @property \<?= trim($relationNamespace, '\\') ?>\<?= $relation->getClassName() ?> $<?= Inflector::variablize($relation->getName()) ?>
36+
<?php else:?>
37+
* @property array|\<?= trim($relationNamespace, '\\') ?>\<?= $relation->getClassName() ?>[] $<?= Inflector::variablize($relation->getName()) ?>
38+
<?php endif?>
39+
3240
<?php endforeach; ?>
3341
<?php foreach ($model->many2many as $relation): ?>
3442
* @property array|\<?= trim($relationNamespace, '\\') ?>\<?= $relation->relatedClassName ?>[] $<?= Inflector::variablize($relation->name) ?>

src/generator/default/model.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@ class <?= $model->getClassName() ?> extends Model
3636
*/
3737
public $<?= $relationName ?>;
3838

39+
<?php endforeach; ?>
40+
<?php foreach ($model->nonDbRelations as $relationName => $relation): ?>
41+
/**
42+
* @var <?=$relation->isHasOne()? $relation->getClassName(): 'array|'.$relation->getClassName().'[]'.PHP_EOL?>
43+
*/
44+
public $<?= $relationName ?>;
45+
3946
<?php endforeach; ?>
4047

4148
public function rules()

src/lib/AttributeResolver.php

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use cebe\yii2openapi\lib\items\DbModel;
1515
use cebe\yii2openapi\lib\items\JunctionSchemas;
1616
use cebe\yii2openapi\lib\items\ManyToManyRelation;
17+
use cebe\yii2openapi\lib\items\NonDbRelation;
1718
use cebe\yii2openapi\lib\openapi\ComponentSchema;
1819
use cebe\yii2openapi\lib\openapi\PropertySchema;
1920
use Yii;
@@ -35,7 +36,10 @@ class AttributeResolver
3536
* @var AttributeRelation[]|array
3637
*/
3738
private $relations = [];
38-
39+
/**
40+
* @var NonDbRelation[]|array
41+
*/
42+
private $nonDbRelations = [];
3943
/**
4044
* @var ManyToManyRelation[]|array
4145
*/
@@ -102,6 +106,7 @@ public function resolve():DbModel
102106
'description' => $this->schema->getDescription(),
103107
'attributes' => $this->attributes,
104108
'relations' => $this->relations,
109+
'nonDbRelations' => $this->nonDbRelations,
105110
'many2many' => $this->many2many,
106111
'indexes' => $this->prepareIndexes($this->schema->getIndexes()),
107112
//For valid primary keys for junction tables
@@ -203,6 +208,17 @@ protected function resolveProperty(PropertySchema $property, bool $isRequired):v
203208
if ($property->isVirtual()) {
204209
throw new InvalidDefinitionException('References not supported for virtual attributes');
205210
}
211+
212+
if ($property->isNonDbReference()) {
213+
$attribute->asNonDbReference($property->getRefClassName());
214+
$relation = Yii::createObject(
215+
NonDbRelation::class,
216+
[$property->getName(), $property->getRefClassName(), NonDbRelation::HAS_ONE]
217+
);
218+
219+
$this->nonDbRelations[$property->getName()] = $relation;
220+
return;
221+
}
206222

207223
$fkProperty = $property->getTargetProperty();
208224
if (!$fkProperty && !$property->getRefSchema()->isObjectSchema()) {
@@ -249,6 +265,18 @@ protected function resolveProperty(PropertySchema $property, bool $isRequired):v
249265
if ($property->isVirtual()) {
250266
throw new InvalidDefinitionException('References not supported for virtual attributes');
251267
}
268+
269+
if ($property->isNonDbReference()) {
270+
$attribute->asNonDbReference($property->getRefClassName());
271+
$relation = Yii::createObject(
272+
NonDbRelation::class,
273+
[$property->getName(), $property->getRefClassName(), NonDbRelation::HAS_MANY]
274+
);
275+
276+
$this->nonDbRelations[$property->getName()] = $relation;
277+
return;
278+
}
279+
252280
if ($property->isRefPointerToSelf()) {
253281
$relatedClassName = $property->getRefClassName();
254282
$attribute->setPhpType($relatedClassName . '[]');

src/lib/items/Attribute.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,14 @@ public function asReference(string $relatedClass):Attribute
190190
$this->columnName = $this->propertyName . '_id';
191191
return $this;
192192
}
193+
194+
public function asNonDbReference(string $relatedClass):Attribute
195+
{
196+
$this->reference = $relatedClass;
197+
$this->columnName = $this->propertyName;
198+
return $this;
199+
}
200+
193201
public function isReadOnly():bool
194202
{
195203
return $this->readOnly;

src/lib/items/DbModel.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ class DbModel extends BaseObject
5757
*/
5858
public $relations = [];
5959

60+
/***
61+
* @var array|\cebe\yii2openapi\lib\items\NonDbRelation[] non-db relations
62+
*/
63+
public $nonDbRelations = [];
64+
6065
/**
6166
* @var array|\cebe\yii2openapi\lib\items\ManyToManyRelation[] many to many relations.
6267
*/

src/lib/items/NonDbRelation.php

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
<?php
2+
3+
/**
4+
* @copyright Copyright (c) 2018 Carsten Brandt <[email protected]> and contributors
5+
* @license https://github.com/cebe/yii2-openapi/blob/master/LICENSE
6+
*/
7+
8+
namespace cebe\yii2openapi\lib\items;
9+
10+
class NonDbRelation
11+
{
12+
public const HAS_ONE = 'hasOne';
13+
public const HAS_MANY = 'hasMany';
14+
15+
/**
16+
* @var string $name
17+
**/
18+
private $name;
19+
20+
/**
21+
* @var string $className
22+
**/
23+
private $className;
24+
25+
/**
26+
* @var string $method (hasOne/hasMany)
27+
**/
28+
private $method;
29+
30+
public function __construct(
31+
string $name,
32+
?string $className = null,
33+
?string $method = null
34+
) {
35+
$this->name = $name;
36+
$this->className = $className;
37+
$this->method = $method;
38+
}
39+
40+
/**
41+
* @param string $name
42+
* @return NonDbRelation
43+
*/
44+
public function setName(string $name):NonDbRelation
45+
{
46+
$this->name = $name;
47+
return $this;
48+
}
49+
50+
/**
51+
* @param string $className
52+
* @return NonDbRelation
53+
*/
54+
public function setClassName(string $className):NonDbRelation
55+
{
56+
$this->className = $className;
57+
return $this;
58+
}
59+
60+
/**
61+
* @param string $method
62+
* @return NonDbRelation
63+
*/
64+
public function setMethod(string $method):NonDbRelation
65+
{
66+
$this->method = $method;
67+
return $this;
68+
}
69+
70+
/**
71+
* @return string
72+
*/
73+
public function getName():string
74+
{
75+
return $this->name;
76+
}
77+
78+
/**
79+
* @return string
80+
*/
81+
public function getClassName():?string
82+
{
83+
return $this->className;
84+
}
85+
86+
/**
87+
* @return string
88+
*/
89+
public function getMethod():?string
90+
{
91+
return $this->method;
92+
}
93+
94+
public function isHasOne():bool
95+
{
96+
return $this->method === self::HAS_ONE;
97+
}
98+
}

src/lib/openapi/PropertySchema.php

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ class PropertySchema
4141
/**@var bool $isItemsReference * */
4242
private $isItemsReference = false;
4343

44+
/**@var bool $isNonDbReference * */
45+
private $isNonDbReference = false;
46+
4447
/**@var string $refPointer * */
4548
private $refPointer;
4649

@@ -79,7 +82,14 @@ public function __construct(SpecObjectInterface $property, string $name, Compone
7982
) {
8083
$this->initItemsReference();
8184
}
82-
$this->schema = $schema;
85+
}
86+
87+
/**
88+
* @return bool
89+
*/
90+
public function isNonDbReference():bool
91+
{
92+
return $this->isNonDbReference;
8393
}
8494

8595
/**
@@ -97,6 +107,9 @@ private function initReference():void
97107
$this->property->getContext()->mode = ReferenceContext::RESOLVE_MODE_ALL;
98108
$this->refSchema = Yii::createObject(ComponentSchema::class, [$this->property->resolve(), $refSchemaName]);
99109
}
110+
if ($this->refSchema && $this->refSchema->isNonDb()) {
111+
$this->isNonDbReference = true;
112+
}
100113
}
101114

102115
/**
@@ -117,6 +130,9 @@ private function initItemsReference():void
117130
$items->getContext()->mode = ReferenceContext::RESOLVE_MODE_ALL;
118131
$this->refSchema = Yii::createObject(ComponentSchema::class, [$items->resolve(), $this->getRefSchemaName()]);
119132
}
133+
if ($this->refSchema && $this->refSchema->isNonDb()) {
134+
$this->isNonDbReference = true;
135+
}
120136
}
121137

122138
public function setName(string $name):void

tests/fixtures/non-db.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
use cebe\yii2openapi\lib\items\Attribute;
55
use cebe\yii2openapi\lib\items\AttributeRelation;
66
use cebe\yii2openapi\lib\items\DbModel;
7+
use cebe\yii2openapi\lib\items\NonDbRelation;
78

89
return [
910
'PetStatistic' => new DbModel([
@@ -25,7 +26,11 @@
2526
'relations' => [
2627
'parentPet' => new AttributeRelation('parentPet', 'pets', 'Pet', 'hasOne', ['id' => 'parentPet_id']),
2728
'favoritePets' => new AttributeRelation('favoritePets', 'pets', 'Pet', 'hasMany', ['pet_statistic_id' => 'id']),
28-
]]),
29+
],
30+
'nonDbRelations' => [
31+
'topDoctors' => new NonDbRelation('topDoctors', 'Doctor', 'hasMany'),
32+
]
33+
]),
2934
'personWatch' => new DbModel([
3035
'pkName' => 'id',
3136
'name' => 'PersonWatch',

tests/specs/petstore_jsonapi.yaml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,21 @@ paths:
9797
description: successfully deleted pet
9898
components:
9999
schemas:
100+
Doctor:
101+
description: Non-db doctor object
102+
x-table: false
103+
required:
104+
- name
105+
properties:
106+
name:
107+
type: string
108+
maxLength: 200
109+
surname:
110+
type: string
111+
maxLength: 200
112+
phones:
113+
type: array
114+
100115
Pet:
101116
description: A Pet
102117
required:
@@ -128,6 +143,8 @@ components:
128143
readOnly: true
129144
items:
130145
$ref: "#/components/schemas/Pet/properties/tag"
146+
doctor:
147+
$ref: "#/components/schemas/Doctor"
131148
PetStatistic:
132149
x-table: false
133150
description: Non-Db model
@@ -156,6 +173,11 @@ components:
156173
readOnly: true
157174
items:
158175
$ref: "#/components/schemas/Pet"
176+
topDoctors:
177+
type: array
178+
readOnly: true
179+
items:
180+
$ref: "#/components/schemas/Doctor"
159181

160182
Pets:
161183
type: array
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace app\models;
4+
5+
class Doctor extends \app\models\base\Doctor
6+
{
7+
8+
9+
}
10+

0 commit comments

Comments
 (0)