188 lines
6.9 KiB
PHP
188 lines
6.9 KiB
PHP
<?php
|
|
|
|
namespace plugin\apidoc\library;
|
|
|
|
use app\service\ConfServiceFacade;
|
|
use laytp\traits\Error;
|
|
use plugin\apidoc\library\apidoc\library\Builder;
|
|
use plugin\apidoc\library\apidoc\library\Extractor;
|
|
use laytp\library\DirFile;
|
|
use think\facade\Env;
|
|
use think\facade\View;
|
|
|
|
class Apidoc
|
|
{
|
|
use Error;
|
|
protected $template = 'index.html';
|
|
protected $output = 'api.html';
|
|
protected $force = true;
|
|
|
|
/**
|
|
* 执行生成程序
|
|
* @param $title
|
|
* @return bool
|
|
* @throws \think\db\exception\DataNotFoundException
|
|
* @throws \think\db\exception\DbException
|
|
* @throws \think\db\exception\ModelNotFoundException
|
|
*/
|
|
public function execute($title)
|
|
{
|
|
// $addon = $input->getOption('addon');
|
|
// if($addon){
|
|
// $addon_service = new Addons();
|
|
// $addon_info = $addon_service->_info->getPluginInfo($addon);
|
|
// $controllerDir = Env::get('root_path') . DS . 'addons' . DS . $addon . DS . $addon_info['api_module'] . DS;
|
|
// }else{
|
|
$controllerDir = app()->getRootPath() . DS . 'app' . DS . 'controller' . DS . 'api' . DS;
|
|
// }
|
|
|
|
$files = new \RecursiveIteratorIterator(
|
|
new \RecursiveDirectoryIterator($controllerDir), \RecursiveIteratorIterator::LEAVES_ONLY
|
|
);
|
|
|
|
$weighs = [];
|
|
$k = 0;
|
|
foreach ($files as $name => $file) {
|
|
if (!$file->isDir()) {
|
|
$filePath = $file->getRealPath();
|
|
$className = $this->getClassFromFile($filePath);
|
|
$classAnnotations = Extractor::getClassAnnotations($className);
|
|
if (isset($classAnnotations['ApiInternal'])) {
|
|
continue;
|
|
}
|
|
$weigh = isset($classAnnotations['ApiWeigh']) ? intval($classAnnotations['ApiWeigh'][0]) : $k;
|
|
$weighs[$this->getClassFromFile($filePath)] = $weigh;
|
|
$k++;
|
|
}
|
|
}
|
|
uasort($weighs, function ($a, $b) {
|
|
if ($a == $b) return 0;
|
|
return ($a > $b) ? -1 : 1;
|
|
});
|
|
|
|
$classes = array_flip($weighs);
|
|
|
|
$builder = new Builder($classes);
|
|
$apiDir = __DIR__ . DS . 'apidoc' . DS;
|
|
$templateDir = $apiDir . 'template' . DS;
|
|
$templateFile = $templateDir . $this->template;
|
|
$var['plugin'] = '';
|
|
$var['title'] = $title;
|
|
$var['apiDomain'] = Env::get('domain.api');
|
|
$var['createSignKey'] = ConfServiceFacade::get('system.basic.signKey');
|
|
$var['apidocList'] = \plugin\apidoc\model\Apidoc::select()->toArray();
|
|
// $content = $builder->render($templateFile, $var);
|
|
$docslist = $builder->render($templateFile, $var);
|
|
$menu = [];
|
|
$menu[] = [
|
|
'id' => 0,
|
|
'title' => '全局说明',
|
|
'docType' => 'meditor'
|
|
];
|
|
$key = 0;
|
|
foreach($var['apidocList'] as $k=>$v){
|
|
$key++;
|
|
$temp = [];
|
|
$temp['id'] = $key;
|
|
$temp['title'] = $v['title'];
|
|
$temp['docType'] = 'meditor';
|
|
$menu[0]['children'][] = $temp;
|
|
}
|
|
foreach($docslist as $k=>$v){
|
|
$key++;
|
|
$temp = [];
|
|
$temp['id'] = $key;
|
|
$temp['title'] = $k;
|
|
$temp['docType'] = 'api';
|
|
foreach($v as $api){
|
|
$key++;
|
|
$children = [];
|
|
$children['id'] = $key;
|
|
$children['title'] = $api['title'];
|
|
$children['docType'] = 'api';
|
|
$temp['children'][] = $children;
|
|
}
|
|
$menu[] = $temp;
|
|
}
|
|
$menuOutputFile = app()->getRootPath() . 'public' . DS . 'static' . DS . 'admin' . DS . 'data' . DS . 'apidocMenu.json';
|
|
file_put_contents($menuOutputFile, json_encode($menu, JSON_UNESCAPED_UNICODE));
|
|
|
|
View::engine()->layout(false);
|
|
$content = View::display(file_get_contents($templateFile), array_merge($var, ['docslist' => $docslist]));
|
|
$outputDir = app()->getRootPath() . DS . 'public' . DS;
|
|
$outputFile = $outputDir . $this->output;
|
|
DirFile::createDir(dirname($outputFile));
|
|
if (!file_put_contents($outputFile, $content)) {
|
|
$this->setError('Cannot save the content to ' . $outputFile);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* get full qualified class name
|
|
*
|
|
* @param string $path_to_file
|
|
* @return string
|
|
* @author JBYRNE http://jarretbyrne.com/2015/06/197/
|
|
*/
|
|
protected function getClassFromFile($path_to_file)
|
|
{
|
|
//Grab the contents of the file
|
|
$contents = file_get_contents($path_to_file);
|
|
|
|
//Start with a blank namespace and class
|
|
$namespace = $class = "";
|
|
|
|
//Set helper values to know that we have found the namespace/class token and need to collect the string values after them
|
|
$getting_namespace = $getting_class = false;
|
|
|
|
//Go through each token and evaluate it as necessary
|
|
foreach (token_get_all($contents) as $token) {
|
|
|
|
//If this token is the namespace declaring, then flag that the next tokens will be the namespace name
|
|
if (is_array($token) && $token[0] == T_NAMESPACE) {
|
|
$getting_namespace = true;
|
|
}
|
|
|
|
//If this token is the class declaring, then flag that the next tokens will be the class name
|
|
if (is_array($token) && $token[0] == T_CLASS) {
|
|
$getting_class = true;
|
|
}
|
|
|
|
//While we're grabbing the namespace name...
|
|
if ($getting_namespace === true) {
|
|
|
|
//If the token is a string or the namespace separator...
|
|
if (is_array($token) && in_array($token[0], [T_STRING, T_NS_SEPARATOR])) {
|
|
|
|
//Append the token's value to the name of the namespace
|
|
$namespace .= $token[1];
|
|
} else if ($token === ';') {
|
|
|
|
//If the token is the semicolon, then we're done with the namespace declaration
|
|
$getting_namespace = false;
|
|
}
|
|
}
|
|
|
|
//While we're grabbing the class name...
|
|
if ($getting_class === true) {
|
|
|
|
//If the token is a string, it's the name of the class
|
|
if (is_array($token) && $token[0] == T_STRING) {
|
|
|
|
//Store the token's value as the class name
|
|
$class = $token[1];
|
|
|
|
//Got what we need, stope here
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//Build the fully-qualified class name and return it
|
|
return $namespace ? $namespace . '\\' . $class : $class;
|
|
}
|
|
}
|