Ejemplo n.º 1
0
 public function __invoke(Analysis $analysis)
 {
     $definitions = $analysis->getAnnotationsOfType('\\Swagger\\Annotations\\Definition');
     // Use the class names for @SWG\Definition()
     foreach ($definitions as $definition) {
         if ($definition->definition === null) {
             if ($definition->_context->is('class')) {
                 $definition->definition = $definition->_context->class;
             } elseif ($definition->_context->is('trait')) {
                 $definition->definition = $definition->_context->trait;
             }
             // if ($definition->type === null) {
             //     $definition->type = 'object';
             // }
         }
     }
     // Merge unmerged @SWG\Property annotations into the @SWG\Definition of the class
     $unmergedProperties = $analysis->unmerged()->getAnnotationsOfType('\\Swagger\\Annotations\\Property');
     foreach ($unmergedProperties as $property) {
         $definitonContext = $property->_context->with('class') ?: $property->_context->with('trait');
         if ($definitonContext->annotations) {
             $definition = false;
             foreach ($definitonContext->annotations as $annotation) {
                 if ($annotation instanceof Definition) {
                     $definition = $annotation;
                 }
             }
             if ($definition) {
                 $definition->merge([$property], true);
             }
         }
     }
 }
Ejemplo n.º 2
0
 public function __invoke(Analysis $analysis)
 {
     $schemas = $analysis->getAnnotationsOfType('\\Swagger\\Annotations\\Schema');
     foreach ($schemas as $schema) {
         if ($schema->_context->is('class')) {
             $existing = [];
             foreach ($schema->properties as $property) {
                 if ($property->property) {
                     $existing[] = $property->property;
                 }
             }
             $classes = $analysis->getSuperClasses($schema->_context->fullyQualifiedName($schema->_context->class));
             foreach ($classes as $class) {
                 foreach ($class['properties'] as $property) {
                     foreach ($property->annotations as $annotation) {
                         if ($annotation instanceof Property && in_array($annotation->property, $existing) === false) {
                             $existing[] = $annotation->property;
                             $schema->merge([$annotation], true);
                         }
                     }
                 }
             }
         }
     }
 }
Ejemplo n.º 3
0
 public function __invoke(Analysis $analysis)
 {
     $paths = [];
     // Merge @SWG\Paths with the same path.
     foreach ($analysis->swagger->paths as $annotation) {
         if (empty($annotation->path)) {
             Logger::notice($annotation->identity() . ' is missing required property "path" in ' . $annotation->_context);
         } elseif (isset($paths[$annotation->path])) {
             $paths[$annotation->path]->mergeProperties($annotation);
             $analysis->annotations->detach($annotation);
         } else {
             $paths[$annotation->path] = $annotation;
         }
     }
     // Merge @SWG\Operations into existing @SWG\Paths or create a new one.
     $operations = $analysis->unmerged()->getAnnotationsOfType('\\Swagger\\Annotations\\Operation');
     foreach ($operations as $operation) {
         if ($operation->path) {
             if (empty($paths[$operation->path])) {
                 $paths[$operation->path] = new Path(['path' => $operation->path, '_context' => new Context(['generated' => true], $operation->_context)]);
                 $analysis->annotations->attach($paths[$operation->path]);
             }
             if ($paths[$operation->path]->merge([$operation])) {
                 Logger::notice('Unable to merge ' . $operation->identity() . ' in ' . $operation->_context);
             }
         }
     }
     $analysis->swagger->paths = array_values($paths);
 }
