Browse Source

more module updates

Bachir Soussi Chiadmi 9 years ago
parent
commit
cde7b73a73
39 changed files with 657 additions and 255 deletions
  1. 31 0
      sites/all/modules/contrib/admin/token/README.txt
  2. 3 3
      sites/all/modules/contrib/admin/token/tests/token_test.info
  3. 3 3
      sites/all/modules/contrib/admin/token/token.info
  4. 19 9
      sites/all/modules/contrib/admin/token/token.module
  5. 6 1
      sites/all/modules/contrib/admin/token/token.pages.inc
  6. 4 0
      sites/all/modules/contrib/admin/token/token.test
  7. 2 0
      sites/all/modules/contrib/files/transliteration/data/x00.php
  8. 10 0
      sites/all/modules/contrib/files/transliteration/data/x04.php
  9. 1 1
      sites/all/modules/contrib/files/transliteration/data/x5b.php
  10. 1 1
      sites/all/modules/contrib/files/transliteration/data/x5e.php
  11. 1 1
      sites/all/modules/contrib/files/transliteration/data/x91.php
  12. 5 0
      sites/all/modules/contrib/files/transliteration/transliteration.admin.inc
  13. 3 3
      sites/all/modules/contrib/files/transliteration/transliteration.info
  14. 10 0
      sites/all/modules/contrib/files/transliteration/transliteration.install
  15. 36 0
      sites/all/modules/contrib/files/transliteration/transliteration.module
  16. 9 1
      sites/all/modules/contrib/mail/views_send/CHANGELOG.txt
  17. 1 1
      sites/all/modules/contrib/mail/views_send/README.txt
  18. 0 26
      sites/all/modules/contrib/mail/views_send/mailsystem-integration-2023977-7.patch
  19. 3 3
      sites/all/modules/contrib/mail/views_send/views_send.info
  20. 112 39
      sites/all/modules/contrib/mail/views_send/views_send.module
  21. 6 2
      sites/all/modules/contrib/search/search_api_saved_searches/CHANGELOG.txt
  22. 20 0
      sites/all/modules/contrib/search/search_api_saved_searches/search_api_saved_searches.api.php
  23. 3 3
      sites/all/modules/contrib/search/search_api_saved_searches/search_api_saved_searches.info
  24. 66 5
      sites/all/modules/contrib/search/search_api_saved_searches/search_api_saved_searches.module
  25. 4 1
      sites/all/modules/contrib/search/search_api_saved_searches/search_api_saved_searches.pages.inc
  26. 3 3
      sites/all/modules/contrib/search/search_api_saved_searches/search_api_saved_searches_i18n/search_api_saved_searches_i18n.info
  27. 12 0
      sites/all/modules/contrib/views/views_bulk_operations/actions/delete.action.inc
  28. 79 42
      sites/all/modules/contrib/views/views_bulk_operations/actions/modify.action.inc
  29. 3 3
      sites/all/modules/contrib/views/views_bulk_operations/actions_permissions.info
  30. 4 2
      sites/all/modules/contrib/views/views_bulk_operations/plugins/operation_types/action.class.php
  31. 3 1
      sites/all/modules/contrib/views/views_bulk_operations/plugins/operation_types/base.class.php
  32. 24 1
      sites/all/modules/contrib/views/views_bulk_operations/views/views_bulk_operations_handler_field_operations.inc
  33. 4 3
      sites/all/modules/contrib/views/views_bulk_operations/views_bulk_operations.info
  34. 145 85
      sites/all/modules/contrib/views/views_bulk_operations/views_bulk_operations.module
  35. 7 7
      sites/all/modules/contrib/views/views_bulk_operations/views_bulk_operations.rules.inc
  36. 2 2
      sites/all/modules/contrib/views/views_php/plugins/views/views_php_plugin_access.inc
  37. 7 0
      sites/all/modules/contrib/views/views_php/plugins/views/views_php_plugin_cache.inc
  38. 3 3
      sites/all/modules/contrib/views/views_php/views_php.info
  39. 2 0
      sites/all/modules/contrib/views/views_php/views_php.views.inc

+ 31 - 0
sites/all/modules/contrib/admin/token/README.txt

@@ -1,2 +1,33 @@
+INTRODUCTION
+------------
 
 Provides common and resuable token UI elements and missing core tokens.
+
+ * For a full description of the module, visit the project page:
+   https://drupal.org/project/token
+
+ * To submit bug reports and feature suggestions, or to track changes:
+   https://drupal.org/project/issues/token
+
+
+INSTALLATION
+------------
+
+Install as usual, see
+https://drupal.org/documentation/install/modules-themes/modules-7 for further
+information.
+
+
+TROUBLESHOOTING
+---------------
+
+Token module doesn't provide any visible functions to the user on its own, it
+just provides token handling services for other modules.
+
+
+MAINTAINERS
+-----------
+
+Current maintainers:
+
+ * Dave Reid (https://drupal.org/user/53892)

+ 3 - 3
sites/all/modules/contrib/admin/token/tests/token_test.info

@@ -5,9 +5,9 @@ core = 7.x
 files[] = token_test.module
 hidden = TRUE
 
-; Information added by drupal.org packaging script on 2013-02-24
-version = "7.x-1.5"
+; Information added by Drupal.org packaging script on 2015-02-28
+version = "7.x-1.6"
 core = "7.x"
 project = "token"
-datestamp = "1361665026"
+datestamp = "1425149060"
 

+ 3 - 3
sites/all/modules/contrib/admin/token/token.info

@@ -3,9 +3,9 @@ description = Provides a user interface for the Token API and some missing core
 core = 7.x
 files[] = token.test
 
-; Information added by drupal.org packaging script on 2013-02-24
-version = "7.x-1.5"
+; Information added by Drupal.org packaging script on 2015-02-28
+version = "7.x-1.6"
 core = "7.x"
 project = "token"
-datestamp = "1361665026"
+datestamp = "1425149060"
 

+ 19 - 9
sites/all/modules/contrib/admin/token/token.module

@@ -180,7 +180,7 @@ function token_theme() {
       'text' => NULL,
       'options' => array(),
       'dialog' => TRUE,
-    ),
+    ) + $info['token_tree']['variables'],
     'file' => 'token.pages.inc',
   );
 
