From 63e726234c4c1c5aa65f7cf0b4868d222827d7de Mon Sep 17 00:00:00 2001 From: Carsten Brandt Date: Sun, 5 Jan 2014 03:19:02 +0100 Subject: [PATCH 01/17] early draft of api doc generator issue #62 --- extensions/yii/phpdoc/.gitignore | 2 + extensions/yii/phpdoc/CHANGELOG.md | 7 + extensions/yii/phpdoc/LICENSE.md | 32 +++ extensions/yii/phpdoc/README.md | 28 +++ extensions/yii/phpdoc/assets/css/api.css | 105 ++++++++++ extensions/yii/phpdoc/assets/css/style.css | 32 +++ .../yii/phpdoc/commands/PhpdocController.php | 89 +++++++++ .../yii/phpdoc/components/BaseRenderer.php | 38 ++++ .../yii/phpdoc/components/OfflineRenderer.php | 182 ++++++++++++++++++ extensions/yii/phpdoc/composer.json | 29 +++ extensions/yii/phpdoc/models/BaseDoc.php | 40 ++++ extensions/yii/phpdoc/models/ClassDoc.php | 75 ++++++++ extensions/yii/phpdoc/models/Context.php | 93 +++++++++ extensions/yii/phpdoc/models/EventDoc.php | 10 + extensions/yii/phpdoc/models/File.php | 48 +++++ extensions/yii/phpdoc/models/FunctionDoc.php | 10 + extensions/yii/phpdoc/models/InterfaceDoc.php | 45 +++++ extensions/yii/phpdoc/models/MethodDoc.php | 13 ++ extensions/yii/phpdoc/models/ParamDoc.php | 18 ++ extensions/yii/phpdoc/models/PropertyDoc.php | 23 +++ extensions/yii/phpdoc/models/TraitDoc.php | 49 +++++ extensions/yii/phpdoc/views/class.php | 49 +++++ extensions/yii/phpdoc/views/classSummary.php | 60 ++++++ extensions/yii/phpdoc/views/index.php | 30 +++ .../yii/phpdoc/views/layouts/offline.php | 64 ++++++ 25 files changed, 1171 insertions(+) create mode 100644 extensions/yii/phpdoc/.gitignore create mode 100644 extensions/yii/phpdoc/CHANGELOG.md create mode 100644 extensions/yii/phpdoc/LICENSE.md create mode 100644 extensions/yii/phpdoc/README.md create mode 100644 extensions/yii/phpdoc/assets/css/api.css create mode 100644 extensions/yii/phpdoc/assets/css/style.css create mode 100644 extensions/yii/phpdoc/commands/PhpdocController.php create mode 100644 extensions/yii/phpdoc/components/BaseRenderer.php create mode 100644 extensions/yii/phpdoc/components/OfflineRenderer.php create mode 100644 extensions/yii/phpdoc/composer.json create mode 100644 extensions/yii/phpdoc/models/BaseDoc.php create mode 100644 extensions/yii/phpdoc/models/ClassDoc.php create mode 100644 extensions/yii/phpdoc/models/Context.php create mode 100644 extensions/yii/phpdoc/models/EventDoc.php create mode 100644 extensions/yii/phpdoc/models/File.php create mode 100644 extensions/yii/phpdoc/models/FunctionDoc.php create mode 100644 extensions/yii/phpdoc/models/InterfaceDoc.php create mode 100644 extensions/yii/phpdoc/models/MethodDoc.php create mode 100644 extensions/yii/phpdoc/models/ParamDoc.php create mode 100644 extensions/yii/phpdoc/models/PropertyDoc.php create mode 100644 extensions/yii/phpdoc/models/TraitDoc.php create mode 100644 extensions/yii/phpdoc/views/class.php create mode 100644 extensions/yii/phpdoc/views/classSummary.php create mode 100644 extensions/yii/phpdoc/views/index.php create mode 100644 extensions/yii/phpdoc/views/layouts/offline.php diff --git a/extensions/yii/phpdoc/.gitignore b/extensions/yii/phpdoc/.gitignore new file mode 100644 index 00000000000..8b7ef350326 --- /dev/null +++ b/extensions/yii/phpdoc/.gitignore @@ -0,0 +1,2 @@ +/vendor +composer.lock diff --git a/extensions/yii/phpdoc/CHANGELOG.md b/extensions/yii/phpdoc/CHANGELOG.md new file mode 100644 index 00000000000..b02962136ed --- /dev/null +++ b/extensions/yii/phpdoc/CHANGELOG.md @@ -0,0 +1,7 @@ +Yii Framework 2 phpdoc extension Change Log +=========================================== + +2.0.0 beta under development +---------------------------- + +- Initial release. diff --git a/extensions/yii/phpdoc/LICENSE.md b/extensions/yii/phpdoc/LICENSE.md new file mode 100644 index 00000000000..e98f03df869 --- /dev/null +++ b/extensions/yii/phpdoc/LICENSE.md @@ -0,0 +1,32 @@ +The Yii framework is free software. It is released under the terms of +the following BSD License. + +Copyright © 2008 by Yii Software LLC (http://www.yiisoft.com) +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name of Yii Software LLC nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/extensions/yii/phpdoc/README.md b/extensions/yii/phpdoc/README.md new file mode 100644 index 00000000000..f0c80870066 --- /dev/null +++ b/extensions/yii/phpdoc/README.md @@ -0,0 +1,28 @@ +API documentation generator for Yii 2 +===================================== + +This extension provides an API documentation generator for the Yii framework 2.0. + +Installation +------------ + +The preferred way to install this extension is through [composer](http://getcomposer.org/download/). + +Either run + +``` +php composer.phar require yiisoft/yii2-phpdoc "*" +``` + +or add + +```json +"yiisoft/yii2-phpdoc": "*" +``` + +to the require section of your composer.json. + +Usage +----- + +TDB \ No newline at end of file diff --git a/extensions/yii/phpdoc/assets/css/api.css b/extensions/yii/phpdoc/assets/css/api.css new file mode 100644 index 00000000000..482c04f461b --- /dev/null +++ b/extensions/yii/phpdoc/assets/css/api.css @@ -0,0 +1,105 @@ +pre { + color: #000000; + background-color: #FFF5E6; + font-family: "courier new", "times new roman", monospace; + line-height: 1.3em; + /* Put a nice border around it. */ + padding: 1px; + width: 90%; + /* Don't wrap its contents, and show scrollbars. */ + /* white-space: nowrap;*/ + overflow: auto; + /* Stop after about 24 lines, and just show a scrollbar. */ + /* max-height: 24em; */ + margin: 5px; + padding-left: 20px; + border: 1px solid #FFE6BF; + border-left: 6px solid #FFE6BF; +} + +div.code { + display: none; + color: #000000; + background-color: #FFF5E6; + font-family: "courier new", "times new roman", monospace; + line-height: 1.3em; + /* Put a nice border around it. */ + padding: 1px; + width: 90%; + /* Don't wrap its contents, and show scrollbars. */ + /* white-space: nowrap;*/ + overflow: auto; + /* Stop after about 24 lines, and just show a scrollbar. */ + /* max-height: 24em; */ + margin: 5px; + padding-left: 20px; + border-left: 6px solid #FFE6BF; +} + +table.summaryTable { + background: #E6ECFF; + border-collapse: collapse; + width: 100%; +} + +table.summaryTable th, table.summaryTable td { + border: 1px #BFCFFF solid; + padding: 0.2em; +} + +table.summaryTable th { + background: #CCD9FF; + text-align: left; +} + +#nav { + padding: 3px; + margin: 0 0 10px 0; + border-top: 1px #BFCFFF solid; +} + +#classDescription { + padding: 5px; + margin: 10px 0 20px 0; + border-bottom: 1px solid #BFCFFF; +} + +.detailHeader { + font-weight: bold; + font-size: 12pt; + margin: 30px 0 5px 0; + border-bottom: 1px solid #BFCFFF; +} + +.detailHeaderTag { + font-weight: normal; + font-size: 10pt; +} + +.signature, .signature2 { + padding: 3px; + color: #000000; + font-family: "courier new", "times new roman", monospace; + line-height: 1.3em; +} + +.signature { + margin: 10px 0 10px 0; + background: #E6ECFF; + border: 1px #BFCFFF solid; +} + +.paramNameCol { + width: 12%; + font-weight: bold; +} + +.paramTypeCol { + width: 12%; +} + +.sourceCode { + margin: 5px 0; + padding:5px; + background:#FFF5E6; +} \ No newline at end of file diff --git a/extensions/yii/phpdoc/assets/css/style.css b/extensions/yii/phpdoc/assets/css/style.css new file mode 100644 index 00000000000..1ead51c76c7 --- /dev/null +++ b/extensions/yii/phpdoc/assets/css/style.css @@ -0,0 +1,32 @@ +body +{ +} + +body, div, span, p, input +{ + font-family: Verdana, sans-serif, Arial; + font-size: 10pt; + color: #333333; +} + +#apiPage { +} + +#apiHeader { + padding: 3px; + color: white; + background: #6078BF; + margin-bottom: 5px; + font-weight: bold; +} + +#apiHeader a { + color: white; +} + +#apiFooter { + margin-top: 5px; + padding: 3px; + border-top: 1px solid #BFCFFF; + text-align: center; +} diff --git a/extensions/yii/phpdoc/commands/PhpdocController.php b/extensions/yii/phpdoc/commands/PhpdocController.php new file mode 100644 index 00000000000..1bb3e321fc5 --- /dev/null +++ b/extensions/yii/phpdoc/commands/PhpdocController.php @@ -0,0 +1,89 @@ + + * @author Qiang Xue + * @since 2.0 + */ +class PhpdocController extends Controller +{ + public function actionIndex($targetDir) + { + echo "hi\n"; + + $targetDir = Yii::getAlias($targetDir); + if (is_dir($targetDir) && !$this->confirm('TargetDirectory already exists. Overwrite?')) { + return 2; + } + + // TODO determine files to analyze + $this->stdout('Searching files to process... '); + $files = $this->findFiles(YII_PATH); +// $files = array_slice($files, 0, 42); // TODO remove this line + $this->stdout('done.' . PHP_EOL, Console::FG_GREEN); + + $fileCount = count($files); + Console::startProgress(0, $fileCount, 'Processing files... ', false); + $context = new Context(); + $done = 0; + foreach($files as $file) { + $context->addFile($file); + Console::updateProgress(++$done, $fileCount); + } + Console::endProgress(true); + $this->stdout('done.' . PHP_EOL, Console::FG_GREEN); + + $this->stdout('Updating cross references and backlinks... '); + $context->updateReferences(); + $this->stdout('done.' . PHP_EOL, Console::FG_GREEN); + + + // TODO LATER analyze for dead links and similar stuff + + // TODO render models + $renderer = new OfflineRenderer(); + $renderer->targetDir = $targetDir; + $renderer->render($context, $this); + } + + + protected function findFiles($path, $except = []) + { + $path = FileHelper::normalizePath($path); + $options = [ + 'filter' => function ($path) { + if (is_file($path)) { + $file = basename($path); + if ($file[0] < 'A' || $file[0] > 'Z') { + return false; + } + } + return null; + }, + 'only' => ['.php'], + 'except' => array_merge($except, [ + '/views/', + '/requirements/', + '/gii/generators/', + ]), + ]; + return FileHelper::findFiles($path, $options); + } + +} \ No newline at end of file diff --git a/extensions/yii/phpdoc/components/BaseRenderer.php b/extensions/yii/phpdoc/components/BaseRenderer.php new file mode 100644 index 00000000000..86e93b2011b --- /dev/null +++ b/extensions/yii/phpdoc/components/BaseRenderer.php @@ -0,0 +1,38 @@ + + */ + +namespace yii\phpdoc\components; + + +use Yii; +use yii\base\Component; +use yii\console\Controller; +use yii\phpdoc\models\Context; +use yii\web\View; + +abstract class BaseRenderer extends Component +{ + + private $_view; + + + public function getView() + { + if ($this->_view === null) { + $this->_view = new View(); + } + return $this->_view; + } + + /** + * @param Context $context + * @param Controller $controller + * @return mixed + */ + public abstract function render($context, $controller); + +} \ No newline at end of file diff --git a/extensions/yii/phpdoc/components/OfflineRenderer.php b/extensions/yii/phpdoc/components/OfflineRenderer.php new file mode 100644 index 00000000000..1d02de0876e --- /dev/null +++ b/extensions/yii/phpdoc/components/OfflineRenderer.php @@ -0,0 +1,182 @@ + + */ + +namespace yii\phpdoc\components; + + +use yii\base\ViewContextInterface; +use yii\console\Controller; +use yii\helpers\Console; +use yii\helpers\FileHelper; +use yii\helpers\Html; +use yii\phpdoc\models\ClassDoc; +use yii\phpdoc\models\Context; +use Yii; +use yii\phpdoc\models\InterfaceDoc; +use yii\phpdoc\models\TraitDoc; + +class OfflineRenderer extends BaseRenderer implements ViewContextInterface +{ + public $targetDir; + + public $layout = '@yii/phpdoc/views/layouts/offline.php'; + public $itemView = '@yii/phpdoc/views/class.php'; + public $indexView = '@yii/phpdoc/views/index.php'; + + public $pageTitle = 'Yii Framework 2.0 API Documentation'; + + /** + * @var Context + */ + protected $context; + + /** + * @param Context $context + * @param Controller $controller + */ + public function render($context, $controller) + { + $this->context = $context; + $dir = Yii::getAlias($this->targetDir); + if (!is_dir($dir)) { + mkdir($dir); + } + + $items = array_merge($context->classes, $context->interfaces, $context->traits); + $itemCount = count($items) + 1; + Console::startProgress(0, $itemCount, 'Rendering files: ', false); + $done = 0; + foreach($items as $item) { + $fileContent = $this->renderWithLayout($this->itemView, [ + 'item' => $item, + 'docContext' => $context, + ]); + file_put_contents($dir . '/' . $this->generateFileName($item->name), $fileContent); + Console::updateProgress(++$done, $itemCount); + } + $indexFileContent = $this->renderWithLayout($this->indexView, [ + 'docContext' => $context, + 'items' => $items, + ]); + file_put_contents($dir . '/index.html', $indexFileContent); + Console::updateProgress(++$done, $itemCount); + Console::endProgress(true); + $controller->stdout('done.' . PHP_EOL, Console::FG_GREEN); + + $controller->stdout('Copying asset files... '); + FileHelper::copyDirectory(__DIR__ . '/../assets/css', $dir . '/css'); + $controller->stdout('done.' . PHP_EOL, Console::FG_GREEN); + + } + + protected function renderWithLayout($viewFile, $params) + { + $output = $this->getView()->render($viewFile, $params, $this); + if ($this->layout !== false) { + $params['content'] = $output; + return $this->getView()->renderFile($this->layout, $params, $this); + } else { + return $output; + } + } + + /** + * creates a link to an item + * @param ClassDoc|InterfaceDoc|TraitDoc $item + * @param string $title + * @return string + */ + public function link($item, $title = null) + { + if ($title === null) { + $title = $item->name; + } + return Html::a($title, null, ['href' => $this->generateFileName($item->name)]); + } + + /** + * @param ClassDoc $class + * @return string + */ + public function renderInheritance($class) + { + $parents[] = $this->link($class); + while ($class->parentClass !== null) { + if(isset($this->context->classes[$class->parentClass])) { + $class = $this->context->classes[$class->parentClass]; + $parents[] = $this->link($class); + } else { + $parents[] = $class->parentClass; // TODO link to php.net + break; + } + } + return implode(" »\n",$parents); + } + + /** + * @param ClassDoc $class + * @return string + */ + public function renderImplements($class) + { + $interfaces = []; + foreach($class->interfaces as $interface) { + if(isset($this->context->interfaces[$interface])) { + $interfaces[] = $this->link($this->context->interfaces[$interface]); + } else { + $interfaces[] = $interface; // TODO link to php.net + } + } + return implode(', ',$interfaces); + } + + /** + * @param ClassDoc|TraitDoc $class + * @return string + */ + public function renderTraitUses($class) + { + $traits = []; + foreach($class->traits as $trait) { + if(isset($this->context->traits[$trait])) { + $traits[] = $this->link($this->context->traits[$trait]); + } else { + $traits[] = $trait; // TODO link to php.net + } + } + return implode(', ',$traits); + } + + public function renderSubclasses($class) + { + $subclasses = []; + foreach($class->subclasses as $subclass) { + if(isset($this->context->classes[$subclass])) { + $subclasses[] = $this->link($this->context->classes[$subclass]); + } else { + $subclasses[] = $subclass; // TODO link to php.net + } + } + return implode(', ',$subclasses); + } + + + public function generateFileName($itemName) + { + return strtolower(str_replace('\\', '_', $itemName)) . '.html'; + } + + /** + * Finds the view file corresponding to the specified relative view name. + * @param string $view a relative view name. The name does NOT start with a slash. + * @return string the view file path. Note that the file may not exist. + */ + public function findViewFile($view) + { + return Yii::getAlias('@yii/phpdoc/views/' . $view); + } +} \ No newline at end of file diff --git a/extensions/yii/phpdoc/composer.json b/extensions/yii/phpdoc/composer.json new file mode 100644 index 00000000000..7fa2ddec397 --- /dev/null +++ b/extensions/yii/phpdoc/composer.json @@ -0,0 +1,29 @@ +{ + "name": "yiisoft/yii2-phpdoc", + "description": "PHP Documentation generator for the Yii framework 2.0", + "keywords": ["yii", "phpdoc", "api", "documentation"], + "type": "yii2-extension", + "license": "BSD-3-Clause", + "support": { + "issues": "https://github.com/yiisoft/yii2/issues?labels=ext%3Aredis", + "forum": "http://www.yiiframework.com/forum/", + "wiki": "http://www.yiiframework.com/wiki/", + "irc": "irc://irc.freenode.net/yii", + "source": "https://github.com/yiisoft/yii2" + }, + "authors": [ + { + "name": "Carsten Brandt", + "email": "mail@cebe.cc" + } + ], + "minimum-stability": "dev", + "require": { + "yiisoft/yii2": "*", + "phpdocumentor/reflection": "1.0.2" + }, + "autoload": { + "psr-0": { "yii\\redis\\": "" } + }, + "target-dir": "yii/redis" +} diff --git a/extensions/yii/phpdoc/models/BaseDoc.php b/extensions/yii/phpdoc/models/BaseDoc.php new file mode 100644 index 00000000000..cbdf2701452 --- /dev/null +++ b/extensions/yii/phpdoc/models/BaseDoc.php @@ -0,0 +1,40 @@ +sourcePath=str_replace('\\','/',str_replace(YII_PATH,'',$reflection->getFileName())); + $this->startLine=$reflection->getStartLine(); + $this->endLine=$reflection->getEndLine(); + } + + public function getSourceUrl($baseUrl,$line=null) + { + if($line===null) + return $baseUrl.$this->sourcePath; + else + return $baseUrl.$this->sourcePath.'#'.$line; + } + + public function getSourceCode() + { + $lines=file(YII_PATH.$this->sourcePath); + return implode("",array_slice($lines,$this->startLine-1,$this->endLine-$this->startLine+1)); + } +} \ No newline at end of file diff --git a/extensions/yii/phpdoc/models/ClassDoc.php b/extensions/yii/phpdoc/models/ClassDoc.php new file mode 100644 index 00000000000..dd51bb5dab7 --- /dev/null +++ b/extensions/yii/phpdoc/models/ClassDoc.php @@ -0,0 +1,75 @@ +name = ltrim($reflector->getName(), '\\'); + $this->startLine = $reflector->getNode()->getAttribute('startLine'); + $this->endLine = $reflector->getNode()->getAttribute('endLine'); + + $this->parentClass = ltrim($reflector->getParentClass(), '\\'); + if (empty($this->parentClass)) { + $this->parentClass = null; + } + $this->isAbstract = $reflector->isAbstract(); + $this->isFinal = $reflector->isFinal(); + + foreach($reflector->getInterfaces() as $interface) { + $this->interfaces[] = ltrim($interface, '\\'); + } + foreach($reflector->getTraits() as $trait) { + $this->traits[] = ltrim($trait, '\\'); + } + + // TODO methods + + // TODO properties + + // TODO docblock + + if ($context !== null) { + $context->addClass($this); + } + + parent::__construct($config); + } +} \ No newline at end of file diff --git a/extensions/yii/phpdoc/models/Context.php b/extensions/yii/phpdoc/models/Context.php new file mode 100644 index 00000000000..78d455d7432 --- /dev/null +++ b/extensions/yii/phpdoc/models/Context.php @@ -0,0 +1,93 @@ + + */ + +namespace yii\phpdoc\models; + + +use yii\base\Component; +use yii\base\Exception; + +class Context extends Component +{ + public $basePath; + + public $files = []; + + /** + * @var ClassDoc[] + */ + public $classes = []; + /** + * @var InterfaceDoc[] + */ + public $interfaces = []; + /** + * @var TraitDoc[] + */ + public $traits = []; + + public function addFile($fileName) + { + $file = new File($fileName, $this); + $this->files[$fileName] = $file; + } + + public function addClass($class) + { + if (isset($this->classes[$class->name])) { + throw new Exception('Duplicate class definition: ' . $class->name . ' in file ' . $class->fileName); + } + $this->classes[$class->name] = $class; + } + + public function addInterface($interface) + { + if (isset($this->interfaces[$interface->name])) { + throw new Exception('Duplicate interface definition: ' . $interface->name . ' in file ' . $interface->fileName); + } + $this->interfaces[$interface->name] = $interface; + } + + public function addTrait($trait) + { + if (isset($this->traits[$trait->name])) { + throw new Exception('Duplicate trait definition: ' . $trait->name . ' in file ' . $trait->fileName); + } + $this->traits[$trait->name] = $trait; + } + + public function updateReferences() + { + // update all subclass references + foreach($this->classes as $class) { + $className = $class->name; + while (isset($this->classes[$class->parentClass])) { + $class = $this->classes[$class->parentClass]; + $class->subclasses[] = $className; + } + } + // update interfaces of subclasses + foreach($this->classes as $class) { + $this->updateSubclassInferfacesTraits($class); + } + // TODO update interface and trait usages + } + + /** + * Add implemented interfaces and used traits to subclasses + * @param ClassDoc $class + */ + protected function updateSubclassInferfacesTraits($class) + { + foreach($class->subclasses as $subclass) { + $subclass = $this->classes[$subclass]; + $subclass->interfaces = array_unique(array_merge($subclass->interfaces, $class->interfaces)); + $subclass->traits = array_unique(array_merge($subclass->traits, $class->traits)); + $this->updateSubclassInferfacesTraits($subclass); + } + } +} \ No newline at end of file diff --git a/extensions/yii/phpdoc/models/EventDoc.php b/extensions/yii/phpdoc/models/EventDoc.php new file mode 100644 index 00000000000..2ce7ad1e8c3 --- /dev/null +++ b/extensions/yii/phpdoc/models/EventDoc.php @@ -0,0 +1,10 @@ +name = $fileName; + $this->_reflection = new FileReflector($fileName, true); + $this->_reflection->process(); + + foreach($this->_reflection->getClasses() as $class) { + $class = new ClassDoc($class, $context); + $class->sourceFile = $fileName; + $this->classes[] = $class; + } + foreach($this->_reflection->getInterfaces() as $interface) { + $this->interfaces[] = new InterfaceDoc($interface, $context); + } + foreach($this->_reflection->getTraits() as $trait) { + $this->traits[] = new TraitDoc($trait, $context); + } + + parent::__construct($config); + } +} \ No newline at end of file diff --git a/extensions/yii/phpdoc/models/FunctionDoc.php b/extensions/yii/phpdoc/models/FunctionDoc.php new file mode 100644 index 00000000000..add2a00d747 --- /dev/null +++ b/extensions/yii/phpdoc/models/FunctionDoc.php @@ -0,0 +1,10 @@ + + */ + +namespace yii\phpdoc\models; + +class InterfaceDoc extends BaseDoc +{ + public $parentInterfaces = []; + + public $implementedBy = []; + + public $methods = []; + + /** + * @param \phpDocumentor\Reflection\InterfaceReflector $reflector + * @param Context $context + * @param array $config + */ + public function __construct($reflector, $context = null, $config = []) + { + // base properties + $this->name = ltrim($reflector->getName(), '\\'); + $this->startLine = $reflector->getNode()->getAttribute('startLine'); + $this->endLine = $reflector->getNode()->getAttribute('endLine'); + + foreach($reflector->getParentInterfaces() as $interface) { + $this->parentInterfaces[] = ltrim($interface, '\\'); + } + + // TODO methods + + // TODO docblock + + if ($context !== null) { + $context->addInterface($this); + } + + parent::__construct($config); + } + +} \ No newline at end of file diff --git a/extensions/yii/phpdoc/models/MethodDoc.php b/extensions/yii/phpdoc/models/MethodDoc.php new file mode 100644 index 00000000000..be29aeaeba2 --- /dev/null +++ b/extensions/yii/phpdoc/models/MethodDoc.php @@ -0,0 +1,13 @@ + + */ + +namespace yii\phpdoc\models; + +class ParamDoc +{ + public $name; + public $description; + public $type; + public $isOptional; + public $defaultValue; + public $isPassedByReference; +} \ No newline at end of file diff --git a/extensions/yii/phpdoc/models/PropertyDoc.php b/extensions/yii/phpdoc/models/PropertyDoc.php new file mode 100644 index 00000000000..8ac0287fbb5 --- /dev/null +++ b/extensions/yii/phpdoc/models/PropertyDoc.php @@ -0,0 +1,23 @@ + + */ + +namespace yii\phpdoc\models; + +class PropertyDoc extends BaseDoc +{ + public $isProtected; + public $isStatic; + public $readOnly; + public $isInherited; + public $definedBy; + + public $type; + public $signature; + + public $getter; + public $setter; +} \ No newline at end of file diff --git a/extensions/yii/phpdoc/models/TraitDoc.php b/extensions/yii/phpdoc/models/TraitDoc.php new file mode 100644 index 00000000000..7fc6e5a95d4 --- /dev/null +++ b/extensions/yii/phpdoc/models/TraitDoc.php @@ -0,0 +1,49 @@ + + */ + +namespace yii\phpdoc\models; + +class TraitDoc extends BaseDoc +{ + // classes using the trait + public $usedByClasses = []; + + public $traits = []; + + public $properties = []; + public $methods = []; + + + /** + * @param \phpDocumentor\Reflection\TraitReflector $reflector + * @param Context $context + * @param array $config + */ + public function __construct($reflector, $context = null, $config = []) + { + // base properties + $this->name = ltrim($reflector->getName(), '\\'); + $this->startLine = $reflector->getNode()->getAttribute('startLine'); + $this->endLine = $reflector->getNode()->getAttribute('endLine'); + + foreach($reflector->getTraits() as $trait) { + $this->traits[] = ltrim($trait, '\\'); + } + + // TODO methods + + // TODO properties + + // TODO docblock + + if ($context !== null) { + $context->addTrait($this); + } + + parent::__construct($config); + } +} \ No newline at end of file diff --git a/extensions/yii/phpdoc/views/class.php b/extensions/yii/phpdoc/views/class.php new file mode 100644 index 00000000000..0af8987e37c --- /dev/null +++ b/extensions/yii/phpdoc/views/class.php @@ -0,0 +1,49 @@ + +