Ejemplo n.º 4
0
 public function __invoke(Analysis $analysis)
 {
     $refs = [];
     /** @var Definition $definition */
     foreach ($analysis->swagger->definitions as $definition) {
         if ($definition->definition) {
             $refs[strtolower($definition->_context->fullyQualifiedName($definition->_context->class))] = '#/definitions/' . $definition->definition;
         }
     }
     $allProperties = $analysis->getAnnotationsOfType('\\Swagger\\Annotations\\Property');
     /** @var \Swagger\Annotations\Property $property */
     foreach ($allProperties as $property) {
         $context = $property->_context;
         // Use the property names for @SWG\Property()
         if ($property->property === null) {
             $property->property = $context->property;
         }
         if (preg_match('/@var\\s+(?<type>[^\\s]+)([ \\t])?(?<description>.+)?$/im', $context->comment, $varMatches)) {
             if ($property->description === null && isset($varMatches['description'])) {
                 $property->description = trim($varMatches['description']);
             }
             if ($property->type === null) {
                 preg_match('/^([^\\[]+)(.*$)/', trim($varMatches['type']), $typeMatches);
                 $type = $typeMatches[1];
                 if (array_key_exists(strtolower($type), static::$types)) {
                     $type = static::$types[strtolower($type)];
                     if (is_array($type)) {
                         if ($property->format === null) {
                             $property->format = $type[1];
                         }
                         $type = $type[0];
                     }
                     $property->type = $type;
                 } elseif ($property->ref === null && $typeMatches[2] === '') {
                     $tmpKey = strtolower($context->fullyQualifiedName($type));
                     $property->ref = array_key_exists($tmpKey, $refs) ? $refs[$tmpKey] : null;
                 }
                 if ($typeMatches[2] === '[]') {
                     if ($property->items === null) {
                         $property->items = new Items(['type' => $property->type, '_context' => new Context(['generated' => true], $context)]);
                         if ($property->items->type === null) {
                             $tmpKey = strtolower($context->fullyQualifiedName($type));
                             $property->items->ref = array_key_exists($tmpKey, $refs) ? $refs[$tmpKey] : null;
                         }
                     }
                     $property->type = 'array';
                 }
             }
         }
         if ($property->description === null) {
             $property->description = $context->phpdocContent();
         }
     }
 }
Ejemplo n.º 5
0
 public function testProcessor()
 {
     $swagger = new Swagger([]);
     $info = new Info([]);
     $analysis = new Analysis([$swagger, $info]);
     $this->assertNull($analysis->swagger);
     $this->assertNull($swagger->info);
     $analysis->process(new MergeIntoSwagger());
     $this->assertInstanceOf('Swagger\\Annotations\\Swagger', $analysis->swagger);
     $this->assertSame($info, $swagger->info);
     $this->assertCount(0, $analysis->unmerged()->annotations);
 }
Ejemplo n.º 6
0
 public function __invoke(Analysis $analysis)
 {
     $allOperations = $analysis->getAnnotationsOfType('\\Swagger\\Annotations\\Operation');
     /** @var Operation $operation */
     foreach ($allOperations as $operation) {
         if (null === $operation->summary) {
             $operation->summary = $operation->_context->phpdocSummary();
         }
         if (null === $operation->description) {
             $operation->description = $operation->_context->phpdocDescription();
         }
     }
 }
Ejemplo n.º 7
0
 public function testMergeOperationsWithSamePath()
 {
     $swagger = new Swagger([]);
     $analysis = new Analysis([$swagger, new Get(['path' => '/comments']), new Post(['path' => '/comments'])]);
     $analysis->process(new MergeIntoSwagger());
     $analysis->process(new BuildPaths());
     $this->assertCount(1, $swagger->paths);
     $path = $swagger->paths[0];
     $this->assertSame('/comments', $path->path);
     $this->assertInstanceOf('\\Swagger\\Annotations\\Path', $path);
     $this->assertInstanceOf('\\Swagger\\Annotations\\Get', $path->get);
     $this->assertInstanceOf('\\Swagger\\Annotations\\Post', $path->post);
     $this->assertNull($path->put);
 }
Ejemplo n.º 8
0
 public function testRegisterProcessor()
 {
     $counter = 0;
     $analysis = new Analysis();
     $analysis->process();
     $this->assertSame(0, $counter);
     $countProcessor = function (Analysis $a) use(&$counter) {
         $counter++;
     };
     Analysis::registerProcessor($countProcessor);
     $analysis->process();
     $this->assertSame(1, $counter);
     Analysis::unregisterProcessor($countProcessor);
     $analysis->process();
     $this->assertSame(1, $counter);
 }
Ejemplo n.º 9
0
 public function __invoke(Analysis $analysis)
 {
     $split = $analysis->split();
     $merged = $split->merged->annotations;
     $unmerged = $split->unmerged->annotations;
     foreach ($analysis->annotations as $annotation) {
         if (property_exists($annotation, '_unmerged')) {
             foreach ($annotation->_unmerged as $i => $item) {
                 if ($merged->contains($item)) {
                     unset($annotation->_unmerged[$i]);
                     // Property was merged
                 }
             }
         }
     }
     $analysis->swagger->_unmerged = [];
     foreach ($unmerged as $annotation) {
         $analysis->swagger->_unmerged[] = $annotation;
     }
 }
