Skip to content

Commit 37c89f4

Browse files
authored
Merge pull request #44025 from nextcloud/fix/remove-oc-app-calls
Migrate away from OC_App and toward IAppManager.
2 parents deac58a + ac1d868 commit 37c89f4

25 files changed

Lines changed: 239 additions & 193 deletions

File tree

apps/settings/lib/Controller/AppSettingsController.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ private function getAppsForCategory($requestedCategory = ''): array {
402402
try {
403403
$this->appManager->getAppPath($app['id']);
404404
$existsLocally = true;
405-
} catch (AppPathNotFoundException $e) {
405+
} catch (AppPathNotFoundException) {
406406
$existsLocally = false;
407407
}
408408

console.php

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
<?php
2+
3+
declare(strict_types=1);
4+
25
/**
36
* @copyright Copyright (c) 2016, ownCloud, Inc.
47
*
@@ -57,7 +60,7 @@ function exceptionHandler($exception) {
5760
exit(1);
5861
}
5962

60-
$config = \OC::$server->getConfig();
63+
$config = \OCP\Server::get(\OCP\IConfig::class);
6164
set_exception_handler('exceptionHandler');
6265

6366
if (!function_exists('posix_getuid')) {
@@ -102,13 +105,7 @@ function exceptionHandler($exception) {
102105
echo "Additionally the function 'pcntl_signal' and 'pcntl_signal_dispatch' need to be enabled in your php.ini." . PHP_EOL;
103106
}
104107

105-
$application = new Application(
106-
$config,
107-
\OC::$server->get(\OCP\EventDispatcher\IEventDispatcher::class),
108-
\OC::$server->getRequest(),
109-
\OC::$server->get(\Psr\Log\LoggerInterface::class),
110-
\OC::$server->query(\OC\MemoryInfo::class)
111-
);
108+
$application = \OCP\Server::get(Application::class);
112109
$application->loadCommands(new ArgvInput(), new ConsoleOutput());
113110
$application->run();
114111
} catch (Exception $ex) {

core/Command/App/Enable.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
<?php
2+
3+
declare(strict_types=1);
4+
25
/**
36
* @copyright Copyright (c) 2016, ownCloud, Inc.
47
*

core/Command/App/GetPath.php

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
<?php
2+
3+
declare(strict_types=1);
4+
25
/**
36
* @copyright Copyright (c) 2016, ownCloud, Inc.
47
*
@@ -23,12 +26,20 @@
2326
namespace OC\Core\Command\App;
2427

2528
use OC\Core\Command\Base;
29+
use OCP\App\AppPathNotFoundException;
30+
use OCP\App\IAppManager;
2631
use Stecman\Component\Symfony\Console\BashCompletion\CompletionContext;
2732
use Symfony\Component\Console\Input\InputArgument;
2833
use Symfony\Component\Console\Input\InputInterface;
2934
use Symfony\Component\Console\Output\OutputInterface;
3035

3136
class GetPath extends Base {
37+
public function __construct(
38+
protected IAppManager $appManager,
39+
) {
40+
parent::__construct();
41+
}
42+
3243
protected function configure(): void {
3344
parent::configure();
3445

@@ -52,14 +63,14 @@ protected function configure(): void {
5263
*/
5364
protected function execute(InputInterface $input, OutputInterface $output): int {
5465
$appName = $input->getArgument('app');
55-
$path = \OC_App::getAppPath($appName);
56-
if ($path !== false) {
57-
$output->writeln($path);
58-
return 0;
66+
try {
67+
$path = $this->appManager->getAppPath($appName);
68+
} catch (AppPathNotFoundException) {
69+
// App not found, exit with non-zero
70+
return self::FAILURE;
5971
}
60-
61-
// App not found, exit with non-zero
62-
return 1;
72+
$output->writeln($path);
73+
return self::SUCCESS;
6374
}
6475

6576
/**

core/Command/App/Install.php

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
<?php
2+
3+
declare(strict_types=1);
4+
25
/**
36
* @copyright Copyright (c) 2016, ownCloud, Inc.
47
*
@@ -36,6 +39,13 @@
3639
use Symfony\Component\Console\Output\OutputInterface;
3740

3841
class Install extends Command {
42+
public function __construct(
43+
protected IAppManager $appManager,
44+
private Installer $installer,
45+
) {
46+
parent::__construct();
47+
}
48+
3949
protected function configure(): void {
4050
$this
4151
->setName('app:install')
@@ -70,32 +80,24 @@ protected function execute(InputInterface $input, OutputInterface $output): int
7080
$appId = $input->getArgument('app-id');
7181
$forceEnable = (bool) $input->getOption('force');
7282

73-
if (\OC_App::getAppPath($appId)) {
83+
if ($this->appManager->isInstalled($appId)) {
7484
$output->writeln($appId . ' already installed');
7585
return 1;
7686
}
7787

7888
try {
79-
/** @var Installer $installer */
80-
$installer = \OC::$server->query(Installer::class);
81-
$installer->downloadApp($appId, $input->getOption('allow-unstable'));
82-
$result = $installer->installApp($appId, $forceEnable);
89+
$this->installer->downloadApp($appId, $input->getOption('allow-unstable'));
90+
$result = $this->installer->installApp($appId, $forceEnable);
8391
} catch (\Exception $e) {
8492
$output->writeln('Error: ' . $e->getMessage());
8593
return 1;
8694
}
8795

88-
if ($result === false) {
89-
$output->writeln($appId . ' couldn\'t be installed');
90-
return 1;
91-
}
92-
93-
$appVersion = \OCP\Server::get(IAppManager::class)->getAppVersion($appId);
96+
$appVersion = $this->appManager->getAppVersion($appId);
9497
$output->writeln($appId . ' ' . $appVersion . ' installed');
9598

9699
if (!$input->getOption('keep-disabled')) {
97-
$appClass = new \OC_App();
98-
$appClass->enable($appId);
100+
$this->appManager->enableApp($appId);
99101
$output->writeln($appId . ' enabled');
100102
}
101103

core/Command/App/Remove.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
<?php
2+
3+
declare(strict_types=1);
4+
25
/**
36
* @copyright Copyright (c) 2018, Patrik Kernstock <[email protected]>
47
*
@@ -68,7 +71,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
6871
$appId = $input->getArgument('app-id');
6972

7073
// Check if the app is installed
71-
if (!\OC_App::getAppPath($appId)) {
74+
if (!$this->manager->isInstalled($appId)) {
7275
$output->writeln($appId . ' is not installed');
7376
return 1;
7477
}
@@ -135,7 +138,7 @@ public function completeOptionValues($optionName, CompletionContext $context): a
135138
*/
136139
public function completeArgumentValues($argumentName, CompletionContext $context): array {
137140
if ($argumentName === 'app-id') {
138-
return \OC_App::getAllApps();
141+
return $this->manager->getInstalledApps();
139142
}
140143
return [];
141144
}

core/Command/App/Update.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
<?php
2+
3+
declare(strict_types=1);
4+
25
/**
36
* @copyright Copyright (c) 2018, michag86 ([email protected])
47
*
@@ -117,7 +120,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
117120
if ($result === false) {
118121
$output->writeln($appId . ' couldn\'t be updated');
119122
$return = 1;
120-
} elseif ($result === true) {
123+
} else {
121124
$output->writeln($appId . ' updated');
122125
}
123126
}

core/Command/L10n/CreateJs.php

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
<?php
2+
3+
declare(strict_types=1);
4+
25
/**
36
* @copyright Copyright (c) 2016, ownCloud, Inc.
47
*
@@ -26,6 +29,7 @@
2629

2730
use DirectoryIterator;
2831

32+
use OCP\App\IAppManager;
2933
use Stecman\Component\Symfony\Console\BashCompletion\Completion\CompletionAwareInterface;
3034
use Stecman\Component\Symfony\Console\BashCompletion\CompletionContext;
3135
use Symfony\Component\Console\Command\Command;
@@ -35,6 +39,12 @@
3539
use UnexpectedValueException;
3640

3741
class CreateJs extends Command implements CompletionAwareInterface {
42+
public function __construct(
43+
protected IAppManager $appManager,
44+
) {
45+
parent::__construct();
46+
}
47+
3848
protected function configure() {
3949
$this
4050
->setName('l10n:createjs')
@@ -55,11 +65,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
5565
$app = $input->getArgument('app');
5666
$lang = $input->getArgument('lang');
5767

58-
$path = \OC_App::getAppPath($app);
59-
if ($path === false) {
60-
$output->writeln("The app <$app> is unknown.");
61-
return 1;
62-
}
68+
$path = $this->appManager->getAppPath($app);
6369
$languages = $lang;
6470
if (empty($lang)) {
6571
$languages = $this->getAllLanguages($path);

lib/autoloader.php

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
*/
3737
namespace OC;
3838

39+
use OCP\App\AppPathNotFoundException;
40+
use OCP\App\IAppManager;
3941
use OCP\AutoloadNotAllowedException;
4042
use OCP\ICache;
4143
use Psr\Log\LoggerInterface;
@@ -113,11 +115,15 @@ public function findClass(string $class): array {
113115
} elseif (strpos($class, 'OCA\\') === 0) {
114116
[, $app, $rest] = explode('\\', $class, 3);
115117
$app = strtolower($app);
116-
$appPath = \OC_App::getAppPath($app);
117-
if ($appPath && stream_resolve_include_path($appPath)) {
118-
$paths[] = $appPath . '/' . strtolower(str_replace('\\', '/', $rest) . '.php');
119-
// If not found in the root of the app directory, insert '/lib' after app id and try again.
120-
$paths[] = $appPath . '/lib/' . strtolower(str_replace('\\', '/', $rest) . '.php');
118+
try {
119+
$appPath = \OCP\Server::get(IAppManager::class)->getAppPath($app);
120+
if (stream_resolve_include_path($appPath)) {
121+
$paths[] = $appPath . '/' . strtolower(str_replace('\\', '/', $rest) . '.php');
122+
// If not found in the root of the app directory, insert '/lib' after app id and try again.
123+
$paths[] = $appPath . '/lib/' . strtolower(str_replace('\\', '/', $rest) . '.php');
124+
}
125+
} catch (AppPathNotFoundException) {
126+
// App not found, ignore
121127
}
122128
} elseif ($class === 'Test\\TestCase') {
123129
// This File is considered public API, so we make sure that the class

lib/private/App/AppManager.php

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -97,15 +97,20 @@ class AppManager implements IAppManager {
9797
/** @var array<string, true> */
9898
private array $loadedApps = [];
9999

100+
private ?AppConfig $appConfig = null;
101+
private ?IURLGenerator $urlGenerator = null;
102+
103+
/**
104+
* Be extremely careful when injecting classes here. The AppManager is used by the installer,
105+
* so it needs to work before installation. See how AppConfig and IURLGenerator are injected for reference
106+
*/
100107
public function __construct(
101108
private IUserSession $userSession,
102109
private IConfig $config,
103-
private AppConfig $appConfig,
104110
private IGroupManager $groupManager,
105111
private ICacheFactory $memCacheFactory,
106112
private IEventDispatcher $dispatcher,
107113
private LoggerInterface $logger,
108-
private IURLGenerator $urlGenerator,
109114
) {
110115
}
111116

@@ -114,7 +119,7 @@ public function getAppIcon(string $appId, bool $dark = false): ?string {
114119
$icon = null;
115120
foreach ($possibleIcons as $iconName) {
116121
try {
117-
$icon = $this->urlGenerator->imagePath($appId, $iconName);
122+
$icon = $this->getUrlGenerator()->imagePath($appId, $iconName);
118123
break;
119124
} catch (\RuntimeException $e) {
120125
// ignore
@@ -123,12 +128,34 @@ public function getAppIcon(string $appId, bool $dark = false): ?string {
123128
return $icon;
124129
}
125130

131+
private function getAppConfig(): AppConfig {
132+
if ($this->appConfig !== null) {
133+
return $this->appConfig;
134+
}
135+
if (!$this->config->getSystemValueBool('installed', false)) {
136+
throw new \Exception('Nextcloud is not installed yet, AppConfig is not available');
137+
}
138+
$this->appConfig = \OCP\Server::get(AppConfig::class);
139+
return $this->appConfig;
140+
}
141+
142+
private function getUrlGenerator(): IURLGenerator {
143+
if ($this->urlGenerator !== null) {
144+
return $this->urlGenerator;
145+
}
146+
if (!$this->config->getSystemValueBool('installed', false)) {
147+
throw new \Exception('Nextcloud is not installed yet, AppConfig is not available');
148+
}
149+
$this->urlGenerator = \OCP\Server::get(IURLGenerator::class);
150+
return $this->urlGenerator;
151+
}
152+
126153
/**
127154
* @return string[] $appId => $enabled
128155
*/
129156
private function getInstalledAppsValues(): array {
130157
if (!$this->installedAppsCache) {
131-
$values = $this->appConfig->getValues(false, 'enabled');
158+
$values = $this->getAppConfig()->getValues(false, 'enabled');
132159

133160
$alwaysEnabledApps = $this->getAlwaysEnabledApps();
134161
foreach ($alwaysEnabledApps as $appId) {
@@ -253,7 +280,7 @@ public function isType(string $app, array $types): bool {
253280
private function getAppTypes(string $app): array {
254281
//load the cache
255282
if (count($this->appTypes) === 0) {
256-
$this->appTypes = $this->appConfig->getValues(false, 'types') ?: [];
283+
$this->appTypes = $this->getAppConfig()->getValues(false, 'types') ?: [];
257284
}
258285

259286
if (isset($this->appTypes[$app])) {
@@ -541,7 +568,7 @@ public function enableApp(string $appId, bool $forceEnable = false): void {
541568
}
542569

543570
$this->installedAppsCache[$appId] = 'yes';
544-
$this->appConfig->setValue($appId, 'enabled', 'yes');
571+
$this->getAppConfig()->setValue($appId, 'enabled', 'yes');
545572
$this->dispatcher->dispatchTyped(new AppEnableEvent($appId));
546573
$this->dispatcher->dispatch(ManagerEvent::EVENT_APP_ENABLE, new ManagerEvent(
547574
ManagerEvent::EVENT_APP_ENABLE, $appId
@@ -595,7 +622,7 @@ public function enableAppForGroups(string $appId, array $groups, bool $forceEnab
595622
}, $groups);
596623

597624
$this->installedAppsCache[$appId] = json_encode($groupIds);
598-
$this->appConfig->setValue($appId, 'enabled', json_encode($groupIds));
625+
$this->getAppConfig()->setValue($appId, 'enabled', json_encode($groupIds));
599626
$this->dispatcher->dispatchTyped(new AppEnableEvent($appId, $groupIds));
600627
$this->dispatcher->dispatch(ManagerEvent::EVENT_APP_ENABLE_FOR_GROUPS, new ManagerEvent(
601628
ManagerEvent::EVENT_APP_ENABLE_FOR_GROUPS, $appId, $groups
@@ -616,15 +643,15 @@ public function disableApp($appId, $automaticDisabled = false) {
616643
}
617644

618645
if ($automaticDisabled) {
619-
$previousSetting = $this->appConfig->getValue($appId, 'enabled', 'yes');
646+
$previousSetting = $this->getAppConfig()->getValue($appId, 'enabled', 'yes');
620647
if ($previousSetting !== 'yes' && $previousSetting !== 'no') {
621648
$previousSetting = json_decode($previousSetting, true);
622649
}
623650
$this->autoDisabledApps[$appId] = $previousSetting;
624651
}
625652

626653
unset($this->installedAppsCache[$appId]);
627-
$this->appConfig->setValue($appId, 'enabled', 'no');
654+
$this->getAppConfig()->setValue($appId, 'enabled', 'no');
628655

629656
// run uninstall steps
630657
$appData = $this->getAppInfo($appId);
@@ -689,7 +716,7 @@ public function getAppsNeedingUpgrade($version) {
689716
$apps = $this->getInstalledApps();
690717
foreach ($apps as $appId) {
691718
$appInfo = $this->getAppInfo($appId);
692-
$appDbVersion = $this->appConfig->getValue($appId, 'installed_version');
719+
$appDbVersion = $this->getAppConfig()->getValue($appId, 'installed_version');
693720
if ($appDbVersion
694721
&& isset($appInfo['version'])
695722
&& version_compare($appInfo['version'], $appDbVersion, '>')

0 commit comments

Comments
 (0)