summaryrefslogtreecommitdiff
path: root/src/Helpers
diff options
context:
space:
mode:
Diffstat (limited to 'src/Helpers')
-rw-r--r--src/Helpers/Authenticator.php93
-rw-r--r--src/Helpers/AuthenticatorServiceProvider.php4
-rw-r--r--src/Helpers/Translation/GettextTranslator.php53
-rw-r--r--src/Helpers/Translation/TranslationNotFound.php9
-rw-r--r--src/Helpers/Translation/TranslationServiceProvider.php86
-rw-r--r--src/Helpers/Translation/Translator.php (renamed from src/Helpers/Translator.php)77
-rw-r--r--src/Helpers/TranslationServiceProvider.php63
7 files changed, 278 insertions, 107 deletions
diff --git a/src/Helpers/Authenticator.php b/src/Helpers/Authenticator.php
index 61d07980..db33339b 100644
--- a/src/Helpers/Authenticator.php
+++ b/src/Helpers/Authenticator.php
@@ -25,6 +25,9 @@ class Authenticator
/** @var string[] */
protected $permissions;
+ /** @var int */
+ protected $passwordAlgorithm = PASSWORD_DEFAULT;
+
/**
* @param ServerRequestInterface $request
* @param Session $session
@@ -48,7 +51,7 @@ class Authenticator
return $this->user;
}
- $userId = $this->session->get('uid');
+ $userId = $this->session->get('user_id');
if (!$userId) {
return null;
}
@@ -104,17 +107,15 @@ class Authenticator
$abilities = (array)$abilities;
if (empty($this->permissions)) {
- $userId = $this->user ? $this->user->id : $this->session->get('uid');
+ $user = $this->user();
- if ($userId) {
- if ($user = $this->user()) {
- $this->permissions = $this->getPermissionsByUser($user);
+ if ($user) {
+ $this->permissions = $this->getPermissionsByUser($user);
- $user->last_login_at = new Carbon();
- $user->save();
- } else {
- $this->session->remove('uid');
- }
+ $user->last_login_at = new Carbon();
+ $user->save();
+ } elseif ($this->session->get('user_id')) {
+ $this->session->remove('user_id');
}
if (empty($this->permissions)) {
@@ -132,6 +133,78 @@ class Authenticator
}
/**
+ * @param string $login
+ * @param string $password
+ * @return User|null
+ */
+ public function authenticate(string $login, string $password)
+ {
+ /** @var User $user */
+ $user = $this->userRepository->whereName($login)->first();
+ if (!$user) {
+ $user = $this->userRepository->whereEmail($login)->first();
+ }
+
+ if (!$user) {
+ return null;
+ }
+
+ if (!$this->verifyPassword($user, $password)) {
+ return null;
+ }
+
+ return $user;
+ }
+
+ /**
+ * @param User $user
+ * @param string $password
+ * @return bool
+ */
+ public function verifyPassword(User $user, string $password)
+ {
+ $algorithm = $this->passwordAlgorithm;
+
+ if (!password_verify($password, $user->password)) {
+ return false;
+ }
+
+ if (password_needs_rehash($user->password, $algorithm)) {
+ $this->setPassword($user, $password);
+ }
+
+ return true;
+ }
+
+ /**
+ * @param UserRepository $user
+ * @param string $password
+ */
+ public function setPassword(User $user, string $password)
+ {
+ $algorithm = $this->passwordAlgorithm;
+
+ $user->password = password_hash($password, $algorithm);
+ $user->save();
+ }
+
+ /**
+ * @return int
+ */
+ public function getPasswordAlgorithm()
+ {
+ return $this->passwordAlgorithm;
+ }
+
+ /**
+ * @param int $passwordAlgorithm
+ */
+ public function setPasswordAlgorithm(int $passwordAlgorithm)
+ {
+ $this->passwordAlgorithm = $passwordAlgorithm;
+ }
+
+ /**
* @param User $user
* @return array
* @codeCoverageIgnore
diff --git a/src/Helpers/AuthenticatorServiceProvider.php b/src/Helpers/AuthenticatorServiceProvider.php
index 715a592f..f06e635d 100644
--- a/src/Helpers/AuthenticatorServiceProvider.php
+++ b/src/Helpers/AuthenticatorServiceProvider.php
@@ -2,14 +2,18 @@
namespace Engelsystem\Helpers;
+use Engelsystem\Config\Config;
use Engelsystem\Container\ServiceProvider;
class AuthenticatorServiceProvider extends ServiceProvider
{
public function register()
{
+ /** @var Config $config */
+ $config = $this->app->get('config');
/** @var Authenticator $authenticator */
$authenticator = $this->app->make(Authenticator::class);
+ $authenticator->setPasswordAlgorithm($config->get('password_algorithm'));
$this->app->instance(Authenticator::class, $authenticator);
$this->app->instance('authenticator', $authenticator);
diff --git a/src/Helpers/Translation/GettextTranslator.php b/src/Helpers/Translation/GettextTranslator.php
new file mode 100644
index 00000000..7f2299e2
--- /dev/null
+++ b/src/Helpers/Translation/GettextTranslator.php
@@ -0,0 +1,53 @@
+<?php
+
+namespace Engelsystem\Helpers\Translation;
+
+use Gettext\Translator;
+
+class GettextTranslator extends Translator
+{
+ /**
+ * @param string $domain
+ * @param string $context
+ * @param string $original
+ * @return string
+ * @throws TranslationNotFound
+ */
+ public function dpgettext($domain, $context, $original)
+ {
+ $this->assertHasTranslation($domain, $context, $original);
+
+ return parent::dpgettext($domain, $context, $original);
+ }
+
+ /**
+ * @param string $domain
+ * @param string $context
+ * @param string $original
+ * @param string $plural
+ * @param string $value
+ * @return string
+ * @throws TranslationNotFound
+ */
+ public function dnpgettext($domain, $context, $original, $plural, $value)
+ {
+ $this->assertHasTranslation($domain, $context, $original);
+
+ return parent::dnpgettext($domain, $context, $original, $plural, $value);
+ }
+
+ /**
+ * @param string $domain
+ * @param string $context
+ * @param string $original
+ * @throws TranslationNotFound
+ */
+ protected function assertHasTranslation($domain, $context, $original)
+ {
+ if ($this->getTranslation($domain, $context, $original)) {
+ return;
+ }
+
+ throw new TranslationNotFound(implode('/', [$domain, $context, $original]));
+ }
+}
diff --git a/src/Helpers/Translation/TranslationNotFound.php b/src/Helpers/Translation/TranslationNotFound.php
new file mode 100644
index 00000000..1552838b
--- /dev/null
+++ b/src/Helpers/Translation/TranslationNotFound.php
@@ -0,0 +1,9 @@
+<?php
+
+namespace Engelsystem\Helpers\Translation;
+
+use Exception;
+
+class TranslationNotFound extends Exception
+{
+}
diff --git a/src/Helpers/Translation/TranslationServiceProvider.php b/src/Helpers/Translation/TranslationServiceProvider.php
new file mode 100644
index 00000000..09337dad
--- /dev/null
+++ b/src/Helpers/Translation/TranslationServiceProvider.php
@@ -0,0 +1,86 @@
+<?php
+
+namespace Engelsystem\Helpers\Translation;
+
+use Engelsystem\Config\Config;
+use Engelsystem\Container\ServiceProvider;
+use Gettext\Translations;
+use Symfony\Component\HttpFoundation\Session\Session;
+
+class TranslationServiceProvider extends ServiceProvider
+{
+ /** @var GettextTranslator */
+ protected $translators = [];
+
+ public function register(): void
+ {
+ /** @var Config $config */
+ $config = $this->app->get('config');
+ /** @var Session $session */
+ $session = $this->app->get('session');
+
+ $locales = $config->get('locales');
+ $locale = $config->get('default_locale');
+ $fallbackLocale = $config->get('fallback_locale', 'en_US');
+
+ $sessionLocale = $session->get('locale', $locale);
+ if (isset($locales[$sessionLocale])) {
+ $locale = $sessionLocale;
+ }
+
+ $session->set('locale', $locale);
+
+ $translator = $this->app->make(
+ Translator::class,
+ [
+ 'locale' => $locale,
+ 'locales' => $locales,
+ 'fallbackLocale' => $fallbackLocale,
+ 'getTranslatorCallback' => [$this, 'getTranslator'],
+ 'localeChangeCallback' => [$this, 'setLocale'],
+ ]
+ );
+ $this->app->instance(Translator::class, $translator);
+ $this->app->instance('translator', $translator);
+ }
+
+ /**
+ * @param string $locale
+ * @codeCoverageIgnore
+ */
+ public function setLocale(string $locale): void
+ {
+ $locale .= '.UTF-8';
+ // Set the users locale
+ putenv('LC_ALL=' . $locale);
+ setlocale(LC_ALL, $locale);
+
+ // Reset numeric formatting to allow output of floats
+ putenv('LC_NUMERIC=C');
+ setlocale(LC_NUMERIC, 'C');
+ }
+
+ /**
+ * @param string $locale
+ * @return GettextTranslator
+ */
+ public function getTranslator(string $locale): GettextTranslator
+ {
+ if (!isset($this->translators[$locale])) {
+ $file = $this->app->get('path.lang') . '/' . $locale . '/default.mo';
+
+ /** @var GettextTranslator $translator */
+ $translator = $this->app->make(GettextTranslator::class);
+
+ /** @var Translations $translations */
+ $translations = $this->app->make(Translations::class);
+ $translations->addFromMoFile($file);
+
+ $translator->loadTranslations($translations);
+
+ $this->translators[$locale] = $translator;
+ }
+
+ return $this->translators[$locale];
+ }
+}
diff --git a/src/Helpers/Translator.php b/src/Helpers/Translation/Translator.php
index 94fbd795..8b11ecb4 100644
--- a/src/Helpers/Translator.php
+++ b/src/Helpers/Translation/Translator.php
@@ -1,6 +1,6 @@
<?php
-namespace Engelsystem\Helpers;
+namespace Engelsystem\Helpers\Translation;
class Translator
{
@@ -10,6 +10,12 @@ class Translator
/** @var string */
protected $locale;
+ /** @var string */
+ protected $fallbackLocale;
+
+ /** @var callable */
+ protected $getTranslatorCallback;
+
/** @var callable */
protected $localeChangeCallback;
@@ -17,15 +23,24 @@ class Translator
* Translator constructor.
*
* @param string $locale
+ * @param string $fallbackLocale
+ * @param callable $getTranslatorCallback
* @param string[] $locales
* @param callable $localeChangeCallback
*/
- public function __construct(string $locale, array $locales = [], callable $localeChangeCallback = null)
- {
+ public function __construct(
+ string $locale,
+ string $fallbackLocale,
+ callable $getTranslatorCallback,
+ array $locales = [],
+ callable $localeChangeCallback = null
+ ) {
$this->localeChangeCallback = $localeChangeCallback;
+ $this->getTranslatorCallback = $getTranslatorCallback;
$this->setLocale($locale);
- $this->setLocales($locales);
+ $this->fallbackLocale = $fallbackLocale;
+ $this->locales = $locales;
}
/**
@@ -37,9 +52,7 @@ class Translator
*/
public function translate(string $key, array $replace = []): string
{
- $translated = $this->translateGettext($key);
-
- return $this->replaceText($translated, $replace);
+ return $this->translateText('gettext', [$key], $replace);
}
/**
@@ -53,7 +66,29 @@ class Translator
*/
public function translatePlural(string $key, string $pluralKey, int $number, array $replace = []): string
{
- $translated = $this->translateGettextPlural($key, $pluralKey, $number);
+ return $this->translateText('ngettext', [$key, $pluralKey, $number], $replace);
+ }
+
+ /**
+ * @param string $type
+ * @param array $parameters
+ * @param array $replace
+ * @return mixed|string
+ */
+ protected function translateText(string $type, array $parameters, array $replace = [])
+ {
+ $translated = $parameters[0];
+
+ foreach ([$this->locale, $this->fallbackLocale] as $lang) {
+ /** @var GettextTranslator $translator */
+ $translator = call_user_func($this->getTranslatorCallback, $lang);
+
+ try {
+ $translated = call_user_func_array([$translator, $type], $parameters);
+ break;
+ } catch (TranslationNotFound $e) {
+ }
+ }
return $this->replaceText($translated, $replace);
}
@@ -75,32 +110,6 @@ class Translator
}
/**
- * Translate the key via gettext
- *
- * @param string $key
- * @return string
- * @codeCoverageIgnore
- */
- protected function translateGettext(string $key): string
- {
- return gettext($key);
- }
-
- /**
- * Translate the key via gettext
- *
- * @param string $key
- * @param string $keyPlural
- * @param int $number
- * @return string
- * @codeCoverageIgnore
- */
- protected function translateGettextPlural(string $key, string $keyPlural, int $number): string
- {
- return ngettext($key, $keyPlural, $number);
- }
-
- /**
* @return string
*/
public function getLocale(): string
diff --git a/src/Helpers/TranslationServiceProvider.php b/src/Helpers/TranslationServiceProvider.php
deleted file mode 100644
index 4565dfcd..00000000
--- a/src/Helpers/TranslationServiceProvider.php
+++ /dev/null
@@ -1,63 +0,0 @@
-<?php
-
-namespace Engelsystem\Helpers;
-
-use Engelsystem\Config\Config;
-use Engelsystem\Container\ServiceProvider;
-use Symfony\Component\HttpFoundation\Session\Session;
-
-class TranslationServiceProvider extends ServiceProvider
-{
- public function register()
- {
- /** @var Config $config */
- $config = $this->app->get('config');
- /** @var Session $session */
- $session = $this->app->get('session');
-
- $locales = $config->get('locales');
- $locale = $config->get('default_locale');
-
- $sessionLocale = $session->get('locale', $locale);
- if (isset($locales[$sessionLocale])) {
- $locale = $sessionLocale;
- }
-
- $this->initGettext();
- $session->set('locale', $locale);
-
- $translator = $this->app->make(
- Translator::class,
- ['locale' => $locale, 'locales' => $locales, 'localeChangeCallback' => [$this, 'setLocale']]
- );
- $this->app->instance(Translator::class, $translator);
- $this->app->instance('translator', $translator);
- }
-
- /**
- * @param string $textDomain
- * @param string $encoding
- * @codeCoverageIgnore
- */
- protected function initGettext($textDomain = 'default', $encoding = 'UTF-8')
- {
- bindtextdomain($textDomain, $this->app->get('path.lang'));
- bind_textdomain_codeset($textDomain, $encoding);
- textdomain($textDomain);
- }
-
- /**
- * @param string $locale
- * @codeCoverageIgnore
- */
- public function setLocale($locale)
- {
- // Set the users locale
- putenv('LC_ALL=' . $locale);
- setlocale(LC_ALL, $locale);
-
- // Reset numeric formatting to allow output of floats
- putenv('LC_NUMERIC=C');
- setlocale(LC_NUMERIC, 'C');
- }
-}