Ejemplo n.º 10
0
 /**
  * {@inheritDoc}
  */
 public function getServiceConfig()
 {
     return array('aliases' => array('service.swagger' => 'Swagger\\Annotations\\Swagger'), 'factories' => array('SwaggerModule\\Options\\ModuleOptions' => function ($serviceManager) {
         $config = $serviceManager->get('Config');
         $config = isset($config['swagger']) ? $config['swagger'] : null;
         if ($config === null) {
             throw new RuntimeException('Configuration for SwaggerModule was not found');
         }
         return new SwaggerModuleOptions($config);
     }, 'Swagger\\Annotations\\Swagger' => function ($serviceManager) {
         /** @var $options \SwaggerModule\Options\ModuleOptions */
         $options = $serviceManager->get('SwaggerModule\\Options\\ModuleOptions');
         $analyser = new SwaggerStaticAnalyser();
         $analysis = new SwaggerAnalysis();
         $processors = SwaggerAnalysis::processors();
         // Crawl directory and parse all files
         $paths = $options->getPaths();
         foreach ($paths as $directory) {
             $finder = SwaggerUtil::finder($directory);
             foreach ($finder as $file) {
                 $analysis->addAnalysis($analyser->fromFile($file->getPathname()));
             }
         }
         // Post processing
         $analysis->process($processors);
         // Validation (Generate notices & warnings)
         $analysis->validate();
         // Pass options to analyzer
         $resourceOptions = $options->getResourceOptions();
         if (!empty($resourceOptions['defaultBasePath'])) {
             $analysis->swagger->basePath = $resourceOptions['defaultBasePath'];
         }
         if (!empty($resourceOptions['defaultHost'])) {
             $analysis->swagger->host = $resourceOptions['defaultHost'];
         }
         if (!empty($resourceOptions['schemes'])) {
             $analysis->swagger->schemes = $resourceOptions['schemes'];
         }
         return $analysis->swagger;
     }));
 }
Ejemplo n.º 11
0
 /**
  * Scan the filesystem for swagger annotations and build swagger-documentation.
  *
  * @param string|array|Finder $directory The directory(s) or filename(s)
  * @param array $options 
  *   exclude: string|array $exclude The directory(s) or filename(s) to exclude (as absolute or relative paths)
  *   analyser: defaults to StaticAnalyser
  *   analysis: defaults to a new Analysis
  *   processors: defaults to the registered processors in Analysis
  * @return Swagger
  */
 function scan($directory, $options = array())
 {
     $analyser = @$options['analyser'] ?: new StaticAnalyser();
     $analysis = @$options['analysis'] ?: new Analysis();
     $processors = @$options['processors'] ?: Analysis::processors();
     $exclude = @$options['exclude'] ?: null;
     // Crawl directory and parse all files
     $finder = Util::finder($directory, $exclude);
     foreach ($finder as $file) {
         $analysis->addAnalysis($analyser->fromFile($file->getPathname()));
     }
     // Post processing
     $analysis->process($processors);
     // Validation (Generate notices & warnings)
     $analysis->validate();
     return $analysis->swagger;
 }