name; +?>

+ + +render('classSummary', ['item' => $item]); ?> + + +renderPartial('propertySummary',array('class'=>$item,'protected'=>false)); ?> +renderPartial('propertySummary',array('class'=>$item,'protected'=>true)); ?> + + +renderPartial('methodSummary',array('class'=>$item,'protected'=>false)); ?> +renderPartial('methodSummary',array('class'=>$item,'protected'=>true)); ?> + + +renderPartial('eventSummary',array('class'=>$item)); ?> + +renderPartial('propertyDetails',array('class'=>$item)); ?> +renderPartial('methodDetails',array('class'=>$item)); ?> diff --git a/extensions/yii/phpdoc/views/classSummary.php b/extensions/yii/phpdoc/views/classSummary.php new file mode 100644 index 00000000000..ca84167a75c --- /dev/null +++ b/extensions/yii/phpdoc/views/classSummary.php @@ -0,0 +1,60 @@ + ++ + + + + + + + + +interfaces)): ?> + + + + + +traits)): ?> + + + + + +subclasses)): ?> + + + + + +since)): ?> + + + + + +version)): ?> + + + + + + + +renderSourceLink($item->sourcePath); ?> + +
Inheritancecontext->renderInheritance($item); ?>
Implementscontext->renderImplements($item); ?>
Uses Traitscontext->renderTraitUses($item); ?>
Subclassescontext->renderSubclasses($item); ?>
Sincesince; ?>
Versionversion; ?>
Source Code
+ +
+description; ?> +
\ No newline at end of file diff --git a/extensions/yii/phpdoc/views/index.php b/extensions/yii/phpdoc/views/index.php new file mode 100644 index 00000000000..1e81798720c --- /dev/null +++ b/extensions/yii/phpdoc/views/index.php @@ -0,0 +1,30 @@ +

Class Reference

