Skip to content
2 changes: 1 addition & 1 deletion apps/settings/lib/Controller/AppSettingsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ private function getAppsForCategory($requestedCategory = ''): array {
try {
$this->appManager->getAppPath($app['id']);
$existsLocally = true;
} catch (AppPathNotFoundException $e) {
} catch (AppPathNotFoundException) {
$existsLocally = false;
}

Expand Down
13 changes: 5 additions & 8 deletions console.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
<?php

declare(strict_types=1);

/**
* @copyright Copyright (c) 2016, ownCloud, Inc.
*
Expand Down Expand Up @@ -57,7 +60,7 @@ function exceptionHandler($exception) {
exit(1);
}

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

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

$application = new Application(
$config,
\OC::$server->get(\OCP\EventDispatcher\IEventDispatcher::class),
\OC::$server->getRequest(),
\OC::$server->get(\Psr\Log\LoggerInterface::class),
\OC::$server->query(\OC\MemoryInfo::class)
);
$application = \OCP\Server::get(Application::class);
$application->loadCommands(new ArgvInput(), new ConsoleOutput());
$application->run();
} catch (Exception $ex) {
Expand Down
3 changes: 3 additions & 0 deletions core/Command/App/Enable.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
<?php

declare(strict_types=1);

/**
* @copyright Copyright (c) 2016, ownCloud, Inc.
*
Expand Down
25 changes: 18 additions & 7 deletions core/Command/App/GetPath.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
<?php

declare(strict_types=1);

/**
* @copyright Copyright (c) 2016, ownCloud, Inc.
*
Expand All @@ -23,12 +26,20 @@
namespace OC\Core\Command\App;

use OC\Core\Command\Base;
use OCP\App\AppPathNotFoundException;
use OCP\App\IAppManager;
use Stecman\Component\Symfony\Console\BashCompletion\CompletionContext;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class GetPath extends Base {
public function __construct(
protected IAppManager $appManager,
) {
parent::__construct();
}

protected function configure(): void {
parent::configure();

Expand All @@ -52,14 +63,14 @@ protected function configure(): void {
*/
protected function execute(InputInterface $input, OutputInterface $output): int {
$appName = $input->getArgument('app');
$path = \OC_App::getAppPath($appName);
if ($path !== false) {
$output->writeln($path);
return 0;
try {
$path = $this->appManager->getAppPath($appName);
} catch (AppPathNotFoundException) {
// App not found, exit with non-zero
return self::FAILURE;
}

// App not found, exit with non-zero
return 1;
$output->writeln($path);
return self::SUCCESS;
}

/**
Expand Down
28 changes: 15 additions & 13 deletions core/Command/App/Install.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
<?php

declare(strict_types=1);

/**
* @copyright Copyright (c) 2016, ownCloud, Inc.
*
Expand Down Expand Up @@ -36,6 +39,13 @@
use Symfony\Component\Console\Output\OutputInterface;

class Install extends Command {
public function __construct(
protected IAppManager $appManager,
private Installer $installer,
) {
parent::__construct();
}

protected function configure(): void {
$this
->setName('app:install')
Expand Down Expand Up @@ -70,32 +80,24 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$appId = $input->getArgument('app-id');
$forceEnable = (bool) $input->getOption('force');

if (\OC_App::getAppPath($appId)) {
if ($this->appManager->isInstalled($appId)) {
$output->writeln($appId . ' already installed');
return 1;
}

try {
/** @var Installer $installer */
$installer = \OC::$server->query(Installer::class);
$installer->downloadApp($appId, $input->getOption('allow-unstable'));
$result = $installer->installApp($appId, $forceEnable);
$this->installer->downloadApp($appId, $input->getOption('allow-unstable'));
$result = $this->installer->installApp($appId, $forceEnable);
} catch (\Exception $e) {
$output->writeln('Error: ' . $e->getMessage());
return 1;
}

if ($result === false) {
$output->writeln($appId . ' couldn\'t be installed');
return 1;
}

$appVersion = \OCP\Server::get(IAppManager::class)->getAppVersion($appId);
$appVersion = $this->appManager->getAppVersion($appId);
$output->writeln($appId . ' ' . $appVersion . ' installed');

if (!$input->getOption('keep-disabled')) {
$appClass = new \OC_App();
$appClass->enable($appId);
$this->appManager->enableApp($appId);
$output->writeln($appId . ' enabled');
}

Expand Down
7 changes: 5 additions & 2 deletions core/Command/App/Remove.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
<?php

declare(strict_types=1);

/**
* @copyright Copyright (c) 2018, Patrik Kernstock <[email protected]>
*
Expand Down Expand Up @@ -68,7 +71,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$appId = $input->getArgument('app-id');

// Check if the app is installed
if (!\OC_App::getAppPath($appId)) {
if (!$this->manager->isInstalled($appId)) {
$output->writeln($appId . ' is not installed');
return 1;
}
Expand Down Expand Up @@ -135,7 +138,7 @@ public function completeOptionValues($optionName, CompletionContext $context): a
*/
public function completeArgumentValues($argumentName, CompletionContext $context): array {
if ($argumentName === 'app-id') {
return \OC_App::getAllApps();
return $this->manager->getInstalledApps();
}
return [];
}
Expand Down
5 changes: 4 additions & 1 deletion core/Command/App/Update.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
<?php

declare(strict_types=1);

/**
* @copyright Copyright (c) 2018, michag86 ([email protected])
*
Expand Down Expand Up @@ -117,7 +120,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
if ($result === false) {
$output->writeln($appId . ' couldn\'t be updated');
$return = 1;
} elseif ($result === true) {
} else {
$output->writeln($appId . ' updated');
}
}
Expand Down
16 changes: 11 additions & 5 deletions core/Command/L10n/CreateJs.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
<?php

declare(strict_types=1);

/**
* @copyright Copyright (c) 2016, ownCloud, Inc.
*
Expand Down Expand Up @@ -26,6 +29,7 @@

use DirectoryIterator;

use OCP\App\IAppManager;
use Stecman\Component\Symfony\Console\BashCompletion\Completion\CompletionAwareInterface;
use Stecman\Component\Symfony\Console\BashCompletion\CompletionContext;
use Symfony\Component\Console\Command\Command;
Expand All @@ -35,6 +39,12 @@
use UnexpectedValueException;

class CreateJs extends Command implements CompletionAwareInterface {
public function __construct(
protected IAppManager $appManager,
) {
parent::__construct();
}

protected function configure() {
$this
->setName('l10n:createjs')
Expand All @@ -55,11 +65,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$app = $input->getArgument('app');
$lang = $input->getArgument('lang');

$path = \OC_App::getAppPath($app);
if ($path === false) {
$output->writeln("The app <$app> is unknown.");
return 1;
}
$path = $this->appManager->getAppPath($app);
$languages = $lang;
if (empty($lang)) {
$languages = $this->getAllLanguages($path);
Expand Down
16 changes: 11 additions & 5 deletions lib/autoloader.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
*/
namespace OC;

use OCP\App\AppPathNotFoundException;
use OCP\App\IAppManager;
use OCP\AutoloadNotAllowedException;
use OCP\ICache;
use Psr\Log\LoggerInterface;
Expand Down Expand Up @@ -113,11 +115,15 @@ public function findClass(string $class): array {
} elseif (strpos($class, 'OCA\\') === 0) {
[, $app, $rest] = explode('\\', $class, 3);
$app = strtolower($app);
$appPath = \OC_App::getAppPath($app);
if ($appPath && stream_resolve_include_path($appPath)) {
$paths[] = $appPath . '/' . strtolower(str_replace('\\', '/', $rest) . '.php');
// If not found in the root of the app directory, insert '/lib' after app id and try again.
$paths[] = $appPath . '/lib/' . strtolower(str_replace('\\', '/', $rest) . '.php');
try {
$appPath = \OCP\Server::get(IAppManager::class)->getAppPath($app);
if (stream_resolve_include_path($appPath)) {
$paths[] = $appPath . '/' . strtolower(str_replace('\\', '/', $rest) . '.php');
// If not found in the root of the app directory, insert '/lib' after app id and try again.
$paths[] = $appPath . '/lib/' . strtolower(str_replace('\\', '/', $rest) . '.php');
}
} catch (AppPathNotFoundException) {
// App not found, ignore
}
} elseif ($class === 'Test\\TestCase') {
// This File is considered public API, so we make sure that the class
Expand Down
47 changes: 37 additions & 10 deletions lib/private/App/AppManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,15 +97,20 @@ class AppManager implements IAppManager {
/** @var array<string, true> */
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 AppConfig $appConfig,
private IGroupManager $groupManager,
private ICacheFactory $memCacheFactory,
private IEventDispatcher $dispatcher,
private LoggerInterface $logger,
private IURLGenerator $urlGenerator,
) {
}

Expand All @@ -114,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 @@ -123,12 +128,34 @@ public function getAppIcon(string $appId, bool $dark = false): ?string {
return $icon;
}

private function getAppConfig(): AppConfig {
if ($this->appConfig !== null) {
return $this->appConfig;
}
if (!$this->config->getSystemValueBool('installed', false)) {
throw new \Exception('Nextcloud is not installed yet, AppConfig is not available');
}
$this->appConfig = \OCP\Server::get(AppConfig::class);
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
*/
private function getInstalledAppsValues(): array {
if (!$this->installedAppsCache) {
$values = $this->appConfig->getValues(false, 'enabled');
$values = $this->getAppConfig()->getValues(false, 'enabled');

Check notice

Code scanning / Psalm

DeprecatedMethod

The method OC\AppConfig::getValues has been marked as deprecated

$alwaysEnabledApps = $this->getAlwaysEnabledApps();
foreach ($alwaysEnabledApps as $appId) {
Expand Down Expand Up @@ -253,7 +280,7 @@ public function isType(string $app, array $types): bool {
private function getAppTypes(string $app): array {
//load the cache
if (count($this->appTypes) === 0) {
$this->appTypes = $this->appConfig->getValues(false, 'types') ?: [];
$this->appTypes = $this->getAppConfig()->getValues(false, 'types') ?: [];

Check notice

Code scanning / Psalm

DeprecatedMethod

The method OC\AppConfig::getValues has been marked as deprecated
}

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

$this->installedAppsCache[$appId] = 'yes';
$this->appConfig->setValue($appId, 'enabled', 'yes');
$this->getAppConfig()->setValue($appId, 'enabled', 'yes');

Check notice

Code scanning / Psalm

DeprecatedMethod

The method OC\AppConfig::setValue has been marked as deprecated
$this->dispatcher->dispatchTyped(new AppEnableEvent($appId));
$this->dispatcher->dispatch(ManagerEvent::EVENT_APP_ENABLE, new ManagerEvent(
ManagerEvent::EVENT_APP_ENABLE, $appId
Expand Down Expand Up @@ -595,7 +622,7 @@ public function enableAppForGroups(string $appId, array $groups, bool $forceEnab
}, $groups);

$this->installedAppsCache[$appId] = json_encode($groupIds);
$this->appConfig->setValue($appId, 'enabled', json_encode($groupIds));
$this->getAppConfig()->setValue($appId, 'enabled', json_encode($groupIds));

Check notice

Code scanning / Psalm

DeprecatedMethod

The method OC\AppConfig::setValue has been marked as deprecated
$this->dispatcher->dispatchTyped(new AppEnableEvent($appId, $groupIds));
$this->dispatcher->dispatch(ManagerEvent::EVENT_APP_ENABLE_FOR_GROUPS, new ManagerEvent(
ManagerEvent::EVENT_APP_ENABLE_FOR_GROUPS, $appId, $groups
Expand All @@ -616,15 +643,15 @@ public function disableApp($appId, $automaticDisabled = false) {
}

if ($automaticDisabled) {
$previousSetting = $this->appConfig->getValue($appId, 'enabled', 'yes');
$previousSetting = $this->getAppConfig()->getValue($appId, 'enabled', 'yes');

Check notice

Code scanning / Psalm

DeprecatedMethod

The method OC\AppConfig::getValue has been marked as deprecated
if ($previousSetting !== 'yes' && $previousSetting !== 'no') {
$previousSetting = json_decode($previousSetting, true);
}
$this->autoDisabledApps[$appId] = $previousSetting;
}

unset($this->installedAppsCache[$appId]);
$this->appConfig->setValue($appId, 'enabled', 'no');
$this->getAppConfig()->setValue($appId, 'enabled', 'no');

Check notice

Code scanning / Psalm

DeprecatedMethod

The method OC\AppConfig::setValue has been marked as deprecated

// run uninstall steps
$appData = $this->getAppInfo($appId);
Expand Down Expand Up @@ -689,7 +716,7 @@ public function getAppsNeedingUpgrade($version) {
$apps = $this->getInstalledApps();
foreach ($apps as $appId) {
$appInfo = $this->getAppInfo($appId);
$appDbVersion = $this->appConfig->getValue($appId, 'installed_version');
$appDbVersion = $this->getAppConfig()->getValue($appId, 'installed_version');

Check notice

Code scanning / Psalm

DeprecatedMethod

The method OC\AppConfig::getValue has been marked as deprecated
if ($appDbVersion
&& isset($appInfo['version'])
&& version_compare($appInfo['version'], $appDbVersion, '>')
Expand Down
Loading