| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314 |
- <?php
- /**
- * @license Apache 2.0
- */
- namespace Swagger;
- /**
- * Context
- *
- * The context in which the annotation is parsed.
- * It includes useful metadata which the Processors can use to augment the annotations.
- *
- * Context hierarchy:
- * - parseContext
- * |- docBlockContext
- * |- classContext
- * |- docBlockContext
- * |- propertyContext
- * |- methodContext
- *
- * @property string $comment The PHP DocComment
- * @property string $filename
- * @property int $line
- * @property int $character
- *
- * @property string $namespace
- * @property array $uses
- * @property string $class
- * @property string $extends
- * @property string $method
- * @property string $property
- * @property Annotations\AbstractAnnotation[] $annotations
- */
- class Context
- {
- /**
- * Prototypical inheritance for properties.
- * @var Context
- */
- private $_parent;
- /**
- * @param array $properties new properties for this context.
- * @param Context $parent The parent context
- */
- public function __construct($properties = [], $parent = null)
- {
- foreach ($properties as $property => $value) {
- $this->$property = $value;
- }
- $this->_parent = $parent;
- }
- /**
- * Check if a property is set directly on this context and not its parent context.
- *
- * @param string $type Example: $c->is('method') or $c->is('class')
- * @return bool
- */
- public function is($type)
- {
- return property_exists($this, $type);
- }
- /**
- * Check if a property is NOT set directly on this context and but its parent context.
- *
- * @param string $type Example: $c->not('method') or $c->not('class')
- * @return bool
- */
- public function not($type)
- {
- return property_exists($this, $type) === false;
- }
- /**
- * Return the context containing the specified property.
- *
- * @param string $property
- * @return boolean|\Swagger\Context
- */
- public function with($property)
- {
- if (property_exists($this, $property)) {
- return $this;
- }
- if ($this->_parent) {
- return $this->_parent->with($property);
- }
- return false;
- }
- /**
- * @return \Swagger\Context
- */
- public function getRootContext()
- {
- if ($this->_parent) {
- return $this->_parent->getRootContext();
- }
- return $this;
- }
- /**
- * Export location for debugging.
- *
- * @return string Example: "file1.php on line 12"
- */
- public function getDebugLocation()
- {
- $location = '';
- if ($this->class && ($this->method || $this->property)) {
- $location .= $this->fullyQualifiedName($this->class);
- if ($this->method) {
- $location .= ($this->static ? '::' : '->') . $this->method . '()';
- } elseif ($this->property) {
- $location .= ($this->static ? '::$' : '->') . $this->property;
- }
- }
- if ($this->filename) {
- if ($location !== '') {
- $location .= ' in ';
- }
- $location .= $this->filename;
- }
- if ($this->line) {
- if ($location !== '') {
- $location .= ' on';
- }
- $location .= ' line ' . $this->line;
- if ($this->character) {
- $location .= ':' . $this->character;
- }
- }
- return $location;
- }
- /**
- * Traverse the context tree to get the property value.
- *
- * @param string $property
- * @return mixed
- */
- public function __get($property)
- {
- if ($this->_parent) {
- return $this->_parent->$property;
- }
- return null;
- }
- public function __toString()
- {
- return $this->getDebugLocation();
- }
- public function __debugInfo()
- {
- return ['-' => $this->getDebugLocation()];
- }
- /**
- * A short piece of text, usually one line, providing the basic function of the associated element.
- * @return string|null
- */
- public function phpdocSummary()
- {
- $content = $this->phpdocContent();
- if (!$content) {
- return null;
- }
- $lines = preg_split('/(\n|\r\n)/', $content);
- $summary = '';
- foreach ($lines as $line) {
- $summary .= $line."\n";
- if ($line === '' || substr($line, -1) === '.') {
- return trim($summary);
- }
- }
- $summary = trim($summary);
- if ($summary === '') {
- return null;
- }
- return $summary;
- }
-
- /**
- * 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.
- * @return string|null
- */
- public function phpdocDescription()
- {
- $summary = $this->phpdocSummary();
- if (!$summary) {
- return null;
- }
- $description = trim(substr($this->phpdocContent(), strlen($summary)));
- if ($description === '') {
- return null;
- }
- return $description;
- }
- /**
- * The text contents of the phpdoc comment (excl. tags)
- * @return string|null
- */
- public function phpdocContent()
- {
- $comment = preg_split('/(\n|\r\n)/', $this->comment);
- $comment[0] = preg_replace('/[ \t]*\\/\*\*/', '', $comment[0]); // strip '/**'
- $i = count($comment) -1;
- $comment[$i] = preg_replace('/\*\/[ \t]*$/', '', $comment[$i]); // strip '*/'
- $lines = [];
- $append = false;
- foreach ($comment as $line) {
- $line = ltrim($line, "\t *");
- if (substr($line, 0, 1) === '@') {
- break;
- }
- if ($append) {
- $i = count($lines) - 1;
- $lines[$i] = substr($lines[$i], 0, -1).$line;
- } else {
- $lines[] = $line;
- }
- $append = (substr($line, -1) === '\\');
- }
- $description = trim(implode("\n", $lines));
- if ($description === '') {
- return null;
- }
- return $description;
- }
- /**
- * Create a Context based on the debug_backtrace
- * @param int $index
- * @return \Swagger\Context
- */
- public static function detect($index = 0)
- {
- $context = new Context();
- $backtrace = debug_backtrace();
- $position = $backtrace[$index];
- if (isset($position['file'])) {
- $context->filename = $position['file'];
- }
- if (isset($position['line'])) {
- $context->line = $position['line'];
- }
- $caller = isset($backtrace[$index + 1]) ? $backtrace[$index + 1] : null;
- if (isset($caller['function'])) {
- $context->method = $caller['function'];
- if (isset($caller['type']) && $caller['type'] === '::') {
- $context->static = true;
- }
- }
- if (isset($caller['class'])) {
- $fqn = explode('\\', $caller['class']);
- $context->class = array_pop($fqn);
- if (count($fqn)) {
- $context->namespace = implode('\\', $fqn);
- }
- }
- // @todo extract namespaces and use statements
- return $context;
- }
- /**
- * Resolve the fully qualified name.
- *
- * @param string $class The class name
- * @return string
- */
- public function fullyQualifiedName($class)
- {
- if ($this->namespace) {
- $namespace = str_replace('\\\\', '\\', '\\' . $this->namespace . '\\');
- } else {
- $namespace = '\\'; // global namespace
- }
- if (strcasecmp($class, $this->class) === 0) {
- return $namespace . $this->class;
- }
- $pos = strpos($class, '\\');
- if ($pos !== false) {
- if ($pos === 0) {
- // Fully qualified name (\Foo\Bar)
- return $class;
- }
- // Qualified name (Foo\Bar)
- if ($this->uses) {
- foreach ($this->uses as $alias => $aliasedNamespace) {
- $alias .= '\\';
- if (strcasecmp(substr($class, 0, strlen($alias)), $alias) === 0) {
- // Aliased namespace (use \Long\Namespace as Foo)
- return '\\' . $aliasedNamespace . substr($class, strlen($alias) - 1);
- }
- }
- }
- } elseif ($this->uses) {
- // Unqualified name (Foo)
- foreach ($this->uses as $alias => $aliasedNamespace) {
- if (strcasecmp($alias, $class) === 0) {
- return '\\' . $aliasedNamespace;
- }
- }
- }
- return $namespace . $class;
- }
- }
|