Browse Source

updated node_export, mimemail, menu_attributes

Bachir Soussi Chiadmi 7 years ago
parent
commit
fdefc824d8
50 changed files with 1597 additions and 1554 deletions
  1. 3 3
      sites/all/modules/contrib/admin/menu_attributes/menu_attributes.info
  2. 5 2
      sites/all/modules/contrib/admin/menu_attributes/menu_attributes.module
  3. 1 1
      sites/all/modules/contrib/admin/node_export/README.txt
  4. 20 20
      sites/all/modules/contrib/admin/node_export/formats/dsv.inc
  5. 4 1
      sites/all/modules/contrib/admin/node_export/formats/xml.inc
  6. 17 0
      sites/all/modules/contrib/admin/node_export/modules/node_export_book/node_export_book.info
  7. 212 0
      sites/all/modules/contrib/admin/node_export/modules/node_export_book/node_export_book.module
  8. 132 0
      sites/all/modules/contrib/admin/node_export/modules/node_export_book/node_export_book_utils.inc
  9. 19 0
      sites/all/modules/contrib/admin/node_export/modules/node_export_dependency/node_export_dependency.core.inc
  10. 3 3
      sites/all/modules/contrib/admin/node_export/modules/node_export_dependency/node_export_dependency.info
  11. 135 16
      sites/all/modules/contrib/admin/node_export/modules/node_export_dependency/node_export_dependency.module
  12. 3 3
      sites/all/modules/contrib/admin/node_export/modules/node_export_features/node_export_features.info
  13. 30 2
      sites/all/modules/contrib/admin/node_export/modules/node_export_features/node_export_features.module
  14. 59 0
      sites/all/modules/contrib/admin/node_export/modules/node_export_features_ui/README.txt
  15. 15 0
      sites/all/modules/contrib/admin/node_export/modules/node_export_features_ui/node_export_features_ui.info
  16. 24 0
      sites/all/modules/contrib/admin/node_export/modules/node_export_features_ui/node_export_features_ui.install
  17. 85 0
      sites/all/modules/contrib/admin/node_export/modules/node_export_features_ui/node_export_features_ui.module
  18. 167 0
      sites/all/modules/contrib/admin/node_export/modules/node_export_features_ui/node_export_features_ui.pages.inc
  19. 4 1
      sites/all/modules/contrib/admin/node_export/modules/node_export_feeds/FeedsNodeExportProcessor.inc
  20. 3 3
      sites/all/modules/contrib/admin/node_export/modules/node_export_feeds/node_export_feeds.info
  21. 5 1
      sites/all/modules/contrib/admin/node_export/modules/node_export_feeds/node_export_feeds.module
  22. 3 3
      sites/all/modules/contrib/admin/node_export/modules/node_export_relation/node_export_relation.info
  23. 4 4
      sites/all/modules/contrib/admin/node_export/modules/node_export_relation/node_export_relation.node_reference.inc
  24. 0 13
      sites/all/modules/contrib/admin/node_export/node_export-1911638_2.patch
  25. 5 3
      sites/all/modules/contrib/admin/node_export/node_export.info
  26. 19 4
      sites/all/modules/contrib/admin/node_export/node_export.install
  27. 206 55
      sites/all/modules/contrib/admin/node_export/node_export.module
  28. 0 1297
      sites/all/modules/contrib/admin/node_export/node_export.module.orig
  29. 1 1
      sites/all/modules/contrib/admin/node_export/node_export.pages.inc
  30. 109 0
      sites/all/modules/contrib/admin/node_export/node_export.test
  31. 1 1
      sites/all/modules/contrib/admin/node_export/node_export.tokens.inc
  32. 3 8
      sites/all/modules/contrib/admin/node_export/views/views_handler_field_node_link_export.inc
  33. 0 56
      sites/all/modules/contrib/admin/node_export/views_bulk_operations_node_export_fails_with_undefined_function-1869918-33.patch
  34. 16 0
      sites/all/modules/contrib/mail/mimemail/CHANGELOG.txt
  35. 11 7
      sites/all/modules/contrib/mail/mimemail/README.txt
  36. 4 0
      sites/all/modules/contrib/mail/mimemail/includes/mimemail.admin.inc
  37. 24 19
      sites/all/modules/contrib/mail/mimemail/mimemail.inc
  38. 3 3
      sites/all/modules/contrib/mail/mimemail/mimemail.info
  39. 2 7
      sites/all/modules/contrib/mail/mimemail/mimemail.install
  40. 1 0
      sites/all/modules/contrib/mail/mimemail/mimemail.module
  41. 10 3
      sites/all/modules/contrib/mail/mimemail/mimemail.rules.inc
  42. 3 3
      sites/all/modules/contrib/mail/mimemail/modules/mimemail_action/mimemail_action.info
  43. 5 1
      sites/all/modules/contrib/mail/mimemail/modules/mimemail_action/mimemail_action.module
  44. 1 1
      sites/all/modules/contrib/mail/mimemail/modules/mimemail_compress/mimemail_compress.inc
  45. 3 3
      sites/all/modules/contrib/mail/mimemail/modules/mimemail_compress/mimemail_compress.info
  46. 12 0
      sites/all/modules/contrib/mail/mimemail/modules/mimemail_example/mimemail_example.info
  47. 20 0
      sites/all/modules/contrib/mail/mimemail/modules/mimemail_example/mimemail_example.install
  48. 170 0
      sites/all/modules/contrib/mail/mimemail/modules/mimemail_example/mimemail_example.module
  49. 7 3
      sites/all/modules/contrib/mail/mimemail/tests/mimemail.test
  50. 8 3
      sites/all/modules/contrib/mail/mimemail/tests/mimemail_rules.test

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

@@ -6,9 +6,9 @@ configure = admin/structure/menu/settings
 
 files[] = menu_attributes.test
 
-; Information added by Drupal.org packaging script on 2015-01-02
-version = "7.x-1.0-rc3+1-dev"
+; Information added by Drupal.org packaging script on 2016-02-15
+version = "7.x-1.0"
 core = "7.x"
 project = "menu_attributes"
-datestamp = "1420231982"
+datestamp = "1455568740"
 

+ 5 - 2
sites/all/modules/contrib/admin/menu_attributes/menu_attributes.module

@@ -16,7 +16,7 @@ function menu_attributes_permission() {
   return array(
     'administer menu attributes' => array(
       'title' => t('Administer menu attributes'),
-      'description' => t('Administer menu attributes.'),
+      'description' => t('Administer menu attributes configuration.'),
     ),
   );
 }
@@ -255,6 +255,9 @@ function _menu_attributes_form_alter(array &$form, array $item = array(), array
   $has_visible_children = (bool) element_get_visible_children($form['options']['attributes']);
   $user_has_access = user_access('administer menu attributes');
   $form['options']['attributes']['#access'] = ($has_visible_children && $user_has_access);
+
+  $has_visible_children = (bool) element_get_visible_children($form['options']['item_attributes']);
+  $form['options']['item_attributes']['#access'] = ($has_visible_children && $user_has_access);
 }
 
 /**
@@ -337,7 +340,7 @@ function menu_attributes_preprocess_menu_link(&$variables) {
         // Class get's special treatment, as it's an array and it should not
         // replace existing values.
         if ($attribute == 'class') {
-          $value = explode(' ', $value);
+          $value = !is_array($value) ? explode(' ', $value) : $value;
           if (isset($attributes[$attribute])) {
             $value = array_merge($attributes[$attribute], $value);
           }

+ 1 - 1
sites/all/modules/contrib/admin/node_export/README.txt

@@ -88,6 +88,6 @@ Regarding the Node export features module which integrates with the Features
 module, any nodes to be used with this must have a UUID (universally unique 
 ID).  To export older nodes that don't have UUID make sure you have selected
 the content type and click on 'create missings uuids' from 
-'admin/settings/uuid' under the fieldset 'Synchronize'.  Then you should be 
+'admin/config/system/uuid' under the fieldset 'Synchronize'.  Then you should be
 able to see more nodes under the feature component, If you don't see the node
 export component, that means no nodes has been configured with UUID.

+ 20 - 20
sites/all/modules/contrib/admin/node_export/formats/dsv.inc

@@ -18,7 +18,7 @@ function node_export_dsv_settings($form, $form_state) {
      'Select how your DSV output will be formatted - this must be configured the
      same on both sites.  By default this is configured to RFC4180 CSV format
      where the delimiter is a comma (,), the enclosure is a double-quote ("),
-     and the seperator is CRLF (\r\n).  Not all configurations may be possible,
+     and the separator is CRLF (\r\n).  Not all configurations may be possible,
      use wisely.  Enclosure will only be used to escape values that contain any
      of the configured strings.  Additionally single-quotes will be used to
      escape values that are equivalent to reserved words (NULL, TRUE, FALSE).'
@@ -45,12 +45,12 @@ function node_export_dsv_settings($form, $form_state) {
     '#required' => TRUE,
   );
 
-  $settings['dsv']['node_export_dsv_seperator'] = array(
+  $settings['dsv']['node_export_dsv_separator'] = array(
     '#type' => 'textfield',
-    '#title' => t('Record seperator'),
+    '#title' => t('Record separator'),
     '#size' => 5,
     '#maxlength' => 255,
-    '#default_value' => variable_get('node_export_dsv_seperator', '\r\n'),
+    '#default_value' => variable_get('node_export_dsv_separator', '\r\n'),
     '#required' => TRUE,
   );
 
@@ -82,15 +82,15 @@ function node_export_dsv_string($string) {
 function node_export_dsv_export($nodes, $format) {
   $delimiter = node_export_dsv_string(variable_get('node_export_dsv_delimiter', ','));
   $enclosure = node_export_dsv_string(variable_get('node_export_dsv_enclosure', '"'));
-  $seperator = node_export_dsv_string(variable_get('node_export_dsv_seperator', '\r\n'));
+  $separator = node_export_dsv_string(variable_get('node_export_dsv_separator', '\r\n'));
   $escape_eol = variable_get('node_export_dsv_escape_eol', 1);
-  return node_export_dsv_encode($nodes, $delimiter, $enclosure, $seperator, $escape_eol);
+  return node_export_dsv_encode($nodes, $delimiter, $enclosure, $separator, $escape_eol);
 }
 
 /**
  * Build DSV string.
  */
-function node_export_dsv_encode($nodes, $delimiter, $enclosure, $seperator, $escape_eol) {
+function node_export_dsv_encode($nodes, $delimiter, $enclosure, $separator, $escape_eol) {
   $encoded_nodes = array();
   $dsv_lines = array();
 
@@ -110,7 +110,7 @@ function node_export_dsv_encode($nodes, $delimiter, $enclosure, $seperator, $esc
     }
   }
 
-  return node_export_dsv_array_to_dsv($dsv_lines, $delimiter, $enclosure, $seperator, $escape_eol);
+  return node_export_dsv_array_to_dsv($dsv_lines, $delimiter, $enclosure, $separator, $escape_eol);
 }
 
 /**
@@ -199,16 +199,16 @@ function node_export_dsv_encode_header_value($parents, $var, $k) {
 function node_export_dsv_import($code_string) {
   $delimiter = node_export_dsv_string(variable_get('node_export_dsv_delimiter', ','));
   $enclosure = node_export_dsv_string(variable_get('node_export_dsv_enclosure', '"'));
-  $seperator = node_export_dsv_string(variable_get('node_export_dsv_seperator', '\r\n'));
-  return node_export_dsv_decode($code_string, $delimiter, $enclosure, $seperator);
+  $separator = node_export_dsv_string(variable_get('node_export_dsv_separator', '\r\n'));
+  return node_export_dsv_decode($code_string, $delimiter, $enclosure, $separator);
 }
 
 /**
  *  Interpret a DSV string.
  */
