aboutsummaryrefslogtreecommitdiffstats
path: root/lib/private/App
diff options
context:
space:
mode:
Diffstat (limited to 'lib/private/App')
-rw-r--r--lib/private/App/AppManager.php51
-rw-r--r--lib/private/App/AppStore/AppNotFoundException.php13
-rw-r--r--lib/private/App/AppStore/Bundles/Bundle.php1
-rw-r--r--lib/private/App/AppStore/Bundles/BundleFetcher.php1
-rw-r--r--lib/private/App/AppStore/Bundles/EducationBundle.php1
-rw-r--r--lib/private/App/AppStore/Bundles/EnterpriseBundle.php1
-rw-r--r--lib/private/App/AppStore/Bundles/GroupwareBundle.php1
-rw-r--r--lib/private/App/AppStore/Bundles/PublicSectorBundle.php1
-rw-r--r--lib/private/App/AppStore/Bundles/SocialSharingBundle.php1
-rw-r--r--lib/private/App/AppStore/Fetcher/AppDiscoverFetcher.php1
-rw-r--r--lib/private/App/AppStore/Fetcher/AppFetcher.php5
-rw-r--r--lib/private/App/AppStore/Fetcher/CategoryFetcher.php1
-rw-r--r--lib/private/App/AppStore/Fetcher/Fetcher.php1
-rw-r--r--lib/private/App/AppStore/Version/Version.php1
-rw-r--r--lib/private/App/AppStore/Version/VersionParser.php1
-rw-r--r--lib/private/App/DependencyAnalyzer.php109
-rw-r--r--lib/private/App/InfoParser.php112
-rw-r--r--lib/private/App/Platform.php1
-rw-r--r--lib/private/App/PlatformRepository.php1
19 files changed, 185 insertions, 119 deletions
diff --git a/lib/private/App/AppManager.php b/lib/private/App/AppManager.php
index f6494fa946d..7778393b3b3 100644
--- a/lib/private/App/AppManager.php
+++ b/lib/private/App/AppManager.php
@@ -1,4 +1,5 @@
<?php
+
/**
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
@@ -8,6 +9,7 @@ namespace OC\App;
use OC\AppConfig;
use OC\AppFramework\Bootstrap\Coordinator;
+use OC\Config\ConfigManager;
use OCP\Activity\IManager as IActivityManager;
use OCP\App\AppPathNotFoundException;
use OCP\App\Events\AppDisableEvent;
@@ -18,6 +20,7 @@ use OCP\Collaboration\AutoComplete\IManager as IAutoCompleteManager;
use OCP\Collaboration\Collaborators\ISearch as ICollaboratorSearch;
use OCP\Diagnostics\IEventLogger;
use OCP\EventDispatcher\IEventDispatcher;
+use OCP\IAppConfig;
use OCP\ICacheFactory;
use OCP\IConfig;
use OCP\IGroup;
@@ -26,6 +29,7 @@ use OCP\INavigationManager;
use OCP\IURLGenerator;
use OCP\IUser;
use OCP\IUserSession;
+use OCP\Server;
use OCP\ServerVersion;
use OCP\Settings\IManager as ISettingsManager;
use Psr\Log\LoggerInterface;
@@ -81,12 +85,13 @@ class AppManager implements IAppManager {
private IEventDispatcher $dispatcher,
private LoggerInterface $logger,
private ServerVersion $serverVersion,
+ private ConfigManager $configManager,
) {
}
private function getNavigationManager(): INavigationManager {
if ($this->navigationManager === null) {
- $this->navigationManager = \OCP\Server::get(INavigationManager::class);
+ $this->navigationManager = Server::get(INavigationManager::class);
}
return $this->navigationManager;
}
@@ -112,7 +117,7 @@ class AppManager implements IAppManager {
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);
+ $this->appConfig = Server::get(AppConfig::class);
return $this->appConfig;
}
@@ -123,7 +128,7 @@ class AppManager implements IAppManager {
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);
+ $this->urlGenerator = Server::get(IURLGenerator::class);
return $this->urlGenerator;
}
@@ -134,7 +139,8 @@ class AppManager implements IAppManager {
*/
private function getEnabledAppsValues(): array {
if (!$this->enabledAppsCache) {
- $values = $this->getAppConfig()->getValues(false, 'enabled');
+ /** @var array<string,string> */
+ $values = $this->getAppConfig()->searchValues('enabled', false, IAppConfig::VALUE_STRING);
$alwaysEnabledApps = $this->getAlwaysEnabledApps();
foreach ($alwaysEnabledApps as $appId) {
@@ -185,9 +191,9 @@ class AppManager implements IAppManager {
if (is_resource($dh)) {
while (($file = readdir($dh)) !== false) {
if (
- $file[0] != '.' &&
- is_dir($apps_dir['path'] . '/' . $file) &&
- is_file($apps_dir['path'] . '/' . $file . '/appinfo/info.xml')
+ $file[0] != '.'
+ && is_dir($apps_dir['path'] . '/' . $file)
+ && is_file($apps_dir['path'] . '/' . $file . '/appinfo/info.xml')
) {
$apps[] = $file;
}
@@ -202,7 +208,7 @@ class AppManager implements IAppManager {
* List all apps enabled for a user
*
* @param \OCP\IUser $user
- * @return string[]
+ * @return list<string>
*/
public function getEnabledAppsForUser(IUser $user) {
$apps = $this->getEnabledAppsValues();
@@ -457,7 +463,7 @@ class AppManager implements IAppManager {
]);
}
- $coordinator = \OCP\Server::get(Coordinator::class);
+ $coordinator = Server::get(Coordinator::class);
$coordinator->bootApp($app);
$eventLogger->start("bootstrap:load_app:$app:info", "Load info.xml for $app and register any services defined in it");
@@ -507,8 +513,8 @@ class AppManager implements IAppManager {
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'];
+ $plugins = isset($info['collaboration']['plugins']['plugin']['@value'])
+ ? [$info['collaboration']['plugins']['plugin']] : $info['collaboration']['plugins']['plugin'];
$collaboratorSearch = null;
$autoCompleteManager = null;
foreach ($plugins as $plugin) {
@@ -545,11 +551,16 @@ class AppManager implements IAppManager {
* @param string $appId
* @param bool $forceEnable
* @throws AppPathNotFoundException
+ * @throws \InvalidArgumentException if the application is not installed yet
*/
public function enableApp(string $appId, bool $forceEnable = false): void {
// Check if app exists
$this->getAppPath($appId);
+ if ($this->config->getAppValue($appId, 'installed_version', '') === '') {
+ throw new \InvalidArgumentException("$appId is not installed, cannot be enabled.");
+ }
+
if ($forceEnable) {
$this->overwriteNextcloudRequirement($appId);
}
@@ -561,6 +572,8 @@ class AppManager implements IAppManager {
ManagerEvent::EVENT_APP_ENABLE, $appId
));
$this->clearAppsCache();
+
+ $this->configManager->migrateConfigLexiconKeys($appId);
}
/**
@@ -596,6 +609,10 @@ class AppManager implements IAppManager {
throw new \InvalidArgumentException("$appId can't be enabled for groups.");
}
+ if ($this->config->getAppValue($appId, 'installed_version', '') === '') {
+ throw new \InvalidArgumentException("$appId is not installed, cannot be enabled.");
+ }
+
if ($forceEnable) {
$this->overwriteNextcloudRequirement($appId);
}
@@ -615,6 +632,8 @@ class AppManager implements IAppManager {
ManagerEvent::EVENT_APP_ENABLE_FOR_GROUPS, $appId, $groups
));
$this->clearAppsCache();
+
+ $this->configManager->migrateConfigLexiconKeys($appId);
}
/**
@@ -752,7 +771,7 @@ class AppManager implements IAppManager {
$data = $parser->parse($path);
if (is_array($data)) {
- $data = \OC_App::parseAppInfo($data, $lang);
+ $data = $parser->applyL10N($data, $lang);
}
return $data;
@@ -775,8 +794,8 @@ class AppManager implements IAppManager {
*
* @return array<string, string>
*/
- public function getAppInstalledVersions(): array {
- return $this->getAppConfig()->getAppInstalledVersions();
+ public function getAppInstalledVersions(bool $onlyEnabled = false): array {
+ return $this->getAppConfig()->getAppInstalledVersions($onlyEnabled);
}
/**
@@ -812,6 +831,10 @@ class AppManager implements IAppManager {
}
private function isAlwaysEnabled(string $appId): bool {
+ if ($appId === 'core') {
+ return true;
+ }
+
$alwaysEnabled = $this->getAlwaysEnabledApps();
return in_array($appId, $alwaysEnabled, true);
}
diff --git a/lib/private/App/AppStore/AppNotFoundException.php b/lib/private/App/AppStore/AppNotFoundException.php
new file mode 100644
index 00000000000..79ceebb4423
--- /dev/null
+++ b/lib/private/App/AppStore/AppNotFoundException.php
@@ -0,0 +1,13 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace OC\App\AppStore;
+
+class AppNotFoundException extends \Exception {
+}
diff --git a/lib/private/App/AppStore/Bundles/Bundle.php b/lib/private/App/AppStore/Bundles/Bundle.php
index 62f09b82f79..1443be81e92 100644
--- a/lib/private/App/AppStore/Bundles/Bundle.php
+++ b/lib/private/App/AppStore/Bundles/Bundle.php
@@ -1,4 +1,5 @@
<?php
+
/**
* SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
diff --git a/lib/private/App/AppStore/Bundles/BundleFetcher.php b/lib/private/App/AppStore/Bundles/BundleFetcher.php
index 01325699e2c..4ff53b0c70b 100644
--- a/lib/private/App/AppStore/Bundles/BundleFetcher.php
+++ b/lib/private/App/AppStore/Bundles/BundleFetcher.php
@@ -1,4 +1,5 @@
<?php
+
/**
* SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
diff --git a/lib/private/App/AppStore/Bundles/EducationBundle.php b/lib/private/App/AppStore/Bundles/EducationBundle.php
index 6770d4a7091..23681ec7416 100644
--- a/lib/private/App/AppStore/Bundles/EducationBundle.php
+++ b/lib/private/App/AppStore/Bundles/EducationBundle.php
@@ -1,4 +1,5 @@
<?php
+
/**
* SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
diff --git a/lib/private/App/AppStore/Bundles/EnterpriseBundle.php b/lib/private/App/AppStore/Bundles/EnterpriseBundle.php
index 88a9ec60a00..fc2d43e0388 100644
--- a/lib/private/App/AppStore/Bundles/EnterpriseBundle.php
+++ b/lib/private/App/AppStore/Bundles/EnterpriseBundle.php
@@ -1,4 +1,5 @@
<?php
+
/**
* SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
diff --git a/lib/private/App/AppStore/Bundles/GroupwareBundle.php b/lib/private/App/AppStore/Bundles/GroupwareBundle.php
index 7c7b74ff53d..93fa70268cd 100644
--- a/lib/private/App/AppStore/Bundles/GroupwareBundle.php
+++ b/lib/private/App/AppStore/Bundles/GroupwareBundle.php
@@ -1,4 +1,5 @@
<?php
+
/**
* SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
diff --git a/lib/private/App/AppStore/Bundles/PublicSectorBundle.php b/lib/private/App/AppStore/Bundles/PublicSectorBundle.php
index 158d525bdcc..106a6353029 100644
--- a/lib/private/App/AppStore/Bundles/PublicSectorBundle.php
+++ b/lib/private/App/AppStore/Bundles/PublicSectorBundle.php
@@ -1,4 +1,5 @@
<?php
+
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
diff --git a/lib/private/App/AppStore/Bundles/SocialSharingBundle.php b/lib/private/App/AppStore/Bundles/SocialSharingBundle.php
index 7f925688ca3..40f0fb15977 100644
--- a/lib/private/App/AppStore/Bundles/SocialSharingBundle.php
+++ b/lib/private/App/AppStore/Bundles/SocialSharingBundle.php
@@ -1,4 +1,5 @@
<?php
+
/**
* SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
diff --git a/lib/private/App/AppStore/Fetcher/AppDiscoverFetcher.php b/lib/private/App/AppStore/Fetcher/AppDiscoverFetcher.php
index 2537d1dcec9..8389e525750 100644
--- a/lib/private/App/AppStore/Fetcher/AppDiscoverFetcher.php
+++ b/lib/private/App/AppStore/Fetcher/AppDiscoverFetcher.php
@@ -1,4 +1,5 @@
<?php
+
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
diff --git a/lib/private/App/AppStore/Fetcher/AppFetcher.php b/lib/private/App/AppStore/Fetcher/AppFetcher.php
index 352646c3f5e..bbf4b00245b 100644
--- a/lib/private/App/AppStore/Fetcher/AppFetcher.php
+++ b/lib/private/App/AppStore/Fetcher/AppFetcher.php
@@ -1,4 +1,5 @@
<?php
+
/**
* SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
@@ -78,8 +79,8 @@ class AppFetcher extends Fetcher {
$minServerVersion = $serverVersion->getMinimumVersion();
$maxServerVersion = $serverVersion->getMaximumVersion();
$minFulfilled = $this->compareVersion->isCompatible($ncVersion, $minServerVersion, '>=');
- $maxFulfilled = $maxServerVersion !== '' &&
- $this->compareVersion->isCompatible($ncVersion, $maxServerVersion, '<=');
+ $maxFulfilled = $maxServerVersion !== ''
+ && $this->compareVersion->isCompatible($ncVersion, $maxServerVersion, '<=');
$isPhpCompatible = true;
if (($release['rawPhpVersionSpec'] ?? '*') !== '*') {
$phpVersion = $versionParser->getVersion($release['rawPhpVersionSpec']);
diff --git a/lib/private/App/AppStore/Fetcher/CategoryFetcher.php b/lib/private/App/AppStore/Fetcher/CategoryFetcher.php
index d72f8fa7e24..d7857d41bee 100644
--- a/lib/private/App/AppStore/Fetcher/CategoryFetcher.php
+++ b/lib/private/App/AppStore/Fetcher/CategoryFetcher.php
@@ -1,4 +1,5 @@
<?php
+
/**
* SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
diff --git a/lib/private/App/AppStore/Fetcher/Fetcher.php b/lib/private/App/AppStore/Fetcher/Fetcher.php
index f998c9e2023..2e949fedb51 100644
--- a/lib/private/App/AppStore/Fetcher/Fetcher.php
+++ b/lib/private/App/AppStore/Fetcher/Fetcher.php
@@ -1,4 +1,5 @@
<?php
+
/**
* SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
diff --git a/lib/private/App/AppStore/Version/Version.php b/lib/private/App/AppStore/Version/Version.php
index b7e679d250a..2d169a291f1 100644
--- a/lib/private/App/AppStore/Version/Version.php
+++ b/lib/private/App/AppStore/Version/Version.php
@@ -1,4 +1,5 @@
<?php
+
/**
* SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
diff --git a/lib/private/App/AppStore/Version/VersionParser.php b/lib/private/App/AppStore/Version/VersionParser.php
index 59715c8d385..8976f28837f 100644
--- a/lib/private/App/AppStore/Version/VersionParser.php
+++ b/lib/private/App/AppStore/Version/VersionParser.php
@@ -1,4 +1,5 @@
<?php
+
/**
* SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
diff --git a/lib/private/App/DependencyAnalyzer.php b/lib/private/App/DependencyAnalyzer.php
index 72b38ca12c7..bde8719c41d 100644
--- a/lib/private/App/DependencyAnalyzer.php
+++ b/lib/private/App/DependencyAnalyzer.php
@@ -1,21 +1,18 @@
<?php
+
+declare(strict_types=1);
+
/**
- * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016-2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
* SPDX-License-Identifier: AGPL-3.0-only
*/
+
namespace OC\App;
use OCP\IL10N;
class DependencyAnalyzer {
- /** @var array */
- private $appInfo;
-
- /**
- * @param Platform $platform
- * @param \OCP\IL10N $l
- */
public function __construct(
private Platform $platform,
private IL10N $l,
@@ -23,11 +20,9 @@ class DependencyAnalyzer {
}
/**
- * @param array $app
- * @returns array of missing dependencies
+ * @return array of missing dependencies
*/
- public function analyze(array $app, bool $ignoreMax = false) {
- $this->appInfo = $app;
+ public function analyze(array $app, bool $ignoreMax = false): array {
if (isset($app['dependencies'])) {
$dependencies = $app['dependencies'];
} else {
@@ -63,12 +58,10 @@ class DependencyAnalyzer {
* Truncates both versions to the lowest common version, e.g.
* 5.1.2.3 and 5.1 will be turned into 5.1 and 5.1,
* 5.2.6.5 and 5.1 will be turned into 5.2 and 5.1
- * @param string $first
- * @param string $second
* @return string[] first element is the first version, second element is the
* second version
*/
- private function normalizeVersions($first, $second) {
+ private function normalizeVersions(string $first, string $second): array {
$first = explode('.', $first);
$second = explode('.', $second);
@@ -83,47 +76,31 @@ class DependencyAnalyzer {
/**
* Parameters will be normalized and then passed into version_compare
* in the same order they are specified in the method header
- * @param string $first
- * @param string $second
- * @param string $operator
* @return bool result similar to version_compare
*/
- private function compare($first, $second, $operator) {
- // we can't normalize versions if one of the given parameters is not a
- // version string but null. In case one parameter is null normalization
- // will therefore be skipped
- if ($first !== null && $second !== null) {
- [$first, $second] = $this->normalizeVersions($first, $second);
- }
+ private function compare(string $first, string $second, string $operator): bool {
+ [$first, $second] = $this->normalizeVersions($first, $second);
return version_compare($first, $second, $operator);
}
/**
* Checks if a version is bigger than another version
- * @param string $first
- * @param string $second
* @return bool true if the first version is bigger than the second
*/
- private function compareBigger($first, $second) {
+ private function compareBigger(string $first, string $second): bool {
return $this->compare($first, $second, '>');
}
/**
* Checks if a version is smaller than another version
- * @param string $first
- * @param string $second
* @return bool true if the first version is smaller than the second
*/
- private function compareSmaller($first, $second) {
+ private function compareSmaller(string $first, string $second): bool {
return $this->compare($first, $second, '<');
}
- /**
- * @param array $dependencies
- * @return array
- */
- private function analyzePhpVersion(array $dependencies) {
+ private function analyzePhpVersion(array $dependencies): array {
$missing = [];
if (isset($dependencies['php']['@attributes']['min-version'])) {
$minVersion = $dependencies['php']['@attributes']['min-version'];
@@ -146,7 +123,7 @@ class DependencyAnalyzer {
return $missing;
}
- private function analyzeArchitecture(array $dependencies) {
+ private function analyzeArchitecture(array $dependencies): array {
$missing = [];
if (!isset($dependencies['architecture'])) {
return $missing;
@@ -169,11 +146,7 @@ class DependencyAnalyzer {
return $missing;
}
- /**
- * @param array $dependencies
- * @return array
- */
- private function analyzeDatabases(array $dependencies) {
+ private function analyzeDatabases(array $dependencies): array {
$missing = [];
if (!isset($dependencies['database'])) {
return $missing;
@@ -186,6 +159,9 @@ class DependencyAnalyzer {
if (!is_array($supportedDatabases)) {
$supportedDatabases = [$supportedDatabases];
}
+ if (isset($supportedDatabases['@value'])) {
+ $supportedDatabases = [$supportedDatabases];
+ }
$supportedDatabases = array_map(function ($db) {
return $this->getValue($db);
}, $supportedDatabases);
@@ -196,11 +172,7 @@ class DependencyAnalyzer {
return $missing;
}
- /**
- * @param array $dependencies
- * @return array
- */
- private function analyzeCommands(array $dependencies) {
+ private function analyzeCommands(array $dependencies): array {
$missing = [];
if (!isset($dependencies['command'])) {
return $missing;
@@ -226,11 +198,7 @@ class DependencyAnalyzer {
return $missing;
}
- /**
- * @param array $dependencies
- * @return array
- */
- private function analyzeLibraries(array $dependencies) {
+ private function analyzeLibraries(array $dependencies): array {
$missing = [];
if (!isset($dependencies['lib'])) {
return $missing;
@@ -271,11 +239,7 @@ class DependencyAnalyzer {
return $missing;
}
- /**
- * @param array $dependencies
- * @return array
- */
- private function analyzeOS(array $dependencies) {
+ private function analyzeOS(array $dependencies): array {
$missing = [];
if (!isset($dependencies['os'])) {
return $missing;
@@ -299,12 +263,7 @@ class DependencyAnalyzer {
return $missing;
}
- /**
- * @param array $dependencies
- * @param array $appInfo
- * @return array
- */
- private function analyzeOC(array $dependencies, array $appInfo, bool $ignoreMax) {
+ private function analyzeOC(array $dependencies, array $appInfo, bool $ignoreMax): array {
$missing = [];
$minVersion = null;
if (isset($dependencies['nextcloud']['@attributes']['min-version'])) {
@@ -320,12 +279,12 @@ class DependencyAnalyzer {
if (!is_null($minVersion)) {
if ($this->compareSmaller($this->platform->getOcVersion(), $minVersion)) {
- $missing[] = $this->l->t('Server version %s or higher is required.', [$this->toVisibleVersion($minVersion)]);
+ $missing[] = $this->l->t('Server version %s or higher is required.', [$minVersion]);
}
}
if (!$ignoreMax && !is_null($maxVersion)) {
if ($this->compareBigger($this->platform->getOcVersion(), $maxVersion)) {
- $missing[] = $this->l->t('Server version %s or lower is required.', [$this->toVisibleVersion($maxVersion)]);
+ $missing[] = $this->l->t('Server version %s or lower is required.', [$maxVersion]);
}
}
return $missing;
@@ -346,25 +305,7 @@ class DependencyAnalyzer {
}
/**
- * Map the internal version number to the Nextcloud version
- *
- * @param string $version
- * @return string
- */
- protected function toVisibleVersion($version) {
- switch ($version) {
- case '9.1':
- return '10';
- default:
- if (str_starts_with($version, '9.1.')) {
- $version = '10.0.' . substr($version, 4);
- }
- return $version;
- }
- }
-
- /**
- * @param $element
+ * @param mixed $element
* @return mixed
*/
private function getValue($element) {
diff --git a/lib/private/App/InfoParser.php b/lib/private/App/InfoParser.php
index 6610121f446..634dc1fbdd5 100644
--- a/lib/private/App/InfoParser.php
+++ b/lib/private/App/InfoParser.php
@@ -1,4 +1,5 @@
<?php
+
/**
* SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
@@ -22,7 +23,7 @@ class InfoParser {
* @param string $file the xml file to be loaded
* @return null|array where null is an indicator for an error
*/
- public function parse($file) {
+ public function parse(string $file): ?array {
if (!file_exists($file)) {
return null;
}
@@ -43,7 +44,7 @@ class InfoParser {
}
$array = $this->xmlToArray($xml);
- if (is_null($array)) {
+ if (is_string($array)) {
return null;
}
@@ -207,11 +208,7 @@ class InfoParser {
return $array;
}
- /**
- * @param $data
- * @return bool
- */
- private function isNavigationItem($data): bool {
+ private function isNavigationItem(array $data): bool {
// Allow settings navigation items with no route entry
$type = $data['type'] ?? 'link';
if ($type === 'settings') {
@@ -220,17 +217,17 @@ class InfoParser {
return isset($data['name'], $data['route']);
}
- /**
- * @param \SimpleXMLElement $xml
- * @return array
- */
- public function xmlToArray($xml) {
- if (!$xml->children()) {
+ public function xmlToArray(\SimpleXMLElement $xml): array|string {
+ $children = $xml->children();
+ if ($children === null || count($children) === 0) {
return (string)$xml;
}
$array = [];
- foreach ($xml->children() as $element => $node) {
+ foreach ($children as $element => $node) {
+ if ($element === null) {
+ throw new \InvalidArgumentException('xml contains a null element');
+ }
$totalElement = count($xml->{$element});
if (!isset($array[$element])) {
@@ -242,15 +239,18 @@ class InfoParser {
$data = [
'@attributes' => [],
];
- if (!count($node->children())) {
- $value = (string)$node;
- if (!empty($value)) {
- $data['@value'] = $value;
+ $converted = $this->xmlToArray($node);
+ if (is_string($converted)) {
+ if (!empty($converted)) {
+ $data['@value'] = $converted;
}
} else {
- $data = array_merge($data, $this->xmlToArray($node));
+ $data = array_merge($data, $converted);
}
foreach ($attributes as $attr => $value) {
+ if ($attr === null) {
+ throw new \InvalidArgumentException('xml contains a null element');
+ }
$data['@attributes'][$attr] = (string)$value;
}
@@ -271,4 +271,78 @@ class InfoParser {
return $array;
}
+
+ /**
+ * Select the appropriate l10n version for fields name, summary and description
+ */
+ public function applyL10N(array $data, ?string $lang = null): array {
+ if ($lang !== '' && $lang !== null) {
+ if (isset($data['name']) && is_array($data['name'])) {
+ $data['name'] = $this->findBestL10NOption($data['name'], $lang);
+ }
+ if (isset($data['summary']) && is_array($data['summary'])) {
+ $data['summary'] = $this->findBestL10NOption($data['summary'], $lang);
+ }
+ if (isset($data['description']) && is_array($data['description'])) {
+ $data['description'] = trim($this->findBestL10NOption($data['description'], $lang));
+ }
+ } elseif (isset($data['description']) && is_string($data['description'])) {
+ $data['description'] = trim($data['description']);
+ } else {
+ $data['description'] = '';
+ }
+
+ return $data;
+ }
+
+ protected function findBestL10NOption(array $options, string $lang): string {
+ // only a single option
+ if (isset($options['@value'])) {
+ return $options['@value'];
+ }
+
+ $fallback = $similarLangFallback = $englishFallback = false;
+
+ $lang = strtolower($lang);
+ $similarLang = $lang;
+ $pos = strpos($similarLang, '_');
+ if ($pos !== false && $pos > 0) {
+ // For "de_DE" we want to find "de" and the other way around
+ $similarLang = substr($lang, 0, $pos);
+ }
+
+ foreach ($options as $option) {
+ if (is_array($option)) {
+ if ($fallback === false) {
+ $fallback = $option['@value'];
+ }
+
+ if (!isset($option['@attributes']['lang'])) {
+ continue;
+ }
+
+ $attributeLang = strtolower($option['@attributes']['lang']);
+ if ($attributeLang === $lang) {
+ return $option['@value'];
+ }
+
+ if ($attributeLang === $similarLang) {
+ $similarLangFallback = $option['@value'];
+ } elseif (str_starts_with($attributeLang, $similarLang . '_')) {
+ if ($similarLangFallback === false) {
+ $similarLangFallback = $option['@value'];
+ }
+ }
+ } else {
+ $englishFallback = $option;
+ }
+ }
+
+ if ($similarLangFallback !== false) {
+ return $similarLangFallback;
+ } elseif ($englishFallback !== false) {
+ return $englishFallback;
+ }
+ return (string)$fallback;
+ }
}
diff --git a/lib/private/App/Platform.php b/lib/private/App/Platform.php
index c2c059220c8..80e4cefed64 100644
--- a/lib/private/App/Platform.php
+++ b/lib/private/App/Platform.php
@@ -1,4 +1,5 @@
<?php
+
/**
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
diff --git a/lib/private/App/PlatformRepository.php b/lib/private/App/PlatformRepository.php
index 6d9a9cd011a..faed8b07feb 100644
--- a/lib/private/App/PlatformRepository.php
+++ b/lib/private/App/PlatformRepository.php
@@ -1,4 +1,5 @@
<?php
+
/**
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.