2017-01-14 17:36:56 +01:00
< ? php
/*
* This file is part of the NelmioApiDocBundle package .
*
* ( c ) Nelmio
*
* For the full copyright and license information , please view the LICENSE
* file that was distributed with this source code .
*/
namespace Nelmio\ApiDocBundle\SwaggerPhp ;
use Nelmio\ApiDocBundle\Annotation\Model as ModelAnnotation ;
use Nelmio\ApiDocBundle\Model\Model ;
use Nelmio\ApiDocBundle\Model\ModelRegistry ;
use Swagger\Analysis ;
2018-03-17 19:23:29 +01:00
use Swagger\Annotations\AbstractAnnotation ;
2017-01-14 17:36:56 +01:00
use Swagger\Annotations\Items ;
use Swagger\Annotations\Parameter ;
use Swagger\Annotations\Response ;
use Swagger\Annotations\Schema ;
use Symfony\Component\PropertyInfo\Type ;
/**
* Resolves the path in SwaggerPhp annotation when needed .
*
* @ internal
*/
final class ModelRegister
{
private $modelRegistry ;
public function __construct ( ModelRegistry $modelRegistry )
{
$this -> modelRegistry = $modelRegistry ;
}
2018-03-17 19:23:29 +01:00
public function __invoke ( Analysis $analysis , array $parentGroups = null )
2017-01-14 17:36:56 +01:00
{
2017-08-27 17:39:06 +02:00
$modelsRegistered = [];
2017-01-14 17:36:56 +01:00
foreach ( $analysis -> annotations as $annotation ) {
2018-03-17 14:36:57 +01:00
// @Model using the ref field
if ( $annotation instanceof Schema && $annotation -> ref instanceof ModelAnnotation ) {
$model = $annotation -> ref ;
2018-03-17 19:23:29 +01:00
$annotation -> ref = $this -> modelRegistry -> register ( new Model ( $this -> createType ( $model -> type ), $this -> getGroups ( $model , $parentGroups )));
2018-03-17 14:36:57 +01:00
2018-03-17 19:23:29 +01:00
// It is no longer an unmerged annotation
$this -> detach ( $model , $annotation , $analysis );
2018-03-17 14:36:57 +01:00
continue ;
}
// Implicit usages
2017-03-16 19:35:04 +01:00
if ( $annotation instanceof Response ) {
$annotationClass = Schema :: class ;
} elseif ( $annotation instanceof Parameter ) {
if ( 'array' === $annotation -> type ) {
$annotationClass = Items :: class ;
} else {
$annotationClass = Schema :: class ;
}
} elseif ( $annotation instanceof Schema ) {
$annotationClass = Items :: class ;
} else {
2017-01-14 17:36:56 +01:00
continue ;
}
2017-03-16 19:35:04 +01:00
$model = null ;
foreach ( $annotation -> _unmerged as $unmerged ) {
if ( $unmerged instanceof ModelAnnotation ) {
$model = $unmerged ;
break ;
}
2017-01-14 17:36:56 +01:00
}
2017-03-16 19:35:04 +01:00
if ( null === $model || ! $model instanceof ModelAnnotation ) {
2017-01-14 17:36:56 +01:00
continue ;
}
2017-03-16 19:35:04 +01:00
if ( ! is_string ( $model -> type )) {
// Ignore invalid annotations, they are validated later
continue ;
2017-01-14 17:36:56 +01:00
}
2018-03-17 14:36:57 +01:00
if ( $annotation instanceof Schema ) {
@ trigger_error ( sprintf ( 'Using `@Model` implicitely in a `@SWG\Schema`, `@SWG\Items` or `@SWG\Property` annotation in %s is deprecated since version 3.2 and won\'t be supported in 4.0. Use `ref=@Model()` instead.' , $annotation -> _context -> getDebugLocation ()), E_USER_DEPRECATED );
}
2017-08-27 17:39:06 +02:00
2017-03-16 19:35:04 +01:00
$annotation -> merge ([ new $annotationClass ([
2018-03-17 19:23:29 +01:00
'ref' => $this -> modelRegistry -> register ( new Model ( $this -> createType ( $model -> type ), $this -> getGroups ( $model , $parentGroups ))),
2017-01-14 17:36:56 +01:00
])]);
// It is no longer an unmerged annotation
2018-03-17 19:23:29 +01:00
$this -> detach ( $model , $annotation , $analysis );
}
}
2017-01-14 17:36:56 +01:00
2018-03-17 19:23:29 +01:00
private function getGroups ( ModelAnnotation $model , array $parentGroups = null )
{
if ( null === $model -> groups ) {
return $parentGroups ;
}
return array_merge ( $parentGroups ? ? [], $model -> groups );
}
private function detach ( ModelAnnotation $model , AbstractAnnotation $annotation , Analysis $analysis )
{
foreach ( $annotation -> _unmerged as $key => $unmerged ) {
if ( $unmerged === $model ) {
unset ( $annotation -> _unmerged [ $key ]);
break ;
2017-01-14 17:36:56 +01:00
}
}
2018-03-17 19:23:29 +01:00
$analysis -> annotations -> detach ( $model );
2017-01-14 17:36:56 +01:00
}
private function createType ( string $type ) : Type
{
if ( '[]' === substr ( $type , - 2 )) {
return new Type ( Type :: BUILTIN_TYPE_ARRAY , false , null , true , null , $this -> createType ( substr ( $type , 0 , - 2 )));
}
return new Type ( Type :: BUILTIN_TYPE_OBJECT , false , $type );
}
}