+ + ++ + + + + + + +$class): ?> + + + + + +
ClassDescription
context->link($class, $class->name); ?>shortDescription; ?>
diff --git a/extensions/yii/phpdoc/views/layouts/offline.php b/extensions/yii/phpdoc/views/layouts/offline.php new file mode 100644 index 00000000000..809de752b0c --- /dev/null +++ b/extensions/yii/phpdoc/views/layouts/offline.php @@ -0,0 +1,64 @@ +beginPage(); +?> + + + + + + + + +head(); ?> +<?php echo $this->context->pageTitle; ?> + + + +beginBody(); ?> +
+ +
+Yii Framework v Class Reference +
+ +
+ +
+ +
+© 2008-2013 by Yii Software LLC
+All Rights Reserved.
+
+ + + +
+endBody(); ?> + + +endPage(); ?> \ No newline at end of file From b17c827067fa07e2bd787afb7b769a2322e88798 Mon Sep 17 00:00:00 2001 From: Carsten Brandt Date: Sun, 5 Jan 2014 04:38:30 +0100 Subject: [PATCH 02/17] renamed phpdoc extension to apidoc --- extensions/yii/{phpdoc => apidoc}/.gitignore | 0 extensions/yii/{phpdoc => apidoc}/CHANGELOG.md | 2 +- extensions/yii/{phpdoc => apidoc}/LICENSE.md | 0 extensions/yii/{phpdoc => apidoc}/README.md | 4 ++-- .../yii/{phpdoc => apidoc}/assets/css/api.css | 0 .../{phpdoc => apidoc}/assets/css/style.css | 2 +- .../commands/PhpdocController.php | 7 +++---- .../components/BaseRenderer.php | 11 +++++------ .../components/OfflineRenderer.php | 16 ++++++++-------- .../yii/{phpdoc => apidoc}/composer.json | 12 ++++++------ .../yii/{phpdoc => apidoc}/models/BaseDoc.php | 7 ++++++- .../yii/{phpdoc => apidoc}/models/ClassDoc.php | 7 ++++++- .../yii/{phpdoc => apidoc}/models/Context.php | 8 ++++---- extensions/yii/apidoc/models/EventDoc.php | 15 +++++++++++++++ .../yii/{phpdoc => apidoc}/models/File.php | 7 ++++++- extensions/yii/apidoc/models/FunctionDoc.php | 15 +++++++++++++++ .../{phpdoc => apidoc}/models/InterfaceDoc.php | 8 ++++---- extensions/yii/apidoc/models/MethodDoc.php | 18 ++++++++++++++++++ extensions/yii/apidoc/models/ParamDoc.php | 18 ++++++++++++++++++ .../{phpdoc => apidoc}/models/PropertyDoc.php | 8 ++++---- .../yii/{phpdoc => apidoc}/models/TraitDoc.php | 8 ++++---- .../yii/{phpdoc => apidoc}/views/class.php | 6 +++--- .../{phpdoc => apidoc}/views/classSummary.php | 6 +++--- .../yii/{phpdoc => apidoc}/views/index.php | 6 +++--- .../views/layouts/offline.php | 0 extensions/yii/phpdoc/models/EventDoc.php | 10 ---------- extensions/yii/phpdoc/models/FunctionDoc.php | 10 ---------- extensions/yii/phpdoc/models/MethodDoc.php | 13 ------------- extensions/yii/phpdoc/models/ParamDoc.php | 18 ------------------ 29 files changed, 135 insertions(+), 107 deletions(-) rename extensions/yii/{phpdoc => apidoc}/.gitignore (100%) rename extensions/yii/{phpdoc => apidoc}/CHANGELOG.md (73%) rename extensions/yii/{phpdoc => apidoc}/LICENSE.md (100%) rename extensions/yii/{phpdoc => apidoc}/README.md (83%) rename extensions/yii/{phpdoc => apidoc}/assets/css/api.css (100%) rename extensions/yii/{phpdoc => apidoc}/assets/css/style.css (88%) rename extensions/yii/{phpdoc => apidoc}/commands/PhpdocController.php (93%) rename extensions/yii/{phpdoc => apidoc}/components/BaseRenderer.php (68%) rename extensions/yii/{phpdoc => apidoc}/components/OfflineRenderer.php (93%) rename extensions/yii/{phpdoc => apidoc}/composer.json (69%) rename extensions/yii/{phpdoc => apidoc}/models/BaseDoc.php (81%) rename extensions/yii/{phpdoc => apidoc}/models/ClassDoc.php (89%) rename extensions/yii/{phpdoc => apidoc}/models/Context.php (92%) create mode 100644 extensions/yii/apidoc/models/EventDoc.php rename extensions/yii/{phpdoc => apidoc}/models/File.php (84%) create mode 100644 extensions/yii/apidoc/models/FunctionDoc.php rename extensions/yii/{phpdoc => apidoc}/models/InterfaceDoc.php (83%) create mode 100644 extensions/yii/apidoc/models/MethodDoc.php create mode 100644 extensions/yii/apidoc/models/ParamDoc.php rename extensions/yii/{phpdoc => apidoc}/models/PropertyDoc.php (57%) rename extensions/yii/{phpdoc => apidoc}/models/TraitDoc.php (83%) rename extensions/yii/{phpdoc => apidoc}/views/class.php (93%) rename extensions/yii/{phpdoc => apidoc}/views/classSummary.php (92%) rename extensions/yii/{phpdoc => apidoc}/views/index.php (84%) rename extensions/yii/{phpdoc => apidoc}/views/layouts/offline.php (100%) delete mode 100644 extensions/yii/phpdoc/models/EventDoc.php delete mode 100644 extensions/yii/phpdoc/models/FunctionDoc.php delete mode 100644 extensions/yii/phpdoc/models/MethodDoc.php delete mode 100644 extensions/yii/phpdoc/models/ParamDoc.php diff --git a/extensions/yii/phpdoc/.gitignore b/extensions/yii/apidoc/.gitignore similarity index 100% rename from extensions/yii/phpdoc/.gitignore rename to extensions/yii/apidoc/.gitignore diff --git a/extensions/yii/phpdoc/CHANGELOG.md b/extensions/yii/apidoc/CHANGELOG.md similarity index 73% rename from extensions/yii/phpdoc/CHANGELOG.md rename to extensions/yii/apidoc/CHANGELOG.md index b02962136ed..16875d20abe 100644 --- a/extensions/yii/phpdoc/CHANGELOG.md +++ b/extensions/yii/apidoc/CHANGELOG.md @@ -1,4 +1,4 @@ -Yii Framework 2 phpdoc extension Change Log +Yii Framework 2 apidoc extension Change Log =========================================== 2.0.0 beta under development diff --git a/extensions/yii/phpdoc/LICENSE.md b/extensions/yii/apidoc/LICENSE.md similarity index 100% rename from extensions/yii/phpdoc/LICENSE.md rename to extensions/yii/apidoc/LICENSE.md diff --git a/extensions/yii/phpdoc/README.md b/extensions/yii/apidoc/README.md similarity index 83% rename from extensions/yii/phpdoc/README.md rename to extensions/yii/apidoc/README.md index f0c80870066..b733d7dba9d 100644 --- a/extensions/yii/phpdoc/README.md +++ b/extensions/yii/apidoc/README.md @@ -11,13 +11,13 @@ The preferred way to install this extension is through [composer](http://getcomp Either run ``` -php composer.phar require yiisoft/yii2-phpdoc "*" +php composer.phar require yiisoft/yii2-apidoc "*" ``` or add ```json -"yiisoft/yii2-phpdoc": "*" +"yiisoft/yii2-apidoc": "*" ``` to the require section of your composer.json. diff --git a/extensions/yii/phpdoc/assets/css/api.css b/extensions/yii/apidoc/assets/css/api.css similarity index 100% rename from extensions/yii/phpdoc/assets/css/api.css rename to extensions/yii/apidoc/assets/css/api.css diff --git a/extensions/yii/phpdoc/assets/css/style.css b/extensions/yii/apidoc/assets/css/style.css similarity index 88% rename from extensions/yii/phpdoc/assets/css/style.css rename to extensions/yii/apidoc/assets/css/style.css index 1ead51c76c7..009c2185072 100644 --- a/extensions/yii/phpdoc/assets/css/style.css +++ b/extensions/yii/apidoc/assets/css/style.css @@ -4,7 +4,7 @@ body body, div, span, p, input { - font-family: Verdana, sans-serif, Arial; + font-family: Verdana, Arial, sans-serif; font-size: 10pt; color: #333333; } diff --git a/extensions/yii/phpdoc/commands/PhpdocController.php b/extensions/yii/apidoc/commands/PhpdocController.php similarity index 93% rename from extensions/yii/phpdoc/commands/PhpdocController.php rename to extensions/yii/apidoc/commands/PhpdocController.php index 1bb3e321fc5..9236580db45 100644 --- a/extensions/yii/phpdoc/commands/PhpdocController.php +++ b/extensions/yii/apidoc/commands/PhpdocController.php @@ -5,20 +5,19 @@ * @license http://www.yiiframework.com/license/ */ -namespace yii\phpdoc\commands; +namespace yii\apidoc\commands; use phpDocumentor\Reflection\FileReflector; use yii\console\Controller; use yii\helpers\Console; use yii\helpers\FileHelper; -use yii\phpdoc\components\OfflineRenderer; -use yii\phpdoc\models\Context; +use yii\apidoc\components\OfflineRenderer; +use yii\apidoc\models\Context; use Yii; /** * * @author Carsten Brandt - * @author Qiang Xue * @since 2.0 */ class PhpdocController extends Controller diff --git a/extensions/yii/phpdoc/components/BaseRenderer.php b/extensions/yii/apidoc/components/BaseRenderer.php similarity index 68% rename from extensions/yii/phpdoc/components/BaseRenderer.php rename to extensions/yii/apidoc/components/BaseRenderer.php index 86e93b2011b..5b8fb693bab 100644 --- a/extensions/yii/phpdoc/components/BaseRenderer.php +++ b/extensions/yii/apidoc/components/BaseRenderer.php @@ -1,17 +1,16 @@ + * @link http://www.yiiframework.com/ + * @copyright Copyright (c) 2008 Yii Software LLC + * @license http://www.yiiframework.com/license/ */ -namespace yii\phpdoc\components; - +namespace yii\apidoc\components; use Yii; use yii\base\Component; use yii\console\Controller; -use yii\phpdoc\models\Context; +use yii\apidoc\models\Context; use yii\web\View; abstract class BaseRenderer extends Component diff --git a/extensions/yii/phpdoc/components/OfflineRenderer.php b/extensions/yii/apidoc/components/OfflineRenderer.php similarity index 93% rename from extensions/yii/phpdoc/components/OfflineRenderer.php rename to extensions/yii/apidoc/components/OfflineRenderer.php index 1d02de0876e..0c3d2dd7fe3 100644 --- a/extensions/yii/phpdoc/components/OfflineRenderer.php +++ b/extensions/yii/apidoc/components/OfflineRenderer.php @@ -1,11 +1,11 @@ + * @link http://www.yiiframework.com/ + * @copyright Copyright (c) 2008 Yii Software LLC + * @license http://www.yiiframework.com/license/ */ -namespace yii\phpdoc\components; +namespace yii\apidoc\components; use yii\base\ViewContextInterface; @@ -13,11 +13,11 @@ use yii\helpers\Console; use yii\helpers\FileHelper; use yii\helpers\Html; -use yii\phpdoc\models\ClassDoc; -use yii\phpdoc\models\Context; +use yii\apidoc\models\ClassDoc; +use yii\apidoc\models\Context; use Yii; -use yii\phpdoc\models\InterfaceDoc; -use yii\phpdoc\models\TraitDoc; +use yii\apidoc\models\InterfaceDoc; +use yii\apidoc\models\TraitDoc; class OfflineRenderer extends BaseRenderer implements ViewContextInterface { diff --git a/extensions/yii/phpdoc/composer.json b/extensions/yii/apidoc/composer.json similarity index 69% rename from extensions/yii/phpdoc/composer.json rename to extensions/yii/apidoc/composer.json index 7fa2ddec397..30608a1cbff 100644 --- a/extensions/yii/phpdoc/composer.json +++ b/extensions/yii/apidoc/composer.json @@ -1,11 +1,11 @@ { - "name": "yiisoft/yii2-phpdoc", - "description": "PHP Documentation generator for the Yii framework 2.0", - "keywords": ["yii", "phpdoc", "api", "documentation"], + "name": "yiisoft/yii2-apidoc", + "description": "API Documentation generator for the Yii framework 2.0", + "keywords": ["yii", "phpdoc", "apidoc", "api", "documentation"], "type": "yii2-extension", "license": "BSD-3-Clause", "support": { - "issues": "https://github.com/yiisoft/yii2/issues?labels=ext%3Aredis", + "issues": "https://github.com/yiisoft/yii2/issues?labels=ext%3Aapidoc", "forum": "http://www.yiiframework.com/forum/", "wiki": "http://www.yiiframework.com/wiki/", "irc": "irc://irc.freenode.net/yii", @@ -23,7 +23,7 @@ "phpdocumentor/reflection": "1.0.2" }, "autoload": { - "psr-0": { "yii\\redis\\": "" } + "psr-0": { "yii\\apidoc\\": "" } }, - "target-dir": "yii/redis" + "target-dir": "yii/apidoc" } diff --git a/extensions/yii/phpdoc/models/BaseDoc.php b/extensions/yii/apidoc/models/BaseDoc.php similarity index 81% rename from extensions/yii/phpdoc/models/BaseDoc.php rename to extensions/yii/apidoc/models/BaseDoc.php index cbdf2701452..888d1aca725 100644 --- a/extensions/yii/phpdoc/models/BaseDoc.php +++ b/extensions/yii/apidoc/models/BaseDoc.php @@ -1,6 +1,11 @@ + * @link http://www.yiiframework.com/ + * @copyright Copyright (c) 2008 Yii Software LLC + * @license http://www.yiiframework.com/license/ */ -namespace yii\phpdoc\models; +namespace yii\apidoc\models; use yii\base\Component; diff --git a/extensions/yii/apidoc/models/EventDoc.php b/extensions/yii/apidoc/models/EventDoc.php new file mode 100644 index 00000000000..22fedc9601b --- /dev/null +++ b/extensions/yii/apidoc/models/EventDoc.php @@ -0,0 +1,15 @@ + + * @link http://www.yiiframework.com/ + * @copyright Copyright (c) 2008 Yii Software LLC + * @license http://www.yiiframework.com/license/ */ -namespace yii\phpdoc\models; +namespace yii\apidoc\models; class InterfaceDoc extends BaseDoc { diff --git a/extensions/yii/apidoc/models/MethodDoc.php b/extensions/yii/apidoc/models/MethodDoc.php new file mode 100644 index 00000000000..cd32c86c8a4 --- /dev/null +++ b/extensions/yii/apidoc/models/MethodDoc.php @@ -0,0 +1,18 @@ + + * @link http://www.yiiframework.com/ + * @copyright Copyright (c) 2008 Yii Software LLC + * @license http://www.yiiframework.com/license/ */ -namespace yii\phpdoc\models; +namespace yii\apidoc\models; class PropertyDoc extends BaseDoc { diff --git a/extensions/yii/phpdoc/models/TraitDoc.php b/extensions/yii/apidoc/models/TraitDoc.php similarity index 83% rename from extensions/yii/phpdoc/models/TraitDoc.php rename to extensions/yii/apidoc/models/TraitDoc.php index 7fc6e5a95d4..20de618e853 100644 --- a/extensions/yii/phpdoc/models/TraitDoc.php +++ b/extensions/yii/apidoc/models/TraitDoc.php @@ -1,11 +1,11 @@ + * @link http://www.yiiframework.com/ + * @copyright Copyright (c) 2008 Yii Software LLC + * @license http://www.yiiframework.com/license/ */ -namespace yii\phpdoc\models; +namespace yii\apidoc\models; class TraitDoc extends BaseDoc { diff --git a/extensions/yii/phpdoc/views/class.php b/extensions/yii/apidoc/views/class.php similarity index 93% rename from extensions/yii/phpdoc/views/class.php rename to extensions/yii/apidoc/views/class.php index 0af8987e37c..ffe60634a9f 100644 --- a/extensions/yii/phpdoc/views/class.php +++ b/extensions/yii/apidoc/views/class.php @@ -1,8 +1,8 @@ - */ - -namespace yii\phpdoc\models; - -class ParamDoc -{ - public $name; - public $description; - public $type; - public $isOptional; - public $defaultValue; - public $isPassedByReference; -} \ No newline at end of file From e33aa9fc0dbc47c67698226ecaca52e79cf4525f Mon Sep 17 00:00:00 2001 From: Carsten Brandt Date: Sun, 5 Jan 2014 05:04:54 +0100 Subject: [PATCH 03/17] simplified model and context creation --- extensions/yii/apidoc/models/BaseDoc.php | 17 +++++ extensions/yii/apidoc/models/ClassDoc.php | 32 ++------- extensions/yii/apidoc/models/Context.php | 65 ++++++++++++++++--- extensions/yii/apidoc/models/File.php | 53 --------------- extensions/yii/apidoc/models/InterfaceDoc.php | 19 ++---- extensions/yii/apidoc/models/TraitDoc.php | 19 ++---- extensions/yii/apidoc/views/class.php | 6 ++ 7 files changed, 93 insertions(+), 118 deletions(-) delete mode 100644 extensions/yii/apidoc/models/File.php diff --git a/extensions/yii/apidoc/models/BaseDoc.php b/extensions/yii/apidoc/models/BaseDoc.php index 888d1aca725..fa8c7092b15 100644 --- a/extensions/yii/apidoc/models/BaseDoc.php +++ b/extensions/yii/apidoc/models/BaseDoc.php @@ -22,6 +22,23 @@ class BaseDoc extends Object public $startLine; public $endLine; + /** + * @param \phpDocumentor\Reflection\BaseReflector $reflector + * @param array $config + */ + public function __construct($reflector, $config = []) + { + // base properties + $this->name = ltrim($reflector->getName(), '\\'); + $this->startLine = $reflector->getNode()->getAttribute('startLine'); + $this->endLine = $reflector->getNode()->getAttribute('endLine'); + + // TODO docblock + + parent::__construct($config); + } + + public function loadSource($reflection) { $this->sourcePath=str_replace('\\','/',str_replace(YII_PATH,'',$reflection->getFileName())); diff --git a/extensions/yii/apidoc/models/ClassDoc.php b/extensions/yii/apidoc/models/ClassDoc.php index 3fe7f3d67d7..3d335680614 100644 --- a/extensions/yii/apidoc/models/ClassDoc.php +++ b/extensions/yii/apidoc/models/ClassDoc.php @@ -19,37 +19,23 @@ class ClassDoc extends BaseDoc public $interfaces = []; public $traits = []; + // will be set by Context::updateReferences() + public $subclasses = []; + // TODO public $properties = []; public $methods = []; public $events = []; public $constants = []; -// public $protectedPropertyCount=0; -// public $publicPropertyCount=0; -// public $protectedMethodCount=0; -// public $publicMethodCount=0; -// -// public $nativePropertyCount=0; -// public $nativeMethodCount=0; -// public $nativeEventCount=0; - - public $sinceVersion; - - public $subclasses = []; - /** * @param \phpDocumentor\Reflection\ClassReflector $reflector - * @param Context $context * @param array $config */ - public function __construct($reflector, $context = null, $config = []) + public function __construct($reflector, $config = []) { - // base properties - $this->name = ltrim($reflector->getName(), '\\'); - $this->startLine = $reflector->getNode()->getAttribute('startLine'); - $this->endLine = $reflector->getNode()->getAttribute('endLine'); + parent::__construct($reflector, $config); $this->parentClass = ltrim($reflector->getParentClass(), '\\'); if (empty($this->parentClass)) { @@ -68,13 +54,5 @@ public function __construct($reflector, $context = null, $config = []) // TODO methods // TODO properties - - // TODO docblock - - if ($context !== null) { - $context->addClass($this); - } - - parent::__construct($config); } } \ No newline at end of file diff --git a/extensions/yii/apidoc/models/Context.php b/extensions/yii/apidoc/models/Context.php index 11ece3ef013..8c3d6586169 100644 --- a/extensions/yii/apidoc/models/Context.php +++ b/extensions/yii/apidoc/models/Context.php @@ -8,15 +8,16 @@ namespace yii\apidoc\models; +use phpDocumentor\Reflection\FileReflector; use yii\base\Component; use yii\base\Exception; class Context extends Component { - public $basePath; - + /** + * @var array list of php files that have been added to this context. + */ public $files = []; - /** * @var ClassDoc[] */ @@ -30,32 +31,66 @@ class Context extends Component */ public $traits = []; + public function addFile($fileName) { - $file = new File($fileName, $this); - $this->files[$fileName] = $file; + if (isset($this->files[$fileName])) { + return; + } + $this->files[$fileName] = $fileName; + + $reflection = new FileReflector($fileName, true); + $reflection->process(); + + foreach($reflection->getClasses() as $class) { + $class = new ClassDoc($class, $this); + $class->sourceFile = $fileName; + $this->addClass($class); + } + foreach($reflection->getInterfaces() as $interface) { + $interface = new InterfaceDoc($interface, $this); + $interface->sourceFile = $fileName; + $this->addInterface($interface); + } + foreach($reflection->getTraits() as $trait) { + $trait = new TraitDoc($trait, $this); + $trait->sourceFile = $fileName; + $this->addTrait($trait); + } } + /** + * @param ClassDoc $class + * @throws \yii\base\Exception when class is already part of this context + */ public function addClass($class) { if (isset($this->classes[$class->name])) { - throw new Exception('Duplicate class definition: ' . $class->name . ' in file ' . $class->fileName); + throw new Exception('Duplicate class definition: ' . $class->name . ' in file ' . $class->sourceFile . '.'); } $this->classes[$class->name] = $class; } + /** + * @param InterfaceDoc $interface + * @throws \yii\base\Exception when interface is already part of this context + */ public function addInterface($interface) { if (isset($this->interfaces[$interface->name])) { - throw new Exception('Duplicate interface definition: ' . $interface->name . ' in file ' . $interface->fileName); + throw new Exception('Duplicate interface definition: ' . $interface->name . ' in file ' . $interface->sourceFile); } $this->interfaces[$interface->name] = $interface; } + /** + * @param TraitDoc $trait + * @throws \yii\base\Exception when trait is already part of this context + */ public function addTrait($trait) { if (isset($this->traits[$trait->name])) { - throw new Exception('Duplicate trait definition: ' . $trait->name . ' in file ' . $trait->fileName); + throw new Exception('Duplicate trait definition: ' . $trait->name . ' in file ' . $trait->sourceFile); } $this->traits[$trait->name] = $trait; } @@ -74,7 +109,19 @@ public function updateReferences() foreach($this->classes as $class) { $this->updateSubclassInferfacesTraits($class); } - // TODO update interface and trait usages + // update implementedBy and usedBy for interfaces and traits + foreach($this->classes as $class) { + foreach($class->interfaces as $interface) { + if (isset($this->interfaces[$interface])) { + $this->interfaces[$interface]->implementedBy[] = $class->name; + } + } + foreach($class->traits as $trait) { + if (isset($this->traits[$trait])) { + $this->traits[$trait]->usedBy[] = $class->name; + } + } + } } /** diff --git a/extensions/yii/apidoc/models/File.php b/extensions/yii/apidoc/models/File.php deleted file mode 100644 index 61597c29de8..00000000000 --- a/extensions/yii/apidoc/models/File.php +++ /dev/null @@ -1,53 +0,0 @@ -name = $fileName; - $this->_reflection = new FileReflector($fileName, true); - $this->_reflection->process(); - - foreach($this->_reflection->getClasses() as $class) { - $class = new ClassDoc($class, $context); - $class->sourceFile = $fileName; - $this->classes[] = $class; - } - foreach($this->_reflection->getInterfaces() as $interface) { - $this->interfaces[] = new InterfaceDoc($interface, $context); - } - foreach($this->_reflection->getTraits() as $trait) { - $this->traits[] = new TraitDoc($trait, $context); - } - - parent::__construct($config); - } -} \ No newline at end of file diff --git a/extensions/yii/apidoc/models/InterfaceDoc.php b/extensions/yii/apidoc/models/InterfaceDoc.php index 1275898b5e3..32f9113ecd8 100644 --- a/extensions/yii/apidoc/models/InterfaceDoc.php +++ b/extensions/yii/apidoc/models/InterfaceDoc.php @@ -11,35 +11,24 @@ class InterfaceDoc extends BaseDoc { public $parentInterfaces = []; + // will be set by Context::updateReferences() public $implementedBy = []; + // TODO public $methods = []; /** * @param \phpDocumentor\Reflection\InterfaceReflector $reflector - * @param Context $context * @param array $config */ - public function __construct($reflector, $context = null, $config = []) + public function __construct($reflector, $config = []) { - // base properties - $this->name = ltrim($reflector->getName(), '\\'); - $this->startLine = $reflector->getNode()->getAttribute('startLine'); - $this->endLine = $reflector->getNode()->getAttribute('endLine'); + parent::__construct($reflector, $config); foreach($reflector->getParentInterfaces() as $interface) { $this->parentInterfaces[] = ltrim($interface, '\\'); } // TODO methods - - // TODO docblock - - if ($context !== null) { - $context->addInterface($this); - } - - parent::__construct($config); } - } \ No newline at end of file diff --git a/extensions/yii/apidoc/models/TraitDoc.php b/extensions/yii/apidoc/models/TraitDoc.php index 20de618e853..eef6b4e0857 100644 --- a/extensions/yii/apidoc/models/TraitDoc.php +++ b/extensions/yii/apidoc/models/TraitDoc.php @@ -10,25 +10,23 @@ class TraitDoc extends BaseDoc { // classes using the trait - public $usedByClasses = []; + // will be set by Context::updateReferences() + public $usedBy = []; public $traits = []; + // TODO public $properties = []; public $methods = []; /** * @param \phpDocumentor\Reflection\TraitReflector $reflector - * @param Context $context * @param array $config */ - public function __construct($reflector, $context = null, $config = []) + public function __construct($reflector, $config = []) { - // base properties - $this->name = ltrim($reflector->getName(), '\\'); - $this->startLine = $reflector->getNode()->getAttribute('startLine'); - $this->endLine = $reflector->getNode()->getAttribute('endLine'); + parent::__construct($reflector, $config); foreach($reflector->getTraits() as $trait) { $this->traits[] = ltrim($trait, '\\'); @@ -38,12 +36,5 @@ public function __construct($reflector, $context = null, $config = []) // TODO properties - // TODO docblock - - if ($context !== null) { - $context->addTrait($this); - } - - parent::__construct($config); } } \ No newline at end of file diff --git a/extensions/yii/apidoc/views/class.php b/extensions/yii/apidoc/views/class.php index ffe60634a9f..5c0ddaa5709 100644 --- a/extensions/yii/apidoc/views/class.php +++ b/extensions/yii/apidoc/views/class.php @@ -15,6 +15,12 @@ } elseif ($item instanceof TraitDoc) { echo 'Trait '; } else { + if ($item->isFinal) { + echo 'Final '; + } + if ($item->isAbstract) { + echo 'Abstract '; + } echo 'Class '; } echo $item->name; From c66a1fa7bd0845e8da388c360001ac0cf0d41701 Mon Sep 17 00:00:00 2001 From: Carsten Brandt Date: Sun, 5 Jan 2014 07:04:08 +0100 Subject: [PATCH 04/17] finished the model layer --- .../yii/apidoc/components/OfflineRenderer.php | 8 +-- extensions/yii/apidoc/models/BaseDoc.php | 41 +++++++++-- extensions/yii/apidoc/models/ClassDoc.php | 20 +++--- extensions/yii/apidoc/models/ConstDoc.php | 13 ++++ extensions/yii/apidoc/models/Context.php | 7 +- extensions/yii/apidoc/models/EventDoc.php | 5 +- extensions/yii/apidoc/models/FunctionDoc.php | 50 ++++++++++++- extensions/yii/apidoc/models/InterfaceDoc.php | 8 +-- extensions/yii/apidoc/models/MethodDoc.php | 22 +++++- extensions/yii/apidoc/models/ParamDoc.php | 27 ++++++- extensions/yii/apidoc/models/PropertyDoc.php | 51 +++++++++++-- extensions/yii/apidoc/models/TraitDoc.php | 12 +--- extensions/yii/apidoc/models/TypeDoc.php | 72 +++++++++++++++++++ 13 files changed, 281 insertions(+), 55 deletions(-) create mode 100644 extensions/yii/apidoc/models/ConstDoc.php create mode 100644 extensions/yii/apidoc/models/TypeDoc.php diff --git a/extensions/yii/apidoc/components/OfflineRenderer.php b/extensions/yii/apidoc/components/OfflineRenderer.php index 0c3d2dd7fe3..509c51d0f77 100644 --- a/extensions/yii/apidoc/components/OfflineRenderer.php +++ b/extensions/yii/apidoc/components/OfflineRenderer.php @@ -23,9 +23,9 @@ class OfflineRenderer extends BaseRenderer implements ViewContextInterface { public $targetDir; - public $layout = '@yii/phpdoc/views/layouts/offline.php'; - public $itemView = '@yii/phpdoc/views/class.php'; - public $indexView = '@yii/phpdoc/views/index.php'; + public $layout = '@yii/apidoc/views/layouts/offline.php'; + public $itemView = '@yii/apidoc/views/class.php'; + public $indexView = '@yii/apidoc/views/index.php'; public $pageTitle = 'Yii Framework 2.0 API Documentation'; @@ -177,6 +177,6 @@ public function generateFileName($itemName) */ public function findViewFile($view) { - return Yii::getAlias('@yii/phpdoc/views/' . $view); + return Yii::getAlias('@yii/apidoc/views/' . $view); } } \ No newline at end of file diff --git a/extensions/yii/apidoc/models/BaseDoc.php b/extensions/yii/apidoc/models/BaseDoc.php index fa8c7092b15..671501555e2 100644 --- a/extensions/yii/apidoc/models/BaseDoc.php +++ b/extensions/yii/apidoc/models/BaseDoc.php @@ -7,38 +7,65 @@ namespace yii\apidoc\models; +use phpDocumentor\Reflection\DocBlock\Tag\DeprecatedTag; +use phpDocumentor\Reflection\DocBlock\Tag\SinceTag; use yii\base\Object; class BaseDoc extends Object { public $name; - public $since; + public $sourceFile; + public $startLine; + public $endLine; public $shortDescription; public $description; + public $since; + public $deprecatedSince; + public $deprecatedReason; + + public $tags = []; - public $sourceFile; - public $startLine; - public $endLine; /** * @param \phpDocumentor\Reflection\BaseReflector $reflector * @param array $config */ - public function __construct($reflector, $config = []) + public function __construct($reflector = null, $config = []) { + parent::__construct($config); + + if ($reflector === null) { + return; + } + // base properties $this->name = ltrim($reflector->getName(), '\\'); $this->startLine = $reflector->getNode()->getAttribute('startLine'); $this->endLine = $reflector->getNode()->getAttribute('endLine'); - // TODO docblock + $docblock = $reflector->getDocBlock(); + if ($docblock !== null) { + $this->shortDescription = $docblock->getShortDescription(); + $this->description = $docblock->getLongDescription(); - parent::__construct($config); + $this->tags = $docblock->getTags(); + foreach($this->tags as $i => $tag) { + if ($tag instanceof SinceTag) { + $this->since = $tag->getVersion(); + unset($this->tags[$i]); + } elseif ($tag instanceof DeprecatedTag) { + $this->deprecatedSince = $tag->getVersion(); + $this->deprecatedReason = $tag->getDescription(); + unset($this->tags[$i]); + } + } + } } + // TODO public function loadSource($reflection) { $this->sourcePath=str_replace('\\','/',str_replace(YII_PATH,'',$reflection->getFileName())); diff --git a/extensions/yii/apidoc/models/ClassDoc.php b/extensions/yii/apidoc/models/ClassDoc.php index 3d335680614..9bb7191dec9 100644 --- a/extensions/yii/apidoc/models/ClassDoc.php +++ b/extensions/yii/apidoc/models/ClassDoc.php @@ -10,7 +10,7 @@ /** * Class ClassDoc */ -class ClassDoc extends BaseDoc +class ClassDoc extends TypeDoc { public $parentClass; @@ -22,9 +22,6 @@ class ClassDoc extends BaseDoc // will be set by Context::updateReferences() public $subclasses = []; - // TODO - public $properties = []; - public $methods = []; public $events = []; public $constants = []; @@ -50,9 +47,16 @@ public function __construct($reflector, $config = []) foreach($reflector->getTraits() as $trait) { $this->traits[] = ltrim($trait, '\\'); } - - // TODO methods - - // TODO properties + foreach($reflector->getConstants() as $constantReflector) { + if (strncmp($constantReflector->getShortName(), 'EVENT_', 6) == 0) { + $event = new EventDoc($constantReflector); + $event->definedBy = $this->name; + $this->events[] = $event; + } else { + $constant = new ConstDoc($constantReflector); + $constant->definedBy = $this->name; + $this->constants[] = $constant; + } + } } } \ No newline at end of file diff --git a/extensions/yii/apidoc/models/ConstDoc.php b/extensions/yii/apidoc/models/ConstDoc.php new file mode 100644 index 00000000000..5eb99a981a0 --- /dev/null +++ b/extensions/yii/apidoc/models/ConstDoc.php @@ -0,0 +1,13 @@ +process(); foreach($reflection->getClasses() as $class) { - $class = new ClassDoc($class, $this); + $class = new ClassDoc($class); $class->sourceFile = $fileName; $this->addClass($class); } foreach($reflection->getInterfaces() as $interface) { - $interface = new InterfaceDoc($interface, $this); + $interface = new InterfaceDoc($interface); $interface->sourceFile = $fileName; $this->addInterface($interface); } foreach($reflection->getTraits() as $trait) { - $trait = new TraitDoc($trait, $this); + $trait = new TraitDoc($trait); $trait->sourceFile = $fileName; $this->addTrait($trait); } @@ -107,6 +107,7 @@ public function updateReferences() } // update interfaces of subclasses foreach($this->classes as $class) { + // TODO do the same for events, constants, methods, properties $this->updateSubclassInferfacesTraits($class); } // update implementedBy and usedBy for interfaces and traits diff --git a/extensions/yii/apidoc/models/EventDoc.php b/extensions/yii/apidoc/models/EventDoc.php index 22fedc9601b..fbdc4d800ad 100644 --- a/extensions/yii/apidoc/models/EventDoc.php +++ b/extensions/yii/apidoc/models/EventDoc.php @@ -7,9 +7,6 @@ namespace yii\apidoc\models; -class EventDoc extends BaseDoc +class EventDoc extends ConstDoc { - public $isInherited; - public $definedBy; - public $trigger; } \ No newline at end of file diff --git a/extensions/yii/apidoc/models/FunctionDoc.php b/extensions/yii/apidoc/models/FunctionDoc.php index b9cee3b651b..d84fd01e200 100644 --- a/extensions/yii/apidoc/models/FunctionDoc.php +++ b/extensions/yii/apidoc/models/FunctionDoc.php @@ -7,9 +7,53 @@ namespace yii\apidoc\models; +use phpDocumentor\Reflection\DocBlock\Tag\ParamTag; +use phpDocumentor\Reflection\DocBlock\Tag\ReturnTag; +use phpDocumentor\Reflection\DocBlock\Tag\ThrowsTag; + class FunctionDoc extends BaseDoc { - public $signature; - public $input=array(); - public $output; + /** + * @var ParamDoc[] + */ + public $params = []; + public $exceptions = []; + public $return; + public $returnType; + public $returnTypes; + public $isReturnByReference; + + /** + * @param \phpDocumentor\Reflection\FunctionReflector $reflector + * @param array $config + */ + public function __construct($reflector, $config = []) + { + parent::__construct($reflector, $config); + + $this->isReturnByReference = $reflector->isByRef(); + + foreach($reflector->getArguments() as $arg) { + $arg = new ParamDoc($arg); + $this->params[$arg->name] = $arg; + } + + foreach($this->tags as $i => $tag) { + if ($tag instanceof ReturnTag) { + $this->returnType = $tag->getType(); + $this->returnTypes = $tag->getTypes(); + $this->return = $tag->getDescription(); + unset($this->tags[$i]); + } elseif ($tag instanceof ParamTag) { + $paramName = $tag->getVariableName(); + $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(); + unset($this->tags[$i]); + } + } + } } diff --git a/extensions/yii/apidoc/models/InterfaceDoc.php b/extensions/yii/apidoc/models/InterfaceDoc.php index 32f9113ecd8..8a996615a91 100644 --- a/extensions/yii/apidoc/models/InterfaceDoc.php +++ b/extensions/yii/apidoc/models/InterfaceDoc.php @@ -7,16 +7,13 @@ namespace yii\apidoc\models; -class InterfaceDoc extends BaseDoc +class InterfaceDoc extends TypeDoc { public $parentInterfaces = []; // will be set by Context::updateReferences() public $implementedBy = []; - // TODO - public $methods = []; - /** * @param \phpDocumentor\Reflection\InterfaceReflector $reflector * @param array $config @@ -29,6 +26,7 @@ public function __construct($reflector, $config = []) $this->parentInterfaces[] = ltrim($interface, '\\'); } - // TODO methods + // interface can not have properties + $this->properties = null; } } \ No newline at end of file diff --git a/extensions/yii/apidoc/models/MethodDoc.php b/extensions/yii/apidoc/models/MethodDoc.php index cd32c86c8a4..70d67ce6064 100644 --- a/extensions/yii/apidoc/models/MethodDoc.php +++ b/extensions/yii/apidoc/models/MethodDoc.php @@ -11,8 +11,26 @@ class MethodDoc extends FunctionDoc { public $isAbstract; public $isFinal; - public $isProtected; + public $isStatic; - public $isInherited; + + public $visibility; + + // will be set by creating class public $definedBy; + + /** + * @param \phpDocumentor\Reflection\ClassReflector\MethodReflector $reflector + * @param array $config + */ + public function __construct($reflector, $config = []) + { + parent::__construct($reflector, $config); + + $this->isAbstract = $reflector->isAbstract(); + $this->isFinal = $reflector->isFinal(); + $this->isStatic = $reflector->isStatic(); + + $this->visibility = $reflector->getVisibility(); + } } diff --git a/extensions/yii/apidoc/models/ParamDoc.php b/extensions/yii/apidoc/models/ParamDoc.php index 6fdd535fce4..b5b664cb955 100644 --- a/extensions/yii/apidoc/models/ParamDoc.php +++ b/extensions/yii/apidoc/models/ParamDoc.php @@ -7,12 +7,33 @@ namespace yii\apidoc\models; -class ParamDoc +use yii\base\Object; + +class ParamDoc extends Object { public $name; - public $description; - public $type; + public $typeHint; public $isOptional; public $defaultValue; public $isPassedByReference; + + // will be set by creating class + public $description; + public $type; + public $types; + + /** + * @param \phpDocumentor\Reflection\FunctionReflector\ArgumentReflector $reflector + * @param array $config + */ + public function __construct($reflector, $config = []) + { + parent::__construct($config); + + $this->name = $reflector->getName(); + $this->typeHint = $reflector->getType(); + $this->isOptional = $reflector->getDefault() !== null; + $this->defaultValue = $reflector->getDefault(); // TODO what about null value? + $this->isPassedByReference = $reflector->isByRef(); + } } \ No newline at end of file diff --git a/extensions/yii/apidoc/models/PropertyDoc.php b/extensions/yii/apidoc/models/PropertyDoc.php index 9fd94e588ba..3a9b447850a 100644 --- a/extensions/yii/apidoc/models/PropertyDoc.php +++ b/extensions/yii/apidoc/models/PropertyDoc.php @@ -7,17 +7,58 @@ namespace yii\apidoc\models; +use phpDocumentor\Reflection\DocBlock\Tag\VarTag; + class PropertyDoc extends BaseDoc { - public $isProtected; + public $visibility; public $isStatic; - public $readOnly; - public $isInherited; - public $definedBy; public $type; - public $signature; + public $types; + public $defaultValue; + // will be set by creating class public $getter; public $setter; + + // will be set by creating class + public $definedBy; + + public function getIsReadOnly() + { + return $this->getter !== null && $this->setter === null; + } + + public function getIsWriteOnly() + { + return $this->getter === null && $this->setter !== null; + } + + /** + * @param \phpDocumentor\Reflection\ClassReflector\PropertyReflector $reflector + * @param array $config + */ + public function __construct($reflector = null, $config = []) + { + parent::__construct($reflector, $config); + + if ($reflector === null) { + return; + } + + $this->visibility = $reflector->getVisibility(); + $this->isStatic = $reflector->isStatic(); + + $this->defaultValue = $reflector->getDefault(); + + foreach($this->tags as $i => $tag) { + if ($tag instanceof VarTag) { + $this->type = $tag->getType(); + $this->types = $tag->getTypes(); + $this->description = $tag->getDescription(); + // TODO set shortDescription + } + } + } } \ No newline at end of file diff --git a/extensions/yii/apidoc/models/TraitDoc.php b/extensions/yii/apidoc/models/TraitDoc.php index eef6b4e0857..13ee9b92a66 100644 --- a/extensions/yii/apidoc/models/TraitDoc.php +++ b/extensions/yii/apidoc/models/TraitDoc.php @@ -7,7 +7,7 @@ namespace yii\apidoc\models; -class TraitDoc extends BaseDoc +class TraitDoc extends TypeDoc { // classes using the trait // will be set by Context::updateReferences() @@ -15,11 +15,6 @@ class TraitDoc extends BaseDoc public $traits = []; - // TODO - public $properties = []; - public $methods = []; - - /** * @param \phpDocumentor\Reflection\TraitReflector $reflector * @param array $config @@ -31,10 +26,5 @@ public function __construct($reflector, $config = []) foreach($reflector->getTraits() as $trait) { $this->traits[] = ltrim($trait, '\\'); } - - // TODO methods - - // TODO properties - } } \ No newline at end of file diff --git a/extensions/yii/apidoc/models/TypeDoc.php b/extensions/yii/apidoc/models/TypeDoc.php new file mode 100644 index 00000000000..a1349a49520 --- /dev/null +++ b/extensions/yii/apidoc/models/TypeDoc.php @@ -0,0 +1,72 @@ +tags as $i => $tag) { + if ($tag instanceof AuthorTag) { + $this->authors[$tag->getAuthorName()] = $tag->getAuthorEmail(); + unset($this->tags[$i]); + } + } + + foreach($reflector->getProperties() as $propertyReflector) { + if ($propertyReflector->getVisibility() != 'private') { + $property = new PropertyDoc($propertyReflector); + $property->definedBy = $this->name; + $this->properties[$property->name] = $property; + } + } + + foreach($reflector->getMethods() as $methodReflector) { + if ($methodReflector->getVisibility() != 'private') { + $method = new MethodDoc($methodReflector); + $method->definedBy = $this->name; + + if (!strncmp($method->name, 'set', 3)) { + $propertyName = lcfirst(substr($method->name, 3)); + if (isset($this->properties[$propertyName])) { + $property = $this->properties[$propertyName]; + if ($property->getter === null && $property->setter === null) { + throw new Exception("Property $propertyName conflicts with a defined setter {$method->name}."); + } + $property->setter = $method; + } else { +// $this->properties[$propertyName] = new PropertyDoc(null, [ +// 'name' => $propertyName, +// // TODO set description and short description +// ]); + } + } elseif (!strncmp($method->name, 'get', 3)) { + // TODO add property + } + $this->methods[$method->name] = $method; + } + } + } +} \ No newline at end of file From da1617340d2626829b7c99b0870e04697224f0ea Mon Sep 17 00:00:00 2001 From: Carsten Brandt Date: Sun, 5 Jan 2014 17:45:56 +0100 Subject: [PATCH 05/17] finished offline template summaries --- .../yii/apidoc/components/OfflineRenderer.php | 88 ++++++++++++++----- extensions/yii/apidoc/models/ClassDoc.php | 6 ++ extensions/yii/apidoc/models/Context.php | 42 ++++++++- extensions/yii/apidoc/models/TypeDoc.php | 53 +++++++++++ extensions/yii/apidoc/views/class.php | 38 ++++---- extensions/yii/apidoc/views/classSummary.php | 79 +++++++---------- extensions/yii/apidoc/views/constSummary.php | 34 +++++++ extensions/yii/apidoc/views/eventSummary.php | 34 +++++++ extensions/yii/apidoc/views/index.php | 2 +- extensions/yii/apidoc/views/methodSummary.php | 40 +++++++++ .../yii/apidoc/views/propertySummary.php | 42 +++++++++ 11 files changed, 372 insertions(+), 86 deletions(-) create mode 100644 extensions/yii/apidoc/views/constSummary.php create mode 100644 extensions/yii/apidoc/views/eventSummary.php create mode 100644 extensions/yii/apidoc/views/methodSummary.php create mode 100644 extensions/yii/apidoc/views/propertySummary.php diff --git a/extensions/yii/apidoc/components/OfflineRenderer.php b/extensions/yii/apidoc/components/OfflineRenderer.php index 509c51d0f77..a3660f73f38 100644 --- a/extensions/yii/apidoc/components/OfflineRenderer.php +++ b/extensions/yii/apidoc/components/OfflineRenderer.php @@ -8,6 +8,10 @@ namespace yii\apidoc\components; +use yii\apidoc\models\ConstDoc; +use yii\apidoc\models\EventDoc; +use yii\apidoc\models\MethodDoc; +use yii\apidoc\models\PropertyDoc; use yii\base\ViewContextInterface; use yii\console\Controller; use yii\helpers\Console; @@ -85,17 +89,50 @@ protected function renderWithLayout($viewFile, $params) } /** - * creates a link to an item - * @param ClassDoc|InterfaceDoc|TraitDoc $item + * creates a link to a type (class, interface or trait) + * @param ClassDoc|InterfaceDoc|TraitDoc $types * @param string $title * @return string */ - public function link($item, $title = null) + public function typeLink($types, $title = null) + { + if (!is_array($types)) { + $types = [$types]; + } + $links = []; + foreach($types as $type) { + if (!is_object($type) && ($t = $this->context->getType($type)) !== null) { + $type = $t; + } + if (!is_object($type)) { + $links[] = $type; + } else { + $links[] = Html::a( + $title !== null ? $title : $type->name, + null, + ['href' => $this->generateFileName($type->name)] + ); + } + } + return implode('|', $links); + } + + /** + * creates a link to a subject + * @param PropertyDoc|MethodDoc|ConstDoc|EventDoc $subject + * @param string $title + * @return string + */ + public function subjectLink($subject, $title = null) { if ($title === null) { - $title = $item->name; + $title = $subject->name; + } + 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']); } - return Html::a($title, null, ['href' => $this->generateFileName($item->name)]); } /** @@ -104,11 +141,11 @@ public function link($item, $title = null) */ public function renderInheritance($class) { - $parents[] = $this->link($class); + $parents[] = $this->typeLink($class); while ($class->parentClass !== null) { if(isset($this->context->classes[$class->parentClass])) { $class = $this->context->classes[$class->parentClass]; - $parents[] = $this->link($class); + $parents[] = $this->typeLink($class); } else { $parents[] = $class->parentClass; // TODO link to php.net break; @@ -118,15 +155,16 @@ public function renderInheritance($class) } /** - * @param ClassDoc $class + * @param array $names * @return string */ - public function renderImplements($class) + public function renderInterfaces($names) { $interfaces = []; - foreach($class->interfaces as $interface) { + sort($names, SORT_STRING); + foreach($names as $interface) { if(isset($this->context->interfaces[$interface])) { - $interfaces[] = $this->link($this->context->interfaces[$interface]); + $interfaces[] = $this->typeLink($this->context->interfaces[$interface]); } else { $interfaces[] = $interface; // TODO link to php.net } @@ -135,15 +173,16 @@ public function renderImplements($class) } /** - * @param ClassDoc|TraitDoc $class + * @param array $names * @return string */ - public function renderTraitUses($class) + public function renderTraits($names) { $traits = []; - foreach($class->traits as $trait) { + sort($names, SORT_STRING); + foreach($names as $trait) { if(isset($this->context->traits[$trait])) { - $traits[] = $this->link($this->context->traits[$trait]); + $traits[] = $this->typeLink($this->context->traits[$trait]); } else { $traits[] = $trait; // TODO link to php.net } @@ -151,17 +190,22 @@ public function renderTraitUses($class) return implode(', ',$traits); } - public function renderSubclasses($class) + /** + * @param array $names + * @return string + */ + public function renderClasses($names) { - $subclasses = []; - foreach($class->subclasses as $subclass) { - if(isset($this->context->classes[$subclass])) { - $subclasses[] = $this->link($this->context->classes[$subclass]); + $classes = []; + sort($names, SORT_STRING); + foreach($names as $class) { + if(isset($this->context->classes[$class])) { + $classes[] = $this->typeLink($this->context->classes[$class]); } else { - $subclasses[] = $subclass; // TODO link to php.net + $classes[] = $class; // TODO link to php.net } } - return implode(', ',$subclasses); + return implode(', ',$classes); } diff --git a/extensions/yii/apidoc/models/ClassDoc.php b/extensions/yii/apidoc/models/ClassDoc.php index 9bb7191dec9..7e7e24bf26d 100644 --- a/extensions/yii/apidoc/models/ClassDoc.php +++ b/extensions/yii/apidoc/models/ClassDoc.php @@ -22,7 +22,13 @@ class ClassDoc extends TypeDoc // will be set by Context::updateReferences() public $subclasses = []; + /** + * @var EventDoc[] + */ public $events = []; + /** + * @var ConstDoc[] + */ public $constants = []; diff --git a/extensions/yii/apidoc/models/Context.php b/extensions/yii/apidoc/models/Context.php index c3b3246bf8f..067014013c1 100644 --- a/extensions/yii/apidoc/models/Context.php +++ b/extensions/yii/apidoc/models/Context.php @@ -32,6 +32,18 @@ class Context extends Component public $traits = []; + public function getType($type) + { + if (isset($this->classes[$type])) { + return $this->classes[$type]; + } elseif (isset($this->interfaces[$type])) { + return $this->interfaces[$type]; + } elseif (isset($this->traits[$type])) { + return $this->traits[$type]; + } + return null; + } + public function addFile($fileName) { if (isset($this->files[$fileName])) { @@ -107,7 +119,6 @@ public function updateReferences() } // update interfaces of subclasses foreach($this->classes as $class) { - // TODO do the same for events, constants, methods, properties $this->updateSubclassInferfacesTraits($class); } // update implementedBy and usedBy for interfaces and traits @@ -119,10 +130,17 @@ public function updateReferences() } foreach($class->traits as $trait) { if (isset($this->traits[$trait])) { - $this->traits[$trait]->usedBy[] = $class->name; + $trait = $this->traits[$trait]; + $trait->usedBy[] = $class->name; + $class->properties = array_merge($trait->properties, $class->properties); // TODO make unique + $class->methods = array_merge($trait->methods, $class->methods); // TODO make unique } } } + // update properties, methods, contants and events of subclasses + foreach($this->classes as $class) { + $this->updateSubclassInheritance($class); + } } /** @@ -135,7 +153,27 @@ protected function updateSubclassInferfacesTraits($class) $subclass = $this->classes[$subclass]; $subclass->interfaces = array_unique(array_merge($subclass->interfaces, $class->interfaces)); $subclass->traits = array_unique(array_merge($subclass->traits, $class->traits)); + $subclass->events = array_merge($class->events, $subclass->events); // TODO make unique + $subclass->constants = array_merge($class->constants, $subclass->constants); // TODO make unique + $subclass->properties = array_merge($class->properties, $subclass->properties); // TODO make unique + $subclass->methods = array_merge($class->methods, $subclass->methods); // TODO make unique $this->updateSubclassInferfacesTraits($subclass); } } + + /** + * Add implemented interfaces and used traits to subclasses + * @param ClassDoc $class + */ + protected function updateSubclassInheritance($class) + { + foreach($class->subclasses as $subclass) { + $subclass = $this->classes[$subclass]; + $subclass->events = array_merge($class->events, $subclass->events); // TODO make unique + $subclass->constants = array_merge($class->constants, $subclass->constants); // TODO make unique + $subclass->properties = array_merge($class->properties, $subclass->properties); // TODO make unique + $subclass->methods = array_merge($class->methods, $subclass->methods); // TODO make unique + $this->updateSubclassInheritance($subclass); + } + } } \ No newline at end of file diff --git a/extensions/yii/apidoc/models/TypeDoc.php b/extensions/yii/apidoc/models/TypeDoc.php index a1349a49520..7ba1027e2d8 100644 --- a/extensions/yii/apidoc/models/TypeDoc.php +++ b/extensions/yii/apidoc/models/TypeDoc.php @@ -13,9 +13,61 @@ class TypeDoc extends BaseDoc { public $authors = []; + /** + * @var MethodDoc[] + */ public $methods = []; + /** + * @var PropertyDoc[] + */ public $properties = []; + + public function getPublicMethods() + { + return $this->getFilteredMethods('public'); + } + + public function getProtectedMethods() + { + return $this->getFilteredMethods('protected'); + } + + private function getFilteredMethods($visibility) + { + $methods = []; + foreach($this->methods as $method) { + if ($method->visibility == $visibility) { + $methods[] = $method; + } + } + return $methods; + } + + public function getPublicProperties() + { + return $this->getFilteredProperties('public'); + } + + public function getProtectedProperties() + { + return $this->getFilteredProperties('protected'); + } + + private function getFilteredProperties($visibility) + { + if ($this->properties === null) { + return []; + } + $properties = []; + foreach($this->properties as $property) { + if ($property->visibility == $visibility) { + $properties[] = $property; + } + } + return $properties; + } + /** * @param \phpDocumentor\Reflection\InterfaceReflector $reflector * @param array $config @@ -48,6 +100,7 @@ public function __construct($reflector, $config = []) $method = new MethodDoc($methodReflector); $method->definedBy = $this->name; + // TODO only set property when subclass of Object if (!strncmp($method->name, 'set', 3)) { $propertyName = lcfirst(substr($method->name, 3)); if (isset($this->properties[$propertyName])) { diff --git a/extensions/yii/apidoc/views/class.php b/extensions/yii/apidoc/views/class.php index 5c0ddaa5709..f3db8cfeba9 100644 --- a/extensions/yii/apidoc/views/class.php +++ b/extensions/yii/apidoc/views/class.php @@ -26,30 +26,36 @@ echo $item->name; ?> -render('classSummary', ['item' => $item]); ?> +render('classSummary', ['item' => $item]) ?> -renderPartial('propertySummary',array('class'=>$item,'protected'=>false)); ?> -renderPartial('propertySummary',array('class'=>$item,'protected'=>true)); ?> +render('propertySummary', ['item' => $item,'protected' => false]) ?> +render('propertySummary', ['item' => $item,'protected' => true]) ?> -renderPartial('methodSummary',array('class'=>$item,'protected'=>false)); ?> -renderPartial('methodSummary',array('class'=>$item,'protected'=>true)); ?> +render('methodSummary', ['item' => $item, 'protected' => false]) ?> +render('methodSummary', ['item' => $item, 'protected' => true]) ?> -renderPartial('eventSummary',array('class'=>$item)); ?> +render('eventSummary', ['item' => $item]) ?> + + +render('constSummary', ['item' => $item]) ?> renderPartial('propertyDetails',array('class'=>$item)); ?> renderPartial('methodDetails',array('class'=>$item)); ?> diff --git a/extensions/yii/apidoc/views/classSummary.php b/extensions/yii/apidoc/views/classSummary.php index 1f6ad9a9ebe..2de381181a1 100644 --- a/extensions/yii/apidoc/views/classSummary.php +++ b/extensions/yii/apidoc/views/classSummary.php @@ -1,60 +1,49 @@ context; ?> -- - - - - - - - - -interfaces)): ?> - - - - - -traits)): ?> - - - - - -subclasses)): ?> - - - - - -since)): ?> - - - - - -version)): ?> - - - - - - - -renderSourceLink($item->sourcePath); ?> - + + + + + + + + interfaces)): ?> + + + traits)): ?> + + + subclasses)): ?> + + + implementedBy)): ?> + + + usedBy)): ?> + + + since)): ?> + + + + + +
Inheritancecontext->renderInheritance($item); ?>
Implementscontext->renderImplements($item); ?>
Uses Traitscontext->renderTraitUses($item); ?>
Subclassescontext->renderSubclasses($item); ?>
Sincesince; ?>
Versionversion; ?>
Source Code
InheritancerenderInheritance($item) ?>
ImplementsrenderInterfaces($item->interfaces) ?>
Uses TraitsrenderTraits($item->traits) ?>
SubclassesrenderClasses($item->subclasses) ?>
Implemented byrenderClasses($item->implementedBy) ?>
Implemented byrenderClasses($item->usedBy) ?>
Available since versionsince ?>
Source CoderenderSourceLink($item->sourcePath) ?>
-description; ?> + shortDescription ?> +

description) ?>

