]> source.dussan.org Git - nextcloud-server.git/commitdiff
Move to lazy panel registration during registration context
authorJulius Härtl <jus@bitgrid.net>
Tue, 23 Jun 2020 13:23:28 +0000 (15:23 +0200)
committerJulius Härtl <jus@bitgrid.net>
Wed, 15 Jul 2020 07:27:57 +0000 (09:27 +0200)
Signed-off-by: Julius Härtl <jus@bitgrid.net>
apps/dashboard/templates/index.php
lib/private/AppFramework/Bootstrap/Coordinator.php
lib/private/AppFramework/Bootstrap/RegistrationContext.php
lib/private/Dashboard/Manager.php
lib/public/AppFramework/Bootstrap/IRegistrationContext.php
lib/public/Dashboard/IManager.php
tests/lib/AppFramework/Bootstrap/CoordinatorTest.php

index b9e614b0f1c60d978e3bd453f19d51219428a8c8..bca9fa30494682d0dcf6789e8f50aeee96450579 100644 (file)
@@ -1,4 +1,4 @@
 <?php
-       \OC_Util::addScript('dashboard', 'dashboard');
+       \OCP\Util::addScript('dashboard', 'dashboard');
 ?>
 <div id="app"></div>
index 3edc0f974727d6ae57dec4c590920d9a9337b0f2..358e71d78541de1bc5d766bd5f3db32a80134ac2 100644 (file)
@@ -30,6 +30,7 @@ use OC_App;
 use OCP\AppFramework\App;
 use OCP\AppFramework\Bootstrap\IBootstrap;
 use OCP\AppFramework\QueryException;
+use OCP\Dashboard\IManager;
 use OCP\EventDispatcher\IEventDispatcher;
 use OCP\ILogger;
 use OCP\IServerContainer;
