You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
166 lines
5.0 KiB
166 lines
5.0 KiB
<?php |
|
/** |
|
* @link http://www.yiiframework.com/ |
|
* @copyright Copyright (c) 2008 Yii Software LLC |
|
* @license http://www.yiiframework.com/license/ |
|
*/ |
|
|
|
namespace yii\apidoc\commands; |
|
|
|
use yii\apidoc\components\BaseController; |
|
use yii\apidoc\models\Context; |
|
use yii\apidoc\renderers\ApiRenderer; |
|
use yii\apidoc\renderers\BaseRenderer; |
|
use yii\helpers\ArrayHelper; |
|
use yii\helpers\Console; |
|
use yii\helpers\FileHelper; |
|
|
|
/** |
|
* Generate class API documentation. |
|
* |
|
* @author Carsten Brandt <mail@cebe.cc> |
|
* @since 2.0 |
|
*/ |
|
class ApiController extends BaseController |
|
{ |
|
/** |
|
* @var string url to where the guide files are located |
|
*/ |
|
public $guide; |
|
|
|
// TODO add force update option |
|
|
|
/** |
|
* Renders API documentation files |
|
* @param array $sourceDirs |
|
* @param string $targetDir |
|
* @return int |
|
*/ |
|
public function actionIndex(array $sourceDirs, $targetDir) |
|
{ |
|
$renderer = $this->findRenderer($this->template); |
|
$targetDir = $this->normalizeTargetDir($targetDir); |
|
if ($targetDir === false || $renderer === false) { |
|
return 1; |
|
} |
|
|
|
$renderer->apiUrl = './'; |
|
|
|
// setup reference to guide |
|
if ($this->guide !== null) { |
|
$guideUrl = $this->guide; |
|
$referenceFile = $guideUrl . '/' . BaseRenderer::GUIDE_PREFIX . 'references.txt'; |
|
} else { |
|
$guideUrl = './'; |
|
$referenceFile = $targetDir . '/' . BaseRenderer::GUIDE_PREFIX . 'references.txt'; |
|
} |
|
if (file_exists($referenceFile)) { |
|
$renderer->guideUrl = $guideUrl; |
|
$renderer->guideReferences = []; |
|
foreach (explode("\n", file_get_contents($referenceFile)) as $reference) { |
|
$renderer->guideReferences[BaseRenderer::GUIDE_PREFIX . $reference]['url'] = $renderer->generateGuideUrl($reference); |
|
} |
|
} |
|
|
|
// search for files to process |
|
if (($files = $this->searchFiles($sourceDirs)) === false) { |
|
return 1; |
|
} |
|
|
|
// load context from cache |
|
$context = $this->loadContext($targetDir); |
|
$this->stdout('Checking for updated files... '); |
|
foreach ($context->files as $file => $sha) { |
|
if (!file_exists($file)) { |
|
$this->stdout('At least one file has been removed. Rebuilding the context...'); |
|
$context = new Context(); |
|
if (($files = $this->searchFiles($sourceDirs)) === false) { |
|
return 1; |
|
} |
|
break; |
|
} |
|
if (sha1_file($file) === $sha) { |
|
unset($files[$file]); |
|
} |
|
} |
|
$this->stdout('done.' . PHP_EOL, Console::FG_GREEN); |
|
|
|
// process files |
|
$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 |
|
$this->storeContext($context, $targetDir); |
|
|
|
$this->updateContext($context); |
|
|
|
// render models |
|
$renderer->controller = $this; |
|
$renderer->render($context, $targetDir); |
|
|
|
if (!empty($context->errors)) { |
|
ArrayHelper::multisort($context->errors, 'file'); |
|
file_put_contents($targetDir . '/errors.txt', print_r($context->errors, true)); |
|
$this->stdout(count($context->errors) . " errors have been logged to $targetDir/errors.txt\n", Console::FG_RED, Console::BOLD); |
|
} |
|
} |
|
|
|
/** |
|
* @inheritdoc |
|
*/ |
|
protected function findFiles($path, $except = []) |
|
{ |
|
if (empty($except)) { |
|
$except = ['vendor/', 'tests/']; |
|
} |
|
$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' => $except, |
|
]; |
|
|
|
return FileHelper::findFiles($path, $options); |
|
} |
|
|
|
/** |
|
* @inheritdoc |
|
* @return ApiRenderer |
|
*/ |
|
protected function findRenderer($template) |
|
{ |
|
$rendererClass = 'yii\\apidoc\\templates\\' . $template . '\\ApiRenderer'; |
|
if (!class_exists($rendererClass)) { |
|
$this->stderr('Renderer not found.' . PHP_EOL); |
|
|
|
return false; |
|
} |
|
|
|
return new $rendererClass(); |
|
} |
|
|
|
/** |
|
* @inheritdoc |
|
*/ |
|
public function options($actionId) |
|
{ |
|
return array_merge(parent::options($actionId), ['template', 'guide']); |
|
} |
|
}
|
|
|