\ No newline at end of file diff --git a/extensions/yii/apidoc/views/constSummary.php b/extensions/yii/apidoc/views/constSummary.php new file mode 100644 index 00000000000..7ed2d1af98e --- /dev/null +++ b/extensions/yii/apidoc/views/constSummary.php @@ -0,0 +1,34 @@ +constants)) { + return; +} ?> +
+

Constants

+ +

Hide inherited constants

+ + ++ + + + + + + +constants as $constant): ?> +definedBy != $item->name ? ' class="inherited"' : '' ?> id="name ?>"> + + + + + +
ConstantDescriptionDefined By
context->subjectLink($constant) ?>shortDescription ?>context->typeLink($constant->definedBy) ?>
+
\ No newline at end of file diff --git a/extensions/yii/apidoc/views/eventSummary.php b/extensions/yii/apidoc/views/eventSummary.php new file mode 100644 index 00000000000..72ebafacb11 --- /dev/null +++ b/extensions/yii/apidoc/views/eventSummary.php @@ -0,0 +1,34 @@ +events)) { + return; +} ?> +
+

Events

+ +

Hide inherited events

+ + ++ + + + + + + +events as $event): ?> +definedBy != $item->name ? ' class="inherited"' : '' ?> id="name ?>"> + + + + + +
EventDescriptionDefined By
context->subjectLink($event) ?>shortDescription ?>context->typeLink($event->definedBy) ?>
+
\ No newline at end of file diff --git a/extensions/yii/apidoc/views/index.php b/extensions/yii/apidoc/views/index.php index c329707d690..bdaa548dcba 100644 --- a/extensions/yii/apidoc/views/index.php +++ b/extensions/yii/apidoc/views/index.php @@ -23,7 +23,7 @@ ksort($items); foreach($items as $i=>$class): ?> - context->link($class, $class->name); ?> + context->typeLink($class, $class->name); ?> shortDescription; ?> diff --git a/extensions/yii/apidoc/views/methodSummary.php b/extensions/yii/apidoc/views/methodSummary.php new file mode 100644 index 00000000000..81a2c41d5ee --- /dev/null +++ b/extensions/yii/apidoc/views/methodSummary.php @@ -0,0 +1,40 @@ +getProtectedMethods()) == 0 || !$protected && count($item->getPublicMethods()) == 0) { + return; +} ?> + +
+

+ +

Hide inherited methods

+ + ++ + + + + + + +methods as $method): ?> +visibility == 'protected' || !$protected && $method->visibility != 'protected'): ?> +definedBy != $item->name ? ' class="inherited"' : '' ?> id="name ?>"> + + + + + + +
MethodDescriptionDefined By
context->subjectLink($method, $method->name.'()') ?>shortDescription ?>context->typeLink($method->definedBy) ?>
+
\ No newline at end of file diff --git a/extensions/yii/apidoc/views/propertySummary.php b/extensions/yii/apidoc/views/propertySummary.php new file mode 100644 index 00000000000..be6af105740 --- /dev/null +++ b/extensions/yii/apidoc/views/propertySummary.php @@ -0,0 +1,42 @@ +getProtectedProperties()) == 0 || !$protected && count($item->getPublicProperties()) == 0) { + return; +} ?> + +
+

+ +

Hide inherited properties

+ + ++ + + + + + + + +properties as $property): ?> +visibility == 'protected' || !$protected && $property->visibility != 'protected'): ?> +definedBy != $item->name ? ' class="inherited"' : '' ?> id="name ?>"> + + + + + + + +
PropertyTypeDescriptionDefined By
context->subjectLink($property); ?>context->typeLink($property->types); ?>shortDescription; ?>context->typeLink($property->definedBy); ?>
+
\ No newline at end of file From b494493482afda1670838e4fb2137bb46713b9f6 Mon Sep 17 00:00:00 2001 From: Carsten Brandt Date: Sun, 5 Jan 2014 17:49:46 +0100 Subject: [PATCH 06/17] ensure methods, properties and events to be unique --- extensions/yii/apidoc/models/ClassDoc.php | 4 ++-- extensions/yii/apidoc/models/Context.php | 16 ++++++---------- extensions/yii/apidoc/models/TypeDoc.php | 8 ++++---- 3 files changed, 12 insertions(+), 16 deletions(-) diff --git a/extensions/yii/apidoc/models/ClassDoc.php b/extensions/yii/apidoc/models/ClassDoc.php index 7e7e24bf26d..c0d27b5c63b 100644 --- a/extensions/yii/apidoc/models/ClassDoc.php +++ b/extensions/yii/apidoc/models/ClassDoc.php @@ -57,11 +57,11 @@ public function __construct($reflector, $config = []) if (strncmp($constantReflector->getShortName(), 'EVENT_', 6) == 0) { $event = new EventDoc($constantReflector); $event->definedBy = $this->name; - $this->events[] = $event; + $this->events[$event->name] = $event; } else { $constant = new ConstDoc($constantReflector); $constant->definedBy = $this->name; - $this->constants[] = $constant; + $this->constants[$constant->name] = $constant; } } } diff --git a/extensions/yii/apidoc/models/Context.php b/extensions/yii/apidoc/models/Context.php index 067014013c1..d16c41f91b5 100644 --- a/extensions/yii/apidoc/models/Context.php +++ b/extensions/yii/apidoc/models/Context.php @@ -132,8 +132,8 @@ public function updateReferences() if (isset($this->traits[$trait])) { $trait = $this->traits[$trait]; $trait->usedBy[] = $class->name; - $class->properties = array_merge($trait->properties, $class->properties); // TODO make unique - $class->methods = array_merge($trait->methods, $class->methods); // TODO make unique + $class->properties = array_merge($trait->properties, $class->properties); + $class->methods = array_merge($trait->methods, $class->methods); } } } @@ -153,10 +153,6 @@ protected function updateSubclassInferfacesTraits($class) $subclass = $this->classes[$subclass]; $subclass->interfaces = array_unique(array_merge($subclass->interfaces, $class->interfaces)); $subclass->traits = array_unique(array_merge($subclass->traits, $class->traits)); - $subclass->events = array_merge($class->events, $subclass->events); // TODO make unique - $subclass->constants = array_merge($class->constants, $subclass->constants); // TODO make unique - $subclass->properties = array_merge($class->properties, $subclass->properties); // TODO make unique - $subclass->methods = array_merge($class->methods, $subclass->methods); // TODO make unique $this->updateSubclassInferfacesTraits($subclass); } } @@ -169,10 +165,10 @@ protected function updateSubclassInheritance($class) { foreach($class->subclasses as $subclass) { $subclass = $this->classes[$subclass]; - $subclass->events = array_merge($class->events, $subclass->events); // TODO make unique - $subclass->constants = array_merge($class->constants, $subclass->constants); // TODO make unique - $subclass->properties = array_merge($class->properties, $subclass->properties); // TODO make unique - $subclass->methods = array_merge($class->methods, $subclass->methods); // TODO make unique + $subclass->events = array_merge($class->events, $subclass->events); + $subclass->constants = array_merge($class->constants, $subclass->constants); + $subclass->properties = array_merge($class->properties, $subclass->properties); + $subclass->methods = array_merge($class->methods, $subclass->methods); $this->updateSubclassInheritance($subclass); } } diff --git a/extensions/yii/apidoc/models/TypeDoc.php b/extensions/yii/apidoc/models/TypeDoc.php index 7ba1027e2d8..c2ccd33d587 100644 --- a/extensions/yii/apidoc/models/TypeDoc.php +++ b/extensions/yii/apidoc/models/TypeDoc.php @@ -36,9 +36,9 @@ public function getProtectedMethods() private function getFilteredMethods($visibility) { $methods = []; - foreach($this->methods as $method) { + foreach($this->methods as $name => $method) { if ($method->visibility == $visibility) { - $methods[] = $method; + $methods[$name] = $method; } } return $methods; @@ -60,9 +60,9 @@ private function getFilteredProperties($visibility) return []; } $properties = []; - foreach($this->properties as $property) { + foreach($this->properties as $name => $property) { if ($property->visibility == $visibility) { - $properties[] = $property; + $properties[$name] = $property; } } return $properties; From 8495be76c0bc74560748d6bb650444743e819db0 Mon Sep 17 00:00:00 2001 From: Carsten Brandt Date: Sun, 5 Jan 2014 18:00:13 +0100 Subject: [PATCH 07/17] renamed item -> type --- .../yii/apidoc/components/OfflineRenderer.php | 26 ++--- extensions/yii/apidoc/views/class.php | 61 ------------ extensions/yii/apidoc/views/classSummary.php | 49 ---------- extensions/yii/apidoc/views/constSummary.php | 8 +- extensions/yii/apidoc/views/eventSummary.php | 8 +- extensions/yii/apidoc/views/index.php | 6 +- extensions/yii/apidoc/views/methodSummary.php | 8 +- .../yii/apidoc/views/propertySummary.php | 8 +- extensions/yii/apidoc/views/type.php | 98 +++++++++++++++++++ 9 files changed, 130 insertions(+), 142 deletions(-) delete mode 100644 extensions/yii/apidoc/views/class.php delete mode 100644 extensions/yii/apidoc/views/classSummary.php create mode 100644 extensions/yii/apidoc/views/type.php diff --git a/extensions/yii/apidoc/components/OfflineRenderer.php b/extensions/yii/apidoc/components/OfflineRenderer.php index a3660f73f38..3f2df9013f2 100644 --- a/extensions/yii/apidoc/components/OfflineRenderer.php +++ b/extensions/yii/apidoc/components/OfflineRenderer.php @@ -28,7 +28,7 @@ class OfflineRenderer extends BaseRenderer implements ViewContextInterface public $targetDir; public $layout = '@yii/apidoc/views/layouts/offline.php'; - public $itemView = '@yii/apidoc/views/class.php'; + public $typeView = '@yii/apidoc/views/type.php'; public $indexView = '@yii/apidoc/views/index.php'; public $pageTitle = 'Yii Framework 2.0 API Documentation'; @@ -50,24 +50,24 @@ public function render($context, $controller) mkdir($dir); } - $items = array_merge($context->classes, $context->interfaces, $context->traits); - $itemCount = count($items) + 1; - Console::startProgress(0, $itemCount, 'Rendering files: ', false); + $types = array_merge($context->classes, $context->interfaces, $context->traits); + $typeCount = count($types) + 1; + Console::startProgress(0, $typeCount, 'Rendering files: ', false); $done = 0; - foreach($items as $item) { - $fileContent = $this->renderWithLayout($this->itemView, [ - 'item' => $item, + foreach($types as $type) { + $fileContent = $this->renderWithLayout($this->typeView, [ + 'type' => $type, 'docContext' => $context, ]); - file_put_contents($dir . '/' . $this->generateFileName($item->name), $fileContent); - Console::updateProgress(++$done, $itemCount); + file_put_contents($dir . '/' . $this->generateFileName($type->name), $fileContent); + Console::updateProgress(++$done, $typeCount); } $indexFileContent = $this->renderWithLayout($this->indexView, [ 'docContext' => $context, - 'items' => $items, + 'types' => $types, ]); file_put_contents($dir . '/index.html', $indexFileContent); - Console::updateProgress(++$done, $itemCount); + Console::updateProgress(++$done, $typeCount); Console::endProgress(true); $controller->stdout('done.' . PHP_EOL, Console::FG_GREEN); @@ -209,9 +209,9 @@ public function renderClasses($names) } - public function generateFileName($itemName) + public function generateFileName($typeName) { - return strtolower(str_replace('\\', '_', $itemName)) . '.html'; + return strtolower(str_replace('\\', '_', $typeName)) . '.html'; } /** diff --git a/extensions/yii/apidoc/views/class.php b/extensions/yii/apidoc/views/class.php deleted file mode 100644 index f3db8cfeba9..00000000000 --- a/extensions/yii/apidoc/views/class.php +++ /dev/null @@ -1,61 +0,0 @@ - -

isFinal) { - echo 'Final '; - } - if ($item->isAbstract) { - echo 'Abstract '; - } - echo 'Class '; - } - echo $item->name; -?>

- - -render('classSummary', ['item' => $item]) ?> - - -render('propertySummary', ['item' => $item,'protected' => false]) ?> -render('propertySummary', ['item' => $item,'protected' => true]) ?> - - -render('methodSummary', ['item' => $item, 'protected' => false]) ?> -render('methodSummary', ['item' => $item, 'protected' => true]) ?> - - -render('eventSummary', ['item' => $item]) ?> - - -render('constSummary', ['item' => $item]) ?> - -renderPartial('propertyDetails',array('class'=>$item)); ?> -renderPartial('methodDetails',array('class'=>$item)); ?> diff --git a/extensions/yii/apidoc/views/classSummary.php b/extensions/yii/apidoc/views/classSummary.php deleted file mode 100644 index 2de381181a1..00000000000 --- a/extensions/yii/apidoc/views/classSummary.php +++ /dev/null @@ -1,49 +0,0 @@ -context; - -?> - - - - - - - - interfaces)): ?> - - - traits)): ?> - - - subclasses)): ?> - - - implementedBy)): ?> - - - usedBy)): ?> - - - since)): ?> - - - - - - -
InheritancerenderInheritance($item) ?>
ImplementsrenderInterfaces($item->interfaces) ?>
Uses TraitsrenderTraits($item->traits) ?>
SubclassesrenderClasses($item->subclasses) ?>
Implemented byrenderClasses($item->implementedBy) ?>
Implemented byrenderClasses($item->usedBy) ?>
Available since versionsince ?>
Source CoderenderSourceLink($item->sourcePath) ?>
- -
- shortDescription ?> -

