Migrate away from OC_App and toward IAppManager.pull/44968/head
@@ -402,7 +402,7 @@ class AppSettingsController extends Controller { | |||
try { | |||
$this->appManager->getAppPath($app['id']); | |||
$existsLocally = true; | |||
} catch (AppPathNotFoundException $e) { | |||
} catch (AppPathNotFoundException) { | |||
$existsLocally = false; | |||
} | |||
@@ -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) { |
@@ -1,4 +1,7 @@ | |||
<?php | |||
declare(strict_types=1); | |||
/** | |||
* @copyright Copyright (c) 2016, ownCloud, Inc. | |||
* |
@@ -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; | |||
} | |||
/** |
@@ -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'); | |||
} | |||
@@ -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 []; | |||
} |
@@ -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'); | |||
} | |||
} |
@@ -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); |
@@ -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 |
@@ -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, '>') |
@@ -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; | |||
} |
@@ -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']); |
@@ -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); |
@@ -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/'; | |||
} |
@@ -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); | |||
} | |||
/** |
@@ -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 */ | |||
} | |||
} | |||
} |
@@ -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 */ |
@@ -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) === '') { |
@@ -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(); |
@@ -83,7 +83,8 @@ class CoordinatorTest extends TestCase { | |||
$this->dashboardManager, | |||
$this->eventDispatcher, | |||
$this->eventLogger, | |||
$this->logger | |||
$this->appManager, | |||
$this->logger, | |||
); | |||
} | |||
@@ -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(); | |||
@@ -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), |
@@ -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])); | |||
} | |||
@@ -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 { |
@@ -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')); |