chore: Move info parsing related method from OC_App to InfoParser

Also fix the tests

Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
pull/53537/head
Côme Chilliet 4 months ago
parent fb4e580109
commit 1f5e232314
No known key found for this signature in database
GPG Key ID: A3E2F658B28C760A
  1. 2
      lib/private/App/AppManager.php
  2. 78
      lib/private/App/InfoParser.php
  3. 75
      lib/private/legacy/OC_App.php
  4. 24
      tests/lib/App/DependencyAnalyzerTest.php
  5. 53
      tests/lib/App/InfoParserTest.php
  6. 56
      tests/lib/AppTest.php

@ -771,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;

@ -23,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;
}
@ -219,7 +219,7 @@ class InfoParser {
public function xmlToArray(\SimpleXMLElement $xml): array|string {
$children = $xml->children();
if ($children === null) {
if ($children === null || count($children) === 0) {
return (string)$xml;
}
@ -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;
}
}

@ -775,81 +775,6 @@ class OC_App {
}
}
protected static 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;
if (strpos($similarLang, '_')) {
// For "de_DE" we want to find "de" and the other way around
$similarLang = substr($lang, 0, strpos($lang, '_'));
}
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;
}
/**
* parses the app data array and enhanced the 'description' value
*
* @param array $data the app data
* @param string $lang
* @return array improved app data
*/
public static function parseAppInfo(array $data, $lang = null): array {
if ($lang && isset($data['name']) && is_array($data['name'])) {
$data['name'] = self::findBestL10NOption($data['name'], $lang);
}
if ($lang && isset($data['summary']) && is_array($data['summary'])) {
$data['summary'] = self::findBestL10NOption($data['summary'], $lang);
}
if ($lang && isset($data['description']) && is_array($data['description'])) {
$data['description'] = trim(self::findBestL10NOption($data['description'], $lang));
} elseif (isset($data['description']) && is_string($data['description'])) {
$data['description'] = trim($data['description']);
} else {
$data['description'] = '';
}
return $data;
}
/**
* @param \OCP\IConfig $config
* @param \OCP\IL10N $l

@ -277,18 +277,6 @@ class DependencyAnalyzerTest extends TestCase {
],
],
],
[
[
'Server version 10 or higher is required.',
],
[
'nextcloud' => [
'@attributes' => [
'min-version' => '9.1',
],
],
],
],
[
[
'Server version 9.2 or higher is required.',
@ -382,18 +370,6 @@ class DependencyAnalyzerTest extends TestCase {
],
],
],
[
[
'Server version 10 or higher is required.',
],
[
'owncloud' => [
'@attributes' => [
'min-version' => '9.1',
],
],
],
],
[
[
'Server version 9.2 or higher is required.',

@ -53,4 +53,57 @@ class InfoParserTest extends TestCase {
['various-single-item.json', 'various-single-item.xml'],
];
}
/**
* Providers for the app data values
*/
public static function appDataProvider(): array {
return [
[
['description' => " \t This is a multiline \n test with \n \t \n \n some new lines "],
['description' => "This is a multiline \n test with \n \t \n \n some new lines"],
],
[
['description' => " \t This is a multiline \n test with \n \t some new lines "],
['description' => "This is a multiline \n test with \n \t some new lines"],
],
[
['description' => hex2bin('5065726d657420646520732761757468656e7469666965722064616e732070697769676f20646972656374656d656e74206176656320736573206964656e74696669616e7473206f776e636c6f75642073616e73206c65732072657461706572206574206d657420c3a0206a6f757273206365757820636920656e20636173206465206368616e67656d656e74206465206d6f742064652070617373652e0d0a0d')],
['description' => "Permet de s'authentifier dans piwigo directement avec ses identifiants owncloud sans les retaper et met à jours ceux ci en cas de changement de mot de passe."],
],
[
['not-a-description' => " \t This is a multiline \n test with \n \t some new lines "],
[
'not-a-description' => " \t This is a multiline \n test with \n \t some new lines ",
'description' => '',
],
],
[
['description' => [100, 'bla']],
['description' => ''],
],
];
}
/**
* Test app info parser
*/
#[\PHPUnit\Framework\Attributes\DataProvider('appDataProvider')]
public function testApplyL10NNoLanguage(array $data, array $expected): void {
$parser = new InfoParser();
$this->assertSame($expected, $parser->applyL10N($data));
}
public function testApplyL10N(): void {
$parser = new InfoParser();
$data = $parser->parse(\OC::$SERVERROOT . '/tests/data/app/description-multi-lang.xml');
$this->assertEquals('English', $parser->applyL10N($data, 'en')['description']);
$this->assertEquals('German', $parser->applyL10N($data, 'de')['description']);
}
public function testApplyL10NSingleLanguage(): void {
$parser = new InfoParser();
$data = $parser->parse(\OC::$SERVERROOT . '/tests/data/app/description-single-lang.xml');
$this->assertEquals('English', $parser->applyL10N($data, 'en')['description']);
}
}

@ -9,7 +9,6 @@
namespace Test;
use OC\App\AppManager;
use OC\App\InfoParser;
use OC\AppConfig;
use OC\Config\ConfigManager;
use OCP\EventDispatcher\IEventDispatcher;
@ -586,59 +585,4 @@ class AppTest extends \Test\TestCase {
// Remove the cache of the mocked apps list with a forceRefresh
\OC_App::getEnabledApps();
}
/**
* Providers for the app data values
*/
public static function appDataProvider(): array {
return [
[
['description' => " \t This is a multiline \n test with \n \t \n \n some new lines "],
['description' => "This is a multiline \n test with \n \t \n \n some new lines"],
],
[
['description' => " \t This is a multiline \n test with \n \t some new lines "],
['description' => "This is a multiline \n test with \n \t some new lines"],
],
[
['description' => hex2bin('5065726d657420646520732761757468656e7469666965722064616e732070697769676f20646972656374656d656e74206176656320736573206964656e74696669616e7473206f776e636c6f75642073616e73206c65732072657461706572206574206d657420c3a0206a6f757273206365757820636920656e20636173206465206368616e67656d656e74206465206d6f742064652070617373652e0d0a0d')],
['description' => "Permet de s'authentifier dans piwigo directement avec ses identifiants owncloud sans les retaper et met à jours ceux ci en cas de changement de mot de passe."],
],
[
['not-a-description' => " \t This is a multiline \n test with \n \t some new lines "],
[
'not-a-description' => " \t This is a multiline \n test with \n \t some new lines ",
'description' => '',
],
],
[
['description' => [100, 'bla']],
['description' => ''],
],
];
}
/**
* Test app info parser
*
* @param array $data
* @param array $expected
*/
#[\PHPUnit\Framework\Attributes\DataProvider('appDataProvider')]
public function testParseAppInfo(array $data, array $expected): void {
$this->assertSame($expected, \OC_App::parseAppInfo($data));
}
public function testParseAppInfoL10N(): void {
$parser = new InfoParser();
$data = $parser->parse(\OC::$SERVERROOT . '/tests/data/app/description-multi-lang.xml');
$this->assertEquals('English', \OC_App::parseAppInfo($data, 'en')['description']);
$this->assertEquals('German', \OC_App::parseAppInfo($data, 'de')['description']);
}
public function testParseAppInfoL10NSingleLanguage(): void {
$parser = new InfoParser();
$data = $parser->parse(\OC::$SERVERROOT . '/tests/data/app/description-single-lang.xml');
$this->assertEquals('English', \OC_App::parseAppInfo($data, 'en')['description']);
}
}

Loading…
Cancel
Save