aboutsummaryrefslogtreecommitdiffstats
path: root/lib/private/App/AppManager.php
diff options
context:
space:
mode:
authorCôme Chilliet <come.chilliet@nextcloud.com>2023-02-07 16:56:04 +0100
committerCôme Chilliet <come.chilliet@nextcloud.com>2023-03-20 10:01:17 +0100
commita7c8090dc3c47c79ed9e7e22967cba7d124f0fa7 (patch)
tree45c7cfba209002f804f735a6a72cd41f1e8edee1 /lib/private/App/AppManager.php
parent07448168dcce5972678473346bf2861ee3f1559b (diff)
downloadnextcloud-server-a7c8090dc3c47c79ed9e7e22967cba7d124f0fa7.tar.gz
nextcloud-server-a7c8090dc3c47c79ed9e7e22967cba7d124f0fa7.zip
Move loadApp function to the AppManager
Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
Diffstat (limited to 'lib/private/App/AppManager.php')
-rw-r--r--lib/private/App/AppManager.php139
1 files changed, 139 insertions, 0 deletions
diff --git a/lib/private/App/AppManager.php b/lib/private/App/AppManager.php
index 0a89711f178..0b0bcecb5dc 100644
--- a/lib/private/App/AppManager.php
+++ b/lib/private/App/AppManager.php
@@ -39,6 +39,8 @@
namespace OC\App;
use OC\AppConfig;
+use OC\AppFramework\Bootstrap\Coordinator;
+use OC\ServerNotAvailableException;
use OCP\App\AppPathNotFoundException;
use OCP\App\Events\AppDisableEvent;
use OCP\App\Events\AppEnableEvent;
@@ -51,6 +53,7 @@ use OCP\IGroup;
use OCP\IGroupManager;
use OCP\IUser;
use OCP\IUserSession;
+use OCP\Settings\IManager as ISettingsManager;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
@@ -108,6 +111,9 @@ class AppManager implements IAppManager {
/** @var array */
private $autoDisabledApps = [];
+ /** @var array<string, true> */
+ private array $loadedApps = [];
+
public function __construct(IUserSession $userSession,
IConfig $config,
AppConfig $appConfig,
@@ -310,6 +316,139 @@ class AppManager implements IAppManager {
}
}
+ public function loadApp(string $app): void {
+ if (isset($this->loadedApps[$app])) {
+ return;
+ }
+ $this->loadedApps[$app] = true;
+ $appPath = \OC_App::getAppPath($app);
+ if ($appPath === false) {
+ return;
+ }
+ $eventLogger = \OC::$server->get(\OCP\Diagnostics\IEventLogger::class);
+ $eventLogger->start("bootstrap:load_app:$app", "Load $app");
+
+ // in case someone calls loadApp() directly
+ \OC_App::registerAutoloading($app, $appPath);
+
+ /** @var Coordinator $coordinator */
+ $coordinator = \OC::$server->get(Coordinator::class);
+ $isBootable = $coordinator->isBootable($app);
+
+ $hasAppPhpFile = is_file($appPath . '/appinfo/app.php');
+
+ if ($isBootable && $hasAppPhpFile) {
+ \OC::$server->getLogger()->error('/appinfo/app.php is not loaded when \OCP\AppFramework\Bootstrap\IBootstrap on the application class is used. Migrate everything from app.php to the Application class.', [
+ 'app' => $app,
+ ]);
+ } elseif ($hasAppPhpFile) {
+ $eventLogger->start("bootstrap:load_app:$app:app.php", "Load legacy app.php app $app");
+ \OC::$server->getLogger()->debug('/appinfo/app.php is deprecated, use \OCP\AppFramework\Bootstrap\IBootstrap on the application class instead.', [
+ 'app' => $app,
+ ]);
+ try {
+ self::requireAppFile($appPath);
+ } catch (\Throwable $ex) {
+ if ($ex instanceof ServerNotAvailableException) {
+ throw $ex;
+ }
+ if (!\OC::$server->getAppManager()->isShipped($app) && !self::isType($app, ['authentication'])) {
+ \OC::$server->getLogger()->logException($ex, [
+ 'message' => "App $app threw an error during app.php load and will be disabled: " . $ex->getMessage(),
+ ]);
+
+ // Only disable apps which are not shipped and that are not authentication apps
+ \OC::$server->getAppManager()->disableApp($app, true);
+ } else {
+ \OC::$server->getLogger()->logException($ex, [
+ 'message' => "App $app threw an error during app.php load: " . $ex->getMessage(),
+ ]);
+ }
+ }
+ $eventLogger->end("bootstrap:load_app:$app:app.php");
+ }
+
+ $coordinator->bootApp($app);
+
+ $eventLogger->start("bootstrap:load_app:$app:info", "Load info.xml for $app and register any services defined in it");
+ $info = self::getAppInfo($app);
+ if (!empty($info['activity']['filters'])) {
+ foreach ($info['activity']['filters'] as $filter) {
+ \OC::$server->getActivityManager()->registerFilter($filter);
+ }
+ }
+ if (!empty($info['activity']['settings'])) {
+ foreach ($info['activity']['settings'] as $setting) {
+ \OC::$server->getActivityManager()->registerSetting($setting);
+ }
+ }
+ if (!empty($info['activity']['providers'])) {
+ foreach ($info['activity']['providers'] as $provider) {
+ \OC::$server->getActivityManager()->registerProvider($provider);
+ }
+ }
+
+ if (!empty($info['settings']['admin'])) {
+ foreach ($info['settings']['admin'] as $setting) {
+ \OC::$server->get(ISettingsManager::class)->registerSetting('admin', $setting);
+ }
+ }
+ if (!empty($info['settings']['admin-section'])) {
+ foreach ($info['settings']['admin-section'] as $section) {
+ \OC::$server->get(ISettingsManager::class)->registerSection('admin', $section);
+ }
+ }
+ if (!empty($info['settings']['personal'])) {
+ foreach ($info['settings']['personal'] as $setting) {
+ \OC::$server->get(ISettingsManager::class)->registerSetting('personal', $setting);
+ }
+ }
+ if (!empty($info['settings']['personal-section'])) {
+ foreach ($info['settings']['personal-section'] as $section) {
+ \OC::$server->get(ISettingsManager::class)->registerSection('personal', $section);
+ }
+ }
+
+ if (!empty($info['collaboration']['plugins'])) {
+ // deal with one or many plugin entries
+ $plugins = isset($info['collaboration']['plugins']['plugin']['@value']) ?
+ [$info['collaboration']['plugins']['plugin']] : $info['collaboration']['plugins']['plugin'];
+ foreach ($plugins as $plugin) {
+ if ($plugin['@attributes']['type'] === 'collaborator-search') {
+ $pluginInfo = [
+ 'shareType' => $plugin['@attributes']['share-type'],
+ 'class' => $plugin['@value'],
+ ];
+ \OC::$server->getCollaboratorSearch()->registerPlugin($pluginInfo);
+ } elseif ($plugin['@attributes']['type'] === 'autocomplete-sort') {
+ \OC::$server->getAutoCompleteManager()->registerSorter($plugin['@value']);
+ }
+ }
+ }
+ $eventLogger->end("bootstrap:load_app:$app:info");
+
+ $eventLogger->end("bootstrap:load_app:$app");
+ }
+ /**
+ * Check if an app is loaded
+ * @param string $app app id
+ * @since 26.0.0
+ */
+ public function isAppLoaded(string $app): bool {
+ return isset($this->loadedApps[$app]);
+ }
+
+ /**
+ * Load app.php from the given app
+ *
+ * @param string $app app name
+ * @throws \Error
+ */
+ private static function requireAppFile(string $app): void {
+ // encapsulated here to avoid variable scope conflicts
+ require_once $app . '/appinfo/app.php';
+ }
+
/**
* Enable an app for every user
*