Api.php 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. <?php
  2. namespace app\admin\command;
  3. use app\admin\command\Api\library\Builder;
  4. use think\Config;
  5. use think\console\Command;
  6. use think\console\Input;
  7. use think\console\input\Option;
  8. use think\console\Output;
  9. use think\Exception;
  10. class Api extends Command
  11. {
  12. protected function configure()
  13. {
  14. $site = Config::get('site');
  15. $this
  16. ->setName('api')
  17. ->addOption('url', 'u', Option::VALUE_OPTIONAL, 'default api url', '')
  18. ->addOption('module', 'm', Option::VALUE_OPTIONAL, 'module name(admin/index/api)', 'api')
  19. ->addOption('output', 'o', Option::VALUE_OPTIONAL, 'output index file name', 'api.html')
  20. ->addOption('template', 'e', Option::VALUE_OPTIONAL, '', 'index.html')
  21. ->addOption('force', 'f', Option::VALUE_OPTIONAL, 'force override general file', false)
  22. ->addOption('title', 't', Option::VALUE_OPTIONAL, 'document title', $site['name'])
  23. ->addOption('author', 'a', Option::VALUE_OPTIONAL, 'document author', $site['name'])
  24. ->addOption('class', 'c', Option::VALUE_OPTIONAL | Option::VALUE_IS_ARRAY, 'extend class', null)
  25. ->addOption('language', 'l', Option::VALUE_OPTIONAL, 'language', 'zh-cn')
  26. ->setDescription('Compress js and css file');
  27. }
  28. protected function execute(Input $input, Output $output)
  29. {
  30. $apiDir = __DIR__ . DS . 'Api' . DS;
  31. $force = $input->getOption('force');
  32. $url = $input->getOption('url');
  33. $language = $input->getOption('language');
  34. $langFile = $apiDir . 'lang' . DS . $language . '.php';
  35. if (!is_file($langFile))
  36. {
  37. throw new Exception('language file not found');
  38. }
  39. $lang = include $langFile;
  40. // 目标目录
  41. $output_dir = ROOT_PATH . 'public' . DS;
  42. $output_file = $output_dir . $input->getOption('output');
  43. if (is_file($output_file) && !$force)
  44. {
  45. throw new Exception("api index file already exists!\nIf you need to rebuild again, use the parameter --force=true ");
  46. }
  47. // 模板文件
  48. $template_dir = $apiDir . 'template' . DS;
  49. $template_file = $template_dir . $input->getOption('template');
  50. if (!is_file($template_file))
  51. {
  52. throw new Exception('template file not found');
  53. }
  54. // 额外的类
  55. $classes = $input->getOption('class');
  56. // 标题
  57. $title = $input->getOption('title');
  58. // 作者
  59. $author = $input->getOption('author');
  60. // 模块
  61. $module = $input->getOption('module');
  62. $moduleDir = APP_PATH . $module . DS;
  63. if (!is_dir($moduleDir))
  64. {
  65. throw new Exception('module not found');
  66. }
  67. $controllerDir = $moduleDir . Config::get('url_controller_layer') . DS;
  68. $files = new \RecursiveIteratorIterator(
  69. new \RecursiveDirectoryIterator($controllerDir), \RecursiveIteratorIterator::LEAVES_ONLY
  70. );
  71. foreach ($files as $name => $file)
  72. {
  73. if (!$file->isDir())
  74. {
  75. $filePath = $file->getRealPath();
  76. $classes[] = $this->get_class_from_file($filePath);
  77. }
  78. }
  79. $config = [
  80. 'title' => $title,
  81. 'author' => $author,
  82. 'description' => '',
  83. 'apiurl' => $url,
  84. ];
  85. $builder = new Builder($classes);
  86. $content = $builder->render($template_file, ['config' => $config, 'lang' => $lang]);
  87. if (!file_put_contents($output_file, $content))
  88. {
  89. throw new Exception('Cannot save the content to ' . $output_file);
  90. }
  91. $output->info("Build Successed!");
  92. }
  93. /**
  94. * get full qualified class name
  95. *
  96. * @param string $path_to_file
  97. * @author JBYRNE http://jarretbyrne.com/2015/06/197/
  98. * @return string
  99. */
  100. protected function get_class_from_file($path_to_file)
  101. {
  102. //Grab the contents of the file
  103. $contents = file_get_contents($path_to_file);
  104. //Start with a blank namespace and class
  105. $namespace = $class = "";
  106. //Set helper values to know that we have found the namespace/class token and need to collect the string values after them
  107. $getting_namespace = $getting_class = false;
  108. //Go through each token and evaluate it as necessary
  109. foreach (token_get_all($contents) as $token)
  110. {
  111. //If this token is the namespace declaring, then flag that the next tokens will be the namespace name
  112. if (is_array($token) && $token[0] == T_NAMESPACE)
  113. {
  114. $getting_namespace = true;
  115. }
  116. //If this token is the class declaring, then flag that the next tokens will be the class name
  117. if (is_array($token) && $token[0] == T_CLASS)
  118. {
  119. $getting_class = true;
  120. }
  121. //While we're grabbing the namespace name...
  122. if ($getting_namespace === true)
  123. {
  124. //If the token is a string or the namespace separator...
  125. if (is_array($token) && in_array($token[0], [T_STRING, T_NS_SEPARATOR]))
  126. {
  127. //Append the token's value to the name of the namespace
  128. $namespace .= $token[1];
  129. }
  130. else if ($token === ';')
  131. {
  132. //If the token is the semicolon, then we're done with the namespace declaration
  133. $getting_namespace = false;
  134. }
  135. }
  136. //While we're grabbing the class name...
  137. if ($getting_class === true)
  138. {
  139. //If the token is a string, it's the name of the class
  140. if (is_array($token) && $token[0] == T_STRING)
  141. {
  142. //Store the token's value as the class name
  143. $class = $token[1];
  144. //Got what we need, stope here
  145. break;
  146. }
  147. }
  148. }
  149. //Build the fully-qualified class name and return it
  150. return $namespace ? $namespace . '\\' . $class : $class;
  151. }
  152. }