Version 1
[yaffs-website] / web / core / modules / locale / src / PoDatabaseReader.php
diff --git a/web/core/modules/locale/src/PoDatabaseReader.php b/web/core/modules/locale/src/PoDatabaseReader.php
new file mode 100644 (file)
index 0000000..55c2b69
--- /dev/null
@@ -0,0 +1,171 @@
+<?php
+
+namespace Drupal\locale;
+
+use Drupal\Component\Gettext\PoHeader;
+use Drupal\Component\Gettext\PoItem;
+use Drupal\Component\Gettext\PoReaderInterface;
+
+/**
+ * Gettext PO reader working with the locale module database.
+ */
+class PoDatabaseReader implements PoReaderInterface {
+
+  /**
+   * An associative array indicating which type of strings should be read.
+   *
+   * Elements of the array:
+   *  - not_customized: boolean indicating if not customized strings should be
+   *    read.
+   *  - customized: boolean indicating if customized strings should be read.
+   *  - no_translated: boolean indicating if non-translated should be read.
+   *
+   * The three options define three distinct sets of strings, which combined
+   * cover all strings.
+   *
+   * @var array
+   */
+  private $options;
+
+  /**
+   * Language code of the language being read from the database.
+   *
+   * @var string
+   */
+  private $langcode;
+
+  /**
+   * Store the result of the query so it can be iterated later.
+   *
+   * @var resource
+   */
+  private $result;
+
+  /**
+   * Constructor, initializes with default options.
+   */
+  public function __construct() {
+    $this->setOptions([]);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getLangcode() {
+    return $this->langcode;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setLangcode($langcode) {
+    $this->langcode = $langcode;
+  }
+
+  /**
+   * Get the options used by the reader.
+   */
+  public function getOptions() {
+    return $this->options;
+  }
+
+  /**
+   * Set the options for the current reader.
+   */
+  public function setOptions(array $options) {
+    $options += [
+      'customized' => FALSE,
+      'not_customized' => FALSE,
+      'not_translated' => FALSE,
+    ];
+    $this->options = $options;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getHeader() {
+    return new PoHeader($this->getLangcode());
+  }
+
+  /**
+   * Implements Drupal\Component\Gettext\PoMetadataInterface::setHeader().
+   *
+   * @throws Exception
+   *   Always, because you cannot set the PO header of a reader.
+   */
+  public function setHeader(PoHeader $header) {
+    throw new \Exception('You cannot set the PO header in a reader.');
+  }
+
+  /**
+   * Builds and executes a database query based on options set earlier.
+   */
+  private function loadStrings() {
+    $langcode = $this->langcode;
+    $options = $this->options;
+    $conditions = [];
+
+    if (array_sum($options) == 0) {
+      // If user asked to not include anything in the translation files,
+      // that would not make sense, so just fall back on providing a template.
+      $langcode = NULL;
+      // Force option to get both translated and untranslated strings.
+      $options['not_translated'] = TRUE;
+    }
+    // Build and execute query to collect source strings and translations.
+    if (!empty($langcode)) {
+      $conditions['language'] = $langcode;
+      // Translate some options into field conditions.
+      if ($options['customized']) {
+        if (!$options['not_customized']) {
+          // Filter for customized strings only.
+          $conditions['customized'] = LOCALE_CUSTOMIZED;
+        }
+        // Else no filtering needed in this case.
+      }
+      else {
+        if ($options['not_customized']) {
+          // Filter for non-customized strings only.
+          $conditions['customized'] = LOCALE_NOT_CUSTOMIZED;
+        }
+        else {
+          // Filter for strings without translation.
+          $conditions['translated'] = FALSE;
+        }
+      }
+      if (!$options['not_translated']) {
+        // Filter for string with translation.
+        $conditions['translated'] = TRUE;
+      }
+      return \Drupal::service('locale.storage')->getTranslations($conditions);
+    }
+    else {
+      // If no language, we don't need any of the target fields.
+      return \Drupal::service('locale.storage')->getStrings($conditions);
+    }
+  }
+
+  /**
+   * Get the database result resource for the given language and options.
+   */
+  private function readString() {
+    if (!isset($this->result)) {
+      $this->result = $this->loadStrings();
+    }
+    return array_shift($this->result);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function readItem() {
+    if ($string = $this->readString()) {
+      $values = (array) $string;
+      $po_item = new PoItem();
+      $po_item->setFromArray($values);
+      return $po_item;
+    }
+  }
+
+}