]> source.dussan.org Git - nextcloud-server.git/commitdiff
Move loadApp function to the AppManager
authorCôme Chilliet <come.chilliet@nextcloud.com>
Tue, 7 Feb 2023 15:56:04 +0000 (16:56 +0100)
committerCôme Chilliet <come.chilliet@nextcloud.com>
Mon, 20 Mar 2023 09:01:17 +0000 (10:01 +0100)
Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
lib/private/App/AppManager.php
lib/private/legacy/OC_App.php
lib/public/App/IAppManager.php

index 0a89711f1789835cfb27110dea64df5dca24d746..0b0bcecb5dcf48c5d85343bcdaf101fd4e0ab76d 100644 (file)
@@ -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
         *
index 3c255e916617822e3233e6e6eb60c922a4242d05..01bce05788163738a3968e39e45a925a1f419858 100644 (file)
@@ -53,11 +53,11 @@ declare(strict_types=1);
 
 use OCP\App\Events\AppUpdateEvent;
 use OCP\AppFramework\QueryException;
+use OCP\App\IAppManager;
 use OCP\App\ManagerEvent;
 use OCP\Authentication\IAlternativeLogin;
 use OCP\EventDispatcher\IEventDispatcher;
 use OCP\ILogger;
-use OCP\Settings\IManager as ISettingsManager;
 use OC\AppFramework\Bootstrap\Coordinator;
 use OC\App\DependencyAnalyzer;
 use OC\App\Platform;
@@ -65,7 +65,6 @@ use OC\DB\MigrationService;
 use OC\Installer;
 use OC\Repair;
 use OC\Repair\Events\RepairErrorEvent;
-use OC\ServerNotAvailableException;
 use Psr\Log\LoggerInterface;
 
 /**
@@ -77,7 +76,6 @@ class OC_App {
        private static $adminForms = [];
        private static $personalForms = [];
        private static $appTypes = [];
-       private static $loadedApps = [];
        private static $altLogin = [];
        private static $alreadyRegistered = [];
        public const supportedApp = 300;
@@ -103,7 +101,7 @@ class OC_App {
         * @return bool
         */
        public static function isAppLoaded(string $app): bool {
-               return isset(self::$loadedApps[$app]);
+               return \OC::$server->get(IAppManager::class)->isAppLoaded($app);
        }
 
        /**
@@ -128,7 +126,7 @@ class OC_App {
                // Add each apps' folder as allowed class path
                foreach ($apps as $app) {
                        // If the app is already loaded then autoloading it makes no sense
-                       if (!isset(self::$loadedApps[$app])) {
+                       if (!self::isAppLoaded($app)) {
                                $path = self::getAppPath($app);
                                if ($path !== false) {
                                        self::registerAutoloading($app, $path);
@@ -139,7 +137,7 @@ class OC_App {
                // prevent app.php from printing output
                ob_start();
                foreach ($apps as $app) {
-                       if (!isset(self::$loadedApps[$app]) && ($types === [] || self::isType($app, $types))) {
+                       if (!self::isAppLoaded($app) && ($types === [] || self::isType($app, $types))) {
                                try {
                                        self::loadApp($app);
                                } catch (\Throwable $e) {
@@ -162,118 +160,7 @@ class OC_App {
         * @throws Exception
         */
        public static function loadApp(string $app): void {
-               if (isset(self::$loadedApps[$app])) {
-                       return;
-               }
-               self::$loadedApps[$app] = true;
-               $appPath = self::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
-               self::registerAutoloading($app, $appPath);
-
-               /** @var Coordinator $coordinator */
-               $coordinator = \OC::$server->query(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");
+               \OC::$server->get(IAppManager::class)->loadApp($app);
        }
 
        /**
@@ -306,17 +193,6 @@ class OC_App {
                }
        }
 
-       /**
-        * Load app.php from the given app
-        *
-        * @param string $app app name
-        * @throws Error
-        */
-       private static function requireAppFile(string $app) {
-               // encapsulated here to avoid variable scope conflicts
-               require_once $app . '/appinfo/app.php';
-       }
-
        /**
         * check if an app is of a specific type
         *
index de36fafcdfeb77c4e8d3a7193633a0e58a711298..51bd5845b7c79984b7afb0bd0b210cd31bbe0345 100644 (file)
@@ -93,6 +93,20 @@ interface IAppManager {
         */
        public function isDefaultEnabled(string $appId):bool;
 
+       /**
+        * Load an app, if not already loaded
+        * @param string $app app id
+        * @since 26.0.0
+        */
+       public function loadApp(string $app): void;
+
+       /**
+        * Check if an app is loaded
+        * @param string $app app id
+        * @since 26.0.0
+        */
+       public function isAppLoaded(string $app): bool;
+
        /**
         * Enable an app for every user
         *