From c97e0f8ba1129b7ad847926332013ffbc0aaf3d2 Mon Sep 17 00:00:00 2001 From: Bachir Soussi Chiadmi Date: Tue, 14 May 2019 10:14:51 +0200 Subject: [PATCH] updated i18n, views, imagestyleflush, field_group patch views_rss_media --- PATCH_LIST.md | 18 +- .../contrib/fields/field_group/CHANGELOG.txt | 31 + .../fields/field_group/field_group.api.php | 6 +- .../field_group/field_group.field_ui.inc | 8 +- .../fields/field_group/field_group.info | 6 +- .../fields/field_group/field_group.module | 47 +- .../horizontal-tabs/horizontal-tabs.js | 6 +- .../field_group/tests/field_group.ui.test | 2 +- .../field_group/tests/field_group_test.info | 6 +- .../contrib/files/imagestyleflush/README.txt | 5 + .../imagestyleflush/imagestyleflush.info | 6 +- .../imagestyleflush/imagestyleflush.install | 39 + .../imagestyleflush/imagestyleflush.module | 92 +- .../contrib/localisation/i18n/README.txt | 2 +- .../contrib/localisation/i18n/i18n.info | 7 +- .../contrib/localisation/i18n/i18n.module | 3 +- .../contrib/localisation/i18n/i18n.test | 2 +- .../localisation/i18n/i18n_block/README.txt | 92 ++ .../i18n/i18n_block/i18n_block.info | 7 +- .../i18n/i18n_block/i18n_block.module | 15 +- .../i18n/i18n_block/i18n_block.test | 5 +- .../localisation/i18n/i18n_contact/README.txt | 76 ++ .../i18n/i18n_contact/i18n_contact.info | 7 +- .../localisation/i18n/i18n_field/README.txt | 78 ++ .../i18n/i18n_field/i18n_field.i18n.inc | 2 +- .../i18n/i18n_field/i18n_field.info | 7 +- .../i18n/i18n_field/i18n_field.module | 124 ++ .../localisation/i18n/i18n_forum/README.txt | 86 ++ .../i18n/i18n_forum/i18n_forum.info | 7 +- .../localisation/i18n/i18n_menu/README.txt | 111 ++ .../i18n/i18n_menu/i18n_menu.info | 7 +- .../i18n/i18n_menu/i18n_menu.module | 154 +-- .../localisation/i18n/i18n_node/README.txt | 96 ++ .../i18n/i18n_node/i18n_node.info | 7 +- .../i18n/i18n_node/i18n_node.module | 42 +- .../i18n/i18n_node/i18n_node.variable.inc | 19 +- .../i18n/i18n_path/i18n_path.info | 7 +- .../i18n/i18n_redirect/README.txt | 82 ++ .../i18n/i18n_redirect/i18n_redirect.info | 7 +- .../localisation/i18n/i18n_select/README.txt | 82 ++ .../i18n/i18n_select/i18n_select.info | 7 +- .../i18n/i18n_select/i18n_select.module | 19 +- .../i18n/i18n_select/i18n_select.test | 84 ++ .../localisation/i18n/i18n_string/README.txt | 94 ++ .../i18n/i18n_string/i18n_string.inc | 28 +- .../i18n/i18n_string/i18n_string.info | 7 +- .../i18n/i18n_string/i18n_string.install | 19 + .../i18n/i18n_string/i18n_string.module | 74 +- .../i18n/i18n_string/i18n_string.pages.inc | 40 +- .../i18n/i18n_string/i18n_string.test | 2 +- .../i18n/i18n_string/i18n_string.variable.inc | 54 +- .../localisation/i18n/i18n_sync/README.txt | 2 +- .../i18n/i18n_sync/i18n_sync.info | 9 +- .../i18n/i18n_sync/i18n_sync.module | 32 +- .../i18n/i18n_sync/i18n_sync.node.inc | 2 +- .../i18n/i18n_taxonomy/README.txt | 103 ++ .../i18n/i18n_taxonomy/i18n_taxonomy.info | 7 +- .../i18n/i18n_taxonomy/i18n_taxonomy.module | 74 +- .../i18n_taxonomy/i18n_taxonomy.pages.inc | 2 +- .../i18n_taxonomy/i18n_taxonomy.tokens.inc | 10 + .../i18n_translation/i18n_translation.info | 7 +- .../i18n_translation/i18n_translation.module | 2 +- .../localisation/i18n/i18n_user/README.txt | 70 ++ .../i18n/i18n_user/i18n_user.info | 7 +- .../i18n/i18n_user/i18n_user.module | 9 +- .../i18n/i18n_variable/README.txt | 84 ++ .../i18n/i18n_variable/i18n_variable.info | 7 +- .../localisation/i18n/tests/i18n_test.info | 7 +- .../localisation/i18n/tests/i18n_test.module | 2 +- .../strict-warning-2149287-1.patch | 22 + .../views_rss_media/views_rss_media.install | 4 +- .../views/views/css/ie/views-admin.ie7.css | 2 +- .../contrib/views/views/css/views-admin.css | 4 +- .../contrib/views/views/drush/views.drush.inc | 5 +- .../handlers/views_handler_area_result.inc | 2 +- .../views/handlers/views_handler_argument.inc | 22 +- .../handlers/views_handler_argument_date.inc | 10 +- .../views_handler_argument_string.inc | 20 +- .../views/handlers/views_handler_field.inc | 26 +- .../handlers/views_handler_field_date.inc | 9 + .../handlers/views_handler_field_entity.inc | 4 +- .../handlers/views_handler_field_links.inc | 1 + .../handlers/views_handler_field_numeric.inc | 10 +- .../views/handlers/views_handler_filter.inc | 202 ++- .../handlers/views_handler_filter_combine.inc | 10 +- .../handlers/views_handler_filter_date.inc | 2 +- .../handlers/views_handler_filter_numeric.inc | 135 +- .../handlers/views_handler_filter_string.inc | 17 +- .../contrib/views/views/help/about.html | 4 +- .../contrib/views/views/help/ui-crashes.html | 4 +- .../contrib/views/views/includes/admin.inc | 22 +- .../contrib/views/views/includes/ajax.inc | 7 +- .../contrib/views/views/includes/handlers.inc | 28 +- .../contrib/views/views/includes/view.inc | 10 +- .../contrib/views/views/js/ajax_view.js | 23 +- .../views/views/js/jquery.ui.dialog.patch.js | 2 +- .../contrib/views/views/js/views-admin.js | 10 +- .../views/views/js/views-contextual.js | 2 +- .../contrib/views/views/js/views-list.js | 2 +- .../views_plugin_row_aggregator_rss.inc | 12 +- .../views/views/modules/comment.views.inc | 34 +- ...ews_handler_field_comment_link_approve.inc | 4 +- ...iews_handler_field_comment_link_delete.inc | 2 +- ...views_handler_field_comment_link_reply.inc | 4 +- .../field/views_handler_field_field.inc | 6 +- .../views/views/modules/node.views.inc | 30 +- .../views/views/modules/taxonomy.views.inc | 2 +- .../views_handler_field_term_link_edit.inc | 34 +- .../views_handler_filter_term_node_tid.inc | 34 +- ...plugin_argument_validate_taxonomy_term.inc | 2 +- ...iews_handler_field_node_link_translate.inc | 2 +- .../views/views/modules/user.views.inc | 23 +- .../modules/user/views_handler_field_user.inc | 4 +- .../views_handler_field_user_language.inc | 8 - .../user/views_handler_field_user_name.inc | 14 +- .../plugins/export_ui/views_ui.class.php | 4 +- .../views/plugins/views_plugin_cache.inc | 17 +- .../views/plugins/views_plugin_display.inc | 313 +++-- .../views_plugin_display_attachment.inc | 51 +- .../plugins/views_plugin_display_page.inc | 20 +- .../plugins/views_plugin_exposed_form.inc | 2 +- .../views/plugins/views_plugin_pager.inc | 8 +- .../views/plugins/views_plugin_pager_full.inc | 11 +- .../plugins/views_plugin_query_default.inc | 46 +- .../views/plugins/views_plugin_style.inc | 4 +- .../plugins/views_plugin_style_jump_menu.inc | 2 +- .../views_plugin_style_summary_jump_menu.inc | 2 +- .../plugins/views_plugin_style_table.inc | 13 +- .../views_handler_filter_numeric.test | 32 + .../handlers/views_handler_manytoone.test | 1099 +++++++++++++++++ .../tests/styles/views_plugin_style.test | 7 + .../user/views_handler_field_user_name.test | 59 + .../views/views/tests/views_clone.test | 277 +++++ .../views/views/tests/views_query.test | 17 + .../contrib/views/views/tests/views_test.info | 6 +- .../contrib/views/views/theme/theme.inc | 34 +- .../views/theme/views-ui-edit-view.tpl.php | 48 - .../modules/contrib/views/views/views.api.php | 4 +- .../modules/contrib/views/views/views.info | 8 +- .../modules/contrib/views/views/views.module | 72 +- .../modules/contrib/views/views/views_ui.info | 6 +- .../contrib/views/views/views_ui.module | 7 +- 142 files changed, 4489 insertions(+), 786 deletions(-) create mode 100644 sites/all/modules/contrib/files/imagestyleflush/imagestyleflush.install create mode 100644 sites/all/modules/contrib/localisation/i18n/i18n_block/README.txt create mode 100644 sites/all/modules/contrib/localisation/i18n/i18n_contact/README.txt create mode 100644 sites/all/modules/contrib/localisation/i18n/i18n_field/README.txt create mode 100644 sites/all/modules/contrib/localisation/i18n/i18n_forum/README.txt create mode 100644 sites/all/modules/contrib/localisation/i18n/i18n_menu/README.txt create mode 100644 sites/all/modules/contrib/localisation/i18n/i18n_node/README.txt create mode 100644 sites/all/modules/contrib/localisation/i18n/i18n_redirect/README.txt create mode 100644 sites/all/modules/contrib/localisation/i18n/i18n_select/README.txt create mode 100644 sites/all/modules/contrib/localisation/i18n/i18n_string/README.txt create mode 100644 sites/all/modules/contrib/localisation/i18n/i18n_taxonomy/README.txt create mode 100644 sites/all/modules/contrib/localisation/i18n/i18n_user/README.txt create mode 100644 sites/all/modules/contrib/localisation/i18n/i18n_variable/README.txt create mode 100644 sites/all/modules/contrib/rss/views_rss_media/strict-warning-2149287-1.patch create mode 100644 sites/all/modules/contrib/views/views/tests/handlers/views_handler_manytoone.test create mode 100644 sites/all/modules/contrib/views/views/tests/views_clone.test delete mode 100644 sites/all/modules/contrib/views/views/theme/views-ui-edit-view.tpl.php diff --git a/PATCH_LIST.md b/PATCH_LIST.md index 0dde4cca..17005240 100644 --- a/PATCH_LIST.md +++ b/PATCH_LIST.md @@ -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 diff --git a/sites/all/modules/contrib/fields/field_group/CHANGELOG.txt b/sites/all/modules/contrib/fields/field_group/CHANGELOG.txt index ea037d87..5798162a 100644 --- a/sites/all/modules/contrib/fields/field_group/CHANGELOG.txt +++ b/sites/all/modules/contrib/fields/field_group/CHANGELOG.txt @@ -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. diff --git a/sites/all/modules/contrib/fields/field_group/field_group.api.php b/sites/all/modules/contrib/fields/field_group/field_group.api.php index cef5b0a8..fdcbe031 100644 --- a/sites/all/modules/contrib/fields/field_group/field_group.api.php +++ b/sites/all/modules/contrib/fields/field_group/field_group.api.php @@ -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']); diff --git a/sites/all/modules/contrib/fields/field_group/field_group.field_ui.inc b/sites/all/modules/contrib/fields/field_group/field_group.field_ui.inc index 8872e386..dbd26d0e 100644 --- a/sites/all/modules/contrib/fields/field_group/field_group.field_ui.inc +++ b/sites/all/modules/contrib/fields/field_group/field_group.field_ui.inc @@ -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'])) { diff --git a/sites/all/modules/contrib/fields/field_group/field_group.info b/sites/all/modules/contrib/fields/field_group/field_group.info index 912b55f7..49eae8dd 100644 --- a/sites/all/modules/contrib/fields/field_group/field_group.info +++ b/sites/all/modules/contrib/fields/field_group/field_group.info @@ -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" diff --git a/sites/all/modules/contrib/fields/field_group/field_group.module b/sites/all/modules/contrib/fields/field_group/field_group.module index 4061519f..4fe2547a 100644 --- a/sites/all/modules/contrib/fields/field_group/field_group.module +++ b/sites/all/modules/contrib/fields/field_group/field_group.module @@ -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. * diff --git a/sites/all/modules/contrib/fields/field_group/horizontal-tabs/horizontal-tabs.js b/sites/all/modules/contrib/fields/field_group/horizontal-tabs/horizontal-tabs.js index 977e1b6c..6429f90f 100644 --- a/sites/all/modules/contrib/fields/field_group/horizontal-tabs/horizontal-tabs.js +++ b/sites/all/modules/contrib/fields/field_group/horizontal-tabs/horizontal-tabs.js @@ -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); diff --git a/sites/all/modules/contrib/fields/field_group/tests/field_group.ui.test b/sites/all/modules/contrib/fields/field_group/tests/field_group.ui.test index 55fa595b..6c4436a9 100644 --- a/sites/all/modules/contrib/fields/field_group/tests/field_group.ui.test +++ b/sites/all/modules/contrib/fields/field_group/tests/field_group.ui.test @@ -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); } diff --git a/sites/all/modules/contrib/fields/field_group/tests/field_group_test.info b/sites/all/modules/contrib/fields/field_group/tests/field_group_test.info index 4391b929..22bd9219 100644 --- a/sites/all/modules/contrib/fields/field_group/tests/field_group_test.info +++ b/sites/all/modules/contrib/fields/field_group/tests/field_group_test.info @@ -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" diff --git a/sites/all/modules/contrib/files/imagestyleflush/README.txt b/sites/all/modules/contrib/files/imagestyleflush/README.txt index 6b784545..8c170d7c 100644 --- a/sites/all/modules/contrib/files/imagestyleflush/README.txt +++ b/sites/all/modules/contrib/files/imagestyleflush/README.txt @@ -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 -------------- diff --git a/sites/all/modules/contrib/files/imagestyleflush/imagestyleflush.info b/sites/all/modules/contrib/files/imagestyleflush/imagestyleflush.info index ee1a7b66..259ae7c1 100644 --- a/sites/all/modules/contrib/files/imagestyleflush/imagestyleflush.info +++ b/sites/all/modules/contrib/files/imagestyleflush/imagestyleflush.info @@ -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" diff --git a/sites/all/modules/contrib/files/imagestyleflush/imagestyleflush.install b/sites/all/modules/contrib/files/imagestyleflush/imagestyleflush.install new file mode 100644 index 00000000..8c004816 --- /dev/null +++ b/sites/all/modules/contrib/files/imagestyleflush/imagestyleflush.install @@ -0,0 +1,39 @@ +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(); + } + } +} diff --git a/sites/all/modules/contrib/files/imagestyleflush/imagestyleflush.module b/sites/all/modules/contrib/files/imagestyleflush/imagestyleflush.module index a02a6631..1e5f518c 100644 --- a/sites/all/modules/contrib/files/imagestyleflush/imagestyleflush.module +++ b/sites/all/modules/contrib/files/imagestyleflush/imagestyleflush.module @@ -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. Add a new one.', 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.'), + '' . t('Note: this will only flush the images. It will not rebuild them.') + . '

' . 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.'), + '' . t('Note: this will only flush the images. It will not rebuild them.') + . '