description) ?>

-
\ No newline at end of file diff --git a/extensions/yii/apidoc/views/constSummary.php b/extensions/yii/apidoc/views/constSummary.php index 7ed2d1af98e..abac8c4b7cf 100644 --- a/extensions/yii/apidoc/views/constSummary.php +++ b/extensions/yii/apidoc/views/constSummary.php @@ -2,11 +2,11 @@ use yii\apidoc\models\ClassDoc; /** - * @var ClassDoc $item + * @var ClassDoc $type * @var yii\web\View $this */ -if (empty($item->constants)) { +if (empty($type->constants)) { return; } ?>
@@ -23,8 +23,8 @@ ConstantDescriptionDefined By -constants as $constant): ?> -definedBy != $item->name ? ' class="inherited"' : '' ?> id="name ?>"> +constants as $constant): ?> +definedBy != $type->name ? ' class="inherited"' : '' ?> id="name ?>"> context->subjectLink($constant) ?> shortDescription ?> context->typeLink($constant->definedBy) ?> diff --git a/extensions/yii/apidoc/views/eventSummary.php b/extensions/yii/apidoc/views/eventSummary.php index 72ebafacb11..94938463250 100644 --- a/extensions/yii/apidoc/views/eventSummary.php +++ b/extensions/yii/apidoc/views/eventSummary.php @@ -2,11 +2,11 @@ use yii\apidoc\models\ClassDoc; /** - * @var ClassDoc $item + * @var ClassDoc $type * @var yii\web\View $this */ -if (empty($item->events)) { +if (empty($type->events)) { return; } ?>
@@ -23,8 +23,8 @@ EventDescriptionDefined By -events as $event): ?> -definedBy != $item->name ? ' class="inherited"' : '' ?> id="name ?>"> +events as $event): ?> +definedBy != $type->name ? ' class="inherited"' : '' ?> id="name ?>"> context->subjectLink($event) ?> shortDescription ?> context->typeLink($event->definedBy) ?> diff --git a/extensions/yii/apidoc/views/index.php b/extensions/yii/apidoc/views/index.php index bdaa548dcba..310e9af9aae 100644 --- a/extensions/yii/apidoc/views/index.php +++ b/extensions/yii/apidoc/views/index.php @@ -4,7 +4,7 @@ use yii\apidoc\models\InterfaceDoc; use yii\apidoc\models\TraitDoc; /** - * @var ClassDoc[]|InterfaceDoc[]|TraitDoc[] $items + * @var ClassDoc[]|InterfaceDoc[]|TraitDoc[] $types * @var yii\web\View $this */ @@ -20,8 +20,8 @@ ClassDescription $class): ?> +ksort($types); +foreach($types as $i=>$class): ?> context->typeLink($class, $class->name); ?> shortDescription; ?> diff --git a/extensions/yii/apidoc/views/methodSummary.php b/extensions/yii/apidoc/views/methodSummary.php index 81a2c41d5ee..19f3e6111ca 100644 --- a/extensions/yii/apidoc/views/methodSummary.php +++ b/extensions/yii/apidoc/views/methodSummary.php @@ -4,12 +4,12 @@ use yii\apidoc\models\InterfaceDoc; use yii\apidoc\models\TraitDoc; /** - * @var ClassDoc|InterfaceDoc|TraitDoc $item + * @var ClassDoc|InterfaceDoc|TraitDoc $type * @var boolean $protected * @var yii\web\View $this */ -if ($protected && count($item->getProtectedMethods()) == 0 || !$protected && count($item->getPublicMethods()) == 0) { +if ($protected && count($type->getProtectedMethods()) == 0 || !$protected && count($type->getPublicMethods()) == 0) { return; } ?> @@ -27,9 +27,9 @@ MethodDescriptionDefined By -methods as $method): ?> +methods as $method): ?> visibility == 'protected' || !$protected && $method->visibility != 'protected'): ?> -definedBy != $item->name ? ' class="inherited"' : '' ?> id="name ?>"> +definedBy != $type->name ? ' class="inherited"' : '' ?> id="name ?>"> context->subjectLink($method, $method->name.'()') ?> shortDescription ?> context->typeLink($method->definedBy) ?> diff --git a/extensions/yii/apidoc/views/propertySummary.php b/extensions/yii/apidoc/views/propertySummary.php index be6af105740..4b1e935e287 100644 --- a/extensions/yii/apidoc/views/propertySummary.php +++ b/extensions/yii/apidoc/views/propertySummary.php @@ -4,12 +4,12 @@ use yii\apidoc\models\InterfaceDoc; use yii\apidoc\models\TraitDoc; /** - * @var ClassDoc|InterfaceDoc|TraitDoc $item + * @var ClassDoc|InterfaceDoc|TraitDoc $type * @var boolean $protected * @var yii\web\View $this */ -if ($protected && count($item->getProtectedProperties()) == 0 || !$protected && count($item->getPublicProperties()) == 0) { +if ($protected && count($type->getProtectedProperties()) == 0 || !$protected && count($type->getPublicProperties()) == 0) { return; } ?> @@ -28,9 +28,9 @@ PropertyTypeDescriptionDefined By -properties as $property): ?> +properties as $property): ?> visibility == 'protected' || !$protected && $property->visibility != 'protected'): ?> -definedBy != $item->name ? ' class="inherited"' : '' ?> id="name ?>"> +definedBy != $type->name ? ' class="inherited"' : '' ?> id="name ?>"> context->subjectLink($property); ?> context->typeLink($property->types); ?> shortDescription; ?> diff --git a/extensions/yii/apidoc/views/type.php b/extensions/yii/apidoc/views/type.php new file mode 100644 index 00000000000..2c201974260 --- /dev/null +++ b/extensions/yii/apidoc/views/type.php @@ -0,0 +1,98 @@ +context; +?> +

isFinal) { + echo 'Final '; + } + if ($type->isAbstract) { + echo 'Abstract '; + } + echo 'Class '; + } + echo $type->name; +?>

+ + + + + + + + + + + interfaces)): ?> + + + traits)): ?> + + + subclasses)): ?> + + + implementedBy)): ?> + + + usedBy)): ?> + + + since)): ?> + + + + + + +
InheritancerenderInheritance($type) ?>
ImplementsrenderInterfaces($type->interfaces) ?>
Uses TraitsrenderTraits($type->traits) ?>
SubclassesrenderClasses($type->subclasses) ?>
Implemented byrenderClasses($type->implementedBy) ?>
Implemented byrenderClasses($type->usedBy) ?>
Available since versionsince ?>
Source CoderenderSourceLink($type->sourcePath) ?>
+ +
+ shortDescription ?> +

description) ?>

+
+ + +render('propertySummary', ['type' => $type,'protected' => false]) ?> +render('propertySummary', ['type' => $type,'protected' => true]) ?> + + +render('methodSummary', ['type' => $type, 'protected' => false]) ?> +render('methodSummary', ['type' => $type, 'protected' => true]) ?> + + +render('eventSummary', ['type' => $type]) ?> + + +render('constSummary', ['type' => $type]) ?> + +renderPartial('propertyDetails',array('type'=>$type)); ?> +renderPartial('methodDetails',array('type'=>$type)); ?> From 81aea73067314b0ade150c38194aa0d74865ec2d Mon Sep 17 00:00:00 2001 From: Carsten Brandt Date: Sun, 5 Jan 2014 21:11:41 +0100 Subject: [PATCH 08/17] finished offline template with all information --- .../yii/apidoc/components/OfflineRenderer.php | 97 +++++++++++++++++-- extensions/yii/apidoc/models/BaseDoc.php | 3 + extensions/yii/apidoc/models/ClassDoc.php | 24 ++++- extensions/yii/apidoc/models/ConstDoc.php | 16 +++ extensions/yii/apidoc/models/Context.php | 1 + extensions/yii/apidoc/models/EventDoc.php | 33 +++++++ extensions/yii/apidoc/models/FunctionDoc.php | 25 +++-- extensions/yii/apidoc/models/InterfaceDoc.php | 6 +- extensions/yii/apidoc/models/MethodDoc.php | 6 +- extensions/yii/apidoc/models/ParamDoc.php | 8 +- extensions/yii/apidoc/models/PropertyDoc.php | 8 +- extensions/yii/apidoc/models/TraitDoc.php | 6 +- extensions/yii/apidoc/models/TypeDoc.php | 64 ++++++++++-- extensions/yii/apidoc/views/constSummary.php | 13 +-- extensions/yii/apidoc/views/eventDetails.php | 34 +++++++ extensions/yii/apidoc/views/eventSummary.php | 14 ++- extensions/yii/apidoc/views/methodDetails.php | 59 +++++++++++ extensions/yii/apidoc/views/methodSummary.php | 2 +- .../yii/apidoc/views/propertyDetails.php | 38 ++++++++ .../yii/apidoc/views/propertySummary.php | 3 +- extensions/yii/apidoc/views/seeAlso.php | 26 +++++ extensions/yii/apidoc/views/type.php | 7 +- framework/yii/base/Exception.php | 2 +- framework/yii/db/BaseActiveRecord.php | 3 +- 24 files changed, 451 insertions(+), 47 deletions(-) create mode 100644 extensions/yii/apidoc/views/eventDetails.php create mode 100644 extensions/yii/apidoc/views/methodDetails.php create mode 100644 extensions/yii/apidoc/views/propertyDetails.php create mode 100644 extensions/yii/apidoc/views/seeAlso.php diff --git a/extensions/yii/apidoc/components/OfflineRenderer.php b/extensions/yii/apidoc/components/OfflineRenderer.php index 3f2df9013f2..bb06141ce6f 100644 --- a/extensions/yii/apidoc/components/OfflineRenderer.php +++ b/extensions/yii/apidoc/components/OfflineRenderer.php @@ -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 @@ protected function renderWithLayout($viewFile, $params) * @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) { - $type = $t; + $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 @@ public function subjectLink($subject, $title = null) 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 @@ public function renderClasses($names) 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.='
'; + $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 ? '&' : '') + . $param->name + . ($param->isOptional ? ' = ' . $param->defaultValue : ''); + } + + //signature); + + return ($method->isReturnByReference ? '&' : '') + . ($method->returnType === null ? 'void' : $this->typeLink($method->returnTypes)) + . ' ' . $method->name . '( ' + . implode(', ', $params) + . ' )'; + } public function generateFileName($typeName) { diff --git a/extensions/yii/apidoc/models/BaseDoc.php b/extensions/yii/apidoc/models/BaseDoc.php index 671501555e2..d52011c94b1 100644 --- a/extensions/yii/apidoc/models/BaseDoc.php +++ b/extensions/yii/apidoc/models/BaseDoc.php @@ -25,6 +25,9 @@ class BaseDoc extends Object public $deprecatedSince; public $deprecatedReason; + /** + * @var \phpDocumentor\Reflection\DocBlock\Tag[] + */ public $tags = []; diff --git a/extensions/yii/apidoc/models/ClassDoc.php b/extensions/yii/apidoc/models/ClassDoc.php index c0d27b5c63b..82da1d50b80 100644 --- a/extensions/yii/apidoc/models/ClassDoc.php +++ b/extensions/yii/apidoc/models/ClassDoc.php @@ -32,14 +32,33 @@ class ClassDoc extends TypeDoc public $constants = []; + /** + * @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 @@ public function __construct($reflector, $config = []) $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; diff --git a/extensions/yii/apidoc/models/ConstDoc.php b/extensions/yii/apidoc/models/ConstDoc.php index 5eb99a981a0..b1d3a93b06f 100644 --- a/extensions/yii/apidoc/models/ConstDoc.php +++ b/extensions/yii/apidoc/models/ConstDoc.php @@ -10,4 +10,20 @@ 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 diff --git a/extensions/yii/apidoc/models/Context.php b/extensions/yii/apidoc/models/Context.php index d16c41f91b5..89bfcfdc060 100644 --- a/extensions/yii/apidoc/models/Context.php +++ b/extensions/yii/apidoc/models/Context.php @@ -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])) { diff --git a/extensions/yii/apidoc/models/EventDoc.php b/extensions/yii/apidoc/models/EventDoc.php index fbdc4d800ad..78aee192782 100644 --- a/extensions/yii/apidoc/models/EventDoc.php +++ b/extensions/yii/apidoc/models/EventDoc.php @@ -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 diff --git a/extensions/yii/apidoc/models/FunctionDoc.php b/extensions/yii/apidoc/models/FunctionDoc.php index d84fd01e200..30338a6dae8 100644 --- a/extensions/yii/apidoc/models/FunctionDoc.php +++ b/extensions/yii/apidoc/models/FunctionDoc.php @@ -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 @@ public function __construct($reflector, $config = []) } 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]); } } diff --git a/extensions/yii/apidoc/models/InterfaceDoc.php b/extensions/yii/apidoc/models/InterfaceDoc.php index 8a996615a91..8aea744cbd1 100644 --- a/extensions/yii/apidoc/models/InterfaceDoc.php +++ b/extensions/yii/apidoc/models/InterfaceDoc.php @@ -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, '\\'); } diff --git a/extensions/yii/apidoc/models/MethodDoc.php b/extensions/yii/apidoc/models/MethodDoc.php index 70d67ce6064..96ca5c30acb 100644 --- a/extensions/yii/apidoc/models/MethodDoc.php +++ b/extensions/yii/apidoc/models/MethodDoc.php @@ -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(); diff --git a/extensions/yii/apidoc/models/ParamDoc.php b/extensions/yii/apidoc/models/ParamDoc.php index b5b664cb955..da5127bd641 100644 --- a/extensions/yii/apidoc/models/ParamDoc.php +++ b/extensions/yii/apidoc/models/ParamDoc.php @@ -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 diff --git a/extensions/yii/apidoc/models/PropertyDoc.php b/extensions/yii/apidoc/models/PropertyDoc.php index 3a9b447850a..68fc414f273 100644 --- a/extensions/yii/apidoc/models/PropertyDoc.php +++ b/extensions/yii/apidoc/models/PropertyDoc.php @@ -56,8 +56,12 @@ public function __construct($reflector = null, $config = []) 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; + } } } } diff --git a/extensions/yii/apidoc/models/TraitDoc.php b/extensions/yii/apidoc/models/TraitDoc.php index 13ee9b92a66..347640a1477 100644 --- a/extensions/yii/apidoc/models/TraitDoc.php +++ b/extensions/yii/apidoc/models/TraitDoc.php @@ -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, '\\'); } diff --git a/extensions/yii/apidoc/models/TypeDoc.php b/extensions/yii/apidoc/models/TypeDoc.php index c2ccd33d587..d892a3dcf85 100644 --- a/extensions/yii/apidoc/models/TypeDoc.php +++ b/extensions/yii/apidoc/models/TypeDoc.php @@ -9,6 +9,7 @@ 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 @@ private function getFilteredProperties($visibility) * @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; } diff --git a/extensions/yii/apidoc/views/constSummary.php b/extensions/yii/apidoc/views/constSummary.php index abac8c4b7cf..63dbbfb2488 100644 --- a/extensions/yii/apidoc/views/constSummary.php +++ b/extensions/yii/apidoc/views/constSummary.php @@ -21,14 +21,15 @@ - ConstantDescriptionDefined By + ConstantValueDescriptionDefined By constants as $constant): ?> -definedBy != $type->name ? ' class="inherited"' : '' ?> id="name ?>"> - context->subjectLink($constant) ?> - shortDescription ?> - context->typeLink($constant->definedBy) ?> - + definedBy != $type->name ? ' class="inherited"' : '' ?> id="name ?>"> + name ?> + value ?> + shortDescription . "\n" . $constant->description) ?> + context->typeLink($constant->definedBy) ?> +
\ No newline at end of file diff --git a/extensions/yii/apidoc/views/eventDetails.php b/extensions/yii/apidoc/views/eventDetails.php new file mode 100644 index 00000000000..9ba925efa17 --- /dev/null +++ b/extensions/yii/apidoc/views/eventDetails.php @@ -0,0 +1,34 @@ +getNativeEvents(); +if (empty($events)) { + return; +} ?> +

Event Details

+ +
+ name; ?> + + event + since)): ?> + (available since version since ?>) + + +
+ + + trigger->signature; ?> +
*/ ?> + +

description; ?>

+ + render('seeAlso', ['object' => $event]); ?> + + diff --git a/extensions/yii/apidoc/views/eventSummary.php b/extensions/yii/apidoc/views/eventSummary.php index 94938463250..56cb0fa527b 100644 --- a/extensions/yii/apidoc/views/eventSummary.php +++ b/extensions/yii/apidoc/views/eventSummary.php @@ -21,13 +21,19 @@ - EventDescriptionDefined By + EventTypeDescriptionDefined By events as $event): ?> definedBy != $type->name ? ' class="inherited"' : '' ?> id="name ?>"> - context->subjectLink($event) ?> - shortDescription ?> - context->typeLink($event->definedBy) ?> + context->subjectLink($event) ?> + context->typeLink($event->types) ?> + + shortDescription ?> + since)): ?> + (available since version since; ?>) + + + context->typeLink($event->definedBy) ?> diff --git a/extensions/yii/apidoc/views/methodDetails.php b/extensions/yii/apidoc/views/methodDetails.php new file mode 100644 index 00000000000..e0c0dbef97c --- /dev/null +++ b/extensions/yii/apidoc/views/methodDetails.php @@ -0,0 +1,59 @@ +getNativeMethods(); +if (empty($methods)) { + return; +} ?> +

Method Details

+ + + +
+ name ?>() + + method + since)): ?> + (available since version since; ?>) + + +
+ + + + params) || !empty($method->return)): ?> + params as $param): ?> + + + + + + + return)): ?> + + + + + + + +
+
+ context->renderMethodSignature($method) ?> +
+
name ?>context->typeLink($param->types) ?>description ?>
context->typeLink($method->returnTypes); ?>return; ?>
+ +renderPartial('sourceCode',array('object'=>$method)); ?> + +

shortDescription ?>

+

description) ?>

+ + render('seeAlso', ['object' => $method]); ?> + + \ No newline at end of file diff --git a/extensions/yii/apidoc/views/methodSummary.php b/extensions/yii/apidoc/views/methodSummary.php index 19f3e6111ca..e597d53931e 100644 --- a/extensions/yii/apidoc/views/methodSummary.php +++ b/extensions/yii/apidoc/views/methodSummary.php @@ -29,7 +29,7 @@ methods as $method): ?> visibility == 'protected' || !$protected && $method->visibility != 'protected'): ?> -definedBy != $type->name ? ' class="inherited"' : '' ?> id="name ?>"> +definedBy != $type->name ? ' class="inherited"' : '' ?> id="name ?>()"> context->subjectLink($method, $method->name.'()') ?> shortDescription ?> context->typeLink($method->definedBy) ?> diff --git a/extensions/yii/apidoc/views/propertyDetails.php b/extensions/yii/apidoc/views/propertyDetails.php new file mode 100644 index 00000000000..80fb34a94b2 --- /dev/null +++ b/extensions/yii/apidoc/views/propertyDetails.php @@ -0,0 +1,38 @@ +getNativeProperties(); +if (empty($properties)) { + return; +} ?> +

Property Details

+ + + +
+ name; ?> + + property + getIsReadOnly()) echo ' read-only '; ?> + getIsWriteOnly()) echo ' write-only '; ?> + since)): ?> + (available since version since; ?>) + + +
+ +
+ context->renderPropertySignature($property); ?> +
+ +

description) ?>

+ + render('seeAlso', ['object' => $property]); ?> + + diff --git a/extensions/yii/apidoc/views/propertySummary.php b/extensions/yii/apidoc/views/propertySummary.php index 4b1e935e287..ae958500d74 100644 --- a/extensions/yii/apidoc/views/propertySummary.php +++ b/extensions/yii/apidoc/views/propertySummary.php @@ -1,10 +1,9 @@ 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; +} +?> +
+

See Also

+
    + +
  • + +