-function node_export_dsv_decode($code_string, $delimiter, $enclosure, $seperator) {
+function node_export_dsv_decode($code_string, $delimiter, $enclosure, $separator) {
   // Get array data from DSV.
-  $array = @node_export_dsv_dsv_to_array($code_string, $delimiter, $enclosure, $seperator);
+  $array = @node_export_dsv_dsv_to_array($code_string, $delimiter, $enclosure, $separator);
 
   // If the first two rows are of equal length, we can assume this is a DSV.
   // Also checks there are a decent number of fields.
@@ -235,7 +235,7 @@ function node_export_dsv_decode($code_string, $delimiter, $enclosure, $seperator
 /**
  *  Encode DSV.
  */
-function node_export_dsv_array_to_dsv($array, $delimiter, $enclosure, $seperator, $escape_eol) {
+function node_export_dsv_array_to_dsv($array, $delimiter, $enclosure, $separator, $escape_eol) {
   $lines = array();
   foreach ($array as $line) {
     $out_item = array();
@@ -246,7 +246,7 @@ function node_export_dsv_array_to_dsv($array, $delimiter, $enclosure, $seperator
       if (
         (stripos($item, $delimiter) !== FALSE)
         || (stripos($item, $enclosure) !== FALSE)
-        || (stripos($item, $seperator) !== FALSE)
+        || (stripos($item, $separator) !== FALSE)
         || ($escape_eol && stripos($item, "\n") !== FALSE)
       ) {
         $item = $enclosure . $item . $enclosure;
@@ -255,13 +255,13 @@ function node_export_dsv_array_to_dsv($array, $delimiter, $enclosure, $seperator
     }
     $lines[] = implode($delimiter, $out_item);
   }
-  return implode($seperator, $lines);
+  return implode($separator, $lines);
 }
 
 /**
  *  Decode DSV.
  */
-function node_export_dsv_dsv_to_array($string, $delimiter, $enclosure, $seperator) {
+function node_export_dsv_dsv_to_array($string, $delimiter, $enclosure, $separator) {
   $lines = array();
   $out_item = array();
   $count = strlen($string);
@@ -269,15 +269,15 @@ function node_export_dsv_dsv_to_array($string, $delimiter, $enclosure, $seperato
   $double_escape = FALSE;
   $position = 0;
   $i = 0;
-  $seperators = str_split($seperator);
+  $separators = str_split($separator);
 
   while ($i < $count) {
     $c = $string[$i];
 
     // Determine whether this is an EOL.
     $is_eol = TRUE;
-    for ($j = 0; $j < count($seperators); $j++) {
-      if (!isset($string[$i + $j]) || $string[$i + $j] != $seperators[$j]) {
+    for ($j = 0; $j < count($separators); $j++) {
+      if (!isset($string[$i + $j]) || $string[$i + $j] != $separators[$j]) {
         $is_eol = FALSE;
         break;
       }
@@ -288,7 +288,7 @@ function node_export_dsv_dsv_to_array($string, $delimiter, $enclosure, $seperato
         $out_item[$position] .= $c;
       }
       else {
-        $i += count($seperators);
+        $i += count($separators);
         $lines[] = $out_item;
         $out_item = array();
         $position = 0;

+ 4 - 1
sites/all/modules/contrib/admin/node_export/formats/xml.inc

@@ -189,6 +189,9 @@ class NodeExportXmlDecoder {
           return NULL;
         }
       }
+      elseif (!empty($stack['attributes']['_NUMERIC_KEYS'])) {
+        return array();
+      }
       return htmlspecialchars_decode(trim($stack['data']));
     }
     else {
@@ -229,4 +232,4 @@ class NodeExportXmlDecoder {
  */
 function node_export_xml_action_form($context, &$form_state) {
   return node_export_action_form($context, $form_state, 'xml');
-}
+}

+ 17 - 0
sites/all/modules/contrib/admin/node_export/modules/node_export_book/node_export_book.info

@@ -0,0 +1,17 @@
+name = "Node export book"
+description = "Adds Book support to Node export"
+core = 7.x
+dependencies[] = book
+dependencies[] = node_export
+files[] = node_export_book.module
+files[] = node_export_book_utils.inc
+package = "Node export"
+project = node_export
+
+
+; Information added by Drupal.org packaging script on 2016-03-04
+version = "7.x-3.1"
+core = "7.x"
+project = "node_export"
+datestamp = "1457077222"
+

+ 212 - 0
sites/all/modules/contrib/admin/node_export/modules/node_export_book/node_export_book.module

@@ -0,0 +1,212 @@
+<?php
+/**
+ * @file
+ *   Adds Book support to the Node export module.
+ */
+
+/**
+ * Implements hook_node_export_node_alter().
+ */
+function node_export_book_node_export_node_alter(&$node, $original_node) {
+  module_load_include('inc', 'node_export_book', 'node_export_book_utils');
+
+  // Throw errors if the node doesn't have a UUID
+  if (module_exists('uuid') and drupal_strlen(_node_export_book_nid_to_uuid($node->nid)) < 1) {
+    drupal_set_message(t('The node %nid does not have a UUID; unable to export!', array('%nid' => $node->nid)), 'error');
+    watchdog('node_export_book', 'Unable to export %nid because it is missing a UUID.', array('%nid' => $node->nid), WATCHDOG_CRITICAL);
+  }
+  elseif (module_exists('book') and property_exists($original_node, 'book')) {
+    // Create a namespace for our export info in the book node
+    if (!property_exists($node, 'node_export_book')) {
+      $node->node_export_book = array();
+    }
+
+    // Dereference the Parent Link ID (PLID) and write the parent node's UUID
+    if (array_key_exists('plid', $original_node->book) and menu_link_load($original_node->book['plid'])) {
+      $node->node_export_book['#parent_uuid'] = _node_export_book_mlid_to_uuid($original_node->book['plid']);
+    }
+    // Dereference the Book ID (BID) and write the book node's UUID
+    if (array_key_exists('bid', $original_node->book) and node_load($original_node->book['bid'])) {
+      $node->node_export_book['#book_uuid'] = _node_export_book_nid_to_uuid($original_node->book['bid']);
+    }
+    // Add the weight of this page in the book heirarchy
+    if (array_key_exists('weight', $original_node->book)) {
+      $node->node_export_book['weight'] = intval($original_node->book['weight']);
+    }
+    if ($original_node->book['bid'] == $original_node->nid) {
+      $node->node_export_book['#is_root'] = TRUE;
+    }
+    else {
+      $node->node_export_book['#is_root'] = FALSE;
+    }
+
+    // When we're done, unset the book info in the node, so it isn't exported
+    // and book.module on the destination site can't get confused
+    unset($node->book);
+  }
+}
+
+/**
+ * Implements hook_node_export_after_import_alter().
+ */
+function node_export_book_node_export_after_import_alter(&$nodes, $format, $save) {
+  module_load_include('inc', 'node_export_book', 'node_export_book_utils');
+
+  if (module_exists('book')) {
+    // A smaller array of child nodes to parse later
+    $child_nodes = array();
+
+    // Loop through all the nodes, process books, and build a smaller array of nodes to parse later
+    foreach ($nodes as &$node) {
+      if (book_type_is_allowed($node->type) and property_exists($node, 'node_export_book')) {
+        // If this is a root book node, create the book
+        if (array_key_exists('#is_root', $node->node_export_book) and $node->node_export_book['#is_root']) {
+          $node->book = array('bid' => 'new');
+          book_node_update($node);
+        }
+        // Otherwise, it's a child node, so add it to a smaller array of nodes to parse
+        else {
+          $child_nodes[] = &$node;
+        }
+      }
+    }
+
+    // Add each child node to the book as a root item
+    foreach ($child_nodes as &$node) {
+      // Find the root book node
+      $book_nid = _node_export_book_uuid_to_nid($node->node_export_book['#book_uuid']);
+
+      // Set up the data we need to make this node a child of the root book node
+      $node->book = array();
+      $node->book['bid'] = $book_nid;
+      $node->book['plid'] = _node_export_book_nid_to_mlid($book_nid);
+
+      // Also set up the weight
+      $node->book['weight'] = $node->node_export_book['weight'];
+
+      // Add this node to the book
+      book_node_update($node);
+
+      // Derefernce the parent node's UUID to a nid
+      $node->node_export_book['#parent_nid'] = _node_export_book_uuid_to_nid($node->node_export_book['#parent_uuid']);
+    }
+
+    // Re-structure the book as it was on the source site
+    foreach ($child_nodes as &$node) {
+      // Force a reload of the node
+      $updated_node = node_load($node->nid, NULL, TRUE);
+
+      // Update this node's Parent Link ID (PLID)
+      $updated_node->book['plid'] = _node_export_book_nid_to_mlid($node->node_export_book['#parent_nid']);
+
+      // Update the node
+      book_node_update($updated_node);
+    }
+  }
+}
+
+/**
+ * Implements hook_menu().
+ */
+function node_export_book_menu() {
+  $items = array();
+
+  $items['admin/content/book/node_export_book/%node'] = array(
+    'title' => 'Export book',
+    'page callback' => '_node_export_book_run_export',
+    'page arguments' => array(4),
+    'access arguments' => array('export bulk nodes'),
+    'type' => MENU_CALLBACK,
+  );
+
+  return $items;
+}
+
+/**
+ * Helper function to export a book.
+ */
+function _node_export_book_run_export($book_root) {
+  if (module_exists('node_export') and module_exists('book')) {
+    $nids = array();
+
+    // Include some useful utilities
+    module_load_include('inc', 'node_export_book', 'node_export_book_utils');
+    module_load_include('inc', 'node_export', 'node_export.pages');
+
+    // Get a list of all nodes in this book
+    $tree = book_menu_subtree_data(menu_link_load(_node_export_book_nid_to_mlid($book_root->nid)));
+    $nids = _node_export_book_get_nids($tree);
+
+    return node_export_gui($nids);
+  }
+}
+
+/**
+ * Helper function to return the node ID of a book page
+ */
+function _node_export_book_get_nids($tree) {
+  $answer = array();
+
+  foreach ($tree as $key => $value) {
+    // Base case: menu item is a node
+    if (is_numeric($tree[$key]['link']['nid'])) {
+      $answer[] = $tree[$key]['link']['nid'];
+    }
+
+    // Recursive case: menu item has children
+    if ($tree[$key]['below']) {
+      $sub_nids = _node_export_book_get_nids($tree[$key]['below']);
+      $answer = array_merge($answer, $sub_nids);
+    }
+  }
+
+  return $answer;
+}
+
+/**
+ * Implements hook_menu_alter().
+ */
+function node_export_book_menu_alter(&$items) {
+  // Alter the page callback for the book overview page
+  $items['admin/content/book']['page callback'] = '_node_export_book_book_admin_overview';
+}
+
+/**
+ * Helper function to override the book overview page and add an Export book
+ * operation.
+ *
+ * @see book_admin_overview()
+ */
+function _node_export_book_book_admin_overview() {
+  $rows = array();
+
+  $headers = array(t('Book'), t('Operations'));
+
+  // Add any recognized books to the table list.
+  foreach (book_get_books() as $book) {
+    $operations = array(
+      'links' => array(
+        'edit' => array(
+          'title' => t('edit order and titles'),
+          'href' => 'admin/content/book/' . $book['nid'],
+        ),
+        'export' => array(
+          'title' => t('export book'),
+          'href' => 'admin/content/book/node_export_book/' . $book['nid'],
+        ),
+      ),
+      'attributes' => array('class' => array('links', 'inline')),
+    );
+
+    $rows[] = array(
+      l($book['title'], $book['href'], $book['options']),
+      theme('links', $operations)
+    );
+  }
+
+  return theme('table', array(
+    'header' => $headers,
+    'rows' => $rows,
+    'empty' => t('No books available.')
+  ));
+}

+ 132 - 0
sites/all/modules/contrib/admin/node_export/modules/node_export_book/node_export_book_utils.inc

@@ -0,0 +1,132 @@
+<?php
+/**
+ * @file
+ *   A bunch of utility functions to help with importing and exporting books.
+ */
+
+/**
+ * Return the Node ID of a node with a given Menu Link ID.
+ *
+ * @param $mlid
+ *   The MLID of a node.
+ *
+ * @return
+ *   The NID of the node with the given MLID; xor NULL if the MLID is not
+ *   pointing to a node.
+ *
+ * @see menu_link_load()
+ */
+function _node_export_book_mlid_to_nid($mlid) {
+  // Load the menu link
+  $menu_item = menu_link_load($mlid);
+
+  if ($menu_item != FALSE) {
+    $path = explode('/', $menu_item['link_path']);
+
+    // Return the node ID if it's a valid node path
+    if ($path[0] == 'node' and is_numeric($path[1])) {
+      return intval($path[1]);
+    }
+  }
+
+  // If we get here, the node wasn't valid
+  return NULL;
+}
+
+/**
+ * Return the Universally Unique ID of a node with a given Menu Link ID.
+ *
+ * @param $mlid
+ *   The MLID of a node.
+ *
+ * @return
+ *   The UUID of the node with the given MLID; xor NULL if the node has not been
+ *   assigned a UUID.
+ *
+ * @see _node_export_book_mlid_to_nid()
+ * @see _node_export_book_nid_to_uuid()
+ */
+function _node_export_book_mlid_to_uuid($mlid) {
+  return _node_export_book_nid_to_uuid(_node_export_book_mlid_to_nid($mlid));
+}
+
+/**
+ * Return the Menu Link ID of a node with a given Node ID.
+ *
+ * @pre
+ *   The node must be in a book.
+ *
+ * @param $nid
+ *   The NID of a node.
+ *
+ * @return
+ *   The MLID of the node with the given NID; xor NULL if the node has no book
+ *   MLID (i.e.: is not in a book).
+ *
+ * @see menu_get_item()
+ */
+function _node_export_book_nid_to_mlid($nid) {
+  $node_path = 'node/' . intval($nid);
+
+  $query = db_select('menu_links', 'ml');
+  $query->addField('ml', 'mlid');
+  $query->condition('link_path', $node_path);
+  $result = $query->execute()->fetchAssoc();
+
+  if ($result == FALSE) {
+    return NULL;
+  }
+
+  return $result['mlid'];
+}
+
+/**
+ * Return the Universally Unique ID of a node with a given Node ID.
+ *
+ * @param $nid
+ *   The NID of a node.
+ *
+ * @return
+ *   The UUID of the node with the given NID; xor (FALSE if the node doesn't
+ *   exist OR there the node has not been assigned a UUID yet).
+ *
+ * @see entity_get_uuid_by_id()
+ */
+function _node_export_book_nid_to_uuid($nid) {
+  $uuid = entity_get_uuid_by_id('node', array($nid), FALSE);
+  return array_pop($uuid);
+}
+
+/**
+ * Return the Node ID of a node with a given Universally-Unique ID.
+ *
+ * @param $uuid
+ *   The UUID of a node.
+ *
+ * @return
+ *   The NID of the node with the given UUID; xor NULL if there are no nodes
+ *   with that UUID.
+ *
+ * @see entity_get_id_by_uuid()
+ */
+function _node_export_book_uuid_to_nid($uuid) {
+  $nid = entity_get_id_by_uuid('node', array($uuid), FALSE);
+  return array_pop($nid);
+}
+
+/**
+ * Return the Menu Link ID of a node with a given Universally-Unique ID.
+ *
+ * @param $uuid
+ *   The UUID of a node.
+ *
+ * @return
+ *   The MLID of the node with the given UUID; xor NULL if there are no nodes
+ *   with that UUID.
+ *
+ * @see _node_export_book_uuid_to_nid()
+ * @see _node_export_book_nid_to_mlid()
+ */
+function _node_export_book_uuid_to_mlid($uuid) {
+  return _node_export_book_nid_to_mlid(_node_export_book_uuid_to_nid($uuid));
+}

+ 19 - 0
sites/all/modules/contrib/admin/node_export/modules/node_export_dependency/node_export_dependency.core.inc

@@ -217,6 +217,25 @@ function entityreference_node_export_dependency_field($entity_type, $entity, $fi
 function field_collection_node_export_dependency_field($entity_type, $entity, $field, $instance, $langcode, $items) {
   $dependencies = array();
   node_export_dependency_add($dependencies, $items, 'field_collection_item', 'value');
+
+  // Loop all items to add their data for export.
+  foreach($items as $index => $item) {
+    if ($field_collection_item = field_collection_item_load($item['value'])) {
+      // Add file field data for export.
+      node_export_file_field_export($field_collection_item,
+        $field_collection_item);
+
+      // Add the field collection item data to the exported data. Mimics
+      // EntityAPIController::export() without the JSON conversion.
+      $dependencies[$index]['node_export_field_collection_data']
+        = get_object_vars($field_collection_item);
+
+      // Support nested fields and field collections too.
+      $dependencies = array_merge($dependencies, field_node_export_dependency(
+        $field_collection_item, 'field_collection_item'));
+    }
+  }
+
   return $dependencies;
 }
 

+ 3 - 3
sites/all/modules/contrib/admin/node_export/modules/node_export_dependency/node_export_dependency.info

@@ -4,9 +4,9 @@ dependencies[] = node_export
 dependencies[] = uuid
 core = 7.x
 package = "Node export"
-; Information added by drupal.org packaging script on 2012-08-20
-version = "7.x-3.0"
+; Information added by Drupal.org packaging script on 2016-03-04
+version = "7.x-3.1"
 core = "7.x"
 project = "node_export"
-datestamp = "1345435979"
+datestamp = "1457077222"
 

+ 135 - 16
sites/all/modules/contrib/admin/node_export/modules/node_export_dependency/node_export_dependency.module

@@ -100,7 +100,7 @@ function node_export_dependency_node_export_alter(&$nodes, $format) {
 /**
  *  Recursively load dependencies.
  */
-function node_export_dependency_load_dependencies(&$nodes, $nid) {
+function node_export_dependency_load_dependencies(&$nodes, $nid, $reset = FALSE) {
   $node = &$nodes[$nid];
   $dependencies = node_export_dependency_get_dependencies('node', $node);
   foreach ($dependencies as $dep_key => &$dependency) {
@@ -114,8 +114,8 @@ function node_export_dependency_load_dependencies(&$nodes, $nid) {
     if ($dependency['type'] == 'node' && variable_get('node_export_dependency_attach_nodes', 1)) {
       // It the node doesn't exist in keyed nodes, add it.
       if (!isset($nodes[$dependency['id']])) {
-        $new_node = node_load($dependency['id']);
-        if (node_export_access_export($new_node)) {
+        $new_node = node_load($dependency['id'], NULL, $reset);
+        if (node_export_access_export($new_node, $reset)) {
           $new_node = node_export_prepare_node($new_node);
           $nodes[$new_node->nid] = $new_node;
           // Recursively load dependent nodes.
@@ -140,20 +140,16 @@ function node_export_dependency_load_dependencies(&$nodes, $nid) {
 /**
  * Implements hook_node_export_import_alter().
  */
-function node_export_dependency_node_export_import_alter($nodes, $format) {
+function node_export_dependency_node_export_after_import_alter($nodes, $format, $save) {
   $node_export_dependency = variable_get('node_export_dependency', array());
-
   foreach ($nodes as $node) {
     if (isset($node->node_export_dependency)) {
       foreach ($node->node_export_dependency as $dep_key => $dependency) {
-        // Try to handle this dependency now, and unset if successfull.
+        // Try to handle this dependency now, and unset if successful.
         // Only do this now if maintaining dependency to original node, because
         // if that setting is turned off, doing this at this stage will break
         // things.
-        if (
-          variable_get('node_export_dependency_existing', 1) &&
-          node_export_dependency_handle_dependency($node, $dependency)
-        ) {
+        if (variable_get('node_export_dependency_existing', 1) && node_export_dependency_handle_dependency($node, $dependency)) {
           unset($node->node_export_dependency[$dep_key]);
         }
         else {
@@ -164,6 +160,7 @@ function node_export_dependency_node_export_import_alter($nodes, $format) {
         }
       }
       unset($node->node_export_dependency);
+      node_save($node);
     }
   }
 
@@ -185,8 +182,10 @@ function node_export_dependency_node_export_import_alter($nodes, $format) {
  *   How many iterations to run.
  * @param $seconds
  *   How long to lock others from processing (will release upon completion).
+ * @param $reset
+ *   Whether to reset the node_load_multiple cache.
  */
-function node_export_dependency_process_outstanding_dependencies($iterations, $seconds = 240) {
+function node_export_dependency_process_outstanding_dependencies($iterations, $seconds = 240, $reset = FALSE) {
   if (REQUEST_TIME - variable_get('node_export_dependency_lock', REQUEST_TIME) >= 0) {
     variable_set('node_export_dependency_lock', REQUEST_TIME + $seconds);
     $node_export_dependency = variable_get('node_export_dependency', array());
@@ -206,9 +205,9 @@ function node_export_dependency_process_outstanding_dependencies($iterations, $s
       $dependencies = &$node_export_dependency[$node_uuid];
       foreach ($dependencies as $dep_key => &$dependency) {
         $nids = entity_get_id_by_uuid('node', array($node_uuid));
-        $node = node_load($nids[$node_uuid]);
+        $node = node_load($nids[$node_uuid], $reset);
         if (!empty($node)) {
-          // Try to handle this dependency now, and unset if successfull.
+          // Try to handle this dependency now, and unset if successful.
           if (node_export_dependency_handle_dependency($node, $dependency)) {
             unset($dependencies[$dep_key]);
             node_save($node);
@@ -257,10 +256,25 @@ function node_export_dependency_init() {
 }
 
 /**
- *  Attempt to handle a dependency.
+ * Attempt to handle a dependency.
+ *
+ * Handles field collection items excluding file/image fields (not supported
+ * yet) and adds the data to the given node.
+ *
+ * Passes all dependencies to hook_node_export_dependency_alter() for external
+ * handling.
+ *
+ * @param $node
+ *   Node object before importing it.
+ * @param $dependency
+ *   Associative array with data for the given dependency as exported under the
+ *   'node_export_dependency' key.
+ *
+ * @return
+ *   TRUE or FALSE whether the dependency was handled.
  *
- *  @return
- *    TRUE or FALSE whether the dependency was handled.
+ * @todo
+ *   Implement file/image field handling for field collection items.
  */
 function node_export_dependency_handle_dependency(&$node, $dependency) {
   $handled = FALSE;
@@ -269,6 +283,111 @@ function node_export_dependency_handle_dependency(&$node, $dependency) {
     // We're not handling it, so it is 'handled'.
     return TRUE;
   }
+
+  // Handle exported field collection items.
+  if ($dependency['type'] == 'field_collection_item' &&
+      isset($dependency['node_export_field_collection_data'])) {
+    $entity_controller = new EntityAPIController("field_collection_item");
+    $field_collection_item = $entity_controller
+      ->create($dependency['node_export_field_collection_data']);
+
+    // The import of file/image field data is not yet supported. Thus we need
+    // to remove any file data from the field collection item's fields to avoid
+    // errors about non-existent files during import.
+
+    $supported_file_fields = array_map('trim', explode(',',
+      variable_get('node_export_file_supported_fields', 'file, image')));
+
+    // Gather information about the field collection item's individual fields.
+    $field_info = field_info_instances('field_collection_item',
+      $dependency['field_name']);
+
+    // Loop all fields to remove possibly contained file data.
+    foreach ($field_info as $field_name => $info) {
+      // If this is some file field.
+      if (in_array($info['widget']['module'], $supported_file_fields) && is_array($field_collection_item->{$field_name})) {
+
+        // Import the files, similar to node_export_file_field_import().
+        foreach ($field_collection_item->{$field_name} as $language => $files) {
+          if (is_array($files)) {
+            foreach ($files as $i => $field_value) {
+
+              $file = (object) $field_value;
+
+              $result = _node_export_file_field_import_file($file);
+
+              // The file was saved successfully, update the file field (by reference).
+              if ($result == TRUE && isset($file->fid)) {
+                // Retain any special properties from the original field value.
+                $field_collection_item->{$field_name}[$language][$i] = array_merge($field_value, (array) $file);
+              }
+
+            }
+          }
+        }
+      }
+    }
+
+    // Get the nid of the host node in the target system, if it already exits.
+    $nid = db_query('SELECT nid FROM {node} WHERE uuid = :uuid',
+      array(':uuid' => $node->uuid))->fetchField();
+
+    if ($nid) {
+      // Find the field collection item's current ID if it already exists.
+      $item_id = db_query('
+        SELECT d.' . $dependency['field_name'] . '_value
+        FROM {field_data_' . $dependency['field_name'] . '} d
+        INNER JOIN {field_collection_item} ci ON
+          ci.item_id = d.' . $dependency['field_name'] . '_value
+          AND ci.revision_id = d.' . $dependency['field_name'] . '_revision_id
+        WHERE d.entity_id = :nid AND d.delta = :delta
+        AND ci.field_name = :field_name',
+        array(
+          ':nid' => $nid,
+          ':delta' => $dependency['delta'],
+          ':field_name' =>  $dependency['field_name'])
+      )->fetchField();
+
+      $field_collection_item->item_id = $item_id ? $item_id : NULL;
+    }
+    else {
+      $field_collection_item->item_id = NULL;
+    }
+
+    if ($field_collection_item->item_id) {
+      // The item already exists in the DB, so we need its uuid and revision_id
+      // to overwrite exactly the existing one with the new data.
+      $data = db_query('
+          SELECT revision_id, uuid
+          FROM {field_collection_item}
+          WHERE item_id = :item_id',
+        array(':item_id' => $field_collection_item->item_id))->fetchAssoc();
+
+      $field_collection_item->uuid = $data['uuid'];
+      $field_collection_item->revision_id = $data['revision_id'];
+
+      // Property is not needed.
+      if (property_exists($field_collection_item, 'is_new')) {
+        unset($field_collection_item->is_new);
+      }
+    }
+    // If there is no item_id, i.e. this is a new field collection item.
+    else {
+      $field_collection_item->is_new = TRUE;
+      $field_collection_item->revision_id = NULL;
+
+      // Remove the old uuid, a new one will be created.
+      unset($field_collection_item->uuid);
+    }
+
+    // Add the field collection item data to the node where node_save() expects
+    // it. It will save the new data later.
+    $node->{$dependency['field_name']}[$dependency['langcode']]
+      [$dependency['delta']]['entity'] = $field_collection_item;
+
+    $handled = TRUE;
+  }
+
   if (!isset($dependency['relationship'])) {
     // Entity id.
     $entity_ids = entity_get_id_by_uuid($dependency['type'], array($dependency['uuid']));

+ 3 - 3
sites/all/modules/contrib/admin/node_export/modules/node_export_features/node_export_features.info

@@ -5,9 +5,9 @@ dependencies[] = uuid
 dependencies[] = features
 core = 7.x
 package = "Node export"
-; Information added by drupal.org packaging script on 2012-08-20
-version = "7.x-3.0"
+; Information added by Drupal.org packaging script on 2016-03-04
+version = "7.x-3.1"
 core = "7.x"
 project = "node_export"
-datestamp = "1345435979"
+datestamp = "1457077222"
 

+ 30 - 2
sites/all/modules/contrib/admin/node_export/modules/node_export_features/node_export_features.module

@@ -85,12 +85,38 @@ function node_export_features_features_export($data, &$export, $module_name = ''
   return $pipe;
 }
 
+/**
+ * Implements hook_node_export_alter().
+ */
+function node_export_features_node_export_alter(&$nodes, $format) {
+  if (_node_export_features_currently_exporting()) {
+    foreach ($nodes as $key => $node) {
+      // Perform cleaning of the node before creating the export for features.
+      // This can help strip volatile attributes like 'created' and 'changed'.
+      $nodes[$key] = node_export_node_clone($node);
+    }
+  }
+}
+
+/**
+ * Check if the code is currently running a feature export.
+ */
+function _node_export_features_currently_exporting($set = FALSE, $value = NULL) {
+  $exporting = &drupal_static(__FUNCTION__, FALSE);
+  if ($set) {
+    $exporting = $value;
+  }
+  return $exporting;
+}
+
 /**
  * Implements hook_features_export_render().
  */
 function node_export_features_features_export_render($module, $data, $export = NULL) {
   $nids = entity_get_id_by_uuid('node', $data);
+  _node_export_features_currently_exporting(TRUE, TRUE);
   $result = node_export($nids);
+  _node_export_features_currently_exporting(TRUE, FALSE);
   if ($result['success']) {
     $node_export['code_string'] = $result['output'];
     $node_export_code = '  $node_export = ' . features_var_export($node_export) . ';';
@@ -125,8 +151,10 @@ function node_export_features_features_rebuild($module) {
       }
     }
     else {
-      foreach ($result['output'] as $status) {
-        drupal_set_message($status);
+      if (!isset($_GET['profile'])) {
+        foreach ($result['output'] as $status) {
+          drupal_set_message($status);
+        }
       }
     }
   }

+ 59 - 0
sites/all/modules/contrib/admin/node_export/modules/node_export_features_ui/README.txt

@@ -0,0 +1,59 @@
+
+
+Node Export Features UI
+=======================
+
+This module works with the Node Export Features module to provide an easy to
+use method of selecting nodes to export.  It is based on this Node Export
+issue: http://drupal.org/node/1626360
+
+Currently, the feature module's UI does not support listing a large number of
+nodes to select from.  Sites with large numbers of nodes caused major UI and
+server performance problems.  Because of this, the node_export_feature module
+currently limits the number of nodes in the Feature UI to only the first 250
+nodes.
+
+The current solution for changing what nodes to display is to write a custom
+module. This module is for people who don't want to write a custom module.
+
+When enabled, it adds a "Feature Configuration" tab on the Node Export settings
+page. ( Admin->Configure->Content Authoring->Node Export )
+
+In the Feature Configuration tab, you can select from a set of filters to
+control what nodes get listed in the Feature modules UI.  The filter are:
+
+* Number of nodes to List:
+
+  Expand or shrink beyond the build in 250 nodes.
+
+  NOTE: Using a large number can cause server and UI performance problems.
+
+* Filter By Content Type:
+
+  Only show nodes of the selected content types.
+
+* Filter By Publishing Options:
+
+  Filter by published, promoted, and sticky status.
+
+* Filter by Title:
+
+  Filter by title using an SQL 'LIKE' statement.  E.g, %Test%One%
+
+* Filter by UUID:
+
+  Supply a specific list of node UUIDs to show.
+
+These filters are 'additive' so each one is an "AND" condition on the query.
+
+
+Installation:
+
+Install Node Export, then enable via the modules page (or drush or...)
+
+
+Features Notes:
+
+If you need to recreate a feature created with one or more of the filters set,
+you will need to make sure that the Node Export Feature filters are the
+same.

+ 15 - 0
sites/all/modules/contrib/admin/node_export/modules/node_export_features_ui/node_export_features_ui.info

@@ -0,0 +1,15 @@
+name = Node Export Features UI
+description = Supply some common filter options to define node available to be exported.
+core = 7.x
+package = "Node export"
+configure = admin/config/content/node_export/features
+
+dependencies[] = node_export_features
+
+
+; Information added by Drupal.org packaging script on 2016-03-04
+version = "7.x-3.1"
+core = "7.x"
+project = "node_export"
+datestamp = "1457077222"
+

+ 24 - 0
sites/all/modules/contrib/admin/node_export/modules/node_export_features_ui/node_export_features_ui.install

@@ -0,0 +1,24 @@
+<?php
+
+/**
+ * @file
+ * The Node export features ui install/uninstall code.
+ */
+
+/**
+ * Implements hook_uninstall().
+ */
+function node_export_features_ui_uninstall() {
+  $settings = array(
+    'node_export_features_ui_range',
+    'node_export_features_ui_content_types',
+    'node_export_features_ui_status',
+    'node_export_features_ui_promote',
+    'node_export_features_ui_sticky',
+    'node_export_features_ui_title',
+    'node_export_features_ui_uuids',
+  );
+  foreach ( $settings as $setting ) {
+    variable_del($setting);
+  }
+}

+ 85 - 0
sites/all/modules/contrib/admin/node_export/modules/node_export_features_ui/node_export_features_ui.module

@@ -0,0 +1,85 @@
+<?php
+/**
+ * @file
+ * Node Export Features UI main module file
+ */
+/**
+ * Implements hook_menu().
+ */
+function node_export_features_ui_menu() {
+  $items = array();
+
+  $items['admin/config/content/node_export/features'] = array(
+    'access arguments' => array('administer site configuration'),
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('node_export_features_ui_settings'),
+    'title' => 'Features Configuration',
+    'description' => 'Configure filters for nodes available to be exported by node export features',
+    'file' => 'node_export_features_ui.pages.inc',
+    'type' => MENU_LOCAL_TASK,
+     'weight' => 10,
+  );
+
+  return $items;
+}
+
+/**
+ * Implements hook_query_alter().
+ */
+function node_export_features_ui_query_alter(QueryAlterableInterface $query) {
+  if ($query->hasTag('node_export_features')) {
+    $range = variable_get('node_export_features_ui_range', 250);
+    $types = variable_get('node_export_features_ui_content_types', array());
+    $status = variable_get('node_export_features_ui_status', 0);
+    $promote = variable_get('node_export_features_ui_promote', 0);
+    $sticky = variable_get('node_export_features_ui_sticky', 0);
+    $title = trim(variable_get('node_export_features_ui_title', ''));
+    $uuids = node_export_features_ui_textarea_to_array(variable_get('node_export_features_ui_uuids', ''));
+
+    // Add in the specified conditions.
+    if ( $range ) {
+      $query->range(0, $range);
+    }
+    if ( ! empty($types) ) {
+      $query->condition('type', $types, 'IN');
+    }
+    if ( $status ) {
+      $query->condition('status', $status-1);
+    }
+    if ( $promote ) {
+      $query->condition('promote', $promote-1);
+    }
+    if ( $sticky ) {
+      $query->condition('sticky', $sticky-1);
+    }
+    if ( $title ) {
+      $query->condition('title', $title, 'LIKE');
+    }
+    if ( ! empty($uuids) ) {
+      $query->condition('uuid', $uuids, 'IN');
+    }
+  }
+}
+/**
+ * Utility function to convert a text area into a array of trimmed non-blank lines.
+ *
+ * @param string $area
+ *   The text area value to parse.
+ * @return array
+ *   The parsed array of non-blank trimmed lines found in the area.
+ *   An empty array is returned if no information found.
+ */
+function node_export_features_ui_textarea_to_array( $area ) {
+  $area = trim($area);
+  $results = array();
+  if ( $area ) {
+    $lines = explode("\r\n", $area);
+    foreach ( $lines as $key => $value ) {
+      $result = trim($value);
+      if ( $result ) {
+        $results[] = $result;
+      }
+    }
+  }
+  return $results;
+}

+ 167 - 0
sites/all/modules/contrib/admin/node_export/modules/node_export_features_ui/node_export_features_ui.pages.inc

@@ -0,0 +1,167 @@
+<?php
+
+/**
+ * @file
+ * The Node export features ui pages file.
+ */
+
+/**
+ * Admin settings form.
+ *
+ * @param array $form
+ *   The current form array.
+ * @param array $form_state
+ *   The current form array
+ * @return array
+ *   A form array
+ */
+function node_export_features_ui_settings($form, &$form_state) {
+
+  $types = node_type_get_names();
+  $filter_types = variable_get('node_export_features_ui_content_types', array());
+  $default_types = array();
+  if ( ! empty($filter_types) ) {
+    foreach ( $types as $key => $value ) {
+      if ( in_array($key, $filter_types)) {
+        $default_types[$key] = $key;
+      }
+      else {
+        $default_type[$key] = 0;
+      }
+    }
+  }
+
+  $form = array();
+
+  $form['info'] = array(
+    '#pre' => '<div id="node-export-features-ui-info">',
+    '#markup' => t('The settings below will effect what nodes will get listed in the Node Export section of the Features UI. Note that each of these is an AND condition and so the limiting effect is additive.  Also, when rebuilding a feature, the same filter settings will need to be applied.'),
+    '#suffix' => '</div>',
+  );
+
+  $form['node_export_features_ui_range'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Number of nodes to list'),
+    '#default_value' => variable_get('node_export_features_ui_range', 250),
+    '#size' => 6,
+    '#element_validate' => array('element_validate_integer_positive'),
+    '#description' => t("The Features' UI and system can become unusable if a a large number of nodes are listed to be exported. This value is the maximum number of nodes tht will be displayed." ),
+  );
+
+  // Content types
+  $form['content types'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Filter by Content Type'),
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+    '#attributes' => array(
+        'class' => array('node-form-options'),
+    ),
+  );
+
+  $form['content types']['node_export_features_ui_content_types'] = array(
+    '#type' => 'checkboxes',
+    '#title' => t('Content types to display'),
+    '#default_value' => $default_types,
+    '#options' => $types,
+    '#description' => t('Which content types should be listed?'),
+  );
+
+  // Node options
+  $form['options'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Filter by Publishing options'),
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+    '#attributes' => array(
+      'class' => array('node-form-options'),
+    ),
+  );
+
+  $form['options']['node_export_features_ui_status'] = array(
+    '#type' => 'select',
+    '#options' => array('Any', 'Unpublished', 'Published'),
+    '#title' => t('Published'),
+    '#default_value' => variable_get('node_export_features_ui_status', 0),
+  );
+  $form['options']['node_export_features_ui_promote'] = array(
+    '#type' => 'select',
+    '#options' => array('Any', 'Unpromoted', 'Promoted'),
+    '#title' => t('Promoted to front page'),
+    '#default_value' => variable_get('node_export_features_ui_promote', 0),
+  );
+  $form['options']['node_export_features_ui_sticky'] = array(
+    '#type' => 'select',
+    '#options' => array('Any', 'Not Sticky', 'Sticky'),
+    '#title' => t('Sticky at top of lists'),
+    '#default_value' => variable_get('node_export_features_ui_sticky', 0),
+  );
+  // Specific node filters
+  $form['node info'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Filter by Specific Node Info'),
+      '#collapsible' => TRUE,
+      '#collapsed' => TRUE,
+      '#attributes' => array(
+          'class' => array('node-form-options'),
+      ),
+  );
+
+  $form['node info']['node_export_features_ui_title'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Title match'),
+      '#default_value' => variable_get('node_export_features_ui_title', ''),
+      '#size' => 60,
+      '#description' => t("An SQL 'LIKE' match for titles. Use % to match any substring and _ to match a single character. For example, %Test_Node% to find any title like A Test Node for... or A Test-Node for..." ),
+  );
+
+  $form['node info']['node_export_features_ui_uuids'] = array(
+    '#type' => 'textarea',
+    '#title' => t('Specific node UUIDs to display'),
+    '#default_value' => variable_get('node_export_features_ui_uuids', ''),
+    '#description' => t('Enter node UUIDs to list.  One uuid per line.'),
+    '#cols' => 20,
+    '#rows' => 10,
+  );
+
+  return system_settings_form($form);
+}
+
+/**
+ * Validate and normalize some of the inputs.
+ *
+ * @param array $form
+ *   The form array
+ * @param array $form_state
+ *   The current form state.
+ */
+function node_export_features_ui_settings_validate($form, &$form_state ) {
+
+  module_load_include('inc', 'uuid');
+
+  $values = $form_state['values'];
+  $field = 'node_export_features_ui_uuids';
+  $uuids = node_export_features_ui_textarea_to_array($values[$field]);
+  $invalid_uuids = array();
+  foreach ( $uuids as $uuid ) {
+    if ( ! uuid_is_valid($uuid) ) {
+      $invalid_uuids[] = $uuid;
+    }
+  }
+  if ( empty($invalid_uuids) ) {
+    $form_state['values'][$field] = implode("\r\n", $uuids);
+  }
+  else {
+    form_set_error($field, t("Invalid UUID(s) found: ") . check_plain(implode(',', $invalid_uuids)));
+  }
+
+  // Convert type options to wanted type array
+  $field = 'node_export_features_ui_content_types';
+  $types = array();
+  foreach ( $values[$field] as $type ) {
+    if ( $type ) {
+      $types[] = $type;
+    }
+  }
+  $form_state['values'][$field] = $types;
+}

+ 4 - 1
sites/all/modules/contrib/admin/node_export/modules/node_export_feeds/FeedsNodeExportProcessor.inc

@@ -98,7 +98,10 @@ class FeedsNodeExportProcessor extends FeedsNodeProcessor {
     node_export_save($node);
     $this->new_nodes[$node->nid] = $node;
     // @todo: Is this what we should do with output messages?
-    drupal_set_message(t("Imported node !nid: !node", array('!nid' => $node->nid, '!node' => l($node->title, 'node/' . $node->nid))));
+    drupal_set_message(t("Imported node !nid: !node", array(
+      '!nid' => $node->nid,
+      '!node' => l($node->title, 'node/' . $node->nid)
+    )));
   }
 
 }

+ 3 - 3
sites/all/modules/contrib/admin/node_export/modules/node_export_feeds/node_export_feeds.info

@@ -6,9 +6,9 @@ dependencies[] = "feeds"
 dependencies[] = "node_export"
 files[] = FeedsNodeExportParser.inc
 files[] = FeedsNodeExportProcessor.inc
-; Information added by drupal.org packaging script on 2012-08-20
-version = "7.x-3.0"
+; Information added by Drupal.org packaging script on 2016-03-04
+version = "7.x-3.1"
 core = "7.x"
 project = "node_export"
-datestamp = "1345435979"
+datestamp = "1457077222"
 

+ 5 - 1
sites/all/modules/contrib/admin/node_export/modules/node_export_feeds/node_export_feeds.module

@@ -8,7 +8,11 @@
  * Implementation of hook_ctools_plugin_api().
  */
 function node_export_feeds_ctools_plugin_api($module = '', $api = '') {
-  if ($module == 'feeds' && in_array($api, array('feeds_importer_default', 'plugins'))) {
+  if ($module == 'feeds' && in_array($api, array(
+      'feeds_importer_default',
+      'plugins'
+    ))
+  ) {
     return array('version' => 1);
   }
 }

+ 3 - 3
sites/all/modules/contrib/admin/node_export/modules/node_export_relation/node_export_relation.info

@@ -4,9 +4,9 @@ dependencies[] = node_export
 dependencies[] = uuid
 core = 7.x
 package = "Node export"
-; Information added by drupal.org packaging script on 2012-08-20
-version = "7.x-3.0"
+; Information added by Drupal.org packaging script on 2016-03-04
+version = "7.x-3.1"
 core = "7.x"
 project = "node_export"
-datestamp = "1345435979"
+datestamp = "1457077222"
 

+ 4 - 4
sites/all/modules/contrib/admin/node_export/modules/node_export_relation/node_export_relation.node_reference.inc

@@ -61,7 +61,7 @@ function node_export_relation_node_reference_update($nodes) {
 /**
  * Recursively load node references.
  */
-function node_export_relation_node_reference_load(&$nodes, $nid) {
+function node_export_relation_node_reference_load(&$nodes, $nid, $reset = FALSE) {
   // Alias for easy referencing.
   $node = &$nodes[$nid];
 
@@ -76,12 +76,12 @@ function node_export_relation_node_reference_load(&$nodes, $nid) {
             // Load the referenced nodes only if its not already loaded
             // This will save if from infinite loop of back references
             if (!isset($nodes[$node_reference['nid']])) {
-              $new_node = node_load($node_reference['nid']);
-              if (node_export_access_export($new_node)) {
+              $new_node = node_load($node_reference['nid'], NULL, $reset);
+              if (node_export_access_export($new_node, $reset)) {
                 $new_node = node_export_prepare_node($new_node);
                 $nodes[$new_node->nid] = $new_node;
                 // Recursively load references of new nodes
-                node_export_relation_node_reference_load($nodes, $new_node->nid);
+                node_export_relation_node_reference_load($nodes, $new_node->nid, $reset);
               }
               elseif (!variable_get('node_export_node_reference_skip', TRUE)) {
                 // Set this node to FALSE to trigger an error in node export.

+ 0 - 13
sites/all/modules/contrib/admin/node_export/node_export-1911638_2.patch

@@ -1,13 +0,0 @@
-Index: node_export.module
-===================================================================
---- node_export.module	(revision 172)
-+++ node_export.module	(working copy)
-@@ -1146,7 +1146,7 @@
- 
-     if (!empty($query)) {
-       watchdog('node_export', 'kept existing managed file at uri "%uri"', array('%uri' => $file->uri), WATCHDOG_NOTICE);
--      $file = file_load(array_shift($query));
-+      $file = (object) array_merge((array) $file, (array) file_load(array_shift($query)));
-     }
- 
-     $file = file_save($file);

+ 5 - 3
sites/all/modules/contrib/admin/node_export/node_export.info

@@ -5,9 +5,11 @@ core = 7.x
 package = "Node export"
 configure = admin/config/content/node_export
 files[]=views/views_handler_field_node_link_export.inc
-; Information added by drupal.org packaging script on 2012-08-20
-version = "7.x-3.0"
+files[]=node_export.test
+
+; Information added by Drupal.org packaging script on 2016-03-04
+version = "7.x-3.1"
 core = "7.x"
 project = "node_export"
-datestamp = "1345435979"
+datestamp = "1457077222"
 

+ 19 - 4
sites/all/modules/contrib/admin/node_export/node_export.install

@@ -35,12 +35,9 @@ function node_export_uninstall() {
   // DSV format.
   variable_del('node_export_dsv_delimiter');
   variable_del('node_export_dsv_enclosure');
-  variable_del('node_export_dsv_seperator');
+  variable_del('node_export_dsv_separator');
   variable_del('node_export_dsv_escape_eol');
 
-  // Old vars.
-  variable_del('node_export_reset_' . $type);
-  variable_del('node_export_nodes_without_confirm');
 
 }
 
@@ -133,3 +130,21 @@ function node_export_update_7303() {
   }
   return 'Node export format modules removed, functionality moved to Node export.';
 }
+
+
+/**
+ * Remove and rename vars.
+ */
+function node_export_update_7304() {
+  $types = node_type_get_names();
+  foreach ($types as $type => $name) {
+    variable_del('node_export_reset_' . $type);
+  }
+
+  $sep = variable_get('node_export_dsv_seperator', '\r\n');
+  variable_set('node_export_dsv_separator', $sep);
+
+  variable_del('node_export_nodes_without_confirm');
+  variable_del('node_export_dsv_seperator');
+}
+

+ 206 - 55
sites/all/modules/contrib/admin/node_export/node_export.module

@@ -38,6 +38,12 @@ function node_export_menu() {
     'description' => 'Configure the settings for Node export.',
     'file' => 'node_export.pages.inc',
   );
+  // Allow other modules to add local task tabs.
+  $items['admin/config/content/node_export/settings'] = array(
+      'title' => 'Settings',
+      'type' => MENU_DEFAULT_LOCAL_TASK,
+  );
+
   $selected_formats = variable_get('node_export_format', array('drupal' => 'drupal'));
   if (count(array_filter($selected_formats)) > 1) {
     $format_handlers = node_export_format_handlers();
@@ -93,10 +99,10 @@ function node_export_menu() {
 /**
  * Check access to export a node.
  */
-function node_export_access_export($node) {
+function node_export_access_export($node, $reset = FALSE) {
   global $user;
-  if (is_int($node)) {
-    $node = node_load($node);
+  if (is_numeric($node)) {
+    $node = node_load($node, NULL, $reset);
   }
 
   if (function_exists('drush_main')) {
@@ -257,31 +263,32 @@ function node_export_bulk_operation($nodes = NULL, $format = NULL, $delivery = N
  */
 function node_export_action_info() {
   $actions = array();
-  if (user_access('export nodes')) {
-    $selected_formats = variable_get('node_export_format', array('drupal' => 'drupal'));
-    $format_handlers = node_export_format_handlers();
-    foreach ($format_handlers as $format_handler => $format) {
-      if (!empty($selected_formats[$format_handler])) {
-         // @todo: should formats be able to define their own actions?
-         if (!empty($format['#file']) && is_file($format['#file'])) {
-           require_once $format['#file'];
-         }
-         $format_action = 'node_export_' . $format_handler . '_action';
-         if (function_exists($format_action . '_form')) {
-           $actions[$format_action] = array(
-             'type' => 'node',
-             'label' => t('Node export') . " (" . $format['#title'] . ")",
-             'behavior' => array('changes_property'),
-             // This action only works when invoked through VBO. That's why it's
-             // declared as non-configurable to prevent it from being shown in the
-             // "Create an advanced action" dropdown on admin/config/system/actions.
-             'configurable' => FALSE,
-             'vbo_configurable' => TRUE,
-           );
-        }
+
+  $selected_formats = variable_get('node_export_format', array('drupal' => 'drupal'));
+  $format_handlers = node_export_format_handlers();
+  foreach ($format_handlers as $format_handler => $format) {
+    if (in_array($format_handler, $selected_formats)) {
+       // @todo: should formats be able to define their own actions?
+       if (!empty($format['#file']) && is_file($format['#file'])) {
+         require_once $format['#file'];
+       }
+       $format_action = 'node_export_' . $format_handler . '_action';
+       if (function_exists($format_action . '_form')) {
+         $actions[$format_action] = array(
+           'type' => 'node',
+           'label' => t('Node export') . " (" . $format['#title'] . ")",
+           'behavior' => array('changes_property'),
+           // This action only works when invoked through VBO. That's why it's
+           // declared as non-configurable to prevent it from being shown in the
+           // "Create an advanced action" dropdown on admin/config/system/actions.
+           'configurable' => FALSE,
+           'vbo_configurable' => TRUE,
+           'triggers' => array('any'),
+         );
       }
     }
   }
+
   return $actions;
 
 }
@@ -314,12 +321,14 @@ function node_export_action_form($context, &$form_state, $format = NULL) {
  *   The format to use for export.
  * @param $msg_t
  *   Function used to translate.
+ * @param $reset
+ *   Whether to reset the node_load_multiple cache.
  * @return
  *   An array with keys 'success' which is a boolean value representing whether
  *   the export was successful and 'output' which contains the code string or an
  *   array of translated error messages to be shown to the user.
  */
-function node_export($nids, $format = NULL, $msg_t = 't') {
+function node_export($nids, $format = NULL, $msg_t = 't', $reset = FALSE) {
   global $user;
 
   // Make $nids an array if it isn't.
@@ -332,9 +341,9 @@ function node_export($nids, $format = NULL, $msg_t = 't') {
 
   $nodes = array();
   foreach ($nids as $nid) {
-    $original_node = node_load($nid);
+    $original_node = node_load($nid, NULL, $reset);
 
-    if (!node_export_access_export($original_node)) {
+    if (!node_export_access_export($original_node, $reset)) {
       // Halt exporting.
       $error = $msg_t("You do not have permission to perform a Node export on one or more of these nodes.  No nodes exported.");
       return array(
@@ -418,7 +427,7 @@ function node_export_prepare_node(&$original_node) {
       }
     }
     if (isset($new_taxonomy['tags']) && count($new_taxonomy['tags'])) {
-      // Comma seperate the tags
+      // Comma separate the tags
       foreach ($new_taxonomy['tags'] as $vid => $tags) {
         $new_taxonomy['tags'][$vid] = implode(', ', $tags);
       }
@@ -571,11 +580,13 @@ function node_export_import($code_string, $msg_t = 't', $save = TRUE) {
   $messages = array();
   foreach ($nodes as $original_node) {
     $node = node_export_node_clone($original_node);
+    $tnid_to_reset = node_export_node_clone_set_tnid($node, $original_node);
 
     // Import file fields.
     node_export_file_field_import($node, $original_node);
 
     // Handle existing nodes.
+    $save_node = $save;
     $nids = entity_get_id_by_uuid('node', array($node->uuid));
     if (!empty($nids[$node->uuid])) {
       $existing = variable_get('node_export_existing', 'new');
@@ -588,17 +599,27 @@ function node_export_import($code_string, $msg_t = 't', $save = TRUE) {
           $node->nid = $nids[$node->uuid];
           $node->is_new = FALSE;
           $node->revision = 1;
+          $tnid_to_reset = 0;
           break;
         case 'skip':
-          $save = FALSE;
+          $save_node = FALSE;
           break;
       }
     }
 
     // Let other modules do special fixing up.
-    drupal_alter('node_export_node_import', $node, $original_node, $save);
+    drupal_alter('node_export_node_import', $node, $original_node, $save_node);
+
+    if ($save_node) {
+      if (!empty($tnid_to_reset) && empty($node->tnid)) {
+        node_export_save($node);
+        $node->tnid = $node->nid;
+
+        // Update the tnid map for other nodes referencing this tnid.
+        $tnid_map = &drupal_static('node_export_import_tnid_map', array());
+        $tnid_map[$tnid_to_reset] = $node->tnid;
+      }
 
-    if ($save) {
       node_export_save($node);
       $new_nodes[$node->nid] = $node;
       $messages[] = $msg_t("Imported node !nid: !node", array('!nid' => $node->nid, '!node' => l($node->title, 'node/' . $node->nid)));
@@ -609,7 +630,7 @@ function node_export_import($code_string, $msg_t = 't', $save = TRUE) {
     }
   }
 
-  if ($save) {
+  if ($count) {
     drupal_alter('node_export_after_import', $new_nodes, $used_format, $save);
     $messages[] = $msg_t("!count of !total nodes were imported.  Some values may have been reset depending on Node export's configuration.", array('!total' => $total, '!count' => $count));
 
@@ -676,6 +697,7 @@ function node_export_save(&$node) {
 
     // Let modules modify the node before it is saved to the database.
     module_invoke_all('node_presave', $node);
+    module_invoke_all('entity_presave', $node, 'node');
 
     if ($node->is_new || !empty($node->revision)) {
       // When inserting either a new node or a new node revision, $node->log
@@ -787,6 +809,12 @@ function node_export_node_clone($original_node) {
   if (variable_get('node_export_reset_author_' . $node->type, TRUE)) {
     $node->name = !empty($user->name) ? $user->name : (!empty($user->uid) ? NULL : variable_get('anonymous', t('Anonymous')));
     $node->uid = $user->uid;
+    $node->revision_uid = $user->uid;
+  }
+
+  // note: a uid of 0 is erroneous in any case, reset it to 1 (admin user)
+  if ($node->revision_uid == 0) {
+    $node->revision_uid = 1;
   }
 
   if (variable_get('node_export_reset_created_' . $node->type, TRUE)) {
@@ -841,10 +869,76 @@ function node_export_node_clone($original_node) {
     $node->sticky = FALSE;
   }
 
+  // check for a data casting error
+  if ($node->data == 'b:0;') { // data has been serialized as a FALSE instead of NULL
+    $node->data = NULL;
+  }
+
+  // sort the node keys, so that there is a consistent representation for
+  // (drupal_)var_export
+  $array_node = (array) $node;
+  ksort( $array_node);
+  $node = (object) $array_node;
+
   return $node;
 
 }
 
+/**
+ * Update the tnid value on the new node based on the tnid value from the old node.
+ *
+ * If the original node has a tnid that matches its nid, then we can deduce that this
+ * tnid needs to be changed to match the node's nid (which will only be set after
+ * first saving the node).
+ *
+ * If the original node has a tnid that does not match its nid, we first check to see
+ * if we have already updated the tnid on another node that had this tnid originally.
+ * If so, we will use that tnid.  Otherwise, we leave the tnid specified in the import
+ * unchanged.
+ *
+ * As such, when importing a set of nodes that are all linked via tnid, it is necessary
+ * that the first node where nid = tnid is imported prior to any of the other nodes
+ * that share that tnid.
+ *
+ * @return number
+ *   original tnid if the tnid on this node needs to be set equal to the node's nid
+ *   when it is saved, otherwise NULL
+ */
+function node_export_node_clone_set_tnid(&$node, $original_node) {
+  if (!empty($original_node->tnid)) {
+    $tnid_map = drupal_static('node_export_import_tnid_map', array());
+    if (!empty($tnid_map[$original_node->tnid])) {
+      $node->tnid = $tnid_map[$original_node->tnid];
+    }
+    elseif (!empty($original_node->nid) && $original_node->tnid == $original_node->nid) {
+      $node->tnid = 0;
+      return $original_node->tnid;
+    }
+  }
+  return NULL;
+}
+
+/**
+ * Implements hook_node_export_alter().
+ * In case when node translation is enabled we have to ensure that original nodes
+ * appear in export before their translations. This is done to properly assign tnid
+ * to translations, because we don't know until the first node in the set is saved.
+ */
+function node_export_node_export_alter(&$nodes, $format_handler) {
+  if (module_exists('translation')) {
+    $source_nodes = array();
+    foreach ($nodes as $i => $node) {
+      if ($node->nid == $node->tnid) {
+        $source_nodes[] = $node;
+        unset($nodes[$i]);
+      }
+    }
+    if ($source_nodes) {
+      $nodes = array_merge($source_nodes, $nodes);
+    }
+  }
+}
+
 /**
  * Create a new menu entry with title, parent and weight exported from
  * another nodes menu. Returns NULL if the node has no menu title.
@@ -967,16 +1061,51 @@ function node_export_format_handlers() {
   if (empty($format_handlers)) {
     $format_handlers = module_invoke_all('node_export_format_handlers');
   }
+  drupal_alter('node_export_format_handlers', $format_handlers);
   return $format_handlers;
 }
 
+/**
+ * Get entity type and bundle of the given entity. Works for nodes and field
+ * collection items.
+ * 
+ * @param $entity
+ *   Entity to get information of.
+ * 
+ * @return
+ *   Associative array with the 'type' and 'bundle' fields.
+ */
+function _node_export_entity_info($entity) {
+  $info = array();
+
+  if (method_exists($entity, 'entityType')
+      && $entity->entityType() == 'field_collection_item') {
+    $info['type'] = $entity->entityType();
+
+    // Field the collection is attached to.
+    $info['bundle'] = $entity->field_name;
+  }
+  else {
+    $info['type'] = 'node';
+    $info['bundle'] = $entity->type;
+  }
+
+  return $info;
+}
 
 /**
  * Handle exporting file fields.
+ * 
+ * @param $entity
+ *   Node or field_collection_item object.
+ * @param $original_entity
+ *   Unused...
  */
-function node_export_file_field_export(&$node, $original_node) {
+function node_export_file_field_export(&$entity, $original_entity) {
+  $entity_info = _node_export_entity_info($entity);
+
   $types = array_filter(variable_get('node_export_file_types', array()));
-  if (in_array($node->type, $types)) {
+  if ($entity_info['type'] != 'node' || in_array($entity->type, $types)) {
     $assets_path = variable_get('node_export_file_assets_path', '');
     $export_mode = variable_get('node_export_file_mode', 'inline');
 
@@ -1011,11 +1140,11 @@ function node_export_file_field_export(&$node, $original_node) {
     }
 
     // get all fields from this node type
-    $fields = field_info_instances('node', $node->type);
+    $fields = field_info_instances($entity_info['type'],
+      $entity_info['bundle']);
     foreach($fields as $field_instance) {
-
       // load field infos to check the type
-      $field = &$node->{$field_instance['field_name']};
+      $field = &$entity->{$field_instance['field_name']};
       $info = field_info_field($field_instance['field_name']);
 
       $supported_fields = array_map('trim', explode(',', variable_get('node_export_file_supported_fields', 'file, image')));
@@ -1032,6 +1161,13 @@ function node_export_file_field_export(&$node, $original_node) {
               // convert file to array to stay into the default node_export_file format
               $file = (object) $file;
 
+              // media field type doesn't load file the whole file on node_load
+              // it loads only fid, title and data associated with file, so in this case we need
+              // to load it by ourselves.
+              if (empty($file->uri) && !empty($file->fid) && $file = file_load($file->fid)) {
+                $field[$language][$i] = (array) $file;
+              }
+
               // Check the file
               if (!isset($file->uri) || !is_file($file->uri)) {
                 drupal_set_message(t("File field found on node, but file doesn't exist on disk? '!path'", array('!path' => $file->uri)), 'error');
@@ -1052,7 +1188,8 @@ function node_export_file_field_export(&$node, $original_node) {
               }
               // Remote export mode
               elseif ($export_mode == 'remote') {
-                $export_data = url($file->uri, array('absolute' => TRUE));
+                // NOTE: This is patched with info from https://drupal.org/node/2046431
+                $export_data = file_create_url($file->uri);
               }
               // Default is 'inline' export mode
               else {
@@ -1074,14 +1211,20 @@ function node_export_file_field_export(&$node, $original_node) {
 
 /**
  * Handle importing file fields.
+ * 
+ * @param $entity
+ *   Node or field_collection_item object.
+ * @param $original_entity
+ *   Unused...
  */
-function node_export_file_field_import(&$node, $original_node) {
+function node_export_file_field_import(&$entity, $original_entity) {
+  $entity_info = _node_export_entity_info($entity);
+
   // Get all fields from this node type.
-  $fields = field_info_instances('node', $node->type);
+  $fields = field_info_instances($entity_info['type'], $entity_info['bundle']);
   foreach($fields as $field_instance) {
-
     // Load field info to check the type.
-    $field = &$node->{$field_instance['field_name']};
+    $field = &$entity->{$field_instance['field_name']};
     $info = field_info_field($field_instance['field_name']);
 
     $supported_fields = array_map('trim', explode(',', variable_get('node_export_file_supported_fields', 'file, image')));
@@ -1093,17 +1236,17 @@ function node_export_file_field_import(&$node, $original_node) {
       // fields with different language than the node one.
       foreach($field as $language => $files) {
         if (is_array($files)) {
-          foreach($files as $i => $file) {
+          foreach($files as $i => $field_value) {
 
-            // Convert file to array to stay into the default node_export_file format.
-            $file = (object)$file;
+            $file = (object) $field_value;
 
             $result = _node_export_file_field_import_file($file);
+
             // The file was saved successfully, update the file field (by reference).
             if ($result == TRUE && isset($file->fid)) {
-              $field[$language][$i] = (array)$file;
+              // Retain any special properties from the original field value.
+              $field[$language][$i] = array_merge($field_value, (array) $file);
             }
-
           }
         }
       }
@@ -1149,6 +1292,9 @@ function _node_export_file_field_import_file(&$file) {
 
     if (!empty($query)) {
       watchdog('node_export', 'kept existing managed file at uri "%uri"', array('%uri' => $file->uri), WATCHDOG_NOTICE);
+      $file = file_load(array_shift($query));
+    } elseif(isset($file->fid)) {
+      unset($file->fid);
       $file = (object) array_merge((array) $file, (array) file_load(array_shift($query)));
     }
 
@@ -1158,7 +1304,13 @@ function _node_export_file_field_import_file(&$file) {
     $directory = drupal_dirname($file->uri);
     if (file_prepare_directory($directory, FILE_CREATE_DIRECTORY)) {
       if (file_put_contents($file->uri, base64_decode($file->node_export_file_data))) {
-        $file = file_save($file);
+        $files = file_load_multiple(array(), array('uri' => $file->uri));
+
+        // Only attempt to save the file if a record doesn't already exist in
+        // the file_managed table.
+        if (count($files) == 0) {
+          $file = file_save($file);
+        }
       }
     }
   }
@@ -1260,12 +1412,11 @@ if (!function_exists('uuid_set_uuid')) {
       return FALSE;
     }
 
-    $query = db_query("UPDATE {" . $table . "} SET uuid = :uuid WHERE " . $key . " = :id", array(':uuid' => $uuid, ':id' => $serial_id));
-    /*
-    if (!$query->rowCount()) {
-      @db_query("INSERT INTO {" . $table . "} (" . $key . ", uuid) VALUES (:id, :uuid)", array(':uuid' => $uuid, ':id' => $serial_id));
-    }
-    */
+    $query = db_update($table)
+      ->fields(array('uuid' => $uuid))
+      ->condition($key, $serial_id, '=')
+      ->execute();
+
 
     return $uuid;
   }

+ 0 - 1297
sites/all/modules/contrib/admin/node_export/node_export.module.orig

@@ -1,1297 +0,0 @@
-<?php
-
-/**
- * @file
- * The Node export module.
- *
- * Allows users to export nodes and then import them into another Drupal installation.
- */
-
-/**
- * Implements hook_permission().
- */
-function node_export_permission() {
-  return array(
-    'export nodes' => array(
-      'title' => t('Export nodes'),
-    ),
-    'export own nodes' => array(
-      'title' => t('Export own nodes'),
-    ),
-    'use PHP to import nodes' => array(
-      'title' => t('Use PHP to import nodes'),
-      'description' => t('Required for importing, but can allow execution of PHP.'),
-      'restrict access' => TRUE,
-    ),
-  );
-}
-
-/**
- * Implements hook_menu().
- */
-function node_export_menu() {
-  $items['admin/config/content/node_export'] = array(
-    'access arguments' => array('administer site configuration'),
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('node_export_settings'),
-    'title' => 'Node export',
-    'description' => 'Configure the settings for Node export.',
-    'file' => 'node_export.pages.inc',
-  );
-  $selected_formats = variable_get('node_export_format', array('drupal' => 'drupal'));
-  if (count(array_filter($selected_formats)) > 1) {
-    $format_handlers = node_export_format_handlers();
-    foreach ($format_handlers as $format_handler => $format) {
-      if (!empty($selected_formats[$format_handler])) {
-        $items['node/%node/node_export/' . $format_handler] = array(
-          'access callback' => 'node_export_access_export',
-          'access arguments' => array(1),
-          'page callback' => 'node_export_gui',
-          'page arguments' => array(1, $format_handler),
-          'title' => 'Node export (' . $format['#title'] . ')',
-          'weight' => 5,
-          'type' => MENU_LOCAL_TASK,
-          'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE,
-          'file' => 'node_export.pages.inc',
-        );
-      }
-    }
-  }
-  else {
-    $items['node/%node/node_export'] = array(
-      'access callback' => 'node_export_access_export',
-      'access arguments' => array(1),
-      'page callback' => 'node_export_gui',
-      'page arguments' => array(1),
-      'title' => 'Node export',
-      'weight' => 5,
-      'type' => MENU_LOCAL_TASK,
-      'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE,
-      'file' => 'node_export.pages.inc',
-    );
-  }
-  $items['admin/content/node_export'] = array(
-    'access arguments' => array('export nodes'),
-    'page callback' => 'node_export_gui',
-    'page arguments' => array(NULL, NULL),
-    'title' => 'Node export',
-    'type' => MENU_CALLBACK,
-    'file' => 'node_export.pages.inc',
-  );
-  $items['node/add/node_export'] = array(
-    'title' => 'Node export: import',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('node_export_import_form'),
-    'access callback' => 'node_export_access_import',
-    'description' => 'Import content using <em>Node export</em>.',
-    'file' => 'node_export.pages.inc',
-  );
-
-  return $items;
-}
-
-/**
- * Check access to export a node.
- */
-function node_export_access_export($node) {
-  global $user;
-  if (is_int($node)) {
-    $node = node_load($node);
-  }
-
-  if (function_exists('drush_main')) {
-    // Always allow drush to export nodes.
-    $access = TRUE;
-  }
-  else {
-    // Check basic role permissions first.
-    $access = (user_access('export nodes') || ($user->uid && ($node->uid == $user->uid) && user_access('export own nodes')));
-    // Make sure the user can view the original node content.
-    $access = $access && node_access('view', $node);
-  }
-
-  // Let other modules alter this - for example to only allow some users
-  // to export specific nodes or types.
-  drupal_alter("node_export_access_export", $access, $node);
-  return $access;
-}
-
-/**
- * Check access to import a node.
- */
-function node_export_access_import($node = NULL) {
-  global $user;
-
-  if (function_exists('drush_main')) {
-    // Always allow drush to import nodes.
-    $access = TRUE;
-  }
-  elseif (defined('MAINTENANCE_MODE') && MAINTENANCE_MODE == 'install') {
-    // During the install phase $user is the Anonymous user; however, in
-    // practice $user is performing tasks only granted to the admin user
-    // (eg: installing modules, changing site settings).  For this reason
-    // it seems sensible to allow this "Anonymous admin" user to import
-    // any nodes they wish.
-    $access = TRUE;
-  }
-  else {
-    // Check basic role permissions first.
-    $access = user_access('use PHP to import nodes');
-
-    if (!is_null($node) && $access) {
-      // Check node conditions.
-      $access = node_access('create', $node->type);
-    }
-  }
-
-  // Let other modules alter this - for example to only allow some users
-  // to import specific nodes or types.
-  drupal_alter("node_export_access_import", $access, $node);
-  return $access;
-}
-
-/**
- * Check access to export an array of nodes.
- */
-function node_export_access_export_nodes($nodes) {
-  // Convert to array if it isn't already.
-  if (is_object($nodes)) {
-    $nodes = array($nodes);
-  }
-  foreach ($nodes as &$node) {
-    if (!node_export_access_export($node)) {
-      return FALSE;
-    }
-  }
-  return TRUE;
-}
-
-/**
- * Check access to import an array of nodes.
- */
-function node_export_access_import_nodes($nodes) {
-  // Convert to array if it isn't already.
-  if (is_object($nodes)) {
-    $nodes = array($nodes);
-  }
-  foreach ($nodes as &$node) {
-    if (!node_export_access_import($node)) {
-      return FALSE;
-    }
-  }
-  return TRUE;
-}
-
-/**
- * Implements hook_node_type_update().
- */
-function node_export_node_type_update($info) {
-  if (!empty($info->old_type) && $info->old_type != $info->type) {
-    if (variable_get('node_export_reset_' . $info->old_type, FALSE)) {
-      variable_del('node_export_reset_' . $info->old_type);
-      variable_set('node_export_reset_' . $info->type, TRUE);
-    }
-  }
-}
-
-/**
- * Implements hook_node_type_delete().
- */
-function node_export_node_type_delete($info) {
-  variable_del('node_export_reset_' . $info->type);
-}
-
-/**
- * Implements hook_views_api().
- */
-function node_export_views_api() {
-  return array(
-    'api' => 3,
-    'path' => drupal_get_path('module', 'node_export') . '/views',
-  );
-}
-
-/**
- * Implements hook_node_operations().
- */
-function node_export_node_operations() {
-  $operations = array();
-  if (user_access('export nodes')) {
-
-    $selected_formats = variable_get('node_export_format', array('drupal' => 'drupal'));
-    if (count(array_filter($selected_formats)) > 1) {
-      $format_handlers = node_export_format_handlers();
-      foreach ($format_handlers as $format_handler => $format) {
-        if ($selected_formats[$format_handler]) {
-          $operations['node_export_' . $format_handler] = array(
-            'label' => t('Node export') . " (" . $format['#title'] . ")",
-            'callback' => 'node_export_bulk_operation',
-            'callback arguments' => array('format' => $format_handler),
-          );
-        }
-      }
-    }
-    else {
-      $operations = array(
-        'node_export' => array(
-          'label' => t('Node export'),
-          'callback' => 'node_export_bulk_operation',
-        ),
-      );
-    }
-
-  }
-  return $operations;
-}
-
-/**
- * Callback for use with hook_node_operations().
- */
-function node_export_bulk_operation($nodes = NULL, $format = NULL, $delivery = NULL) {
-  module_load_include('inc', 'node_export', 'node_export.pages');
-  return node_export_gui($nodes, $format, $delivery);
-}
-
-/**
- * Implements hook_action_info()
- */
-function node_export_action_info() {
-  $actions = array();
-  if (user_access('export nodes')) {
-    $selected_formats = variable_get('node_export_format', array('drupal' => 'drupal'));
-    $format_handlers = node_export_format_handlers();
-    foreach ($format_handlers as $format_handler => $format) {
-      if (!empty($selected_formats[$format_handler])) {
-         // @todo: should formats be able to define their own actions?
-         if (!empty($format['#file']) && is_file($format['#file'])) {
-           require_once $format['#file'];
-         }
-         $format_action = 'node_export_' . $format_handler . '_action';
-         if (function_exists($format_action . '_form')) {
-           $actions[$format_action] = array(
-             'type' => 'node',
-             'label' => t('Node export') . " (" . $format['#title'] . ")",
-             'behavior' => array('changes_property'),
-             // This action only works when invoked through VBO. That's why it's
-             // declared as non-configurable to prevent it from being shown in the
-             // "Create an advanced action" dropdown on admin/config/system/actions.
-             'configurable' => FALSE,
-             'vbo_configurable' => TRUE,
-           );
-        }
-      }
-    }
-  }
-  return $actions;
-
-}
-
-/**
- * Export Nodes Action "Configuration" Form
- *
- * Technically for a normal action this is where you would provide config
- * for the actual execution of the action. However, we're hijacking it to
- * present the completed node_export_gui page.
- */
-function node_export_action_form($context, &$form_state, $format = NULL) {
-  // Get the name of the vbo views field
-  $vbo = _views_bulk_operations_get_field($form_state['build_info']['args'][0]);
-
-  // Adjust the selection in case the user chose 'select all'
-  if (!empty($form_state['select_all_pages'])) {
-    views_bulk_operations_direct_adjust($form_state['selection'], $vbo);
-  }
-  $nodes = array_combine($form_state['selection'], $form_state['selection']);
-  return node_export_bulk_operation($nodes, $format);
-}
-
-/**
- * Export nodes.
- *
- * @param $nids
- *   A node ID or array of node IDs to export.
- * @param $format
- *   The format to use for export.
- * @param $msg_t
- *   Function used to translate.
- * @return
- *   An array with keys 'success' which is a boolean value representing whether
- *   the export was successful and 'output' which contains the code string or an
- *   array of translated error messages to be shown to the user.
- */
-function node_export($nids, $format = NULL, $msg_t = 't') {
-  global $user;
-
-  // Make $nids an array if it isn't.
-  if (is_int($nids)) {
-    $nids = array($nids);
-  }
-  elseif (is_object($nids)) {
-    $nids = array($nids->nid);
-  }
-
-  $nodes = array();
-  foreach ($nids as $nid) {
-    $original_node = node_load($nid);
-
-    if (!node_export_access_export($original_node)) {
-      // Halt exporting.
-      $error = $msg_t("You do not have permission to perform a Node export on one or more of these nodes.  No nodes exported.");
-      return array(
-        'success' => FALSE,
-        'output' => array($error),
-      );
-    }
-
-    $node = node_export_prepare_node($original_node);
-
-    $nodes[] = $node;
-  }
-
-  // Get the node code from the format handler
-  $format_handlers = node_export_format_handlers();
-  $node_export_format = variable_get('node_export_format', array('drupal' => 'drupal'));
-  $format_handler = $format ? $format : reset($node_export_format);
-  if (!isset($format_handlers[$format_handler])) {
-    $format_handler = 'drupal';
-  }
-
-  // Let other modules do special fixing up.
-  drupal_alter('node_export', $nodes, $format_handler);
-
-  // If any nodes are set to FALSE, then an error was triggered in another module.
-  // Currently modules doing this should also leave a watchdog warning.
-  if (in_array(FALSE, $nodes)) {
-    // Halt exporting.
-    $error = $msg_t('An error occurred when processing nodes, please check your logs.  No nodes exported.');
-    return array(
-      'success' => FALSE,
-      'output' => array($error),
-    );
-  }
-
-  if (!empty($format_handlers[$format_handler]['#file']) && is_file($format_handlers[$format_handler]['#file'])) {
-    require_once $format_handlers[$format_handler]['#file'];
-  }
-
-  $code_string = call_user_func(
-    $format_handlers[$format_handler]['#export_callback'],
-    $nodes,
-    $format_handler
-  );
-
-  // Let modules modify the node code.
-  drupal_alter('node_export_encode', $code_string, $nodes, $format_handler);
-
-  return array(
-    'success' => TRUE,
-    'output' => $code_string,
-    'format' => $format_handler,
-  );
-
-}
-
-/**
- * Prepare a single node during export.
- */
-function node_export_prepare_node(&$original_node) {
-  // Create UUID if it's not there.
-  if (!uuid_get_uuid('node', 'nid', $original_node->nid)) {
-    $original_node->uuid = uuid_set_uuid('node', 'nid', $original_node->nid);
-    // Save it so future node exports are consistent.
-    node_save($original_node);
-  }
-
-  $node = clone($original_node);
-
-  // Fix taxonomy array
-  if (isset($node->taxonomy) && count($node->taxonomy)) {
-    $vocabularies = taxonomy_get_vocabularies();
-    $new_taxonomy = array();
-    foreach ($node->taxonomy as $term) {
-      // Free-tagging vocabularies need a different format
-      if ($vocabularies[$term->vid]->tags) {
-        $new_taxonomy['tags'][$term->vid][] = $term->name;
-      }
-      else {
-        $new_taxonomy[$term->vid][$term->tid] = $term->tid;
-      }
-    }
-    if (isset($new_taxonomy['tags']) && count($new_taxonomy['tags'])) {
-      // Comma seperate the tags
-      foreach ($new_taxonomy['tags'] as $vid => $tags) {
-        $new_taxonomy['tags'][$vid] = implode(', ', $tags);
-      }
-    }
-    $node->taxonomy = $new_taxonomy;
-  }
-
-  // Attach path to the node.  Drupal doesn't attach this anymore for
-  // performance reasons http://drupal.org/node/332333#comment-2163634.
-  $node->path = path_load(array('source' => 'node/' . $node->nid));
-
-  // Fix menu array
-  $node->menu = node_export_get_menu($original_node);
-
-  // Remove recursion from the object.
-  $node = node_export_remove_recursion($node);
-
-  // Add a parameter to identify this node as coming from D7, might be useful some day.
-  $node->node_export_drupal_version = '7';
-
-  // Export file fields.
-  node_export_file_field_export($node, $original_node);
-
-  // Let other modules do special fixing up.
-  drupal_alter('node_export_node', $node, $original_node);
-
-  return $node;
-}
-
-/**
- *  Check if all types in the import exist.
- *
- *  @return
- *    TRUE if all types exist, otherwise an array of missing type names.
- */
-function node_export_import_types_check($nodes) {
-  $missing_types = array();
-  foreach ($nodes as $node) {
-    if (node_type_get_name($node) == FALSE) {
-      $missing_types[$node->type] = $node->type;
-    }
-  }
-  return (!empty($missing_types) ? $missing_types : TRUE);
-}
-
-/**
- * Import Function
- *
- * @param $code_string
- *   The string of export code.
- * @param $msg_t
- *   Function used to translate.
- * @param $save
- *   When TRUE will save the nodes that are imported.
- * @return
- *   An array with keys 'success' which is a boolean value representing whether
- *   the import was successful and 'output' which contains an array of
- *   translated strings to be shown to the user as messages.
- */
-function node_export_import($code_string, $msg_t = 't', $save = TRUE) {
-  // Early check to avoid letting hooligans and the elderly pass data to the
-  // eval() function call.
-  if (!node_export_access_import()) {
-    $error = $msg_t(
-      'You do not have permission to import any nodes.'
-    );
-    return array(
-      'success' => FALSE,
-      'output' => array($error),
-    );
-  }
-
-  // Allow modules to manipulate the $code_string.
-  drupal_alter('node_export_decode', $code_string);
-
-  // Pass the string to each format handler until one returns something useful.
-  $format_handlers = node_export_format_handlers();
-  $nodes = array();
-  $used_format = "";
-  foreach ($format_handlers as $format_handler => $format) {
-
-    if (!empty($format['#file']) && is_file($format['#file'])) {
-      require_once $format['#file'];
-    }
-
-    $nodes = call_user_func(
-      $format['#import_callback'],
-      $code_string
-    );
-
-    if (!empty($nodes)) {
-      $used_format = $format_handler;
-      break;
-    }
-  }
-
-  if (isset($nodes['success']) && !$nodes['success']) {
-    // Instead of returning nodes, the format handler returned an error array.
-    // Translate the errors and return them.
-    foreach ($nodes['output'] as $key => $output) {
-      $nodes['output'][$key] = $msg_t($output);
-    }
-    return array(
-      'success' => FALSE,
-      'output' => $nodes['output'],
-    );
-  }
-
-  if ($used_format == "") {
-    $error = $msg_t(
-      'Node export was unable to recognize the format of the supplied code.  No nodes imported.'
-    );
-    return array(
-      'success' => FALSE,
-      'output' => array($error),
-    );
-  }
-
-  $nodes = node_export_restore_recursion($nodes);
-
-  $types_exist = node_export_import_types_check($nodes);
-  if ($types_exist !== TRUE) {
-    // There was a problem with the content types check.
-    $error = $msg_t(
-      'Error encountered during import.  Node types unknown on this site: %t.  No nodes imported.',
-      array('%t' => implode(", ", $types_exist))
-    );
-    return array(
-      'success' => FALSE,
-      'output' => array($error),
-    );
-  }
-
-  if (!node_export_access_import_nodes($nodes)) {
-    // There was a problem with permissions.
-    $error = $msg_t(
-      'You do not have permission to perform a Node export: import on one or more of these nodes.  No nodes imported.'
-    );
-    return array(
-      'success' => FALSE,
-      'output' => array($error),
-    );
-  }
-
-  $count = 0;
-  $total = count($nodes);
-  // Let other modules do special fixing up.
-  drupal_alter('node_export_import', $nodes, $used_format, $save);
-  $new_nodes = array();
-  $messages = array();
-  foreach ($nodes as $original_node) {
-    $node = node_export_node_clone($original_node);
-
-    // Import file fields.
-    node_export_file_field_import($node, $original_node);
-
-    // Handle existing nodes.
-    $nids = entity_get_id_by_uuid('node', array($node->uuid));
-    if (!empty($nids[$node->uuid])) {
-      $existing = variable_get('node_export_existing', 'new');
-      switch ($existing) {
-        case 'new':
-          $node->is_new = TRUE;
-          unset($node->uuid);
-          break;
-        case 'revision':
-          $node->nid = $nids[$node->uuid];
-          $node->is_new = FALSE;
-          $node->revision = 1;
-          break;
-        case 'skip':
-          $save = FALSE;
-          break;
-      }
-    }
-
-    // Let other modules do special fixing up.
-    drupal_alter('node_export_node_import', $node, $original_node, $save);
-
-    if ($save) {
-      node_export_save($node);
-      $new_nodes[$node->nid] = $node;
-      $messages[] = $msg_t("Imported node !nid: !node", array('!nid' => $node->nid, '!node' => l($node->title, 'node/' . $node->nid)));
-      $count++;
-    }
-    else {
-      $new_nodes[] = $node;
-    }
-  }
-
-  if ($save) {
-    drupal_alter('node_export_after_import', $new_nodes, $used_format, $save);
-    $messages[] = $msg_t("!count of !total nodes were imported.  Some values may have been reset depending on Node export's configuration.", array('!total' => $total, '!count' => $count));
-
-    // Clear the page and block caches.
-    cache_clear_all();
-
-    // Nodes were saved, so return the nids.
-    return array(
-      'success' => TRUE,
-      'output' => $messages,
-      'nids' => array_keys($new_nodes),
-      'format' => $used_format,
-    );
-  }
-  else {
-    // We didn't save, so return full nodes.
-    return array(
-      'success' => TRUE,
-      'output' => $messages,
-      'nodes' => $new_nodes,
-      'format' => $used_format,
-    );
-  }
-
-}
-
-
-/**
- * Save a node object into the database.
- *
- * $node->changed is not forced like in node_save().
- *
- * A modified version of node_save().
- */
-function node_export_save(&$node) {
-  $transaction = db_transaction();
-
-  try {
-    // Load the stored entity, if any.
-    if (!empty($node->nid) && !isset($node->original)) {
-      $node->original = entity_load_unchanged('node', $node->nid);
-    }
-
-    field_attach_presave('node', $node);
-    global $user;
-
-    // Determine if we will be inserting a new node.
-    if (!isset($node->is_new)) {
-      $node->is_new = empty($node->nid);
-    }
-
-    // Set the timestamp fields.
-    if (empty($node->created)) {
-      $node->created = REQUEST_TIME;
-    }
-
-    // The update of the changed value is forced in the original node_save().
-    if (empty($node->changed)) {
-      $node->changed = REQUEST_TIME;
-    }
-
-    $node->timestamp = REQUEST_TIME;
-    $update_node = TRUE;
-
-    // Let modules modify the node before it is saved to the database.
-    module_invoke_all('node_presave', $node);
-
-    if ($node->is_new || !empty($node->revision)) {
-      // When inserting either a new node or a new node revision, $node->log
-      // must be set because {node_revision}.log is a text column and therefore
-      // cannot have a default value. However, it might not be set at this
-      // point (for example, if the user submitting a node form does not have
-      // permission to create revisions), so we ensure that it is at least an
-      // empty string in that case.
-      // @todo: Make the {node_revision}.log column nullable so that we can
-      // remove this check.
-      if (!isset($node->log)) {
-        $node->log = '';
-      }
-    }
-    elseif (empty($node->log)) {
-      // If we are updating an existing node without adding a new revision, we
-      // need to make sure $node->log is unset whenever it is empty. As long as
-      // $node->log is unset, drupal_write_record() will not attempt to update
-      // the existing database column when re-saving the revision; therefore,
-      // this code allows us to avoid clobbering an existing log entry with an
-      // empty one.
-      unset($node->log);
-    }
-
-    // When saving a new node revision, unset any existing $node->vid so as to
-    // ensure that a new revision will actually be created, then store the old
-    // revision ID in a separate property for use by node hook implementations.
-    if (!$node->is_new && !empty($node->revision) && $node->vid) {
-      $node->old_vid = $node->vid;
-      unset($node->vid);
-    }
-
-    // Save the node and node revision.
-    if ($node->is_new) {
-      // For new nodes, save new records for both the node itself and the node
-      // revision.
-      drupal_write_record('node', $node);
-      _node_save_revision($node, $user->uid);
-      $op = 'insert';
-    }
-    else {
-      // For existing nodes, update the node record which matches the value of
-      // $node->nid.
-      drupal_write_record('node', $node, 'nid');
-      // Then, if a new node revision was requested, save a new record for
-      // that; otherwise, update the node revision record which matches the
-      // value of $node->vid.
-      if (!empty($node->revision)) {
-        _node_save_revision($node, $user->uid);
-      }
-      else {
-        _node_save_revision($node, $user->uid, 'vid');
-        $update_node = FALSE;
-      }
-      $op = 'update';
-    }
-    if ($update_node) {
-      db_update('node')
-        ->fields(array('vid' => $node->vid))
-        ->condition('nid', $node->nid)
-        ->execute();
-    }
-
-    // Call the node specific callback (if any). This can be
-    // node_invoke($node, 'insert') or
-    // node_invoke($node, 'update').
-    node_invoke($node, $op);
-
-    // Save fields.
-    $function = "field_attach_$op";
-    $function('node', $node);
-
-    module_invoke_all('node_' . $op, $node);
-    module_invoke_all('entity_' . $op, $node, 'node');
-
-    // Update the node access table for this node. There's no need to delete
-    // existing records if the node is new.
-    $delete = $op == 'update';
-    node_access_acquire_grants($node, $delete);
-
-    // Clear internal properties.
-    unset($node->is_new);
-    unset($node->original);
-    // Clear the static loading cache.
-    entity_get_controller('node')->resetCache(array($node->nid));
-
-    // Ignore slave server temporarily to give time for the
-    // saved node to be propagated to the slave.
-    db_ignore_slave();
-  }
-  catch (Exception $e) {
-    $transaction->rollback();
-    watchdog_exception('node', $e);
-    throw $e;
-  }
-}
-
-/**
- * Prepare a clone of the node during import.
- */
-function node_export_node_clone($original_node) {
-  global $user;
-
-  $node = clone($original_node);
-
-  $node->nid = NULL;
-  $node->vid = NULL;
-
-  if (variable_get('node_export_reset_author_' . $node->type, TRUE)) {
-    $node->name = !empty($user->name) ? $user->name : (!empty($user->uid) ? NULL : variable_get('anonymous', t('Anonymous')));
-    $node->uid = $user->uid;
-  }
-
-  if (variable_get('node_export_reset_created_' . $node->type, TRUE)) {
-    $node->created = NULL;
-  }
-
-  if (variable_get('node_export_reset_changed_' . $node->type, TRUE)) {
-    $node->changed = NULL;
-  }
-
-  if (variable_get('node_export_reset_revision_timestamp_'. $node->type, TRUE)) {
-    $node->revision_timestamp = NULL;
-  }
-
-  if (variable_get('node_export_reset_last_comment_timestamp_'. $node->type, TRUE)) {
-    $node->last_comment_timestamp = NULL;
-  }
-
-  if (variable_get('node_export_reset_menu_' . $node->type, TRUE)) {
-    $node->menu = NULL;
-  }
-
-  if (variable_get('node_export_reset_path_' . $node->type, TRUE)) {
-    $node->path = NULL;
-  }
-  else {
-    if (is_array($node->path) && isset($node->path['pid'])) {
-      unset($node->path['pid']);
-    }
-    if (module_exists('pathauto')) {
-      // Prevent pathauto from creating a new path alias.
-      $node->path['pathauto'] = FALSE;
-    }
-  }
-
-  if (variable_get('node_export_reset_book_mlid_' . $node->type, TRUE) && isset($node->book['mlid'])) {
-    $node->book['mlid'] = NULL;
-  }
-
-  // @todo - is this still needed?
-  $node->files = array();
-
-  if (variable_get('node_export_reset_status_' . $node->type, FALSE)) {
-    $node->status = FALSE;
-  }
-
-  if (variable_get('node_export_reset_promote_' . $node->type, FALSE)) {
-    $node->promote = FALSE;
-  }
-
-  if (variable_get('node_export_reset_sticky_' . $node->type, FALSE)) {
-    $node->sticky = FALSE;
-  }
-
-  return $node;
-
-}
-
-/**
- * Create a new menu entry with title, parent and weight exported from
- * another nodes menu. Returns NULL if the node has no menu title.
- */
-function node_export_get_menu($node) {
-
-  // This will fetch the existing menu item if the node had one.
-  module_invoke_all('node_prepare', $node);
-
-  $type = $node->type;
-
-  // Only keep the values we care about.
-  if (!empty($node->menu['mlid'])) {
-
-    // Store a copy of the old menu
-    $old_menu = $node->menu;
-
-    // Now fetch the defaults for a new menu entry.
-    $node = new stdClass;
-    $node->type = $type;
-    //module_invoke_all('node_prepare', $node);
-
-    node_object_prepare($node);
-
-    // Make a list of values to attempt to copy.
-    $menu_fields = array(
-      'link_title',
-      'plid',
-      'menu_name',
-      'weight',
-      'hidden',
-      'expanded',
-      'has_children',
-    );
-
-    // Copy those fields from the old menu over the new menu defaults.
-    foreach ($menu_fields as $menu_field) {
-      $node->menu[$menu_field] = $old_menu[$menu_field];
-    }
-
-    // Copy the menu description from the old menu.
-    // Issue #1287300.
-    if (isset($old_menu['options']['attributes']['title'])) {
-      $node->menu['description'] = $old_menu['options']['attributes']['title'];
-    }
-    else {
-      $node->menu['description'] = '';
-    }
-
-    // Ensure menu will be created during node import.
-    // Issue #1139120.
-    $node->menu['enabled'] = 1;
-
-    // Return the menu.
-    return $node->menu;
-  }
-
-}
-
-/**
- * Remove recursion problem from an object or array.
- */
-function node_export_remove_recursion($o) {
-  static $replace;
-  if (!isset($replace)) {
-    $replace = create_function(
-      '$m',
-      '$r="\x00{$m[1]}ecursion_export_node_";return \'s:\'.strlen($r.$m[2]).\':"\'.$r.$m[2].\'";\';'
-    );
-  }
-  if (is_array($o) || is_object($o)) {
-    $re = '#(r|R):([0-9]+);#';
-    $serialize = serialize($o);
-    if (preg_match($re, $serialize)) {
-      $last = $pos = 0;
-      while (false !== ($pos = strpos($serialize, 's:', $pos))) {
-        $chunk = substr($serialize, $last, $pos - $last);
-        if (preg_match($re, $chunk)) {
-          $length = strlen($chunk);
-          $chunk = preg_replace_callback($re, $replace, $chunk);
-          $serialize = substr($serialize, 0, $last) . $chunk . substr($serialize, $last + ($pos - $last));
-          $pos += strlen($chunk) - $length;
-        }
-        $pos += 2;
-        $last = strpos($serialize, ':', $pos);
-        $length = substr($serialize, $pos, $last - $pos);
-        $last += 4 + $length;
-        $pos = $last;
-      }
-      $serialize = substr($serialize, 0, $last) . preg_replace_callback($re, $replace, substr($serialize, $last));
-      $o = unserialize($serialize);
-    }
-  }
-  return $o;
-}
-
-/**
- * Restore recursion to an object or array.
- */
-function node_export_restore_recursion($o) {
-  return unserialize(
-    preg_replace(
-      '#s:[0-9]+:"\x00(r|R)ecursion_export_node_([0-9]+)";#',
-      '\1:\2;',
-      serialize($o)
-    )
-  );
-}
-
-/**
- * Get a list of possible format handlers (other than the default).
- *
- * @return
- *   An array of format handlers from hook implementations.
- * @see hook_node_export_format_handlers()
- */
-function node_export_format_handlers() {
-  module_load_include('inc', 'node_export', 'node_export.formats');
-  $format_handlers = &drupal_static(__FUNCTION__);
-  if (empty($format_handlers)) {
-    $format_handlers = module_invoke_all('node_export_format_handlers');
-  }
-  return $format_handlers;
-}
-
-
-/**
- * Handle exporting file fields.
- */
-function node_export_file_field_export(&$node, $original_node) {
-  $types = array_filter(variable_get('node_export_file_types', array()));
-  if (in_array($node->type, $types)) {
-    $assets_path = variable_get('node_export_file_assets_path', '');
-    $export_mode = variable_get('node_export_file_mode', 'inline');
-
-    switch ($export_mode) {
-      case 'local':
-        $export_var = 'node_export_file_path';
-        break;
-      case 'remote':
-        $export_var = 'node_export_file_url';
-        break;
-      default:
-      case 'inline':
-        $export_var = 'node_export_file_data';
-        break;
-    }
-
-    // If files are supposed to be copied to the assets path.
-    if ($export_mode == 'local' && $assets_path) {
-      // Ensure the assets path is created
-      if (!is_dir($assets_path) && mkdir($assets_path, 0777, TRUE) == FALSE) {
-        drupal_set_message(t("Could not create assets path! '!path'", array('!path' => $assets_path)), 'error');
-        // Don't continue if the assets path is not ready
-        return;
-      }
-
-      // Ensure it is writable
-      if (!is_writable($assets_path)) {
-        drupal_set_message(t("Assets path is not writable! '!path'", array('!path' => $assets_path)), 'error');
-        // Don't continue if the assets path is not ready
-        return;
-      }
-    }
-
-    // get all fields from this node type
-    $fields = field_info_instances('node', $node->type);
-    foreach($fields as $field_instance) {
-
-      // load field infos to check the type
-      $field = &$node->{$field_instance['field_name']};
-      $info = field_info_field($field_instance['field_name']);
-
-      $supported_fields = array_map('trim', explode(',', variable_get('node_export_file_supported_fields', 'file, image')));
-
-      // check if this field should implement file import/export system
-      if (in_array($info['type'], $supported_fields)) {
-
-        // we need to loop into each language because i18n translation can build
-        // fields with different language than the node one.
-        foreach($field as $language => $files) {
-          if (is_array($files)) {
-            foreach($files as $i => $file) {
-
-              // convert file to array to stay into the default node_export_file format
-              $file = (object) $file;
-
-              // Check the file
-              if (!isset($file->uri) || !is_file($file->uri)) {
-                drupal_set_message(t("File field found on node, but file doesn't exist on disk? '!path'", array('!path' => $file->uri)), 'error');
-                continue;
-              }
-
-              if ($export_mode == 'local') {
-                if ($assets_path) {
-                  $export_data = $assets_path . '/' . basename($file->uri);
-                  if (!copy($file->uri, $export_data)) {
-                    drupal_set_message(t("Export file error, could not copy '%filepath' to '%exportpath'.", array('%filepath' => $file->uri, '%exportpath' => $export_data)), 'error');
-                    return FALSE;
-                  }
-                }
-                else {
-                  $export_data = $file->uri;
-                }
-              }
-              // Remote export mode
-              elseif ($export_mode == 'remote') {
-                $export_data = url($file->uri, array('absolute' => TRUE));
-              }
-              // Default is 'inline' export mode
-              else {
-                $export_data = base64_encode(file_get_contents($file->uri));
-              }
-
-              // build the field again, and remove fid to be sure that imported node
-              // will rebuild the file again, or keep an existing one with a different fid
-              $field[$language][$i]['fid'] = NULL;
-              $field[$language][$i][$export_var] = $export_data;
-
-            }
-          }
-        }
-      }
-    }
-  }
-}
-
-/**
- * Handle importing file fields.
- */
-function node_export_file_field_import(&$node, $original_node) {
-  // Get all fields from this node type.
-  $fields = field_info_instances('node', $node->type);
-  foreach($fields as $field_instance) {
-
-    // Load field info to check the type.
-    $field = &$node->{$field_instance['field_name']};
-    $info = field_info_field($field_instance['field_name']);
-
-    $supported_fields = array_map('trim', explode(',', variable_get('node_export_file_supported_fields', 'file, image')));
-
-    // Check if this field should implement file import/export system.
-    if (in_array($info['type'], $supported_fields)) {
-
-      // We need to loop into each language because i18n translation can build
-      // fields with different language than the node one.
-      foreach($field as $language => $files) {
-        if (is_array($files)) {
-          foreach($files as $i => $file) {
-
-            // Convert file to array to stay into the default node_export_file format.
-            $file = (object)$file;
-
-            $result = _node_export_file_field_import_file($file);
-            // The file was saved successfully, update the file field (by reference).
-            if ($result == TRUE && isset($file->fid)) {
-              $field[$language][$i] = (array)$file;
-            }
-
-          }
-        }
-      }
-    }
-  }
-}
-
-/**
- * Detects remote and local file exports and imports accordingly.
- *
- * @param &$file
- *   The file, passed by reference.
- * @return TRUE or FALSE
- *   Depending on success or failure.  On success the $file object will
- *   have a valid $file->fid attribute.
- */
-function _node_export_file_field_import_file(&$file) {
-  // This is here for historical reasons to support older exports.  It can be
-  // removed in the next major version.
-  $file->uri = strtr($file->uri, array('#FILES_DIRECTORY_PATH#' => 'public:/'));
-
-  // The file is already in the right location AND either the
-  // node_export_file_path is not set or the node_export_file_path and filepath
-  // contain the same file
-  if (is_file($file->uri) &&
-    (
-      (!isset($file->node_export_file_path) || !is_file($file->node_export_file_path)) ||
-      (
-        is_file($file->node_export_file_path) &&
-        filesize($file->uri) == filesize($file->node_export_file_path) &&
-        strtoupper(dechex(crc32(file_get_contents($file->uri)))) ==
-          strtoupper(dechex(crc32(file_get_contents($file->node_export_file_path))))
-      )
-    )
-  ) {
-    // Keep existing file if it exists already at this uri (see also #1023254)
-    // Issue #1058750.
-    $query = db_select('file_managed', 'f')
-        ->fields('f', array('fid'))
-        ->condition('uri', $file->uri)
-        ->execute()
-        ->fetchCol();
-
-    if (!empty($query)) {
-      watchdog('node_export', 'kept existing managed file at uri "%uri"', array('%uri' => $file->uri), WATCHDOG_NOTICE);
-      $file = file_load(array_shift($query));
-    }
-
-    $file = file_save($file);
-  }
-  elseif (isset($file->node_export_file_data)) {
-    $directory = drupal_dirname($file->uri);
-    if (file_prepare_directory($directory, FILE_CREATE_DIRECTORY)) {
-      if (file_put_contents($file->uri, base64_decode($file->node_export_file_data))) {
-        $file = file_save($file);
-      }
-    }
-  }
-  // The file is in a local location, move it to the
-  // destination then finish the save
-  elseif (isset($file->node_export_file_path) && is_file($file->node_export_file_path)) {
-    $directory = drupal_dirname($file->uri);
-    if (file_prepare_directory($directory, FILE_CREATE_DIRECTORY)) {
-      // The $file->node_export_file_path is passed to reference, and modified
-      // by file_unmanaged_copy().  Making a copy to avoid tainting the original.
-      $node_export_file_path = $file->node_export_file_path;
-      file_unmanaged_copy($node_export_file_path, $directory, FILE_EXISTS_REPLACE);
-
-      // At this point the $file->node_export_file_path will contain the
-      // destination of the copied file
-      //$file->uri = $node_export_file_path;
-      $file = file_save($file);
-    }
-  }
-  // The file is in a remote location, attempt to download it
-  elseif (isset($file->node_export_file_url)) {
-    // Need time to do the download
-    ini_set('max_execution_time', 900);
-
-    $temp_path = file_directory_temp() . '/' . md5(mt_rand()) . '.txt';
-    if (($source = fopen($file->node_export_file_url, 'r')) == FALSE) {
-      drupal_set_message(t("Could not open '@file' for reading.", array('@file' => $file->node_export_file_url)));
-      return FALSE;
-    }
-    elseif (($dest = fopen($temp_path, 'w')) == FALSE) {
-      drupal_set_message(t("Could not open '@file' for writing.", array('@file' => $file->uri)));
-      return FALSE;
-    }
-    else {
-      // PHP5 specific, downloads the file and does buffering
-      // automatically.
-      $bytes_read = @stream_copy_to_stream($source, $dest);
-
-      // Flush all buffers and wipe the file statistics cache
-      @fflush($source);
-      @fflush($dest);
-      clearstatcache();
-
-      if ($bytes_read != filesize($temp_path)) {
-        drupal_set_message(t("Remote export '!url' could not be fully downloaded, '@file' to temporary location '!temp'.", array('!url' => $file->node_export_file_url, '@file' => $file->uri, '!temp' => $temp_path)));
-        return FALSE;
-      }
-      // File was downloaded successfully!
-      else {
-        if (!@copy($temp_path, $file->uri)) {
-          unlink($temp_path);
-          drupal_set_message(t("Could not move temporary file '@temp' to '@file'.", array('@temp' => $temp_path, '@file' => $file->uri)));
-          return FALSE;
-        }
-
-        unlink($temp_path);
-        $file->filesize = filesize($file->uri);
-        $file->filemime = file_get_mimetype($file->uri);
-      }
-    }
-
-    fclose($source);
-    fclose($dest);
-
-    $file = file_save($file);
-  }
-  // Unknown error
-  else {
-    drupal_set_message(t("Unknown error occurred attempting to import file: @filepath", array('@filepath' => $file->uri)), 'error');
-    return FALSE;
-  }
-
-  return TRUE;
-}
-
-// Remove once http://drupal.org/node/858274 is resolved.
-if (!function_exists('uuid_set_uuid')) {
-  /**
-   * API function to set the UUID of an object based on its serial ID.
-   *
-   * @param $table
-   *   Base table of the object. Currently, one of node, revision_revisions,
-   *   users, vocabulary or term_data.
-   * @param $key
-   *   The name of the serial ID column.
-   * @param $serial_id
-   *   The serial ID of the object.
-   * @param $uuid
-   *   Optional UUID.  If omitted, a UUID will be generated.
-   * @return
-   *   The UUID on success, FALSE if the uuid provided is not valid.
-   */
-  function uuid_set_uuid($table, $key, $serial_id, $uuid = FALSE) {
-    if (empty($uuid)) {
-      $uuid = uuid_generate();
-    }
-
-    if (!uuid_is_valid($uuid)) {
-      return FALSE;
-    }
-
-    $query = db_query("UPDATE {" . $table . "} SET uuid = :uuid WHERE " . $key . " = :id", array(':uuid' => $uuid, ':id' => $serial_id));
-    /*
-    if (!$query->rowCount()) {
-      @db_query("INSERT INTO {" . $table . "} (" . $key . ", uuid) VALUES (:id, :uuid)", array(':uuid' => $uuid, ':id' => $serial_id));
-    }
-    */
-
-    return $uuid;
-  }
-}
-
-// Remove once http://drupal.org/node/858274 is resolved.
-if (!function_exists('uuid_get_uuid')) {
-  /**
-   * API function to get the UUID of an object based on its serial ID.
-   *
-   * @param $entity_type
-   *   The entity type.
-   * @param $key
-   *   The name of the serial ID column.
-   * @param $id
-   *   The serial ID of the object.
-   * @return
-   *   The UUID of the object, or FALSE if not found.
-   */
-  function uuid_get_uuid($entity_type, $key, $id) {
-    $supported = uuid_get_core_entity_info();
-    if (!isset($supported[$entity_type])) {
-      return FALSE;
-    }
-    $entity_info = entity_get_info($entity_type);
-    $table = $entity_info['base table'];
-    return db_query("SELECT uuid FROM {" . $table . "} WHERE " . $key . " = :id", array(':id' => $id))->fetchField();
-  }
-}

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

@@ -268,7 +268,7 @@ function node_export_settings($form, &$form_state) {
     '#title' => t('Supported file field types'),
     '#default_value' => variable_get('node_export_file_supported_fields', 'file, image'),
     '#maxlength' => 512,
-    '#description' => t('Comma seperated list of file field types to detect for export/import.'),
+    '#description' => t('Comma separated list of file field types to detect for export/import.'),
   );
 
   return system_settings_form($form);

+ 109 - 0
sites/all/modules/contrib/admin/node_export/node_export.test

@@ -0,0 +1,109 @@
+<?php
+/**
+ * @file
+ * Node export/import tests.
+ */
+
+define('ORIGINAL_TITLE', 'Original node title');
+define('CHANGED_TITLE', 'Changed node title');
+define('ORIGINAL_BODY', 'This is some original test text for the node body.');
+define('CHANGED_BODY', 'Changed test text for the node body.');
+
+/**
+ * Test XML export and import.
+ */
+class NodeExportXMLTestCase extends DrupalWebTestCase {
+  protected $user;
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Node Export XML export/import test',
+      'description' => 'Test exporting a node as XML, changing the exported XML, then importing the changed XML.',
+      'group' => 'Node Export',
+    );
+  }
+
+  function setUp() {
+    parent::setUp('node_export');
+    // Make sure the export gives back a file.
+    variable_set('node_export_code', 'file');
+    // We want to test XML export.
+    variable_set('node_export_format', array('xml'));
+    variable_set('node_export_existing', 'revision');
+    $this->user = $this->drupalCreateUser(array('access content', 'access administration pages', 'administer site configuration', 'administer users', 'administer permissions', 'administer content types', 'administer nodes', 'bypass node access', 'export nodes', 'export own nodes', 'use PHP to import nodes'));
+    $this->drupalLogin($this->user);
+  }
+
+  /**
+   * Test XML export and import.
+   */
+  function testNodeExportXMLExportImport() {
+    $langcode = LANGUAGE_NONE;
+    $title_key = 'title';
+    $body_key = "body[{$langcode}][0][value]";
+    $original_title = ORIGINAL_TITLE;
+    $changed_title = CHANGED_TITLE;
+    $original_body = ORIGINAL_BODY;
+    $changed_body = CHANGED_BODY;
+    $settings = array(
+      'type' => 'page',
+      'title' => $original_title,
+      'body' => array($langcode => array(array('value' => $original_body))),
+    );
+
+    $node = $this->drupalCreateNode($settings);
+
+    $this->verbose('Node created: ' . var_export($node, TRUE));
+    $this->drupalGet("node/{$node->nid}/edit");
+    $this->assertFieldByName($title_key, $original_title, "Found original title in edit form.");
+    $this->assertFieldByName($body_key, $original_body, "Found original body in edit form.");
+
+    // Test export.
+    $xml_file = $this->drupalGet("node/{$node->nid}/node_export");
+    // Check if the export is valid XML.
+    $this->assertResponse(200, 'Export was successful.');
+    $this->assertTrue(simplexml_load_string($xml_file), 'XML is valid.');
+
+    $node_export = simplexml_load_string($xml_file);
+    debug($node_export->asXml(), 'Before changing the XML');
+
+    // Find the original title in the XML.
+    $original_title_value = $node_export->xpath("node[1]/title[text() = '{$original_title}']");
+    $title_found = !empty($original_title_value);
+    $this->assertTrue($title_found, 'Original title was found in the XML.');
+    if ($title_found) {
+      // Change the title value.
+      $original_title_value[0][0] = $changed_title;
+    }
+    // Find the original body in the XML.
+    $original_body_value = $node_export->xpath("node[1]//body//n0//*[text() = '{$original_body}']");
+    $body_found = !empty($original_body_value);
+    $this->assertTrue($body_found, 'Original body was found in the XML.');
+    if ($body_found) {
+      // Change the body value.
+      $original_body_value[0][0] = $changed_body;
+    }
+
+    // Find the changed title in the XML.
+    $changed_title_value = $node_export->xpath("node[1]/title[text() = '{$changed_title}']");
+    $this->assertTrue(!empty($changed_title_value), 'Changed title was found in the XML.');
+    // Find the changed body in the XML.
+    $changed_body_value = $node_export->xpath("node[1]//body//n0//*[text() = '{$changed_body}']");
+    $this->assertTrue(!empty($changed_body_value), 'Changed body was found in the XML.');
+
+    if ($title_found || $body_found) {
+      debug($node_export->asXml(), 'After changing the XML');
+    }
+
+    // Test import.
+    $import_info = node_export_import($node_export->asXml());
+    $this->assertTrue($import_info['success'], 'Import was succesful.');
+    if ($import_info['success']) {
+      $this->assertEqual($import_info['format'], 'xml', 'XML was imported.');
+    }
+
+    $this->drupalGet("node/{$node->nid}/edit");
+    $this->assertFieldByName($title_key, $changed_title, "Found changed title in edit form.");
+    $this->assertFieldByName($body_key, $changed_body, "Found changed body in edit form.");
+  }
+}

+ 1 - 1
sites/all/modules/contrib/admin/node_export/node_export.tokens.inc

@@ -55,7 +55,7 @@ function node_export_token_info() {
       'node_export_filename' => array(
         'nid-list' => array(
           'name' => t("Node ID list"),
-          'description' => t("Comma seperated list of Node IDs in square brackets (if available)."),
+          'description' => t("Comma separated list of Node IDs in square brackets (if available)."),
         ),
         'node-count' => array(
           'name' => t("Node count"),

+ 3 - 8
sites/all/modules/contrib/admin/node_export/views/views_handler_field_node_link_export.inc

@@ -13,19 +13,14 @@
 class views_handler_field_node_link_export extends views_handler_field_node_link {
   function construct() {
     parent::construct();
-    $this->additional_fields['uid'] = 'uid';
-    $this->additional_fields['type'] = 'type';
-    $this->additional_fields['format'] = array('table' => 'node_revisions', 'field' => 'format');
+    $this->additional_fields['nid'] = 'nid';
   }
 
   function render($values) {
-    // Insure that user has access to export this node.
+    // Ensure that user has access to export this node.
     $node = new stdClass();
     $node->nid = $values->{$this->aliases['nid']};
-    $node->uid = $values->{$this->aliases['uid']};
-    $node->type = $values->{$this->aliases['type']};
-    $node->format = $values->{$this->aliases['format']};
-    if (!node_export_access_check($node)) {
+    if (!node_export_access_export($node->nid)) {
       return;
     }
 

+ 0 - 56
sites/all/modules/contrib/admin/node_export/views_bulk_operations_node_export_fails_with_undefined_function-1869918-33.patch

@@ -1,56 +0,0 @@
-diff --git a/node_export.module b/node_export.module
-index 8bdadb9..052fa6c 100755
---- a/node_export.module
-+++ b/node_export.module
-@@ -38,7 +38,7 @@ function node_export_menu() {
-     'description' => 'Configure the settings for Node export.',
-     'file' => 'node_export.pages.inc',
-   );
--  $selected_formats = variable_get('node_export_format', array('drupal'));
-+  $selected_formats = variable_get('node_export_format', array('drupal' => 'drupal'));
-   if (count(array_filter($selected_formats)) > 1) {
-     $format_handlers = node_export_format_handlers();
-     foreach ($format_handlers as $format_handler => $format) {
-@@ -218,7 +218,7 @@ function node_export_node_operations() {
-   $operations = array();
-   if (user_access('export nodes')) {
- 
--    $selected_formats = variable_get('node_export_format', array('drupal'));
-+    $selected_formats = variable_get('node_export_format', array('drupal' => 'drupal'));
-     if (count(array_filter($selected_formats)) > 1) {
-       $format_handlers = node_export_format_handlers();
-       foreach ($format_handlers as $format_handler => $format) {
-@@ -258,7 +258,7 @@ function node_export_bulk_operation($nodes = NULL, $format = NULL, $delivery = N
- function node_export_action_info() {
-   $actions = array();
-   if (user_access('export nodes')) {
--    $selected_formats = variable_get('node_export_format', array('drupal'));
-+    $selected_formats = variable_get('node_export_format', array('drupal' => 'drupal'));
-     $format_handlers = node_export_format_handlers();
-     foreach ($format_handlers as $format_handler => $format) {
-       if (!empty($selected_formats[$format_handler])) {
-@@ -296,10 +296,13 @@ function node_export_action_info() {
- function node_export_action_form($context, &$form_state, $format = NULL) {
-   // Get the name of the vbo views field
-   $vbo = _views_bulk_operations_get_field($form_state['build_info']['args'][0]);
-+
-   // Adjust the selection in case the user chose 'select all'
--  _views_bulk_operations_adjust_selection($form_state['selection'], $form_state['select_all_pages'], $vbo);
-+  if (!empty($form_state['select_all_pages'])) {
-+    views_bulk_operations_direct_adjust($form_state['selection'], $vbo);
-+  }
-   $nodes = array_combine($form_state['selection'], $form_state['selection']);
--  return node_export_bulk_operation($nodes);
-+  return node_export_bulk_operation($nodes, $format);
- }
- 
- /**
-@@ -347,7 +350,7 @@ function node_export($nids, $format = NULL, $msg_t = 't') {
- 
-   // Get the node code from the format handler
-   $format_handlers = node_export_format_handlers();
--  $node_export_format = variable_get('node_export_format', array('drupal'));
-+  $node_export_format = variable_get('node_export_format', array('drupal' => 'drupal'));
-   $format_handler = $format ? $format : reset($node_export_format);
-   if (!isset($format_handlers[$format_handler])) {
-     $format_handler = 'drupal';

+ 16 - 0
sites/all/modules/contrib/mail/mimemail/CHANGELOG.txt

@@ -1,6 +1,22 @@
 Mime Mail 7.x-1.x, xxxx-xx-xx
 -----------------------
 
+Mime Mail 7.x-1.0-beta4, 2015-08-02
+-----------------------
+- #2413495 by sgabe, siggi_kid: Public images not embedded when file default scheme is private
+- #2312747 by Lukas von Blarer: Remove 'itok' token from image URL
+- #2366659 by david_garcia: Attachments created by content generate warnings
+- #2404719 by alexp999: Missing space in RFC headers breaks DKIM
+- #1908318 by jvieille, zionduc, bisonbleu | anrkaid: Sender is double encoded.
+- #2359771 by PascalAnimateur: Support for OG membership tokens.
+- #2218037 by sgabe | pinkonomy: Fixed integrity constraint violation.
+- #2219609 by mitrpaka, sgabe: Convert float properties just for images.
+- #2057703 by New Zeal, sgabe: Warning: is_file() expects a valid path.
+- #2202127 by k.skarlatos: Added List-Unsubscribe header field for bulk mails.
+- #2297135 by tobiasb: Language prefix with absolute-path reference.
+- #2297091 by cameron1729: TLDs in Return-Path trimmed to 4 characters.
+- #2237109 by Dane Powell: Indicate text format for body in Rules.
+
 Mime Mail 7.x-1.0-beta3, 2014-03-05
 -----------------------
 - Public files test incorrect if similar path is not below root.

+ 11 - 7
sites/all/modules/contrib/mail/mimemail/README.txt

@@ -84,6 +84,12 @@
     the mail.css file found anywhere in your theme folder or
     the combined CSS style sheets of your theme if enabled.
 
+  Since some email clients (namely Outlook 2007 and GMail) is tend to only regard
+  inline CSS, you can use the Compressor to convert CSS styles into inline style
+  attributes. It transmogrifies the HTML source by parsing the CSS and inserting the
+  CSS definitions into tags within the HTML based on the CSS selectors. To use the
+  Compressor, just enable it.
+
   To create a custom mail template copy the mimemail-message.tpl.php file from
   the mimemail/theme directory into your default theme's folder. Both general and
   by-mailkey theming can be performed:
@@ -100,17 +106,15 @@
   or any other active theme.
 
   Images with absolute URL will be available as remote content. To embed images
-  into emails you have to use a relative URL or an internal path.
+  into emails you have to use a relative URL or an internal path. Due to security
+  concerns, only files residing in the public file system (e.g sites/default/files)
+  can be used by default.
+
   For example:
     instead of http://www.mysite.com/sites/default/files/mypicture.jpg
     use /home/www/public_html/drupal/sites/default/files/mypicture.jpg
     or /sites/default/files/mypicture.jpg
-
-  Since some email clients (namely Outlook 2007 and GMail) is tend to only regard
-  inline CSS, you can use the Compressor to convert CSS styles into inline style
-  attributes. It transmogrifies the HTML source by parsing the CSS and inserting the
-  CSS definitions into tags within the HTML based on the CSS selectors. To use the
-  Compressor, just enable it.
+    or public://mypicture.jpg
 
   The 'send arbitrary files' permission allows you to attach or embed files located
   outside Drupal's public files directory. Note that this has security implications:

+ 4 - 0
sites/all/modules/contrib/mail/mimemail/includes/mimemail.admin.inc

@@ -84,6 +84,10 @@ function mimemail_admin_settings() {
     '#default_value' => variable_get('mimemail_format', filter_fallback_format()),
     '#access' => count($formats) > 1,
     '#attributes' => array('class' => array('filter-list')),
+    '#description' => t('The filter set that will be applied to the message body.
+      If you are using Mime Mail as default mail sytem, make sure to enable
+      "Convert line breaks into HTML" and "Convert URLs into links" with a long
+      enough maximum length for e.g. password reset URLs!'),
   );
 
   $form['mimemail']['advanced'] = array(

+ 24 - 19
sites/all/modules/contrib/mail/mimemail/mimemail.inc

@@ -37,7 +37,7 @@ function mimemail_rfc_headers($headers) {
         $value = wordwrap($value, 50, "$crlf ", FALSE);
       }
     }
-    $header .= $key . ":" . $value . $crlf;
+    $header .= $key . ": " . $value . $crlf;
   }
   return trim($header);
 }
@@ -66,7 +66,8 @@ function mimemail_headers($headers, $from = NULL) {
     }
     // This may not work. The MTA may rewrite the Return-Path.
     if (!isset($headers['Return-Path']) || $headers['Return-Path'] == $default_from) {
-      if (preg_match('/[a-z\d\-\.\+_]+@(?:[a-z\d\-]+\.)+[a-z\d]{2,4}/i', $from, $matches)) {
+      // According to IANA the current longest TLD is 23 characters.
+      if (preg_match('/[a-z\d\-\.\+_]+@(?:[a-z\d\-]+\.)+[a-z\d]{2,23}/i', $from, $matches)) {
         $headers['Return-Path'] = "<$matches[0]>";
       }
     }
@@ -80,7 +81,10 @@ function mimemail_headers($headers, $from = NULL) {
   // Run all headers through mime_header_encode() to convert non-ascii
   // characters to an rfc compliant string, similar to drupal_mail().
   foreach ($headers as $key => $value) {
-    $headers[$key] = mime_header_encode($value);
+    // According to RFC 2047 addresses MUST NOT be encoded.
+    if ($key !== 'From' && $key !== 'Sender') {
+      $headers[$key] = mime_header_encode($value);
+    }
   }
 
   return $headers;
@@ -187,19 +191,22 @@ function _mimemail_file($url = NULL, $content = NULL, $name = '', $type = '', $d
     $file = $content;
   }
 
-  if (isset($file) && (@is_file($file) || $content)) {
-    $public_path = file_default_scheme() . '://';
-    $no_access = !user_access('send arbitrary files');
-    $not_in_public_path = strpos(drupal_realpath($file), drupal_realpath($public_path)) !== 0;
-    if (@is_file($file) && $not_in_public_path && $no_access) {
-      return $url;
+  if (isset($file)) {
+    $is_file = @is_file($file);
+
+    if ($is_file) {
+      $access = user_access('send arbitrary files');
+      $in_public_path = strpos(@drupal_realpath($file), drupal_realpath('public://')) === 0;
+      if (!$in_public_path && !$access) {
+        return $url;
+      }
     }
 
     if (!$name) {
-      $name = (@is_file($file)) ? basename($file) : 'attachment.dat';
+      $name = $is_file ? basename($file) : 'attachment.dat';
     }
     if (!$type) {
-      $type = ($name) ? file_get_mimetype($name) : file_get_mimetype($file);
+      $type = $is_file ? file_get_mimetype($file) : file_get_mimetype($name);
     }
 
     $id = md5($file) .'@'. $_SERVER['HTTP_HOST'];
@@ -322,7 +329,7 @@ function mimemail_multipart_body($parts, $content_type = 'multipart/mixed; chars
       }
 
       if (isset($part['file'])) {
-        $file = (is_file($part['file'])) ? file_get_contents($part['file']) : $part['file'];
+        $file = (@is_file($part['file'])) ? file_get_contents($part['file']) : $part['file'];
         $part_body = chunk_split(base64_encode($file), 76, variable_get('mimemail_crlf', "\n"));
 
       }
@@ -457,17 +464,14 @@ function _mimemail_url($url, $to_embed = NULL) {
   else {
     $url = preg_replace('!^' . base_path() . '!', '', $url, 1);
     if ($is_image) {
+      // Remove security token from URL, this allows for styled image embedding.
+      // @see https://drupal.org/drupal-7.20-release-notes
+      $url = preg_replace('/\\?itok=.*$/', '', $url);
       if ($to_link) {
         // Exclude images from embedding if needed.
         $url = file_create_url($url);
         $url = str_replace(' ', '%20', $url);
       }
-      else {
-        // Remove security token from URL, this allows for styled image embedding.
-        // @see https://drupal.org/drupal-7.20-release-notes
-        $url = preg_replace('/\\?itok=.*$/', '', $url);
-      }
-
     }
     return $url;
   }
@@ -490,9 +494,10 @@ function _mimemail_url($url, $to_embed = NULL) {
   $language = language_default();
 
   // Check for language prefix.
+  $path = trim($path, '/');
   $args = explode('/', $path);
   foreach ($languages as $lang) {
-    if ($args[0] == $lang->prefix) {
+    if (!empty($args) && $args[0] == $lang->prefix) {
       $prefix = array_shift($args);
       $language = $lang;
       $path = implode('/', $args);

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

@@ -14,9 +14,9 @@ files[] = tests/mimemail.test
 files[] = tests/mimemail_rules.test
 files[] = tests/mimemail_compress.test
 
-; Information added by Drupal.org packaging script on 2014-03-05
-version = "7.x-1.0-beta3"
+; Information added by Drupal.org packaging script on 2015-08-02
+version = "7.x-1.0-beta4"
 core = "7.x"
 project = "mimemail"
-datestamp = "1394018015"
+datestamp = "1438530555"
 

+ 2 - 7
sites/all/modules/contrib/mail/mimemail/mimemail.install

@@ -5,13 +5,6 @@
  * Install, update and uninstall functions for Mime Mail module.
  */
 
-/**
- * Implements hook_install().
- */
-function mimemail_install() {
-  user_role_grant_permissions(DRUPAL_AUTHENTICATED_RID, array('edit mimemail user settings'));
-}
-
 /**
  * Implements hook_enable().
  */
@@ -23,6 +16,8 @@ function mimemail_enable() {
       'mimemail' => 'MimeMailSystem',
     )
   );
+
+  user_role_grant_permissions(DRUPAL_AUTHENTICATED_RID, array('edit mimemail user settings'));
 }
 
 /**

+ 1 - 0
sites/all/modules/contrib/mail/mimemail/mimemail.module

@@ -157,6 +157,7 @@ function mimemail_mail($key, &$message, $params) {
     'cc' => 'Cc',
     'bcc' => 'Bcc',
     'reply-to' => 'Reply-to',
+    'list-unsubscribe' => 'List-Unsubscribe',
   );
   foreach ($address_headers as $param_key => $address_header) {
     $params[$param_key] = empty($params[$param_key]) ? array() : explode(',', $params[$param_key]);

+ 10 - 3
sites/all/modules/contrib/mail/mimemail/mimemail.rules.inc

@@ -57,6 +57,12 @@ function mimemail_rules_action_info() {
           'description' => t("The address to reply to. Leave it empty to use the sender's address."),
           'optional' => TRUE,
         ),
+        'list_unsubscribe' => array(
+          'type' => 'text',
+          'label' => t('Unsubscription e-mail and/or URL'),
+          'description' => t("An e-mail address and/or a URL which can be used for unsubscription. Values must be enclosed by angel brackets and separated by a comma."),
+          'optional' => TRUE,
+        ),
         'subject' => array(
           'type' => 'text',
           'label' => t('Subject'),
@@ -66,7 +72,7 @@ function mimemail_rules_action_info() {
         'body' => array(
           'type' => 'text',
           'label' => t('Body'),
-          'description' => t("The mail's message HTML body."),
+          'description' => t('The mail\'s HTML body. Will be formatted using the text format selected on the <a href="@url">settings</a> page.', array('@url' => url('admin/config/system/mimemail'))),
           'sanitize' => TRUE,
           'optional' => TRUE,
           'translatable' => TRUE,
@@ -74,7 +80,7 @@ function mimemail_rules_action_info() {
         'plaintext' => array(
           'type' => 'text',
           'label' => t('Plain text body'),
-          'description' => t("The mail's message plaintext body."),
+          'description' => t("The mail's plaintext body."),
           'optional' => TRUE,
           'translatable' => TRUE,
         ),
@@ -238,7 +244,7 @@ function mimemail_rules_action_mail_to_users_of_role_upgrade($element, RulesPlug
 /**
  * Action Implementation: Send HTML mail.
  */
-function rules_action_mimemail($key, $to, $cc = NULL, $bcc = NULL, $from_name = NULL, $from_mail = NULL, $reply_to = NULL, $subject, $body, $plaintext = NULL, $attachments = array(), $langcode, $settings, RulesState $state, RulesPlugin $element) {
+function rules_action_mimemail($key, $to, $cc = NULL, $bcc = NULL, $from_name = NULL, $from_mail = NULL, $reply_to = NULL, $list_unsubscribe = NULL, $subject, $body, $plaintext = NULL, $attachments = array(), $langcode, $settings, RulesState $state, RulesPlugin $element) {
   module_load_include('inc', 'mimemail');
 
   // Set the sender name and from address.
@@ -268,6 +274,7 @@ function rules_action_mimemail($key, $to, $cc = NULL, $bcc = NULL, $from_name =
     'cc' => $cc,
     'bcc' => $bcc,
     'reply-to' => $reply_to,
+    'list-unsubscribe' => $list_unsubscribe,
     'plaintext' => $plaintext,
     'attachments' => $attachments,
   );

+ 3 - 3
sites/all/modules/contrib/mail/mimemail/modules/mimemail_action/mimemail_action.info

@@ -6,9 +6,9 @@ dependencies[] = trigger
 core = 7.x
 
 
-; Information added by Drupal.org packaging script on 2014-03-05
-version = "7.x-1.0-beta3"
+; Information added by Drupal.org packaging script on 2015-08-02
+version = "7.x-1.0-beta4"
 core = "7.x"
 project = "mimemail"
-datestamp = "1394018015"
+datestamp = "1438530555"
 

+ 5 - 1
sites/all/modules/contrib/mail/mimemail/modules/mimemail_action/mimemail_action.module

@@ -24,7 +24,11 @@ function mimemail_action_info() {
  */
 function mimemail_send_email_action($entity, $context) {
   if (empty($context['node'])) {
-    $context['node'] = $entity;
+    if (get_class($entity) == 'OgMembership') {
+      $context['user'] = user_load($entity->etid);
+    } else {
+      $context['node'] = $entity;
+    }
   }
 
   $to = token_replace($context['to'], $context);

+ 1 - 1
sites/all/modules/contrib/mail/mimemail/modules/mimemail_compress/mimemail_compress.inc

@@ -145,7 +145,7 @@ class mimemail_compress {
 
         // Convert float to align for images.
         $float = preg_match ('/float:(left|right)/', $style, $matches);
-        if ($float) {
+        if ($node->nodeName == 'img' && $float) {
           $node->setAttribute('align', $matches[1]);
           $node->setAttribute('vspace', 5);
           $node->setAttribute('hspace', 5);

+ 3 - 3
sites/all/modules/contrib/mail/mimemail/modules/mimemail_compress/mimemail_compress.info

@@ -6,9 +6,9 @@ core = 7.x
 
 files[] = mimemail_compress.inc
 
-; Information added by Drupal.org packaging script on 2014-03-05
-version = "7.x-1.0-beta3"
+; Information added by Drupal.org packaging script on 2015-08-02
+version = "7.x-1.0-beta4"
 core = "7.x"
 project = "mimemail"
-datestamp = "1394018015"
+datestamp = "1438530555"
 

+ 12 - 0
sites/all/modules/contrib/mail/mimemail/modules/mimemail_example/mimemail_example.info

@@ -0,0 +1,12 @@
+name = Mime Mail Example
+description = Example of how to use the Mime Mail module.
+dependencies[] = mimemail
+package = Example modules
+core = 7.x
+
+; Information added by Drupal.org packaging script on 2015-08-02
+version = "7.x-1.0-beta4"
+core = "7.x"
+project = "mimemail"
+datestamp = "1438530555"
+

+ 20 - 0
sites/all/modules/contrib/mail/mimemail/modules/mimemail_example/mimemail_example.install

@@ -0,0 +1,20 @@
+<?php
+
+/**
+ * @file
+ * Install, update and uninstall functions for Mime Mail Example module.
+ */
+
+/**
+ * Implements hook_enable().
+ */
+function mimemail_example_enable() {
+  mailsystem_set(array('mimemail_example' => 'MimeMailSystem'));
+}
+
+/**
+ * Implements hook_disable().
+ */
+function mimemail_example_disable() {
+  mailsystem_clear(array('mimemail_example' => 'MimeMailSystem'));
+}

+ 170 - 0
sites/all/modules/contrib/mail/mimemail/modules/mimemail_example/mimemail_example.module

@@ -0,0 +1,170 @@
+<?php
+
+/**
+ * @file
+ * Core and contrib hook implementations for Mime Mail Example module.
+ */
+
+/**
+ * Implements hook_menu().
+ */
+function mimemail_example_menu() {
+  $items['example/mimemail_example'] = array(
+    'title' => 'Mime Mail Example',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('mimemail_example_form'),
+    'access arguments' => array('access content'),
+  );
+
+  return $items;
+}
+
+/**
+ * Implements hook_mail().
+ */
+function mimemail_example_mail($key, &$message, $params) {
+  $message['subject'] = $params['subject'];
+  $message['body'][] = $params['body'];
+}
+
+/**
+ * The example email contact form.
+ */
+function mimemail_example_form() {
+  global $user;
+
+  $form['intro'] = array(
+    '#markup' => t('Use this form to send a HTML message to an e-mail address. No spamming!'),
+  );
+
+  $form['key'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Key'),
+    '#default_value' => 'test',
+    '#required' => TRUE,
+  );
+
+  $form['to'] = array(
+    '#type' => 'textfield',
+    '#title' => t('To'),
+    '#default_value' => $user->mail,
+    '#required' => TRUE,
+  );
+
+  $form['from'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Sender name'),
+  );
+
+  $form['from_mail'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Sender e-mail address'),
+  );
+
+  $form['params'] = array(
+    '#tree' => TRUE,
+    'headers' => array(
+      'Cc' => array(
+        '#type' => 'textfield',
+        '#title' => t('Cc'),
+      ),
+      'Bcc' => array(
+        '#type' => 'textfield',
+        '#title' => t('Bcc'),
+      ),
+      'Reply-to' => array(
+        '#type' => 'textfield',
+        '#title' => t('Reply to'),
+      ),
+      'List-unsubscribe' => array(
+        '#type' => 'textfield',
+        '#title' => t('List-unsubscribe'),
+      ),
+    ),
+    'subject' => array(
+      '#type' => 'textfield',
+      '#title' => t('Subject'),
+    ),
+    'body' => array(
+      '#type' => 'textarea',
+      '#title' => t('HTML message'),
+    ),
+    'plain' => array(
+      '#type' => 'hidden',
+      '#states' => array(
+        'value' => array(
+          ':input[name="body"]' => array('value' => ''),
+        ),
+      ),
+    ),
+    'plaintext' => array(
+      '#type' => 'textarea',
+      '#title' => t('Plain text message'),
+    ),
+    'attachments' => array(
+      '#name' => 'files[attachment]',
+      '#type' => 'file',
+      '#title' => t('Choose a file to send as attachment'),
+    ),
+  );
+
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Send message'),
+  );
+
+  return $form;
+}
+
+/**
+ * Form validation logic for the email contact form.
+ */
+function mimemail_example_form_validate($form, &$form_state) {
+  $values = &$form_state['values'];
+
+  if (!valid_email_address($values['to'])) {
+    form_set_error('to', t('That e-mail address is not valid.'));
+  }
+
+  $file = file_save_upload('attachment');
+  if ($file) {
+    $file = file_move($file, 'public://');
+    $values['params']['attachments'][] = array(
+      'filepath' => $file->uri,
+    );
+  }
+}
+
+/**
+ * Form submission logic for the email contact form.
+ */
+function mimemail_example_form_submit($form, &$form_state) {
+  $values = $form_state['values'];
+
+  $module = 'mimemail_example';
+  $key = $values['key'];
+  $to = $values['to'];
+  $language = language_default();
+  $params = $values['params'];
+
+  if (!empty($values['from_mail'])) {
+    module_load_include('inc', 'mimemail');
+    $from = mimemail_address(array(
+      'name' => $values['from'],
+      'mail' => $values['from_mail'],
+    ));
+  }
+  else {
+    $from = $values['from'];
+  }
+
+  $send = TRUE;
+
+  $result = drupal_mail($module, $key, $to, $language, $params, $from, $send);
+  if ($result['result'] == TRUE) {
+    drupal_set_message(t('Your message has been sent.'));
+  }
+  else {
+    drupal_set_message(t('There was a problem sending your message and it was not sent.'), 'error');
+  }
+}

+ 7 - 3
sites/all/modules/contrib/mail/mimemail/tests/mimemail.test

@@ -71,12 +71,16 @@ class MimeMailWebTestCase extends DrupalWebTestCase {
   public function setUp() {
     parent::setUp('mailsystem', 'mimemail');
 
-    // Create and login user.
-    $this->adminUser = $this->drupalCreateUser(array(
+    $permissions = array(
       'access administration pages',
       'administer site configuration',
-    ));
+    );
 
+    // Check to make sure that the array of permissions are valid.
+    $this->checkPermissions($permissions, TRUE);
+
+    // Create and login user.
+    $this->adminUser = $this->drupalCreateUser($permissions);
     $this->drupalLogin($this->adminUser);
   }
 

+ 8 - 3
sites/all/modules/contrib/mail/mimemail/tests/mimemail_rules.test

@@ -24,15 +24,20 @@ class MimeMailRulesTestCase extends DrupalWebTestCase {
   public function setUp() {
     parent::setUp('mailsystem', 'locale', 'entity', 'entity_token', 'rules', 'mimemail');
 
-    // Create and login user.
-    $this->adminUser = $this->drupalCreateUser(array(
+    $permissions = array(
       'access administration pages',
       'edit mimemail user settings',
       'administer languages',
       'administer rules',
       'bypass rules access',
       'access rules debug',
-    ));
+    );
+
+    // Check to make sure that the array of permissions are valid.
+    $this->checkPermissions($permissions, TRUE);
+
+    // Create and login user.
+    $this->adminUser = $this->drupalCreateUser($permissions);
     $this->drupalLogin($this->adminUser);
 
     // Enable another language too.