Merge pull request #44025 from nextcloud/fix/remove-oc-app-calls

Migrate away from OC_App and toward IAppManager.
This commit is contained in:
Côme Chilliet 2024-04-22 16:41:15 +02:00 committed by GitHub
commit 37c89f4191
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
25 changed files with 239 additions and 193 deletions

View File

@ -402,7 +402,7 @@ class AppSettingsController extends Controller {
try { try {
$this->appManager->getAppPath($app['id']); $this->appManager->getAppPath($app['id']);
$existsLocally = true; $existsLocally = true;
} catch (AppPathNotFoundException $e) { } catch (AppPathNotFoundException) {
$existsLocally = false; $existsLocally = false;
} }

View File

@ -1,4 +1,7 @@
<?php <?php
declare(strict_types=1);
/** /**
* @copyright Copyright (c) 2016, ownCloud, Inc. * @copyright Copyright (c) 2016, ownCloud, Inc.
* *
@ -57,7 +60,7 @@ try {
exit(1); exit(1);
} }
$config = \OC::$server->getConfig(); $config = \OCP\Server::get(\OCP\IConfig::class);
set_exception_handler('exceptionHandler'); set_exception_handler('exceptionHandler');
if (!function_exists('posix_getuid')) { 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; echo "Additionally the function 'pcntl_signal' and 'pcntl_signal_dispatch' need to be enabled in your php.ini." . PHP_EOL;
} }
$application = new Application( $application = \OCP\Server::get(Application::class);
$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->loadCommands(new ArgvInput(), new ConsoleOutput()); $application->loadCommands(new ArgvInput(), new ConsoleOutput());
$application->run(); $application->run();
} catch (Exception $ex) { } catch (Exception $ex) {

View File

@ -1,4 +1,7 @@
<?php <?php
declare(strict_types=1);
/** /**
* @copyright Copyright (c) 2016, ownCloud, Inc. * @copyright Copyright (c) 2016, ownCloud, Inc.
* *

View File

@ -1,4 +1,7 @@
<?php <?php
declare(strict_types=1);
/** /**
* @copyright Copyright (c) 2016, ownCloud, Inc. * @copyright Copyright (c) 2016, ownCloud, Inc.
* *
@ -23,12 +26,20 @@
namespace OC\Core\Command\App; namespace OC\Core\Command\App;
use OC\Core\Command\Base; use OC\Core\Command\Base;
use OCP\App\AppPathNotFoundException;
use OCP\App\IAppManager;
use Stecman\Component\Symfony\Console\BashCompletion\CompletionContext; use Stecman\Component\Symfony\Console\BashCompletion\CompletionContext;
use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;
class GetPath extends Base { class GetPath extends Base {
public function __construct(
protected IAppManager $appManager,
) {
parent::__construct();
}
protected function configure(): void { protected function configure(): void {
parent::configure(); parent::configure();
@ -52,14 +63,14 @@ class GetPath extends Base {
*/ */
protected function execute(InputInterface $input, OutputInterface $output): int { protected function execute(InputInterface $input, OutputInterface $output): int {
$appName = $input->getArgument('app'); $appName = $input->getArgument('app');
$path = \OC_App::getAppPath($appName); try {
if ($path !== false) { $path = $this->appManager->getAppPath($appName);
$output->writeln($path); } catch (AppPathNotFoundException) {
return 0; // App not found, exit with non-zero
return self::FAILURE;
} }
$output->writeln($path);
// App not found, exit with non-zero return self::SUCCESS;
return 1;
} }
/** /**

View File

@ -1,4 +1,7 @@
<?php <?php
declare(strict_types=1);
/** /**
* @copyright Copyright (c) 2016, ownCloud, Inc. * @copyright Copyright (c) 2016, ownCloud, Inc.
* *
@ -36,6 +39,13 @@ use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;
class Install extends Command { class Install extends Command {
public function __construct(
protected IAppManager $appManager,
private Installer $installer,
) {
parent::__construct();
}
protected function configure(): void { protected function configure(): void {
$this $this
->setName('app:install') ->setName('app:install')
@ -70,32 +80,24 @@ class Install extends Command {
$appId = $input->getArgument('app-id'); $appId = $input->getArgument('app-id');
$forceEnable = (bool) $input->getOption('force'); $forceEnable = (bool) $input->getOption('force');
if (\OC_App::getAppPath($appId)) { if ($this->appManager->isInstalled($appId)) {
$output->writeln($appId . ' already installed'); $output->writeln($appId . ' already installed');
return 1; return 1;
} }
try { try {
/** @var Installer $installer */ $this->installer->downloadApp($appId, $input->getOption('allow-unstable'));
$installer = \OC::$server->query(Installer::class); $result = $this->installer->installApp($appId, $forceEnable);
$installer->downloadApp($appId, $input->getOption('allow-unstable'));
$result = $installer->installApp($appId, $forceEnable);
} catch (\Exception $e) { } catch (\Exception $e) {
$output->writeln('Error: ' . $e->getMessage()); $output->writeln('Error: ' . $e->getMessage());
return 1; return 1;
} }
if ($result === false) { $appVersion = $this->appManager->getAppVersion($appId);
$output->writeln($appId . ' couldn\'t be installed');
return 1;
}
$appVersion = \OCP\Server::get(IAppManager::class)->getAppVersion($appId);
$output->writeln($appId . ' ' . $appVersion . ' installed'); $output->writeln($appId . ' ' . $appVersion . ' installed');
if (!$input->getOption('keep-disabled')) { if (!$input->getOption('keep-disabled')) {
$appClass = new \OC_App(); $this->appManager->enableApp($appId);
$appClass->enable($appId);
$output->writeln($appId . ' enabled'); $output->writeln($appId . ' enabled');
} }