+
diff --git a/extensions/yii/apidoc/views/type.php b/extensions/yii/apidoc/views/type.php index 2c201974260..a911b6309e2 100644 --- a/extensions/yii/apidoc/views/type.php +++ b/extensions/yii/apidoc/views/type.php @@ -94,5 +94,8 @@ render('constSummary', ['type' => $type]) ?> -renderPartial('propertyDetails',array('type'=>$type)); ?> -renderPartial('methodDetails',array('type'=>$type)); ?> +render('propertyDetails', ['type' => $type]) ?> +render('methodDetails', ['type' => $type]) ?> + + render('eventDetails', ['type' => $type]) ?> + diff --git a/framework/yii/base/Exception.php b/framework/yii/base/Exception.php index 7e01bd498b7..8f1af5ead9b 100644 --- a/framework/yii/base/Exception.php +++ b/framework/yii/base/Exception.php @@ -34,7 +34,7 @@ public function toArray() /** * 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) diff --git a/framework/yii/db/BaseActiveRecord.php b/framework/yii/db/BaseActiveRecord.php index cefcfe68084..dcd613e3f71 100644 --- a/framework/yii/db/BaseActiveRecord.php +++ b/framework/yii/db/BaseActiveRecord.php @@ -138,7 +138,6 @@ public static function find($q = null) * @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 @@ public function hasMany($class, $link) * 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) { From 5982544678787119b13a4f699a928dfc5cf2b68d Mon Sep 17 00:00:00 2001 From: Carsten Brandt Date: Sun, 5 Jan 2014 22:11:54 +0100 Subject: [PATCH 09/17] finished render command, added cli script --- extensions/yii/apidoc/apidoc | 49 ++++++++++++++++ extensions/yii/apidoc/apidoc.bat | 20 +++++++ ...docController.php => RenderController.php} | 58 ++++++++++++++----- extensions/yii/apidoc/composer.json | 3 +- extensions/yii/apidoc/models/Context.php | 47 ++------------- 5 files changed, 119 insertions(+), 58 deletions(-) create mode 100755 extensions/yii/apidoc/apidoc create mode 100644 extensions/yii/apidoc/apidoc.bat rename extensions/yii/apidoc/commands/{PhpdocController.php => RenderController.php} (59%) diff --git a/extensions/yii/apidoc/apidoc b/extensions/yii/apidoc/apidoc new file mode 100755 index 00000000000..91f79819027 --- /dev/null +++ b/extensions/yii/apidoc/apidoc @@ -0,0 +1,49 @@ +#!/usr/bin/env php + 'yii2-apidoc', + 'basePath' => __DIR__, + 'enableCoreCommands' => false, + 'controllerNamespace' => 'yii\\apidoc\\commands', + 'controllerPath' => '@yii/apidoc/commands', +]); +$exitCode = $application->run(); +exit($exitCode); diff --git a/extensions/yii/apidoc/apidoc.bat b/extensions/yii/apidoc/apidoc.bat new file mode 100644 index 00000000000..ae004071bc0 --- /dev/null +++ b/extensions/yii/apidoc/apidoc.bat @@ -0,0 +1,20 @@ +@echo off + +rem ------------------------------------------------------------- +rem Yii command line bootstrap script for Windows. +rem +rem @author Qiang Xue +rem @link http://www.yiiframework.com/ +rem @copyright Copyright © 2012 Yii Software LLC +rem @license http://www.yiiframework.com/license/ +rem ------------------------------------------------------------- + +@setlocal + +set YII_PATH=%~dp0 + +if "%PHP_COMMAND%" == "" set PHP_COMMAND=php.exe + +"%PHP_COMMAND%" "%YII_PATH%apidoc" %* + +@endlocal diff --git a/extensions/yii/apidoc/commands/PhpdocController.php b/extensions/yii/apidoc/commands/RenderController.php similarity index 59% rename from extensions/yii/apidoc/commands/PhpdocController.php rename to extensions/yii/apidoc/commands/RenderController.php index 9236580db45..33aee5078fc 100644 --- a/extensions/yii/apidoc/commands/PhpdocController.php +++ b/extensions/yii/apidoc/commands/RenderController.php @@ -16,30 +16,59 @@ use Yii; /** + * Command to render API Documentation files * * @author Carsten Brandt * @since 2.0 */ -class PhpdocController extends Controller +class RenderController extends Controller { - public function actionIndex($targetDir) + /** + * Renders API documentation files + * @param array $sourceDirs + * @param string $targetDir + * @return int + */ + public function actionIndex(array $sourceDirs, $targetDir) { - echo "hi\n"; - $targetDir = Yii::getAlias($targetDir); if (is_dir($targetDir) && !$this->confirm('TargetDirectory already exists. Overwrite?')) { return 2; } + if (!is_dir($targetDir)) { + mkdir($targetDir); + } - // TODO determine files to analyze $this->stdout('Searching files to process... '); - $files = $this->findFiles(YII_PATH); -// $files = array_slice($files, 0, 42); // TODO remove this line + $files = []; + foreach($sourceDirs as $source) { + foreach($this->findFiles($source) as $fileName) { + $files[$fileName] = $fileName; + } + } + $this->stdout('done.' . PHP_EOL, Console::FG_GREEN); + $context = new Context(); + + $cacheFile = $targetDir . '/cache/' . md5(serialize($files)) . '.tmp'; + if (file_exists($cacheFile)) { + $this->stdout('Loading processed data from cache... '); + $context = unserialize(file_get_contents($cacheFile)); + $this->stdout('done.' . PHP_EOL, Console::FG_GREEN); + + $this->stdout('Checking for updated files... '); + foreach($context->files as $file => $sha) { + if (sha1_file($file) === $sha) { + unset($files[$file]); + } + } + $this->stdout('done.' . PHP_EOL, Console::FG_GREEN); + } + $fileCount = count($files); + $this->stdout($fileCount . ' file' . ($fileCount == 1 ? '' : 's') . ' to update.' . PHP_EOL); Console::startProgress(0, $fileCount, 'Processing files... ', false); - $context = new Context(); $done = 0; foreach($files as $file) { $context->addFile($file); @@ -48,20 +77,22 @@ public function actionIndex($targetDir) Console::endProgress(true); $this->stdout('done.' . PHP_EOL, Console::FG_GREEN); + // save processed data to cache + if (!is_dir(dirname($cacheFile))) { + mkdir(dirname($cacheFile)); + } + file_put_contents($cacheFile, serialize($context)); + $this->stdout('Updating cross references and backlinks... '); $context->updateReferences(); $this->stdout('done.' . PHP_EOL, Console::FG_GREEN); - - // TODO LATER analyze for dead links and similar stuff - - // TODO render models + // render models $renderer = new OfflineRenderer(); $renderer->targetDir = $targetDir; $renderer->render($context, $this); } - protected function findFiles($path, $except = []) { $path = FileHelper::normalizePath($path); @@ -84,5 +115,4 @@ protected function findFiles($path, $except = []) ]; return FileHelper::findFiles($path, $options); } - } \ No newline at end of file diff --git a/extensions/yii/apidoc/composer.json b/extensions/yii/apidoc/composer.json index 30608a1cbff..bf1c4b5ecf1 100644 --- a/extensions/yii/apidoc/composer.json +++ b/extensions/yii/apidoc/composer.json @@ -25,5 +25,6 @@ "autoload": { "psr-0": { "yii\\apidoc\\": "" } }, - "target-dir": "yii/apidoc" + "target-dir": "yii/apidoc", + "bin": ["apidoc"] } diff --git a/extensions/yii/apidoc/models/Context.php b/extensions/yii/apidoc/models/Context.php index 89bfcfdc060..549c318d795 100644 --- a/extensions/yii/apidoc/models/Context.php +++ b/extensions/yii/apidoc/models/Context.php @@ -47,10 +47,7 @@ public function getType($type) public function addFile($fileName) { - if (isset($this->files[$fileName])) { - return; - } - $this->files[$fileName] = $fileName; + $this->files[$fileName] = sha1_file($fileName); $reflection = new FileReflector($fileName, true); $reflection->process(); @@ -58,54 +55,18 @@ public function addFile($fileName) foreach($reflection->getClasses() as $class) { $class = new ClassDoc($class); $class->sourceFile = $fileName; - $this->addClass($class); + $this->classes[$class->name] = $class; } foreach($reflection->getInterfaces() as $interface) { $interface = new InterfaceDoc($interface); $interface->sourceFile = $fileName; - $this->addInterface($interface); + $this->interfaces[$interface->name] = $interface; } foreach($reflection->getTraits() as $trait) { $trait = new TraitDoc($trait); $trait->sourceFile = $fileName; - $this->addTrait($trait); - } - } - - /** - * @param ClassDoc $class - * @throws \yii\base\Exception when class is already part of this context - */ - public function addClass($class) - { - if (isset($this->classes[$class->name])) { - throw new Exception('Duplicate class definition: ' . $class->name . ' in file ' . $class->sourceFile . '.'); - } - $this->classes[$class->name] = $class; - } - - /** - * @param InterfaceDoc $interface - * @throws \yii\base\Exception when interface is already part of this context - */ - public function addInterface($interface) - { - if (isset($this->interfaces[$interface->name])) { - throw new Exception('Duplicate interface definition: ' . $interface->name . ' in file ' . $interface->sourceFile); - } - $this->interfaces[$interface->name] = $interface; - } - - /** - * @param TraitDoc $trait - * @throws \yii\base\Exception when trait is already part of this context - */ - public function addTrait($trait) - { - if (isset($this->traits[$trait->name])) { - throw new Exception('Duplicate trait definition: ' . $trait->name . ' in file ' . $trait->sourceFile); + $this->traits[$trait->name] = $trait; } - $this->traits[$trait->name] = $trait; } public function updateReferences() From f7e00887d6881b7c232e690e6fba1324cd434a32 Mon Sep 17 00:00:00 2001 From: Carsten Brandt Date: Mon, 6 Jan 2014 00:30:39 +0100 Subject: [PATCH 10/17] restructured apidoc templates --- extensions/yii/apidoc/README.md | 10 ++ extensions/yii/apidoc/apidoc | 2 +- .../yii/apidoc/commands/RenderController.php | 36 +++++++- extensions/yii/apidoc/models/BaseDoc.php | 5 + extensions/yii/apidoc/models/ClassDoc.php | 4 +- extensions/yii/apidoc/models/ConstDoc.php | 5 + extensions/yii/apidoc/models/Context.php | 6 +- extensions/yii/apidoc/models/EventDoc.php | 5 + extensions/yii/apidoc/models/FunctionDoc.php | 5 + extensions/yii/apidoc/models/InterfaceDoc.php | 5 + extensions/yii/apidoc/models/MethodDoc.php | 5 + extensions/yii/apidoc/models/ParamDoc.php | 5 + extensions/yii/apidoc/models/PropertyDoc.php | 5 + extensions/yii/apidoc/models/TraitDoc.php | 5 + extensions/yii/apidoc/models/TypeDoc.php | 5 + .../BaseRenderer.php | 31 +++---- .../yii/apidoc/templates/html/README.md | 4 + .../html/Renderer.php} | 92 +++++++++++++------ .../html}/views/constSummary.php | 0 .../html}/views/eventDetails.php | 0 .../html}/views/eventSummary.php | 0 .../html}/views/methodDetails.php | 0 .../html}/views/methodSummary.php | 0 .../html}/views/propertyDetails.php | 0 .../html}/views/propertySummary.php | 0 .../{ => templates/html}/views/seeAlso.php | 0 .../{ => templates/html}/views/type.php | 18 ++-- .../yii/apidoc/templates/offline/Renderer.php | 44 +++++++++ .../offline}/assets/css/api.css | 0 .../offline}/assets/css/style.css | 0 .../{ => templates/offline}/views/index.php | 0 .../offline/views}/offline.php | 1 + 32 files changed, 238 insertions(+), 60 deletions(-) rename extensions/yii/apidoc/{components => templates}/BaseRenderer.php (50%) create mode 100644 extensions/yii/apidoc/templates/html/README.md rename extensions/yii/apidoc/{components/OfflineRenderer.php => templates/html/Renderer.php} (79%) rename extensions/yii/apidoc/{ => templates/html}/views/constSummary.php (100%) rename extensions/yii/apidoc/{ => templates/html}/views/eventDetails.php (100%) rename extensions/yii/apidoc/{ => templates/html}/views/eventSummary.php (100%) rename extensions/yii/apidoc/{ => templates/html}/views/methodDetails.php (100%) rename extensions/yii/apidoc/{ => templates/html}/views/methodSummary.php (100%) rename extensions/yii/apidoc/{ => templates/html}/views/propertyDetails.php (100%) rename extensions/yii/apidoc/{ => templates/html}/views/propertySummary.php (100%) rename extensions/yii/apidoc/{ => templates/html}/views/seeAlso.php (100%) rename extensions/yii/apidoc/{ => templates/html}/views/type.php (75%) create mode 100644 extensions/yii/apidoc/templates/offline/Renderer.php rename extensions/yii/apidoc/{ => templates/offline}/assets/css/api.css (100%) rename extensions/yii/apidoc/{ => templates/offline}/assets/css/style.css (100%) rename extensions/yii/apidoc/{ => templates/offline}/views/index.php (100%) rename extensions/yii/apidoc/{views/layouts => templates/offline/views}/offline.php (96%) diff --git a/extensions/yii/apidoc/README.md b/extensions/yii/apidoc/README.md index b733d7dba9d..7d20c71b42c 100644 --- a/extensions/yii/apidoc/README.md +++ b/extensions/yii/apidoc/README.md @@ -25,4 +25,14 @@ to the require section of your composer.json. Usage ----- +TDB + +Creating your own templates +--------------------------- + +TDB + +Using the model layer +--------------------- + TDB \ No newline at end of file diff --git a/extensions/yii/apidoc/apidoc b/extensions/yii/apidoc/apidoc index 91f79819027..c19d6423343 100755 --- a/extensions/yii/apidoc/apidoc +++ b/extensions/yii/apidoc/apidoc @@ -32,7 +32,7 @@ foreach($yiiDirs as $dir) { } } if (!class_exists('Yii')) { - echo "\nThe Yii Framework 2.0 does not seem to be installed. Try running composer install.\n\n"; + echo PHP_EOL . "The Yii Framework 2.0 does not seem to be installed. Try running composer install." . PHP_EOL . PHP_EOL; exit(1); } diff --git a/extensions/yii/apidoc/commands/RenderController.php b/extensions/yii/apidoc/commands/RenderController.php index 33aee5078fc..8a46de3938e 100644 --- a/extensions/yii/apidoc/commands/RenderController.php +++ b/extensions/yii/apidoc/commands/RenderController.php @@ -8,6 +8,8 @@ namespace yii\apidoc\commands; use phpDocumentor\Reflection\FileReflector; +use TokenReflection\ReflectionFile; +use yii\apidoc\templates\BaseRenderer; use yii\console\Controller; use yii\helpers\Console; use yii\helpers\FileHelper; @@ -23,6 +25,8 @@ */ class RenderController extends Controller { + public $template = 'offline'; + /** * Renders API documentation files * @param array $sourceDirs @@ -31,7 +35,7 @@ class RenderController extends Controller */ public function actionIndex(array $sourceDirs, $targetDir) { - $targetDir = Yii::getAlias($targetDir); + $targetDir = rtrim(Yii::getAlias($targetDir), '\\/'); if (is_dir($targetDir) && !$this->confirm('TargetDirectory already exists. Overwrite?')) { return 2; } @@ -39,6 +43,9 @@ public function actionIndex(array $sourceDirs, $targetDir) mkdir($targetDir); } + $renderer = $this->findRenderer(); + $renderer->targetDir = $targetDir; + $this->stdout('Searching files to process... '); $files = []; foreach($sourceDirs as $source) { @@ -88,11 +95,26 @@ public function actionIndex(array $sourceDirs, $targetDir) $this->stdout('done.' . PHP_EOL, Console::FG_GREEN); // render models - $renderer = new OfflineRenderer(); - $renderer->targetDir = $targetDir; $renderer->render($context, $this); } + /** + * @return BaseRenderer + */ + protected function findRenderer() + { + $file = Yii::getAlias('@yii/apidoc/templates/' . $this->template . '/Renderer.php'); + $reflection = new FileReflector($file, true); + $reflection->process(); + $classes = $reflection->getClasses(); + if (empty($classes)) { + $this->stderr('Renderer not found.' . PHP_EOL); + } + $rendererClass = reset($classes)->getName(); + require($file); + return new $rendererClass(); + } + protected function findFiles($path, $except = []) { $path = FileHelper::normalizePath($path); @@ -115,4 +137,12 @@ protected function findFiles($path, $except = []) ]; return FileHelper::findFiles($path, $options); } + + /** + * @inheritdoc + */ + public function globalOptions() + { + return array_merge(parent::globalOptions(), ['template']); + } } \ No newline at end of file diff --git a/extensions/yii/apidoc/models/BaseDoc.php b/extensions/yii/apidoc/models/BaseDoc.php index d52011c94b1..b595dcc62dc 100644 --- a/extensions/yii/apidoc/models/BaseDoc.php +++ b/extensions/yii/apidoc/models/BaseDoc.php @@ -11,6 +11,11 @@ use phpDocumentor\Reflection\DocBlock\Tag\SinceTag; use yii\base\Object; +/** + * + * @author Carsten Brandt + * @since 2.0 + */ class BaseDoc extends Object { public $name; diff --git a/extensions/yii/apidoc/models/ClassDoc.php b/extensions/yii/apidoc/models/ClassDoc.php index 82da1d50b80..a70ae8530a9 100644 --- a/extensions/yii/apidoc/models/ClassDoc.php +++ b/extensions/yii/apidoc/models/ClassDoc.php @@ -8,7 +8,9 @@ namespace yii\apidoc\models; /** - * Class ClassDoc + * + * @author Carsten Brandt + * @since 2.0 */ class ClassDoc extends TypeDoc { diff --git a/extensions/yii/apidoc/models/ConstDoc.php b/extensions/yii/apidoc/models/ConstDoc.php index b1d3a93b06f..a0fbf08accc 100644 --- a/extensions/yii/apidoc/models/ConstDoc.php +++ b/extensions/yii/apidoc/models/ConstDoc.php @@ -7,6 +7,11 @@ namespace yii\apidoc\models; +/** + * + * @author Carsten Brandt + * @since 2.0 + */ class ConstDoc extends BaseDoc { public $definedBy; diff --git a/extensions/yii/apidoc/models/Context.php b/extensions/yii/apidoc/models/Context.php index 549c318d795..53781954de0 100644 --- a/extensions/yii/apidoc/models/Context.php +++ b/extensions/yii/apidoc/models/Context.php @@ -7,11 +7,15 @@ namespace yii\apidoc\models; - use phpDocumentor\Reflection\FileReflector; use yii\base\Component; use yii\base\Exception; +/** + * + * @author Carsten Brandt + * @since 2.0 + */ class Context extends Component { /** diff --git a/extensions/yii/apidoc/models/EventDoc.php b/extensions/yii/apidoc/models/EventDoc.php index 78aee192782..41771c52c5f 100644 --- a/extensions/yii/apidoc/models/EventDoc.php +++ b/extensions/yii/apidoc/models/EventDoc.php @@ -10,6 +10,11 @@ use phpDocumentor\Reflection\DocBlock\Tag\ParamTag; use phpDocumentor\Reflection\DocBlock\Tag\ReturnTag; +/** + * + * @author Carsten Brandt + * @since 2.0 + */ class EventDoc extends ConstDoc { public $type; diff --git a/extensions/yii/apidoc/models/FunctionDoc.php b/extensions/yii/apidoc/models/FunctionDoc.php index 30338a6dae8..1120f77b2e7 100644 --- a/extensions/yii/apidoc/models/FunctionDoc.php +++ b/extensions/yii/apidoc/models/FunctionDoc.php @@ -13,6 +13,11 @@ use phpDocumentor\Reflection\DocBlock\Tag\ThrowsTag; use yii\base\Exception; +/** + * + * @author Carsten Brandt + * @since 2.0 + */ class FunctionDoc extends BaseDoc { /** diff --git a/extensions/yii/apidoc/models/InterfaceDoc.php b/extensions/yii/apidoc/models/InterfaceDoc.php index 8aea744cbd1..57cd9ce21f8 100644 --- a/extensions/yii/apidoc/models/InterfaceDoc.php +++ b/extensions/yii/apidoc/models/InterfaceDoc.php @@ -7,6 +7,11 @@ namespace yii\apidoc\models; +/** + * + * @author Carsten Brandt + * @since 2.0 + */ class InterfaceDoc extends TypeDoc { public $parentInterfaces = []; diff --git a/extensions/yii/apidoc/models/MethodDoc.php b/extensions/yii/apidoc/models/MethodDoc.php index 96ca5c30acb..0f7288fbf5d 100644 --- a/extensions/yii/apidoc/models/MethodDoc.php +++ b/extensions/yii/apidoc/models/MethodDoc.php @@ -7,6 +7,11 @@ namespace yii\apidoc\models; +/** + * + * @author Carsten Brandt + * @since 2.0 + */ class MethodDoc extends FunctionDoc { public $isAbstract; diff --git a/extensions/yii/apidoc/models/ParamDoc.php b/extensions/yii/apidoc/models/ParamDoc.php index da5127bd641..0d4c162dd3e 100644 --- a/extensions/yii/apidoc/models/ParamDoc.php +++ b/extensions/yii/apidoc/models/ParamDoc.php @@ -9,6 +9,11 @@ use yii\base\Object; +/** + * + * @author Carsten Brandt + * @since 2.0 + */ class ParamDoc extends Object { public $name; diff --git a/extensions/yii/apidoc/models/PropertyDoc.php b/extensions/yii/apidoc/models/PropertyDoc.php index 68fc414f273..cf17b0d8776 100644 --- a/extensions/yii/apidoc/models/PropertyDoc.php +++ b/extensions/yii/apidoc/models/PropertyDoc.php @@ -9,6 +9,11 @@ use phpDocumentor\Reflection\DocBlock\Tag\VarTag; +/** + * + * @author Carsten Brandt + * @since 2.0 + */ class PropertyDoc extends BaseDoc { public $visibility; diff --git a/extensions/yii/apidoc/models/TraitDoc.php b/extensions/yii/apidoc/models/TraitDoc.php index 347640a1477..37f17998061 100644 --- a/extensions/yii/apidoc/models/TraitDoc.php +++ b/extensions/yii/apidoc/models/TraitDoc.php @@ -7,6 +7,11 @@ namespace yii\apidoc\models; +/** + * + * @author Carsten Brandt + * @since 2.0 + */ class TraitDoc extends TypeDoc { // classes using the trait diff --git a/extensions/yii/apidoc/models/TypeDoc.php b/extensions/yii/apidoc/models/TypeDoc.php index d892a3dcf85..9ceaf269420 100644 --- a/extensions/yii/apidoc/models/TypeDoc.php +++ b/extensions/yii/apidoc/models/TypeDoc.php @@ -11,6 +11,11 @@ use yii\base\Exception; use yii\helpers\StringHelper; +/** + * + * @author Carsten Brandt + * @since 2.0 + */ class TypeDoc extends BaseDoc { public $authors = []; diff --git a/extensions/yii/apidoc/components/BaseRenderer.php b/extensions/yii/apidoc/templates/BaseRenderer.php similarity index 50% rename from extensions/yii/apidoc/components/BaseRenderer.php rename to extensions/yii/apidoc/templates/BaseRenderer.php index 5b8fb693bab..4f29e43aab0 100644 --- a/extensions/yii/apidoc/components/BaseRenderer.php +++ b/extensions/yii/apidoc/templates/BaseRenderer.php @@ -5,33 +5,28 @@ * @license http://www.yiiframework.com/license/ */ -namespace yii\apidoc\components; +namespace yii\apidoc\templates; use Yii; use yii\base\Component; use yii\console\Controller; use yii\apidoc\models\Context; +use yii\web\AssetManager; use yii\web\View; +/** + * Base class for all API documentation renderers + * + * @author Carsten Brandt + * @since 2.0 + */ abstract class BaseRenderer extends Component { - - private $_view; - - - public function getView() - { - if ($this->_view === null) { - $this->_view = new View(); - } - return $this->_view; - } - /** - * @param Context $context - * @param Controller $controller - * @return mixed + * Renders a given [[Context]]. + * + * @param Context $context the api documentation context to render. + * @param Controller $controller the apidoc controller instance. Can be used to control output. */ public abstract function render($context, $controller); - -} \ No newline at end of file +} \ No newline at end of file diff --git a/extensions/yii/apidoc/templates/html/README.md b/extensions/yii/apidoc/templates/html/README.md new file mode 100644 index 00000000000..90e3b35922f --- /dev/null +++ b/extensions/yii/apidoc/templates/html/README.md @@ -0,0 +1,4 @@ +The html API doc template +------------------------- + +This templates provides view files and a Renderer class that can be reused in other html templates. \ No newline at end of file diff --git a/extensions/yii/apidoc/components/OfflineRenderer.php b/extensions/yii/apidoc/templates/html/Renderer.php similarity index 79% rename from extensions/yii/apidoc/components/OfflineRenderer.php rename to extensions/yii/apidoc/templates/html/Renderer.php index bb06141ce6f..bf730c76bb9 100644 --- a/extensions/yii/apidoc/components/OfflineRenderer.php +++ b/extensions/yii/apidoc/templates/html/Renderer.php @@ -5,8 +5,7 @@ * @license http://www.yiiframework.com/license/ */ -namespace yii\apidoc\components; - +namespace yii\apidoc\templates\html; use yii\apidoc\models\BaseDoc; use yii\apidoc\models\ConstDoc; @@ -14,35 +13,80 @@ use yii\apidoc\models\MethodDoc; use yii\apidoc\models\PropertyDoc; use yii\apidoc\models\TypeDoc; +use yii\apidoc\models\ClassDoc; +use yii\apidoc\models\Context; +use yii\apidoc\models\InterfaceDoc; +use yii\apidoc\models\TraitDoc; +use yii\apidoc\templates\BaseRenderer; use yii\base\ViewContextInterface; use yii\console\Controller; use yii\helpers\Console; -use yii\helpers\FileHelper; use yii\helpers\Html; -use yii\apidoc\models\ClassDoc; -use yii\apidoc\models\Context; use Yii; -use yii\apidoc\models\InterfaceDoc; -use yii\apidoc\models\TraitDoc; +use yii\web\AssetManager; +use yii\web\View; -class OfflineRenderer extends BaseRenderer implements ViewContextInterface +/** + * The base class for HTML API documentation renderers. + * + * @author Carsten Brandt + * @since 2.0 + */ +abstract class Renderer extends BaseRenderer implements ViewContextInterface { + /** + * @var string directory to use for output of html files. Can be a path alias. + */ public $targetDir; - - public $layout = '@yii/apidoc/views/layouts/offline.php'; - public $typeView = '@yii/apidoc/views/type.php'; - public $indexView = '@yii/apidoc/views/index.php'; - + /** + * @var string string to use as the title of the generated page. + */ public $pageTitle = 'Yii Framework 2.0 API Documentation'; - /** - * @var Context + * @var string path or alias of the layout file to use. + */ + public $layout; + /** + * @var string path or alias of the view file to use for rendering types (classes, interfaces, traits). + */ + public $typeView = '@yii/apidoc/templates/html/views/type.php'; + /** + * @var string path or alias of the view file to use for rendering the index page. + */ + public $indexView = '@yii/apidoc/templates/html/views/index.php'; + /** + * @var Context the [[Context]] currently being rendered. */ protected $context; + /** + * @var View + */ + private $_view; + + /** + * @return View the view instance + */ + public function getView() + { + if ($this->_view === null) { + $this->_view = new View(); + $assetPath = Yii::getAlias($this->targetDir) . '/assets'; + if (!is_dir($assetPath)) { + mkdir($assetPath); + } + $this->_view->assetManager = new AssetManager([ + 'basePath' => $assetPath, + 'baseUrl' => '/assets', + ]); + } + return $this->_view; + } /** - * @param Context $context - * @param Controller $controller + * Renders a given [[Context]]. + * + * @param Context $context the api documentation context to render. + * @param Controller $controller the apidoc controller instance. Can be used to control output. */ public function render($context, $controller) { @@ -72,11 +116,6 @@ public function render($context, $controller) Console::updateProgress(++$done, $typeCount); Console::endProgress(true); $controller->stdout('done.' . PHP_EOL, Console::FG_GREEN); - - $controller->stdout('Copying asset files... '); - FileHelper::copyDirectory(__DIR__ . '/../assets/css', $dir . '/css'); - $controller->stdout('done.' . PHP_EOL, Console::FG_GREEN); - } protected function renderWithLayout($viewFile, $params) @@ -93,7 +132,7 @@ protected function renderWithLayout($viewFile, $params) /** * creates a link to a type (class, interface or trait) * @param ClassDoc|InterfaceDoc|TraitDoc $types - * @param string $title + * @param BaseDoc $context * @return string */ public function typeLink($types, $context = null) @@ -161,6 +200,7 @@ public function subjectLink($subject, $title = null) */ private function resolveNamespace($context) { + // TODO use phpdoc Context for this if ($context === null) { return ''; } @@ -285,8 +325,6 @@ public function renderMethodSignature($method) . ($param->isOptional ? ' = ' . $param->defaultValue : ''); } - //signature); - return ($method->isReturnByReference ? '&' : '') . ($method->returnType === null ? 'void' : $this->typeLink($method->returnTypes)) . ' ' . $method->name . '( ' @@ -294,7 +332,7 @@ public function renderMethodSignature($method) . ' )'; } - public function generateFileName($typeName) + protected function generateFileName($typeName) { return strtolower(str_replace('\\', '_', $typeName)) . '.html'; } @@ -306,6 +344,6 @@ public function generateFileName($typeName) */ public function findViewFile($view) { - return Yii::getAlias('@yii/apidoc/views/' . $view); + return Yii::getAlias('@yii/apidoc/templates/html/views/' . $view); } } \ No newline at end of file diff --git a/extensions/yii/apidoc/views/constSummary.php b/extensions/yii/apidoc/templates/html/views/constSummary.php similarity index 100% rename from extensions/yii/apidoc/views/constSummary.php rename to extensions/yii/apidoc/templates/html/views/constSummary.php diff --git a/extensions/yii/apidoc/views/eventDetails.php b/extensions/yii/apidoc/templates/html/views/eventDetails.php similarity index 100% rename from extensions/yii/apidoc/views/eventDetails.php rename to extensions/yii/apidoc/templates/html/views/eventDetails.php diff --git a/extensions/yii/apidoc/views/eventSummary.php b/extensions/yii/apidoc/templates/html/views/eventSummary.php similarity index 100% rename from extensions/yii/apidoc/views/eventSummary.php rename to extensions/yii/apidoc/templates/html/views/eventSummary.php diff --git a/extensions/yii/apidoc/views/methodDetails.php b/extensions/yii/apidoc/templates/html/views/methodDetails.php similarity index 100% rename from extensions/yii/apidoc/views/methodDetails.php rename to extensions/yii/apidoc/templates/html/views/methodDetails.php diff --git a/extensions/yii/apidoc/views/methodSummary.php b/extensions/yii/apidoc/templates/html/views/methodSummary.php similarity index 100% rename from extensions/yii/apidoc/views/methodSummary.php rename to extensions/yii/apidoc/templates/html/views/methodSummary.php diff --git a/extensions/yii/apidoc/views/propertyDetails.php b/extensions/yii/apidoc/templates/html/views/propertyDetails.php similarity index 100% rename from extensions/yii/apidoc/views/propertyDetails.php rename to extensions/yii/apidoc/templates/html/views/propertyDetails.php diff --git a/extensions/yii/apidoc/views/propertySummary.php b/extensions/yii/apidoc/templates/html/views/propertySummary.php similarity index 100% rename from extensions/yii/apidoc/views/propertySummary.php rename to extensions/yii/apidoc/templates/html/views/propertySummary.php diff --git a/extensions/yii/apidoc/views/seeAlso.php b/extensions/yii/apidoc/templates/html/views/seeAlso.php similarity index 100% rename from extensions/yii/apidoc/views/seeAlso.php rename to extensions/yii/apidoc/templates/html/views/seeAlso.php diff --git a/extensions/yii/apidoc/views/type.php b/extensions/yii/apidoc/templates/html/views/type.php similarity index 75% rename from extensions/yii/apidoc/views/type.php rename to extensions/yii/apidoc/templates/html/views/type.php index a911b6309e2..50959dc628b 100644 --- a/extensions/yii/apidoc/views/type.php +++ b/extensions/yii/apidoc/templates/html/views/type.php @@ -81,21 +81,21 @@ -render('propertySummary', ['type' => $type,'protected' => false]) ?> -render('propertySummary', ['type' => $type,'protected' => true]) ?> +render('@yii/apidoc/templates/html/views/propertySummary', ['type' => $type,'protected' => false]) ?> +render('@yii/apidoc/templates/html/views/propertySummary', ['type' => $type,'protected' => true]) ?> -render('methodSummary', ['type' => $type, 'protected' => false]) ?> -render('methodSummary', ['type' => $type, 'protected' => true]) ?> +render('@yii/apidoc/templates/html/views/methodSummary', ['type' => $type, 'protected' => false]) ?> +render('@yii/apidoc/templates/html/views/methodSummary', ['type' => $type, 'protected' => true]) ?> -render('eventSummary', ['type' => $type]) ?> +render('@yii/apidoc/templates/html/views/eventSummary', ['type' => $type]) ?> -render('constSummary', ['type' => $type]) ?> +render('@yii/apidoc/templates/html/views/constSummary', ['type' => $type]) ?> -render('propertyDetails', ['type' => $type]) ?> -render('methodDetails', ['type' => $type]) ?> +render('@yii/apidoc/templates/html/views/propertyDetails', ['type' => $type]) ?> +render('@yii/apidoc/templates/html/views/methodDetails', ['type' => $type]) ?> - render('eventDetails', ['type' => $type]) ?> + render('@yii/apidoc/templates/html/views/eventDetails', ['type' => $type]) ?> diff --git a/extensions/yii/apidoc/templates/offline/Renderer.php b/extensions/yii/apidoc/templates/offline/Renderer.php new file mode 100644 index 00000000000..1e544b7190f --- /dev/null +++ b/extensions/yii/apidoc/templates/offline/Renderer.php @@ -0,0 +1,44 @@ + + * @since 2.0 + */ +class Renderer extends \yii\apidoc\templates\html\Renderer +{ + public $layout = '@yii/apidoc/templates/offline/views/offline.php'; + public $indexView = '@yii/apidoc/templates/offline/views/index.php'; + + public $pageTitle = 'Yii Framework 2.0 API Documentation'; + + /** + * Renders a given [[Context]]. + * + * @param Context $context the api documentation context to render. + * @param Controller $controller the apidoc controller instance. Can be used to control output. + */ + public function render($context, $controller) + { + parent::render($context, $controller); + + $dir = Yii::getAlias($this->targetDir); + + $controller->stdout('Copying asset files... '); + FileHelper::copyDirectory(__DIR__ . '/assets/css', $dir . '/css'); + $controller->stdout('done.' . PHP_EOL, Console::FG_GREEN); + } + +} \ No newline at end of file diff --git a/extensions/yii/apidoc/assets/css/api.css b/extensions/yii/apidoc/templates/offline/assets/css/api.css similarity index 100% rename from extensions/yii/apidoc/assets/css/api.css rename to extensions/yii/apidoc/templates/offline/assets/css/api.css diff --git a/extensions/yii/apidoc/assets/css/style.css b/extensions/yii/apidoc/templates/offline/assets/css/style.css similarity index 100% rename from extensions/yii/apidoc/assets/css/style.css rename to extensions/yii/apidoc/templates/offline/assets/css/style.css diff --git a/extensions/yii/apidoc/views/index.php b/extensions/yii/apidoc/templates/offline/views/index.php similarity index 100% rename from extensions/yii/apidoc/views/index.php rename to extensions/yii/apidoc/templates/offline/views/index.php diff --git a/extensions/yii/apidoc/views/layouts/offline.php b/extensions/yii/apidoc/templates/offline/views/offline.php similarity index 96% rename from extensions/yii/apidoc/views/layouts/offline.php rename to extensions/yii/apidoc/templates/offline/views/offline.php index 809de752b0c..36b2487e203 100644 --- a/extensions/yii/apidoc/views/layouts/offline.php +++ b/extensions/yii/apidoc/templates/offline/views/offline.php @@ -35,6 +35,7 @@ All Rights Reserved.
+ head(); ?> <?php echo $this->context->pageTitle; ?> @@ -35,16 +34,22 @@ All Rights Reserved.
- diff --git a/framework/yii/helpers/BaseHtml.php b/framework/yii/helpers/BaseHtml.php index b3a88c1d822..b25ffa4a534 100644 --- a/framework/yii/helpers/BaseHtml.php +++ b/framework/yii/helpers/BaseHtml.php @@ -1471,7 +1471,7 @@ public static function url($url) return Yii::$app->getRequest()->getUrl(); } else { $url = Yii::getAlias($url); - if ($url !== '' && ($url[0] === '/' || $url[0] === '#' || strpos($url, '://'))) { + if ($url !== '' && ($url[0] === '/' || $url[0] === '#' || strpos($url, '://') || !strncmp($url, './', 2))) { return $url; } else { return Yii::$app->getRequest()->getBaseUrl() . '/' . $url; From 55f9111f471bd6d051336fd7892505752358297f Mon Sep 17 00:00:00 2001 From: Carsten Brandt Date: Mon, 6 Jan 2014 03:01:03 +0100 Subject: [PATCH 12/17] markdown support and links --- extensions/yii/apidoc/helpers/Markdown.php | 76 +++++++++++++++++++ extensions/yii/apidoc/models/BaseDoc.php | 9 ++- extensions/yii/apidoc/models/ClassDoc.php | 18 +++++ extensions/yii/apidoc/models/FunctionDoc.php | 2 +- extensions/yii/apidoc/models/TypeDoc.php | 24 ++++++ .../yii/apidoc/templates/BaseRenderer.php | 33 +++++++- .../yii/apidoc/templates/html/Renderer.php | 17 +++-- .../templates/html/views/constSummary.php | 3 +- .../templates/html/views/eventDetails.php | 3 +- .../templates/html/views/eventSummary.php | 3 +- .../templates/html/views/methodDetails.php | 9 ++- .../templates/html/views/methodSummary.php | 15 ++-- .../templates/html/views/propertyDetails.php | 3 +- .../templates/html/views/propertySummary.php | 17 +++-- .../apidoc/templates/html/views/seeAlso.php | 9 ++- .../yii/apidoc/templates/html/views/type.php | 7 +- .../templates/offline/assets/css/api.css | 6 ++ 17 files changed, 216 insertions(+), 38 deletions(-) create mode 100644 extensions/yii/apidoc/helpers/Markdown.php diff --git a/extensions/yii/apidoc/helpers/Markdown.php b/extensions/yii/apidoc/helpers/Markdown.php new file mode 100644 index 00000000000..2bbad50ccef --- /dev/null +++ b/extensions/yii/apidoc/helpers/Markdown.php @@ -0,0 +1,76 @@ + + */ + +namespace yii\apidoc\helpers; + + +use phpDocumentor\Reflection\DocBlock\Type\Collection; +use yii\apidoc\models\MethodDoc; +use yii\apidoc\models\TypeDoc; +use yii\apidoc\templates\BaseRenderer; +use yii\helpers\Html; + +class Markdown extends \yii\helpers\Markdown +{ + /** + * @var BaseRenderer + */ + public static $renderer; + + /** + * Converts markdown into HTML + * + * @param string $content + * @param TypeDoc $context + * @return string + */ + public static function process($content, $context) + { + $content = trim(parent::process($content, [])); + if (!strncmp($content, '

', 3) && substr($content, -4, 4) == '

') { + $content = substr($content, 3, -4); + } + + $content = preg_replace_callback('/\[\[([\w\d\\\\\(\):]+)(\|[\w\d ]*)?\]\]/xm', function($matches) use ($context) { + $object = $matches[1]; + $title = (empty($matches[2]) || $matches[2] == '|') ? null : substr($matches[2], 1); + + if (($pos = strpos($object, '::')) !== false) { + $typeName = substr($object, 0, $pos); + $subjectName = substr($object, $pos + 2); + // Collection resolves relative types + $typeName = (new Collection([$typeName], $context->phpDocContext))->__toString(); + $type = static::$renderer->context->getType($typeName); + if ($type === null) { + return '' . $typeName . '::' . $subjectName . ''; + } else { + if (($subject = $type->findSubject($subjectName)) !== null) { + if ($title === null) { + $title = $type->name . '::' . $subject->name; + if ($subject instanceof MethodDoc) { + $title .= '()'; + } + } + return static::$renderer->subjectLink($subject, $title); + } else { + return '' . $type->name . '::' . $subjectName . ''; + } + } + } elseif (($subject = $context->findSubject($object)) !== null) { + return static::$renderer->subjectLink($subject, $title); + } + // Collection resolves relative types + $object = (new Collection([$object], $context->phpDocContext))->__toString(); + if (($type = static::$renderer->context->getType($object)) !== null) { + return static::$renderer->typeLink($type, $title); + } + return '' . $object . ''; + }, $content); + + return $content; + } +} \ No newline at end of file diff --git a/extensions/yii/apidoc/models/BaseDoc.php b/extensions/yii/apidoc/models/BaseDoc.php index b595dcc62dc..c470ab56180 100644 --- a/extensions/yii/apidoc/models/BaseDoc.php +++ b/extensions/yii/apidoc/models/BaseDoc.php @@ -18,6 +18,11 @@ */ class BaseDoc extends Object { + /** + * @var \phpDocumentor\Reflection\DocBlock\Context + */ + public $phpDocContext; + public $name; public $sourceFile; @@ -55,9 +60,11 @@ public function __construct($reflector = null, $config = []) $docblock = $reflector->getDocBlock(); if ($docblock !== null) { - $this->shortDescription = $docblock->getShortDescription(); + $this->shortDescription = ucfirst($docblock->getShortDescription()); $this->description = $docblock->getLongDescription(); + $this->phpDocContext = $docblock->getContext(); + $this->tags = $docblock->getTags(); foreach($this->tags as $i => $tag) { if ($tag instanceof SinceTag) { diff --git a/extensions/yii/apidoc/models/ClassDoc.php b/extensions/yii/apidoc/models/ClassDoc.php index a70ae8530a9..d9b17a48093 100644 --- a/extensions/yii/apidoc/models/ClassDoc.php +++ b/extensions/yii/apidoc/models/ClassDoc.php @@ -34,6 +34,24 @@ class ClassDoc extends TypeDoc public $constants = []; + public function findSubject($subjectName) + { + if (($subject = parent::findSubject($subjectName)) !== null) { + return $subject; + } + foreach($this->events as $name => $event) { + if ($subjectName == $name) { + return $event; + } + } + foreach($this->constants as $name => $constant) { + if ($subjectName == $name) { + return $constant; + } + } + return null; + } + /** * @return EventDoc[] */ diff --git a/extensions/yii/apidoc/models/FunctionDoc.php b/extensions/yii/apidoc/models/FunctionDoc.php index 1120f77b2e7..9c7e2128b8a 100644 --- a/extensions/yii/apidoc/models/FunctionDoc.php +++ b/extensions/yii/apidoc/models/FunctionDoc.php @@ -60,7 +60,7 @@ public function __construct($reflector = null, $config = []) 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]->description = ucfirst($tag->getDescription()); $this->params[$paramName]->type = $tag->getType(); $this->params[$paramName]->types = $tag->getTypes(); unset($this->tags[$i]); diff --git a/extensions/yii/apidoc/models/TypeDoc.php b/extensions/yii/apidoc/models/TypeDoc.php index 9ceaf269420..5a833835186 100644 --- a/extensions/yii/apidoc/models/TypeDoc.php +++ b/extensions/yii/apidoc/models/TypeDoc.php @@ -30,6 +30,30 @@ class TypeDoc extends BaseDoc public $namespace; + + public function findSubject($subjectName) + { + if ($subjectName[0] != '$') { + foreach($this->methods as $name => $method) { + if (rtrim($subjectName, '()') == $name) { + return $method; + } + } + } + if (substr($subjectName, -2, 2) == '()') { + return null; + } + if ($this->properties === null) { + return null; + } + foreach($this->properties as $name => $property) { + if (ltrim($subjectName, '$') == ltrim($name, '$')) { + return $property; + } + } + return null; + } + /** * @return MethodDoc[] */ diff --git a/extensions/yii/apidoc/templates/BaseRenderer.php b/extensions/yii/apidoc/templates/BaseRenderer.php index 4f29e43aab0..97d58a50f14 100644 --- a/extensions/yii/apidoc/templates/BaseRenderer.php +++ b/extensions/yii/apidoc/templates/BaseRenderer.php @@ -8,11 +8,16 @@ namespace yii\apidoc\templates; use Yii; +use yii\apidoc\models\ClassDoc; +use yii\apidoc\models\ConstDoc; +use yii\apidoc\models\Context; +use yii\apidoc\models\EventDoc; +use yii\apidoc\models\InterfaceDoc; +use yii\apidoc\models\MethodDoc; +use yii\apidoc\models\PropertyDoc; +use yii\apidoc\models\TraitDoc; use yii\base\Component; use yii\console\Controller; -use yii\apidoc\models\Context; -use yii\web\AssetManager; -use yii\web\View; /** * Base class for all API documentation renderers @@ -22,6 +27,12 @@ */ abstract class BaseRenderer extends Component { + /** + * @var Context the [[Context]] currently being rendered. + */ + public $context; + + /** * Renders a given [[Context]]. * @@ -29,4 +40,20 @@ abstract class BaseRenderer extends Component * @param Controller $controller the apidoc controller instance. Can be used to control output. */ public abstract function render($context, $controller); + + /** + * creates a link to a type (class, interface or trait) + * @param ClassDoc|InterfaceDoc|TraitDoc $types + * @param string $title + * @return string + */ + public abstract function typeLink($types, $title = null); + + /** + * creates a link to a subject + * @param PropertyDoc|MethodDoc|ConstDoc|EventDoc $subject + * @param string $title + * @return string + */ + public abstract function subjectLink($subject, $title = null); } \ No newline at end of file diff --git a/extensions/yii/apidoc/templates/html/Renderer.php b/extensions/yii/apidoc/templates/html/Renderer.php index 4d5ae2005e0..21296953ae3 100644 --- a/extensions/yii/apidoc/templates/html/Renderer.php +++ b/extensions/yii/apidoc/templates/html/Renderer.php @@ -7,6 +7,7 @@ namespace yii\apidoc\templates\html; +use yii\apidoc\helpers\Markdown; use yii\apidoc\models\BaseDoc; use yii\apidoc\models\ConstDoc; use yii\apidoc\models\EventDoc; @@ -54,15 +55,17 @@ abstract class Renderer extends BaseRenderer implements ViewContextInterface * @var string path or alias of the view file to use for rendering the index page. */ public $indexView = '@yii/apidoc/templates/html/views/index.php'; - /** - * @var Context the [[Context]] currently being rendered. - */ - protected $context; /** * @var View */ private $_view; + + public function init() + { + Markdown::$renderer = $this; + } + /** * @return View the view instance */ @@ -179,7 +182,11 @@ public function typeLink($types, $context = null) public function subjectLink($subject, $title = null) { if ($title === null) { - $title = $subject->name; + if ($subject instanceof MethodDoc) { + $title = $subject->name . '()'; + } else { + $title = $subject->name; + } } if (($type = $this->context->getType($subject->definedBy)) === null) { return $subject->name; diff --git a/extensions/yii/apidoc/templates/html/views/constSummary.php b/extensions/yii/apidoc/templates/html/views/constSummary.php index 63dbbfb2488..a872aa509a9 100644 --- a/extensions/yii/apidoc/templates/html/views/constSummary.php +++ b/extensions/yii/apidoc/templates/html/views/constSummary.php @@ -1,5 +1,6 @@ definedBy != $type->name ? ' class="inherited"' : '' ?> id="name ?>"> name ?> value ?> - shortDescription . "\n" . $constant->description) ?> + shortDescription . "\n" . $constant->description, $type) ?> context->typeLink($constant->definedBy) ?> diff --git a/extensions/yii/apidoc/templates/html/views/eventDetails.php b/extensions/yii/apidoc/templates/html/views/eventDetails.php index 9ba925efa17..a5b3091d8bc 100644 --- a/extensions/yii/apidoc/templates/html/views/eventDetails.php +++ b/extensions/yii/apidoc/templates/html/views/eventDetails.php @@ -1,5 +1,6 @@ trigger->signature; ?> */ ?> -

description; ?>

+

description, $type); ?>

render('seeAlso', ['object' => $event]); ?> diff --git a/extensions/yii/apidoc/templates/html/views/eventSummary.php b/extensions/yii/apidoc/templates/html/views/eventSummary.php index 56cb0fa527b..0c179b63cdf 100644 --- a/extensions/yii/apidoc/templates/html/views/eventSummary.php +++ b/extensions/yii/apidoc/templates/html/views/eventSummary.php @@ -1,5 +1,6 @@ context->subjectLink($event) ?> context->typeLink($event->types) ?> - shortDescription ?> + shortDescription, $type) ?> since)): ?> (available since version since; ?>) diff --git a/extensions/yii/apidoc/templates/html/views/methodDetails.php b/extensions/yii/apidoc/templates/html/views/methodDetails.php index e0c0dbef97c..c3e52906736 100644 --- a/extensions/yii/apidoc/templates/html/views/methodDetails.php +++ b/extensions/yii/apidoc/templates/html/views/methodDetails.php @@ -1,5 +1,6 @@ name ?> context->typeLink($param->types) ?> - description ?> + description, $type) ?> return)): ?> context->typeLink($method->returnTypes); ?> - return; ?> + return, $type); ?> @@ -51,8 +52,8 @@ renderPartial('sourceCode',array('object'=>$method)); ?> -