Ejemplo n.º 12
0
    public function testCleanUnmergedProcessor()
    {
        $comment = <<<END
@SWG\\Info(
    title="Info only has one contact field.",
    version="test",
)
@SWG\\License(
    name="MIT",
    @SWG\\Contact(
        name="Batman"
    )
)

END;
        $analysis = new Analysis($this->parseComment($comment));
        $this->assertCount(3, $analysis->annotations);
        $analysis->process(new MergeIntoSwagger());
        $this->assertCount(4, $analysis->annotations);
        $before = $analysis->split();
        $this->assertCount(2, $before->merged->annotations, 'Generated @SWG\\Swagger + @SWG\\Info');
        $this->assertCount(2, $before->unmerged->annotations, '@SWG\\License + @SWG\\Contact');
        $this->assertCount(0, $analysis->swagger->_unmerged);
        $analysis->validate();
        // Validation fails to detect the unmerged annotations.
        // CleanUnmerged should place the unmerged annotions into the swagger->_unmerged array.
        $analysis->process(new CleanUnmerged());
        $between = $analysis->split();
        $this->assertCount(2, $between->merged->annotations, 'Generated @SWG\\Swagger + @SWG\\Info');
        $this->assertCount(2, $between->unmerged->annotations, '@SWG\\License + @SWG\\Contact');
        $this->assertCount(2, $analysis->swagger->_unmerged);
        // 1 would also be oke, Could a'Only the @SWG\License'
        $this->assertSwaggerLogEntryStartsWith('Unexpected @SWG\\License(), expected to be inside @SWG\\Info in ');
        $this->assertSwaggerLogEntryStartsWith('Unexpected @SWG\\Contact(), expected to be inside @SWG\\Info in ');
        $analysis->validate();
        // When a processor places a previously unmerged annotation into the swagger obect.
        $license = $analysis->getAnnotationsOfType('Swagger\\Annotations\\License')[0];
        $contact = $analysis->getAnnotationsOfType('Swagger\\Annotations\\Contact')[0];
        $analysis->swagger->info->contact = $contact;
        $this->assertCount(1, $license->_unmerged);
        $analysis->process(new CleanUnmerged());
        $this->assertCount(0, $license->_unmerged);
        $after = $analysis->split();
        $this->assertCount(3, $after->merged->annotations, 'Generated @SWG\\Swagger + @SWG\\Info + @SWG\\Contact');
        $this->assertCount(1, $after->unmerged->annotations, '@SWG\\License');
        $this->assertCount(1, $analysis->swagger->_unmerged);
        $this->assertSwaggerLogEntryStartsWith('Unexpected @SWG\\License(), expected to be inside @SWG\\Info in ');
        $analysis->validate();
    }
 public function provideDataForGetScanOptions()
 {
     return ['exclude' => ['exclude', __DIR__], 'analyser' => ['analyser', $this->prophesize('Swagger\\StaticAnalyser')->reveal()], 'analysis' => ['analysis', $this->prophesize('Swagger\\Analysis')->reveal()], 'processors' => ['processors', Analysis::processors()]];
 }
Ejemplo n.º 14
0
/**
 * Same as the Swagger\scan however allows for LaravelModels
 *
 * @param string|array|Finder $directory The directory(s) or filename(s)
 * @param array $options
 *   exclude: string|array $exclude The directory(s) or filename(s) to exclude (as absolute or relative paths)
 *   analyser: defaults to StaticAnalyser
 *   analysis: defaults to a new Analysis
 *   processors: defaults to the registered processors in Analysis
 *   models: the laravel models to convert into definitions
 * @return Swagger
 */
function scan($directory, $options = array())
{
    $models = @$options['models'] ?: [];
    $options['processors'] = @$options['processors'] ?: array_merge([new LaravelSwagger($models)], Analysis::processors());
    return \Swagger\scan($directory, $options);
}
Ejemplo n.º 15
0
 /**
  * Loads the Laravel Models into the Swagger JSON
  *
  * @param Analysis $analysis
  */
 private function load_models(Analysis $analysis)
 {
     foreach ($this->models as $model) {
         /** @var Model $model */
         $obj = new $model();
         if ($obj instanceof Model) {
             //check to make sure it is a model
             $reflection = new ReflectionClass($obj);
             $with = $reflection->getProperty('with');
             $with->setAccessible(true);
             $list = Schema::getColumnListing($obj->getTable());
             $list = array_diff($list, $obj->getHidden());
             $properties = [];
             foreach ($list as $item) {
                 $data = ['property' => $item, 'type' => $this->get_type($obj->getTable(), $item)];
                 $default = $this->get_default($obj->getTable(), $item);
                 if (!is_null($default)) {
                     $data['default'] = $default;
                 }
                 $properties[] = new Property($data);
             }
             foreach ($with->getValue($obj) as $item) {
                 $class = get_class($obj->{$item}()->getModel());
                 $properties[] = new Property(['property' => $item, 'ref' => '#/definitions/' . $class]);
             }
             $definition = new Definition(['definition' => $model, 'properties' => $properties]);
             $analysis->addAnnotation($definition, new Context(['-', $model]));
         }
     }
 }