PoDatabaseReader.php 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. <?php
  2. /**
  3. * @file
  4. * Definition of PoDatabaseReader.
  5. */
  6. /**
  7. * Gettext PO reader working with the locale module database.
  8. */
  9. class PoDatabaseReader implements PoReaderInterface {
  10. /**
  11. * An associative array indicating which type of strings should be read.
  12. *
  13. * Elements of the array:
  14. * - not_customized: boolean indicating if not customized strings should be
  15. * read.
  16. * - customized: boolean indicating if customized strings should be read.
  17. * - no_translated: boolean indicating if non-translated should be read.
  18. *
  19. * The three options define three distinct sets of strings, which combined
  20. * cover all strings.
  21. *
  22. * @var array
  23. */
  24. private $_options;
  25. /**
  26. * Language code of the language being read from the database.
  27. *
  28. * @var string
  29. */
  30. private $_langcode;
  31. /**
  32. * Store the result of the query so it can be iterated later.
  33. *
  34. * @var resource
  35. */
  36. private $_result;
  37. /**
  38. * Database storage to retrieve the strings from.
  39. *
  40. * @var StringDatabaseStorage
  41. */
  42. protected $storage;
  43. /**
  44. * Constructor, initializes with default options.
  45. */
  46. function __construct() {
  47. $this->setOptions(array());
  48. $this->storage = new StringDatabaseStorage();
  49. }
  50. /**
  51. * Implements PoMetadataInterface::getLangcode().
  52. */
  53. public function getLangcode() {
  54. return $this->_langcode;
  55. }
  56. /**
  57. * Implements PoMetadataInterface::setLangcode().
  58. */
  59. public function setLangcode($langcode) {
  60. $this->_langcode = $langcode;
  61. }
  62. /**
  63. * Get the options used by the reader.
  64. */
  65. function getOptions() {
  66. return $this->_options;
  67. }
  68. /**
  69. * Set the options for the current reader.
  70. */
  71. function setOptions(array $options) {
  72. $options += array(
  73. 'customized' => FALSE,
  74. 'not_customized' => FALSE,
  75. 'not_translated' => FALSE,
  76. );
  77. $this->_options = $options;
  78. }
  79. /**
  80. * Implements PoMetadataInterface::getHeader().
  81. */
  82. function getHeader() {
  83. return new PoHeader($this->getLangcode());
  84. }
  85. /**
  86. * Implements PoMetadataInterface::setHeader().
  87. *
  88. * @throws Exception
  89. * Always, because you cannot set the PO header of a reader.
  90. */
  91. function setHeader(PoHeader $header) {
  92. throw new \Exception('You cannot set the PO header in a reader.');
  93. }
  94. /**
  95. * Builds and executes a database query based on options set earlier.
  96. */
  97. private function loadStrings() {
  98. $langcode = $this->_langcode;
  99. $options = $this->_options;
  100. $conditions = array();
  101. if (array_sum($options) == 0) {
  102. // If user asked to not include anything in the translation files,
  103. // that would not make sense, so just fall back on providing a template.
  104. $langcode = NULL;
  105. // Force option to get both translated and untranslated strings.
  106. $options['not_translated'] = TRUE;
  107. }
  108. // Build and execute query to collect source strings and translations.
  109. if (!empty($langcode)) {
  110. $conditions['language'] = $langcode;
  111. // Translate some options into field conditions.
  112. if ($options['customized']) {
  113. if (!$options['not_customized']) {
  114. // Filter for customized strings only.
  115. $conditions['customized'] = L10N_UPDATE_CUSTOMIZED;
  116. }
  117. // Else no filtering needed in this case.
  118. }
  119. else {
  120. if ($options['not_customized']) {
  121. // Filter for non-customized strings only.
  122. $conditions['customized'] = L10N_UPDATE_NOT_CUSTOMIZED;
  123. }
  124. else {
  125. // Filter for strings without translation.
  126. $conditions['translated'] = FALSE;
  127. }
  128. }
  129. if (!$options['not_translated']) {
  130. // Filter for string with translation.
  131. $conditions['translated'] = TRUE;
  132. }
  133. return $this->storage->getTranslations($conditions);
  134. }
  135. else {
  136. // If no language, we don't need any of the target fields.
  137. return $this->storage->getStrings($conditions);
  138. }
  139. }
  140. /**
  141. * Get the database result resource for the given language and options.
  142. */
  143. private function readString() {
  144. if (!isset($this->_result)) {
  145. $this->_result = $this->loadStrings();
  146. }
  147. return array_shift($this->_result);
  148. }
  149. /**
  150. * Implements PoReaderInterface::readItem().
  151. */
  152. function readItem() {
  153. if ($string = $this->readString()) {
  154. $values = (array)$string;
  155. $poItem = new PoItem();
  156. $poItem->setFromArray($values);
  157. return $poItem;
  158. }
  159. }
  160. }