forked from friendica/friendica-directory
- Add Utils/L10n class - Add translator functions to PHP Renderer - Refactor web controllers to prevent duplicated code - Add locale middleware - Add translation file loading - Add i18n settingsstable
parent
13a2068a8b
commit
5b7bb030de
@ -1,141 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Friendica\Directory\Content;
|
||||
|
||||
/**
|
||||
* @author Hypolite Petovan <mrpetovan@gmail.com>
|
||||
*/
|
||||
class L10n
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $lang;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $strings;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $lang_path;
|
||||
|
||||
public function __construct(string $language = 'en', string $lang_path = '')
|
||||
{
|
||||
$this->lang = $language;
|
||||
$this->lang_path = $lang_path;
|
||||
|
||||
$this->loadTranslationTable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads string translation table
|
||||
*
|
||||
* First addon strings are loaded, then globals
|
||||
*
|
||||
* Uses an App object shim since all the strings files refer to $a->strings
|
||||
*
|
||||
* @param string $lang language code to load
|
||||
*/
|
||||
private function loadTranslationTable(): void
|
||||
{
|
||||
if (file_exists($this->lang_path . '/' . $this->lang . '/strings.php')) {
|
||||
$this->strings = include $this->lang_path . '/' . $this->lang . '/strings.php';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the localized version of a singular/plural string with optional string interpolation
|
||||
*
|
||||
* This function takes two english strings as parameters, singular and plural, as
|
||||
* well as a count. If a localized version exists for the current language, they
|
||||
* are used instead. Discrimination between singular and plural is done using the
|
||||
* localized function if any or the default one. Finally, a string interpolation
|
||||
* is performed using the count as parameter.
|
||||
*
|
||||
* Usages:
|
||||
* - L10n::tt('Like', 'Likes', $count)
|
||||
* - L10n::tt("%s user deleted", "%s users deleted", count($users))
|
||||
*
|
||||
* @param string $singular
|
||||
* @param string $plural
|
||||
* @param int $count
|
||||
* @return string
|
||||
*/
|
||||
public function tt(string $singular, string $plural, int $count): string
|
||||
{
|
||||
if (!empty($this->strings[$singular])) {
|
||||
$t = $this->strings[$singular];
|
||||
if (is_array($t)) {
|
||||
$plural_function = 'string_plural_select_' . str_replace('-', '_', $this->lang);
|
||||
if (function_exists($plural_function)) {
|
||||
$i = $plural_function($count);
|
||||
} else {
|
||||
$i = $this->stringPluralSelectDefault($count);
|
||||
}
|
||||
|
||||
// for some languages there is only a single array item
|
||||
if (!isset($t[$i])) {
|
||||
$s = $t[0];
|
||||
} else {
|
||||
$s = $t[$i];
|
||||
}
|
||||
} else {
|
||||
$s = $t;
|
||||
}
|
||||
} elseif ($this->stringPluralSelectDefault($count)) {
|
||||
$s = $plural;
|
||||
} else {
|
||||
$s = $singular;
|
||||
}
|
||||
|
||||
$s = @sprintf($s, $count);
|
||||
|
||||
return $s;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the localized version of the provided string with optional string interpolation
|
||||
*
|
||||
* This function takes a english string as parameter, and if a localized version
|
||||
* exists for the current language, substitutes it before performing an eventual
|
||||
* string interpolation (sprintf) with additional optional arguments.
|
||||
*
|
||||
* Usages:
|
||||
* - L10n::t('This is an example')
|
||||
* - L10n::t('URL %s returned no result', $url)
|
||||
* - L10n::t('Current version: %s, new version: %s', $current_version, $new_version)
|
||||
*
|
||||
* @param string $s
|
||||
* @param array $vars Variables to interpolate in the translation string
|
||||
* @return string
|
||||
*/
|
||||
public function t($s, ...$vars): string
|
||||
{
|
||||
if (empty($s)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (!empty($this->strings[$s])) {
|
||||
$t = $this->strings[$s];
|
||||
$s = is_array($t) ? $t[0] : $t;
|
||||
}
|
||||
|
||||
if (count($vars) > 0) {
|
||||
$s = sprintf($s, ...$vars);
|
||||
}
|
||||
|
||||
return $s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a fallback which will not collide with a function defined in any language file
|
||||
*/
|
||||
private function stringPluralSelectDefault(int $n): bool
|
||||
{
|
||||
return $n != 1;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Friendica\Directory\Controllers\Web;
|
||||
|
||||
|
||||
abstract class BaseController
|
||||
{
|
||||
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Friendica\Directory\Routes\Http;
|
||||
|
||||
/**
|
||||
* @author Hypolite Petovan <mrpetovan@gmail.com>
|
||||
*/
|
||||
class Servers extends BaseRoute
|
||||
{
|
||||
public function __invoke(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args): \Slim\Http\Response
|
||||
{
|
||||
return (new \Friendica\Directory\Controllers\Web\Servers(
|
||||
$this->container->atlas,
|
||||
$this->container->renderer,
|
||||
$this->container->l10n,
|
||||
$this->container->simplecache)
|
||||
)->render($request, $response);
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace Friendica\Directory\Routes\Web;
|
||||
|
||||
use Friendica\Directory\Controllers\Web\BaseController;
|
||||
|
||||
/**
|
||||
* @author Hypolite Petovan <mrpetovan@gmail.com>
|
||||
*/
|
||||
abstract class BaseRoute
|
||||
{
|
||||
/**
|
||||
* @var \Slim\Container
|
||||
*/
|
||||
protected $container;
|
||||
|
||||
/**
|
||||
* @var BaseController
|
||||
*/
|
||||
protected $controller;
|
||||
|
||||
public function __construct(\Slim\Container $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
}
|
||||
|
||||
public function __invoke(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args): \Slim\Http\Response
|
||||
{
|
||||
$defaults = [
|
||||
'languages' => $this->container->settings['i18n']['locales'],
|
||||
'lang' => $request->getAttribute('locale'),
|
||||
'baseUrl' => $request->getUri()->getBaseUrl(),
|
||||
'content' => '',
|
||||
'noNavSearch' => false
|
||||
];
|
||||
|
||||
$values = $this->controller->render($request, $response, $args);
|
||||
|
||||
$values = $values + $defaults;
|
||||
|
||||
// Render index view
|
||||
return $this->container->renderer->render($response, 'layout.phtml', $values);
|
||||
}
|
||||
}
|
@ -1,20 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace Friendica\Directory\Routes\Http;
|
||||
namespace Friendica\Directory\Routes\Web;
|
||||
|
||||
/**
|
||||
* @author Hypolite Petovan <mrpetovan@gmail.com>
|
||||
*/
|
||||
class Directory extends BaseRoute
|
||||
{
|
||||
public function __invoke(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args): \Slim\Http\Response
|
||||
public function __construct(\Slim\Container $container)
|
||||
{
|
||||
return (new \Friendica\Directory\Controllers\Web\Directory(
|
||||
parent::__construct($container);
|
||||
|
||||
$this->controller = new \Friendica\Directory\Controllers\Web\Directory(
|
||||
$this->container->atlas,
|
||||
$this->container->get('\Friendica\Directory\Models\Profile'),
|
||||
$this->container->get('\Friendica\Directory\Views\Widget\AccountTypeTabs'),
|
||||
$this->container->renderer,
|
||||
$this->container->l10n)
|
||||
)->render($request, $response, $args);
|
||||
$this->container->l10n
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace Friendica\Directory\Routes\Web;
|
||||
|
||||
/**
|
||||
* @author Hypolite Petovan <mrpetovan@gmail.com>
|
||||
*/
|
||||
class Search extends BaseRoute
|
||||
{
|
||||
public function __construct(\Slim\Container $container)
|
||||
{
|
||||
parent::__construct($container);
|
||||
|
||||
$this->controller = new \Friendica\Directory\Controllers\Web\Search(
|
||||
$this->container->atlas,
|
||||
$this->container->get('\Friendica\Directory\Models\Profile'),
|
||||
$this->container->get('\Friendica\Directory\Views\Widget\AccountTypeTabs'),
|
||||
$this->container->renderer,
|
||||
$this->container->l10n
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Friendica\Directory\Routes\Web;
|
||||
|
||||
/**
|
||||
* @author Hypolite Petovan <mrpetovan@gmail.com>
|
||||
*/
|
||||
class Servers extends BaseRoute
|
||||
{
|
||||
public function __construct(\Slim\Container $container)
|
||||
{
|
||||
parent::__construct($container);
|
||||
|
||||
$this->controller = new \Friendica\Directory\Controllers\Web\Servers(
|
||||
$this->container->atlas,
|
||||
$this->container->renderer,
|
||||
$this->container->l10n,
|
||||
$this->container->simplecache
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace Friendica\Directory\Views\Widget;
|
||||
|
||||
/**
|
||||
* @author Hypolite Petovan <mrpetovan@gmail.com>
|
||||
*/
|
||||
class PopularLanguages
|
||||
{
|
||||
/**
|
||||
* @var \Atlas\Pdo\Connection
|
||||
*/
|
||||
private $connection;
|
||||
/**
|
||||
* @var \Friendica\Directory\Views\PhpRenderer
|
||||
*/
|
||||
private $renderer;
|
||||
|
||||
public function __construct(\Atlas\Pdo\Connection $connection, \Friendica\Directory\Views\PhpRenderer $renderer)
|
||||
{
|
||||
$this->connection = $connection;
|
||||
$this->renderer = $renderer;
|
||||
}
|
||||
|
||||
public function render(): string
|
||||
{
|
||||
$stmt = 'SELECT `language`, COUNT(*) AS `total` FROM `profile` WHERE `language` IS NOT NULL GROUP BY `language` ORDER BY COUNT(`language`) DESC LIMIT 10';
|
||||
$languages = $this->connection->fetchAll($stmt);
|
||||
|
||||
$vars = [
|
||||
'languages' => $languages
|
||||
];
|
||||
|
||||
return $this->renderer->fetch('widget/popularlanguages.phtml', $vars);
|
||||
}
|
||||
}
|
@ -1,9 +1,40 @@
|
||||
<?php
|
||||
// Application middleware
|
||||
|
||||
// e.g: $app->add(new \Slim\Csrf\Guard);
|
||||
// configure middleware
|
||||
use Boronczyk\LocalizationMiddleware;
|
||||
|
||||
$app->add(new \Gofabian\Negotiation\NegotiationMiddleware([
|
||||
'accept' => ['text/html', 'application/json']
|
||||
]));
|
||||
|
||||
|
||||
$middleware = new LocalizationMiddleware(
|
||||
$container->get('settings')['i18n']['locales'],
|
||||
$container->get('settings')['i18n']['default']
|
||||
);
|
||||
|
||||
$middleware->setLocaleCallback(function (string $locale) use ($container) {
|
||||
$langPath = $container->get('settings')['i18n']['path'];
|
||||
|
||||
$translator = $container->get('l10n');
|
||||
if (is_a($translator, 'Gettext\GettextTranslator')) {
|
||||
// One of them will end up working, right?
|
||||
$translator->setLanguage($locale);
|
||||
$translator->setLanguage($locale . '.utf8');
|
||||
$translator->setLanguage($locale . '.UTF8');
|
||||
$translator->setLanguage($locale . '.utf-8');
|
||||
$translator->setLanguage($locale . '.UTF-8');
|
||||
|
||||
$translator->loadDomain('strings', $langPath);
|
||||
} else {
|
||||
/** @var $translator \Gettext\Translator */
|
||||
if (file_exists($langPath . '/' . $locale . '/LC_MESSAGES/strings.mo')) {
|
||||
$translator->loadTranslations(Gettext\Translations::fromMoFile($langPath . '/' . $locale . '/LC_MESSAGES/strings.mo'));
|
||||
} elseif (file_exists($langPath . '/' . $locale . '/LC_MESSAGES/strings.po')) {
|
||||
$translator->loadTranslations(Gettext\Translations::fromPoFile($langPath . '/' . $locale . '/LC_MESSAGES/strings.po'));
|
||||
}
|
||||
}
|
||||
});
|
||||
$middleware->setUriParamName('lang');
|
||||
|
||||
$app->add($middleware);
|
@ -0,0 +1,12 @@
|
||||
<div>
|
||||
<h3><?php echo $this->__('Popular Languages')?></h3>
|
||||
<ul>
|
||||
<?php foreach ($languages as $language): ?>
|
||||
<li>
|
||||
<a href="search?field=language&q=<?php echo $this->escapeUrl($language['language']) ?>">
|
||||
<?php echo $this->e(Friendica\Directory\Utils\L10n::langToString($language['language'])) ?>
|
||||
</a>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
Loading…
Reference in new issue