Explorar o código

updated views

Bachir Soussi Chiadmi %!s(int64=7) %!d(string=hai) anos
pai
achega
992c9a552a
Modificáronse 59 ficheiros con 1275 adicións e 252 borrados
  1. 38 23
      sites/all/modules/contrib/views/views/handlers/views_handler_area_view.inc
  2. 1 4
      sites/all/modules/contrib/views/views/handlers/views_handler_argument.inc
  3. 1 1
      sites/all/modules/contrib/views/views/handlers/views_handler_field.inc
  4. 9 56
      sites/all/modules/contrib/views/views/handlers/views_handler_field_contextual_links.inc
  5. 55 0
      sites/all/modules/contrib/views/views/handlers/views_handler_field_ctools_dropdown.inc
  6. 155 0
      sites/all/modules/contrib/views/views/handlers/views_handler_field_links.inc
  7. 1 1
      sites/all/modules/contrib/views/views/handlers/views_handler_field_math.inc
  8. 6 5
      sites/all/modules/contrib/views/views/handlers/views_handler_field_numeric.inc
  9. 5 0
      sites/all/modules/contrib/views/views/handlers/views_handler_filter_combine.inc
  10. 7 0
      sites/all/modules/contrib/views/views/includes/admin.inc
  11. 2 2
      sites/all/modules/contrib/views/views/includes/ajax.inc
  12. 1 1
      sites/all/modules/contrib/views/views/includes/cache.inc
  13. 51 26
      sites/all/modules/contrib/views/views/includes/handlers.inc
  14. 4 1
      sites/all/modules/contrib/views/views/includes/plugins.inc
  15. 30 18
      sites/all/modules/contrib/views/views/includes/view.inc
  16. 1 1
      sites/all/modules/contrib/views/views/js/ajax_view.js
  17. 1 1
      sites/all/modules/contrib/views/views/js/views-admin.js
  18. 0 39
      sites/all/modules/contrib/views/views/modules/field.views.inc
  19. 21 0
      sites/all/modules/contrib/views/views/modules/field/views_handler_field_field.inc
  20. 7 0
      sites/all/modules/contrib/views/views/modules/locale.views.inc
  21. 1 1
      sites/all/modules/contrib/views/views/modules/locale/views_handler_field_locale_link_edit.inc
  22. 107 0
      sites/all/modules/contrib/views/views/modules/locale/views_handler_sort_node_language.inc
  23. 18 0
      sites/all/modules/contrib/views/views/modules/node.views.inc
  24. 21 0
      sites/all/modules/contrib/views/views/modules/node/views_handler_field_node_version_count.inc
  25. 1 1
      sites/all/modules/contrib/views/views/modules/node/views_handler_filter_node_uid_revision.inc
  26. 36 0
      sites/all/modules/contrib/views/views/modules/node/views_handler_filter_node_version_count.inc
  27. 19 0
      sites/all/modules/contrib/views/views/modules/node/views_handler_sort_node_version_count.inc
  28. 1 1
      sites/all/modules/contrib/views/views/modules/search/views_handler_argument_search.inc
  29. 1 1
      sites/all/modules/contrib/views/views/modules/search/views_handler_filter_search.inc
  30. 3 3
      sites/all/modules/contrib/views/views/modules/statistics.views.inc
  31. 21 0
      sites/all/modules/contrib/views/views/modules/statistics/views_handler_field_node_counter_timestamp.inc
  32. 21 0
      sites/all/modules/contrib/views/views/modules/statistics/views_handler_field_statistics_numeric.inc
  33. 14 0
      sites/all/modules/contrib/views/views/modules/taxonomy.views.inc
  34. 191 0
      sites/all/modules/contrib/views/views/modules/taxonomy/views_handler_argument_term_node_tid_depth_join.inc
  35. 16 0
      sites/all/modules/contrib/views/views/modules/taxonomy/views_handler_filter_term_node_tid.inc
  36. 142 0
      sites/all/modules/contrib/views/views/modules/taxonomy/views_handler_filter_term_node_tid_depth_join.inc
  37. 3 3
      sites/all/modules/contrib/views/views/modules/translation.views.inc
  38. 8 0
      sites/all/modules/contrib/views/views/modules/views.views.inc
  39. 1 1
      sites/all/modules/contrib/views/views/plugins/export_ui/views_ui.class.php
  40. 1 1
      sites/all/modules/contrib/views/views/plugins/views_plugin_argument_validate.inc
  41. 17 0
      sites/all/modules/contrib/views/views/plugins/views_plugin_cache_time.inc
  42. 50 14
      sites/all/modules/contrib/views/views/plugins/views_plugin_display.inc
  43. 2 2
      sites/all/modules/contrib/views/views/plugins/views_plugin_display_block.inc
  44. 32 9
      sites/all/modules/contrib/views/views/plugins/views_plugin_query_default.inc
  45. 17 7
      sites/all/modules/contrib/views/views/plugins/views_plugin_style.inc
  46. 34 1
      sites/all/modules/contrib/views/views/plugins/views_plugin_style_rss.inc
  47. 11 0
      sites/all/modules/contrib/views/views/test_templates/README.txt
  48. 0 0
      sites/all/modules/contrib/views/views/test_templates/views-view--frontpage.tpl.php
  49. 2 2
      sites/all/modules/contrib/views/views/tests/styles/views_plugin_style.test
  50. 0 1
      sites/all/modules/contrib/views/views/tests/views_query.test
  51. 3 3
      sites/all/modules/contrib/views/views/tests/views_test.info
  52. 1 1
      sites/all/modules/contrib/views/views/tests/views_test.module
  53. 1 1
      sites/all/modules/contrib/views/views/theme/views-view-table.tpl.php
  54. 34 8
      sites/all/modules/contrib/views/views/views.api.php
  55. 13 3
      sites/all/modules/contrib/views/views/views.info
  56. 15 1
      sites/all/modules/contrib/views/views/views.install
  57. 17 4
      sites/all/modules/contrib/views/views/views.module
  58. 3 3
      sites/all/modules/contrib/views/views/views_ui.info
  59. 1 1
      sites/all/modules/contrib/views/views/views_ui.module

+ 38 - 23
sites/all/modules/contrib/views/views/handlers/views_handler_area_view.inc

