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 ++++++++++ extensions/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 ++++ extensions/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 0000000..8b7ef35 --- /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 0000000..b029621 --- /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 0000000..e98f03d --- /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 0000000..f0c8087 --- /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 0000000..482c04f --- /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 0000000..1ead51c --- /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 0000000..1bb3e32 --- /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 0000000..86e93b2 --- /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 0000000..1d02de0 --- /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 0000000..7fa2dde --- /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 0000000..cbdf270 --- /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 0000000..dd51bb5 --- /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 0000000..78d455d --- /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 0000000..2ce7ad1 --- /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 0000000..add2a00 --- /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 0000000..be29aea --- /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 0000000..8ac0287 --- /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 0000000..7fc6e5a --- /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 0000000..0af8987 --- /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 0000000..ca84167 --- /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 0000000..1e81798 --- /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 0000000..809de75 --- /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/apidoc/.gitignore | 2 + extensions/yii/apidoc/CHANGELOG.md | 7 + extensions/yii/apidoc/LICENSE.md | 32 ++++ extensions/yii/apidoc/README.md | 28 ++++ extensions/yii/apidoc/assets/css/api.css | 105 ++++++++++++ extensions/yii/apidoc/assets/css/style.css | 32 ++++ .../yii/apidoc/commands/PhpdocController.php | 88 ++++++++++ extensions/yii/apidoc/components/BaseRenderer.php | 37 +++++ .../yii/apidoc/components/OfflineRenderer.php | 182 +++++++++++++++++++++ extensions/yii/apidoc/composer.json | 29 ++++ extensions/yii/apidoc/models/BaseDoc.php | 45 +++++ extensions/yii/apidoc/models/ClassDoc.php | 80 +++++++++ extensions/yii/apidoc/models/Context.php | 93 +++++++++++ extensions/yii/apidoc/models/EventDoc.php | 15 ++ extensions/yii/apidoc/models/File.php | 53 ++++++ extensions/yii/apidoc/models/FunctionDoc.php | 15 ++ extensions/yii/apidoc/models/InterfaceDoc.php | 45 +++++ extensions/yii/apidoc/models/MethodDoc.php | 18 ++ extensions/yii/apidoc/models/ParamDoc.php | 18 ++ extensions/yii/apidoc/models/PropertyDoc.php | 23 +++ extensions/yii/apidoc/models/TraitDoc.php | 49 ++++++ extensions/yii/apidoc/views/class.php | 49 ++++++ extensions/yii/apidoc/views/classSummary.php | 60 +++++++ extensions/yii/apidoc/views/index.php | 30 ++++ extensions/yii/apidoc/views/layouts/offline.php | 64 ++++++++ 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 ---------- extensions/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 ---- extensions/yii/phpdoc/views/layouts/offline.php | 64 -------- 50 files changed, 1199 insertions(+), 1171 deletions(-) create mode 100644 extensions/yii/apidoc/.gitignore create mode 100644 extensions/yii/apidoc/CHANGELOG.md create mode 100644 extensions/yii/apidoc/LICENSE.md create mode 100644 extensions/yii/apidoc/README.md create mode 100644 extensions/yii/apidoc/assets/css/api.css create mode 100644 extensions/yii/apidoc/assets/css/style.css create mode 100644 extensions/yii/apidoc/commands/PhpdocController.php create mode 100644 extensions/yii/apidoc/components/BaseRenderer.php create mode 100644 extensions/yii/apidoc/components/OfflineRenderer.php create mode 100644 extensions/yii/apidoc/composer.json create mode 100644 extensions/yii/apidoc/models/BaseDoc.php create mode 100644 extensions/yii/apidoc/models/ClassDoc.php create mode 100644 extensions/yii/apidoc/models/Context.php create mode 100644 extensions/yii/apidoc/models/EventDoc.php create mode 100644 extensions/yii/apidoc/models/File.php create mode 100644 extensions/yii/apidoc/models/FunctionDoc.php create mode 100644 extensions/yii/apidoc/models/InterfaceDoc.php create mode 100644 extensions/yii/apidoc/models/MethodDoc.php create mode 100644 extensions/yii/apidoc/models/ParamDoc.php create mode 100644 extensions/yii/apidoc/models/PropertyDoc.php create mode 100644 extensions/yii/apidoc/models/TraitDoc.php create mode 100644 extensions/yii/apidoc/views/class.php create mode 100644 extensions/yii/apidoc/views/classSummary.php create mode 100644 extensions/yii/apidoc/views/index.php create mode 100644 extensions/yii/apidoc/views/layouts/offline.php delete mode 100644 extensions/yii/phpdoc/.gitignore delete mode 100644 extensions/yii/phpdoc/CHANGELOG.md delete mode 100644 extensions/yii/phpdoc/LICENSE.md delete mode 100644 extensions/yii/phpdoc/README.md delete mode 100644 extensions/yii/phpdoc/assets/css/api.css delete mode 100644 extensions/yii/phpdoc/assets/css/style.css delete mode 100644 extensions/yii/phpdoc/commands/PhpdocController.php delete mode 100644 extensions/yii/phpdoc/components/BaseRenderer.php delete mode 100644 extensions/yii/phpdoc/components/OfflineRenderer.php delete mode 100644 extensions/yii/phpdoc/composer.json delete mode 100644 extensions/yii/phpdoc/models/BaseDoc.php delete mode 100644 extensions/yii/phpdoc/models/ClassDoc.php delete mode 100644 extensions/yii/phpdoc/models/Context.php delete mode 100644 extensions/yii/phpdoc/models/EventDoc.php delete mode 100644 extensions/yii/phpdoc/models/File.php delete mode 100644 extensions/yii/phpdoc/models/FunctionDoc.php delete mode 100644 extensions/yii/phpdoc/models/InterfaceDoc.php delete mode 100644 extensions/yii/phpdoc/models/MethodDoc.php delete mode 100644 extensions/yii/phpdoc/models/ParamDoc.php delete mode 100644 extensions/yii/phpdoc/models/PropertyDoc.php delete mode 100644 extensions/yii/phpdoc/models/TraitDoc.php delete mode 100644 extensions/yii/phpdoc/views/class.php delete mode 100644 extensions/yii/phpdoc/views/classSummary.php delete mode 100644 extensions/yii/phpdoc/views/index.php delete mode 100644 extensions/yii/phpdoc/views/layouts/offline.php diff --git a/extensions/yii/apidoc/.gitignore b/extensions/yii/apidoc/.gitignore new file mode 100644 index 0000000..8b7ef35 --- /dev/null +++ b/extensions/yii/apidoc/.gitignore @@ -0,0 +1,2 @@ +/vendor +composer.lock diff --git a/extensions/yii/apidoc/CHANGELOG.md b/extensions/yii/apidoc/CHANGELOG.md new file mode 100644 index 0000000..16875d2 --- /dev/null +++ b/extensions/yii/apidoc/CHANGELOG.md @@ -0,0 +1,7 @@ +Yii Framework 2 apidoc extension Change Log +=========================================== + +2.0.0 beta under development +---------------------------- + +- Initial release. diff --git a/extensions/yii/apidoc/LICENSE.md b/extensions/yii/apidoc/LICENSE.md new file mode 100644 index 0000000..e98f03d --- /dev/null +++ b/extensions/yii/apidoc/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/apidoc/README.md b/extensions/yii/apidoc/README.md new file mode 100644 index 0000000..b733d7d --- /dev/null +++ b/extensions/yii/apidoc/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-apidoc "*" +``` + +or add + +```json +"yiisoft/yii2-apidoc": "*" +``` + +to the require section of your composer.json. + +Usage +----- + +TDB \ No newline at end of file diff --git a/extensions/yii/apidoc/assets/css/api.css b/extensions/yii/apidoc/assets/css/api.css new file mode 100644 index 0000000..482c04f --- /dev/null +++ b/extensions/yii/apidoc/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/apidoc/assets/css/style.css b/extensions/yii/apidoc/assets/css/style.css new file mode 100644 index 0000000..009c218 --- /dev/null +++ b/extensions/yii/apidoc/assets/css/style.css @@ -0,0 +1,32 @@ +body +{ +} + +body, div, span, p, input +{ + font-family: Verdana, Arial, sans-serif; + 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/apidoc/commands/PhpdocController.php b/extensions/yii/apidoc/commands/PhpdocController.php new file mode 100644 index 0000000..9236580 --- /dev/null +++ b/extensions/yii/apidoc/commands/PhpdocController.php @@ -0,0 +1,88 @@ + + * @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/apidoc/components/BaseRenderer.php b/extensions/yii/apidoc/components/BaseRenderer.php new file mode 100644 index 0000000..5b8fb69 --- /dev/null +++ b/extensions/yii/apidoc/components/BaseRenderer.php @@ -0,0 +1,37 @@ +_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/apidoc/components/OfflineRenderer.php b/extensions/yii/apidoc/components/OfflineRenderer.php new file mode 100644 index 0000000..0c3d2dd --- /dev/null +++ b/extensions/yii/apidoc/components/OfflineRenderer.php @@ -0,0 +1,182 @@ +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/apidoc/composer.json b/extensions/yii/apidoc/composer.json new file mode 100644 index 0000000..30608a1 --- /dev/null +++ b/extensions/yii/apidoc/composer.json @@ -0,0 +1,29 @@ +{ + "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%3Aapidoc", + "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\\apidoc\\": "" } + }, + "target-dir": "yii/apidoc" +} diff --git a/extensions/yii/apidoc/models/BaseDoc.php b/extensions/yii/apidoc/models/BaseDoc.php new file mode 100644 index 0000000..888d1ac --- /dev/null +++ b/extensions/yii/apidoc/models/BaseDoc.php @@ -0,0 +1,45 @@ +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/apidoc/models/ClassDoc.php b/extensions/yii/apidoc/models/ClassDoc.php new file mode 100644 index 0000000..3fe7f3d --- /dev/null +++ b/extensions/yii/apidoc/models/ClassDoc.php @@ -0,0 +1,80 @@ +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/apidoc/models/Context.php b/extensions/yii/apidoc/models/Context.php new file mode 100644 index 0000000..11ece3e --- /dev/null +++ b/extensions/yii/apidoc/models/Context.php @@ -0,0 +1,93 @@ +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/apidoc/models/EventDoc.php b/extensions/yii/apidoc/models/EventDoc.php new file mode 100644 index 0000000..22fedc9 --- /dev/null +++ b/extensions/yii/apidoc/models/EventDoc.php @@ -0,0 +1,15 @@ +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/FunctionDoc.php b/extensions/yii/apidoc/models/FunctionDoc.php new file mode 100644 index 0000000..b9cee3b --- /dev/null +++ b/extensions/yii/apidoc/models/FunctionDoc.php @@ -0,0 +1,15 @@ +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/apidoc/models/MethodDoc.php b/extensions/yii/apidoc/models/MethodDoc.php new file mode 100644 index 0000000..cd32c86 --- /dev/null +++ b/extensions/yii/apidoc/models/MethodDoc.php @@ -0,0 +1,18 @@ +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/apidoc/views/class.php b/extensions/yii/apidoc/views/class.php new file mode 100644 index 0000000..ffe6063 --- /dev/null +++ b/extensions/yii/apidoc/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/apidoc/views/classSummary.php b/extensions/yii/apidoc/views/classSummary.php new file mode 100644 index 0000000..1f6ad9a --- /dev/null +++ b/extensions/yii/apidoc/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/apidoc/views/index.php b/extensions/yii/apidoc/views/index.php new file mode 100644 index 0000000..c329707 --- /dev/null +++ b/extensions/yii/apidoc/views/index.php @@ -0,0 +1,30 @@ +

Class Reference

+ + ++ + + + + + + +$class): ?> + + + + + +
ClassDescription
context->link($class, $class->name); ?>shortDescription; ?>
diff --git a/extensions/yii/apidoc/views/layouts/offline.php b/extensions/yii/apidoc/views/layouts/offline.php new file mode 100644 index 0000000..809de75 --- /dev/null +++ b/extensions/yii/apidoc/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 diff --git a/extensions/yii/phpdoc/.gitignore b/extensions/yii/phpdoc/.gitignore deleted file mode 100644 index 8b7ef35..0000000 --- a/extensions/yii/phpdoc/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/vendor -composer.lock diff --git a/extensions/yii/phpdoc/CHANGELOG.md b/extensions/yii/phpdoc/CHANGELOG.md deleted file mode 100644 index b029621..0000000 --- a/extensions/yii/phpdoc/CHANGELOG.md +++ /dev/null @@ -1,7 +0,0 @@ -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 deleted file mode 100644 index e98f03d..0000000 --- a/extensions/yii/phpdoc/LICENSE.md +++ /dev/null @@ -1,32 +0,0 @@ -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 deleted file mode 100644 index f0c8087..0000000 --- a/extensions/yii/phpdoc/README.md +++ /dev/null @@ -1,28 +0,0 @@ -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 deleted file mode 100644 index 482c04f..0000000 --- a/extensions/yii/phpdoc/assets/css/api.css +++ /dev/null @@ -1,105 +0,0 @@ -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 deleted file mode 100644 index 1ead51c..0000000 --- a/extensions/yii/phpdoc/assets/css/style.css +++ /dev/null @@ -1,32 +0,0 @@ -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 deleted file mode 100644 index 1bb3e32..0000000 --- a/extensions/yii/phpdoc/commands/PhpdocController.php +++ /dev/null @@ -1,89 +0,0 @@ - - * @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 deleted file mode 100644 index 86e93b2..0000000 --- a/extensions/yii/phpdoc/components/BaseRenderer.php +++ /dev/null @@ -1,38 +0,0 @@ - - */ - -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 deleted file mode 100644 index 1d02de0..0000000 --- a/extensions/yii/phpdoc/components/OfflineRenderer.php +++ /dev/null @@ -1,182 +0,0 @@ - - */ - -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 deleted file mode 100644 index 7fa2dde..0000000 --- a/extensions/yii/phpdoc/composer.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "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 deleted file mode 100644 index cbdf270..0000000 --- a/extensions/yii/phpdoc/models/BaseDoc.php +++ /dev/null @@ -1,40 +0,0 @@ -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 deleted file mode 100644 index dd51bb5..0000000 --- a/extensions/yii/phpdoc/models/ClassDoc.php +++ /dev/null @@ -1,75 +0,0 @@ -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 deleted file mode 100644 index 78d455d..0000000 --- a/extensions/yii/phpdoc/models/Context.php +++ /dev/null @@ -1,93 +0,0 @@ - - */ - -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 deleted file mode 100644 index 2ce7ad1..0000000 --- a/extensions/yii/phpdoc/models/EventDoc.php +++ /dev/null @@ -1,10 +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/phpdoc/models/FunctionDoc.php b/extensions/yii/phpdoc/models/FunctionDoc.php deleted file mode 100644 index add2a00..0000000 --- a/extensions/yii/phpdoc/models/FunctionDoc.php +++ /dev/null @@ -1,10 +0,0 @@ - - */ - -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 deleted file mode 100644 index be29aea..0000000 --- a/extensions/yii/phpdoc/models/MethodDoc.php +++ /dev/null @@ -1,13 +0,0 @@ - - */ - -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 deleted file mode 100644 index 8ac0287..0000000 --- a/extensions/yii/phpdoc/models/PropertyDoc.php +++ /dev/null @@ -1,23 +0,0 @@ - - */ - -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 deleted file mode 100644 index 7fc6e5a..0000000 --- a/extensions/yii/phpdoc/models/TraitDoc.php +++ /dev/null @@ -1,49 +0,0 @@ - - */ - -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 deleted file mode 100644 index 0af8987..0000000 --- a/extensions/yii/phpdoc/views/class.php +++ /dev/null @@ -1,49 +0,0 @@ - -

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 deleted file mode 100644 index ca84167..0000000 --- a/extensions/yii/phpdoc/views/classSummary.php +++ /dev/null @@ -1,60 +0,0 @@ - -- - - - - - - - - -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 deleted file mode 100644 index 1e81798..0000000 --- a/extensions/yii/phpdoc/views/index.php +++ /dev/null @@ -1,30 +0,0 @@ -

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 deleted file mode 100644 index 809de75..0000000 --- a/extensions/yii/phpdoc/views/layouts/offline.php +++ /dev/null @@ -1,64 +0,0 @@ -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 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 888d1ac..fa8c709 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 3fe7f3d..3d33568 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 @@ class ClassDoc extends BaseDoc // 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 11ece3e..8c3d658 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 @@ class Context extends Component 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 61597c2..0000000 --- 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 1275898..32f9113 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 20de618..eef6b4e 100644 --- a/extensions/yii/apidoc/models/TraitDoc.php +++ b/extensions/yii/apidoc/models/TraitDoc.php @@ -10,25 +10,23 @@ namespace yii\apidoc\models; 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 @@ class TraitDoc extends BaseDoc // 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 ffe6063..5c0ddaa 100644 --- a/extensions/yii/apidoc/views/class.php +++ b/extensions/yii/apidoc/views/class.php @@ -15,6 +15,12 @@ use yii\apidoc\models\TraitDoc; } 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 0c3d2dd..509c51d 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 @@ class OfflineRenderer extends BaseRenderer implements ViewContextInterface */ 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 fa8c709..6715015 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 3d33568..9bb7191 100644 --- a/extensions/yii/apidoc/models/ClassDoc.php +++ b/extensions/yii/apidoc/models/ClassDoc.php @@ -10,7 +10,7 @@ namespace yii\apidoc\models; /** * 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 @@ class ClassDoc extends BaseDoc 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 0000000..5eb99a9 --- /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 @@ class Context extends Component } // 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 22fedc9..fbdc4d8 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 b9cee3b..d84fd01 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 32f9113..8a99661 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 @@ class InterfaceDoc extends BaseDoc $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 cd32c86..70d67ce 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 6fdd535..b5b664c 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 9fd94e5..3a9b447 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 eef6b4e..13ee9b9 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 @@ class TraitDoc extends BaseDoc 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 0000000..a1349a4 --- /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 ++++++++++ extensions/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 509c51d..a3660f7 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 @@ class OfflineRenderer extends BaseRenderer implements ViewContextInterface } /** - * 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 @@ class OfflineRenderer extends BaseRenderer implements ViewContextInterface */ 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 @@ class OfflineRenderer extends BaseRenderer implements ViewContextInterface } /** - * @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 @@ class OfflineRenderer extends BaseRenderer implements ViewContextInterface } /** - * @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 @@ class OfflineRenderer extends BaseRenderer implements ViewContextInterface 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 9bb7191..7e7e24b 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 c3b3246..0670140 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 @@ class Context extends Component } // 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 @@ class Context extends Component } 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 @@ class Context extends Component $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 a1349a4..7ba1027 100644 --- a/extensions/yii/apidoc/models/TypeDoc.php +++ b/extensions/yii/apidoc/models/TypeDoc.php @@ -13,9 +13,61 @@ use yii\base\Exception; 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 @@ class TypeDoc extends BaseDoc $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 5c0ddaa..f3db8cf 100644 --- a/extensions/yii/apidoc/views/class.php +++ b/extensions/yii/apidoc/views/class.php @@ -26,30 +26,36 @@ use yii\apidoc\models\TraitDoc; 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 1f6ad9a..2de3811 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 0000000..7ed2d1a --- /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 0000000..72ebafa --- /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 c329707..bdaa548 100644 --- a/extensions/yii/apidoc/views/index.php +++ b/extensions/yii/apidoc/views/index.php @@ -23,7 +23,7 @@ use yii\apidoc\models\TraitDoc; 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 0000000..81a2c41 --- /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 0000000..be6af10 --- /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 7e7e24b..c0d27b5 100644 --- a/extensions/yii/apidoc/models/ClassDoc.php +++ b/extensions/yii/apidoc/models/ClassDoc.php @@ -57,11 +57,11 @@ class ClassDoc extends TypeDoc 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 0670140..d16c41f 100644 --- a/extensions/yii/apidoc/models/Context.php +++ b/extensions/yii/apidoc/models/Context.php @@ -132,8 +132,8 @@ class Context extends Component 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 @@ class Context extends Component $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 @@ class Context extends Component { 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 7ba1027..c2ccd33 100644 --- a/extensions/yii/apidoc/models/TypeDoc.php +++ b/extensions/yii/apidoc/models/TypeDoc.php @@ -36,9 +36,9 @@ class TypeDoc extends BaseDoc 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 @@ class TypeDoc extends BaseDoc 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 +- extensions/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 a3660f7..3f2df90 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 @@ class OfflineRenderer extends BaseRenderer implements ViewContextInterface 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 @@ class OfflineRenderer extends BaseRenderer implements ViewContextInterface } - 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 f3db8cf..0000000 --- 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 2de3811..0000000 --- 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 7ed2d1a..abac8c4 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 @@ if (empty($item->constants)) { 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 72ebafa..9493846 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 @@ if (empty($item->events)) { 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 bdaa548..310e9af 100644 --- a/extensions/yii/apidoc/views/index.php +++ b/extensions/yii/apidoc/views/index.php @@ -4,7 +4,7 @@ use yii\apidoc\models\ClassDoc; 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 @@ use yii\apidoc\models\TraitDoc; 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 81a2c41..19f3e61 100644 --- a/extensions/yii/apidoc/views/methodSummary.php +++ b/extensions/yii/apidoc/views/methodSummary.php @@ -4,12 +4,12 @@ use yii\apidoc\models\ClassDoc; 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 @@ if ($protected && count($item->getProtectedMethods()) == 0 || !$protected && cou 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 be6af10..4b1e935 100644 --- a/extensions/yii/apidoc/views/propertySummary.php +++ b/extensions/yii/apidoc/views/propertySummary.php @@ -4,12 +4,12 @@ use yii\apidoc\models\ClassDoc; 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 @@ if ($protected && count($item->getProtectedProperties()) == 0 || !$protected && 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 0000000..2c20197 --- /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 +- extensions/yii/apidoc/views/propertyDetails.php | 38 +++++++++ extensions/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 3f2df90..bb06141 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 @@ class OfflineRenderer extends BaseRenderer implements ViewContextInterface * @param string $title * @return string */ - public function typeLink($types, $title = null) + public function typeLink($types, $context = null) { if (!is_array($types)) { $types = [$types]; } $links = []; foreach($types as $type) { - if (!is_object($type) && ($t = $this->context->getType($type)) !== null) { - $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 @@ class OfflineRenderer extends BaseRenderer implements ViewContextInterface if (($type = $this->context->getType($subject->definedBy)) === null) { return $subject->name; } else { - return Html::a($title, null, ['href' => $this->generateFileName($type->name) . '#' . $subject->name . '-detail']); + $link = $this->generateFileName($type->name); + if ($subject instanceof MethodDoc) { + $link .= '#' . $subject->name . '()'; + } else { + $link .= '#' . $subject->name; + } + $link .= '-detail'; + return Html::a($title, null, ['href' => $link]); + } + } + + /** + * @param BaseDoc $context + */ + private function resolveNamespace($context) + { + if ($context === null) { + return ''; + } + if ($context instanceof TypeDoc) { + return $context->namespace; } + if ($context->hasProperty('definedBy')) { + $type = $this->context->getType($context); + if ($type !== null) { + return $type->namespace; + } + } + return ''; } /** @@ -208,6 +249,50 @@ class OfflineRenderer extends BaseRenderer implements ViewContextInterface return implode(', ',$classes); } + /** + * @param PropertyDoc $property + * @return string + */ + public function renderPropertySignature($property) + { + return $this->typeLink($property->types) . ' ' . $property->name . ' = ' . ($property->defaultValue === null ? 'null' : $property->defaultValue); + // TODO + if(!empty($property->signature)) + return $property->signature; + $sig=''; + if(!empty($property->getter)) + $sig=$property->getter->signature; + if(!empty($property->setter)) + { + if($sig!=='') + $sig.='
'; + $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 6715015..d52011c 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 c0d27b5..82da1d5 100644 --- a/extensions/yii/apidoc/models/ClassDoc.php +++ b/extensions/yii/apidoc/models/ClassDoc.php @@ -33,13 +33,32 @@ class ClassDoc extends TypeDoc /** + * @return EventDoc[] + */ + public function getNativeEvents() + { + $events = []; + foreach($this->events as $name => $event) { + if ($event->definedBy != $this->name) { + continue; + } + $events[$name] = $event; + } + return $events; + } + + /** * @param \phpDocumentor\Reflection\ClassReflector $reflector * @param array $config */ - public function __construct($reflector, $config = []) + public function __construct($reflector = null, $config = []) { parent::__construct($reflector, $config); + if ($reflector === null) { + return; + } + $this->parentClass = ltrim($reflector->getParentClass(), '\\'); if (empty($this->parentClass)) { $this->parentClass = null; @@ -54,7 +73,8 @@ class ClassDoc extends TypeDoc $this->traits[] = ltrim($trait, '\\'); } foreach($reflector->getConstants() as $constantReflector) { - if (strncmp($constantReflector->getShortName(), 'EVENT_', 6) == 0) { + $docblock = $constantReflector->getDocBlock(); + if ($docblock !== null && count($docblock->getTagsByName('event')) > 0) { $event = new EventDoc($constantReflector); $event->definedBy = $this->name; $this->events[$event->name] = $event; diff --git a/extensions/yii/apidoc/models/ConstDoc.php b/extensions/yii/apidoc/models/ConstDoc.php index 5eb99a9..b1d3a93 100644 --- a/extensions/yii/apidoc/models/ConstDoc.php +++ b/extensions/yii/apidoc/models/ConstDoc.php @@ -10,4 +10,20 @@ namespace yii\apidoc\models; class ConstDoc extends BaseDoc { public $definedBy; + public $value; + + /** + * @param \phpDocumentor\Reflection\ClassReflector\ConstantReflector $reflector + * @param array $config + */ + public function __construct($reflector = null, $config = []) + { + parent::__construct($reflector, $config); + + if ($reflector === null) { + return; + } + + $this->value = $reflector->getValue(); + } } \ No newline at end of file diff --git a/extensions/yii/apidoc/models/Context.php b/extensions/yii/apidoc/models/Context.php index d16c41f..89bfcfd 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 fbdc4d8..78aee19 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 d84fd01..30338a6 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 @@ class FunctionDoc extends BaseDoc } foreach($this->tags as $i => $tag) { - if ($tag instanceof ReturnTag) { - $this->returnType = $tag->getType(); - $this->returnTypes = $tag->getTypes(); - $this->return = $tag->getDescription(); + if ($tag instanceof ThrowsTag) { + $this->exceptions[$tag->getType()] = $tag->getDescription(); unset($this->tags[$i]); + } elseif ($tag instanceof PropertyTag) { + // TODO handle property tag } elseif ($tag instanceof ParamTag) { $paramName = $tag->getVariableName(); + if (!isset($this->params[$paramName])) { + echo 'undefined parameter documented: ' . $paramName . ' in ' . $this->name . "\n"; // todo add this to a log file + } $this->params[$paramName]->description = $tag->getDescription(); $this->params[$paramName]->type = $tag->getType(); $this->params[$paramName]->types = $tag->getTypes(); unset($this->tags[$i]); - } elseif ($tag instanceof ThrowsTag) { - $this->exceptions[$tag->getType()] = $tag->getDescription(); + } elseif ($tag instanceof ReturnTag) { + $this->returnType = $tag->getType(); + $this->returnTypes = $tag->getTypes(); + $this->return = $tag->getDescription(); unset($this->tags[$i]); } } diff --git a/extensions/yii/apidoc/models/InterfaceDoc.php b/extensions/yii/apidoc/models/InterfaceDoc.php index 8a99661..8aea744 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 70d67ce..96ca5c3 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 b5b664c..da5127b 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 3a9b447..68fc414 100644 --- a/extensions/yii/apidoc/models/PropertyDoc.php +++ b/extensions/yii/apidoc/models/PropertyDoc.php @@ -56,8 +56,12 @@ class PropertyDoc extends BaseDoc if ($tag instanceof VarTag) { $this->type = $tag->getType(); $this->types = $tag->getTypes(); - $this->description = $tag->getDescription(); - // TODO set shortDescription + $this->description = ucfirst($tag->getDescription()); + if (($pos = strpos($this->description, '.')) !== false) { + $this->shortDescription = substr($this->description, 0, $pos); + } else { + $this->shortDescription = $this->description; + } } } } diff --git a/extensions/yii/apidoc/models/TraitDoc.php b/extensions/yii/apidoc/models/TraitDoc.php index 13ee9b9..347640a 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 c2ccd33..d892a3d 100644 --- a/extensions/yii/apidoc/models/TypeDoc.php +++ b/extensions/yii/apidoc/models/TypeDoc.php @@ -9,6 +9,7 @@ namespace yii\apidoc\models; use phpDocumentor\Reflection\DocBlock\Tag\AuthorTag; use yii\base\Exception; +use yii\helpers\StringHelper; class TypeDoc extends BaseDoc { @@ -22,48 +23,95 @@ class TypeDoc extends BaseDoc */ public $properties = []; + public $namespace; + /** + * @return MethodDoc[] + */ + public function getNativeMethods() + { + return $this->getFilteredMethods(null, $this->name); + } + + /** + * @return MethodDoc[] + */ public function getPublicMethods() { return $this->getFilteredMethods('public'); } + /** + * @return MethodDoc[] + */ public function getProtectedMethods() { return $this->getFilteredMethods('protected'); } - private function getFilteredMethods($visibility) + /** + * @param null $visibility + * @param null $definedBy + * @return MethodDoc[] + */ + private function getFilteredMethods($visibility = null, $definedBy = null) { $methods = []; foreach($this->methods as $name => $method) { - if ($method->visibility == $visibility) { - $methods[$name] = $method; + if ($visibility !== null && $method->visibility != $visibility) { + continue; + } + if ($definedBy !== null && $method->definedBy != $definedBy) { + continue; } + $methods[$name] = $method; } return $methods; } + /** + * @return PropertyDoc[] + */ + public function getNativeProperties() + { + return $this->getFilteredProperties(null, $this->name); + } + + /** + * @return PropertyDoc[] + */ public function getPublicProperties() { return $this->getFilteredProperties('public'); } + /** + * @return PropertyDoc[] + */ public function getProtectedProperties() { return $this->getFilteredProperties('protected'); } - private function getFilteredProperties($visibility) + /** + * @param null $visibility + * @param null $definedBy + * @return PropertyDoc[] + */ + private function getFilteredProperties($visibility = null, $definedBy = null) { if ($this->properties === null) { return []; } $properties = []; foreach($this->properties as $name => $property) { - if ($property->visibility == $visibility) { - $properties[$name] = $property; + if ($visibility !== null && $property->visibility != $visibility) { + continue; + } + if ($definedBy !== null && $property->definedBy != $definedBy) { + continue; } + $properties[$name] = $property; } return $properties; } @@ -72,10 +120,12 @@ class TypeDoc extends BaseDoc * @param \phpDocumentor\Reflection\InterfaceReflector $reflector * @param array $config */ - public function __construct($reflector, $config = []) + public function __construct($reflector = null, $config = []) { parent::__construct($reflector, $config); + $this->namespace = StringHelper::basename($this->name); + if ($reflector === null) { return; } diff --git a/extensions/yii/apidoc/views/constSummary.php b/extensions/yii/apidoc/views/constSummary.php index abac8c4..63dbbfb 100644 --- a/extensions/yii/apidoc/views/constSummary.php +++ b/extensions/yii/apidoc/views/constSummary.php @@ -21,14 +21,15 @@ if (empty($type->constants)) { - 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 0000000..9ba925e --- /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 9493846..56cb0fa 100644 --- a/extensions/yii/apidoc/views/eventSummary.php +++ b/extensions/yii/apidoc/views/eventSummary.php @@ -21,13 +21,19 @@ if (empty($type->events)) { - 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 0000000..e0c0dbe --- /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 19f3e61..e597d53 100644 --- a/extensions/yii/apidoc/views/methodSummary.php +++ b/extensions/yii/apidoc/views/methodSummary.php @@ -29,7 +29,7 @@ if ($protected && count($type->getProtectedMethods()) == 0 || !$protected && cou 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 0000000..80fb34a --- /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 4b1e935..ae95850 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 2c20197..a911b63 100644 --- a/extensions/yii/apidoc/views/type.php +++ b/extensions/yii/apidoc/views/type.php @@ -94,5 +94,8 @@ $renderer = $this->context; 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 7e01bd4..8f1af5e 100644 --- a/framework/yii/base/Exception.php +++ b/framework/yii/base/Exception.php @@ -34,7 +34,7 @@ class Exception extends \Exception implements Arrayable /** * Returns the array representation of the exception and all previous exceptions recursively. - * @param \Exception exception object + * @param \Exception $exception object * @return array the array representation of the exception. */ protected function toArrayRecursive($exception) diff --git a/framework/yii/db/BaseActiveRecord.php b/framework/yii/db/BaseActiveRecord.php index cefcfe6..dcd613e 100644 --- a/framework/yii/db/BaseActiveRecord.php +++ b/framework/yii/db/BaseActiveRecord.php @@ -138,7 +138,6 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface * @param array $attributes attribute values (name-value pairs) to be saved into the table * @param string|array $condition the conditions that will be put in the WHERE part of the UPDATE SQL. * Please refer to [[Query::where()]] on how to specify this parameter. - * @param array $params the parameters (name => value) to be bound to the query. * @return integer the number of rows updated */ public static function updateAll($attributes, $condition = '') @@ -379,7 +378,7 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface * Populates the named relation with the related records. * Note that this method does not check if the relation exists or not. * @param string $name the relation name (case-sensitive) - * @param ActiveRecord|array|null the related records to be populated into the relation. + * @param ActiveRecord|array|null $records the related records to be populated into the relation. */ public function populateRelation($name, $records) { 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 ++++ .../yii/apidoc/commands/PhpdocController.php | 88 --------------- .../yii/apidoc/commands/RenderController.php | 118 +++++++++++++++++++++ extensions/yii/apidoc/composer.json | 3 +- extensions/yii/apidoc/models/Context.php | 47 +------- 6 files changed, 193 insertions(+), 132 deletions(-) create mode 100755 extensions/yii/apidoc/apidoc create mode 100644 extensions/yii/apidoc/apidoc.bat delete mode 100644 extensions/yii/apidoc/commands/PhpdocController.php create mode 100644 extensions/yii/apidoc/commands/RenderController.php diff --git a/extensions/yii/apidoc/apidoc b/extensions/yii/apidoc/apidoc new file mode 100755 index 0000000..91f7981 --- /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 0000000..ae00407 --- /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/PhpdocController.php deleted file mode 100644 index 9236580..0000000 --- a/extensions/yii/apidoc/commands/PhpdocController.php +++ /dev/null @@ -1,88 +0,0 @@ - - * @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/apidoc/commands/RenderController.php b/extensions/yii/apidoc/commands/RenderController.php new file mode 100644 index 0000000..33aee50 --- /dev/null +++ b/extensions/yii/apidoc/commands/RenderController.php @@ -0,0 +1,118 @@ + + * @since 2.0 + */ +class RenderController extends Controller +{ + /** + * Renders API documentation files + * @param array $sourceDirs + * @param string $targetDir + * @return int + */ + public function actionIndex(array $sourceDirs, $targetDir) + { + $targetDir = Yii::getAlias($targetDir); + if (is_dir($targetDir) && !$this->confirm('TargetDirectory already exists. Overwrite?')) { + return 2; + } + if (!is_dir($targetDir)) { + mkdir($targetDir); + } + + $this->stdout('Searching files to process... '); + $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); + $done = 0; + foreach($files as $file) { + $context->addFile($file); + Console::updateProgress(++$done, $fileCount); + } + 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); + + // 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/apidoc/composer.json b/extensions/yii/apidoc/composer.json index 30608a1..bf1c4b5 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 89bfcfd..549c318 100644 --- a/extensions/yii/apidoc/models/Context.php +++ b/extensions/yii/apidoc/models/Context.php @@ -47,10 +47,7 @@ class Context extends Component 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 @@ class Context extends Component 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 +- extensions/yii/apidoc/assets/css/api.css | 105 ------- extensions/yii/apidoc/assets/css/style.css | 32 -- .../yii/apidoc/commands/RenderController.php | 36 ++- extensions/yii/apidoc/components/BaseRenderer.php | 37 --- .../yii/apidoc/components/OfflineRenderer.php | 311 ------------------ 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 + extensions/yii/apidoc/templates/BaseRenderer.php | 32 ++ extensions/yii/apidoc/templates/html/README.md | 4 + extensions/yii/apidoc/templates/html/Renderer.php | 349 +++++++++++++++++++++ .../apidoc/templates/html/views/constSummary.php | 35 +++ .../apidoc/templates/html/views/eventDetails.php | 34 ++ .../apidoc/templates/html/views/eventSummary.php | 40 +++ .../apidoc/templates/html/views/methodDetails.php | 59 ++++ .../apidoc/templates/html/views/methodSummary.php | 40 +++ .../templates/html/views/propertyDetails.php | 38 +++ .../templates/html/views/propertySummary.php | 41 +++ .../yii/apidoc/templates/html/views/seeAlso.php | 26 ++ .../yii/apidoc/templates/html/views/type.php | 101 ++++++ .../yii/apidoc/templates/offline/Renderer.php | 44 +++ .../apidoc/templates/offline/assets/css/api.css | 105 +++++++ .../apidoc/templates/offline/assets/css/style.css | 32 ++ .../yii/apidoc/templates/offline/views/index.php | 30 ++ .../yii/apidoc/templates/offline/views/offline.php | 65 ++++ extensions/yii/apidoc/views/constSummary.php | 35 --- extensions/yii/apidoc/views/eventDetails.php | 34 -- extensions/yii/apidoc/views/eventSummary.php | 40 --- extensions/yii/apidoc/views/index.php | 30 -- extensions/yii/apidoc/views/layouts/offline.php | 64 ---- extensions/yii/apidoc/views/methodDetails.php | 59 ---- extensions/yii/apidoc/views/methodSummary.php | 40 --- extensions/yii/apidoc/views/propertyDetails.php | 38 --- extensions/yii/apidoc/views/propertySummary.php | 41 --- extensions/yii/apidoc/views/seeAlso.php | 26 -- extensions/yii/apidoc/views/type.php | 101 ------ 47 files changed, 1177 insertions(+), 999 deletions(-) delete mode 100644 extensions/yii/apidoc/assets/css/api.css delete mode 100644 extensions/yii/apidoc/assets/css/style.css delete mode 100644 extensions/yii/apidoc/components/BaseRenderer.php delete mode 100644 extensions/yii/apidoc/components/OfflineRenderer.php create mode 100644 extensions/yii/apidoc/templates/BaseRenderer.php create mode 100644 extensions/yii/apidoc/templates/html/README.md create mode 100644 extensions/yii/apidoc/templates/html/Renderer.php create mode 100644 extensions/yii/apidoc/templates/html/views/constSummary.php create mode 100644 extensions/yii/apidoc/templates/html/views/eventDetails.php create mode 100644 extensions/yii/apidoc/templates/html/views/eventSummary.php create mode 100644 extensions/yii/apidoc/templates/html/views/methodDetails.php create mode 100644 extensions/yii/apidoc/templates/html/views/methodSummary.php create mode 100644 extensions/yii/apidoc/templates/html/views/propertyDetails.php create mode 100644 extensions/yii/apidoc/templates/html/views/propertySummary.php create mode 100644 extensions/yii/apidoc/templates/html/views/seeAlso.php create mode 100644 extensions/yii/apidoc/templates/html/views/type.php create mode 100644 extensions/yii/apidoc/templates/offline/Renderer.php create mode 100644 extensions/yii/apidoc/templates/offline/assets/css/api.css create mode 100644 extensions/yii/apidoc/templates/offline/assets/css/style.css create mode 100644 extensions/yii/apidoc/templates/offline/views/index.php create mode 100644 extensions/yii/apidoc/templates/offline/views/offline.php delete mode 100644 extensions/yii/apidoc/views/constSummary.php delete mode 100644 extensions/yii/apidoc/views/eventDetails.php delete mode 100644 extensions/yii/apidoc/views/eventSummary.php delete mode 100644 extensions/yii/apidoc/views/index.php delete mode 100644 extensions/yii/apidoc/views/layouts/offline.php delete mode 100644 extensions/yii/apidoc/views/methodDetails.php delete mode 100644 extensions/yii/apidoc/views/methodSummary.php delete mode 100644 extensions/yii/apidoc/views/propertyDetails.php delete mode 100644 extensions/yii/apidoc/views/propertySummary.php delete mode 100644 extensions/yii/apidoc/views/seeAlso.php delete mode 100644 extensions/yii/apidoc/views/type.php diff --git a/extensions/yii/apidoc/README.md b/extensions/yii/apidoc/README.md index b733d7d..7d20c71 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 91f7981..c19d642 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/assets/css/api.css b/extensions/yii/apidoc/assets/css/api.css deleted file mode 100644 index 482c04f..0000000 --- a/extensions/yii/apidoc/assets/css/api.css +++ /dev/null @@ -1,105 +0,0 @@ -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/apidoc/assets/css/style.css b/extensions/yii/apidoc/assets/css/style.css deleted file mode 100644 index 009c218..0000000 --- a/extensions/yii/apidoc/assets/css/style.css +++ /dev/null @@ -1,32 +0,0 @@ -body -{ -} - -body, div, span, p, input -{ - font-family: Verdana, Arial, sans-serif; - 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/apidoc/commands/RenderController.php b/extensions/yii/apidoc/commands/RenderController.php index 33aee50..8a46de3 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 @@ use Yii; */ 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 @@ class RenderController extends Controller mkdir($targetDir); } + $renderer = $this->findRenderer(); + $renderer->targetDir = $targetDir; + $this->stdout('Searching files to process... '); $files = []; foreach($sourceDirs as $source) { @@ -88,11 +95,26 @@ class RenderController extends Controller $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 @@ class RenderController extends Controller ]; 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/components/BaseRenderer.php b/extensions/yii/apidoc/components/BaseRenderer.php deleted file mode 100644 index 5b8fb69..0000000 --- a/extensions/yii/apidoc/components/BaseRenderer.php +++ /dev/null @@ -1,37 +0,0 @@ -_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/apidoc/components/OfflineRenderer.php b/extensions/yii/apidoc/components/OfflineRenderer.php deleted file mode 100644 index bb06141..0000000 --- a/extensions/yii/apidoc/components/OfflineRenderer.php +++ /dev/null @@ -1,311 +0,0 @@ -context = $context; - $dir = Yii::getAlias($this->targetDir); - if (!is_dir($dir)) { - mkdir($dir); - } - - $types = array_merge($context->classes, $context->interfaces, $context->traits); - $typeCount = count($types) + 1; - Console::startProgress(0, $typeCount, 'Rendering files: ', false); - $done = 0; - foreach($types as $type) { - $fileContent = $this->renderWithLayout($this->typeView, [ - 'type' => $type, - 'docContext' => $context, - ]); - file_put_contents($dir . '/' . $this->generateFileName($type->name), $fileContent); - Console::updateProgress(++$done, $typeCount); - } - $indexFileContent = $this->renderWithLayout($this->indexView, [ - 'docContext' => $context, - 'types' => $types, - ]); - file_put_contents($dir . '/index.html', $indexFileContent); - 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) - { - $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 a type (class, interface or trait) - * @param ClassDoc|InterfaceDoc|TraitDoc $types - * @param string $title - * @return string - */ - public function typeLink($types, $context = null) - { - if (!is_array($types)) { - $types = [$types]; - } - $links = []; - foreach($types as $type) { - $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( - $type->name, - null, - ['href' => $this->generateFileName($type->name)] - ) . $postfix; - } - } - 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 = $subject->name; - } - if (($type = $this->context->getType($subject->definedBy)) === null) { - return $subject->name; - } else { - $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 ''; - } - - /** - * @param ClassDoc $class - * @return string - */ - public function renderInheritance($class) - { - $parents[] = $this->typeLink($class); - while ($class->parentClass !== null) { - if(isset($this->context->classes[$class->parentClass])) { - $class = $this->context->classes[$class->parentClass]; - $parents[] = $this->typeLink($class); - } else { - $parents[] = $class->parentClass; // TODO link to php.net - break; - } - } - return implode(" »\n",$parents); - } - - /** - * @param array $names - * @return string - */ - public function renderInterfaces($names) - { - $interfaces = []; - sort($names, SORT_STRING); - foreach($names as $interface) { - if(isset($this->context->interfaces[$interface])) { - $interfaces[] = $this->typeLink($this->context->interfaces[$interface]); - } else { - $interfaces[] = $interface; // TODO link to php.net - } - } - return implode(', ',$interfaces); - } - - /** - * @param array $names - * @return string - */ - public function renderTraits($names) - { - $traits = []; - sort($names, SORT_STRING); - foreach($names as $trait) { - if(isset($this->context->traits[$trait])) { - $traits[] = $this->typeLink($this->context->traits[$trait]); - } else { - $traits[] = $trait; // TODO link to php.net - } - } - return implode(', ',$traits); - } - - /** - * @param array $names - * @return string - */ - public function renderClasses($names) - { - $classes = []; - sort($names, SORT_STRING); - foreach($names as $class) { - if(isset($this->context->classes[$class])) { - $classes[] = $this->typeLink($this->context->classes[$class]); - } else { - $classes[] = $class; // TODO link to php.net - } - } - 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) - { - return strtolower(str_replace('\\', '_', $typeName)) . '.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/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 d52011c..b595dcc 100644 --- a/extensions/yii/apidoc/models/BaseDoc.php +++ b/extensions/yii/apidoc/models/BaseDoc.php @@ -11,6 +11,11 @@ use phpDocumentor\Reflection\DocBlock\Tag\DeprecatedTag; 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 82da1d5..a70ae85 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 b1d3a93..a0fbf08 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 549c318..5378195 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 78aee19..41771c5 100644 --- a/extensions/yii/apidoc/models/EventDoc.php +++ b/extensions/yii/apidoc/models/EventDoc.php @@ -10,6 +10,11 @@ namespace yii\apidoc\models; 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 30338a6..1120f77 100644 --- a/extensions/yii/apidoc/models/FunctionDoc.php +++ b/extensions/yii/apidoc/models/FunctionDoc.php @@ -13,6 +13,11 @@ use phpDocumentor\Reflection\DocBlock\Tag\ReturnTag; 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 8aea744..57cd9ce 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 96ca5c3..0f7288f 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 da5127b..0d4c162 100644 --- a/extensions/yii/apidoc/models/ParamDoc.php +++ b/extensions/yii/apidoc/models/ParamDoc.php @@ -9,6 +9,11 @@ namespace yii\apidoc\models; 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 68fc414..cf17b0d 100644 --- a/extensions/yii/apidoc/models/PropertyDoc.php +++ b/extensions/yii/apidoc/models/PropertyDoc.php @@ -9,6 +9,11 @@ namespace yii\apidoc\models; 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 347640a..37f1799 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 d892a3d..9ceaf26 100644 --- a/extensions/yii/apidoc/models/TypeDoc.php +++ b/extensions/yii/apidoc/models/TypeDoc.php @@ -11,6 +11,11 @@ use phpDocumentor\Reflection\DocBlock\Tag\AuthorTag; 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/templates/BaseRenderer.php b/extensions/yii/apidoc/templates/BaseRenderer.php new file mode 100644 index 0000000..4f29e43 --- /dev/null +++ b/extensions/yii/apidoc/templates/BaseRenderer.php @@ -0,0 +1,32 @@ + + * @since 2.0 + */ +abstract class BaseRenderer extends Component +{ + /** + * 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 diff --git a/extensions/yii/apidoc/templates/html/README.md b/extensions/yii/apidoc/templates/html/README.md new file mode 100644 index 0000000..90e3b35 --- /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/templates/html/Renderer.php b/extensions/yii/apidoc/templates/html/Renderer.php new file mode 100644 index 0000000..bf730c7 --- /dev/null +++ b/extensions/yii/apidoc/templates/html/Renderer.php @@ -0,0 +1,349 @@ + + * @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; + /** + * @var string string to use as the title of the generated page. + */ + public $pageTitle = 'Yii Framework 2.0 API Documentation'; + /** + * @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; + } + + /** + * 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) + { + $this->context = $context; + $dir = Yii::getAlias($this->targetDir); + if (!is_dir($dir)) { + mkdir($dir); + } + + $types = array_merge($context->classes, $context->interfaces, $context->traits); + $typeCount = count($types) + 1; + Console::startProgress(0, $typeCount, 'Rendering files: ', false); + $done = 0; + foreach($types as $type) { + $fileContent = $this->renderWithLayout($this->typeView, [ + 'type' => $type, + 'docContext' => $context, + ]); + file_put_contents($dir . '/' . $this->generateFileName($type->name), $fileContent); + Console::updateProgress(++$done, $typeCount); + } + $indexFileContent = $this->renderWithLayout($this->indexView, [ + 'docContext' => $context, + 'types' => $types, + ]); + file_put_contents($dir . '/index.html', $indexFileContent); + Console::updateProgress(++$done, $typeCount); + Console::endProgress(true); + $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 a type (class, interface or trait) + * @param ClassDoc|InterfaceDoc|TraitDoc $types + * @param BaseDoc $context + * @return string + */ + public function typeLink($types, $context = null) + { + if (!is_array($types)) { + $types = [$types]; + } + $links = []; + foreach($types as $type) { + $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( + $type->name, + null, + ['href' => $this->generateFileName($type->name)] + ) . $postfix; + } + } + 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 = $subject->name; + } + if (($type = $this->context->getType($subject->definedBy)) === null) { + return $subject->name; + } else { + $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) + { + // TODO use phpdoc Context for this + 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 ''; + } + + /** + * @param ClassDoc $class + * @return string + */ + public function renderInheritance($class) + { + $parents[] = $this->typeLink($class); + while ($class->parentClass !== null) { + if(isset($this->context->classes[$class->parentClass])) { + $class = $this->context->classes[$class->parentClass]; + $parents[] = $this->typeLink($class); + } else { + $parents[] = $class->parentClass; // TODO link to php.net + break; + } + } + return implode(" »\n",$parents); + } + + /** + * @param array $names + * @return string + */ + public function renderInterfaces($names) + { + $interfaces = []; + sort($names, SORT_STRING); + foreach($names as $interface) { + if(isset($this->context->interfaces[$interface])) { + $interfaces[] = $this->typeLink($this->context->interfaces[$interface]); + } else { + $interfaces[] = $interface; // TODO link to php.net + } + } + return implode(', ',$interfaces); + } + + /** + * @param array $names + * @return string + */ + public function renderTraits($names) + { + $traits = []; + sort($names, SORT_STRING); + foreach($names as $trait) { + if(isset($this->context->traits[$trait])) { + $traits[] = $this->typeLink($this->context->traits[$trait]); + } else { + $traits[] = $trait; // TODO link to php.net + } + } + return implode(', ',$traits); + } + + /** + * @param array $names + * @return string + */ + public function renderClasses($names) + { + $classes = []; + sort($names, SORT_STRING); + foreach($names as $class) { + if(isset($this->context->classes[$class])) { + $classes[] = $this->typeLink($this->context->classes[$class]); + } else { + $classes[] = $class; // TODO link to php.net + } + } + 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 : ''); + } + + return ($method->isReturnByReference ? '&' : '') + . ($method->returnType === null ? 'void' : $this->typeLink($method->returnTypes)) + . ' ' . $method->name . '( ' + . implode(', ', $params) + . ' )'; + } + + protected function generateFileName($typeName) + { + return strtolower(str_replace('\\', '_', $typeName)) . '.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/apidoc/templates/html/views/' . $view); + } +} \ No newline at end of file diff --git a/extensions/yii/apidoc/templates/html/views/constSummary.php b/extensions/yii/apidoc/templates/html/views/constSummary.php new file mode 100644 index 0000000..63dbbfb --- /dev/null +++ b/extensions/yii/apidoc/templates/html/views/constSummary.php @@ -0,0 +1,35 @@ +constants)) { + return; +} ?> +
+

Constants

+ +

Hide inherited constants

+ + ++ + + + + + + +constants as $constant): ?> + definedBy != $type->name ? ' class="inherited"' : '' ?> id="name ?>"> + + + + + + +
ConstantValueDescriptionDefined By
name ?>value ?>shortDescription . "\n" . $constant->description) ?>context->typeLink($constant->definedBy) ?>
+
\ No newline at end of file diff --git a/extensions/yii/apidoc/templates/html/views/eventDetails.php b/extensions/yii/apidoc/templates/html/views/eventDetails.php new file mode 100644 index 0000000..9ba925e --- /dev/null +++ b/extensions/yii/apidoc/templates/html/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/templates/html/views/eventSummary.php b/extensions/yii/apidoc/templates/html/views/eventSummary.php new file mode 100644 index 0000000..56cb0fa --- /dev/null +++ b/extensions/yii/apidoc/templates/html/views/eventSummary.php @@ -0,0 +1,40 @@ +events)) { + return; +} ?> +
+

Events

+ +

Hide inherited events

+ + ++ + + + + + + +events as $event): ?> +definedBy != $type->name ? ' class="inherited"' : '' ?> id="name ?>"> + + + + + + +
EventTypeDescriptionDefined By
context->subjectLink($event) ?>context->typeLink($event->types) ?> + shortDescription ?> + since)): ?> + (available since version since; ?>) + + context->typeLink($event->definedBy) ?>
+
\ No newline at end of file diff --git a/extensions/yii/apidoc/templates/html/views/methodDetails.php b/extensions/yii/apidoc/templates/html/views/methodDetails.php new file mode 100644 index 0000000..e0c0dbe --- /dev/null +++ b/extensions/yii/apidoc/templates/html/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/templates/html/views/methodSummary.php b/extensions/yii/apidoc/templates/html/views/methodSummary.php new file mode 100644 index 0000000..e597d53 --- /dev/null +++ b/extensions/yii/apidoc/templates/html/views/methodSummary.php @@ -0,0 +1,40 @@ +getProtectedMethods()) == 0 || !$protected && count($type->getPublicMethods()) == 0) { + return; +} ?> + +
+

+ +

Hide inherited methods

+ + ++ + + + + + + +methods as $method): ?> +visibility == 'protected' || !$protected && $method->visibility != 'protected'): ?> +definedBy != $type->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/templates/html/views/propertyDetails.php b/extensions/yii/apidoc/templates/html/views/propertyDetails.php new file mode 100644 index 0000000..80fb34a --- /dev/null +++ b/extensions/yii/apidoc/templates/html/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/templates/html/views/propertySummary.php b/extensions/yii/apidoc/templates/html/views/propertySummary.php new file mode 100644 index 0000000..ae95850 --- /dev/null +++ b/extensions/yii/apidoc/templates/html/views/propertySummary.php @@ -0,0 +1,41 @@ +getProtectedProperties()) == 0 || !$protected && count($type->getPublicProperties()) == 0) { + return; +} ?> + +
+

+ +

Hide inherited properties

+ + ++ + + + + + + + +properties as $property): ?> +visibility == 'protected' || !$protected && $property->visibility != 'protected'): ?> +definedBy != $type->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 diff --git a/extensions/yii/apidoc/templates/html/views/seeAlso.php b/extensions/yii/apidoc/templates/html/views/seeAlso.php new file mode 100644 index 0000000..e955318 --- /dev/null +++ b/extensions/yii/apidoc/templates/html/views/seeAlso.php @@ -0,0 +1,26 @@ +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/templates/html/views/type.php b/extensions/yii/apidoc/templates/html/views/type.php new file mode 100644 index 0000000..50959dc --- /dev/null +++ b/extensions/yii/apidoc/templates/html/views/type.php @@ -0,0 +1,101 @@ +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('@yii/apidoc/templates/html/views/propertySummary', ['type' => $type,'protected' => false]) ?> +render('@yii/apidoc/templates/html/views/propertySummary', ['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('@yii/apidoc/templates/html/views/eventSummary', ['type' => $type]) ?> + + +render('@yii/apidoc/templates/html/views/constSummary', ['type' => $type]) ?> + +render('@yii/apidoc/templates/html/views/propertyDetails', ['type' => $type]) ?> +render('@yii/apidoc/templates/html/views/methodDetails', ['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 0000000..1e544b7 --- /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/templates/offline/assets/css/api.css b/extensions/yii/apidoc/templates/offline/assets/css/api.css new file mode 100644 index 0000000..482c04f --- /dev/null +++ b/extensions/yii/apidoc/templates/offline/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/apidoc/templates/offline/assets/css/style.css b/extensions/yii/apidoc/templates/offline/assets/css/style.css new file mode 100644 index 0000000..009c218 --- /dev/null +++ b/extensions/yii/apidoc/templates/offline/assets/css/style.css @@ -0,0 +1,32 @@ +body +{ +} + +body, div, span, p, input +{ + font-family: Verdana, Arial, sans-serif; + 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/apidoc/templates/offline/views/index.php b/extensions/yii/apidoc/templates/offline/views/index.php new file mode 100644 index 0000000..310e9af --- /dev/null +++ b/extensions/yii/apidoc/templates/offline/views/index.php @@ -0,0 +1,30 @@ +

Class Reference

+ + ++ + + + + + + +$class): ?> + + + + + +
ClassDescription
context->typeLink($class, $class->name); ?>shortDescription; ?>
diff --git a/extensions/yii/apidoc/templates/offline/views/offline.php b/extensions/yii/apidoc/templates/offline/views/offline.php new file mode 100644 index 0000000..36b2487 --- /dev/null +++ b/extensions/yii/apidoc/templates/offline/views/offline.php @@ -0,0 +1,65 @@ +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 diff --git a/extensions/yii/apidoc/views/constSummary.php b/extensions/yii/apidoc/views/constSummary.php deleted file mode 100644 index 63dbbfb..0000000 --- a/extensions/yii/apidoc/views/constSummary.php +++ /dev/null @@ -1,35 +0,0 @@ -constants)) { - return; -} ?> -
-

Constants

- -

Hide inherited constants

- - -- - - - - - - -constants as $constant): ?> - definedBy != $type->name ? ' class="inherited"' : '' ?> id="name ?>"> - - - - - - -
ConstantValueDescriptionDefined By
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 deleted file mode 100644 index 9ba925e..0000000 --- a/extensions/yii/apidoc/views/eventDetails.php +++ /dev/null @@ -1,34 +0,0 @@ -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 deleted file mode 100644 index 56cb0fa..0000000 --- a/extensions/yii/apidoc/views/eventSummary.php +++ /dev/null @@ -1,40 +0,0 @@ -events)) { - return; -} ?> -
-

Events

- -

Hide inherited events

- - -- - - - - - - -events as $event): ?> -definedBy != $type->name ? ' class="inherited"' : '' ?> id="name ?>"> - - - - - - -
EventTypeDescriptionDefined By
context->subjectLink($event) ?>context->typeLink($event->types) ?> - shortDescription ?> - since)): ?> - (available since version since; ?>) - - 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 deleted file mode 100644 index 310e9af..0000000 --- a/extensions/yii/apidoc/views/index.php +++ /dev/null @@ -1,30 +0,0 @@ -

Class Reference

- - -- - - - - - - -$class): ?> - - - - - -
ClassDescription
context->typeLink($class, $class->name); ?>shortDescription; ?>
diff --git a/extensions/yii/apidoc/views/layouts/offline.php b/extensions/yii/apidoc/views/layouts/offline.php deleted file mode 100644 index 809de75..0000000 --- a/extensions/yii/apidoc/views/layouts/offline.php +++ /dev/null @@ -1,64 +0,0 @@ -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 diff --git a/extensions/yii/apidoc/views/methodDetails.php b/extensions/yii/apidoc/views/methodDetails.php deleted file mode 100644 index e0c0dbe..0000000 --- a/extensions/yii/apidoc/views/methodDetails.php +++ /dev/null @@ -1,59 +0,0 @@ -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 deleted file mode 100644 index e597d53..0000000 --- a/extensions/yii/apidoc/views/methodSummary.php +++ /dev/null @@ -1,40 +0,0 @@ -getProtectedMethods()) == 0 || !$protected && count($type->getPublicMethods()) == 0) { - return; -} ?> - -
-

- -

Hide inherited methods

- - -- - - - - - - -methods as $method): ?> -visibility == 'protected' || !$protected && $method->visibility != 'protected'): ?> -definedBy != $type->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/propertyDetails.php b/extensions/yii/apidoc/views/propertyDetails.php deleted file mode 100644 index 80fb34a..0000000 --- a/extensions/yii/apidoc/views/propertyDetails.php +++ /dev/null @@ -1,38 +0,0 @@ -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 deleted file mode 100644 index ae95850..0000000 --- a/extensions/yii/apidoc/views/propertySummary.php +++ /dev/null @@ -1,41 +0,0 @@ -getProtectedProperties()) == 0 || !$protected && count($type->getPublicProperties()) == 0) { - return; -} ?> - -
-

- -

Hide inherited properties

- - -- - - - - - - - -properties as $property): ?> -visibility == 'protected' || !$protected && $property->visibility != 'protected'): ?> -definedBy != $type->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 diff --git a/extensions/yii/apidoc/views/seeAlso.php b/extensions/yii/apidoc/views/seeAlso.php deleted file mode 100644 index e955318..0000000 --- a/extensions/yii/apidoc/views/seeAlso.php +++ /dev/null @@ -1,26 +0,0 @@ -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 deleted file mode 100644 index a911b63..0000000 --- a/extensions/yii/apidoc/views/type.php +++ /dev/null @@ -1,101 +0,0 @@ -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]) ?> - -render('propertyDetails', ['type' => $type]) ?> -render('methodDetails', ['type' => $type]) ?> - - render('eventDetails', ['type' => $type]) ?> - From b9c1eff373a76f9c120c821fb11f63aeb8df8e25 Mon Sep 17 00:00:00 2001 From: Carsten Brandt Date: Mon, 6 Jan 2014 01:16:25 +0100 Subject: [PATCH 11/17] fixed javascript --- extensions/yii/apidoc/templates/html/Renderer.php | 2 +- .../yii/apidoc/templates/offline/Renderer.php | 18 ------------- .../templates/offline/assets/AssetBundle.php | 31 ++++++++++++++++++++++ .../yii/apidoc/templates/offline/views/offline.php | 26 +++++++++++------- framework/yii/helpers/BaseHtml.php | 2 +- 5 files changed, 49 insertions(+), 30 deletions(-) create mode 100644 extensions/yii/apidoc/templates/offline/assets/AssetBundle.php diff --git a/extensions/yii/apidoc/templates/html/Renderer.php b/extensions/yii/apidoc/templates/html/Renderer.php index bf730c7..4d5ae20 100644 --- a/extensions/yii/apidoc/templates/html/Renderer.php +++ b/extensions/yii/apidoc/templates/html/Renderer.php @@ -76,7 +76,7 @@ abstract class Renderer extends BaseRenderer implements ViewContextInterface } $this->_view->assetManager = new AssetManager([ 'basePath' => $assetPath, - 'baseUrl' => '/assets', + 'baseUrl' => './assets', ]); } return $this->_view; diff --git a/extensions/yii/apidoc/templates/offline/Renderer.php b/extensions/yii/apidoc/templates/offline/Renderer.php index 1e544b7..a618fc8 100644 --- a/extensions/yii/apidoc/templates/offline/Renderer.php +++ b/extensions/yii/apidoc/templates/offline/Renderer.php @@ -23,22 +23,4 @@ class Renderer extends \yii\apidoc\templates\html\Renderer 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/templates/offline/assets/AssetBundle.php b/extensions/yii/apidoc/templates/offline/assets/AssetBundle.php new file mode 100644 index 0000000..e8c7024 --- /dev/null +++ b/extensions/yii/apidoc/templates/offline/assets/AssetBundle.php @@ -0,0 +1,31 @@ + + * @since 2.0 + */ +class AssetBundle extends \yii\web\AssetBundle +{ + public $sourcePath = '@yii/apidoc/templates/offline/assets/css'; + public $css = [ + 'api.css', + 'style.css', + ]; + public $depends = [ + 'yii\web\JqueryAsset', + ]; + public $jsOptions = [ + 'position' => View::POS_HEAD, + ]; +} diff --git a/extensions/yii/apidoc/templates/offline/views/offline.php b/extensions/yii/apidoc/templates/offline/views/offline.php index 36b2487..b5565c5 100644 --- a/extensions/yii/apidoc/templates/offline/views/offline.php +++ b/extensions/yii/apidoc/templates/offline/views/offline.php @@ -4,6 +4,8 @@ * @var yii\web\View $this */ +\yii\apidoc\templates\offline\assets\AssetBundle::register($this); + $this->beginPage(); ?> @@ -11,9 +13,6 @@ $this->beginPage(); - - - head(); ?> <?php echo $this->context->pageTitle; ?> @@ -35,16 +34,22 @@ $this->beginPage(); All Rights Reserved.
- diff --git a/framework/yii/helpers/BaseHtml.php b/framework/yii/helpers/BaseHtml.php index b3a88c1..b25ffa4 100644 --- a/framework/yii/helpers/BaseHtml.php +++ b/framework/yii/helpers/BaseHtml.php @@ -1471,7 +1471,7 @@ class BaseHtml 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 +++++++ extensions/yii/apidoc/templates/BaseRenderer.php | 33 +++++++++- extensions/yii/apidoc/templates/html/Renderer.php | 17 +++-- .../apidoc/templates/html/views/constSummary.php | 3 +- .../apidoc/templates/html/views/eventDetails.php | 3 +- .../apidoc/templates/html/views/eventSummary.php | 3 +- .../apidoc/templates/html/views/methodDetails.php | 9 +-- .../apidoc/templates/html/views/methodSummary.php | 15 +++-- .../templates/html/views/propertyDetails.php | 3 +- .../templates/html/views/propertySummary.php | 17 ++--- .../yii/apidoc/templates/html/views/seeAlso.php | 9 ++- .../yii/apidoc/templates/html/views/type.php | 7 +- .../apidoc/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 0000000..2bbad50 --- /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 b595dcc..c470ab5 100644 --- a/extensions/yii/apidoc/models/BaseDoc.php +++ b/extensions/yii/apidoc/models/BaseDoc.php @@ -18,6 +18,11 @@ use yii\base\Object; */ class BaseDoc extends Object { + /** + * @var \phpDocumentor\Reflection\DocBlock\Context + */ + public $phpDocContext; + public $name; public $sourceFile; @@ -55,9 +60,11 @@ class BaseDoc extends Object $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 a70ae85..d9b17a4 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 1120f77..9c7e212 100644 --- a/extensions/yii/apidoc/models/FunctionDoc.php +++ b/extensions/yii/apidoc/models/FunctionDoc.php @@ -60,7 +60,7 @@ class FunctionDoc extends BaseDoc 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 9ceaf26..5a83383 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 4f29e43..97d58a5 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 @@ -23,10 +28,32 @@ use yii\web\View; abstract class BaseRenderer extends Component { /** + * @var Context the [[Context]] currently being rendered. + */ + public $context; + + + /** * 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); + + /** + * 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 4d5ae20..2129695 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; @@ -55,14 +56,16 @@ abstract class Renderer extends BaseRenderer implements ViewContextInterface */ 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 @@ abstract class Renderer extends BaseRenderer implements ViewContextInterface 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 63dbbfb..a872aa5 100644 --- a/extensions/yii/apidoc/templates/html/views/constSummary.php +++ b/extensions/yii/apidoc/templates/html/views/constSummary.php @@ -1,5 +1,6 @@ constants)) { 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 9ba925e..a5b3091 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 56cb0fa..0c179b6 100644 --- a/extensions/yii/apidoc/templates/html/views/eventSummary.php +++ b/extensions/yii/apidoc/templates/html/views/eventSummary.php @@ -1,5 +1,6 @@ events)) { 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 e0c0dbe..c3e5290 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 @@ if (empty($methods)) { 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 e597d53..c3ca6d5 100644 --- a/extensions/yii/apidoc/templates/html/views/methodSummary.php +++ b/extensions/yii/apidoc/templates/html/views/methodSummary.php @@ -1,5 +1,6 @@ getProtectedMethods()) == 0 || !$protected && cou 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 80fb34a..628f9bd 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 ae95850..3730431 100644 --- a/extensions/yii/apidoc/templates/html/views/propertySummary.php +++ b/extensions/yii/apidoc/templates/html/views/propertySummary.php @@ -1,5 +1,6 @@ getProtectedProperties()) == 0 || !$protected && 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 e955318..9990714 100644 --- a/extensions/yii/apidoc/templates/html/views/seeAlso.php +++ b/extensions/yii/apidoc/templates/html/views/seeAlso.php @@ -9,7 +9,12 @@ $see = []; foreach($object->tags as $tag) { /** @var $tag phpDocumentor\Reflection\DocBlock\Tag\SeeTag */ if (get_class($tag) == 'phpDocumentor\Reflection\DocBlock\Tag\SeeTag') { - $see[] = $tag->getReference(); + $ref = $tag->getReference(); + if (strpos($ref, '://') === false) { + $see[] = '[[' . $ref . ']]'; + } else { + $see[] = $ref; + } } } if (empty($see)) { @@ -20,7 +25,7 @@ if (empty($see)) {

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 50959dc..64de2d1 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 @@ $renderer = $this->context;
- 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 482c04f..8ad7e07 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 --- extensions/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 c3e5290..5501133 100644 --- a/extensions/yii/apidoc/templates/html/views/methodDetails.php +++ b/extensions/yii/apidoc/templates/html/views/methodDetails.php @@ -32,7 +32,7 @@ if (empty($methods)) { context->renderMethodSignature($method) ?> - params) || !empty($method->return)): ?> + params) || !empty($method->return) || !empty($method->exceptions)): ?> params as $param): ?> name ?> @@ -42,11 +42,18 @@ if (empty($methods)) { 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 ---- extensions/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 5378195..4260cbf 100644 --- a/extensions/yii/apidoc/models/Context.php +++ b/extensions/yii/apidoc/models/Context.php @@ -103,10 +103,16 @@ class Context extends Component } } } - // 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 @@ class Context extends Component $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 9c7e212..62026a8 100644 --- a/extensions/yii/apidoc/models/FunctionDoc.php +++ b/extensions/yii/apidoc/models/FunctionDoc.php @@ -54,7 +54,7 @@ class FunctionDoc extends BaseDoc $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 5a83383..a4c68d2 100644 --- a/extensions/yii/apidoc/models/TypeDoc.php +++ b/extensions/yii/apidoc/models/TypeDoc.php @@ -178,25 +178,6 @@ class TypeDoc extends BaseDoc 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 2129695..bc53d3a 100644 --- a/extensions/yii/apidoc/templates/html/Renderer.php +++ b/extensions/yii/apidoc/templates/html/Renderer.php @@ -302,20 +302,17 @@ abstract class Renderer extends BaseRenderer implements ViewContextInterface */ 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 @@ abstract class Renderer extends BaseRenderer implements ViewContextInterface 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 7d20c71..0ae1ec3 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 +++++--- extensions/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 2bbad50..682603d 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 0000000..288178d --- /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 4260cbf..94fd1dc 100644 --- a/extensions/yii/apidoc/models/Context.php +++ b/extensions/yii/apidoc/models/Context.php @@ -160,7 +160,7 @@ class Context extends Component 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 @@ class Context extends Component 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 62026a8..232d236 100644 --- a/extensions/yii/apidoc/models/FunctionDoc.php +++ b/extensions/yii/apidoc/models/FunctionDoc.php @@ -58,7 +58,8 @@ class FunctionDoc extends BaseDoc } 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 0d4c162..2be9de8 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 @@ class ParamDoc extends Object $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 cf17b0d..dbe4a20 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 @@ class PropertyDoc extends BaseDoc $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 8a46de3..cbd97ae 100644 --- a/extensions/yii/apidoc/commands/RenderController.php +++ b/extensions/yii/apidoc/commands/RenderController.php @@ -129,11 +129,7 @@ class RenderController extends Controller 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 682603d..6139b15 100644 --- a/extensions/yii/apidoc/helpers/Markdown.php +++ b/extensions/yii/apidoc/helpers/Markdown.php @@ -13,6 +13,7 @@ use yii\apidoc\models\TypeDoc; 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 c470ab5..9c8cfb9 100644 --- a/extensions/yii/apidoc/models/BaseDoc.php +++ b/extensions/yii/apidoc/models/BaseDoc.php @@ -12,6 +12,7 @@ use phpDocumentor\Reflection\DocBlock\Tag\SinceTag; 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 d9b17a4..020105f 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 a0fbf08..1f185da 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 41771c5..2c15f3d 100644 --- a/extensions/yii/apidoc/models/EventDoc.php +++ b/extensions/yii/apidoc/models/EventDoc.php @@ -11,6 +11,7 @@ use phpDocumentor\Reflection\DocBlock\Tag\ParamTag; 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 232d236..82c09ec 100644 --- a/extensions/yii/apidoc/models/FunctionDoc.php +++ b/extensions/yii/apidoc/models/FunctionDoc.php @@ -14,6 +14,7 @@ use phpDocumentor\Reflection\DocBlock\Tag\ThrowsTag; 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 57cd9ce..10b6d65 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 0f7288f..e31d31c 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 2be9de8..de6ef5d 100644 --- a/extensions/yii/apidoc/models/ParamDoc.php +++ b/extensions/yii/apidoc/models/ParamDoc.php @@ -11,6 +11,7 @@ use yii\apidoc\helpers\PrettyPrinter; 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 dbe4a20..b865fba 100644 --- a/extensions/yii/apidoc/models/PropertyDoc.php +++ b/extensions/yii/apidoc/models/PropertyDoc.php @@ -11,6 +11,7 @@ use phpDocumentor\Reflection\DocBlock\Tag\VarTag; 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 37f1799..1169f99 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 a4c68d2..6561fc7 100644 --- a/extensions/yii/apidoc/models/TypeDoc.php +++ b/extensions/yii/apidoc/models/TypeDoc.php @@ -12,6 +12,7 @@ use yii\base\Exception; use yii\helpers\StringHelper; /** + * Base class for API documentation information for classes, interfaces and traits. * * @author Carsten Brandt * @since 2.0