@@ -47,6 +48,9 @@ class Coordinator {
        /** @var Registry */
        private $registry;
 
+       /** @var IManager */
+       private $dashboardManager;
+
        /** @var IEventDispatcher */
        private $eventDispatcher;
 
@@ -58,10 +62,12 @@ class Coordinator {
 
        public function __construct(IServerContainer $container,
                                                                Registry $registry,
+                                                               IManager $dashboardManager,
                                                                IEventDispatcher $eventListener,
                                                                ILogger $logger) {
                $this->serverContainer = $container;
                $this->registry = $registry;
+               $this->dashboardManager = $dashboardManager;
                $this->eventDispatcher = $eventListener;
                $this->logger = $logger;
        }
@@ -117,6 +123,7 @@ class Coordinator {
                 */
                $this->registrationContext->delegateCapabilityRegistrations($apps);
                $this->registrationContext->delegateCrashReporterRegistrations($apps, $this->registry);
+               $this->registrationContext->delegateDashboardPanelRegistrations($apps, $this->dashboardManager);
                $this->registrationContext->delegateEventListenerRegistrations($this->eventDispatcher);
                $this->registrationContext->delegateContainerRegistrations($apps);
                $this->registrationContext->delegateMiddlewareRegistrations($apps);
index 15b1cfa51e8170bd6392b9efc961b94eca403f2f..270035a290859437f61aecb3716da5e61756bea7 100644 (file)
@@ -29,6 +29,7 @@ use Closure;
 use OC\Support\CrashReport\Registry;
 use OCP\AppFramework\App;
 use OCP\AppFramework\Bootstrap\IRegistrationContext;
+use OCP\Dashboard\IManager;
 use OCP\EventDispatcher\IEventDispatcher;
 use OCP\ILogger;
 use Throwable;
@@ -41,6 +42,9 @@ class RegistrationContext {
        /** @var array[] */
        private $crashReporters = [];
 
+       /** @var array[] */
+       private $dashboardPanels = [];
+
        /** @var array[] */
        private $services = [];
 
@@ -93,6 +97,13 @@ class RegistrationContext {
                                );
                        }
 
+                       public function registerDashboardPanel(string $panelClass): void {
+                               $this->context->registerDashboardPanel(
+                                       $this->appId,
+                                       $panelClass
+                               );
+                       }
+
                        public function registerService(string $name, callable $factory, bool $shared = true): void {
                                $this->context->registerService(
                                        $this->appId,
@@ -157,6 +168,13 @@ class RegistrationContext {
                ];
        }
 
+       public function registerDashboardPanel(string $appId, string $panelClass): void {
+               $this->dashboardPanels[] = [
+                       'appId' => $appId,
+                       'class' => $panelClass
+               ];
+       }
+
        public function registerService(string $appId, string $name, callable $factory, bool $shared = true): void {
                $this->services[] = [
                        "appId" => $appId,
@@ -241,6 +259,23 @@ class RegistrationContext {
                }
        }
 
+       /**
+        * @param App[] $apps
+        */
+       public function delegateDashboardPanelRegistrations(array $apps, IManager $dashboardManager): void {
+               foreach ($this->dashboardPanels as $panel) {
+                       try {
+                               $dashboardManager->lazyRegisterPanel($panel['class']);
+                       } catch (Throwable $e) {
+                               $appId = $panel['appId'];
+                               $this->logger->logException($e, [
+                                       'message' => "Error during dashboard registration of $appId: " . $e->getMessage(),
+                                       'level' => ILogger::ERROR,
+                               ]);
+                       }
+               }
+       }
+
        public function delegateEventListenerRegistrations(IEventDispatcher $eventDispatcher): void {
                foreach ($this->eventListeners as $registration) {
                        try {
index 99d8999c24a4c412cfbc9ecb7a20ce8c72243b55..0d149dc9a13ecc84559f58397cf3c9da79deca41 100644 (file)
 
 namespace OC\Dashboard;
 
+use OCP\AppFramework\QueryException;
 use OCP\Dashboard\IManager;
 use OCP\Dashboard\IPanel;
+use OCP\IServerContainer;
 
 class Manager implements IManager {
+
+       /** @var array */
+       private $lazyPanels = [];
+
+       /** @var IPanel[] */
        private $panels = [];
 
+       /** @var IServerContainer */
+       private $serverContainer;
+
+       public function __construct(IServerContainer $serverContainer) {
+               $this->serverContainer = $serverContainer;
+       }
+
        /**
         * @inheritDoc
         */
@@ -40,7 +54,48 @@ class Manager implements IManager {
                $this->panels[$panel->getId()] = $panel;
        }
 
+       public function lazyRegisterPanel(string $panelClass): void {
+               $this->lazyPanels[] = $panelClass;
+       }
+
+       public function loadLazyPanels(): void {
+               $classes = $this->lazyPanels;
+               foreach ($classes as $class) {
+                       try {
+                               /** @var IPanel $panel */
+                               $panel = $this->serverContainer->query($class);
+                       } catch (QueryException $e) {
+                               /*
+                                * There is a circular dependency between the logger and the registry, so
+                                * we can not inject it. Thus the static call.
+                                */
+                               \OC::$server->getLogger()->logException($e, [
+                                       'message' => 'Could not load lazy dashbaord panel: ' . $e->getMessage(),
+                                       'level' => ILogger::FATAL,
+                               ]);
+                       }
+                       /**
+                        * Try to register the loaded reporter. Theoretically it could be of a wrong
+                        * type, so we might get a TypeError here that we should catch.
+                        */
+                       try {
+                               $this->registerPanel($panel);
+                       } catch (Throwable $e) {
+                               /*
+                                * There is a circular dependency between the logger and the registry, so
+                                * we can not inject it. Thus the static call.
+                                */
+                               \OC::$server->getLogger()->logException($e, [
+                                       'message' => 'Could not register lazy crash reporter: ' . $e->getMessage(),
+                                       'level' => ILogger::FATAL,
+                               ]);
+                       }
+               }
+               $this->lazyPanels = [];
+       }
+
        public function getPanels(): array {
+               $this->loadLazyPanels();
                return $this->panels;
        }
 }
index 12367e5ed05f60b7490f0878b53fe9d928ef2fb6..8ce140996b7002b521c94971df4ecc8fc0a1efb6 100644 (file)
@@ -55,6 +55,15 @@ interface IRegistrationContext {
         */
        public function registerCrashReporter(string $reporterClass): void;
 
+       /**
+        * Register an implementation of \OCP\Dashboard\IPanel that
+        * will handle the implementation of a dashboard panel
+        *
+        * @param string $panelClass
+        * @return void
+        * @since 20.0.0
+        */
+       public function registerDashboardPanel(string $panelClass): void;
        /**
         * Register a service
         *
index a5185ae22a7f6530502b76eded2809735e7efa9a..21d67407fb85159aed5c5ba44c9d9ebb0d1ca9de 100644 (file)
@@ -37,6 +37,12 @@ interface IManager {
         */
        public function registerPanel(IPanel $panel): void;
 
+       /**
+        * @param string $panelClass
+        * @since 20.0.0
+        */
+       public function lazyRegisterPanel(string $panelClass): void;
+
        /**
         * @since 20.0.0
         *
index c12e5eeb15063f0e6b43af138f9327432865c70e..1fca34423d51d01c9556d0ce367f0d1b8d6ba5d7 100644 (file)
@@ -33,6 +33,7 @@ use OCP\AppFramework\Bootstrap\IBootContext;
 use OCP\AppFramework\Bootstrap\IBootstrap;
 use OCP\AppFramework\Bootstrap\IRegistrationContext;
 use OCP\AppFramework\QueryException;
+use OCP\Dashboard\IManager;
 use OCP\EventDispatcher\IEventDispatcher;
 use OCP\ILogger;
 use OCP\IServerContainer;
@@ -50,6 +51,9 @@ class CoordinatorTest extends TestCase {
        /** @var Registry|MockObject */
        private $crashReporterRegistry;
 
+       /** @var IManager|MockObject */
+       private $dashboardManager;
+
        /** @var IEventDispatcher|MockObject */
        private $eventDispatcher;
 
@@ -65,12 +69,14 @@ class CoordinatorTest extends TestCase {
                $this->appManager = $this->createMock(IAppManager::class);
                $this->serverContainer = $this->createMock(IServerContainer::class);
                $this->crashReporterRegistry = $this->createMock(Registry::class);
+               $this->dashboardManager = $this->createMock(IManager::class);
                $this->eventDispatcher = $this->createMock(IEventDispatcher::class);
                $this->logger = $this->createMock(ILogger::class);
 
                $this->coordinator = new Coordinator(
                        $this->serverContainer,
                        $this->crashReporterRegistry,
+                       $this->dashboardManager,
                        $this->eventDispatcher,
                        $this->logger
                );