i18nblocks.module

Tracking 6.x-1.x branch
  1. drupal
    1. 5 contributions/i18n/i18nblocks/i18nblocks.module
    2. 6 contributions/i18n/i18nblocks/i18nblocks.module

Internationalization (i18n) submodule: Multilingual meta-blocks

@author Jose A. Reyero, 2005

@ TODO Add strings on block update.

Functions & methods

NameDescription
i18nblocks_block_delete_submitRemove strings for deleted custom blocks.
i18nblocks_db_rewrite_sqlImplementation of hook_db_rewrite_sql().
i18nblocks_form_alterImplementation of block form_alter().
i18nblocks_form_block_box_delete_alterImplementation of hook_form_FORM_ID_alter().
i18nblocks_form_submitForms api callback. Submit function.
i18nblocks_helpImplementation of hook_help().
i18nblocks_loadGet block language data.
i18nblocks_localeImplementation of hook_locale().
i18nblocks_locale_refreshRefresh all strings.
i18nblocks_preprocess_blockImplementation of hook_preprocess_block().
i18nblocks_saveSet block language data.
i18nblocks_translate_blockTranslate block.
_block_typesBlock types
_i18nblocks_listGet list of blocks i18n properties

Constants

NameDescription
I18N_BLOCK_LANGUAGE
I18N_BLOCK_LOCALIZABLE
I18N_BLOCK_LOCALIZE

File

