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; } }