vendor/zircote/swagger-php/src/Context.php line 263

Open in your IDE?
  1. <?php
  2. /**
  3.  * @license Apache 2.0
  4.  */
  5. namespace Swagger;
  6. /**
  7.  * Context
  8.  *
  9.  * The context in which the annotation is parsed.
  10.  * It includes useful metadata which the Processors can use to augment the annotations.
  11.  *
  12.  * Context hierarchy:
  13.  * - parseContext
  14.  *   |- docBlockContext
  15.  *   |- classContext
  16.  *      |- docBlockContext
  17.  *      |- propertyContext
  18.  *      |- methodContext
  19.  *
  20.  * @property string $comment  The PHP DocComment
  21.  * @property string $filename
  22.  * @property int $line
  23.  * @property int $character
  24.  *
  25.  * @property string $namespace
  26.  * @property array $uses
  27.  * @property string $class
  28.  * @property string $extends
  29.  * @property string $method
  30.  * @property string $property
  31.  * @property Annotations\AbstractAnnotation[] $annotations
  32.  */
  33. class Context
  34. {
  35.     /**
  36.      * Prototypical inheritance for properties.
  37.      * @var Context
  38.      */
  39.     private $_parent;
  40.     /**
  41.      * @param array $properties new properties for this context.
  42.      * @param Context $parent The parent context
  43.      */
  44.     public function __construct($properties = [], $parent null)
  45.     {
  46.         foreach ($properties as $property => $value) {
  47.             $this->$property $value;
  48.         }
  49.         $this->_parent $parent;
  50.     }
  51.     /**
  52.      * Check if a property is set directly on this context and not its parent context.
  53.      *
  54.      * @param string $type Example: $c->is('method') or $c->is('class')
  55.      * @return bool
  56.      */
  57.     public function is($type)
  58.     {
  59.         return property_exists($this$type);
  60.     }
  61.     /**
  62.      * Check if a property is NOT set directly on this context and but its parent context.
  63.      *
  64.      * @param string $type Example: $c->not('method') or $c->not('class')
  65.      * @return bool
  66.      */
  67.     public function not($type)
  68.     {
  69.         return property_exists($this$type) === false;
  70.     }
  71.     /**
  72.      * Return the context containing the specified property.
  73.      *
  74.      * @param string $property
  75.      * @return boolean|\Swagger\Context
  76.      */
  77.     public function with($property)
  78.     {
  79.         if (property_exists($this$property)) {
  80.             return $this;
  81.         }
  82.         if ($this->_parent) {
  83.             return $this->_parent->with($property);
  84.         }
  85.         return false;
  86.     }
  87.     /**
  88.      * @return \Swagger\Context
  89.      */
  90.     public function getRootContext()
  91.     {
  92.         if ($this->_parent) {
  93.             return $this->_parent->getRootContext();
  94.         }
  95.         return $this;
  96.     }
  97.     /**
  98.      * Export location for debugging.
  99.      *
  100.      * @return string Example: "file1.php on line 12"
  101.      */
  102.     public function getDebugLocation()
  103.     {
  104.         $location '';
  105.         if ($this->class && ($this->method || $this->property)) {
  106.             $location .= $this->fullyQualifiedName($this->class);
  107.             if ($this->method) {
  108.                 $location .= ($this->static '::' '->') . $this->method '()';
  109.             } elseif ($this->property) {
  110.                 $location .= ($this->static '::$' '->') . $this->property;
  111.             }
  112.         }
  113.         if ($this->filename) {
  114.             if ($location !== '') {
  115.                 $location .= ' in ';
  116.             }
  117.             $location .= $this->filename;
  118.         }
  119.         if ($this->line) {
  120.             if ($location !== '') {
  121.                 $location .= ' on';
  122.             }
  123.             $location .= ' line ' $this->line;
  124.             if ($this->character) {
  125.                 $location .= ':' $this->character;
  126.             }
  127.         }
  128.         return $location;
  129.     }
  130.     /**
  131.      * Traverse the context tree to get the property value.
  132.      *
  133.      * @param string $property
  134.      * @return mixed
  135.      */
  136.     public function __get($property)
  137.     {
  138.         if ($this->_parent) {
  139.             return $this->_parent->$property;
  140.         }
  141.         return null;
  142.     }
  143.     public function __toString()
  144.     {
  145.         return $this->getDebugLocation();
  146.     }
  147.     public function __debugInfo()
  148.     {
  149.         return ['-' => $this->getDebugLocation()];
  150.     }
  151.     /**
  152.      * A short piece of text, usually one line, providing the basic function of the associated element.
  153.      * @return string|null
  154.      */
  155.     public function phpdocSummary()
  156.     {
  157.         $content $this->phpdocContent();
  158.         if (!$content) {
  159.             return null;
  160.         }
  161.         $lines preg_split('/(\n|\r\n)/'$content);
  162.         $summary '';
  163.         foreach ($lines as $line) {
  164.             $summary .= $line."\n";
  165.             if ($line === '' || substr($line, -1) === '.') {
  166.                 return trim($summary);
  167.             }
  168.         }
  169.         $summary trim($summary);
  170.         if ($summary === '') {
  171.             return null;
  172.         }
  173.         return $summary;
  174.     }
  175.     
  176.     /**
  177.      * An optional longer piece of text providing more details on the associated element’s function. This is very useful when working with a complex element.
  178.      * @return string|null
  179.      */
  180.     public function phpdocDescription()
  181.     {
  182.         $summary $this->phpdocSummary();
  183.         if (!$summary) {
  184.             return null;
  185.         }
  186.         $description trim(substr($this->phpdocContent(), strlen($summary)));
  187.         if ($description === '') {
  188.             return null;
  189.         }
  190.         return $description;
  191.     }
  192.     /**
  193.      * The text contents of the phpdoc comment (excl. tags)
  194.      * @return string|null
  195.      */
  196.     public function phpdocContent()
  197.     {
  198.         $comment preg_split('/(\n|\r\n)/', (string) $this->comment);
  199.         $comment[0] = preg_replace('/[ \t]*\\/\*\*/'''$comment[0]); // strip '/**'
  200.         $i count($comment) -1;
  201.         $comment[$i] = preg_replace('/\*\/[ \t]*$/'''$comment[$i]); // strip '*/'
  202.         $lines = [];
  203.         $append false;
  204.         foreach ($comment as $line) {
  205.             $line ltrim($line"\t *");
  206.             if (substr($line01) === '@') {
  207.                 break;
  208.             }
  209.             if ($append) {
  210.                 $i count($lines) - 1;
  211.                 $lines[$i] = substr($lines[$i], 0, -1).$line;
  212.             } else {
  213.                 $lines[] = $line;
  214.             }
  215.             $append = (substr($line, -1) === '\\');
  216.         }
  217.         $description trim(implode("\n"$lines));
  218.         if ($description === '') {
  219.             return null;
  220.         }
  221.         return $description;
  222.     }
  223.     /**
  224.      * Create a Context based on the debug_backtrace
  225.      * @param int $index
  226.      * @return \Swagger\Context
  227.      */
  228.     public static function detect($index 0)
  229.     {
  230.         $context = new Context();
  231.         $backtrace debug_backtrace();
  232.         $position $backtrace[$index];
  233.         if (isset($position['file'])) {
  234.             $context->filename $position['file'];
  235.         }
  236.         if (isset($position['line'])) {
  237.             $context->line $position['line'];
  238.         }
  239.         $caller = isset($backtrace[$index 1]) ? $backtrace[$index 1] : null;
  240.         if (isset($caller['function'])) {
  241.             $context->method $caller['function'];
  242.             if (isset($caller['type']) && $caller['type'] === '::') {
  243.                 $context->static true;
  244.             }
  245.         }
  246.         if (isset($caller['class'])) {
  247.             $fqn explode('\\'$caller['class']);
  248.             $context->class array_pop($fqn);
  249.             if (count($fqn)) {
  250.                 $context->namespace implode('\\'$fqn);
  251.             }
  252.         }
  253.         // @todo extract namespaces and use statements
  254.         return $context;
  255.     }
  256.     /**
  257.      * Resolve the fully qualified name.
  258.      *
  259.      * @param string $class  The class name
  260.      * @return string
  261.      */
  262.     public function fullyQualifiedName($class)
  263.     {
  264.         if ($this->namespace) {
  265.             $namespace str_replace('\\\\''\\''\\' $this->namespace '\\');
  266.         } else {
  267.             $namespace '\\'// global namespace
  268.         }
  269.         if (strcasecmp($class$this->class) === 0) {
  270.             return $namespace $this->class;
  271.         }
  272.         $pos strpos($class'\\');
  273.         if ($pos !== false) {
  274.             if ($pos === 0) {
  275.                 // Fully qualified name (\Foo\Bar)
  276.                 return $class;
  277.             }
  278.             // Qualified name (Foo\Bar)
  279.             if ($this->uses) {
  280.                 foreach ($this->uses as $alias => $aliasedNamespace) {
  281.                     $alias .= '\\';
  282.                     if (strcasecmp(substr($class0strlen($alias)), $alias) === 0) {
  283.                         // Aliased namespace (use \Long\Namespace as Foo)
  284.                         return '\\' $aliasedNamespace substr($classstrlen($alias) - 1);
  285.                     }
  286.                 }
  287.             }
  288.         } elseif ($this->uses) {
  289.             // Unqualified name (Foo)
  290.             foreach ($this->uses as $alias => $aliasedNamespace) {
  291.                 if (strcasecmp($alias$class) === 0) {
  292.                     return '\\' $aliasedNamespace;
  293.                 }
  294.             }
  295.         }
  296.         return $namespace $class;
  297.     }
  298. }