*/ class InitPermissionsCommand extends Command { /** * The name of command. * * @var string */ protected $name = 'init:permissions'; /** * The description of command. * * @var string */ protected $description = 'test'; /** * The type of class being generated. * * @var string */ protected $type = 'permission'; /** * Execute the console command. * * @return void */ public function handle() { $router = $this->getRouter(); $routeCollection = $router->getRoutes(); $rows = []; $permissions = []; foreach ($routeCollection as $route) { if (!Str::startsWith($route['uri'], '/admin')) continue; $row = [ 'verb' => $route['method'], 'path' => $route['uri'], 'namedRoute' => $this->getNamedRoute($route['action']), 'controller' => $this->getController($route['action']), 'action' => $this->getAction($route['action']), 'middleware' => $this->getMiddleware($route['action']), ]; $index = count($rows); if ($row['controller'] != 'None' && $index > 0) { $reflection = new \ReflectionClass($row['controller']); $controllerDoc = $reflection->getDocComment(); //解析类的注释头 $controllerParseResult = $this->parse($controllerDoc); if (array_key_exists('name', $controllerParseResult)) { $row['controller_name'] = $controllerParseResult['name']; } elseif (array_key_exists('description', $controllerParseResult)) { $row['controller_name'] = $controllerParseResult['description']; } else { $row['controller_name'] = $controllerParseResult['long_description']; } try { $method = $reflection->getMethod($row['action'])->getDocComment(); $methodParseResult = $this->parse($method); if (array_key_exists('name', $methodParseResult)) { $row['action_name'] = $methodParseResult['name']; } elseif (array_key_exists('description', $methodParseResult)) { $row['action_name'] = $methodParseResult['description']; } else { $row['action_name'] = $methodParseResult['long_description']; } } catch (\Exception $exception) { dd($route, $exception); } $row['is_must'] = 0; if (array_key_exists('must', $methodParseResult)) { $row['is_must'] = 1; } // $name = str_replace('/', ':', trim($row['path'], '/')) . ':' . $row['action']; // $name = str_replace('\\', ':', str_replace(['App\Http\Controllers\\'], '', $row['controller'])) . ':' . $row['action']; $name = $row['verb'] . '|' . str_replace('/', ':', trim($row['path'], '/')); $permissions[] = [ 'name' => $name, 'nickname' => $row['action_name'], 'module' => $row['controller_name'], 'url' => $row['path'], 'method' => $row['verb'], 'controller' => $row['controller'], 'action' => $row['action'], 'is_must' => $row['is_must'], 'guard_name' => 'admins', ]; } $rows[] = $row; } // if ($this->laravel->bound(Router::class)) { // $routes = $this->laravel->make(Router::class)->getRoutes(); // // foreach ($routes as $route) { // foreach ($route->getRoutes() as $innerRoute) { // $rows[] = [ // 'verb' => implode('|', $innerRoute->getMethods()), // 'path' => $innerRoute->getPath(), // 'namedRoute' => $innerRoute->getName(), // 'controller' => get_class($innerRoute->getControllerInstance()), // 'action' => $this->getAction($innerRoute->getAction()), // 'middleware' => implode('|', $innerRoute->getMiddleware()), // ]; // } // } // } // $headers = array('Verb', 'Path', 'NamedRoute', 'Controller', 'Action', 'Middleware', 'controller_name', 'action_name', 'is_must'); // $this->table($headers, $rows); // $headers = array('name', 'nickname', 'module', 'url', 'method', 'controller', 'action', 'is_must', 'guard_name'); // $this->table($headers, $permissions); DB::statement('SET FOREIGN_KEY_CHECKS = 0'); // 禁用外键约束 DB::table('base_permissions')->truncate(); DB::statement('SET FOREIGN_KEY_CHECKS = 1'); // 启用外键约束 DB::transaction(function () use ($permissions) { foreach ($permissions as $permission) { Permission::query()->updateOrCreate(['name' => $permission['name']], $permission); } }); $this->line('ok'); } /** * Get the router. * * @return \Laravel\Lumen\Routing\Router */ protected function getRouter() { return isset($this->laravel->router) ? $this->laravel->router : $this->laravel; } /** * @param array $action * @return string */ protected function getNamedRoute(array $action) { return (!isset($action['as'])) ? "" : $action['as']; } /** * @param array $action * @return mixed|string */ protected function getController(array $action) { if (empty($action['uses'])) { return 'None'; } return current(explode("@", $action['uses'])); } /** * @param array $action * @return string */ protected function getAction(array $action) { if (!empty($action['uses']) && is_string($action['uses'])) { $data = $action['uses']; if (($pos = strpos($data, "@")) !== false) { return substr($data, $pos + 1); } else { return "METHOD NOT FOUND"; } } else { return 'Closure'; } } /** * @param array $action * @return string */ protected function getMiddleware(array $action) { return (isset($action['middleware'])) ? (is_array($action['middleware'])) ? join(", ", $action['middleware']) : $action['middleware'] : ''; } function parse($doc = '') { $params = []; if ($doc == '') { return $params; } // Get the comment if (preg_match('#^/\*\*(.*)\*/#s', $doc, $comment) === false) return $params; $comment = trim($comment[1]); // Get all the lines and strip the * from the first character if (preg_match_all('#^\s*\*(.*)#m', $comment, $lines) === false) return $params; $this->parseLines($lines[1], $params); return $params; } private function parseLines($lines, &$params) { foreach ($lines as $line) { $parsedLine = $this->parseLine($line, $params); // Parse the line if ($parsedLine === false && !isset($params['description'])) { if (isset($desc)) { // Store the first line in the short description $params['description'] = implode(PHP_EOL, $desc); } $desc = array(); } elseif ($parsedLine !== false) { $desc[] = $parsedLine; // Store the line in the long description } } $desc = implode(' ', $desc); if (!empty($desc)) $params['long_description'] = $desc; } private function parseLine($line, &$params) { // trim the whitespace from the line $line = trim($line); if (empty ($line)) return false; // Empty line if (strpos($line, '@') === 0) { if (strpos($line, ' ') > 0) { // Get the parameter name $param = substr($line, 1, strpos($line, ' ') - 1); $value = substr($line, strlen($param) + 2); // Get the value } else { $param = substr($line, 1); $value = ''; } // Parse the line and return false if the parameter is valid if ($this->setParam($param, $value, $params)) return false; } return $line; } private function setParam($param, $value, &$params) { if ($param == 'param' || $param == 'return') $value = $this->formatParamOrReturn($value); if ($param == 'class') list($param, $value) = $this->formatClass($value); if (empty ($params[$param])) { $params[$param] = $value; } else if ($param == 'param') { $arr = array( $params[$param], $value ); $params[$param] = $arr; } else { if (array_key_exists($param, $params)) $params[$param] = (string)$value . $params[$param]; } return true; } private function formatParamOrReturn($string) { $pos = strpos($string, ' '); $type = substr($string, 0, $pos); return '(' . $type . ')' . substr($string, $pos + 1); } private function formatClass($value) { $r = preg_split("[\(|\)]", $value); if (is_array($r)) { $param = $r [0]; parse_str($r [1], $value); foreach ($value as $key => $val) { $val = explode(',', $val); if (count($val) > 1) $value [$key] = $val; } } else { $param = 'Unknown'; } return array( $param, $value ); } }