PoDatabaseReader.php 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  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. * D7: Text group.
  39. *
  40. * @var string
  41. */
  42. protected $_textgroup;
  43. /**
  44. * Database storage to retrieve the strings from.
  45. *
  46. * @var StringDatabaseStorage
  47. */
  48. protected $storage;
  49. /**
  50. * Constructor, initializes with default options.
  51. */
  52. public function __construct() {
  53. $this->setOptions(array());
  54. $this->storage = new StringDatabaseStorage();
  55. }
  56. /**
  57. * Implements PoMetadataInterface::getLangcode().
  58. */
  59. public function getLangcode() {
  60. return $this->_langcode;
  61. }
  62. /**
  63. * Implements PoMetadataInterface::setLangcode().
  64. */
  65. public function setLangcode($langcode) {
  66. $this->_langcode = $langcode;
  67. }
  68. /**
  69. * Get the options used by the reader.
  70. */
  71. public function getOptions() {
  72. return $this->_options;
  73. }
  74. /**
  75. * Set the options for the current reader.
  76. */
  77. public function setOptions(array $options) {
  78. $options += array(
  79. 'customized' => FALSE,
  80. 'not_customized' => FALSE,
  81. 'not_translated' => FALSE,
  82. );
  83. $this->_options = $options;
  84. }
  85. /**
  86. * @param \string $textgroup
  87. */
  88. public function setTextgroup($textgroup) {
  89. $this->_textgroup = $textgroup;
  90. }
  91. /**
  92. * Implements PoMetadataInterface::getHeader().
  93. */
  94. public function getHeader() {
  95. return new PoHeader($this->getLangcode());
  96. }
  97. /**
  98. * Implements PoMetadataInterface::setHeader().
  99. *
  100. * @throws Exception
  101. * Always, because you cannot set the PO header of a reader.
  102. */
  103. public function setHeader(PoHeader $header) {
  104. throw new \Exception('You cannot set the PO header in a reader.');
  105. }
  106. /**
  107. * Builds and executes a database query based on options set earlier.
  108. */
  109. private function loadStrings() {
  110. $langcode = $this->_langcode;
  111. $options = $this->_options;
  112. $textgroup = $this->_textgroup;
  113. $conditions = array();
  114. if ($textgroup) {
  115. $conditions['textgroup'] = $textgroup;
  116. }
  117. if (array_sum($options) == 0) {
  118. // If user asked to not include anything in the translation files,
  119. // that would not make sense, so just fall back on providing a template.
  120. $langcode = NULL;
  121. // Force option to get both translated and untranslated strings.
  122. $options['not_translated'] = TRUE;
  123. }
  124. // Build and execute query to collect source strings and translations.
  125. if (!empty($langcode)) {
  126. $conditions['language'] = $langcode;
  127. // Translate some options into field conditions.
  128. if ($options['customized']) {
  129. if (!$options['not_customized']) {
  130. // Filter for customized strings only.
  131. $conditions['customized'] = L10N_UPDATE_CUSTOMIZED;
  132. }
  133. // Else no filtering needed in this case.
  134. }
  135. else {
  136. if ($options['not_customized']) {
  137. // Filter for non-customized strings only.
  138. $conditions['customized'] = L10N_UPDATE_NOT_CUSTOMIZED;
  139. }
  140. else {
  141. // Filter for strings without translation.
  142. $conditions['translated'] = FALSE;
  143. }
  144. }
  145. if (!$options['not_translated']) {
  146. // Filter for string with translation.
  147. $conditions['translated'] = TRUE;
  148. }
  149. return $this->storage->getTranslations($conditions);
  150. }
  151. else {
  152. // If no language, we don't need any of the target fields.
  153. return $this->storage->getStrings($conditions);
  154. }
  155. }
  156. /**
  157. * Get the database result resource for the given language and options.
  158. */
  159. private function readString() {
  160. if (!isset($this->_result)) {
  161. $this->_result = $this->loadStrings();
  162. }
  163. return array_shift($this->_result);
  164. }
  165. /**
  166. * Implements PoReaderInterface::readItem().
  167. */
  168. public function readItem() {
  169. if ($string = $this->readString()) {
  170. $values = (array) $string;
  171. $poItem = new PoItem();
  172. $poItem->setFromArray($values);
  173. return $poItem;
  174. }
  175. }
  176. }