Routes.php 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. <?php
  2. /**
  3. * 获取所有路由
  4. * @author xinnianq 2017-10-11
  5. */
  6. namespace common\components;
  7. use Yii;
  8. class Routes {
  9. /**
  10. * Get list of application routes [获取应用的所有路由]
  11. * @return array
  12. */
  13. public static function getAppRoutes($module = null)
  14. {
  15. if ($module === null) {
  16. $module = Yii::$app;
  17. } elseif (is_string($module)) {
  18. $module = Yii::$app->getModule($module);
  19. }
  20. $key = [__METHOD__, $module->getUniqueId()];
  21. // $cache = Configs::instance()->cache;
  22. // if ($cache === null || ($result = $cache->get($key)) === false) {
  23. $result = [];
  24. self::getRouteRecrusive($module, $result);
  25. // if ($cache !== null) {
  26. // $cache->set($key, $result, Configs::instance()->cacheDuration, new TagDependency([
  27. // 'tags' => self::CACHE_TAG,
  28. // ]));
  29. // }
  30. // }
  31. return $result;
  32. }
  33. /**
  34. * 递归Get route(s)
  35. * @param \yii\base\Module $module
  36. * @param array $result
  37. */
  38. protected static function getRouteRecrusive($module, &$result)
  39. {
  40. $token = "Get Route of '" . get_class($module) . "' with id '" . $module->uniqueId . "'";
  41. Yii::beginProfile($token, __METHOD__);
  42. try {
  43. // foreach ($module->getModules() as $id => $child) {
  44. // if (($child = $module->getModule($id)) !== null) {
  45. // self::getRouteRecrusive($child, $result);
  46. // }
  47. // }
  48. foreach ($module->controllerMap as $id => $type) {
  49. self::getControllerActions($type, $id, $module, $result);
  50. }
  51. $namespace = trim($module->controllerNamespace, '\\') . '\\';
  52. self::getControllerFiles($module, $namespace, '', $result);
  53. //$all = '/' . ltrim($module->uniqueId . '/*', '/'); //###############################
  54. //$result[$all] = $all;
  55. } catch (\Exception $exc) {
  56. Yii::error($exc->getMessage(), __METHOD__);
  57. }
  58. Yii::endProfile($token, __METHOD__);
  59. }
  60. /**
  61. * Get list controller under module
  62. * @param \yii\base\Module $module
  63. * @param string $namespace
  64. * @param string $prefix
  65. * @param mixed $result
  66. * @return mixed
  67. */
  68. protected static function getControllerFiles($module, $namespace, $prefix, &$result)
  69. {
  70. $path = Yii::getAlias('@' . str_replace('\\', '/', $namespace), false);
  71. $token = "Get controllers from '$path'";
  72. Yii::beginProfile($token, __METHOD__);
  73. try {
  74. if (!is_dir($path)) {
  75. return;
  76. }
  77. foreach (scandir($path) as $file) {
  78. if ($file == '.' || $file == '..') {
  79. continue;
  80. }
  81. if (is_dir($path . '/' . $file) && preg_match('%^[a-z0-9_/]+$%i', $file . '/')) {
  82. self::getControllerFiles($module, $namespace . $file . '\\', $prefix . $file . '/', $result);
  83. } elseif (strcmp(substr($file, -14), 'Controller.php') === 0) {
  84. $baseName = substr(basename($file), 0, -14);
  85. $name = strtolower(preg_replace('/(?<![A-Z])[A-Z]/', ' \0', $baseName));
  86. $id = ltrim(str_replace(' ', '-', $name), '-');
  87. $className = $namespace . $baseName . 'Controller';
  88. if (strpos($className, '-') === false && class_exists($className) && is_subclass_of($className, 'yii\base\Controller')) {
  89. self::getControllerActions($className, $prefix . $id, $module, $result);
  90. }
  91. }
  92. }
  93. } catch (\Exception $exc) {
  94. Yii::error($exc->getMessage(), __METHOD__);
  95. }
  96. Yii::endProfile($token, __METHOD__);
  97. }
  98. /**
  99. * Get list action of controller 获取controller的action
  100. * @param mixed $type
  101. * @param string $id
  102. * @param \yii\base\Module $module
  103. * @param string $result
  104. */
  105. protected static function getControllerActions($type, $id, $module, &$result)
  106. {
  107. $token = "Create controller with cofig=" . \yii\helpers\VarDumper::dumpAsString($type) . " and id='$id'";
  108. Yii::beginProfile($token, __METHOD__);
  109. try {
  110. /* @var $controller \yii\base\Controller */
  111. $controller = Yii::createObject($type, [$id, $module]);
  112. self::getActionRoutes($controller, $result);
  113. //$all = "/{$controller->uniqueId}/*"; //#####################################################
  114. //$result[$all] = $all;
  115. } catch (\Exception $exc) {
  116. Yii::error($exc->getMessage(), __METHOD__);
  117. }
  118. Yii::endProfile($token, __METHOD__);
  119. }
  120. /**
  121. * Get route of action
  122. * @param \yii\base\Controller $controller
  123. * @param array $result all controller action.
  124. */
  125. protected static function getActionRoutes($controller, &$result)
  126. {
  127. $token = "Get actions of controller '" . $controller->uniqueId . "'";
  128. Yii::beginProfile($token, __METHOD__);
  129. try {
  130. $prefix = '/' . $controller->uniqueId . '/';
  131. // foreach ($controller->actions() as $id => $value) {
  132. // //$result[$prefix . $id] = $prefix . $id; //###########################################
  133. // $result[$controller->uniqueId][$prefix . $id][0] = $prefix . $id;
  134. // $result[$controller->uniqueId][$prefix . $id][1] = '';
  135. // }
  136. $class = new \ReflectionClass($controller);
  137. $result['/'.$controller->uniqueId.'/']['controllerDescription'] = self::getHelpSummary($controller); //控制器描述
  138. foreach ($class->getMethods() as $method) {
  139. $name = $method->getName();
  140. if ($method->isPublic() && !$method->isStatic() && strpos($name, 'action') === 0 && $name !== 'actions') {
  141. $name = strtolower(preg_replace('/(?<![A-Z])[A-Z]/', ' \0', substr($name, 6)));
  142. $id = $prefix . ltrim(str_replace(' ', '-', $name), '-');
  143. //$result[$id] = $id; //####################################
  144. $result['/'.$controller->uniqueId.'/']['route'][$id][0] = $id;
  145. //获取方法描述开始#############
  146. $summary = self::getActionHelpSummary($controller,$controller->createAction(ltrim(str_replace(' ', '-', $name), '-')));
  147. $result['/'.$controller->uniqueId.'/']['route'][$id][1] = $summary;
  148. //获取方法描述结束#############
  149. }
  150. }
  151. } catch (\Exception $exc) {
  152. Yii::error($exc->getMessage().$exc->getLine().'##'.$exc->getCode().'@@', __METHOD__);
  153. }
  154. Yii::endProfile($token, __METHOD__);
  155. }
  156. /**
  157. * 获取控制器描述
  158. * Returns one-line short summary describing this controller.
  159. *
  160. * You may override this method to return customized summary.
  161. * The default implementation returns first line from the PHPDoc comment.
  162. *
  163. * @return string
  164. */
  165. public static function getHelpSummary($controller)
  166. {
  167. return self::parseDocCommentSummary(new \ReflectionClass($controller));
  168. }
  169. //获取方法描述开始#############
  170. /**
  171. * Returns a one-line short summary describing the specified action.
  172. * @param Action $action action to get summary for
  173. * @return string a one-line short summary describing the specified action.
  174. */
  175. public static function getActionHelpSummary($controller,$action)
  176. {
  177. return self::parseDocCommentSummary(self::getActionMethodReflection($controller,$action));
  178. }
  179. /**
  180. * @param Action $action
  181. * @return \ReflectionMethod
  182. */
  183. protected static function getActionMethodReflection($controller,$action)
  184. {
  185. $_reflections = [];
  186. if (!isset($_reflections[$action->id])) {
  187. if ($action instanceof \yii\base\InlineAction) {
  188. $_reflections[$action->id] = new \ReflectionMethod($controller, $action->actionMethod);
  189. } else {
  190. $_reflections[$action->id] = new \ReflectionMethod($action, 'run');
  191. }
  192. }
  193. return $_reflections[$action->id];
  194. }
  195. /**
  196. * Returns the first line of docblock.
  197. *
  198. * @param \Reflector $reflection
  199. * @return string
  200. */
  201. protected static function parseDocCommentSummary($reflection)
  202. {
  203. $docLines = preg_split('~\R~u', $reflection->getDocComment());
  204. if (isset($docLines[1])) {
  205. return trim($docLines[1], "\t *");
  206. }
  207. return '';
  208. }
  209. //获取方法描述结束#############
  210. }