first import
This commit is contained in:
27
sites/all/modules/i18n/i18n_select/i18n_select.admin.inc
Normal file
27
sites/all/modules/i18n/i18n_select/i18n_select.admin.inc
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Helper functions for select administration.
|
||||
*/
|
||||
|
||||
function i18n_select_admin_settings() {
|
||||
$form['types'] = array(
|
||||
'#type' => 'variable_fieldset',
|
||||
'#title' => t('Content to filter by language'),
|
||||
'#variable_list' => array('i18n_select_nodes', 'i18n_select_taxonomy'),
|
||||
);
|
||||
$form['mode'] = array(
|
||||
'#type' => 'variable_fieldset',
|
||||
'#title' => t('Content selection mode'),
|
||||
'#variable_list' => array('i18n_select_missing_translation', 'i18n_select_skip_tags'),
|
||||
);
|
||||
// Enable for specific pages. This works pretty much like block visibility
|
||||
// Note this page requires 'administer site configuration' so we don't need to check permissions
|
||||
$form['pages'] = array(
|
||||
'#type' => 'variable_fieldset',
|
||||
'#title' => t('Enable for specific pages'),
|
||||
'#variable_list' => array('i18n_select_page_mode', 'i18n_select_page_list', 'i18n_select_page_block'),
|
||||
);
|
||||
return system_settings_form($form);
|
||||
}
|
14
sites/all/modules/i18n/i18n_select/i18n_select.info
Normal file
14
sites/all/modules/i18n/i18n_select/i18n_select.info
Normal file
@@ -0,0 +1,14 @@
|
||||
name = Multilingual select
|
||||
description = API module for multilingual content selection
|
||||
dependencies[] = i18n
|
||||
package = Multilingual - Internationalization
|
||||
core = 7.x
|
||||
configure = admin/config/regional/i18n/select
|
||||
files[] = i18n_select.test
|
||||
|
||||
; Information added by drupal.org packaging script on 2013-01-13
|
||||
version = "7.x-1.8"
|
||||
core = "7.x"
|
||||
project = "i18n"
|
||||
datestamp = "1358075001"
|
||||
|
314
sites/all/modules/i18n/i18n_select/i18n_select.module
Normal file
314
sites/all/modules/i18n/i18n_select/i18n_select.module
Normal file
@@ -0,0 +1,314 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Multilingual content selection module.
|
||||
*
|
||||
* Alters content queries to add language conditions.
|
||||
*
|
||||
* Queries tagged with 'i18n_select' or that already have a language condition will not be altered.
|
||||
*/
|
||||
|
||||
// No language selection
|
||||
define('I18N_SELECT_NONE', 0);
|
||||
// Content with current language and undefined language
|
||||
define('I18N_SELECT_NORMAL', 1);
|
||||
// Select default language when current language is missing
|
||||
define('I18N_SELECT_MISSING', 2);
|
||||
|
||||
/**
|
||||
* Enable on every page except the listed pages.
|
||||
*/
|
||||
define('I18N_SELECT_PAGE_NOTLISTED', 0);
|
||||
/**
|
||||
* Enable on only the listed pages.
|
||||
*/
|
||||
define('I18N_SELECT_PAGE_LISTED', 1);
|
||||
/**
|
||||
* Enable if the associated PHP code returns TRUE.
|
||||
*/
|
||||
define('I18N_SELECT_PAGE_PHP', 2);
|
||||
|
||||
/**
|
||||
* Implements hook_init().
|
||||
*/
|
||||
function i18n_select_init() {
|
||||
// Determine selection mode for this page
|
||||
i18n_select(i18n_select_page());
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_block_list_alter().
|
||||
*
|
||||
* Dirty trick to enable selection for blocks though it may be disabled for the current page.
|
||||
*/
|
||||
function i18n_select_block_list_alter(&$blocks) {
|
||||
// Still, skip for form submission. There are pages like the ones produced
|
||||
// by overlay that render the blocks before the page.
|
||||
// See overlay_init(), overlay_overlay_child_initialize()
|
||||
if (empty($_POST) && !isset($_GET['token']) && variable_get('i18n_select_page_block', TRUE)) {
|
||||
i18n_select(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_menu().
|
||||
*/
|
||||
function i18n_select_menu() {
|
||||
$items['admin/config/regional/i18n/select'] = array(
|
||||
'title' => 'Selection',
|
||||
'description' => 'Configure extended options for multilingual content and translations.',
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('i18n_select_admin_settings'),
|
||||
'access arguments' => array('administer site configuration'),
|
||||
'file' => 'i18n_select.admin.inc',
|
||||
'type' => MENU_LOCAL_TASK,
|
||||
);
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current mode for i18n selection
|
||||
*
|
||||
* @param $type
|
||||
* Selection type: 'nodes', 'taxonomy', etc..
|
||||
*/
|
||||
function i18n_select_mode($type = NULL) {
|
||||
if (i18n_select() && (!$type || variable_get('i18n_select_' . $type, TRUE))) {
|
||||
return I18N_SELECT_NORMAL;
|
||||
}
|
||||
else {
|
||||
return I18N_SELECT_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check current path to enable selection
|
||||
*
|
||||
* This works pretty much like block visibility
|
||||
*
|
||||
* @return boolean
|
||||
* TRUE if content selection should be enabled for this page.
|
||||
*/
|
||||
function i18n_select_page() {
|
||||
static $mode;
|
||||
|
||||
if (!isset($mode)) {
|
||||
$mode = &drupal_static(__FUNCTION__);
|
||||
$visibility = variable_get('i18n_select_page_mode', I18N_SELECT_PAGE_NOTLISTED);
|
||||
if ($pages = variable_get('i18n_select_page_list', 'admin/*')) {
|
||||
// Convert path to lowercase. This allows comparison of the same path
|
||||
// with different case. Ex: /Page, /page, /PAGE.
|
||||
$pages = drupal_strtolower($pages);
|
||||
if ($visibility < I18N_SELECT_PAGE_PHP) {
|
||||
// Convert the Drupal path to lowercase
|
||||
$path = drupal_strtolower(drupal_get_path_alias($_GET['q']));
|
||||
// Compare the lowercase internal and lowercase path alias (if any).
|
||||
$page_match = drupal_match_path($path, $pages);
|
||||
if ($path != $_GET['q']) {
|
||||
$page_match = $page_match || drupal_match_path($_GET['q'], $pages);
|
||||
}
|
||||
// When $visibility has a value of 0 (I18N_SELECT_PAGE_NOTLISTED),
|
||||
// the block is displayed on all pages except those listed in $pages.
|
||||
// When set to 1 (I18N_SELECT_PAGE_LISTED), it is displayed only on those
|
||||
// pages listed in $pages.
|
||||
$mode = !($visibility xor $page_match);
|
||||
}
|
||||
elseif (module_exists('php')) {
|
||||
$mode = php_eval($pages);
|
||||
}
|
||||
else {
|
||||
$mode = FALSE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// No pages defined, still respect the setting (unlike blocks)
|
||||
$mode = $visibility == I18N_SELECT_PAGE_NOTLISTED;
|
||||
}
|
||||
}
|
||||
|
||||
return $mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_query_node_access_alter().
|
||||
*
|
||||
* Rewrite node queries so language selection options are enforced.
|
||||
*/
|
||||
function i18n_select_query_node_access_alter(QueryAlterableInterface $query) {
|
||||
if (i18n_select_mode('nodes') && i18n_select_check_query($query, 'nid') &&
|
||||
($table_alias = i18n_select_check_table($query, 'node', 'nid'))) {
|
||||
$query->condition($table_alias . '.language', i18n_select_langcodes());
|
||||
// Mark query as altered
|
||||
$query->addTag('i18n_select');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_query_term_access_alter().
|
||||
*
|
||||
* Rewrite taxonomy term queries so language selection options are enforced.
|
||||
*/
|
||||
function i18n_select_query_term_access_alter(QueryAlterableInterface $query) {
|
||||
if (module_exists('i18n_taxonomy') && i18n_select_mode('taxonomy') && i18n_select_check_query($query, 'tid') &&
|
||||
($table_alias = i18n_select_check_table($query, 'taxonomy_term_data', 'tid'))) {
|
||||
$query->condition($table_alias . '.language', i18n_select_langcodes());
|
||||
// Mark query as altered
|
||||
$query->addTag('i18n_select');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check table exists in query and get alias for it.
|
||||
*
|
||||
* @param $query
|
||||
* Query object
|
||||
* @param $table_name
|
||||
* Table name to find.
|
||||
* @param $field_name
|
||||
* field to join the table if needed.
|
||||
*
|
||||
* @return
|
||||
* Table alias if found, none if not.
|
||||
*/
|
||||
function i18n_select_check_table($query, $table_name, $field_name) {
|
||||
$tables = $query->getTables();
|
||||
foreach ($tables as $table) {
|
||||
if (!($table instanceof SelectQueryInterface) && $table['table'] == $table_name) {
|
||||
return _i18n_select_table_alias($table);
|
||||
}
|
||||
}
|
||||
// Join the table if we can find the key field on any of the tables
|
||||
// And all the conditions have a table alias (or there's a unique table).
|
||||
if (count($tables) == 1) {
|
||||
$table = reset($tables);
|
||||
$table_alias = _i18n_select_table_alias($table);
|
||||
if (i18n_select_check_conditions($query, $table_alias)) {
|
||||
$join_table = $table_alias;
|
||||
}
|
||||
}
|
||||
elseif (i18n_select_check_conditions($query)) {
|
||||
// Try to find the right field in the table schema.
|
||||
foreach ($tables as $table) {
|
||||
$schema = drupal_get_schema($table['table']);
|
||||
if ($schema && !empty($schema['fields'][$field_name])) {
|
||||
$join_table = _i18n_select_table_alias($table);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty($join_table)) {
|
||||
return $query->join($table_name, $table_name, $join_table . '.' . $field_name . ' = %alias.' . $field_name);
|
||||
}
|
||||
else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get table alias
|
||||
*/
|
||||
function _i18n_select_table_alias($table) {
|
||||
return !empty($table['alias']) ? $table['alias'] : $table['table'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check all query conditions have a table alias.
|
||||
*
|
||||
* @param $table_alias
|
||||
* Optional table alias for fields without table.
|
||||
*
|
||||
* @return boolean
|
||||
* TRUE if table conditions are ok, FALSE otherwise.
|
||||
*/
|
||||
function i18n_select_check_conditions($query, $table_alias = NULL) {
|
||||
$conditions =& $query->conditions();
|
||||
foreach ($conditions as $index => $condition) {
|
||||
if (is_array($condition) && isset($condition['field'])) {
|
||||
if (strpos($condition['field'], '.') === FALSE) {
|
||||
if ($table_alias) {
|
||||
// Change the condition to include a table alias.
|
||||
$conditions[$index]['field'] = $table_alias . '.' . $condition['field'];
|
||||
}
|
||||
else {
|
||||
// We won't risk joining anything here.
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether we should apply language conditions here:
|
||||
* - The query has not been tagged with 'i18n_select'
|
||||
* - The query doesn't have already a language condition
|
||||
* - All the conditions have a table alias or there's only one table.
|
||||
* - We are not loading specific objects (no condition for index field).
|
||||
*
|
||||
* @param $query
|
||||
* Query object.
|
||||
* @param $index_field
|
||||
* Object index field to check we don't have 'IN' conditions for it.
|
||||
*/
|
||||
function i18n_select_check_query($query, $index_field = NULL) {
|
||||
static $tags;
|
||||
// Skip queries with certain tags
|
||||
if (!isset($tags)) {
|
||||
$tags = ($skip = variable_get('i18n_select_skip_tags', 'views')) ? array_map('trim', explode(',', $skip)) : array();
|
||||
$tags[] = 'i18n_select';
|
||||
}
|
||||
foreach ($tags as $tag) {
|
||||
if ($query->hasTag($tag)) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
// Check all the conditions to see whether the query is suitable for altering.
|
||||
foreach ($query->conditions() as $condition) {
|
||||
if (is_array($condition)) {
|
||||
// @todo For some complex queries, like search ones, field is a DatabaseCondition object
|
||||
if (!isset($condition['field']) || !is_string($condition['field'])) {
|
||||
// There's a weird condition field, we won't take any chances.
|
||||
return FALSE;
|
||||
}
|
||||
else {
|
||||
// Just check the condition doesn't include the language field
|
||||
if (strpos($condition['field'], '.') === FALSE) {
|
||||
$field = $condition['field'];
|
||||
}
|
||||
else {
|
||||
list($table, $field) = explode('.', $condition['field']);
|
||||
}
|
||||
if ($field == 'language') {
|
||||
return FALSE;
|
||||
}
|
||||
// Check 'IN' conditions for index field, usually entity loading for specific objects.
|
||||
if ($field == $index_field && $condition['operator'] == 'IN') {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// If the language field is present we don't want to do any filtering.
|
||||
$fields = $query->getFields();
|
||||
if (isset($fields['language'])) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get main language for content selection
|
||||
*/
|
||||
function i18n_select_language() {
|
||||
return $GLOBALS[LANGUAGE_TYPE_CONTENT];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get language codes for content selection to use in query conditions
|
||||
*/
|
||||
function i18n_select_langcodes() {
|
||||
return array(i18n_select_language()->language, LANGUAGE_NONE);
|
||||
}
|
||||
|
86
sites/all/modules/i18n/i18n_select/i18n_select.test
Normal file
86
sites/all/modules/i18n/i18n_select/i18n_select.test
Normal file
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Test language selection modes
|
||||
*/
|
||||
|
||||
class i18nSelectTestCase extends Drupali18nTestCase {
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Content Selection',
|
||||
'group' => 'Internationalization',
|
||||
'description' => 'Internationalization Content Selection'
|
||||
);
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
parent::setUp('translation', 'i18n_variable', 'i18n_select');
|
||||
parent::setUpLanguages();
|
||||
parent::setUpContentTranslation();
|
||||
}
|
||||
|
||||
function testIi18nSelect() {
|
||||
drupal_static_reset('language_list');
|
||||
$language_list = language_list();
|
||||
$language_count = count($language_list);
|
||||
// Set site name for each language and check pages later
|
||||
variable_set('i18n_variable_list', array('site_name'));
|
||||
foreach (i18n_language_list() as $langcode => $name) {
|
||||
i18n_variable_set('site_name', "Drupal-$name", $langcode);
|
||||
}
|
||||
|
||||
// Enable tags field for page content type.
|
||||
$edit = array(
|
||||
'fields[_add_existing_field][label]' => t('Tags'),
|
||||
'fields[_add_existing_field][field_name]' => 'field_tags',
|
||||
'fields[_add_existing_field][widget_type]' => 'taxonomy_autocomplete',
|
||||
);
|
||||
$this->drupalPost('admin/structure/types/manage/page/fields', $edit, t('Save'));
|
||||
$this->drupalPost(NULL, array(), t('Save settings'));
|
||||
|
||||
// Create some content and check selection modes
|
||||
$this->drupalLogin($this->content_editor);
|
||||
|
||||
// variable_set('language_content_type_story', 1);
|
||||
$neutral = $this->drupalCreateNode(array('type' => 'page', 'promote' => 1));
|
||||
$source = $this->createNode('page', $this->randomName(), $this->randomString(20), language_default('language'), array('field_tags[und]' => $tag_name = $this->randomName()));
|
||||
$translations = $this->createNodeTranslationSet($source);
|
||||
|
||||
drupal_static_reset('translation_node_get_translations');
|
||||
$this->assertEqual(count(translation_node_get_translations($source->tnid)), $language_count, "Created $language_count $source->type translations.");
|
||||
|
||||
// Log in user with access content permission
|
||||
$user = $this->drupalCreateUser(array('access comments', 'access content'));
|
||||
$this->drupalLogin($user);
|
||||
// Default selection mode, only language neutral and current
|
||||
variable_set('i18n_select_nodes', TRUE);
|
||||
foreach (i18n_language_list() as $langcode => $name) {
|
||||
$this->i18nGet($langcode);
|
||||
$this->assertText("Drupal-$name", 'Checked translated site name: Drupal-' . $name);
|
||||
$display = array($translations[$langcode], $neutral);
|
||||
$hide = $translations;
|
||||
unset($hide[$langcode]);
|
||||
$this->assertContent($display, $hide);
|
||||
// Visit the taxonomy page of that node and try again. Only the translated
|
||||
// pages are tagged.
|
||||
unset($display[1]);
|
||||
$this->i18nGet($langcode, 'taxonomy/term/' . $source->field_tags[LANGUAGE_NONE][0]['tid']);
|
||||
$this->assertContent($display, $hide);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Check some nodes are displayed, some are not
|
||||
*/
|
||||
function assertContent($display, $hide = array()) {
|
||||
$languages = language_list();
|
||||
foreach ($display as $node) {
|
||||
$this->assertText($node->title, 'Content displayed for ' . i18n_language_name($node->language));
|
||||
}
|
||||
foreach ($hide as $node) {
|
||||
$this->assertNoText($node->title, 'Content not displayed for ' . i18n_language_name($node->language));
|
||||
}
|
||||
}
|
||||
}
|
73
sites/all/modules/i18n/i18n_select/i18n_select.variable.inc
Normal file
73
sites/all/modules/i18n/i18n_select/i18n_select.variable.inc
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Variable information
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_variable_info().
|
||||
*/
|
||||
function i18n_select_variable_info($options = array()) {
|
||||
$variables['i18n_select_nodes'] = array(
|
||||
'title' => t('Select nodes by language', array(), $options),
|
||||
'type' => 'boolean',
|
||||
'default' => TRUE,
|
||||
'group' => 'i18n',
|
||||
);
|
||||
$variables['i18n_select_taxonomy'] = array(
|
||||
'title' => t('Select taxonomy terms by language', array(), $options),
|
||||
'type' => 'boolean',
|
||||
'default' => TRUE,
|
||||
'group' => 'i18n',
|
||||
'element' => array('#disabled' => !module_exists('i18n_taxonomy')),
|
||||
);
|
||||
|
||||
// Enable / disable for specific pages
|
||||
$description = t("Specify pages by using their paths. Enter one path per line. The '*' character is a wildcard. Example paths are %blog for the blog page and %blog-wildcard for every personal blog. %front is the front page.", array('%blog' => 'blog', '%blog-wildcard' => 'blog/*', '%front' => '<front>'), $options);
|
||||
if (module_exists('php')) {
|
||||
$title = t('Pages or PHP code');
|
||||
$description .= ' ' . t('If the PHP option is chosen, enter PHP code between %php. Note that executing incorrect PHP code can break your Drupal site.', array('%php' => '<?php ?>'), $options);
|
||||
}
|
||||
else {
|
||||
$title = t('Pages', array(), $options);
|
||||
}
|
||||
$variables['i18n_select_page_mode'] = array(
|
||||
'type' => 'select',
|
||||
'options callback' => 'i18n_select_variable_option_list',
|
||||
'default' => I18N_SELECT_PAGE_NOTLISTED,
|
||||
);
|
||||
$variables['i18n_select_page_list'] = array(
|
||||
'type' => 'text',
|
||||
'title' => $title,
|
||||
'default' => 'admin/*',
|
||||
'description' => $description,
|
||||
);
|
||||
$variables['i18n_select_page_block'] = array(
|
||||
'type' => 'boolean',
|
||||
'title' => t('Enable always for block content though it may be disabled for the page', array(), $options),
|
||||
'default' => TRUE,
|
||||
);
|
||||
$variables['i18n_select_skip_tags'] = array(
|
||||
'title' => t('Skip tags', array(), $options),
|
||||
'type' => 'string',
|
||||
'default' => 'views',
|
||||
'group' => 'i18n',
|
||||
'description' => t('Skip queries with these tags. Enter a list of tags separated by commas.'),
|
||||
'localize' => FALSE,
|
||||
);
|
||||
return $variables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Options for page selection mode
|
||||
*/
|
||||
function i18n_select_variable_option_list($variable, $options = array()) {
|
||||
$options = array(
|
||||
I18N_SELECT_PAGE_NOTLISTED => t('All pages except those listed', array(), $options),
|
||||
I18N_SELECT_PAGE_LISTED => t('Only the listed pages', array(), $options),
|
||||
);
|
||||
if (module_exists('php')) {
|
||||
$options += array(I18N_SELECT_PAGE_PHP => t('Pages on which this PHP code returns <code>TRUE</code> (experts only)'));
|
||||
}
|
||||
return $options;
|
||||
}
|
Reference in New Issue
Block a user