diff --git a/modules/dashboard/php/dashboard.class.inc b/modules/dashboard/php/dashboard.class.inc index 6a94cd93b62..bce0e3d91a8 100644 --- a/modules/dashboard/php/dashboard.class.inc +++ b/modules/dashboard/php/dashboard.class.inc @@ -66,6 +66,8 @@ class Dashboard extends \NDB_Form $DB = \NDB_Factory::singleton()->database(); $user = \User::singleton(); + // FIXME: This should use \LORIS\LorisInstance->getActiveModules(), but there + // is no access to a LORISInstance object at this point in the code. $this->modules = \Module::getActiveModules($DB); $this->smallwidgets = []; diff --git a/src/LorisInstance.php b/src/LorisInstance.php new file mode 100644 index 00000000000..f5ba4834c45 --- /dev/null +++ b/src/LorisInstance.php @@ -0,0 +1,103 @@ +DB = $db; + $this->modulesDirs = $modulesDirs; + } + + /** + * Return an active database connection to this instance. + * + * @return \Database + */ + public function getDatabaseConnection() : \Database + { + return $this->DB; + } + + /** + * Return a list of directories on the filesystem which + * may contain modules. + * + * @return string[] + */ + private function getModulesDirs() : array + { + return $this->modulesDirs; + } + + /** + * Retrieve all active module descriptors from the given database. + * + * @param \Database $db an open connection to a database containing a 'modules' + * table + * + * @return \Module[] + */ + public function getActiveModules(): array + { + $mnames = $this->getDatabaseConnection()->pselectCol( + "SELECT Name FROM modules WHERE Active='Y'", + [] + ); + return array_map( + function ($name) { + return \Module::factory($name); + }, + $mnames + ); + } + + /** + * Return true if the LORISInstance has a module named + * $name. To be installed it must be both available on + * the filesystem, and active in the modules table. + * + * @return bool + */ + public function hasModule(string $name) : bool + { + $dirs = $this->getModulesDirs(); + $found = false; + foreach ($dirs as $subdir) { + if (is_dir($subdir . "/" . $name)) { + $found = true; + break; + } + } + + if ($found === false) { + return false; + } + + foreach ($this->getActiveModules() as $module) { + if ($module->getName() == $name) { + return true; + } + } + return false; + } +} diff --git a/src/Middleware/UserPageDecorationMiddleware.php b/src/Middleware/UserPageDecorationMiddleware.php index 3fc0e92513c..829c2af9162 100644 --- a/src/Middleware/UserPageDecorationMiddleware.php +++ b/src/Middleware/UserPageDecorationMiddleware.php @@ -22,8 +22,7 @@ public function __construct( string $pagename, \NDB_Config $config, array $JS, - array $CSS, - \Database $DB + array $CSS ) { $this->JSFiles = $JS; @@ -32,7 +31,6 @@ public function __construct( $this->BaseURL = $baseurl; $this->PageName = $pagename; $this->user = $user; - $this->DB = $DB; } /** @@ -48,14 +46,15 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface { ob_start(); // Set the page template variables - // $user is set by the page base router + // $user and $loris is set by the page base router $user = $request->getAttribute("user"); + $loris = $request->getAttribute("loris"); $tpl_data = array( 'test_name' => $this->PageName, ); + $menu = []; - $menu = []; - $modules = \Module::getActiveModules($this->DB); + $modules = $loris->getActiveModules(); foreach ($modules as $module) { if (!$module->hasAccess($user)) { continue; diff --git a/src/Router/BaseRouter.php b/src/Router/BaseRouter.php index 1faf8e007e1..1731b5f5778 100644 --- a/src/Router/BaseRouter.php +++ b/src/Router/BaseRouter.php @@ -30,8 +30,7 @@ */ class BaseRouter extends PrefixRouter implements RequestHandlerInterface { - protected $projectdir; - protected $moduledir; + protected $lorisinstance; protected $user; /** @@ -44,9 +43,14 @@ class BaseRouter extends PrefixRouter implements RequestHandlerInterface */ public function __construct(\User $user, string $projectdir, string $moduledir) { - $this->user = $user; - $this->projectdir = $projectdir; - $this->moduledir = $moduledir; + $this->user = $user; + $this->lorisinstance = new \LORIS\LorisInstance( + \NDB_Factory::singleton()->database(), + [ + $projectdir . "/modules", + $moduledir, + ] + ); } /** @@ -66,7 +70,9 @@ public function handle(ServerRequestInterface $request) : ResponseInterface // Remove any trailing slash remaining, so that foo/ and foo are the same // route $path = preg_replace("/\/$/", "", $path); - $request = $request->withAttribute("user", $this->user); + $request = $request->withAttribute("user", $this->user) + ->withAttribute("loris", $this->lorisinstance); + if ($path == "") { if ($this->user instanceof \LORIS\AnonymousUser) { $modulename = "login"; @@ -84,9 +90,9 @@ public function handle(ServerRequestInterface $request) : ResponseInterface $components = preg_split("/\/+?/", $path); $modulename = $components[0]; } - if (is_dir($this->moduledir . "/" . $modulename) - || is_dir($this->projectdir . "/modules/" . $modulename) - ) { + + $factory = \NDB_Factory::singleton(); + if ($this->lorisinstance->hasModule($modulename)) { $uri = $request->getURI(); $suburi = $this->stripPrefix($modulename, $uri); @@ -96,7 +102,6 @@ public function handle(ServerRequestInterface $request) : ResponseInterface $baseurl = $uri->withPath($baseurl)->withQuery(""); $request = $request->withAttribute("baseurl", $baseurl->__toString()); - $factory = \NDB_Factory::singleton(); $factory->setBaseURL($baseurl); $module = \Module::factory($modulename); @@ -112,8 +117,8 @@ public function handle(ServerRequestInterface $request) : ResponseInterface $path = $uri->getPath(); $baseurl = $uri->withPath("/")->withQuery(""); - $factory = \NDB_Factory::singleton(); $factory->setBaseURL($baseurl); + switch (count($components)) { case 1: $request = $request