chore: Move getAppPath and getAppWebPath implementations into AppManager

Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
This commit is contained in:
Côme Chilliet 2025-07-29 17:47:40 +02:00
parent 3e01a429e7
commit e5606d7fe3
No known key found for this signature in database
GPG key ID: A3E2F658B28C760A
2 changed files with 81 additions and 64 deletions

View file

@ -678,29 +678,87 @@ class AppManager implements IAppManager {
/**
* Get the directory for the given app.
*
* @psalm-taint-specialize
*
* @throws AppPathNotFoundException if app folder can't be found
*/
public function getAppPath(string $appId, bool $ignoreCache = false): string {
$appPath = \OC_App::getAppPath($appId, $ignoreCache);
if ($appPath === false) {
throw new AppPathNotFoundException('Could not find path for ' . $appId);
$appId = $this->cleanAppId($appId);
if ($appId === '') {
throw new AppPathNotFoundException('App id is empty');
} elseif ($appId === 'core') {
return __DIR__ . '/../../../core';
}
return $appPath;
if (($dir = $this->findAppInDirectories($appId, $ignoreCache)) != false) {
return $dir['path'] . '/' . $appId;
}
throw new AppPathNotFoundException('Could not find path for ' . $appId);
}
/**
* Get the web path for the given app.
*
* @param string $appId
* @return string
* @throws AppPathNotFoundException if app path can't be found
*/
public function getAppWebPath(string $appId): string {
$appWebPath = \OC_App::getAppWebPath($appId);
if ($appWebPath === false) {
throw new AppPathNotFoundException('Could not find web path for ' . $appId);
if (($dir = $this->findAppInDirectories($appId)) != false) {
return \OC::$WEBROOT . $dir['url'] . '/' . $appId;
}
throw new AppPathNotFoundException('Could not find web path for ' . $appId);
}
/**
* Find the apps root for an app id.
*
* If multiple copies are found, the apps root the latest version is returned.
*
* @param bool $ignoreCache ignore cache and rebuild it
* @return false|array{path: string, url: string} the apps root shape
*/
public function findAppInDirectories(string $appId, bool $ignoreCache = false) {
$sanitizedAppId = $this->cleanAppId($appId);
if ($sanitizedAppId !== $appId) {
return false;
}
// FIXME replace by a property or a cache
static $app_dir = [];
if (isset($app_dir[$appId]) && !$ignoreCache) {
return $app_dir[$appId];
}
$possibleApps = [];
foreach (\OC::$APPSROOTS as $dir) {
if (file_exists($dir['path'] . '/' . $appId)) {
$possibleApps[] = $dir;
}
}
if (empty($possibleApps)) {
return false;
} elseif (count($possibleApps) === 1) {
$dir = array_shift($possibleApps);
$app_dir[$appId] = $dir;
return $dir;
} else {
$versionToLoad = [];
foreach ($possibleApps as $possibleApp) {
$appData = $this->getAppInfoByPath($possibleApp['path'] . '/' . $appId . '/appinfo/info.xml');
$version = $appData['version'] ?? '';
if (empty($versionToLoad) || version_compare($version, $versionToLoad['version'], '>')) {
$versionToLoad = [
'dir' => $possibleApp,
'version' => $version,
];
}
}
if (!isset($versionToLoad['dir'])) {
return false;
}
$app_dir[$appId] = $versionToLoad['dir'];
return $versionToLoad['dir'];
}
return $appWebPath;
}
/**

View file

@ -6,12 +6,14 @@ declare(strict_types=1);
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
* SPDX-License-Identifier: AGPL-3.0-only
*/
use OC\App\AppManager;
use OC\App\DependencyAnalyzer;
use OC\App\Platform;
use OC\AppFramework\Bootstrap\Coordinator;
use OC\Installer;
use OC\Repair;
use OC\Repair\Events\RepairErrorEvent;
use OCP\App\AppPathNotFoundException;
use OCP\App\IAppManager;
use OCP\Authentication\IAlternativeLogin;
use OCP\EventDispatcher\IEventDispatcher;
@ -239,49 +241,12 @@ class OC_App {
*
* If multiple copies are found, the apps root the latest version is returned.
*
* @param string $appId
* @param bool $ignoreCache ignore cache and rebuild it
* @return false|array{path: string, url: string} the apps root shape
* @deprecated 32.0.0 internal, use getAppPath or getAppWebPath
*/
public static function findAppInDirectories(string $appId, bool $ignoreCache = false) {
$sanitizedAppId = self::cleanAppId($appId);
if ($sanitizedAppId !== $appId) {
return false;
}
static $app_dir = [];
if (isset($app_dir[$appId]) && !$ignoreCache) {
return $app_dir[$appId];
}
$possibleApps = [];
foreach (OC::$APPSROOTS as $dir) {
if (file_exists($dir['path'] . '/' . $appId)) {
$possibleApps[] = $dir;
}
}
if (empty($possibleApps)) {
return false;
} elseif (count($possibleApps) === 1) {
$dir = array_shift($possibleApps);
$app_dir[$appId] = $dir;
return $dir;
} else {
$versionToLoad = [];
foreach ($possibleApps as $possibleApp) {
$version = self::getAppVersionByPath($possibleApp['path'] . '/' . $appId);
if (empty($versionToLoad) || version_compare($version, $versionToLoad['version'], '>')) {
$versionToLoad = [
'dir' => $possibleApp,
'version' => $version,
];
}
}
$app_dir[$appId] = $versionToLoad['dir'];
return $versionToLoad['dir'];
//TODO - write test
}
return Server::get(AppManager::class)->findAppInDirectories($appId, $ignoreCache);
}
/**
@ -296,17 +261,11 @@ class OC_App {
* @deprecated 11.0.0 use Server::get(IAppManager)->getAppPath()
*/
public static function getAppPath(string $appId, bool $refreshAppPath = false) {
$appId = self::cleanAppId($appId);
if ($appId === '') {
try {
return Server::get(IAppManager::class)->getAppPath($appId, $refreshAppPath);
} catch (AppPathNotFoundException) {
return false;
} elseif ($appId === 'core') {
return __DIR__ . '/../../../core';
}
if (($dir = self::findAppInDirectories($appId, $refreshAppPath)) != false) {
return $dir['path'] . '/' . $appId;
}
return false;
}
/**
@ -315,20 +274,20 @@ class OC_App {
*
* @param string $appId
* @return string|false
* @deprecated 18.0.0 use \OC::$server->getAppManager()->getAppWebPath()
* @deprecated 18.0.0 use Server::get(IAppManager)->getAppWebPath()
*/
public static function getAppWebPath(string $appId) {
if (($dir = self::findAppInDirectories($appId)) != false) {
return OC::$WEBROOT . $dir['url'] . '/' . $appId;
try {
return Server::get(IAppManager::class)->getAppWebPath($appId);
} catch (AppPathNotFoundException) {
return false;
}
return false;
}
/**
* get app's version based on it's path
*
* @param string $path
* @return string
* @deprecated 32.0.0 use Server::get(IAppManager)->getAppInfoByPath() with the path to info.xml directly
*/
public static function getAppVersionByPath(string $path): string {
$infoFile = $path . '/appinfo/info.xml';