| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336 |
- <?php
- /**
- * @license Apache 2.0
- */
- namespace Swagger;
- use Closure;
- use Exception;
- use SplObjectStorage;
- use stdClass;
- use Swagger\Annotations\AbstractAnnotation;
- use Swagger\Annotations\Swagger;
- use Swagger\Processors\AugmentDefinitions;
- use Swagger\Processors\AugmentOperations;
- use Swagger\Processors\AugmentParameters;
- use Swagger\Processors\AugmentProperties;
- use Swagger\Processors\BuildPaths;
- use Swagger\Processors\CleanUnmerged;
- use Swagger\Processors\HandleReferences;
- use Swagger\Processors\InheritProperties;
- use Swagger\Processors\MergeIntoSwagger;
- /**
- * Result of the analyser which pretends to be an array of annotations, but also contains detected classes and helper functions for the processors.
- */
- class Analysis
- {
- /**
- * @var SplObjectStorage
- */
- public $annotations;
- /**
- * Class definitions
- * @var array
- */
- public $classes = [];
- /**
- * The target Swagger annotation.
- * @var Swagger
- */
- public $swagger;
- /**
- * Registry for the post-processing operations.
- * @var Closure[]
- */
- private static $processors;
- /**
- * @param array $annotations
- * @param null $context
- */
- public function __construct($annotations = [], $context = null)
- {
- $this->annotations = new SplObjectStorage();
- if (count($annotations) !== 0) {
- if ($context === null) {
- $context = Context::detect(1);
- }
- $this->addAnnotations($annotations, $context);
- }
- }
- /**
- * @param AbstractAnnotation $annotation
- * @param Context $context
- */
- public function addAnnotation($annotation, $context)
- {
- if ($this->annotations->contains($annotation)) {
- return;
- }
- if ($annotation instanceof AbstractAnnotation) {
- $context = $annotation->_context;
- } else {
- if ($context->is('annotations') === false) {
- $context->annotations = [];
- }
- if (in_array($annotation, $context->annotations, true) === false) {
- $context->annotations[] = $annotation;
- }
- }
- $this->annotations->attach($annotation, $context);
- $blacklist = property_exists($annotation, '_blacklist') ? $annotation::$_blacklist : [];
- foreach ($annotation as $property => $value) {
- if (in_array($property, $blacklist)) {
- if ($property === '_unmerged') {
- foreach ($value as $item) {
- $this->addAnnotation($item, $context);
- }
- }
- continue;
- } elseif (is_array($value)) {
- foreach ($value as $item) {
- if ($item instanceof AbstractAnnotation) {
- $this->addAnnotation($item, $context);
- }
- }
- } elseif ($value instanceof AbstractAnnotation) {
- $this->addAnnotation($value, $context);
- }
- }
- }
- /**
- * @param array $annotations
- * @param Context $context
- */
- public function addAnnotations($annotations, $context)
- {
- foreach ($annotations as $annotation) {
- $this->addAnnotation($annotation, $context);
- }
- }
- /**
- * @param array $definition
- */
- public function addClassDefinition($definition)
- {
- $class = $definition['context']->fullyQualifiedName($definition['class']);
- $this->classes[$class] = $definition;
- }
- /**
- * @param Analysis $analysis
- */
- public function addAnalysis($analysis)
- {
- foreach ($analysis->annotations as $annotation) {
- $this->addAnnotation($annotation, $analysis->annotations[$annotation]);
- }
- $this->classes = array_merge($this->classes, $analysis->classes);
- if ($this->swagger === null && $analysis->swagger) {
- $this->swagger = $analysis->swagger;
- $analysis->target->_context->analysis = $this;
- }
- }
- public function getSubClasses($class)
- {
- $definitions = [];
- foreach ($this->classes as $subclass => $definition) {
- if ($definition['extends'] === $class) {
- $definitions[$subclass] = $definition;
- $definitions = array_merge($definitions, $this->getSubClasses($subclass));
- }
- }
- return $definitions;
- }
- public function getSuperClasses($class)
- {
- $classDefinition = isset($this->classes[$class]) ? $this->classes[$class] : null;
- if (!$classDefinition || empty($classDefinition['extends'])) { // unknown class, or no inheritance?
- return [];
- }
- $extends = $classDefinition['extends'];
- $extendsDefinition = isset($this->classes[$extends]) ? $this->classes[$extends] : null;
- if (!$extendsDefinition) {
- return [];
- }
- $definitions = array_merge([$extends => $extendsDefinition], $this->getSuperClasses($extends));
- return $definitions;
- }
- /**
- *
- * @param string $class
- * @param boolean $strict Innon-strict mode childclasses are also detected.
- * @return array
- */
- public function getAnnotationsOfType($class, $strict = false)
- {
- $annotations = [];
- if ($strict) {
- foreach ($this->annotations as $annotation) {
- if (get_class($annotation) === $class) {
- $annotations[] = $annotation;
- }
- }
- } else {
- foreach ($this->annotations as $annotation) {
- if ($annotation instanceof $class) {
- $annotations[] = $annotation;
- }
- }
- }
- return $annotations;
- }
- /**
- *
- * @param object $annotation
- * @return \Swagger\Context
- */
- public function getContext($annotation)
- {
- if ($annotation instanceof AbstractAnnotation) {
- return $annotation->_context;
- }
- if ($this->annotations->contains($annotation) === false) {
- throw new Exception('Annotation not found');
- }
- $context = $this->annotations[$annotation];
- if ($context instanceof Context) {
- return $context;
- }
- var_dump($context);
- ob_flush();
- die;
- throw new Exception('Annotation has no context'); // Weird, did you use the addAnnotation/addAnnotations methods?
- }
- /**
- * Build an analysis with only the annotations that are merged into the swagger annotation.
- *
- * @return Analysis
- */
- public function merged()
- {
- if (!$this->swagger) {
- throw new Exception('No swagger target set. Run the MergeIntoSwagger processor');
- }
- $unmerged = $this->swagger->_unmerged;
- $this->swagger->_unmerged = [];
- $analysis = new Analysis([$this->swagger]);
- $this->swagger->_unmerged = $unmerged;
- return $analysis;
- }
- /**
- * Analysis with only the annotations that not merged.
- *
- * @return Analysis
- */
- public function unmerged()
- {
- return $this->split()->unmerged;
- }
- /**
- * Split the annotation into two analysis.
- * One with annotations that are merged and one with annotations that are not merged.
- *
- * @return object {merged: Analysis, unmerged: Analysis}
- */
- public function split()
- {
- $result = new stdClass();
- $result->merged = $this->merged();
- $result->unmerged = new Analysis();
- foreach ($this->annotations as $annotation) {
- if ($result->merged->annotations->contains($annotation) === false) {
- $result->unmerged->annotations->attach($annotation, $this->annotations[$annotation]);
- }
- }
- return $result;
- }
- /**
- * Apply the processor(s)
- * @param Closure|Closure[] $processors One or more processors
- */
- public function process($processors = null)
- {
- if ($processors === null) { // Use the default and registered processors.
- $processors = self::processors();
- }
- if (is_array($processors) === false && is_callable($processors)) {
- $processors = [$processors];
- }
- foreach ($processors as $processor) {
- $processor($this);
- }
- }
- /**
- * Get direct access to the processors array.
- * @return array reference
- */
- public static function &processors()
- {
- if (!self::$processors) {
- // Add default processors.
- self::$processors = [
- new MergeIntoSwagger(),
- new BuildPaths(),
- new HandleReferences(),
- new AugmentDefinitions(),
- new AugmentProperties(),
- new InheritProperties(),
- new AugmentOperations(),
- new AugmentParameters(),
- new CleanUnmerged(),
- ];
- }
- return self::$processors;
- }
- /**
- * Register a processor
- * @param Closure $processor
- */
- public static function registerProcessor($processor)
- {
- array_push(self::processors(), $processor);
- }
- /**
- * Unregister a processor
- * @param Closure $processor
- */
- public static function unregisterProcessor($processor)
- {
- $processors = &self::processors();
- $key = array_search($processor, $processors, true);
- if ($key === false) {
- throw new Exception('Given processor was not registered');
- }
- unset($processors[$key]);
- }
- public function validate()
- {
- if ($this->swagger) {
- return $this->swagger->validate();
- }
- Logger::notice('No swagger target set. Run the MergeIntoSwagger processor before validate()');
- return false;
- }
- }
|