swagger-php/src/Context.php

193 lines
4.9 KiB
PHP

<?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 $class
* @property string $extends
* @property string $method
* @property string $property
*/
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 = array(), $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);
}
/**
* 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->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();
}
/**
* @return string|null
*/
public function extractDescription() {
$lines = explode("\n", $this->comment);
unset($lines[0]);
$description = '';
foreach ($lines as $line) {
$line = ltrim($line, "\t *");
if (substr($line, 0, 1) === '@') {
break;
}
$description .= $line . ' ';
}
$description = trim($description);
if ($description === '') {
return null;
}
if (stripos($description, 'license')) {
return null; // Don't use the GPL/MIT license text as the description.
}
return $description;
}
/**
* Create a Context based on the debug_backtrace
* @param int $index
* @return \Swagger\Context
*/
static public function detect($index = 0) {
$context = new Context();
$backtrace = debug_backtrace();
$call = $backtrace[$index];
if (isset($call['function'])) {
$context->method = $call['function'];
if (isset($call['type']) && $call['type'] === '::') {
$context->static = true;
}
}
if (isset($call['class'])) {
$context->class = $call['class'];
}
if (isset($call['file'])) {
$context->filename = $call['file'];
}
if (isset($call['line'])) {
$context->line = $call['line'];
}
return $context;
}
}