Merge pull request #1690 from nextcloud/backport-1586-fix-multi-translation-names-and-descriptions-9
[stable9] Fix multi translation names and descriptions
This commit is contained in:
commit
6fdef86eeb
|
@ -606,15 +606,16 @@ class OC_App {
|
||||||
* Read all app metadata from the info.xml file
|
* Read all app metadata from the info.xml file
|
||||||
*
|
*
|
||||||
* @param string $appId id of the app or the path of the info.xml file
|
* @param string $appId id of the app or the path of the info.xml file
|
||||||
* @param boolean $path (optional)
|
* @param boolean $path
|
||||||
|
* @param string $lang
|
||||||
* @return array|null
|
* @return array|null
|
||||||
* @note all data is read from info.xml, not just pre-defined fields
|
* @note all data is read from info.xml, not just pre-defined fields
|
||||||
*/
|
*/
|
||||||
public static function getAppInfo($appId, $path = false) {
|
public static function getAppInfo($appId, $path = false, $lang = null) {
|
||||||
if ($path) {
|
if ($path) {
|
||||||
$file = $appId;
|
$file = $appId;
|
||||||
} else {
|
} else {
|
||||||
if (isset(self::$appInfo[$appId])) {
|
if ($lang === null && isset(self::$appInfo[$appId])) {
|
||||||
return self::$appInfo[$appId];
|
return self::$appInfo[$appId];
|
||||||
}
|
}
|
||||||
$appPath = self::getAppPath($appId);
|
$appPath = self::getAppPath($appId);
|
||||||
|
@ -628,7 +629,7 @@ class OC_App {
|
||||||
$data = $parser->parse($file);
|
$data = $parser->parse($file);
|
||||||
|
|
||||||
if (is_array($data)) {
|
if (is_array($data)) {
|
||||||
$data = OC_App::parseAppInfo($data);
|
$data = OC_App::parseAppInfo($data, $lang);
|
||||||
}
|
}
|
||||||
if(isset($data['ocsid'])) {
|
if(isset($data['ocsid'])) {
|
||||||
$storedId = \OC::$server->getConfig()->getAppValue($appId, 'ocsid');
|
$storedId = \OC::$server->getConfig()->getAppValue($appId, 'ocsid');
|
||||||
|
@ -637,7 +638,9 @@ class OC_App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($lang === null) {
|
||||||
self::$appInfo[$appId] = $data;
|
self::$appInfo[$appId] = $data;
|
||||||
|
}
|
||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
@ -787,11 +790,12 @@ class OC_App {
|
||||||
//we don't want to show configuration for these
|
//we don't want to show configuration for these
|
||||||
$blacklist = \OC::$server->getAppManager()->getAlwaysEnabledApps();
|
$blacklist = \OC::$server->getAppManager()->getAlwaysEnabledApps();
|
||||||
$appList = array();
|
$appList = array();
|
||||||
|
$langCode = \OC::$server->getL10N('core')->getLanguageCode();
|
||||||
|
|
||||||
foreach ($installedApps as $app) {
|
foreach ($installedApps as $app) {
|
||||||
if (array_search($app, $blacklist) === false) {
|
if (array_search($app, $blacklist) === false) {
|
||||||
|
|
||||||
$info = OC_App::getAppInfo($app);
|
$info = OC_App::getAppInfo($app, false, $langCode);
|
||||||
if (!is_array($info)) {
|
if (!is_array($info)) {
|
||||||
\OCP\Util::writeLog('core', 'Could not read app info file for app "' . $app . '"', \OCP\Util::ERROR);
|
\OCP\Util::writeLog('core', 'Could not read app info file for app "' . $app . '"', \OCP\Util::ERROR);
|
||||||
continue;
|
continue;
|
||||||
|
@ -1200,13 +1204,69 @@ class OC_App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static function findBestL10NOption($options, $lang) {
|
||||||
|
$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'];
|
||||||
|
} else if (strpos($attributeLang, $similarLang . '_') === 0) {
|
||||||
|
if ($similarLangFallback === false) {
|
||||||
|
$similarLangFallback = $option['@value'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$englishFallback = $option;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($similarLangFallback !== false) {
|
||||||
|
return $similarLangFallback;
|
||||||
|
} else if ($englishFallback !== false) {
|
||||||
|
return $englishFallback;
|
||||||
|
}
|
||||||
|
return (string) $fallback;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* parses the app data array and enhanced the 'description' value
|
* parses the app data array and enhanced the 'description' value
|
||||||
*
|
*
|
||||||
* @param array $data the app data
|
* @param array $data the app data
|
||||||
|
* @param string $lang
|
||||||
* @return array improved app data
|
* @return array improved app data
|
||||||
*/
|
*/
|
||||||
public static function parseAppInfo(array $data) {
|
public static function parseAppInfo(array $data, $lang = null) {
|
||||||
|
|
||||||
|
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'] = self::findBestL10NOption($data['description'], $lang);
|
||||||
|
}
|
||||||
|
|
||||||
// just modify the description if it is available
|
// just modify the description if it is available
|
||||||
// otherwise this will create a $data element with an empty 'description'
|
// otherwise this will create a $data element with an empty 'description'
|
||||||
|
|
|
@ -165,6 +165,18 @@ OC.Settings.Apps = OC.Settings.Apps || {
|
||||||
app.previewAsIcon = true;
|
app.previewAsIcon = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_.isArray(app.author)) {
|
||||||
|
var authors = [];
|
||||||
|
_.each(app.author, function (author) {
|
||||||
|
if (typeof author === 'string') {
|
||||||
|
authors.push(author);
|
||||||
|
} else {
|
||||||
|
authors.push(author['@value']);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
app.author = authors.join(', ');
|
||||||
|
}
|
||||||
|
|
||||||
var html = template(app);
|
var html = template(app);
|
||||||
if (selector) {
|
if (selector) {
|
||||||
selector.html(html);
|
selector.html(html);
|
||||||
|
@ -450,6 +462,24 @@ OC.Settings.Apps = OC.Settings.Apps || {
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Splits the query by spaces and tries to find all substring in the app
|
||||||
|
* @param {string} string
|
||||||
|
* @param {string} query
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
_search: function(string, query) {
|
||||||
|
var keywords = query.split(' '),
|
||||||
|
stringLower = string.toLowerCase(),
|
||||||
|
found = true;
|
||||||
|
|
||||||
|
_.each(keywords, function(keyword) {
|
||||||
|
found = found && stringLower.indexOf(keyword) !== -1;
|
||||||
|
});
|
||||||
|
|
||||||
|
return found;
|
||||||
|
},
|
||||||
|
|
||||||
filter: function(query) {
|
filter: function(query) {
|
||||||
var $appList = $('#apps-list'),
|
var $appList = $('#apps-list'),
|
||||||
$emptyList = $('#apps-list-empty');
|
$emptyList = $('#apps-list-empty');
|
||||||
|
@ -466,22 +496,39 @@ OC.Settings.Apps = OC.Settings.Apps || {
|
||||||
|
|
||||||
// App Name
|
// App Name
|
||||||
var apps = _.filter(OC.Settings.Apps.State.apps, function (app) {
|
var apps = _.filter(OC.Settings.Apps.State.apps, function (app) {
|
||||||
return app.name.toLowerCase().indexOf(query) !== -1;
|
return OC.Settings.Apps._search(app.name, query);
|
||||||
});
|
});
|
||||||
|
|
||||||
// App ID
|
// App ID
|
||||||
apps = apps.concat(_.filter(OC.Settings.Apps.State.apps, function (app) {
|
apps = apps.concat(_.filter(OC.Settings.Apps.State.apps, function (app) {
|
||||||
return app.id.toLowerCase().indexOf(query) !== -1;
|
return OC.Settings.Apps._search(app.id, query);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// App Description
|
// App Description
|
||||||
apps = apps.concat(_.filter(OC.Settings.Apps.State.apps, function (app) {
|
apps = apps.concat(_.filter(OC.Settings.Apps.State.apps, function (app) {
|
||||||
return app.description.toLowerCase().indexOf(query) !== -1;
|
return OC.Settings.Apps._search(app.description, query);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Author Name
|
// Author Name
|
||||||
apps = apps.concat(_.filter(OC.Settings.Apps.State.apps, function (app) {
|
apps = apps.concat(_.filter(OC.Settings.Apps.State.apps, function (app) {
|
||||||
return app.author.toLowerCase().indexOf(query) !== -1;
|
if (_.isArray(app.author)) {
|
||||||
|
var authors = [];
|
||||||
|
_.each(app.author, function (author) {
|
||||||
|
if (typeof author === 'string') {
|
||||||
|
authors.push(author);
|
||||||
|
} else {
|
||||||
|
authors.push(author['@value']);
|
||||||
|
if (!_.isUndefined(author['@attributes']['homepage'])) {
|
||||||
|
authors.push(author['@attributes']['homepage']);
|
||||||
|
}
|
||||||
|
if (!_.isUndefined(author['@attributes']['mail'])) {
|
||||||
|
authors.push(author['@attributes']['mail']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return OC.Settings.Apps._search(authors.join(' '), query);
|
||||||
|
}
|
||||||
|
return OC.Settings.Apps._search(app.author, query);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// App status
|
// App status
|
||||||
|
|
Loading…
Reference in New Issue