t('Localizable block'),
I18N_BLOCK_METABLOCK => t('Multilingual block (Metablock)'),
);
}
/**
* Implementation of hook_help()
*/
function i18nblocks_help($section, $arg) {
switch ($section) {
case 'admin/help#i18nblocks':
$output = '
'.t('This module provides support for multilingual blocks.').'
';
$output .= ''.t('You can set up a language for a block or define it as translatable:').'
';
$output .= '';
$output .= '- '.t('Blocks with a language will be displayed only in pages with that language.').'
';
$output .= '- '.t('Translatable blocks can be translated using the localization interface.').'
';
$output .= '
';
return $output;
}
}
/**
* Implementation of hook_db_rewrite_sql()
*/
function i18nblocks_db_rewrite_sql($query, $primary_table, $primary_key) {
global $language;
if ($primary_table == 'b' && $primary_key == 'bid') {
$return['join'] = 'LEFT JOIN {i18n_blocks} i18n ON b.module = i18n.module AND b.delta = i18n.delta';
$return['where'] = i18n_db_rewrite_where('i18n', 'block', 'simple');
return $return;
}
}
/**
* Implementation of hook_block()
*
* Blocks in i18n_blocks with no language are suppossed to be translatable
*/
/*
function i18nblocks_block($op = 'list', $delta = 0, $edit = array()) {
switch($op) {
case 'list':
$blocks = array();
$result = db_query("SELECT i.*, b.info FROM {i18n_blocks} i INNER JOIN {boxes} b ON i.delta = b.bid WHERE i.module = 'block' AND i.language = ''");
while ($data = db_fetch_object($result)) {
$blocks[$data->ibid]['info'] = $data->info . t('[Translatable]');
}
return $blocks;
case 'view':
return i18nblocks_get_block($delta, i18n_get_lang());
break;
case 'configure':
$form['i18nblocks']['#value'] = t('This is a localizable block');
return $form;
}
}
*/
/**
* Implementation of hook_locale().
*
* This one doesn't need locale refresh because strings are stored from module config form.
*/
function i18nblocks_locale($op = 'groups', $group = NULL) {
switch ($op) {
case 'groups':
return array('blocks' => t('Blocks'));
}
}
/**
* Implementation of block form_alter().
*
* Remove block title for multilingual blocks.
*/
function i18nblocks_form_alter(&$form, $form_state, $form_id) {
if (($form_id == 'block_admin_configure' || $form_id == 'block_box_form' || $form_id == 'block_add_block_form')) {
$module = $form['module']['#value'];
$delta = $form['delta']['#value'];
$form['i18n'] = array(
'#type' => 'fieldset',
'#title' => t('Multilingual settings'),
'#collapsible' => TRUE,
'#weight' => -1,
);
// For i18nblocks, just a help text
if ($module == 'i18nblocks') {
$form['i18n']['text'] = array('#value' => t('This is a translatable block.'));
// Unset block title
unset($form['block_settings']['title']);
$form['block_settings']['title'] = array('#type' => 'value', '#value' => '');
} else {
$i18nblock = i18nblocks_load($module, $delta);
$form['i18n'] = array(
'#type' => 'fieldset',
'#title' => t('Multilingual settings'),
'#collapsible' => TRUE,
'#weight' => 0,
);
// Language options will depend on block type
$options = array('' => t('All languages'));
if ($module == 'block') {
$options[I18N_BLOCK_LOCALIZE] = t('All languages (Translatable)');
}
$options += locale_language_list('name');
$form['i18n']['language'] = array(
'#type' => 'radios',
'#title' => t('Language'),
'#default_value' => $i18nblock->language,
'#options' => $options,
);
// Pass i18ndelta value
$form['i18n']['ibid'] = array('#type' => 'value', '#value' => $i18nblock->ibid);
$form['#submit'][] = 'i18nblocks_form_submit';
}
}
}
/**
* Forms api callback. Submit function
*/
function i18nblocks_form_submit($form, &$form_state) {
$values = $form_state['values'];
// Dirty trick to act on new created blocks. Delta may be zero for other modules than block.
if (!$values['delta'] && $values['module'] == 'block') {
// The last insert id will return a different value in mysql
//$values['delta'] = db_last_insert_id('boxes', 'bid');
$values['delta'] = db_result(db_query("SELECT MAX(bid) FROM {boxes}"));
}
switch ($values['language']) {
case I18N_BLOCK_LOCALIZE: // Translatable block
$values['language'] = '';
i18nblocks_save($values);
break;
case '': // No language, delete all i18n information
if ($values['ibid']) {
db_query("DELETE FROM {i18n_blocks} WHERE ibid = %d", $values['ibid']);
}
break;
default: // The block has a language
i18nblocks_save($values);
}
}
/**
* Get block language data
*/
function i18nblocks_load($module, $delta) {
$block = db_fetch_object(db_query("SELECT * FROM {i18n_blocks} WHERE module = '%s' AND delta = '%s'", $module, $delta));
// If no result, return default settings
if ($block && !$block->language) {
$block->language = I18N_BLOCK_LOCALIZE;
}
return $block ? $block : (object)array('language' => '', 'ibid' => 0);
}
/**
* Set block language data
*
* @param array $block
* Array of block parameters: module, delata, ibid (internal i18nblocks delta)
*/
function i18nblocks_save($block) {
// Update strings for localizable blocks
if ($block['ibid']) {
db_query("UPDATE {i18n_blocks} SET language = '%s' WHERE ibid = %d", $block['language'], $block['ibid']);
} else {
db_query("INSERT INTO {i18n_blocks}(module, delta, language) VALUES('%s', '%s', '%s')", $block['module'], $block['delta'], $block['language']);
$block['ibid'] = db_last_insert_id('i18n_blocks', 'ibid');
}
if (!$block['language']) {
$delta = $block['ibid'];
tt("blocks:block:$delta:title", $block['title'], NULL, TRUE);
tt("blocks:block:$delta:content", $block['body'], NULL, TRUE);
}
}
/**
* Load and translate block data
*
* @param $delta
* Block id
* @param $language
* Language to localize the block
*/
function i18nblocks_get_block($delta, $language){
// Get block metadata
$meta = db_fetch_object(db_query("SELECT b.* FROM {blocks} b INNER JOIN {i18n_blocks} i ON i.delta = b.delta AND i.module = b.module WHERE i.ibid = '%d'", $delta));
// Get block data from module
$block = module_invoke($meta->module, 'block', 'view', $meta->delta);
if ($block) {
// Override the default title
if ($meta->title) {
// Check plain here to allow module generated titles to keep any markup.
$block['subject'] = $meta->title == '' ? '' : check_plain(tt("blocks:block:$delta:title", $meta->title, $language));
} elseif (!empty($block['subject'])) {
$block['subject'] = tt("blocks:block:$delta:title", $block['subject'], $language);
}
$block['content'] = tt("blocks:block:$delta:content", $block['content'], $language);
return $block;
}
}
/**
* Translate localizable block
*/
function i18nblocks_translate_block($block) {
if ($block->title) {
// Check plain here to allow module generated titles to keep any markup.
$block->subject = $block->title == '' ? '' : check_plain(tt("blocks:block:$block->delta:title", $block->title));
} elseif (!empty($block->subject)) {
$block->subject = tt("blocks:block:$block->delta:title", $block->subject);
}
$block->content = tt("blocks:block:$block->delta:content", $block->content);
return $block;
}
/**
* Implementation of hook_theme()
*
* Overrides the theme_blocks() definition
*/
function i18nblocks_theme() {
return array(
'blocks' => array(
'function' => 'i18nblocks_theme_blocks',
'arguments' => array('region' => NULL),
),
);
}
/**
* Overrides theme_blocks() and translates blocks on the go
*/
function i18nblocks_theme_blocks($region) {
$output = '';
$i18nmenu = module_exists('i18nmenu');
$i18nblocks = _i18nblocks_list();
if ($list = block_list($region)) {
foreach ($list as $key => $block) {
// Configurable blocks, may be localizable
if ($block->module == 'block') {
if (isset($i18nblocks['block'][$block->delta])) {
$block = i18nblocks_translate_block($block);
}
}
elseif ($i18nmenu) {
// Replace menu blocks by their translated version
if ($block->module == 'menu') {
$block->content = i18nmenu_translated_tree($block->delta);
} elseif ($block->module == 'user' && $block->delta == 1) {
$block->content = i18nmenu_translated_tree('navigation');
}
}
// Finally, render the block using standard theming
$output .= theme('block', $block);
}
}
// Add any content assigned to this region through drupal_set_content() calls.
$output .= drupal_get_content($region);
return $output;
}
/**
* Get list of blocks i18n properties
*/
function _i18nblocks_list($langcode = '') {
static $list = array();
// Handle issues when no $langcode, use a different array index
$index = $langcode ? $langcode : I18N_BLOCK_LOCALIZE;
if (!isset($list[$index])) {
$list[$index] = array();
$result = db_query("SELECT * FROM {i18n_blocks} WHERE language = '%s'", $langcode);
while ($info = db_fetch_object($result)) {
$list[$index][$info->module][$info->delta] = $info;
}
}
return $list[$index];
}