@@ -273,8 +273,8 @@ function token_form_block_admin_configure_alter(&$form, $form_state) {
  * Implements hook_widget_form_alter().
  */
 function token_field_widget_form_alter(&$element, &$form_state, $context) {
-  if (!empty($element['#description']) && is_string($element['#description'])) {
-    $element['#description'] = filter_xss_admin(token_replace($element['#description']));
+  if (!empty($element['#description']) && !empty($context['instance']['description'])) {
+    $element['#description'] = filter_xss_admin(token_replace($context['instance']['description']));
   }
 }
 
@@ -412,12 +412,18 @@ function token_get_entity_mapping($value_type = 'token', $value = NULL, $fallbac
  */
 function token_entity_info_alter(&$info) {
   foreach (array_keys($info) as $entity_type) {
-    // Add a token view mode if it does not already exist.
-    if (!empty($info[$entity_type]['view modes']) && !isset($info[$entity_type]['view modes']['token'])) {
-      $info[$entity_type]['view modes']['token'] = array(
-        'label' => t('Tokens'),
-        'custom settings' => FALSE,
-      );
+    // Add a token view mode if it does not already exist. Only work with
+    // fieldable entities.
+    if (!empty($info[$entity_type]['fieldable'])) {
+      if (!isset($info[$entity_type])) {
+        $info[$entity_type]['view modes'] = array();
+      }
+      if (!isset($info[$entity_type]['view modes']['token'])) {
+        $info[$entity_type]['view modes']['token'] = array(
+          'label' => t('Tokens'),
+          'custom settings' => FALSE,
+        );
+      }
     }
 
     if (!empty($info[$entity_type]['token type'])) {
@@ -647,6 +653,10 @@ function token_get_invalid_tokens($type, $tokens) {
   $invalid_tokens = array();
 
   foreach ($tokens as $token => $full_token) {
+    if (isset($token_info['tokens'][$type][$token])) {
+      continue;
+    }
+
     // Split token up if it has chains.
     $parts = explode(':', $token, 2);
 

+ 6 - 1
sites/all/modules/contrib/admin/token/token.pages.inc

@@ -19,7 +19,12 @@ function theme_token_tree_link($variables) {
   }
 
   $info = token_theme();
-  $variables['options']['query']['options'] = array_intersect_key($variables, $info['token_tree']['variables']);
+  $tree_variables = array_intersect_key($variables, $info['token_tree']['variables']);
+  $tree_variables = drupal_array_diff_assoc_recursive($tree_variables, $info['token_tree']['variables']);
+  if (!isset($variables['options']['query']['options'])) {
+    $variables['options']['query']['options'] = array();
+  }
+  $variables['options']['query']['options'] += $tree_variables;
 
   // We should never pass the dialog option to theme_token_tree(). It is only
   // used for this function.

+ 4 - 0
sites/all/modules/contrib/admin/token/token.test

@@ -137,6 +137,7 @@ class TokenUnitTestCase extends TokenTestHelper {
         '[node:created:short]',
         '[node:created:custom:invalid]',
         '[node:created:custom:mm-YYYY]',
+        '[node:colons:in:name]',
         '[site:name]',
         '[site:slogan]',
         '[current-date:short]',
@@ -147,6 +148,7 @@ class TokenUnitTestCase extends TokenTestHelper {
         '[node:title:invalid]',
         '[node:created:invalid]',
         '[node:created:short:invalid]',
+        '[node:colons:in:name:invalid]',
         '[invalid:title]',
         '[site:invalid]',
         '[user:ip-address]',
@@ -166,6 +168,7 @@ class TokenUnitTestCase extends TokenTestHelper {
         '[node:created:short]',
         '[node:created:custom:invalid]',
         '[node:created:custom:mm-YYYY]',
+        '[node:colons:in:name]',
         '[site:name]',
         '[site:slogan]',
         '[user:uid]',
@@ -176,6 +179,7 @@ class TokenUnitTestCase extends TokenTestHelper {
         '[node:title:invalid]',
         '[node:created:invalid]',
         '[node:created:short:invalid]',
+        '[node:colons:in:name:invalid]',
         '[invalid:title]',
         '[site:invalid]',
         '[user:ip-address]',

+ 2 - 0
sites/all/modules/contrib/files/transliteration/data/x00.php

@@ -15,8 +15,10 @@ $base = array(
 // Overrides for Danish input.
 $variant['da'] = array(
   0xC5 => 'Aa',
+  0xC6 => 'Ae',
   0xD8 => 'Oe',
   0xE5 => 'aa',
+  0xE6 => 'ae',
   0xF8 => 'oe',
 );
 

+ 10 - 0
sites/all/modules/contrib/files/transliteration/data/x04.php

@@ -44,3 +44,13 @@ $variant['kg'] = array(
   0xE8 => 'Q',
   0xE9 => 'q',
 );
+
+// Overrides for Ukrainian input.
+$variant['uk'] = array(
+  0x90 => 'G',
+  0x91 => 'g',
+  0x04 => 'YE',
+  0x54 => 'ye',
+  0x18 => 'Y',
+  0x38 => 'y',
+);

+ 1 - 1
sites/all/modules/contrib/files/transliteration/data/x5b.php

@@ -9,7 +9,7 @@ $base = array(
   0x50 => 'Zi ', 'Jie ', 'Jue ', 'Jue ', 'Kong ', 'Yun ', 'Zi ', 'Zi ', 'Cun ', 'Sun ', 'Fu ', 'Bei ', 'Zi ', 'Xiao ', 'Xin ', 'Meng ',
   0x60 => 'Si ', 'Tai ', 'Bao ', 'Ji ', 'Gu ', 'Nu ', 'Xue ', NULL, 'Zhuan ', 'Hai ', 'Luan ', 'Sun ', 'Huai ', 'Mie ', 'Cong ', 'Qian ',
   0x70 => 'Shu ', 'Chan ', 'Ya ', 'Zi ', 'Ni ', 'Fu ', 'Zi ', 'Li ', 'Xue ', 'Bo ', 'Ru ', 'Lai ', 'Nie ', 'Nie ', 'Ying ', 'Luan ',
-  0x80 => 'Mian ', 'Zhu ', 'Rong ', 'Ta ', 'Gui ', 'Zhai ', 'Qiong ', 'Yu ', 'Shou ', 'An ', 'Tu ', 'Song ', 'Wan ', 'Rou ', 'Yao ', 'Hong ',
+  0x80 => 'Mian ', 'Ning ', 'Rong ', 'Ta ', 'Gui ', 'Zhai ', 'Qiong ', 'Yu ', 'Shou ', 'An ', 'Tu ', 'Song ', 'Wan ', 'Rou ', 'Yao ', 'Hong ',
   0x90 => 'Yi ', 'Jing ', 'Zhun ', 'Mi ', 'Zhu ', 'Dang ', 'Hong ', 'Zong ', 'Guan ', 'Zhou ', 'Ding ', 'Wan ', 'Yi ', 'Bao ', 'Shi ', 'Shi ',
   0xA0 => 'Chong ', 'Shen ', 'Ke ', 'Xuan ', 'Shi ', 'You ', 'Huan ', 'Yi ', 'Tiao ', 'Shi ', 'Xian ', 'Gong ', 'Cheng ', 'Qun ', 'Gong ', 'Xiao ',
   0xB0 => 'Zai ', 'Zha ', 'Bao ', 'Hai ', 'Yan ', 'Xiao ', 'Jia ', 'Shen ', 'Chen ', 'Rong ', 'Huang ', 'Mi ', 'Kou ', 'Kuan ', 'Bin ', 'Su ',

+ 1 - 1
sites/all/modules/contrib/files/transliteration/data/x5e.php

@@ -8,7 +8,7 @@ $base = array(
   0x40 => 'Zheng ', 'Xu ', 'Mi ', 'Wei ', 'Wo ', 'Fu ', 'Yi ', 'Bang ', 'Ping ', 'Tazuna ', 'Gong ', 'Pan ', 'Huang ', 'Dao ', 'Mi ', 'Jia ',
   0x50 => 'Teng ', 'Hui ', 'Zhong ', 'Shan ', 'Man ', 'Mu ', 'Biao ', 'Guo ', 'Ze ', 'Mu ', 'Bang ', 'Zhang ', 'Jiong ', 'Chan ', 'Fu ', 'Zhi ',
   0x60 => 'Hu ', 'Fan ', 'Chuang ', 'Bi ', 'Hei ', NULL, 'Mi ', 'Qiao ', 'Chan ', 'Fen ', 'Meng ', 'Bang ', 'Chou ', 'Mie ', 'Chu ', 'Jie ',
-  0x70 => 'Xian ', 'Lan ', 'Gan ', 'Ping ', 'Nian ', 'Qian ', 'Bing ', 'Bing ', 'Xing ', 'Gan ', 'Yao ', 'Huan ', 'You ', 'You ', 'Ji ', 'Yan ',
+  0x70 => 'Xian ', 'Lan ', 'Gan ', 'Ping ', 'Nian ', 'Qian ', 'Bing ', 'Bing ', 'Xing ', 'Gan ', 'Yao ', 'Huan ', 'You ', 'You ', 'Ji ', 'Guang ',
   0x80 => 'Pi ', 'Ting ', 'Ze ', 'Guang ', 'Zhuang ', 'Mo ', 'Qing ', 'Bi ', 'Qin ', 'Dun ', 'Chuang ', 'Gui ', 'Ya ', 'Bai ', 'Jie ', 'Xu ',
   0x90 => 'Lu ', 'Wu ', NULL, 'Ku ', 'Ying ', 'Di ', 'Pao ', 'Dian ', 'Ya ', 'Miao ', 'Geng ', 'Ci ', 'Fu ', 'Tong ', 'Pang ', 'Fei ',
   0xA0 => 'Xiang ', 'Yi ', 'Zhi ', 'Tiao ', 'Zhi ', 'Xiu ', 'Du ', 'Zuo ', 'Xiao ', 'Tu ', 'Gui ', 'Ku ', 'Pang ', 'Ting ', 'You ', 'Bu ',

+ 1 - 1
sites/all/modules/contrib/files/transliteration/data/x91.php

@@ -13,7 +13,7 @@ $base = array(
   0x90 => 'Hu ', 'Xu ', 'Xing ', 'Tan ', 'Jiu ', 'Chun ', 'Yun ', 'Po ', 'Ke ', 'Sou ', 'Mi ', 'Quan ', 'Chou ', 'Cuo ', 'Yun ', 'Yong ',
   0xA0 => 'Ang ', 'Zha ', 'Hai ', 'Tang ', 'Jiang ', 'Piao ', 'Shan ', 'Yu ', 'Li ', 'Zao ', 'Lao ', 'Yi ', 'Jiang ', 'Pu ', 'Jiao ', 'Xi ',
   0xB0 => 'Tan ', 'Po ', 'Nong ', 'Yi ', 'Li ', 'Ju ', 'Jiao ', 'Yi ', 'Niang ', 'Ru ', 'Xun ', 'Chou ', 'Yan ', 'Ling ', 'Mi ', 'Mi ',
-  0xC0 => 'Niang ', 'Xin ', 'Jiao ', 'Xi ', 'Mi ', 'Yan ', 'Bian ', 'Cai ', 'Shi ', 'You ', 'Shi ', 'Shi ', 'Li ', 'Zhong ', 'Ye ', 'Liang ',
+  0xC0 => 'Niang ', 'Xin ', 'Jiao ', 'Xi ', 'Mi ', 'Yan ', 'Bian ', 'Cai ', 'Shi ', 'You ', 'Shi ', 'Shi ', 'Li ', 'Chong ', 'Ye ', 'Liang ',
   0xD0 => 'Li ', 'Jin ', 'Jin ', 'Qiu ', 'Yi ', 'Diao ', 'Dao ', 'Zhao ', 'Ding ', 'Po ', 'Qiu ', 'He ', 'Fu ', 'Zhen ', 'Zhi ', 'Ba ',
   0xE0 => 'Luan ', 'Fu ', 'Nai ', 'Diao ', 'Shan ', 'Qiao ', 'Kou ', 'Chuan ', 'Zi ', 'Fan ', 'Yu ', 'Hua ', 'Han ', 'Gong ', 'Qi ', 'Mang ',
   0xF0 => 'Ri ', 'Di ', 'Si ', 'Xi ', 'Yi ', 'Chai ', 'Shi ', 'Tu ', 'Xi ', 'Nu ', 'Qian ', 'Ishiyumi ', 'Jian ', 'Pi ', 'Ye ', 'Yin ',

+ 5 - 0
sites/all/modules/contrib/files/transliteration/transliteration.admin.inc

@@ -149,6 +149,11 @@ function transliteration_file_query() {
       $regex = '/[a-z0-9_.-]+$';
       break;
 
+    case 'mssql':
+      $operator = 'LIKE';
+      $regex = '%[^a-z0-9_.-]%';
+      break;
+
     default:
       return FALSE;
   }

+ 3 - 3
sites/all/modules/contrib/files/transliteration/transliteration.info

@@ -3,9 +3,9 @@ description = Converts non-latin text to US-ASCII and sanitizes file names.
 core = 7.x
 configure = admin/config/media/file-system
 
-; Information added by drupal.org packaging script on 2012-06-01
-version = "7.x-3.1"
+; Information added by Drupal.org packaging script on 2014-03-17
+version = "7.x-3.2"
 core = "7.x"
 project = "transliteration"
-datestamp = "1338540713"
+datestamp = "1395079444"
 

+ 10 - 0
sites/all/modules/contrib/files/transliteration/transliteration.install

@@ -31,3 +31,13 @@ function transliteration_uninstall() {
   variable_del('transliteration_file_lowercase');
   variable_del('transliteration_search');
 }
+
+/**
+ * Remove unnecessary Drupal 6 variables.
+ */
+function transliteration_update_7300() {
+  // Delete all the transliteration_filter_no_known_transliteration_* variables
+  // and then clear the variable cache.
+  db_query("DELETE FROM {variable} WHERE name LIKE 'transliteration_filter_no_known_transliteration_%'");
+  cache_clear_all('variables', 'cache');
+}

+ 36 - 0
sites/all/modules/contrib/files/transliteration/transliteration.module

@@ -47,11 +47,27 @@ function transliteration_form_system_file_system_settings_alter(&$form, &$form_s
     '#description' => t('Enable to convert file names to US-ASCII character set for cross-platform compatibility.'),
     '#default_value' => variable_get('transliteration_file_uploads', TRUE),
   );
+  $form['transliteration']['transliteration_file_uploads_display_name'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Transliterate the displayed file name.'),
+    '#description' => t('Enable to also convert the file name that is displayed within the site (for example, in link text).'),
+    '#default_value' => variable_get('transliteration_file_uploads_display_name', TRUE),
+    '#states' => array(
+      'invisible' => array(
+        'input[name="transliteration_file_uploads"]' => array('checked' => FALSE),
+      ),
+    ),
+  );
   $form['transliteration']['transliteration_file_lowercase'] = array(
     '#type' => 'checkbox',
     '#title' => t('Lowercase transliterated file names.'),
     '#default_value' => variable_get('transliteration_file_lowercase', TRUE),
     '#description' => t('This is a recommended setting to prevent issues with case-insensitive file systems. It has no effect if transliteration has been disabled.'),
+    '#states' => array(
+      'invisible' => array(
+        'input[name="transliteration_file_uploads"]' => array('checked' => FALSE),
+      ),
+    ),
   );
   $form['buttons']['#weight'] = 1;
 }
@@ -102,6 +118,9 @@ function transliteration_clean_filename($filename, $source_langcode = NULL) {
     }
     return $filename;
   }
+
+  // Allow other modules to alter the filename prior to processing.
+  drupal_alter('transliteration_clean_filename_prepare', $filename, $source_langcode);
   $filename = transliteration_get($filename, '', $source_langcode);
   // Replace whitespace.
   $filename = str_replace(' ', '_', $filename);
@@ -170,6 +189,23 @@ function transliteration_init() {
   }
 }
 
+/**
+ * Implements hook_file_presave().
+ */
+function transliteration_file_presave($file) {
+  // If an uploaded file had its name altered in transliteration_init() and if
+  // the human-readable display name is not being transliterated, restore the
+  // original version as the human-readable name before saving. (The
+  // transliterated version will still be used in the file URI, which is the
+  // only place where it matters.)
+  if (!empty($_FILES['files']['name']) && variable_get('transliteration_file_uploads', TRUE) && !variable_get('transliteration_file_uploads_display_name', TRUE)) {
+    $key = array_search($file->filename, $_FILES['files']['name']);
+    if ($key !== FALSE && isset($_FILES['files']['orig_name'][$key])) {
+      $file->filename = $_FILES['files']['orig_name'][$key];
+    }
+  }
+}
+
 /**
  * Implements hook_search_preprocess().
  *

+ 9 - 1
sites/all/modules/contrib/mail/views_send/CHANGELOG.txt

@@ -1,6 +1,14 @@
+Views Send 7.x-1.1, 2014-06-21
+------------------------------
+#2225631 by hansfn: Using filter_fallback_format() instead of hard-coded value for message text format.
+#2258947 by hansfn: Call to a member function get_value() on a non-object.
+#2089409 by hansfn: Added support for Mandrill.
 
-Views Send 7.x-1.x, xxxx-xx-xx
+Views Send 7.x-1.0, 2014-04-15
 ------------------------------
+#2202769 by hansfn: Subject not displaying correctly
+#2122909 by hansfn: Unwanted conversion of quotes in fields used for recipient's e-mail and name
+#2023977 by hansfn: Views Send overrides Mail System module configuration
 #1963960 by hansfn: Add hooks.
 #1957442 by hansfn: Token replacement doesn't work for repeated field.
 #1939332 by hansfn: Token list doesn't update.

+ 1 - 1
sites/all/modules/contrib/mail/views_send/README.txt

@@ -25,7 +25,7 @@ DEPENDENCIES & INTEGRATION
  * Views Send depends on Views.
  * The module integrates features from:
   o Mime Mail. When the Mime Mail module is enabled, the user can choose to send
-    rich HTML messages.
+    rich HTML messages and/or use attachments.
   o Tokens. When the Tokens module is enabled, the user can insert context tokens
     into the subject or body of the message. Note that row-based tokens are
     available even if Tokens module is disabled.

+ 0 - 26
sites/all/modules/contrib/mail/views_send/mailsystem-integration-2023977-7.patch

@@ -1,26 +0,0 @@
-diff --git a/views_send.module b/views_send.module
-index 283d434..58bbff9 100644
---- a/views_send.module
-+++ b/views_send.module
-@@ -960,8 +960,9 @@ function _views_send_prepare_mail(&$message, $plain_format=TRUE, $attachments=ar
-   $params['headers'] = $headers;
- 
-   if (VIEWS_SEND_MIMEMAIL) {
-+    $mailsystem = mailsystem_get();
-     mailsystem_set(array(
--      "views_send_$key" => 'MimeMailSystem'
-+      "views_send_$key" => $mailsystem['mimemail']
-     ));
-     $params['attachments'] = $attachments;
-     if ($plain_format) {
-@@ -1010,8 +1011,9 @@ function views_send_deliver($message) {
- 
-   if (VIEWS_SEND_MIMEMAIL) {
-     $mail['subject'] = mime_header_encode($message->subject);
-+    $mailsystem = mailsystem_get();
-     mailsystem_set(array(
--      "views_send_$key" => 'MimeMailSystem'
-+      "views_send_$key" => $mailsystem['mimemail']
-     ));
-   }
- 

+ 3 - 3
sites/all/modules/contrib/mail/views_send/views_send.info

@@ -8,9 +8,9 @@ core = 7.x
 files[] = views_send.rules.inc
 files[] = views/views_send_handler_field_selector.inc
 
-; Information added by drupal.org packaging script on 2013-05-12
-version = "7.x-1.0-rc3"
+; Information added by Drupal.org packaging script on 2014-06-21
+version = "7.x-1.1"
 core = "7.x"
 project = "views_send"
-datestamp = "1368398411"
+datestamp = "1403371134"
 

+ 112 - 39
sites/all/modules/contrib/mail/views_send/views_send.module

@@ -33,9 +33,22 @@ define('VIEWS_SEND_TOKEN_PREFIX', '[');
 define('VIEWS_SEND_TOKEN_POSTFIX', ']');
 
 /**
- * Detect and store Mime Mail module presence.
+ * Detect if there is MIME support (thorough modules like Mime Mail or Mandrill).
  */
-define('VIEWS_SEND_MIMEMAIL', module_exists('mimemail'));
+define('VIEWS_SEND_MIMEMAIL', module_exists('mimemail') || module_exists('mandrill'));
+
+/**
+ * Sets the mailsystem for Views Send (if not already set).
+ */
+function _views_send_mailsystem_set($key) {
+  $mailsystem = mailsystem_get();
+  $mailsystem_key = "views_send_$key";
+  if (empty($mailsystem[$mailsystem_key])) {
+    mailsystem_set(array(
+      $mailsystem_key => $mailsystem['default-system']
+    ));
+  }
+}
 
 /**
  * Gets the selector field if it exists on the passed-in view.
@@ -54,6 +67,31 @@ function _views_send_get_field($view) {
   return FALSE;
 }
 
+/**
+ * Gets the raw field value from a result row in a view.
+ * 
+ * @return
+ *  An array with raw values from the field.
+ */
+function _views_send_get_raw_field_from_views_row($view, $row_id, $field_id) {
+  $result = array();
+  $raw_value = $view->style_plugin->get_field_value($row_id, $field_id);
+  if (!is_array($raw_value)) {
+      $result[] = trim($raw_value);
+  } 
+  else { 
+    foreach ($raw_value as $arr) {
+      if (isset($arr['value'])) {
+        $value = $arr['value'];
+      } else {
+        list($value) = array_values($arr);
+      }
+      $result[] = trim($value);
+    }
+  }
+  return $result;
+}
+
 /**
  * Implements hook_views_form_substitutions().
  */
@@ -156,6 +194,8 @@ function views_send_form_alter(&$form, &$form_state, $form_id) {
 
 /**
  * Multistep form callback for the "configure" step.
+ *
+ @TODO: Hide "Sender" (from) if Mandrill is used.
  */
 function views_send_config_form($form, &$form_state, $view, $output) {
   $display = $view->name . ':' . $view->current_display;
@@ -233,7 +273,7 @@ function views_send_config_form($form, &$form_state, $view, $output) {
   $saved_message = variable_get('views_send_message_' . $display);
   $form['mail']['views_send_message'] = array(
     '#type' => 'text_format',
-    '#format' => isset($saved_message['format']) ? $saved_message['format'] : 'plain_text',
+    '#format' => isset($saved_message['format']) ? $saved_message['format'] : filter_fallback_format(),
     '#title' => t('Message'),
     '#description' => t('Enter the body of the message. You can use tokens in the message.'),
     '#required' => TRUE,
@@ -379,12 +419,10 @@ function views_send_config_form_validate($form, &$form_state) {
 
     $to_mail_field = $values['views_send_tokens'][$values['views_send_to_mail']];
     foreach ($form_state['selection'] as $row_id) {
-      $to_mail_rendered = $view->style_plugin->get_field($row_id, $to_mail_field);
-      $to_mail_arr = explode(',', strip_tags($to_mail_rendered));
-      foreach ($to_mail_arr as $to_mail) {
-        $to_mail = trim($to_mail);
-        if (!valid_email_address($to_mail)) {
-          $wrong_addresses[$row_id] = $to_mail;
+      $mail_addresses = _views_send_get_raw_field_from_views_row($view, $row_id, $to_mail_field);
+      foreach ($mail_addresses as $mail_address) {
+        if (!valid_email_address($mail_address)) {
+          $wrong_addresses[$row_id] = $mail_address;
           break;
         }
       }
@@ -422,8 +460,13 @@ function views_send_confirm_form($form, &$form_state, $view, $output) {
   $configuration = $form_state['configuration'];
 
   if (!VIEWS_SEND_MIMEMAIL && ($configuration['views_send_message']['format'] != 'plain_text')) {
-    drupal_set_message(t("Only plain text is supported in the message. Any HTML will be converted to text. If you want to format the message with HTML, you'll have to install and enable the !mimemail module.",
-      array('!mimemail' => '<a href="http://drupal.org/project/mimemail">Mime Mail</a>'))
+    drupal_set_message(
+      t("Only plain text is supported in the message. Any HTML will be converted to text. If you want to format the message with HTML, you'll have to install and enable the !mimemail or !mandrill module.",
+        array(
+          '!mimemail' => '<a href="http://drupal.org/project/mimemail">Mime Mail</a>',
+          '!mandrill' => '<a href="http://drupal.org/project/mandrill">Mandrill</a>'
+        )
+      )
     );
   }
 
@@ -440,15 +483,23 @@ function views_send_confirm_form($form, &$form_state, $view, $output) {
       '</div>',
   );
 
+  // To: parts. (Mail is mandatory, name is optional.)
   $recipients = array();
-  $to_name_field = $configuration['views_send_tokens'][$configuration['views_send_to_name']];
+  if (!empty($configuration['views_send_to_name'])) {
+    $to_name_field = $configuration['views_send_tokens'][$configuration['views_send_to_name']];
+  }
+  else {
+    $to_name_field = false;
+    $to_name = '';
+  }
   $to_mail_field = $configuration['views_send_tokens'][$configuration['views_send_to_mail']];
   foreach ($form_state['selection'] as $row_id) {
-    $to_name = strip_tags($view->style_plugin->get_field($row_id, $to_name_field));
-    $to_mail_rendered = $view->style_plugin->get_field($row_id, $to_mail_field);
-    $to_mail_arr = explode(',', strip_tags($to_mail_rendered));
-    foreach ($to_mail_arr as $to_mail) {
-      $recipients[] = check_plain(empty($to_name) ? $to_mail : trim($to_name) . ' <' .  $to_mail . '>');
+    if ($to_name_field) {
+      list($to_name) = _views_send_get_raw_field_from_views_row($view, $row_id, $to_name_field);
+    }
+    $mail_addresses = _views_send_get_raw_field_from_views_row($view, $row_id, $to_mail_field);
+    foreach ($mail_addresses as $mail_address) {
+      $recipients[] = check_plain(empty($to_name) ? $mail_address : trim($to_name) . ' <' .  $mail_address . '>');
     }
   }
 
@@ -563,7 +614,7 @@ function views_send_form_submit($form, &$form_state) {
 
       // Redirect.
       $query = drupal_get_query_parameters($_GET, array('q'));
-      $form_state['redirect'] = array('path' => $field->view->get_url(), array('query' => $query));
+      $form_state['redirect'] = array($field->view->get_url(), array('query' => $query));
       break;
   }
 }
@@ -596,12 +647,21 @@ function views_send_queue_mail($params, $selected_rows, $view) {
   $from_mail = trim($params['views_send_from_mail']);
   $from_name = $params['views_send_from_name'];
 
+  // To: parts. (Mail is mandatory, name is optional.)
   $to_mail_key = $params['views_send_tokens'][$params['views_send_to_mail']];
-  $to_name_key = $params['views_send_tokens'][$params['views_send_to_name']];
+  if (!empty($params['views_send_to_name'])) {
+    $to_name_key = $params['views_send_tokens'][$params['views_send_to_name']];
+  }
+  else {
+    $to_name_key = false;
+    $to_name = '';
+  }
   foreach ($selected_rows as $row_id) {
     // To: parts.
-    $to_mail = trim(strip_tags($view->style_plugin->get_field($row_id, $to_mail_key)));
-    $to_name = trim(strip_tags($view->style_plugin->get_field($row_id, $to_name_key)));
+    $to_mail = implode(',', _views_send_get_raw_field_from_views_row($view, $row_id, $to_mail_key));
+    if ($to_name_key) {
+      list($to_name) = _views_send_get_raw_field_from_views_row($view, $row_id, $to_name_key);
+    }
 
     $subject = $params['views_send_subject'];
     $body = $params['views_send_message']['value'];
@@ -658,10 +718,10 @@ function views_send_queue_mail($params, $selected_rows, $view) {
     $message = array(
       'uid' => $user->uid,
       'timestamp' => time(),
-      'from_name' => $from_name,
-      'from_mail' => $from_mail,
-      'to_name' => $to_name,
-      'to_mail' => $to_mail,
+      'from_name' => trim($from_name),
+      'from_mail' => trim($from_mail),
+      'to_name' => trim($to_name),
+      'to_mail' => trim($to_mail),
       'subject' => strip_tags($subject),
       'body' => $body,
       'headers' => $headers,
@@ -702,7 +762,7 @@ function views_send_queue_mail($params, $selected_rows, $view) {
     );
     batch_set($batch);
     drupal_set_message(
-      t('@total messages processed.', array('@total' => count($selected_rows)))
+      format_plural(count($selected_rows), '1 message processed.', '@count messages processed.')
     );
   }
   else {
@@ -713,7 +773,7 @@ function views_send_queue_mail($params, $selected_rows, $view) {
     }
 
     drupal_set_message(
-      t('@total messages added to the spool.', array('@total' => count($selected_rows)))
+      format_plural(count($selected_rows), '1 message added to the spool.', '@count messages added to the spool.')
     );
     if (module_exists('rules')) {
       rules_invoke_event('views_send_all_email_added_to_spool', count($selected_rows));
@@ -900,10 +960,26 @@ function _views_send_headers($receipt, $priority, $from, $additional_headers) {
  * Build a formatted e-mail address.
  */
 function _views_send_format_address($mail, $name, $encode = TRUE) {
-  $name = trim($name);
-
   // Do not format addres on Windows based PHP systems or when $name is empty.
-  return ((substr(PHP_OS, 0, 3) == 'WIN') || empty($name)) ? $mail : '"' . ($encode ? mime_header_encode($name) : $name) . '" <' . $mail . '>';
+  if ((substr(PHP_OS, 0, 3) == 'WIN') || empty($name)) {
+    return $mail;
+  }
+  else {
+    $name = ($encode ? _views_send_mime_header_encode($name) : $name);
+    return sprintf('"%s" <%s>', $name, $mail);
+  }
+}
+
+/**
+ * Returns a mime-encoded string for strings that contain UTF-8.
+ *
+ * Simplified and correct version of mime_header_decode.
+ */ 
+function _views_send_mime_header_encode($string) {
+  if (preg_match('/[^\x20-\x7E]/', $string)) {
+    $string = '=?UTF-8?B?' . base64_encode($string) . '?=';
+  }
+  return $string;
 }
 
 /**
@@ -960,10 +1036,7 @@ function _views_send_prepare_mail(&$message, $plain_format=TRUE, $attachments=ar
   $params['headers'] = $headers;
 
   if (VIEWS_SEND_MIMEMAIL) {
-    $mailsystem = mailsystem_get();
-    mailsystem_set(array(
-      "views_send_$key" => $mailsystem['mimemail']
-    ));
+    _views_send_mailsystem_set($key);
     $params['attachments'] = $attachments;
     if ($plain_format) {
       $params['plain'] = TRUE;
@@ -1010,13 +1083,13 @@ function views_send_deliver($message) {
   );
 
   if (VIEWS_SEND_MIMEMAIL) {
-    $mail['subject'] = mime_header_encode($message->subject);
-    $mailsystem = mailsystem_get();
-    mailsystem_set(array(
-      "views_send_$key" => $mailsystem['mimemail']
-    ));
+    _views_send_mailsystem_set($key);
   }
 
+  // Mime encode the subject before passing to the mail function 
+  // to work around a bug in Drupal's mime_header_encode.
+  $mail['subject'] = _views_send_mime_header_encode($message->subject);
+  
   $system = drupal_mail_system('views_send', $key);
   return $system->mail($mail);
 }

+ 6 - 2
sites/all/modules/contrib/search/search_api_saved_searches/CHANGELOG.txt

@@ -1,5 +1,9 @@
-Search API Saved Searches 1.x, dev (xx/xx/xxxx):
-------------------------------------------------
+Search API Saved Searches 1.3 (05/24/2014):
+-------------------------------------------
+- #2082325 by balajidharma, drunken monkey: Added classes to edit and delete
+  links.
+- #2088045 by leeomara, drunken monkey: Added hook to override generated names.
+- #2042299 by drunken monkey: Added access callbacks for both entity types.
 
 Search API Saved Searches 1.2 (07/21/2013):
 -------------------------------------------

+ 20 - 0
sites/all/modules/contrib/search/search_api_saved_searches/search_api_saved_searches.api.php

@@ -230,6 +230,26 @@ function hook_search_api_saved_searches_new_results_alter(array &$results, Searc
   }
 }
 
+/**
+ * Alters the name assigned to a newly created saved search.
+ *
+ * @param string $name
+ *   The suggested name of the saved search. Likely the search term, or
+ *   the translated string "Saved search".
+ * @param array $query
+ *   An associative array with the following keys:
+ *   - index_id: The machine name of the index the search was run on.
+ *   - keys: The parsed search keys.
+ *   - original_keys: The keys as entered by the user.
+ *   - fields: The fulltext fields searched by the query.
+ *   - filters: An array of filters set for the query, as returned by
+ *     SearchApiQueryFilterInterface::getFilters().
+ *   - options: All options set on the query.
+ */
+function hook_search_api_saved_search_create_name_alter(&$name, array $query) {
+  $name = 'foo';
+}
+
 /**
  * @} End of "addtogroup hooks".
  */

+ 3 - 3
sites/all/modules/contrib/search/search_api_saved_searches/search_api_saved_searches.info

@@ -10,9 +10,9 @@ files[] = views/handler_field_saved_search_interval.inc
 files[] = views/handler_field_saved_search_link.inc
 files[] = views/handler_field_saved_search_name.inc
 
-; Information added by drupal.org packaging script on 2013-07-21
-version = "7.x-1.2"
+; Information added by Drupal.org packaging script on 2014-05-24
+version = "7.x-1.3"
 core = "7.x"
 project = "search_api_saved_searches"
-datestamp = "1374443489"
+datestamp = "1400922530"
 

+ 66 - 5
sites/all/modules/contrib/search/search_api_saved_searches/search_api_saved_searches.module

@@ -113,6 +113,7 @@ function search_api_saved_searches_entity_info() {
     'entity class' => 'SearchApiSavedSearchesSettings',
     'base table' => 'search_api_saved_searches_settings',
     'uri callback' => 'search_api_saved_searches_settings_url',
+    'access callback' => 'search_api_saved_searches_settings_access',
     'module' => 'search_api_saved_searches',
     'exportable' => TRUE,
     'entity keys' => array(
@@ -126,6 +127,7 @@ function search_api_saved_searches_entity_info() {
     'controller class' => 'EntityAPIController',
     'entity class' => 'SearchApiSavedSearch',
     'base table' => 'search_api_saved_search',
+    'access callback' => 'search_api_saved_search_access',
     'module' => 'search_api_saved_searches',
     'exportable' => FALSE,
     'entity keys' => array(
@@ -203,6 +205,66 @@ function search_api_saved_searches_settings_url(SearchApiSavedSearchesSettings $
   return array('path' => 'admin/config/search/search_api/index/' . $settings->index_id . '/saved_searches');
 }
 
+/**
+ * Access callback for settings entities.
+ *
+ * @param string $op
+ *   The operation being performed. One of "view", "update", "create" or
+ *   "delete".
+ * @param SearchApiSavedSearchesSettings|null $settings
+ *   (optional) The entity to check access for. If NULL is given, it will be
+ *   determined whether access is allowed for all settings.
+ * @param object|null $account
+ *   The user to check for. NULL to check for the global user.
+ *
+ * @return bool
+ *   Whether access is allowed or not.
+ *
+ * @see entity_access
+ */
+function search_api_saved_searches_settings_access($op, SearchApiSavedSearchesSettings $settings = NULL, $account = NULL) {
+  return user_access('administer search_api_saved_searches', $account);
+}
+
+/**
+ * Access callback for saved search entities.
+ *
+ * @param string $op
+ *   The operation being performed. One of "view", "update", "create" or
+ *   "delete".
+ * @param SearchApiSavedSearch|null $search
+ *   (optional) The entity to check access for. If NULL is given, it will be
+ *   determined whether access is allowed for all searches.
+ * @param object|null $account
+ *   The user to check for. NULL to check for the global user.
+ *
+ * @return bool
+ *   Whether access is allowed or not.
+ *
+ * @see entity_access
+ */
+function search_api_saved_search_access($op, SearchApiSavedSearch $search = NULL, $account = NULL) {
+  if (user_access('administer search_api_saved_searches', $account)) {
+    return TRUE;
+  }
+  if (!$account) {
+    global $user;
+    $account = $user;
+  }
+  switch ($op) {
+    case 'create':
+      return user_access('use search_api_saved_searches', $account);
+
+    default:
+      // If the search was created by an anonymous user, there's no way we can
+      // correctly determine access here.
+      if (!$search || !$search->uid) {
+        return FALSE;
+      }
+      return $search->uid == $account->uid;
+  }
+}
+
 /**
  * Implements hook_user_insert().
  *
@@ -949,13 +1011,12 @@ function search_api_saved_searches_save_form_submit(array $form, array &$form_st
  * Helper function for creating a name for a saved search with the given query.
  */
 function _search_api_saved_searches_create_name(array $query) {
-  if (!empty($query['original_keys'])) {
-    // @todo This could be an array under some circumstances.
+  if (!empty($query['original_keys']) && is_scalar($query['original_keys'])) {
     $ret[] = $query['original_keys'];
   }
-  // @todo File through filters, looking for things that could go in a name.
-
-  return isset($ret) ? implode(' / ', $ret) : t('Saved search');
+  $name = isset($ret) ? implode(' / ', $ret) : t('Saved search');
+  drupal_alter('search_api_saved_search_create_name', $name, $query);
+  return $name;
 }
 
 /**

+ 4 - 1
sites/all/modules/contrib/search/search_api_saved_searches/search_api_saved_searches.pages.inc

@@ -45,13 +45,16 @@ function search_api_saved_searches_user_listing($account) {
       $interval = format_interval($search->notify_interval, 1);
     }
 
+    $edit_options['attributes']['class'][] = 'saved-search-edit';
+    $delete_options['attributes']['class'][] = 'saved-search-delete';
+
     $path = $base_path . $search->id;
     $rows[] = array(
       $name,
       $created,
       $last_execute,
       $interval,
-      l(t('edit'), $path . '/edit') . ' | ' . l(t('delete'), $path . '/delete'),
+      l(t('edit'), $path . '/edit', $edit_options) . ' | ' . l(t('delete'), $path . '/delete', $delete_options),
     );
   }
 

+ 3 - 3
sites/all/modules/contrib/search/search_api_saved_searches/search_api_saved_searches_i18n/search_api_saved_searches_i18n.info

@@ -8,9 +8,9 @@ package = Multilingual - Internationalization
 files[] = search_api_saved_searches_i18n.controller.inc
 files[] = search_api_saved_searches_i18n.string_wrapper.inc
 
-; Information added by drupal.org packaging script on 2013-07-21
-version = "7.x-1.2"
+; Information added by Drupal.org packaging script on 2014-05-24
+version = "7.x-1.3"
 core = "7.x"
 project = "search_api_saved_searches"
-datestamp = "1374443489"
+datestamp = "1400922530"
 

+ 12 - 0
sites/all/modules/contrib/views/views_bulk_operations/actions/delete.action.inc

@@ -14,6 +14,12 @@ function views_bulk_operations_delete_action_info() {
       'behavior' => array('deletes_property'),
       'triggers' => array('any'),
     ),
+    'views_bulk_operations_delete_revision' => array(
+      'type' => 'entity',
+      'label' => t('Delete revision'),
+      'configurable' => FALSE,
+      'behavior' => array('deletes_property'),
+    ),
   );
 }
 
@@ -23,3 +29,9 @@ function views_bulk_operations_delete_item($entity, $context) {
 
   entity_delete($context['entity_type'], $entity_id);
 }
+
+function views_bulk_operations_delete_revision($entity, $context) {
+  $info = entity_get_info($context['entity_type']);
+  $revision_id = $entity->{$info['entity keys']['revision']};
+  entity_revision_delete($context['entity_type'], $revision_id);
+}

+ 79 - 42
sites/all/modules/contrib/views/views_bulk_operations/actions/modify.action.inc

@@ -29,15 +29,19 @@ function views_bulk_operations_modify_action_info() {
  */
 function views_bulk_operations_modify_action($entity, $context) {
   list(,,$bundle_name) = entity_extract_ids($context['entity_type'], $entity);
-
   // Handle Field API fields.
   if (!empty($context['selected']['bundle_' . $bundle_name])) {
     // The pseudo entity is cloned so that changes to it don't get carried
     // over to the next execution.
     $pseudo_entity = clone $context['entities'][$bundle_name];
     foreach ($context['selected']['bundle_' . $bundle_name] as $key) {
+      // Get this field's language. We can just pull it from the pseudo entity
+      // as it was created using field_attach_form and entity_language so it's
+      // already been figured out if this field is translatable or not and
+      // applied the appropriate language code to the field
+      $language = key($pseudo_entity->{$key});
       // Replace any tokens that might exist in the field columns.
-      foreach ($pseudo_entity->{$key}[LANGUAGE_NONE] as $delta => &$item) {
+      foreach ($pseudo_entity->{$key}[$language] as $delta => &$item) {
         foreach ($item as $column => $value) {
           if (is_string($value)) {
             $item[$column] = token_replace($value, array($context['entity_type'] => $entity), array('sanitize' => FALSE));
@@ -46,11 +50,11 @@ function views_bulk_operations_modify_action($entity, $context) {
       }
 
       if (in_array($key, $context['append']['bundle_' . $bundle_name]) && !empty($entity->$key)) {
-        $entity->{$key}[LANGUAGE_NONE] = array_merge($entity->{$key}[LANGUAGE_NONE], $pseudo_entity->{$key}[LANGUAGE_NONE]);
+        $entity->{$key}[$language] = array_merge($entity->{$key}[$language], $pseudo_entity->{$key}[$language]);
 
         // Check if we breached cardinality, and notify the user.
         $field_info = field_info_field($key);
-        $field_count = count($entity->{$key}[LANGUAGE_NONE]);
+        $field_count = count($entity->{$key}[$language]);
         if ($field_info['cardinality'] != FIELD_CARDINALITY_UNLIMITED && $field_count > $field_info['cardinality']) {
           $entity_label = entity_label($context['entity_type'], $entity);
           $warning = t('Tried to set !field_count values for field !field_name that supports a maximum of !cardinality.',
@@ -59,9 +63,14 @@ function views_bulk_operations_modify_action($entity, $context) {
                              '!cardinality' => $field_info['cardinality']));
           drupal_set_message($warning, 'warning', FALSE);
         }
+
+        // Prevent storing duplicate references.
+        if (strpos($field_info['type'], 'reference') !== FALSE) {
+          $entity->{$key}[$language] = array_unique($entity->{$key}[LANGUAGE_NONE], SORT_REGULAR);
+        }
       }
       else {
-        $entity->$key = $pseudo_entity->$key;
+        $entity->{$key}[$language] = $pseudo_entity->{$key}[$language];
       }
     }
   }
@@ -148,6 +157,11 @@ function views_bulk_operations_modify_action_form($context, &$form_state) {
           ),
         ),
       );
+      // The default #maxlength for textfields is 128, while most varchar
+      // columns hold 255 characters, which makes it a saner default here.
+      if ($determined_type == 'textfield') {
+        $form['properties'][$key]['#maxlength'] = 255;
+      }
 
       if (!empty($property['options list'])) {
         $form['properties'][$key]['#type'] = 'select';
@@ -170,6 +184,8 @@ function views_bulk_operations_modify_action_form($context, &$form_state) {
     }
   }
 
+  // Going to need this for multilingual nodes
+  global $language;
   foreach ($bundles as $bundle_name => $bundle) {
     $bundle_key = $info['entity keys']['bundle'];
     $default_values = array();
@@ -177,6 +193,7 @@ function views_bulk_operations_modify_action_form($context, &$form_state) {
     if (!empty($bundle_key)) {
       $default_values[$bundle_key] = $bundle_name;
     }
+    $default_values['language'] = $language->language;
     $entity = entity_create($context['entity_type'], $default_values);
     $form_state['entities'][$bundle_name] = $entity;
 
@@ -195,7 +212,7 @@ function views_bulk_operations_modify_action_form($context, &$form_state) {
       '#title' => $label,
       '#parents' => array($form_key),
     );
-    field_attach_form($context['entity_type'], $entity, $form[$form_key], $form_state, LANGUAGE_NONE);
+    field_attach_form($context['entity_type'], $entity, $form[$form_key], $form_state, entity_language($context['entity_type'], $entity));
     // Now that all the widgets have been added, sort them by #weight.
     // This ensures that they will stay in the correct order when they get
     // assigned new weights.
@@ -206,8 +223,10 @@ function views_bulk_operations_modify_action_form($context, &$form_state) {
     $weight = 0;
     foreach (element_get_visible_children($form[$form_key]) as $field_name) {
       // For our use case it makes no sense for any field widget to be required.
-      $language = $form[$form_key][$field_name]['#language'];
-      _views_bulk_operations_modify_action_unset_required($form[$form_key][$field_name][$language]);
+      if (isset($form[$form_key][$field_name]['#language'])) {
+        $field_language = $form[$form_key][$field_name]['#language'];
+        _views_bulk_operations_modify_action_unset_required($form[$form_key][$field_name][$field_language]);
+      }
 
       // The admin has specified which fields to display, but this field didn't
       // make the cut. Hide it with #access => FALSE and move on.
@@ -216,32 +235,34 @@ function views_bulk_operations_modify_action_form($context, &$form_state) {
         continue;
       }
 
-      $field = $instances[$field_name];
-      $form[$form_key]['show_value'][$field_name] = array(
-        '#type' => 'checkbox',
-        '#title' => $field['label'],
-      );
-      $form[$form_key][$field_name]['#states'] = array(
-        'visible' => array(
-          '#edit-bundle-' . str_replace('_', '-', $bundle_name) . '-show-value-' . str_replace('_', '-', $field_name) => array('checked' => TRUE),
-        ),
-      );
-      // All field widgets get reassigned weights so that additional elements
-      // added between them (such as "_append") can be properly ordered.
-      $form[$form_key][$field_name]['#weight'] = $weight++;
-
-      $field_info = field_info_field($field_name);
-      if ($field_info['cardinality'] != 1) {
-        $form[$form_key]['_append::' . $field_name] = array(
+      if (isset($instances[$field_name])) {
+        $field = $instances[$field_name];
+        $form[$form_key]['show_value'][$field_name] = array(
           '#type' => 'checkbox',
-          '#title' => t('Add new value(s) to %label, instead of overwriting the existing values.', array('%label' => $field['label'])),
-          '#states' => array(
-            'visible' => array(
-              '#edit-bundle-' . str_replace('_', '-', $bundle_name) . '-show-value-' . str_replace('_', '-', $field_name) => array('checked' => TRUE),
-            ),
+          '#title' => $field['label'],
+        );
+        $form[$form_key][$field_name]['#states'] = array(
+          'visible' => array(
+            '#edit-bundle-' . str_replace('_', '-', $bundle_name) . '-show-value-' . str_replace('_', '-', $field_name) => array('checked' => TRUE),
           ),
-          '#weight' => $weight++,
         );
+        // All field widgets get reassigned weights so that additional elements
+        // added between them (such as "_append") can be properly ordered.
+        $form[$form_key][$field_name]['#weight'] = $weight++;
+
+        $field_info = field_info_field($field_name);
+        if ($field_info['cardinality'] != 1) {
+          $form[$form_key]['_append::' . $field_name] = array(
+            '#type' => 'checkbox',
+            '#title' => t('Add new value(s) to %label, instead of overwriting the existing values.', array('%label' => $field['label'])),
+            '#states' => array(
+              'visible' => array(
+                '#edit-bundle-' . str_replace('_', '-', $bundle_name) . '-show-value-' . str_replace('_', '-', $field_name) => array('checked' => TRUE),
+              ),
+            ),
+            '#weight' => $weight++,
+          );
+        }
       }
     }
 
@@ -411,8 +432,12 @@ function _views_bulk_operations_modify_action_get_properties($entity_type, $disp
   // List of supported types.
   $supported_types = array('text', 'token', 'integer', 'decimal', 'date', 'duration',
                            'boolean', 'uri', 'list');
-
   $property_info = entity_get_property_info($entity_type);
+  if (empty($property_info['properties'])) {
+    // Stop here if no properties were found.
+    return array();
+  }
+
   foreach ($property_info['properties'] as $key => $property) {
     if (in_array($key, $disabled_properties)) {
       continue;
@@ -463,27 +488,38 @@ function _views_bulk_operations_modify_action_get_bundles($entity_type, $context
   $bundles = array();
 
   $view = $context['view'];
+  $vbo = _views_bulk_operations_get_field($view);
   $display_values = $context['settings']['display_values'];
   $info = entity_get_info($entity_type);
   $bundle_key = $info['entity keys']['bundle'];
+
   // Check if this View has a filter on the bundle key and assemble a list
   // of allowed bundles according to the filter.
-  $filtered_bundles = array();
-  if (!empty($bundle_key) && isset($view->filter[$bundle_key]) && !empty($view->filter[$bundle_key]->value)) {
-    $operator = $view->filter[$bundle_key]->operator;
-    if ($operator == 'in') {
-      $filtered_bundles = $view->filter[$bundle_key]->value;
-    }
-    elseif ($operator == 'not in') {
-      $bundle_names = array_keys($info['bundles']);
-      $filtered_bundles = array_diff($bundle_names, $view->filter[$bundle_key]->value);
+  $filtered_bundles = array_keys($info['bundles']);
+
+  // Go over all the filters and find any relevant ones.
+  foreach ($view->filter as $key => $filter) {
+    // Check it's the right field on the right table.
+    if ($filter->table == $vbo->table && $filter->field == $bundle_key) {
+      // Exposed filters may have no bundles, so check that there is a value.
+      if (empty($filter->value)) {
+        continue;
+      }
+
+      $operator = $filter->operator;
+      if ($operator == 'in') {
+        $filtered_bundles = array_intersect($filtered_bundles, $filter->value);
+      }
+      elseif ($operator == 'not in') {
+        $filtered_bundles = array_diff($filtered_bundles, $filter->value);
+      }
     }
   }
 
   foreach ($info['bundles'] as $bundle_name => $bundle) {
     // The view is limited to specific bundles, but this bundle isn't one of
     // them. Ignore it.
-    if (!empty($filtered_bundles) && !in_array($bundle_name, $filtered_bundles)) {
+    if (!in_array($bundle_name, $filtered_bundles)) {
       continue;
     }
 
@@ -575,6 +611,7 @@ function views_bulk_operations_modify_action_views_bulk_operations_form($options
     '#multiple' => TRUE,
     '#description' => t('Select which values the action form should present to the user.'),
     '#default_value' => $options['display_values'],
+    '#size' => 10,
   );
   return $form;
 }

+ 3 - 3
sites/all/modules/contrib/views/views_bulk_operations/actions_permissions.info

@@ -3,9 +3,9 @@ description = Provides permission-based access control for actions. Used by View
 package = Administration
 core = 7.x
 
-; Information added by drupal.org packaging script on 2012-12-03
-version = "7.x-3.1"
+; Information added by Drupal.org packaging script on 2013-12-23
+version = "7.x-3.2"
 core = "7.x"
 project = "views_bulk_operations"
-datestamp = "1354500015"
+datestamp = "1387798183"
 

+ 4 - 2
sites/all/modules/contrib/views/views_bulk_operations/plugins/operation_types/action.class.php

@@ -141,9 +141,11 @@ class ViewsBulkOperationsAction extends ViewsBulkOperationsBaseOperation {
    * @param $dom_id
    *   The dom path to the level where the admin options form is embedded.
    *   Needed for #dependency.
+   * @param $field_handler
+   *   The Views field handler object for the VBO field.
    */
-  public function adminOptionsForm($dom_id) {
-    $form = parent::adminOptionsForm($dom_id);
+  public function adminOptionsForm($dom_id, $field_handler) {
+    $form = parent::adminOptionsForm($dom_id, $field_handler);
 
     $settings_form_callback = $this->operationInfo['callback'] . '_views_bulk_operations_form';
     if (function_exists($settings_form_callback)) {

+ 3 - 1
sites/all/modules/contrib/views/views_bulk_operations/plugins/operation_types/base.class.php

@@ -173,8 +173,10 @@ abstract class ViewsBulkOperationsBaseOperation {
    * @param $dom_id
    *   The dom path to the level where the admin options form is embedded.
    *   Needed for #dependency.
+   * @param $field_handler
+   *   The Views field handler object for the VBO field.
    */
-  public function adminOptionsForm($dom_id) {
+  public function adminOptionsForm($dom_id, $field_handler) {
     $label = $this->getAdminOption('label', '');
 
     $form = array();

+ 24 - 1
sites/all/modules/contrib/views/views_bulk_operations/views/views_bulk_operations_handler_field_operations.inc

@@ -57,15 +57,32 @@ class views_bulk_operations_handler_field_operations extends views_handler_field
         'enable_select_all_pages' => array('default' => TRUE),
         'force_single' => array('default' => FALSE),
         'entity_load_capacity' => array('default' => 10),
+        'skip_batching' => array('default' => 0),
       ),
     );
     $options['vbo_operations'] = array(
       'default' => array(),
+      'unpack_translatable' => 'unpack_operations',
     );
 
     return $options;
   }
 
+  function unpack_operations(&$translatable, $storage, $option, $definition, $parents, $keys) {
+    $translatable[] = array(
+      'value' => t('- Choose an operation -'),
+      'keys' => array_merge($keys, array('noop')),
+    );
+    foreach ($storage[$option] as $key => $operation) {
+      if (!empty($operation['override_label']) && !empty($operation['label'])) {
+        $translatable[] = array(
+          'value' => $operation['label'],
+          'keys' => array_merge($keys, array($key)),
+        );
+      }
+    }
+  }
+
   function options_form(&$form, &$form_state) {
     parent::options_form($form, $form_state);
 
@@ -102,6 +119,12 @@ class views_bulk_operations_handler_field_operations extends views_handler_field
       '#description' => t("Improve execution performance at the cost of memory usage. Set to '1' if you're having problems."),
       '#default_value' => $this->options['vbo_settings']['entity_load_capacity'],
     );
+    $form['vbo_settings']['skip_batching'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Skip batching'),
+      '#default_value' => $this->options['vbo_settings']['skip_batching'],
+      '#description' => '<b>' . t('Warning:') . '</b> ' . t('This will cause timeouts for larger amounts of selected items.'),
+    );
 
     // Display operations and their settings.
     $form['vbo_operations'] = array(
@@ -142,7 +165,7 @@ class views_bulk_operations_handler_field_operations extends views_handler_field
         ),
       );
 
-      $form['vbo_operations'][$operation_id] += $operation->adminOptionsForm($dom_id);
+      $form['vbo_operations'][$operation_id] += $operation->adminOptionsForm($dom_id, $this);
     }
   }
 

+ 4 - 3
sites/all/modules/contrib/views/views_bulk_operations/views_bulk_operations.info

@@ -4,13 +4,14 @@ dependencies[] = entity
 dependencies[] = views
 package = Views
 core = 7.x
+php = 5.2.9
 
 files[] = plugins/operation_types/base.class.php
 files[] = views/views_bulk_operations_handler_field_operations.inc
 
-; Information added by drupal.org packaging script on 2012-12-03
-version = "7.x-3.1"
+; Information added by Drupal.org packaging script on 2013-12-23
+version = "7.x-3.2"
 core = "7.x"
 project = "views_bulk_operations"
-datestamp = "1354500015"
+datestamp = "1387798183"
 

+ 145 - 85
sites/all/modules/contrib/views/views_bulk_operations/views_bulk_operations.module

@@ -45,10 +45,12 @@ function views_bulk_operations_load_action_includes() {
   $files = array(
     'archive.action.inc',
     'argument_selector.action.inc',
+    'book.action.inc',
     'delete.action.inc',
     'modify.action.inc',
     'script.action.inc',
     'user_roles.action.inc',
+    'user_cancel.action.inc',
   );
 
   if (!$loaded) {
@@ -110,7 +112,7 @@ function views_bulk_operations_theme() {
       'variables' => array('view' => NULL, 'enable_select_all_pages' => TRUE),
     ),
     'views_bulk_operations_confirmation' => array(
-      'variables' => array('rows' => NULL, 'vbo' => NULL),
+      'variables' => array('rows' => NULL, 'vbo' => NULL, 'operation' => NULL, 'select_all_pages' => FALSE),
     ),
   );
   $files = views_bulk_operations_load_action_includes();
@@ -300,6 +302,29 @@ function views_bulk_operations_form_alter(&$form, &$form_state, $form_id) {
     return;
   }
 
+  // Add basic VBO functionality.
+  if ($form_state['step'] == 'views_form_views_form') {
+    // The submit button added by Views Form API might be used by a non-VBO Views
+    // Form handler. If there's no such handler on the view, hide the button.
+    $has_other_views_form_handlers = FALSE;
+    foreach ($vbo->view->field as $field) {
+      if (property_exists($field, 'views_form_callback') || method_exists($field, 'views_form')) {
+        if (!($field instanceof views_bulk_operations_handler_field_operations)) {
+          $has_other_views_form_handlers = TRUE;
+        }
+      }
+    }
+    if (!$has_other_views_form_handlers) {
+      $form['actions']['#access'] = FALSE;
+    }
+    // The VBO field is excluded from display, stop here.
+    if (!empty($vbo->options['exclude'])) {
+      return;
+    }
+
+    $form = views_bulk_operations_form($form, $form_state, $vbo);
+  }
+
   // Cache the built form to prevent it from being rebuilt prior to validation
   // and submission, which could lead to data being processed incorrectly,
   // because the views rows (and thus, the form elements as well) have changed
@@ -319,15 +344,25 @@ function views_bulk_operations_form_alter(&$form, &$form_state, $form_id) {
     }
   }
 
-  // Add basic VBO functionality.
-  if ($form_state['step'] == 'views_form_views_form') {
-    $form = views_bulk_operations_form($form, $form_state, $vbo);
-  }
-
   // Give other modules a chance to alter the form.
   drupal_alter('views_bulk_operations_form', $form, $form_state, $vbo);
 }
 
+/**
+ * Implements hook_views_post_build().
+ *
+ * Hides the VBO field if no operations are available.
+ * This causes the entire VBO form to be hidden.
+ *
+ * @see views_bulk_operations_form_alter().
+ */
+function views_bulk_operations_views_post_build(&$view) {
+  $vbo = _views_bulk_operations_get_field($view);
+  if ($vbo && $vbo->get_selected_operations() < 1) {
+    $vbo->options['exclude'] = TRUE;
+  }
+}
+
 /**
  * Returns the 'select all' div that gets inserted below the table header row
  * (for table style plugins with grouping disabled), or above the view results
@@ -409,7 +444,12 @@ function theme_views_bulk_operations_select_all($variables) {
 function views_bulk_operations_form($form, &$form_state, $vbo) {
   $form['#attached']['js'][] = drupal_get_path('module', 'views_bulk_operations') . '/js/views_bulk_operations.js';
   $form['#attached']['css'][] = drupal_get_path('module', 'views_bulk_operations') . '/css/views_bulk_operations.css';
-  $form['#prefix'] = '<div class="vbo-views-form">';
+  // Wrap the form in a div with specific classes for JS targeting and theming.
+  $class = 'vbo-views-form';
+  if (empty($vbo->view->result)) {
+    $class .= ' vbo-views-form-empty';
+  }
+  $form['#prefix'] = '<div class="' . $class . '">';
   $form['#suffix'] = '</div>';
 
   // Force browser to reload the page if Back is hit.
@@ -426,25 +466,10 @@ function views_bulk_operations_form($form, &$form_state, $vbo) {
     '#attributes' => array('class' => 'select-all-rows'),
     '#default_value' => FALSE,
   );
-
-  // The submit button added by Views Form API might be used by a non-VBO Views
-  // Form handler. If there's no such handler on the view, hide the button.
-  $has_other_views_form_handlers = FALSE;
-  foreach ($vbo->view->field as $field) {
-    if (property_exists($field, 'views_form_callback') || method_exists($field, 'views_form')) {
-      if (!($field instanceof views_bulk_operations_handler_field_operations)) {
-        $has_other_views_form_handlers = TRUE;
-      }
-    }
-  }
-  if (!$has_other_views_form_handlers) {
-    $form['actions']['submit']['#access'] = FALSE;
-  }
-
   $form['select'] = array(
     '#type' => 'fieldset',
     '#title' => t('Operations'),
-    '#collapsible' => TRUE,
+    '#collapsible' => FALSE,
     '#attributes' => array('class' => array('container-inline')),
   );
   if ($vbo->get_vbo_option('display_type') == 0) {
@@ -573,7 +598,7 @@ function views_bulk_operations_confirm_form($form, &$form_state, $view, $output)
   $form = confirm_form($form,
     t('Are you sure you want to perform %operation on the selected items?', array('%operation' => $operation->label())),
     array('path' => $view->get_url(), 'query' => $query),
-    theme('views_bulk_operations_confirmation', array('rows' => $rows, 'vbo' => $vbo, 'select_all_pages' => $form_state['select_all_pages']))
+    theme('views_bulk_operations_confirmation', array('rows' => $rows, 'vbo' => $vbo, 'operation' => $operation, 'select_all_pages' => $form_state['select_all_pages']))
   );
   // Add VBO's submit handler to the Confirm button added by config_form().
   $form['actions']['submit']['#submit'] = array('views_bulk_operations_form_submit');
@@ -676,8 +701,8 @@ function views_bulk_operations_form_submit($form, &$form_state) {
  * Entry point for executing the chosen operation upon selected rows.
  *
  * If the selected operation is an aggregate operation (requiring all selected
- * items to be passed at the same time), or the execution is being triggered
- * through Drush, the operation is executed directly.
+ * items to be passed at the same time), restricted to a single value, or has
+ * the skip_batching option set, the operation is executed directly.
  * This means that there is no batching & queueing, the PHP execution
  * time limit is ignored (if allowed), all selected entities are loaded and
  * processed.
@@ -703,9 +728,13 @@ function views_bulk_operations_form_submit($form, &$form_state) {
 function views_bulk_operations_execute($vbo, $operation, $selection, $select_all_pages = FALSE) {
   global $user;
 
-  // This is an aggregate operation, and it requires all rows to be selected.
-  // Try to load them without a batch.
-  if ($operation->aggregate() && $select_all_pages) {
+  // Determine if the operation needs to be executed directly.
+  $aggregate = $operation->aggregate();
+  $skip_batching = $vbo->get_vbo_option('skip_batching');
+  $force_single = $vbo->get_vbo_option('force_single');
+  $execute_directly = ($aggregate || $skip_batching || $force_single);
+  // Try to load all rows without a batch if needed.
+  if ($execute_directly && $select_all_pages) {
     views_bulk_operations_direct_adjust($selection, $vbo);
   }
 
@@ -713,6 +742,15 @@ function views_bulk_operations_execute($vbo, $operation, $selection, $select_all
   $options = array(
     'revision' => $vbo->revision,
     'entity_load_capacity' => $vbo->get_vbo_option('entity_load_capacity', 10),
+    // The information needed to recreate the view, to avoid serializing the
+    // whole object. Passed to the executed operation. Also used by
+    // views_bulk_operations_adjust_selection().
+    'view_info' => array(
+      'name' => $vbo->view->name,
+      'display' => $vbo->view->current_display,
+      'arguments' => $vbo->view->args,
+      'exposed_input' => $vbo->view->get_exposed_input(),
+    ),
   );
   // Create an array of rows in the needed format.
   $rows = array();
@@ -735,8 +773,8 @@ function views_bulk_operations_execute($vbo, $operation, $selection, $select_all
     }
   }
 
-  // Aggregate operations can only be executed directly.
-  if ($operation->aggregate()) {
+  if ($execute_directly) {
+    // Execute the operation directly and stop here.
     views_bulk_operations_direct_process($operation, $rows, $options);
     return;
   }
@@ -763,18 +801,8 @@ function views_bulk_operations_execute($vbo, $operation, $selection, $select_all
   if ($select_all_pages && $vbo->view->query->pager->has_more_records()) {
     $total_rows = $vbo->view->total_rows;
 
-    // Pass information needed to recreate the view inside a batch,
-    // to avoid having to serialize the current object (which is expensive).
-    $view_info = array(
-      'name' => $vbo->view->name,
-      'display' => $vbo->view->current_display,
-      'arguments' => $vbo->view->args,
-      'exposed_input' => $vbo->view->get_exposed_input(),
-      'entity_load_capacity' => $vbo->get_vbo_option('entity_load_capacity', 10),
-    );
-
     $batch['operations'][] = array(
-      'views_bulk_operations_adjust_selection', array($view_info, $queue_name, $operation, $options),
+      'views_bulk_operations_adjust_selection', array($queue_name, $operation, $options),
     );
   }
   else {
@@ -808,22 +836,21 @@ function views_bulk_operations_execute($vbo, $operation, $selection, $select_all
 /**
  * Batch API callback: loads the view page by page and enqueues all items.
  *
- * @param $view_info
- *   An array of information about the view, used to recreate and re-execute it.
  * @param $queue_name
  *   The name of the queue to which the items should be added.
  * @param $operation
  *   The operation object.
  * @param $options
- *   An array of options that affect execution (revision, entity_load_capacity).
- *   Passed along with each new queue item.
+ *   An array of options that affect execution (revision, entity_load_capacity,
+ *   view_info). Passed along with each new queue item.
  */
-function views_bulk_operations_adjust_selection($view_info, $queue_name, $operation, $options, &$context) {
+function views_bulk_operations_adjust_selection($queue_name, $operation, $options, &$context) {
   if (!isset($context['sandbox']['progress'])) {
     $context['sandbox']['progress'] = 0;
     $context['sandbox']['max'] = 0;
   }
 
+  $view_info = $options['view_info'];
   $view = views_get_view($view_info['name']);
   $view->set_exposed_input($view_info['exposed_input']);
   $view->set_arguments($view_info['arguments']);
@@ -927,7 +954,7 @@ function views_bulk_operations_active_queue_process($queue_name, $operation, $to
   static $queue;
 
   // It is still possible to hit the time limit.
-  @set_time_limit(0);
+  drupal_set_time_limit(0);
 
   // Prepare the sandbox.
   if (!isset($context['sandbox']['progress'])) {
@@ -980,19 +1007,35 @@ function views_bulk_operations_queue_item_process($queue_item_data, &$log = NULL
   $account = user_load($queue_item_data['uid']);
   $entity_type = $operation->entityType;
   $entity_ids = array();
-  foreach ($row_group as $row_id => $row) {
+  foreach ($row_group as $row_index => $row) {
     $entity_ids[] = $row['entity_id'];
   }
 
   $entities = _views_bulk_operations_entity_load($entity_type, $entity_ids, $options['revision']);
-  foreach ($row_group as $row_id => $row) {
+  foreach ($row_group as $row_index => $row) {
     $entity_id = $row['entity_id'];
     // A matching entity couldn't be loaded. Skip this item.
     if (!isset($entities[$entity_id])) {
       continue;
     }
 
-    $entity = $entities[$entity_id];
+    if ($options['revision']) {
+      // Don't reload revisions for now, they are not statically cached and
+      // usually don't run into the edge case described below.
+      $entity = $entities[$entity_id];
+    }
+    else {
+      // A previous action might have resulted in the entity being resaved
+      // (e.g. node synchronization from a prior node in this batch), so try
+      // to reload it. If no change occurred, the entity will be retrieved
+      // from the static cache, resulting in no performance penalty.
+      $entity = entity_load_single($entity_type, $entity_id);
+      if (empty($entity)) {
+        // The entity is no longer valid.
+        continue;
+      }
+    }
+
     // If the current entity can't be accessed, skip it and log a notice.
     if (!_views_bulk_operations_entity_access($operation, $entity_type, $entity, $account)) {
       $message = 'Skipped %operation on @type %title due to insufficient permissions.';
@@ -1014,11 +1057,14 @@ function views_bulk_operations_queue_item_process($queue_item_data, &$log = NULL
 
     $operation_context = array(
       'progress' => $row['position'],
-      'rows' => $row['views_row'],
+      'view_info' => $options['view_info'],
     );
+    if ($operation->needsRows()) {
+      $operation_context['rows'] = array($row_index => $row['views_row']);
+    }
     $operation->execute($entity, $operation_context);
 
-    unset($row_group[$row_id]);
+    unset($row_group[$row_index]);
   }
 }
 
@@ -1055,11 +1101,11 @@ function views_bulk_operations_direct_adjust(&$selection, $vbo) {
 
 /**
  * Processes the passed rows directly (without batching and queueing).
- *
- * This is a legacy function that is now only used for aggregate operations.
  */
 function views_bulk_operations_direct_process($operation, $rows, $options) {
-  @set_time_limit(0);
+  global $user;
+
+  drupal_set_time_limit(0);
 
   // Prepare an array of status information. Imitates the Batch API naming
   // for consistency. Passed to views_bulk_operations_execute_finished().
@@ -1067,42 +1113,56 @@ function views_bulk_operations_direct_process($operation, $rows, $options) {
   $context['results']['progress'] = 0;
   $context['results']['log'] = array();
 
-  $entity_type = $operation->entityType;
-  $entity_ids = array();
-  foreach ($rows as $row_index => $row) {
-    $entity_ids[] = $row['entity_id'];
-  }
-  $entities = _views_bulk_operations_entity_load($entity_type, $entity_ids, $options['revision']);
-
-  foreach ($entities as $id => $entity) {
-    if (!_views_bulk_operations_entity_access($operation, $entity_type, $entity)) {
-      $context['results']['log'][] = t('Skipped %operation on @type %title due to insufficient permissions.', array(
-        '%operation' => $operation->label(),
-        '@type' => $entity_type,
-        '%title' => _views_bulk_operations_entity_label($entity_type, $entity),
-      ));
-      unset($entities[$id]);
+  if ($operation->aggregate()) {
+    // Load all entities.
+    $entity_type = $operation->entityType;
+    $entity_ids = array();
+    foreach ($rows as $row_index => $row) {
+      $entity_ids[] = $row['entity_id'];
+    }
+    $entities = _views_bulk_operations_entity_load($entity_type, $entity_ids, $options['revision']);
+
+    // Filter out entities that can't be accessed.
+    foreach ($entities as $id => $entity) {
+      if (!_views_bulk_operations_entity_access($operation, $entity_type, $entity)) {
+        $context['results']['log'][] = t('Skipped %operation on @type %title due to insufficient permissions.', array(
+          '%operation' => $operation->label(),
+          '@type' => $entity_type,
+          '%title' => _views_bulk_operations_entity_label($entity_type, $entity),
+        ));
+        unset($entities[$id]);
+      }
     }
-  }
-  if (empty($entities)) {
-    return;
-  }
 
-  // Pass the selected rows to the operation if needed.
-  $operation_context = array();
-  if ($operation->needsRows()) {
-    $operation_context['rows'] = array();
-    foreach ($rows as $row_index => $row) {
-      $operation_context['rows'][$row_index] = $row['views_row'];
+    // If there are any entities left, execute the operation on them.
+    if ($entities) {
+      $operation_context = array(
+        'view_info' => $options['view_info'],
+      );
+      // Pass the selected rows to the operation if needed.
+      if ($operation->needsRows()) {
+        $operation_context['rows'] = array();
+        foreach ($rows as $row_index => $row) {
+          $operation_context['rows'][$row_index] = $row['views_row'];
+        }
+      }
+      $operation->execute($entities, $operation_context);
     }
   }
-  $operation->execute($entities, $operation_context);
+  else {
+    // Imitate a queue and process the entities one by one.
+    $queue_item_data = array(
+      'uid' => $user->uid,
+      'arguments' => array($rows, $operation, $options),
+    );
+    views_bulk_operations_queue_item_process($queue_item_data, $context['results']['log']);
+  }
 
-  $context['results']['log'][] = t('Performed aggregate %operation on @items.', array(
+  $context['results']['progress'] += count($rows);
+  $context['results']['log'][] = t('Performed %operation on @items.', array(
     '%operation' => $operation->label(),
-    '@items' => format_plural(count($entities), '1 item', '@count items'),
+    '@items' => format_plural(count($rows), '1 item', '@count items'),
   ));
-  $context['results']['progress'] += count($entities);
 
   views_bulk_operations_execute_finished(TRUE, $context['results'], array());
 }

+ 7 - 7
sites/all/modules/contrib/views/views_bulk_operations/views_bulk_operations.rules.inc

@@ -113,8 +113,9 @@ function views_bulk_operations_rules_action_info() {
  */
 function views_bulk_operations_views_list() {
   $selectable_displays = array();
-  foreach (views_get_enabled_views() as $name => $view) {
-    foreach ($view->display as $display_name => $display) {
+  foreach (views_get_enabled_views() as $name => $base_view) {
+    foreach ($base_view->display as $display_name => $display) {
+      $view = $base_view->clone_view();
       $view->build($display_name);
       $vbo = _views_bulk_operations_get_field($view);
       if ($vbo) {
@@ -158,13 +159,12 @@ function views_bulk_operations_condition_result_count($view, $args, $minimum) {
 function views_bulk_operations_action_load_list($view, $args) {
   $vbo = _views_bulk_operations_rules_get_field($view, $args);
 
-  // Get all entity ids.
-  $ids = array();
+  // Get all entities, pass ids to the wrapper for lazy loading.
+  $entity_type = $vbo->get_entity_type();
+  $entities = entity_metadata_wrapper("list<$entity_type>", array());
   foreach ($vbo->view->result as $row_index => $result) {
-    $ids[] = $vbo->get_value($result);
+    $entities[] = entity_metadata_wrapper($entity_type, $vbo->get_value($result));
   }
-  // And load the entity objects.
-  $entities = entity_load($vbo->get_entity_type(), $ids);
 
   return array('entity_list' => $entities);
 }

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

@@ -53,7 +53,7 @@ class views_php_plugin_access extends views_plugin_access {
    */
   function access($account) {
     if (!empty($this->options['php_access'])) {
-      return views_php_check_access($this->options['php_access'], $this->view->name, $this->view->current_display, $account);
+      return views_php_check_access($this->options['php_access'], $this->view->name, $this->display->id, $account);
     }
     return TRUE;
   }
@@ -63,7 +63,7 @@ class views_php_plugin_access extends views_plugin_access {
    */
   function get_access_callback() {
     if (!empty($this->options['php_access'])) {
-      return array('views_php_check_access', array($this->options['php_access'], $this->view->name, $this->view->current_display));
+      return array('views_php_check_access', array($this->options['php_access'], $this->view->name, $this->display->id));
     }
     return TRUE;
   }

+ 7 - 0
sites/all/modules/contrib/views/views_php/plugins/views/views_php_plugin_cache.inc

@@ -43,6 +43,13 @@ class views_php_plugin_cache extends views_plugin_cache {
     );
   }
 
+  /**
+   * Implements views_plugin#options_submit()
+   */
+  function options_submit(&$form, &$form_state) {
+    $form_state['values']['cache_options'] += $form_state['values']['options'];
+  }
+
   /**
    * Implements views_plugin_cache#cache_get()
    */

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

@@ -15,9 +15,9 @@ files[] = plugins/views/views_php_plugin_pager.inc
 files[] = plugins/views/views_php_plugin_query.inc
 files[] = plugins/views/views_php_plugin_wrapper.inc
 
-; Information added by drupal.org packaging script on 2013-09-11
-version = "7.x-1.x-dev"
+; Information added by Drupal.org packaging script on 2014-05-08
+version = "7.x-1.0-alpha1+2-dev"
 core = "7.x"
 project = "views_php"
-datestamp = "1378900545"
+datestamp = "1399543127"
 

+ 2 - 0
sites/all/modules/contrib/views/views_php/views_php.views.inc

@@ -41,6 +41,7 @@ function views_php_views_plugins() {
       'php' => array(
         'title' => t('PHP'),
         'help' => t('Use PHP code to grant access.'),
+        'help topic' => '',
         'handler' => 'views_php_plugin_access',
         'uses options' => TRUE,
       ),
@@ -49,6 +50,7 @@ function views_php_views_plugins() {
       'php' => array(
         'title' => t('PHP'),
         'help' => t('Use PHP code to determine whether a should be cached.'),
+        'help topic' => '',
         'handler' => 'views_php_plugin_cache',
         'uses options' => TRUE,
       ),