View source
  1. <?php
  2. /**
  3. * @file
  4. * Internationalization (i18n) submodule: Multilingual meta-blocks
  5. *
  6. * @author Jose A. Reyero, 2005
  7. *
  8. * @ TODO Add strings on block update.
  9. */
  10. // Tag for localizable block, cannot be any language.
  11. define('I18N_BLOCK_LOCALIZE', '__LOCALIZE__');
  12. // Block type: localizable
  13. define('I18N_BLOCK_LOCALIZABLE', 1);
  14. // Block type: block with language
  15. define('I18N_BLOCK_LANGUAGE', 0);
  16. /**
  17. * Block types
  18. */
  19. function _block_types() {
  20. return array(
  21. I18N_BLOCK_LOCALIZE => t('Localizable block'),
  22. I18N_BLOCK_METABLOCK => t('Multilingual block (Metablock)'),
  23. );
  24. }
  25. /**
  26. * Implementation of hook_help().
  27. */
  28. function i18nblocks_help($path, $arg) {
  29. switch ($path) {
  30. case 'admin/help#i18nblocks':
  31. $output = '<p>'. t('This module provides support for multilingual blocks.') .'</p>';
  32. $output .= '<p>'. t('You can set up a language for a block or define it as translatable:') .'</p>';
  33. $output .= '<ul>';
  34. $output .= '<li>'. t('Blocks with a language will be displayed only in pages with that language.') .'</li>';
  35. $output .= '<li>'. t('Translatable blocks can be translated using the localization interface.') .'</li>';
  36. $output .= '</ul>';
  37. $output .= '<p>'. t('To search and translate strings, use the <a href="@translate-interface">translation interface</a> pages.', array('@translate-interface' => url('admin/build/translate'))) .'</p>';
  38. return $output;
  39. }
  40. }
  41. /**
  42. * Implementation of hook_db_rewrite_sql().
  43. */
  44. function i18nblocks_db_rewrite_sql($query, $primary_table, $primary_key) {
  45. if ($primary_table == 'b' && $primary_key == 'bid') {
  46. $return['join'] = 'LEFT JOIN {i18n_blocks} i18n ON (b.module = i18n.module AND b.delta = i18n.delta)';
  47. $return['where'] = i18n_db_rewrite_where('i18n', 'block', 'simple');
  48. return $return;
  49. }
  50. }
  51. /**
  52. * Implementation of hook_locale().
  53. *
  54. * This one doesn't need locale refresh because strings are stored from module config form.
  55. */
  56. function i18nblocks_locale($op = 'groups', $group = NULL) {
  57. switch ($op) {
  58. case 'groups':
  59. return array('blocks' => t('Blocks'));
  60. case 'info':
  61. $info['blocks']['refresh callback'] = 'i18nblocks_locale_refresh';
  62. $info['blocks']['format'] = TRUE;
  63. return $info;
  64. }
  65. }
  66. /**
  67. * Refresh all strings.
  68. */
  69. function i18nblocks_locale_refresh() {
  70. $result = db_query("SELECT DISTINCT b.module, b.delta, b.title, bx.body, bx.format, i.ibid, i.language FROM {blocks} b LEFT JOIN {boxes} bx ON b.module = 'block' AND b.delta = bx.bid LEFT JOIN {i18n_blocks} i ON b.module = i.module AND b.delta = i.delta");
  71. while ($block = db_fetch_object($result)) {
  72. if (!$block->language) {
  73. // If the block has a custom title and no language it must be translated
  74. if ($block->title && $block->title != '<none>') {
  75. i18nstrings_update("blocks:$block->module:$block->delta:title", $block->title);
  76. }
  77. // If the block has body and no language, must be a custom block (box)
  78. if ($block->body) {
  79. i18nstrings_update("blocks:$block->module:$block->delta:body", $block->body, $block->format);
  80. }
  81. }
  82. }
  83. return TRUE; // Meaning it completed with no issues
  84. }
  85. /**
  86. * Implementation of hook_form_FORM_ID_alter().
  87. */
  88. function i18nblocks_form_block_box_delete_alter(&$form, $form_state) {
  89. $delta = db_result(db_query("SELECT ibid FROM {i18n_blocks} WHERE delta = '%d'", arg(4)));
  90. $form['delta'] = array(
  91. '#type' => 'value',
  92. '#value' => $delta,
  93. );
  94. $form['#submit'][] = 'i18nblocks_block_delete_submit';
  95. }
  96. /**
  97. * Remove strings for deleted custom blocks.
  98. */
  99. function i18nblocks_block_delete_submit(&$form, $form_state) {
  100. $delta = $form_state['values']['delta'];
  101. // Delete stored strings for the title and content fields.
  102. i18nstrings_remove_string("blocks:block:$delta:title");
  103. i18nstrings_remove_string("blocks:block:$delta:body");
  104. }
  105. /**
  106. * Implementation of block form_alter().
  107. *
  108. * Remove block title for multilingual blocks.
  109. */
  110. function i18nblocks_form_alter(&$form, $form_state, $form_id) {
  111. if (($form_id == 'block_admin_configure' || $form_id == 'block_box_form' || $form_id == 'block_add_block_form')) {
  112. $module = $form['module']['#value'];
  113. $delta = $form['delta']['#value'];
  114. $form['i18n'] = array(
  115. '#type' => 'fieldset',
  116. '#title' => t('Multilingual settings'),
  117. '#collapsible' => TRUE,
  118. '#weight' => -1,
  119. );
  120. $i18nblock = i18nblocks_load($module, $delta);
  121. $form['i18n'] = array(
  122. '#type' => 'fieldset',
  123. '#title' => t('Multilingual settings'),
  124. '#collapsible' => TRUE,
  125. '#weight' => 0,
  126. );
  127. // Language options will depend on block type.
  128. $options = array('' => t('All languages'));
  129. if ($module == 'block') {
  130. $options[I18N_BLOCK_LOCALIZE] = t('All languages (Translatable)');
  131. }
  132. $options += locale_language_list('name');
  133. $form['i18n']['language'] = array(
  134. '#type' => 'radios',
  135. '#title' => t('Language'),
  136. '#default_value' => $i18nblock->language,
  137. '#options' => $options,
  138. );
  139. // Pass i18ndelta value.
  140. $form['i18n']['ibid'] = array('#type' => 'value', '#value' => $i18nblock->ibid);
  141. $form['#submit'][] = 'i18nblocks_form_submit';
  142. }
  143. }
  144. /**
  145. * Forms api callback. Submit function.
  146. */
  147. function i18nblocks_form_submit($form, &$form_state) {
  148. $values = $form_state['values'];
  149. // Dirty trick to act on new created blocks. Delta may be zero for other modules than block.
  150. if (!$values['delta'] && $values['module'] == 'block') {
  151. // The last insert id will return a different value in mysql
  152. //$values['delta'] = db_last_insert_id('boxes', 'bid');
  153. $values['delta'] = db_result(db_query("SELECT MAX(bid) FROM {boxes}"));
  154. }
  155. i18nblocks_save($values);
  156. }
  157. /**
  158. * Get block language data.
  159. */
  160. function i18nblocks_load($module, $delta) {
  161. $block = db_fetch_object(db_query("SELECT * FROM {i18n_blocks} WHERE module = '%s' AND delta = '%s'", $module, $delta));
  162. // If no result, return default settings
  163. if ($block && !$block->language) {
  164. $block->language = I18N_BLOCK_LOCALIZE;
  165. }
  166. return $block ? $block : (object)array('language' => '', 'ibid' => 0);
  167. }
  168. /**
  169. * Set block language data.
  170. *
  171. * @param array $block
  172. * Array of block parameters: module, delata, ibid (internal i18nblocks delta).
  173. */
  174. function i18nblocks_save($block) {
  175. if (!empty($block['language'])) {
  176. if ($block['language'] == I18N_BLOCK_LOCALIZE) {
  177. $block['language'] = '';
  178. }
  179. // Update strings for localizable blocks.
  180. if ($block['ibid']) {
  181. drupal_write_record('i18n_blocks', $block, 'ibid');
  182. }
  183. else {
  184. drupal_write_record('i18n_blocks', $block);
  185. }
  186. }
  187. else {
  188. // No language, delete all i18n information.
  189. db_query("DELETE FROM {i18n_blocks} WHERE module = '%s' AND delta = '%s'", $block['module'], $block['delta']);
  190. }
  191. // If localize block or block without language
  192. if (!$block['language']) {
  193. // We use ibid property instead of block's delta as block id for strings
  194. $module = $block['module'];
  195. $delta = $block['delta'];
  196. if (!empty($block['title']) && $block['title'] != '<none>') {
  197. i18nstrings_update("blocks:$module:$delta:title", $block['title']);
  198. }
  199. if (isset($block['body'])) {
  200. i18nstrings_update("blocks:$module:$delta:body", $block['body'], $block['format']);
  201. }
  202. }
  203. }
  204. /**
  205. * Translate block.
  206. *
  207. * @param $block
  208. * Core block object
  209. */
  210. function i18nblocks_translate_block($block) {
  211. // Localizable blocks may get the body translated too.
  212. $localizable = _i18nblocks_list();
  213. if (!empty($block->content) && $localizable && isset($localizable[$block->module][$block->delta])) {
  214. $block->content = i18nstrings_text("blocks:$block->module:$block->delta:body", $block->content);
  215. }
  216. // If it has a custom title, localize it
  217. if (!empty($block->title) && $block->title != '<none>') {
  218. // Check plain here to allow module generated titles to keep any markup.
  219. $block->subject = i18nstrings_string("blocks:$block->module:$block->delta:title", $block->subject);
  220. }
  221. return $block;
  222. }
  223. /**
  224. * Implementation of hook_preprocess_block().
  225. *
  226. * Translate blocks.
  227. *
  228. * @see block.tpl.php
  229. */
  230. function i18nblocks_preprocess_block(&$variables) {
  231. global $language;
  232. $block = $variables['block'];
  233. // Replace menu blocks by their translated version.
  234. if (module_exists('i18nmenu')) {
  235. if ($block->module == 'menu') {
  236. $block->content = i18nmenu_translated_tree($block->delta);
  237. if ($block->subject && empty($block->title)) {
  238. $block->subject = i18nstrings_string('menu:menu:' . $block->delta . ':title', $block->subject);
  239. }
  240. }
  241. elseif ($block->module == 'user' && $block->delta == 1) {
  242. $block->content = i18nmenu_translated_tree('navigation');
  243. }
  244. }
  245. // If the block has language, do nothing, it is suppossed to be translated
  246. $havelanguage = _i18nblocks_list($language->language);
  247. if ($havelanguage && isset($havelanguage[$block->module][$block->delta])) {
  248. return;
  249. }
  250. else {
  251. $variables['block'] = i18nblocks_translate_block($block);
  252. }
  253. }
  254. /**
  255. * Get list of blocks i18n properties
  256. */
  257. function _i18nblocks_list($langcode = '') {
  258. static $list = array();
  259. // Handle issues when no $langcode, use a different array index
  260. $index = $langcode ? $langcode : I18N_BLOCK_LOCALIZE;
  261. if (!isset($list[$index])) {
  262. $list[$index] = array();
  263. $result = db_query("SELECT * FROM {i18n_blocks} WHERE language = '%s'", $langcode);
  264. while ($info = db_fetch_object($result)) {
  265. $list[$index][$info->module][$info->delta] = $info;
  266. }
  267. }
  268. return $list[$index];
  269. }