diff --git a/lib/base.php b/lib/base.php index 7f666daceb..115a0968af 100644 --- a/lib/base.php +++ b/lib/base.php @@ -641,7 +641,7 @@ class OC { /** @var \OC\AppFramework\Bootstrap\Coordinator $bootstrapCoordinator */ $bootstrapCoordinator = \OC::$server->query(\OC\AppFramework\Bootstrap\Coordinator::class); - $bootstrapCoordinator->runRegistration(); + $bootstrapCoordinator->runInitialRegistration(); \OC::$server->getEventLogger()->start('init_session', 'Initialize session'); OC_App::loadApps(['session']); diff --git a/lib/private/AppFramework/Bootstrap/Coordinator.php b/lib/private/AppFramework/Bootstrap/Coordinator.php index c8155c3b5b..06a17e5242 100644 --- a/lib/private/AppFramework/Bootstrap/Coordinator.php +++ b/lib/private/AppFramework/Bootstrap/Coordinator.php @@ -38,7 +38,6 @@ use OCP\Dashboard\IManager; use OCP\EventDispatcher\IEventDispatcher; use OCP\ILogger; use OCP\IServerContainer; -use RuntimeException; use Throwable; use function class_exists; use function class_implements; @@ -79,14 +78,23 @@ class Coordinator { $this->logger = $logger; } - public function runRegistration(): void { - if ($this->registrationContext !== null) { - throw new RuntimeException('Registration has already been run'); - } + public function runInitialRegistration(): void { + $this->registerApps(OC_App::getEnabledApps()); + } - $this->registrationContext = new RegistrationContext($this->logger); + public function runLazyRegistration(string $appId): void { + $this->registerApps([$appId]); + } + + /** + * @param string[] $appIds + */ + private function registerApps(array $appIds): void { + if ($this->registrationContext === null) { + $this->registrationContext = new RegistrationContext($this->logger); + } $apps = []; - foreach (OC_App::getEnabledApps() as $appId) { + foreach ($appIds as $appId) { /* * First, we have to enable the app's autoloader * diff --git a/lib/private/AppFramework/Bootstrap/RegistrationContext.php b/lib/private/AppFramework/Bootstrap/RegistrationContext.php index 023590596e..68e2701de2 100644 --- a/lib/private/AppFramework/Bootstrap/RegistrationContext.php +++ b/lib/private/AppFramework/Bootstrap/RegistrationContext.php @@ -264,7 +264,7 @@ class RegistrationContext { * @param App[] $apps */ public function delegateCapabilityRegistrations(array $apps): void { - foreach ($this->capabilities as $registration) { + while (($registration = array_pop($this->capabilities)) !== null) { try { $apps[$registration['appId']] ->getContainer() @@ -283,7 +283,7 @@ class RegistrationContext { * @param App[] $apps */ public function delegateCrashReporterRegistrations(array $apps, Registry $registry): void { - foreach ($this->crashReporters as $registration) { + while (($registration = array_pop($this->crashReporters)) !== null) { try { $registry->registerLazy($registration['class']); } catch (Throwable $e) { @@ -300,7 +300,7 @@ class RegistrationContext { * @param App[] $apps */ public function delegateDashboardPanelRegistrations(array $apps, IManager $dashboardManager): void { - foreach ($this->dashboardPanels as $panel) { + while (($panel = array_pop($this->dashboardPanels)) !== null) { try { $dashboardManager->lazyRegisterWidget($panel['class']); } catch (Throwable $e) { @@ -314,7 +314,7 @@ class RegistrationContext { } public function delegateEventListenerRegistrations(IEventDispatcher $eventDispatcher): void { - foreach ($this->eventListeners as $registration) { + while (($registration = array_pop($this->eventListeners)) !== null) { try { if (isset($registration['priority'])) { $eventDispatcher->addServiceListener( @@ -342,7 +342,7 @@ class RegistrationContext { * @param App[] $apps */ public function delegateContainerRegistrations(array $apps): void { - foreach ($this->services as $registration) { + while (($registration = array_pop($this->services)) !== null) { try { /** * Register the service and convert the callable into a \Closure if necessary @@ -402,7 +402,7 @@ class RegistrationContext { * @param App[] $apps */ public function delegateMiddlewareRegistrations(array $apps): void { - foreach ($this->middlewares as $middleware) { + while (($middleware = array_pop($this->middlewares)) !== null) { try { $apps[$middleware['appId']] ->getContainer() diff --git a/lib/private/Installer.php b/lib/private/Installer.php index 9388711697..a2c4f9beff 100644 --- a/lib/private/Installer.php +++ b/lib/private/Installer.php @@ -42,6 +42,7 @@ namespace OC; use Doctrine\DBAL\Exception\TableExistsException; use OC\App\AppStore\Bundles\Bundle; use OC\App\AppStore\Fetcher\AppFetcher; +use OC\AppFramework\Bootstrap\Coordinator; use OC\Archive\TAR; use OC_App; use OC_DB; @@ -138,6 +139,9 @@ class Installer { // check for required dependencies \OC_App::checkAppDependencies($this->config, $l, $info, $ignoreMax); + /** @var Coordinator $coordinator */ + $coordinator = \OC::$server->get(Coordinator::class); + $coordinator->runLazyRegistration($appId); \OC_App::registerAutoloading($appId, $basedir); $previousVersion = $this->config->getAppValue($info['id'], 'installed_version', false);