Skip to content
Prev Previous commit
fix: Lazy load IURLGenerator from AppManager to avoid installation crash
Signed-off-by: Côme Chilliet <[email protected]>
  • Loading branch information
come-nc committed Apr 22, 2024
commit ac1d868d18074752029a9f4fdeda6614daa62010
19 changes: 17 additions & 2 deletions lib/private/App/AppManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,15 +98,19 @@ class AppManager implements IAppManager {
private array $loadedApps = [];

private ?AppConfig $appConfig = null;
private ?IURLGenerator $urlGenerator = null;

/**
* Be extremely careful when injecting classes here. The AppManager is used by the installer,
* so it needs to work before installation. See how AppConfig and IURLGenerator are injected for reference
*/
public function __construct(
private IUserSession $userSession,
private IConfig $config,
private IGroupManager $groupManager,
private ICacheFactory $memCacheFactory,
private IEventDispatcher $dispatcher,
private LoggerInterface $logger,
private IURLGenerator $urlGenerator,
) {
}

Expand All @@ -115,7 +119,7 @@ public function getAppIcon(string $appId, bool $dark = false): ?string {
$icon = null;
foreach ($possibleIcons as $iconName) {
try {
$icon = $this->urlGenerator->imagePath($appId, $iconName);
$icon = $this->getUrlGenerator()->imagePath($appId, $iconName);
break;
} catch (\RuntimeException $e) {
// ignore
Expand All @@ -135,6 +139,17 @@ private function getAppConfig(): AppConfig {
return $this->appConfig;
}

private function getUrlGenerator(): IURLGenerator {
if ($this->urlGenerator !== null) {
return $this->urlGenerator;
}
if (!$this->config->getSystemValueBool('installed', false)) {
throw new \Exception('Nextcloud is not installed yet, AppConfig is not available');
}
$this->urlGenerator = \OCP\Server::get(IURLGenerator::class);
return $this->urlGenerator;
}

/**
* @return string[] $appId => $enabled
*/
Expand Down
1 change: 0 additions & 1 deletion lib/private/Server.php
Original file line number Diff line number Diff line change
Expand Up @@ -897,7 +897,6 @@ public function __construct($webRoot, \OC\Config $config) {
$c->get(ICacheFactory::class),
$c->get(IEventDispatcher::class),
$c->get(LoggerInterface::class),
$c->get(IURLGenerator::class),
);
});
/** @deprecated 19.0.0 */
Expand Down
9 changes: 2 additions & 7 deletions tests/lib/App/AppManagerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ protected function getAppConfig() {
/** @var LoggerInterface|MockObject */
protected $logger;

protected IURLGenerator|MockObject $urlGenerator;
protected IURLGenerator&MockObject $urlGenerator;

/** @var IAppManager */
protected $manager;
Expand All @@ -118,6 +118,7 @@ protected function setUp(): void {
$this->urlGenerator = $this->createMock(IURLGenerator::class);

$this->overwriteService(AppConfig::class, $this->appConfig);
$this->overwriteService(IURLGenerator::class, $this->urlGenerator);

$this->cacheFactory->expects($this->any())
->method('createDistributed')
Expand All @@ -136,7 +137,6 @@ protected function setUp(): void {
$this->cacheFactory,
$this->eventDispatcher,
$this->logger,
$this->urlGenerator,
);
}

Expand Down Expand Up @@ -279,7 +279,6 @@ public function testEnableAppForGroups() {
$this->cacheFactory,
$this->eventDispatcher,
$this->logger,
$this->urlGenerator,
])
->onlyMethods([
'getAppPath',
Expand Down Expand Up @@ -333,7 +332,6 @@ public function testEnableAppForGroupsAllowedTypes(array $appInfo) {
$this->cacheFactory,
$this->eventDispatcher,
$this->logger,
$this->urlGenerator,
])
->onlyMethods([
'getAppPath',
Expand Down Expand Up @@ -395,7 +393,6 @@ public function testEnableAppForGroupsForbiddenTypes($type) {
$this->cacheFactory,
$this->eventDispatcher,
$this->logger,
$this->urlGenerator,
])
->onlyMethods([
'getAppPath',
Expand Down Expand Up @@ -598,7 +595,6 @@ public function testGetAppsNeedingUpgrade() {
$this->cacheFactory,
$this->eventDispatcher,
$this->logger,
$this->urlGenerator,
])
->onlyMethods(['getAppInfo'])
->getMock();
Expand Down Expand Up @@ -657,7 +653,6 @@ public function testGetIncompatibleApps() {
$this->cacheFactory,
$this->eventDispatcher,
$this->logger,
$this->urlGenerator,
])
->onlyMethods(['getAppInfo'])
->getMock();
Expand Down