1212use cebe \openapi \spec \Reference ;
1313use cebe \openapi \SpecObjectInterface ;
1414use cebe \yii2openapi \lib \CustomSpecAttr ;
15+ use cebe \yii2openapi \lib \exceptions \InvalidDefinitionException ;
1516use Throwable ;
1617use Yii ;
1718use yii \db \Schema as YiiDbSchema ;
2021use yii \helpers \StringHelper ;
2122use function is_int ;
2223use function strpos ;
23- use function substr ;
2424
2525class PropertySchema
2626{
@@ -61,6 +61,7 @@ class PropertySchema
6161 * @param \cebe\openapi\SpecObjectInterface $property
6262 * @param string $name
6363 * @param \cebe\yii2openapi\lib\openapi\ComponentSchema $schema
64+ * @throws \cebe\yii2openapi\lib\exceptions\InvalidDefinitionException
6465 * @throws \yii\base\InvalidConfigException
6566 */
6667 public function __construct (SpecObjectInterface $ property , string $ name , ComponentSchema $ schema )
@@ -82,21 +83,24 @@ public function __construct(SpecObjectInterface $property, string $name, Compone
8283 }
8384
8485 /**
86+ * @throws \cebe\yii2openapi\lib\exceptions\InvalidDefinitionException
8587 * @throws \yii\base\InvalidConfigException
8688 */
8789 private function initReference ():void
8890 {
8991 $ this ->isReference = true ;
9092 $ this ->refPointer = $ this ->property ->getJsonReference ()->getJsonPointer ()->getPointer ();
93+ $ refSchemaName = $ this ->getRefSchemaName ();
9194 if ($ this ->isRefPointerToSelf ()) {
9295 $ this ->refSchema = $ this ->schema ;
9396 } elseif ($ this ->isRefPointerToSchema ()) {
9497 $ this ->property ->getContext ()->mode = ReferenceContext::RESOLVE_MODE_ALL ;
95- $ this ->refSchema = Yii::createObject (ComponentSchema::class, [$ this ->property ->resolve ()]);
98+ $ this ->refSchema = Yii::createObject (ComponentSchema::class, [$ this ->property ->resolve (), $ refSchemaName ]);
9699 }
97100 }
98101
99102 /**
103+ * @throws \cebe\yii2openapi\lib\exceptions\InvalidDefinitionException
100104 * @throws \yii\base\InvalidConfigException
101105 */
102106 private function initItemsReference ():void
@@ -111,7 +115,7 @@ private function initItemsReference():void
111115 $ this ->refSchema = $ this ->schema ;
112116 } elseif ($ this ->isRefPointerToSchema ()) {
113117 $ items ->getContext ()->mode = ReferenceContext::RESOLVE_MODE_ALL ;
114- $ this ->refSchema = Yii::createObject (ComponentSchema::class, [$ items ->resolve ()]);
118+ $ this ->refSchema = Yii::createObject (ComponentSchema::class, [$ items ->resolve (), $ this -> getRefSchemaName () ]);
115119 }
116120 }
117121
@@ -135,6 +139,11 @@ public function getProperty():SpecObjectInterface
135139 return $ this ->property ;
136140 }
137141
142+ public function getRefPointer (): string
143+ {
144+ return $ this ->refPointer ?? '' ;
145+ }
146+
138147 public function getRefSchema ():ComponentSchema
139148 {
140149 if (!$ this ->isReference && !$ this ->isItemsReference ) {
@@ -174,18 +183,23 @@ public function isRefPointerToSchema():bool
174183
175184 public function isRefPointerToSelf ():bool
176185 {
177- return $ this ->isRefPointerToSchema () && strpos ($ this ->refPointer , '/properties/ ' ) !== false ;
186+ return $ this ->isRefPointerToSchema ()
187+ && strpos ($ this ->refPointer , '/ ' . $ this ->schema ->getName () . '/ ' ) !== false
188+ && strpos ($ this ->refPointer , '/properties/ ' ) !== false ;
178189 }
179190
180-
181-
182191 public function getRefSchemaName ():string
183192 {
184193 if (!$ this ->isReference && !$ this ->isItemsReference ) {
185194 throw new BadMethodCallException ('Property should be a reference or contains items with reference ' );
186195 }
187- $ name = substr ($ this ->refPointer , self ::REFERENCE_PATH_LEN );
188- return $ this ->isRefPointerToSelf () ? substr ($ name , 0 , strpos ($ name , '/properties/ ' )) : $ name ;
196+ $ pattern = strpos ($ this ->refPointer , '/properties/ ' ) !== false ?
197+ '~^ ' .self ::REFERENCE_PATH .'(?<schemaName>.+)/properties/(?<propName>.+)$~ '
198+ : '~^ ' .self ::REFERENCE_PATH .'(?<schemaName>.+)$~ ' ;
199+ if (!\preg_match ($ pattern , $ this ->refPointer , $ matches )) {
200+ throw new InvalidDefinitionException ('Invalid schema reference ' );
201+ }
202+ return $ matches ['schemaName ' ];
189203 }
190204
191205 public function getRefClassName ():string
0 commit comments