' . 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; + } } diff --git a/sites/all/modules/contrib/localisation/i18n/README.txt b/sites/all/modules/contrib/localisation/i18n/README.txt index 5a8a4f14..060563bb 100644 --- a/sites/all/modules/contrib/localisation/i18n/README.txt +++ b/sites/all/modules/contrib/localisation/i18n/README.txt @@ -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 ==================================================================== diff --git a/sites/all/modules/contrib/localisation/i18n/i18n.info b/sites/all/modules/contrib/localisation/i18n/i18n.info index 335533f9..46f21698 100644 --- a/sites/all/modules/contrib/localisation/i18n/i18n.info +++ b/sites/all/modules/contrib/localisation/i18n/i18n.info @@ -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" diff --git a/sites/all/modules/contrib/localisation/i18n/i18n.module b/sites/all/modules/contrib/localisation/i18n/i18n.module index b65061dc..4985271f 100644 --- a/sites/all/modules/contrib/localisation/i18n/i18n.module +++ b/sites/all/modules/contrib/localisation/i18n/i18n.module @@ -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); } /** diff --git a/sites/all/modules/contrib/localisation/i18n/i18n.test b/sites/all/modules/contrib/localisation/i18n/i18n.test index 8e979100..2a82e17a 100644 --- a/sites/all/modules/contrib/localisation/i18n/i18n.test +++ b/sites/all/modules/contrib/localisation/i18n/i18n.test @@ -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); diff --git a/sites/all/modules/contrib/localisation/i18n/i18n_block/README.txt b/sites/all/modules/contrib/localisation/i18n/i18n_block/README.txt new file mode 100644 index 00000000..a4e80ad9 --- /dev/null +++ b/sites/all/modules/contrib/localisation/i18n/i18n_block/README.txt @@ -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 diff --git a/sites/all/modules/contrib/localisation/i18n/i18n_block/i18n_block.info b/sites/all/modules/contrib/localisation/i18n/i18n_block/i18n_block.info index 5497d05b..89cf38b8 100644 --- a/sites/all/modules/contrib/localisation/i18n/i18n_block/i18n_block.info +++ b/sites/all/modules/contrib/localisation/i18n/i18n_block/i18n_block.info @@ -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" diff --git a/sites/all/modules/contrib/localisation/i18n/i18n_block/i18n_block.module b/sites/all/modules/contrib/localisation/i18n/i18n_block/i18n_block.module index 5328a5fc..6c8c79bb 100644 --- a/sites/all/modules/contrib/localisation/i18n/i18n_block/i18n_block.module +++ b/sites/all/modules/contrib/localisation/i18n/i18n_block/i18n_block.module @@ -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', diff --git a/sites/all/modules/contrib/localisation/i18n/i18n_block/i18n_block.test b/sites/all/modules/contrib/localisation/i18n/i18n_block/i18n_block.test index b1e46809..e33d99ef 100644 --- a/sites/all/modules/contrib/localisation/i18n/i18n_block/i18n_block.test +++ b/sites/all/modules/contrib/localisation/i18n/i18n_block/i18n_block.test @@ -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.'); diff --git a/sites/all/modules/contrib/localisation/i18n/i18n_contact/README.txt b/sites/all/modules/contrib/localisation/i18n/i18n_contact/README.txt new file mode 100644 index 00000000..73d94a3f --- /dev/null +++ b/sites/all/modules/contrib/localisation/i18n/i18n_contact/README.txt @@ -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 diff --git a/sites/all/modules/contrib/localisation/i18n/i18n_contact/i18n_contact.info b/sites/all/modules/contrib/localisation/i18n/i18n_contact/i18n_contact.info index 225e780a..76978ff1 100644 --- a/sites/all/modules/contrib/localisation/i18n/i18n_contact/i18n_contact.info +++ b/sites/all/modules/contrib/localisation/i18n/i18n_contact/i18n_contact.info @@ -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" diff --git a/sites/all/modules/contrib/localisation/i18n/i18n_field/README.txt b/sites/all/modules/contrib/localisation/i18n/i18n_field/README.txt new file mode 100644 index 00000000..04d038ef --- /dev/null +++ b/sites/all/modules/contrib/localisation/i18n/i18n_field/README.txt @@ -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 diff --git a/sites/all/modules/contrib/localisation/i18n/i18n_field/i18n_field.i18n.inc b/sites/all/modules/contrib/localisation/i18n/i18n_field/i18n_field.i18n.inc index 1e31c483..c1e6e9c4 100644 --- a/sites/all/modules/contrib/localisation/i18n/i18n_field/i18n_field.i18n.inc +++ b/sites/all/modules/contrib/localisation/i18n/i18n_field/i18n_field.i18n.inc @@ -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; } diff --git a/sites/all/modules/contrib/localisation/i18n/i18n_field/i18n_field.info b/sites/all/modules/contrib/localisation/i18n/i18n_field/i18n_field.info index c5596edc..b3596f9c 100644 --- a/sites/all/modules/contrib/localisation/i18n/i18n_field/i18n_field.info +++ b/sites/all/modules/contrib/localisation/i18n/i18n_field/i18n_field.info @@ -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" diff --git a/sites/all/modules/contrib/localisation/i18n/i18n_field/i18n_field.module b/sites/all/modules/contrib/localisation/i18n/i18n_field/i18n_field.module index eadd2f5c..6f97006b 100644 --- a/sites/all/modules/contrib/localisation/i18n/i18n_field/i18n_field.module +++ b/sites/all/modules/contrib/localisation/i18n/i18n_field/i18n_field.module @@ -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; + } +} diff --git a/sites/all/modules/contrib/localisation/i18n/i18n_forum/README.txt b/sites/all/modules/contrib/localisation/i18n/i18n_forum/README.txt new file mode 100644 index 00000000..8b0a0cdf --- /dev/null +++ b/sites/all/modules/contrib/localisation/i18n/i18n_forum/README.txt @@ -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 diff --git a/sites/all/modules/contrib/localisation/i18n/i18n_forum/i18n_forum.info b/sites/all/modules/contrib/localisation/i18n/i18n_forum/i18n_forum.info index 5c0f0a10..17e7f0e5 100644 --- a/sites/all/modules/contrib/localisation/i18n/i18n_forum/i18n_forum.info +++ b/sites/all/modules/contrib/localisation/i18n/i18n_forum/i18n_forum.info @@ -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" diff --git a/sites/all/modules/contrib/localisation/i18n/i18n_menu/README.txt b/sites/all/modules/contrib/localisation/i18n/i18n_menu/README.txt new file mode 100644 index 00000000..4f5c935b --- /dev/null +++ b/sites/all/modules/contrib/localisation/i18n/i18n_menu/README.txt @@ -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 diff --git a/sites/all/modules/contrib/localisation/i18n/i18n_menu/i18n_menu.info b/sites/all/modules/contrib/localisation/i18n/i18n_menu/i18n_menu.info index 98938d5e..6b03ca65 100644 --- a/sites/all/modules/contrib/localisation/i18n/i18n_menu/i18n_menu.info +++ b/sites/all/modules/contrib/localisation/i18n/i18n_menu/i18n_menu.info @@ -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" diff --git a/sites/all/modules/contrib/localisation/i18n/i18n_menu/i18n_menu.module b/sites/all/modules/contrib/localisation/i18n/i18n_menu/i18n_menu.module index b7bd7374..46ce7388 100644 --- a/sites/all/modules/contrib/localisation/i18n/i18n_menu/i18n_menu.module +++ b/sites/all/modules/contrib/localisation/i18n/i18n_menu/i18n_menu.module @@ -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; } } } diff --git a/sites/all/modules/contrib/localisation/i18n/i18n_node/README.txt b/sites/all/modules/contrib/localisation/i18n/i18n_node/README.txt new file mode 100644 index 00000000..c65e1c13 --- /dev/null +++ b/sites/all/modules/contrib/localisation/i18n/i18n_node/README.txt @@ -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 diff --git a/sites/all/modules/contrib/localisation/i18n/i18n_node/i18n_node.info b/sites/all/modules/contrib/localisation/i18n/i18n_node/i18n_node.info index b5b50289..45c78290 100644 --- a/sites/all/modules/contrib/localisation/i18n/i18n_node/i18n_node.info +++ b/sites/all/modules/contrib/localisation/i18n/i18n_node/i18n_node.info @@ -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" diff --git a/sites/all/modules/contrib/localisation/i18n/i18n_node/i18n_node.module b/sites/all/modules/contrib/localisation/i18n/i18n_node/i18n_node.module index 8f14bcd9..b6957e8f 100644 --- a/sites/all/modules/contrib/localisation/i18n/i18n_node/i18n_node.module +++ b/sites/all/modules/contrib/localisation/i18n/i18n_node/i18n_node.module @@ -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. diff --git a/sites/all/modules/contrib/localisation/i18n/i18n_node/i18n_node.variable.inc b/sites/all/modules/contrib/localisation/i18n/i18n_node/i18n_node.variable.inc index 9362fc3f..b9b0495f 100644 --- a/sites/all/modules/contrib/localisation/i18n/i18n_node/i18n_node.variable.inc +++ b/sites/all/modules/contrib/localisation/i18n/i18n_node/i18n_node.variable.inc @@ -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'), diff --git a/sites/all/modules/contrib/localisation/i18n/i18n_path/i18n_path.info b/sites/all/modules/contrib/localisation/i18n/i18n_path/i18n_path.info index 3fec36ec..cba9b1fa 100644 --- a/sites/all/modules/contrib/localisation/i18n/i18n_path/i18n_path.info +++ b/sites/all/modules/contrib/localisation/i18n/i18n_path/i18n_path.info @@ -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" diff --git a/sites/all/modules/contrib/localisation/i18n/i18n_redirect/README.txt b/sites/all/modules/contrib/localisation/i18n/i18n_redirect/README.txt new file mode 100644 index 00000000..fd262af1 --- /dev/null +++ b/sites/all/modules/contrib/localisation/i18n/i18n_redirect/README.txt @@ -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 diff --git a/sites/all/modules/contrib/localisation/i18n/i18n_redirect/i18n_redirect.info b/sites/all/modules/contrib/localisation/i18n/i18n_redirect/i18n_redirect.info index 978e695e..7d6567de 100644 --- a/sites/all/modules/contrib/localisation/i18n/i18n_redirect/i18n_redirect.info +++ b/sites/all/modules/contrib/localisation/i18n/i18n_redirect/i18n_redirect.info @@ -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" diff --git a/sites/all/modules/contrib/localisation/i18n/i18n_select/README.txt b/sites/all/modules/contrib/localisation/i18n/i18n_select/README.txt new file mode 100644 index 00000000..ba8c432c --- /dev/null +++ b/sites/all/modules/contrib/localisation/i18n/i18n_select/README.txt @@ -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 diff --git a/sites/all/modules/contrib/localisation/i18n/i18n_select/i18n_select.info b/sites/all/modules/contrib/localisation/i18n/i18n_select/i18n_select.info index ded2059c..25902957 100644 --- a/sites/all/modules/contrib/localisation/i18n/i18n_select/i18n_select.info +++ b/sites/all/modules/contrib/localisation/i18n/i18n_select/i18n_select.info @@ -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" diff --git a/sites/all/modules/contrib/localisation/i18n/i18n_select/i18n_select.module b/sites/all/modules/contrib/localisation/i18n/i18n_select/i18n_select.module index bcba5782..9063fe9d 100644 --- a/sites/all/modules/contrib/localisation/i18n/i18n_select/i18n_select.module +++ b/sites/all/modules/contrib/localisation/i18n/i18n_select/i18n_select.module @@ -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; } } diff --git a/sites/all/modules/contrib/localisation/i18n/i18n_select/i18n_select.test b/sites/all/modules/contrib/localisation/i18n/i18n_select/i18n_select.test index b46fb986..5af85431 100644 --- a/sites/all/modules/contrib/localisation/i18n/i18n_select/i18n_select.test +++ b/sites/all/modules/contrib/localisation/i18n/i18n_select/i18n_select.test @@ -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'); + } + +} diff --git a/sites/all/modules/contrib/localisation/i18n/i18n_string/README.txt b/sites/all/modules/contrib/localisation/i18n/i18n_string/README.txt new file mode 100644 index 00000000..673a3f3e --- /dev/null +++ b/sites/all/modules/contrib/localisation/i18n/i18n_string/README.txt @@ -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 diff --git a/sites/all/modules/contrib/localisation/i18n/i18n_string/i18n_string.inc b/sites/all/modules/contrib/localisation/i18n/i18n_string/i18n_string.inc index 33fa444d..65b4efa7 100644 --- a/sites/all/modules/contrib/localisation/i18n/i18n_string/i18n_string.inc +++ b/sites/all/modules/contrib/localisation/i18n/i18n_string/i18n_string.inc @@ -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; } } } diff --git a/sites/all/modules/contrib/localisation/i18n/i18n_string/i18n_string.info b/sites/all/modules/contrib/localisation/i18n/i18n_string/i18n_string.info index 06152042..fec3d948 100644 --- a/sites/all/modules/contrib/localisation/i18n/i18n_string/i18n_string.info +++ b/sites/all/modules/contrib/localisation/i18n/i18n_string/i18n_string.info @@ -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" diff --git a/sites/all/modules/contrib/localisation/i18n/i18n_string/i18n_string.install b/sites/all/modules/contrib/localisation/i18n/i18n_string/i18n_string.install index 30e8cd26..23987920 100644 --- a/sites/all/modules/contrib/localisation/i18n/i18n_string/i18n_string.install +++ b/sites/all/modules/contrib/localisation/i18n/i18n_string/i18n_string.install @@ -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 diff --git a/sites/all/modules/contrib/localisation/i18n/i18n_string/i18n_string.module b/sites/all/modules/contrib/localisation/i18n/i18n_string/i18n_string.module index 9c232c08..1fe45d6b 100644 --- a/sites/all/modules/contrib/localisation/i18n/i18n_string/i18n_string.module +++ b/sites/all/modules/contrib/localisation/i18n/i18n_string/i18n_string.module @@ -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)); diff --git a/sites/all/modules/contrib/localisation/i18n/i18n_string/i18n_string.pages.inc b/sites/all/modules/contrib/localisation/i18n/i18n_string/i18n_string.pages.inc index 4d0da59c..fd657b5a 100644 --- a/sites/all/modules/contrib/localisation/i18n/i18n_string/i18n_string.pages.inc +++ b/sites/all/modules/contrib/localisation/i18n/i18n_string/i18n_string.pages.inc @@ -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); } diff --git a/sites/all/modules/contrib/localisation/i18n/i18n_string/i18n_string.test b/sites/all/modules/contrib/localisation/i18n/i18n_string/i18n_string.test index d4563405..9e52dfa0 100644 --- a/sites/all/modules/contrib/localisation/i18n/i18n_string/i18n_string.test +++ b/sites/all/modules/contrib/localisation/i18n/i18n_string/i18n_string.test @@ -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; diff --git a/sites/all/modules/contrib/localisation/i18n/i18n_string/i18n_string.variable.inc b/sites/all/modules/contrib/localisation/i18n/i18n_string/i18n_string.variable.inc index cb677e3c..932751f1 100644 --- a/sites/all/modules/contrib/localisation/i18n/i18n_string/i18n_string.variable.inc +++ b/sites/all/modules/contrib/localisation/i18n/i18n_string/i18n_string.variable.inc @@ -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()); -} \ No newline at end of file +} + +/** + * 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); +} diff --git a/sites/all/modules/contrib/localisation/i18n/i18n_sync/README.txt b/sites/all/modules/contrib/localisation/i18n/i18n_sync/README.txt index ce7ea6aa..c106dcb6 100644 --- a/sites/all/modules/contrib/localisation/i18n/i18n_sync/README.txt +++ b/sites/all/modules/contrib/localisation/i18n/i18n_sync/README.txt @@ -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: diff --git a/sites/all/modules/contrib/localisation/i18n/i18n_sync/i18n_sync.info b/sites/all/modules/contrib/localisation/i18n/i18n_sync/i18n_sync.info index c22a68ad..b42a9d92 100644 --- a/sites/all/modules/contrib/localisation/i18n/i18n_sync/i18n_sync.info +++ b/sites/all/modules/contrib/localisation/i18n/i18n_sync/i18n_sync.info @@ -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" diff --git a/sites/all/modules/contrib/localisation/i18n/i18n_sync/i18n_sync.module b/sites/all/modules/contrib/localisation/i18n/i18n_sync/i18n_sync.module index 8aaadbec..8a5ec5c3 100644 --- a/sites/all/modules/contrib/localisation/i18n/i18n_sync/i18n_sync.module +++ b/sites/all/modules/contrib/localisation/i18n/i18n_sync/i18n_sync.module @@ -33,7 +33,7 @@ function i18n_sync($status = NULL) { function i18n_sync_help($path, $arg) { switch ($path) { case 'admin/help#i18n_sync' : - $output = '

' . t('This module synchronizes content taxonomy and fields accross translations:') . '

'; + $output = '

' . t('This module synchronizes content taxonomy and fields across translations:') . '

'; $output .= '

' . 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:') . '

'; $output .= ' diff --git a/sites/all/modules/contrib/views/views/help/ui-crashes.html b/sites/all/modules/contrib/views/views/help/ui-crashes.html index da0ca4fd..6c207949 100644 --- a/sites/all/modules/contrib/views/views/help/ui-crashes.html +++ b/sites/all/modules/contrib/views/views/help/ui-crashes.html @@ -1,10 +1,10 @@

Troubleshooting UI crashes

-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.

JSON prepends data with jQuery, causing editing and preview problems.

diff --git a/sites/all/modules/contrib/views/views/includes/admin.inc b/sites/all/modules/contrib/views/views/includes/admin.inc index a8211b03..810c70fc 100644 --- a/sites/all/modules/contrib/views/views/includes/admin.inc +++ b/sites/all/modules/contrib/views/views/includes/admin.inc @@ -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 = '
    '; + $prefix = '
      '; $suffix = '
    '; $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), ); diff --git a/sites/all/modules/contrib/views/views/includes/ajax.inc b/sites/all/modules/contrib/views/views/includes/ajax.inc index e7b3789d..37eee9c7 100644 --- a/sites/all/modules/contrib/views/views/includes/ajax.inc +++ b/sites/all/modules/contrib/views/views/includes/ajax.inc @@ -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); diff --git a/sites/all/modules/contrib/views/views/includes/handlers.inc b/sites/all/modules/contrib/views/views/includes/handlers.inc index d631c052..8c2f8ece 100644 --- a/sites/all/modules/contrib/views/views/includes/handlers.inc +++ b/sites/all/modules/contrib/views/views/includes/handlers.inc @@ -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. diff --git a/sites/all/modules/contrib/views/views/includes/view.inc b/sites/all/modules/contrib/views/views/includes/view.inc index ae6df4c6..4f26650b 100644 --- a/sites/all/modules/contrib/views/views/includes/view.inc +++ b/sites/all/modules/contrib/views/views/includes/view.inc @@ -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}); diff --git a/sites/all/modules/contrib/views/views/js/ajax_view.js b/sites/all/modules/contrib/views/views/js/ajax_view.js index c3e5bb92..5012c33e 100644 --- a/sites/all/modules/contrib/views/views/js/ajax_view.js +++ b/sites/all/modules/contrib/views/views/js/ajax_view.js @@ -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( diff --git a/sites/all/modules/contrib/views/views/js/jquery.ui.dialog.patch.js b/sites/all/modules/contrib/views/views/js/jquery.ui.dialog.patch.js index bc468f75..0b099ce9 100644 --- a/sites/all/modules/contrib/views/views/js/jquery.ui.dialog.patch.js +++ b/sites/all/modules/contrib/views/views/js/jquery.ui.dialog.patch.js @@ -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 * diff --git a/sites/all/modules/contrib/views/views/js/views-admin.js b/sites/all/modules/contrib/views/views/js/views-admin.js index 3c557501..807d7f7b 100644 --- a/sites/all/modules/contrib/views/views/js/views-admin.js +++ b/sites/all/modules/contrib/views/views/js/views-admin.js @@ -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; diff --git a/sites/all/modules/contrib/views/views/js/views-contextual.js b/sites/all/modules/contrib/views/views/js/views-contextual.js index 5245af6f..09fabc9d 100644 --- a/sites/all/modules/contrib/views/views/js/views-contextual.js +++ b/sites/all/modules/contrib/views/views/js/views-contextual.js @@ -1,6 +1,6 @@ /** * @file - * Javascript related to contextual links. + * JavaScript related to contextual links. */ (function ($) { diff --git a/sites/all/modules/contrib/views/views/js/views-list.js b/sites/all/modules/contrib/views/views/js/views-list.js index be67103c..d7a274dc 100644 --- a/sites/all/modules/contrib/views/views/js/views-list.js +++ b/sites/all/modules/contrib/views/views/js/views-list.js @@ -1,6 +1,6 @@ /** * @file - * Javascript related to the main view list. + * JavaScript related to the main view list. */ (function ($) { diff --git a/sites/all/modules/contrib/views/views/modules/aggregator/views_plugin_row_aggregator_rss.inc b/sites/all/modules/contrib/views/views/modules/aggregator/views_plugin_row_aggregator_rss.inc index ca5ab60d..72e94188 100644 --- a/sites/all/modules/contrib/views/views/modules/aggregator/views_plugin_row_aggregator_rss.inc +++ b/sites/all/modules/contrib/views/views/modules/aggregator/views_plugin_row_aggregator_rss.inc @@ -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, )); } diff --git a/sites/all/modules/contrib/views/views/modules/comment.views.inc b/sites/all/modules/contrib/views/views/modules/comment.views.inc index 17c31c77..3cecfcc2 100644 --- a/sites/all/modules/contrib/views/views/modules/comment.views.inc +++ b/sites/all/modules/contrib/views/views/modules/comment.views.inc @@ -133,8 +133,8 @@ function comment_views_data() { // Email address. $data['comment']['mail'] = array( - 'title' => t('Mail'), - 'help' => t('Email of user that posted the comment. Will be empty if the author is a registered user.'), + 'title' => t('E-mail'), + 'help' => t('E-mail of user that posted the comment. Will be empty if the author is a registered user.'), 'field' => array( 'handler' => 'views_handler_field', 'click sortable' => TRUE, @@ -320,7 +320,7 @@ function comment_views_data() { // Status (approved or not). $data['comment']['status'] = array( - 'title' => t('Approved'), + 'title' => t('Approved status'), 'help' => t('Whether the comment is approved (or still in the moderation queue).'), 'field' => array( 'handler' => 'views_handler_field_boolean', @@ -331,7 +331,7 @@ function comment_views_data() { ), 'filter' => array( 'handler' => 'views_handler_filter_boolean_operator', - 'label' => t('Approved comment'), + 'label' => t('Approved comment status'), 'type' => 'yes-no', ), 'sort' => array( @@ -342,7 +342,7 @@ function comment_views_data() { // Link to view comment. $data['comment']['view_comment'] = array( 'field' => array( - 'title' => t('View link'), + 'title' => t('Link to comment'), 'help' => t('Provide a simple link to view the comment.'), 'handler' => 'views_handler_field_comment_link', ), @@ -351,7 +351,7 @@ function comment_views_data() { // Link to edit comment. $data['comment']['edit_comment'] = array( 'field' => array( - 'title' => t('Edit link'), + 'title' => t('Link to edit comment'), 'help' => t('Provide a simple link to edit the comment.'), 'handler' => 'views_handler_field_comment_link_edit', ), @@ -360,7 +360,7 @@ function comment_views_data() { // Link to delete comment. $data['comment']['delete_comment'] = array( 'field' => array( - 'title' => t('Delete link'), + 'title' => t('Link to delete comment'), 'help' => t('Provide a simple link to delete the comment.'), 'handler' => 'views_handler_field_comment_link_delete', ), @@ -369,7 +369,7 @@ function comment_views_data() { // Link to approve comment. $data['comment']['approve_comment'] = array( 'field' => array( - 'title' => t('Approve link'), + 'title' => t('Link to approve comment'), 'help' => t('Provide a simple link to approve the comment.'), 'handler' => 'views_handler_field_comment_link_approve', ), @@ -378,7 +378,7 @@ function comment_views_data() { // Link to reply to comment. $data['comment']['replyto_comment'] = array( 'field' => array( - 'title' => t('Reply-to link'), + 'title' => t('Link to reply-to comment'), 'help' => t('Provide a simple link to reply to the comment.'), 'handler' => 'views_handler_field_comment_link_reply', ), @@ -419,6 +419,20 @@ function comment_views_data() { ), ); + $data['comment']['cid'] = array( + 'title' => t('Comment id'), + 'help' => t('Unique identifier for the comment.'), + 'filter' => array( + 'handler' => 'views_handler_filter_numeric', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_numeric', + ), + 'field' => array( + 'handler' => 'views_handler_field_numeric', + ), + ); + $data['comment']['uid'] = array( 'title' => t('Author uid'), 'help' => t('If you need more fields than the uid add the comment: author relationship'), @@ -544,7 +558,7 @@ function comment_views_data() { 'title' => t('Last comment CID'), 'help' => t('Display the last comment of a node'), 'relationship' => array( - 'title' => t('Last Comment'), + 'title' => t('Last comment'), 'help' => t('The last comment of a node.'), 'group' => t('Comment'), 'base' => 'comment', diff --git a/sites/all/modules/contrib/views/views/modules/comment/views_handler_field_comment_link_approve.inc b/sites/all/modules/contrib/views/views/modules/comment/views_handler_field_comment_link_approve.inc index b161eeb0..6776a6c6 100644 --- a/sites/all/modules/contrib/views/views/modules/comment/views_handler_field_comment_link_approve.inc +++ b/sites/all/modules/contrib/views/views/modules/comment/views_handler_field_comment_link_approve.inc @@ -16,7 +16,7 @@ class views_handler_field_comment_link_approve extends views_handler_field_comme * {@inheritdoc} */ public function access() { - //needs permission to administer comments in general + // Needs permission to administer comments in general. return user_access('administer comments'); } @@ -32,7 +32,7 @@ class views_handler_field_comment_link_approve extends views_handler_field_comme } $text = !empty($this->options['text']) ? $this->options['text'] : t('approve'); - $cid = $this->get_value($values, 'cid'); + $cid = $this->get_value($values, 'cid'); $this->options['alter']['make_link'] = TRUE; $this->options['alter']['path'] = "comment/" . $cid . "/approve"; diff --git a/sites/all/modules/contrib/views/views/modules/comment/views_handler_field_comment_link_delete.inc b/sites/all/modules/contrib/views/views/modules/comment/views_handler_field_comment_link_delete.inc index 6b230eac..ade8cb9b 100644 --- a/sites/all/modules/contrib/views/views/modules/comment/views_handler_field_comment_link_delete.inc +++ b/sites/all/modules/contrib/views/views/modules/comment/views_handler_field_comment_link_delete.inc @@ -25,7 +25,7 @@ class views_handler_field_comment_link_delete extends views_handler_field_commen */ public function render_link($data, $values) { $text = !empty($this->options['text']) ? $this->options['text'] : t('delete'); - $cid = $this->get_value($values, 'cid'); + $cid = $this->get_value($values, 'cid'); $this->options['alter']['make_link'] = TRUE; $this->options['alter']['path'] = "comment/" . $cid . "/delete"; diff --git a/sites/all/modules/contrib/views/views/modules/comment/views_handler_field_comment_link_reply.inc b/sites/all/modules/contrib/views/views/modules/comment/views_handler_field_comment_link_reply.inc index 581b06dd..aa2d7dad 100644 --- a/sites/all/modules/contrib/views/views/modules/comment/views_handler_field_comment_link_reply.inc +++ b/sites/all/modules/contrib/views/views/modules/comment/views_handler_field_comment_link_reply.inc @@ -25,8 +25,8 @@ class views_handler_field_comment_link_reply extends views_handler_field_comment */ public function render_link($data, $values) { $text = !empty($this->options['text']) ? $this->options['text'] : t('reply'); - $nid = $this->get_value($values, 'nid'); - $cid = $this->get_value($values, 'cid'); + $nid = $this->get_value($values, 'nid'); + $cid = $this->get_value($values, 'cid'); $this->options['alter']['make_link'] = TRUE; $this->options['alter']['path'] = "comment/reply/" . $nid . '/' . $cid; diff --git a/sites/all/modules/contrib/views/views/modules/field/views_handler_field_field.inc b/sites/all/modules/contrib/views/views/modules/field/views_handler_field_field.inc index cbc22513..da316049 100644 --- a/sites/all/modules/contrib/views/views/modules/field/views_handler_field_field.inc +++ b/sites/all/modules/contrib/views/views/modules/field/views_handler_field_field.inc @@ -127,7 +127,7 @@ class views_handler_field_field extends views_handler_field { */ public function access() { $base_table = $this->get_base_table(); - return field_access('view', $this->field_info, $this->definition['entity_tables'][$base_table]); + return isset($this->definition['entity_tables'][$base_table]) && field_access('view', $this->field_info, $this->definition['entity_tables'][$base_table]); } /** @@ -537,6 +537,7 @@ class views_handler_field_field extends views_handler_field { 'ul' => t('Unordered list'), 'ol' => t('Ordered list'), 'separator' => t('Simple separator'), + 'count' => t('Count'), ), '#dependency' => array('edit-options-group-rows' => array(TRUE)), '#default_value' => $this->options['multi_type'], @@ -727,6 +728,9 @@ class views_handler_field_field extends views_handler_field { if ($this->options['multi_type'] == 'separator') { return implode(filter_xss_admin($this->options['separator']), $items); } + elseif ($this->options['multi_type'] == 'count') { + return count($items); + } else { return theme('item_list', array( diff --git a/sites/all/modules/contrib/views/views/modules/node.views.inc b/sites/all/modules/contrib/views/views/modules/node.views.inc index 642825f7..2eb351d9 100644 --- a/sites/all/modules/contrib/views/views/modules/node.views.inc +++ b/sites/all/modules/contrib/views/views/modules/node.views.inc @@ -155,7 +155,7 @@ function node_views_data() { // Published status. $data['node']['status'] = array( - 'title' => t('Published'), + 'title' => t('Published status'), 'help' => t('Whether or not the content is published.'), 'field' => array( 'handler' => 'views_handler_field_boolean', @@ -166,7 +166,7 @@ function node_views_data() { ), 'filter' => array( 'handler' => 'views_handler_filter_boolean_operator', - 'label' => t('Published'), + 'label' => t('Published status'), 'type' => 'yes-no', 'use equal' => TRUE, // Use status = 1 instead of status <> 0 in WHERE statment. @@ -178,18 +178,18 @@ function node_views_data() { // Published status + extra. $data['node']['status_extra'] = array( - 'title' => t('Published or admin'), + 'title' => t('Published status or admin user'), 'help' => t('Filters out unpublished content if the current user cannot view it.'), 'filter' => array( 'field' => 'status', 'handler' => 'views_handler_filter_node_status', - 'label' => t('Published or admin'), + 'label' => t('Published status or admin user'), ), ); // Promote status. $data['node']['promote'] = array( - 'title' => t('Promoted to front page'), + 'title' => t('Promoted to front page status'), 'help' => t('Whether or not the content is promoted to the front page.'), 'field' => array( 'handler' => 'views_handler_field_boolean', @@ -200,7 +200,7 @@ function node_views_data() { ), 'filter' => array( 'handler' => 'views_handler_filter_boolean_operator', - 'label' => t('Promoted to front page'), + 'label' => t('Promoted to front page status'), 'type' => 'yes-no', ), 'sort' => array( @@ -211,7 +211,7 @@ function node_views_data() { // Sticky. $data['node']['sticky'] = array( // The item it appears as on the UI, - 'title' => t('Sticky'), + 'title' => t('Sticky status'), // The help that appears on the UI, 'help' => t('Whether or not the content is sticky.'), // Information for displaying a title as a field. @@ -224,7 +224,7 @@ function node_views_data() { ), 'filter' => array( 'handler' => 'views_handler_filter_boolean_operator', - 'label' => t('Sticky'), + 'label' => t('Sticky status'), 'type' => 'yes-no', ), 'sort' => array( @@ -241,7 +241,7 @@ function node_views_data() { $data['node']['view_node']['moved to'] = array('views_entity_node', 'view_node'); $data['views_entity_node']['view_node'] = array( 'field' => array( - 'title' => t('Link'), + 'title' => t('Link to content'), 'help' => t('Provide a simple link to the content.'), 'handler' => 'views_handler_field_node_link', ), @@ -250,7 +250,7 @@ function node_views_data() { $data['node']['edit_node']['moved to'] = array('views_entity_node', 'edit_node'); $data['views_entity_node']['edit_node'] = array( 'field' => array( - 'title' => t('Edit link'), + 'title' => t('Link to edit content'), 'help' => t('Provide a simple link to edit the content.'), 'handler' => 'views_handler_field_node_link_edit', ), @@ -259,7 +259,7 @@ function node_views_data() { $data['node']['delete_node']['moved to'] = array('views_entity_node', 'delete_node'); $data['views_entity_node']['delete_node'] = array( 'field' => array( - 'title' => t('Delete link'), + 'title' => t('Link to delete content'), 'help' => t('Provide a simple link to delete the content.'), 'handler' => 'views_handler_field_node_link_delete', ), @@ -387,7 +387,7 @@ function node_views_data() { 'title' => t('Author uid'), 'help' => t('The user authoring the content. If you need more fields than the uid add the content: author relationship'), 'relationship' => array( - 'title' => t('Author'), + 'title' => t('Content author'), 'help' => t('Relate content to the user who created it.'), 'handler' => 'views_handler_relationship', 'base' => 'users', @@ -606,7 +606,7 @@ function node_views_data() { $data['node_revision']['link_to_revision'] = array( 'field' => array( - 'title' => t('Link'), + 'title' => t('Link to revision'), 'help' => t('Provide a simple link to the revision.'), 'handler' => 'views_handler_field_node_revision_link', ), @@ -614,7 +614,7 @@ function node_views_data() { $data['node_revision']['revert_revision'] = array( 'field' => array( - 'title' => t('Revert link'), + 'title' => t('Link to revert revision'), 'help' => t('Provide a simple link to revert to the revision.'), 'handler' => 'views_handler_field_node_revision_link_revert', ), @@ -622,7 +622,7 @@ function node_views_data() { $data['node_revision']['delete_revision'] = array( 'field' => array( - 'title' => t('Delete link'), + 'title' => t('Link to delete revision'), 'help' => t('Provide a simple link to delete the content revision.'), 'handler' => 'views_handler_field_node_revision_link_delete', ), diff --git a/sites/all/modules/contrib/views/views/modules/taxonomy.views.inc b/sites/all/modules/contrib/views/views/modules/taxonomy.views.inc index ddf91e13..99c3b713 100644 --- a/sites/all/modules/contrib/views/views/modules/taxonomy.views.inc +++ b/sites/all/modules/contrib/views/views/modules/taxonomy.views.inc @@ -17,7 +17,7 @@ function taxonomy_views_data() { // 'taxonomy_vocabulary' table. $data['vocabulary']['moved to'] = 'taxonomy_vocabulary'; $data['taxonomy_vocabulary']['table']['group'] = t('Taxonomy vocabulary'); - + $data['taxonomy_vocabulary']['table']['entity type'] = 'taxonomy_vocabulary'; $data['taxonomy_vocabulary']['table']['join'] = array( // Vocabulary links to taxonomy_term_data directly via vid. 'taxonomy_term_data' => array( diff --git a/sites/all/modules/contrib/views/views/modules/taxonomy/views_handler_field_term_link_edit.inc b/sites/all/modules/contrib/views/views/modules/taxonomy/views_handler_field_term_link_edit.inc index 1e238f44..3bd32123 100644 --- a/sites/all/modules/contrib/views/views/modules/taxonomy/views_handler_field_term_link_edit.inc +++ b/sites/all/modules/contrib/views/views/modules/taxonomy/views_handler_field_term_link_edit.inc @@ -59,20 +59,26 @@ class views_handler_field_term_link_edit extends views_handler_field { /** * {@inheritdoc} */ - public function render($values) { - // Check there is an actual value, as on a relationship there may not be. - if ($tid = $this->get_value($values, 'tid')) { - // Mock a term object for taxonomy_term_edit_access(). Use machine name - // and vid to ensure compatibility with vid based and machine name based - // access checks. See http://drupal.org/node/995156 - $term = new stdClass(); - $term->vid = $values->{$this->aliases['vid']}; - $term->vocabulary_machine_name = $values->{$this->aliases['vocabulary_machine_name']}; - if (taxonomy_term_edit_access($term)) { - $text = !empty($this->options['text']) ? $this->options['text'] : t('edit'); - $tid = $this->get_value($values, 'tid'); - return l($text, 'taxonomy/term/' . $tid . '/edit', array('query' => drupal_get_destination())); - } + function render($values) { + $value = $this->get_value($values, 'tid'); + return $this->render_link($this->sanitize_value($value), $values); + } + + /** + * {@inheritdoc} + */ + function render_link($data, $values) { + // Mock a term object for taxonomy_term_edit_access(). Use machine name and + // vid to ensure compatibility with vid based and machine name based + // access checks. See http://drupal.org/node/995156 + $term = new stdClass(); + $term->vid = $values->{$this->aliases['vid']}; + $term->vocabulary_machine_name = $values->{$this->aliases['vocabulary_machine_name']}; + if ($data && taxonomy_term_edit_access($term)) { + $text = !empty($this->options['text']) ? $this->options['text'] : t('edit'); + $this->options['alter']['path'] = "taxonomy/term/$data/edit"; + $this->options['alter']['query'] = drupal_get_destination(); + return $text; } } diff --git a/sites/all/modules/contrib/views/views/modules/taxonomy/views_handler_filter_term_node_tid.inc b/sites/all/modules/contrib/views/views/modules/taxonomy/views_handler_filter_term_node_tid.inc index 0b3188ae..03b8d11e 100644 --- a/sites/all/modules/contrib/views/views/modules/taxonomy/views_handler_filter_term_node_tid.inc +++ b/sites/all/modules/contrib/views/views/modules/taxonomy/views_handler_filter_term_node_tid.inc @@ -61,6 +61,7 @@ class views_handler_filter_term_node_tid extends views_handler_filter_many_to_on $options['vocabulary'] = array('default' => 0); $options['hierarchy'] = array('default' => 0); $options['error_message'] = array('default' => TRUE, 'bool' => TRUE); + $options['optgroups'] = array('default' => 0); return $options; } @@ -106,6 +107,14 @@ class views_handler_filter_term_node_tid extends views_handler_filter_many_to_on '#default_value' => !empty($this->options['hierarchy']), '#dependency' => array('radio:options[type]' => array('select')), ); + + $form['optgroups'] = array( + '#type' => 'checkbox', + '#title' => t('Show groups in dropdown'), + '#default_value' => !empty($this->options['optgroups']), + '#dependency' => array('radio:options[type]' => array('select')), + ); + } /** @@ -145,15 +154,22 @@ class views_handler_filter_term_node_tid extends views_handler_filter_many_to_on else { if (!empty($this->options['hierarchy']) && $this->options['limit']) { $tree = taxonomy_get_tree($vocabulary->vid, 0, NULL, TRUE); - $options = array(); - - if ($tree) { - // Translation system needs full entity objects, so we have access to - // label. - foreach ($tree as $term) { - $choice = new stdClass(); - $choice->option = array($term->tid => str_repeat('-', $term->depth) . entity_label('taxonomy_term', $term)); - $options[] = $choice; + if (!empty($tree)) { + if (!empty($this->options['optgroups'])) { + foreach ($tree as $term) { + $term_name = entity_label('taxonomy_term', $term); + if ($term->parents[0] == 0) { + $parent_name = $term_name; + } + else { + $options[$parent_name][$term->tid] = str_repeat('-', $term->depth - 1) . $term_name; + } + } + } + else { + foreach ($tree as $term) { + $options[$term->tid] = str_repeat('-', $term->depth) . entity_label('taxonomy_term', $term); + } } } } diff --git a/sites/all/modules/contrib/views/views/modules/taxonomy/views_plugin_argument_validate_taxonomy_term.inc b/sites/all/modules/contrib/views/views/modules/taxonomy/views_plugin_argument_validate_taxonomy_term.inc index 343af3cb..7e7f2c15 100644 --- a/sites/all/modules/contrib/views/views/modules/taxonomy/views_plugin_argument_validate_taxonomy_term.inc +++ b/sites/all/modules/contrib/views/views/modules/taxonomy/views_plugin_argument_validate_taxonomy_term.inc @@ -227,7 +227,7 @@ class views_plugin_argument_validate_taxonomy_term extends views_plugin_argument $query = db_select('taxonomy_term_data', 'td'); $query->addTag('taxonomy_term_access'); - $query->condition('tid', $args); + $query->condition('td.tid', $args); $query->addField('td', 'tid', 'tid'); if (!empty($vocabularies)) { $query->leftJoin('taxonomy_vocabulary', 'tv', 'td.vid = tv.vid'); diff --git a/sites/all/modules/contrib/views/views/modules/translation/views_handler_field_node_link_translate.inc b/sites/all/modules/contrib/views/views/modules/translation/views_handler_field_node_link_translate.inc index aedbb834..257c3b86 100644 --- a/sites/all/modules/contrib/views/views/modules/translation/views_handler_field_node_link_translate.inc +++ b/sites/all/modules/contrib/views/views/modules/translation/views_handler_field_node_link_translate.inc @@ -20,7 +20,7 @@ class views_handler_field_node_link_translate extends views_handler_field_node_l $node = $this->get_value($values); $node->status = 1; // unpublished nodes ignore access control. - if (empty($node->language) || !translation_supported_type($node->type) || !node_access('view', $node) || !user_access('translate content')) { + if ($node->language == LANGUAGE_NONE || !translation_supported_type($node->type) || !node_access('view', $node) || !user_access('translate content')) { return; } diff --git a/sites/all/modules/contrib/views/views/modules/user.views.inc b/sites/all/modules/contrib/views/views/modules/user.views.inc index 97abd272..7d96a735 100644 --- a/sites/all/modules/contrib/views/views/modules/user.views.inc +++ b/sites/all/modules/contrib/views/views/modules/user.views.inc @@ -110,6 +110,19 @@ function user_views_data() { ), ); + // Comments authored. + $data['users']['uid_comment'] = array( + 'relationship' => array( + 'title' => t('Comments authored'), + 'help' => t('Relate comments to the user who created it. This relationship will create one record for each comment created by the user.'), + 'handler' => 'views_handler_relationship', + 'base' => 'comment', + 'base field' => 'uid', + 'field' => 'uid', + 'label' => t('comments'), + ), + ); + // User name. $data['users']['name'] = array( // The item it appears as on the UI, @@ -139,7 +152,7 @@ function user_views_data() { // The item it appears as on the UI, 'title' => t('E-mail'), // The help that appears on the UI, - 'help' => t('Email address for a given user. This field is normally not shown to users, so be cautious when using it.'), + 'help' => t('E-mail address for a given user. This field is normally not shown to users, so be cautious when using it.'), 'field' => array( 'handler' => 'views_handler_field_user_mail', 'click sortable' => TRUE, @@ -200,7 +213,7 @@ function user_views_data() { // Link. $data['users']['view_user'] = array( 'field' => array( - 'title' => t('Link'), + 'title' => t('Link to user'), 'help' => t('Provide a simple link to the user.'), 'handler' => 'views_handler_field_user_link', ), @@ -318,7 +331,7 @@ function user_views_data() { // Active status. $data['users']['status'] = array( // The item it appears as on the UI, - 'title' => t('Active'), + 'title' => t('Active status'), // The help that appears on the UI, 'help' => t('Whether a user is active or blocked.'), // Information for displaying a title as a field. @@ -357,7 +370,7 @@ function user_views_data() { $data['users']['edit_node'] = array( 'field' => array( - 'title' => t('Edit link'), + 'title' => t('Link to edit user'), 'help' => t('Provide a simple link to edit the user.'), 'handler' => 'views_handler_field_user_link_edit', ), @@ -365,7 +378,7 @@ function user_views_data() { $data['users']['cancel_node'] = array( 'field' => array( - 'title' => t('Cancel link'), + 'title' => t('Link to cancel user'), 'help' => t('Provide a simple link to cancel the user.'), 'handler' => 'views_handler_field_user_link_cancel', ), diff --git a/sites/all/modules/contrib/views/views/modules/user/views_handler_field_user.inc b/sites/all/modules/contrib/views/views/modules/user/views_handler_field_user.inc index 79396122..8856c4ab 100644 --- a/sites/all/modules/contrib/views/views/modules/user/views_handler_field_user.inc +++ b/sites/all/modules/contrib/views/views/modules/user/views_handler_field_user.inc @@ -17,9 +17,7 @@ class views_handler_field_user extends views_handler_field { */ public function init(&$view, &$data) { parent::init($view, $data); - if (!empty($this->options['link_to_user'])) { - $this->additional_fields['uid'] = 'uid'; - } + $this->additional_fields['uid'] = 'uid'; } /** diff --git a/sites/all/modules/contrib/views/views/modules/user/views_handler_field_user_language.inc b/sites/all/modules/contrib/views/views/modules/user/views_handler_field_user_language.inc index b96963d9..9f2ae4f3 100644 --- a/sites/all/modules/contrib/views/views/modules/user/views_handler_field_user_language.inc +++ b/sites/all/modules/contrib/views/views/modules/user/views_handler_field_user_language.inc @@ -35,12 +35,4 @@ class views_handler_field_user_language extends views_handler_field_user { return $this->sanitize_value($lang->name); } - /** - * {@inheritdoc} - */ - public function render($values) { - $value = $this->get_value($values); - return $this->render_link($this->sanitize_value($value), $values); - } - } diff --git a/sites/all/modules/contrib/views/views/modules/user/views_handler_field_user_name.inc b/sites/all/modules/contrib/views/views/modules/user/views_handler_field_user_name.inc index 7043718a..c7bf8c69 100644 --- a/sites/all/modules/contrib/views/views/modules/user/views_handler_field_user_name.inc +++ b/sites/all/modules/contrib/views/views/modules/user/views_handler_field_user_name.inc @@ -12,16 +12,6 @@ */ class views_handler_field_user_name extends views_handler_field_user { - /** - * Add uid in the query so we can test for anonymous if needed. - */ - public function init(&$view, &$data) { - parent::init($view, $data); - if (!empty($this->options['overwrite_anonymous']) || !empty($this->options['format_username'])) { - $this->additional_fields['uid'] = 'uid'; - } - } - /** * {@inheritdoc} */ @@ -73,6 +63,10 @@ class views_handler_field_user_name extends views_handler_field_user { $account = new stdClass(); $account->uid = $this->get_value($values, 'uid'); $account->name = $this->get_value($values); + // If we don't have a UID, we can't format anything. + if (!isset($account->uid)) { + return $data; + } if (!empty($this->options['link_to_user']) || !empty($this->options['overwrite_anonymous'])) { if (!empty($this->options['overwrite_anonymous']) && !$account->uid) { // This is an anonymous user, and we're overriting the text. diff --git a/sites/all/modules/contrib/views/views/plugins/export_ui/views_ui.class.php b/sites/all/modules/contrib/views/views/plugins/export_ui/views_ui.class.php index 97a69a1e..81cbdac3 100644 --- a/sites/all/modules/contrib/views/views/plugins/export_ui/views_ui.class.php +++ b/sites/all/modules/contrib/views/views/plugins/export_ui/views_ui.class.php @@ -364,6 +364,8 @@ class views_ui extends ctools_export_ui { * */ function clone_page($js, $input, $item, $step = NULL) { + $args = func_get_args(); + drupal_set_title($this->get_page_title('clone', $item)); $name = $item->{$this->plugin['export']['key']}; @@ -380,7 +382,7 @@ class views_ui extends ctools_export_ui { 'no_redirect' => TRUE, 'step' => $step, // Store these in case additional args are needed. - 'function args' => func_get_args(), + 'function args' => $args, ); $output = drupal_build_form('views_ui_clone_form', $form_state); diff --git a/sites/all/modules/contrib/views/views/plugins/views_plugin_cache.inc b/sites/all/modules/contrib/views/views/plugins/views_plugin_cache.inc index 6fdc5bba..80eb8314 100644 --- a/sites/all/modules/contrib/views/views/plugins/views_plugin_cache.inc +++ b/sites/all/modules/contrib/views/views/plugins/views_plugin_cache.inc @@ -181,7 +181,7 @@ class views_plugin_cache extends views_plugin { } /** - * Start caching javascript, css and other out of band info. + * Start caching JavaScript, css and other out of band info. * * This takes a snapshot of the current system state so that we don't * duplicate it. Later on, when gather_headers() is run, this information @@ -214,10 +214,10 @@ class views_plugin_cache extends views_plugin { $css_start = isset($this->storage['css']) ? $this->storage['css'] : array(); $this->storage['css'] = $this->assetDiff($css, $css_start, $array_mapping_func); - // Get javascript after/before views renders. + // Get JavaScript after/before views renders. $js = drupal_add_js(); $js_start = isset($this->storage['js']) ? $this->storage['js'] : array(); - // If there are any differences between the old and the new javascript then + // If there are any differences between the old and the new JavaScript then // store them to be added later. $this->storage['js'] = $this->assetDiff($js, $js_start, $array_mapping_func); @@ -353,8 +353,15 @@ class views_plugin_cache extends views_plugin { // If the default query back-end is used generate SQL query strings from // the query objects. if ($build_info[$index] instanceof SelectQueryInterface) { - $query = clone $build_info[$index]; - $query->preExecute(); + $query = $build_info[$index]; + + // If the query was not yet prepared, work on a clone and run + // preExecute(). + if (!$query->isPrepared()) { + $query = clone $build_info[$index]; + $query->preExecute(); + } + $key_data['build_info'][$index] = array( 'sql' => (string) $query, 'arguments' => $query->getArguments(), diff --git a/sites/all/modules/contrib/views/views/plugins/views_plugin_display.inc b/sites/all/modules/contrib/views/views/plugins/views_plugin_display.inc index fd8de19e..7383ac98 100644 --- a/sites/all/modules/contrib/views/views/plugins/views_plugin_display.inc +++ b/sites/all/modules/contrib/views/views/plugins/views_plugin_display.inc @@ -32,12 +32,16 @@ class views_plugin_display extends views_plugin { public $view = NULL; /** + * List of handlers for this display. * + * @var array */ public $handlers = array(); /** * Stores all available display extenders. + * + * @var array */ public $extender = array(); @@ -131,7 +135,7 @@ class views_plugin_display extends views_plugin { $pager = array( 'type' => $type, 'options' => array( - 'offset' => intval($offset) + 'offset' => intval($offset), ), ); @@ -143,8 +147,8 @@ class views_plugin_display extends views_plugin { $pager['options']['id'] = $id; } - // Unset the previous options - // After edit and save the view they will be erased + // Unset the previous options. After edit and save the view they will be + // erased. $this->set_option('items_per_page', NULL); $this->set_option('offset', NULL); $this->set_option('use_pager', NULL); @@ -152,10 +156,9 @@ class views_plugin_display extends views_plugin { $changed = TRUE; } - - // Plugable headers, footer and empty texts are - // not compatible with previous version of views - // This code converts old values into a configured handler for each area + // Plugable headers, footer and empty texts are not compatible with + // previous version of views. This code converts old values into a + // configured handler for each area. foreach (array('header', 'footer', 'empty') as $area) { $converted = FALSE; if (isset($this->options[$area]) && !is_array($this->options[$area])) { @@ -182,7 +185,7 @@ class views_plugin_display extends views_plugin { $changed = TRUE; } } - // Ensure that options are at least an empty array + // Ensure that options are at least an empty array. if (!$converted) { $this->set_option($area, array()); } @@ -195,7 +198,7 @@ class views_plugin_display extends views_plugin { $query_settings = $this->get_option('query'); $query_settings['options']['distinct'] = $distinct; $this->set_option('query', $query_settings); - // Clear the values + // Clear the values. $this->set_option('distinct', NULL); $changed = TRUE; } @@ -217,10 +220,10 @@ class views_plugin_display extends views_plugin { // Convert filter groups. $filter_groups = $this->get_option('filter_groups'); // Only convert if it wasn't converted yet, which is the case if there is a - // 0 group. + // '0' group. if (isset($filter_groups['groups'][0])) { // Update filter groups. - $filter_groups ['groups'] = views_array_key_plus($filter_groups['groups']); + $filter_groups['groups'] = views_array_key_plus($filter_groups['groups']); $this->set_option('filter_groups', $filter_groups); // Update the filter group on each filter. $filters = $this->get_option('filters'); @@ -285,16 +288,19 @@ class views_plugin_display extends views_plugin { } /** - * Determine if this display is the 'default' display which contains - * fallback settings + * If this display is the 'default' display which contains fallback settings. + * + * @return bool + * This is the default display and contains fallback settings. */ public function is_default_display() { return FALSE; } /** - * Determine if this display uses exposed filters, so the view - * will know whether or not to build them. + * Does this display uses exposed filters? + * + * So the view will know whether or not to build them. */ public function uses_exposed() { if (!isset($this->has_exposed)) { @@ -319,13 +325,12 @@ class views_plugin_display extends views_plugin { } /** - * Determine if this display should display the exposed - * filters widgets, so the view will know whether or not - * to render them. + * Determine if this display should display the exposed filters widgets. * - * Regardless of what this function - * returns, exposed filters will not be used nor - * displayed unless uses_exposed() returns TRUE. + * If so, the view will know whether or not to render them. + * + * Regardless of what this function returns, exposed filters will not be used + * nor displayed unless uses_exposed() returns TRUE. */ public function displays_exposed() { return TRUE; @@ -422,8 +427,7 @@ class views_plugin_display extends views_plugin { } /** - * Static member function to list which sections are defaultable - * and what items each section contains. + * List which sections are defaultable and what items each section contains. */ public function defaultable_sections($section = NULL) { $sections = array( @@ -464,10 +468,30 @@ class views_plugin_display extends views_plugin { 'link_display' => array('link_display', 'link_url'), // Force these to cascade properly. - 'style_plugin' => array('style_plugin', 'style_options', 'row_plugin', 'row_options'), - 'style_options' => array('style_plugin', 'style_options', 'row_plugin', 'row_options'), - 'row_plugin' => array('style_plugin', 'style_options', 'row_plugin', 'row_options'), - 'row_options' => array('style_plugin', 'style_options', 'row_plugin', 'row_options'), + 'style_plugin' => array( + 'style_plugin', + 'style_options', + 'row_plugin', + 'row_options', + ), + 'style_options' => array( + 'style_plugin', + 'style_options', + 'row_plugin', + 'row_options', + ), + 'row_plugin' => array( + 'style_plugin', + 'style_options', + 'row_plugin', + 'row_options', + ), + 'row_options' => array( + 'style_plugin', + 'style_options', + 'row_plugin', + 'row_options', + ), 'pager' => array('pager', 'pager_options'), 'pager_options' => array('pager', 'pager_options'), @@ -475,7 +499,7 @@ class views_plugin_display extends views_plugin { 'exposed_form' => array('exposed_form', 'exposed_form_options'), 'exposed_form_options' => array('exposed_form', 'exposed_form_options'), - // These guys are special + // These guys are special. 'header' => array('header'), 'footer' => array('footer'), 'empty' => array('empty'), @@ -636,42 +660,60 @@ class views_plugin_display extends views_plugin { // therefore need special handling. 'access' => array( 'contains' => array( - 'type' => array('default' => 'none', 'export' => 'export_plugin', 'unpack_translatable' => 'unpack_plugin'), - ), + 'type' => array( + 'default' => 'none', + 'export' => 'export_plugin', + 'unpack_translatable' => 'unpack_plugin', + ), + ), ), 'cache' => array( 'contains' => array( - 'type' => array('default' => 'none', 'export' => 'export_plugin', 'unpack_translatable' => 'unpack_plugin'), - ), + 'type' => array( + 'default' => 'none', + 'export' => 'export_plugin', + 'unpack_translatable' => 'unpack_plugin', + ), + ), ), 'query' => array( 'contains' => array( - 'type' => array('default' => 'views_query', 'export' => 'export_plugin'), + 'type' => array( + 'default' => 'views_query', + 'export' => 'export_plugin', + ), 'options' => array('default' => array(), 'export' => FALSE), - ), + ), ), - // Note that exposed_form plugin has options in a separate array, - // while access and cache do not. access and cache are legacy and - // that pattern should not be repeated, but it is left as is to - // reduce the need to modify older views. Let's consider the - // pattern used here to be the template from which future plugins - // should be copied. + // Note that exposed_form plugin has options in a separate array, while + // access and cache do not. access and cache are legacy and that pattern + // should not be repeated, but it is left as is to reduce the need to + // modify older views. Let's consider the pattern used here to be the + // template from which future plugins should be copied. 'exposed_form' => array( 'contains' => array( - 'type' => array('default' => 'basic', 'export' => 'export_plugin', 'unpack_translatable' => 'unpack_plugin'), + 'type' => array( + 'default' => 'basic', + 'export' => 'export_plugin', + 'unpack_translatable' => 'unpack_plugin', + ), 'options' => array('default' => array(), 'export' => FALSE), - ), + ), ), 'pager' => array( 'contains' => array( - 'type' => array('default' => 'full', 'export' => 'export_plugin', 'unpack_translatable' => 'unpack_plugin'), + 'type' => array( + 'default' => 'full', + 'export' => 'export_plugin', + 'unpack_translatable' => 'unpack_plugin', + ), 'options' => array('default' => array(), 'export' => FALSE), - ), + ), ), - // Note that the styles have their options completely independent. - // Like access and cache above, this is a legacy pattern and - // should not be repeated. + // Note that the styles have their options completely independent. Like + // access and cache above, this is a legacy pattern and should not be + // repeated. 'style_plugin' => array( 'default' => 'default', 'export' => 'export_style', @@ -817,7 +859,7 @@ class views_plugin_display extends views_plugin { else { return $display_id; } - // fall-through returns NULL + // Fall-through returns NULL. } /** @@ -898,6 +940,7 @@ class views_plugin_display extends views_plugin { * The name of the plugin defined in hook_views_plugins. * * @return views_plugin|FALSE + * FALSE if no plugin, otherwise the requested instance of a plugin. */ public function get_plugin($type = 'style', $name = NULL) { static $cache = array(); @@ -931,7 +974,7 @@ class views_plugin_display extends views_plugin { $plugin = views_get_plugin($type, $name); if (!$plugin) { - return; + return FALSE; } if ($type != 'query') { $plugin->init($this->view, $this->display, $options); @@ -1033,13 +1076,13 @@ class views_plugin_display extends views_plugin { /** * List of fields for the current display with the associated relationship. * - * @param $groupable_only - * Return only an array of field labels from handler that return TRUE - * from use_string_group_by method. + * @param bool $groupable_only + * Return only an array of field labels from handler that return TRUE from + * use_string_group_by method. */ public function get_field_labels() { - // Use func_get_arg so the function signature isn't amended but we can - // still pass TRUE into the function to filter by groupable handlers. + // Use func_get_arg so the function signature isn't amended but we can still + // pass TRUE into the function to filter by groupable handlers. $args = func_get_args(); $groupable_only = isset($args[0]) ? $args[0] : FALSE; @@ -1080,9 +1123,8 @@ class views_plugin_display extends views_plugin { return $this->default_display->set_option($option, $value); } - // Set this in two places: On the handler where we'll notice it - // but also on the display object so it gets saved. This should - // only be a temporary fix. + // Set this in two places: On the handler where we'll notice it but also on + // the display object so it gets saved. This should only be a temporary fix. $this->display->display_options[$option] = $value; return $this->options[$option] = $value; } @@ -1118,14 +1160,24 @@ class views_plugin_display extends views_plugin { $text = views_ui_truncate($text, 24); } - return l($text, 'admin/structure/views/nojs/display/' . $this->view->name . '/' . $this->display->id . '/' . $section, array('attributes' => array('class' => 'views-ajax-link ' . $class, 'title' => $title, 'id' => drupal_html_id('views-' . $this->display->id . '-' . $section)), 'html' => TRUE)); + return l($text, + 'admin/structure/views/nojs/display/' . $this->view->name . '/' . $this->display->id . '/' . $section, + array( + 'attributes' => array( + 'class' => 'views-ajax-link ' . $class, + 'title' => $title, + 'id' => drupal_html_id('views-' . $this->display->id . '-' . $section), + ), + 'html' => TRUE, + ) + ); } /** * Returns to tokens for arguments. * - * This function is similar to views_handler_field::get_render_tokens() - * but without fields tokens. + * This function is similar to views_handler_field::get_render_tokens() but + * without fields tokens. */ public function get_arguments_tokens() { $tokens = array(); @@ -1344,9 +1396,9 @@ class views_plugin_display extends views_plugin { ); $languages = array( - '***CURRENT_LANGUAGE***' => t("Current user's language"), - '***DEFAULT_LANGUAGE***' => t("Default site language"), - LANGUAGE_NONE => t('Language neutral'), + '***CURRENT_LANGUAGE***' => t("Current user's language"), + '***DEFAULT_LANGUAGE***' => t("Default site language"), + LANGUAGE_NONE => t('Language neutral'), ); if (module_exists('locale')) { $languages = array_merge($languages, locale_language_list()); @@ -1361,7 +1413,7 @@ class views_plugin_display extends views_plugin { $access_plugin = $this->get_plugin('access'); if (!$access_plugin) { - // default to the no access control plugin. + // Default to the no access control plugin. $access_plugin = views_get_plugin('access', 'none'); } @@ -1381,7 +1433,7 @@ class views_plugin_display extends views_plugin { $cache_plugin = $this->get_plugin('cache'); if (!$cache_plugin) { - // default to the no cache control plugin. + // Default to the no cache control plugin. $cache_plugin = views_get_plugin('cache', 'none'); } @@ -1406,7 +1458,7 @@ class views_plugin_display extends views_plugin { if ($this->uses_link_display()) { $display_id = $this->get_link_display(); $link_display = empty($this->view->display[$display_id]) ? t('None') : check_plain($this->view->display[$display_id]->display_title); - $link_display = $this->get_option('link_display') == 'custom_url' ? t('Custom URL') : $link_display; + $link_display = $this->get_option('link_display') == 'custom_url' ? t('Custom URL') : $link_display; $options['link_display'] = array( 'category' => 'other', 'title' => t('Link display'), @@ -1478,10 +1530,9 @@ class views_plugin_display extends views_plugin { } $form['#title'] = check_plain($this->display->display_title) . ': '; - // Set the 'section' to highlight on the form. - // If it's the item we're looking at is pulling from the default display, - // reflect that. Don't use is_defaulted since we want it to show up even - // on the default display. + // Set the 'section' to highlight on the form. If it's the item we're + // looking at is pulling from the default display, reflect that. Don't use + // is_defaulted since we want it to show up even on the default display. if (!empty($this->options['defaults'][$form_state['section']])) { $form['#section'] = 'default-' . $form_state['section']; } @@ -1587,9 +1638,9 @@ class views_plugin_display extends views_plugin { '#title' => t("Display 'more' link only if there is more content"), '#description' => t("Leave this unchecked to display the 'more' link even if there are no more items to display."), '#default_value' => !$this->get_option('use_more_always'), - '#dependency' => array( - 'edit-use-more' => array(TRUE), - ), + '#dependency' => array( + 'edit-use-more' => array(TRUE), + ), ); $form['open_new_window'] = array( '#type' => 'checkbox', @@ -1629,7 +1680,7 @@ class views_plugin_display extends views_plugin { '#tree' => TRUE, ); $access = $this->get_option('access'); - $form['access']['type'] = array( + $form['access']['type'] = array( '#type' => 'radios', '#options' => views_fetch_plugin_names('access', NULL, array($this->view->base_table)), '#default_value' => $access['type'], @@ -1674,7 +1725,7 @@ class views_plugin_display extends views_plugin { '#tree' => TRUE, ); $cache = $this->get_option('cache'); - $form['cache']['type'] = array( + $form['cache']['type'] = array( '#type' => 'radios', '#options' => views_fetch_plugin_names('cache', NULL, array($this->view->base_table)), '#default_value' => $cache['type'], @@ -1784,7 +1835,7 @@ class views_plugin_display extends views_plugin { case 'style_plugin': $form['#title'] .= t('How should this view be styled'); $form['#help_topic'] = 'style'; - $form['style_plugin'] = array( + $form['style_plugin'] = array( '#type' => 'radios', '#options' => views_fetch_plugin_names('style', $this->get_style_type(), array($this->view->base_table)), '#default_value' => $this->get_option('style_plugin'), @@ -1832,7 +1883,7 @@ class views_plugin_display extends views_plugin { case 'row_plugin': $form['#title'] .= t('How should each row in this view be styled'); $form['#help_topic'] = 'style-row'; - $form['row_plugin'] = array( + $form['row_plugin'] = array( '#type' => 'radios', '#options' => views_fetch_plugin_names('row', $this->get_style_type(), array($this->view->base_table)), '#default_value' => $this->get_option('row_plugin'), @@ -1884,7 +1935,7 @@ class views_plugin_display extends views_plugin { $output .= theme('item_list', array( 'items' => $items, - 'type' => $type + 'type' => $type, )); } } @@ -1946,14 +1997,14 @@ class views_plugin_display extends views_plugin { } } else { - // include non-engine theme files + // Include non-engine theme files. foreach ($base_theme as $base) { // Include the theme file or the engine. if (!empty($base->owner)) { include_once DRUPAL_ROOT . '/' . $base->owner; } } - // and our theme gets one too. + // And our theme gets one too. if (!empty($theme->owner)) { include_once DRUPAL_ROOT . '/' . $theme->owner; } @@ -1972,15 +2023,15 @@ class views_plugin_display extends views_plugin { } $funcs = array(); - // Get theme functions for the display. Note that some displays may - // not have themes. The 'feed' display, for example, completely - // delegates to the style. + // Get theme functions for the display. Note that some displays may not + // have themes. The 'feed' display, for example, completely delegates to + // the style. if (!empty($this->definition['theme'])) { - $funcs[] = $this->option_link(t('Display output'), 'analyze-theme-display') . ': ' . $this->format_themes($this->theme_functions()); + $funcs[] = $this->option_link(t('Display output'), 'analyze-theme-display') . ': ' . $this->format_themes($this->theme_functions()); $themes = $this->additional_theme_functions(); if ($themes) { foreach ($themes as $theme) { - $funcs[] = $this->option_link(t('Alternative display output'), 'analyze-theme-display') . ': ' . $this->format_themes($theme); + $funcs[] = $this->option_link(t('Alternative display output'), 'analyze-theme-display') . ': ' . $this->format_themes($theme); } } } @@ -1991,7 +2042,7 @@ class views_plugin_display extends views_plugin { $themes = $plugin->additional_theme_functions(); if ($themes) { foreach ($themes as $theme) { - $funcs[] = $this->option_link(t('Alternative style'), 'analyze-theme-style') . ': ' . $this->format_themes($theme); + $funcs[] = $this->option_link(t('Alternative style'), 'analyze-theme-style') . ': ' . $this->format_themes($theme); } } @@ -2002,7 +2053,7 @@ class views_plugin_display extends views_plugin { $themes = $row_plugin->additional_theme_functions(); if ($themes) { foreach ($themes as $theme) { - $funcs[] = $this->option_link(t('Alternative row style'), 'analyze-theme-row') . ': ' . $this->format_themes($theme); + $funcs[] = $this->option_link(t('Alternative row style'), 'analyze-theme-row') . ': ' . $this->format_themes($theme); } } } @@ -2158,8 +2209,8 @@ class views_plugin_display extends views_plugin { $output .= '

    ' . t('This is the default theme template used for this row style.') . '

    '; - // Field templates aren't registered the normal way...and they're always - // this one, anyhow. + // Field templates aren't registered the normal way... and they're + // always this one, anyhow. $output .= '
    ' . check_plain(file_get_contents(drupal_get_path('module', 'views') . '/theme/views-view-field.tpl.php')) . '
    '; $form['analysis'] = array( @@ -2189,7 +2240,7 @@ class views_plugin_display extends views_plugin { ); $exposed_form = $this->get_option('exposed_form'); - $form['exposed_form']['type'] = array( + $form['exposed_form']['type'] = array( '#type' => 'radios', '#options' => views_fetch_plugin_names('exposed_form', NULL, array($this->view->base_table)), '#default_value' => $exposed_form['type'], @@ -2232,7 +2283,7 @@ class views_plugin_display extends views_plugin { ); $pager = $this->get_option('pager'); - $form['pager']['type'] = array( + $form['pager']['type'] = array( '#type' => 'radios', '#options' => views_fetch_plugin_names('pager', empty($this->definition['use pager']) ? 'basic' : NULL, array($this->view->base_table)), '#default_value' => $pager['type'], @@ -2287,7 +2338,7 @@ class views_plugin_display extends views_plugin { $template_path = isset($registry[$theme]['path']) ? $registry[$theme]['path'] . '/' : './'; if (file_exists($template_path . $template)) { $hint = t('File found in folder @template-path', array('@template-path' => $template_path)); - $template = '' . $template . ''; + $template = '' . $template . ''; } else { $template = '' . $template . ' ' . t('(File not found, in folder @template-path)', array('@template-path' => $template_path)) . ''; @@ -2297,7 +2348,7 @@ class views_plugin_display extends views_plugin { $fixed[] = $template; } - return implode(', ', array_reverse($fixed)); + return theme('item_list', array('items' => array_reverse($fixed))); } /** @@ -2335,7 +2386,7 @@ class views_plugin_display extends views_plugin { case 'style_options': $style = TRUE; case 'row_options': - // if row, $style will be empty. + // If row, $style will be empty. $plugin = $this->get_plugin(empty($style) ? 'row' : 'style'); if ($plugin) { $plugin->options_validate($form[$form_state['section']], $form_state); @@ -2384,6 +2435,7 @@ class views_plugin_display extends views_plugin { /** * Perform any necessary changes to the form values prior to storage. + * * There is no need for this function to actually store the data. */ public function options_submit(&$form, &$form_state) { @@ -2474,7 +2526,7 @@ class views_plugin_display extends views_plugin { case 'use_ajax': case 'hide_attachment_summary': case 'hide_admin_links': - $this->set_option($section, (bool)$form_state['values'][$section]); + $this->set_option($section, (bool) $form_state['values'][$section]); break; case 'use_more': @@ -2499,7 +2551,7 @@ class views_plugin_display extends views_plugin { $this->set_option($section, $form_state['values'][$section]); $this->set_option('row_options', array()); - // send ajax form to options page if we use it. + // Send ajax form to options page if we use it. if (!empty($plugin->definition['uses options'])) { views_ui_add_form_to_stack('display', $this->view, $this->display->id, array('row_options')); } @@ -2515,7 +2567,7 @@ class views_plugin_display extends views_plugin { if ($plugin) { $this->set_option($section, $form_state['values'][$section]); $this->set_option('style_options', array()); - // send ajax form to options page if we use it. + // Send ajax form to options page if we use it. if (!empty($plugin->definition['uses options'])) { views_ui_add_form_to_stack('display', $this->view, $this->display->id, array('style_options')); } @@ -2526,7 +2578,7 @@ class views_plugin_display extends views_plugin { case 'style_options': $style = TRUE; case 'row_options': - // if row, $style will be empty. + // If row, $style will be empty. $plugin = $this->get_plugin(empty($style) ? 'row' : 'style'); if ($plugin) { $plugin->options_submit($form['options'][$section], $form_state); @@ -2610,8 +2662,8 @@ class views_plugin_display extends views_plugin { * Which option should be marked as overridden, for example "filters". * @param bool $new_state * Select the new state of the option. - * - TRUE: Revert to default. - * - FALSE: Mark it as overridden. + * - TRUE: Revert to default. + * - FALSE: Mark it as overridden. */ public function set_override($section, $new_state = NULL) { $options = $this->defaultable_sections($section); @@ -2631,7 +2683,7 @@ class views_plugin_display extends views_plugin { unset($this->display->display_options[$option]); } else { - // copy existing values into our display. + // Copy existing values into our display. $this->options[$option] = $this->get_option($option); $this->display->display_options[$option] = $this->options[$option]; } @@ -2702,7 +2754,12 @@ class views_plugin_display extends views_plugin { $path = check_url(url($path, $url_options)); - return theme($theme, array('more_url' => $path, 'new_window' => $this->use_more_open_new_window(), 'link_text' => check_plain($this->use_more_text()), 'view' => $this->view)); + return theme($theme, array( + 'more_url' => $path, + 'new_window' => $this->use_more_open_new_window(), + 'link_text' => check_plain($this->use_more_text()), + 'view' => $this->view, + )); } } } @@ -2790,9 +2847,10 @@ class views_plugin_display extends views_plugin { } /** - * Set up any variables on the view prior to execution. These are separated - * from execute because they are extremely common and unlikely to be - * overridden on an individual display. + * Set up any variables on the view prior to execution. + * + * These are separated from execute because they are extremely common and + * unlikely to be overridden on an individual display. */ public function pre_execute() { $this->view->set_use_ajax($this->use_ajax()); @@ -2955,7 +3013,7 @@ class views_plugin_display extends views_plugin { */ public function view_special_blocks($type) { if ($type == '-exp') { - // avoid interfering with the admin forms. + // Avoid interfering with the admin forms. if (arg(0) == 'admin' && arg(1) == 'structure' && arg(2) == 'views') { return; } @@ -3011,7 +3069,7 @@ class views_plugin_display extends views_plugin { $output = ''; // Cut the 's' off because the data is stored as the plural form but we need - // the singular form. Who designed that anyway? Oh yeah, I did. :( + // the singular form. if ($option != 'header' && $option != 'footer' && $option != 'empty') { $type = substr($option, 0, -1); } @@ -3026,9 +3084,9 @@ class views_plugin_display extends views_plugin { else { $handler_type = $type; } - // If aggregation is on, the group type might override the actual - // handler that is in use. This piece of code checks that and, - // if necessary, sets the override handler. + // If aggregation is on, the group type might override the actual handler + // that is in use. This piece of code checks that and, if necessary, sets + // the override handler. $override = NULL; if ($this->use_group_by() && !empty($info['group_type'])) { if (empty($this->view->query)) { @@ -3057,8 +3115,8 @@ class views_plugin_display extends views_plugin { * Special handling for the style export. * * Styles are stored as style_plugin and style_options or row_plugin and - * row_options accordingly. The options are told not to export, and the - * export for the plugin should export both. + * row_options accordingly. The options are told not to export, and the export + * for the plugin should export both. */ public function export_style($indent, $prefix, $storage, $option, $definition, $parents) { $output = ''; @@ -3092,7 +3150,7 @@ class views_plugin_display extends views_plugin { } /** - * Special handling for plugin export + * Special handling for plugin export. * * Plugins other than styles are stored in array with 'type' being the key * to the plugin. For modern plugins, the options are stored in the 'options' @@ -3110,7 +3168,7 @@ class views_plugin_display extends views_plugin { $output .= $indent . $new_prefix . "['$option'] = '$value';\n"; - if ($plugin_type != 'access' && $plugin_type!= 'cache') { + if ($plugin_type != 'access' && $plugin_type != 'cache') { $new_prefix .= "['options']"; } @@ -3172,7 +3230,7 @@ class views_plugin_display extends views_plugin { $output = ''; // Cut the 's' off because the data is stored as the plural form but we need - // the singular form. Who designed that anyway? Oh yeah, I did. :( + // the singular form. if ($option != 'header' && $option != 'footer' && $option != 'empty') { $type = substr($option, 0, -1); } @@ -3190,7 +3248,8 @@ class views_plugin_display extends views_plugin { $handler = views_get_handler($info['table'], $info['field'], $handler_type); if ($handler) { $handler->init($this->view, $info); - $handler->unpack_translatables($translatable, array_merge($parents, array($type, $info['table'], $info['id']))); + $items = array_merge($parents, array($type, $info['table'], $info['id'])); + $handler->unpack_translatables($translatable, $items); } // Prevent reference problems. @@ -3203,14 +3262,13 @@ class views_plugin_display extends views_plugin { /** * Provide some helpful text for the arguments. * - * The result should contain of an array with - * - filter value present: The title of the fieldset in the argument - * where you can configure what should be done with a given argument. - * - filter value not present: The tiel of the fieldset in the argument - * where you can configure what should be done if the argument does not - * exist. - * - description: A description about how arguments comes to the display. - * For example blocks don't get it from url. + * The result should contain of an array with: + * - filter value present: The title of the fieldset in the argument where + * you can configure what should be done with a given argument. + * - filter value not present: The tiel of the fieldset in the argument where + * you can configure what should be done if the argument does not exist. + * - description: A description about how arguments comes to the display. For + * example blocks don't get it from url. */ public function get_argument_text() { return array( @@ -3223,13 +3281,14 @@ class views_plugin_display extends views_plugin { /** * Provide some helpful text for pagers. * - * The result should contain of an array within - * - items per page title + * The result should contain of an array with: + * - items per page title. + * - items per page description. */ public function get_pager_text() { return array( 'items per page title' => t('Items to display'), - 'items per page description' => t('The number of items to display. Enter 0 for no limit.') + 'items per page description' => t('The number of items to display. Enter 0 for no limit.'), ); } diff --git a/sites/all/modules/contrib/views/views/plugins/views_plugin_display_attachment.inc b/sites/all/modules/contrib/views/views/plugins/views_plugin_display_attachment.inc index c80771a0..57bd0906 100644 --- a/sites/all/modules/contrib/views/views/plugins/views_plugin_display_attachment.inc +++ b/sites/all/modules/contrib/views/views/plugins/views_plugin_display_attachment.inc @@ -22,6 +22,8 @@ class views_plugin_display_attachment extends views_plugin_display { public function option_definition () { $options = parent::option_definition(); + $options['show_title'] = array('default' => FALSE, 'bool' => TRUE); + $options['show_title_empty'] = array('default' => FALSE, 'bool' => TRUE); $options['displays'] = array('default' => array()); $options['attachment_position'] = array('default' => 'before'); $options['inherit_arguments'] = array('default' => TRUE, 'bool' => TRUE); @@ -88,6 +90,18 @@ class views_plugin_display_attachment extends views_plugin_display { $attach_to = t('Not defined'); } + $options['show_title'] = array( + 'category' => 'title', + 'title' => t('Show title'), + 'value' => $this->get_option('show_title') ? t('Yes') : t('No'), + ); + + $options['show_title_empty'] = array( + 'category' => 'title', + 'title' => t('Show title even if view has no results'), + 'value' => $this->get_option('show_title_empty') ? t('Yes') : t('No'), + ); + $options['displays'] = array( 'category' => 'attachment', 'title' => t('Attach to'), @@ -134,6 +148,24 @@ class views_plugin_display_attachment extends views_plugin_display { parent::options_form($form, $form_state); switch ($form_state['section']) { + case 'show_title': + $form['#title'] .= t('Title'); + $form['show_title'] = array( + '#type' => 'checkbox', + '#title' => t('Show title'), + '#description' => t('Do you want to show the title of the attachment?'), + '#default_value' => $this->get_option('show_title'), + ); + break; + case 'show_title_empty': + $form['#title'] .= t('Title'); + $form['show_title_empty'] = array( + '#type' => 'checkbox', + '#title' => t('Show title for empty view'), + '#description' => t('Do you want to show the title of the attachment even if the view has no results?'), + '#default_value' => $this->get_option('show_title_empty'), + ); + break; case 'inherit_arguments': $form['#title'] .= t('Inherit contextual filters'); $form['inherit_arguments'] = array( @@ -210,6 +242,8 @@ class views_plugin_display_attachment extends views_plugin_display { // It is very important to call the parent function here. parent::options_submit($form, $form_state); switch ($form_state['section']) { + case 'show_title': + case 'show_title_empty': case 'inherit_arguments': case 'inherit_pager': case 'render_pager': @@ -242,7 +276,7 @@ class views_plugin_display_attachment extends views_plugin_display { $args = $this->get_option('inherit_arguments') ? $this->view->args : array(); $view->set_arguments($args); - $exposed_input = $this->get_option('inherit_exposed_filters') ? $this->view->exposed_input : array(); + $exposed_input = $this->get_option('inherit_exposed_filters') && isset($this->view->exposed_input) ? $this->view->exposed_input : array(); $view->set_exposed_input($exposed_input); $view->set_display($this->display->id); if ($this->get_option('inherit_pager')) { @@ -250,7 +284,20 @@ class views_plugin_display_attachment extends views_plugin_display { $view->display_handler->set_option('pager', $this->view->display[$display_id]->handler->get_option('pager')); } - $attachment = $view->execute_display($this->display->id, $args); + $attachment_output = $view->execute_display($this->display->id, $args); + + $attachment = ''; + if ($view->display_handler->get_option('show_title') && $view->display_handler->get_option('title')) { + if ($view->display_handler->get_option('show_title_empty') || !empty($view->result)) { + $attachment .= theme('html_tag', array( + 'element' => array( + '#tag' => 'h2', + '#value' => $view->display_handler->get_option('title'), + ), + )); + } + } + $attachment .= $attachment_output; switch ($this->get_option('attachment_position')) { case 'before': diff --git a/sites/all/modules/contrib/views/views/plugins/views_plugin_display_page.inc b/sites/all/modules/contrib/views/views/plugins/views_plugin_display_page.inc index e2cc0177..9b9e900b 100644 --- a/sites/all/modules/contrib/views/views/plugins/views_plugin_display_page.inc +++ b/sites/all/modules/contrib/views/views/plugins/views_plugin_display_page.inc @@ -167,6 +167,9 @@ class views_plugin_display_page extends views_plugin_display { case 'default tab': $items[$path]['type'] = MENU_DEFAULT_LOCAL_TASK; break; + case 'local action': + $items[$path]['type'] = MENU_LOCAL_ACTION; + break; } // Add context for contextual links. @@ -311,6 +314,8 @@ class views_plugin_display_page extends views_plugin_display { case 'default tab': $menu_str = t('Tab: @title', array('@title' => $menu['title'])); break; + case 'local action': + $menu_str = t('Local action: @title', array('@title' => $menu['title'])); } $options['menu'] = array( @@ -345,6 +350,7 @@ class views_plugin_display_page extends views_plugin_display { '#field_prefix' => '' . url(NULL, array('absolute' => TRUE)) . (variable_get('clean_url', 0) ? '' : '?q='), '#field_suffix' => '‎', '#attributes' => array('dir'=>'ltr'), + '#maxlength' => 255, ); break; @@ -360,6 +366,7 @@ class views_plugin_display_page extends views_plugin_display { if (empty($menu)) { $menu = array('type' => 'none', 'title' => '', 'weight' => 0); } + $menu_type_dependencies = array('normal', 'tab', 'default tab', 'local action'); $form['menu']['type'] = array( '#prefix' => '
    ', '#suffix' => '
    ', @@ -369,7 +376,8 @@ class views_plugin_display_page extends views_plugin_display { 'none' => t('No menu entry'), 'normal' => t('Normal menu entry'), 'tab' => t('Menu tab'), - 'default tab' => t('Default menu tab') + 'default tab' => t('Default menu tab'), + 'local action' => t('Local action'), ), '#default_value' => $menu['type'], ); @@ -379,14 +387,14 @@ class views_plugin_display_page extends views_plugin_display { '#type' => 'textfield', '#default_value' => $menu['title'], '#description' => t('If set to normal or tab, enter the text to use for the menu item.'), - '#dependency' => array('radio:menu[type]' => array('normal', 'tab', 'default tab')), + '#dependency' => array('radio:menu[type]' => $menu_type_dependencies), ); $form['menu']['description'] = array( '#title' => t('Description'), '#type' => 'textfield', '#default_value' => $menu['description'], '#description' => t("If set to normal or tab, enter the text to use for the menu item's description."), - '#dependency' => array('radio:menu[type]' => array('normal', 'tab', 'default tab')), + '#dependency' => array('radio:menu[type]' => $menu_type_dependencies), ); // Only display the menu selector if menu module is enabled. @@ -414,7 +422,7 @@ class views_plugin_display_page extends views_plugin_display { '#type' => 'textfield', '#default_value' => isset($menu['weight']) ? $menu['weight'] : 0, '#description' => t('The lower the weight the higher/further left it will appear.'), - '#dependency' => array('radio:menu[type]' => array('normal', 'tab', 'default tab')), + '#dependency' => array('radio:menu[type]' => $menu_type_dependencies), ); $form['menu']['context'] = array( '#title' => t('Context'), @@ -502,8 +510,8 @@ class views_plugin_display_page extends views_plugin_display { '#type' => 'textfield', '#default_value' => $tab_options['weight'], '#size' => 5, - '#description' => t('If the parent menu item is a tab, enter the weight of the tab. The lower the number, the more to the left it will be.'), - '#dependency' => array('radio:tab_options[type]' => array('tab')), + '#description' => t('Enter the weight of the item. The lower the number, the more to the left it will be.'), + '#dependency' => array('radio:tab_options[type]' => array('normal', 'tab')), ); break; } diff --git a/sites/all/modules/contrib/views/views/plugins/views_plugin_exposed_form.inc b/sites/all/modules/contrib/views/views/plugins/views_plugin_exposed_form.inc index 2bba7302..5493be36 100644 --- a/sites/all/modules/contrib/views/views/plugins/views_plugin_exposed_form.inc +++ b/sites/all/modules/contrib/views/views/plugins/views_plugin_exposed_form.inc @@ -128,7 +128,7 @@ class views_plugin_exposed_form extends views_plugin { $form['autosubmit_hide'] = array( '#type' => 'checkbox', '#title' => t('Hide submit button'), - '#description' => t('Hide submit button if javascript is enabled.'), + '#description' => t('Hide submit button if JavaScript is enabled.'), '#default_value' => $this->options['autosubmit_hide'], '#dependency' => array( 'edit-exposed-form-options-autosubmit' => array(1), diff --git a/sites/all/modules/contrib/views/views/plugins/views_plugin_pager.inc b/sites/all/modules/contrib/views/views/plugins/views_plugin_pager.inc index ab458639..0217f4dd 100644 --- a/sites/all/modules/contrib/views/views/plugins/views_plugin_pager.inc +++ b/sites/all/modules/contrib/views/views/plugins/views_plugin_pager.inc @@ -50,7 +50,7 @@ class views_plugin_pager extends views_plugin { * most pagers will not need to override this method. */ public function get_items_per_page() { - return isset($this->options['items_per_page']) ? $this->options['items_per_page'] : 0; + return isset($this->options['items_per_page']) ? (int) $this->options['items_per_page'] : 0; } /** @@ -59,7 +59,7 @@ class views_plugin_pager extends views_plugin { * This is mostly used for things that will override the value. */ public function set_items_per_page($items) { - $this->options['items_per_page'] = $items; + $this->options['items_per_page'] = (int) $items; } /** @@ -69,14 +69,14 @@ class views_plugin_pager extends views_plugin { * so few pagers will need to override this method. */ public function get_offset() { - return isset($this->options['offset']) ? $this->options['offset'] : 0; + return isset($this->options['offset']) ? (int) $this->options['offset'] : 0; } /** * Set the page offset, or how many items to skip. */ public function set_offset($offset) { - $this->options['offset'] = $offset; + $this->options['offset'] = (int) $offset; } /** diff --git a/sites/all/modules/contrib/views/views/plugins/views_plugin_pager_full.inc b/sites/all/modules/contrib/views/views/plugins/views_plugin_pager_full.inc index fff7691d..578bebee 100644 --- a/sites/all/modules/contrib/views/views/plugins/views_plugin_pager_full.inc +++ b/sites/all/modules/contrib/views/views/plugins/views_plugin_pager_full.inc @@ -252,7 +252,7 @@ class views_plugin_pager_full extends views_plugin_pager { public function query() { if ($this->items_per_page_exposed()) { if (!empty($_GET['items_per_page']) && $_GET['items_per_page'] > 0) { - $this->options['items_per_page'] = $_GET['items_per_page']; + $this->options['items_per_page'] = (int) $_GET['items_per_page']; } elseif (!empty($_GET['items_per_page']) && $_GET['items_per_page'] == 'All' && $this->options['expose']['items_per_page_options_all']) { $this->options['items_per_page'] = 0; @@ -260,16 +260,15 @@ class views_plugin_pager_full extends views_plugin_pager { } if ($this->offset_exposed()) { if (isset($_GET['offset']) && $_GET['offset'] >= 0) { - $this->options['offset'] = $_GET['offset']; + $this->options['offset'] = (int) $_GET['offset']; } } - $limit = $this->options['items_per_page']; - $offset = $this->current_page * $this->options['items_per_page'] + $this->options['offset']; + $limit = $this->get_items_per_page(); + $offset = $this->current_page * $limit + $this->get_offset(); if (!empty($this->options['total_pages'])) { if ($this->current_page >= $this->options['total_pages']) { - $limit = $this->options['items_per_page']; - $offset = $this->options['total_pages'] * $this->options['items_per_page']; + $offset = $this->options['total_pages'] * $limit; } } diff --git a/sites/all/modules/contrib/views/views/plugins/views_plugin_query_default.inc b/sites/all/modules/contrib/views/views/plugins/views_plugin_query_default.inc index 2911a560..db3e7e27 100644 --- a/sites/all/modules/contrib/views/views/plugins/views_plugin_query_default.inc +++ b/sites/all/modules/contrib/views/views/plugins/views_plugin_query_default.inc @@ -248,15 +248,26 @@ class views_plugin_query_default extends views_plugin_query { public function options_form(&$form, &$form_state) { parent::options_form($form, $form_state); - $form['disable_sql_rewrite'] = array( - '#title' => t('Disable SQL rewriting'), - '#description' => t('Disabling SQL rewriting will disable node_access checks as well as other modules that implement hook_query_alter().'), - '#type' => 'checkbox', - '#default_value' => !empty($this->options['disable_sql_rewrite']), - '#suffix' => '
    ' - . t('WARNING: Disabling SQL rewriting means that node access security is disabled. This may allow users to see data they should not be able to see if your view is misconfigured. Please use this option only if you understand and accept this security risk.') - . '
    ', - ); + // Establish which query tag will be affected by disable_sql_rewrite. + // This 'access query tag' is defined by hook_views_data() for the base table. + // e.g. node_views_data() + if (!empty($form_state['view']->base_table)) { + $base_table = $form_state['view']->base_table; + $base_table_data = views_fetch_data($base_table); + if (!empty($base_table_data['table']['base']['access query tag'])) { + $access_tag = $base_table_data['table']['base']['access query tag']; + $disable_rewrite = !empty($this->options['disable_sql_rewrite']); + $form['disable_sql_rewrite'] = array( + '#title' => t('Disable access checks'), + '#description' => t('Do not apply %access_tag checks to this query. Selecting this option omits that tag from the alterable query.', array('%access_tag' => $access_tag)), + '#type' => 'checkbox', + '#default_value' => $disable_rewrite, + '#suffix' => '
    ' + . t('WARNING: Disabling access checks means that %access_tag security is disabled. This may allow users to see data they should not be able to see if your view is misconfigured. Please use this option only if you understand and accept this security risk.', array('%access_tag' => $access_tag)) + . '
    ', + ); + } + } $form['distinct'] = array( '#type' => 'checkbox', '#title' => t('Distinct'), @@ -1214,7 +1225,10 @@ class views_plugin_query_default extends views_plugin_query { } // This is a formula, using no tables. elseif (empty($field['table'])) { - if (!in_array($fieldname, $non_aggregates)) { + if (Database::getConnection()->databaseType() != 'pgsql') { + $non_aggregates[] = $fieldname; + } + elseif (!in_array($fieldname, $non_aggregates)) { $non_aggregates[] = $fieldname; } $placeholders = !empty($field['placeholders']) ? $field['placeholders'] : array(); @@ -1224,13 +1238,16 @@ class views_plugin_query_default extends views_plugin_query { elseif ($this->distinct && !in_array($fieldname, $this->groupby)) { // d7cx: This code was there, apparently needed for PostgreSQL // $string = db_driver() == 'pgsql' ? "FIRST($string)" : $string; - if (!in_array($string, $non_aggregates)) { + if (Database::getConnection()->databaseType() == 'pgsql' && !in_array($string, $non_aggregates)) { $non_aggregates[] = $string; } $query->addField(!empty($field['table']) ? $field['table'] : $this->base_table, $field['field'], $fieldname); } elseif (empty($field['aggregate'])) { - if (!in_array($string, $non_aggregates)) { + if (Database::getConnection()->databaseType() != 'pgsql') { + $non_aggregates[] = $fieldname; + } + elseif (!in_array($string, $non_aggregates)) { $non_aggregates[] = $string; } $query->addField(!empty($field['table']) ? $field['table'] : $this->base_table, $field['field'], $fieldname); @@ -1340,8 +1357,9 @@ class views_plugin_query_default extends views_plugin_query { if (count($this->having)) { $this->has_aggregate = TRUE; } - elseif (!$this->has_aggregate) { - // Allow 'GROUP BY' even no aggregation function has been set. + // Allow 'GROUP BY' even if no aggregation function has been set, but only + // when there is a legitimate display_handler. + elseif (!$this->has_aggregate && !empty($this->view->display_handler)) { $this->has_aggregate = $this->view->display_handler->get_option('group_by'); } if ($this->has_aggregate && (!empty($this->groupby) || !empty($non_aggregates))) { diff --git a/sites/all/modules/contrib/views/views/plugins/views_plugin_style.inc b/sites/all/modules/contrib/views/views/plugins/views_plugin_style.inc index 6f3cf34c..1433f319 100644 --- a/sites/all/modules/contrib/views/views/plugins/views_plugin_style.inc +++ b/sites/all/modules/contrib/views/views/plugins/views_plugin_style.inc @@ -372,6 +372,7 @@ class views_plugin_style extends views_plugin { $output = ''; foreach ($sets as $set) { $row = reset($set['rows']); + $level = isset($set['level']) ? $set['level'] : 0; // Render as a grouping set. if (is_array($row) && isset($row['group'])) { $output .= theme(views_theme_functions('views_view_grouping', $this->view, $this->display), @@ -463,7 +464,7 @@ class views_plugin_style extends views_plugin { // hierarchically positioned set where the current row belongs to. // While iterating, parent groups, that do not exist yet, are added. $set = &$sets; - foreach ($groupings as $info) { + foreach ($groupings as $level => $info) { $field = $info['field']; $rendered = isset($info['rendered']) ? $info['rendered'] : $group_rendered; $rendered_strip = isset($info['rendered_strip']) ? $info['rendered_strip'] : FALSE; @@ -496,6 +497,7 @@ class views_plugin_style extends views_plugin { // Create the group if it does not exist yet. if (empty($set[$grouping])) { $set[$grouping]['group'] = $group_content; + $set[$grouping]['level'] = $level; $set[$grouping]['rows'] = array(); } diff --git a/sites/all/modules/contrib/views/views/plugins/views_plugin_style_jump_menu.inc b/sites/all/modules/contrib/views/views/plugins/views_plugin_style_jump_menu.inc index 3d83ea34..418766b1 100644 --- a/sites/all/modules/contrib/views/views/plugins/views_plugin_style_jump_menu.inc +++ b/sites/all/modules/contrib/views/views/plugins/views_plugin_style_jump_menu.inc @@ -65,7 +65,7 @@ class views_plugin_style_jump_menu extends views_plugin_style { '#type' => 'checkbox', '#title' => t('Hide the "Go" button'), '#default_value' => !empty($this->options['hide']), - '#description' => t('If hidden, this button will only be hidden for users with javascript and the page will automatically jump when the select is changed.'), + '#description' => t('If hidden, this button will only be hidden for users with JavaScript and the page will automatically jump when the select is changed.'), ); $form['text'] = array( diff --git a/sites/all/modules/contrib/views/views/plugins/views_plugin_style_summary_jump_menu.inc b/sites/all/modules/contrib/views/views/plugins/views_plugin_style_summary_jump_menu.inc index 17fdcca9..ee75f24e 100644 --- a/sites/all/modules/contrib/views/views/plugins/views_plugin_style_summary_jump_menu.inc +++ b/sites/all/modules/contrib/views/views/plugins/views_plugin_style_summary_jump_menu.inc @@ -66,7 +66,7 @@ class views_plugin_style_summary_jump_menu extends views_plugin_style { '#type' => 'checkbox', '#title' => t('Hide the "Go" button'), '#default_value' => !empty($this->options['hide']), - '#description' => t('If hidden, this button will only be hidden for users with javascript and the page will automatically jump when the select is changed.'), + '#description' => t('If hidden, this button will only be hidden for users with JavaScript and the page will automatically jump when the select is changed.'), ); $form['text'] = array( diff --git a/sites/all/modules/contrib/views/views/plugins/views_plugin_style_table.inc b/sites/all/modules/contrib/views/views/plugins/views_plugin_style_table.inc index 75fe3897..54679205 100644 --- a/sites/all/modules/contrib/views/views/plugins/views_plugin_style_table.inc +++ b/sites/all/modules/contrib/views/views/plugins/views_plugin_style_table.inc @@ -31,6 +31,7 @@ class views_plugin_style_table extends views_plugin_style { $options = parent::option_definition(); $options['columns'] = array('default' => array()); + $options['class'] = array('default' => array()); $options['default'] = array('default' => ''); $options['info'] = array('default' => array()); $options['override'] = array('default' => TRUE, 'bool' => TRUE); @@ -178,7 +179,7 @@ class views_plugin_style_table extends views_plugin_style { $form['sticky'] = array( '#type' => 'checkbox', - '#title' => t('Enable Drupal style "sticky" table headers (Javascript)'), + '#title' => t('Enable Drupal style "sticky" table headers (JavaScript)'), '#default_value' => !empty($this->options['sticky']), '#description' => t('(Sticky header effects will not be active for preview below, only on live output.)'), ); @@ -198,6 +199,14 @@ class views_plugin_style_table extends views_plugin_style { '#default_value' => $this->options['summary'], '#maxlength' => 255, ); + + $form['class'] = array( + '#type' => 'textfield', + '#title' => t('CSS classes'), + '#description' => t('Add CSS classes to the table; multiple classes may be separated by spaces.'), + '#default_value' => $this->options['class'], + '#maxlength' => 255, + ); // Note: views UI registers this theme handler on our behalf. Your module // will have to register your theme handlers if you do stuff like this. @@ -296,7 +305,7 @@ class views_plugin_style_table extends views_plugin_style { '#type' => 'checkbox', '#title' => t('Show the empty text in the table'), '#default_value' => $this->options['empty_table'], - '#description' => t('Per default the table is hidden for an empty view. With this option it is posible to show an empty table with the text in it.'), + '#description' => t('Per default the table is hidden for an empty view. With this option it is possible to show an empty table with the text in it.'), ); $form['description_markup'] = array( diff --git a/sites/all/modules/contrib/views/views/tests/handlers/views_handler_filter_numeric.test b/sites/all/modules/contrib/views/views/tests/handlers/views_handler_filter_numeric.test index 6cfe2d37..a18e20ac 100644 --- a/sites/all/modules/contrib/views/views/tests/handlers/views_handler_filter_numeric.test +++ b/sites/all/modules/contrib/views/views/tests/handlers/views_handler_filter_numeric.test @@ -314,6 +314,38 @@ class ViewsHandlerFilterNumericTest extends ViewsSqlTest { $this->assertIdenticalResultset($view, $resultset, $this->column_map); } + /** + * Tests the limit operators functionality. + */ + public function testFilterNumericExposedLimitOperators() { + $filters = $this->getGroupedExposedFilters(); + $view = $this->getBasicView(); + + $available_operators = array('<', '>', 'between'); + + $filters['age']['expose'] += array( + 'limit_operators' => TRUE, + 'available_operators' => drupal_map_assoc($available_operators), + ); + + $view->display['default']->handler->override_option('filters', $filters); + + + $this->executeView($view); + + $form = array(); + $form_state = array(); + $view->filter['age']->operator_form($form, $form_state); + + $operator = $form['operator']; + + $this->assertTrue(in_array($operator['#default_value'], $available_operators), 'Default value operator found in list of available operators.'); + + foreach ($available_operators as $available_operator) { + $this->assertTrue($operator['#options'][$available_operator], format_string('@operator found in options', array('@operator' => $available_operator))); + } + } + public function testAllowEmpty() { $view = $this->getBasicView(); diff --git a/sites/all/modules/contrib/views/views/tests/handlers/views_handler_manytoone.test b/sites/all/modules/contrib/views/views/tests/handlers/views_handler_manytoone.test new file mode 100644 index 00000000..fb06645e --- /dev/null +++ b/sites/all/modules/contrib/views/views/tests/handlers/views_handler_manytoone.test @@ -0,0 +1,1099 @@ + 'Handler: Many To One Helper', + 'description' => 'Tests the many to one helper handler', + 'group' => 'Views Handlers', + ); + } + + /** + * Clears views data cache. + */ + protected function clearViewsDataCache() { + drupal_static_reset('_views_fetch_data_cache'); + drupal_static_reset('_views_fetch_data_recursion_protected'); + drupal_static_reset('_views_fetch_data_fully_loaded'); + } + + /** + * Returns a new term with random properties. + * + * @param string $vocabulary + * Vocabulary ID to create term in. + * + * @return object + * Term with random properties. + */ + protected function createTerm($vocabulary) { + $term = new stdClass(); + $term->name = $this->randomName(); + $term->description = $this->randomName(); + // Use the first available text format. + $term->format = db_query_range('SELECT format FROM {filter_format}', 0, 1)->fetchField(); + $term->vid = $vocabulary->vid; + taxonomy_term_save($term); + return $term; + } + + /** + * {@inheritdoc} + */ + public function setUp() { + parent::setUp(); + + // Create boolean field. + $this->fields[0] = array( + 'field_name' => 'field_bool', + 'type' => 'list_boolean', + 'cardinality' => 1, + 'settings' => array( + 'allowed_values' => array( + 0 => '', + 1 => '', + ), + ), + ); + $this->fields[0] = field_create_field($this->fields[0]); + + // Create text list field. + $this->fields[1] = array( + 'field_name' => 'field_list', + 'type' => 'list_text', + 'cardinality' => FIELD_CARDINALITY_UNLIMITED, + 'settings' => array( + 'allowed_values' => array( + 1 => '1', + 2 => '2', + 3 => '3', + ), + ), + ); + $this->fields[1] = field_create_field($this->fields[1]); + + // Create boolean field instance for article nodes. + $instance = array( + 'field_name' => $this->fields[0]['field_name'], + 'entity_type' => 'node', + 'bundle' => 'article', + 'widget' => array( + 'type' => 'options_onoff', + ), + ); + $this->instances[0][] = field_create_instance($instance); + + // Create text list field instance for article nodes. + $instance = array( + 'field_name' => $this->fields[1]['field_name'], + 'entity_type' => 'node', + 'bundle' => 'article', + 'widget' => array( + 'type' => 'options_buttons', + ), + ); + $this->instances[1][] = field_create_instance($instance); + + // Create boolean field instance for users. + $instance = array( + 'field_name' => $this->fields[0]['field_name'], + 'entity_type' => 'user', + 'bundle' => 'user', + 'widget' => array( + 'type' => 'options_onoff', + ), + ); + $this->instances[0][] = field_create_instance($instance); + + // Create text list field instance for users. + $instance = array( + 'field_name' => $this->fields[1]['field_name'], + 'entity_type' => 'user', + 'bundle' => 'user', + 'widget' => array( + 'type' => 'options_buttons', + ), + ); + $this->instances[1][] = field_create_instance($instance); + + // Create tags field instance for users. + $instance = array( + 'field_name' => 'field_tags', + 'entity_type' => 'user', + 'bundle' => 'user', + ); + $this->instances[2][] = field_create_instance($instance); + + // Clear views data cache. + $this->clearViewsDataCache(); + + // Create 62 tags. + $vocabulary = taxonomy_vocabulary_machine_name_load('tags'); + for ($i = 0; $i < 62; $i++) { + $this->terms[] = $this->createTerm($vocabulary); + } + + // Create a node where the field_bool is checked, field_list is '1' and + // tag is term 2. + $node = array(); + $node['type'] = 'article'; + $node[$this->fields[0]['field_name']][LANGUAGE_NONE][]['value'] = '1'; + $node[$this->fields[1]['field_name']][LANGUAGE_NONE][]['value'] = '1'; + $node['field_tags'][LANGUAGE_NONE][]['tid'] = $this->terms[1]->tid; + $this->nodes[0] = $this->drupalCreateNode($node); + + // Create a node where the field_bool is not checked, field_list is empty + // and tag is term 1. + $node = array(); + $node['type'] = 'article'; + $node[$this->fields[0]['field_name']] = array(); + $node[$this->fields[1]['field_name']] = array(); + $node['field_tags'][LANGUAGE_NONE][]['tid'] = $this->terms[0]->tid; + $this->nodes[1] = $this->drupalCreateNode($node); + + // Create a node where the field_bool is not checked, field_list is empty + // and tag is term 1 and 2. + $node = array(); + $node['type'] = 'article'; + $node[$this->fields[0]['field_name']] = array(); + $node[$this->fields[1]['field_name']] = array(); + $node['field_tags'][LANGUAGE_NONE][]['tid'] = $this->terms[0]->tid; + $node['field_tags'][LANGUAGE_NONE][]['tid'] = $this->terms[1]->tid; + $this->nodes[2] = $this->drupalCreateNode($node); + + // Create a user where field_bool is checked, field_list is '1' and tag is + // term 1. + $permissions = array('access content'); + $account = $this->drupalCreateUser($permissions); + $account->{$this->fields[0]['field_name']}[LANGUAGE_NONE][]['value'] = '1'; + $account->{$this->fields[1]['field_name']}[LANGUAGE_NONE][]['value'] = '1'; + $account->field_tags[LANGUAGE_NONE][]['tid'] = $this->terms[0]->tid; + $this->accounts[0] = user_save($account); + } + + /** + * Tests "none of" filter with terms in excess of JOIN limit selected. + */ + public function testJoinLimitNoneOf() { + $view = $this->getJoinLimitNoneOfTestView(); + $this->executeView($view); + + // Assert that nodes have been created and have expected field values. + $value = field_get_items('node', $this->nodes[0], 'field_tags', LANGUAGE_NONE); + $value = isset($value[0]['tid']) ? (int) $value[0]['tid'] : 0; + $this->assertIdentical($value, 2, 'First node has been created and tags field references term 2.'); + + $value = field_get_items('node', $this->nodes[1], 'field_tags', LANGUAGE_NONE); + $value = isset($value[0]['tid']) ? (int) $value[0]['tid'] : 0; + $this->assertIdentical($value, 1, 'Second node has been created and tags field references term 1.'); + + // Assert that user has been created and has expected field values. + $value = field_get_items('user', $this->accounts[0], 'field_tags', LANGUAGE_NONE); + $value = isset($value[0]['tid']) ? (int) $value[0]['tid'] : 0; + $this->assertIdentical($value, 1, 'User has been created and tags field references term 1.'); + + // Assert that node id with empty field value matches user id so that the + // node would be excluded from the result, if the joins are missing extras. + $this->assertIdentical((int) $this->accounts[0]->uid, (int) $this->nodes[1]->nid, 'Node id of second node matches uid of first user.'); + + // Assert correct result set. + $result_count = isset($view->result) && is_array($view->result) ? count($view->result) : 0; + $this->assertEqual($result_count, 1, 'View has one result.'); + $nid = isset($view->result[0]->nid) ? (int) $view->result[0]->nid : 0; + $this->assertIdentical($nid, (int) $this->nodes[1]->nid, 'View result has correct node id.'); + } + + /** + * Tests duplicate grouped "none of" filters on boolean field. + */ + public function testGroupedNoneOf() { + $view = $this->getGroupedNoneOfTestView(); + $this->executeView($view); + + // Assert that nodes have been created and have expected field values. + $value = field_get_items('node', $this->nodes[0], $this->fields[0]['field_name'], LANGUAGE_NONE); + $value = isset($value[0]['value']) ? (int) $value[0]['value'] : 0; + $this->assertIdentical($value, 1, 'First node has been created and boolean field is checked.'); + + $value = field_get_items('node', $this->nodes[1], $this->fields[0]['field_name'], LANGUAGE_NONE); + $this->assertFalse($value, 'Second node has been created and boolean field is not checked.'); + + $value = field_get_items('node', $this->nodes[2], $this->fields[0]['field_name'], LANGUAGE_NONE); + $this->assertFalse($value, 'Third node has been created and boolean field is not checked.'); + + // Assert that user has been created and has expected field values. + $value = field_get_items('user', $this->accounts[0], $this->fields[0]['field_name'], LANGUAGE_NONE); + $value = isset($value[0]['value']) ? (int) $value[0]['value'] : 0; + $this->assertIdentical($value, 1, 'User has been created and boolean field is checked.'); + + // Assert that node ID with empty field value matches user ID so that the + // node would be excluded from the result, if the joins are missing extras. + $this->assertIdentical((int) $this->accounts[0]->uid, (int) $this->nodes[1]->nid, 'Node ID of second node matches UID of first user.'); + + // Assert correct result set. + $result_count = isset($view->result) && is_array($view->result) ? count($view->result) : 0; + $this->assertEqual($result_count, 2, 'View has two results.'); + $nid = isset($view->result[0]->nid) ? (int) $view->result[0]->nid : 0; + $result1 = ($nid === (int) $this->nodes[1]->nid); + $nid = isset($view->result[1]->nid) ? (int) $view->result[1]->nid : 0; + $result2 = ($nid === (int) $this->nodes[2]->nid); + $this->assertTrue($result1 && $result2, 'View result has correct node IDs.'); + } + + /** + * Tests duplicate grouped "one of" filters on taxonomy term field. + */ + public function testGroupedOneOf() { + $view = $this->getGroupedOneOfTestView(); + $this->executeView($view); + + // Assert that nodes have been created and have expected field values. + $value = field_get_items('node', $this->nodes[0], 'field_tags', LANGUAGE_NONE); + $value = isset($value[0]['tid']) ? (int) $value[0]['tid'] : 0; + $this->assertIdentical($value, 2, 'First node has been created and tags field references term 2.'); + + $value = field_get_items('node', $this->nodes[1], 'field_tags', LANGUAGE_NONE); + $value = isset($value[0]['tid']) ? (int) $value[0]['tid'] : 0; + $this->assertIdentical($value, 1, 'Second node has been created and tags field references term 1.'); + + $value = field_get_items('node', $this->nodes[2], 'field_tags', LANGUAGE_NONE); + $value = !empty($value[0]['tid']) && !empty($value[1]['tid']); + $this->assertTrue($value, 'Third node has been created and tags field references both terms 1 and 2.'); + + // Assert that user has been created and has expected field values. + $value = field_get_items('user', $this->accounts[0], 'field_tags', LANGUAGE_NONE); + $value = isset($value[0]['tid']) ? (int) $value[0]['tid'] : 0; + $this->assertIdentical($value, 1, 'User has been created and tags field references term 1.'); + + // Assert that node ID with empty field value matches user ID so that the + // node would be excluded from the result, if the joins are missing extras. + $this->assertIdentical((int) $this->accounts[0]->uid, (int) $this->nodes[1]->nid, 'Node ID of second node matches UID of first user.'); + + // Assert correct result set. + $result_count = isset($view->result) && is_array($view->result) ? count($view->result) : 0; + $this->assertEqual($result_count, 2, 'View has two results.'); + $nid = isset($view->result[0]->nid) ? (int) $view->result[0]->nid : 0; + $result1 = ($nid === (int) $this->nodes[1]->nid); + $nid = isset($view->result[1]->nid) ? (int) $view->result[1]->nid : 0; + $result2 = ($nid === (int) $this->nodes[2]->nid); + $this->assertTrue($result1 && $result2, 'View result has correct node IDs.'); + } + + /** + * Tests exposed filter with "Reduce duplicates." and grouped options. + */ + public function testReducedExposedGroupedOptions() { + // Assert that nodes have been created and have expected field values. + $value = field_get_items('node', $this->nodes[0], 'field_list', LANGUAGE_NONE); + $value = isset($value[0]['value']) ? (int) $value[0]['value'] : 0; + $this->assertIdentical($value, 1, 'First node has been created and list field has value 1.'); + + $value = field_get_items('node', $this->nodes[1], 'field_list', LANGUAGE_NONE); + $this->assertFalse($value, 'Second node has been created and list field is empty.'); + + $value = field_get_items('node', $this->nodes[2], 'field_list', LANGUAGE_NONE); + $this->assertFalse($value, 'Third node has been created and list field is empty.'); + + // Assert that user has been created and has expected field values. + $value = field_get_items('user', $this->accounts[0], 'field_list', LANGUAGE_NONE); + $value = isset($value[0]['value']) ? (int) $value[0]['value'] : 0; + $this->assertIdentical($value, 1, 'User has been created and list field has value 1.'); + + // Assert that node ID with empty field value matches user ID so that the + // node would be excluded from the result option 1, if the joins are missing + // extras. + $this->assertIdentical((int) $this->accounts[0]->uid, (int) $this->nodes[1]->nid, 'Node ID of second node matches UID of first user.'); + + // Default option: Any. + $view = $this->getReducedExposedGroupedOptionsTestView(); + $this->executeView($view); + + // Assert correct result set. + $result_count = isset($view->result) && is_array($view->result) ? count($view->result) : 0; + $this->assertEqual($result_count, 3, 'Default option: View has three results.'); + $nid = isset($view->result[0]->nid) ? (int) $view->result[0]->nid : 0; + $result1 = ($nid === (int) $this->nodes[0]->nid); + $nid = isset($view->result[1]->nid) ? (int) $view->result[1]->nid : 0; + $result2 = ($nid === (int) $this->nodes[1]->nid); + $nid = isset($view->result[2]->nid) ? (int) $view->result[2]->nid : 0; + $result3 = ($nid === (int) $this->nodes[2]->nid); + $this->assertTrue($result1 && $result2 && $result3, 'Default option: View result has correct node ID.'); + + // Option 1: Is none of 1 or 2. + $view = $this->getReducedExposedGroupedOptionsTestView(); + $view->set_exposed_input(array( + 'field_list_value' => '1', + )); + $this->executeView($view); + + // Assert correct result set. + $result_count = isset($view->result) && is_array($view->result) ? count($view->result) : 0; + $this->assertEqual($result_count, 2, 'Option 1: View has two results.'); + $nid = isset($view->result[0]->nid) ? (int) $view->result[0]->nid : 0; + $result1 = ($nid === (int) $this->nodes[1]->nid); + $nid = isset($view->result[1]->nid) ? (int) $view->result[1]->nid : 0; + $result2 = ($nid === (int) $this->nodes[2]->nid); + $this->assertTrue($result1 && $result2, 'Option 1: View result has correct node ID.'); + + // Option 2: Is one of 1. + $view = $this->getReducedExposedGroupedOptionsTestView(); + $view->set_exposed_input(array( + 'field_list_value' => '2', + )); + $this->executeView($view); + + // Assert correct result set. + $result_count = isset($view->result) && is_array($view->result) ? count($view->result) : 0; + $this->assertEqual($result_count, 1, 'Option 2: View has one result.'); + $nid = isset($view->result[0]->nid) ? (int) $view->result[0]->nid : 0; + $this->assertIdentical($nid, (int) $this->nodes[0]->nid, 'Option 2: View result has correct node ID.'); + + // Option 3: Is one of 1 or 2. + $view = $this->getReducedExposedGroupedOptionsTestView(); + $view->set_exposed_input(array( + 'field_list_value' => '3', + )); + $this->executeView($view); + + // Assert correct result set. + $result_count = isset($view->result) && is_array($view->result) ? count($view->result) : 0; + $this->assertEqual($result_count, 1, 'Option 3: View has one result.'); + $nid = isset($view->result[0]->nid) ? (int) $view->result[0]->nid : 0; + $this->assertIdentical($nid, (int) $this->nodes[0]->nid, 'Option 3: View result has correct node ID.'); + + /* @todo: Fix and uncomment in issue #3045168. + * // Option 4: Is all of 1 and 2. + * $view = $this->getReducedExposedGroupedOptionsTestView(); + * $view->set_exposed_input(array( + * 'field_list_value' => '4', + * )); + * $this->executeView($view); + * + * // Assert correct result set. + * $result_count = isset($view->result) && is_array($view->result) ? count($view->result) : 1; + * $this->assertEqual($result_count, 0, 'Option 4: View has empty result.'); + */ + + // Option 5: Is empty. + $view = $this->getReducedExposedGroupedOptionsTestView(); + $view->set_exposed_input(array( + 'field_list_value' => '5', + )); + $this->executeView($view); + + // Assert correct result set. + $result_count = isset($view->result) && is_array($view->result) ? count($view->result) : 0; + $this->assertEqual($result_count, 2, 'Option 5: View has two results.'); + $nid = isset($view->result[0]->nid) ? (int) $view->result[0]->nid : 0; + $result1 = ($nid === (int) $this->nodes[1]->nid); + $nid = isset($view->result[1]->nid) ? (int) $view->result[1]->nid : 0; + $result2 = ($nid === (int) $this->nodes[2]->nid); + $this->assertTrue($result1 && $result2, 'Option 5: View result has correct node IDs.'); + + // Option 6: Is not empty. + $view = $this->getReducedExposedGroupedOptionsTestView(); + $view->set_exposed_input(array( + 'field_list_value' => '6', + )); + $this->executeView($view); + + // Assert correct result set. + $result_count = isset($view->result) && is_array($view->result) ? count($view->result) : 0; + $this->assertEqual($result_count, 1, 'Option 6: View has one result.'); + $nid = isset($view->result[0]->nid) ? (int) $view->result[0]->nid : 0; + $this->assertIdentical($nid, (int) $this->nodes[0]->nid, 'Option 6: View result has correct node ID.'); + } + + /** + * Tests exposed filter on term ID with grouped options. + */ + public function testTermIdExposedGroupedOptions() { + // Assert that nodes have been created and have expected field values. + $value = field_get_items('node', $this->nodes[0], 'field_tags', LANGUAGE_NONE); + $value = isset($value[0]['tid']) ? (int) $value[0]['tid'] : 0; + $this->assertIdentical($value, 2, 'First node has been created and tags field references term 2.'); + + $value = field_get_items('node', $this->nodes[1], 'field_tags', LANGUAGE_NONE); + $value = isset($value[0]['tid']) ? (int) $value[0]['tid'] : 0; + $this->assertIdentical($value, 1, 'Second node has been created and tags field references term 1.'); + + // Assert that user has been created and has expected field values. + $value = field_get_items('user', $this->accounts[0], 'field_tags', LANGUAGE_NONE); + $value = isset($value[0]['tid']) ? (int) $value[0]['tid'] : 0; + $this->assertIdentical($value, 1, 'User has been created and tags field references term 1.'); + + // Assert that node ID with empty field value matches user ID so that the + // node would be excluded from the result option 1, if the joins are missing + // extras. + $this->assertIdentical((int) $this->accounts[0]->uid, (int) $this->nodes[1]->nid, 'Node ID of second node matches UID of first user.'); + + // Default option: Any. + $view = $this->getTermIdExposedGroupedOptionsTestView(); + $this->executeView($view); + + // Assert correct result set. + $result_count = isset($view->result) && is_array($view->result) ? count($view->result) : 0; + $this->assertEqual($result_count, 3, 'Default option: View has three results.'); + $nid = isset($view->result[0]->nid) ? (int) $view->result[0]->nid : 0; + $result1 = ($nid === (int) $this->nodes[0]->nid); + $nid = isset($view->result[1]->nid) ? (int) $view->result[1]->nid : 0; + $result2 = ($nid === (int) $this->nodes[1]->nid); + $nid = isset($view->result[2]->nid) ? (int) $view->result[2]->nid : 0; + $result3 = ($nid === (int) $this->nodes[2]->nid); + $this->assertTrue($result1 && $result2 && $result3, 'Default option: View result has correct node ID.'); + + // Option 1: Is none of 2. + $view = $this->getTermIdExposedGroupedOptionsTestView(); + $view->set_exposed_input(array( + 'field_tags_tid' => '1', + )); + $this->executeView($view); + + // Assert correct result set. + $result_count = isset($view->result) && is_array($view->result) ? count($view->result) : 0; + $this->assertEqual($result_count, 1, 'Option 1: View has one result.'); + $nid = isset($view->result[0]->nid) ? (int) $view->result[0]->nid : 0; + $this->assertIdentical($nid, (int) $this->nodes[1]->nid, 'Option 1: View result has correct node ID.'); + + // Option 2: Is none of 1 or 2. + $view = $this->getTermIdExposedGroupedOptionsTestView(); + $view->set_exposed_input(array( + 'field_tags_tid' => '2', + )); + $this->executeView($view); + + // Assert correct result set. + $result_count = isset($view->result) && is_array($view->result) ? count($view->result) : 1; + $this->assertEqual($result_count, 0, 'Option 2: View has empty result.'); + + // Option 3: Is one of 1. + $view = $this->getTermIdExposedGroupedOptionsTestView(); + $view->set_exposed_input(array( + 'field_tags_tid' => '3', + )); + $this->executeView($view); + + // Assert correct result set. + $result_count = isset($view->result) && is_array($view->result) ? count($view->result) : 0; + $this->assertEqual($result_count, 2, 'Option 3: View has two results.'); + $nid = isset($view->result[0]->nid) ? (int) $view->result[0]->nid : 0; + $result1 = ($nid === (int) $this->nodes[1]->nid); + $nid = isset($view->result[1]->nid) ? (int) $view->result[1]->nid : 0; + $result2 = ($nid === (int) $this->nodes[2]->nid); + $this->assertTrue($result1 && $result2, 'Option 3: View result has correct node ID.'); + + // Option 4: Is one of 1 or 2. + $view = $this->getTermIdExposedGroupedOptionsTestView(); + $view->set_exposed_input(array( + 'field_tags_tid' => '4', + )); + $this->executeView($view); + + // Assert correct result set. + $result_count = isset($view->result) && is_array($view->result) ? count($view->result) : 0; + $nid = isset($view->result[0]->nid) ? (int) $view->result[0]->nid : 0; + $result1 = ($nid === (int) $this->nodes[0]->nid); + $nid = isset($view->result[1]->nid) ? (int) $view->result[1]->nid : 0; + $result2 = ($nid === (int) $this->nodes[1]->nid); + $nid = isset($view->result[2]->nid) ? (int) $view->result[2]->nid : 0; + $result3 = ($nid === (int) $this->nodes[2]->nid); + $nid = isset($view->result[3]->nid) ? (int) $view->result[3]->nid : 0; + $result4 = ($nid === (int) $this->nodes[2]->nid); + $this->assertTrue($result1 && $result2 && $result3 && $result4, 'Option 4: View result has correct node ID.'); + $this->verbose($view->result); + $this->assertEqual($result_count, 4, 'Option 4: View has four results.'); + + /* @todo: Fix and uncomment in issue #3045168. + * // Option 5: Is all of 1 and 2. + * $view = $this->getTermIdExposedGroupedOptionsTestView(); + * $view->set_exposed_input(array( + * 'field_tags_tid' => '5', + * )); + * $this->executeView($view); + * + * // Assert correct result set. + * $result_count = isset($view->result) && is_array($view->result) ? count($view->result) : 0; + * $nid = isset($view->result[0]->nid) ? (int) $view->result[0]->nid : 0; + * $this->assertIdentical($nid, (int) $this->nodes[2]->nid, 'Option 5: View result has correct node ID.'); + * $this->assertIdentical($result_count, 1, 'Option 5: View has one result.'); + */ + + // Option 6: Is empty. + $view = $this->getTermIdExposedGroupedOptionsTestView(); + $view->set_exposed_input(array( + 'field_tags_tid' => '6', + )); + $this->executeView($view); + + // Assert correct result set. + $result_count = isset($view->result) && is_array($view->result) ? count($view->result) : 1; + $this->assertIdentical($result_count, 0, 'Option 6: View has empty result.'); + + // Option 7: Is not empty. + $view = $this->getTermIdExposedGroupedOptionsTestView(); + $view->set_exposed_input(array( + 'field_tags_tid' => '7', + )); + $this->executeView($view); + + // Assert correct result set. + $result_count = isset($view->result) && is_array($view->result) ? count($view->result) : 0; + $nid = isset($view->result[0]->nid) ? (int) $view->result[0]->nid : 0; + $result1 = ($nid === (int) $this->nodes[0]->nid); + $nid = isset($view->result[1]->nid) ? (int) $view->result[1]->nid : 0; + $result2 = ($nid === (int) $this->nodes[1]->nid); + $nid = isset($view->result[2]->nid) ? (int) $view->result[2]->nid : 0; + $result3 = ($nid === (int) $this->nodes[2]->nid); + $nid = isset($view->result[3]->nid) ? (int) $view->result[3]->nid : 0; + $result4 = ($nid === (int) $this->nodes[2]->nid); + $this->assertTrue($result1 && $result2 && $result3 && $result4, 'Option 7: View result has correct node ID.'); + $this->verbose($view->result); + $this->assertIdentical($result_count, 4, 'Option 7: View has four results.'); + } + + /** + * Generates test_not view. + */ + protected function getGroupedNoneOfTestView() { + $view = new view(); + $view->name = 'test_not'; + $view->description = ''; + $view->tag = 'default'; + $view->base_table = 'node'; + $view->human_name = 'test_not'; + $view->core = 7; + $view->api_version = '3.0'; + $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ + + /* Display: Master */ + $handler = $view->new_display('default', 'Master', 'default'); + $handler->display->display_options['use_more_always'] = FALSE; + $handler->display->display_options['access']['type'] = 'perm'; + $handler->display->display_options['cache']['type'] = 'none'; + $handler->display->display_options['query']['type'] = 'views_query'; + $handler->display->display_options['exposed_form']['type'] = 'basic'; + $handler->display->display_options['pager']['type'] = 'full'; + $handler->display->display_options['style_plugin'] = 'default'; + $handler->display->display_options['row_plugin'] = 'fields'; + /* Field: Content: Title */ + $handler->display->display_options['fields']['title']['id'] = 'title'; + $handler->display->display_options['fields']['title']['table'] = 'node'; + $handler->display->display_options['fields']['title']['field'] = 'title'; + $handler->display->display_options['fields']['title']['label'] = ''; + $handler->display->display_options['fields']['title']['alter']['word_boundary'] = FALSE; + $handler->display->display_options['fields']['title']['alter']['ellipsis'] = FALSE; + /* Sort criterion: Content: Nid */ + $handler->display->display_options['sorts']['nid']['id'] = 'nid'; + $handler->display->display_options['sorts']['nid']['table'] = 'node'; + $handler->display->display_options['sorts']['nid']['field'] = 'nid'; + $handler->display->display_options['filter_groups']['operator'] = 'OR'; + $handler->display->display_options['filter_groups']['groups'] = array( + 1 => 'AND', + 2 => 'AND', + ); + /* Filter criterion: Content: Published */ + $handler->display->display_options['filters']['status']['id'] = 'status'; + $handler->display->display_options['filters']['status']['table'] = 'node'; + $handler->display->display_options['filters']['status']['field'] = 'status'; + $handler->display->display_options['filters']['status']['value'] = 1; + $handler->display->display_options['filters']['status']['group'] = 1; + $handler->display->display_options['filters']['status']['expose']['operator'] = FALSE; + /* Filter criterion: Content: Type */ + $handler->display->display_options['filters']['type']['id'] = 'type'; + $handler->display->display_options['filters']['type']['table'] = 'node'; + $handler->display->display_options['filters']['type']['field'] = 'type'; + $handler->display->display_options['filters']['type']['value'] = array( + 'article' => 'article', + ); + $handler->display->display_options['filters']['type']['group'] = 1; + /* Filter criterion: Field: field_bool (field_bool) */ + $handler->display->display_options['filters']['field_bool_value']['id'] = 'field_bool_value'; + $handler->display->display_options['filters']['field_bool_value']['table'] = 'field_data_field_bool'; + $handler->display->display_options['filters']['field_bool_value']['field'] = 'field_bool_value'; + $handler->display->display_options['filters']['field_bool_value']['operator'] = 'not'; + $handler->display->display_options['filters']['field_bool_value']['value'] = array( + 1 => '1', + ); + $handler->display->display_options['filters']['field_bool_value']['group'] = 1; + /* Filter criterion: Field: field_bool (field_bool) */ + $handler->display->display_options['filters']['field_bool_value_1']['id'] = 'field_bool_value_1'; + $handler->display->display_options['filters']['field_bool_value_1']['table'] = 'field_data_field_bool'; + $handler->display->display_options['filters']['field_bool_value_1']['field'] = 'field_bool_value'; + $handler->display->display_options['filters']['field_bool_value_1']['operator'] = 'not'; + $handler->display->display_options['filters']['field_bool_value_1']['value'] = array( + 1 => '1', + ); + $handler->display->display_options['filters']['field_bool_value_1']['group'] = 2; + /* Filter criterion: Content: Type */ + $handler->display->display_options['filters']['type_1']['id'] = 'type_1'; + $handler->display->display_options['filters']['type_1']['table'] = 'node'; + $handler->display->display_options['filters']['type_1']['field'] = 'type'; + $handler->display->display_options['filters']['type_1']['value'] = array( + 'article' => 'article', + ); + $handler->display->display_options['filters']['type_1']['group'] = 2; + /* Filter criterion: Content: Published */ + $handler->display->display_options['filters']['status_1']['id'] = 'status_1'; + $handler->display->display_options['filters']['status_1']['table'] = 'node'; + $handler->display->display_options['filters']['status_1']['field'] = 'status'; + $handler->display->display_options['filters']['status_1']['value'] = '1'; + $handler->display->display_options['filters']['status_1']['group'] = 2; + + return $view; + } + + /** + * Generates test_oneof view. + */ + protected function getGroupedOneOfTestView() { + $view = new view(); + $view->name = 'test_oneof'; + $view->description = ''; + $view->tag = 'default'; + $view->base_table = 'node'; + $view->human_name = 'test_oneof'; + $view->core = 7; + $view->api_version = '3.0'; + $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ + + /* Display: Master */ + $handler = $view->new_display('default', 'Master', 'default'); + $handler->display->display_options['use_more_always'] = FALSE; + $handler->display->display_options['access']['type'] = 'perm'; + $handler->display->display_options['cache']['type'] = 'none'; + $handler->display->display_options['query']['type'] = 'views_query'; + $handler->display->display_options['exposed_form']['type'] = 'basic'; + $handler->display->display_options['pager']['type'] = 'full'; + $handler->display->display_options['style_plugin'] = 'default'; + $handler->display->display_options['row_plugin'] = 'fields'; + /* Field: Content: Title */ + $handler->display->display_options['fields']['title']['id'] = 'title'; + $handler->display->display_options['fields']['title']['table'] = 'node'; + $handler->display->display_options['fields']['title']['field'] = 'title'; + $handler->display->display_options['fields']['title']['label'] = ''; + $handler->display->display_options['fields']['title']['alter']['word_boundary'] = FALSE; + $handler->display->display_options['fields']['title']['alter']['ellipsis'] = FALSE; + /* Sort criterion: Content: Nid */ + $handler->display->display_options['sorts']['nid']['id'] = 'nid'; + $handler->display->display_options['sorts']['nid']['table'] = 'node'; + $handler->display->display_options['sorts']['nid']['field'] = 'nid'; + $handler->display->display_options['filter_groups']['operator'] = 'OR'; + $handler->display->display_options['filter_groups']['groups'] = array( + 1 => 'AND', + 2 => 'AND', + ); + /* Filter criterion: Content: Tags (field_tags) */ + $handler->display->display_options['filters']['field_tags_tid']['id'] = 'field_tags_tid'; + $handler->display->display_options['filters']['field_tags_tid']['table'] = 'field_data_field_tags'; + $handler->display->display_options['filters']['field_tags_tid']['field'] = 'field_tags_tid'; + $handler->display->display_options['filters']['field_tags_tid']['value'] = array( + 1 => '1', + ); + $handler->display->display_options['filters']['field_tags_tid']['group'] = 2; + $handler->display->display_options['filters']['field_tags_tid']['reduce_duplicates'] = TRUE; + $handler->display->display_options['filters']['field_tags_tid']['type'] = 'select'; + $handler->display->display_options['filters']['field_tags_tid']['vocabulary'] = 'tags'; + /* Filter criterion: Content: Tags (field_tags) */ + $handler->display->display_options['filters']['field_tags_tid_1']['id'] = 'field_tags_tid_1'; + $handler->display->display_options['filters']['field_tags_tid_1']['table'] = 'field_data_field_tags'; + $handler->display->display_options['filters']['field_tags_tid_1']['field'] = 'field_tags_tid'; + $handler->display->display_options['filters']['field_tags_tid_1']['value'] = array( + 1 => '1', + ); + $handler->display->display_options['filters']['field_tags_tid_1']['reduce_duplicates'] = TRUE; + $handler->display->display_options['filters']['field_tags_tid_1']['type'] = 'select'; + $handler->display->display_options['filters']['field_tags_tid_1']['vocabulary'] = 'tags'; + return $view; + } + + /** + * Generates test_reduced_exposed_grouped_options view. + */ + protected function getReducedExposedGroupedOptionsTestView() { + $view = new view(); + $view->name = 'test_reduced_exposed_grouped_options'; + $view->description = ''; + $view->tag = 'default'; + $view->base_table = 'node'; + $view->human_name = 'test_reduced_exposed_grouped_options'; + $view->core = 7; + $view->api_version = '3.0'; + $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ + + /* Display: Master */ + $handler = $view->new_display('default', 'Master', 'default'); + $handler->display->display_options['use_more_always'] = FALSE; + $handler->display->display_options['access']['type'] = 'perm'; + $handler->display->display_options['cache']['type'] = 'none'; + $handler->display->display_options['query']['type'] = 'views_query'; + $handler->display->display_options['exposed_form']['type'] = 'basic'; + $handler->display->display_options['pager']['type'] = 'full'; + $handler->display->display_options['style_plugin'] = 'default'; + $handler->display->display_options['row_plugin'] = 'fields'; + /* Field: Content: Title */ + $handler->display->display_options['fields']['title']['id'] = 'title'; + $handler->display->display_options['fields']['title']['table'] = 'node'; + $handler->display->display_options['fields']['title']['field'] = 'title'; + $handler->display->display_options['fields']['title']['label'] = ''; + $handler->display->display_options['fields']['title']['alter']['word_boundary'] = FALSE; + $handler->display->display_options['fields']['title']['alter']['ellipsis'] = FALSE; + /* Sort criterion: Content: Nid */ + $handler->display->display_options['sorts']['nid']['id'] = 'nid'; + $handler->display->display_options['sorts']['nid']['table'] = 'node'; + $handler->display->display_options['sorts']['nid']['field'] = 'nid'; + /* Filter criterion: Content: Published */ + $handler->display->display_options['filters']['status']['id'] = 'status'; + $handler->display->display_options['filters']['status']['table'] = 'node'; + $handler->display->display_options['filters']['status']['field'] = 'status'; + $handler->display->display_options['filters']['status']['value'] = 1; + $handler->display->display_options['filters']['status']['group'] = 1; + $handler->display->display_options['filters']['status']['expose']['operator'] = FALSE; + /* Filter criterion: Content: list (field_list) */ + $handler->display->display_options['filters']['field_list_value']['id'] = 'field_list_value'; + $handler->display->display_options['filters']['field_list_value']['table'] = 'field_data_field_list'; + $handler->display->display_options['filters']['field_list_value']['field'] = 'field_list_value'; + $handler->display->display_options['filters']['field_list_value']['exposed'] = TRUE; + $handler->display->display_options['filters']['field_list_value']['expose']['operator_id'] = 'field_list_value_op'; + $handler->display->display_options['filters']['field_list_value']['expose']['label'] = 'list (field_list)'; + $handler->display->display_options['filters']['field_list_value']['expose']['operator'] = 'field_list_value_op'; + $handler->display->display_options['filters']['field_list_value']['expose']['identifier'] = 'field_list_value'; + $handler->display->display_options['filters']['field_list_value']['is_grouped'] = TRUE; + $handler->display->display_options['filters']['field_list_value']['group_info']['label'] = 'list (field_list)'; + $handler->display->display_options['filters']['field_list_value']['group_info']['identifier'] = 'field_list_value'; + $handler->display->display_options['filters']['field_list_value']['group_info']['group_items'] = array( + 1 => array( + 'title' => 'Not 1 or 2', + 'operator' => 'not', + 'value' => array( + 1 => '1', + 2 => '2', + ), + ), + 2 => array( + 'title' => '1', + 'operator' => 'or', + 'value' => array( + 1 => '1', + ), + ), + 3 => array( + 'title' => '1 or 2', + 'operator' => 'or', + 'value' => array( + 1 => '1', + 2 => '2', + ), + ), + 4 => array( + 'title' => '1 and 2', + 'operator' => 'and', + 'value' => array( + 1 => '1', + 2 => '2', + ), + ), + 5 => array( + 'title' => 'empty', + 'operator' => 'empty', + 'value' => array(), + ), + 6 => array( + 'title' => 'not empty', + 'operator' => 'not empty', + 'value' => array(), + ), + ); + return $view; + } + + /** + * Generates test_tid_exposed_grouped_options view. + */ + protected function getTermIdExposedGroupedOptionsTestView() { + $view = new view(); + $view->name = 'test_tid_exposed_grouped_options'; + $view->description = ''; + $view->tag = 'default'; + $view->base_table = 'node'; + $view->human_name = 'test_tid_exposed_grouped_options'; + $view->core = 7; + $view->api_version = '3.0'; + $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ + + /* Display: Master */ + $handler = $view->new_display('default', 'Master', 'default'); + $handler->display->display_options['use_more_always'] = FALSE; + $handler->display->display_options['access']['type'] = 'perm'; + $handler->display->display_options['cache']['type'] = 'none'; + $handler->display->display_options['query']['type'] = 'views_query'; + $handler->display->display_options['exposed_form']['type'] = 'basic'; + $handler->display->display_options['pager']['type'] = 'full'; + $handler->display->display_options['style_plugin'] = 'default'; + $handler->display->display_options['row_plugin'] = 'fields'; + /* Field: Content: Title */ + $handler->display->display_options['fields']['title']['id'] = 'title'; + $handler->display->display_options['fields']['title']['table'] = 'node'; + $handler->display->display_options['fields']['title']['field'] = 'title'; + $handler->display->display_options['fields']['title']['label'] = ''; + $handler->display->display_options['fields']['title']['alter']['word_boundary'] = FALSE; + $handler->display->display_options['fields']['title']['alter']['ellipsis'] = FALSE; + /* Sort criterion: Content: Nid */ + $handler->display->display_options['sorts']['nid']['id'] = 'nid'; + $handler->display->display_options['sorts']['nid']['table'] = 'node'; + $handler->display->display_options['sorts']['nid']['field'] = 'nid'; + /* Filter criterion: Content: Published */ + $handler->display->display_options['filters']['status']['id'] = 'status'; + $handler->display->display_options['filters']['status']['table'] = 'node'; + $handler->display->display_options['filters']['status']['field'] = 'status'; + $handler->display->display_options['filters']['status']['value'] = 1; + $handler->display->display_options['filters']['status']['group'] = 1; + $handler->display->display_options['filters']['status']['expose']['operator'] = FALSE; + /* Filter criterion: Content: Tags (field_tags) */ + $handler->display->display_options['filters']['field_tags_tid']['id'] = 'field_tags_tid'; + $handler->display->display_options['filters']['field_tags_tid']['table'] = 'field_data_field_tags'; + $handler->display->display_options['filters']['field_tags_tid']['field'] = 'field_tags_tid'; + $handler->display->display_options['filters']['field_tags_tid']['value'] = array( + 1 => '1', + 2 => '2', + ); + $handler->display->display_options['filters']['field_tags_tid']['exposed'] = TRUE; + $handler->display->display_options['filters']['field_tags_tid']['expose']['operator_id'] = 'field_tags_tid_op'; + $handler->display->display_options['filters']['field_tags_tid']['expose']['label'] = 'Tags (field_tags)'; + $handler->display->display_options['filters']['field_tags_tid']['expose']['operator'] = 'field_tags_tid_op'; + $handler->display->display_options['filters']['field_tags_tid']['expose']['identifier'] = 'field_tags_tid'; + $handler->display->display_options['filters']['field_tags_tid']['expose']['remember_roles'] = array( + 2 => '2', + ); + $handler->display->display_options['filters']['field_tags_tid']['is_grouped'] = TRUE; + $handler->display->display_options['filters']['field_tags_tid']['group_info']['label'] = 'Tags (field_tags)'; + $handler->display->display_options['filters']['field_tags_tid']['group_info']['identifier'] = 'field_tags_tid'; + $handler->display->display_options['filters']['field_tags_tid']['group_info']['group_items'] = array( + 1 => array( + 'title' => 'Is none of 2', + 'operator' => 'not', + 'value' => array( + 2 => '2', + ), + ), + 2 => array( + 'title' => 'Is none of 1 or 2', + 'operator' => 'not', + 'value' => array( + 1 => '1', + 2 => '2', + ), + ), + 3 => array( + 'title' => 'Is one of 1', + 'operator' => 'or', + 'value' => array( + 1 => '1', + ), + ), + 4 => array( + 'title' => 'Is one of 1 or 2', + 'operator' => 'or', + 'value' => array( + 1 => '1', + 2 => '2', + ), + ), + 5 => array( + 'title' => 'Is all of 1 and 2', + 'operator' => 'and', + 'value' => array( + 1 => '1', + 2 => '2', + ), + ), + 6 => array( + 'title' => 'Is empty', + 'operator' => 'empty', + 'value' => array( + 1 => '1', + 2 => '2', + ), + ), + 7 => array( + 'title' => 'Is not empty', + 'operator' => 'not empty', + 'value' => array( + 1 => '1', + 2 => '2', + ), + ), + ); + $handler->display->display_options['filters']['field_tags_tid']['type'] = 'select'; + $handler->display->display_options['filters']['field_tags_tid']['vocabulary'] = 'tags'; + return $view; + } + + /** + * Generates test_join_limit_none_of view. + */ + protected function getJoinLimitNoneOfTestView() { + $view = new view(); + $view->name = 'test_join_limit_none_of'; + $view->description = ''; + $view->tag = 'default'; + $view->base_table = 'node'; + $view->human_name = 'test_join_limit_none_of'; + $view->core = 7; + $view->api_version = '3.0'; + $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ + + /* Display: Master */ + $handler = $view->new_display('default', 'Master', 'default'); + $handler->display->display_options['use_more_always'] = FALSE; + $handler->display->display_options['access']['type'] = 'perm'; + $handler->display->display_options['cache']['type'] = 'none'; + $handler->display->display_options['query']['type'] = 'views_query'; + $handler->display->display_options['exposed_form']['type'] = 'basic'; + $handler->display->display_options['pager']['type'] = 'full'; + $handler->display->display_options['style_plugin'] = 'default'; + $handler->display->display_options['row_plugin'] = 'fields'; + /* Field: Content: Title */ + $handler->display->display_options['fields']['title']['id'] = 'title'; + $handler->display->display_options['fields']['title']['table'] = 'node'; + $handler->display->display_options['fields']['title']['field'] = 'title'; + $handler->display->display_options['fields']['title']['label'] = ''; + $handler->display->display_options['fields']['title']['alter']['word_boundary'] = FALSE; + $handler->display->display_options['fields']['title']['alter']['ellipsis'] = FALSE; + /* Sort criterion: Content: Post date */ + $handler->display->display_options['sorts']['created']['id'] = 'created'; + $handler->display->display_options['sorts']['created']['table'] = 'node'; + $handler->display->display_options['sorts']['created']['field'] = 'created'; + $handler->display->display_options['sorts']['created']['order'] = 'DESC'; + /* Filter criterion: Content: Published */ + $handler->display->display_options['filters']['status']['id'] = 'status'; + $handler->display->display_options['filters']['status']['table'] = 'node'; + $handler->display->display_options['filters']['status']['field'] = 'status'; + $handler->display->display_options['filters']['status']['value'] = 1; + $handler->display->display_options['filters']['status']['group'] = 1; + $handler->display->display_options['filters']['status']['expose']['operator'] = FALSE; + /* Filter criterion: Content: Tags (field_tags) */ + $handler->display->display_options['filters']['field_tags_tid']['id'] = 'field_tags_tid'; + $handler->display->display_options['filters']['field_tags_tid']['table'] = 'field_data_field_tags'; + $handler->display->display_options['filters']['field_tags_tid']['field'] = 'field_tags_tid'; + $handler->display->display_options['filters']['field_tags_tid']['operator'] = 'not'; + $handler->display->display_options['filters']['field_tags_tid']['value'] = array( + 2 => '2', + 3 => '3', + 4 => '4', + 5 => '5', + 6 => '6', + 7 => '7', + 8 => '8', + 9 => '9', + 10 => '10', + 11 => '11', + 12 => '12', + 13 => '13', + 14 => '14', + 15 => '15', + 16 => '16', + 17 => '17', + 18 => '18', + 19 => '19', + 20 => '20', + 21 => '21', + 22 => '22', + 23 => '23', + 24 => '24', + 25 => '25', + 26 => '26', + 27 => '27', + 28 => '28', + 29 => '29', + 30 => '30', + 31 => '31', + 32 => '32', + 33 => '33', + 34 => '34', + 35 => '35', + 36 => '36', + 37 => '37', + 38 => '38', + 39 => '39', + 40 => '40', + 41 => '41', + 42 => '42', + 43 => '43', + 44 => '44', + 45 => '45', + 46 => '46', + 47 => '47', + 48 => '48', + 49 => '49', + 50 => '50', + 51 => '51', + 52 => '52', + 53 => '53', + 54 => '54', + 55 => '55', + 56 => '56', + 57 => '57', + 58 => '58', + 59 => '59', + 60 => '60', + 61 => '61', + 62 => '62', + 63 => '63', + 64 => '64', + 65 => '65', + 66 => '66', + 67 => '67', + 68 => '68', + 69 => '69', + 61 => '61', + 62 => '62', + ); + $handler->display->display_options['filters']['field_tags_tid']['type'] = 'select'; + $handler->display->display_options['filters']['field_tags_tid']['vocabulary'] = 'tags'; + return $view; + } + +} diff --git a/sites/all/modules/contrib/views/views/tests/styles/views_plugin_style.test b/sites/all/modules/contrib/views/views/tests/styles/views_plugin_style.test index 20a24eb9..89d2816c 100644 --- a/sites/all/modules/contrib/views/views/tests/styles/views_plugin_style.test +++ b/sites/all/modules/contrib/views/views/tests/styles/views_plugin_style.test @@ -78,6 +78,7 @@ class ViewsPluginStyleTestCase extends ViewsPluginStyleTestBase { $expected = array(); $expected['Job: Singer'] = array(); $expected['Job: Singer']['group'] = 'Job: Singer'; + $expected['Job: Singer']['level'] = '0'; $expected['Job: Singer']['rows'][0] = new StdClass(); $expected['Job: Singer']['rows'][0]->views_test_name = 'John'; $expected['Job: Singer']['rows'][0]->views_test_job = 'Singer'; @@ -88,6 +89,7 @@ class ViewsPluginStyleTestCase extends ViewsPluginStyleTestBase { $expected['Job: Singer']['rows'][1]->views_test_id = '2'; $expected['Job: Drummer'] = array(); $expected['Job: Drummer']['group'] = 'Job: Drummer'; + $expected['Job: Drummer']['level'] = '0'; $expected['Job: Drummer']['rows'][2] = new StdClass(); $expected['Job: Drummer']['rows'][2]->views_test_name = 'Ringo'; $expected['Job: Drummer']['rows'][2]->views_test_job = 'Drummer'; @@ -161,8 +163,10 @@ class ViewsPluginStyleTestCase extends ViewsPluginStyleTestBase { $expected = array(); $expected['Job: Singer'] = array(); $expected['Job: Singer']['group'] = 'Job: Singer'; + $expected['Job: Singer']['level'] = 0; $expected['Job: Singer']['rows']['Age: 25'] = array(); $expected['Job: Singer']['rows']['Age: 25']['group'] = 'Age: 25'; + $expected['Job: Singer']['rows']['Age: 25']['level'] = 1; $expected['Job: Singer']['rows']['Age: 25']['rows'][0] = new StdClass(); $expected['Job: Singer']['rows']['Age: 25']['rows'][0]->views_test_name = 'John'; $expected['Job: Singer']['rows']['Age: 25']['rows'][0]->views_test_job = 'Singer'; @@ -170,6 +174,7 @@ class ViewsPluginStyleTestCase extends ViewsPluginStyleTestBase { $expected['Job: Singer']['rows']['Age: 25']['rows'][0]->views_test_id = '1'; $expected['Job: Singer']['rows']['Age: 27'] = array(); $expected['Job: Singer']['rows']['Age: 27']['group'] = 'Age: 27'; + $expected['Job: Singer']['rows']['Age: 27']['level'] = 1; $expected['Job: Singer']['rows']['Age: 27']['rows'][1] = new StdClass(); $expected['Job: Singer']['rows']['Age: 27']['rows'][1]->views_test_name = 'George'; $expected['Job: Singer']['rows']['Age: 27']['rows'][1]->views_test_job = 'Singer'; @@ -177,8 +182,10 @@ class ViewsPluginStyleTestCase extends ViewsPluginStyleTestBase { $expected['Job: Singer']['rows']['Age: 27']['rows'][1]->views_test_id = '2'; $expected['Job: Drummer'] = array(); $expected['Job: Drummer']['group'] = 'Job: Drummer'; + $expected['Job: Drummer']['level'] = 0; $expected['Job: Drummer']['rows']['Age: 28'] = array(); $expected['Job: Drummer']['rows']['Age: 28']['group'] = 'Age: 28'; + $expected['Job: Drummer']['rows']['Age: 28']['level'] = 1; $expected['Job: Drummer']['rows']['Age: 28']['rows'][2] = new StdClass(); $expected['Job: Drummer']['rows']['Age: 28']['rows'][2]->views_test_name = 'Ringo'; $expected['Job: Drummer']['rows']['Age: 28']['rows'][2]->views_test_job = 'Drummer'; diff --git a/sites/all/modules/contrib/views/views/tests/user/views_handler_field_user_name.test b/sites/all/modules/contrib/views/views/tests/user/views_handler_field_user_name.test index 60ec3b25..73a8ac11 100644 --- a/sites/all/modules/contrib/views/views/tests/user/views_handler_field_user_name.test +++ b/sites/all/modules/contrib/views/views/tests/user/views_handler_field_user_name.test @@ -51,6 +51,23 @@ class viewsHandlerFieldUserNameTest extends ViewsSqlTest { $this->assertIdentical($render, $anon_name, 'For user0 it should use the configured anonymous text if overwrite_anonymous is checked.'); } + + /** + * Tests that deselecting 'link_to_user' and 'format_username' works. + */ + public function testOptions() { + $view = $this->view_raw_user_name(); + $view->init_display(); + $this->executeView($view); + + $view->row_index = 0; + + $username = $view->result[0]->users_name = 'test'; + $view->result[0]->uid = 1; + $render = $view->field['name']->advanced_render($view->result[0]); + $this->assertTrue(strpos($render, $username) !== FALSE, 'If link to user is checked the username should be part of the output.'); + } + function view_user_name() { $view = new view(); $view->name = 'test_views_handler_field_user_name'; @@ -93,4 +110,46 @@ class viewsHandlerFieldUserNameTest extends ViewsSqlTest { return $view; } + function view_raw_user_name() { + $view = new view; + $view->name = 'test_views_handler_field_user_name'; + $view->description = ''; + $view->tag = 'default'; + $view->base_table = 'users'; + $view->human_name = 'test_views_handler_field_user_name'; + $view->core = 7; + $view->api_version = '3.0'; + $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ + + /* Display: Master */ + $handler = $view->new_display('default', 'Master', 'default'); + $handler->display->display_options['access']['type'] = 'none'; + $handler->display->display_options['cache']['type'] = 'none'; + $handler->display->display_options['query']['type'] = 'views_query'; + $handler->display->display_options['query']['options']['query_comment'] = FALSE; + $handler->display->display_options['exposed_form']['type'] = 'basic'; + $handler->display->display_options['pager']['type'] = 'full'; + $handler->display->display_options['style_plugin'] = 'default'; + $handler->display->display_options['row_plugin'] = 'fields'; + /* Field: User: Name */ + $handler->display->display_options['fields']['name']['id'] = 'name'; + $handler->display->display_options['fields']['name']['table'] = 'users'; + $handler->display->display_options['fields']['name']['field'] = 'name'; + $handler->display->display_options['fields']['name']['label'] = ''; + $handler->display->display_options['fields']['name']['alter']['alter_text'] = 0; + $handler->display->display_options['fields']['name']['alter']['make_link'] = 0; + $handler->display->display_options['fields']['name']['alter']['absolute'] = 0; + $handler->display->display_options['fields']['name']['alter']['word_boundary'] = 0; + $handler->display->display_options['fields']['name']['alter']['ellipsis'] = 0; + $handler->display->display_options['fields']['name']['alter']['strip_tags'] = 0; + $handler->display->display_options['fields']['name']['alter']['trim'] = 0; + $handler->display->display_options['fields']['name']['alter']['html'] = 0; + $handler->display->display_options['fields']['name']['hide_empty'] = 0; + $handler->display->display_options['fields']['name']['empty_zero'] = 0; + $handler->display->display_options['fields']['name']['link_to_user'] = 0; + $handler->display->display_options['fields']['name']['format_username'] = 0; + $handler->display->display_options['fields']['name']['overwrite_anonymous'] = 0; + + return $view; + } } diff --git a/sites/all/modules/contrib/views/views/tests/views_clone.test b/sites/all/modules/contrib/views/views/tests/views_clone.test new file mode 100644 index 00000000..7ac10aba --- /dev/null +++ b/sites/all/modules/contrib/views/views/tests/views_clone.test @@ -0,0 +1,277 @@ + 'Test cloning a view', + 'description' => 'Tests clone_view method of views class', + 'group' => 'Views', + ); + } + + /** + * Returns a new term with random properties in vocabulary $vocabulary. + */ + protected function createTerm($vocabulary) { + $term = new stdClass(); + $term->name = $this->randomName(); + $term->description = $this->randomName(); + // Use the first available text format. + $term->format = db_query_range('SELECT format FROM {filter_format}', 0, 1)->fetchField(); + $term->vid = $vocabulary->vid; + taxonomy_term_save($term); + return $term; + } + + /** + * {@inheritdoc} + */ + public function setUp() { + parent::setUp(); + + $vocabulary = taxonomy_vocabulary_machine_name_load('tags'); + $this->term = $this->createTerm($vocabulary); + + $node = array(); + $node['type'] = 'article'; + $node['field_tags'][LANGUAGE_NONE][]['tid'] = $this->term->tid; + $this->node = $this->drupalCreateNode($node); + } + + /** + * Test cloning a view. + */ + public function testClone() { + // Prepare view to be cloned. + $view = $this->getTestCloneView(); + $view->set_arguments(array( + 0 => $this->node->nid, + )); + $view->set_exposed_input(array( + 'field_tags_tid' => $this->term->tid, + )); + + // Execute view to be cloned. + $result = $view->execute(); + + // To make sure that we are properly testing removal of all properties, we + // first need to assert that they are actually present in the original view. + $keys = array( + 'current_display', + 'display_handler', + '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) { + $this->assertTrue(isset($view->{$key}), $key . 'is set in original view.'); + } + $this->assertTrue($view->built, 'Assert original view built.'); + $this->assertTrue($view->executed, 'Assert original view executed.'); + $this->assertNotEqual($view->build_info, array(), 'Assert original view has build_info.'); + $this->assertNotEqual($view->attachment_before, '', 'Assert original view has attachment_before.'); + $this->assertNotEqual($view->attachment_after, '', 'Assert original view has attachment_after.'); + $this->assertNotEqual($view->result, array(), 'Assert original view has result.'); + + // Clone view. + $clone = $view->clone_view(); + + // Assert that all relevant properties have been removed or reset. + $keys = array( + 'current_display', + 'display_handler', + '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) { + $this->assertFalse(isset($clone->{$key}), $key . ' has been removed in cloned view.'); + } + foreach ($clone->display as $id => $display) { + $this->assertFalse(isset($clone->display[$id]->handler), 'Make sure all display handlers have been destroyed.'); + } + $this->assertFalse($clone->built, 'Assert cloned view not built.'); + $this->assertFalse($clone->executed, 'Assert cloned view not executed.'); + $this->assertEqual($clone->build_info, array(), 'Assert cloned view has empty build_info.'); + $this->assertEqual($clone->attachment_before, '', 'Assert cloned view has empty attachment_before.'); + $this->assertEqual($clone->attachment_after, '', 'Assert cloned view has empty attachment_after.'); + $this->assertEqual($clone->result, array(), 'Assert cloned view has empty result.'); + + // Execute cloned view. + $clone->execute(); + + // Assert result sets are equal. + $this->assertEqual($view->result, $clone->result, 'Result sets of cloned view and original view match.'); + } + + /** + * Generate test_clone view. + */ + protected function getTestCloneView() { + $view = new view(); + $view->name = 'test_clone'; + $view->description = ''; + $view->tag = 'default'; + $view->base_table = 'node'; + $view->human_name = 'test_clone'; + $view->core = 7; + $view->api_version = '3.0'; + $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ + /* Display: Master */ + $handler = $view->new_display('default', 'Master', 'default'); + $handler->display->display_options['title'] = 'test_clone'; + $handler->display->display_options['use_more_always'] = FALSE; + $handler->display->display_options['access']['type'] = 'perm'; + $handler->display->display_options['cache']['type'] = 'none'; + $handler->display->display_options['query']['type'] = 'views_query'; + $handler->display->display_options['exposed_form']['type'] = 'basic'; + $handler->display->display_options['pager']['type'] = 'full'; + $handler->display->display_options['pager']['options']['items_per_page'] = '10'; + $handler->display->display_options['style_plugin'] = 'default'; + $handler->display->display_options['row_plugin'] = 'node'; + /* Header: Global: Text area */ + $handler->display->display_options['header']['area']['id'] = 'area'; + $handler->display->display_options['header']['area']['table'] = 'views'; + $handler->display->display_options['header']['area']['field'] = 'area'; + $handler->display->display_options['header']['area']['label'] = 'Header'; + $handler->display->display_options['header']['area']['content'] = 'Header'; + $handler->display->display_options['header']['area']['format'] = 'filtered_html'; + /* Footer: Global: Text area */ + $handler->display->display_options['footer']['area']['id'] = 'area'; + $handler->display->display_options['footer']['area']['table'] = 'views'; + $handler->display->display_options['footer']['area']['field'] = 'area'; + $handler->display->display_options['footer']['area']['label'] = 'Footer'; + $handler->display->display_options['footer']['area']['content'] = 'Footer'; + $handler->display->display_options['footer']['area']['format'] = 'filtered_html'; + /* No results behavior: Global: Text area */ + $handler->display->display_options['empty']['area']['id'] = 'area'; + $handler->display->display_options['empty']['area']['table'] = 'views'; + $handler->display->display_options['empty']['area']['field'] = 'area'; + $handler->display->display_options['empty']['area']['label'] = 'Empty'; + $handler->display->display_options['empty']['area']['empty'] = TRUE; + $handler->display->display_options['empty']['area']['content'] = 'Empty'; + $handler->display->display_options['empty']['area']['format'] = 'filtered_html'; + /* Relationship: Comment: Last Comment */ + $handler->display->display_options['relationships']['cid']['id'] = 'cid'; + $handler->display->display_options['relationships']['cid']['table'] = 'node_comment_statistics'; + $handler->display->display_options['relationships']['cid']['field'] = 'cid'; + /* Field: Content: Title */ + $handler->display->display_options['fields']['title']['id'] = 'title'; + $handler->display->display_options['fields']['title']['table'] = 'node'; + $handler->display->display_options['fields']['title']['field'] = 'title'; + $handler->display->display_options['fields']['title']['label'] = ''; + $handler->display->display_options['fields']['title']['alter']['word_boundary'] = FALSE; + $handler->display->display_options['fields']['title']['alter']['ellipsis'] = FALSE; + /* Sort criterion: Content: Post date */ + $handler->display->display_options['sorts']['created']['id'] = 'created'; + $handler->display->display_options['sorts']['created']['table'] = 'node'; + $handler->display->display_options['sorts']['created']['field'] = 'created'; + $handler->display->display_options['sorts']['created']['order'] = 'DESC'; + /* Contextual filter: Content: Nid */ + $handler->display->display_options['arguments']['nid']['id'] = 'nid'; + $handler->display->display_options['arguments']['nid']['table'] = 'node'; + $handler->display->display_options['arguments']['nid']['field'] = 'nid'; + $handler->display->display_options['arguments']['nid']['default_argument_type'] = 'fixed'; + $handler->display->display_options['arguments']['nid']['summary']['number_of_records'] = '0'; + $handler->display->display_options['arguments']['nid']['summary']['format'] = 'default_summary'; + $handler->display->display_options['arguments']['nid']['summary_options']['items_per_page'] = '25'; + /* Filter criterion: Content: Published */ + $handler->display->display_options['filters']['status']['id'] = 'status'; + $handler->display->display_options['filters']['status']['table'] = 'node'; + $handler->display->display_options['filters']['status']['field'] = 'status'; + $handler->display->display_options['filters']['status']['value'] = 'All'; + $handler->display->display_options['filters']['status']['group'] = 1; + $handler->display->display_options['filters']['status']['exposed'] = TRUE; + $handler->display->display_options['filters']['status']['expose']['operator_id'] = ''; + $handler->display->display_options['filters']['status']['expose']['label'] = 'Published'; + $handler->display->display_options['filters']['status']['expose']['operator'] = 'status_op'; + $handler->display->display_options['filters']['status']['expose']['identifier'] = 'status'; + $handler->display->display_options['filters']['status']['expose']['remember_roles'] = array( + 2 => '2', + ); + /* Filter criterion: Content: Tags (field_tags) */ + $handler->display->display_options['filters']['field_tags_tid']['id'] = 'field_tags_tid'; + $handler->display->display_options['filters']['field_tags_tid']['table'] = 'field_data_field_tags'; + $handler->display->display_options['filters']['field_tags_tid']['field'] = 'field_tags_tid'; + $handler->display->display_options['filters']['field_tags_tid']['exposed'] = TRUE; + $handler->display->display_options['filters']['field_tags_tid']['expose']['operator_id'] = 'field_tags_tid_op'; + $handler->display->display_options['filters']['field_tags_tid']['expose']['label'] = 'Tags (field_tags)'; + $handler->display->display_options['filters']['field_tags_tid']['expose']['operator'] = 'field_tags_tid_op'; + $handler->display->display_options['filters']['field_tags_tid']['expose']['identifier'] = 'field_tags_tid'; + $handler->display->display_options['filters']['field_tags_tid']['expose']['remember_roles'] = array( + 2 => '2', + ); + $handler->display->display_options['filters']['field_tags_tid']['reduce_duplicates'] = TRUE; + $handler->display->display_options['filters']['field_tags_tid']['type'] = 'select'; + $handler->display->display_options['filters']['field_tags_tid']['vocabulary'] = 'tags'; + /* Display: Page */ + $handler = $view->new_display('page', 'Page', 'page'); + $handler->display->display_options['path'] = 'test-clone'; + /* Display: attachment_before */ + $handler = $view->new_display('attachment', 'attachment_before', 'attachment_1'); + $handler->display->display_options['pager']['type'] = 'some'; + $handler->display->display_options['displays'] = array( + 'default' => 'default', + 'page' => 'page', + ); + $handler->display->display_options['inherit_exposed_filters'] = TRUE; + /* Display: attachment_after */ + $handler = $view->new_display('attachment', 'attachment_after', 'attachment_2'); + $handler->display->display_options['pager']['type'] = 'some'; + $handler->display->display_options['displays'] = array( + 'default' => 'default', + 'page' => 'page', + ); + $handler->display->display_options['attachment_position'] = 'after'; + $handler->display->display_options['inherit_exposed_filters'] = TRUE; + /* Display: Feed */ + $handler = $view->new_display('feed', 'Feed', 'feed_1'); + $handler->display->display_options['pager']['type'] = 'some'; + $handler->display->display_options['style_plugin'] = 'rss'; + $handler->display->display_options['row_plugin'] = 'node_rss'; + $handler->display->display_options['path'] = 'test_clone/rss'; + $handler->display->display_options['displays'] = array( + 'default' => 'default', + 'page' => 'page', + ); + return $view; + } + +} diff --git a/sites/all/modules/contrib/views/views/tests/views_query.test b/sites/all/modules/contrib/views/views/tests/views_query.test index 5acf01e9..ed10f3be 100644 --- a/sites/all/modules/contrib/views/views/tests/views_query.test +++ b/sites/all/modules/contrib/views/views/tests/views_query.test @@ -152,6 +152,23 @@ abstract class ViewsTestCase extends DrupalWebTestCase { $this->drupalLogin($account); } + /** + * {@inheritdoc} + */ + protected function verbose($message, $title = NULL) { + // Handle arrays, objects, etc. + if (!is_string($message)) { + $message = "
    \n" . print_r($message, TRUE) . "\n
    \n"; + } + + // Optional title to go before the output. + if (!empty($title)) { + $title = '

    ' . check_plain($title) . "

    \n"; + } + + parent::verbose($title . $message); + } + } /** diff --git a/sites/all/modules/contrib/views/views/tests/views_test.info b/sites/all/modules/contrib/views/views/tests/views_test.info index 5095b7f2..d7e79211 100644 --- a/sites/all/modules/contrib/views/views/tests/views_test.info +++ b/sites/all/modules/contrib/views/views/tests/views_test.info @@ -5,8 +5,8 @@ core = 7.x dependencies[] = views hidden = TRUE -; Information added by Drupal.org packaging script on 2019-04-03 -version = "7.x-3.22" +; Information added by Drupal.org packaging script on 2019-05-10 +version = "7.x-3.23" core = "7.x" project = "views" -datestamp = "1554307093" +datestamp = "1557505389" diff --git a/sites/all/modules/contrib/views/views/theme/theme.inc b/sites/all/modules/contrib/views/views/theme/theme.inc index 7382f01d..99b8efe7 100644 --- a/sites/all/modules/contrib/views/views/theme/theme.inc +++ b/sites/all/modules/contrib/views/views/theme/theme.inc @@ -379,8 +379,10 @@ function template_preprocess_views_view_summary(&$vars) { $active_urls = drupal_map_assoc(array( // Force system path. url($_GET['q'], array('alias' => TRUE)), + url($_GET['q'], $url_options + array('alias' => TRUE)), // Could be an alias. url($_GET['q']), + url($_GET['q'], $url_options), )); // Collect all arguments foreach row, to be able to alter them for example by @@ -430,8 +432,10 @@ function template_preprocess_views_view_summary_unformatted(&$vars) { $active_urls = drupal_map_assoc(array( // Force system path. url($_GET['q'], array('alias' => TRUE)), + url($_GET['q'], $url_options + array('alias' => TRUE)), // Could be an alias. url($_GET['q']), + url($_GET['q'], $url_options), )); // Collect all arguments foreach row, to be able to alter them for example by @@ -479,9 +483,24 @@ function template_preprocess_views_view_table(&$vars) { $vars['rows'] = array(); $vars['field_classes'] = array(); $vars['header'] = array(); + $vars['classes_array'] = array(); $options = $view->style_plugin->options; $handler = $view->style_plugin; + + if (!empty($handler->options['class'])) { + $classes = explode(' ', $handler->options['class']); + $classes = array_map('views_clean_css_identifier', $classes); + + if (!empty($classes)) { + // Trim empty class entries. + foreach ($classes as $key => $class) { + if (!empty($class)) { + $vars['classes_array'][] = $class; + } + } + } + } $default_row_class = isset($options['default_row_class']) ? $options['default_row_class'] : TRUE; $row_class_special = isset($options['row_class_special']) ? $options['row_class_special'] : TRUE; @@ -647,7 +666,7 @@ function template_preprocess_views_view_table(&$vars) { $vars['row_classes'][count($vars['row_classes']) - 1][] = 'views-row-last'; } - $vars['classes_array'] = array('views-table'); + $vars['classes_array'][] = 'views-table'; if (empty($vars['rows']) && !empty($options['empty_table'])) { $vars['rows'][0][0] = $view->display_handler->render_area('empty'); // Calculate the amounts of rows with output. @@ -710,7 +729,7 @@ function template_preprocess_views_view_grid(&$vars) { } if ($row) { // Fill up the last line only if it's configured, but this is default. - if (!empty($handler->options['fill_single_line']) && count($rows)) { + if (!empty($handler->options['fill_single_line'])) { for ($i = 0; $i < ($columns - $col_count); $i++) { $row[] = ''; } @@ -739,8 +758,15 @@ function template_preprocess_views_view_grid(&$vars) { $remainders--; } } - for ($i = 0; $i < count($rows[0]); $i++) { - // This should be string so that's okay :) + + // Fill out the row with empty values, if needed. + if (!empty($handler->options['fill_single_line'])) { + $column_fill = $columns; + } + else { + $column_fill = count($rows[0]); + } + for ($i = 0; $i < $column_fill; $i++) { if (!isset($rows[count($rows) - 1][$i])) { $rows[count($rows) - 1][$i] = ''; } diff --git a/sites/all/modules/contrib/views/views/theme/views-ui-edit-view.tpl.php b/sites/all/modules/contrib/views/views/theme/views-ui-edit-view.tpl.php deleted file mode 100644 index f4333324..00000000 --- a/sites/all/modules/contrib/views/views/theme/views-ui-edit-view.tpl.php +++ /dev/null @@ -1,48 +0,0 @@ - -
    - -
    - break this lock.', - array('!user' => $locked, '!age' => $lock_age, '!break' => $break)); ?> -
    - -
    - vid)): ?> -
    - -
    - - - @base.', - array('%name' => $view->name, '@base' => $base_table)); ?> -
    - - - -
    -
    - -
    -
    - - -
    -
    - - - -

    -
    - -
    -
    diff --git a/sites/all/modules/contrib/views/views/views.api.php b/sites/all/modules/contrib/views/views/views.api.php index ea53a37c..dcf80195 100644 --- a/sites/all/modules/contrib/views/views/views.api.php +++ b/sites/all/modules/contrib/views/views/views.api.php @@ -752,7 +752,7 @@ function hook_views_plugin_option_definition_alter(&$options, $plugin) { * Alter existing handler option definitions. * * This can be used to edit default or add new option definitions to existing - * handers. The reason for doing this is that only overriding the relevent form + * handlers. The reason for doing this is that only overriding the relevent form * with hook_form_alter() is insufficent because submitted form values will be * ignored if they haven't been declared as an available option. * @@ -787,7 +787,7 @@ function hook_views_handler_option_definition_alter(&$options, $handler) { * - api: (required) The version of the Views API the module implements. * - path: (optional) If includes are stored somewhere other than within the * root module directory, specify its path here. - * - template path: (optional) A path where the module has stored it's views + * - template path: (optional) A path where the module has stored its views * template files. When you have specified this key views automatically * uses the template files for the views. You can use the same naming * conventions like for normal views template files. diff --git a/sites/all/modules/contrib/views/views/views.info b/sites/all/modules/contrib/views/views/views.info index d9d1c116..a857b233 100644 --- a/sites/all/modules/contrib/views/views/views.info +++ b/sites/all/modules/contrib/views/views/views.info @@ -285,6 +285,7 @@ files[] = tests/handlers/views_handler_filter_equality.test files[] = tests/handlers/views_handler_filter_in_operator.test files[] = tests/handlers/views_handler_filter_numeric.test files[] = tests/handlers/views_handler_filter_string.test +files[] = tests/handlers/views_handler_manytoone.test files[] = tests/handlers/views_handler_sort_random.test files[] = tests/handlers/views_handler_sort_date.test files[] = tests/handlers/views_handler_sort.test @@ -326,11 +327,12 @@ files[] = tests/user/views_user_argument_default.test files[] = tests/user/views_user_argument_validate.test files[] = tests/user/views_user.test files[] = tests/views_cache.test +files[] = tests/views_clone.test files[] = tests/views_view.test files[] = tests/views_ui.test -; Information added by Drupal.org packaging script on 2019-04-03 -version = "7.x-3.22" +; Information added by Drupal.org packaging script on 2019-05-10 +version = "7.x-3.23" core = "7.x" project = "views" -datestamp = "1554307093" +datestamp = "1557505389" diff --git a/sites/all/modules/contrib/views/views/views.module b/sites/all/modules/contrib/views/views/views.module index 58cfed4f..aa407f02 100644 --- a/sites/all/modules/contrib/views/views/views.module +++ b/sites/all/modules/contrib/views/views/views.module @@ -752,6 +752,65 @@ function views_block_info() { return $items; } +/** + * Implements hook_block_configure(). + */ +function views_block_configure($delta = '') { + // If there's no Views UI module there's nothing to link to. + if (!module_exists('views_ui')) { + return array(); + } + + // If the user doesn't have access to edit the view then don't bother with + // anything else. + if (!user_access('administer views')) { + return array(); + } + + // If this is 32, this should be an md5 hash. + if (strlen($delta) == 32) { + $hashes = variable_get('views_block_hashes', array()); + if (!empty($hashes[$delta])) { + $delta = $hashes[$delta]; + } + } + + // Some added precaution in case the delta is missing values. + list($view_name, $display_id) = explode('-', $delta, 2) + array('', ''); + + // If the view name or display ID can't be found, there's something wrong. + if ($view_name === '' || $display_id === '') { + return array(); + } + + $view = views_get_view($view_name); + if (empty($view)) { + return array(); + } + + if (!isset($view->display[$display_id])) { + return array(); + } + + /** @var \views_display $display */ + $display = $view->display[$display_id]; + + $view_label = $view->get_human_name(); + $display_label = $display->display_title; + + $path = "admin/structure/views/view/$view_name/edit/$display_id"; + + return array( + 'fieldset' => array( + '#type' => 'fieldset', + '#title' => t('Configure this views display'), + 'content' => array( + '#markup' => l($view_label . ' - ' . $display_label, $path), + ), + ), + ); +} + /** * Implements hook_block_view(). */ @@ -1231,7 +1290,7 @@ function views_add_css($file) { * Include views .js files. */ function views_add_js($file) { - // If javascript has been disabled by the user, never add js files. + // If JavaScript has been disabled by the user, never add js files. if (variable_get('views_no_javascript', FALSE)) { return; } @@ -2586,6 +2645,17 @@ function views_views_api() { ); } +/** + * Implements hook_admin_menu_cache_info(). + */ +function views_admin_menu_cache_info() { + $caches['views'] = array( + 'title' => t('Views'), + 'callback' => 'views_invalidate_cache', + ); + return $caches; +} + if (!function_exists('aggregator_views_api')) { /** * Provide Views integration for the Aggregator module. diff --git a/sites/all/modules/contrib/views/views/views_ui.info b/sites/all/modules/contrib/views/views/views_ui.info index 3053db91..7a8e5383 100644 --- a/sites/all/modules/contrib/views/views/views_ui.info +++ b/sites/all/modules/contrib/views/views/views_ui.info @@ -8,8 +8,8 @@ dependencies[] = views files[] = views_ui.module files[] = plugins/views_wizard/views_ui_base_views_wizard.class.php -; Information added by Drupal.org packaging script on 2019-04-03 -version = "7.x-3.22" +; Information added by Drupal.org packaging script on 2019-05-10 +version = "7.x-3.23" core = "7.x" project = "views" -datestamp = "1554307093" +datestamp = "1557505389" diff --git a/sites/all/modules/contrib/views/views/views_ui.module b/sites/all/modules/contrib/views/views/views_ui.module index 387e6697..0eadd6ff 100644 --- a/sites/all/modules/contrib/views/views/views_ui.module +++ b/sites/all/modules/contrib/views/views/views_ui.module @@ -804,6 +804,9 @@ function views_ui_contextual_links_suppress_pop() { * @see http://drupal.org/node/774876 */ function views_ui_ajax_get_form($form_id) { + $args = func_get_args(); + array_shift($args); + // @see ajax_get_form() $form_state = array( 'no_redirect' => TRUE, @@ -812,8 +815,6 @@ function views_ui_ajax_get_form($form_id) { $form_state['rebuild_info']['copy']['#action'] = TRUE; // @see drupal_get_form() - $args = func_get_args(); - array_shift($args); $form_state['build_info']['args'] = $args; $form = drupal_build_form($form_id, $form_state); @@ -902,7 +903,7 @@ function _views_ui_get_displays_list($view) { * @see /js/jquery.ui.dialog.patch.js * @see /js/jquery.ui.dialog.min.js * - * The javascript patch overwrites the $.ui.dialog.overlay.events object to + * The 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. */