mirror of
https://github.com/nextcloud/server.git
synced 2026-06-10 09:13:19 -04:00
fix: Add proper methods in IAppManager for namespace handling
Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
This commit is contained in:
parent
7c7b53163a
commit
bdfe8ed77e
10 changed files with 81 additions and 37 deletions
|
|
@ -76,6 +76,9 @@ class AppManager implements IAppManager {
|
|||
/** @var array<string, true> */
|
||||
private array $loadedApps = [];
|
||||
|
||||
/** @var string[] */
|
||||
private $namespaceCache = [];
|
||||
|
||||
private ?AppConfig $appConfig = null;
|
||||
private ?IURLGenerator $urlGenerator = null;
|
||||
private ?INavigationManager $navigationManager = null;
|
||||
|
|
@ -1197,4 +1200,44 @@ class AppManager implements IAppManager {
|
|||
public function isAppCompatible(string $serverVersion, array $appInfo, bool $ignoreMax = false): bool {
|
||||
return count($this->dependencyAnalyzer->analyzeServerVersion($serverVersion, $appInfo, $ignoreMax)) === 0;
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function getAppNamespace(string $appId): string {
|
||||
$topNamespace = 'OCA\\';
|
||||
|
||||
// Hit the cache!
|
||||
if (isset($this->namespaceCache[$appId])) {
|
||||
return $topNamespace . $this->namespaceCache[$appId];
|
||||
}
|
||||
|
||||
$appInfo = $this->getAppInfo($appId);
|
||||
if (isset($appInfo['namespace'])) {
|
||||
$this->namespaceCache[$appId] = trim($appInfo['namespace']);
|
||||
} else {
|
||||
// If the tag is not found, fall back to uppercasing the first letter
|
||||
$this->namespaceCache[$appId] = ucfirst($appId);
|
||||
}
|
||||
|
||||
return $topNamespace . $this->namespaceCache[$appId];
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function getAppFromNamespace(string $className): ?string {
|
||||
$topNamespace = 'OCA\\';
|
||||
|
||||
if (str_starts_with($className, 'OC\\Core')) {
|
||||
return 'core';
|
||||
}
|
||||
if (!str_starts_with($className, $topNamespace)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach ($this->namespaceCache as $appId => $namespace) {
|
||||
if (str_starts_with($className, $topNamespace . $namespace . '\\')) {
|
||||
return $appId;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,9 +30,6 @@ use OCP\Server;
|
|||
* Handles all the dependency injection, controllers and output flow
|
||||
*/
|
||||
class App {
|
||||
/** @var string[] */
|
||||
private static $nameSpaceCache = [];
|
||||
|
||||
/**
|
||||
* Turns an app id into a namespace by either reading the appinfo.xml's
|
||||
* namespace tag or uppercasing the appid's first letter
|
||||
|
|
@ -40,36 +37,22 @@ class App {
|
|||
* @param string $topNamespace the namespace which should be prepended to
|
||||
* the transformed app id, defaults to OCA\
|
||||
* @return string the starting namespace for the app
|
||||
* @deprecated 34.0.0 use IAppManager::getAppNamespace
|
||||
*/
|
||||
public static function buildAppNamespace(string $appId, string $topNamespace = 'OCA\\'): string {
|
||||
// Hit the cache!
|
||||
if (isset(self::$nameSpaceCache[$appId])) {
|
||||
return $topNamespace . self::$nameSpaceCache[$appId];
|
||||
$appManager = Server::get(IAppManager::class);
|
||||
$namespace = $appManager->getAppNamespace($appId);
|
||||
if ($topNamespace !== 'OCA\\') {
|
||||
return $topNamespace . substr($namespace, strlen('OCA\\'));
|
||||
}
|
||||
|
||||
$appInfo = Server::get(IAppManager::class)->getAppInfo($appId);
|
||||
if (isset($appInfo['namespace'])) {
|
||||
self::$nameSpaceCache[$appId] = trim($appInfo['namespace']);
|
||||
} else {
|
||||
// if the tag is not found, fall back to uppercasing the first letter
|
||||
self::$nameSpaceCache[$appId] = ucfirst($appId);
|
||||
}
|
||||
|
||||
return $topNamespace . self::$nameSpaceCache[$appId];
|
||||
return $namespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 34.0.0 use IAppManager::getAppFromNamespace
|
||||
*/
|
||||
public static function getAppIdForClass(string $className, string $topNamespace = 'OCA\\'): ?string {
|
||||
if (!str_starts_with($className, $topNamespace)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach (self::$nameSpaceCache as $appId => $namespace) {
|
||||
if (str_starts_with($className, $topNamespace . $namespace . '\\')) {
|
||||
return $appId;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
return Server::get(IAppManager::class)->getAppFromNamespace($className);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ class Coordinator {
|
|||
if ($appId === 'core') {
|
||||
$appNameSpace = 'OC\\Core';
|
||||
} else {
|
||||
$appNameSpace = App::buildAppNamespace($appId);
|
||||
$appNameSpace = $this->appManager->getAppNamespace($appId);
|
||||
}
|
||||
$applicationClassName = $appNameSpace . '\\AppInfo\\Application';
|
||||
|
||||
|
|
@ -147,7 +147,7 @@ class Coordinator {
|
|||
}
|
||||
$this->bootedApps[$appId] = true;
|
||||
|
||||
$appNameSpace = App::buildAppNamespace($appId);
|
||||
$appNameSpace = $this->appManager->getAppNamespace($appId);
|
||||
$applicationClassName = $appNameSpace . '\\AppInfo\\Application';
|
||||
if (!class_exists($applicationClassName)) {
|
||||
// Nothing to boot
|
||||
|
|
@ -181,8 +181,8 @@ class Coordinator {
|
|||
$this->eventLogger->end('bootstrap:boot_app:' . $appId);
|
||||
}
|
||||
|
||||
public function isBootable(string $appId) {
|
||||
$appNameSpace = App::buildAppNamespace($appId);
|
||||
public function isBootable(string $appId): bool {
|
||||
$appNameSpace = $this->appManager->getAppNamespace($appId);
|
||||
$applicationClassName = $appNameSpace . '\\AppInfo\\Application';
|
||||
return class_exists($applicationClassName)
|
||||
&& in_array(IBootstrap::class, class_implements($applicationClassName), true);
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ use Psr\Log\LoggerInterface;
|
|||
class DIContainer extends SimpleContainer implements IAppContainer {
|
||||
private array $middleWares = [];
|
||||
private ServerContainer $server;
|
||||
private IAppManager $appManager;
|
||||
|
||||
public function __construct(
|
||||
protected string $appName,
|
||||
|
|
@ -93,6 +94,7 @@ class DIContainer extends SimpleContainer implements IAppContainer {
|
|||
$server = \OC::$server;
|
||||
}
|
||||
$this->server = $server;
|
||||
$this->appManager = $this->server->get(IAppManager::class);
|
||||
$this->server->registerAppContainer($this->appName, $this);
|
||||
|
||||
// aliases
|
||||
|
|
@ -363,6 +365,7 @@ class DIContainer extends SimpleContainer implements IAppContainer {
|
|||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param list<class-string> $chain
|
||||
* @return mixed
|
||||
* @throws QueryException if the query could not be resolved
|
||||
*/
|
||||
|
|
@ -375,7 +378,7 @@ class DIContainer extends SimpleContainer implements IAppContainer {
|
|||
return parent::query($name, chain: $chain);
|
||||
} elseif ($this->appName === 'core' && str_starts_with($name, 'OC\\Core\\')) {
|
||||
return parent::query($name, chain: $chain);
|
||||
} elseif (str_starts_with($name, App::buildAppNamespace($this->appName) . '\\')) {
|
||||
} elseif (str_starts_with($name, $this->appManager->getAppNamespace($this->appName) . '\\')) {
|
||||
return parent::query($name, chain: $chain);
|
||||
} elseif (
|
||||
str_starts_with($name, 'OC\\AppFramework\\Services\\')
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ class MigrationService {
|
|||
} else {
|
||||
$appManager = Server::get(IAppManager::class);
|
||||
$appPath = $appManager->getAppPath($this->appName);
|
||||
$namespace = App::buildAppNamespace($this->appName);
|
||||
$namespace = $appManager->getAppNamespace($this->appName);
|
||||
$this->migrationsPath = "$appPath/lib/Migration";
|
||||
$this->migrationsNamespace = $namespace . '\\Migration';
|
||||
|
||||
|
|
|
|||
|
|
@ -483,7 +483,7 @@ class Router implements IRouter {
|
|||
} catch (AppPathNotFoundException) {
|
||||
return [];
|
||||
}
|
||||
$appNameSpace = App::buildAppNamespace($app);
|
||||
$appNameSpace = $this->appManager->getAppNamespace($app);
|
||||
}
|
||||
|
||||
if (!file_exists($appControllerPath)) {
|
||||
|
|
@ -553,7 +553,7 @@ class Router implements IRouter {
|
|||
}
|
||||
|
||||
private function getApplicationClass(string $appName) {
|
||||
$appNameSpace = App::buildAppNamespace($appName);
|
||||
$appNameSpace = $this->appManager->getAppNamespace($appName);
|
||||
|
||||
$applicationClassName = $appNameSpace . '\\AppInfo\\Application';
|
||||
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ class OC_App {
|
|||
self::$alreadyRegistered[$key] = true;
|
||||
|
||||
// Register on PSR-4 composer autoloader
|
||||
$appNamespace = App::buildAppNamespace($app);
|
||||
$appNamespace = Server::get(IAppManager::class)->getAppNamespace($app);
|
||||
\OC::$server->registerNamespace($app, $appNamespace);
|
||||
|
||||
if (file_exists($path . '/composer/autoload.php')) {
|
||||
|
|
|
|||
|
|
@ -373,4 +373,18 @@ interface IAppManager {
|
|||
* @since 32.0.0
|
||||
*/
|
||||
public function isAppCompatible(string $serverVersion, array $appInfo, bool $ignoreMax = false): bool;
|
||||
|
||||
/**
|
||||
* Get the app namespace
|
||||
*
|
||||
* @since 34.0.0
|
||||
*/
|
||||
public function getAppNamespace(string $appId): string;
|
||||
|
||||
/**
|
||||
* Get the app id for this namespace
|
||||
*
|
||||
* @since 34.0.0
|
||||
*/
|
||||
public function getAppFromNamespace(string $className): ?string;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ class App {
|
|||
* the transformed app id, defaults to OCA\
|
||||
* @return string the starting namespace for the app
|
||||
* @since 8.0.0
|
||||
* @deprecated 34.0.0 use IAppManager::getAppNamespace
|
||||
*/
|
||||
public static function buildAppNamespace(string $appId, string $topNamespace = 'OCA\\'): string {
|
||||
return \OC\AppFramework\App::buildAppNamespace($appId, $topNamespace);
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ class InfoXmlTest extends TestCase {
|
|||
\OC_App::registerAutoloading($app, $appPath);
|
||||
|
||||
//Add the appcontainer
|
||||
$applicationClassName = App::buildAppNamespace($app) . '\\AppInfo\\Application';
|
||||
$applicationClassName = $this->appManager->getAppNamespace($app) . '\\AppInfo\\Application';
|
||||
if (class_exists($applicationClassName)) {
|
||||
$application = new $applicationClassName();
|
||||
$this->addToAssertionCount(1);
|
||||
|
|
|
|||
Loading…
Reference in a new issue