shortDescription ?>

-

description) ?>

+

shortDescription, $type) ?>

+

description, $type) ?>

render('seeAlso', ['object' => $method]); ?> diff --git a/extensions/yii/apidoc/templates/html/views/methodSummary.php b/extensions/yii/apidoc/templates/html/views/methodSummary.php index e597d53931e..c3ca6d5082e 100644 --- a/extensions/yii/apidoc/templates/html/views/methodSummary.php +++ b/extensions/yii/apidoc/templates/html/views/methodSummary.php @@ -1,5 +1,6 @@ MethodDescriptionDefined By methods as $method): ?> -visibility == 'protected' || !$protected && $method->visibility != 'protected'): ?> -definedBy != $type->name ? ' class="inherited"' : '' ?> id="name ?>()"> - context->subjectLink($method, $method->name.'()') ?> - shortDescription ?> - context->typeLink($method->definedBy) ?> - - + visibility == 'protected' || !$protected && $method->visibility != 'protected'): ?> + definedBy != $type->name ? ' class="inherited"' : '' ?> id="name ?>()"> + context->subjectLink($method, $method->name.'()') ?> + shortDescription, $type) ?> + context->typeLink($method->definedBy, $type) ?> + + \ No newline at end of file diff --git a/extensions/yii/apidoc/templates/html/views/propertyDetails.php b/extensions/yii/apidoc/templates/html/views/propertyDetails.php index 80fb34a94b2..628f9bdbe2d 100644 --- a/extensions/yii/apidoc/templates/html/views/propertyDetails.php +++ b/extensions/yii/apidoc/templates/html/views/propertyDetails.php @@ -1,5 +1,6 @@ context->renderPropertySignature($property); ?> -

description) ?>

+

description, $type) ?>

render('seeAlso', ['object' => $property]); ?> diff --git a/extensions/yii/apidoc/templates/html/views/propertySummary.php b/extensions/yii/apidoc/templates/html/views/propertySummary.php index ae958500d74..3730431ee65 100644 --- a/extensions/yii/apidoc/templates/html/views/propertySummary.php +++ b/extensions/yii/apidoc/templates/html/views/propertySummary.php @@ -1,5 +1,6 @@ PropertyTypeDescriptionDefined By properties as $property): ?> -visibility == 'protected' || !$protected && $property->visibility != 'protected'): ?> -definedBy != $type->name ? ' class="inherited"' : '' ?> id="name ?>"> - context->subjectLink($property); ?> - context->typeLink($property->types); ?> - shortDescription; ?> - context->typeLink($property->definedBy); ?> - - + visibility == 'protected' || !$protected && $property->visibility != 'protected'): ?> + definedBy != $type->name ? ' class="inherited"' : '' ?> id="name ?>"> + context->subjectLink($property) ?> + context->typeLink($property->types) ?> + shortDescription, $type) ?> + context->typeLink($property->definedBy) ?> + + \ No newline at end of file diff --git a/extensions/yii/apidoc/templates/html/views/seeAlso.php b/extensions/yii/apidoc/templates/html/views/seeAlso.php index e955318db10..9990714f5f2 100644 --- a/extensions/yii/apidoc/templates/html/views/seeAlso.php +++ b/extensions/yii/apidoc/templates/html/views/seeAlso.php @@ -9,7 +9,12 @@ foreach($object->tags as $tag) { /** @var $tag phpDocumentor\Reflection\DocBlock\Tag\SeeTag */ if (get_class($tag) == 'phpDocumentor\Reflection\DocBlock\Tag\SeeTag') { - $see[] = $tag->getReference(); + $ref = $tag->getReference(); + if (strpos($ref, '://') === false) { + $see[] = '[[' . $ref . ']]'; + } else { + $see[] = $ref; + } } } if (empty($see)) { @@ -20,7 +25,7 @@

See Also

    -
  • +
  • context->context->getType($object->definedBy)) ?>
