aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCôme Chilliet <91878298+come-nc@users.noreply.github.com>2024-04-22 16:41:15 +0200
committerGitHub <noreply@github.com>2024-04-22 16:41:15 +0200
commit37c89f41918b316c8ba2961a6c7e8ab417161ba9 (patch)
tree46c8d58ba84f8a18dd2a8c37fc3bba3222307133
parentdeac58ab7ee75e0081dd76af3f756ae4c218d207 (diff)
parentac1d868d18074752029a9f4fdeda6614daa62010 (diff)
downloadnextcloud-server-37c89f41918b316c8ba2961a6c7e8ab417161ba9.tar.gz
nextcloud-server-37c89f41918b316c8ba2961a6c7e8ab417161ba9.zip
Merge pull request #44025 from nextcloud/fix/remove-oc-app-calls
Migrate away from OC_App and toward IAppManager.
-rw-r--r--apps/settings/lib/Controller/AppSettingsController.php2
-rw-r--r--console.php13
-rw-r--r--core/Command/App/Enable.php3
-rw-r--r--core/Command/App/GetPath.php25
-rw-r--r--core/Command/App/Install.php28
-rw-r--r--core/Command/App/Remove.php7
-rw-r--r--core/Command/App/Update.php5
-rw-r--r--core/Command/L10n/CreateJs.php16
-rw-r--r--lib/autoloader.php16
-rw-r--r--lib/private/App/AppManager.php47
-rw-r--r--lib/private/AppFramework/Bootstrap/Coordinator.php46
-rw-r--r--lib/private/Console/Application.php37
-rw-r--r--lib/private/Installer.php7
-rw-r--r--lib/private/L10N/Factory.php50
-rw-r--r--lib/private/Route/CachingRouter.php6
-rw-r--r--lib/private/Route/Router.php25
-rw-r--r--lib/private/Server.php5
-rw-r--r--lib/private/legacy/OC_App.php2
-rw-r--r--tests/lib/App/AppManagerTest.php24
-rw-r--r--tests/lib/AppFramework/Bootstrap/CoordinatorTest.php3
-rw-r--r--tests/lib/AppFramework/Routing/RoutingTest.php19
-rw-r--r--tests/lib/AppTest.php1
-rw-r--r--tests/lib/L10N/FactoryTest.php39
-rw-r--r--tests/lib/L10N/L10nTest.php4
-rw-r--r--tests/lib/Route/RouterTest.php2
25 files changed, 239 insertions, 193 deletions
diff --git a/apps/settings/lib/Controller/AppSettingsController.php b/apps/settings/lib/Controller/AppSettingsController.php
index 9dfe4772b93..2d6697c7d29 100644
--- a/apps/settings/lib/Controller/AppSettingsController.php
+++ b/apps/settings/lib/Controller/AppSettingsController.php
@@ -402,7 +402,7 @@ class AppSettingsController extends Controller {
try {
$this->appManager->getAppPath($app['id']);
$existsLocally = true;
- } catch (AppPathNotFoundException $e) {
+ } catch (AppPathNotFoundException) {
$existsLocally = false;
}
diff --git a/console.php b/console.php
index 68647a874c4..6bfbf964d94 100644
--- a/console.php
+++ b/console.php
@@ -1,4 +1,7 @@
<?php
+
+declare(strict_types=1);
+
/**
* @copyright Copyright (c) 2016, ownCloud, Inc.
*
@@ -57,7 +60,7 @@ try {
exit(1);
}
- $config = \OC::$server->getConfig();
+ $config = \OCP\Server::get(\OCP\IConfig::class);
set_exception_handler('exceptionHandler');
if (!function_exists('posix_getuid')) {
@@ -102,13 +105,7 @@ try {
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) {
diff --git a/core/Command/App/Enable.php b/core/Command/App/Enable.php
index ed29f2fed92..579432a1dd0 100644
--- a/core/Command/App/Enable.php
+++ b/core/Command/App/Enable.php
@@ -1,4 +1,7 @@
<?php
+
+declare(strict_types=1);
+
/**
* @copyright Copyright (c) 2016, ownCloud, Inc.
*
diff --git a/core/Command/App/GetPath.php b/core/Command/App/GetPath.php
index ea614070e7d..d5433253dd9 100644
--- a/core/Command/App/GetPath.php
+++ b/core/Command/App/GetPath.php
@@ -1,4 +1,7 @@
<?php
+
+declare(strict_types=1);
+
/**
* @copyright Copyright (c) 2016, ownCloud, Inc.
*
@@ -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();
@@ -52,14 +63,14 @@ class GetPath extends Base {
*/
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;
}
/**
diff --git a/core/Command/App/Install.php b/core/Command/App/Install.php
index 2d02fff4dbf..a5657e8397d 100644
--- a/core/Command/App/Install.php
+++ b/core/Command/App/Install.php
@@ -1,4 +1,7 @@
<?php
+
+declare(strict_types=1);
+
/**
* @copyright Copyright (c) 2016, ownCloud, Inc.
*
@@ -36,6 +39,13 @@ use Symfony\Component\Console\Input\InputOption;
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')
@@ -70,32 +80,24 @@ class Install extends Command {
$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');
}
diff --git a/core/Command/App/Remove.php b/core/Command/App/Remove.php
index 5fa05079bd8..388f5603fe7 100644
--- a/core/Command/App/Remove.php
+++ b/core/Command/App/Remove.php
@@ -1,4 +1,7 @@
<?php
+
+declare(strict_types=1);
+
/**
* @copyright Copyright (c) 2018, Patrik Kernstock <info@pkern.at>
*
@@ -68,7 +71,7 @@ class Remove extends Command implements CompletionAwareInterface {
$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;
}
@@ -135,7 +138,7 @@ class Remove extends Command implements CompletionAwareInterface {
*/
public function completeArgumentValues($argumentName, CompletionContext $context): array {
if ($argumentName === 'app-id') {
- return \OC_App::getAllApps();
+ return $this->manager->getInstalledApps();
}
return [];
}
diff --git a/core/Command/App/Update.php b/core/Command/App/Update.php
index c8e62cb5b71..c2e24bf94b7 100644
--- a/core/Command/App/Update.php
+++ b/core/Command/App/Update.php
@@ -1,4 +1,7 @@
<?php
+
+declare(strict_types=1);
+
/**
* @copyright Copyright (c) 2018, michag86 (michag86@arcor.de)
*
@@ -117,7 +120,7 @@ class Update extends Command {
if ($result === false) {
$output->writeln($appId . ' couldn\'t be updated');
$return = 1;
- } elseif ($result === true) {
+ } else {
$output->writeln($appId . ' updated');
}
}
diff --git a/core/Command/L10n/CreateJs.php b/core/Command/L10n/CreateJs.php
index 6472e7aec1c..724e94f28d5 100644
--- a/core/Command/L10n/CreateJs.php
+++ b/core/Command/L10n/CreateJs.php
@@ -1,4 +1,7 @@
<?php
+
+declare(strict_types=1);
+
/**
* @copyright Copyright (c) 2016, ownCloud, Inc.
*
@@ -26,6 +29,7 @@ namespace OC\Core\Command\L10n;
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;
@@ -35,6 +39,12 @@ use Symfony\Component\Console\Output\OutputInterface;
use UnexpectedValueException;
class CreateJs extends Command implements CompletionAwareInterface {
+ public function __construct(
+ protected IAppManager $appManager,
+ ) {
+ parent::__construct();
+ }
+
protected function configure() {
$this
->setName('l10n:createjs')
@@ -55,11 +65,7 @@ class CreateJs extends Command implements CompletionAwareInterface {
$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);
diff --git a/lib/autoloader.php b/lib/autoloader.php
index 0f8a2ad9687..773813a32cf 100644
--- a/lib/autoloader.php
+++ b/lib/autoloader.php
@@ -36,6 +36,8 @@ declare(strict_types=1);
*/
namespace OC;
+use OCP\App\AppPathNotFoundException;
+use OCP\App\IAppManager;
use OCP\AutoloadNotAllowedException;
use OCP\ICache;
use Psr\Log\LoggerInterface;
@@ -113,11 +115,15 @@ class Autoloader {
} 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
diff --git a/lib/private/App/AppManager.php b/lib/private/App/AppManager.php
index c6e6ba2975e..3867dcc509e 100644
--- a/lib/private/App/AppManager.php
+++ b/lib/private/App/AppManager.php
@@ -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,
) {
}
@@ -114,7 +119,7 @@ class AppManager implements IAppManager {
$icon = null;
foreach ($possibleIcons as $iconName) {
try {
- $icon = $this->urlGenerator->imagePath($appId, $iconName);
+ $icon = $this->getUrlGenerator()->imagePath($appId, $iconName);
break;
} catch (\RuntimeException $e) {
// ignore
@@ -123,12 +128,34 @@ class AppManager implements IAppManager {
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');
$alwaysEnabledApps = $this->getAlwaysEnabledApps();
foreach ($alwaysEnabledApps as $appId) {
@@ -253,7 +280,7 @@ class AppManager implements IAppManager {
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') ?: [];
}
if (isset($this->appTypes[$app])) {
@@ -541,7 +568,7 @@ class AppManager implements IAppManager {
}
$this->installedAppsCache[$appId] = 'yes';
- $this->appConfig->setValue($appId, 'enabled', 'yes');
+ $this->getAppConfig()->setValue($appId, 'enabled', 'yes');
$this->dispatcher->dispatchTyped(new AppEnableEvent($appId));
$this->dispatcher->dispatch(ManagerEvent::EVENT_APP_ENABLE, new ManagerEvent(
ManagerEvent::EVENT_APP_ENABLE, $appId
@@ -595,7 +622,7 @@ class AppManager implements IAppManager {
}, $groups);
$this->installedAppsCache[$appId] = json_encode($groupIds);
- $this->appConfig->setValue($appId, 'enabled', json_encode($groupIds));
+ $this->getAppConfig()->setValue($appId, 'enabled', json_encode($groupIds));
$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
@@ -616,7 +643,7 @@ class AppManager implements IAppManager {
}
if ($automaticDisabled) {
- $previousSetting = $this->appConfig->getValue($appId, 'enabled', 'yes');
+ $previousSetting = $this->getAppConfig()->getValue($appId, 'enabled', 'yes');
if ($previousSetting !== 'yes' && $previousSetting !== 'no') {
$previousSetting = json_decode($previousSetting, true);
}
@@ -624,7 +651,7 @@ class AppManager implements IAppManager {
}
unset($this->installedAppsCache[$appId]);
- $this->appConfig->setValue($appId, 'enabled', 'no');
+ $this->getAppConfig()->setValue($appId, 'enabled', 'no');
// run uninstall steps
$appData = $this->getAppInfo($appId);
@@ -689,7 +716,7 @@ class AppManager implements IAppManager {
$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');
if ($appDbVersion
&& isset($appInfo['version'])
&& version_compare($appInfo['version'], $appDbVersion, '>')
diff --git a/lib/private/AppFramework/Bootstrap/Coordinator.php b/lib/private/AppFramework/Bootstrap/Coordinator.php
index 8526a3dc1a1..6c49e7dd943 100644
--- a/lib/private/AppFramework/Bootstrap/Coordinator.php
+++ b/lib/private/AppFramework/Bootstrap/Coordinator.php
@@ -32,6 +32,8 @@ namespace OC\AppFramework\Bootstrap;
use OC\Support\CrashReport\Registry;
use OC_App;
+use OCP\App\AppPathNotFoundException;
+use OCP\App\IAppManager;
use OCP\AppFramework\App;
use OCP\AppFramework\Bootstrap\IBootstrap;
use OCP\AppFramework\QueryException;
@@ -46,24 +48,6 @@ use function class_implements;
use function in_array;
class Coordinator {
- /** @var IServerContainer */
- private $serverContainer;
-
- /** @var Registry */
- private $registry;
-
- /** @var IManager */
- private $dashboardManager;
-
- /** @var IEventDispatcher */
- private $eventDispatcher;
-
- /** @var IEventLogger */
- private $eventLogger;
-
- /** @var LoggerInterface */
- private $logger;
-
/** @var RegistrationContext|null */
private $registrationContext;
@@ -71,19 +55,14 @@ class Coordinator {
private $bootedApps = [];
public function __construct(
- IServerContainer $container,
- Registry $registry,
- IManager $dashboardManager,
- IEventDispatcher $eventListener,
- IEventLogger $eventLogger,
- LoggerInterface $logger
+ private IServerContainer $serverContainer,
+ private Registry $registry,
+ private IManager $dashboardManager,
+ private IEventDispatcher $eventDispatcher,
+ private IEventLogger $eventLogger,
+ private IAppManager $appManager,
+ private LoggerInterface $logger,
) {
- $this->serverContainer = $container;
- $this->registry = $registry;
- $this->dashboardManager = $dashboardManager;
- $this->eventDispatcher = $eventListener;
- $this->eventLogger = $eventLogger;
- $this->logger = $logger;
}
public function runInitialRegistration(): void {
@@ -108,11 +87,10 @@ class Coordinator {
$this->eventLogger->start("bootstrap:register_app:$appId:autoloader", "Setup autoloader for $appId");
/*
* First, we have to enable the app's autoloader
- *
- * @todo use $this->appManager->getAppPath($appId) here
*/
- $path = OC_App::getAppPath($appId);
- if ($path === false) {
+ try {
+ $path = $this->appManager->getAppPath($appId);
+ } catch (AppPathNotFoundException) {
// Ignore
continue;
}
diff --git a/lib/private/Console/Application.php b/lib/private/Console/Application.php
index ec8d5900f36..ae8d7c2a33c 100644
--- a/lib/private/Console/Application.php
+++ b/lib/private/Console/Application.php
@@ -32,7 +32,7 @@ namespace OC\Console;
use OC\MemoryInfo;
use OC\NeedsUpdateException;
-use OC_App;
+use OCP\App\AppPathNotFoundException;
use OCP\App\IAppManager;
use OCP\Console\ConsoleEvent;
use OCP\EventDispatcher\IEventDispatcher;
@@ -47,25 +47,18 @@ use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class Application {
- private IConfig $config;
private SymfonyApplication $application;
- private IEventDispatcher $dispatcher;
- private IRequest $request;
- private LoggerInterface $logger;
- private MemoryInfo $memoryInfo;
- public function __construct(IConfig $config,
- IEventDispatcher $dispatcher,
- IRequest $request,
- LoggerInterface $logger,
- MemoryInfo $memoryInfo) {
+ public function __construct(
+ private IConfig $config,
+ private IEventDispatcher $dispatcher,
+ private IRequest $request,
+ private LoggerInterface $logger,
+ private MemoryInfo $memoryInfo,
+ private IAppManager $appManager,
+ ) {
$defaults = \OC::$server->get('ThemingDefaults');
- $this->config = $config;
$this->application = new SymfonyApplication($defaults->getName(), \OC_Util::getVersionString());
- $this->dispatcher = $dispatcher;
- $this->request = $request;
- $this->logger = $logger;
- $this->memoryInfo = $memoryInfo;
}
/**
@@ -111,15 +104,15 @@ class Application {
} elseif ($this->config->getSystemValueBool('maintenance')) {
$this->writeMaintenanceModeInfo($input, $output);
} else {
- OC_App::loadApps();
- $appManager = \OCP\Server::get(IAppManager::class);
- foreach ($appManager->getInstalledApps() as $app) {
- $appPath = \OC_App::getAppPath($app);
- if ($appPath === false) {
+ $this->appManager->loadApps();
+ foreach ($this->appManager->getInstalledApps() as $app) {
+ try {
+ $appPath = $this->appManager->getAppPath($app);
+ } catch (AppPathNotFoundException) {
continue;
}
// load commands using info.xml
- $info = $appManager->getAppInfo($app);
+ $info = $this->appManager->getAppInfo($app);
if (isset($info['commands'])) {
try {
$this->loadCommandsFromInfoXml($info['commands']);
diff --git a/lib/private/Installer.php b/lib/private/Installer.php
index 6ab497b9dea..c4af480d4ca 100644
--- a/lib/private/Installer.php
+++ b/lib/private/Installer.php
@@ -560,12 +560,13 @@ class Installer {
if ($output instanceof IOutput) {
$output->debug('Installing ' . $app);
}
- //install the database
- $appPath = OC_App::getAppPath($app);
- \OC_App::registerAutoloading($app, $appPath);
+ $appManager = \OCP\Server::get(IAppManager::class);
$config = \OCP\Server::get(IConfig::class);
+ $appPath = $appManager->getAppPath($app);
+ \OC_App::registerAutoloading($app, $appPath);
+
$ms = new MigrationService($app, \OCP\Server::get(Connection::class));
if ($output instanceof IOutput) {
$ms->setOutput($output);
diff --git a/lib/private/L10N/Factory.php b/lib/private/L10N/Factory.php
index a9717b679ed..785915fc82b 100644
--- a/lib/private/L10N/Factory.php
+++ b/lib/private/L10N/Factory.php
@@ -40,6 +40,8 @@ declare(strict_types=1);
namespace OC\L10N;
+use OCP\App\AppPathNotFoundException;
+use OCP\App\IAppManager;
use OCP\ICache;
use OCP\ICacheFactory;
use OCP\IConfig;
@@ -88,38 +90,17 @@ class Factory implements IFactory {
'pt_BR', 'pt_PT', 'da', 'fi_FI', 'nb_NO', 'sv', 'tr', 'zh_CN', 'ko'
];
- /** @var IConfig */
- protected $config;
-
- /** @var IRequest */
- protected $request;
-
- /** @var IUserSession */
- protected IUserSession $userSession;
-
private ICache $cache;
- /** @var string */
- protected $serverRoot;
-
- /**
- * @param IConfig $config
- * @param IRequest $request
- * @param IUserSession $userSession
- * @param string $serverRoot
- */
public function __construct(
- IConfig $config,
- IRequest $request,
- IUserSession $userSession,
+ protected IConfig $config,
+ protected IRequest $request,
+ protected IUserSession $userSession,
ICacheFactory $cacheFactory,
- $serverRoot
+ protected string $serverRoot,
+ protected IAppManager $appManager,
) {
- $this->config = $config;
- $this->request = $request;
- $this->userSession = $userSession;
$this->cache = $cacheFactory->createLocal('L10NFactory');
- $this->serverRoot = $serverRoot;
}
/**
@@ -558,13 +539,9 @@ class Factory implements IFactory {
/**
* Get a list of language files that should be loaded
*
- * @param string $app
- * @param string $lang
* @return string[]
*/
- // FIXME This method is only public, until OC_L10N does not need it anymore,
- // FIXME This is also the reason, why it is not in the public interface
- public function getL10nFilesForApp($app, $lang) {
+ private function getL10nFilesForApp(string $app, string $lang): array {
$languageFiles = [];
$i18nDir = $this->findL10nDir($app);
@@ -572,7 +549,7 @@ class Factory implements IFactory {
if (($this->isSubDirectory($transFile, $this->serverRoot . '/core/l10n/')
|| $this->isSubDirectory($transFile, $this->serverRoot . '/lib/l10n/')
- || $this->isSubDirectory($transFile, \OC_App::getAppPath($app) . '/l10n/'))
+ || $this->isSubDirectory($transFile, $this->appManager->getAppPath($app) . '/l10n/'))
&& file_exists($transFile)
) {
// load the translations file
@@ -602,9 +579,12 @@ class Factory implements IFactory {
if (file_exists($this->serverRoot . '/' . $app . '/l10n/')) {
return $this->serverRoot . '/' . $app . '/l10n/';
}
- } elseif ($app && \OC_App::getAppPath($app) !== false) {
- // Check if the app is in the app folder
- return \OC_App::getAppPath($app) . '/l10n/';
+ } elseif ($app) {
+ try {
+ return $this->appManager->getAppPath($app) . '/l10n/';
+ } catch (AppPathNotFoundException) {
+ /* App not found, continue */
+ }
}
return $this->serverRoot . '/core/l10n/';
}
diff --git a/lib/private/Route/CachingRouter.php b/lib/private/Route/CachingRouter.php
index 69fb3c986c9..78f05b1f80a 100644
--- a/lib/private/Route/CachingRouter.php
+++ b/lib/private/Route/CachingRouter.php
@@ -24,6 +24,7 @@
*/
namespace OC\Route;
+use OCP\App\IAppManager;
use OCP\Diagnostics\IEventLogger;
use OCP\ICache;
use OCP\ICacheFactory;
@@ -41,10 +42,11 @@ class CachingRouter extends Router {
IRequest $request,
IConfig $config,
IEventLogger $eventLogger,
- ContainerInterface $container
+ ContainerInterface $container,
+ IAppManager $appManager,
) {
$this->cache = $cacheFactory->createLocal('route');
- parent::__construct($logger, $request, $config, $eventLogger, $container);
+ parent::__construct($logger, $request, $config, $eventLogger, $container, $appManager);
}
/**
diff --git a/lib/private/Route/Router.php b/lib/private/Route/Router.php
index 28a25b4addf..90a6d85d8b5 100644
--- a/lib/private/Route/Router.php
+++ b/lib/private/Route/Router.php
@@ -35,6 +35,8 @@ namespace OC\Route;
use DirectoryIterator;
use OC\AppFramework\Routing\RouteParser;
+use OCP\App\AppPathNotFoundException;
+use OCP\App\IAppManager;
use OCP\AppFramework\App;
use OCP\AppFramework\Http\Attribute\Route as RouteAttribute;
use OCP\Diagnostics\IEventLogger;
@@ -71,22 +73,17 @@ class Router implements IRouter {
protected $loaded = false;
/** @var array */
protected $loadedApps = [];
- protected LoggerInterface $logger;
/** @var RequestContext */
protected $context;
- private IEventLogger $eventLogger;
- private IConfig $config;
- private ContainerInterface $container;
public function __construct(
- LoggerInterface $logger,
+ protected LoggerInterface $logger,
IRequest $request,
- IConfig $config,
- IEventLogger $eventLogger,
- ContainerInterface $container
+ private IConfig $config,
+ private IEventLogger $eventLogger,
+ private ContainerInterface $container,
+ private IAppManager $appManager,
) {
- $this->logger = $logger;
- $this->config = $config;
$baseUrl = \OC::$WEBROOT;
if (!($config->getSystemValue('htaccess.IgnoreFrontController', false) === true || getenv('front_controller_active') === 'true')) {
$baseUrl .= '/index.php';
@@ -101,8 +98,6 @@ class Router implements IRouter {
$this->context = new RequestContext($baseUrl, $method, $host, $schema);
// TODO cache
$this->root = $this->getCollection('root');
- $this->eventLogger = $eventLogger;
- $this->container = $container;
}
/**
@@ -114,12 +109,14 @@ class Router implements IRouter {
if ($this->routingFiles === null) {
$this->routingFiles = [];
foreach (\OC_APP::getEnabledApps() as $app) {
- $appPath = \OC_App::getAppPath($app);
- if ($appPath !== false) {
+ try {
+ $appPath = $this->appManager->getAppPath($app);
$file = $appPath . '/appinfo/routes.php';
if (file_exists($file)) {
$this->routingFiles[$app] = $file;
}
+ } catch (AppPathNotFoundException) {
+ /* ignore */
}
}
}
diff --git a/lib/private/Server.php b/lib/private/Server.php
index 5d897c322d5..21d60d55829 100644
--- a/lib/private/Server.php
+++ b/lib/private/Server.php
@@ -653,7 +653,8 @@ class Server extends ServerContainer implements IServerContainer {
$c->getRequest(),
$c->get(IUserSession::class),
$c->get(ICacheFactory::class),
- \OC::$SERVERROOT
+ \OC::$SERVERROOT,
+ $c->get(IAppManager::class),
);
});
/** @deprecated 19.0.0 */
@@ -892,12 +893,10 @@ class Server extends ServerContainer implements IServerContainer {
return new \OC\App\AppManager(
$c->get(IUserSession::class),
$c->get(\OCP\IConfig::class),
- $c->get(\OC\AppConfig::class),
$c->get(IGroupManager::class),
$c->get(ICacheFactory::class),
$c->get(IEventDispatcher::class),
$c->get(LoggerInterface::class),
- $c->get(IURLGenerator::class),
);
});
/** @deprecated 19.0.0 */
diff --git a/lib/private/legacy/OC_App.php b/lib/private/legacy/OC_App.php
index c652fcfb9ba..ea79cc3ea76 100644
--- a/lib/private/legacy/OC_App.php
+++ b/lib/private/legacy/OC_App.php
@@ -354,7 +354,7 @@ class OC_App {
* @param string $appId
* @param bool $refreshAppPath should be set to true only during install/upgrade
* @return string|false
- * @deprecated 11.0.0 use \OC::$server->getAppManager()->getAppPath()
+ * @deprecated 11.0.0 use \OCP\Server::get(IAppManager)->getAppPath()
*/
public static function getAppPath(string $appId, bool $refreshAppPath = false) {
if ($appId === null || trim($appId) === '') {
diff --git a/tests/lib/App/AppManagerTest.php b/tests/lib/App/AppManagerTest.php
index dfbaedff957..756c29972b1 100644
--- a/tests/lib/App/AppManagerTest.php
+++ b/tests/lib/App/AppManagerTest.php
@@ -99,7 +99,7 @@ class AppManagerTest extends TestCase {
/** @var LoggerInterface|MockObject */
protected $logger;
- protected IURLGenerator|MockObject $urlGenerator;
+ protected IURLGenerator&MockObject $urlGenerator;
/** @var IAppManager */
protected $manager;
@@ -116,19 +116,27 @@ class AppManagerTest extends TestCase {
$this->eventDispatcher = $this->createMock(IEventDispatcher::class);
$this->logger = $this->createMock(LoggerInterface::class);
$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')
->with('settings')
->willReturn($this->cache);
+
+ $this->config
+ ->method('getSystemValueBool')
+ ->with('installed', false)
+ ->willReturn(true);
+
$this->manager = new AppManager(
$this->userSession,
$this->config,
- $this->appConfig,
$this->groupManager,
$this->cacheFactory,
$this->eventDispatcher,
$this->logger,
- $this->urlGenerator,
);
}
@@ -267,12 +275,10 @@ class AppManagerTest extends TestCase {
->setConstructorArgs([
$this->userSession,
$this->config,
- $this->appConfig,
$this->groupManager,
$this->cacheFactory,
$this->eventDispatcher,
$this->logger,
- $this->urlGenerator,
])
->onlyMethods([
'getAppPath',
@@ -322,12 +328,10 @@ class AppManagerTest extends TestCase {
->setConstructorArgs([
$this->userSession,
$this->config,
- $this->appConfig,
$this->groupManager,
$this->cacheFactory,
$this->eventDispatcher,
$this->logger,
- $this->urlGenerator,
])
->onlyMethods([
'getAppPath',
@@ -385,12 +389,10 @@ class AppManagerTest extends TestCase {
->setConstructorArgs([
$this->userSession,
$this->config,
- $this->appConfig,
$this->groupManager,
$this->cacheFactory,
$this->eventDispatcher,
$this->logger,
- $this->urlGenerator,
])
->onlyMethods([
'getAppPath',
@@ -589,12 +591,10 @@ class AppManagerTest extends TestCase {
->setConstructorArgs([
$this->userSession,
$this->config,
- $this->appConfig,
$this->groupManager,
$this->cacheFactory,
$this->eventDispatcher,
$this->logger,
- $this->urlGenerator,
])
->onlyMethods(['getAppInfo'])
->getMock();
@@ -649,12 +649,10 @@ class AppManagerTest extends TestCase {
->setConstructorArgs([
$this->userSession,
$this->config,
- $this->appConfig,
$this->groupManager,
$this->cacheFactory,
$this->eventDispatcher,
$this->logger,
- $this->urlGenerator,
])
->onlyMethods(['getAppInfo'])
->getMock();
diff --git a/tests/lib/AppFramework/Bootstrap/CoordinatorTest.php b/tests/lib/AppFramework/Bootstrap/CoordinatorTest.php
index a706abecc4f..193f9295551 100644
--- a/tests/lib/AppFramework/Bootstrap/CoordinatorTest.php
+++ b/tests/lib/AppFramework/Bootstrap/CoordinatorTest.php
@@ -83,7 +83,8 @@ class CoordinatorTest extends TestCase {
$this->dashboardManager,
$this->eventDispatcher,
$this->eventLogger,
- $this->logger
+ $this->appManager,
+ $this->logger,
);
}
diff --git a/tests/lib/AppFramework/Routing/RoutingTest.php b/tests/lib/AppFramework/Routing/RoutingTest.php
index c9812a5dfb7..c5e6f70cdc6 100644
--- a/tests/lib/AppFramework/Routing/RoutingTest.php
+++ b/tests/lib/AppFramework/Routing/RoutingTest.php
@@ -6,6 +6,7 @@ use OC\AppFramework\DependencyInjection\DIContainer;
use OC\AppFramework\Routing\RouteConfig;
use OC\Route\Route;
use OC\Route\Router;
+use OCP\App\IAppManager;
use OCP\Diagnostics\IEventLogger;
use OCP\IConfig;
use OCP\IRequest;
@@ -142,7 +143,8 @@ class RoutingTest extends \Test\TestCase {
$this->createMock(IRequest::class),
$this->createMock(IConfig::class),
$this->createMock(IEventLogger::class),
- $this->createMock(ContainerInterface::class)
+ $this->createMock(ContainerInterface::class),
+ $this->createMock(IAppManager::class),
])
->getMock();
@@ -169,7 +171,8 @@ class RoutingTest extends \Test\TestCase {
$this->createMock(IRequest::class),
$this->createMock(IConfig::class),
$this->createMock(IEventLogger::class),
- $this->createMock(ContainerInterface::class)
+ $this->createMock(ContainerInterface::class),
+ $this->createMock(IAppManager::class),
])
->getMock();
@@ -235,7 +238,8 @@ class RoutingTest extends \Test\TestCase {
$this->createMock(IRequest::class),
$this->createMock(IConfig::class),
$this->createMock(IEventLogger::class),
- $this->createMock(ContainerInterface::class)
+ $this->createMock(ContainerInterface::class),
+ $this->createMock(IAppManager::class),
])
->getMock();
@@ -291,7 +295,8 @@ class RoutingTest extends \Test\TestCase {
$this->createMock(IRequest::class),
$this->createMock(IConfig::class),
$this->createMock(IEventLogger::class),
- $this->createMock(ContainerInterface::class)
+ $this->createMock(ContainerInterface::class),
+ $this->createMock(IAppManager::class),
])
->getMock();
@@ -324,7 +329,8 @@ class RoutingTest extends \Test\TestCase {
$this->createMock(IRequest::class),
$this->createMock(IConfig::class),
$this->createMock(IEventLogger::class),
- $this->createMock(ContainerInterface::class)
+ $this->createMock(ContainerInterface::class),
+ $this->createMock(IAppManager::class),
])
->getMock();
@@ -377,7 +383,8 @@ class RoutingTest extends \Test\TestCase {
$this->createMock(IRequest::class),
$this->createMock(IConfig::class),
$this->createMock(IEventLogger::class),
- $this->createMock(ContainerInterface::class)
+ $this->createMock(ContainerInterface::class),
+ $this->createMock(IAppManager::class),
])
->getMock();
diff --git a/tests/lib/AppTest.php b/tests/lib/AppTest.php
index 4e723e5d2f1..06331700737 100644
--- a/tests/lib/AppTest.php
+++ b/tests/lib/AppTest.php
@@ -560,7 +560,6 @@ class AppTest extends \Test\TestCase {
$this->overwriteService(AppManager::class, new AppManager(
\OC::$server->getUserSession(),
\OC::$server->getConfig(),
- $appConfig,
\OC::$server->getGroupManager(),
\OC::$server->getMemCacheFactory(),
\OC::$server->get(IEventDispatcher::class),
diff --git a/tests/lib/L10N/FactoryTest.php b/tests/lib/L10N/FactoryTest.php
index 20eb355f6f4..4f12cb8d53c 100644
--- a/tests/lib/L10N/FactoryTest.php
+++ b/tests/lib/L10N/FactoryTest.php
@@ -13,6 +13,8 @@ namespace Test\L10N;
use OC\L10N\Factory;
use OC\L10N\LanguageNotFoundException;
+use OCP\App\AppPathNotFoundException;
+use OCP\App\IAppManager;
use OCP\ICacheFactory;
use OCP\IConfig;
use OCP\IRequest;
@@ -38,6 +40,9 @@ class FactoryTest extends TestCase {
/** @var string */
protected $serverRoot;
+ /** @var IAppManager|MockObject */
+ protected IAppManager $appManager;
+
protected function setUp(): void {
parent::setUp();
@@ -45,6 +50,7 @@ class FactoryTest extends TestCase {
$this->request = $this->createMock(IRequest::class);
$this->userSession = $this->createMock(IUserSession::class);
$this->cacheFactory = $this->createMock(ICacheFactory::class);
+ $this->appManager = $this->createMock(IAppManager::class);
$this->serverRoot = \OC::$SERVERROOT;
@@ -76,12 +82,13 @@ class FactoryTest extends TestCase {
$this->userSession,
$this->cacheFactory,
$this->serverRoot,
+ $this->appManager,
])
->setMethods($methods)
->getMock();
}
- return new Factory($this->config, $this->request, $this->userSession, $this->cacheFactory, $this->serverRoot);
+ return new Factory($this->config, $this->request, $this->userSession, $this->cacheFactory, $this->serverRoot, $this->appManager);
}
public function dataFindAvailableLanguages(): array {
@@ -402,7 +409,7 @@ class FactoryTest extends TestCase {
public function dataGetL10nFilesForApp(): array {
return [
- [null, 'de', [\OC::$SERVERROOT . '/core/l10n/de.json']],
+ ['', 'de', [\OC::$SERVERROOT . '/core/l10n/de.json']],
['core', 'ru', [\OC::$SERVERROOT . '/core/l10n/ru.json']],
['lib', 'ru', [\OC::$SERVERROOT . '/lib/l10n/ru.json']],
['settings', 'de', [\OC::$SERVERROOT . '/apps/settings/l10n/de.json']],
@@ -415,17 +422,28 @@ class FactoryTest extends TestCase {
/**
* @dataProvider dataGetL10nFilesForApp
*
- * @param string|null $app
+ * @param string $app
* @param string $expected
*/
public function testGetL10nFilesForApp($app, $lang, $expected): void {
$factory = $this->getFactory();
+ if (in_array($app, ['settings','files'])) {
+ $this->appManager
+ ->method('getAppPath')
+ ->with($app)
+ ->willReturn(\OC::$SERVERROOT . '/apps/' . $app);
+ } else {
+ $this->appManager
+ ->method('getAppPath')
+ ->with($app)
+ ->willThrowException(new AppPathNotFoundException());
+ }
self::assertSame($expected, $this->invokePrivate($factory, 'getL10nFilesForApp', [$app, $lang]));
}
public function dataFindL10NDir(): array {
return [
- [null, \OC::$SERVERROOT . '/core/l10n/'],
+ ['', \OC::$SERVERROOT . '/core/l10n/'],
['core', \OC::$SERVERROOT . '/core/l10n/'],
['lib', \OC::$SERVERROOT . '/lib/l10n/'],
['settings', \OC::$SERVERROOT . '/apps/settings/l10n/'],
@@ -437,11 +455,22 @@ class FactoryTest extends TestCase {
/**
* @dataProvider dataFindL10NDir
*
- * @param string|null $app
+ * @param string $app
* @param string $expected
*/
public function testFindL10NDir($app, $expected): void {
$factory = $this->getFactory();
+ if (in_array($app, ['settings','files'])) {
+ $this->appManager
+ ->method('getAppPath')
+ ->with($app)
+ ->willReturn(\OC::$SERVERROOT . '/apps/' . $app);
+ } else {
+ $this->appManager
+ ->method('getAppPath')
+ ->with($app)
+ ->willThrowException(new AppPathNotFoundException());
+ }
self::assertSame($expected, $this->invokePrivate($factory, 'findL10nDir', [$app]));
}
diff --git a/tests/lib/L10N/L10nTest.php b/tests/lib/L10N/L10nTest.php
index 9817f8b0141..a6d74256212 100644
--- a/tests/lib/L10N/L10nTest.php
+++ b/tests/lib/L10N/L10nTest.php
@@ -11,6 +11,7 @@ namespace Test\L10N;
use DateTime;
use OC\L10N\Factory;
use OC\L10N\L10N;
+use OCP\App\IAppManager;
use OCP\ICacheFactory;
use OCP\IConfig;
use OCP\IRequest;
@@ -34,7 +35,8 @@ class L10nTest extends TestCase {
/** @var IUserSession $userSession */
$userSession = $this->createMock(IUserSession::class);
$cacheFactory = $this->createMock(ICacheFactory::class);
- return new Factory($config, $request, $userSession, $cacheFactory, \OC::$SERVERROOT);
+ $appManager = $this->createMock(IAppManager::class);
+ return new Factory($config, $request, $userSession, $cacheFactory, \OC::$SERVERROOT, $appManager);
}
public function testSimpleTranslationWithTrailingColon(): void {
diff --git a/tests/lib/Route/RouterTest.php b/tests/lib/Route/RouterTest.php
index 301058f74a6..89cd0489616 100644
--- a/tests/lib/Route/RouterTest.php
+++ b/tests/lib/Route/RouterTest.php
@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace Test\Route;
use OC\Route\Router;
+use OCP\App\IAppManager;
use OCP\Diagnostics\IEventLogger;
use OCP\IConfig;
use OCP\IRequest;
@@ -54,6 +55,7 @@ class RouterTest extends TestCase {
$this->createMock(IConfig::class),
$this->createMock(IEventLogger::class),
$this->createMock(ContainerInterface::class),
+ $this->createMock(IAppManager::class),
);
$this->assertEquals('/index.php/apps/files/', $router->generate('files.view.index'));