@@ -51,33 +51,48 @@ class views_handler_area_view extends views_handler_area {
    * Render the area
    */
   function render($empty = FALSE) {
-    if (!empty($this->options['view_to_insert'])) {
-      list($view_name, $display_id) = explode(':', $this->options['view_to_insert']);
-
-      $view = views_get_view($view_name);
-      if (empty($view) || !$view->access($display_id)) {
-        return;
-      }
-      $view->set_display($display_id);
-
-      // Avoid recursion
-      $view->parent_views += $this->view->parent_views;
-      $view->parent_views[] = "$view_name:$display_id";
-
-      // Check if the view is part of the parent views of this view
-      $search = "$view_name:$display_id";
-      if (in_array($search, $this->view->parent_views)) {
-        drupal_set_message(t("Recursion detected in view @view display @display.", array('@view' => $view_name, '@display' => $display_id)), 'error');
+    if ($view = $this->loadView()) {
+      if (!empty($this->options['inherit_arguments']) && !empty($this->view->args)) {
+        return $view->preview(NULL, $this->view->args);
       }
       else {
-        if (!empty($this->options['inherit_arguments']) && !empty($this->view->args)) {
-          return $view->preview($display_id, $this->view->args);
-        }
-        else {
-          return $view->preview($display_id);
-        }
+        return $view->preview(NULL);
       }
     }
     return '';
   }
+
+  /**
+   * Loads the used view for rendering.
+   *
+   * @return \view|NULL
+   *   The loaded view or NULL, in case the view was not loadable / recursion
+   *   got detected / access got denied.
+   */
+  protected function loadView() {
+    if (empty($this->options['view_to_insert'])) {
+      return NULL;
+    }
+    list($view_name, $display_id) = explode(':', $this->options['view_to_insert']);
+
+    $view = views_get_view($view_name);
+    if (empty($view) || !$view->access($display_id)) {
+      return NULL;
+    }
+    $view->set_display($display_id);
+
+    // Avoid recursion.
+    $view->parent_views += $this->view->parent_views;
+    $view->parent_views[] = "$view_name:$display_id";
+
+    // Check if the view is part of the parent views of this view.
+    $search = "$view_name:$display_id";
+    if (in_array($search, $this->view->parent_views)) {
+      drupal_set_message(t("Recursion detected in view @view display @display.", array('@view' => $view_name, '@display' => $display_id)), 'error');
+      return NULL;
+    }
+
+    return $view;
+  }
+
 }

+ 1 - 4
sites/all/modules/contrib/views/views/handlers/views_handler_argument.inc

@@ -419,7 +419,7 @@ class views_handler_argument extends views_handler {
     // Let the plugins do validation.
     $default_id = $form_state['values']['options']['default_argument_type'];
     $plugin = $this->get_plugin('argument default', $default_id);
-    if ($plugin) {
+    if ($plugin && isset($form['argument_default'][$default_id]) && isset($form_state['values']['options']['argument_default'][$default_id])) {
       $plugin->options_validate($form['argument_default'][$default_id], $form_state, $form_state['values']['options']['argument_default'][$default_id]);
     }
 
@@ -1075,9 +1075,6 @@ class views_handler_argument extends views_handler {
     $argument = clone $this;
     if (!isset($arg) && $argument->has_default_argument()) {
       $arg = $argument->get_default_argument();
-
-      // remember that this argument was computed, not passed on the URL.
-      $this->is_default = TRUE;
     }
     // Set the argument, which will also validate that the argument can be set.
     if ($argument->set_argument($arg)) {

+ 1 - 1
sites/all/modules/contrib/views/views/handlers/views_handler_field.inc

@@ -372,7 +372,7 @@ class views_handler_field extends views_handler {
    *   Optional name of the field where the value is stored.
    */
   function get_value($values, $field = NULL) {
-    $alias = isset($field) && isset($this->aliases[$field]) ? $this->aliases[$field] : $this->field_alias;
+    $alias = isset($field) ? $this->aliases[$field] : $this->field_alias;
     if (isset($values->{$alias})) {
       return $values->{$alias};
     }

+ 9 - 56
sites/all/modules/contrib/views/views/handlers/views_handler_field_contextual_links.inc

@@ -10,35 +10,7 @@
  *
  * @ingroup views_field_handlers
  */
-class views_handler_field_contextual_links extends views_handler_field {
-  function option_definition() {
-    $options = parent::option_definition();
-
-    $options['fields'] = array('default' => array());
-    $options['destination'] = array('default' => TRUE, 'bool' => TRUE);
-
-    return $options;
-  }
-
-  function options_form(&$form, &$form_state) {
-    $all_fields = $this->view->display_handler->get_field_labels();
-    // Offer to include only those fields that follow this one.
-    $field_options = array_slice($all_fields, 0, array_search($this->options['id'], array_keys($all_fields)));
-    $form['fields'] = array(
-      '#type' => 'checkboxes',
-      '#title' => t('Fields'),
-      '#description' => t('Fields to be included as contextual links.'),
-      '#options' => $field_options,
-      '#default_value' => $this->options['fields'],
-    );
-    $form['destination'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Include destination'),
-      '#description' => t('Include a "destination" parameter in the link to return the user to the original view upon completing the contextual action.'),
-      '#default_value' => $this->options['destination'],
-    );
-  }
-
+class views_handler_field_contextual_links extends views_handler_field_links {
   function pre_render(&$values) {
     // Add a row plugin css class for the contextual link.
     $class = 'contextual-links-region';
@@ -50,35 +22,18 @@ class views_handler_field_contextual_links extends views_handler_field {
     }
   }
 
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
+    $form['fields']['#description'] = t('Fields to be included as contextual links.');
+    $form['destination']['#description'] = t('Include a "destination" parameter in the link to return the user to the original view upon completing the contextual action.');
+  }
+
   /**
    * Render the contextual fields.
    */
   function render($values) {
-    $links = array();
-    foreach ($this->options['fields'] as $field) {
-      if (empty($this->view->style_plugin->rendered_fields[$this->view->row_index][$field])) {
-        continue;
-      }
-      $title = $this->view->field[$field]->last_render_text;
-      $path = '';
-      if (!empty($this->view->field[$field]->options['alter']['path'])) {
-        $path = $this->view->field[$field]->options['alter']['path'];
-      }
-      if (!empty($title) && !empty($path)) {
-        // Make sure that tokens are replaced for this paths as well.
-        $tokens = $this->get_render_tokens(array());
-        $path = strip_tags(decode_entities(strtr($path, $tokens)));
-
-        $links[$field] = array(
-          'href' => $path,
-          'title' => $title,
-        );
-        if (!empty($this->options['destination'])) {
-          $links[$field]['query'] = drupal_get_destination();
-        }
-      }
-    }
-
+    $links = $this->get_links();
     if (!empty($links)) {
       $build = array(
         '#prefix' => '<div class="contextual-links-wrapper">',
@@ -97,6 +52,4 @@ class views_handler_field_contextual_links extends views_handler_field {
       return '';
     }
   }
-
-  function query() { }
 }

+ 55 - 0
sites/all/modules/contrib/views/views/handlers/views_handler_field_ctools_dropdown.inc

@@ -0,0 +1,55 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_ctools_dropdown.
+ */
+
+/**
+ * Field handler which displays some amount of links as ctools dropdown button.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_ctools_dropdown extends views_handler_field_links {
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['views_admin_css'] = array('default' => TRUE, 'bool' => TRUE);
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    $form['fields']['#description'] = t('Fields to be included as ctools dropdown button.');
+    $form['destination']['#description'] = t('Include a "destination" parameter in the link to return the user to the original view upon completing a link action.');
+
+    $form['views_admin_css'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Include Views admin CSS'),
+      '#description' => t("Add additional css to match the style of the Views admin screen."),
+      '#default_value' => $this->options['views_admin_css'],
+    );
+  }
+
+  /**
+   * Render the dropdown button.
+   */
+  function render($values) {
+    static $added_admin_css;
+    $links = $this->get_links();
+
+    if (!empty($links)) {
+      if (!empty($this->options['views_admin_css']) && !$added_admin_css) {
+        views_include('admin');
+        views_ui_add_admin_css();
+        $added_admin_css = TRUE;
+      }
+
+      return theme('links__ctools_dropbutton', array('links' => $links, 'attributes' => array('class' => array('links', 'inline'))));
+    }
+    else {
+      return '';
+    }
+  }
+}

+ 155 - 0
sites/all/modules/contrib/views/views/handlers/views_handler_field_links.inc

@@ -0,0 +1,155 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_links.
+ */
+
+/**
+ * A abstract handler which provides a collection of links.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_links extends views_handler_field {
+
+  /**
+   * Overrides views_handler_field::option_definition().
+   */
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['fields'] = array('default' => array());
+    $options['check_access'] = array('default' => FALSE);
+    $options['destination'] = array('default' => TRUE, 'bool' => TRUE);
+
+    return $options;
+  }
+
+  /**
+   * Overrides views_handler_field::options_form().
+   */
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
+    $all_fields = $this->view->display_handler->get_field_labels();
+    // Offer to include only those fields that follow this one.
+    $field_options = array_slice($all_fields, 0, array_search($this->options['id'], array_keys($all_fields)));
+    $form['fields'] = array(
+      '#type' => 'checkboxes',
+      '#title' => t('Fields'),
+      '#description' => t('Fields to be included as links.'),
+      '#options' => $field_options,
+      '#default_value' => $this->options['fields'],
+      '#required' => TRUE,
+    );
+
+    $form['check_access'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Evaluate router path for access'),
+      '#default_value' => $this->options['check_access'],
+      '#description' => t('Will check if the path exists and is accessible for the current user. Might be useful, might be slow.'),
+    );
+
+    $form['destination'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Include destination'),
+      '#description' => t('Include a "destination" parameter in the link to return the user to the original view upon completing the link action.'),
+      '#default_value' => $this->options['destination'],
+    );
+  }
+
+  /**
+   * Overrides views_handler_field::options_form().
+   */
+  function options_submit(&$form, &$form_state) {
+    // Remove unselected options.
+    $form_state['values']['options']['fields'] = array_filter($form_state['values']['options']['fields']);
+  }
+
+  /**
+   * Return the list of links of this field.
+   *
+   * @return array
+   *   The links which are used by the render function.
+   */
+  function get_links() {
+    $links = array();
+    foreach ($this->options['fields'] as $field) {
+      if (empty($this->view->field[$field]->last_render_text)) {
+        continue;
+      }
+
+      $title = $this->view->field[$field]->last_render_text;
+      // Use the alter settings for the link field source not this links field.
+      $alter = $this->view->field[$field]->options['alter'];
+      $url = array('query' => array());
+
+      // Copy code from views_handler_field::render_as_link().
+      $path = $alter['path'];
+      if (!empty($path) && $path != '<front>') {
+        // Leave path alone on <front> as strip_tags() would remove this.
+        // Replace tokens and strip any HTML tags in the path.
+        $tokens = $this->get_render_tokens(array());
+        $path = strip_tags(decode_entities(strtr($path, $tokens)));
+
+        if (!empty($alter['path_case']) && $alter['path_case'] != 'none') {
+          $path = $this->case_transform($path, $alter['path_case']);
+        }
+
+        if (!empty($alter['replace_spaces'])) {
+          $path = str_replace(' ', '-', $path);
+        }
+
+        $url = drupal_parse_url($path);
+        if (empty($url)) {
+          // Seriously malformed URLs may return FALSE or empty arrays.
+          continue;
+        }
+        $path = $url['path'];
+
+        // Check router menu item access for the current user.
+        if ($this->options['check_access']) {
+          $menu_item = menu_get_item($path);
+          if (!$menu_item || empty($menu_item['access'])) {
+            continue;
+          }
+        }
+
+        if (!empty($this->options['destination']) && empty($alter['external'])) {
+          // Override any destination argument included in URL.
+          $url['query'] = array_merge($url['query'], drupal_get_destination());
+        }
+
+        // Omit tweaks of query, fragment, and link_class.
+
+        $alt = strtr($alter['alt'], $tokens);
+        if ($alt && $alt != $title) {
+          // Set the title attribute only if it improves accessibility.
+          $url['attributes']['title'] = decode_entities($alt);
+        }
+
+        if (!empty($alter['rel']) && $rel = strtr($alter['rel'], $tokens)) {
+          $url['attributes']['rel'] = $rel;
+        }
+
+        $target = check_plain(trim(strtr($alter['target'], $tokens)));
+        if (!empty($target)) {
+          $url['attributes']['target'] = $target;
+        }
+      }
+
+      $links[$field] = array(
+        'href' => $path,
+        'title' => $title,
+      ) + $url;
+    }
+
+    return $links;
+  }
+
+  /**
+   * Overrides views_handler_field::query().
+   */
+  function query() { }
+
+}

+ 1 - 1
sites/all/modules/contrib/views/views/handlers/views_handler_field_math.inc

@@ -26,7 +26,7 @@ class views_handler_field_math extends views_handler_field_numeric {
     $form['expression'] = array(
       '#type' => 'textarea',
       '#title' => t('Expression'),
-      '#description' => t('Enter mathematical expressions such as 2 + 2 or sqrt(5). You may assign variables and create mathematical functions and evaluate them. Use the ; to separate these. For example: f(x) = x + 2; f(2).'),
+      '#description' => t("Enter mathematical expressions such as 2 + 2 or sqrt(5). You may assign variables and create mathematical functions and evaluate them. Use the ; to separate these. For example: f(x) = x + 2; f(2). The result of the previous row's mathematical expression can be accessed by using the [expression] token itself."),
       '#default_value' => $this->options['expression'],
     );
 

+ 6 - 5
sites/all/modules/contrib/views/views/handlers/views_handler_field_numeric.inc

@@ -107,6 +107,12 @@ class views_handler_field_numeric extends views_handler_field {
 
   function render($values) {
     $value = $this->get_value($values);
+
+    // Hiding should happen before rounding or adding prefix/suffix.
+    if ($this->options['hide_empty'] && empty($value) && ($value !== 0 || $this->options['empty_zero'])) {
+      return '';
+    }
+
     if (!empty($this->options['set_precision'])) {
       $value = number_format($value, $this->options['precision'], $this->options['decimal'], $this->options['separator']);
     }
@@ -120,11 +126,6 @@ class views_handler_field_numeric extends views_handler_field {
       }
     }
 
-    // Check to see if hiding should happen before adding prefix and suffix.
-    if ($this->options['hide_empty'] && empty($value) && ($value !== 0 || $this->options['empty_zero'])) {
-      return '';
-    }
-
     // Should we format as a plural.
     if (!empty($this->options['format_plural'])) {
       $value = format_plural($value, $this->options['format_plural_singular'], $this->options['format_plural_plural']);

+ 5 - 0
sites/all/modules/contrib/views/views/handlers/views_handler_filter_combine.inc

@@ -54,6 +54,11 @@ class views_handler_filter_combine extends views_handler_filter_string {
     $fields = array();
     // Only add the fields if they have a proper field and table alias.
     foreach ($this->options['fields'] as $id) {
+      // Field access checks may have removed this handler.
+      if (!isset($this->view->field[$id])) {
+        continue;
+      }
+
       $field = $this->view->field[$id];
       // Always add the table of the selected fields to be sure a table alias
       // exists.

+ 7 - 0
sites/all/modules/contrib/views/views/includes/admin.inc

@@ -4961,6 +4961,13 @@ function views_ui_admin_settings_advanced() {
     '#description' => t('Select a translation method to use for Views data like header, footer, and empty text.'),
   );
 
+  $form['locale']['views_localize_all'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Use same translation method for exported views'),
+    '#description' => t('Exported views will use Core translation by default. Enable this to always use the configured translation method.'),
+    '#default_value' => variable_get('views_localize_all', FALSE),
+  );
+
   $regions = array();
   $regions['watchdog'] = t('Watchdog');
   if (module_exists('devel')) {

+ 2 - 2
sites/all/modules/contrib/views/views/includes/ajax.inc

@@ -48,12 +48,12 @@ function views_ajax() {
 
       // Add all $_POST data, because AJAX is always a post and many things,
       // such as tablesorts, exposed filters and paging assume $_GET.
-      $_GET = $_POST + $_GET;
+      $_GET = $_POST + drupal_get_query_parameters($_GET, array('page'));
 
       // Overwrite the destination.
       // @see drupal_get_destination()
       $origin_destination = $path;
-      $query = drupal_http_build_query($_REQUEST);
+      $query = drupal_http_build_query(drupal_get_query_parameters());
       if ($query != '') {
         $origin_destination .= '?' . $query;
       }

+ 1 - 1
sites/all/modules/contrib/views/views/includes/cache.inc

@@ -141,7 +141,7 @@ function _views_fetch_plugin_data($type = NULL, $plugin = NULL, $reset = FALSE)
       }
     }
     // If not available in the cache, build it and cache it.
-    if (!$cache) {
+    if (!$cache || $reset) {
       $cache = views_discover_plugins();
       cache_set($cache_key, $cache);
     }

+ 51 - 26
sites/all/modules/contrib/views/views/includes/handlers.inc

@@ -758,7 +758,7 @@ class views_many_to_one_helper {
    */
   public $placeholders = array();
 
-  function views_many_to_one_helper(&$handler) {
+  function __construct(&$handler) {
     $this->handler = &$handler;
   }
 
@@ -1547,7 +1547,6 @@ class views_join {
       if (is_array($this->extra)) {
         $extras = array();
         foreach ($this->extra as $info) {
-          $extra = '';
           // Figure out the table name. Remember, only use aliases provided
           // if at all possible.
           $join_table = '';
@@ -1565,36 +1564,63 @@ class views_join {
             }
           }
 
-          // Convert a single-valued array of values to the single-value case,
-          // and transform from IN() notation to = notation
-          if (is_array($info['value']) && count($info['value']) == 1) {
-            if (empty($info['operator'])) {
-              $operator = '=';
+          // If left_field is set use it for a field-to-field condition.
+          if (!empty($info['left_field'])) {
+            $operator = !empty($info['operator']) ? $info['operator'] : '=';
+            $left_table = (isset($info['left_table'])) ? $info['left_table'] : $left['alias'];
+            $extras[] = "$join_table$info[field] $operator $left_table.$info[left_field]";
+          }
+          // Else if formula is set, us it for a flexible on clause.
+          elseif (!empty($info['formula'])) {
+            // If a field is given, we build a "$field $op $formula".
+            // Without it would only be "$formula".
+            $extra = '';
+            if (isset($info['field'])) {
+              // With a single value, the '=' operator is implicit.
+              $operator = !empty($info['operator']) ? $info['operator'] : '=';
+              $extra .= "$join_table$info[field] $operator ";
             }
-            else {
-              $operator = $info['operator'] == 'NOT IN' ? '!=' : '=';
+            $extra .= $info['formula'];
+            // Add placeholder arguments.
+            if (isset($info['formula_arguments']) && is_array($info['formula_arguments'])) {
+              $arguments = array_merge($arguments, $info['formula_arguments']);
             }
-            $info['value'] = array_shift($info['value']);
+            $extras[] = $extra;
           }
+          // Otherwise - and if we have a value - use it for a field-to-value condition.
+          elseif (!empty($info['value'])) {
+            // Convert a single-valued array of values to the single-value case,
+            // and transform from IN() notation to = notation
+            if (is_array($info['value']) && count($info['value']) == 1) {
+              if (empty($info['operator'])) {
+                $operator = '=';
+              }
+              else {
+                $operator = $info['operator'] == 'NOT IN' ? '!=' : '=';
+              }
+              $info['value'] = array_shift($info['value']);
+            }
 
-          if (is_array($info['value'])) {
-            // 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_');
-              $arguments[$placeholder_i] = $value;
+            if (is_array($info['value'])) {
+              // With an array of values, we need multiple placeholders and the
+              // 'IN' operator is implicit.
+              foreach ($info['value'] as $value) {
+                $placeholder_i = ':views_join_condition_' . $select_query->nextPlaceholder();
+                $arguments[$placeholder_i] = $value;
+              }
+
+              $operator = !empty($info['operator']) ? $info['operator'] : 'IN';
+              $placeholder = '( ' . implode(', ', array_keys($arguments)) . ' )';
+            }
+            else {
+              // With a single value, the '=' operator is implicit.
+              $operator = !empty($info['operator']) ? $info['operator'] : '=';
+              $placeholder = ':views_join_condition_' . $select_query->nextPlaceholder();
+              $arguments[$placeholder] = $info['value'];
             }
 
-            $operator = !empty($info['operator']) ? $info['operator'] : 'IN';
-            $placeholder = '( ' . implode(', ', array_keys($arguments)) . ' )';
+            $extras[] = "$join_table$info[field] $operator $placeholder";
           }
-          else {
-            // With a single value, the '=' operator is implicit.
-            $operator = !empty($info['operator']) ? $info['operator'] : '=';
-            $placeholder = $view_query->placeholder('views_join_condition_');
-            $arguments[$placeholder] = $info['value'];
-          }
-          $extras[] = "$join_table$info[field] $operator $placeholder";
         }
 
         if ($extras) {
@@ -1660,7 +1686,6 @@ class views_join_subquery extends views_join {
       if (is_array($this->extra)) {
         $extras = array();
         foreach ($this->extra as $info) {
-          $extra = '';
           // Figure out the table name. Remember, only use aliases provided
           // if at all possible.
           $join_table = '';

+ 4 - 1
sites/all/modules/contrib/views/views/includes/plugins.inc

@@ -408,7 +408,7 @@ function views_views_plugins() {
  */
 function views_discover_plugins() {
   $cache = array('display' => array(), 'style' => array(), 'row' => array(), 'argument default' => array(), 'argument validator' => array(), 'access' => array(), 'cache' => array(), 'exposed_form' => array());
-  // Get plugins from all mdoules.
+  // Get plugins from all modules.
   foreach (module_implements('views_plugins') as $module) {
     $function = $module . '_views_plugins';
     $result = $function();
@@ -526,6 +526,9 @@ class views_plugin extends views_object {
    * Provide a full list of possible theme templates used by this style.
    */
   function theme_functions() {
+    if (empty($this->definition['theme'])) {
+      $this->definition['theme'] = 'views_view';
+    }
     return views_theme_functions($this->definition['theme'], $this->view, $this->display);
   }
 

+ 30 - 18
sites/all/modules/contrib/views/views/includes/view.inc

@@ -812,8 +812,6 @@ class view extends views_db_object {
           if (isset($arg)) {
             $this->args[$position] = $arg;
           }
-          // remember that this argument was computed, not passed on the URL.
-          $argument->is_default = TRUE;
         }
 
         // Set the argument, which will also validate that the argument can be set.
@@ -1150,7 +1148,7 @@ class view extends views_db_object {
       $cache = $this->display_handler->get_plugin('cache');
     }
     if ($cache && $cache->cache_get('results')) {
-      if($this->query->pager->use_pager()) {
+      if($this->query->pager->use_pager() || !empty($this->get_total_rows)) {
         $this->query->pager->total_items = $this->total_rows;
         $this->query->pager->update_page_info();
       }
@@ -1593,7 +1591,7 @@ class view extends views_db_object {
       $position = 0;
       if (!empty($this->argument)) {
         foreach ($this->argument as $argument_id => $argument) {
-          if (!empty($argument->is_default) && !empty($argument->options['default_argument_skip_url'])) {
+          if (!empty($argument->options['default_argument_skip_url'])) {
             unset($args[$position]);
           }
           $position++;
@@ -1818,6 +1816,9 @@ class view extends views_db_object {
       $this->vid = $vid ? $vid : NULL;
     }
 
+    // Let modules modify the view just prior to saving it.
+    module_invoke_all('views_view_presave', $this);
+
     $transaction = db_transaction();
 
     try {
@@ -1848,6 +1849,9 @@ class view extends views_db_object {
 
     // Clear caches.
     views_invalidate_cache();
+
+    // Notify modules that this view has been saved.
+    module_invoke_all('views_view_save', $this);
   }
 
   /**
@@ -1887,6 +1891,9 @@ class view extends views_db_object {
       // Clear caches.
       views_invalidate_cache();
     }
+
+    // Notify modules that this view has been deleted.
+    module_invoke_all('views_view_delete', $this);
   }
 
   /**
@@ -2076,25 +2083,26 @@ class view extends views_db_object {
   }
 
   /**
-   * Find and initialize the localizer plugin.
+   * Find and initialize the localization plugin.
    */
   function init_localization() {
-    if (isset($this->localization_plugin) && is_object($this->localization_plugin)) {
-      return TRUE;
-    }
+    // If the translate attribute isn't set, init the localization plugin.
+    if (!isset($this->localization_plugin->translate)) {
+      $this->localization_plugin = views_get_plugin('localization', views_get_localization_plugin());
 
-    $this->localization_plugin = views_get_plugin('localization', views_get_localization_plugin());
+      // If the plugin is still not set, turn off all localization by using the
+      // views_plugin_localization_none plugin. This plugin has the translate
+      // property set to FALSE, signifying localization should not occur.
+      if (empty($this->localization_plugin)) {
+        $this->localization_plugin = views_get_plugin('localization', 'none');
+      }
 
-    if (empty($this->localization_plugin)) {
-      $this->localization_plugin = views_get_plugin('localization', 'none');
-      return FALSE;
+      // Init the plugin.
+      $this->localization_plugin->init($this);
     }
 
-    /**
-    * Figure out whether there should be options.
-    */
-    $this->localization_plugin->init($this);
-
+    // Return the value of the translate property. This is set to FALSE if
+    // localization is off.
     return $this->localization_plugin->translate;
   }
 
@@ -2102,6 +2110,10 @@ class view extends views_db_object {
    * Determine whether a view supports admin string translation.
    */
   function is_translatable() {
+    // Use translation no matter what type of view.
+    if (variable_get('views_localize_all', FALSE)) {
+      return TRUE;
+    }
     // If the view is normal or overridden, use admin string translation.
     // A newly created view won't have a type. Accept this.
     return (!isset($this->type) || in_array($this->type, array(t('Normal'), t('Overridden')))) ? TRUE : FALSE;
@@ -2566,7 +2578,7 @@ class views_display extends views_db_object {
   var $display_options;
 
   var $db_table = 'views_display';
-  function views_display($init = TRUE) {
+  function __construct($init = TRUE) {
     parent::init($init);
   }
 

+ 1 - 1
sites/all/modules/contrib/views/views/js/ajax_view.js

@@ -57,7 +57,7 @@ Drupal.views.ajaxView = function(settings) {
   this.settings = settings;
 
   // Add the ajax to exposed forms.
-  this.$exposed_form = this.$view.children('.view-filters').children('form');
+  this.$exposed_form = $('#views-exposed-form-'+ settings.view_name.replace(/_/g, '-') + '-' + settings.view_display_id.replace(/_/g, '-'));
   this.$exposed_form.once(jQuery.proxy(this.attachExposedFormAjax, this));
 
   // Add the ajax to pagers.

+ 1 - 1
sites/all/modules/contrib/views/views/js/views-admin.js

@@ -352,7 +352,7 @@ Drupal.viewsUi.OptionsSearch.prototype.handleKeyup = function (event) {
 
   // Determine the user's search query. The search text has been converted to
   // lowercase.
-  search = this.$searchBox.val().toLowerCase();
+  search = (this.$searchBox.val() || '').toLowerCase();
   words = search.split(' ');
   wordsLength = words.length;
 

+ 0 - 39
sites/all/modules/contrib/views/views/modules/field.views.inc

@@ -435,45 +435,6 @@ function field_views_field_default_views_data($field) {
           'field_name' => $field['field_name'],
         );
       }
-
-      // Expose additional language column for translatable fields.
-      if (!empty($field['translatable'])) {
-        $title_language = t('@label (!name:language)', array('@label' => $label, '!name' => $field['field_name']));
-        $title_short_language = t('@label:language', array('@label' => $label));
-
-        $data[$table]['language'] = array(
-          'group' => $group,
-          'title' => $title_language,
-          'title short' => $title_short_language,
-          'help' => t('Language - Appears in: @bundles.', array('@bundles' => implode(', ', $bundles_names))),
-        );
-        $data[$table]['language']['field'] = array(
-          'handler' => 'views_handler_field_locale_language',
-        );
-        $data[$table]['language']['argument'] = array(
-          'field' => 'language',
-          'table' => $table,
-          'handler' => 'views_handler_argument_locale_language',
-          'additional fields' => $additional_fields,
-          'empty field name' => t('<No value>'),
-          'field_name' => $field['field_name'],
-        );
-        $data[$table]['language']['filter'] = array(
-          'field' => 'language',
-          'table' => $table,
-          'handler' => 'views_handler_filter_locale_language',
-          'additional fields' => $additional_fields,
-          'field_name' => $field['field_name'],
-          'allow empty' => TRUE,
-        );
-        $data[$table]['language']['sort'] = array(
-          'field' => 'language',
-          'table' => $table,
-          'handler' => 'views_handler_sort',
-          'additional fields' => $additional_fields,
-          'field_name' => $field['field_name'],
-        );
-      }
     }
   }
 

+ 21 - 0
sites/all/modules/contrib/views/views/modules/field/views_handler_field_field.inc

@@ -383,6 +383,10 @@ class views_handler_field_field extends views_handler_field {
       'default' => FALSE,
       'bool' => TRUE,
     );
+    $options['delta_random'] = array(
+      'default' => FALSE,
+      'bool' => TRUE,
+    );
 
     $options['multi_type'] = array(
       'default' => 'separator'
@@ -576,6 +580,14 @@ class views_handler_field_field extends views_handler_field {
       '#title' => t('First and last only'),
       '#type' => 'checkbox',
       '#default_value' => $this->options['delta_first_last'],
+      '#suffix' => $suffix,
+      '#dependency' => array('edit-options-group-rows' => array(TRUE)),
+      '#fieldset' => 'multiple_field_settings',
+    );
+    $form['delta_random'] = array(
+      '#title' => t('Random order'),
+      '#type' => 'checkbox',
+      '#default_value' => $this->options['delta_random'],
       '#suffix' => '</div>',
       '#dependency' => array('edit-options-group-rows' => array(TRUE)),
       '#fieldset' => 'multiple_field_settings',
@@ -716,6 +728,10 @@ class views_handler_field_field extends views_handler_field {
   }
 
   function get_value($values, $field = NULL) {
+    if (!isset($values->_field_data[$this->field_alias]['entity']) || !is_object($values->_field_data[$this->field_alias]['entity'])) {
+      return array();
+    }
+
     // Go ahead and render and store in $this->items.
     $entity = clone $values->_field_data[$this->field_alias]['entity'];
 
@@ -757,6 +773,11 @@ class views_handler_field_field extends views_handler_field {
       return array();
     }
 
+    // If requested, randomize the order of the deltas.
+    if ($this->options['delta_random'] && !empty($entity->{$this->definition['field_name']})) {
+      shuffle($entity->{$this->definition['field_name']}[$langcode]);
+    }
+
     // We are supposed to show only certain deltas.
     if ($this->limit_values && !empty($entity->{$this->definition['field_name']})) {
       $all_values = !empty($entity->{$this->definition['field_name']}[$langcode]) ? $entity->{$this->definition['field_name']}[$langcode] : array();

+ 7 - 0
sites/all/modules/contrib/views/views/modules/locale.views.inc

@@ -218,4 +218,11 @@ function locale_views_data_alter(&$data) {
       'handler' => 'views_handler_sort',
     ),
   );
+  $data['node']['specific_language'] = array(
+    'title' => t('Specific language'),
+    'help' => t('Sort by a specific language that the content is in.'),
+    'sort' => array(
+      'handler' => 'views_handler_sort_node_language',
+    ),
+  );
 }

+ 1 - 1
sites/all/modules/contrib/views/views/modules/locale/views_handler_field_locale_link_edit.inc

@@ -52,7 +52,7 @@ class views_handler_field_locale_link_edit extends views_handler_field {
     $text = !empty($this->options['text']) ? $this->options['text'] : t('edit');
 
     $this->options['alter']['make_link'] = TRUE;
-    $this->options['alter']['path'] = 'admin/build/translate/edit/' . $data;
+    $this->options['alter']['path'] = 'admin/config/regional/translate/edit/' . $data;
     $this->options['alter']['query'] = drupal_get_destination();
 
     return $text;

+ 107 - 0
sites/all/modules/contrib/views/views/modules/locale/views_handler_sort_node_language.inc

@@ -0,0 +1,107 @@
+<?php
+
+/**
+ * Sort handler that allows sorting on a specific language.
+ *
+ * @ingroup views_sort_handlers
+ */
+class views_handler_sort_node_language extends views_handler_sort {
+
+  /**
+   * {@inheritdoc}
+   */
+  function can_expose() {
+    return FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  function query() {
+    if (isset($this->options['language'])) {
+      $langcode = $this->get_system_langcode($this->options['language']);
+      // Validate the langcode.
+      if (preg_match('/^[a-z0-9\-]+$/i', $langcode)) {
+        $this->ensure_my_table();
+        // See https://stackoverflow.com/questions/14104055/ordering-by-specific-field-value-first
+        $formula = "{$this->table_alias}_language = '{$langcode}'";
+        $this->query->add_orderby($this->table_alias, NULL, $this->options['order'], $formula);
+      }
+    }
+  }
+
+  /**
+   * Converts a views language code into a Drupal language code.
+   */
+  function get_system_langcode($langcode) {
+    global $language_content;
+    $default_language = language_default('language');
+    $system_langcode = str_replace(array(
+      '***CURRENT_LANGUAGE***',
+      '***DEFAULT_LANGUAGE***',
+      ),
+      array(
+        $language_content->language,
+        $default_language,
+      ),
+      $langcode);
+    return $system_langcode;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['language'] = array('default' => '***CURRENT_LANGUAGE***');
+    return $options;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  function admin_summary() {
+    $summary = parent::admin_summary();
+    if ($this->options['language']) {
+      $language_options = $this->get_language_options();
+      $summary = t('@order, @language', array(
+        '@order' => $summary,
+        '@language' => $language_options[$this->options['language']],
+      ));
+    }
+    return $summary;
+  }
+
+  /**
+   * Returns languages to sort by.
+   *
+   * @return array
+   *   All the languages.
+   */
+  function get_language_options() {
+    $languages = array(
+      '***CURRENT_LANGUAGE***' => t("Current user's language"),
+      '***DEFAULT_LANGUAGE***' => t("Default site language"),
+      LANGUAGE_NONE => t('No language')
+    );
+    $languages = array_merge($languages, views_language_list());
+    return $languages;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  function show_sort_form(&$form, &$form_state) {
+    parent::show_sort_form($form, $form_state);
+
+    $form['language'] = array(
+      '#type' => 'radios',
+      '#title' => t("Specific language"),
+      '#description' => t("Choose which specific language to sort by. Not to be confused with the 'Language' sort handler, which sorts by language."),
+      '#options' => $this->get_language_options(),
+      '#default_value' => $this->options['language'],
+    );
+  }
+
+}
+

+ 18 - 0
sites/all/modules/contrib/views/views/modules/node.views.inc

@@ -406,6 +406,23 @@ function node_views_data() {
     ),
   );
 
+  $data['node']['version_count'] = array(
+    'title' => t('Version Count'),
+    'help' => t('The total count of versions/revisions of a certain node.'),
+    'field' => array(
+      'handler' => 'views_handler_field_node_version_count',
+      'field' => 'nid',
+      'click sortable' => TRUE,
+    ),
+    'filter' => array(
+      'handler' => 'views_handler_filter_node_version_count',
+      'allow empty' => FALSE,
+    ),
+    'sort' => array(
+      'handler' => 'views_handler_sort_node_version_count',
+    ),
+  );
+
   // ----------------------------------------------------------------------
   // Content revision table
 
@@ -413,6 +430,7 @@ function node_views_data() {
   // have a group defined will go into this field by default.
   $data['node_revisions']['moved to'] = 'node_revision';
   $data['node_revision']['table']['entity type'] = 'node';
+  $data['node_revision']['table']['revision'] = TRUE;
   $data['node_revision']['table']['group']  = t('Content revision');
   // Support the conversion of the field body
   $data['node_revisions']['body']['moved to'] = array('field_revision_data', 'body-revision_id');

+ 21 - 0
sites/all/modules/contrib/views/views/modules/node/views_handler_field_node_version_count.inc

@@ -0,0 +1,21 @@
+<?php
+/**
+ * @file
+ * Definition of views_handler_field_node_version_count.
+ */
+
+/**
+ * A handler that loads the total count of versions/revisions of a certain node.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_node_version_count extends views_handler_field_numeric {
+  function query() {
+    $this->ensure_my_table();
+    // Add the field.
+    $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
+    $this->field_alias = $this->query->add_field(NULL, '(SELECT COUNT(vid) FROM {node_revision} WHERE nid = {node}.nid)', 'node_version_count', $params);
+
+    $this->add_additional_fields();
+  }
+}

+ 1 - 1
sites/all/modules/contrib/views/views/modules/node/views_handler_filter_node_uid_revision.inc

@@ -18,7 +18,7 @@ class views_handler_filter_node_uid_revision extends views_handler_filter_user_n
 
     $args = array_values($this->value);
 
-    $this->query->add_where_expression($this->options['group'], "$this->table_alias.uid IN($placeholder) " . $condition . " OR
+    $this->query->add_where_expression($this->options['group'], "$this->table_alias.uid IN($placeholder) " . "OR
       ((SELECT COUNT(*) FROM {node_revision} nr WHERE nr.uid IN($placeholder) AND nr.nid = $this->table_alias.nid) > 0)", array($placeholder => $args),
       $args);
   }

+ 36 - 0
sites/all/modules/contrib/views/views/modules/node/views_handler_filter_node_version_count.inc

@@ -0,0 +1,36 @@
+<?php
+
+/**
+ * Filter to handle dates stored as a timestamp.
+ *
+ * @ingroup views_filter_handlers
+ */
+class views_handler_filter_node_version_count extends views_handler_filter_numeric {
+  function op_between($field) {
+    if ($this->operator == 'between') {
+      $this->query->add_where_expression($this->options['group'], '(SELECT COUNT(vid) FROM {node_revision} WHERE nid = {' . $this->table_alias . '}.nid) BETWEEN :min AND :max', array(':min' => $this->value['min'], ':max' => $this->value['max']));
+    }
+    else {
+      $this->query->add_where_expression($this->options['group'], '((SELECT COUNT(vid) FROM {node_revision} WHERE nid = {' . $this->table_alias . '}.nid) <= :min OR (SELECT COUNT(vid) FROM {node_revision} WHERE nid = {' . $this->table_alias . '}.nid) >= :max)', array(':min' => $this->value['min'], ':max' => $this->value['max']));
+    }
+  }
+
+  function op_simple($field) {
+    $this->query->add_where_expression($this->options['group'], '(SELECT COUNT(vid) FROM {node_revision} WHERE nid = {' . $this->table_alias . '}.nid)' . $this->operator . ' :value', array(':value' => $this->value['value']));
+  }
+
+  function op_empty($field) {
+    if ($this->operator == 'empty') {
+      $operator = "IS NULL";
+    }
+    else {
+      $operator = "IS NOT NULL";
+    }
+
+    $this->query->add_where_expression($this->options['group'], '(SELECT COUNT(vid) FROM {node_revision} WHERE nid = {' . $this->table_alias . '}.nid) ' . $this->operator);
+  }
+
+  function op_regex($field) {
+    $this->query->add_where_expression($this->options['group'], '(SELECT COUNT(vid) FROM {node_revision} WHERE nid = {' . $this->table_alias . '}.nid) RLIKE :value', array(':value' => $this->value['value']));
+  }
+}

+ 19 - 0
sites/all/modules/contrib/views/views/modules/node/views_handler_sort_node_version_count.inc

@@ -0,0 +1,19 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_sort_node_version_count.
+ */
+
+/**
+ * A handler that sorts on the total count of versions/revisions of a node.
+ *
+ * @ingroup views_sort_handlers
+ */
+class views_handler_sort_node_version_count extends views_handler_sort {
+  function query() {
+    $this->ensure_my_table();
+
+    $this->query->add_orderby(NULL, '(SELECT COUNT(vid) FROM {node_revision} WHERE nid = {' . $this->table_alias . '}.nid)', $this->options['order'], 'sort_node_version_count');
+  }
+}

+ 1 - 1
sites/all/modules/contrib/views/views/modules/search/views_handler_argument_search.inc

@@ -56,7 +56,7 @@ class views_handler_argument_search extends views_handler_argument {
       $join->construct('search_total', $search_index, 'word', 'word');
       $search_total = $this->query->add_relationship('search_total', $join, $search_index);
 
-      $this->search_score = $this->query->add_field('', "SUM($search_index.score * $search_total.count)", 'score', array('aggregate' => TRUE));
+      $this->search_score = $this->query->add_field('', "$search_index.score * $search_total.count", 'score', array('aggregate' => TRUE, 'function' => 'sum'));
 
       if (empty($this->query->relationships[$this->relationship])) {
         $base_table = $this->query->base_table;

+ 1 - 1
sites/all/modules/contrib/views/views/modules/search/views_handler_filter_search.inc

@@ -150,7 +150,7 @@ class views_handler_filter_search extends views_handler_filter {
         $join->construct('search_total', $search_index, 'word', 'word');
         $search_total = $this->query->add_relationship('search_total', $join, $search_index);
 
-        $this->search_score = $this->query->add_field('', "SUM($search_index.score * $search_total.count)", 'score', array('aggregate' => TRUE));
+        $this->search_score = $this->query->add_field('', "$search_index.score * $search_total.count", 'score', array('aggregate' => TRUE, 'function' => 'sum'));
       }
 
       if (empty($this->query->relationships[$this->relationship])) {

+ 3 - 3
sites/all/modules/contrib/views/views/modules/statistics.views.inc

@@ -32,7 +32,7 @@ function statistics_views_data() {
     'help' => t('The total number of times the node has been viewed.'),
 
     'field' => array(
-      'handler' => 'views_handler_field_numeric',
+      'handler' => 'views_handler_field_statistics_numeric',
       'click sortable' => TRUE,
      ),
     'filter' => array(
@@ -49,7 +49,7 @@ function statistics_views_data() {
     'help' => t('The total number of times the node has been viewed today.'),
 
     'field' => array(
-      'handler' => 'views_handler_field_numeric',
+      'handler' => 'views_handler_field_statistics_numeric',
       'click sortable' => TRUE,
      ),
     'filter' => array(
@@ -66,7 +66,7 @@ function statistics_views_data() {
     'help' => t('The most recent time the node has been viewed.'),
 
     'field' => array(
-      'handler' => 'views_handler_field_date',
+      'handler' => 'views_handler_field_node_counter_timestamp',
       'click sortable' => TRUE,
     ),
     'filter' => array(

+ 21 - 0
sites/all/modules/contrib/views/views/modules/statistics/views_handler_field_node_counter_timestamp.inc

@@ -0,0 +1,21 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_node_counter_timestamp.
+ */
+
+/**
+ * Field handler to present the most recent time the node has been viewed.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_node_counter_timestamp extends views_handler_field_date {
+  /**
+   * {@inheritdoc}
+   */
+  public function access() {
+    // Needs permission to see total page views.
+    return user_access('view post access counter');
+  }
+}

+ 21 - 0
sites/all/modules/contrib/views/views/modules/statistics/views_handler_field_statistics_numeric.inc

@@ -0,0 +1,21 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_field_statistics_numeric.
+ */
+
+/**
+ * Field handler to present numeric values from the statistics module.
+ *
+ * @ingroup views_field_handlers
+ */
+class views_handler_field_statistics_numeric extends views_handler_field_numeric {
+  /**
+   * {@inheritdoc}
+   */
+  public function access() {
+    // Needs permission to see total page views.
+    return user_access('view post access counter');
+  }
+}

+ 14 - 0
sites/all/modules/contrib/views/views/modules/taxonomy.views.inc

@@ -407,6 +407,20 @@ function taxonomy_views_data_alter(&$data) {
     ),
   );
 
+  $data['node']['term_node_tid_depth_join'] = array(
+    'help' => t('Display content if it has the selected taxonomy terms, or children of the selected terms. Due to additional complexity, this has fewer options than the versions without depth.'),
+    'real field' => 'nid',
+    'argument' => array(
+      'title' => t('Has taxonomy term ID with depth (using joins)'),
+      'handler' => 'views_handler_argument_term_node_tid_depth_join',
+      'accept depth modifier' => TRUE,
+    ),
+    'filter' => array(
+      'title' => t('Has taxonomy terms with depth (using joins)'),
+      'handler' => 'views_handler_filter_term_node_tid_depth_join',
+    ),
+  );
+
   $data['node']['term_node_tid_depth_modifier'] = array(
     'title' => t('Has taxonomy term ID depth modifier'),
     'help' => t('Allows the "depth" for Taxonomy: Term ID (with depth) to be modified via an additional contextual filter value.'),

+ 191 - 0
sites/all/modules/contrib/views/views/modules/taxonomy/views_handler_argument_term_node_tid_depth_join.inc

@@ -0,0 +1,191 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_argument_term_node_tid_depth_join.
+ */
+
+/**
+ * Argument handler for taxonomy terms with depth.
+ *
+ * This handler is actually part of the node table and has some restrictions,
+ * because it uses a subquery to find nodes with.
+ *
+ * @ingroup views_argument_handlers
+ */
+class views_handler_argument_term_node_tid_depth_join extends views_handler_argument {
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['depth'] = array('default' => 0);
+    $options['break_phrase'] = array('default' => FALSE, 'bool' => TRUE);
+    $options['set_breadcrumb'] = array('default' => FALSE, 'bool' => TRUE);
+    $options['use_taxonomy_term_path'] = array('default' => FALSE, 'bool' => TRUE);
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    $form['depth'] = array(
+      '#type' => 'weight',
+      '#title' => t('Depth'),
+      '#default_value' => $this->options['depth'],
+      '#description' => t('The depth will match nodes tagged with terms in the hierarchy. For example, if you have the term "fruit" and a child term "apple", with a depth of 1 (or higher) then filtering for the term "fruit" will get nodes that are tagged with "apple" as well as "fruit". If negative, the reverse is true; searching for "apple" will also pick up nodes tagged with "fruit" if depth is -1 (or lower).'),
+    );
+
+    $form['break_phrase'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Allow multiple values'),
+      '#description' => t('If selected, users can enter multiple values in the form of 1+2+3. Due to the number of JOINs it would require, AND will be treated as OR with this filter.'),
+      '#default_value' => !empty($this->options['break_phrase']),
+    );
+
+    $form['set_breadcrumb'] = array(
+      '#type' => 'checkbox',
+      '#title' => t("Set the breadcrumb for the term parents"),
+      '#description' => t('If selected, the breadcrumb trail will include all parent terms, each one linking to this view. Note that this only works if just one term was received.'),
+      '#default_value' => !empty($this->options['set_breadcrumb']),
+    );
+
+    $form['use_taxonomy_term_path'] = array(
+      '#type' => 'checkbox',
+      '#title' => t("Use Drupal's taxonomy term path to create breadcrumb links"),
+      '#description' => t('If selected, the links in the breadcrumb trail will be created using the standard drupal method instead of the custom views method. This is useful if you are using modules like taxonomy redirect to modify your taxonomy term links.'),
+      '#default_value' => !empty($this->options['use_taxonomy_term_path']),
+      '#dependency' => array('edit-options-set-breadcrumb' => array(TRUE)),
+    );
+    parent::options_form($form, $form_state);
+  }
+
+  function set_breadcrumb(&$breadcrumb) {
+    if (empty($this->options['set_breadcrumb']) || !is_numeric($this->argument)) {
+      return;
+    }
+
+    return views_taxonomy_set_breadcrumb($breadcrumb, $this);
+  }
+
+  /**
+   * Override default_actions() to remove summary actions.
+   */
+  function default_actions($which = NULL) {
+    if ($which) {
+      if (in_array($which, array('ignore', 'not found', 'empty', 'default'))) {
+        return parent::default_actions($which);
+      }
+      return;
+    }
+    $actions = parent::default_actions();
+    unset($actions['summary asc']);
+    unset($actions['summary desc']);
+    unset($actions['summary asc by count']);
+    unset($actions['summary desc by count']);
+    return $actions;
+  }
+
+  function query($group_by = FALSE) {
+    $this->ensure_my_table();
+
+    if (!empty($this->options['break_phrase'])) {
+      $tids = new stdClass();
+      $tids->value = $this->argument;
+      $tids = views_break_phrase($this->argument, $tids);
+      if ($tids->value == array(-1)) {
+        return FALSE;
+      }
+
+      if (count($tids->value) > 1) {
+        $operator = 'IN';
+      }
+      else {
+        $operator = '=';
+      }
+
+      $tids = $tids->value;
+    }
+    else {
+      $operator = "=";
+      $tids = $this->argument;
+    }
+
+    // The tids variable can be an integer or an array of integers.
+    $tids = is_array($tids) ? $tids : array($tids);
+
+    if ($this->options['depth'] > 0) {
+      // When the depth is positive search the children.
+      foreach ($tids as $tid) {
+        // The term must be loaded to get vid for use in taxonomy_get_tree().
+        if ($term = taxonomy_term_load($tid)) {
+          // For every tid argument find all the children down to the depth set
+          // in the options and save the tids for the condition.
+          $tree = taxonomy_get_tree($term->vid, $term->tid, (int) $this->options['depth']);
+          $tids = array_merge($tids, array_map('_taxonomy_get_tid_from_term', $tree));
+        }
+      }
+    }
+    elseif ($this->options['depth'] < 0) {
+      // When the depth is negative search the parents.
+      foreach ($tids as $tid) {
+        // For every tid argument find all the parents up to the depth set
+        // in the options and add the tids into the array. Since there is
+        // no taxonomy function to get all parents with a depth limit it
+        // is done here building a multidimensional array.
+        if ($term = taxonomy_term_load($tid)) {
+          // A variable is needed to track the current depth level.
+          $n = 0;
+          // Initialise our depth based parents array with the leaf term.
+          $parents[$n--][] = $term;
+          while ($n >= $this->options['depth']) {
+            // At each depth find the parents of the current terms.
+            // It is important to note that it is possible for a term to have
+            // multiple parents so get the parents of every parent and so on.
+            $parents[$n] = array();
+            foreach ($parents[$n + 1] as $term) {
+              $parents[$n] += taxonomy_get_parents($term->tid);
+            }
+            // Save all the tids for the condition.
+            $tids = array_merge($tids, array_map('_taxonomy_get_tid_from_term', $parents[$n]));
+            $n--;
+          }
+        }
+      }
+    }
+
+    // Check the size of the array and set the operator accordingly.
+    if (count($tids) > 1) {
+      $operator = 'IN';
+    }
+    else {
+      $tids = current($tids);
+      $operator = '=';
+    }
+
+    // Join on taxonomy index table.
+    $join = new views_join();
+    $join->table = 'taxonomy_index';
+    $join->field = 'nid';
+    $join->left_table = $this->table_alias;
+    $join->left_field = $this->real_field;
+    $join->type = 'INNER';
+    $join->extra = array(
+      array(
+        'field' => 'tid',
+        'value' => $tids,
+        'operator' => $operator,
+      )
+    );
+    $taxonomy_index_alias = $this->query->add_relationship('taxonomy_index', $join, 'node');
+
+    // Distinct is required to prevent duplicate rows.
+    $this->query->distinct = TRUE;
+  }
+
+  function title() {
+    $term = taxonomy_term_load($this->argument);
+    if (!empty($term)) {
+      return check_plain($term->name);
+    }
+
+    return t('No name');
+  }
+}

+ 16 - 0
sites/all/modules/contrib/views/views/modules/taxonomy/views_handler_filter_term_node_tid.inc

@@ -206,6 +206,9 @@ class views_handler_filter_term_node_tid extends views_handler_filter_many_to_on
     if (empty($form_state['exposed'])) {
       // Retain the helper option
       $this->helper->options_form($form, $form_state);
+
+      // Show help text if not exposed to end users.
+      $form['value']['#description'] = t('Leave blank for all. Otherwise, the first selected term will be the default instead of "Any".');
     }
   }
 
@@ -228,12 +231,25 @@ class views_handler_filter_term_node_tid extends views_handler_filter_many_to_on
       return TRUE;
     }
 
+    // We need to know the operator, which is normally set in
+    // views_handler_filter::accept_exposed_input(), before we actually call
+    // the parent version of ourselves.
+    if (!empty($this->options['expose']['use_operator']) && !empty($this->options['expose']['operator_id']) && isset($input[$this->options['expose']['operator_id']])) {
+      $this->operator = $input[$this->options['expose']['operator_id']];
+    }
+
     // If view is an attachment and is inheriting exposed filters, then assume
     // exposed input has already been validated
     if (!empty($this->view->is_attachment) && $this->view->display_handler->uses_exposed()) {
       $this->validated_exposed_input = (array) $this->view->exposed_raw_input[$this->options['expose']['identifier']];
     }
 
+    // If we're checking for EMPTY or NOT, we don't need any input, and we can
+    // say that our input conditions are met by just having the right operator.
+    if ($this->operator == 'empty' || $this->operator == 'not empty') {
+      return TRUE;
+    }
+
     // If it's non-required and there's no value don't bother filtering.
     if (!$this->options['expose']['required'] && empty($this->validated_exposed_input)) {
       return FALSE;

+ 142 - 0
sites/all/modules/contrib/views/views/modules/taxonomy/views_handler_filter_term_node_tid_depth_join.inc

@@ -0,0 +1,142 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_filter_term_node_tid_depth_join.
+ */
+
+/**
+ * Filter handler for taxonomy terms with depth.
+ *
+ * This handler is actually part of the node table and has some restrictions,
+ * because it uses a subquery to find nodes with.
+ *
+ * @ingroup views_filter_handlers
+ */
+class views_handler_filter_term_node_tid_depth_join extends views_handler_filter_term_node_tid {
+  function operator_options($which = 'title') {
+    return array(
+      'or' => t('Is one of'),
+    );
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['depth'] = array('default' => 0);
+
+    return $options;
+  }
+
+  function extra_options_form(&$form, &$form_state) {
+    parent::extra_options_form($form, $form_state);
+
+    $form['depth'] = array(
+      '#type' => 'weight',
+      '#title' => t('Depth'),
+      '#default_value' => $this->options['depth'],
+      '#description' => t('The depth will match nodes tagged with terms in the hierarchy. For example, if you have the term "fruit" and a child term "apple", with a depth of 1 (or higher) then filtering for the term "fruit" will get nodes that are tagged with "apple" as well as "fruit". If negative, the reverse is true; searching for "apple" will also pick up nodes tagged with "fruit" if depth is -1 (or lower).'),
+    );
+  }
+
+  function query() {
+    // If no filter values are present, then do nothing.
+    if (count($this->value) == 0) {
+      return;
+    }
+    elseif (count($this->value) == 1) {
+      // Somethis $this->value is an array with a single element so convert it.
+      if (is_array($this->value)) {
+        $this->value = current($this->value);
+      }
+      $operator = '=';
+    }
+    else {
+      $operator = 'IN';# " IN (" . implode(', ', array_fill(0, sizeof($this->value), '%d')) . ")";
+    }
+
+    // The normal use of ensure_my_table() here breaks Views.
+    // So instead we trick the filter into using the alias of the base table.
+    // See http://drupal.org/node/271833
+    // If a relationship is set, we must use the alias it provides.
+    if (!empty($this->relationship)) {
+      $this->table_alias = $this->relationship;
+    }
+    // If no relationship, then use the alias of the base table.
+    elseif (isset($this->query->table_queue[$this->query->base_table]['alias'])) {
+      $this->table_alias = $this->query->table_queue[$this->query->base_table]['alias'];
+    }
+    // This should never happen, but if it does, we fail quietly.
+    else {
+      return;
+    }
+
+    // The tids variable can be an integer or an array of integers.
+    $tids = is_array($this->value) ?  $this->value : array($this->value);
+
+    if ($this->options['depth'] > 0) {
+      // When the depth is positive search the children.
+      foreach ($tids as $tid) {
+        // The term must be loaded to get vid for use in taxonomy_get_tree().
+        if ($term = taxonomy_term_load($tid)) {
+          // For every tid argument find all the children down to the depth set
+          // in the options and save the tids for the condition.
+          $tree = taxonomy_get_tree($term->vid, $term->tid, (int) $this->options['depth']);
+          $tids = array_merge($tids, array_map('_taxonomy_get_tid_from_term', $tree));
+        }
+      }
+    }
+    elseif ($this->options['depth'] < 0) {
+      // When the depth is negative search the parents.
+      foreach ($tids as $tid) {
+        // For every tid argument find all the parents up to the depth set
+        // in the options and add the tids into the array. Since there is
+        // no taxonomy function to get all parents with a depth limit it
+        // is done here building a multidimensional array.
+        if ($term = taxonomy_term_load($tid)) {
+          // A variable is needed to track the current depth level.
+          $n = 0;
+          // Initialise our depth based parents array with the leaf term.
+          $parents[$n--][] = $term;
+          while ($n >= $this->options['depth']) {
+            // At each depth find the parents of the current terms.
+            // It is important to note that it is possible for a term to have
+            // multiple parents so get the parents of every parent and so on.
+            $parents[$n] = array();
+            foreach ($parents[$n + 1] as $term) {
+              $parents[$n] += taxonomy_get_parents($term->tid);
+            }
+            // Save all the tids for the condition.
+            $tids = array_merge($tids, array_map('_taxonomy_get_tid_from_term', $parents[$n]));
+            $n--;
+          }
+        }
+      }
+    }
+
+    // Check the size of the array and set the operator accordingly.
+    if (count($tids) > 1) {
+      $operator = 'IN';
+    }
+    else {
+      $tids = current($tids);
+      $operator = '=';
+    }
+
+    // Join on taxonomy index table.
+    $join = new views_join();
+    $join->table = 'taxonomy_index';
+    $join->field = 'nid';
+    $join->left_table = $this->table_alias;
+    $join->left_field = $this->real_field;
+    $join->type = 'INNER';
+    $join->extra = array(
+      array(
+        'field' => 'tid',
+        'value' => $tids,
+        'operator' => $operator,
+      )
+    );
+    $taxonomy_index_alias = $this->query->add_relationship('taxonomy_index', $join, 'node');
+  }
+}

+ 3 - 3
sites/all/modules/contrib/views/views/modules/translation.views.inc

@@ -51,7 +51,7 @@ function translation_views_data_alter(&$data) {
     ),
   );
 
-  // The source translation.
+  // All translations.
   $data['node']['translation'] = array(
     'group' => t('Content translation'),
     'title' => t('Translations'),
@@ -62,7 +62,7 @@ function translation_views_data_alter(&$data) {
       'base' => 'node',
       'base field' => 'tnid',
       'relationship table' => 'node',
-      'relationship field' => 'nid',
+      'relationship field' => 'tnid',
       'handler' => 'views_handler_relationship_translation',
       'label' => t('Translations'),
     ),
@@ -78,7 +78,7 @@ function translation_views_data_alter(&$data) {
     ),
   );
 
-  // The source translation.
+  // Child translation.
   $data['node']['child_translation'] = array(
     'group' => t('Node translation'),
     'title' => t('Child translation'),

+ 8 - 0
sites/all/modules/contrib/views/views/modules/views.views.inc

@@ -99,6 +99,14 @@ function views_views_data() {
     );
   }
 
+  $data['views']['ctools_dropdown'] = array(
+    'title' => t('Dropdown links'),
+    'help' => t('Displays fields in a dropdown list, like on the views listing page.'),
+    'field' => array(
+      'handler' => 'views_handler_field_ctools_dropdown',
+    ),
+  );
+
   $data['views']['combine'] = array(
    'title' => t('Combine fields filter'),
     'help' => t('Combine two fields together and search by them.'),

+ 1 - 1
sites/all/modules/contrib/views/views/plugins/export_ui/views_ui.class.php

@@ -385,8 +385,8 @@ class views_ui extends ctools_export_ui {
     $output = parent::list_page($js, $input);
     if (is_string($output)) {
       $output = '<div id="views-ui-list-page">' . $output . '</div>';
-      return $output;
     }
+    return $output;
   }
 }
 

+ 1 - 1
sites/all/modules/contrib/views/views/plugins/views_plugin_argument_validate.inc

@@ -86,7 +86,7 @@ class views_plugin_argument_validate extends views_plugin {
   /**
    * Process the summary arguments for displaying.
    *
-   * Some plugins alter the argument so it uses something else interal.
+   * Some plugins alter the argument so it uses something else internally.
    * For example the user validation set's the argument to the uid,
    * for a faster query. But there are use cases where you want to use
    * the old value again, for example the summary.

+ 17 - 0
sites/all/modules/contrib/views/views/plugins/views_plugin_cache_time.inc

@@ -107,4 +107,21 @@ class views_plugin_cache_time extends views_plugin_cache {
       return CACHE_PERMANENT;
     }
   }
+
+  function cache_set($type) {
+    $lifespan = $this->get_lifespan($type);
+    if ($lifespan >= 0) {
+      parent::cache_set($type);
+    }
+  }
+
+  function cache_get($type) {
+    $lifespan = $this->get_lifespan($type);
+    if ($lifespan >= 0) {
+      return parent::cache_get($type);
+    }
+    else {
+      return FALSE;
+    }
+  }
 }

+ 50 - 14
sites/all/modules/contrib/views/views/plugins/views_plugin_display.inc

@@ -53,7 +53,7 @@ class views_plugin_display extends views_plugin {
           $this->extender[$extender] = $plugin;
         }
         else {
-          vpr('Invalid display extender @extender', array('@handler' => $extender));
+          vpr('Invalid display extender @extender', array('@extender' => $extender));
         }
       }
     }
@@ -739,7 +739,7 @@ class views_plugin_display extends views_plugin {
   function uses_link_display() { return !$this->has_path(); }
 
   /**
-   * Check to see if the display can put the exposed formin a block.
+   * Check to see if the display can put the exposed form in a block.
    *
    * By default, displays that do not have a path cannot disconnect
    * the exposed form and put it in a block, because the form has no
@@ -1150,7 +1150,7 @@ class views_plugin_display extends views_plugin {
       );
     }
 
-    $display_comment = check_plain(drupal_substr($this->get_option('display_comment'), 0, 10));
+    $display_comment = check_plain(views_ui_truncate($this->get_option('display_comment'), 80));
     $options['display_comment'] = array(
       'category' => 'other',
       'title' => t('Comment'),
@@ -1419,7 +1419,7 @@ class views_plugin_display extends views_plugin {
     }
     $form['#title'] = check_plain($this->display->display_title) . ': ';
 
-    // Set the 'section' to hilite on the form.
+    // 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.
@@ -1573,8 +1573,12 @@ class views_plugin_display extends views_plugin {
         $plugin = $this->get_plugin('access');
         $form['#title'] .= t('Access options');
         if ($plugin) {
-          $form['#help_topic'] = $plugin->definition['help topic'];
-          $form['#help_module'] = $plugin->definition['module'];
+          if (!empty($plugin->definition['help topic'])) {
+            $form['#help_topic'] = $plugin->definition['help topic'];
+          }
+          if (!empty($plugin->definition['module'])) {
+            $form['#help_module'] = $plugin->definition['module'];
+          }
 
           $form['access_options'] = array(
             '#tree' => TRUE,
@@ -1615,8 +1619,12 @@ class views_plugin_display extends views_plugin {
         $plugin = $this->get_plugin('cache');
         $form['#title'] .= t('Caching options');
         if ($plugin) {
-          $form['#help_topic'] = $plugin->definition['help topic'];
-          $form['#help_module'] = $plugin->definition['module'];
+          if (!empty($plugin->definition['help topic'])) {
+            $form['#help_topic'] = $plugin->definition['help topic'];
+          }
+          if (!empty($plugin->definition['module'])) {
+            $form['#help_module'] = $plugin->definition['module'];
+          }
 
           $form['cache_options'] = array(
             '#tree' => TRUE,
@@ -1635,11 +1643,10 @@ class views_plugin_display extends views_plugin {
         $form['#title'] .= t('Query options');
         $this->view->init_query();
         if ($this->view->query) {
-          if (isset($this->view->query->definition['help topic'])) {
+          if (!empty($this->view->query->definition['help topic'])) {
             $form['#help_topic'] = $this->view->query->definition['help topic'];
           }
-
-          if (isset($this->view->query->definition['module'])) {
+          if (!empty($this->view->query->definition['module'])) {
             $form['#help_module'] = $this->view->query->definition['module'];
           }
 
@@ -1734,8 +1741,10 @@ class views_plugin_display extends views_plugin {
         }
         $plugin = $this->get_plugin(empty($style) ? 'row' : 'style');
         if ($plugin) {
-          if (isset($plugin->definition['help topic'])) {
+          if (!empty($plugin->definition['help topic'])) {
             $form['#help_topic'] = $plugin->definition['help topic'];
+          }
+          if (!empty($plugin->definition['module'])) {
             $form['#help_module'] = $plugin->definition['module'];
           }
           $form[$form_state['section']] = array(
@@ -2117,7 +2126,12 @@ class views_plugin_display extends views_plugin {
         $plugin = $this->get_plugin('exposed_form');
         $form['#title'] .= t('Exposed form options');
         if ($plugin) {
-          $form['#help_topic'] = $plugin->definition['help topic'];
+          if (!empty($plugin->definition['help topic'])) {
+            $form['#help_topic'] = $plugin->definition['help topic'];
+          }
+          if (!empty($plugin->definition['module'])) {
+            $form['#help_module'] = $plugin->definition['module'];
+          }
 
           $form['exposed_form_options'] = array(
             '#tree' => TRUE,
@@ -2154,7 +2168,12 @@ class views_plugin_display extends views_plugin {
         $plugin = $this->get_plugin('pager');
         $form['#title'] .= t('Pager options');
         if ($plugin) {
-          $form['#help_topic'] = $plugin->definition['help topic'];
+          if (!empty($plugin->definition['help topic'])) {
+            $form['#help_topic'] = $plugin->definition['help topic'];
+          }
+          if (!empty($plugin->definition['module'])) {
+            $form['#help_module'] = $plugin->definition['module'];
+          }
 
           $form['pager_options'] = array(
             '#tree' => TRUE,
@@ -2556,6 +2575,23 @@ class views_plugin_display extends views_plugin {
           $url_options['query'] = $this->view->exposed_raw_input;
         }
         $theme = views_theme_functions('views_more', $this->view, $this->display);
+
+        $parsed_url = drupal_parse_url($path);
+        // Preserve the query string from url.
+        if (!empty($parsed_url['query'])) {
+          if (!empty($url_options['query'])) {
+            $url_options['query'] = array_merge($parsed_url['query'], $url_options['query']);
+          }
+          else {
+            $url_options['query'] = $parsed_url['query'];
+          }
+          $path = $parsed_url['path'];
+        }
+        // Add fragment if applicable.
+        if (!empty($parsed_url['fragment'])) {
+          $url_options['fragment'] = $parsed_url['fragment'];
+        }
+
         $path = check_url(url($path, $url_options));
 
         return theme($theme, array('more_url' => $path, 'link_text' => check_plain($this->use_more_text()), 'view' => $this->view));

+ 2 - 2
sites/all/modules/contrib/views/views/plugins/views_plugin_display_block.inc

@@ -222,8 +222,8 @@ class views_plugin_display_block extends views_plugin_display {
   }
 
   /**
-   * Save the block cache setting in the blocks table if this block allready
-   * exists in the blocks table. Dirty fix untill http://drupal.org/node/235673 gets in.
+   * Save the block cache setting in the blocks table if this block already
+   * exists in the blocks table. Dirty fix until http://drupal.org/node/235673 gets in.
    */
   function save_block_cache($delta, $cache_setting) {
     if (strlen($delta) >= 32) {

+ 32 - 9
sites/all/modules/contrib/views/views/plugins/views_plugin_query_default.inc

@@ -143,7 +143,7 @@ class views_plugin_query_default extends views_plugin_query {
     );
 
 /**
- * -- we no longer want the base field to appear automatigically.
+ * -- we no longer want the base field to appear automatically.
     if ($base_field) {
       $this->fields[$base_field] = array(
         'table' => $base_table,
@@ -888,7 +888,7 @@ class views_plugin_query_default extends views_plugin_query {
   /**
    * Add a complex WHERE clause to the query.
    *
-   * The caller is reponsible for ensuring that all fields are fully qualified
+   * The caller is responsible for ensuring that all fields are fully qualified
    * (TABLE.FIELD) and that the table already exists in the query.
    * Internally the dbtng method "where" is used.
    *
@@ -1592,7 +1592,7 @@ class views_plugin_query_default extends views_plugin_query {
           'sort' => 'views_handler_sort_group_by_numeric',
         ),
       )
-    );
+    ) + views_fetch_plugin_data('query_aggregate');
   }
 
   /**
@@ -1620,7 +1620,8 @@ class views_plugin_query_default extends views_plugin_query {
     }
     $entity_type = $table_data['table']['entity type'];
     $info = entity_get_info($entity_type);
-    $id_alias = $this->get_field_alias($base_table_alias, $info['entity keys']['id']);
+    $is_revision = !empty($table_data['table']['revision']);
+    $id_alias = $this->get_field_alias($base_table_alias, $info['entity keys'][$is_revision ? 'revision' : 'id']);
 
     // Assemble the ids of the entities to load.
     $ids = array();
@@ -1630,12 +1631,34 @@ class views_plugin_query_default extends views_plugin_query {
       }
     }
 
-    $entities = entity_load($entity_type, $ids);
-    // Re-key the array by row-index.
-    $result = array();
-    foreach ($ids as $key => $id) {
-      $result[$key] = isset($entities[$id]) ? $entities[$id] : FALSE;
+    if (!$is_revision) {
+      $entities = entity_load($entity_type, $ids);
+
+      // Re-key the array by row-index.
+      $result = array();
+      foreach ($ids as $key => $id) {
+        $result[$key] = isset($entities[$id]) ? $entities[$id] : FALSE;
+      }
+    }
+    else {
+      // There's no way in core to load revisions in bulk.
+      $result = array();
+      foreach ($ids as $key => $id) {
+        // Nodes can be dealt with in core.
+        if ($entity_type == 'node') {
+          $result[$key] = node_load(NULL, $id);
+        }
+        // Otherwise see if entity is enabled.
+        elseif (module_exists('entity')) {
+          $result[$key] = entity_revision_load($entity_type, $id);
+        }
+        else {
+          // Otherwise this isn't supported.
+          watchdog('views', 'Attempt to load a revision on an unsupported entity type @entity_type.', array('@entity_type' => $entity_type), WATCHDOG_WARNING);
+        }
+      }
     }
+
     return array($entity_type, $result);
   }
 }

+ 17 - 7
sites/all/modules/contrib/views/views/plugins/views_plugin_style.inc

@@ -123,13 +123,23 @@ class views_plugin_style extends views_plugin {
   function get_row_class($row_index) {
     if ($this->uses_row_class()) {
       $class = $this->options['row_class'];
+
       if ($this->uses_fields() && $this->view->field) {
-        $class = strip_tags($this->tokenize_value($class, $row_index));
+        $classes = array();
+
+        // Explode the value by whitespace, this allows the function to handle
+        // a single class name and multiple class names that are then tokenized.
+        foreach(explode(' ', $class) as $token_class) {
+          $classes[] = strip_tags($this->tokenize_value($token_class, $row_index));
+        }
+      }
+      else {
+        $classes = explode(' ', $class);
       }
 
-      $classes = explode(' ', $class);
+      // Convert whatever the result is to a nice clean class name
       foreach ($classes as &$class) {
-        $class = drupal_clean_css_identifier($class);
+        $class = drupal_html_class($class);
       }
       return implode(' ', $classes);
     }
@@ -182,7 +192,7 @@ class views_plugin_style extends views_plugin {
   function options_form(&$form, &$form_state) {
     parent::options_form($form, $form_state);
     // Only fields-based views can handle grouping.  Style plugins can also exclude
-    // themselves from being groupable by setting their "use grouping" definiton
+    // themselves from being groupable by setting their "use grouping" definition
     // key to FALSE.
     // @TODO: Document "uses grouping" in docs.php when docs.php is written.
     if ($this->uses_fields() && $this->definition['uses grouping']) {
@@ -191,7 +201,7 @@ class views_plugin_style extends views_plugin {
       $options += $field_labels;
       // If there are no fields, we can't group on them.
       if (count($options) > 1) {
-        // This is for backward compability, when there was just a single select form.
+        // This is for backward compatibility, when there was just a single select form.
         if (is_string($this->options['grouping'])) {
           $grouping = $this->options['grouping'];
           $this->options['grouping'] = array();
@@ -419,7 +429,7 @@ class views_plugin_style extends views_plugin {
    *   @endcode
    */
   function render_grouping($records, $groupings = array(), $group_rendered = NULL) {
-    // This is for backward compability, when $groupings was a string containing
+    // This is for backward compatibility, when $groupings was a string containing
     // the ID of a single field.
     if (is_string($groupings)) {
       $rendered = $group_rendered === NULL ? TRUE : $group_rendered;
@@ -486,7 +496,7 @@ class views_plugin_style extends views_plugin {
       );
     }
 
-    // If this parameter isn't explicitely set modify the output to be fully
+    // If this parameter isn't explicitly set modify the output to be fully
     // backward compatible to code before Views 7.x-3.0-rc2.
     // @TODO Remove this as soon as possible e.g. October 2020
     if ($group_rendered === NULL) {

+ 34 - 1
sites/all/modules/contrib/views/views/plugins/views_plugin_style_rss.inc

@@ -71,6 +71,36 @@ class views_plugin_style_rss extends views_plugin_style {
     return array();
   }
 
+  /**
+   * Return an atom:link XHTML element to add to the channel to comply with
+   * the RSS 2.0 specification.
+   *
+   * @see http://validator.w3.org/feed/docs/warning/MissingAtomSelfLink.html
+   *
+   * @return
+   *   An array that can be passed to format_xml_elements().
+   */
+  function get_channel_elements_atom_link() {
+    $url_options = array('absolute' => TRUE);
+    $input = $this->view->get_exposed_input();
+    if ($input) {
+      $url_options['query'] = $input;
+    }
+    $url = url($this->view->get_url(), $url_options);
+
+    return array(
+      array(
+        'namespace' => array('xmlns:atom' => 'http://www.w3.org/2005/Atom'),
+        'key' => 'atom:link',
+        'attributes' => array(
+          'href' => $url,
+          'rel' => 'self',
+          'type' => 'application/rss+xml',
+        ),
+      ),
+    );
+  }
+
   /**
    * Get RSS feed description.
    *
@@ -99,7 +129,10 @@ class views_plugin_style_rss extends views_plugin_style {
 
     // Fetch any additional elements for the channel and merge in their
     // namespaces.
-    $this->channel_elements = $this->get_channel_elements();
+    $this->channel_elements = array_merge(
+      $this->get_channel_elements(),
+      $this->get_channel_elements_atom_link()
+    );
     foreach ($this->channel_elements as $element) {
       if (isset($element['namespace'])) {
         $this->namespaces = array_merge($this->namespaces, $element['namespace']);

+ 11 - 0
sites/all/modules/contrib/views/views/test_templates/README.txt

@@ -0,0 +1,11 @@
+Workaround for:
+
+- https://www.drupal.org/node/2450447
+- https://www.drupal.org/node/2415991
+
+
+Files of this folder cannot be included inside the views/tests directory because
+they are included as tests cases and make testbot crash.
+
+This files could be moved to tests/templates once
+https://www.drupal.org/node/2415991 be properly fixed.

+ 0 - 0
sites/all/modules/contrib/views/views/tests/templates/views-view--frontpage.tpl.php → sites/all/modules/contrib/views/views/test_templates/views-view--frontpage.tpl.php


+ 2 - 2
sites/all/modules/contrib/views/views/tests/styles/views_plugin_style.test

@@ -241,7 +241,7 @@ class ViewsPluginStyleTestCase extends ViewsPluginStyleTestBase {
     // Setup some random css class.
     $view->init_display();
     $view->init_style();
-    $random_name = $this->randomName();
+    $random_name = drupal_html_class($this->randomName());
     $view->style_plugin->options['row_class'] = $random_name . " test-token-[name]";
 
     $rendered_output = $view->preview();
@@ -255,7 +255,7 @@ class ViewsPluginStyleTestCase extends ViewsPluginStyleTestBase {
       $this->assertTrue(strpos($class, $random_name) !== FALSE, 'Take sure that a custom css class is added to the output.');
 
       // Check token replacement.
-      $name = $view->field['name']->get_value($view->result[$count]);
+      $name = drupal_html_class($view->field['name']->get_value($view->result[$count]));
       $this->assertTrue(strpos($class, "test-token-$name") !== FALSE, 'Take sure that a token in custom css class is replaced.');
 
       $count++;

+ 0 - 1
sites/all/modules/contrib/views/views/tests/views_query.test

@@ -132,7 +132,6 @@ abstract class ViewsSqlTest extends ViewsTestCase {
     variable_set('views_test_schema', $this->schemaDefinition());
     variable_set('views_test_views_data', $this->viewsData());
     variable_set('views_test_views_plugins', $this->viewsPlugins());
-
     module_enable(array('views_test'));
     $this->resetAll();
 

+ 3 - 3
sites/all/modules/contrib/views/views/tests/views_test.info

@@ -5,9 +5,9 @@ core = 7.x
 dependencies[] = views
 hidden = TRUE
 
-; Information added by Drupal.org packaging script on 2015-04-29
-version = "7.x-3.11"
+; Information added by Drupal.org packaging script on 2016-06-15
+version = "7.x-3.14"
 core = "7.x"
 project = "views"
-datestamp = "1430321048"
+datestamp = "1466019588"
 

+ 1 - 1
sites/all/modules/contrib/views/views/tests/views_test.module

@@ -23,7 +23,7 @@ function views_test_permission() {
 function views_test_views_api() {
   return array(
     'api' => 3.0,
-    'template path' => drupal_get_path('module', 'views_test') . '/templates',
+    'template path' => drupal_get_path('module', 'views') . '/test_templates',
   );
 }
 

+ 1 - 1
sites/all/modules/contrib/views/views/theme/views-view-table.tpl.php

@@ -27,7 +27,7 @@
     <thead>
       <tr>
         <?php foreach ($header as $field => $label): ?>
-          <th <?php if ($header_classes[$field]) { print 'class="'. $header_classes[$field] . '" '; } ?>>
+          <th <?php if ($header_classes[$field]) { print 'class="'. $header_classes[$field] . '" '; } ?> scope="col">
             <?php print $label; ?>
           </th>
         <?php endforeach; ?>

+ 34 - 8
sites/all/modules/contrib/views/views/views.api.php

@@ -143,7 +143,7 @@
  * responsible for building the query. Instead, they are objects that are used
  * to display the view or make other modifications.
  *
- * There are 10 types of plugins in Views:
+ * There are several types of plugins in Views:
  * - Display: Display plugins are responsible for controlling *where* a view
  *   lives; that is, how they are being exposed to other parts of Drupal. Page
  *   and block are the most common displays, as well as the ubiquitous 'master'
@@ -431,7 +431,7 @@ function hook_views_data() {
       'label' => t('Published'),
       // This setting is used by the boolean filter handler, as possible option.
       'type' => 'yes-no',
-      // use boolean_field = 1 instead of boolean_field <> 0 in WHERE statment.
+      // use boolean_field = 1 instead of boolean_field <> 0 in WHERE statement.
       'use equal' => TRUE,
     ),
     'sort' => array(
@@ -602,7 +602,7 @@ function hook_field_views_data_views_data_alter(&$data, $field) {
  *   must be one of row, display, display_extender, style, argument default,
  *   argument validator, access, query, cache, pager, exposed_form or
  *   localization. The plugin name should be prefixed with your module name.
- *   The value for each entry is an associateive array that may contain the
+ *   The value for each entry is an associative array that may contain the
  *   following entries:
  *   - Used by all plugin types:
  *     - title (required): The name of the plugin, as shown in Views. Wrap in
@@ -723,7 +723,7 @@ function hook_views_plugins_alter(&$plugins) {
  *   - 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 files. When you have specificed this key views automatically
+ *     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.
  */
@@ -859,7 +859,7 @@ function hook_views_default_views_alter(&$views) {
  *   The View being executed.
  * @return
  *   An array with keys being the strings to replace, and the values the strings
- *   to replace them with. The strings to replace are ofted surrounded with
+ *   to replace them with. The strings to replace are often surrounded with
  *   '***', as illustrated in the example implementation.
  */
 function hook_views_query_substitutions($view) {
@@ -924,7 +924,7 @@ function hook_views_pre_view(&$view, &$display_id, &$args) {
  *   The view object about to be processed.
  */
 function hook_views_pre_build(&$view) {
-  // Because of some unexplicable business logic, we should remove all
+  // Because of some inexplicable business logic, we should remove all
   // attachments from all views on Mondays.
   // (This alter could be done later in the execution process as well.)
   if (date('D') == 'Mon') {
@@ -1153,8 +1153,8 @@ function hook_views_ajax_data_alter(&$commands, $view) {
   // Replace Views' method for scrolling to the top of the element with your
   // custom scrolling method.
   foreach ($commands as &$command) {
-    if ($command['method'] == 'viewsScrollTop') {
-      $command['method'] .= 'myScrollTop';
+    if ($command['command'] == 'viewsScrollTop') {
+      $command['command'] .= 'myScrollTop';
     }
   }
 }
@@ -1171,6 +1171,32 @@ function hook_views_invalidate_cache() {
   cache_clear_all('views:*', 'cache_mymodule', TRUE);
 }
 
+/**
+ * Allow modules to alter a view prior to being saved.
+ */
+function hook_views_view_presave($view) {
+  // Do some adjustments to the view. Handle with care.
+  if (mymodule_check_view($view)) {
+    mymodule_do_some_voodoo($view);
+  }
+}
+
+/**
+ * Allow modules to respond to a view being saved.
+ */
+function hook_views_view_save($view) {
+  // Make a watchdog entry.
+  watchdog('views', 'The view @name was deleted by @user at @time', array('@name' => $view->name, '@user' => $GLOBALS['user']->name, '@time' => format_date(time())));
+}
+
+/**
+ * Allow modules to respond to a view being deleted or reverted.
+ */
+function hook_views_view_delete($view) {
+  // Make a watchdog entry.
+  watchdog('views', 'The view @name was deleted by @user at @time', array('@name' => $view->name, '@user' => $GLOBALS['user']->name, '@time' => format_date(time())));
+}
+
 /**
  * @}
  */

+ 13 - 3
sites/all/modules/contrib/views/views/views.info

@@ -27,9 +27,11 @@ files[] = handlers/views_handler_field.inc
 files[] = handlers/views_handler_field_counter.inc
 files[] = handlers/views_handler_field_boolean.inc
 files[] = handlers/views_handler_field_contextual_links.inc
+files[] = handlers/views_handler_field_ctools_dropdown.inc
 files[] = handlers/views_handler_field_custom.inc
 files[] = handlers/views_handler_field_date.inc
 files[] = handlers/views_handler_field_entity.inc
+files[] = handlers/views_handler_field_links.inc
 files[] = handlers/views_handler_field_markup.inc
 files[] = handlers/views_handler_field_math.inc
 files[] = handlers/views_handler_field_numeric.inc
@@ -116,6 +118,7 @@ files[] = modules/locale/views_handler_field_locale_link_edit.inc
 files[] = modules/locale/views_handler_filter_locale_group.inc
 files[] = modules/locale/views_handler_filter_locale_language.inc
 files[] = modules/locale/views_handler_filter_locale_version.inc
+files[] = modules/locale/views_handler_sort_node_language.inc
 files[] = modules/node/views_handler_argument_dates_various.inc
 files[] = modules/node/views_handler_argument_node_language.inc
 files[] = modules/node/views_handler_argument_node_nid.inc
@@ -133,11 +136,14 @@ files[] = modules/node/views_handler_field_node_revision_link_delete.inc
 files[] = modules/node/views_handler_field_node_revision_link_revert.inc
 files[] = modules/node/views_handler_field_node_path.inc
 files[] = modules/node/views_handler_field_node_type.inc
+files[] = modules/node/views_handler_field_node_version_count.inc
 files[] = modules/node/views_handler_filter_history_user_timestamp.inc
 files[] = modules/node/views_handler_filter_node_access.inc
 files[] = modules/node/views_handler_filter_node_status.inc
 files[] = modules/node/views_handler_filter_node_type.inc
 files[] = modules/node/views_handler_filter_node_uid_revision.inc
+files[] = modules/node/views_handler_filter_node_version_count.inc
+files[] = modules/node/views_handler_sort_node_version_count.inc
 files[] = modules/node/views_plugin_argument_default_node.inc
 files[] = modules/node/views_plugin_argument_validate_node.inc
 files[] = modules/node/views_plugin_row_node_rss.inc
@@ -151,6 +157,8 @@ files[] = modules/search/views_handler_filter_search.inc
 files[] = modules/search/views_handler_sort_search_score.inc
 files[] = modules/search/views_plugin_row_search_view.inc
 files[] = modules/statistics/views_handler_field_accesslog_path.inc
+files[] = modules/statistics/views_handler_field_node_counter_timestamp.inc
+files[] = modules/statistics/views_handler_field_statistics_numeric.inc
 files[] = modules/system/views_handler_argument_file_fid.inc
 files[] = modules/system/views_handler_field_file.inc
 files[] = modules/system/views_handler_field_file_extension.inc
@@ -161,6 +169,7 @@ files[] = modules/system/views_handler_filter_file_status.inc
 files[] = modules/taxonomy/views_handler_argument_taxonomy.inc
 files[] = modules/taxonomy/views_handler_argument_term_node_tid.inc
 files[] = modules/taxonomy/views_handler_argument_term_node_tid_depth.inc
+files[] = modules/taxonomy/views_handler_argument_term_node_tid_depth_join.inc
 files[] = modules/taxonomy/views_handler_argument_term_node_tid_depth_modifier.inc
 files[] = modules/taxonomy/views_handler_argument_vocabulary_vid.inc
 files[] = modules/taxonomy/views_handler_argument_vocabulary_machine_name.inc
@@ -169,6 +178,7 @@ files[] = modules/taxonomy/views_handler_field_term_node_tid.inc
 files[] = modules/taxonomy/views_handler_field_term_link_edit.inc
 files[] = modules/taxonomy/views_handler_filter_term_node_tid.inc
 files[] = modules/taxonomy/views_handler_filter_term_node_tid_depth.inc
+files[] = modules/taxonomy/views_handler_filter_term_node_tid_depth_join.inc
 files[] = modules/taxonomy/views_handler_filter_vocabulary_vid.inc
 files[] = modules/taxonomy/views_handler_filter_vocabulary_machine_name.inc
 files[] = modules/taxonomy/views_handler_relationship_node_term_data.inc
@@ -318,9 +328,9 @@ files[] = tests/views_cache.test
 files[] = tests/views_view.test
 files[] = tests/views_ui.test
 
-; Information added by Drupal.org packaging script on 2015-04-29
-version = "7.x-3.11"
+; Information added by Drupal.org packaging script on 2016-06-15
+version = "7.x-3.14"
 core = "7.x"
 project = "views"
-datestamp = "1430321048"
+datestamp = "1466019588"
 

+ 15 - 1
sites/all/modules/contrib/views/views/views.install

@@ -402,7 +402,7 @@ function views_update_6008() {
 }
 
 /**
- * Enlarge the views_display.display_options field to accomodate a larger set
+ * Enlarge the views_display.display_options field to accommodate a larger set
  * of configurations (e. g. fields, filters, etc.) on a display.
  */
 function views_schema_6009() {
@@ -631,3 +631,17 @@ function views_update_7301() {
   );
   db_change_field('views_view', 'name', 'name', $new_field);
 }
+
+/**
+ * Remove headers field from cache tables
+ *
+ * @see system_update_7054().
+ */
+function views_update_7302() {
+  if (db_field_exists('cache_views', 'headers')) {
+    db_drop_field('cache_views', 'headers');
+  }
+  if (db_field_exists('cache_views_data', 'headers')) {
+    db_drop_field('cache_views_data', 'headers');
+  }
+}

+ 17 - 4
sites/all/modules/contrib/views/views/views.module

@@ -1020,8 +1020,21 @@ function views_access() {
  * permissions. If the $account argument is omitted, the current user
  * is used.
  */
-function views_check_perm($perm, $account = NULL) {
-  return user_access($perm, $account) || user_access('access all views', $account);
+function views_check_perm($perms, $account = NULL) {
+  // Backward compatibility to ensure also a single permission string is
+  // properly processed.
+  $perms = is_array($perms) ? $perms : array($perms);
+  if (user_access('access all views', $account)) {
+    return TRUE;
+  }
+  // Perms are handled as OR, as soon one permission allows access TRUE is
+  // returned.
+  foreach ($perms as $perm) {
+    if (user_access($perm, $account)) {
+      return TRUE;
+    }
+  }
+  return FALSE;
 }
 
 /**
@@ -1298,7 +1311,7 @@ function views_fetch_plugin_data($type = NULL, $plugin = NULL, $reset = FALSE) {
  *   Either 'display', 'style' or 'row'
  * @param $key
  *   For style plugins, this is an optional type to restrict to. May be 'normal',
- *   'summary', 'feed' or others based on the neds of the display.
+ *   'summary', 'feed' or others based on the needs of the display.
  * @param $base
  *   An array of possible base tables.
  *
@@ -2413,7 +2426,7 @@ function views_process_check_options($element, &$form_state) {
  * Trim the field down to the specified length.
  *
  * @param $alter
- *   - max_length: Maximum lenght of the string, the rest gets truncated.
+ *   - max_length: Maximum length of the string, the rest gets truncated.
  *   - word_boundary: Trim only on a word boundary.
  *   - ellipsis: Show an ellipsis (...) at the end of the trimmed string.
  *   - html: Take sure that the html is correct.

+ 3 - 3
sites/all/modules/contrib/views/views/views_ui.info

@@ -7,9 +7,9 @@ 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 2015-04-29
-version = "7.x-3.11"
+; Information added by Drupal.org packaging script on 2016-06-15
+version = "7.x-3.14"
 core = "7.x"
 project = "views"
-datestamp = "1430321048"
+datestamp = "1466019588"
 

+ 1 - 1
sites/all/modules/contrib/views/views/views_ui.module

@@ -248,7 +248,7 @@ function views_ui_theme() {
 }
 
 /**
- * Impements hook_custom_theme()
+ * Implements hook_custom_theme().
  */
 function views_ui_custom_theme() {
   $theme = variable_get('views_ui_custom_theme', '_default');