diff --git a/src/Api/ApiServiceProvider.php b/src/Api/ApiServiceProvider.php index 45623f26742f2adebb930db28ebc5eda449f7e3c..a97980601ba9c33566a87b03d62e5af8df033a45 100644 --- a/src/Api/ApiServiceProvider.php +++ b/src/Api/ApiServiceProvider.php @@ -18,7 +18,6 @@ namespace Discuz\Api; -use App\Common\Utils; use Discuz\Api\Controller\AbstractSerializeController; use Discuz\Api\Events\ApiExceptionRegisterHandler; use Discuz\Api\Events\ConfigMiddleware; @@ -104,43 +103,57 @@ class ApiServiceProvider extends ServiceProvider protected function populateRoutes(RouteCollection $route) { - $reqUri = '';$uri=''; - if (isset($_SERVER['REQUEST_URI'])) { - $reqUri = $_SERVER['REQUEST_URI']; - $uri = str_replace(['/',' '], ['',''], $reqUri); - } - $route->group('/api', function (RouteCollection $route) { - require $this->app->basePath('routes/api.php'); - }); - if (strpos($uri, 'apiv3') === 0) { + $reqUri = $_SERVER['REQUEST_URI'] ?? ''; + if(empty($reqUri)) return; + preg_match("/(?<=plugin\/).*?(?=\/api)/", $reqUri, $m); + $pluginName = $m[0]; + $adminApiPrefix = '/api/backAdmin'; + $userApiPrefix = '/api'; + $userApiV3Prefix = '/apiv3'; + $pluginApiPrefix = '/plugin/' . $pluginName . '/api'; + if ($this->matchPrefix($reqUri, $adminApiPrefix)) { + $route->group('/api/backAdmin', function (RouteCollection $route) { + require $this->app->basePath('routes/apiadmin.php'); + }); + } else if ($this->matchPrefix($reqUri, $userApiV3Prefix)) { $route->group('/apiv3', function (RouteCollection $route) { require $this->app->basePath('routes/apiv3.php'); }); - } else if (strpos($uri, 'api') === 0) { - $route->group('/api/backAdmin', function (RouteCollection $route) { - require $this->app->basePath('routes/apiadmin.php'); + } else if ($this->matchPrefix($reqUri, $userApiPrefix)) { + $route->group('/api', function (RouteCollection $route) { + require $this->app->basePath('routes/api.php'); + }); + } else if ($this->matchPrefix($reqUri, $pluginApiPrefix)) { + $this->setPluginRoutes($route, $pluginName); + } else { + $route->group('/api', function (RouteCollection $route) { + require $this->app->basePath('routes/api.php'); }); - } else if (strpos($uri, 'plugin') === 0 && strpos($uri, 'api')) { - $this->setPluginRoutes($route, $reqUri); } } - private function setPluginRoutes($route, $reqUri) + + private function setPluginRoutes(RouteCollection $route, $pluginName) { $plugins = \Discuz\Common\Utils::getPluginList(); - preg_match("/(?<=plugin\/).*?(?=\/api)/", $reqUri, $m); - $pluginName = $m[0]; - foreach ($plugins as $plugin) { - if (strtolower($pluginName) == strtolower($plugin['name_en'])) { - $route->group('/plugin/' . $plugin['name_en'] . '/api/', function (RouteCollection $route) use ($plugin) { - $routes = $plugin['routes']; - foreach ($routes as $name => $info) { - $method = strtolower($info['method']); - $route->$method($name, $plugin['name_en'] . '.' . str_replace('/', '.', $name), $info['controller']); - } - }); - break; + $plugin = array_filter($plugins, function ($item) use ($pluginName) { + return strtolower($item['name_en']) == strtolower($pluginName); + }); + $plugin = current($plugin); + if (empty($plugin)) exit('plugin ' . $pluginName . ' not exist.'); + $prefix = '/plugin/' . $plugin['name_en'] . '/api/'; + $route->group($prefix, function (RouteCollection $route) use ($plugin) { + $pluginFiles = $plugin['plugin_' . $plugin['app_id']]; + if (isset($pluginFiles['routes'])) { + foreach ($pluginFiles['routes'] as $routeFile) { + require_once $routeFile; + } } - } + }); + } + + private function matchPrefix($uri, $prefix) + { + return ($uri & $prefix) == $prefix; } } diff --git a/src/Common/Utils.php b/src/Common/Utils.php index 3f1497622bcee12dd7139a66f8c5fa9355085eea..09bf297100e67c14692e3004680268f04a97bffc 100644 --- a/src/Common/Utils.php +++ b/src/Common/Utils.php @@ -10,6 +10,7 @@ use Discuz\Base\DzqLog; use Illuminate\Http\Request; use Illuminate\Support\Str; use Discuz\Http\DiscuzResponseFactory; +use Symfony\Component\Finder\Finder; /** * Copyright (C) 2020 Tencent Cloud. @@ -177,46 +178,40 @@ class Utils $cacheConfig = DzqCache::get(CacheKey::PLUGIN_LOCAL_CONFIG); if ($cacheConfig) return $cacheConfig; $pluginDir = base_path('plugin'); - $directories = array_diff(scandir($pluginDir), ['.', '..']); + $directories = Finder::create()->in($pluginDir)->directories()->depth(0)->sortByName(); $plugins = []; - foreach ($directories as $dirName) { - $subPlugins = array_diff(scandir($pluginDir . '/' . $dirName), ['.', '..']); - $configName = ''; - $viewName = ''; - $databaseName = ''; - $consoleName = ''; + foreach ($directories as $dir) { + $basePath = $dir->getPathname(); + $subPlugins = Finder::create()->in($basePath)->depth(0); + $configPath = null; + $viewPath = null; + $databasePath = null; + $consolePath = null; + $routesPath = null; foreach ($subPlugins as $item) { - switch (strtolower($item)) { - case 'config.php': - $configName = $item; - break; - case 'view': - $viewName = $item; - break; - case 'database': - $databaseName = $item; - break; - case 'console': - $consoleName = $item; - break; + $filename = strtolower($item->getFilenameWithoutExtension()); + $fileVar = $filename . 'Path'; + if ($filename == 'routes') { + $routesPath = $item->getPathname(); + $routeFiles = Finder::create()->in($routesPath)->path('/.*\.php/')->files(); + $routesPath = []; + foreach ($routeFiles as $routeFile) { + $routesPath[] = $routeFile->getPathname(); + } + } else { + $$fileVar = $item->getPathname(); } } - if ($configName == '') { - continue; - } - $basePath = $pluginDir . '/' . $dirName . '/'; - $configPath = $basePath . $configName; - $viewPath = $viewName == '' ? null : $basePath . $viewName . '/'; - $databasePath = $databaseName == '' ? null : $basePath . $databaseName . '/'; - $consolePath = $consoleName == '' ? null : $basePath . $consoleName . '/'; - $config = require($configPath); + if (strtolower(substr($configPath, -4, 4)) != 'json') continue; + $config = json_decode(file_get_contents($configPath), 256); if ($config['status'] == DzqConst::BOOL_YES) { $config['plugin_' . $config['app_id']] = [ 'base' => $basePath, 'view' => $viewPath, 'database' => $databasePath, 'console' => $consolePath, - 'config' => $configPath + 'config' => $configPath, + 'routes' => $routesPath ]; } diff --git a/src/Database/PluginCommand.php b/src/Database/PluginCommand.php index a0f335f6a0e5986f8794442cc47101ffe8e2f9cf..018b2626fdcac10bec9d7bf7e3d6e737ee30cb10 100644 --- a/src/Database/PluginCommand.php +++ b/src/Database/PluginCommand.php @@ -32,11 +32,11 @@ class PluginCommand extends Command if (empty($name)) throw new \Exception('expected one plugin name,used like [ php disco migrate:plugin --name=test ]'); $pluginList = Utils::getPluginList(); - $basePath = base_path().'/'; + $basePath = base_path().DIRECTORY_SEPARATOR; foreach ($pluginList as $item) { if (strtolower($item['name_en']) == strtolower($name)) { $paths = 'plugin_' . $item['app_id']; - $absolutePath = $item[$paths]['database'] . 'migrations'; + $absolutePath = $item[$paths]['database'] . '/migrations'; $localPath = str_replace($basePath,'',$absolutePath); if (!file_exists($absolutePath)) throw new \Exception($absolutePath . ' directory in ' . $item['name_en'] . ' not exist.'); // $this->call('migrate', array_filter(['--path' => $databasePath, '--force' => true])); diff --git a/src/Http/RouteCollection.php b/src/Http/RouteCollection.php index a0457374bb82e1dac637dec8cc3295984844d202..063e7c04085d41ab1f72db3e66e03f6e29e35108 100644 --- a/src/Http/RouteCollection.php +++ b/src/Http/RouteCollection.php @@ -84,6 +84,7 @@ class RouteCollection public function addRoute($method, $path, $name, $handler) { $path = $this->currentGroupPrefix . $path; + $path = str_replace('//','/',$path); $routeDatas = $this->routeParser->parse($path); foreach ($routeDatas as $routeData) { $this->dataGenerator->addRoute($method, $routeData, $handler);