Index: uuid_features_do/uuid_features.module
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
Subsystem: com.intellij.openapi.diff.impl.patch.BaseRevisionTextPatchEP
<+><?php\n\n/**\n * Implements hook_menu().\n */\nfunction uuid_features_menu() {\n  $items['admin/config/content/uuid_features'] = array(\n    'access arguments' => array('administer site configuration'),\n    'page callback' => 'drupal_get_form',\n    'page arguments' => array('uuid_features_settings'),\n    'title' => 'UUID Features Integration',\n    'description' => 'Configure the settings for UUID Features Integration.',\n  );\n  return $items;\n}\n\n/**\n * Implements hook_features_api().\n */\nfunction uuid_features_features_api() {\n  $components = array();\n\n  $components['uuid_node'] = array(\n    'name' => t('Content'),\n    'feature_source' => TRUE,\n    'default_hook' => 'uuid_features_default_content',\n    'default_file' => FEATURES_DEFAULTS_INCLUDED,\n    'file' => drupal_get_path('module', 'uuid_features') . '/includes/uuid_node.features.inc',\n  );\n\n  if (module_exists('taxonomy')) {\n    $components['uuid_term'] = array(\n      'name' => t('Taxonomy Term'),\n      'feature_source' => TRUE,\n      'default_hook' => 'uuid_features_default_terms',\n      'default_file' => FEATURES_DEFAULTS_INCLUDED,\n      'file' => drupal_get_path('module', 'uuid_features') . '/includes/uuid_term.features.inc',\n    );\n  }\n\n  // Depends on http://drupal.org/node/808690\n  if (function_exists('uuid_file_insert')) {\n    $components['uuid_file'] = array(\n      'name' => t('File'),\n      'default_hook' => 'uuid_features_default_files',\n      'default_file' => FEATURES_DEFAULTS_INCLUDED,\n      'file' => drupal_get_path('module', 'uuid_features') . '/includes/uuid_file.features.inc',\n    );\n  }\n\n  $components['uuid_bean'] = array(\n    'name' => t('Bean'),\n    'feature_resource' => TRUE,\n    'default_hook' => 'uuid_features_default_beans',\n    'default_file' => FEATURES_DEFAULTS_INCLUDED,\n    'file' => drupal_get_path('module', 'uuid_features') . '/includes/uuid_bean.features.inc',\n  );\n\n  return $components;\n}\n\n/**\n * Load all include files for enabled modules that this module provides\n * on-behalf-of functionality for.\n */\nfunction uuid_features_load_module_includes() {\n  static $loaded = FALSE;\n\n  if (!$loaded) {\n    $inc_path = drupal_get_path('module', 'uuid_features') . '/includes/modules';\n    foreach (module_list() as $module) {\n      $file = \"$inc_path/$module.inc\";\n      if (file_exists($file)) {\n        include_once DRUPAL_ROOT . '/' . $file;\n      }\n    }\n    $loaded = TRUE;\n  }\n}\n\n/**\n * Implements hook_features_pipe_COMPONENT_alter().\n *\n * When exporting a vocabulary, include its terms.\n */\nfunction uuid_features_features_pipe_taxonomy_alter(&$pipe, $data, $export) {\n  if (variable_get('uuid_features_vocabulary_terms', FALSE) == TRUE) {\n    if (!is_array($data)) {\n      $data = array($data);\n    }\n    if (empty($pipe['uuid_term'])) {\n      $pipe['uuid_term'] = array();\n    }\n    foreach ($data as $machine_name) {\n      if ($vocab = taxonomy_vocabulary_machine_name_load($machine_name)) {\n        $export['features']['uuid_term'] = array();\n        foreach (taxonomy_get_tree($vocab->vid) as $term) {\n          uuid_term_features_get_dependencies($export, $term->uuid);\n        }\n        if (!empty($export['features']['uuid_term'])) {\n          $pipe['uuid_term'] = array_merge($pipe['uuid_term'], $export['features']['uuid_term']);\n        }\n      }\n    }\n  }\n}\n/**\n * Menu callback to configure module settings.\n */\nfunction uuid_features_settings($form, &$form_state) {\n\n  $form['settings']['uuid_features_vocabulary_terms'] = array(\n    '#type' => 'checkbox',\n    '#title' => t('Auto detect uuid terms'),\n    '#description' => t('When exporting a vocabulary, include its terms.'),\n    '#default_value' => variable_get('uuid_features_vocabulary_terms', FALSE),\n  );\n\n  $entity_info = entity_get_info();\n  foreach ($entity_info as $type => $info) {\n    foreach($info['bundles'] as $bundle => $bundle_info) {\n      $bundles[$type][$bundle] = $bundle_info['label'];\n    }\n  }\n\n  $form['file']['uuid_features_file_node_types'] = array(\n    '#type' => 'checkboxes',\n    '#title' => t('Files exported for nodes'),\n    '#description' => t('Which content types should export file fields?'),\n    '#default_value' => variable_get('uuid_features_file_node_types', array()),\n    '#options' => $bundles['node'],\n  );\n\n  $form['file']['uuid_features_file_taxonomy_term_types'] = array(\n    '#type' => 'checkboxes',\n    '#title' => t('Files exported for taxonomy terms'),\n    '#description' => t('Which vocabularies should export file fields?'),\n    '#default_value' => variable_get('uuid_features_file_taxonomy_term_types', array()),\n    '#options' => $bundles['taxonomy_term'],\n  );\n\n  $form['file']['uuid_features_file_mode'] = array(\n    '#type' => 'radios',\n    '#title' => t('File export mode'),\n    '#default_value' => variable_get('uuid_features_file_mode', 'inline'),\n    '#options' => array(\n      'inline' => t('Inline Base64'),\n      'local' => t('Local file export'),\n      'remote' => t('Remote file export, URL')\n     ),\n    '#description' => t('Should file exports be inline inside the export code, a local path to the file, or a URL? Inline Base64 is the easiest option to use but can sometimes exceed PHP post limits, local and remote modes are more useful for power users.  <em>NOTE: Remote mode only works with a public files directory.</em>'),\n  );\n\n  $form['file']['uuid_features_file_assets_path'] = array(\n    '#type' => 'textfield',\n    '#title' => t('Local file field assets path'),\n    '#size' => 60,\n    '#maxlength' => 255,\n    '#default_value' => variable_get('uuid_features_file_assets_path', ''),\n    '#description' => t(\n      'Optionally, copy files to this path when the node is exported.\n      The primary advantage of this is to divert exported files into a\n      safe location so they can be committed to source control (eg: SVN,\n      CVS, Git).  <em>Tip: For install profile developers, setting this\n      path to <code>profiles/my_profile/uuid_features_assets</code> may be\n      useful.</em>'\n    ),\n    '#required' => FALSE,\n    '#states' => array(\n      'visible' => array(\n        ':input[name=uuid_features_file_mode]' => array('value' => 'local'),\n      ),\n    ),\n  );\n\n  $form['file']['uuid_features_file_supported_fields'] = array(\n    '#type' => 'textfield',\n    '#title' => t('Supported file field types'),\n    '#default_value' => variable_get('uuid_features_file_supported_fields', 'file, image'),\n    '#maxlength' => 512,\n    '#description' => t('Comma seperated list of file field types to detect for export/import.'),\n  );\n\n  return system_settings_form($form);\n}\n\n/**\n * Handle exporting file fields.\n */\nfunction uuid_features_file_field_export(&$export, $entity_type) {\n  switch ($entity_type) {\n    case \"taxonomy_term\":\n      $export_bundle = $export->vocabulary_machine_name;\n      break;\n    case \"node\":\n      $export_bundle = $export->type;\n      break;\n  }\n  $bundles = array_filter(variable_get('uuid_features_file_' . $entity_type . '_types', array()));\n  $fields = field_info_instances($entity_type, $export_bundle);\n  $supported_fields = array_map('trim', explode(',', variable_get('uuid_features_file_supported_fields', 'file, image')));\n  if (!in_array($export_bundle, $bundles)) {\n    foreach ($fields as $field_instance) {\n      $field = &$export->{$field_instance['field_name']};\n      $info = field_info_field($field_instance['field_name']);\n      // If this field should implement file import/export system but\n      // filefield exports are not enabled for this entity, just set the field\n      // to an empty array.\n      if (in_array($info['type'], $supported_fields)) {\n        $field = array();\n      }\n    }\n  }\n  else {\n    $orig_assets_path = $assets_path = variable_get('uuid_features_file_assets_path', '');\n    $export_mode = variable_get('uuid_features_file_mode', 'inline');\n\n    switch ($export_mode) {\n      case 'local':\n        $export_var = 'uuid_features_file_path';\n        break;\n      case 'remote':\n        $export_var = 'uuid_features_file_url';\n        break;\n      default:\n      case 'inline':\n        $export_var = 'uuid_features_file_data';\n        break;\n    }\n    // If files are supposed to be copied to the assets path.\n    if ($export_mode == 'local' && $assets_path) {\n      // Ensure the assets path is created\n      if ((!is_dir($assets_path) && mkdir($assets_path, 0777, TRUE) == FALSE)\n        || !is_writable($assets_path)\n      ) {\n        // Try creating a public path if the local path isn't writeable.\n        // This is a kludgy solution to allow writing file assets to places\n        // such as the profiles/myprofile directory, which isn't supposed to\n        // be writeable\n        $new_assets_path = 'public://' . $assets_path;\n        if (!is_dir($new_assets_path) && mkdir($new_assets_path, 0777, TRUE) == FALSE) {\n          drupal_set_message(t(\"Could not create assets path! '!path'\", array('!path' => $assets_path)), 'error');\n          // Don't continue if the assets path is not ready\n          return;\n        }\n        $assets_path = $new_assets_path;\n      }\n    }\n\n    // get all fields from this entity\n    foreach ($fields as $field_instance) {\n      // load field infos to check the type\n      $field = &$export->{$field_instance['field_name']};\n      $info = field_info_field($field_instance['field_name']);\n      // check if this field should implement file import/export system\n      if (in_array($info['type'], $supported_fields)) {\n        // we need to loop into each language because i18n translation can build\n        // fields with different language than the node one.\n        foreach($field as $language => $files) {\n          if (is_array($files)) {\n            foreach($files as $i => $file) {\n\n              // convert file to array to stay into the default uuid_features_file format\n              $file = (object) $file;\n\n              // Check the file\n              if (!isset($file->uri) || !is_file($file->uri)) {\n                drupal_set_message(t(\"File field found on term, but file doesn't exist on disk? '!path'\", array('!path' => $file->uri)), 'error');\n                continue;\n              }\n\n              if ($export_mode == 'local') {\n                if ($assets_path) {\n                  // The writeable path may be different from the path that gets saved\n                  // during the feature export to handle the public path/local path\n                  // dilemma mentioned above.\n                  $writeable_export_data = $assets_path . '/' . basename($file->uri);\n                  $export_data = $orig_assets_path . '/' . basename($file->uri);\n                  if (!copy($file->uri, $writeable_export_data)) {\n                    drupal_set_message(t(\"Export file error, could not copy '%filepath' to '%exportpath'.\", array('%filepath' => $file->uri, '%exportpath' => $writeable_export_data)), 'error');\n                    return FALSE;\n                  }\n                }\n                else {\n                  $export_data = $file->uri;\n                }\n              }\n              // Remote export mode\n              elseif ($export_mode == 'remote') {\n                $export_data = url($file->uri, array('absolute' => TRUE));\n              }\n              // Default is 'inline' export mode\n              else {\n                $export_data = base64_encode(file_get_contents($file->uri));\n              }\n\n              // build the field again, and remove fid to be sure that imported node\n              // will rebuild the file again, or keep an existing one with a different fid\n              $field[$language][$i]['fid'] = NULL;\n              $field[$language][$i]['timestamp'] = NULL;\n              $field[$language][$i][$export_var] = $export_data;\n            }\n          }\n        }\n      }\n    }\n  }\n}\n//entity_type\n/**\n * Handle importing file fields.\n */\nfunction uuid_features_file_field_import(&$import, $entity_type) {\n  switch ($entity_type) {\n    case \"taxonomy_term\":\n      $import_bundle = $import->vocabulary_machine_name;\n      break;\n    case \"node\":\n      $import_bundle = $import->type;\n      break;\n  }\n  // Get all fields from this bundle.\n  $fields = field_info_instances($entity_type, $import_bundle);\n\n  foreach($fields as $field_instance) {\n    // Load field info to check the type.\n    $field = &$import->{$field_instance['field_name']};\n    $info = field_info_field($field_instance['field_name']);\n    $supported_fields = array_map('trim', explode(',', variable_get('uuid_features_file_supported_fields', 'file, image')));\n    // Check if this field should implement file import/export system.\n    if (in_array($info['type'], $supported_fields)) {\n      // We need to loop into each language because i18n translation can build\n      // fields with different language than the term one.\n      foreach($field as $language => $files) {\n        if (is_array($files)) {\n          foreach($files as $i => $file) {\n            // Convert file to array to stay into the default uuid_features_file format.\n            $file = (object)$file;\n            $result = _uuid_features_file_field_import_file($file);\n            // The file was saved successfully, update the file field (by reference).\n            if ($result == TRUE && isset($file->fid)) {\n              $field[$language][$i] = (array)$file;\n            }\n            else {\n              $field[$language][$i] = array();\n            }\n          }\n        }\n      }\n    }\n  }\n}\n\n/**\n * Detects remote and local file exports and imports accordingly.\n *\n * @param &$file\n *   The file, passed by reference.\n * @return TRUE or FALSE\n *   Depending on success or failure.  On success the $file object will\n *   have a valid $file->fid attribute.\n */\nfunction _uuid_features_file_field_import_file(&$file) {\n  // This is here for historical reasons to support older exports.  It can be\n  // removed in the next major version.\n  $file->uri = strtr($file->uri, array('#FILES_DIRECTORY_PATH#' => 'public:/'));\n\n  // The file is already in the right location AND either the\n  // uuid_features_file_path is not set or the uuid_features_file_path and filepath\n  // contain the same file\n  if (is_file($file->uri) &&\n    (\n      (!isset($file->uuid_features_file_path) || !is_file($file->uuid_features_file_path)) ||\n      (\n        is_file($file->uuid_features_file_path) &&\n        filesize($file->uri) == filesize($file->uuid_features_file_path) &&\n        strtoupper(dechex(crc32(file_get_contents($file->uri)))) ==\n          strtoupper(dechex(crc32(file_get_contents($file->uuid_features_file_path))))\n      )\n    )\n  ) {\n    // Keep existing file if it exists already at this uri (see also #1023254)\n    // Issue #1058750.\n    $query = db_select('file_managed', 'f')\n        ->fields('f', array('fid'))\n        ->condition('uri', $file->uri)\n        ->execute()\n        ->fetchCol();\n\n    if (!empty($query)) {\n      watchdog('uuid_features', 'kept existing managed file at uri \"%uri\"', array('%uri' => $file->uri), WATCHDOG_NOTICE);\n      $file = file_load(array_shift($query));\n    }\n\n    $file = file_save($file);\n  }\n  elseif (isset($file->uuid_features_file_data)) {\n    $directory = drupal_dirname($file->uri);\n    if (file_prepare_directory($directory, FILE_CREATE_DIRECTORY)) {\n      if (file_put_contents($file->uri, base64_decode($file->uuid_features_file_data))) {\n        $file = file_save($file);\n      }\n    }\n  }\n  // The file is in a local location, move it to the\n  // destination then finish the save\n  elseif (isset($file->uuid_features_file_path) && is_file($file->uuid_features_file_path)) {\n    $directory = drupal_dirname($file->uri);\n    if (file_prepare_directory($directory, FILE_CREATE_DIRECTORY)) {\n      // The $file->uuid_features_file_path is passed to reference, and modified\n      // by file_unmanaged_copy().  Making a copy to avoid tainting the original.\n      $uuid_features_file_path = $file->uuid_features_file_path;\n      file_unmanaged_copy($uuid_features_file_path, $directory, FILE_EXISTS_REPLACE);\n\n      // At this point the $file->uuid_features_file_path will contain the\n      // destination of the copied file\n      //$file->uri = $uuid_features_file_path;\n      $file = file_save($file);\n    }\n  }\n  // The file is in a remote location, attempt to download it\n  elseif (isset($file->uuid_features_file_url)) {\n    // Need time to do the download\n    ini_set('max_execution_time', 900);\n\n    $temp_path = file_directory_temp() . '/' . md5(mt_rand()) . '.txt';\n    if (($source = fopen($file->uuid_features_file_url, 'r')) == FALSE) {\n      drupal_set_message(t(\"Could not open '@file' for reading.\", array('@file' => $file->uuid_features_file_url)));\n      return FALSE;\n    }\n    elseif (($dest = fopen($temp_path, 'w')) == FALSE) {\n      drupal_set_message(t(\"Could not open '@file' for writing.\", array('@file' => $file->uri)));\n      return FALSE;\n    }\n    else {\n      // PHP5 specific, downloads the file and does buffering\n      // automatically.\n      $bytes_read = @stream_copy_to_stream($source, $dest);\n\n      // Flush all buffers and wipe the file statistics cache\n      @fflush($source);\n      @fflush($dest);\n      clearstatcache();\n\n      if ($bytes_read != filesize($temp_path)) {\n        drupal_set_message(t(\"Remote export '!url' could not be fully downloaded, '@file' to temporary location '!temp'.\", array('!url' => $file->uuid_features_file_url, '@file' => $file->uri, '!temp' => $temp_path)));\n        return FALSE;\n      }\n      // File was downloaded successfully!\n      else {\n        if (!@copy($temp_path, $file->uri)) {\n          unlink($temp_path);\n          drupal_set_message(t(\"Could not move temporary file '@temp' to '@file'.\", array('@temp' => $temp_path, '@file' => $file->uri)));\n          return FALSE;\n        }\n\n        unlink($temp_path);\n        $file->filesize = filesize($file->uri);\n        $file->filemime = file_get_mimetype($file->uri);\n      }\n    }\n\n    fclose($source);\n    fclose($dest);\n\n    $file = file_save($file);\n  }\n  // Unknown error\n  else {\n    drupal_set_message(t(\"Unknown error occurred attempting to import file: @filepath\", array('@filepath' => $file->uri)), 'error');\n    return FALSE;\n  }\n\n  return TRUE;\n}\n
===================================================================
--- uuid_features_do/uuid_features.module	(revision d34d00fac27dde4247fec411f1a196411bd6e913)
+++ uuid_features_do/uuid_features.module	(revision )
@@ -20,6 +20,14 @@
 function uuid_features_features_api() {
   $components = array();
 
+  $components['uuid_user'] = array(
+    'name' => t('Users'),
+    'feature_source' => TRUE,
+    'default_hook' => 'uuid_features_default_users',
+    'default_file' => FEATURES_DEFAULTS_INCLUDED,
+    'file' => drupal_get_path('module', 'uuid_features') . '/includes/uuid_user.features.inc',
+  );
+
   $components['uuid_node'] = array(
     'name' => t('Content'),
     'feature_source' => TRUE,
Index: uuid_features_do/includes/uuid_user.features.inc
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- uuid_features_do/includes/uuid_user.features.inc	(revision )
+++ uuid_features_do/includes/uuid_user.features.inc	(revision )
@@ -0,0 +1,134 @@
+<?php
+/**
+ * @file
+ * Features hooks for the uuid_user features component.
+ */
+
+/**
+ * Implements hook_features_export_options().
+ */
+function uuid_user_features_export_options() {
+  $options = array();
+
+  $query = 'SELECT u.uid, u.name, u.mail, u.uuid
+    FROM {users} u WHERE uid > 0 ORDER BY u.name ASC';
+  $results = db_query($query);
+  foreach ($results as $user) {
+    $options[$user->uuid] = t('@name: @mail', array(
+      '@name' => $user->name,
+      '@mail' => $user->mail,
+    ));
+  }
+
+  return $options;
+}
+
+/**
+ * Implements hook_features_export().
+ */
+function uuid_user_features_export($data, &$export, $module_name = '') {
+  $pipe = array();
+
+  $export['dependencies']['uuid_features'] = 'uuid_features';
+
+  uuid_features_load_module_includes();
+
+  $uids = entity_get_id_by_uuid('user', $data);
+  foreach ($uids as $uuid => $uid) {
+    // Load the existing user, with a fresh cache.
+    $user = user_load($uid, TRUE);
+
+    $export['features']['uuid_user'][$uuid] = $uuid;
+
+    $data = &$export;
+    drupal_alter('uuid_user_features_export', $data, $user);
+  }
+
+  return $pipe;
+}
+
+/**
+ * Implements hook_features_export_render().
+ */
+function uuid_user_features_export_render($module, $data) {
+  $translatables = $code = array();
+
+  uuid_features_load_module_includes();
+
+  $code[] = '  $users = array();';
+  $code[] = '';
+  $uids = entity_get_id_by_uuid('user', $data);
+  foreach ($uids as $uuid => $uid) {
+    // Only export the user if it exists.
+    if ($uid === FALSE) {
+      continue;
+    }
+    // Attempt to load the user, using a fresh cache.
+    $account = user_load($uid, TRUE);
+    if (empty($account)) {
+      continue;
+    }
+    $export = clone $account;
+
+    // Use date instead of created, in the same format used by node_object_prepare.
+    $export->date = format_date($export->created, 'custom', 'Y-m-d H:i:s O');
+    $export->pass = user_password(10);
+    unset($export->uid);
+
+    // The hook_alter signature is:
+    // hook_uuid_node_features_export_render_alter(&$export, $user, $module);
+    drupal_alter('uuid_user_features_export_render', $export, $account, $module);
+
+    $code[] = '  $users[] = ' . features_var_export($export) . ';';
+  }
+
+  if (!empty($translatables)) {
+    $code[] = features_translatables_export($translatables, '  ');
+  }
+
+  $code[] = '  return $users;';
+  $code = implode("\n", $code);
+  return array('uuid_features_default_users' => $code);
+}
+
+/**
+ * Implements hook_features_revert().
+ */
+function uuid_user_features_revert($module) {
+  uuid_user_features_rebuild($module);
+}
+
+/**
+ * Implements hook_features_rebuild().
+ * Rebuilds users based on UUID from code defaults.
+ */
+function uuid_user_features_rebuild($module) {
+  $users = module_invoke($module, 'uuid_features_default_users');
+  if (!empty($users)) {
+    module_load_include('inc', 'user', 'user.pages');
+
+    foreach ($users as $data) {
+      $account = (object) $data;
+
+      // Find the matching user by name with a fresh cache
+      $existing = user_load_by_name($account->name);
+      if (isset($existing->uid)) {
+          $account->uid = $existing->uid;
+      }
+      else {
+        $account->uid = NULL;
+      }
+      // The hook_alter signature is:
+      // hook_uuid_user_features_rebuild_alter(&user, $module);
+      drupal_alter('uuid_user_features_rebuild', $account, $module);
+      if($account->uid === NULL) {
+        $account = user_save(NULL, (array) $account);
+      }
+      else {
+        $account = user_save($existing, (array) $account);
+      }
+      // Clear out previously loaded user account if one was found
+      unset($existing);
+    }
+  }
+}
