aboutsummaryrefslogtreecommitdiff
path: root/lib/classes/I18NString.php
diff options
context:
space:
mode:
authorJan-Hendrik Willms <tleilax+github@gmail.com>2021-07-22 16:07:19 +0200
committerJan-Hendrik Willms <tleilax+github@gmail.com>2021-07-22 16:19:12 +0200
commita3da1483a9e689846179159355badfec8073dbec (patch)
tree770dcca6bdf5f6f2a11b0e7fcbbeda6919a3fc52 /lib/classes/I18NString.php
current code from svn, revision 62608
Diffstat (limited to 'lib/classes/I18NString.php')
-rw-r--r--lib/classes/I18NString.php368
1 files changed, 368 insertions, 0 deletions
diff --git a/lib/classes/I18NString.php b/lib/classes/I18NString.php
new file mode 100644
index 0000000..4dc6156
--- /dev/null
+++ b/lib/classes/I18NString.php
@@ -0,0 +1,368 @@
+<?php
+
+/**
+ * I18NString class
+ */
+class I18NString
+{
+
+ /**
+ * Text in default content language.
+ *
+ * @var string
+ */
+ protected $base;
+
+ /**
+ * Text in additional languages.
+ *
+ * @var array|null
+ */
+ protected $lang;
+
+ /**
+ * Database info for id, table, field.
+ *
+ * @var array
+ */
+ protected $metadata;
+
+ /**
+ * Holds the language the content is translated into.
+ *
+ * @var string
+ */
+ protected static $content_language = null;
+
+ /**
+ * Holds the language the content is translated into by default.
+ *
+ * @var string
+ */
+ protected static $default_language = null;
+
+ /**
+ * Initialize a new I18NString instance.
+ *
+ * @param string $base Text in default content language.
+ * @param array $lang Text in additional languages.
+ * @param array $metadata Database info for id, table, field.
+ */
+ public function __construct($base, $lang = null, $metadata = [])
+ {
+ $this->base = $base;
+ $this->lang = $lang;
+ $this->metadata = $metadata;
+ }
+
+ /**
+ * Return the text representation of this i18n field in selected language.
+ * The language is selected by self::content_language (with precendence)
+ * or by $_SESSION['_language'].
+ *
+ * @returns string
+ */
+ public function __toString()
+ {
+ if (self::$content_language) {
+ return $this->localized(self::$content_language) ?? (string) $this->base;
+ } else {
+ if (isset($_SESSION['_language'])
+ && $_SESSION['_language'] != self::getDefaultLanguage()
+ && $this->translation($_SESSION['_language'])) {
+ return $this->translation($_SESSION['_language']);
+ }
+ }
+
+ return (string) $this->base;
+ }
+
+ /**
+ * Sets the language the content is translated into.
+ *
+ * @param string $language
+ */
+ public static function setContentLanguage($language)
+ {
+ self::$content_language = $language;
+ }
+
+ /**
+ * Returns the language the contnet is translated into.
+ *
+ * @return string The language the content is translated into.
+ */
+ public static function getContentLanguage()
+ {
+ return self::$content_language ?: self::getDefaultLanguage();
+ }
+
+ /**
+ * Sets the default language the content is translated into. The default is
+ * normally defined by the first entry in $GLOBALS['CONTENT_LANGUAGES'] (see
+ * config_defaults.inc.php).
+ *
+ * @param string $language
+ */
+ public static function setDefaultLanguage($language = null)
+ {
+ self::$default_language = $language ?: key($GLOBALS['CONTENT_LANGUAGES']);
+ }
+
+ /**
+ * Returns the language all values are translated into by default. The
+ * language ist normally defined in $GLOBALS['CONTENT_LANGUAGES'] (see
+ * config_defaults.inc.php).
+ *
+ * @return string The default language all values are translated into.
+ */
+ public static function getDefaultLanguage()
+ {
+ return self::$default_language ?: key($GLOBALS['CONTENT_LANGUAGES']);
+ }
+
+ /**
+ * Sets the original (untranslated) value of this i18n field.
+ *
+ * @param string $text The original value.
+ * @return string The original value.
+ */
+ public function setOriginal($text)
+ {
+ return $this->base = $text;
+ }
+
+ /**
+ * Sets all translations of this i18n field.
+ *
+ * @param array $lang An array with languages as keys and translations
+ * as values.
+ * @return array The array with translations.
+ */
+ public function setTranslations($lang)
+ {
+ return $this->lang = $lang;
+ }
+
+ /**
+ * Sets the metadata (database info for id, table, field) of this i18n field.
+ *
+ * @param array $metadata Database info for id, table, field.
+ */
+ public function setMetadata($metadata)
+ {
+ $this->metadata = $metadata;
+ }
+
+ /**
+ * Return the string in the default content language.
+ *
+ * @return string String in default content language.
+ */
+ public function original()
+ {
+ return $this->base;
+ }
+
+ /**
+ * Return the string in the specified additional language.
+ *
+ * @param string The additional language.
+ * @return string The translated value.
+ */
+ public function translation($lang)
+ {
+ return $this->toArray()[$lang];
+ }
+
+ /**
+ * Returns the string in the specified language (additional languages and
+ * default languages).
+ *
+ * @param string $lang Additional language or default language.
+ * @return string The localized string.
+ */
+ public function localized($lang)
+ {
+ if ($lang == self::getDefaultLanguage()) {
+ return $this->base;
+ }
+
+ return $this->translation($lang);
+ }
+
+ /**
+ * Sets the translation for the given language. If the given language is
+ * the default language, sets the original.
+ *
+ * @param type $text The translated or original value.
+ * @param type $lang The additional or default language.
+ * @return string The translated or original value.
+ * @throws InvalidArgumentException
+ */
+ public function setLocalized($text, $lang)
+ {
+ if ($lang == self::getDefaultLanguage()) {
+ return $this->setOriginal($text);
+ }
+
+ if (!Config::get()->CONTENT_LANGUAGES[$lang]) {
+ throw new InvalidArgumentException('Language not configured.');
+ }
+
+ return $this->lang[$lang] = $text;
+ }
+
+ /**
+ * Return an array containing the text in all additional languages.
+ *
+ * @return array The array with translations.
+ */
+ public function toArray()
+ {
+ if (is_null($this->lang)) {
+ $object_id = $this->metadata['object_id'];
+ $table = $this->metadata['table'];
+ $field = $this->metadata['field'];
+ if (!$table || !$field) {
+ throw new RuntimeException('fetching translations not possible, metadata is missing');
+ }
+ $this->lang = self::fetchDataForField($object_id, $table, $field);
+ }
+ return $this->lang;
+ }
+
+ /**
+ * Trim all language strings
+ *
+ * @param string $symbols All symbols to trim.
+ * @return I18NString Returns this.
+ */
+ public function trim($symbols = " \t\n\r\0\x0B")
+ {
+ foreach ($this->lang as &$lang) {
+ $lang = trim($lang, $symbols);
+ }
+ $this->base = trim($this->base, $symbols);
+ return $this;
+ }
+
+ /**
+ * Stores the i18n String manually in the database
+ *
+ */
+ public function storeTranslations()
+ {
+ if (is_array($this->lang)) {
+ $db = DBManager::get();
+ $object_id = $this->metadata['object_id'];
+ $table = $this->metadata['table'];
+ $field = $this->metadata['field'];
+ if (!$object_id || !$table || !$field) {
+ throw new RuntimeException('store not possible, metadata is missing');
+ }
+ /* Replace translations */
+ $deleted = $db->execute("DELETE FROM i18n WHERE object_id = ? AND `table` = ? AND field = ?", [$object_id, $table, $field]);
+ $i18nSQL = $db->prepare("INSERT INTO `i18n` (`object_id`, `table`, `field`, `lang`, `value`) VALUES (?,?,?,?,?)");
+ foreach ($this->lang as $lang => $value) {
+ if (mb_strlen($value)) {
+ $i18nSQL->execute([$object_id, $table, $field, $lang, (string) $value]);
+ }
+ }
+ }
+ }
+
+ /**
+ * Removes all translations for this I18NString object.
+ *
+ */
+ public function removeTranslations()
+ {
+ $this->lang = [];
+ $this->storeTranslations();
+ }
+
+ /**
+ * Returns an I18NString object by given object_id, table and field.
+ *
+ * @param string $object_id The id of the object with i18n fields.
+ * @param string $table The name of the table with the original values.
+ * @param string $field The name of the i18n field.
+ * @param string $base Sets the original value or retrieve it from database
+ * if null.
+ * @return I18NString The I18NString object.
+ */
+ public static function load($object_id, $table, $field, $base = null)
+ {
+ $db = DBManager::get();
+ if (is_null($base)) {
+ // Find pk
+ SimpleORMap::tableScheme($table);
+ if (count(SimpleORMap::$schemes[$table]['pk']) > 1) {
+ throw new RuntimeException(sprintf('table %s has multiple primary key, not implemented yet', $table));
+ } else {
+ $pk = SimpleORMap::$schemes[$table]['pk'][0];
+ }
+ $base = $db->fetchColumn("SELECT `$field` FROM `$table` WHERE `$pk` = ?", [$object_id]);
+ }
+ return new self($base, self::fetchDataForField($object_id, $table, $field), compact('object_id', 'table', 'field'));
+ }
+
+ /**
+ * Retrieves all translations of one field.
+ *
+ * @param string $object_id The id of the object with i18n fields.
+ * @param string $table The name of the table with the original values.
+ * @param string $field The name of the i18n field.
+ * @return array An array with language as key and translation as value.
+ */
+ public static function fetchDataForField($object_id, $table, $field)
+ {
+ $db = DBManager::get();
+ $values = $db->fetchPairs("SELECT `lang`, `value` FROM `i18n` WHERE `object_id` = ? AND `table` = ? AND `field` = ?", [$object_id, $table, $field]);
+ $data = [];
+ foreach (array_keys(Config::get()->CONTENT_LANGUAGES) as $lang) {
+ if ($lang != self::getDefaultLanguage()) {
+ $data[$lang] = mb_strlen($values[$lang]) ? $values[$lang] : null;
+ }
+ }
+ return $data;
+ }
+
+ /**
+ * Retrieves all translations of all fields for given object (by id) and
+ * table.
+ *
+ * @param string $object_id The id of the object with i18n fields.
+ * @param string $table The name of the table with the original values.
+ * @return array An array with all translations of all fields grouped by
+ * field.
+ */
+ public static function fetchDataForRow($object_id, $table)
+ {
+ $db = DBManager::get();
+ return $db->fetchGrouped("SELECT `field`, `lang`, `value` FROM `i18n` WHERE `object_id` = ? AND `table` = ?", [$object_id, $table]);
+ }
+
+ /**
+ * Removes all translations by given object id and table name. Accepts the
+ * language as third parameter to remove only translations to this language.
+ *
+ * @param string $object_id The id of the sorm object.
+ * @param string $table The table name.
+ * @param string $lang Optional name of language.
+ * @return int The number of deleted translations.
+ */
+ public static function removeAllTranslations($object_id, $table, $lang = null)
+ {
+ $db = DBManager::get();
+ if ($lang) {
+ return $db->execute('DELETE FROM `i18n` '
+ . 'WHERE `object_id` = ? AND `table` = ? AND `lang` = ?',
+ [$object_id, $table, $lang]);
+ }
+ return $db->execute('DELETE FROM `i18n` '
+ . 'WHERE `object_id` = ? AND `table` = ?',
+ [$object_id, $table]);
+ }
+}