diff --git a/extensions/yii/apidoc/templates/html/views/type.php b/extensions/yii/apidoc/templates/html/views/type.php index 50959dc628b..64de2d1439e 100644 --- a/extensions/yii/apidoc/templates/html/views/type.php +++ b/extensions/yii/apidoc/templates/html/views/type.php @@ -1,12 +1,13 @@ context; @@ -76,8 +77,8 @@
- shortDescription ?> -

description) ?>

+ shortDescription, $type) ?> +

description, $type) ?>

diff --git a/extensions/yii/apidoc/templates/offline/assets/css/api.css b/extensions/yii/apidoc/templates/offline/assets/css/api.css index 482c04f461b..8ad7e07fae5 100644 --- a/extensions/yii/apidoc/templates/offline/assets/css/api.css +++ b/extensions/yii/apidoc/templates/offline/assets/css/api.css @@ -17,6 +17,12 @@ pre { border-left: 6px solid #FFE6BF; } +code { + color: #000000; + background-color: #FFF5E6; + padding: 1px; +} + div.code { display: none; color: #000000; From 53b3198dec6cf6959d246b1521df9791d3765011 Mon Sep 17 00:00:00 2001 From: Carsten Brandt Date: Mon, 6 Jan 2014 03:41:18 +0100 Subject: [PATCH 13/17] add exceptions to method docs --- .../yii/apidoc/templates/html/views/methodDetails.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/extensions/yii/apidoc/templates/html/views/methodDetails.php b/extensions/yii/apidoc/templates/html/views/methodDetails.php index c3e52906736..55011332112 100644 --- a/extensions/yii/apidoc/templates/html/views/methodDetails.php +++ b/extensions/yii/apidoc/templates/html/views/methodDetails.php @@ -32,7 +32,7 @@ context->renderMethodSignature($method) ?> - params) || !empty($method->return)): ?> + params) || !empty($method->return) || !empty($method->exceptions)): ?> params as $param): ?> name ?> @@ -42,11 +42,18 @@ return)): ?> - + context->typeLink($method->returnTypes); ?> return, $type); ?> + exceptions as $exception => $description): ?> + + + context->typeLink($exception) ?> + + + From 5ede58fef678a9e0f97864251d3483eb6091976d Mon Sep 17 00:00:00 2001 From: Carsten Brandt Date: Mon, 6 Jan 2014 04:30:50 +0100 Subject: [PATCH 14/17] finished the property feature --- extensions/yii/apidoc/models/Context.php | 119 +++++++++++++++++- extensions/yii/apidoc/models/FunctionDoc.php | 2 +- extensions/yii/apidoc/models/TypeDoc.php | 19 --- .../yii/apidoc/templates/html/Renderer.php | 25 ++-- 4 files changed, 130 insertions(+), 35 deletions(-) diff --git a/extensions/yii/apidoc/models/Context.php b/extensions/yii/apidoc/models/Context.php index 53781954de0..4260cbf972e 100644 --- a/extensions/yii/apidoc/models/Context.php +++ b/extensions/yii/apidoc/models/Context.php @@ -103,10 +103,16 @@ public function updateReferences() } } } - // update properties, methods, contants and events of subclasses + // inherit properties, methods, contants and events to subclasses foreach($this->classes as $class) { $this->updateSubclassInheritance($class); } + // add properties from getters and setters + foreach($this->classes as $class) { + $this->handlePropertyFeature($class); + } + + // TODO reference exceptions to methods where they are thrown } /** @@ -138,4 +144,115 @@ protected function updateSubclassInheritance($class) $this->updateSubclassInheritance($subclass); } } + + /** + * Add properties for getters and setters if class is subclass of [[yii\base\Object]]. + * @param ClassDoc $class + */ + protected function handlePropertyFeature($class) + { + if (!$this->isSubclassOf($class, 'yii\base\Object')) { + return; + } + foreach($class->getPublicMethods() as $name => $method) { + if (!strncmp($name, 'get', 3) && $this->paramsOptional($method)) { + $propertyName = '$' . lcfirst(substr($method->name, 3)); + if (isset($class->properties[$propertyName])) { + $property = $class->properties[$propertyName]; + if ($property->getter === null && $property->setter === null) { + echo "Property $propertyName conflicts with a defined getter {$method->name} in {$class->name}."; // TODO log these messages somewhere + } + $property->getter = $method; + } else { + $class->properties[$propertyName] = new PropertyDoc(null, [ + 'name' => $propertyName, + 'definedBy' => $class->name, + 'visibility' => 'public', + 'isStatic' => false, + 'type' => $method->returnType, + 'types' => $method->returnTypes, + 'shortDescription' => (($pos = strpos($method->return, '.')) !== false) ? + substr($method->return, 0, $pos) : $method->return, + 'description' => $method->return, + 'getter' => $method + // TODO set default value + ]); + } + } + if (!strncmp($name, 'set', 3) && $this->paramsOptional($method, 1)) { + $propertyName = '$' . lcfirst(substr($method->name, 3)); + if (isset($class->properties[$propertyName])) { + $property = $class->properties[$propertyName]; + if ($property->getter === null && $property->setter === null) { + echo "Property $propertyName conflicts with a defined setter {$method->name} in {$class->name}."; // TODO log these messages somewhere + } + $property->setter = $method; + } else { + $param = $this->getFirstNotOptionalParameter($method); + $class->properties[$propertyName] = new PropertyDoc(null, [ + 'name' => $propertyName, + 'definedBy' => $class->name, + 'visibility' => 'public', + 'isStatic' => false, + 'type' => $param->type, + 'types' => $param->types, + 'shortDescription' => (($pos = strpos($param->description, '.')) !== false) ? + substr($param->description, 0, $pos) : $param->description, + 'description' => $param->description, + 'setter' => $method + ]); + } + } + } + } + + /** + * @param MethodDoc $method + * @param integer $number number of not optional parameters + * @return bool + */ + private function paramsOptional($method, $number = 0) + { + foreach($method->params as $param) { + if (!$param->isOptional && $number-- <= 0) { + return false; + } + } + return true; + } + + /** + * @param MethodDoc $method + * @return ParamDoc + */ + private function getFirstNotOptionalParameter($method) + { + foreach($method->params as $param) { + if (!$param->isOptional) { + return $param; + } + } + return null; + } + + /** + * @param ClassDoc $classA + * @param ClassDoc $classB + */ + protected function isSubclassOf($classA, $classB) + { + if (is_object($classB)) { + $classB = $classB->name; + } + if ($classA->name == $classB) { + return true; + } + while($classA->parentClass !== null && isset($this->classes[$classA->parentClass])) { + $classA = $this->classes[$classA->parentClass]; + if ($classA->name == $classB) { + return true; + } + } + return false; + } } \ No newline at end of file diff --git a/extensions/yii/apidoc/models/FunctionDoc.php b/extensions/yii/apidoc/models/FunctionDoc.php index 9c7e2128b8a..62026a85217 100644 --- a/extensions/yii/apidoc/models/FunctionDoc.php +++ b/extensions/yii/apidoc/models/FunctionDoc.php @@ -54,7 +54,7 @@ public function __construct($reflector = null, $config = []) $this->exceptions[$tag->getType()] = $tag->getDescription(); unset($this->tags[$i]); } elseif ($tag instanceof PropertyTag) { - // TODO handle property tag + // ignore property tag } elseif ($tag instanceof ParamTag) { $paramName = $tag->getVariableName(); if (!isset($this->params[$paramName])) { diff --git a/extensions/yii/apidoc/models/TypeDoc.php b/extensions/yii/apidoc/models/TypeDoc.php index 5a833835186..a4c68d2060b 100644 --- a/extensions/yii/apidoc/models/TypeDoc.php +++ b/extensions/yii/apidoc/models/TypeDoc.php @@ -178,25 +178,6 @@ public function __construct($reflector = null, $config = []) if ($methodReflector->getVisibility() != 'private') { $method = new MethodDoc($methodReflector); $method->definedBy = $this->name; - - // TODO only set property when subclass of Object - if (!strncmp($method->name, 'set', 3)) { - $propertyName = lcfirst(substr($method->name, 3)); - if (isset($this->properties[$propertyName])) { - $property = $this->properties[$propertyName]; - if ($property->getter === null && $property->setter === null) { - throw new Exception("Property $propertyName conflicts with a defined setter {$method->name}."); - } - $property->setter = $method; - } else { -// $this->properties[$propertyName] = new PropertyDoc(null, [ -// 'name' => $propertyName, -// // TODO set description and short description -// ]); - } - } elseif (!strncmp($method->name, 'get', 3)) { - // TODO add property - } $this->methods[$method->name] = $method; } } diff --git a/extensions/yii/apidoc/templates/html/Renderer.php b/extensions/yii/apidoc/templates/html/Renderer.php index 21296953ae3..bc53d3aaed7 100644 --- a/extensions/yii/apidoc/templates/html/Renderer.php +++ b/extensions/yii/apidoc/templates/html/Renderer.php @@ -302,20 +302,17 @@ public function renderClasses($names) */ 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.='
'; - $sig.=$property->setter->signature; + if ($property->getter !== null || $property->setter !== null) { + $sig = []; + if ($property->getter !== null) { + $sig[] = $this->renderMethodSignature($property->getter); + } + if ($property->setter !== null) { + $sig[] = $this->renderMethodSignature($property->setter); + } + return implode('
', $sig); } - return $sig; + return $this->typeLink($property->types) . ' ' . $property->name . ' = ' . ($property->defaultValue === null ? 'null' : $property->defaultValue); } /** @@ -334,7 +331,7 @@ public function renderMethodSignature($method) return ($method->isReturnByReference ? '&' : '') . ($method->returnType === null ? 'void' : $this->typeLink($method->returnTypes)) - . ' ' . $method->name . '( ' + . ' ' . $this->subjectLink($method, $method->name) . '( ' . implode(', ', $params) . ' )'; } From 82f7937ade3ac3729b7e91c6f0c66cfa77ef670a Mon Sep 17 00:00:00 2001 From: Carsten Brandt Date: Mon, 6 Jan 2014 05:00:17 +0100 Subject: [PATCH 15/17] readme for apidoc --- extensions/yii/apidoc/README.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/extensions/yii/apidoc/README.md b/extensions/yii/apidoc/README.md index 7d20c71b42c..0ae1ec31a50 100644 --- a/extensions/yii/apidoc/README.md +++ b/extensions/yii/apidoc/README.md @@ -25,7 +25,17 @@ to the require section of your composer.json. Usage ----- -TDB +To generate API documentation, run the `apidoc` command. + +``` +vendor/bin/apidoc source/directory ./output +``` + +By default the `offline` template will be used. You can choose a different templates with the `--template=name` parameter. +Currently there is only the `offline` template available. + +You may also add the `yii\apidoc\commands\RenderController` to your console application class map and +run it inside of your applications console app. Creating your own templates --------------------------- From 2245a7e36dd274d52c5bd786d81b56a05baa97d0 Mon Sep 17 00:00:00 2001 From: Carsten Brandt Date: Mon, 6 Jan 2014 05:05:53 +0100 Subject: [PATCH 16/17] short array syntax --- extensions/yii/apidoc/helpers/Markdown.php | 13 +++--- .../yii/apidoc/helpers/PrettyPrinter.php | 41 +++++++++++++++++++ extensions/yii/apidoc/models/Context.php | 4 +- extensions/yii/apidoc/models/FunctionDoc.php | 3 +- extensions/yii/apidoc/models/ParamDoc.php | 7 +++- extensions/yii/apidoc/models/PropertyDoc.php | 6 ++- 6 files changed, 64 insertions(+), 10 deletions(-) create mode 100644 extensions/yii/apidoc/helpers/PrettyPrinter.php diff --git a/extensions/yii/apidoc/helpers/Markdown.php b/extensions/yii/apidoc/helpers/Markdown.php index 2bbad50ccef..682603dd7ec 100644 --- a/extensions/yii/apidoc/helpers/Markdown.php +++ b/extensions/yii/apidoc/helpers/Markdown.php @@ -1,19 +1,22 @@ + * @link http://www.yiiframework.com/ + * @copyright Copyright (c) 2008 Yii Software LLC + * @license http://www.yiiframework.com/license/ */ namespace yii\apidoc\helpers; - use phpDocumentor\Reflection\DocBlock\Type\Collection; use yii\apidoc\models\MethodDoc; use yii\apidoc\models\TypeDoc; use yii\apidoc\templates\BaseRenderer; -use yii\helpers\Html; +/** + * + * @author Carsten Brandt + * @since 2.0 + */ class Markdown extends \yii\helpers\Markdown { /** diff --git a/extensions/yii/apidoc/helpers/PrettyPrinter.php b/extensions/yii/apidoc/helpers/PrettyPrinter.php new file mode 100644 index 00000000000..288178dd99c --- /dev/null +++ b/extensions/yii/apidoc/helpers/PrettyPrinter.php @@ -0,0 +1,41 @@ + + * @since 2.0 + */ +class PrettyPrinter extends \phpDocumentor\Reflection\PrettyPrinter +{ + public function pExpr_Array(PHPParser_Node_Expr_Array $node) + { + return '[' . $this->pCommaSeparated($node->items) . ']'; + } + + /** + * Returns a simple human readable output for a value. + * + * @param PHPParser_Node_Expr $value The value node as provided by PHP-Parser. + * @return string + */ + public static function getRepresentationOfValue(PHPParser_Node_Expr $value) + { + if ($value === null) { + return ''; + } + + $printer = new static(); + return $printer->prettyPrintExpr($value); + } +} \ No newline at end of file diff --git a/extensions/yii/apidoc/models/Context.php b/extensions/yii/apidoc/models/Context.php index 4260cbf972e..94fd1dc2b34 100644 --- a/extensions/yii/apidoc/models/Context.php +++ b/extensions/yii/apidoc/models/Context.php @@ -160,7 +160,7 @@ protected function handlePropertyFeature($class) if (isset($class->properties[$propertyName])) { $property = $class->properties[$propertyName]; if ($property->getter === null && $property->setter === null) { - echo "Property $propertyName conflicts with a defined getter {$method->name} in {$class->name}."; // TODO log these messages somewhere + echo "Property $propertyName conflicts with a defined getter {$method->name} in {$class->name}.\n"; // TODO log these messages somewhere } $property->getter = $method; } else { @@ -184,7 +184,7 @@ protected function handlePropertyFeature($class) if (isset($class->properties[$propertyName])) { $property = $class->properties[$propertyName]; if ($property->getter === null && $property->setter === null) { - echo "Property $propertyName conflicts with a defined setter {$method->name} in {$class->name}."; // TODO log these messages somewhere + echo "Property $propertyName conflicts with a defined setter {$method->name} in {$class->name}.\n"; // TODO log these messages somewhere } $property->setter = $method; } else { diff --git a/extensions/yii/apidoc/models/FunctionDoc.php b/extensions/yii/apidoc/models/FunctionDoc.php index 62026a85217..232d236f8b6 100644 --- a/extensions/yii/apidoc/models/FunctionDoc.php +++ b/extensions/yii/apidoc/models/FunctionDoc.php @@ -58,7 +58,8 @@ public function __construct($reflector = null, $config = []) } 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 + echo 'undefined parameter documented: ' . $paramName . ' in ' . $this->name . "()\n"; // TODO log these messages somewhere + continue; } $this->params[$paramName]->description = ucfirst($tag->getDescription()); $this->params[$paramName]->type = $tag->getType(); diff --git a/extensions/yii/apidoc/models/ParamDoc.php b/extensions/yii/apidoc/models/ParamDoc.php index 0d4c162dd3e..2be9de84c7d 100644 --- a/extensions/yii/apidoc/models/ParamDoc.php +++ b/extensions/yii/apidoc/models/ParamDoc.php @@ -7,6 +7,7 @@ namespace yii\apidoc\models; +use yii\apidoc\helpers\PrettyPrinter; use yii\base\Object; /** @@ -42,7 +43,11 @@ public function __construct($reflector = null, $config = []) $this->name = $reflector->getName(); $this->typeHint = $reflector->getType(); $this->isOptional = $reflector->getDefault() !== null; - $this->defaultValue = $reflector->getDefault(); + + // bypass $reflector->getDefault() for short array syntax + if ($reflector->getNode()->default) { + $this->defaultValue = PrettyPrinter::getRepresentationOfValue($reflector->getNode()->default); + } $this->isPassedByReference = $reflector->isByRef(); } } \ No newline at end of file diff --git a/extensions/yii/apidoc/models/PropertyDoc.php b/extensions/yii/apidoc/models/PropertyDoc.php index cf17b0d8776..dbe4a2085dc 100644 --- a/extensions/yii/apidoc/models/PropertyDoc.php +++ b/extensions/yii/apidoc/models/PropertyDoc.php @@ -8,6 +8,7 @@ namespace yii\apidoc\models; use phpDocumentor\Reflection\DocBlock\Tag\VarTag; +use yii\apidoc\helpers\PrettyPrinter; /** * @@ -55,7 +56,10 @@ public function __construct($reflector = null, $config = []) $this->visibility = $reflector->getVisibility(); $this->isStatic = $reflector->isStatic(); - $this->defaultValue = $reflector->getDefault(); + // bypass $reflector->getDefault() for short array syntax + if ($reflector->getNode()->default) { + $this->defaultValue = PrettyPrinter::getRepresentationOfValue($reflector->getNode()->default); + } foreach($this->tags as $i => $tag) { if ($tag instanceof VarTag) { From c7c4d3c075bf1e1be1847ed61b248737f3bd81b8 Mon Sep 17 00:00:00 2001 From: Carsten Brandt Date: Mon, 6 Jan 2014 05:37:43 +0100 Subject: [PATCH 17/17] final cleanup apidoc generator --- extensions/yii/apidoc/commands/RenderController.php | 6 +----- extensions/yii/apidoc/helpers/Markdown.php | 1 + extensions/yii/apidoc/models/BaseDoc.php | 1 + extensions/yii/apidoc/models/ClassDoc.php | 1 + extensions/yii/apidoc/models/ConstDoc.php | 1 + extensions/yii/apidoc/models/EventDoc.php | 1 + extensions/yii/apidoc/models/FunctionDoc.php | 1 + extensions/yii/apidoc/models/InterfaceDoc.php | 1 + extensions/yii/apidoc/models/MethodDoc.php | 1 + extensions/yii/apidoc/models/ParamDoc.php | 1 + extensions/yii/apidoc/models/PropertyDoc.php | 1 + extensions/yii/apidoc/models/TraitDoc.php | 1 + extensions/yii/apidoc/models/TypeDoc.php | 1 + 13 files changed, 13 insertions(+), 5 deletions(-) diff --git a/extensions/yii/apidoc/commands/RenderController.php b/extensions/yii/apidoc/commands/RenderController.php index 8a46de3938e..cbd97aeefca 100644 --- a/extensions/yii/apidoc/commands/RenderController.php +++ b/extensions/yii/apidoc/commands/RenderController.php @@ -129,11 +129,7 @@ protected function findFiles($path, $except = []) return null; }, 'only' => ['.php'], - 'except' => array_merge($except, [ - '/views/', - '/requirements/', - '/gii/generators/', - ]), + 'except' => $except, ]; return FileHelper::findFiles($path, $options); } diff --git a/extensions/yii/apidoc/helpers/Markdown.php b/extensions/yii/apidoc/helpers/Markdown.php index 682603dd7ec..6139b15e62e 100644 --- a/extensions/yii/apidoc/helpers/Markdown.php +++ b/extensions/yii/apidoc/helpers/Markdown.php @@ -13,6 +13,7 @@ use yii\apidoc\templates\BaseRenderer; /** + * A Markdown helper with support for class reference links. * * @author Carsten Brandt * @since 2.0 diff --git a/extensions/yii/apidoc/models/BaseDoc.php b/extensions/yii/apidoc/models/BaseDoc.php index c470ab56180..9c8cfb92ce7 100644 --- a/extensions/yii/apidoc/models/BaseDoc.php +++ b/extensions/yii/apidoc/models/BaseDoc.php @@ -12,6 +12,7 @@ use yii\base\Object; /** + * Base class for API documentation information. * * @author Carsten Brandt * @since 2.0 diff --git a/extensions/yii/apidoc/models/ClassDoc.php b/extensions/yii/apidoc/models/ClassDoc.php index d9b17a48093..020105f2e33 100644 --- a/extensions/yii/apidoc/models/ClassDoc.php +++ b/extensions/yii/apidoc/models/ClassDoc.php @@ -8,6 +8,7 @@ namespace yii\apidoc\models; /** + * Represents API documentation information for a `class`. * * @author Carsten Brandt * @since 2.0 diff --git a/extensions/yii/apidoc/models/ConstDoc.php b/extensions/yii/apidoc/models/ConstDoc.php index a0fbf08accc..1f185da9f57 100644 --- a/extensions/yii/apidoc/models/ConstDoc.php +++ b/extensions/yii/apidoc/models/ConstDoc.php @@ -8,6 +8,7 @@ namespace yii\apidoc\models; /** + * Represents API documentation information for a `constant`. * * @author Carsten Brandt * @since 2.0 diff --git a/extensions/yii/apidoc/models/EventDoc.php b/extensions/yii/apidoc/models/EventDoc.php index 41771c52c5f..2c15f3d1e25 100644 --- a/extensions/yii/apidoc/models/EventDoc.php +++ b/extensions/yii/apidoc/models/EventDoc.php @@ -11,6 +11,7 @@ use phpDocumentor\Reflection\DocBlock\Tag\ReturnTag; /** + * Represents API documentation information for an `event`. * * @author Carsten Brandt * @since 2.0 diff --git a/extensions/yii/apidoc/models/FunctionDoc.php b/extensions/yii/apidoc/models/FunctionDoc.php index 232d236f8b6..82c09ec279b 100644 --- a/extensions/yii/apidoc/models/FunctionDoc.php +++ b/extensions/yii/apidoc/models/FunctionDoc.php @@ -14,6 +14,7 @@ use yii\base\Exception; /** + * Represents API documentation information for a `function`. * * @author Carsten Brandt * @since 2.0 diff --git a/extensions/yii/apidoc/models/InterfaceDoc.php b/extensions/yii/apidoc/models/InterfaceDoc.php index 57cd9ce21f8..10b6d65576f 100644 --- a/extensions/yii/apidoc/models/InterfaceDoc.php +++ b/extensions/yii/apidoc/models/InterfaceDoc.php @@ -8,6 +8,7 @@ namespace yii\apidoc\models; /** + * Represents API documentation information for an `interface`. * * @author Carsten Brandt * @since 2.0 diff --git a/extensions/yii/apidoc/models/MethodDoc.php b/extensions/yii/apidoc/models/MethodDoc.php index 0f7288fbf5d..e31d31cbd6b 100644 --- a/extensions/yii/apidoc/models/MethodDoc.php +++ b/extensions/yii/apidoc/models/MethodDoc.php @@ -8,6 +8,7 @@ namespace yii\apidoc\models; /** + * Represents API documentation information for a `method`. * * @author Carsten Brandt * @since 2.0 diff --git a/extensions/yii/apidoc/models/ParamDoc.php b/extensions/yii/apidoc/models/ParamDoc.php index 2be9de84c7d..de6ef5d23d3 100644 --- a/extensions/yii/apidoc/models/ParamDoc.php +++ b/extensions/yii/apidoc/models/ParamDoc.php @@ -11,6 +11,7 @@ use yii\base\Object; /** + * Represents API documentation information for a [[FunctionDoc|function]] or [[MethodDoc|method]] `param`. * * @author Carsten Brandt * @since 2.0 diff --git a/extensions/yii/apidoc/models/PropertyDoc.php b/extensions/yii/apidoc/models/PropertyDoc.php index dbe4a2085dc..b865fba765c 100644 --- a/extensions/yii/apidoc/models/PropertyDoc.php +++ b/extensions/yii/apidoc/models/PropertyDoc.php @@ -11,6 +11,7 @@ use yii\apidoc\helpers\PrettyPrinter; /** + * Represents API documentation information for a `property`. * * @author Carsten Brandt * @since 2.0 diff --git a/extensions/yii/apidoc/models/TraitDoc.php b/extensions/yii/apidoc/models/TraitDoc.php index 37f17998061..1169f997d6d 100644 --- a/extensions/yii/apidoc/models/TraitDoc.php +++ b/extensions/yii/apidoc/models/TraitDoc.php @@ -8,6 +8,7 @@ namespace yii\apidoc\models; /** + * Represents API documentation information for a `trait`. * * @author Carsten Brandt * @since 2.0 diff --git a/extensions/yii/apidoc/models/TypeDoc.php b/extensions/yii/apidoc/models/TypeDoc.php index a4c68d2060b..6561fc72173 100644 --- a/extensions/yii/apidoc/models/TypeDoc.php +++ b/extensions/yii/apidoc/models/TypeDoc.php @@ -12,6 +12,7 @@ use yii\helpers\StringHelper; /** + * Base class for API documentation information for classes, interfaces and traits. * * @author Carsten Brandt * @since 2.0