Commit 81aea730 by Carsten Brandt

finished offline template with all information

parent 8495be76
......@@ -8,10 +8,12 @@
namespace yii\apidoc\components;
use yii\apidoc\models\BaseDoc;
use yii\apidoc\models\ConstDoc;
use yii\apidoc\models\EventDoc;
use yii\apidoc\models\MethodDoc;
use yii\apidoc\models\PropertyDoc;
use yii\apidoc\models\TypeDoc;
use yii\base\ViewContextInterface;
use yii\console\Controller;
use yii\helpers\Console;
......@@ -94,24 +96,36 @@ class OfflineRenderer extends BaseRenderer implements ViewContextInterface
* @param string $title
* @return string
*/
public function typeLink($types, $title = null)
public function typeLink($types, $context = null)
{
if (!is_array($types)) {
$types = [$types];
}
$links = [];
foreach($types as $type) {
if (!is_object($type) && ($t = $this->context->getType($type)) !== null) {
$postfix = '';
if (!is_object($type)) {
if (substr($type, -2, 2) == '[]') {
$postfix = '[]';
$type = substr($type, 0, -2);
}
if (($t = $this->context->getType(ltrim($type, '\\'))) !== null) {
$type = $t;
} elseif ($type[0] !== '\\' && ($t = $this->context->getType($this->resolveNamespace($context) . '\\' . ltrim($type, '\\'))) !== null) {
$type = $t;
} else {
ltrim($type, '\\');
}
}
if (!is_object($type)) {
$links[] = $type;
} else {
$links[] = Html::a(
$title !== null ? $title : $type->name,
$type->name,
null,
['href' => $this->generateFileName($type->name)]
);
) . $postfix;
}
}
return implode('|', $links);
......@@ -131,8 +145,35 @@ class OfflineRenderer extends BaseRenderer implements ViewContextInterface
if (($type = $this->context->getType($subject->definedBy)) === null) {
return $subject->name;
} else {
return Html::a($title, null, ['href' => $this->generateFileName($type->name) . '#' . $subject->name . '-detail']);
$link = $this->generateFileName($type->name);
if ($subject instanceof MethodDoc) {
$link .= '#' . $subject->name . '()';
} else {
$link .= '#' . $subject->name;
}
$link .= '-detail';
return Html::a($title, null, ['href' => $link]);
}
}
/**
* @param BaseDoc $context
*/
private function resolveNamespace($context)
{
if ($context === null) {
return '';
}
if ($context instanceof TypeDoc) {
return $context->namespace;
}
if ($context->hasProperty('definedBy')) {
$type = $this->context->getType($context);
if ($type !== null) {
return $type->namespace;
}
}
return '';
}
/**
......@@ -208,6 +249,50 @@ class OfflineRenderer extends BaseRenderer implements ViewContextInterface
return implode(', ',$classes);
}
/**
* @param PropertyDoc $property
* @return string
*/
public function renderPropertySignature($property)
{
return $this->typeLink($property->types) . ' ' . $property->name . ' = ' . ($property->defaultValue === null ? 'null' : $property->defaultValue);
// TODO
if(!empty($property->signature))
return $property->signature;
$sig='';
if(!empty($property->getter))
$sig=$property->getter->signature;
if(!empty($property->setter))
{
if($sig!=='')
$sig.='<br/>';
$sig.=$property->setter->signature;
}
return $sig;
}
/**
* @param MethodDoc $method
* @return string
*/
public function renderMethodSignature($method)
{
$params = [];
foreach($method->params as $param) {
$params[] = (empty($param->typeHint) ? '' : $param->typeHint . ' ')
. ($param->isPassedByReference ? '<b>&</b>' : '')
. $param->name
. ($param->isOptional ? ' = ' . $param->defaultValue : '');
}
//<?php echo preg_replace('/\{\{([^\{\}]*?)\|([^\{\}]*?)\}\}\(/','$2(',$method->signature);
return ($method->isReturnByReference ? '<b>&</b>' : '')
. ($method->returnType === null ? 'void' : $this->typeLink($method->returnTypes))
. ' ' . $method->name . '( '
. implode(', ', $params)
. ' )';
}
public function generateFileName($typeName)
{
......
......@@ -25,6 +25,9 @@ class BaseDoc extends Object
public $deprecatedSince;
public $deprecatedReason;
/**
* @var \phpDocumentor\Reflection\DocBlock\Tag[]
*/
public $tags = [];
......
......@@ -33,13 +33,32 @@ class ClassDoc extends TypeDoc
/**
* @return EventDoc[]
*/
public function getNativeEvents()
{
$events = [];
foreach($this->events as $name => $event) {
if ($event->definedBy != $this->name) {
continue;
}
$events[$name] = $event;
}
return $events;
}
/**
* @param \phpDocumentor\Reflection\ClassReflector $reflector
* @param array $config
*/
public function __construct($reflector, $config = [])
public function __construct($reflector = null, $config = [])
{
parent::__construct($reflector, $config);
if ($reflector === null) {
return;
}
$this->parentClass = ltrim($reflector->getParentClass(), '\\');
if (empty($this->parentClass)) {
$this->parentClass = null;
......@@ -54,7 +73,8 @@ class ClassDoc extends TypeDoc
$this->traits[] = ltrim($trait, '\\');
}
foreach($reflector->getConstants() as $constantReflector) {
if (strncmp($constantReflector->getShortName(), 'EVENT_', 6) == 0) {
$docblock = $constantReflector->getDocBlock();
if ($docblock !== null && count($docblock->getTagsByName('event')) > 0) {
$event = new EventDoc($constantReflector);
$event->definedBy = $this->name;
$this->events[$event->name] = $event;
......
......@@ -10,4 +10,20 @@ namespace yii\apidoc\models;
class ConstDoc extends BaseDoc
{
public $definedBy;
public $value;
/**
* @param \phpDocumentor\Reflection\ClassReflector\ConstantReflector $reflector
* @param array $config
*/
public function __construct($reflector = null, $config = [])
{
parent::__construct($reflector, $config);
if ($reflector === null) {
return;
}
$this->value = $reflector->getValue();
}
}
\ No newline at end of file
......@@ -34,6 +34,7 @@ class Context extends Component
public function getType($type)
{
$type = ltrim($type, '\\');
if (isset($this->classes[$type])) {
return $this->classes[$type];
} elseif (isset($this->interfaces[$type])) {
......
......@@ -7,6 +7,39 @@
namespace yii\apidoc\models;
use phpDocumentor\Reflection\DocBlock\Tag\ParamTag;
use phpDocumentor\Reflection\DocBlock\Tag\ReturnTag;
class EventDoc extends ConstDoc
{
public $type;
public $types;
/**
* @param \phpDocumentor\Reflection\ClassReflector\ConstantReflector $reflector
* @param array $config
*/
public function __construct($reflector = null, $config = [])
{
parent::__construct($reflector, $config);
if ($reflector === null) {
return;
}
foreach($this->tags as $i => $tag) {
if ($tag->getName() == 'event') {
$eventTag = new ReturnTag('event', $tag->getContent(), $tag->getDocBlock(), $tag->getLocation());
$this->type = $eventTag->getType();
$this->types = $eventTag->getTypes();
$this->description = ucfirst($eventTag->getDescription());
if (($pos = strpos($this->description, '.')) !== false) {
$this->shortDescription = substr($this->description, 0, $pos);
} else {
$this->shortDescription = $this->description;
}
unset($this->tags[$i]);
}
}
}
}
\ No newline at end of file
......@@ -8,8 +8,10 @@
namespace yii\apidoc\models;
use phpDocumentor\Reflection\DocBlock\Tag\ParamTag;
use phpDocumentor\Reflection\DocBlock\Tag\PropertyTag;
use phpDocumentor\Reflection\DocBlock\Tag\ReturnTag;
use phpDocumentor\Reflection\DocBlock\Tag\ThrowsTag;
use yii\base\Exception;
class FunctionDoc extends BaseDoc
{
......@@ -27,10 +29,14 @@ class FunctionDoc extends BaseDoc
* @param \phpDocumentor\Reflection\FunctionReflector $reflector
* @param array $config
*/
public function __construct($reflector, $config = [])
public function __construct($reflector = null, $config = [])
{
parent::__construct($reflector, $config);
if ($reflector === null) {
return;
}
$this->isReturnByReference = $reflector->isByRef();
foreach($reflector->getArguments() as $arg) {
......@@ -39,19 +45,24 @@ class FunctionDoc extends BaseDoc
}
foreach($this->tags as $i => $tag) {
if ($tag instanceof ReturnTag) {
$this->returnType = $tag->getType();
$this->returnTypes = $tag->getTypes();
$this->return = $tag->getDescription();
if ($tag instanceof ThrowsTag) {
$this->exceptions[$tag->getType()] = $tag->getDescription();
unset($this->tags[$i]);
} elseif ($tag instanceof PropertyTag) {
// TODO handle property tag
} elseif ($tag instanceof ParamTag) {
$paramName = $tag->getVariableName();
if (!isset($this->params[$paramName])) {
echo 'undefined parameter documented: ' . $paramName . ' in ' . $this->name . "\n"; // todo add this to a log file
}
$this->params[$paramName]->description = $tag->getDescription();
$this->params[$paramName]->type = $tag->getType();
$this->params[$paramName]->types = $tag->getTypes();
unset($this->tags[$i]);
} elseif ($tag instanceof ThrowsTag) {
$this->exceptions[$tag->getType()] = $tag->getDescription();
} elseif ($tag instanceof ReturnTag) {
$this->returnType = $tag->getType();
$this->returnTypes = $tag->getTypes();
$this->return = $tag->getDescription();
unset($this->tags[$i]);
}
}
......
......@@ -18,10 +18,14 @@ class InterfaceDoc extends TypeDoc
* @param \phpDocumentor\Reflection\InterfaceReflector $reflector
* @param array $config
*/
public function __construct($reflector, $config = [])
public function __construct($reflector = null, $config = [])
{
parent::__construct($reflector, $config);
if ($reflector === null) {
return;
}
foreach($reflector->getParentInterfaces() as $interface) {
$this->parentInterfaces[] = ltrim($interface, '\\');
}
......
......@@ -23,10 +23,14 @@ class MethodDoc extends FunctionDoc
* @param \phpDocumentor\Reflection\ClassReflector\MethodReflector $reflector
* @param array $config
*/
public function __construct($reflector, $config = [])
public function __construct($reflector = null, $config = [])
{
parent::__construct($reflector, $config);
if ($reflector === null) {
return;
}
$this->isAbstract = $reflector->isAbstract();
$this->isFinal = $reflector->isFinal();
$this->isStatic = $reflector->isStatic();
......
......@@ -26,14 +26,18 @@ class ParamDoc extends Object
* @param \phpDocumentor\Reflection\FunctionReflector\ArgumentReflector $reflector
* @param array $config
*/
public function __construct($reflector, $config = [])
public function __construct($reflector = null, $config = [])
{
parent::__construct($config);
if ($reflector === null) {
return;
}
$this->name = $reflector->getName();
$this->typeHint = $reflector->getType();
$this->isOptional = $reflector->getDefault() !== null;
$this->defaultValue = $reflector->getDefault(); // TODO what about null value?
$this->defaultValue = $reflector->getDefault();
$this->isPassedByReference = $reflector->isByRef();
}
}
\ No newline at end of file
......@@ -56,8 +56,12 @@ class PropertyDoc extends BaseDoc
if ($tag instanceof VarTag) {
$this->type = $tag->getType();
$this->types = $tag->getTypes();
$this->description = $tag->getDescription();
// TODO set shortDescription
$this->description = ucfirst($tag->getDescription());
if (($pos = strpos($this->description, '.')) !== false) {
$this->shortDescription = substr($this->description, 0, $pos);
} else {
$this->shortDescription = $this->description;
}
}
}
}
......
......@@ -19,10 +19,14 @@ class TraitDoc extends TypeDoc
* @param \phpDocumentor\Reflection\TraitReflector $reflector
* @param array $config
*/
public function __construct($reflector, $config = [])
public function __construct($reflector = null, $config = [])
{
parent::__construct($reflector, $config);
if ($reflector === null) {
return;
}
foreach($reflector->getTraits() as $trait) {
$this->traits[] = ltrim($trait, '\\');
}
......
......@@ -9,6 +9,7 @@ namespace yii\apidoc\models;
use phpDocumentor\Reflection\DocBlock\Tag\AuthorTag;
use yii\base\Exception;
use yii\helpers\StringHelper;
class TypeDoc extends BaseDoc
{
......@@ -22,48 +23,95 @@ class TypeDoc extends BaseDoc
*/
public $properties = [];
public $namespace;
/**
* @return MethodDoc[]
*/
public function getNativeMethods()
{
return $this->getFilteredMethods(null, $this->name);
}
/**
* @return MethodDoc[]
*/
public function getPublicMethods()
{
return $this->getFilteredMethods('public');
}
/**
* @return MethodDoc[]
*/
public function getProtectedMethods()
{
return $this->getFilteredMethods('protected');
}
private function getFilteredMethods($visibility)
/**
* @param null $visibility
* @param null $definedBy
* @return MethodDoc[]
*/
private function getFilteredMethods($visibility = null, $definedBy = null)
{
$methods = [];
foreach($this->methods as $name => $method) {
if ($method->visibility == $visibility) {
$methods[$name] = $method;
if ($visibility !== null && $method->visibility != $visibility) {
continue;
}
if ($definedBy !== null && $method->definedBy != $definedBy) {
continue;
}
$methods[$name] = $method;
}
return $methods;
}
/**
* @return PropertyDoc[]
*/
public function getNativeProperties()
{
return $this->getFilteredProperties(null, $this->name);
}
/**
* @return PropertyDoc[]
*/
public function getPublicProperties()
{
return $this->getFilteredProperties('public');
}
/**
* @return PropertyDoc[]
*/
public function getProtectedProperties()
{
return $this->getFilteredProperties('protected');
}
private function getFilteredProperties($visibility)
/**
* @param null $visibility
* @param null $definedBy
* @return PropertyDoc[]
*/
private function getFilteredProperties($visibility = null, $definedBy = null)
{
if ($this->properties === null) {
return [];
}
$properties = [];
foreach($this->properties as $name => $property) {
if ($property->visibility == $visibility) {
$properties[$name] = $property;
if ($visibility !== null && $property->visibility != $visibility) {
continue;
}
if ($definedBy !== null && $property->definedBy != $definedBy) {
continue;
}
$properties[$name] = $property;
}
return $properties;
}
......@@ -72,10 +120,12 @@ class TypeDoc extends BaseDoc
* @param \phpDocumentor\Reflection\InterfaceReflector $reflector
* @param array $config
*/
public function __construct($reflector, $config = [])
public function __construct($reflector = null, $config = [])
{
parent::__construct($reflector, $config);
$this->namespace = StringHelper::basename($this->name);
if ($reflector === null) {
return;
}
......
......@@ -21,14 +21,15 @@ if (empty($type->constants)) {
<col class="col-defined" />
</colgroup>
<tr>
<th>Constant</th><th>Description</th><th>Defined By</th>
<th>Constant</th><th>Value</th><th>Description</th><th>Defined By</th>
</tr>
<?php foreach($type->constants as $constant): ?>
<tr<?= $constant->definedBy != $type->name ? ' class="inherited"' : '' ?> id="<?= $constant->name ?>">
<td><?= $this->context->subjectLink($constant) ?></td>
<td><?= $constant->shortDescription ?></td>
<tr<?= $constant->definedBy != $type->name ? ' class="inherited"' : '' ?> id="<?= $constant->name ?>">
<td><?= $constant->name ?></td>
<td><?= $constant->value ?></td>
<td><?= nl2br($constant->shortDescription . "\n" . $constant->description) ?></td>
<td><?= $this->context->typeLink($constant->definedBy) ?></td>
</tr>
</tr>
<?php endforeach; ?>
</table>
</div>
\ No newline at end of file
<?php
use yii\apidoc\models\ClassDoc;
/**
* @var ClassDoc $type
* @var yii\web\View $this
*/
$events = $type->getNativeEvents();
if (empty($events)) {
return;
} ?>
<h2>Event Details</h2>
<?php foreach($events as $event): ?>
<div class="detailHeader" id="<?= $event->name.'-detail' ?>">
<?php echo $event->name; ?>
<span class="detailHeaderTag">
event
<?php if(!empty($event->since)): ?>
(available since version <?= $event->since ?>)
<?php endif; ?>
</span>
</div>
<?php /*
<div class="signature">
<?php echo $event->trigger->signature; ?>
</div>*/ ?>
<p><?php echo $event->description; ?></p>
<?= $this->render('seeAlso', ['object' => $event]); ?>
<?php endforeach; ?>
......@@ -21,12 +21,18 @@ if (empty($type->events)) {
<col class="col-defined" />
</colgroup>
<tr>
<th>Event</th><th>Description</th><th>Defined By</th>
<th>Event</th><th>Type</th><th>Description</th><th>Defined By</th>
</tr>
<?php foreach($type->events as $event): ?>
<tr<?= $event->definedBy != $type->name ? ' class="inherited"' : '' ?> id="<?= $event->name ?>">
<td><?= $this->context->subjectLink($event) ?></td>
<td><?= $event->shortDescription ?></td>
<td><?= $this->context->typeLink($event->types) ?></td>
<td>
<?= $event->shortDescription ?>
<?php if(!empty($event->since)): ?>
(available since version <?php echo $event->since; ?>)
<?php endif; ?>
</td>
<td><?= $this->context->typeLink($event->definedBy) ?></td>
</tr>
<?php endforeach; ?>
......
<?php
use yii\apidoc\models\ClassDoc;
use yii\apidoc\models\TraitDoc;
/**
* @var ClassDoc|TraitDoc $type
* @var yii\web\View $this
*/
$methods = $type->getNativeMethods();
if (empty($methods)) {
return;
} ?>
<h2>Method Details</h2>
<?php foreach($methods as $method): ?>
<div class="detailHeader" id="<?= $method->name . '()-detail' ?>">
<?= $method->name ?>()
<span class="detailHeaderTag">
method
<?php if (!empty($method->since)): ?>
(available since version <?php echo $method->since; ?>)
<?php endif; ?>
</span>
</div>
<table class="summaryTable">
<tr><td colspan="3">
<div class="signature2">
<?= $this->context->renderMethodSignature($method) ?>
</div>
</td></tr>
<?php if(!empty($method->params) || !empty($method->return)): ?>
<?php foreach($method->params as $param): ?>
<tr>
<td class="paramNameCol"><?= $param->name ?></td>
<td class="paramTypeCol"><?= $this->context->typeLink($param->types) ?></td>
<td class="paramDescCol"><?= $param->description ?></td>
</tr>
<?php endforeach; ?>
<?php if(!empty($method->return)): ?>
<tr>
<td class="paramNameCol"><?= '{return}'; ?></td>
<td class="paramTypeCol"><?= $this->context->typeLink($method->returnTypes); ?></td>
<td class="paramDescCol"><?= $method->return; ?></td>
</tr>
<?php endif; ?>
<?php endif; ?>
</table>
<!-- --><?php //$this->renderPartial('sourceCode',array('object'=>$method)); ?>
<p><strong><?= $method->shortDescription ?></strong></p>
<p><?= nl2br($method->description) ?></p>
<?= $this->render('seeAlso', ['object' => $method]); ?>
<?php endforeach; ?>
\ No newline at end of file
......@@ -29,7 +29,7 @@ if ($protected && count($type->getProtectedMethods()) == 0 || !$protected && cou
</tr>
<?php foreach($type->methods as $method): ?>
<?php if($protected && $method->visibility == 'protected' || !$protected && $method->visibility != 'protected'): ?>
<tr<?= $method->definedBy != $type->name ? ' class="inherited"' : '' ?> id="<?= $method->name ?>">
<tr<?= $method->definedBy != $type->name ? ' class="inherited"' : '' ?> id="<?= $method->name ?>()">
<td><?= $this->context->subjectLink($method, $method->name.'()') ?></td>
<td><?= $method->shortDescription ?></td>
<td><?= $this->context->typeLink($method->definedBy) ?></td>
......
<?php
use yii\apidoc\models\ClassDoc;
use yii\apidoc\models\TraitDoc;
/**
* @var ClassDoc|TraitDoc $type
* @var yii\web\View $this
*/
$properties = $type->getNativeProperties();
if (empty($properties)) {
return;
} ?>
<h2>Property Details</h2>
<?php foreach($properties as $property): ?>
<div class="detailHeader" id="<?= $property->name.'-detail' ?>">
<?php echo $property->name; ?>
<span class="detailHeaderTag">
property
<?php if($property->getIsReadOnly()) echo ' <em>read-only</em> '; ?>
<?php if($property->getIsWriteOnly()) echo ' <em>write-only</em> '; ?>
<?php if(!empty($property->since)): ?>
(available since version <?php echo $property->since; ?>)
<?php endif; ?>
</span>
</div>
<div class="signature">
<?php echo $this->context->renderPropertySignature($property); ?>
</div>
<p><?= nl2br($property->description) ?></p>
<?= $this->render('seeAlso', ['object' => $property]); ?>
<?php endforeach; ?>
<?php
use yii\apidoc\models\ClassDoc;
use yii\apidoc\models\InterfaceDoc;
use yii\apidoc\models\TraitDoc;
/**
* @var ClassDoc|InterfaceDoc|TraitDoc $type
* @var ClassDoc|TraitDoc $type
* @var boolean $protected
* @var yii\web\View $this
*/
......
<?php
/**
* @var yii\apidoc\models\BaseDoc $object
* @var yii\web\View $this
*/
$see = [];
foreach($object->tags as $tag) {
/** @var $tag phpDocumentor\Reflection\DocBlock\Tag\SeeTag */
if (get_class($tag) == 'phpDocumentor\Reflection\DocBlock\Tag\SeeTag') {
$see[] = $tag->getReference();
}
}
if (empty($see)) {
return;
}
?>
<div class="SeeAlso">
<h4>See Also</h4>
<ul>
<?php foreach($see as $ref): ?>
<li><?= $ref ?></li>
<?php endforeach; ?>
</ul>
</div>
......@@ -94,5 +94,8 @@ $renderer = $this->context;
<a name="constants"></a>
<?= $this->render('constSummary', ['type' => $type]) ?>
<?php //$this->renderPartial('propertyDetails',array('type'=>$type)); ?>
<?php //$this->renderPartial('methodDetails',array('type'=>$type)); ?>
<?= $this->render('propertyDetails', ['type' => $type]) ?>
<?= $this->render('methodDetails', ['type' => $type]) ?>
<?php if($type instanceof ClassDoc): ?>
<?= $this->render('eventDetails', ['type' => $type]) ?>
<?php endif; ?>
......@@ -34,7 +34,7 @@ class Exception extends \Exception implements Arrayable
/**
* Returns the array representation of the exception and all previous exceptions recursively.
* @param \Exception exception object
* @param \Exception $exception object
* @return array the array representation of the exception.
*/
protected function toArrayRecursive($exception)
......
......@@ -138,7 +138,6 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface
* @param array $attributes attribute values (name-value pairs) to be saved into the table
* @param string|array $condition the conditions that will be put in the WHERE part of the UPDATE SQL.
* Please refer to [[Query::where()]] on how to specify this parameter.
* @param array $params the parameters (name => value) to be bound to the query.
* @return integer the number of rows updated
*/
public static function updateAll($attributes, $condition = '')
......@@ -379,7 +378,7 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface
* Populates the named relation with the related records.
* Note that this method does not check if the relation exists or not.
* @param string $name the relation name (case-sensitive)
* @param ActiveRecord|array|null the related records to be populated into the relation.
* @param ActiveRecord|array|null $records the related records to be populated into the relation.
*/
public function populateRelation($name, $records)
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment