Skip to content

Commit 3cf39c5

Browse files
Allow lazy app registration
During app installation we run migration steps. Those steps may use services the app registers or classes from composer. Hence we have to make sure the app runs through the registration. Signed-off-by: Christoph Wurst <[email protected]>
1 parent b5ba1de commit 3cf39c5

File tree

4 files changed

+26
-14
lines changed

4 files changed

+26
-14
lines changed

lib/base.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -641,7 +641,7 @@ public static function init() {
641641

642642
/** @var \OC\AppFramework\Bootstrap\Coordinator $bootstrapCoordinator */
643643
$bootstrapCoordinator = \OC::$server->query(\OC\AppFramework\Bootstrap\Coordinator::class);
644-
$bootstrapCoordinator->runRegistration();
644+
$bootstrapCoordinator->runInitialRegistration();
645645

646646
\OC::$server->getEventLogger()->start('init_session', 'Initialize session');
647647
OC_App::loadApps(['session']);

lib/private/AppFramework/Bootstrap/Coordinator.php

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
use OCP\EventDispatcher\IEventDispatcher;
3939
use OCP\ILogger;
4040
use OCP\IServerContainer;
41-
use RuntimeException;
4241
use Throwable;
4342
use function class_exists;
4443
use function class_implements;
@@ -79,14 +78,23 @@ public function __construct(IServerContainer $container,
7978
$this->logger = $logger;
8079
}
8180

82-
public function runRegistration(): void {
83-
if ($this->registrationContext !== null) {
84-
throw new RuntimeException('Registration has already been run');
85-
}
81+
public function runInitialRegistration(): void {
82+
$this->registerApps(OC_App::getEnabledApps());
83+
}
8684

87-
$this->registrationContext = new RegistrationContext($this->logger);
85+
public function runLazyRegistration(string $appId): void {
86+
$this->registerApps([$appId]);
87+
}
88+
89+
/**
90+
* @param string[] $appIds
91+
*/
92+
private function registerApps(array $appIds): void {
93+
if ($this->registrationContext === null) {
94+
$this->registrationContext = new RegistrationContext($this->logger);
95+
}
8896
$apps = [];
89-
foreach (OC_App::getEnabledApps() as $appId) {
97+
foreach ($appIds as $appId) {
9098
/*
9199
* First, we have to enable the app's autoloader
92100
*

lib/private/AppFramework/Bootstrap/RegistrationContext.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ public function registerInitialState(string $appId, string $class): void {
264264
* @param App[] $apps
265265
*/
266266
public function delegateCapabilityRegistrations(array $apps): void {
267-
foreach ($this->capabilities as $registration) {
267+
while (($registration = array_pop($this->capabilities)) !== null) {
268268
try {
269269
$apps[$registration['appId']]
270270
->getContainer()
@@ -283,7 +283,7 @@ public function delegateCapabilityRegistrations(array $apps): void {
283283
* @param App[] $apps
284284
*/
285285
public function delegateCrashReporterRegistrations(array $apps, Registry $registry): void {
286-
foreach ($this->crashReporters as $registration) {
286+
while (($registration = array_pop($this->crashReporters)) !== null) {
287287
try {
288288
$registry->registerLazy($registration['class']);
289289
} catch (Throwable $e) {
@@ -300,7 +300,7 @@ public function delegateCrashReporterRegistrations(array $apps, Registry $regist
300300
* @param App[] $apps
301301
*/
302302
public function delegateDashboardPanelRegistrations(array $apps, IManager $dashboardManager): void {
303-
foreach ($this->dashboardPanels as $panel) {
303+
while (($panel = array_pop($this->dashboardPanels)) !== null) {
304304
try {
305305
$dashboardManager->lazyRegisterWidget($panel['class']);
306306
} catch (Throwable $e) {
@@ -314,7 +314,7 @@ public function delegateDashboardPanelRegistrations(array $apps, IManager $dashb
314314
}
315315

316316
public function delegateEventListenerRegistrations(IEventDispatcher $eventDispatcher): void {
317-
foreach ($this->eventListeners as $registration) {
317+
while (($registration = array_pop($this->eventListeners)) !== null) {
318318
try {
319319
if (isset($registration['priority'])) {
320320
$eventDispatcher->addServiceListener(
@@ -342,7 +342,7 @@ public function delegateEventListenerRegistrations(IEventDispatcher $eventDispat
342342
* @param App[] $apps
343343
*/
344344
public function delegateContainerRegistrations(array $apps): void {
345-
foreach ($this->services as $registration) {
345+
while (($registration = array_pop($this->services)) !== null) {
346346
try {
347347
/**
348348
* Register the service and convert the callable into a \Closure if necessary
@@ -402,7 +402,7 @@ public function delegateContainerRegistrations(array $apps): void {
402402
* @param App[] $apps
403403
*/
404404
public function delegateMiddlewareRegistrations(array $apps): void {
405-
foreach ($this->middlewares as $middleware) {
405+
while (($middleware = array_pop($this->middlewares)) !== null) {
406406
try {
407407
$apps[$middleware['appId']]
408408
->getContainer()

lib/private/Installer.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
use Doctrine\DBAL\Exception\TableExistsException;
4343
use OC\App\AppStore\Bundles\Bundle;
4444
use OC\App\AppStore\Fetcher\AppFetcher;
45+
use OC\AppFramework\Bootstrap\Coordinator;
4546
use OC\Archive\TAR;
4647
use OC_App;
4748
use OC_DB;
@@ -138,6 +139,9 @@ public function installApp(string $appId, bool $forceEnable = false): string {
138139

139140
// check for required dependencies
140141
\OC_App::checkAppDependencies($this->config, $l, $info, $ignoreMax);
142+
/** @var Coordinator $coordinator */
143+
$coordinator = \OC::$server->get(Coordinator::class);
144+
$coordinator->runLazyRegistration($appId);
141145
\OC_App::registerAutoloading($appId, $basedir);
142146

143147
$previousVersion = $this->config->getAppValue($info['id'], 'installed_version', false);

0 commit comments

Comments
 (0)