InitPermissionsCommand.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. <?php
  2. namespace App\Console\Commands;
  3. use App\Repositories\Models\Base\Permission;
  4. use Illuminate\Console\Command;
  5. use Illuminate\Support\Facades\DB;
  6. use Illuminate\Support\Facades\File;
  7. use Illuminate\Support\Str;
  8. /**
  9. * Class PresenterCommand
  10. * @package Prettus\Repository\Generators\Commands
  11. * @author Anderson Andrade <contato@andersonandra.de>
  12. */
  13. class InitPermissionsCommand extends Command
  14. {
  15. /**
  16. * The name of command.
  17. *
  18. * @var string
  19. */
  20. protected $name = 'init:permissions';
  21. /**
  22. * The description of command.
  23. *
  24. * @var string
  25. */
  26. protected $description = 'test';
  27. /**
  28. * The type of class being generated.
  29. *
  30. * @var string
  31. */
  32. protected $type = 'permission';
  33. /**
  34. * Execute the console command.
  35. *
  36. * @return void
  37. */
  38. public function handle()
  39. {
  40. $router = $this->getRouter();
  41. $routeCollection = $router->getRoutes();
  42. $rows = [];
  43. $permissions = [];
  44. foreach ($routeCollection as $route) {
  45. if (!Str::startsWith($route['uri'], '/admin')) continue;
  46. $row = [
  47. 'verb' => $route['method'],
  48. 'path' => $route['uri'],
  49. 'namedRoute' => $this->getNamedRoute($route['action']),
  50. 'controller' => $this->getController($route['action']),
  51. 'action' => $this->getAction($route['action']),
  52. 'middleware' => $this->getMiddleware($route['action']),
  53. ];
  54. $index = count($rows);
  55. if ($row['controller'] != 'None' && $index > 0) {
  56. $reflection = new \ReflectionClass($row['controller']);
  57. $controllerDoc = $reflection->getDocComment();
  58. //解析类的注释头
  59. $controllerParseResult = $this->parse($controllerDoc);
  60. if (array_key_exists('name', $controllerParseResult)) {
  61. $row['controller_name'] = $controllerParseResult['name'];
  62. } elseif (array_key_exists('description', $controllerParseResult)) {
  63. $row['controller_name'] = $controllerParseResult['description'];
  64. } else {
  65. $row['controller_name'] = $controllerParseResult['long_description'];
  66. }
  67. try {
  68. $method = $reflection->getMethod($row['action'])->getDocComment();
  69. $methodParseResult = $this->parse($method);
  70. if (array_key_exists('name', $methodParseResult)) {
  71. $row['action_name'] = $methodParseResult['name'];
  72. } elseif (array_key_exists('description', $methodParseResult)) {
  73. $row['action_name'] = $methodParseResult['description'];
  74. } else {
  75. $row['action_name'] = $methodParseResult['long_description'];
  76. }
  77. } catch (\Exception $exception) {
  78. dd($route, $exception);
  79. }
  80. $row['is_must'] = 0;
  81. if (array_key_exists('must', $methodParseResult)) {
  82. $row['is_must'] = 1;
  83. }
  84. // $name = str_replace('/', ':', trim($row['path'], '/')) . ':' . $row['action'];
  85. // $name = str_replace('\\', ':', str_replace(['App\Http\Controllers\\'], '', $row['controller'])) . ':' . $row['action'];
  86. $name = $row['verb'] . '|' . str_replace('/', ':', trim($row['path'], '/'));
  87. $permissions[] = [
  88. 'name' => $name,
  89. 'nickname' => $row['action_name'],
  90. 'module' => $row['controller_name'],
  91. 'url' => $row['path'],
  92. 'method' => $row['verb'],
  93. 'controller' => $row['controller'],
  94. 'action' => $row['action'],
  95. 'is_must' => $row['is_must'],
  96. 'guard_name' => 'admins',
  97. ];
  98. }
  99. $rows[] = $row;
  100. }
  101. // if ($this->laravel->bound(Router::class)) {
  102. // $routes = $this->laravel->make(Router::class)->getRoutes();
  103. //
  104. // foreach ($routes as $route) {
  105. // foreach ($route->getRoutes() as $innerRoute) {
  106. // $rows[] = [
  107. // 'verb' => implode('|', $innerRoute->getMethods()),
  108. // 'path' => $innerRoute->getPath(),
  109. // 'namedRoute' => $innerRoute->getName(),
  110. // 'controller' => get_class($innerRoute->getControllerInstance()),
  111. // 'action' => $this->getAction($innerRoute->getAction()),
  112. // 'middleware' => implode('|', $innerRoute->getMiddleware()),
  113. // ];
  114. // }
  115. // }
  116. // }
  117. // $headers = array('Verb', 'Path', 'NamedRoute', 'Controller', 'Action', 'Middleware', 'controller_name', 'action_name', 'is_must');
  118. // $this->table($headers, $rows);
  119. // $headers = array('name', 'nickname', 'module', 'url', 'method', 'controller', 'action', 'is_must', 'guard_name');
  120. // $this->table($headers, $permissions);
  121. DB::statement('SET FOREIGN_KEY_CHECKS = 0'); // 禁用外键约束
  122. DB::table('base_permissions')->truncate();
  123. DB::statement('SET FOREIGN_KEY_CHECKS = 1'); // 启用外键约束
  124. DB::transaction(function () use ($permissions) {
  125. foreach ($permissions as $permission) {
  126. Permission::query()->updateOrCreate(['name' => $permission['name']], $permission);
  127. }
  128. });
  129. $this->line('ok');
  130. }
  131. /**
  132. * Get the router.
  133. *
  134. * @return \Laravel\Lumen\Routing\Router
  135. */
  136. protected function getRouter()
  137. {
  138. return isset($this->laravel->router) ? $this->laravel->router : $this->laravel;
  139. }
  140. /**
  141. * @param array $action
  142. * @return string
  143. */
  144. protected function getNamedRoute(array $action)
  145. {
  146. return (!isset($action['as'])) ? "" : $action['as'];
  147. }
  148. /**
  149. * @param array $action
  150. * @return mixed|string
  151. */
  152. protected function getController(array $action)
  153. {
  154. if (empty($action['uses'])) {
  155. return 'None';
  156. }
  157. return current(explode("@", $action['uses']));
  158. }
  159. /**
  160. * @param array $action
  161. * @return string
  162. */
  163. protected function getAction(array $action)
  164. {
  165. if (!empty($action['uses']) && is_string($action['uses'])) {
  166. $data = $action['uses'];
  167. if (($pos = strpos($data, "@")) !== false) {
  168. return substr($data, $pos + 1);
  169. } else {
  170. return "METHOD NOT FOUND";
  171. }
  172. } else {
  173. return 'Closure';
  174. }
  175. }
  176. /**
  177. * @param array $action
  178. * @return string
  179. */
  180. protected function getMiddleware(array $action)
  181. {
  182. return (isset($action['middleware'])) ? (is_array($action['middleware'])) ? join(", ", $action['middleware']) : $action['middleware'] : '';
  183. }
  184. function parse($doc = '')
  185. {
  186. $params = [];
  187. if ($doc == '') {
  188. return $params;
  189. }
  190. // Get the comment
  191. if (preg_match('#^/\*\*(.*)\*/#s', $doc, $comment) === false) return $params;
  192. $comment = trim($comment[1]);
  193. // Get all the lines and strip the * from the first character
  194. if (preg_match_all('#^\s*\*(.*)#m', $comment, $lines) === false) return $params;
  195. $this->parseLines($lines[1], $params);
  196. return $params;
  197. }
  198. private function parseLines($lines, &$params)
  199. {
  200. foreach ($lines as $line) {
  201. $parsedLine = $this->parseLine($line, $params); // Parse the line
  202. if ($parsedLine === false && !isset($params['description'])) {
  203. if (isset($desc)) {
  204. // Store the first line in the short description
  205. $params['description'] = implode(PHP_EOL, $desc);
  206. }
  207. $desc = array();
  208. } elseif ($parsedLine !== false) {
  209. $desc[] = $parsedLine; // Store the line in the long description
  210. }
  211. }
  212. $desc = implode(' ', $desc);
  213. if (!empty($desc))
  214. $params['long_description'] = $desc;
  215. }
  216. private function parseLine($line, &$params)
  217. {
  218. // trim the whitespace from the line
  219. $line = trim($line);
  220. if (empty ($line))
  221. return false; // Empty line
  222. if (strpos($line, '@') === 0) {
  223. if (strpos($line, ' ') > 0) {
  224. // Get the parameter name
  225. $param = substr($line, 1, strpos($line, ' ') - 1);
  226. $value = substr($line, strlen($param) + 2); // Get the value
  227. } else {
  228. $param = substr($line, 1);
  229. $value = '';
  230. }
  231. // Parse the line and return false if the parameter is valid
  232. if ($this->setParam($param, $value, $params)) return false;
  233. }
  234. return $line;
  235. }
  236. private function setParam($param, $value, &$params)
  237. {
  238. if ($param == 'param' || $param == 'return') $value = $this->formatParamOrReturn($value);
  239. if ($param == 'class') list($param, $value) = $this->formatClass($value);
  240. if (empty ($params[$param])) {
  241. $params[$param] = $value;
  242. } else if ($param == 'param') {
  243. $arr = array(
  244. $params[$param],
  245. $value
  246. );
  247. $params[$param] = $arr;
  248. } else {
  249. if (array_key_exists($param, $params)) $params[$param] = (string)$value . $params[$param];
  250. }
  251. return true;
  252. }
  253. private function formatParamOrReturn($string)
  254. {
  255. $pos = strpos($string, ' ');
  256. $type = substr($string, 0, $pos);
  257. return '(' . $type . ')' . substr($string, $pos + 1);
  258. }
  259. private function formatClass($value)
  260. {
  261. $r = preg_split("[\(|\)]", $value);
  262. if (is_array($r)) {
  263. $param = $r [0];
  264. parse_str($r [1], $value);
  265. foreach ($value as $key => $val) {
  266. $val = explode(',', $val);
  267. if (count($val) > 1)
  268. $value [$key] = $val;
  269. }
  270. } else {
  271. $param = 'Unknown';
  272. }
  273. return array(
  274. $param,
  275. $value
  276. );
  277. }
  278. }