updated i18n, views, imagestyleflush, field_group
patch views_rss_media
This commit is contained in:
parent
9adc940a67
commit
c97e0f8ba1
@ -12,16 +12,16 @@ contentadminrelink
|
||||
entityreference
|
||||
feedback
|
||||
filter_path_alias
|
||||
termreferencetree
|
||||
?? views
|
||||
wysiwyg
|
||||
views_rss_media (https://www.drupal.org/node/2472409)
|
||||
node_export :
|
||||
- https://www.drupal.org/node/1869918
|
||||
- https://www.drupal.org/node/1911638
|
||||
flag_lists
|
||||
- https://www.drupal.org/project/flag_lists/issues/2114731
|
||||
login_tobogan (pd with field permission et donc field collection)
|
||||
- https://www.drupal.org/node/1365764#comment-10286257
|
||||
- logintoboggan-exempting_lt_preauth_role_from_user_permissions_js-1365764-52.patch
|
||||
- interdiff-1365764-23-52-do-not-test.diff
|
||||
flag_lists
|
||||
- https://www.drupal.org/project/flag_lists/issues/2114731
|
||||
node_export :
|
||||
- https://www.drupal.org/node/1869918
|
||||
- https://www.drupal.org/node/1911638
|
||||
termreferencetree
|
||||
?? views
|
||||
views_rss_media (https://www.drupal.org/node/2472409)
|
||||
wysiwyg
|
||||
|
@ -1,6 +1,37 @@
|
||||
/* $Id*/
|
||||
CHANGELOG for field_group for Drupal 7
|
||||
|
||||
Field Group origin/7.x-1.x, 2017-11-04
|
||||
--------------------------------------
|
||||
- Tests fail after new 'administer fields' permission.
|
||||
- Update CHANGELOG.txt to 7.x-1.5 Release.
|
||||
- Revert "Issue #2646106 by jribeiro: Update CHANGELOG.txt to 7.x-1.5 Release".
|
||||
- Update CHANGELOG.txt to 7.x-1.5 Release.
|
||||
- Fix whitespace between "&" and parameters for some functions.
|
||||
- Avoid bad code pattern (that is picked up by security scanners) when getting hash.
|
||||
- Should #array_parents be updated in field_group_fields_nest()?.
|
||||
- "Show" appears in horizontal tab title if node form submitted through ajax.
|
||||
- CSS breaks i18n string translation interface.
|
||||
- "uncaught exception: Syntax error, unrecognized expression: #" after 7.x-1.4 update.
|
||||
- PHP7 - Uniform Variable Syntax updates are causing exported field_groups to not have names.
|
||||
|
||||
Field_group 7.x-1.5
|
||||
o Added extra formatting on html element attributes.
|
||||
o Fixed bug on automatic ID generation in javascript.
|
||||
o Issue #2511960 by rrfegade: spelling errors in D7.
|
||||
o Issue #2194279 by Georgique: Export translatables (label and descriptions) in Features.
|
||||
o Issue #2386335 by Dubs: Integer Group Array Keys can create empty node forms.
|
||||
o Issue #2269133 by sammuell: Accordion is always closed when using jQuery update module.
|
||||
o Issue #2258939 by Snipon: Fixed Change to preventDefault on multipage controls.
|
||||
o Issue #2173937 by jantoine, omerida | Bernieman: Fixed Accordion Element has fixed height in HTML.
|
||||
o Issue #2311789 by eelkeblok: Fixed Group is incorrectly determined to be empty with nested form elements.
|
||||
o Issue #2272003 by karolrybak | Kwb: Fixed Fieldgroup no longer renders after using more than one 'HTML Element' on the same level.
|
||||
o Issue #2309219 by czigor: Fixed Proper CTools exportable loading.
|
||||
o Issue #2283245 by stefan.r | jrb: Fixed New id functionality breaks tests and CSS on existing field groups.
|
||||
o Issue #2295133 by boyan.borisov, interX: Fixed field_group_update_7007 error.
|
||||
o Remove field_group.css, the css is not needed anymore.
|
||||
o Fix horiziontal tabs when used as standalone element.
|
||||
|
||||
Field_group 7.x-1.4
|
||||
o Issue #2129805 by RaF: Incorrect markup when open div & custom classes provided.
|
||||
o Issue #2037731 by maximpodorov, Zach Harkey: Remove id attribute from HTML elements.
|
||||
|
@ -220,7 +220,7 @@ function hook_field_group_format_settings($group) {
|
||||
* @param Array $elements by address.
|
||||
* @param Object $group The Field group info.
|
||||
*/
|
||||
function hook_field_group_pre_render(& $element, $group, & $form) {
|
||||
function hook_field_group_pre_render(&$element, $group, &$form) {
|
||||
|
||||
// You can prepare some variables to use in the logic.
|
||||
$view_mode = isset($form['#view_mode']) ? $form['#view_mode'] : 'form';
|
||||
@ -268,7 +268,7 @@ function hook_field_group_pre_render(& $element, $group, & $form) {
|
||||
*
|
||||
* Function that fungates as last resort to alter the pre_render build.
|
||||
*/
|
||||
function hook_field_group_pre_render_alter(&$element, $group, & $form) {
|
||||
function hook_field_group_pre_render_alter(&$element, $group, &$form) {
|
||||
|
||||
if ($group->format_type == 'htab') {
|
||||
$element['#theme_wrappers'] = array('my_horizontal_tab');
|
||||
@ -285,7 +285,7 @@ function hook_field_group_pre_render_alter(&$element, $group, & $form) {
|
||||
*
|
||||
* @param Array $elements by address.
|
||||
*/
|
||||
function hook_field_group_build_pre_render_alter(& $element) {
|
||||
function hook_field_group_build_pre_render_alter(&$element) {
|
||||
|
||||
// Prepare variables.
|
||||
$display = isset($element['#view_mode']);
|
||||
|
@ -99,10 +99,10 @@ function field_group_field_ui_overview_form_alter(&$form, &$form_state, $display
|
||||
// Play around with form_state so we only need to hold things
|
||||
// between requests, until the save button was hit.
|
||||
if (isset($form_state['field_group'][$name])) {
|
||||
$group = & $form_state['field_group'][$name];
|
||||
$group = &$form_state['field_group'][$name];
|
||||
}
|
||||
else {
|
||||
$group = & $params->groups[$name];
|
||||
$group = &$params->groups[$name];
|
||||
}
|
||||
|
||||
// Check the currently selected formatter, and merge persisted values for
|
||||
@ -456,7 +456,7 @@ function field_group_format_settings_label_validate($element, &$form_state) {
|
||||
* @param Object $group
|
||||
* @param array $settings
|
||||
*/
|
||||
function field_group_formatter_row_update(& $group, $settings) {
|
||||
function field_group_formatter_row_update(&$group, $settings) {
|
||||
// if the row has changed formatter type, update the group object
|
||||
if (!empty($settings['format']['type']) && $settings['format']['type'] != $group->format_type) {
|
||||
$group->format_type = $settings['format']['type'];
|
||||
@ -469,7 +469,7 @@ function field_group_formatter_row_update(& $group, $settings) {
|
||||
* @param Object $group The group object
|
||||
* @param Array $settings Configuration settings
|
||||
*/
|
||||
function field_group_formatter_settings_update(& $group, $settings) {
|
||||
function field_group_formatter_settings_update(&$group, $settings) {
|
||||
|
||||
// for format changes we load the defaults.
|
||||
if (empty($settings['format_settings']['settings'])) {
|
||||
|
@ -6,9 +6,9 @@ dependencies[] = ctools
|
||||
core = 7.x
|
||||
files[] = tests/field_group.ui.test
|
||||
files[] = tests/field_group.display.test
|
||||
; Information added by Drupal.org packaging script on 2016-02-28
|
||||
version = "7.x-1.5+2-dev"
|
||||
; Information added by Drupal.org packaging script on 2017-11-03
|
||||
version = "7.x-1.6"
|
||||
core = "7.x"
|
||||
project = "field_group"
|
||||
datestamp = "1456658044"
|
||||
datestamp = "1509751991"
|
||||
|
||||
|
@ -258,8 +258,6 @@ function field_group_field_attach_delete_bundle($entity_type, $bundle) {
|
||||
* Implements hook_field_attach_form().
|
||||
*/
|
||||
function field_group_field_attach_form($entity_type, $entity, &$form, &$form_state, $langcode) {
|
||||
|
||||
$form['#attached']['css'][] = drupal_get_path('module', 'field_group') . '/field_group.field_ui.css';
|
||||
field_group_attach_groups($form, 'form', $form_state);
|
||||
$form['#pre_render'][] = 'field_group_form_pre_render';
|
||||
}
|
||||
@ -1110,7 +1108,7 @@ function field_group_pre_render_tab(&$element, $group, &$form) {
|
||||
* Implements hook_field_group_build_pre_render_alter().
|
||||
* @param Array $elements by address.
|
||||
*/
|
||||
function field_group_field_group_build_pre_render_alter(& $element) {
|
||||
function field_group_field_group_build_pre_render_alter(&$element) {
|
||||
|
||||
// Someone is doing a node view, in a node view. Reset content.
|
||||
// TODO Check if this breaks something else.
|
||||
@ -2027,6 +2025,19 @@ function field_group_fields_nest(&$element, &$vars = NULL) {
|
||||
// Construct own weight, as some fields (for example preprocess fields) don't have weight set.
|
||||
$element[$group_name] = array();
|
||||
$group_references[$group_name] = &$element[$group_name];
|
||||
// Get group parents
|
||||
$parents = array();
|
||||
$current_group = $group;
|
||||
while (!empty($current_group)) {
|
||||
array_unshift($parents, $current_group->group_name);
|
||||
$current_group = isset($element['#fieldgroups'][$current_group->parent_name]) ?
|
||||
$element['#fieldgroups'][$current_group->parent_name] : NULL;
|
||||
}
|
||||
$group_references[$group_name]['#array_parents'] = $parents;
|
||||
$element['#fieldgroups'][$group_name]->array_parents = $parents;
|
||||
// Remove self from parents and set #field_parents
|
||||
array_pop($parents);
|
||||
$group_references[$group_name]['#field_parents'] = $parents;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2077,6 +2088,19 @@ function field_group_fields_nest(&$element, &$vars = NULL) {
|
||||
// list intact (but if it is a field we don't mind).
|
||||
$group_references[$parent_name][$child_name] = &$element[$child_name];
|
||||
$group_references[$parent_name]['#weight'] = $element['#fieldgroups'][$parent_name]->weight;
|
||||
// Prepend #array_parents & #field_parents of group child element & its element_children
|
||||
// if those keys are set, and don't already include the group parents
|
||||
$group_child = &$group_references[$parent_name][$child_name];
|
||||
$group_parents = $group_references[$parent_name]['#array_parents'];
|
||||
$process_elements = array_merge(array(&$group_child), _field_group_element_children_recursive_ref($group_child));
|
||||
foreach ($process_elements as $key => $current_element) {
|
||||
if (isset($current_element['#array_parents']) && !in_array($group_parents[0], $current_element['#array_parents'])) {
|
||||
$process_elements[$key]['#array_parents'] = array_merge($group_parents, $current_element['#array_parents']);
|
||||
}
|
||||
if (isset($current_element['#field_parents']) && !in_array($group_parents[0], $current_element['#field_parents'])) {
|
||||
$process_elements[$key]['#field_parents'] = array_merge($group_parents, $current_element['#field_parents']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The child has been copied to its parent: remove it from the root element.
|
||||
@ -2093,6 +2117,23 @@ function field_group_fields_nest(&$element, &$vars = NULL) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive element_children, returns children by reference
|
||||
*/
|
||||
function _field_group_element_children_recursive_ref(&$element) {
|
||||
$results = array();
|
||||
$children = element_children($element);
|
||||
foreach ($children as $key) {
|
||||
$child = &$element[$key];
|
||||
if (is_array($child)) {
|
||||
$results[] = &$child;
|
||||
$results = array_merge($results, _field_group_element_children_recursive_ref($child));
|
||||
}
|
||||
unset($child);
|
||||
}
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to pre render the field group element.
|
||||
*
|
||||
|
@ -29,8 +29,10 @@ Drupal.behaviors.horizontalTabs = {
|
||||
|
||||
// Transform each fieldset into a tab.
|
||||
$fieldsets.each(function (i) {
|
||||
var $legend = $('> legend', this);
|
||||
$('.element-invisible', $legend).remove();
|
||||
var horizontal_tab = new Drupal.horizontalTab({
|
||||
title: $('> legend', this).text(),
|
||||
title: $legend.text(),
|
||||
fieldset: $(this)
|
||||
});
|
||||
horizontal_tab.item.addClass('horizontal-tab-button-' + i);
|
||||
@ -52,7 +54,7 @@ Drupal.behaviors.horizontalTabs = {
|
||||
// element that matches the URL fragment, activate that tab.
|
||||
var hash = window.location.hash.replace(/[=%;,\/]/g, "");
|
||||
if (hash !== '#' && $(hash, this).length) {
|
||||
tab_focus = $(window.location.hash, this).closest('.horizontal-tabs-pane');
|
||||
tab_focus = $(hash, this).closest('.horizontal-tabs-pane');
|
||||
}
|
||||
else {
|
||||
tab_focus = $('> .horizontal-tabs-pane:first', this);
|
||||
|
@ -22,7 +22,7 @@ class GroupUITestCase extends DrupalWebTestCase {
|
||||
parent::setUp('field_test', 'field_group', 'field_group_test');
|
||||
|
||||
// Create test user.
|
||||
$admin_user = $this->drupalCreateUser(array('administer content types', 'administer nodes', 'access administration pages', 'bypass node access'));
|
||||
$admin_user = $this->drupalCreateUser(array('administer content types', 'administer nodes', 'access administration pages', 'bypass node access', 'administer fields'));
|
||||
$this->drupalLogin($admin_user);
|
||||
}
|
||||
|
||||
|
@ -5,9 +5,9 @@ package = Fields
|
||||
hidden = TRUE
|
||||
|
||||
|
||||
; Information added by Drupal.org packaging script on 2016-02-28
|
||||
version = "7.x-1.5+2-dev"
|
||||
; Information added by Drupal.org packaging script on 2017-11-03
|
||||
version = "7.x-1.6"
|
||||
core = "7.x"
|
||||
project = "field_group"
|
||||
datestamp = "1456658044"
|
||||
datestamp = "1509751991"
|
||||
|
||||
|
@ -11,6 +11,7 @@ Features
|
||||
|
||||
- Flush all image styles
|
||||
- Flush each individual image style
|
||||
- Integrates with the admin_menu module
|
||||
|
||||
|
||||
Dependencies
|
||||
@ -29,6 +30,8 @@ Install
|
||||
2) In your Drupal site, enable the module under Administration -> Modules
|
||||
(/admin/modules).
|
||||
|
||||
3) Visit the Administration -> People -> Permissions page to give the
|
||||
appropriate roles access to flush image styles.
|
||||
|
||||
Usage
|
||||
-----
|
||||
@ -36,6 +39,8 @@ Usage
|
||||
You can flush image styles under Administration -> Configuration -> Media
|
||||
-> Image styles
|
||||
|
||||
Note that this module only flushes images. It does not rebuild them.
|
||||
|
||||
|
||||
Known problems
|
||||
--------------
|
||||
|
@ -4,9 +4,9 @@ package = Media
|
||||
core = 7.x
|
||||
configure = admin/config/media/image-styles
|
||||
|
||||
; Information added by Drupal.org packaging script on 2015-11-07
|
||||
version = "7.x-1.3"
|
||||
; Information added by Drupal.org packaging script on 2017-12-09
|
||||
version = "7.x-1.5"
|
||||
core = "7.x"
|
||||
project = "imagestyleflush"
|
||||
datestamp = "1446884340"
|
||||
datestamp = "1512780486"
|
||||
|
||||
|
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains install and update functions for imagestyleflush.
|
||||
*/
|
||||
|
||||
/**
|
||||
* A new permission has been defined. Give it to all roles that currently
|
||||
* have the 'administer image styles' permission.
|
||||
*/
|
||||
function imagestyleflush_update_7000() {
|
||||
// Since hook_update_N() can run on disabled modules, ensure the module
|
||||
// file is loaded so we can get the list of permissions.
|
||||
module_load_include('module', 'imagestyleflush', 'imagestyleflush');
|
||||
$permissions = array_keys(imagestyleflush_permission());
|
||||
|
||||
// Get existing role_permissions.
|
||||
$rids = db_select('role_permission', 'rp')
|
||||
->fields('rp', array('rid'))
|
||||
->condition('permission', 'administer image styles')
|
||||
->execute()
|
||||
->fetchCol();
|
||||
|
||||
// Add the permissions for each role.
|
||||
foreach ($rids as $rid) {
|
||||
foreach ($permissions as $name) {
|
||||
db_merge('role_permission')
|
||||
->key(array(
|
||||
'rid' => $rid,
|
||||
'permission' => $name,
|
||||
))
|
||||
->fields(array(
|
||||
'module' => 'imagestyleflush',
|
||||
))
|
||||
->execute();
|
||||
}
|
||||
}
|
||||
}
|
@ -14,7 +14,7 @@ function imagestyleflush_menu() {
|
||||
'description' => 'Flush all image styles.',
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('imagestyleflush_form'),
|
||||
'access arguments' => array('administer image styles'),
|
||||
'access arguments' => array('flush image styles'),
|
||||
'type' => MENU_LOCAL_ACTION,
|
||||
'weight' => 3,
|
||||
);
|
||||
@ -23,12 +23,24 @@ function imagestyleflush_menu() {
|
||||
'description' => 'Flush an image style.',
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('imagestyleflush_form', 5),
|
||||
'access arguments' => array('administer image styles'),
|
||||
'access arguments' => array('flush image styles'),
|
||||
);
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_permission().
|
||||
*/
|
||||
function imagestyleflush_permission() {
|
||||
return array(
|
||||
'flush image styles' => array(
|
||||
'title' => t('Flush image styles'),
|
||||
'description' => t('Allow users to flush image styles.'),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_theme_registry_alter().
|
||||
*/
|
||||
@ -44,7 +56,10 @@ function imagestyleflush_theme_registry_alter(&$theme_registry) {
|
||||
function imagestyleflush_image_style_list($variables) {
|
||||
$styles = $variables['styles'];
|
||||
|
||||
$header = array(t('Style name'), t('Settings'), array('data' => t('Operations'), 'colspan' => 3));
|
||||
// Account for an extra column added by the image_styles_admin submodule of
|
||||
// the imagecache_actions module.
|
||||
$colspan = module_exists('image_styles_admin') ? 4 : 3;
|
||||
$header = array(t('Style name'), t('Settings'), array('data' => t('Operations'), 'colspan' => $colspan));
|
||||
$rows = array();
|
||||
foreach ($styles as $style) {
|
||||
$row = array();
|
||||
@ -77,7 +92,7 @@ function imagestyleflush_image_style_list($variables) {
|
||||
|
||||
if (empty($rows)) {
|
||||
$rows[] = array(array(
|
||||
'colspan' => 4,
|
||||
'colspan' => $colspan,
|
||||
'data' => t('There are currently no styles. <a href="!url">Add a new one</a>.', array('!url' => url('admin/config/media/image-styles/add'))),
|
||||
));
|
||||
}
|
||||
@ -105,7 +120,8 @@ function imagestyleflush_form($form, &$form_state, $style = NULL) {
|
||||
),
|
||||
t('Are you sure you want to flush the %style image style?', array('%style' => $style['label'])),
|
||||
'admin/config/media/image-styles',
|
||||
t('This action cannot be undone.'),
|
||||
'<em>' . t('Note: this will only flush the images. It will not rebuild them.')
|
||||
. '</em><br><br>' . t('This action cannot be undone.'),
|
||||
t('Flush'), t('Cancel')
|
||||
);
|
||||
}
|
||||
@ -114,7 +130,8 @@ function imagestyleflush_form($form, &$form_state, $style = NULL) {
|
||||
NULL,
|
||||
t('Are you sure you want to flush all image styles?'),
|
||||
'admin/config/media/image-styles',
|
||||
t('This action cannot be undone.'),
|
||||
'<em>' . t('Note: this will only flush the images. It will not rebuild them.')
|
||||
. '</em><br><br>' . t('This action cannot be undone.'),
|
||||
t('Flush'), t('Cancel')
|
||||
);
|
||||
}
|
||||
@ -138,6 +155,12 @@ function imagestyleflush_form_submit($form, &$form_state) {
|
||||
}
|
||||
}
|
||||
|
||||
// Redirect to the destination URL.
|
||||
$destination = drupal_get_destination();
|
||||
if ($destination['destination'] != current_path()) {
|
||||
$operations[] = array('imagestyleflush_batch_destination_redirect', $destination);
|
||||
}
|
||||
|
||||
$batch = array(
|
||||
'operations' => $operations,
|
||||
'finished' => 'imagestyleflush_batch_finished',
|
||||
@ -146,6 +169,15 @@ function imagestyleflush_form_submit($form, &$form_state) {
|
||||
batch_set($batch);
|
||||
}
|
||||
|
||||
/**
|
||||
* Batch operation. Redirect the batch operation if it was called from the
|
||||
* admin_menu item.
|
||||
*/
|
||||
function imagestyleflush_batch_destination_redirect($destination, &$context) {
|
||||
// Set the destination redirect.
|
||||
$context['results']['redirect'] = $destination;
|
||||
}
|
||||
|
||||
/**
|
||||
* Batch message.
|
||||
*/
|
||||
@ -156,5 +188,51 @@ function imagestyleflush_batch_finished($success, $results, $operations) {
|
||||
else {
|
||||
drupal_set_message(t('An error occurred while flushing the image caches.'), 'error');
|
||||
}
|
||||
drupal_goto('admin/config/media/image-styles');
|
||||
|
||||
if (!empty($results['redirect'])) {
|
||||
drupal_goto($results['redirect']);
|
||||
}
|
||||
else {
|
||||
// Send the user to the right place depending on their access.
|
||||
if (user_access('administer image styles')) {
|
||||
drupal_goto('admin/config/media/image-styles');
|
||||
}
|
||||
else {
|
||||
drupal_goto();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_admin_menu_output_build().
|
||||
*/
|
||||
function imagestyleflush_admin_menu_output_build(&$content) {
|
||||
// Add link to the icon menu to flush image styles.
|
||||
if (isset($content['icon'])) {
|
||||
$styles = image_styles();
|
||||
$access = user_access('flush image styles');
|
||||
$destination = drupal_get_destination();
|
||||
|
||||
$style_links = array();
|
||||
foreach ($styles as $style) {
|
||||
$style_links[$style['name']] = array(
|
||||
'#title' => $style['label'],
|
||||
'#href' => 'admin/config/media/image-styles/flush/' . $style['name'],
|
||||
'#access' => $access,
|
||||
'#options' => array(
|
||||
'query' => $destination,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
$content['icon']['icon']['flush-image-styles'] = array(
|
||||
'#title' => t('Flush all image styles'),
|
||||
'#access' => $access,
|
||||
'#href' => 'admin/config/media/image-styles/flush',
|
||||
'#options' => array(
|
||||
'query' => $destination,
|
||||
),
|
||||
'#weight' => 25,
|
||||
) + $style_links;
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ For support, please create a support request for this module's project:
|
||||
|
||||
Support questions by email to the module maintainer will be simply ignored. Use the issue tracker.
|
||||
|
||||
Now if you want professional (paid) support the module maintainer may be available occassionally.
|
||||
Now if you want professional (paid) support the module maintainer may be available occasionally.
|
||||
Drop me a message to check availability and hourly rates, http://reyero.net/en/contact
|
||||
|
||||
====================================================================
|
||||
|
@ -8,9 +8,8 @@ files[] = i18n_object.inc
|
||||
files[] = i18n.test
|
||||
configure = admin/config/regional/i18n
|
||||
|
||||
; Information added by Drupal.org packaging script on 2015-05-07
|
||||
version = "7.x-1.13"
|
||||
; Information added by Drupal.org packaging script on 2018-08-17
|
||||
version = "7.x-1.26"
|
||||
core = "7.x"
|
||||
project = "i18n"
|
||||
datestamp = "1430999922"
|
||||
|
||||
datestamp = "1534531985"
|
||||
|
@ -198,7 +198,8 @@ function i18n_language_field_extra() {
|
||||
*/
|
||||
function i18n_language_list($field = 'name', $mode = NULL) {
|
||||
$mode = isset($mode) ? $mode : variable_get('i18n_language_list', I18N_LANGUAGE_ENABLED);
|
||||
return locale_language_list($field, I18N_LANGUAGE_EXTENDED & $mode);
|
||||
$all = I18N_LANGUAGE_EXTENDED & $mode;
|
||||
return locale_language_list($field, $all);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -11,7 +11,7 @@ class Drupali18nTestCase extends DrupalWebTestCase {
|
||||
|
||||
function setUpLanguages($admin_permissions = array()) {
|
||||
// Setup admin user.
|
||||
$this->admin_user = $this->drupalCreateUser(array_merge(array('bypass node access', 'administer nodes', 'administer languages', 'administer content types', 'administer blocks', 'access administration pages', 'translate interface'), $admin_permissions));
|
||||
$this->admin_user = $this->drupalCreateUser(array_merge(array('bypass node access', 'administer nodes', 'administer languages', 'administer content types', 'administer fields', 'administer blocks', 'access administration pages', 'translate interface'), $admin_permissions));
|
||||
|
||||
$this->drupalLogin($this->admin_user);
|
||||
|
||||
|
@ -0,0 +1,92 @@
|
||||
CONTENTS OF THIS FILE
|
||||
---------------------
|
||||
|
||||
* Introduction
|
||||
* Requirements
|
||||
* Recommended modules
|
||||
* Installation
|
||||
* Configuration
|
||||
* Troubleshooting
|
||||
* Maintainers
|
||||
|
||||
|
||||
INTRODUCTION
|
||||
------------
|
||||
|
||||
The Block languages module, part of the Internationalization
|
||||
(https://www.drupal.org/project/i18n) package, allows the user to configure
|
||||
for which languages each block is visible.
|
||||
|
||||
* For a full description of the module,
|
||||
visit https://www.drupal.org/node/1279698.
|
||||
|
||||
* To submit bug reports and feature suggestions, or to track changes visit
|
||||
https://www.drupal.org/project/issues/i18n.
|
||||
|
||||
|
||||
REQUIREMENTS
|
||||
------------
|
||||
|
||||
This module requires the following module:
|
||||
|
||||
* Internationalization - https://www.drupal.org/project/i18n
|
||||
|
||||
|
||||
RECOMMENDED MODULES
|
||||
-------------------
|
||||
|
||||
* Internationalization Views - https://www.drupal.org/project/i18nviews
|
||||
* Language Icons - https://www.drupal.org/project/languageicons
|
||||
* Translation Overview - https://www.drupal.org/project/translation_overview
|
||||
* Localization Client - https://www.drupal.org/project/l10n_client
|
||||
* Internationalization contributions -
|
||||
https://www.drupal.org/project/i18n_contrib
|
||||
|
||||
|
||||
INSTALLATION
|
||||
------------
|
||||
|
||||
This is a submodule of the Internationalization module. Install the
|
||||
Internationalization module as you would normally install a contributed Drupal
|
||||
module. Visit https://www.drupal.org/node/895232 for further information.
|
||||
|
||||
|
||||
CONFIGURATION
|
||||
-------------
|
||||
|
||||
The settings for visibility per language are provided under Visibility
|
||||
Settings via the Languages tab when configuring a block.
|
||||
|
||||
The Languages tab also provides a setting for whether the block is translatable.
|
||||
For custom blocks, the block title and the block content will be translatable.
|
||||
For blocks defined by modules, only the block title will be translatable. If
|
||||
"Make this block translatable" is selected, a Translate tab will appear for that
|
||||
block. This tab provides a UI for adding translations of the block in each
|
||||
available language.
|
||||
|
||||
|
||||
TROUBLESHOOTING
|
||||
---------------
|
||||
|
||||
Conflicts with Context
|
||||
|
||||
The Block languages module conflicts with the Context module, which alters how
|
||||
blocks are rendered. This issue can be tracked in the Internationalization
|
||||
issue queue: http://drupal.org/node/1343044
|
||||
|
||||
String Errors
|
||||
|
||||
The user must allow your used string format to be translated on
|
||||
admin/config/regional/i18n/strings or you are going to have an error message
|
||||
like "The string blocks:block:1:body for textgroup blocks is not allowed for
|
||||
translation because of its text format."
|
||||
|
||||
|
||||
MAINTAINERS
|
||||
-----------
|
||||
|
||||
* Jose Reyero - https://www.drupal.org/u/jose-reyero
|
||||
* Florian Weber (webflo) - https://www.drupal.org/u/webflo
|
||||
* Peter Philipp - https://www.drupal.org/u/das-peter
|
||||
* Joseph Olstad - https://www.drupal.org/u/joseph.olstad
|
||||
* Nathaniel Catchpole - https://www.drupal.org/u/catch
|
@ -8,9 +8,8 @@ files[] = i18n_block.inc
|
||||
files[] = i18n_block.test
|
||||
|
||||
|
||||
; Information added by Drupal.org packaging script on 2015-05-07
|
||||
version = "7.x-1.13"
|
||||
; Information added by Drupal.org packaging script on 2018-08-17
|
||||
version = "7.x-1.26"
|
||||
core = "7.x"
|
||||
project = "i18n"
|
||||
datestamp = "1430999922"
|
||||
|
||||
datestamp = "1534531985"
|
||||
|
@ -37,6 +37,17 @@ function i18n_block_menu() {
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_permission().
|
||||
*/
|
||||
function i18n_block_permission() {
|
||||
return array(
|
||||
'translate blocks' => array(
|
||||
'title' => t('Translate Blocks'),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement hook_menu_alter().
|
||||
*
|
||||
@ -59,7 +70,7 @@ function i18n_block_menu_alter(&$items) {
|
||||
*/
|
||||
function i18n_block_translate_tab_access($module, $delta) {
|
||||
$block = block_load($module, $delta);
|
||||
return user_access('translate interface') && $block && isset($block->i18n_mode) && ($block->i18n_mode == I18N_MODE_LOCALIZE);
|
||||
return (user_access('translate interface') || user_access('translate blocks')) && $block && isset($block->i18n_mode) && ($block->i18n_mode == I18N_MODE_LOCALIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -226,7 +237,7 @@ function i18n_block_form_block_admin_configure_alter(&$form, &$form_state, $form
|
||||
'#options' => i18n_language_list(),
|
||||
'#description' => t('If no language is selected, block will show regardless of language.'),
|
||||
);
|
||||
if (user_access('translate interface')) {
|
||||
if (user_access('translate interface') || user_access('translate blocks')) {
|
||||
$form['actions']['translate'] = array(
|
||||
'#type' => 'submit',
|
||||
'#name' => 'save_translate',
|
||||
|
@ -72,15 +72,16 @@ class i18nBlocksTestCase extends Drupali18nTestCase {
|
||||
|
||||
$this->clickLink(t('translate'));
|
||||
|
||||
// Title is a textarea, body is a text_format.
|
||||
$this->assertFieldByName('strings[blocks:block:' . $box2['delta'] . ':title]', $translations['title']['es']);
|
||||
$this->assertFieldByName('strings[blocks:block:' . $box2['delta'] . ':body]', $translations['body']['es']);
|
||||
$this->assertFieldByName('strings[blocks:block:' . $box2['delta'] . ':body][value]', $translations['body']['es']);
|
||||
|
||||
// Update the translation.
|
||||
$translations['title']['es'] = $this->randomName(10);
|
||||
$translations['body']['es'] = $this->randomName(20);
|
||||
$edit = array(
|
||||
'strings[blocks:block:' . $box2['delta'] . ':title]' => $translations['title']['es'],
|
||||
'strings[blocks:block:' . $box2['delta'] . ':body]' => $translations['body']['es'],
|
||||
'strings[blocks:block:' . $box2['delta'] . ':body][value]' => $translations['body']['es'],
|
||||
);
|
||||
$this->drupalPost(NULL, $edit, t('Save translation'));
|
||||
$this->i18nAssertTranslations($translations['title'], '', 'Updated block title translation displayed.');
|
||||
|
@ -0,0 +1,76 @@
|
||||
CONTENTS OF THIS FILE
|
||||
---------------------
|
||||
|
||||
* Introduction
|
||||
* Requirements
|
||||
* Recommended modules
|
||||
* Installation
|
||||
* Configuration
|
||||
* Maintainers
|
||||
|
||||
|
||||
INTRODUCTION
|
||||
------------
|
||||
|
||||
The Contact translation module, part of the Internationalization
|
||||
(https://www.drupal.org/project/i18n) package, helps with the multilingual
|
||||
configuration of the site contact forms. This module makes contact categories
|
||||
and replies available for translation.
|
||||
|
||||
* For a full description of the module, visit
|
||||
https://www.drupal.org/node/1396984.
|
||||
|
||||
* To submit bug reports and feature suggestions, or to track changes,
|
||||
visit https://www.drupal.org/project/issues/i18n.
|
||||
|
||||
|
||||
REQUIREMENTS
|
||||
------------
|
||||
|
||||
This module requires the following module:
|
||||
|
||||
* Internationalization - https://www.drupal.org/project/i18n
|
||||
|
||||
|
||||
RECOMMENDED MODULES
|
||||
-------------------
|
||||
|
||||
* Internationalization Views - https://www.drupal.org/project/i18nviews
|
||||
* Language Icons - https://www.drupal.org/project/languageicons
|
||||
* Translation Overview - https://www.drupal.org/project/translation_overview
|
||||
* Localization Client - https://www.drupal.org/project/l10n_client
|
||||
* Internationalization contributions -
|
||||
https://www.drupal.org/project/i18n_contrib
|
||||
|
||||
|
||||
INSTALLATION
|
||||
------------
|
||||
|
||||
This is a submodule of the Internationalization module. Install the
|
||||
Internationalization module as you would normally install a contributed Drupal
|
||||
module. Visit https://www.drupal.org/node/895232 for further information.
|
||||
|
||||
|
||||
CONFIGURATION
|
||||
-------------
|
||||
|
||||
1. Enable the Contact translation module included with the Internationalization
|
||||
module.
|
||||
2. Go to Administration > Structure > Contact form.
|
||||
3. Select edit for the form to configure.
|
||||
4. Select the Translate tab.
|
||||
5. Select the translate link for a language.
|
||||
6. Translate the Category and Auto-reply text.
|
||||
7. Select Save translation.
|
||||
8. Repeat steps 5 to 7 for each language.
|
||||
9. Repeat steps 2 to 8 for all forms.
|
||||
|
||||
|
||||
MAINTAINERS
|
||||
-----------
|
||||
|
||||
* Jose Reyero - https://www.drupal.org/u/jose-reyero
|
||||
* Florian Weber (webflo) - https://www.drupal.org/u/webflo
|
||||
* Peter Philipp - https://www.drupal.org/u/das-peter
|
||||
* Joseph Olstad - https://www.drupal.org/u/joseph.olstad
|
||||
* Nathaniel Catchpole - https://www.drupal.org/u/catch
|
@ -5,9 +5,8 @@ dependencies[] = i18n_string
|
||||
package = Multilingual - Internationalization
|
||||
core = 7.x
|
||||
|
||||
; Information added by Drupal.org packaging script on 2015-05-07
|
||||
version = "7.x-1.13"
|
||||
; Information added by Drupal.org packaging script on 2018-08-17
|
||||
version = "7.x-1.26"
|
||||
core = "7.x"
|
||||
project = "i18n"
|
||||
datestamp = "1430999922"
|
||||
|
||||
datestamp = "1534531985"
|
||||
|
@ -0,0 +1,78 @@
|
||||
CONTENTS OF THIS FILE
|
||||
---------------------
|
||||
|
||||
* Introduction
|
||||
* Requirements
|
||||
* Recommended modules
|
||||
* Installation
|
||||
* Configuration
|
||||
* Maintainers
|
||||
|
||||
|
||||
INTRODUCTION
|
||||
------------
|
||||
|
||||
The Field translation module, part of the Internationalization
|
||||
(https://www.drupal.org/project/i18n) package, allows for translation of text
|
||||
associated with a field's settings including the label, help text, default
|
||||
value, and list options.
|
||||
|
||||
* For a full description of the module, visit this page
|
||||
https://www.drupal.org/node/1279346.
|
||||
|
||||
* To submit bug reports and feature suggestions, or to track changes visit
|
||||
https://www.drupal.org/project/issues/i18n.
|
||||
|
||||
|
||||
REQUIREMENTS
|
||||
------------
|
||||
|
||||
This module requires the following module:
|
||||
|
||||
* Internationalization - https://www.drupal.org/project/i18n
|
||||
|
||||
|
||||
RECOMMENDED MODULES
|
||||
-------------------
|
||||
|
||||
* Internationalization Views - https://www.drupal.org/project/i18nviews
|
||||
* Language Icons - https://www.drupal.org/project/languageicons
|
||||
* Translation Overview - https://www.drupal.org/project/translation_overview
|
||||
* Localization Client - https://www.drupal.org/project/l10n_client
|
||||
* Internationalization contributions -
|
||||
https://www.drupal.org/project/i18n_contrib
|
||||
|
||||
|
||||
INSTALLATION
|
||||
------------
|
||||
|
||||
This is a submodule of the Internationalization module. Install the
|
||||
Internationalization module as you would normally install a contributed Drupal
|
||||
module. Visit https://www.drupal.org/node/895232 for further information.
|
||||
|
||||
|
||||
CONFIGURATION
|
||||
-------------
|
||||
|
||||
1. Enable the Field translation module included with Internationalization.
|
||||
2. Go to Administration > Configuration > Regional and language > Translate
|
||||
interface.
|
||||
3. Select the Filter Translatable Strings field set and limit search to fields.
|
||||
4. Edit the desired field and Save.
|
||||
|
||||
For the translation to be displayed, the user needs to use some of the Field
|
||||
Formatters provided by this module whose name usually ends up in 'translated'.
|
||||
For most core fields it is Default translated.
|
||||
|
||||
Note: The Field Translation module does not provide content translation for
|
||||
fields. This functionality is provided by the Entity Translation (ET) module.
|
||||
|
||||
|
||||
MAINTAINERS
|
||||
-----------
|
||||
|
||||
* Jose Reyero - https://www.drupal.org/u/jose-reyero
|
||||
* Florian Weber (webflo) - https://www.drupal.org/u/webflo
|
||||
* Peter Philipp - https://www.drupal.org/u/das-peter
|
||||
* Joseph Olstad - https://www.drupal.org/u/joseph.olstad
|
||||
* Nathaniel Catchpole - https://www.drupal.org/u/catch
|
@ -72,7 +72,7 @@ function i18n_field_i18n_string_info() {
|
||||
'description' => t('Configurable fields descriptions, defaults, options, etc.'),
|
||||
'format' => FALSE, // This group doesn't have formatted strings
|
||||
'list' => TRUE, // This group can list all strings
|
||||
'class' => 'i18n_string_textgroup_cached',
|
||||
'class' => variable_get('i18n_string_textgroup_class_field', 'i18n_string_textgroup_cached'),
|
||||
);
|
||||
return $groups;
|
||||
}
|
||||
|
@ -6,9 +6,8 @@ package = Multilingual - Internationalization
|
||||
core = 7.x
|
||||
files[] = i18n_field.inc
|
||||
files[] = i18n_field.test
|
||||
; Information added by Drupal.org packaging script on 2015-05-07
|
||||
version = "7.x-1.13"
|
||||
; Information added by Drupal.org packaging script on 2018-08-17
|
||||
version = "7.x-1.26"
|
||||
core = "7.x"
|
||||
project = "i18n"
|
||||
datestamp = "1430999922"
|
||||
|
||||
datestamp = "1534531985"
|
||||
|
@ -194,6 +194,9 @@ function i18n_field_field_widget_form_alter(&$element, &$form_state, $context) {
|
||||
// Single-value file fields and image fields.
|
||||
$alter_element = &$element[0];
|
||||
}
|
||||
elseif ($field['type'] == 'url' && $field['module'] == 'url' && $field['cardinality'] == 1) {
|
||||
$alter_element = &$element;
|
||||
}
|
||||
elseif (isset($element['value'])) {
|
||||
// Number fields. Single-value text fields.
|
||||
$alter_element = &$element['value'];
|
||||
@ -202,6 +205,10 @@ function i18n_field_field_widget_form_alter(&$element, &$form_state, $context) {
|
||||
// Entityreference fields using the entityreference_autocomplete widget.
|
||||
$alter_element = &$element['target_id'];
|
||||
}
|
||||
elseif ($field['type'] == 'node_reference' && isset($element['nid'])) {
|
||||
// The node_reference fields using the entityreference_autocomplete widget.
|
||||
$alter_element = &$element['nid'];
|
||||
}
|
||||
else {
|
||||
// All other fields.
|
||||
$alter_element = &$element;
|
||||
@ -446,3 +453,120 @@ function i18n_field_type_info($type = NULL, $property = NULL) {
|
||||
return $info;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_info_alter().
|
||||
*/
|
||||
function i18n_field_field_info_alter(&$field_info) {
|
||||
foreach(array_keys($field_info) as $type) {
|
||||
$field_info[$type]['property_callbacks'][] = 'i18n_field_entity_property_callback';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prime the cache to avoid single db queries for entity fields / properties.
|
||||
*
|
||||
* This is mainly uses when large operations are occuring like a flush of the
|
||||
* entity_property_infos().
|
||||
*/
|
||||
function i18n_field_prime_caches() {
|
||||
global $language;
|
||||
static $cache_primed;
|
||||
|
||||
// Fill the cache. This should avoid single db queries when filling the
|
||||
// properties.
|
||||
if (empty($cache_primed)) {
|
||||
$cache_primed = TRUE;
|
||||
$text_group = i18n_string_textgroup('field');
|
||||
// Load all strings at once to avoid callbacks for each individual string.
|
||||
$text_group->load_strings();
|
||||
$text_group->multiple_translation_search(array('type' => '*', 'objectid' => '*', 'property' => '*'), $language->language);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback to translate entity property info for a fields.
|
||||
*
|
||||
* @see entity_metadata_field_entity_property_info()
|
||||
* @see entity_metadata_field_default_property_callback()
|
||||
* @see i18n_field_i18n_object_info_alter()
|
||||
* @see hook_module_implements_alter()
|
||||
*/
|
||||
function i18n_field_entity_property_callback(&$info, $entity_type, $field, $instance, $field_type) {
|
||||
global $language;
|
||||
|
||||
// This could create a endless recursion if it's called during rebuilding the
|
||||
// cache for i18n_object_info(). So if the cache of i18n_object_info isn't
|
||||
// available yet we assume the worst case, leave the info alone but trigger a
|
||||
// rebuild of the property when hook_i18n_object_info_alter is invoked. At
|
||||
// that point the info is available and we can rely on it.
|
||||
if (!$info = &drupal_static('i18n_object_info')) {
|
||||
$i18n_field_entity_property_callback_fallback = &drupal_static(__FUNCTION__);
|
||||
$i18n_field_entity_property_callback_fallback = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
i18n_field_prime_caches();
|
||||
$name = $field['field_name'];
|
||||
$property = &$info[$entity_type]['bundles'][$instance['bundle']]['properties'][$name];
|
||||
$property['label'] = i18n_field_translate_property($instance, 'label', $language->language);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_i18n_object_info_alter().
|
||||
*/
|
||||
function i18n_field_i18n_object_info_alter(&$info) {
|
||||
if (drupal_static('i18n_field_entity_property_callback')) {
|
||||
if ($info = drupal_static('i18n_object_info')) {
|
||||
// Clean static and permanent cache of the data and then re-run the property
|
||||
// building.
|
||||
// Use a lock to avoid stampeding.
|
||||
$lock_name = 'i18n_field_entity_property_callback_fallback:' . $GLOBALS['language']->language;
|
||||
// See if another request is already doing this. If so we bail out here as
|
||||
// we won't help with anything at the moment.
|
||||
if (!lock_may_be_available($lock_name)) {
|
||||
return;
|
||||
}
|
||||
if (lock_acquire($lock_name)) {
|
||||
i18n_field_prime_caches();
|
||||
// Inject translated properties.
|
||||
$entity_property_info = entity_get_property_info();
|
||||
foreach ($entity_property_info as $entity_type => $properties) {
|
||||
if (isset($properties['bundles'])) {
|
||||
foreach ($properties['bundles'] as $bundle => $bundle_properties) {
|
||||
if ($bundle_properties['properties']) {
|
||||
foreach ($bundle_properties['properties'] as $bundle_property => $bundle_property_info) {
|
||||
if ($instance = field_info_instance($entity_type, $bundle_property, $bundle)) {
|
||||
$property = &$entity_property_info[$entity_type]['bundles'][$instance['bundle']]['properties'][$bundle_property];
|
||||
$property['label'] = i18n_field_translate_property($instance, 'label', $GLOBALS['language']->language);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Inject into static cache.
|
||||
$entity_get_property_info = &drupal_static('entity_get_property_info', array());
|
||||
$entity_get_property_info = $entity_property_info;
|
||||
// Write permanent cache.
|
||||
cache_set('entity_property_info:' . $GLOBALS['language']->language, $entity_property_info);
|
||||
lock_release($lock_name);
|
||||
}
|
||||
}
|
||||
else {
|
||||
watchdog('i18n_field', 'Unable to run fall-back handling for entity property translation due missing "i18n_object_info" cache', array(), WATCHDOG_WARNING);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_module_implements_alter().
|
||||
*/
|
||||
function i18n_field_module_implements_alter(&$implementations, $hook) {
|
||||
if ($hook == 'i18n_object_info_alter') {
|
||||
// Move our hook implementation to the bottom.
|
||||
$group = $implementations['i18n_field'];
|
||||
unset($implementations['i18n_field']);
|
||||
$implementations['i18n_field'] = $group;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,86 @@
|
||||
CONTENTS OF THIS FILE
|
||||
---------------------
|
||||
|
||||
* Introduction
|
||||
* Requirements
|
||||
* Recommended modules
|
||||
* Installation
|
||||
* Configuration
|
||||
* Maintainers
|
||||
|
||||
|
||||
INTRODUCTION
|
||||
------------
|
||||
|
||||
The Multilingual forum module, part of the Internationalization
|
||||
(https://www.drupal.org/project/i18n) package, helps with the multilingual
|
||||
configuration of the site’s forums.
|
||||
|
||||
* For a full description of the module visit
|
||||
https://www.drupal.org/node/1396988.
|
||||
|
||||
* To submit bug reports and feature suggestions, or to track changes visit
|
||||
https://www.drupal.org/project/issues/i18n.
|
||||
|
||||
|
||||
REQUIREMENTS
|
||||
------------
|
||||
|
||||
This module requires the following module:
|
||||
|
||||
* Internationalization - https://www.drupal.org/project/i18n
|
||||
|
||||
|
||||
RECOMMENDED MODULES
|
||||
-------------------
|
||||
|
||||
* Internationalization Views - https://www.drupal.org/project/i18nviews
|
||||
* Language Icons - https://www.drupal.org/project/languageicons
|
||||
* Translation Overview - https://www.drupal.org/project/translation_overview
|
||||
* Localization Client - https://www.drupal.org/project/l10n_client
|
||||
* Internationalization contributions -
|
||||
https://www.drupal.org/project/i18n_contrib
|
||||
|
||||
INSTALLATION
|
||||
------------
|
||||
|
||||
This is a submodule of the Internationalization module. Install the
|
||||
Internationalization module as you would normally install a contributed Drupal
|
||||
module. Visit https://www.drupal.org/node/895232 for further information.
|
||||
|
||||
|
||||
CONFIGURATION
|
||||
-------------
|
||||
|
||||
To configure forum vocabulary
|
||||
|
||||
1. Enable the Multilingual forum module included with Internationalization.
|
||||
2. Go to Administration > Structure > Taxonomy.
|
||||
3. Select the "edit vocabulary" for the Forums vocabulary.
|
||||
4. Choose the translation mode (Localize or Translate).
|
||||
5. Select the "Save and translate" button.
|
||||
6. Select the "translate" link for a language.
|
||||
7. Translate the "Name" and "Description" for the forum.
|
||||
8. Select the "Save translation" button.
|
||||
9. Repeat steps 6 to 8 for each language.
|
||||
|
||||
To configure forum terms
|
||||
|
||||
1. Go to Administration > Structure > Forums.
|
||||
2. Select the "edit" link for a forum or container.
|
||||
3. Select the "Translate" tab.
|
||||
4. Select the "translate" link for a language.
|
||||
5. Translate the "Name" and "Description" for the term.
|
||||
6. Select the "Save translation" button.
|
||||
7. Repeat steps 4 to 6 for each language.
|
||||
8. Repeat all steps for all terms.
|
||||
|
||||
|
||||
MAINTAINERS
|
||||
-----------
|
||||
|
||||
* Jose Reyero - https://www.drupal.org/u/jose-reyero
|
||||
* Florian Weber (webflo) - https://www.drupal.org/u/webflo
|
||||
* Peter Philipp - https://www.drupal.org/u/das-peter
|
||||
* Joseph Olstad - https://www.drupal.org/u/joseph.olstad
|
||||
* Nathaniel Catchpole - https://www.drupal.org/u/catch
|
@ -7,9 +7,8 @@ package = Multilingual - Internationalization
|
||||
core = 7.x
|
||||
files[] = i18n_forum.test
|
||||
|
||||
; Information added by Drupal.org packaging script on 2015-05-07
|
||||
version = "7.x-1.13"
|
||||
; Information added by Drupal.org packaging script on 2018-08-17
|
||||
version = "7.x-1.26"
|
||||
core = "7.x"
|
||||
project = "i18n"
|
||||
datestamp = "1430999922"
|
||||
|
||||
datestamp = "1534531985"
|
||||
|
111
sites/all/modules/contrib/localisation/i18n/i18n_menu/README.txt
Normal file
111
sites/all/modules/contrib/localisation/i18n/i18n_menu/README.txt
Normal file
@ -0,0 +1,111 @@
|
||||
CONTENTS OF THIS FILE
|
||||
---------------------
|
||||
|
||||
* Introduction
|
||||
* Requirements
|
||||
* Recommended modules
|
||||
* Installation
|
||||
* Configuration
|
||||
* Troubleshooting
|
||||
* Maintainers
|
||||
|
||||
|
||||
INTRODUCTION
|
||||
------------
|
||||
|
||||
The Menu translation module, part of the Internationalization
|
||||
(https://www.drupal.org/project/i18n) package, allows users to select a
|
||||
translation mode for each menu.
|
||||
|
||||
* For a full description of the module, visit this page:
|
||||
https://www.drupal.org/node/1113982.
|
||||
|
||||
* To submit bug reports and feature suggestions, or to track changes:
|
||||
https://www.drupal.org/project/issues/i18n.
|
||||
|
||||
|
||||
REQUIREMENTS
|
||||
------------
|
||||
|
||||
This module requires the following module:
|
||||
|
||||
* Internationalization - https://www.drupal.org/project/i18n
|
||||
|
||||
|
||||
RECOMMENDED MODULES
|
||||
-------------------
|
||||
|
||||
* Internationalization Views - https://www.drupal.org/project/i18nviews
|
||||
* Language Icons - https://www.drupal.org/project/languageicons
|
||||
* Translation Overview - https://www.drupal.org/project/translation_overview
|
||||
* Localization Client - https://www.drupal.org/project/l10n_client
|
||||
* Internationalization contributions -
|
||||
https://www.drupal.org/project/i18n_contrib
|
||||
|
||||
To link menu item menus to nodes, it is useful to have the following modules:
|
||||
|
||||
* Entity translation i18n menu module, a submodule of Entity translation -
|
||||
https://www.drupal.org/project/entity_translation
|
||||
* Menu translation node module - https://www.drupal.org/project/i18n_menu_node
|
||||
|
||||
|
||||
INSTALLATION
|
||||
------------
|
||||
|
||||
This is a submodule of the Internationalization module. Install the
|
||||
Internationalization module as you would normally install a contributed Drupal
|
||||
module. Visit https://www.drupal.org/node/895232 for further information.
|
||||
|
||||
|
||||
CONFIGURATION
|
||||
-------------
|
||||
|
||||
Language-specific menus
|
||||
1. To create or edit a menu, navigate to Structure > Menus > (menu to edit) >
|
||||
Edit.
|
||||
2. In the Translation mode section, choose Fixed Language and a Language field
|
||||
will appear.
|
||||
3. Select a language, select Save, and add or update the menu items as needed.
|
||||
The menu block will only appear when viewing content in the same language.
|
||||
|
||||
There are three modes available: Translate and Localize, Fixed Language, and No
|
||||
Multilingual Options.
|
||||
|
||||
Translate and Localize:
|
||||
The user can create one menu for all languages, and translate or localize each
|
||||
menu item. There are two ways that menu items will be translated.
|
||||
1. The user can set a language when creating a custom menu item so that the menu
|
||||
item will only show up for that language. Menu items that link to nodes in a
|
||||
particular language will be treated this way.
|
||||
2. The user can localize other custom menu items without a language
|
||||
(for example, menu items linking to Views pages). Use the Translate tab to
|
||||
translate the menu item title and description. Translators can also use the
|
||||
"Translate interface" pages to translate these menu items.
|
||||
|
||||
Fixed Language:
|
||||
If the user chooses Fixed Language, they'll have to set up a separate menu in
|
||||
each language. This could become tedious if have a lot of languages enabled on
|
||||
the site, but is useful if the content or menu structure is different for each
|
||||
language.
|
||||
|
||||
No Multilingual Options:
|
||||
Only the menu will be translatable.
|
||||
|
||||
TROUBLESHOOTING
|
||||
---------------
|
||||
|
||||
A menu item linked to a node will be displayed only when the node language
|
||||
matches the page language. This is due to how the menu system works and the
|
||||
"Language selection" feature in i18n. Therefore, to get translated menus items
|
||||
that link to nodes, you first need translated content. For more information
|
||||
visit https://www.drupal.org/docs/7/multilingual/translating-content.
|
||||
|
||||
|
||||
MAINTAINERS
|
||||
-----------
|
||||
|
||||
* Jose Reyero - https://www.drupal.org/u/jose-reyero
|
||||
* Florian Weber (webflo) - https://www.drupal.org/u/webflo
|
||||
* Peter Philipp - https://www.drupal.org/u/das-peter
|
||||
* Joseph Olstad - https://www.drupal.org/u/joseph.olstad
|
||||
* Nathaniel Catchpole - https://www.drupal.org/u/catch
|
@ -10,9 +10,8 @@ core = 7.x
|
||||
files[] = i18n_menu.inc
|
||||
files[] = i18n_menu.test
|
||||
|
||||
; Information added by Drupal.org packaging script on 2015-05-07
|
||||
version = "7.x-1.13"
|
||||
; Information added by Drupal.org packaging script on 2018-08-17
|
||||
version = "7.x-1.26"
|
||||
core = "7.x"
|
||||
project = "i18n"
|
||||
datestamp = "1430999922"
|
||||
|
||||
datestamp = "1534531985"
|
||||
|
@ -53,6 +53,24 @@ function i18n_menu_menu_alter(&$items) {
|
||||
$items['admin/structure/menu/item/%menu_link'] = $items['admin/structure/menu/item/%menu_link/edit'];
|
||||
$items['admin/structure/menu/item/%menu_link']['type'] = MENU_CALLBACK;
|
||||
$items['admin/structure/menu/item/%menu_link/edit']['type'] = MENU_DEFAULT_LOCAL_TASK;
|
||||
$items['admin/structure/menu/manage/%menu']['title callback'] = 'i18n_menu_menu_overview_title';
|
||||
}
|
||||
|
||||
/**
|
||||
* Preprocess theme_menu_admin_overview to translate menu name and description
|
||||
*
|
||||
* @param $variables
|
||||
*/
|
||||
function i18n_menu_preprocess_menu_admin_overview(&$variables) {
|
||||
$variables['title'] = i18n_string(array('menu', 'menu', $variables['name'], 'title'), $variables['title'], array('sanitize' => FALSE));
|
||||
$variables['description'] = i18n_string(array('menu', 'menu', $variables['name'], 'description'), $variables['description'], array('sanitize' => FALSE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Title callback for the menu overview page and links.
|
||||
*/
|
||||
function i18n_menu_menu_overview_title($menu) {
|
||||
return i18n_string(array('menu', 'menu', $menu['menu_name'], 'title'), $menu['title']);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -379,7 +397,7 @@ function i18n_menu_localize_tree($tree, $langcode = NULL) {
|
||||
if (_i18n_menu_link_process($item['link'])) {
|
||||
if (!_i18n_menu_link_is_visible($item['link'], $langcode)) {
|
||||
// Remove links for other languages than current.
|
||||
// Links with language wont be localized.
|
||||
// Links with language won't be localized.
|
||||
unset($tree[$index]);
|
||||
// @todo Research whether the above has any advantage over:
|
||||
// $item['hidden'] = TRUE;
|
||||
@ -504,7 +522,7 @@ function _i18n_menu_link_localize(&$link, $langcode = NULL) {
|
||||
function _i18n_menu_link_description($link, $langcode = NULL) {
|
||||
if (!empty($link['options']['attributes']['title'])) {
|
||||
$key = i18n_object_info('menu_link', 'key');
|
||||
return i18n_string_translate(array('menu', 'item', $link[$key], 'description'), $link['options']['attributes']['title'], array('langcode' => $langcode));
|
||||
return i18n_string_translate(array('menu', 'item', $link[$key], 'description'), $link['options']['attributes']['title'], array('langcode' => $langcode, 'sanitize' => FALSE));
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
@ -515,9 +533,11 @@ function _i18n_menu_link_description($link, $langcode = NULL) {
|
||||
* Check whether this link is to be processed by i18n_menu and start processing.
|
||||
*/
|
||||
function _i18n_menu_link_process(&$link) {
|
||||
// Only visible links that have a language property and haven't been processed
|
||||
// before. We also check that they belong to a menu with language options.
|
||||
if (empty($link['i18n_menu']) && !empty($link['language']) && !empty($link['access']) && empty($link['hidden']) && i18n_menu_mode($link['menu_name'])) {
|
||||
// Only links that have a language property and haven't been processed before.
|
||||
// We also translate links marked as hidden because core breadcrumbs ignore
|
||||
// that flag and excluding them would basically interfere with core behaviour.
|
||||
// We also check that they belong to a menu with language options.
|
||||
if (empty($link['i18n_menu']) && !empty($link['language']) && !empty($link['access']) && i18n_menu_mode($link['menu_name'])) {
|
||||
// Mark so it won't be processed twice.
|
||||
$link['i18n_menu'] = TRUE;
|
||||
// Skip if administering this menu or this menu item.
|
||||
@ -579,7 +599,7 @@ function _i18n_menu_link_is_visible($link, $langcode = NULL) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get localizable properties for menu link checking agains the router item.
|
||||
* Get localizable properties for menu link checking against the router item.
|
||||
*/
|
||||
function _i18n_menu_link_localizable_properties($link) {
|
||||
$props = array();
|
||||
@ -723,15 +743,19 @@ function i18n_menu_form_menu_edit_item_alter(&$form, &$form_state) {
|
||||
* Add a "translate" link in operations column for each menu item.
|
||||
*/
|
||||
function i18n_menu_form_menu_overview_form_alter(&$form, &$form_state) {
|
||||
foreach (element_children($form) as $element) {
|
||||
if (substr($element, 0, 5) == 'mlid:') {
|
||||
$mlid = $form[$element]['#item']['mlid'];
|
||||
if (i18n_get_object('menu', $mlid)->get_translate_access()) {
|
||||
$form[$element]['operations']['translate'] = array(
|
||||
'#type' => 'link',
|
||||
'#title' => t('translate'),
|
||||
'#href' => "admin/structure/menu/item/{$mlid}/translate",
|
||||
);
|
||||
if (i18n_menu_mode($form['#menu']['menu_name'], I18N_MODE_MULTIPLE)) {
|
||||
foreach (element_children($form) as $element) {
|
||||
if (substr($element, 0, 5) == 'mlid:') {
|
||||
$item = $form[$element]["#item"];
|
||||
$mlid = $form[$element]['#item']['mlid'];
|
||||
if (i18n_get_object('menu', $mlid)->get_translate_access()) {
|
||||
$form[$element]['operations']['translate'] = array(
|
||||
'#type' => 'link',
|
||||
'#title' => t('translate'),
|
||||
'#href' => "admin/structure/menu/item/{$mlid}/translate",
|
||||
);
|
||||
$form[$element]['title']['#markup'] = l(_i18n_menu_link_title($item), $item['href'], $item['localized_options']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -898,93 +922,25 @@ function i18n_menu_query_features_menu_link_alter($query) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_init().
|
||||
* Implements hook_query_TAG_alter()
|
||||
*
|
||||
* Using tag 'preferred_menu_links' added in menu_link_get_preferred().
|
||||
* See http://drupal.org/node/1854134
|
||||
*/
|
||||
function i18n_menu_init() {
|
||||
function i18n_menu_query_preferred_menu_links_alter(QueryAlterableInterface $query) {
|
||||
global $language;
|
||||
// Get queried tables.
|
||||
$tables = $query->getTables();
|
||||
|
||||
// The only way to override the default preferred menu link for a path is to
|
||||
// inject it into the static cache of the function menu_link_get_preferred().
|
||||
|
||||
// The problem with the default implementation is that it does not take the
|
||||
// language of a menu link into account. Whe having different menu trees for
|
||||
// different menus, this means that the active trail will not work for all but
|
||||
// one language.
|
||||
|
||||
// The code below is identical to the mentioned function except the added
|
||||
// language condition on the query.
|
||||
|
||||
// TODO: Adding an alter tag to the query would allow to do this with a simple
|
||||
// hook_query_alter() implementation.
|
||||
|
||||
$preferred_links = &drupal_static('menu_link_get_preferred');
|
||||
|
||||
$path = $_GET['q'];
|
||||
|
||||
// Look for the correct menu link by building a list of candidate paths,
|
||||
// which are ordered by priority (translated hrefs are preferred over
|
||||
// untranslated paths). Afterwards, the most relevant path is picked from
|
||||
// the menus, ordered by menu preference.
|
||||
$item = menu_get_item($path);
|
||||
$path_candidates = array();
|
||||
// 1. The current item href.
|
||||
$path_candidates[$item['href']] = $item['href'];
|
||||
// 2. The tab root href of the current item (if any).
|
||||
if ($item['tab_parent'] && ($tab_root = menu_get_item($item['tab_root_href']))) {
|
||||
$path_candidates[$tab_root['href']] = $tab_root['href'];
|
||||
}
|
||||
// 3. The current item path (with wildcards).
|
||||
$path_candidates[$item['path']] = $item['path'];
|
||||
// 4. The tab root path of the current item (if any).
|
||||
if (!empty($tab_root)) {
|
||||
$path_candidates[$tab_root['path']] = $tab_root['path'];
|
||||
}
|
||||
// Retrieve a list of menu names, ordered by preference.
|
||||
$menu_names = menu_get_active_menu_names();
|
||||
// Use an illegal menu name as the key for the preferred menu link.
|
||||
$selected_menu = MENU_PREFERRED_LINK;
|
||||
// Put the selected menu at the front of the list.
|
||||
array_unshift($menu_names, $selected_menu);
|
||||
|
||||
$query = db_select('menu_links', 'ml', array('fetch' => PDO::FETCH_ASSOC));
|
||||
$query->leftJoin('menu_router', 'm', 'm.path = ml.router_path');
|
||||
$query->fields('ml');
|
||||
// Weight must be taken from {menu_links}, not {menu_router}.
|
||||
$query->addField('ml', 'weight', 'link_weight');
|
||||
$query->fields('m');
|
||||
$query->condition('ml.link_path', $path_candidates, 'IN');
|
||||
|
||||
// Only look menu links with none or the current language.
|
||||
$query->condition('ml.language', array(LANGUAGE_NONE, i18n_language_interface()->language), 'IN');
|
||||
|
||||
// Sort candidates by link path and menu name.
|
||||
$candidates = array();
|
||||
foreach ($query->execute() as $candidate) {
|
||||
$candidate['weight'] = $candidate['link_weight'];
|
||||
$candidates[$candidate['link_path']][$candidate['menu_name']] = $candidate;
|
||||
// Add any menus not already in the menu name search list.
|
||||
if (!in_array($candidate['menu_name'], $menu_names)) {
|
||||
$menu_names[] = $candidate['menu_name'];
|
||||
}
|
||||
}
|
||||
|
||||
// Store the most specific link for each menu. Also save the most specific
|
||||
// link of the most preferred menu in $preferred_link.
|
||||
foreach ($path_candidates as $link_path) {
|
||||
if (isset($candidates[$link_path])) {
|
||||
foreach ($menu_names as $menu_name) {
|
||||
if (empty($preferred_links[$path][$menu_name]) && isset($candidates[$link_path][$menu_name])) {
|
||||
$candidate_item = $candidates[$link_path][$menu_name];
|
||||
$map = explode('/', $path);
|
||||
_menu_translate($candidate_item, $map);
|
||||
if ($candidate_item['access']) {
|
||||
$preferred_links[$path][$menu_name] = $candidate_item;
|
||||
if (empty($preferred_links[$path][MENU_PREFERRED_LINK])) {
|
||||
// Store the most specific link.
|
||||
$preferred_links[$path][MENU_PREFERRED_LINK] = $candidate_item;
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($tables as $alias => $table) {
|
||||
if ($table['table'] == 'menu_links') {
|
||||
// Add language filter, ensuring that we don't have any collision when
|
||||
// determining the active menu trail when there are multiple menu items
|
||||
// with same link path but different languages.
|
||||
if ($language) {
|
||||
$query->condition('language', array($language->language, LANGUAGE_NONE), 'IN');
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,96 @@
|
||||
CONTENTS OF THIS FILE
|
||||
---------------------
|
||||
|
||||
* Introduction
|
||||
* Requirements
|
||||
* Recommended modules
|
||||
* Installation
|
||||
* Configuration
|
||||
* Maintainers
|
||||
|
||||
|
||||
INTRODUCTION
|
||||
------------
|
||||
|
||||
The Multilingual content module, part of the Internationalization
|
||||
(https://www.drupal.org/project/i18n) package, provides extended multilingual
|
||||
options for nodes. These options help accommodate a variety of translation
|
||||
workflows by controlling how the language for nodes is set.
|
||||
|
||||
Note that the Multilingual content module lives in the i18n_node directory
|
||||
in the Internationalization package. Don't confuse this module with the core
|
||||
Content translation module.
|
||||
|
||||
* For a full description of the module visit:
|
||||
https://www.drupal.org/node/1279644.
|
||||
|
||||
* To submit bug reports and feature suggestions, or to track changes visit
|
||||
https://www.drupal.org/project/issues/i18n.
|
||||
|
||||
|
||||
REQUIREMENTS
|
||||
------------
|
||||
|
||||
This module requires the following module:
|
||||
|
||||
* Internationalization - https://www.drupal.org/project/i18n
|
||||
|
||||
|
||||
RECOMMENDED MODULES
|
||||
-------------------
|
||||
|
||||
* Internationalization Views - https://www.drupal.org/project/i18nviews
|
||||
* Language Icons - https://www.drupal.org/project/languageicons
|
||||
* Translation Overview - https://www.drupal.org/project/translation_overview
|
||||
* Localization Client - https://www.drupal.org/project/l10n_client
|
||||
* Internationalization contributions -
|
||||
https://www.drupal.org/project/i18n_contrib
|
||||
|
||||
|
||||
INSTALLATION
|
||||
------------
|
||||
|
||||
This is a submodule of the Internationalization module. Install the
|
||||
Internationalization module as you would normally install a contributed Drupal
|
||||
module. Visit https://www.drupal.org/node/895232 for further information.
|
||||
|
||||
|
||||
CONFIGURATION
|
||||
-------------
|
||||
|
||||
For each content type, the following Extended language options are available
|
||||
under the Multilingual Settings tab.
|
||||
1. "Set current language as default for new content" can be useful for content
|
||||
that is community-generated.
|
||||
2. "Require language" prevents users from creating 'Language neutral' nodes.
|
||||
3. "Lock language" prevents users from changing the language of a node after
|
||||
it's created.
|
||||
|
||||
Site-wide Settings for Node Translation
|
||||
1. There are also site-wide settings provided to help streamline how
|
||||
multilingual content is created. Navigate to Config > Regional and language >
|
||||
Multilingual settings > Node Options.
|
||||
2. "Switch interface for translating" switches the language of the user
|
||||
interface to the chosen language when a user translates a node. This is
|
||||
useful if users speak the language in which the translation is written. It
|
||||
means that after the node translation is saved, the language of the UI will
|
||||
match the language of the node.
|
||||
3. "Hide content translation links" will prevent the language switcher links
|
||||
from appearing in nodes and teasers. This is useful if a language switcher
|
||||
block is enabled on the site.
|
||||
4. The user can also select the default language for new nodes if the
|
||||
corresponding content type doesn't have language support. By default, it is
|
||||
set to be in the default language of the site, but this can be changed to be
|
||||
language neutral. This is a useful option when thinking about forward
|
||||
compatibility for adding multilingual support to these content types in the
|
||||
future.
|
||||
|
||||
|
||||
MAINTAINERS
|
||||
-----------
|
||||
|
||||
* Jose Reyero - https://www.drupal.org/u/jose-reyero
|
||||
* Florian Weber (webflo) - https://www.drupal.org/u/webflo
|
||||
* Peter Philipp - https://www.drupal.org/u/das-peter
|
||||
* Joseph Olstad - https://www.drupal.org/u/joseph.olstad
|
||||
* Nathaniel Catchpole - https://www.drupal.org/u/catch
|
@ -9,9 +9,8 @@ configure = admin/config/regional/i18n/node
|
||||
files[]=i18n_node.test
|
||||
files[]=i18n_node.variable.inc
|
||||
|
||||
; Information added by Drupal.org packaging script on 2015-05-07
|
||||
version = "7.x-1.13"
|
||||
; Information added by Drupal.org packaging script on 2018-08-17
|
||||
version = "7.x-1.26"
|
||||
core = "7.x"
|
||||
project = "i18n"
|
||||
datestamp = "1430999922"
|
||||
|
||||
datestamp = "1534531985"
|
||||
|
@ -222,8 +222,16 @@ function i18n_node_language_mode($type) {
|
||||
function i18n_node_node_prepare($node) {
|
||||
$options = variable_get('i18n_node_options_' . $node->type, array());
|
||||
if (i18n_node_type_enabled($node) && empty($node->nid) && !i18n_object_langcode($node) && in_array('current', $options)) {
|
||||
$default = variable_get('i18n_node_default_language_for_' . $node->type, '-- current --');
|
||||
|
||||
// Set current language for new nodes if option enabled
|
||||
$node->language = i18n_language_content()->language;
|
||||
if ($default === '-- current --') {
|
||||
$node->language = i18n_language_content()->language;
|
||||
}
|
||||
// If a custom language was specified, apply it.
|
||||
else {
|
||||
$node->language = $default;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -249,13 +257,16 @@ function i18n_node_permission() {
|
||||
/**
|
||||
* Implements hook_node_view()
|
||||
*/
|
||||
function i18n_node_node_view($node) {
|
||||
function i18n_node_node_view($node, $view_mode, $langcode) {
|
||||
if (i18n_node_type_enabled($node)) {
|
||||
$node->content['language'] = array(
|
||||
'#type' => 'item',
|
||||
'#title' => t('Language'),
|
||||
'#markup' => i18n_language_name($node->language),
|
||||
);
|
||||
$extra_fields_display_settings = field_extra_fields_get_display('node', $node->type, $view_mode);
|
||||
if ($extra_fields_display_settings['language']['visible']) {
|
||||
$node->content['language'] = array(
|
||||
'#type' => 'item',
|
||||
'#title' => t('Language'),
|
||||
'#markup' => i18n_language_name($node->language),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -265,7 +276,9 @@ function i18n_node_node_view($node) {
|
||||
* Handles links for extended languages. Sets current interface language.
|
||||
*/
|
||||
function i18n_node_node_view_alter(&$build) {
|
||||
$node = $build['#node'];
|
||||
if (isset($build['#node'])) {
|
||||
$node = $build['#node'];
|
||||
}
|
||||
// Hide node translation links.
|
||||
if (variable_get('i18n_hide_translation_links', 0)) {
|
||||
if (isset($build['links']['translation'])) {
|
||||
@ -417,7 +430,16 @@ function i18n_node_form_node_type_form_alter(&$form, &$form_state) {
|
||||
// Some settings about node languages. Add variables for node type from variable definition
|
||||
if ($form['#node_type']->type) {
|
||||
variable_type_include('node_type');
|
||||
$form['i18n'] += node_variable_type_subform($form['#node_type']->type, array('i18n_node_options', 'i18n_node_extended'));
|
||||
$form['i18n'] += node_variable_type_subform($form['#node_type']->type, array('i18n_node_options', 'i18n_node_default_language_for', 'i18n_node_extended'));
|
||||
// Only show custom default language field if "current" is checked.
|
||||
$form['i18n']['i18n_node_default_language_for']['#states'] = array(
|
||||
'visible' => array(
|
||||
':input[name="i18n_node_options[current]"]' => array('checked' => TRUE),
|
||||
),
|
||||
'required' => array(
|
||||
':input[name="i18n_node_options[current]"]' => array('checked' => TRUE),
|
||||
),
|
||||
);
|
||||
}
|
||||
// Add disabled message
|
||||
if ($disabled) {
|
||||
@ -506,8 +528,6 @@ function _i18n_node_form_node_form_alter($form, &$form_state) {
|
||||
}
|
||||
}
|
||||
elseif (variable_get('i18n_node_default_language_none', 0) && !isset($form['#node']->nid)) {
|
||||
// Override locale module setting default language to nodes. It is already in form_state.
|
||||
// $form['language']['#value'] = $form_state['values']['language'] = LANGUAGE_NONE;
|
||||
// Only do this if the language is really disabled
|
||||
if (variable_get('language_content_type_' . $node->type, 0) == 0) {
|
||||
// Override locale module setting default language to nodes. It is already in form_state.
|
||||
|
@ -45,13 +45,30 @@ function i18n_node_variable_info($options = array()) {
|
||||
'repeat' => array(
|
||||
'type' => 'options',
|
||||
'options' => array(
|
||||
'current' => t('Set current language as default for new content.', array(), $options),
|
||||
// Note: this was previously used only to mark new, translatable nodes
|
||||
// with the current language of the user. Now, this setting is extended
|
||||
// to allow a specific language to be chosen (defaulting to the current
|
||||
// language). This was done for backwards compatibility reasons.
|
||||
'current' => t('Set custom language as default for new content.', array(), $options),
|
||||
'required' => t('Require language (Do not allow Language Neutral).', array(), $options),
|
||||
'lock' => t('Lock language (Cannot be changed).', array(), $options),
|
||||
),
|
||||
),
|
||||
'group' => 'i18n',
|
||||
);
|
||||
// This field will only be displayed if "current" is checked above.
|
||||
$variables['i18n_node_default_language_for_[node_type]'] = array(
|
||||
'type' => 'multiple',
|
||||
'title' => t('Custom default language', array(), $options),
|
||||
'repeat' => array(
|
||||
'type' => 'select',
|
||||
'options' => array_merge(array(
|
||||
'-- current --' => t('Current language')
|
||||
), locale_language_list('name')),
|
||||
'default' => '-- current --',
|
||||
),
|
||||
'group' => 'i18n',
|
||||
);
|
||||
$variables['i18n_node_extended_[node_type]'] = array(
|
||||
'type' => 'multiple',
|
||||
'title' => t('Extended language support'),
|
||||
|
@ -6,9 +6,8 @@ core = 7.x
|
||||
|
||||
files[] = i18n_path.inc
|
||||
files[] = i18n_path.test
|
||||
; Information added by Drupal.org packaging script on 2015-05-07
|
||||
version = "7.x-1.13"
|
||||
; Information added by Drupal.org packaging script on 2018-08-17
|
||||
version = "7.x-1.26"
|
||||
core = "7.x"
|
||||
project = "i18n"
|
||||
datestamp = "1430999922"
|
||||
|
||||
datestamp = "1534531985"
|
||||
|
@ -0,0 +1,82 @@
|
||||
CONTENTS OF THIS FILE
|
||||
---------------------
|
||||
|
||||
* Introduction
|
||||
* Requirements
|
||||
* Recommended modules
|
||||
* Installation
|
||||
* Configuration
|
||||
* Maintainers
|
||||
|
||||
|
||||
INTRODUCTION
|
||||
------------
|
||||
|
||||
The Redirect translation module, part of the Internationalization
|
||||
(https://www.drupal.org/project/i18n) package, improves search engine
|
||||
optimization (SEO) for multilingual websites.
|
||||
|
||||
It redirects anonymous users (including web crawlers) to the translation of the
|
||||
page in the requested language, if it exists, using a 301 redirect code.
|
||||
|
||||
* For a full description of the module, visit this page:
|
||||
https://www.drupal.org/node/1280468.
|
||||
|
||||
* To submit bug reports and feature suggestions, or to track changes:
|
||||
https://www.drupal.org/project/issues/i18n.
|
||||
|
||||
|
||||
REQUIREMENTS
|
||||
------------
|
||||
|
||||
This module requires the following module:
|
||||
|
||||
* Internationalization - https://www.drupal.org/project/i18n
|
||||
|
||||
The Translation redirect module requires the implementation of
|
||||
hook_i18n_translate_path by another module for the redirect page to be
|
||||
determined. Currently, the Multilingual content, Path translation, and Taxonomy
|
||||
translation modules implement this hook.
|
||||
|
||||
|
||||
RECOMMENDED MODULES
|
||||
-------------------
|
||||
|
||||
* Internationalization Views - https://www.drupal.org/project/i18nviews
|
||||
* Language Icons - https://www.drupal.org/project/languageicons
|
||||
* Translation Overview - https://www.drupal.org/project/translation_overview
|
||||
* Localization Client - https://www.drupal.org/project/l10n_client
|
||||
* Internationalization contributions -
|
||||
https://www.drupal.org/project/i18n_contrib
|
||||
|
||||
|
||||
INSTALLATION
|
||||
------------
|
||||
|
||||
This is a submodule of the Internationalization module. Install the
|
||||
Internationalization module as you would normally install a contributed Drupal
|
||||
module. Visit https://www.drupal.org/node/895232 for further information.
|
||||
|
||||
|
||||
CONFIGURATION
|
||||
-------------
|
||||
|
||||
No configuration is necessary.
|
||||
|
||||
For node translation, enable the Multilingual content and the Translation
|
||||
redirect modules. For non-node pages, the redirection hook must be implemented
|
||||
by the relevant module.
|
||||
For example, for taxonomy pages, you should enable the Taxonomy translation
|
||||
module because the module provides the necessary hook code. If you are using the
|
||||
Path translation module to create translation sets for non-node pages, then it
|
||||
implements the hook code for determining the redirection page.
|
||||
|
||||
|
||||
MAINTAINERS
|
||||
-----------
|
||||
|
||||
* Jose Reyero - https://www.drupal.org/u/jose-reyero
|
||||
* Florian Weber (webflo) - https://www.drupal.org/u/webflo
|
||||
* Peter Philipp - https://www.drupal.org/u/das-peter
|
||||
* Joseph Olstad - https://www.drupal.org/u/joseph.olstad
|
||||
* Nathaniel Catchpole - https://www.drupal.org/u/catch
|
@ -4,9 +4,8 @@ dependencies[] = i18n
|
||||
package = Multilingual - Internationalization
|
||||
core = 7.x
|
||||
|
||||
; Information added by Drupal.org packaging script on 2015-05-07
|
||||
version = "7.x-1.13"
|
||||
; Information added by Drupal.org packaging script on 2018-08-17
|
||||
version = "7.x-1.26"
|
||||
core = "7.x"
|
||||
project = "i18n"
|
||||
datestamp = "1430999922"
|
||||
|
||||
datestamp = "1534531985"
|
||||
|
@ -0,0 +1,82 @@
|
||||
CONTENTS OF THIS FILE
|
||||
---------------------
|
||||
|
||||
* Introduction
|
||||
* Requirements
|
||||
* Recommended modules
|
||||
* Installation
|
||||
* Configuration
|
||||
* Maintainers
|
||||
|
||||
|
||||
INTRODUCTION
|
||||
------------
|
||||
|
||||
The Multilingual select module, part of the Internationalization
|
||||
(https://www.drupal.org/project/i18n) package, allows the user to define whether
|
||||
content is filtered by language on pages provided by Drupal core.
|
||||
|
||||
* For a full description of the module visit:
|
||||
https://www.drupal.org/node/1279512.
|
||||
|
||||
* To submit bug reports and feature suggestions, or to track changes visit
|
||||
https://www.drupal.org/project/issues/i18n.
|
||||
|
||||
|
||||
REQUIREMENTS
|
||||
------------
|
||||
|
||||
This module requires the following module:
|
||||
|
||||
* Internationalization - https://www.drupal.org/project/i18n
|
||||
* Variable - https://www.drupal.org/project/variable
|
||||
|
||||
|
||||
RECOMMENDED MODULES
|
||||
-------------------
|
||||
|
||||
* Internationalization Views - https://www.drupal.org/project/i18nviews
|
||||
* Language Icons - https://www.drupal.org/project/languageicons
|
||||
* Translation Overview - https://www.drupal.org/project/translation_overview
|
||||
* Localization Client - https://www.drupal.org/project/l10n_client
|
||||
* Internationalization contributions -
|
||||
https://www.drupal.org/project/i18n_contrib
|
||||
|
||||
|
||||
INSTALLATION
|
||||
------------
|
||||
|
||||
This is a submodule of the Internationalization module. Install the
|
||||
Internationalization module as you would normally install a contributed Drupal
|
||||
module. Visit https://www.drupal.org/node/895232 for further information.
|
||||
|
||||
|
||||
CONFIGURATION
|
||||
-------------
|
||||
|
||||
The module allows the user to configure whether or not to filter pages by the
|
||||
current language. If the Taxonomy translation submodule is also enabled, an
|
||||
option will be available for how taxonomy term pages are filtered. It also
|
||||
allows the exclusion of the module’s language selection handling for some
|
||||
elements and certain paths.
|
||||
|
||||
1. Enable the Multilingual select module included with Internationalization.
|
||||
2. Navigate to Configuration > Regional and language > Multilingual settings >
|
||||
Selection.
|
||||
3. Select nodes and taxonomy can be filtered by language in the Content to
|
||||
Filter by Language field set.
|
||||
4. The "Content Selection Mode" allows content with specific tags to be skipped
|
||||
by entering a list of tags.
|
||||
5. The "Enable for Specific Pages" field set allows specific pages to be
|
||||
included by path.
|
||||
6. After making choices, Save configuration.
|
||||
|
||||
|
||||
MAINTAINERS
|
||||
-----------
|
||||
|
||||
* Jose Reyero - https://www.drupal.org/u/jose-reyero
|
||||
* Florian Weber (webflo) - https://www.drupal.org/u/webflo
|
||||
* Peter Philipp - https://www.drupal.org/u/das-peter
|
||||
* Joseph Olstad - https://www.drupal.org/u/joseph.olstad
|
||||
* Nathaniel Catchpole - https://www.drupal.org/u/catch
|
@ -6,9 +6,8 @@ core = 7.x
|
||||
configure = admin/config/regional/i18n/select
|
||||
files[] = i18n_select.test
|
||||
|
||||
; Information added by Drupal.org packaging script on 2015-05-07
|
||||
version = "7.x-1.13"
|
||||
; Information added by Drupal.org packaging script on 2018-08-17
|
||||
version = "7.x-1.26"
|
||||
core = "7.x"
|
||||
project = "i18n"
|
||||
datestamp = "1430999922"
|
||||
|
||||
datestamp = "1534531985"
|
||||
|
@ -82,11 +82,11 @@ function i18n_select_mode($type = NULL) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check current path to enable selection
|
||||
* Check current path to enable selection.
|
||||
*
|
||||
* This works pretty much like block visibility
|
||||
* This works pretty much like block visibility.
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
* TRUE if content selection should be enabled for this page.
|
||||
*/
|
||||
function i18n_select_page() {
|
||||
@ -100,8 +100,11 @@ function i18n_select_page() {
|
||||
// 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']));
|
||||
// @see views_ajax()
|
||||
// @see I18NSelectAdminViewsAjax::testViewsAjaxWithoutSkippingTags()
|
||||
$path = isset($_REQUEST['view_path']) ? $_REQUEST['view_path'] : $_GET['q'];
|
||||
// Convert the Drupal path to lowercase.
|
||||
$path = drupal_strtolower(drupal_get_path_alias($path));
|
||||
// Compare the lowercase internal and lowercase path alias (if any).
|
||||
$page_match = drupal_match_path($path, $pages);
|
||||
if ($path != $_GET['q']) {
|
||||
@ -109,8 +112,8 @@ function i18n_select_page() {
|
||||
}
|
||||
// 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.
|
||||
// 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')) {
|
||||
@ -121,7 +124,7 @@ function i18n_select_page() {
|
||||
}
|
||||
}
|
||||
else {
|
||||
// No pages defined, still respect the setting (unlike blocks)
|
||||
// No pages defined, still respect the setting (unlike blocks).
|
||||
$mode = $visibility == I18N_SELECT_PAGE_NOTLISTED;
|
||||
}
|
||||
}
|
||||
|
@ -84,3 +84,87 @@ class i18nSelectTestCase extends Drupali18nTestCase {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test case for AJAX queries on "views/ajax" when view on admin page.
|
||||
*/
|
||||
class I18NSelectAdminViewsAjax extends Drupali18nTestCase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => t('I18N select Admin Views (AJAX)'),
|
||||
'group' => 'Internationalization',
|
||||
'description' => t('Test AJAX requests to the "views/ajax" when view located on "admin/*" and list of skipping tags is empty.'),
|
||||
// Skip this test when "admin_views" module does not exists.
|
||||
'dependencies' => array('admin_views'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp('translation', 'i18n_variable', 'i18n_select', 'admin_views');
|
||||
parent::setUpLanguages(array('access content overview'));
|
||||
parent::setUpContentTranslation();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test AJAX of a view without skipping tags for selection.
|
||||
*
|
||||
* @see i18n_select_page()
|
||||
*/
|
||||
public function testViewsAjaxWithoutSkippingTags() {
|
||||
// If this variable will have the "views" value then this test will not
|
||||
// have sense. For instance, we want apply language selection filter
|
||||
// for views and remove "views" from "i18n_select_skip_tags" variable.
|
||||
// In this case all AJAX for views, on administration part of the site,
|
||||
// will be broken because the "i18n_select_page()" function will work
|
||||
// with "views/ajax" path instead of, for example, "admin/content".
|
||||
variable_set('i18n_select_skip_tags', '');
|
||||
|
||||
// Create one hundred of nodes.
|
||||
for ($i = 1; $i <= 100; $i++) {
|
||||
// Create every second node on Spanish language and
|
||||
// every first - on English.
|
||||
$node = $this->createNode('page', "Node $i", '', $i % 2 ? $this->default_language : $this->secondary_language);
|
||||
|
||||
// Update "changed" in order to sort the content by updating date. In
|
||||
// other case all nodes will be with the same date and not arranged in
|
||||
// order.
|
||||
db_update('node')
|
||||
->fields(array('changed' => strtotime("+ $i minute")))
|
||||
->condition('nid', $node->nid)
|
||||
->execute();
|
||||
}
|
||||
|
||||
$this->drupalGet('admin/content');
|
||||
|
||||
// Check that latest node exists at the top.
|
||||
$this->assertText('Node 100');
|
||||
// Check that our page contains fifty nodes (the latest must be 51).
|
||||
$this->assertNoText('Node 50');
|
||||
|
||||
// Test $_REQUEST['view_path']. There's no form to submit to, so
|
||||
// drupalPost() won't work here. This just tests a direct $_POST
|
||||
// request instead.
|
||||
$this->curlExec(array(
|
||||
CURLOPT_URL => $this->getAbsoluteUrl('views/ajax'),
|
||||
CURLOPT_POST => TRUE,
|
||||
CURLOPT_POSTFIELDS => http_build_query(array(
|
||||
'page' => 1,
|
||||
'view_path' => 'admin/content',
|
||||
'view_name' => 'admin_views_node',
|
||||
'view_display_id' => 'system_1',
|
||||
)),
|
||||
));
|
||||
|
||||
// Check that we are successfully switched to a new page of content.
|
||||
$this->assertText('Node 50');
|
||||
$this->assertNoText('Node 100');
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,94 @@
|
||||
CONTENTS OF THIS FILE
|
||||
---------------------
|
||||
|
||||
* Introduction
|
||||
* Requirements
|
||||
* Recommended modules
|
||||
* Installation
|
||||
* Configuration
|
||||
* Maintainers
|
||||
|
||||
|
||||
INTRODUCTION
|
||||
------------
|
||||
|
||||
The String translation module, part of the Internationalization
|
||||
(https://www.drupal.org/project/i18n) package, provides support for other
|
||||
modules to translate user-defined strings. This is an API module that must be
|
||||
enabled only when required by other modules in the i18n package.
|
||||
|
||||
|
||||
* For a full description of the module, visit this page:
|
||||
https://www.drupal.org/node/1279668
|
||||
|
||||
* To submit bug reports and feature suggestions, or to track changes:
|
||||
https://www.drupal.org/project/issues/i18n
|
||||
|
||||
|
||||
REQUIREMENTS
|
||||
------------
|
||||
|
||||
This module requires the following module:
|
||||
|
||||
* Internationalization - https://www.drupal.org/project/i18n
|
||||
|
||||
|
||||
RECOMMENDED MODULES
|
||||
-------------------
|
||||
|
||||
* Internationalization Views - https://www.drupal.org/project/i18nviews
|
||||
* Language Icons - https://www.drupal.org/project/languageicons
|
||||
* Translation Overview - https://www.drupal.org/project/translation_overview
|
||||
* Localization Client - https://www.drupal.org/project/l10n_client
|
||||
* Internationalization contributions -
|
||||
https://www.drupal.org/project/i18n_contrib
|
||||
|
||||
|
||||
INSTALLATION
|
||||
------------
|
||||
|
||||
This is a submodule of the Internationalization module. Install the
|
||||
Internationalization module as you would normally install a contributed Drupal
|
||||
module. Visit https://www.drupal.org/node/895232 for further information.
|
||||
|
||||
|
||||
CONFIGURATION
|
||||
-------------
|
||||
|
||||
Strings will be translated from the source languages. By default the source
|
||||
language is the site's default language, so changing the default language could
|
||||
break these translations.
|
||||
|
||||
1. The user can set which language is used as the source language via
|
||||
Administration > Configuration > Regional and language > Multilingual
|
||||
settings > Strings. By default, only plain strings are enabled, so regular
|
||||
blocks are not fully translatable.
|
||||
2. To allow Filtered HTML, Full HTML or Plain text select the appropriate radio
|
||||
box(es) and Save configuration.
|
||||
3. To select the strings to be translated navigate to Administration >
|
||||
Configuration > Regional and language > Translate interface and select on
|
||||
Stings vertical tab. From here the user can select which text groups to
|
||||
translate and select the Refresh strings tab.
|
||||
|
||||
|
||||
FAQ
|
||||
---
|
||||
|
||||
The String translation module allows you to configure which text formats are
|
||||
translatable. Formats like PHP Filter and Full HTML are translated before they
|
||||
are processed, so allowing a translator to edit these can be a security risk.
|
||||
This is particularly problematic when importing translations in bulk from a CSV
|
||||
file, since the translator's access to the import formats isn't verified by
|
||||
Drupal. After updating this setting, be sure to refresh the strings via
|
||||
Administration > Configuration > Regional and language > Translate interface >
|
||||
Strings so that strings in forbidden formats are deleted.
|
||||
|
||||
|
||||
MAINTAINERS
|
||||
-----------
|
||||
|
||||
* Jose Reyero - https://www.drupal.org/u/jose-reyero
|
||||
* Florian Weber (webflo) - https://www.drupal.org/u/webflo
|
||||
* Peter Philipp - https://www.drupal.org/u/das-peter
|
||||
* Joseph Olstad - https://www.drupal.org/u/joseph.olstad
|
||||
* Nathaniel Catchpole - https://www.drupal.org/u/catch
|
@ -703,9 +703,19 @@ class i18n_string_textgroup_default {
|
||||
// Create source string so we get an lid
|
||||
$this->save_source($string);
|
||||
}
|
||||
|
||||
// Convert objectid to objectkey if it's numeric.
|
||||
if (!isset($string->objectkey)) {
|
||||
$string->objectkey = (int)$string->objectid;
|
||||
if (is_numeric($string->objectid)) {
|
||||
$string->objectkey = (int)$string->objectid;
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure objectkey is numeric.
|
||||
if (!is_numeric($string->objectkey)) {
|
||||
$string->objectkey = 0;
|
||||
}
|
||||
|
||||
if (!isset($string->format)) {
|
||||
$string->format = '';
|
||||
}
|
||||
@ -1166,10 +1176,17 @@ class i18n_string_object_wrapper extends i18n_object_wrapper {
|
||||
$info = is_array($info) ? $info : array('title' => $info);
|
||||
$field_name = isset($info['field']) ? $info['field'] : $field;
|
||||
$value = $this->get_field($field_name);
|
||||
if (is_array($value) && isset($value['value'])) {
|
||||
$format = isset($value['format']) ? $value['format'] : NULL;
|
||||
$value = $value['value'];
|
||||
}
|
||||
else {
|
||||
$format = isset($info['format']) ? $this->get_field($info['format']) : NULL;
|
||||
}
|
||||
$strings[$this->get_textgroup()][$string_type][$object_id][$field] = array(
|
||||
'string' => is_array($value) || isset($info['empty']) && $value === $info['empty'] ? NULL : $value,
|
||||
'title' => $info['title'],
|
||||
'format' => isset($info['format']) ? $this->get_field($info['format']) : NULL,
|
||||
'format' => $format,
|
||||
'name' => array_merge($object_keys, array($field)),
|
||||
);
|
||||
}
|
||||
@ -1481,7 +1498,12 @@ class i18n_string_textgroup_cached extends i18n_string_textgroup_default {
|
||||
foreach ($context as $key => $value) {
|
||||
if ($value != '*') {
|
||||
$try = array_merge($context, array($key => '*'));
|
||||
return $this->multiple_cache_get($try);
|
||||
$cached_results = $this->multiple_cache_get($try);
|
||||
// Now filter the ones that actually match.
|
||||
if (!empty($cached_results)) {
|
||||
$cached_results = $this->string_filter($cached_results, $context);
|
||||
}
|
||||
return $cached_results;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,9 +10,8 @@ files[] = i18n_string.inc
|
||||
files[] = i18n_string.test
|
||||
configure = admin/config/regional/i18n/strings
|
||||
|
||||
; Information added by Drupal.org packaging script on 2015-05-07
|
||||
version = "7.x-1.13"
|
||||
; Information added by Drupal.org packaging script on 2018-08-17
|
||||
version = "7.x-1.26"
|
||||
core = "7.x"
|
||||
project = "i18n"
|
||||
datestamp = "1430999922"
|
||||
|
||||
datestamp = "1534531985"
|
||||
|
@ -94,6 +94,7 @@ function i18n_string_schema() {
|
||||
),
|
||||
'objectindex' => array(
|
||||
'type' => 'int',
|
||||
'size' => 'big',
|
||||
'not null' => TRUE,
|
||||
'default' => 0,
|
||||
'description' => 'Integer value of Object ID.',
|
||||
@ -245,6 +246,24 @@ function i18n_string_update_7002() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removed due to buggy upgrade for #2200647.
|
||||
*/
|
||||
function i18n_string_update_7003() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Change objectindex from int to bigint.
|
||||
*/
|
||||
function i18n_string_update_7004() {
|
||||
db_change_field('i18n_string', 'objectindex', 'objectindex', array(
|
||||
'type' => 'int',
|
||||
'size' => 'big',
|
||||
'not null' => TRUE,
|
||||
'default' => 0,
|
||||
'description' => 'Integer value of Object ID.',
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes for update script
|
||||
|
@ -118,13 +118,14 @@ function i18n_string_menu() {
|
||||
'file' => 'i18n_string.admin.inc',
|
||||
'access arguments' => array('translate interface'),
|
||||
);
|
||||
|
||||
$items['admin/config/regional/i18n/strings'] = array(
|
||||
'title' => 'Strings',
|
||||
'description' => 'Options for user defined strings.',
|
||||
'weight' => 20,
|
||||
'type' => MENU_LOCAL_TASK,
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('variable_edit_form', array('i18n_string_allowed_formats', 'i18n_string_source_language')),
|
||||
'page arguments' => array('variable_edit_form', array('i18n_string_allowed_formats', 'i18n_string_source_language', 'i18n_string_textgroup_class_[textgroup]')),
|
||||
'access arguments' => array('administer site configuration'),
|
||||
);
|
||||
// AJAX callback path for strings.
|
||||
@ -258,6 +259,34 @@ function i18n_string_locale_translate_import_form_submit($form, &$form_state) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_element_info_alter().
|
||||
*
|
||||
* We need to do this on the element info level as wysiwyg also does so and form
|
||||
* API (incorrectly) does not merge in the defaults for values that are arrays.
|
||||
*/
|
||||
function i18n_string_element_info_alter(&$types) {
|
||||
$types['text_format']['#pre_render'][] = 'i18n_string_pre_render_text_format';
|
||||
}
|
||||
|
||||
/**
|
||||
* The '#pre_render' function to alter the text format element in a translation.
|
||||
* The text format for a translation is taken form the original, so the text
|
||||
* format drop down should be disabled.
|
||||
*
|
||||
* @param array $element
|
||||
* The text_format element which will be rendered.
|
||||
*
|
||||
* @return array
|
||||
* The altered text_format element with a disabled "Text format" select.
|
||||
*/
|
||||
function i18n_string_pre_render_text_format($element) {
|
||||
if (!empty($element['#i18n_string_is_translation'])) {
|
||||
$element['format']['format']['#attributes']['disabled'] = TRUE;
|
||||
}
|
||||
return $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if translation is required for this language code.
|
||||
*
|
||||
@ -334,7 +363,10 @@ function i18n_string_update_context($oldname, $newname) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get textgroup handler
|
||||
* Get textgroup handler.
|
||||
*
|
||||
* @return i18n_string_textgroup_default
|
||||
*
|
||||
*/
|
||||
function i18n_string_textgroup($textgroup) {
|
||||
$groups = &drupal_static(__FUNCTION__);
|
||||
@ -488,6 +520,19 @@ function i18n_string_group_info($group = NULL, $property = NULL, $default = NULL
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_i18n_string_info_alter().
|
||||
*
|
||||
* Set determined classes to use for the text group.
|
||||
*/
|
||||
function i18n_string_i18n_string_info_alter(&$info) {
|
||||
foreach (array_keys($info) as $name) {
|
||||
// If class is not defined. Classes from other modules, fixed classes and etc.
|
||||
if (!isset($info[$name]['class'])) {
|
||||
$info[$name]['class'] = variable_get('i18n_string_textgroup_class_' . $name, 'i18n_string_textgroup_default');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate / update multiple strings
|
||||
@ -519,11 +564,12 @@ function i18n_string_multiple($operation, $name, $strings, $options = array()) {
|
||||
*
|
||||
* This function is intended to return translations for plain strings that have NO text format
|
||||
*
|
||||
* @param $name
|
||||
* @param array|string name
|
||||
* Array or string concatenated with ':' that contains textgroup and string context
|
||||
* @param $string
|
||||
* String in default language or array of strings to be translated
|
||||
* @param $options
|
||||
* @param array|string $string
|
||||
* A string in the default language, a string wth format (array with keys
|
||||
* value and format),or an array of strings (without format) to be translated.
|
||||
* @param array $options
|
||||
* An associative array of additional options, with the following keys:
|
||||
* - 'langcode' (defaults to the current language) The language code to translate to a language other than what is used to display the page.
|
||||
* - 'filter' Filtering callback to apply to the translated string only
|
||||
@ -531,8 +577,13 @@ function i18n_string_multiple($operation, $name, $strings, $options = array()) {
|
||||
* - 'callback' Callback to apply to the result (both to translated or untranslated string
|
||||
* - 'sanitize' Whether to filter the translation applying the text format if any, default is TRUE
|
||||
* - 'sanitize default' Whether to filter the default value if no translation found, default is FALSE
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function i18n_string_translate($name, $string, $options = array()) {
|
||||
if (is_array($string) && isset($string['value'])) {
|
||||
$string = $string['value'];
|
||||
}
|
||||
if (is_array($string)) {
|
||||
return i18n_string_translate_list($name, $string, $options);
|
||||
}
|
||||
@ -583,10 +634,17 @@ function i18n_string_translate_access($string_format, $account = NULL) {
|
||||
* Message if the user cannot translate that string.
|
||||
*/
|
||||
function i18n_string_translate_check_string($i18nstring, $account = NULL) {
|
||||
if (!user_access('translate interface', $account) || !user_access('translate user-defined strings', $account)) {
|
||||
// Check block translation permissions.
|
||||
if ($i18nstring->textgroup == 'blocks') {
|
||||
if (!user_access('translate interface', $account) && !user_access('translate blocks', $account)) {
|
||||
return t('This is a user-defined string within a block. You are not allowed to translate blocks.');
|
||||
}
|
||||
}
|
||||
elseif (!user_access('translate interface', $account) || !user_access('translate user-defined strings', $account)) {
|
||||
return t('This is a user-defined string. You are not allowed to translate these strings.');
|
||||
}
|
||||
elseif (!empty($i18nstring->format)) {
|
||||
|
||||
if (!empty($i18nstring->format)) {
|
||||
if (!i18n_string_allowed_format($i18nstring->format)) {
|
||||
$format = filter_format_load($i18nstring->format);
|
||||
return t('This string uses the %name text format. Strings with this format are not allowed for translation.', array('%name' => $format->name));
|
||||
|
@ -170,14 +170,16 @@ function i18n_string_translate_page_form_base($form, $langcode, $redirect = NULL
|
||||
|
||||
/**
|
||||
* Create field elements for strings
|
||||
*
|
||||
* @param i18n_string_object[] $strings
|
||||
* @param string $langcode
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function i18n_string_translate_page_form_strings($strings, $langcode) {
|
||||
$formats = filter_formats();
|
||||
global $user;
|
||||
$form = array();
|
||||
foreach ($strings as $item) {
|
||||
// We may have a source or not. Load it, our string may get the format from it.
|
||||
$source = $item->get_source();
|
||||
$format_id = $source ? $source->format : $item->format;
|
||||
$description = '';
|
||||
// Check permissions to translate this string, depends on format, etc..
|
||||
if ($message = $item->check_translate_access()) {
|
||||
// We'll display a disabled element with the reason it cannot be translated.
|
||||
@ -188,27 +190,31 @@ function i18n_string_translate_page_form_strings($strings, $langcode) {
|
||||
$disabled = FALSE;
|
||||
$description = '';
|
||||
// If we don't have a source and it can be translated, we create it.
|
||||
if (!$source) {
|
||||
if (!$item->get_source()) {
|
||||
// Enable messages just as a reminder these strings are not being updated properly.
|
||||
$status = $item->update(array('messages' => TRUE));
|
||||
if ($status === FALSE || $status === SAVED_DELETED) {
|
||||
// We don't have a source string so nothing to translate here
|
||||
$disabled = TRUE;
|
||||
}
|
||||
else {
|
||||
$source = $item->get_source();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$default_value = $item->format_translation($langcode, array('langcode' => $langcode, 'sanitize' => FALSE, 'debug' => FALSE));
|
||||
$available_formats = array_keys(filter_formats($user));
|
||||
if (!in_array($item->format, $available_formats)) {
|
||||
$item->format = NULL;
|
||||
}
|
||||
$form[$item->get_name()] = array(
|
||||
'#title' => $item->get_title(),
|
||||
'#type' => 'textarea',
|
||||
'#type' => $item->format ? 'text_format' : 'textarea',
|
||||
'#default_value' => $default_value,
|
||||
'#format' => $item->format,
|
||||
// This will trigger i18n_string_pre_render_text_format() to actually
|
||||
// alter the element.
|
||||
'#i18n_string_is_translation' => TRUE,
|
||||
'#disabled' => $disabled,
|
||||
'#description' => $description . _i18n_string_translate_format_help($format_id),
|
||||
//'#i18n_string_format' => $source ? $source->format : 0,
|
||||
'#description' => $description,
|
||||
// If disabled, provide smaller textarea (that can be expanded anyway).
|
||||
'#rows' => $disabled ? 1 : min(ceil(str_word_count($default_value) / 12), 10),
|
||||
// Change the parent for disabled strings so we don't get empty values later
|
||||
@ -226,6 +232,16 @@ function i18n_string_translate_page_form_submit($form, &$form_state) {
|
||||
foreach ($form_state['values']['strings'] as $name => $value) {
|
||||
$count++;
|
||||
list($textgroup, $context) = i18n_string_context(explode(':', $name));
|
||||
if (is_array($value)) {
|
||||
if (isset($value['value'])) {
|
||||
$value = $value['value'];
|
||||
$form_state['values']['strings'][$name] = $value;
|
||||
}
|
||||
else {
|
||||
form_set_error("strings][$name", t('Unable to get the translated string value.'));
|
||||
watchdog('locale', 'Unable to get the translated string value, string array is: %string', array('%string' => var_dump($value)), WATCHDOG_WARNING);
|
||||
}
|
||||
}
|
||||
$result = i18n_string_textgroup($textgroup)->update_translation($context, $form_state['values']['langcode'], $value);
|
||||
$success += ($result ? 1 : 0);
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ class i18nStringTestCase extends Drupali18nTestCase {
|
||||
$this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
|
||||
$this->clickLink(t('edit'));
|
||||
// Just add a random translation.
|
||||
$translation = $this->randomString();
|
||||
$translation = $this->randomName();
|
||||
$edit = array();
|
||||
foreach ($this->getOtherLanguages() as $language) {
|
||||
$langcode = $language->language;
|
||||
|
@ -34,9 +34,32 @@ function i18n_string_variable_info($options = array()) {
|
||||
'default' => 0,
|
||||
'group' => 'debug',
|
||||
);
|
||||
$variables['i18n_string_textgroup_class_[textgroup]'] = array(
|
||||
'title' => t('Class to use for the text group'),
|
||||
'description' => t('Determines which the class will be use for string translation in the text group.', array(), $options),
|
||||
'repeat' => array(
|
||||
'type' => 'select',
|
||||
'default' => 'i18n_string_textgroup_default',
|
||||
'options callback' => 'i18n_string_variable_textgroup_class_list',
|
||||
),
|
||||
'submit callback' => 'i18n_string_variable_textgroup_class_submit_callback',
|
||||
'group' => 'i18n',
|
||||
);
|
||||
return $variables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_variable_type_info().
|
||||
*/
|
||||
function i18n_string_variable_type_info() {
|
||||
$type['textgroup'] = array(
|
||||
'title' => t('Text group'),
|
||||
'type' => 'select',
|
||||
'options callback' => 'i18n_string_variable_textgroup_list',
|
||||
);
|
||||
return $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Options callback, format list
|
||||
*/
|
||||
@ -54,4 +77,33 @@ function i18n_string_variable_format_list() {
|
||||
*/
|
||||
function i18n_string_variable_format_default() {
|
||||
return array(filter_fallback_format());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Options callback, text groups list.
|
||||
*/
|
||||
function i18n_string_variable_textgroup_list() {
|
||||
$groups = array();
|
||||
foreach (i18n_string_group_info() as $name => $info) {
|
||||
$groups[$name] = $info['title'];
|
||||
}
|
||||
return $groups;
|
||||
}
|
||||
|
||||
/**
|
||||
* Options callback, text group classes list.
|
||||
*/
|
||||
function i18n_string_variable_textgroup_class_list($variable, $options = array()) {
|
||||
return array(
|
||||
'i18n_string_textgroup_default' => t('Text group handler default.', array(), $options),
|
||||
'i18n_string_textgroup_cached' => t('Text group handler which include persistent caching.', array(), $options),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit callback. Execute Reset the persistent caches after save the text group class variables.
|
||||
*/
|
||||
function i18n_string_variable_textgroup_class_submit_callback($variable, $options, $form, $form_state) {
|
||||
// Reset the persistent caches.
|
||||
cache_clear_all('i18n:string:' , 'cache', TRUE);
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ README.txt
|
||||
==========
|
||||
Drupal module: i18n_sync (Synchronization)
|
||||
|
||||
This module will handle content synchronization accross translations.
|
||||
This module will handle content synchronization across translations.
|
||||
|
||||
The available list of fields to synchronize will include standard node fields and cck fields.
|
||||
To have aditional fields, add the list in a variable in the settings.php file, like this:
|
||||
|
@ -1,5 +1,5 @@
|
||||
name = Synchronize translations
|
||||
description = Synchronizes taxonomy and fields accross translations of the same content.
|
||||
description = Synchronizes taxonomy and fields across translations of the same content.
|
||||
dependencies[] = i18n
|
||||
dependencies[] = translation
|
||||
package = Multilingual - Internationalization
|
||||
@ -10,9 +10,8 @@ files[] = i18n_sync.install
|
||||
files[] = i18n_sync.module.inc
|
||||
files[] = i18n_sync.node.inc
|
||||
files[] = i18n_sync.test
|
||||
; Information added by Drupal.org packaging script on 2015-05-07
|
||||
version = "7.x-1.13"
|
||||
; Information added by Drupal.org packaging script on 2018-08-17
|
||||
version = "7.x-1.26"
|
||||
core = "7.x"
|
||||
project = "i18n"
|
||||
datestamp = "1430999922"
|
||||
|
||||
datestamp = "1534531985"
|
||||
|
@ -33,7 +33,7 @@ function i18n_sync($status = NULL) {
|
||||
function i18n_sync_help($path, $arg) {
|
||||
switch ($path) {
|
||||
case 'admin/help#i18n_sync' :
|
||||
$output = '<p>' . t('This module synchronizes content taxonomy and fields accross translations:') . '</p>';
|
||||
$output = '<p>' . t('This module synchronizes content taxonomy and fields across translations:') . '</p>';
|
||||
$output .= '<p>' . t('First you need to select which fields should be synchronized. Then, after a node has been updated, all enabled vocabularies and fields will be synchronized as follows:') . '</p>';
|
||||
$output .= '<ul>';
|
||||
$output .= '<li>' . t('All the node fields selected for synchronization will be set to the same value for all translations.') . '</li>';
|
||||
@ -91,6 +91,7 @@ function i18n_sync_form_node_type_form_alter(&$form, &$form_state) {
|
||||
|
||||
$form['i18n_sync']['i18n_sync_node_type'] = array(
|
||||
'#tree' => TRUE,
|
||||
'#weight' => 1,
|
||||
);
|
||||
|
||||
// Each set provides title and options. We build a big checkboxes control for it to be
|
||||
@ -121,6 +122,21 @@ function i18n_sync_form_node_type_form_alter(&$form, &$form_state) {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Add option to restrict syncing only when editing the translation source.
|
||||
$form['i18n_sync']['i18n_sync_source_description'] = array(
|
||||
'#prefix' => '<div>', '#suffix' => '</div>',
|
||||
'#markup' => t('Restrict synchronization to the translation source.'),
|
||||
'#weight' => 2,
|
||||
);
|
||||
$form['i18n_sync']['i18n_sync_source'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Synchronize translations only when saving the translation source'),
|
||||
'#default_value' => variable_get('i18n_sync_source_' . $type, FALSE),
|
||||
'#disabled' => $disabled,
|
||||
'#weight' => 3,
|
||||
'#description' => t('If not checked each node will trigger the synchronization, whether it\'s the source or not.'),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -167,9 +183,17 @@ function i18n_sync_node_insert($node) {
|
||||
*/
|
||||
function i18n_sync_node_update($node) {
|
||||
// Let's go with field synchronization.
|
||||
if (i18n_sync_node_check($node) && !empty($node->tnid) && ($fields = i18n_sync_node_fields($node->type)) && ($translations = i18n_sync_node_get_translations($node, TRUE))) {
|
||||
module_load_include('node.inc', 'i18n_sync');
|
||||
i18n_sync_node_translation($node, $translations, $fields, 'update');
|
||||
if (i18n_sync_node_check($node) && !empty($node->tnid) && (!variable_get('i18n_sync_source_' . $node->type, TRUE) || $node->tnid == $node->nid) && ($fields = i18n_sync_node_fields($node->type)) && ($translations = i18n_sync_node_get_translations($node, TRUE))) {
|
||||
$do_sync = TRUE;
|
||||
if (module_exists('entity_translation')) {
|
||||
if (entity_translation_enabled_bundle('node', $node->type)) {
|
||||
$do_sync = FALSE;
|
||||
}
|
||||
}
|
||||
if ($do_sync) {
|
||||
module_load_include('node.inc', 'i18n_sync');
|
||||
i18n_sync_node_translation($node, $translations, $fields, 'update');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -98,7 +98,7 @@ function i18n_sync_node_translation_nodereference_field(&$node, &$translation, $
|
||||
* Example:
|
||||
* English A references English B and English C.
|
||||
* English A and B are translated to German A and B, but English C is not.
|
||||
* The syncronization from English A to German A would it German B and English C.
|
||||
* The synchronization from English A to German A would it German B and English C.
|
||||
*/
|
||||
function i18n_sync_node_translation_reference_field(&$reference_node, $default_value, $langcode) {
|
||||
if (isset($reference_node->tnid) && translation_supported_type($reference_node->type)) {
|
||||
|
@ -0,0 +1,103 @@
|
||||
CONTENTS OF THIS FILE
|
||||
---------------------
|
||||
|
||||
* Introduction
|
||||
* Requirements
|
||||
* Recommended modules
|
||||
* Installation
|
||||
* Configuration
|
||||
* Maintainers
|
||||
|
||||
|
||||
INTRODUCTION
|
||||
------------
|
||||
|
||||
The Taxonomy translation module, part of the Internationalization
|
||||
(https://www.drupal.org/project/i18n) package, provides multiple options to
|
||||
translate taxonomy vocabularies and terms. For each vocabulary, there are four
|
||||
types of behaviors to choose from: Language-independent terms, Language-specific
|
||||
terms, Localized terms, and Mixed-language vocabulary.
|
||||
|
||||
* For a full description of the module visit:
|
||||
https://www.drupal.org/node/1114016
|
||||
|
||||
* To submit bug reports and feature suggestions, or to track changes visit:
|
||||
https://www.drupal.org/project/issues/i18n
|
||||
|
||||
|
||||
REQUIREMENTS
|
||||
------------
|
||||
|
||||
This module requires the following module:
|
||||
|
||||
* Internationalization - https://www.drupal.org/project/i18n
|
||||
|
||||
|
||||
RECOMMENDED MODULES
|
||||
-------------------
|
||||
|
||||
* Internationalization Views - https://www.drupal.org/project/i18nviews
|
||||
* Language Icons - https://www.drupal.org/project/languageicons
|
||||
* Translation Overview - https://www.drupal.org/project/translation_overview
|
||||
* Localization Client - https://www.drupal.org/project/l10n_client
|
||||
* Internationalization contributions -
|
||||
https://www.drupal.org/project/i18n_contrib
|
||||
|
||||
|
||||
INSTALLATION
|
||||
------------
|
||||
|
||||
This is a submodule of the Internationalization module. Install the
|
||||
Internationalization module as you would normally install a contributed Drupal
|
||||
module. Visit https://www.drupal.org/node/895232 for further information.
|
||||
|
||||
|
||||
CONFIGURATION
|
||||
-------------
|
||||
|
||||
Language-independent terms - only vocabulary will be translatable.
|
||||
1. Navigate to Structure > Taxonomy.
|
||||
2. Select the "edit vocabulary" link.
|
||||
3. Select the "No multilingual options for terms".
|
||||
|
||||
Language-specific terms - vocabulary is only used for content in that language.
|
||||
The terms will only be available if the term language matches the UI language.
|
||||
1. Navigate to Structure > Taxonomy and select the "edit vocabulary link".
|
||||
2. Choose "Fixed Language" and a Language drop-down field will be displayed.
|
||||
3. Select the language.
|
||||
4. Select "Fixed Language" and Save.
|
||||
|
||||
Localized terms - Terms are common for all languages, but their name and
|
||||
description may be localized.
|
||||
1. Navigate to Structure > Taxonomy > vocabulary-to-edit > Edit.
|
||||
2. Select "Localize" and select Save.
|
||||
3. Edit a term and there will be a Translate tab. Select this tab.
|
||||
4. Select Translate, translate the Name and Description, select
|
||||
"Save translation", and repeat for all languages.
|
||||
5. Repeat the process for all terms.
|
||||
6. Navigate to Structure > Content types > term-to-edit > Manage display.
|
||||
7. By default, the term reference is set to Link. Change this to "Link
|
||||
(localized)" and Save.
|
||||
The vocabulary will be appropriate for the language.
|
||||
|
||||
Mixed-language vocabulary - Use for vocabularies with terms in multiple
|
||||
languages.
|
||||
1. Navigate to Structure > Taxonomy > vocabulary-to-edit > Edit.
|
||||
2. Select the Translate radio button and Save.
|
||||
3. Edit a vocabulary term and there will be a new Language field. Choose a
|
||||
language and then select Save and translate.
|
||||
4. There are two options, the user can either select "Add translation link" or
|
||||
the user can select an existing term in the Select translations form.
|
||||
5. Create translations for the terms and add terms for specific languages only.
|
||||
Now if the user edits a node associated with this vocabulary, only the relevant
|
||||
terms will appear.
|
||||
|
||||
|
||||
MAINTAINERS
|
||||
-----------
|
||||
|
||||
* Jose Reyero - https://www.drupal.org/u/jose-reyero
|
||||
* Florian Weber (webflo) - https://www.drupal.org/u/webflo
|
||||
* Peter Philipp - https://www.drupal.org/u/das-peter
|
||||
* Joseph Olstad - https://www.drupal.org/u/joseph.olstad
|
||||
* Nathaniel Catchpole - https://www.drupal.org/u/catch
|
@ -11,9 +11,8 @@ files[] = i18n_taxonomy.pages.inc
|
||||
files[] = i18n_taxonomy.admin.inc
|
||||
files[] = i18n_taxonomy.test
|
||||
|
||||
; Information added by Drupal.org packaging script on 2015-05-07
|
||||
version = "7.x-1.13"
|
||||
; Information added by Drupal.org packaging script on 2018-08-17
|
||||
version = "7.x-1.26"
|
||||
core = "7.x"
|
||||
project = "i18n"
|
||||
datestamp = "1430999922"
|
||||
|
||||
datestamp = "1534531985"
|
||||
|
@ -213,7 +213,12 @@ function i18n_taxonomy_field_formatter_view($entity_type, $entity, $field, $inst
|
||||
);
|
||||
}
|
||||
else {
|
||||
$term = $item['taxonomy_term'];
|
||||
if (isset($item['taxonomy_term'])) {
|
||||
$term = $item['taxonomy_term'];
|
||||
}
|
||||
else {
|
||||
$term = taxonomy_term_load($item['tid']);
|
||||
}
|
||||
$uri = entity_uri('taxonomy_term', $term);
|
||||
$element[$delta] = array(
|
||||
'#type' => 'link',
|
||||
@ -372,10 +377,19 @@ function i18n_taxonomy_field_prepare_translation($entity_type, $entity, $field,
|
||||
* The array of valid terms for this field, keyed by term id.
|
||||
*/
|
||||
function i18n_taxonomy_allowed_values($field) {
|
||||
global $language;
|
||||
$options = array();
|
||||
foreach ($field['settings']['allowed_values'] as $tree) {
|
||||
if ($vocabulary = taxonomy_vocabulary_machine_name_load($tree['vocabulary'])) {
|
||||
if ($terms = taxonomy_get_tree($vocabulary->vid, $tree['parent'])) {
|
||||
if (i18n_taxonomy_vocabulary_mode($vocabulary->vid) == I18N_MODE_TRANSLATE) {
|
||||
$parent = i18n_taxonomy_translation_term_tid($tree['parent'], NULL, $tree['parent']);
|
||||
$language = i18n_language_context();
|
||||
$terms = i18n_taxonomy_get_tree($vocabulary->vid, $language->language, $parent);
|
||||
}
|
||||
else {
|
||||
$terms = taxonomy_get_tree($vocabulary->vid, $tree['parent']);
|
||||
}
|
||||
if ($terms) {
|
||||
foreach ($terms as $term) {
|
||||
$options[$term->tid] = str_repeat('-', $term->depth) . i18n_taxonomy_term_name($term);
|
||||
}
|
||||
@ -742,6 +756,28 @@ function i18n_taxonomy_form_taxonomy_form_term_alter(&$form, &$form_state) {
|
||||
// Add language field or not depending on taxonomy mode.
|
||||
switch (i18n_taxonomy_vocabulary_mode($vocabulary->vid)) {
|
||||
case I18N_MODE_TRANSLATE:
|
||||
// Set $form_state['storage'] default as empty array because we will add
|
||||
// the translation and target from $_GET. So we still have it when the
|
||||
// page partially reloads with ajax.
|
||||
if(!isset($form_state['storage'])) {
|
||||
$form_state['storage'] = array();
|
||||
}
|
||||
// get translation from $_GET or $form_state['storage']
|
||||
$translation = null;
|
||||
if(isset($_GET['translation'])) {
|
||||
$translation = $_GET['translation'];
|
||||
$form_state['storage']['translation'] = $translation;
|
||||
} else if(isset($form_state['storage']) && isset($form_state['storage']['translation'])){
|
||||
$translation = $form_state['storage']['translation'];
|
||||
}
|
||||
// get target from $_GET or $form_state['storage']
|
||||
$target = null;
|
||||
if(isset($_GET['target'])) {
|
||||
$target = $_GET['target'];
|
||||
$form_state['storage']['target'] = $target;
|
||||
} else if(isset($form_state['storage']) && isset($form_state['storage']['target'])){
|
||||
$target = $form_state['storage']['target'];
|
||||
}
|
||||
$form['language'] = array(
|
||||
'#description' => t('This term belongs to a multilingual vocabulary. You can set a language for it.'),
|
||||
) + i18n_element_language_select($term);
|
||||
@ -749,7 +785,7 @@ function i18n_taxonomy_form_taxonomy_form_term_alter(&$form, &$form_state) {
|
||||
// If the term to be added will be a translation of a source term,
|
||||
// set the default value of the option list to the target language and
|
||||
// create a form element for storing the translation set of the source term.
|
||||
if (empty($term->tid) && isset($_GET['translation']) && isset($_GET['target']) && ($source_term = taxonomy_term_load($_GET['translation'])) && ($target_language = i18n_language_object($_GET['target']))) {
|
||||
if (empty($term->tid) && isset($translation) && isset($target) && ($source_term = taxonomy_term_load($translation)) && ($target_language = i18n_language_object($target))) {
|
||||
// Set context language to target language.
|
||||
i18n_language_context($target_language);
|
||||
|
||||
@ -991,7 +1027,7 @@ function i18n_taxonomy_translate_terms($taxonomy, $langcode, $fullterms = TRUE)
|
||||
}
|
||||
elseif ($term->language && $term->language != $langcode) {
|
||||
$translation_set = i18n_translation_set_load($term->i18n_tsid);
|
||||
$translations = $translation_set->get_translations();
|
||||
$translations = ($translation_set) ? $translation_set->get_translations() : NULL;
|
||||
|
||||
if ($translations && !empty($translations[$langcode])) {
|
||||
$newterm = $translations[$langcode];
|
||||
@ -1020,6 +1056,10 @@ function i18n_taxonomy_localize_terms($terms) {
|
||||
if (!i18n_string_translate_langcode()) {
|
||||
return $terms;
|
||||
}
|
||||
// $terms is not a valid array or term.
|
||||
if (empty($terms)) {
|
||||
return $terms;
|
||||
}
|
||||
$object_info = i18n_object_info('taxonomy_term');
|
||||
$list = is_array($terms) ? $terms : array($terms);
|
||||
foreach ($list as $index => $term) {
|
||||
@ -1087,7 +1127,7 @@ function i18n_taxonomy_get_tree($vid, $langcode, $parent = 0, $max_depth = NULL,
|
||||
$query->join('taxonomy_term_hierarchy', 'h', 'h.tid = t.tid');
|
||||
$result = $query
|
||||
->addTag('translatable')
|
||||
->addTag('term_access')
|
||||
->addTag('taxonomy_term_access')
|
||||
->fields('t')
|
||||
->fields('h', array('parent'))
|
||||
->condition('t.vid', $vid)
|
||||
@ -1216,6 +1256,11 @@ function i18n_taxonomy_field_uuid_presave($entity_type, $entity, $field, $instan
|
||||
* Implements hook_entity_info_alter().
|
||||
*/
|
||||
function i18n_taxonomy_entity_info_alter(&$entity_info) {
|
||||
if (isset($entity_info['taxonomy_vocabulary'])) {
|
||||
// Add altered vocabulary schema fields.
|
||||
$entity_info['taxonomy_vocabulary']['schema_fields_sql']['base table'][] = 'i18n_mode';
|
||||
$entity_info['taxonomy_vocabulary']['schema_fields_sql']['base table'][] = 'language';
|
||||
}
|
||||
if (isset($entity_info['taxonomy_term'])) {
|
||||
// Core doesn't provide a label callback for taxonomy terms. By setting one
|
||||
// we can use it to return the correct localized term name.
|
||||
@ -1261,3 +1306,22 @@ function i18n_taxonomy_modules_enabled($modules) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_views_pre_render().
|
||||
*/
|
||||
function i18n_taxonomy_views_pre_render(&$view) {
|
||||
if($view->base_table !== 'rules_scheduler') {
|
||||
global $language;
|
||||
|
||||
foreach ($view->result as $delta => $term){
|
||||
if (isset($term->tid)) {
|
||||
i18n_string_translate_langcode($language->language);
|
||||
$localized_term = i18n_taxonomy_localize_terms(taxonomy_term_load($term->tid));
|
||||
$term->tid = $localized_term->tid;
|
||||
$term->taxonomy_term_data_name = $localized_term->name;
|
||||
$term->taxonomy_term_data_description = $localized_term->description;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ function _i18n_taxonomy_autocomplete($langcode, $vids, $tags_typed = '') {
|
||||
$query = db_select('taxonomy_term_data', 't')
|
||||
->fields('t', array('tid', 'name'));
|
||||
$query->addTag('translatable');
|
||||
$query->addTag('term_access');
|
||||
$query->addTag('taxonomy_term_access');
|
||||
// Disable i18n_select for this query
|
||||
$query->addTag('i18n_select');
|
||||
// Add language condition
|
||||
|
@ -15,6 +15,10 @@ function i18n_taxonomy_token_info() {
|
||||
'name' => t("Name (localized)"),
|
||||
'description' => t("The name of the taxonomy term."),
|
||||
);
|
||||
$term['localized-name'] = array(
|
||||
'name' => t("Name in current language"),
|
||||
'description' => t("The name of the taxonomy term in current language."),
|
||||
);
|
||||
$term['i18n-description'] = array(
|
||||
'name' => t("Description (localized)"),
|
||||
'description' => t("The optional description of the taxonomy term."),
|
||||
@ -69,6 +73,12 @@ function i18n_taxonomy_tokens($type, $tokens, array $data = array(), array $opti
|
||||
$replacements[$original] = $sanitize ? check_plain($name) : $name;
|
||||
break;
|
||||
|
||||
case 'localized-name':
|
||||
$translated_term = i18n_taxonomy_term_get_translation($term, $langcode);
|
||||
$name = i18n_taxonomy_term_name($translated_term, $langcode);
|
||||
$replacements[$original] = $sanitize ? check_plain($name) : $name;
|
||||
break;
|
||||
|
||||
case 'i18n-description':
|
||||
$replacements[$original] = i18n_string_text(array('taxonomy', 'term', $term->tid, 'description'), $term->description, array('langcode' => $langcode, 'format' => $term->format, 'sanitize' => $sanitize, 'cache' => TRUE));
|
||||
break;
|
||||
|
@ -6,9 +6,8 @@ core = 7.x
|
||||
|
||||
files[] = i18n_translation.inc
|
||||
|
||||
; Information added by Drupal.org packaging script on 2015-05-07
|
||||
version = "7.x-1.13"
|
||||
; Information added by Drupal.org packaging script on 2018-08-17
|
||||
version = "7.x-1.26"
|
||||
core = "7.x"
|
||||
project = "i18n"
|
||||
datestamp = "1430999922"
|
||||
|
||||
datestamp = "1534531985"
|
||||
|
@ -20,7 +20,7 @@ class I18nTranslationSetController extends DrupalDefaultEntityController {
|
||||
* @param $queried_entities
|
||||
* Associative array of query results, keyed on the entity ID.
|
||||
* @param $revision_id
|
||||
* ID of the revision that was loaded, or FALSE if teh most current revision
|
||||
* ID of the revision that was loaded, or FALSE if the most current revision
|
||||
* was loaded.
|
||||
*/
|
||||
protected function attachLoad(&$queried_entities, $revision_id = FALSE) {
|
||||
|
@ -0,0 +1,70 @@
|
||||
CONTENTS OF THIS FILE
|
||||
---------------------
|
||||
|
||||
* Introduction
|
||||
* Requirements
|
||||
* Recommended modules
|
||||
* Installation
|
||||
* Configuration
|
||||
* Maintainers
|
||||
|
||||
|
||||
INTRODUCTION
|
||||
------------
|
||||
|
||||
The User mail translation module, part of the Internationalization
|
||||
(https://www.drupal.org/project/i18n) package, translates emails sent from the
|
||||
User module.
|
||||
|
||||
* For a full description of the module, visit this page:
|
||||
https://www.drupal.org/node/133977.
|
||||
|
||||
* To submit bug reports and feature suggestions, or to track changes:
|
||||
https://www.drupal.org/project/issues/i18n.
|
||||
|
||||
|
||||
REQUIREMENTS
|
||||
------------
|
||||
|
||||
This module requires the following module:
|
||||
|
||||
* Internationalization - https://www.drupal.org/project/i18n
|
||||
|
||||
|
||||
RECOMMENDED MODULES
|
||||
-------------------
|
||||
|
||||
* Internationalization Views - https://www.drupal.org/project/i18nviews
|
||||
* Language Icons - https://www.drupal.org/project/languageicons
|
||||
* Translation Overview - https://www.drupal.org/project/translation_overview
|
||||
* Localization Client - https://www.drupal.org/project/l10n_client
|
||||
* Internationalization contributions -
|
||||
https://www.drupal.org/project/i18n_contrib
|
||||
|
||||
|
||||
INSTALLATION
|
||||
------------
|
||||
|
||||
This is a submodule of the Internationalization module. Install the
|
||||
Internationalization module as you would normally install a contributed Drupal
|
||||
module. Visit https://www.drupal.org/node/895232 for further information.
|
||||
|
||||
|
||||
CONFIGURATION
|
||||
-------------
|
||||
|
||||
To configure email translations
|
||||
1. Navigate to Administration > Configuration > Regional and language >
|
||||
Multilingual settings and select the variables tab.
|
||||
2. Select the "User emails" tab. Select the variables to be translated. Save
|
||||
configuration.
|
||||
|
||||
|
||||
MAINTAINERS
|
||||
-----------
|
||||
|
||||
* Jose Reyero - https://www.drupal.org/u/jose-reyero
|
||||
* Florian Weber (webflo) - https://www.drupal.org/u/webflo
|
||||
* Peter Philipp - https://www.drupal.org/u/das-peter
|
||||
* Joseph Olstad - https://www.drupal.org/u/joseph.olstad
|
||||
* Nathaniel Catchpole - https://www.drupal.org/u/catch
|
@ -4,9 +4,8 @@ core = 7.x
|
||||
package = Multilingual - Internationalization
|
||||
dependencies[] = i18n_variable
|
||||
|
||||
; Information added by Drupal.org packaging script on 2015-05-07
|
||||
version = "7.x-1.13"
|
||||
; Information added by Drupal.org packaging script on 2018-08-17
|
||||
version = "7.x-1.26"
|
||||
core = "7.x"
|
||||
project = "i18n"
|
||||
datestamp = "1430999922"
|
||||
|
||||
datestamp = "1534531985"
|
||||
|
@ -9,7 +9,14 @@
|
||||
*/
|
||||
function i18n_user_mail_alter(&$message) {
|
||||
if ($message['module'] == 'user') {
|
||||
$language = $message['language'];
|
||||
$message['language'] = language_default();
|
||||
if (isset($message['params']['account'])) {
|
||||
$user_preferred = user_preferred_language($message['params']['account']);
|
||||
if (isset($user_preferred)) {
|
||||
$message['language'] = $user_preferred;
|
||||
}
|
||||
}
|
||||
$language = (isset($message['language']) ? $message['language'] : language_default());
|
||||
$variables = array('user' => $message['params']['account']);
|
||||
$key = $message['key'];
|
||||
|
||||
|
@ -0,0 +1,84 @@
|
||||
CONTENTS OF THIS FILE
|
||||
---------------------
|
||||
|
||||
* Introduction
|
||||
* Requirements
|
||||
* Recommended modules
|
||||
* Installation
|
||||
* Configuration
|
||||
* Maintainers
|
||||
|
||||
|
||||
INTRODUCTION
|
||||
------------
|
||||
|
||||
The Variable translation module, part of the Internationalization
|
||||
(https://www.drupal.org/project/i18n) package, allows the user to translate text
|
||||
and settings that are stored in Drupal as variables. These variables include
|
||||
text such as 'site name' and 'site slogan', as well as settings like 'Default
|
||||
front page' and 'Default 404 page'.
|
||||
|
||||
* For a full description of the module, visit:
|
||||
https://www.drupal.org/node/1113374.
|
||||
|
||||
* To submit bug reports and feature suggestions, or to track changes visit:
|
||||
https://www.drupal.org/project/issues/i18n.
|
||||
|
||||
|
||||
REQUIREMENTS
|
||||
------------
|
||||
|
||||
This module requires the following modules:
|
||||
|
||||
* Internationalization - https://www.drupal.org/project/i18n
|
||||
* Variable - https://www.drupal.org/project/variable
|
||||
|
||||
|
||||
RECOMMENDED MODULES
|
||||
-------------------
|
||||
|
||||
* Internationalization Views - https://www.drupal.org/project/i18nviews
|
||||
* Language Icons - https://www.drupal.org/project/languageicons
|
||||
* Translation Overview - https://www.drupal.org/project/translation_overview
|
||||
* Localization Client - https://www.drupal.org/project/l10n_client
|
||||
* Internationalization contributions -
|
||||
https://www.drupal.org/project/i18n_contrib
|
||||
|
||||
|
||||
INSTALLATION
|
||||
------------
|
||||
|
||||
This is a submodule of the Internationalization module. Install the
|
||||
Internationalization module as you would normally install a contributed Drupal
|
||||
module. Visit https://www.drupal.org/node/895232 for further information.
|
||||
|
||||
|
||||
CONFIGURATION
|
||||
-------------
|
||||
|
||||
To enable multilingual variables
|
||||
|
||||
1. Enable the Variable translation module included with the Internationalization
|
||||
package.
|
||||
2. Go to Administration > Configuration > Regional and language > Multilingual
|
||||
settings.
|
||||
3. Select on the Variables tab.
|
||||
4. Select the variables that will be multilingual.
|
||||
5. Save configuration.
|
||||
|
||||
Once the user has the correct settings, they'll be marked with "This is a
|
||||
multilingual variable" when the user navigates to the corresponding
|
||||
administration pages. The user must switch the site language while in the
|
||||
administration pages to set the variables for each language. A language switcher
|
||||
link will appear at the top of each administrative page that has multilingual
|
||||
variables.
|
||||
|
||||
|
||||
MAINTAINERS
|
||||
-----------
|
||||
|
||||
* Jose Reyero - https://www.drupal.org/u/jose-reyero
|
||||
* Florian Weber (webflo) - https://www.drupal.org/u/webflo
|
||||
* Peter Philipp - https://www.drupal.org/u/das-peter
|
||||
* Joseph Olstad - https://www.drupal.org/u/joseph.olstad
|
||||
* Nathaniel Catchpole - https://www.drupal.org/u/catch
|
@ -10,9 +10,8 @@ configure = admin/config/regional/i18n/variable
|
||||
files[] = i18n_variable.class.inc
|
||||
files[] = i18n_variable.test
|
||||
|
||||
; Information added by Drupal.org packaging script on 2015-05-07
|
||||
version = "7.x-1.13"
|
||||
; Information added by Drupal.org packaging script on 2018-08-17
|
||||
version = "7.x-1.26"
|
||||
core = "7.x"
|
||||
project = "i18n"
|
||||
datestamp = "1430999922"
|
||||
|
||||
datestamp = "1534531985"
|
||||
|
@ -7,9 +7,8 @@ package = Testing
|
||||
core = 6.x
|
||||
hidden = TRUE
|
||||
|
||||
; Information added by Drupal.org packaging script on 2015-05-07
|
||||
version = "7.x-1.13"
|
||||
; Information added by Drupal.org packaging script on 2018-08-17
|
||||
version = "7.x-1.26"
|
||||
core = "7.x"
|
||||
project = "i18n"
|
||||
datestamp = "1430999922"
|
||||
|
||||
datestamp = "1534531985"
|
||||
|
@ -40,7 +40,7 @@ function i18n_test_i18n_string_info() {
|
||||
'title' => t('Test Cached Strings'),
|
||||
'description' => t('Translatable items of a textgroup with caching enabled.'),
|
||||
'format' => FALSE, // This group doesn't have strings with format
|
||||
'class' => 'i18n_string_textgroup_cached_logged',
|
||||
'class' => variable_get('i18n_string_textgroup_class_test_cached', 'i18n_string_textgroup_cached_logged'),
|
||||
);
|
||||
return $groups;
|
||||
}
|
||||
|
@ -0,0 +1,22 @@
|
||||
diff --git a/views_rss_media.install b/views_rss_media.install
|
||||
index cfee050..e7a0cc7 100644
|
||||
--- a/views_rss_media.install
|
||||
+++ b/views_rss_media.install
|
||||
@@ -16,6 +16,8 @@ define('VIEWS_RSS_MEDIA_REQUIRED_BUILD', '7.x-2.x-dev-20120314');
|
||||
function views_rss_media_requirements($phase) {
|
||||
$requirements = array();
|
||||
$t = get_t();
|
||||
+ $vrb_array = explode('-', VIEWS_RSS_BUILD);
|
||||
+ $vrmrb_array = explode('-', VIEWS_RSS_MEDIA_REQUIRED_BUILD);
|
||||
if (!defined('VIEWS_RSS_BUILD')) {
|
||||
$requirements['views_rss_media'] = array(
|
||||
'title' => $t('Views RSS: Media (MRSS) Elements'),
|
||||
@@ -26,7 +28,7 @@ function views_rss_media_requirements($phase) {
|
||||
'value' => NULL,
|
||||
);
|
||||
}
|
||||
- elseif (array_pop(explode('-', VIEWS_RSS_BUILD)) < array_pop(explode('-', VIEWS_RSS_MEDIA_REQUIRED_BUILD))) {
|
||||
+ elseif (array_pop($vrb_array) < array_pop($vrmrb_array)) {
|
||||
$requirements['views_rss_media'] = array(
|
||||
'title' => $t('Views RSS: Media (MRSS) Elements'),
|
||||
'description' => $t('Your current build of <a href="@views_rss_url">Views RSS</a> module (!views_rss_build) is too old for this version of <em>Views RSS: Media (MRSS) Elements</em> module to work properly. Minimum version required is <strong>!views_rss_required</strong>. Please upgrade.', array(
|
@ -16,6 +16,8 @@ define('VIEWS_RSS_MEDIA_REQUIRED_BUILD', '7.x-2.x-dev-20120314');
|
||||
function views_rss_media_requirements($phase) {
|
||||
$requirements = array();
|
||||
$t = get_t();
|
||||
$vrb_array = explode('-', VIEWS_RSS_BUILD);
|
||||
$vrmrb_array = explode('-', VIEWS_RSS_MEDIA_REQUIRED_BUILD);
|
||||
if (!defined('VIEWS_RSS_BUILD')) {
|
||||
$requirements['views_rss_media'] = array(
|
||||
'title' => $t('Views RSS: Media (MRSS) Elements'),
|
||||
@ -26,7 +28,7 @@ function views_rss_media_requirements($phase) {
|
||||
'value' => NULL,
|
||||
);
|
||||
}
|
||||
elseif (array_pop(explode('-', VIEWS_RSS_BUILD)) < array_pop(explode('-', VIEWS_RSS_MEDIA_REQUIRED_BUILD))) {
|
||||
elseif (array_pop($vrb_array) < array_pop($vrmrb_array)) {
|
||||
$requirements['views_rss_media'] = array(
|
||||
'title' => $t('Views RSS: Media (MRSS) Elements'),
|
||||
'description' => $t('Your current build of <a href="@views_rss_url">Views RSS</a> module (!views_rss_build) is too old for this version of <em>Views RSS: Media (MRSS) Elements</em> module to work properly. Minimum version required is <strong>!views_rss_required</strong>. Please upgrade.', array(
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
/**
|
||||
* IE7 has no idea how large this container should be and it doesn't
|
||||
* apply has-layout. Expand it's width to 100% and trigger has-layout.
|
||||
* apply has-layout. Expand its width to 100% and trigger has-layout.
|
||||
*/
|
||||
.views-edit-view .views-displays {
|
||||
height: 1%;
|
||||
|
@ -312,9 +312,7 @@ div.form-item-options-value-all {
|
||||
|
||||
/* @end */
|
||||
|
||||
|
||||
|
||||
/* @group Javascript dependent styling */
|
||||
/* @group JavaScript dependent styling */
|
||||
|
||||
.js-only {
|
||||
display: none;
|
||||
|
@ -119,10 +119,11 @@ function views_drush_command() {
|
||||
* Callback function for views-revert command.
|
||||
*/
|
||||
function views_revert_views() {
|
||||
$args = func_get_args();
|
||||
// The provided views names specified in the command.
|
||||
$viewnames = _convert_csv_to_array($args);
|
||||
$views = views_get_all_views();
|
||||
$i = 0;
|
||||
// The provided views names specified in the command.
|
||||
$viewnames = _convert_csv_to_array(func_get_args());
|
||||
|
||||
// Find all overridden views.
|
||||
foreach ($views as $view) {
|
||||
|
@ -101,7 +101,7 @@ class views_handler_area_result extends views_handler_area {
|
||||
$replacements["@$item"] = ${$item};
|
||||
}
|
||||
// Send the output.
|
||||
if (!empty($total)) {
|
||||
if (!empty($total) || !empty($this->options['empty'])) {
|
||||
$output .= filter_xss_admin(str_replace(array_keys($replacements), array_values($replacements), $format));
|
||||
}
|
||||
return $output;
|
||||
|
@ -14,7 +14,7 @@
|
||||
/**
|
||||
* Base class for arguments.
|
||||
*
|
||||
* The basic argument works for very simple arguments such as nid and uid
|
||||
* The basic argument works for very simple arguments such as nid and uid.
|
||||
*
|
||||
* Definition terms for this handler:
|
||||
* - name field: The field to use for the name to use in the summary, which is
|
||||
@ -158,9 +158,10 @@ class views_handler_argument extends views_handler {
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the argument can generate a breadcrumb
|
||||
* Determine if the argument can generate a breadcrumb.
|
||||
*
|
||||
* @return bool
|
||||
* Indicates whether the argument can generate a breadcrumb.
|
||||
*/
|
||||
public function uses_breadcrumb() {
|
||||
$info = $this->default_actions($this->options['default_action']);
|
||||
@ -195,6 +196,7 @@ class views_handler_argument extends views_handler {
|
||||
* Determine if the argument needs a style plugin.
|
||||
*
|
||||
* @return bool
|
||||
* the argument needs a plugin style.
|
||||
*/
|
||||
public function needs_style_plugin() {
|
||||
$info = $this->default_actions($this->options['default_action']);
|
||||
@ -527,8 +529,7 @@ class views_handler_argument extends views_handler {
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a list of default behaviors for this argument if the argument
|
||||
* is not present.
|
||||
* List of default behaviors for this argument if the argument is not present.
|
||||
*
|
||||
* Override this method to provide additional (or fewer) default behaviors.
|
||||
*/
|
||||
@ -657,8 +658,9 @@ class views_handler_argument extends views_handler {
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a form for selecting further summary options when the default
|
||||
* action is set to display one.
|
||||
* Form for selecting further summary options.
|
||||
*
|
||||
* Only used when the default action is set to display one.
|
||||
*/
|
||||
public function default_summary_form(&$form, &$form_state) {
|
||||
$style_plugins = views_fetch_plugin_data('style');
|
||||
@ -795,10 +797,10 @@ class views_handler_argument extends views_handler {
|
||||
}
|
||||
|
||||
/**
|
||||
* Default action: empty
|
||||
* Default action: empty.
|
||||
*
|
||||
* If an argument was expected and was not given, in this case, display the
|
||||
* view's empty text
|
||||
* view's empty text.
|
||||
*/
|
||||
public function default_empty() {
|
||||
// We return with no query; this will force the empty text.
|
||||
@ -967,6 +969,8 @@ class views_handler_argument extends views_handler {
|
||||
*
|
||||
* @param string $order
|
||||
* The order selected in the UI.
|
||||
* @param string $by
|
||||
* Optional alias for this field.
|
||||
*/
|
||||
public function summary_sort($order, $by = NULL) {
|
||||
$this->query->add_orderby(NULL, NULL, $order, (!empty($by) ? $by : $this->name_alias));
|
||||
@ -1116,7 +1120,7 @@ class views_handler_argument extends views_handler {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the input for this argument
|
||||
* Set the input for this argument.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if it successfully validates; FALSE if it does not.
|
||||
|
@ -17,7 +17,7 @@
|
||||
* Definitions terms:
|
||||
* - many to one: If true, the "many to one" helper will be used.
|
||||
* - invalid input: A string to give to the user for obviously invalid input.
|
||||
* This is deprecated in favor of argument validators.
|
||||
* This is deprecated in favor of argument validators.
|
||||
*
|
||||
* @see views_many_to_one_helper()
|
||||
*
|
||||
@ -26,12 +26,12 @@
|
||||
class views_handler_argument_date extends views_handler_argument_formula {
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $option_name = 'default_argument_date';
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $arg_format = 'Y-m-d';
|
||||
|
||||
@ -46,9 +46,9 @@ class views_handler_argument_date extends views_handler_argument_formula {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the empty argument value to the current date,
|
||||
* Set the empty argument value to the current date.
|
||||
*
|
||||
* formatted appropriately for this argument.
|
||||
* Formatted appropriately for this argument.
|
||||
*
|
||||
* @return string
|
||||
* The default argument.
|
||||
|
@ -38,6 +38,7 @@ class views_handler_argument_string extends views_handler_argument {
|
||||
$options['path_case'] = array('default' => 'none');
|
||||
$options['transform_dash'] = array('default' => FALSE, 'bool' => TRUE);
|
||||
$options['break_phrase'] = array('default' => FALSE, 'bool' => TRUE);
|
||||
$options['not'] = array('default' => FALSE, 'bool' => TRUE);
|
||||
|
||||
if (!empty($this->definition['many to one'])) {
|
||||
$options['add_table'] = array('default' => FALSE, 'bool' => TRUE);
|
||||
@ -132,6 +133,13 @@ class views_handler_argument_string extends views_handler_argument {
|
||||
'#default_value' => !empty($this->options['break_phrase']),
|
||||
'#fieldset' => 'more',
|
||||
);
|
||||
$form['not'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Exclude'),
|
||||
'#description' => t('If selected, the numbers entered for the filter will be excluded rather than limiting the view.'),
|
||||
'#default_value' => !empty($this->options['not']),
|
||||
'#fieldset' => 'more',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -207,21 +215,19 @@ class views_handler_argument_string extends views_handler_argument {
|
||||
}
|
||||
|
||||
if (count($this->value) > 1) {
|
||||
$operator = 'IN';
|
||||
$operator = empty($this->options['not']) ? 'IN' : 'NOT IN';
|
||||
$argument = $this->value;
|
||||
}
|
||||
else {
|
||||
$operator = '=';
|
||||
$operator = empty($this->options['not']) ? '=' : '!=';
|
||||
}
|
||||
|
||||
if ($formula) {
|
||||
$placeholder = $this->placeholder();
|
||||
if ($operator == 'IN') {
|
||||
$field .= " IN($placeholder)";
|
||||
}
|
||||
else {
|
||||
$field .= ' = ' . $placeholder;
|
||||
if (count($this->value) > 1) {
|
||||
$placeholder = "($placeholder)";
|
||||
}
|
||||
$field .= " $operator $placeholder";
|
||||
$placeholders = array(
|
||||
$placeholder => $argument,
|
||||
);
|
||||
|
@ -68,7 +68,7 @@ class views_handler_field extends views_handler {
|
||||
|
||||
/**
|
||||
* @var array
|
||||
* Stores additional fields which get's added to the query.
|
||||
* Stores additional fields which get added to the query.
|
||||
* The generated aliases are stored in $aliases.
|
||||
*/
|
||||
public $additional_fields = array();
|
||||
@ -424,6 +424,7 @@ class views_handler_field extends views_handler {
|
||||
'absolute' => array('default' => FALSE, 'bool' => TRUE),
|
||||
'external' => array('default' => FALSE, 'bool' => TRUE),
|
||||
'replace_spaces' => array('default' => FALSE, 'bool' => TRUE),
|
||||
'unwanted_characters' => array('default' => ''),
|
||||
'path_case' => array('default' => 'none', 'translatable' => FALSE),
|
||||
'trim_whitespace' => array('default' => FALSE, 'bool' => TRUE),
|
||||
'alt' => array('default' => '', 'translatable' => TRUE),
|
||||
@ -744,6 +745,16 @@ class views_handler_field extends views_handler {
|
||||
'edit-options-alter-make-link' => array(1),
|
||||
),
|
||||
);
|
||||
$form['alter']['unwanted_characters'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => t('Remove unwanted characters'),
|
||||
'#description' => t('Space-separated list of characters to remove from the URL path'),
|
||||
'#default_value' => $this->options['alter']['unwanted_characters'],
|
||||
'#dependency' => array(
|
||||
'edit-options-alter-make-link' => array(1)
|
||||
),
|
||||
'#maxlength' => 255,
|
||||
);
|
||||
$form['alter']['path_case'] = array(
|
||||
'#type' => 'select',
|
||||
'#title' => t('Transform the case'),
|
||||
@ -782,7 +793,7 @@ class views_handler_field extends views_handler {
|
||||
'#title' => t('Rel Text'),
|
||||
'#type' => 'textfield',
|
||||
'#default_value' => $this->options['alter']['rel'],
|
||||
'#description' => t('Include Rel attribute for use in lightbox2 or other javascript utility.'),
|
||||
'#description' => t('Include Rel attribute for use in lightbox2 or other JavaScript utility.'),
|
||||
'#dependency' => array(
|
||||
'edit-options-alter-make-link' => array(1),
|
||||
),
|
||||
@ -1234,8 +1245,9 @@ If you would like to have the characters \'[\' and \']\' please use the html ent
|
||||
* Render this field as altered text, from a fieldset set by the user.
|
||||
*/
|
||||
public function render_altered($alter, $tokens) {
|
||||
// Filter this right away as our substitutions are already sanitized.
|
||||
$value = filter_xss_admin($alter['text']);
|
||||
// We trust admins so we allow any tag content. This is important for
|
||||
// displays such as XML where we should not mess with tags.
|
||||
$value = $alter['text'];
|
||||
$value = strtr($value, $tokens);
|
||||
|
||||
return $value;
|
||||
@ -1287,6 +1299,12 @@ If you would like to have the characters \'[\' and \']\' please use the html ent
|
||||
if (!empty($alter['replace_spaces'])) {
|
||||
$path = str_replace(' ', '-', $path);
|
||||
}
|
||||
|
||||
if (!empty($alter['unwanted_characters'])) {
|
||||
foreach (explode(' ', $alter['unwanted_characters']) as $unwanted) {
|
||||
$path = str_replace($unwanted, '', $path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the URL and move any query and fragment parameters out of the path.
|
||||
|
@ -8,6 +8,9 @@
|
||||
/**
|
||||
* A handler to provide proper displays for dates.
|
||||
*
|
||||
* This may be used on table fields that hold either UNIX timestamps or SQL
|
||||
* datetime strings.
|
||||
*
|
||||
* @ingroup views_field_handlers
|
||||
*/
|
||||
class views_handler_field_date extends views_handler_field {
|
||||
@ -138,6 +141,12 @@ class views_handler_field_date extends views_handler_field {
|
||||
*/
|
||||
public function render($values) {
|
||||
$value = $this->get_value($values);
|
||||
|
||||
if (!is_numeric($value)) {
|
||||
// If the value isn't numeric, assume it's an SQL DATETIME.
|
||||
$value = strtotime($value);
|
||||
}
|
||||
|
||||
$format = $this->options['date_format'];
|
||||
if (in_array($format, $this->supported_date_types())) {
|
||||
$custom_format = $this->options['custom_date_format'];
|
||||
|
@ -41,7 +41,9 @@ class views_handler_field_entity extends views_handler_field {
|
||||
|
||||
// Initialize the entity-type used.
|
||||
$table_data = views_fetch_data($this->table);
|
||||
$this->entity_type = $table_data['table']['entity type'];
|
||||
if (isset($table_data['table']['entity type'])) {
|
||||
$this->entity_type = $table_data['table']['entity type'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -64,6 +64,7 @@ class views_handler_field_links extends views_handler_field {
|
||||
public function options_submit(&$form, &$form_state) {
|
||||
// Remove unselected options.
|
||||
$form_state['values']['options']['fields'] = array_filter($form_state['values']['options']['fields']);
|
||||
parent::options_submit($form, $form_state);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -118,6 +118,11 @@ class views_handler_field_numeric extends views_handler_field {
|
||||
public function render($values) {
|
||||
$value = $this->get_value($values);
|
||||
|
||||
// Output nothing if the value is null.
|
||||
if (is_null($value)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Hiding should happen before rounding or adding prefix/suffix.
|
||||
if ($this->options['hide_empty'] && empty($value) && ($value !== 0 || $this->options['empty_zero'])) {
|
||||
return '';
|
||||
@ -127,12 +132,13 @@ class views_handler_field_numeric extends views_handler_field {
|
||||
$value = number_format($value, $this->options['precision'], $this->options['decimal'], $this->options['separator']);
|
||||
}
|
||||
else {
|
||||
$remainder = abs($value) - intval(abs($value));
|
||||
$point_position = strpos($value, '.');
|
||||
$remainder = ($point_position === FALSE) ? '' : substr($value, $point_position + 1);
|
||||
$value = $value > 0 ? floor($value) : ceil($value);
|
||||
$value = number_format($value, 0, '', $this->options['separator']);
|
||||
if ($remainder) {
|
||||
// The substr may not be locale safe.
|
||||
$value .= $this->options['decimal'] . substr($remainder, 2);
|
||||
$value .= $this->options['decimal'] . $remainder;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,15 +15,14 @@
|
||||
* available as standard operators.
|
||||
*
|
||||
* Object flags:
|
||||
* You can set some specific behavior by setting up the following flags on
|
||||
* your custom class.
|
||||
*
|
||||
* - always_multiple:
|
||||
* Disable the possibility to force a single value.
|
||||
* - no_operator:
|
||||
* Disable the possibility to use operators.
|
||||
* - always_required:
|
||||
* Disable the possibility to allow a exposed input to be optional.
|
||||
* It's possible to set specific behavior using the following flags on the
|
||||
* custom class:
|
||||
* - always_multiple:
|
||||
* Disable the possibility to force a single value.
|
||||
* - no_operator:
|
||||
* Disable the possibility to use operators.
|
||||
* - always_required:
|
||||
* Disable the possibility to allow a exposed input to be optional.
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -34,8 +33,10 @@
|
||||
class views_handler_filter extends views_handler {
|
||||
|
||||
/**
|
||||
* Contains the actual value of the field,either configured in the views ui
|
||||
* or entered in the exposed filters.
|
||||
* Contains the actual value of the field.
|
||||
*
|
||||
* This will be either configured in the views UI or entered in the exposed
|
||||
* filters.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
@ -135,13 +136,17 @@ class views_handler_filter extends views_handler {
|
||||
'use_operator' => array('default' => FALSE, 'bool' => TRUE),
|
||||
'operator_label' => array('default' => '', 'translatable' => TRUE),
|
||||
'operator' => array('default' => ''),
|
||||
'limit_operators' => array('default' => FALSE, 'bool' => TRUE),
|
||||
'available_operators' => array('default' => array()),
|
||||
'identifier' => array('default' => ''),
|
||||
'required' => array('default' => FALSE, 'bool' => TRUE),
|
||||
'remember' => array('default' => FALSE, 'bool' => TRUE),
|
||||
'multiple' => array('default' => FALSE, 'bool' => TRUE),
|
||||
'remember_roles' => array('default' => array(
|
||||
DRUPAL_AUTHENTICATED_RID => DRUPAL_AUTHENTICATED_RID,
|
||||
)),
|
||||
'remember_roles' => array(
|
||||
'default' => array(
|
||||
DRUPAL_AUTHENTICATED_RID => DRUPAL_AUTHENTICATED_RID,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@ -205,9 +210,8 @@ class views_handler_filter extends views_handler {
|
||||
/**
|
||||
* Provide the basic form which calls through to subforms.
|
||||
*
|
||||
* If overridden, it is best to call through to the parent,
|
||||
* or to at least make sure all of the functions in this form
|
||||
* are called.
|
||||
* If overridden, it is best to call through to the parent, or to at least
|
||||
* make sure all of the functions in this form are called.
|
||||
*/
|
||||
public function options_form(&$form, &$form_state) {
|
||||
parent::options_form($form, $form_state);
|
||||
@ -248,7 +252,7 @@ class views_handler_filter extends views_handler {
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple validate handler
|
||||
* Simple validate handler.
|
||||
*/
|
||||
public function options_validate(&$form, &$form_state) {
|
||||
$this->operator_validate($form, $form_state);
|
||||
@ -274,6 +278,8 @@ class views_handler_filter extends views_handler {
|
||||
$this->value_submit($form, $form_state);
|
||||
}
|
||||
if (!empty($this->options['exposed'])) {
|
||||
$options = &$form_state['values']['options']['expose'];
|
||||
$options['available_operators'] = (!empty($options['use_operator']) && !empty($options['limit_operators'])) ? array_filter($options['available_operators']) : array();
|
||||
$this->expose_submit($form, $form_state);
|
||||
}
|
||||
if ($this->is_a_group()) {
|
||||
@ -293,14 +299,29 @@ class views_handler_filter extends views_handler {
|
||||
/**
|
||||
* Options form subform for setting the operator.
|
||||
*
|
||||
* This may be overridden by child classes, and it must
|
||||
* define $form['operator'];
|
||||
* This may be overridden by child classes, and it must define
|
||||
* $form['operator'].
|
||||
*
|
||||
* @see options_form()
|
||||
*/
|
||||
public function operator_form(&$form, &$form_state) {
|
||||
$options = $this->operator_options();
|
||||
if (!empty($options)) {
|
||||
$available = $this->options['expose']['available_operators'];
|
||||
if ($this->options['expose']['limit_operators'] && count($available)) {
|
||||
foreach ($options as $key => $value) {
|
||||
if (!isset($available[$key])) {
|
||||
unset($options[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure we have a valid default value if the current one is
|
||||
// excluded.
|
||||
if (!isset($options[$this->operator])) {
|
||||
// Just choose the first.
|
||||
$this->operator = key($options);
|
||||
}
|
||||
}
|
||||
$form['operator'] = array(
|
||||
'#type' => count($options) < 10 ? 'radios' : 'select',
|
||||
'#title' => t('Operator'),
|
||||
@ -313,7 +334,7 @@ class views_handler_filter extends views_handler {
|
||||
/**
|
||||
* Provide a list of options for the default operator form.
|
||||
*
|
||||
* Should be overridden by classes that don't override operator_form
|
||||
* Should be overridden by classes that don't override operator_form.
|
||||
*/
|
||||
public function operator_options() {
|
||||
return array();
|
||||
@ -511,6 +532,33 @@ class views_handler_filter extends views_handler {
|
||||
'#title' => t('Required'),
|
||||
'#default_value' => $this->options['expose']['required'],
|
||||
);
|
||||
|
||||
$operator_options = $this->operator_options();
|
||||
if (count($operator_options)) {
|
||||
$form['expose']['limit_operators'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Limit operators'),
|
||||
'#description' => t('When checked, the operator will be exposed to the user'),
|
||||
'#default_value' => !empty($this->options['expose']['limit_operators']),
|
||||
'#dependency' => array(
|
||||
'edit-options-expose-use-operator' => array(1),
|
||||
),
|
||||
'#description' => t('Restrict which operators will be available to select in the exposed operator form.'),
|
||||
);
|
||||
|
||||
$form['expose']['available_operators'] = array(
|
||||
'#type' => 'checkboxes',
|
||||
'#title' => t('Limit the exposed operators'),
|
||||
'#default_value' => $this->options['expose']['available_operators'],
|
||||
'#prefix' => '<div id="edit-options-expose-available-operators-wrapper"><div id="edit-options-expose-available-operators">',
|
||||
'#suffix' => '</div></div>',
|
||||
'#description' => t('Select which operators will be available to select in the exposed operator form. If none are selected, all the operators listed here will be used.'),
|
||||
'#options' => $operator_options,
|
||||
'#dependency' => array(
|
||||
'edit-options-expose-limit-operators' => array(1),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
$form['expose']['required'] = array(
|
||||
@ -533,7 +581,7 @@ class views_handler_filter extends views_handler {
|
||||
);
|
||||
|
||||
if (!empty($form['operator']['#type'])) {
|
||||
// Increase the width of the left (operator) column.
|
||||
// Increase the width of the left (operator) column.
|
||||
$form['operator']['#prefix'] = '<div class="views-group-box views-left-40">';
|
||||
$form['operator']['#suffix'] = '</div>';
|
||||
$form['value']['#prefix'] = '<div class="views-group-box views-right-60">';
|
||||
@ -552,7 +600,7 @@ class views_handler_filter extends views_handler {
|
||||
'#size' => 40,
|
||||
'#description' => t('This will appear before your operator select field.'),
|
||||
'#dependency' => array(
|
||||
'edit-options-expose-use-operator' => array(1)
|
||||
'edit-options-expose-use-operator' => array(1),
|
||||
),
|
||||
);
|
||||
$form['expose']['operator_id'] = array(
|
||||
@ -562,7 +610,7 @@ class views_handler_filter extends views_handler {
|
||||
'#size' => 40,
|
||||
'#description' => t('This will appear in the URL after the ? to identify this operator.'),
|
||||
'#dependency' => array(
|
||||
'edit-options-expose-use-operator' => array(1)
|
||||
'edit-options-expose-use-operator' => array(1),
|
||||
),
|
||||
'#fieldset' => 'more',
|
||||
);
|
||||
@ -629,6 +677,12 @@ class views_handler_filter extends views_handler {
|
||||
if (!$this->view->display_handler->is_identifier_unique($form_state['id'], $form_state['values']['options']['expose']['identifier'])) {
|
||||
form_error($form['expose']['identifier'], t('This identifier is used by another handler.'));
|
||||
}
|
||||
|
||||
// Filter out roles which weren't selected, so that they aren't exported.
|
||||
// This is purely cosmetic.
|
||||
if (!empty($form_state['values']['options']['expose']['remember_roles'])) {
|
||||
$form_state['values']['options']['expose']['remember_roles'] = array_filter($form_state['values']['options']['expose']['remember_roles']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -657,10 +711,13 @@ class views_handler_filter extends views_handler {
|
||||
if (empty($group['remove'])) {
|
||||
// Check if the title is defined but value wasn't defined.
|
||||
if (!empty($group['title'])) {
|
||||
if ((!is_array($group['value']) && trim($group['value']) == "") ||
|
||||
(is_array($group['value']) && count(array_filter($group['value'], '_views_array_filter_zero')) == 0)) {
|
||||
form_error($form['group_info']['group_items'][$id]['value'],
|
||||
t('The value is required if title for this item is defined.'));
|
||||
// No value is needed for 'empty' and 'not empty' operator.
|
||||
if (!in_array($group['operator'], array('empty', 'not empty'))) {
|
||||
if ((!is_array($group['value']) && trim($group['value']) == "") ||
|
||||
(is_array($group['value']) && count(array_filter($group['value'], '_views_array_filter_zero')) == 0)) {
|
||||
form_error($form['group_info']['group_items'][$id]['value'],
|
||||
t('The value is required if title for this item is defined.'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -786,9 +843,8 @@ class views_handler_filter extends views_handler {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render our chunk of the exposed filter form when selecting
|
||||
* Render our chunk of the exposed filter form when selecting.
|
||||
*
|
||||
* You can override this if it doesn't do what you expect.
|
||||
*/
|
||||
@ -802,7 +858,7 @@ class views_handler_filter extends views_handler {
|
||||
$operator = $this->options['expose']['operator_id'];
|
||||
$this->operator_form($form, $form_state);
|
||||
$form[$operator] = $form['operator'];
|
||||
$form[$operator]['#title'] = $this->options['expose']['operator_label'];
|
||||
$form[$operator]['#title'] = $this->options['expose']['operator_label'];
|
||||
$form[$operator]['#title_display'] = 'invisible';
|
||||
|
||||
$this->exposed_translate($form[$operator], 'operator');
|
||||
@ -813,7 +869,19 @@ class views_handler_filter extends views_handler {
|
||||
// Build the form and set the value based on the identifier.
|
||||
if (!empty($this->options['expose']['identifier'])) {
|
||||
$value = $this->options['expose']['identifier'];
|
||||
$this->value_form($form, $form_state);
|
||||
if ($this->operator == 'empty' || $this->operator == 'not empty') {
|
||||
$boolean = new views_handler_filter_boolean_operator();
|
||||
$boolean->value = $this->value = 'All';
|
||||
$boolean->value_value = $this->value_value = '';
|
||||
$boolean->value_options = $this->value_options = array(
|
||||
1 => t('Yes'),
|
||||
0 => t('No'),
|
||||
);
|
||||
$boolean->value_form($form, $form_state);
|
||||
}
|
||||
else {
|
||||
$this->value_form($form, $form_state);
|
||||
}
|
||||
$form[$value] = $form['value'];
|
||||
|
||||
if (isset($form[$value]['#title']) && !empty($form[$value]['#type']) && $form[$value]['#type'] != 'checkbox') {
|
||||
@ -955,7 +1023,7 @@ class views_handler_filter extends views_handler {
|
||||
|
||||
// The string '- Any -' will not be rendered.
|
||||
// @see theme_views_ui_build_group_filter_form()
|
||||
$groups = array('All' => '- Any -');
|
||||
$groups = array('All' => '- Any -');
|
||||
|
||||
// Provide 3 options to start when we are in a new group.
|
||||
if (count($this->options['group_info']['group_items']) == 0) {
|
||||
@ -968,6 +1036,7 @@ class views_handler_filter extends views_handler {
|
||||
if (!empty($form_state['values']['options']['group_info']['group_items'][$item_id]['remove'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Each rows contains three widgets:
|
||||
// a) The title, where users define how they identify a pair of operator
|
||||
// | value.
|
||||
@ -979,14 +1048,14 @@ class views_handler_filter extends views_handler {
|
||||
$row = array();
|
||||
$groups[$item_id] = '';
|
||||
$this->operator_form($row, $form_state);
|
||||
// Force the operator form to be a select box. Some handlers uses
|
||||
// radios and they occupy a lot of space in a table row.
|
||||
// Force the operator form to be a select box. Some handlers uses radios
|
||||
// and they occupy a lot of space in a table row.
|
||||
$row['operator']['#type'] = 'select';
|
||||
$row['operator']['#title'] = '';
|
||||
$this->value_form($row, $form_state);
|
||||
|
||||
// Fix the dependencies to update value forms when operators changes.
|
||||
// This is needed because forms are inside a new form and their ids
|
||||
// This is needed because forms are inside a new form and their IDs
|
||||
// changes. Dependencies are used when operator changes from to
|
||||
// 'Between', 'Not Between', etc, and two or more widgets are displayed.
|
||||
$without_children = TRUE;
|
||||
@ -1041,6 +1110,7 @@ class views_handler_filter extends views_handler {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// From all groups, let chose which is the default.
|
||||
$form['group_info']['default_group'] = array(
|
||||
'#type' => 'radios',
|
||||
@ -1049,8 +1119,9 @@ class views_handler_filter extends views_handler {
|
||||
'#required' => TRUE,
|
||||
'#attributes' => array(
|
||||
'class' => array('default-radios'),
|
||||
)
|
||||
),
|
||||
);
|
||||
|
||||
// From all groups, let chose which is the default.
|
||||
$form['group_info']['default_group_multiple'] = array(
|
||||
'#type' => 'checkboxes',
|
||||
@ -1058,7 +1129,7 @@ class views_handler_filter extends views_handler {
|
||||
'#default_value' => $this->options['group_info']['default_group_multiple'],
|
||||
'#attributes' => array(
|
||||
'class' => array('default-checkboxes'),
|
||||
)
|
||||
),
|
||||
);
|
||||
|
||||
$form['group_info']['add_group'] = array(
|
||||
@ -1086,7 +1157,6 @@ class views_handler_filter extends views_handler {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Make some translations to a form item to make it more suitable to exposing.
|
||||
*/
|
||||
@ -1190,13 +1260,13 @@ class views_handler_filter extends views_handler {
|
||||
/**
|
||||
* Transform the input from a grouped filter into a standard filter.
|
||||
*
|
||||
* When a filter is a group, find the set of operator and values
|
||||
* that the choosed item represents, and inform views that a normal
|
||||
* filter was submitted by telling the operator and the value selected.
|
||||
* When a filter is a group, find the set of operator and values that the
|
||||
* choosen item represents, and inform views that a normal filter was
|
||||
* submitted by telling the operator and the value selected.
|
||||
*
|
||||
* The param $selected_group_id is only passed when the filter uses the
|
||||
* checkboxes widget, and this function will be called for each item
|
||||
* choosed in the checkboxes.
|
||||
* checkboxes widget, and this function will be called for each item choosen
|
||||
* in the checkboxes.
|
||||
*/
|
||||
public function convert_exposed_input(&$input, $selected_group_id = NULL) {
|
||||
if ($this->is_a_group()) {
|
||||
@ -1234,9 +1304,12 @@ class views_handler_filter extends views_handler {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the options available for a grouped filter that users checkboxes
|
||||
* as widget, and therefore has to be applied several times, one per
|
||||
* item selected.
|
||||
* Options available for a grouped filter which uses checkboxes.
|
||||
*
|
||||
* Note: has to be applied several times, one per item selected.
|
||||
*
|
||||
* @return array
|
||||
* The options available for a grouped filter.
|
||||
*/
|
||||
public function group_multiple_exposed_input(&$input) {
|
||||
if (!empty($input[$this->options['group_info']['identifier']])) {
|
||||
@ -1246,7 +1319,7 @@ class views_handler_filter extends views_handler {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Indicate whether users can select multiple group items.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if users can select multiple groups items of a grouped exposed
|
||||
@ -1258,8 +1331,9 @@ class views_handler_filter extends views_handler {
|
||||
|
||||
/**
|
||||
* If set to remember exposed input in the session, store it there.
|
||||
* This function is similar to store_exposed_input but modified to
|
||||
* work properly when the filter is a group.
|
||||
*
|
||||
* This function is similar to store_exposed_input but modified to work
|
||||
* properly when the filter is a group.
|
||||
*/
|
||||
public function store_group_input($input, $status) {
|
||||
if (!$this->is_a_group() || empty($this->options['group_info']['identifier'])) {
|
||||
@ -1312,14 +1386,13 @@ class views_handler_filter extends views_handler {
|
||||
|
||||
// Various ways to check for the absence of non-required input.
|
||||
if (empty($this->options['expose']['required'])) {
|
||||
if (($this->operator == 'empty' || $this->operator == 'not empty') && $value === '') {
|
||||
$value = ' ';
|
||||
if ($this->operator == 'empty' || $this->operator == 'not empty') {
|
||||
$value = is_array($value) ? $value['value'] : $value;
|
||||
$this->operator = ($this->operator == 'empty' && empty($value)) || ($this->operator == 'not empty' && !empty($value)) ? 'not empty' : 'empty';
|
||||
}
|
||||
|
||||
if ($this->operator != 'empty' && $this->operator != 'not empty') {
|
||||
if ($value == 'All' || $value === array()) {
|
||||
return FALSE;
|
||||
}
|
||||
if ($value == 'All' || $value === array()) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!empty($this->always_multiple) && $value === '') {
|
||||
@ -1342,7 +1415,7 @@ class views_handler_filter extends views_handler {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Store the exposed input for processing later.
|
||||
*/
|
||||
public function store_exposed_input($input, $status) {
|
||||
if (empty($this->options['exposed']) || empty($this->options['expose']['identifier'])) {
|
||||
@ -1392,7 +1465,9 @@ class views_handler_filter extends views_handler {
|
||||
$session[$this->options['expose']['operator_id']] = $input[$this->options['expose']['operator_id']];
|
||||
}
|
||||
|
||||
$session[$this->options['expose']['identifier']] = $input[$this->options['expose']['identifier']];
|
||||
if (isset($input[$this->options['expose']['identifier']])) {
|
||||
$session[$this->options['expose']['identifier']] = $input[$this->options['expose']['identifier']];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1419,9 +1494,9 @@ class views_handler_filter extends views_handler {
|
||||
* @return bool
|
||||
* Whether the filter can be used in OR groups.
|
||||
*/
|
||||
public function can_group() {
|
||||
return TRUE;
|
||||
}
|
||||
public function can_group() {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1476,14 +1551,15 @@ class views_handler_filter_broken extends views_handler_filter {
|
||||
* Filter by no empty values, though allow to use "0".
|
||||
*
|
||||
* @param string $var
|
||||
* The string to check.
|
||||
*
|
||||
* @return bool
|
||||
* Indicates if the argument is an empty string.
|
||||
*/
|
||||
function _views_array_filter_zero($var) {
|
||||
return trim($var) != "";
|
||||
return trim($var) != '';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
@ -73,7 +73,7 @@ class views_handler_filter_combine extends views_handler_filter_string {
|
||||
// Always add the table of the selected fields to be sure a table alias
|
||||
// exists.
|
||||
$field->ensure_my_table();
|
||||
if (!empty($field->field_alias) && !empty($field->field_alias)) {
|
||||
if (!empty($field->table_alias) && !empty($field->real_field)) {
|
||||
$fields[] = "$field->table_alias.$field->real_field";
|
||||
}
|
||||
}
|
||||
@ -198,6 +198,14 @@ class views_handler_filter_combine extends views_handler_filter_string {
|
||||
$this->query->add_where_expression($this->options['group'], "$field RLIKE $placeholder", array($placeholder => $this->value));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function op_not_regex($field) {
|
||||
$placeholder = $this->placeholder();
|
||||
$this->query->add_where_expression($this->options['group'], "$field NOT RLIKE $placeholder", array($placeholder => $this->value));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -158,7 +158,7 @@ class views_handler_filter_date extends views_handler_filter_numeric {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
elseif ($operators[$operator]['values'] == 2) {
|
||||
if ($this->value['min'] == '' || $this->value['max'] == '') {
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -116,6 +116,12 @@ class views_handler_filter_numeric extends views_handler_filter {
|
||||
'method' => 'op_regex',
|
||||
'values' => 1,
|
||||
),
|
||||
'not_regular_expression' => array(
|
||||
'title' => t('Not regular expression'),
|
||||
'short' => t('not regex'),
|
||||
'method' => 'op_not_regex',
|
||||
'values' => 1,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@ -159,72 +165,108 @@ class views_handler_filter_numeric extends views_handler_filter {
|
||||
// not rendered, we can't render dependencies; instead we only
|
||||
// render the form items we need.
|
||||
$which = 'all';
|
||||
$limit_operators = !empty($this->options['expose']['limit_operators']) && (count($this->options['expose']['available_operators']) > 0);
|
||||
$use_value = FALSE;
|
||||
$use_minmax = FALSE;
|
||||
|
||||
if (!empty($form['operator'])) {
|
||||
$source = ($form['operator']['#type'] == 'radios') ? 'radio:options[operator]' : 'edit-options-operator';
|
||||
}
|
||||
|
||||
if (!empty($form_state['exposed'])) {
|
||||
$operator_values_with_1_values = $this->operator_values(1);
|
||||
$operator_values_with_2_values = $this->operator_values(2);
|
||||
if ($limit_operators) {
|
||||
// If limit operators is enabled, check that at least one operator
|
||||
// with two values is enabled to display the min max widgets
|
||||
foreach ($operator_values_with_2_values as $operator) {
|
||||
if (isset($this->options['expose']['available_operators'][$operator])) {
|
||||
$use_minmax = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// the same for operators with one value
|
||||
foreach ($operator_values_with_1_values as $operator) {
|
||||
if (isset($this->options['expose']['available_operators'][$operator])) {
|
||||
$use_value = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
$use_minmax = $use_value = TRUE;
|
||||
}
|
||||
$identifier = $this->options['expose']['identifier'];
|
||||
|
||||
if (empty($this->options['expose']['use_operator']) || empty($this->options['expose']['operator_id'])) {
|
||||
// exposed and locked.
|
||||
$which = in_array($this->operator, $this->operator_values(2)) ? 'minmax' : 'value';
|
||||
$which = in_array($this->operator, $operator_values_with_2_values) ? 'minmax' : 'value';
|
||||
}
|
||||
else {
|
||||
$source = 'edit-' . drupal_html_id($this->options['expose']['operator_id']);
|
||||
}
|
||||
}
|
||||
|
||||
if ($which == 'all') {
|
||||
$form['value']['value'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => empty($form_state['exposed']) ? t('Value') : '',
|
||||
'#size' => 30,
|
||||
'#default_value' => $this->value['value'],
|
||||
'#dependency' => array($source => $this->operator_values(1)),
|
||||
);
|
||||
if (!empty($form_state['exposed']) && !isset($form_state['input'][$identifier]['value'])) {
|
||||
$form_state['input'][$identifier]['value'] = $this->value['value'];
|
||||
}
|
||||
else {
|
||||
$use_minmax = $use_value = TRUE;
|
||||
}
|
||||
elseif ($which == 'value') {
|
||||
// When exposed we drop the value-value and just do value if
|
||||
// the operator is locked.
|
||||
$form['value'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => empty($form_state['exposed']) ? t('Value') : '',
|
||||
'#size' => 30,
|
||||
'#default_value' => $this->value['value'],
|
||||
);
|
||||
if (!empty($form_state['exposed']) && !isset($form_state['input'][$identifier])) {
|
||||
$form_state['input'][$identifier] = $this->value['value'];
|
||||
|
||||
if ($use_value) {
|
||||
if ($which == 'all') {
|
||||
$form['value']['value'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => empty($form_state['exposed']) ? t('Value') : '',
|
||||
'#size' => 30,
|
||||
'#default_value' => $this->value['value'],
|
||||
'#dependency' => array($source => $this->operator_values(1)),
|
||||
);
|
||||
if (!empty($form_state['exposed']) && !isset($form_state['input'][$identifier]['value'])) {
|
||||
$form_state['input'][$identifier]['value'] = $this->value['value'];
|
||||
}
|
||||
}
|
||||
elseif ($which == 'value') {
|
||||
// When exposed we drop the value-value and just do value if
|
||||
// the operator is locked.
|
||||
$form['value'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => empty($form_state['exposed']) ? t('Value') : '',
|
||||
'#size' => 30,
|
||||
'#default_value' => $this->value['value'],
|
||||
);
|
||||
if (!empty($form_state['exposed']) && !isset($form_state['input'][$identifier])) {
|
||||
$form_state['input'][$identifier] = $this->value['value'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($which == 'all' || $which == 'minmax') {
|
||||
$form['value']['min'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => empty($form_state['exposed']) ? t('Min') : '',
|
||||
'#size' => 30,
|
||||
'#default_value' => $this->value['min'],
|
||||
);
|
||||
$form['value']['max'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => empty($form_state['exposed']) ? t('And max') : t('And'),
|
||||
'#size' => 30,
|
||||
'#default_value' => $this->value['max'],
|
||||
);
|
||||
if ($which == 'all') {
|
||||
$dependency = array(
|
||||
'#dependency' => array($source => $this->operator_values(2)),
|
||||
if ($use_minmax) {
|
||||
$form['value']['min'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => empty($form_state['exposed']) ? t('Min') : '',
|
||||
'#size' => 30,
|
||||
'#default_value' => $this->value['min'],
|
||||
);
|
||||
$form['value']['min'] += $dependency;
|
||||
$form['value']['max'] += $dependency;
|
||||
$form['value']['max'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => empty($form_state['exposed']) ? t('And max') : t('And'),
|
||||
'#size' => 30,
|
||||
'#default_value' => $this->value['max'],
|
||||
);
|
||||
|
||||
if ($which == 'all') {
|
||||
$dependency = array(
|
||||
'#dependency' => array($source => $this->operator_values(2)),
|
||||
);
|
||||
|
||||
$form['value']['min'] += $dependency;
|
||||
$form['value']['max'] += $dependency;
|
||||
}
|
||||
}
|
||||
if (!empty($form_state['exposed']) && !isset($form_state['input'][$identifier]['min'])) {
|
||||
|
||||
if (!empty($form_state['exposed']) && !isset($form_state['input'][$identifier]['min']) && $use_minmax) {
|
||||
$form_state['input'][$identifier]['min'] = $this->value['min'];
|
||||
}
|
||||
if (!empty($form_state['exposed']) && !isset($form_state['input'][$identifier]['max'])) {
|
||||
if (!empty($form_state['exposed']) && !isset($form_state['input'][$identifier]['max']) && $use_minmax) {
|
||||
$form_state['input'][$identifier]['max'] = $this->value['max'];
|
||||
}
|
||||
|
||||
@ -291,6 +333,13 @@ class views_handler_filter_numeric extends views_handler_filter {
|
||||
$this->query->add_where($this->options['group'], $field, $this->value['value'], 'RLIKE');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function op_not_regex($field) {
|
||||
$this->query->add_where($this->options['group'], $field, $this->value['value'], 'NOT RLIKE');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -135,6 +135,12 @@ class views_handler_filter_string extends views_handler_filter {
|
||||
'method' => 'op_regex',
|
||||
'values' => 1,
|
||||
),
|
||||
'not_regular_expression' => array(
|
||||
'title' => t('Not regular expression'),
|
||||
'short' => t('not regex'),
|
||||
'method' => 'op_not_regex',
|
||||
'values' => 1,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@ -274,7 +280,9 @@ class views_handler_filter_string extends views_handler_filter {
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function op_contains($field) {
|
||||
$this->query->add_where($this->options['group'], $field, '%' . db_like($this->value) . '%', 'LIKE');
|
||||
if (!empty($this->value)) {
|
||||
$this->query->add_where($this->options['group'], $field, '%' . db_like($this->value) . '%', 'LIKE');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -371,6 +379,13 @@ class views_handler_filter_string extends views_handler_filter {
|
||||
$this->query->add_where($this->options['group'], $field, $this->value, 'RLIKE');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function op_not_regex($field) {
|
||||
$this->query->add_where($this->options['group'], $field, $this->value, 'NOT RLIKE');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -19,9 +19,9 @@ The "building block" design of the views system provides power and flexibility,
|
||||
|
||||
<li><a href="topic:views/header">Header</a>, which allow you to add by default one or more text area above the views output. </li>
|
||||
|
||||
<li><a href="topic:views/footer">Footer</a>, which allow you to add by default one or more text area beneath the views output. </li>
|
||||
<li><a href="topic:views/footer">Footer</a>, which allow you to add by default one or more text area beneath the views output. </li>
|
||||
|
||||
<li>The <a href="topic:views/footer">Emtpy Text</a> content will be displayed, when you choose in the Arguments Section "Action to take if argument is not present" the option "Display empty text".</li>
|
||||
<li>The <a href="topic:views/footer">Emtpy Text</a> content will be displayed, when you choose in the Arguments Section "Action to take if argument is not present" the option "Display empty text".</li>
|
||||
|
||||
|
||||
</ul>
|
||||
|
@ -1,10 +1,10 @@
|
||||
<h2>Troubleshooting UI crashes</h2>
|
||||
|
||||
There are a number of reasons why the Views UI may crash; the most common state or result of a crash is either a white screen (everyone's favorite WSOD), or a screen of what looks like garbage text. This is generally a javascript crash of some fashion.
|
||||
There are a number of reasons why the Views UI may crash; the most common state or result of a crash is either a white screen (everyone's favorite WSOD), or a screen of what looks like garbage text. This is generally JavaScript crash of some fashion.
|
||||
|
||||
To get the most timely and accurate help in the issue queue, please try to gather this information:
|
||||
|
||||
Check your javascript console. In Firefox, you can hit ctrl-shift-j or use firebug. Copy this information into the issue, or attach it as a text file. Really - this is the single biggest thing you can do to help figure out where the crash is coming from.
|
||||
Check your JavaScript console. In Firefox, you can hit ctrl-shift-j or use firebug. Copy this information into the issue, or attach it as a text file. Really - this is the single biggest thing you can do to help figure out where the crash is coming from.
|
||||
|
||||
|
||||
<h3>JSON prepends data with jQuery, causing editing and preview problems.</h3>
|
||||
|
@ -691,7 +691,7 @@ function views_ui_ajax_update_form($form, $form_state) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Non-Javascript fallback for updating the add view form.
|
||||
* Non-JavaScript fallback for updating the add view form.
|
||||
*/
|
||||
function views_ui_nojs_submit($form, &$form_state) {
|
||||
$form_state['rebuild'] = TRUE;
|
||||
@ -1598,7 +1598,7 @@ function views_ui_get_display_tab_details($view, $display) {
|
||||
$is_enabled = $display->handler->get_option('enabled');
|
||||
|
||||
if (!$is_display_deleted && $is_deletable && !$is_default) {
|
||||
$prefix = '<div class="ctools-no-js ctools-button ctools-dropbutton"><div class="ctools-link"><a href="#" class="ctools-twisty ctools-text">open</a></div><div class="ctools-content"><ul class="horizontal right actions">';
|
||||
$prefix = '<div class="ctools-no-js ctools-button ctools-dropbutton"><div class="ctools-link"><a href="#" class="ctools-twisty ctools-text"><span class="element-invisible">open</span></a></div><div class="ctools-content"><ul class="horizontal right actions">';
|
||||
$suffix = '</ul></div></div>';
|
||||
$item_element = 'li';
|
||||
}
|
||||
@ -2987,6 +2987,10 @@ function views_ui_add_form_to_stack($key, &$view, $display_id, $args, $top = FAL
|
||||
* together.
|
||||
*/
|
||||
function views_ui_ajax_form($js, $key, $view, $display_id = '') {
|
||||
$args = func_get_args();
|
||||
// Remove the known args.
|
||||
array_splice($args, 0, 4);
|
||||
|
||||
// Reset the cache of IDs. Drupal rather aggressively prevents id duplication
|
||||
// but this causes it to remember IDs that are no longer even being used.
|
||||
if (isset($_POST['ajax_html_ids'])) {
|
||||
@ -2999,9 +3003,6 @@ function views_ui_ajax_form($js, $key, $view, $display_id = '') {
|
||||
}
|
||||
|
||||
views_include('ajax');
|
||||
$args = func_get_args();
|
||||
// Remove the known args.
|
||||
array_splice($args, 0, 4);
|
||||
|
||||
$form_state = views_ui_build_form_state($js, $key, $view, $display_id, $args);
|
||||
// check to see if this is the top form of the stack. If it is, pop
|
||||
@ -3044,6 +3045,11 @@ function views_ui_ajax_form($js, $key, $view, $display_id = '') {
|
||||
$stack = $view->stack;
|
||||
$top = array_shift($stack);
|
||||
$top[0] = $js;
|
||||
|
||||
// Change view into a reference.
|
||||
$stepview = $top[2];
|
||||
$top[2] = &$stepview;
|
||||
|
||||
$form_state = call_user_func_array('views_ui_build_form_state', $top);
|
||||
$form_state['input'] = array();
|
||||
$form_state['url'] = url(views_ui_build_form_url($form_state));
|
||||
@ -3165,7 +3171,7 @@ function views_ui_reorder_displays_form($form, &$form_state) {
|
||||
$form['#title'] = t('Displays Reorder');
|
||||
$form['#section'] = 'reorder';
|
||||
|
||||
// Add javascript settings that will be added via $.extend for tabledragging.
|
||||
// Add JavaScript settings that will be added via $.extend for tabledragging.
|
||||
$form['#js']['tableDrag']['reorder-displays']['weight'][0] = array(
|
||||
'target' => 'weight',
|
||||
'source' => NULL,
|
||||
@ -3548,7 +3554,7 @@ function views_ui_rearrange_form($form, &$form_state) {
|
||||
);
|
||||
}
|
||||
|
||||
// Add javascript settings that will be added via $.extend for tabledragging.
|
||||
// Add JavaScript settings that will be added via $.extend for tabledragging.
|
||||
$form['#js']['tableDrag']['arrange']['weight'][0] = array(
|
||||
'target' => 'weight',
|
||||
'source' => NULL,
|
||||
@ -5036,7 +5042,7 @@ function views_ui_admin_settings_advanced() {
|
||||
$form['debug']['views_no_javascript'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Disable JavaScript with Views'),
|
||||
'#description' => t("If you are having problems with the JavaScript, you can disable it here. The Views UI should degrade and still be usable without javascript; it's just not as good."),
|
||||
'#description' => t("If you are having problems with the JavaScript, you can disable it here. The Views UI should degrade and still be usable without JavaScript; it's just not as good."),
|
||||
'#default_value' => variable_get('views_no_javascript', FALSE),
|
||||
);
|
||||
|
||||
|
@ -18,8 +18,8 @@ function views_ajax() {
|
||||
if (isset($_REQUEST['view_name']) && isset($_REQUEST['view_display_id'])) {
|
||||
$name = $_REQUEST['view_name'];
|
||||
$display_id = $_REQUEST['view_display_id'];
|
||||
$args = isset($_REQUEST['view_args']) && $_REQUEST['view_args'] !== '' ? explode('/', $_REQUEST['view_args']) : array();
|
||||
$path = isset($_REQUEST['view_path']) ? rawurldecode($_REQUEST['view_path']) : NULL;
|
||||
$args = isset($_REQUEST['view_args']) && $_REQUEST['view_args'] !== '' ? explode('/', htmlspecialchars_decode($_REQUEST['view_args'], ENT_QUOTES)) : array();
|
||||
$path = isset($_REQUEST['view_path']) ? htmlspecialchars_decode($_REQUEST['view_path'], ENT_QUOTES) : NULL;
|
||||
$dom_id = isset($_REQUEST['view_dom_id']) ? preg_replace('/[^a-zA-Z0-9_-]+/', '-', $_REQUEST['view_dom_id']) : NULL;
|
||||
$pager_element = isset($_REQUEST['pager_element']) ? intval($_REQUEST['pager_element']) : NULL;
|
||||
|
||||
@ -72,7 +72,8 @@ function views_ajax() {
|
||||
// Reuse the same DOM id so it matches that in Drupal.settings.
|
||||
$view->dom_id = $dom_id;
|
||||
|
||||
$commands[] = ajax_command_replace('.view-dom-id-' . $dom_id, $view->preview($display_id, $args));
|
||||
// Always return HTML with the same DOM ID that was sent by the browser.
|
||||
$commands[] = ajax_command_replace('.view-dom-id-' . $dom_id, preg_replace('/view-dom-id-[a-zA-Z0-9_-]+/', 'view-dom-id-' . $view->dom_id, $view->preview($display_id, $args), 1));
|
||||
}
|
||||
drupal_alter('views_ajax_data', $commands, $view);
|
||||
return array('#type' => 'ajax', '#commands' => $commands);
|
||||
|
@ -278,6 +278,9 @@ class views_handler extends views_object {
|
||||
return $title;
|
||||
}
|
||||
$title = ($short && isset($this->definition['title short'])) ? $this->definition['title short'] : $this->definition['title'];
|
||||
if (empty($this->definition['group'])) {
|
||||
return $title;
|
||||
}
|
||||
return t('!group: !title', array('!group' => $this->definition['group'], '!title' => $title));
|
||||
}
|
||||
|
||||
@ -418,8 +421,10 @@ class views_handler extends views_object {
|
||||
'#collapsed' => TRUE,
|
||||
'#weight' => 150,
|
||||
);
|
||||
|
||||
// Allow to alter the default values brought into the form.
|
||||
drupal_alter('views_handler_options', $this->options, $view);
|
||||
// Triggers hook_views_handler_options_alter().
|
||||
drupal_alter('views_handler_options', $this->options, $this);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1001,7 +1006,8 @@ class views_many_to_one_helper {
|
||||
|
||||
// Clone the join for each table:
|
||||
$this->handler->table_aliases = array();
|
||||
foreach ($this->handler->value as $value) {
|
||||
$values = $this->handler->operator === 'not' ? array($this->handler->value) : $this->handler->value;
|
||||
foreach ($values as $value) {
|
||||
$join = $this->get_join();
|
||||
if ($this->handler->operator == 'and') {
|
||||
$join->type = 'INNER';
|
||||
@ -1014,6 +1020,9 @@ class views_many_to_one_helper {
|
||||
'value' => $value,
|
||||
'numeric' => !empty($this->handler->definition['numeric']),
|
||||
);
|
||||
if (($this->handler->is_a_group() && is_array($value)) || $this->handler->operator === 'not') {
|
||||
$value = serialize($value);
|
||||
}
|
||||
// The table alias needs to be unique to this value across the
|
||||
// multiple times the filter or argument is called by the view.
|
||||
if (!isset($this->handler->view->many_to_one_aliases[$field][$value])) {
|
||||
@ -1028,6 +1037,9 @@ class views_many_to_one_helper {
|
||||
$this->handler->table_alias = $alias;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$this->handler->table_aliases[$value] = $this->handler->view->many_to_one_aliases[$field][$value];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $this->handler->table_alias;
|
||||
@ -1068,7 +1080,12 @@ class views_many_to_one_helper {
|
||||
}
|
||||
else {
|
||||
$value = is_array($value) ? array_pop($value) : $value;
|
||||
$operator = '=';
|
||||
if (is_array($value) && count($value) > 1) {
|
||||
$operator = 'IN';
|
||||
}
|
||||
else {
|
||||
$operator = '=';
|
||||
}
|
||||
}
|
||||
$add_condition = FALSE;
|
||||
}
|
||||
@ -1675,15 +1692,18 @@ class views_join {
|
||||
}
|
||||
|
||||
if (is_array($info['value'])) {
|
||||
$value_placeholders = array();
|
||||
|
||||
// With an array of values, we need multiple placeholders and the
|
||||
// 'IN' operator is implicit.
|
||||
foreach ($info['value'] as $value) {
|
||||
$placeholder_i = $view_query->placeholder('views_join_condition_');
|
||||
$value_placeholders[] = $placeholder_i;
|
||||
$arguments[$placeholder_i] = $value;
|
||||
}
|
||||
|
||||
$operator = !empty($info['operator']) ? $info['operator'] : 'IN';
|
||||
$placeholder = '( ' . implode(', ', array_keys($arguments)) . ' )';
|
||||
$placeholder = '( ' . implode(', ', $value_placeholders) . ' )';
|
||||
}
|
||||
else {
|
||||
// With a single value, the '=' operator is implicit.
|
||||
|
@ -843,7 +843,11 @@ class view extends views_db_object {
|
||||
|
||||
$argument->set_relationship();
|
||||
|
||||
$arg = isset($this->args[$position]) ? $this->args[$position] : NULL;
|
||||
$arg = NULL;
|
||||
if (isset($this->args[$position]) && $this->args[$position] !== '') {
|
||||
$arg = $this->args[$position];
|
||||
}
|
||||
|
||||
$argument->position = $position;
|
||||
|
||||
if (isset($arg) || $argument->has_default_argument()) {
|
||||
@ -1575,7 +1579,7 @@ class view extends views_db_object {
|
||||
/**
|
||||
* Override the view's current title.
|
||||
*
|
||||
* The tokens in the title get's replaced before rendering.
|
||||
* The tokens in the title get replaced before rendering.
|
||||
*/
|
||||
public function set_title($title) {
|
||||
$this->build_info['title'] = $title;
|
||||
@ -2008,7 +2012,7 @@ class view extends views_db_object {
|
||||
public function clone_view() {
|
||||
$clone = clone $this;
|
||||
|
||||
$keys = array('current_display', 'display_handler', 'build_info', 'built', 'executed', 'attachment_before', 'attachment_after', 'field', 'argument', 'filter', 'sort', 'relationship', 'header', 'footer', 'empty', 'query', 'inited', 'style_plugin', 'plugin_name', 'exposed_data', 'exposed_input', 'exposed_widgets', 'many_to_one_tables', 'feed_icon');
|
||||
$keys = array('current_display', 'display_handler', 'build_info', 'built', 'executed', 'attachment_before', 'attachment_after', 'field', 'argument', 'filter', 'sort', 'relationship', 'header', 'footer', 'empty', 'query', 'inited', 'style_plugin', 'plugin_name', 'exposed_data', 'exposed_input', 'exposed_widgets', 'many_to_one_aliases', 'many_to_one_tables', 'feed_icon');
|
||||
foreach ($keys as $key) {
|
||||
if (isset($clone->{$key})) {
|
||||
unset($clone->{$key});
|
||||
|
@ -20,7 +20,7 @@
|
||||
Drupal.views.instances = {};
|
||||
|
||||
/**
|
||||
* Javascript object for a certain view.
|
||||
* JavaScript object for a certain view.
|
||||
*/
|
||||
Drupal.views.ajaxView = function(settings) {
|
||||
var selector = '.view-dom-id-' + settings.view_dom_id;
|
||||
@ -69,9 +69,6 @@
|
||||
|
||||
// Add the ajax to pagers.
|
||||
this.$view
|
||||
// Don't attach to nested views. Doing so would attach multiple behaviors
|
||||
// to a given element.
|
||||
.filter(jQuery.proxy(this.filterNestedViews, this))
|
||||
.once(jQuery.proxy(this.attachPagerAjax, this));
|
||||
|
||||
// Add a trigger to update this view specifically. In order to trigger a
|
||||
@ -100,12 +97,6 @@
|
||||
this.exposedFormAjax = new Drupal.ajax($(button).attr('id'), button, this.element_settings);
|
||||
};
|
||||
|
||||
Drupal.views.ajaxView.prototype.filterNestedViews = function() {
|
||||
// If there is at least one parent with a view class, this view
|
||||
// is nested (e.g., an attachment). Bail.
|
||||
return !this.$view.parents('.view').length;
|
||||
};
|
||||
|
||||
/**
|
||||
* Attach the ajax behavior to each link.
|
||||
*/
|
||||
@ -119,8 +110,20 @@
|
||||
*/
|
||||
Drupal.views.ajaxView.prototype.attachPagerLinkAjax = function(id, link) {
|
||||
var $link = $(link);
|
||||
// Don't attach to pagers inside nested views.
|
||||
if ($link.closest('.view')[0] !== this.$view[0]) {
|
||||
return;
|
||||
}
|
||||
var viewData = {};
|
||||
var href = $link.attr('href');
|
||||
|
||||
// Provide a default page if none has been set. This must be done
|
||||
// prior to merging with settings to avoid accidentally using the
|
||||
// page landed on instead of page 1.
|
||||
if (typeof(viewData.page) === 'undefined') {
|
||||
viewData.page = 0;
|
||||
}
|
||||
|
||||
// Construct an object using the settings defaults and then overriding
|
||||
// with data specific to the link.
|
||||
$.extend(
|
||||
|
@ -10,7 +10,7 @@
|
||||
* @see views_ui.module
|
||||
* @see js/jquery.ui.dialog.min.js
|
||||
*
|
||||
* This javascript patch overwrites the $.ui.dialog.overlay.events object to remove
|
||||
* This JavaScript patch overwrites the $.ui.dialog.overlay.events object to remove
|
||||
* the mousedown, mouseup and click events from the list of events that are bound
|
||||
* in $.ui.dialog.overlay.create
|
||||
*
|
||||
|
@ -981,11 +981,11 @@ Drupal.viewsUi.resizeModal = function (e, no_shrink) {
|
||||
var difference = 0;
|
||||
difference += parseInt($scroll.css('padding-top'));
|
||||
difference += parseInt($scroll.css('padding-bottom'));
|
||||
difference += $('.views-override').outerHeight(true);
|
||||
difference += $('.views-messages').outerHeight(true);
|
||||
difference += $('#views-ajax-title').outerHeight(true);
|
||||
difference += $('.views-add-form-selected').outerHeight(true);
|
||||
difference += $('.form-buttons', $modal).outerHeight(true);
|
||||
difference += $('.views-override').outerHeight(true) || 0;
|
||||
difference += $('.views-messages').outerHeight(true) || 0;
|
||||
difference += $('#views-ajax-title').outerHeight(true) || 0;
|
||||
difference += $('.views-add-form-selected').outerHeight(true) || 0;
|
||||
difference += $('.form-buttons', $modal).outerHeight(true) || 0;
|
||||
|
||||
height = scrollHeight + difference;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @file
|
||||
* Javascript related to contextual links.
|
||||
* JavaScript related to contextual links.
|
||||
*/
|
||||
(function ($) {
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @file
|
||||
* Javascript related to the main view list.
|
||||
* JavaScript related to the main view list.
|
||||
*/
|
||||
(function ($) {
|
||||
|
||||
|
@ -11,12 +11,12 @@
|
||||
class views_plugin_row_aggregator_rss extends views_plugin_row {
|
||||
|
||||
/**
|
||||
*
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public $base_table = 'aggregator_item';
|
||||
|
||||
/**
|
||||
*
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public $base_field = 'iid';
|
||||
|
||||
@ -52,8 +52,8 @@ class views_plugin_row_aggregator_rss extends views_plugin_row {
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function render($row) {
|
||||
$iid = $row->{$this->field_alias};
|
||||
$sql = "SELECT ai.iid, ai.fid, ai.title, ai.link, ai.author, ai.description, ";
|
||||
$iid = $row->{$this->field_alias};
|
||||
$sql = "SELECT ai.iid, ai.fid, ai.title, ai.link, ai.author, ai.description, ";
|
||||
$sql .= "ai.timestamp, ai.guid, af.title AS feed_title, ai.link AS feed_LINK ";
|
||||
$sql .= "FROM {aggregator_item} ai LEFT JOIN {aggregator_feed} af ON ai.fid = af.fid ";
|
||||
$sql .= "WHERE ai.iid = :iid";
|
||||
@ -72,7 +72,7 @@ class views_plugin_row_aggregator_rss extends views_plugin_row {
|
||||
array(
|
||||
'key' => 'guid',
|
||||
'value' => $item->guid,
|
||||
'attributes' => array('isPermaLink' => 'false')
|
||||
'attributes' => array('isPermaLink' => 'false'),
|
||||
),
|
||||
);
|
||||
|
||||
@ -85,7 +85,7 @@ class views_plugin_row_aggregator_rss extends views_plugin_row {
|
||||
return theme($this->theme_functions(), array(
|
||||
'view' => $this->view,
|
||||
'options' => $this->options,
|
||||
'row' => $item
|
||||
'row' => $item,
|
||||
));
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user