mirror of https://gitee.com/karson/fastadmin.git
parent
dd3d6f3172
commit
39c6720cfc
|
|
@ -23,9 +23,10 @@ class Api extends Command
|
||||||
->addOption('template', 'e', Option::VALUE_OPTIONAL, '', 'index.html')
|
->addOption('template', 'e', Option::VALUE_OPTIONAL, '', 'index.html')
|
||||||
->addOption('force', 'f', Option::VALUE_OPTIONAL, 'force override general file', false)
|
->addOption('force', 'f', Option::VALUE_OPTIONAL, 'force override general file', false)
|
||||||
->addOption('title', 't', Option::VALUE_OPTIONAL, 'document title', $site['name'])
|
->addOption('title', 't', Option::VALUE_OPTIONAL, 'document title', $site['name'])
|
||||||
->addOption('author', 'a', Option::VALUE_OPTIONAL, 'document author', $site['name'])
|
|
||||||
->addOption('class', 'c', Option::VALUE_OPTIONAL | Option::VALUE_IS_ARRAY, 'extend class', null)
|
->addOption('class', 'c', Option::VALUE_OPTIONAL | Option::VALUE_IS_ARRAY, 'extend class', null)
|
||||||
->addOption('language', 'l', Option::VALUE_OPTIONAL, 'language', 'zh-cn')
|
->addOption('language', 'l', Option::VALUE_OPTIONAL, 'language', 'zh-cn')
|
||||||
|
->addOption('addon', 'a', Option::VALUE_OPTIONAL, 'addon name', null)
|
||||||
|
->addOption('controller', 'r', Option::VALUE_REQUIRED | Option::VALUE_IS_ARRAY, 'controller name', null)
|
||||||
->setDescription('Build Api document from controller');
|
->setDescription('Build Api document from controller');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -58,12 +59,21 @@ class Api extends Command
|
||||||
$classes = $input->getOption('class');
|
$classes = $input->getOption('class');
|
||||||
// 标题
|
// 标题
|
||||||
$title = $input->getOption('title');
|
$title = $input->getOption('title');
|
||||||
// 作者
|
|
||||||
$author = $input->getOption('author');
|
|
||||||
// 模块
|
// 模块
|
||||||
$module = $input->getOption('module');
|
$module = $input->getOption('module');
|
||||||
|
// 插件
|
||||||
|
$addon = $input->getOption('addon');
|
||||||
|
|
||||||
$moduleDir = APP_PATH . $module . DS;
|
$moduleDir = $addonDir = '';
|
||||||
|
if ($addon) {
|
||||||
|
$addonInfo = get_addon_info($addon);
|
||||||
|
if (!$addonInfo) {
|
||||||
|
throw new Exception('addon not found');
|
||||||
|
}
|
||||||
|
$moduleDir = ADDON_PATH . $addon . DS;
|
||||||
|
} else {
|
||||||
|
$moduleDir = APP_PATH . $module . DS;
|
||||||
|
}
|
||||||
if (!is_dir($moduleDir)) {
|
if (!is_dir($moduleDir)) {
|
||||||
throw new Exception('module not found');
|
throw new Exception('module not found');
|
||||||
}
|
}
|
||||||
|
|
@ -81,31 +91,44 @@ class Api extends Command
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$controllerDir = $moduleDir . Config::get('url_controller_layer') . DS;
|
//控制器名
|
||||||
$files = new \RecursiveIteratorIterator(
|
$controller = $input->getOption('controller') ?: [];
|
||||||
new \RecursiveDirectoryIterator($controllerDir),
|
if (!$controller) {
|
||||||
\RecursiveIteratorIterator::LEAVES_ONLY
|
$controllerDir = $moduleDir . Config::get('url_controller_layer') . DS;
|
||||||
);
|
$files = new \RecursiveIteratorIterator(
|
||||||
|
new \RecursiveDirectoryIterator($controllerDir),
|
||||||
|
\RecursiveIteratorIterator::LEAVES_ONLY
|
||||||
|
);
|
||||||
|
|
||||||
foreach ($files as $name => $file) {
|
foreach ($files as $name => $file) {
|
||||||
if (!$file->isDir() && $file->getExtension() == 'php') {
|
if (!$file->isDir() && $file->getExtension() == 'php') {
|
||||||
$filePath = $file->getRealPath();
|
$filePath = $file->getRealPath();
|
||||||
|
$classes[] = $this->get_class_from_file($filePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
foreach ($controller as $index => $item) {
|
||||||
|
$filePath = $moduleDir . Config::get('url_controller_layer') . DS . $item . '.php';
|
||||||
$classes[] = $this->get_class_from_file($filePath);
|
$classes[] = $this->get_class_from_file($filePath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$classes = array_unique(array_filter($classes));
|
$classes = array_unique(array_filter($classes));
|
||||||
|
|
||||||
$config = [
|
$config = [
|
||||||
'sitename' => config('site.name'),
|
'sitename' => config('site.name'),
|
||||||
'title' => $title,
|
'title' => $title,
|
||||||
'author' => $author,
|
'author' => config('site.name'),
|
||||||
'description' => '',
|
'description' => '',
|
||||||
'apiurl' => $url,
|
'apiurl' => $url,
|
||||||
'language' => $language,
|
'language' => $language,
|
||||||
];
|
];
|
||||||
$builder = new Builder($classes);
|
try {
|
||||||
$content = $builder->render($template_file, ['config' => $config, 'lang' => $lang]);
|
$builder = new Builder($classes);
|
||||||
|
$content = $builder->render($template_file, ['config' => $config, 'lang' => $lang]);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
print_r($e);
|
||||||
|
}
|
||||||
if (!file_put_contents($output_file, $content)) {
|
if (!file_put_contents($output_file, $content)) {
|
||||||
throw new Exception('Cannot save the content to ' . $output_file);
|
throw new Exception('Cannot save the content to ' . $output_file);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,9 @@ return [
|
||||||
'Tokentips' => 'Token在会员注册或登录后都会返回,WEB端同时存在于Cookie中',
|
'Tokentips' => 'Token在会员注册或登录后都会返回,WEB端同时存在于Cookie中',
|
||||||
'Apiurltips' => 'API接口URL',
|
'Apiurltips' => 'API接口URL',
|
||||||
'Savetips' => '点击保存后Token和Api url都将保存在本地Localstorage中',
|
'Savetips' => '点击保存后Token和Api url都将保存在本地Localstorage中',
|
||||||
|
'Authorization' => '权限',
|
||||||
|
'NeedLogin' => '登录',
|
||||||
|
'NeedRight' => '鉴权',
|
||||||
'ReturnHeaders' => '响应头',
|
'ReturnHeaders' => '响应头',
|
||||||
'ReturnParameters' => '返回参数',
|
'ReturnParameters' => '返回参数',
|
||||||
'Response' => '响应输出',
|
'Response' => '响应输出',
|
||||||
|
|
|
||||||
|
|
@ -43,9 +43,11 @@ class Builder
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Extractor::getClassMethodAnnotations($class);
|
Extractor::getClassMethodAnnotations($class);
|
||||||
|
//Extractor::getClassPropertyValues($class);
|
||||||
}
|
}
|
||||||
$allClassAnnotation = Extractor::getAllClassAnnotations();
|
$allClassAnnotation = Extractor::getAllClassAnnotations();
|
||||||
$allClassMethodAnnotation = Extractor::getAllClassMethodAnnotations();
|
$allClassMethodAnnotation = Extractor::getAllClassMethodAnnotations();
|
||||||
|
//$allClassPropertyValue = Extractor::getAllClassPropertyValues();
|
||||||
|
|
||||||
// foreach ($allClassMethodAnnotation as $className => &$methods) {
|
// foreach ($allClassMethodAnnotation as $className => &$methods) {
|
||||||
// foreach ($methods as &$method) {
|
// foreach ($methods as &$method) {
|
||||||
|
|
@ -162,10 +164,12 @@ class Builder
|
||||||
list($allClassAnnotations, $allClassMethodAnnotations) = $this->extractAnnotations();
|
list($allClassAnnotations, $allClassMethodAnnotations) = $this->extractAnnotations();
|
||||||
|
|
||||||
$sectorArr = [];
|
$sectorArr = [];
|
||||||
foreach ($allClassAnnotations as $index => $allClassAnnotation) {
|
foreach ($allClassAnnotations as $index => &$allClassAnnotation) {
|
||||||
$sector = isset($allClassAnnotation['ApiSector']) ? $allClassAnnotation['ApiSector'][0] : $allClassAnnotation['ApiTitle'][0];
|
$sector = isset($allClassAnnotation['ApiSector']) ? $allClassAnnotation['ApiSector'][0] : $allClassAnnotation['ApiTitle'][0];
|
||||||
$sectorArr[$sector] = isset($allClassAnnotation['ApiWeigh']) ? $allClassAnnotation['ApiWeigh'][0] : 0;
|
$sectorArr[$sector] = isset($allClassAnnotation['ApiWeigh']) ? $allClassAnnotation['ApiWeigh'][0] : 0;
|
||||||
}
|
}
|
||||||
|
unset($allClassAnnotation);
|
||||||
|
|
||||||
arsort($sectorArr);
|
arsort($sectorArr);
|
||||||
$routes = include_once CONF_PATH . 'route.php';
|
$routes = include_once CONF_PATH . 'route.php';
|
||||||
$subdomain = false;
|
$subdomain = false;
|
||||||
|
|
@ -175,7 +179,7 @@ class Builder
|
||||||
$counter = 0;
|
$counter = 0;
|
||||||
$section = null;
|
$section = null;
|
||||||
$weigh = 0;
|
$weigh = 0;
|
||||||
$docslist = [];
|
$docsList = [];
|
||||||
foreach ($allClassMethodAnnotations as $class => $methods) {
|
foreach ($allClassMethodAnnotations as $class => $methods) {
|
||||||
foreach ($methods as $name => $docs) {
|
foreach ($methods as $name => $docs) {
|
||||||
if (isset($docs['ApiSector'][0])) {
|
if (isset($docs['ApiSector'][0])) {
|
||||||
|
|
@ -190,28 +194,30 @@ class Builder
|
||||||
if ($subdomain) {
|
if ($subdomain) {
|
||||||
$route = substr($route, 4);
|
$route = substr($route, 4);
|
||||||
}
|
}
|
||||||
$docslist[$section][$class . $name] = [
|
$docsList[$section][$name] = [
|
||||||
'id' => $counter,
|
'id' => $counter,
|
||||||
'method' => is_array($docs['ApiMethod'][0]) ? $docs['ApiMethod'][0]['data'] : $docs['ApiMethod'][0],
|
'method' => is_array($docs['ApiMethod'][0]) ? $docs['ApiMethod'][0]['data'] : $docs['ApiMethod'][0],
|
||||||
'method_label' => $this->generateBadgeForMethod($docs),
|
'methodLabel' => $this->generateBadgeForMethod($docs),
|
||||||
'section' => $section,
|
'section' => $section,
|
||||||
'route' => $route,
|
'route' => $route,
|
||||||
'title' => is_array($docs['ApiTitle'][0]) ? $docs['ApiTitle'][0]['data'] : $docs['ApiTitle'][0],
|
'title' => is_array($docs['ApiTitle'][0]) ? $docs['ApiTitle'][0]['data'] : $docs['ApiTitle'][0],
|
||||||
'summary' => is_array($docs['ApiSummary'][0]) ? $docs['ApiSummary'][0]['data'] : $docs['ApiSummary'][0],
|
'summary' => is_array($docs['ApiSummary'][0]) ? $docs['ApiSummary'][0]['data'] : $docs['ApiSummary'][0],
|
||||||
'body' => isset($docs['ApiBody'][0]) ? is_array($docs['ApiBody'][0]) ? $docs['ApiBody'][0]['data'] : $docs['ApiBody'][0] : '',
|
'body' => isset($docs['ApiBody'][0]) ? is_array($docs['ApiBody'][0]) ? $docs['ApiBody'][0]['data'] : $docs['ApiBody'][0] : '',
|
||||||
'headerslist' => $this->generateHeadersTemplate($docs),
|
'headersList' => $this->generateHeadersTemplate($docs),
|
||||||
'paramslist' => $this->generateParamsTemplate($docs),
|
'paramsList' => $this->generateParamsTemplate($docs),
|
||||||
'returnheaderslist' => $this->generateReturnHeadersTemplate($docs),
|
'returnHeadersList' => $this->generateReturnHeadersTemplate($docs),
|
||||||
'returnparamslist' => $this->generateReturnParamsTemplate($docs),
|
'returnParamsList' => $this->generateReturnParamsTemplate($docs),
|
||||||
'weigh' => is_array($docs['ApiWeigh'][0]) ? $docs['ApiWeigh'][0]['data'] : $docs['ApiWeigh'][0],
|
'weigh' => is_array($docs['ApiWeigh'][0]) ? $docs['ApiWeigh'][0]['data'] : $docs['ApiWeigh'][0],
|
||||||
'return' => isset($docs['ApiReturn']) ? is_array($docs['ApiReturn'][0]) ? $docs['ApiReturn'][0]['data'] : $docs['ApiReturn'][0] : '',
|
'return' => isset($docs['ApiReturn']) ? is_array($docs['ApiReturn'][0]) ? $docs['ApiReturn'][0]['data'] : $docs['ApiReturn'][0] : '',
|
||||||
|
'needLogin' => $docs['ApiPermissionLogin'][0],
|
||||||
|
'needRight' => $docs['ApiPermissionRight'][0],
|
||||||
];
|
];
|
||||||
$counter++;
|
$counter++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//重建排序
|
//重建排序
|
||||||
foreach ($docslist as $index => &$methods) {
|
foreach ($docsList as $index => &$methods) {
|
||||||
$methodSectorArr = [];
|
$methodSectorArr = [];
|
||||||
foreach ($methods as $name => $method) {
|
foreach ($methods as $name => $method) {
|
||||||
$methodSectorArr[$name] = isset($method['weigh']) ? $method['weigh'] : 0;
|
$methodSectorArr[$name] = isset($method['weigh']) ? $method['weigh'] : 0;
|
||||||
|
|
@ -219,9 +225,8 @@ class Builder
|
||||||
arsort($methodSectorArr);
|
arsort($methodSectorArr);
|
||||||
$methods = array_merge(array_flip(array_keys($methodSectorArr)), $methods);
|
$methods = array_merge(array_flip(array_keys($methodSectorArr)), $methods);
|
||||||
}
|
}
|
||||||
$docslist = array_merge(array_flip(array_keys($sectorArr)), $docslist);
|
$docsList = array_merge(array_flip(array_keys($sectorArr)), $docsList);
|
||||||
$docslist = array_filter($docslist , function($v) {return is_array($v) ; }) ;
|
return $docsList;
|
||||||
return $docslist;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getView()
|
public function getView()
|
||||||
|
|
@ -237,8 +242,8 @@ class Builder
|
||||||
*/
|
*/
|
||||||
public function render($template, $vars = [])
|
public function render($template, $vars = [])
|
||||||
{
|
{
|
||||||
$docslist = $this->parse();
|
$docsList = $this->parse();
|
||||||
|
|
||||||
return $this->view->display(file_get_contents($template), array_merge($vars, ['docslist' => $docslist]));
|
return $this->view->display(file_get_contents($template), array_merge($vars, ['docsList' => $docsList]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,8 @@ class Extractor
|
||||||
|
|
||||||
private static $classMethodAnnotationCache;
|
private static $classMethodAnnotationCache;
|
||||||
|
|
||||||
|
private static $classPropertyValueCache;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates that annotations should has strict behavior, 'false' by default
|
* Indicates that annotations should has strict behavior, 'false' by default
|
||||||
* @var boolean
|
* @var boolean
|
||||||
|
|
@ -66,14 +68,16 @@ class Extractor
|
||||||
/**
|
/**
|
||||||
* Gets all anotations with pattern @SomeAnnotation() from a given class
|
* Gets all anotations with pattern @SomeAnnotation() from a given class
|
||||||
*
|
*
|
||||||
* @param string $className class name to get annotations
|
* @param string $className class name to get annotations
|
||||||
* @return array self::$classAnnotationCache all annotated elements
|
* @return array self::$classAnnotationCache all annotated elements
|
||||||
*/
|
*/
|
||||||
public static function getClassAnnotations($className)
|
public static function getClassAnnotations($className)
|
||||||
{
|
{
|
||||||
if (!isset(self::$classAnnotationCache[$className])) {
|
if (!isset(self::$classAnnotationCache[$className])) {
|
||||||
$class = new \ReflectionClass($className);
|
$class = new \ReflectionClass($className);
|
||||||
self::$classAnnotationCache[$className] = self::parseAnnotations($class->getDocComment());
|
$annotationArr = self::parseAnnotations($class->getDocComment());
|
||||||
|
$annotationArr['ApiTitle'] = !isset($annotationArr['ApiTitle'][0]) || !trim($annotationArr['ApiTitle'][0]) ? [$class->getShortName()] : $annotationArr['ApiTitle'];
|
||||||
|
self::$classAnnotationCache[$className] = $annotationArr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return self::$classAnnotationCache[$className];
|
return self::$classAnnotationCache[$className];
|
||||||
|
|
@ -96,6 +100,17 @@ class Extractor
|
||||||
return self::$classMethodAnnotationCache[$className];
|
return self::$classMethodAnnotationCache[$className];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function getClassPropertyValues($className)
|
||||||
|
{
|
||||||
|
$class = new \ReflectionClass($className);
|
||||||
|
|
||||||
|
foreach ($class->getProperties() as $object) {
|
||||||
|
self::$classPropertyValueCache[$className][$object->name] = self::getClassPropertyValue($className, $object->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$classMethodAnnotationCache[$className];
|
||||||
|
}
|
||||||
|
|
||||||
public static function getAllClassAnnotations()
|
public static function getAllClassAnnotations()
|
||||||
{
|
{
|
||||||
return self::$classAnnotationCache;
|
return self::$classAnnotationCache;
|
||||||
|
|
@ -106,11 +121,25 @@ class Extractor
|
||||||
return self::$classMethodAnnotationCache;
|
return self::$classMethodAnnotationCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function getAllClassPropertyValues()
|
||||||
|
{
|
||||||
|
return self::$classPropertyValueCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getClassPropertyValue($className, $property)
|
||||||
|
{
|
||||||
|
$_SERVER['REQUEST_METHOD'] = 'GET';
|
||||||
|
$reflectionClass = new \ReflectionClass($className);
|
||||||
|
$reflectionProperty = $reflectionClass->getProperty($property);
|
||||||
|
$reflectionProperty->setAccessible(true);
|
||||||
|
return $reflectionProperty->getValue($reflectionClass->newInstanceWithoutConstructor());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets all anotations with pattern @SomeAnnotation() from a determinated method of a given class
|
* Gets all anotations with pattern @SomeAnnotation() from a determinated method of a given class
|
||||||
*
|
*
|
||||||
* @param string $className class name
|
* @param string $className class name
|
||||||
* @param string $methodName method name to get annotations
|
* @param string $methodName method name to get annotations
|
||||||
* @return array self::$annotationCache all annotated elements of a method given
|
* @return array self::$annotationCache all annotated elements of a method given
|
||||||
*/
|
*/
|
||||||
public static function getMethodAnnotations($className, $methodName)
|
public static function getMethodAnnotations($className, $methodName)
|
||||||
|
|
@ -138,8 +167,8 @@ class Extractor
|
||||||
* Gets all anotations with pattern @SomeAnnotation() from a determinated method of a given class
|
* Gets all anotations with pattern @SomeAnnotation() from a determinated method of a given class
|
||||||
* and instance its abcAnnotation class
|
* and instance its abcAnnotation class
|
||||||
*
|
*
|
||||||
* @param string $className class name
|
* @param string $className class name
|
||||||
* @param string $methodName method name to get annotations
|
* @param string $methodName method name to get annotations
|
||||||
* @return array self::$annotationCache all annotated objects of a method given
|
* @return array self::$annotationCache all annotated objects of a method given
|
||||||
*/
|
*/
|
||||||
public function getMethodAnnotationsObjects($className, $methodName)
|
public function getMethodAnnotationsObjects($className, $methodName)
|
||||||
|
|
@ -189,7 +218,11 @@ class Extractor
|
||||||
$methodName = $method->getName();
|
$methodName = $method->getName();
|
||||||
|
|
||||||
$methodAnnotations = self::parseAnnotations($docblockMethod);
|
$methodAnnotations = self::parseAnnotations($docblockMethod);
|
||||||
|
$methodAnnotations['ApiTitle'] = !isset($methodAnnotations['ApiTitle'][0]) || !trim($methodAnnotations['ApiTitle'][0]) ? [$method->getName()] : $methodAnnotations['ApiTitle'];
|
||||||
|
|
||||||
$classAnnotations = self::parseAnnotations($dockblockClass);
|
$classAnnotations = self::parseAnnotations($dockblockClass);
|
||||||
|
$classAnnotations['ApiTitle'] = !isset($classAnnotations['ApiTitle'][0]) || !trim($classAnnotations['ApiTitle'][0]) ? [$class->getShortName()] : $classAnnotations['ApiTitle'];
|
||||||
|
|
||||||
if (isset($methodAnnotations['ApiInternal']) || $methodName == '_initialize' || $methodName == '_empty') {
|
if (isset($methodAnnotations['ApiInternal']) || $methodName == '_initialize' || $methodName == '_empty') {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
@ -264,15 +297,15 @@ class Extractor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$methodAnnotations['ApiPermissionLogin'] = [!in_array('*', $noNeedLogin) && !in_array($methodName, $noNeedLogin)];
|
$methodAnnotations['ApiPermissionLogin'] = [!in_array('*', $noNeedLogin) && !in_array($methodName, $noNeedLogin)];
|
||||||
$methodAnnotations['ApiPermissionRight'] = [!in_array('*', $noNeedRight) && !in_array($methodName, $noNeedRight)];
|
$methodAnnotations['ApiPermissionRight'] = !$methodAnnotations['ApiPermissionLogin'][0] ? false : [!in_array('*', $noNeedRight) && !in_array($methodName, $noNeedRight)];
|
||||||
return $methodAnnotations;
|
return $methodAnnotations;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse annotations
|
* Parse annotations
|
||||||
*
|
*
|
||||||
* @param string $docblock
|
* @param string $docblock
|
||||||
* @param string $name
|
* @param string $name
|
||||||
* @return array parsed annotations params
|
* @return array parsed annotations params
|
||||||
*/
|
*/
|
||||||
private static function parseCustomAnnotations($docblock, $name = 'param')
|
private static function parseCustomAnnotations($docblock, $name = 'param')
|
||||||
|
|
@ -291,7 +324,7 @@ class Extractor
|
||||||
/**
|
/**
|
||||||
* Parse annotations
|
* Parse annotations
|
||||||
*
|
*
|
||||||
* @param string $docblock
|
* @param string $docblock
|
||||||
* @return array parsed annotations params
|
* @return array parsed annotations params
|
||||||
*/
|
*/
|
||||||
private static function parseAnnotations($docblock)
|
private static function parseAnnotations($docblock)
|
||||||
|
|
@ -337,7 +370,7 @@ class Extractor
|
||||||
/**
|
/**
|
||||||
* Parse individual annotation arguments
|
* Parse individual annotation arguments
|
||||||
*
|
*
|
||||||
* @param string $content arguments string
|
* @param string $content arguments string
|
||||||
* @return array annotated arguments
|
* @return array annotated arguments
|
||||||
*/
|
*/
|
||||||
private static function parseArgs($content)
|
private static function parseArgs($content)
|
||||||
|
|
@ -480,8 +513,8 @@ class Extractor
|
||||||
/**
|
/**
|
||||||
* Try determinate the original type variable of a string
|
* Try determinate the original type variable of a string
|
||||||
*
|
*
|
||||||
* @param string $val string containing possibles variables that can be cast to bool or int
|
* @param string $val string containing possibles variables that can be cast to bool or int
|
||||||
* @param boolean $trim indicate if the value passed should be trimmed after to try cast
|
* @param boolean $trim indicate if the value passed should be trimmed after to try cast
|
||||||
* @return mixed returns the value converted to original type if was possible
|
* @return mixed returns the value converted to original type if was possible
|
||||||
*/
|
*/
|
||||||
private static function castValue($val, $trim = false)
|
private static function castValue($val, $trim = false)
|
||||||
|
|
|
||||||
|
|
@ -27,12 +27,12 @@
|
||||||
font-family: "Roboto", "SF Pro SC", "SF Pro Display", "SF Pro Icons", "PingFang SC", BlinkMacSystemFont, -apple-system, "Segoe UI", "Microsoft Yahei", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", "Helvetica", "Arial", sans-serif;
|
font-family: "Roboto", "SF Pro SC", "SF Pro Display", "SF Pro Icons", "PingFang SC", BlinkMacSystemFont, -apple-system, "Segoe UI", "Microsoft Yahei", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", "Helvetica", "Arial", sans-serif;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
}
|
}
|
||||||
h2 { font-size: 1.6em; }
|
h2 { font-size: 1.2em; }
|
||||||
hr { margin-top: 10px; }
|
hr { margin-top: 10px; }
|
||||||
.tab-pane { padding-top: 10px; }
|
.tab-pane { padding-top: 10px; }
|
||||||
.mt0 { margin-top: 0px; }
|
.mt0 { margin-top: 0px; }
|
||||||
.footer { font-size: 12px; color: #666; }
|
.footer { font-size: 12px; color: #666; }
|
||||||
.label { display: inline-block; min-width: 65px; padding: 0.3em 0.6em 0.3em; }
|
.docs-list .label { display: inline-block; min-width: 65px; padding: 0.3em 0.6em 0.3em; }
|
||||||
.string { color: green; }
|
.string { color: green; }
|
||||||
.number { color: darkorange; }
|
.number { color: darkorange; }
|
||||||
.boolean { color: blue; }
|
.boolean { color: blue; }
|
||||||
|
|
@ -65,12 +65,24 @@
|
||||||
#sidebar > .list-group > a{
|
#sidebar > .list-group > a{
|
||||||
text-indent:0;
|
text-indent:0;
|
||||||
}
|
}
|
||||||
|
#sidebar .child > a .tag{
|
||||||
|
position: absolute;
|
||||||
|
right: 10px;
|
||||||
|
top: 11px;
|
||||||
|
}
|
||||||
|
#sidebar .child > a .pull-right{
|
||||||
|
margin-left:3px;
|
||||||
|
}
|
||||||
#sidebar .child {
|
#sidebar .child {
|
||||||
border:1px solid #ddd;
|
border:1px solid #ddd;
|
||||||
border-bottom:none;
|
border-bottom:none;
|
||||||
}
|
}
|
||||||
|
#sidebar .child:last-child {
|
||||||
|
border-bottom:1px solid #ddd;
|
||||||
|
}
|
||||||
#sidebar .child > a {
|
#sidebar .child > a {
|
||||||
border:0;
|
border:0;
|
||||||
|
min-height: 40px;
|
||||||
}
|
}
|
||||||
#sidebar .list-group a.current {
|
#sidebar .list-group a.current {
|
||||||
background:#f5f5f5;
|
background:#f5f5f5;
|
||||||
|
|
@ -94,6 +106,9 @@
|
||||||
.label-primary {
|
.label-primary {
|
||||||
background-color: #248aff;
|
background-color: #248aff;
|
||||||
}
|
}
|
||||||
|
.docs-list .panel .panel-body .table {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
@ -138,25 +153,34 @@
|
||||||
<!-- menu -->
|
<!-- menu -->
|
||||||
<div id="sidebar">
|
<div id="sidebar">
|
||||||
<div class="list-group panel">
|
<div class="list-group panel">
|
||||||
{foreach name="docslist" id="docs"}
|
{foreach name="docsList" id="docs"}
|
||||||
<a href="#{$key}" class="list-group-item" data-toggle="collapse" data-parent="#sidebar">{$key} <i class="fa fa-caret-down"></i></a>
|
<a href="#{$key}" class="list-group-item" data-toggle="collapse" data-parent="#sidebar">{$key} <i class="fa fa-caret-down"></i></a>
|
||||||
<div class="child collapse" id="{$key}">
|
<div class="child collapse" id="{$key}">
|
||||||
{foreach name="docs" id="api" }
|
{foreach name="docs" id="api" }
|
||||||
<a href="javascript:;" data-id="{$api.id}" class="list-group-item">{$api.title}</a>
|
<a href="javascript:;" data-id="{$api.id}" class="list-group-item">{$api.title}
|
||||||
|
<span class="tag">
|
||||||
|
{if $api.needRight}
|
||||||
|
<span class="label label-danger pull-right">鉴</span>
|
||||||
|
{/if}
|
||||||
|
{if $api.needLogin}
|
||||||
|
<span class="label label-success pull-right noneedlogin">登</span>
|
||||||
|
{/if}
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
{/foreach}
|
{/foreach}
|
||||||
</div>
|
</div>
|
||||||
{/foreach}
|
{/foreach}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-group" id="accordion">
|
<div class="panel-group docs-list" id="accordion">
|
||||||
{foreach name="docslist" id="docs"}
|
{foreach name="docsList" id="docs"}
|
||||||
<h2>{$key}</h2>
|
<h2>{$key}</h2>
|
||||||
<hr>
|
<hr>
|
||||||
{foreach name="docs" id="api" }
|
{foreach name="docs" id="api" }
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading" id="heading-{$api.id}">
|
<div class="panel-heading" id="heading-{$api.id}">
|
||||||
<h4 class="panel-title">
|
<h4 class="panel-title">
|
||||||
<span class="label {$api.method_label}">{$api.method|strtoupper}</span>
|
<span class="label {$api.methodLabel}">{$api.method|strtoupper}</span>
|
||||||
<a data-toggle="collapse" data-parent="#accordion{$api.id}" href="#collapseOne{$api.id}"> {$api.title} <span class="text-muted">{$api.route}</span></a>
|
<a data-toggle="collapse" data-parent="#accordion{$api.id}" href="#collapseOne{$api.id}"> {$api.title} <span class="text-muted">{$api.route}</span></a>
|
||||||
</h4>
|
</h4>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -177,10 +201,27 @@
|
||||||
<div class="well">
|
<div class="well">
|
||||||
{$api.summary}
|
{$api.summary}
|
||||||
</div>
|
</div>
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading"><strong>{$lang.Authorization}</strong></div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<table class="table table-hover">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>{$lang.NeedLogin}</td>
|
||||||
|
<td>{$api.needLogin?'是':'否'}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{$lang.NeedRight}</td>
|
||||||
|
<td>{$api.needRight?'是':'否'}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading"><strong>{$lang.Headers}</strong></div>
|
<div class="panel-heading"><strong>{$lang.Headers}</strong></div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
{if $api.headerslist}
|
{if $api.headersList}
|
||||||
<table class="table table-hover">
|
<table class="table table-hover">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
|
@ -191,7 +232,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{foreach name="api['headerslist']" id="header"}
|
{foreach name="api['headersList']" id="header"}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{$header.name}</td>
|
<td>{$header.name}</td>
|
||||||
<td>{$header.type}</td>
|
<td>{$header.type}</td>
|
||||||
|
|
@ -209,7 +250,7 @@
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading"><strong>{$lang.Parameters}</strong></div>
|
<div class="panel-heading"><strong>{$lang.Parameters}</strong></div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
{if $api.paramslist}
|
{if $api.paramsList}
|
||||||
<table class="table table-hover">
|
<table class="table table-hover">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
|
@ -220,7 +261,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{foreach name="api['paramslist']" id="param"}
|
{foreach name="api['paramsList']" id="param"}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{$param.name}</td>
|
<td>{$param.name}</td>
|
||||||
<td>{$param.type}</td>
|
<td>{$param.type}</td>
|
||||||
|
|
@ -246,12 +287,12 @@
|
||||||
<div class="tab-pane" id="sandbox{$api.id}">
|
<div class="tab-pane" id="sandbox{$api.id}">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
{if $api.headerslist}
|
{if $api.headersList}
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading"><strong>{$lang.Headers}</strong></div>
|
<div class="panel-heading"><strong>{$lang.Headers}</strong></div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<div class="headers">
|
<div class="headers">
|
||||||
{foreach name="api['headerslist']" id="param"}
|
{foreach name="api['headersList']" id="param"}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="control-label" for="{$param.name}">{$param.name}</label>
|
<label class="control-label" for="{$param.name}">{$param.name}</label>
|
||||||
<input type="{$param.type}" class="form-control input-sm" id="{$param.name}" {if $param.required}required{/if} placeholder="{$param.description} - Ex: {$param.sample}" name="{$param.name}">
|
<input type="{$param.type}" class="form-control input-sm" id="{$param.name}" {if $param.required}required{/if} placeholder="{$param.description} - Ex: {$param.sample}" name="{$param.name}">
|
||||||
|
|
@ -262,11 +303,15 @@
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading"><strong>{$lang.Parameters}</strong></div>
|
<div class="panel-heading"><strong>{$lang.Parameters}</strong>
|
||||||
|
<div class="pull-right">
|
||||||
|
<a href="javascript:" class="btn btn-xs btn-info btn-append">追加</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<form enctype="application/x-www-form-urlencoded" role="form" action="{$api.route}" method="{$api.method}" name="form{$api.id}" id="form{$api.id}">
|
<form enctype="application/x-www-form-urlencoded" role="form" action="{$api.route}" method="{$api.method}" name="form{$api.id}" id="form{$api.id}">
|
||||||
{if $api.paramslist}
|
{if $api.paramsList}
|
||||||
{foreach name="api['paramslist']" id="param"}
|
{foreach name="api['paramsList']" id="param"}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="control-label" for="{$param.name}">{$param.name}</label>
|
<label class="control-label" for="{$param.name}">{$param.name}</label>
|
||||||
<input type="{$param.type}" class="form-control input-sm" id="{$param.name}" {if $param.required}required{/if} placeholder="{$param.description}{if $param.sample} - 例: {$param.sample}{/if}" name="{$param.name}">
|
<input type="{$param.type}" class="form-control input-sm" id="{$param.name}" {if $param.required}required{/if} placeholder="{$param.description}{if $param.sample} - 例: {$param.sample}{/if}" name="{$param.name}">
|
||||||
|
|
@ -277,7 +322,7 @@
|
||||||
无
|
无
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
<div class="form-group">
|
<div class="form-group form-group-submit">
|
||||||
<button type="submit" class="btn btn-success send" rel="{$api.id}">{$lang.Send}</button>
|
<button type="submit" class="btn btn-success send" rel="{$api.id}">{$lang.Send}</button>
|
||||||
<button type="reset" class="btn btn-info" rel="{$api.id}">{$lang.Reset}</button>
|
<button type="reset" class="btn btn-info" rel="{$api.id}">{$lang.Reset}</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -298,7 +343,7 @@
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading"><strong>{$lang.ReturnParameters}</strong></div>
|
<div class="panel-heading"><strong>{$lang.ReturnParameters}</strong></div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
{if $api.returnparamslist}
|
{if $api.returnParamsList}
|
||||||
<table class="table table-hover">
|
<table class="table table-hover">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
|
@ -308,7 +353,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{foreach name="api['returnparamslist']" id="param"}
|
{foreach name="api['returnParamsList']" id="param"}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{$param.name}</td>
|
<td>{$param.name}</td>
|
||||||
<td>{$param.type}</td>
|
<td>{$param.type}</td>
|
||||||
|
|
@ -346,10 +391,10 @@
|
||||||
|
|
||||||
<div class="row mt0 footer">
|
<div class="row mt0 footer">
|
||||||
<div class="col-md-6" align="left">
|
<div class="col-md-6" align="left">
|
||||||
Generated on {:date('Y-m-d H:i:s')}
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6" align="right">
|
<div class="col-md-6" align="right">
|
||||||
<a href="./" target="_blank">{$config.sitename}</a>
|
Generated on {:date('Y-m-d H:i:s')} <a href="./" target="_blank">{$config.sitename}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -475,7 +520,7 @@
|
||||||
$sample.html('<pre>' + str + '</pre>');
|
$sample.html('<pre>' + str + '</pre>');
|
||||||
});
|
});
|
||||||
|
|
||||||
$('body').on('click', '#save_data', function (e) {
|
$(document).on('click', '#save_data', function (e) {
|
||||||
if (storage) {
|
if (storage) {
|
||||||
storage.setItem('token', $('#token').val());
|
storage.setItem('token', $('#token').val());
|
||||||
storage.setItem('apiUrl', $('#apiUrl').val());
|
storage.setItem('apiUrl', $('#apiUrl').val());
|
||||||
|
|
@ -483,8 +528,20 @@
|
||||||
alert('Your browser does not support local storage');
|
alert('Your browser does not support local storage');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
$(document).on('click', '.btn-append', function (e) {
|
||||||
|
$($("#appendtpl").html()).insertBefore($(this).closest(".panel").find(".form-group-submit"));
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
$(document).on('click', '.btn-remove', function (e) {
|
||||||
|
$(this).closest(".form-group").remove();
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
$(document).on('keyup', '.input-custom-name', function (e) {
|
||||||
|
$(this).closest(".row").find(".input-custom-value").attr("name", $(this).val());
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
$('body').on('click', '.send', function (e) {
|
$(document).on('click', '.send', function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
var form = $(this).closest('form');
|
var form = $(this).closest('form');
|
||||||
//added /g to get all the matched params instead of only first
|
//added /g to get all the matched params instead of only first
|
||||||
|
|
@ -577,5 +634,21 @@
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
<script type="text/html" id="appendtpl">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="control-label">自定义</label>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-4">
|
||||||
|
<input type="text" class="form-control input-sm input-custom-name" placeholder="名称">
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-6">
|
||||||
|
<input type="text" class="form-control input-sm input-custom-value" placeholder="值">
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-2 text-center">
|
||||||
|
<a href="javascript:" class="btn btn-sm btn-danger btn-remove">删除</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
966
public/api.html
966
public/api.html
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue