tmgmt_locale.plugin.inc 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. <?php
  2. /**
  3. * @file
  4. * Provides the locale source controller.
  5. */
  6. /**
  7. * Translation plugin controller for locale strings.
  8. */
  9. class TMGMTLocaleSourcePluginController extends TMGMTDefaultSourcePluginController {
  10. /**
  11. * Updates translation associated to a specific locale source.
  12. *
  13. * @param string $lid
  14. * The Locale ID.
  15. * @param string $target_language
  16. * Target language to update translation.
  17. * @param string $translation
  18. * Translation value.
  19. *
  20. * @return bool
  21. * Success or not updating the locale translation.
  22. */
  23. protected function updateTranslation($lid, $target_language, $translation) {
  24. $languages = locale_language_list('name', TRUE);
  25. if (!$lid || !array_key_exists($target_language, $languages) || !$translation) {
  26. return FALSE;
  27. }
  28. $exists = db_query("SELECT COUNT(lid) FROM {locales_target} WHERE lid = :lid AND language = :language", array(':lid' => $lid, ':language' => $target_language))
  29. ->fetchField();
  30. $fields = array(
  31. 'translation' => $translation,
  32. );
  33. if (module_exists('l10n_update')) {
  34. module_load_include('inc', 'l10n_update');
  35. $fields += array(
  36. 'l10n_status' => L10N_UPDATE_STRING_CUSTOM,
  37. );
  38. }
  39. // @todo Only singular strings are managed here, we should take care of
  40. // plural information of processed string.
  41. if (!$exists) {
  42. $fields += array(
  43. 'lid' => $lid,
  44. 'language' => $target_language,
  45. );
  46. db_insert('locales_target')
  47. ->fields($fields)
  48. ->execute();
  49. }
  50. else {
  51. db_update('locales_target')
  52. ->fields($fields)
  53. ->condition('lid', $lid)
  54. ->condition('language', $target_language)
  55. ->execute();
  56. }
  57. // Clear locale caches.
  58. _locale_invalidate_js($target_language);
  59. cache_clear_all('locale:' . $target_language, 'cache');
  60. return TRUE;
  61. }
  62. /**
  63. * Helper function to obtain a locale object for given job item.
  64. *
  65. * @param TMGMTJobItem $job_item
  66. *
  67. * @return locale object
  68. */
  69. protected function getLocaleObject(TMGMTJobItem $job_item) {
  70. $locale_lid = $job_item->item_id;
  71. // Check existence of assigned lid.
  72. $exists = db_query("SELECT COUNT(lid) FROM {locales_source} WHERE lid = :lid", array(':lid' => $locale_lid))->fetchField();
  73. if (!$exists) {
  74. throw new TMGMTException(t('Unable to load locale with id %id', array('%id' => $job_item->item_id)));
  75. }
  76. // This is necessary as the method is also used in the getLabel() callback
  77. // and for that case the job is not available in the cart.
  78. if (!empty($job_item->tjid)) {
  79. $source_language = $job_item->getJob()->source_language;
  80. }
  81. else {
  82. $source_language = $job_item->getSourceLangCode();
  83. }
  84. if ($source_language == 'en') {
  85. $query = db_select('locales_source', 'ls');
  86. $query
  87. ->fields('ls')
  88. ->condition('ls.lid', $locale_lid);
  89. $locale_object = $query
  90. ->execute()
  91. ->fetchObject();
  92. $locale_object->language = 'en';
  93. if (empty($locale_object)) {
  94. return null;
  95. }
  96. $locale_object->origin = 'source';
  97. }
  98. else {
  99. $query = db_select('locales_target', 'lt');
  100. $query->join('locales_source', 'ls', 'ls.lid = lt.lid');
  101. $query
  102. ->fields('lt')
  103. ->fields('ls')
  104. ->condition('lt.lid', $locale_lid)
  105. ->condition('lt.language', $source_language);
  106. $locale_object = $query
  107. ->execute()
  108. ->fetchObject();
  109. if (empty($locale_object)) {
  110. return null;
  111. }
  112. $locale_object->origin = 'target';
  113. }
  114. return $locale_object;
  115. }
  116. /**
  117. * {@inheritdoc}
  118. */
  119. public function getLabel(TMGMTJobItem $job_item) {
  120. if ($locale_object = $this->getLocaleObject($job_item)) {
  121. if ($locale_object->origin == 'source') {
  122. $label = $locale_object->source;
  123. }
  124. else {
  125. $label = $locale_object->translation;
  126. }
  127. return truncate_utf8(strip_tags($label), 30, FALSE, TRUE);
  128. }
  129. }
  130. /**
  131. * [@inheritdoc}
  132. */
  133. public function getType(TMGMTJobItem $job_item) {
  134. return $this->getItemTypeLabel($job_item->item_type);
  135. }
  136. /**
  137. * {@inheritdoc}
  138. */
  139. public function getData(TMGMTJobItem $job_item) {
  140. $locale_object = $this->getLocaleObject($job_item);
  141. if (empty($locale_object)) {
  142. $languages = language_list();
  143. throw new TMGMTException(t('Unable to load %language translation for the locale %id',
  144. array('%language' => $languages[$job_item->getJob()->source_language]->name, '%id' => $job_item->item_id)));
  145. }
  146. if ($locale_object->origin == 'source') {
  147. $text = $locale_object->source;
  148. }
  149. else {
  150. $text = $locale_object->translation;
  151. }
  152. // Identify placeholders that need to be escaped. Assume that placeholders
  153. // consist of alphanumeric characters and _,- only and are delimited by
  154. // non-alphanumeric characters. There are cases that don't match, for
  155. // example appended SI units like "@valuems", there only @value is the
  156. // actual placeholder.
  157. $escape = array();
  158. if (preg_match_all('/([@!%][a-zA-Z0-9_-]+)/', $text, $matches, PREG_OFFSET_CAPTURE)) {
  159. foreach ($matches[0] as $match) {
  160. $escape[$match[1]]['string'] = $match[0];
  161. }
  162. }
  163. $structure['singular'] = array(
  164. '#label' => t('Singular'),
  165. '#text' => (string) $text,
  166. '#translate' => TRUE,
  167. '#escape' => $escape,
  168. );
  169. return $structure;
  170. }
  171. /**
  172. * {@inheritdoc}
  173. */
  174. public function saveTranslation(TMGMTJobItem $job_item) {
  175. $job = tmgmt_job_load($job_item->tjid);
  176. $data = $job_item->getData();
  177. if (isset($data['singular'])) {
  178. $translation = $data['singular']['#translation']['#text'];
  179. // Update the locale string in the system.
  180. // @todo: Send error message to user if update fails.
  181. if ($this->updateTranslation($job_item->item_id, $job->target_language, $translation)) {
  182. $job_item->accepted();
  183. }
  184. }
  185. // @todo: Temporary backwards compability with existing jobs, remove in next
  186. // release.
  187. if (isset($data[$job_item->item_id])) {
  188. $translation = $data[$job_item->item_id]['#translation']['#text'];
  189. // Update the locale string in the system.
  190. // @todo: Send error message to user if update fails.
  191. if ($this->updateTranslation($job_item->item_id, $job->target_language, $translation)) {
  192. $job_item->accepted();
  193. }
  194. }
  195. }
  196. /**
  197. * {@inheritdoc}
  198. */
  199. public function getSourceLangCode(TMGMTJobItem $job_item) {
  200. // For the locale source English is always the source language.
  201. return 'en';
  202. }
  203. /**
  204. * {@inheritdoc}
  205. */
  206. public function getExistingLangCodes(TMGMTJobItem $job_item) {
  207. $query = db_select('locales_target', 'lt');
  208. $query->fields('lt', array('language'));
  209. $query->condition('lt.lid', $job_item->item_id);
  210. $existing_lang_codes = array('en');
  211. foreach ($query->execute() as $language) {
  212. $existing_lang_codes[] = $language->language;
  213. }
  214. return $existing_lang_codes;
  215. }
  216. }