View File

@ -1,4 +1,7 @@
<?php <?php
declare(strict_types=1);
/** /**
* @copyright Copyright (c) 2018, Patrik Kernstock <info@pkern.at> * @copyright Copyright (c) 2018, Patrik Kernstock <info@pkern.at>
* *
@ -68,7 +71,7 @@ class Remove extends Command implements CompletionAwareInterface {
$appId = $input->getArgument('app-id'); $appId = $input->getArgument('app-id');
// Check if the app is installed // Check if the app is installed
if (!\OC_App::getAppPath($appId)) { if (!$this->manager->isInstalled($appId)) {
$output->writeln($appId . ' is not installed'); $output->writeln($appId . ' is not installed');
return 1; return 1;
} }
@ -135,7 +138,7 @@ class Remove extends Command implements CompletionAwareInterface {
*/ */
public function completeArgumentValues($argumentName, CompletionContext $context): array { public function completeArgumentValues($argumentName, CompletionContext $context): array {
if ($argumentName === 'app-id') { if ($argumentName === 'app-id') {
return \OC_App::getAllApps(); return $this->manager->getInstalledApps();
} }
return []; return [];
} }

View File

@ -1,4 +1,7 @@
<?php <?php
declare(strict_types=1);
/** /**
* @copyright Copyright (c) 2018, michag86 (michag86@arcor.de) * @copyright Copyright (c) 2018, michag86 (michag86@arcor.de)
* *
@ -117,7 +120,7 @@ class Update extends Command {
if ($result === false) { if ($result === false) {
$output->writeln($appId . ' couldn\'t be updated'); $output->writeln($appId . ' couldn\'t be updated');
$return = 1; $return = 1;
} elseif ($result === true) { } else {
$output->writeln($appId . ' updated'); $output->writeln($appId . ' updated');
} }
} }

View File

@ -1,4 +1,7 @@
<?php <?php
declare(strict_types=1);
/** /**
* @copyright Copyright (c) 2016, ownCloud, Inc. * @copyright Copyright (c) 2016, ownCloud, Inc.
* *
@ -26,6 +29,7 @@ namespace OC\Core\Command\L10n;
use DirectoryIterator; use DirectoryIterator;
use OCP\App\IAppManager;
use Stecman\Component\Symfony\Console\BashCompletion\Completion\CompletionAwareInterface; use Stecman\Component\Symfony\Console\BashCompletion\Completion\CompletionAwareInterface;
use Stecman\Component\Symfony\Console\BashCompletion\CompletionContext; use Stecman\Component\Symfony\Console\BashCompletion\CompletionContext;
use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Command\Command;
@ -35,6 +39,12 @@ use Symfony\Component\Console\Output\OutputInterface;
use UnexpectedValueException; use UnexpectedValueException;
class CreateJs extends Command implements CompletionAwareInterface { class CreateJs extends Command implements CompletionAwareInterface {
public function __construct(
protected IAppManager $appManager,
) {
parent::__construct();
}
protected function configure() { protected function configure() {
$this $this
->setName('l10n:createjs') ->setName('l10n:createjs')
@ -55,11 +65,7 @@ class CreateJs extends Command implements CompletionAwareInterface {
$app = $input->getArgument('app'); $app = $input->getArgument('app');
$lang = $input->getArgument('lang'); $lang = $input->getArgument('lang');
$path = \OC_App::getAppPath($app); $path = $this->appManager->getAppPath($app);
if ($path === false) {
$output->writeln("The app <$app> is unknown.");
return 1;
}
$languages = $lang; $languages = $lang;
if (empty($lang)) { if (empty($lang)) {
$languages = $this->getAllLanguages($path); $languages = $this->getAllLanguages($path);

View File

@ -36,6 +36,8 @@ declare(strict_types=1);
*/ */
namespace OC; namespace OC;
use OCP\App\AppPathNotFoundException;
use OCP\App\IAppManager;
use OCP\AutoloadNotAllowedException; use OCP\AutoloadNotAllowedException;
use OCP\ICache; use OCP\ICache;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
@ -113,11 +115,15 @@ class Autoloader {
} elseif (strpos($class, 'OCA\\') === 0) { } elseif (strpos($class, 'OCA\\') === 0) {
[, $app, $rest] = explode('\\', $class, 3); [, $app, $rest] = explode('\\', $class, 3);
$app = strtolower($app); $app = strtolower($app);
$appPath = \OC_App::getAppPath($app); try {
if ($appPath && stream_resolve_include_path($appPath)) { $appPath = \OCP\Server::get(IAppManager::class)->getAppPath($app);
$paths[] = $appPath . '/' . strtolower(str_replace('\\', '/', $rest) . '.php'); if (stream_resolve_include_path($appPath)) {
// If not found in the root of the app directory, insert '/lib' after app id and try again. $paths[] = $appPath . '/' . strtolower(str_replace('\\', '/', $rest) . '.php');
$paths[] = $appPath . '/lib/' . 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') { } elseif ($class === 'Test\\TestCase') {
// This File is considered public API, so we make sure that the class // This File is considered public API, so we make sure that the class

View File

@ -97,15 +97,20 @@ class AppManager implements IAppManager {
/** @var array<string, true> */ /** @var array<string, true> */
private array $loadedApps = []; 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( public function __construct(
private IUserSession $userSession, private IUserSession $userSession,
private IConfig $config, private IConfig $config,
private AppConfig $appConfig,
private IGroupManager $groupManager, private IGroupManager $groupManager,
private ICacheFactory $memCacheFactory, private ICacheFactory $memCacheFactory,
private IEventDispatcher $dispatcher, private IEventDispatcher $dispatcher,
private LoggerInterface $logger, private LoggerInterface $logger,
private IURLGenerator $urlGenerator,
) { ) {
} }
@ -114,7 +119,7 @@ class AppManager implements IAppManager {
$icon = null; $icon = null;
foreach ($possibleIcons as $iconName) { foreach ($possibleIcons as $iconName) {
try { try {
$icon = $this->urlGenerator->imagePath($appId, $iconName); $icon = $this->getUrlGenerator()->imagePath($appId, $iconName);
break; break;
} catch (\RuntimeException $e) { } catch (\RuntimeException $e) {
// ignore // ignore
@ -123,12 +128,34 @@ class AppManager implements IAppManager {
return $icon; 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 * @return string[] $appId => $enabled
*/ */
private function getInstalledAppsValues(): array { private function getInstalledAppsValues(): array {
if (!$this->installedAppsCache) { if (!$this->installedAppsCache) {
$values = $this->appConfig->getValues(false, 'enabled'); $values = $this->getAppConfig()->getValues(false, 'enabled');
$alwaysEnabledApps = $this->getAlwaysEnabledApps(); $alwaysEnabledApps = $this->getAlwaysEnabledApps();
foreach ($alwaysEnabledApps as $appId) { foreach ($alwaysEnabledApps as $appId) {
@ -253,7 +280,7 @@ class AppManager implements IAppManager {
private function getAppTypes(string $app): array { private function getAppTypes(string $app): array {
//load the cache //load the cache
if (count($this->appTypes) === 0) { if (count($this->appTypes) === 0) {
$this->appTypes = $this->appConfig->getValues(false, 'types') ?: []; $this->appTypes = $this->getAppConfig()->getValues(false, 'types') ?: [];
} }
if (isset($this->appTypes[$app])) { if (isset($this->appTypes[$app])) {
@ -541,7 +568,7 @@ class AppManager implements IAppManager {
} }
$this->installedAppsCache[$appId] = 'yes'; $this->installedAppsCache[$appId] = 'yes';
$this->appConfig->setValue($appId, 'enabled', 'yes'); $this->getAppConfig()->setValue($appId, 'enabled', 'yes');
$this->dispatcher->dispatchTyped(new AppEnableEvent($appId)); $this->dispatcher->dispatchTyped(new AppEnableEvent($appId));
$this->dispatcher->dispatch(ManagerEvent::EVENT_APP_ENABLE, new ManagerEvent( $this->dispatcher->dispatch(ManagerEvent::EVENT_APP_ENABLE, new ManagerEvent(
ManagerEvent::EVENT_APP_ENABLE, $appId ManagerEvent::EVENT_APP_ENABLE, $appId
@ -595,7 +622,7 @@ class AppManager implements IAppManager {
}, $groups); }, $groups);
$this->installedAppsCache[$appId] = json_encode($groupIds); $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->dispatchTyped(new AppEnableEvent($appId, $groupIds));
$this->dispatcher->dispatch(ManagerEvent::EVENT_APP_ENABLE_FOR_GROUPS, new ManagerEvent( $this->dispatcher->dispatch(ManagerEvent::EVENT_APP_ENABLE_FOR_GROUPS, new ManagerEvent(
ManagerEvent::EVENT_APP_ENABLE_FOR_GROUPS, $appId, $groups ManagerEvent::EVENT_APP_ENABLE_FOR_GROUPS, $appId, $groups
@ -616,7 +643,7 @@ class AppManager implements IAppManager {
} }
if ($automaticDisabled) { if ($automaticDisabled) {
$previousSetting = $this->appConfig->getValue($appId, 'enabled', 'yes'); $previousSetting = $this->getAppConfig()->getValue($appId, 'enabled', 'yes');
if ($previousSetting !== 'yes' && $previousSetting !== 'no') { if ($previousSetting !== 'yes' && $previousSetting !== 'no') {
$previousSetting = json_decode($previousSetting, true); $previousSetting = json_decode($previousSetting, true);
} }
@ -624,7 +651,7 @@ class AppManager implements IAppManager {
} }
unset($this->installedAppsCache[$appId]); unset($this->installedAppsCache[$appId]);
$this->appConfig->setValue($appId, 'enabled', 'no'); $this->getAppConfig()->setValue($appId, 'enabled', 'no');
// run uninstall steps // run uninstall steps
$appData = $this->getAppInfo($appId); $appData = $this->getAppInfo($appId);
@ -689,7 +716,7 @@ class AppManager implements IAppManager {
$apps = $this->getInstalledApps(); $apps = $this->getInstalledApps();
foreach ($apps as $appId) { foreach ($apps as $appId) {
$appInfo = $this->getAppInfo($appId); $appInfo = $this->getAppInfo($appId);
$appDbVersion = $this->appConfig->getValue($appId, 'installed_version'); $appDbVersion = $this->getAppConfig()->getValue($appId, 'installed_version');
if ($appDbVersion if ($appDbVersion
&& isset($appInfo['version']) && isset($appInfo['version'])
&& version_compare($appInfo['version'], $appDbVersion, '>') && version_compare($appInfo['version'], $appDbVersion, '>')

View File

@ -32,6 +32,8 @@ namespace OC\AppFramework\Bootstrap;
use OC\Support\CrashReport\Registry; use OC\Support\CrashReport\Registry;
use OC_App; use OC_App;
use OCP\App\AppPathNotFoundException;
use OCP\App\IAppManager;
use OCP\AppFramework\App; use OCP\AppFramework\App;
use OCP\AppFramework\Bootstrap\IBootstrap; use OCP\AppFramework\Bootstrap\IBootstrap;
use OCP\AppFramework\QueryException; use OCP\AppFramework\QueryException;
@ -46,24 +48,6 @@ use function class_implements;
use function in_array; use function in_array;
class Coordinator { 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 */ /** @var RegistrationContext|null */
private $registrationContext; private $registrationContext;
@ -71,19 +55,14 @@ class Coordinator {
private $bootedApps = []; private $bootedApps = [];
public function __construct( public function __construct(
IServerContainer $container, private IServerContainer $serverContainer,
Registry $registry, private Registry $registry,
IManager $dashboardManager, private IManager $dashboardManager,
IEventDispatcher $eventListener, private IEventDispatcher $eventDispatcher,
IEventLogger $eventLogger, private IEventLogger $eventLogger,
LoggerInterface $logger 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 { public function runInitialRegistration(): void {
@ -108,11 +87,10 @@ class Coordinator {
$this->eventLogger->start("bootstrap:register_app:$appId:autoloader", "Setup autoloader for $appId"); $this->eventLogger->start("bootstrap:register_app:$appId:autoloader", "Setup autoloader for $appId");
/* /*
* First, we have to enable the app's autoloader * First, we have to enable the app's autoloader
*
* @todo use $this->appManager->getAppPath($appId) here
*/ */
$path = OC_App::getAppPath($appId); try {
if ($path === false) { $path = $this->appManager->getAppPath($appId);
} catch (AppPathNotFoundException) {
// Ignore // Ignore
continue; continue;
} }

View File

@ -32,7 +32,7 @@ namespace OC\Console;
use OC\MemoryInfo; use OC\MemoryInfo;
use OC\NeedsUpdateException; use OC\NeedsUpdateException;
use OC_App; use OCP\App\AppPathNotFoundException;
use OCP\App\IAppManager; use OCP\App\IAppManager;
use OCP\Console\ConsoleEvent; use OCP\Console\ConsoleEvent;
use OCP\EventDispatcher\IEventDispatcher; use OCP\EventDispatcher\IEventDispatcher;
@ -47,25 +47,18 @@ use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;
class Application { class Application {
private IConfig $config;
private SymfonyApplication $application; private SymfonyApplication $application;
private IEventDispatcher $dispatcher;
private IRequest $request;
private LoggerInterface $logger;
private MemoryInfo $memoryInfo;
public function __construct(IConfig $config, public function __construct(
IEventDispatcher $dispatcher, private IConfig $config,
IRequest $request, private IEventDispatcher $dispatcher,
LoggerInterface $logger, private IRequest $request,
MemoryInfo $memoryInfo) { private LoggerInterface $logger,
private MemoryInfo $memoryInfo,
private IAppManager $appManager,
) {
$defaults = \OC::$server->get('ThemingDefaults'); $defaults = \OC::$server->get('ThemingDefaults');
$this->config = $config;
$this->application = new SymfonyApplication($defaults->getName(), \OC_Util::getVersionString()); $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')) { } elseif ($this->config->getSystemValueBool('maintenance')) {
$this->writeMaintenanceModeInfo($input, $output); $this->writeMaintenanceModeInfo($input, $output);
} else { } else {
OC_App::loadApps(); $this->appManager->loadApps();
$appManager = \OCP\Server::get(IAppManager::class); foreach ($this->appManager->getInstalledApps() as $app) {
foreach ($appManager->getInstalledApps() as $app) { try {
$appPath = \OC_App::getAppPath($app); $appPath = $this->appManager->getAppPath($app);
if ($appPath === false) { } catch (AppPathNotFoundException) {
continue; continue;
} }
// load commands using info.xml // load commands using info.xml
$info = $appManager->getAppInfo($app); $info = $this->appManager->getAppInfo($app);
if (isset($info['commands'])) { if (isset($info['commands'])) {
try { try {
$this->loadCommandsFromInfoXml($info['commands']); $this->loadCommandsFromInfoXml($info['commands']);

View File

@ -560,12 +560,13 @@ class Installer {
if ($output instanceof IOutput) { if ($output instanceof IOutput) {
$output->debug('Installing ' . $app); $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); $config = \OCP\Server::get(IConfig::class);
$appPath = $appManager->getAppPath($app);
\OC_App::registerAutoloading($app, $appPath);
$ms = new MigrationService($app, \OCP\Server::get(Connection::class)); $ms = new MigrationService($app, \OCP\Server::get(Connection::class));
if ($output instanceof IOutput) { if ($output instanceof IOutput) {
$ms->setOutput($output); $ms->setOutput($output);

View File

@ -40,6 +40,8 @@ declare(strict_types=1);
namespace OC\L10N; namespace OC\L10N;
use OCP\App\AppPathNotFoundException;
use OCP\App\IAppManager;
use OCP\ICache; use OCP\ICache;
use OCP\ICacheFactory; use OCP\ICacheFactory;
use OCP\IConfig; 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' '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; private ICache $cache;
/** @var string */
protected $serverRoot;
/**
* @param IConfig $config
* @param IRequest $request
* @param IUserSession $userSession
* @param string $serverRoot
*/
public function __construct( public function __construct(
IConfig $config, protected IConfig $config,
IRequest $request, protected IRequest $request,
IUserSession $userSession, protected IUserSession $userSession,
ICacheFactory $cacheFactory, ICacheFactory $cacheFactory,
$serverRoot protected string $serverRoot,
protected IAppManager $appManager,
) { ) {
$this->config = $config;
$this->request = $request;
$this->userSession = $userSession;
$this->cache = $cacheFactory->createLocal('L10NFactory'); $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 * Get a list of language files that should be loaded
* *
* @param string $app
* @param string $lang
* @return string[] * @return string[]
*/ */
// FIXME This method is only public, until OC_L10N does not need it anymore, private function getL10nFilesForApp(string $app, string $lang): array {
// FIXME This is also the reason, why it is not in the public interface
public function getL10nFilesForApp($app, $lang) {
$languageFiles = []; $languageFiles = [];
$i18nDir = $this->findL10nDir($app); $i18nDir = $this->findL10nDir($app);
@ -572,7 +549,7 @@ class Factory implements IFactory {
if (($this->isSubDirectory($transFile, $this->serverRoot . '/core/l10n/') if (($this->isSubDirectory($transFile, $this->serverRoot . '/core/l10n/')
|| $this->isSubDirectory($transFile, $this->serverRoot . '/lib/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) && file_exists($transFile)
) { ) {
// load the translations file // load the translations file
@ -602,9 +579,12 @@ class Factory implements IFactory {
if (file_exists($this->serverRoot . '/' . $app . '/l10n/')) { if (file_exists($this->serverRoot . '/' . $app . '/l10n/')) {
return $this->serverRoot . '/' . $app . '/l10n/'; return $this->serverRoot . '/' . $app . '/l10n/';
} }
} elseif ($app && \OC_App::getAppPath($app) !== false) { } elseif ($app) {
// Check if the app is in the app folder try {
return \OC_App::getAppPath($app) . '/l10n/'; return $this->appManager->getAppPath($app) . '/l10n/';
} catch (AppPathNotFoundException) {
/* App not found, continue */
}
} }
return $this->serverRoot . '/core/l10n/'; return $this->serverRoot . '/core/l10n/';
} }

View File

@ -24,6 +24,7 @@
*/ */
namespace OC\Route; namespace OC\Route;
use OCP\App\IAppManager;
use OCP\Diagnostics\IEventLogger; use OCP\Diagnostics\IEventLogger;
use OCP\ICache; use OCP\ICache;
use OCP\ICacheFactory; use OCP\ICacheFactory;
@ -41,10 +42,11 @@ class CachingRouter extends Router {
IRequest $request, IRequest $request,
IConfig $config, IConfig $config,
IEventLogger $eventLogger, IEventLogger $eventLogger,
ContainerInterface $container ContainerInterface $container,
IAppManager $appManager,
) { ) {
$this->cache = $cacheFactory->createLocal('route'); $this->cache = $cacheFactory->createLocal('route');
parent::__construct($logger, $request, $config, $eventLogger, $container); parent::__construct($logger, $request, $config, $eventLogger, $container, $appManager);
} }
/** /**

View File

@ -35,6 +35,8 @@ namespace OC\Route;
use DirectoryIterator; use DirectoryIterator;
use OC\AppFramework\Routing\RouteParser; use OC\AppFramework\Routing\RouteParser;
use OCP\App\AppPathNotFoundException;
use OCP\App\IAppManager;
use OCP\AppFramework\App; use OCP\AppFramework\App;
use OCP\AppFramework\Http\Attribute\Route as RouteAttribute; use OCP\AppFramework\Http\Attribute\Route as RouteAttribute;
use OCP\Diagnostics\IEventLogger; use OCP\Diagnostics\IEventLogger;
@ -71,22 +73,17 @@ class Router implements IRouter {
protected $loaded = false; protected $loaded = false;
/** @var array */ /** @var array */
protected $loadedApps = []; protected $loadedApps = [];
protected LoggerInterface $logger;
/** @var RequestContext */ /** @var RequestContext */
protected $context; protected $context;
private IEventLogger $eventLogger;
private IConfig $config;
private ContainerInterface $container;
public function __construct( public function __construct(
LoggerInterface $logger, protected LoggerInterface $logger,
IRequest $request, IRequest $request,
IConfig $config, private IConfig $config,
IEventLogger $eventLogger, private IEventLogger $eventLogger,
ContainerInterface $container private ContainerInterface $container,
private IAppManager $appManager,
) { ) {
$this->logger = $logger;
$this->config = $config;
$baseUrl = \OC::$WEBROOT; $baseUrl = \OC::$WEBROOT;
if (!($config->getSystemValue('htaccess.IgnoreFrontController', false) === true || getenv('front_controller_active') === 'true')) { if (!($config->getSystemValue('htaccess.IgnoreFrontController', false) === true || getenv('front_controller_active') === 'true')) {
$baseUrl .= '/index.php'; $baseUrl .= '/index.php';
@ -101,8 +98,6 @@ class Router implements IRouter {
$this->context = new RequestContext($baseUrl, $method, $host, $schema); $this->context = new RequestContext($baseUrl, $method, $host, $schema);
// TODO cache // TODO cache
$this->root = $this->getCollection('root'); $this->root = $this->getCollection('root');
$this->eventLogger = $eventLogger;
$this->container = $container;
} }
/** /**
@ -114,12 +109,14 @@ class Router implements IRouter {
if ($this->routingFiles === null) { if ($this->routingFiles === null) {
$this->routingFiles = []; $this->routingFiles = [];
foreach (\OC_APP::getEnabledApps() as $app) { foreach (\OC_APP::getEnabledApps() as $app) {
$appPath = \OC_App::getAppPath($app); try {
if ($appPath !== false) { $appPath = $this->appManager->getAppPath($app);
$file = $appPath . '/appinfo/routes.php'; $file = $appPath . '/appinfo/routes.php';
if (file_exists($file)) { if (file_exists($file)) {
$this->routingFiles[$app] = $file; $this->routingFiles[$app] = $file;
} }
} catch (AppPathNotFoundException) {
/* ignore */
} }
} }
} }

View File

@ -653,7 +653,8 @@ class Server extends ServerContainer implements IServerContainer {
$c->getRequest(), $c->getRequest(),
$c->get(IUserSession::class), $c->get(IUserSession::class),
$c->get(ICacheFactory::class), $c->get(ICacheFactory::class),
\OC::$SERVERROOT \OC::$SERVERROOT,
$c->get(IAppManager::class),
); );
}); });
/** @deprecated 19.0.0 */ /** @deprecated 19.0.0 */
@ -892,12 +893,10 @@ class Server extends ServerContainer implements IServerContainer {
return new \OC\App\AppManager( return new \OC\App\AppManager(
$c->get(IUserSession::class), $c->get(IUserSession::class),
$c->get(\OCP\IConfig::class), $c->get(\OCP\IConfig::class),
$c->get(\OC\AppConfig::class),
$c->get(IGroupManager::class), $c->get(IGroupManager::class),
$c->get(ICacheFactory::class), $c->get(ICacheFactory::class),
$c->get(IEventDispatcher::class), $c->get(IEventDispatcher::class),
$c->get(LoggerInterface::class), $c->get(LoggerInterface::class),
$c->get(IURLGenerator::class),
); );
}); });
/** @deprecated 19.0.0 */ /** @deprecated 19.0.0 */

View File

@ -354,7 +354,7 @@ class OC_App {
* @param string $appId * @param string $appId
* @param bool $refreshAppPath should be set to true only during install/upgrade * @param bool $refreshAppPath should be set to true only during install/upgrade
* @return string|false * @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) { public static function getAppPath(string $appId, bool $refreshAppPath = false) {
if ($appId === null || trim($appId) === '') { if ($appId === null || trim($appId) === '') {

View File

@ -99,7 +99,7 @@ class AppManagerTest extends TestCase {
/** @var LoggerInterface|MockObject */ /** @var LoggerInterface|MockObject */
protected $logger; protected $logger;
protected IURLGenerator|MockObject $urlGenerator; protected IURLGenerator&MockObject $urlGenerator;
/** @var IAppManager */ /** @var IAppManager */
protected $manager; protected $manager;
@ -116,19 +116,27 @@ class AppManagerTest extends TestCase {
$this->eventDispatcher = $this->createMock(IEventDispatcher::class); $this->eventDispatcher = $this->createMock(IEventDispatcher::class);
$this->logger = $this->createMock(LoggerInterface::class); $this->logger = $this->createMock(LoggerInterface::class);
$this->urlGenerator = $this->createMock(IURLGenerator::class); $this->urlGenerator = $this->createMock(IURLGenerator::class);
$this->overwriteService(AppConfig::class, $this->appConfig);
$this->overwriteService(IURLGenerator::class, $this->urlGenerator);
$this->cacheFactory->expects($this->any()) $this->cacheFactory->expects($this->any())
->method('createDistributed') ->method('createDistributed')
->with('settings') ->with('settings')
->willReturn($this->cache); ->willReturn($this->cache);
$this->config
->method('getSystemValueBool')
->with('installed', false)
->willReturn(true);
$this->manager = new AppManager( $this->manager = new AppManager(
$this->userSession, $this->userSession,
$this->config, $this->config,
$this->appConfig,
$this->groupManager, $this->groupManager,
$this->cacheFactory, $this->cacheFactory,
$this->eventDispatcher, $this->eventDispatcher,
$this->logger, $this->logger,
$this->urlGenerator,
); );
} }
@ -267,12 +275,10 @@ class AppManagerTest extends TestCase {
->setConstructorArgs([ ->setConstructorArgs([
$this->userSession, $this->userSession,
$this->config, $this->config,
$this->appConfig,
$this->groupManager, $this->groupManager,
$this->cacheFactory, $this->cacheFactory,
$this->eventDispatcher, $this->eventDispatcher,
$this->logger, $this->logger,
$this->urlGenerator,
]) ])
->onlyMethods([ ->onlyMethods([
'getAppPath', 'getAppPath',
@ -322,12 +328,10 @@ class AppManagerTest extends TestCase {
->setConstructorArgs([ ->setConstructorArgs([
$this->userSession, $this->userSession,
$this->config, $this->config,
$this->appConfig,
$this->groupManager, $this->groupManager,
$this->cacheFactory, $this->cacheFactory,
$this->eventDispatcher, $this->eventDispatcher,
$this->logger, $this->logger,
$this->urlGenerator,
]) ])
->onlyMethods([ ->onlyMethods([
'getAppPath', 'getAppPath',
@ -385,12 +389,10 @@ class AppManagerTest extends TestCase {
->setConstructorArgs([ ->setConstructorArgs([
$this->userSession, $this->userSession,
$this->config, $this->config,
$this->appConfig,
$this->groupManager, $this->groupManager,
$this->cacheFactory, $this->cacheFactory,
$this->eventDispatcher, $this->eventDispatcher,
$this->logger, $this->logger,
$this->urlGenerator,
]) ])
->onlyMethods([ ->onlyMethods([
'getAppPath', 'getAppPath',
@ -589,12 +591,10 @@ class AppManagerTest extends TestCase {
->setConstructorArgs([ ->setConstructorArgs([
$this->userSession, $this->userSession,
$this->config, $this->config,
$this->appConfig,
$this->groupManager, $this->groupManager,
$this->cacheFactory, $this->cacheFactory,
$this->eventDispatcher, $this->eventDispatcher,
$this->logger, $this->logger,
$this->urlGenerator,
]) ])
->onlyMethods(['getAppInfo']) ->onlyMethods(['getAppInfo'])
->getMock(); ->getMock();
@ -649,12 +649,10 @@ class AppManagerTest extends TestCase {
->setConstructorArgs([ ->setConstructorArgs([
$this->userSession, $this->userSession,
$this->config, $this->config,
$this->appConfig,
$this->groupManager, $this->groupManager,
$this->cacheFactory, $this->cacheFactory,
$this->eventDispatcher, $this->eventDispatcher,
$this->logger, $this->logger,
$this->urlGenerator,
]) ])
->onlyMethods(['getAppInfo']) ->onlyMethods(['getAppInfo'])
->getMock(); ->getMock();

View File

@ -83,7 +83,8 @@ class CoordinatorTest extends TestCase {
$this->dashboardManager, $this->dashboardManager,
$this->eventDispatcher, $this->eventDispatcher,
$this->eventLogger, $this->eventLogger,
$this->logger $this->appManager,
$this->logger,
); );
} }

View File

@ -6,6 +6,7 @@ use OC\AppFramework\DependencyInjection\DIContainer;
use OC\AppFramework\Routing\RouteConfig; use OC\AppFramework\Routing\RouteConfig;
use OC\Route\Route; use OC\Route\Route;
use OC\Route\Router; use OC\Route\Router;
use OCP\App\IAppManager;
use OCP\Diagnostics\IEventLogger; use OCP\Diagnostics\IEventLogger;
use OCP\IConfig; use OCP\IConfig;
use OCP\IRequest; use OCP\IRequest;
@ -142,7 +143,8 @@ class RoutingTest extends \Test\TestCase {
$this->createMock(IRequest::class), $this->createMock(IRequest::class),
$this->createMock(IConfig::class), $this->createMock(IConfig::class),
$this->createMock(IEventLogger::class), $this->createMock(IEventLogger::class),
$this->createMock(ContainerInterface::class) $this->createMock(ContainerInterface::class),
$this->createMock(IAppManager::class),
]) ])
->getMock(); ->getMock();
@ -169,7 +171,8 @@ class RoutingTest extends \Test\TestCase {
$this->createMock(IRequest::class), $this->createMock(IRequest::class),
$this->createMock(IConfig::class), $this->createMock(IConfig::class),
$this->createMock(IEventLogger::class), $this->createMock(IEventLogger::class),
$this->createMock(ContainerInterface::class) $this->createMock(ContainerInterface::class),
$this->createMock(IAppManager::class),
]) ])
->getMock(); ->getMock();
@ -235,7 +238,8 @@ class RoutingTest extends \Test\TestCase {
$this->createMock(IRequest::class), $this->createMock(IRequest::class),
$this->createMock(IConfig::class), $this->createMock(IConfig::class),
$this->createMock(IEventLogger::class), $this->createMock(IEventLogger::class),
$this->createMock(ContainerInterface::class) $this->createMock(ContainerInterface::class),
$this->createMock(IAppManager::class),
]) ])
->getMock(); ->getMock();
@ -291,7 +295,8 @@ class RoutingTest extends \Test\TestCase {
$this->createMock(IRequest::class), $this->createMock(IRequest::class),
$this->createMock(IConfig::class), $this->createMock(IConfig::class),
$this->createMock(IEventLogger::class), $this->createMock(IEventLogger::class),
$this->createMock(ContainerInterface::class) $this->createMock(ContainerInterface::class),
$this->createMock(IAppManager::class),
]) ])
->getMock(); ->getMock();
@ -324,7 +329,8 @@ class RoutingTest extends \Test\TestCase {
$this->createMock(IRequest::class), $this->createMock(IRequest::class),
$this->createMock(IConfig::class), $this->createMock(IConfig::class),
$this->createMock(IEventLogger::class), $this->createMock(IEventLogger::class),
$this->createMock(ContainerInterface::class) $this->createMock(ContainerInterface::class),
$this->createMock(IAppManager::class),
]) ])
->getMock(); ->getMock();
@ -377,7 +383,8 @@ class RoutingTest extends \Test\TestCase {
$this->createMock(IRequest::class), $this->createMock(IRequest::class),
$this->createMock(IConfig::class), $this->createMock(IConfig::class),
$this->createMock(IEventLogger::class), $this->createMock(IEventLogger::class),
$this->createMock(ContainerInterface::class) $this->createMock(ContainerInterface::class),
$this->createMock(IAppManager::class),
]) ])
->getMock(); ->getMock();

View File

@ -560,7 +560,6 @@ class AppTest extends \Test\TestCase {
$this->overwriteService(AppManager::class, new AppManager( $this->overwriteService(AppManager::class, new AppManager(
\OC::$server->getUserSession(), \OC::$server->getUserSession(),
\OC::$server->getConfig(), \OC::$server->getConfig(),
$appConfig,
\OC::$server->getGroupManager(), \OC::$server->getGroupManager(),
\OC::$server->getMemCacheFactory(), \OC::$server->getMemCacheFactory(),
\OC::$server->get(IEventDispatcher::class), \OC::$server->get(IEventDispatcher::class),

View File

@ -13,6 +13,8 @@ namespace Test\L10N;
use OC\L10N\Factory; use OC\L10N\Factory;
use OC\L10N\LanguageNotFoundException; use OC\L10N\LanguageNotFoundException;
use OCP\App\AppPathNotFoundException;
use OCP\App\IAppManager;
use OCP\ICacheFactory; use OCP\ICacheFactory;
use OCP\IConfig; use OCP\IConfig;
use OCP\IRequest; use OCP\IRequest;
@ -38,6 +40,9 @@ class FactoryTest extends TestCase {
/** @var string */ /** @var string */
protected $serverRoot; protected $serverRoot;
/** @var IAppManager|MockObject */
protected IAppManager $appManager;
protected function setUp(): void { protected function setUp(): void {
parent::setUp(); parent::setUp();
@ -45,6 +50,7 @@ class FactoryTest extends TestCase {
$this->request = $this->createMock(IRequest::class); $this->request = $this->createMock(IRequest::class);
$this->userSession = $this->createMock(IUserSession::class); $this->userSession = $this->createMock(IUserSession::class);
$this->cacheFactory = $this->createMock(ICacheFactory::class); $this->cacheFactory = $this->createMock(ICacheFactory::class);
$this->appManager = $this->createMock(IAppManager::class);
$this->serverRoot = \OC::$SERVERROOT; $this->serverRoot = \OC::$SERVERROOT;
@ -76,12 +82,13 @@ class FactoryTest extends TestCase {
$this->userSession, $this->userSession,
$this->cacheFactory, $this->cacheFactory,
$this->serverRoot, $this->serverRoot,
$this->appManager,
]) ])
->setMethods($methods) ->setMethods($methods)
->getMock(); ->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 { public function dataFindAvailableLanguages(): array {
@ -402,7 +409,7 @@ class FactoryTest extends TestCase {
public function dataGetL10nFilesForApp(): array { public function dataGetL10nFilesForApp(): array {
return [ return [
[null, 'de', [\OC::$SERVERROOT . '/core/l10n/de.json']], ['', 'de', [\OC::$SERVERROOT . '/core/l10n/de.json']],
['core', 'ru', [\OC::$SERVERROOT . '/core/l10n/ru.json']], ['core', 'ru', [\OC::$SERVERROOT . '/core/l10n/ru.json']],
['lib', 'ru', [\OC::$SERVERROOT . '/lib/l10n/ru.json']], ['lib', 'ru', [\OC::$SERVERROOT . '/lib/l10n/ru.json']],
['settings', 'de', [\OC::$SERVERROOT . '/apps/settings/l10n/de.json']], ['settings', 'de', [\OC::$SERVERROOT . '/apps/settings/l10n/de.json']],
@ -415,17 +422,28 @@ class FactoryTest extends TestCase {
/** /**
* @dataProvider dataGetL10nFilesForApp * @dataProvider dataGetL10nFilesForApp
* *
* @param string|null $app * @param string $app
* @param string $expected * @param string $expected
*/ */
public function testGetL10nFilesForApp($app, $lang, $expected): void { public function testGetL10nFilesForApp($app, $lang, $expected): void {
$factory = $this->getFactory(); $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])); self::assertSame($expected, $this->invokePrivate($factory, 'getL10nFilesForApp', [$app, $lang]));
} }
public function dataFindL10NDir(): array { public function dataFindL10NDir(): array {
return [ return [
[null, \OC::$SERVERROOT . '/core/l10n/'], ['', \OC::$SERVERROOT . '/core/l10n/'],
['core', \OC::$SERVERROOT . '/core/l10n/'], ['core', \OC::$SERVERROOT . '/core/l10n/'],
['lib', \OC::$SERVERROOT . '/lib/l10n/'], ['lib', \OC::$SERVERROOT . '/lib/l10n/'],
['settings', \OC::$SERVERROOT . '/apps/settings/l10n/'], ['settings', \OC::$SERVERROOT . '/apps/settings/l10n/'],
@ -437,11 +455,22 @@ class FactoryTest extends TestCase {
/** /**
* @dataProvider dataFindL10NDir * @dataProvider dataFindL10NDir
* *
* @param string|null $app * @param string $app
* @param string $expected * @param string $expected
*/ */
public function testFindL10NDir($app, $expected): void { public function testFindL10NDir($app, $expected): void {
$factory = $this->getFactory(); $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])); self::assertSame($expected, $this->invokePrivate($factory, 'findL10nDir', [$app]));
} }

View File

@ -11,6 +11,7 @@ namespace Test\L10N;
use DateTime; use DateTime;
use OC\L10N\Factory; use OC\L10N\Factory;
use OC\L10N\L10N; use OC\L10N\L10N;
use OCP\App\IAppManager;
use OCP\ICacheFactory; use OCP\ICacheFactory;
use OCP\IConfig; use OCP\IConfig;
use OCP\IRequest; use OCP\IRequest;
@ -34,7 +35,8 @@ class L10nTest extends TestCase {
/** @var IUserSession $userSession */ /** @var IUserSession $userSession */
$userSession = $this->createMock(IUserSession::class); $userSession = $this->createMock(IUserSession::class);
$cacheFactory = $this->createMock(ICacheFactory::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 { public function testSimpleTranslationWithTrailingColon(): void {

View File

@ -24,6 +24,7 @@ declare(strict_types=1);
namespace Test\Route; namespace Test\Route;
use OC\Route\Router; use OC\Route\Router;
use OCP\App\IAppManager;
use OCP\Diagnostics\IEventLogger; use OCP\Diagnostics\IEventLogger;
use OCP\IConfig; use OCP\IConfig;
use OCP\IRequest; use OCP\IRequest;
@ -54,6 +55,7 @@ class RouterTest extends TestCase {
$this->createMock(IConfig::class), $this->createMock(IConfig::class),
$this->createMock(IEventLogger::class), $this->createMock(IEventLogger::class),
$this->createMock(ContainerInterface::class), $this->createMock(ContainerInterface::class),
$this->createMock(IAppManager::class),
); );
$this->assertEquals('/index.php/apps/files/', $router->generate('files.view.index')); $this->assertEquals('/index.php/apps/files/', $router->generate('files.view.index'));