first import
This commit is contained in:
38
sites/all/modules/uuid_features/includes/modules/content.inc
Normal file
38
sites/all/modules/uuid_features/includes/modules/content.inc
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* uuid_node hooks on behalf of the content module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_uuid_node_features_export_render_alter().
|
||||
*
|
||||
* For most CCK fields, it is enough to simply add the values from each db
|
||||
* column into a field array.
|
||||
*/
|
||||
function content_uuid_node_features_export_render_alter(&$export, $node, $module) {
|
||||
if (!empty($types[$node->type])) {
|
||||
// Find CCK text fields.
|
||||
foreach ($types[$node->type]['fields'] as $field) {
|
||||
// Let field modules do their own thing if they want.
|
||||
if (!module_hook($field['module'], 'uuid_node_features_export_render_alter')) {
|
||||
$field_name = $field['field_name'];
|
||||
$export->$field_name = array();
|
||||
// If the content type has changed since the last export, this field
|
||||
// may not exist.
|
||||
if (isset($node->$field_name)) {
|
||||
// Loop through all values of the field.
|
||||
foreach ($node->$field_name as $delta => $data) {
|
||||
$export->{$field_name}[$delta] = array();
|
||||
|
||||
// Save the value of each column.
|
||||
foreach ($field['columns'] as $column => $column_data) {
|
||||
$export->{$field_name}[$delta][$column] = $data[$column];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* uuid_node hooks on behalf of the filefield module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_uuid_node_features_export_alter().
|
||||
*/
|
||||
function filefield_uuid_node_features_export_alter(&$export, &$pipe, $node) {
|
||||
$types = content_types();
|
||||
if (!empty($types[$node->type])) {
|
||||
// Find CCK filefields.
|
||||
foreach ($types[$node->type]['fields'] as $field) {
|
||||
if ($field['module'] == 'filefield') {
|
||||
$field_name = $field['field_name'];
|
||||
|
||||
// If the content type has changed since the last export, this field
|
||||
// may not exist.
|
||||
if (isset($node->$field_name)) {
|
||||
// Loop through all values of the field.
|
||||
foreach ($node->$field_name as $delta => $data) {
|
||||
if (!empty($data['fid'])) {
|
||||
$uuid = uuid_get_uuid('files', 'fid', $data['fid']);
|
||||
// If the referenced file doesn't have a uuid, take this opportunity to
|
||||
// create one.
|
||||
if (empty($uuid)) {
|
||||
$uuid = uuid_set_uuid('files', 'fid', $data['fid']);
|
||||
}
|
||||
$pipe['uuid_file'][$uuid] = $uuid;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_uuid_node_features_export_render_alter().
|
||||
*/
|
||||
function filefield_uuid_node_features_export_render_alter(&$export, $node, $module) {
|
||||
$types = content_types();
|
||||
if (!empty($types[$node->type])) {
|
||||
// Find CCK filefields.
|
||||
foreach ($types[$node->type]['fields'] as $field) {
|
||||
if ($field['module'] == 'filefield') {
|
||||
$field_name = $field['field_name'];
|
||||
$export->$field_name = array();
|
||||
|
||||
// Loop through all values of the field.
|
||||
foreach ($node->$field_name as $delta => $data) {
|
||||
if (!empty($data['fid'])) {
|
||||
$export->{$field_name}[$delta] = array(
|
||||
'uuid' => uuid_get_uuid('files', 'fid', $data['fid']),
|
||||
'list' => $data['list'],
|
||||
'data' => $data['data'],
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_uuid_node_features_rebuild_alter().
|
||||
* Replace filefield uuid's with a field array suitable for node_save().
|
||||
*/
|
||||
function filefield_uuid_node_features_rebuild_alter(&$node, $module) {
|
||||
$types = content_types();
|
||||
if (!empty($types[$node->type])) {
|
||||
// Find CCK nodereference fields.
|
||||
foreach ($types[$node->type]['fields'] as $field) {
|
||||
if ($field['module'] == 'filefield') {
|
||||
$field_name = $field['field_name'];
|
||||
|
||||
// Loop through all values of the field.
|
||||
foreach ($node->$field_name as $delta => $data) {
|
||||
$fid = uuid_get_serial_id('files', 'fid', $data['uuid']);
|
||||
$file = field_file_load($fid);
|
||||
|
||||
$node->{$field_name}[$delta] = $file + $data;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* uuid_node hooks on behalf of the nodereference module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_uuid_node_features_export_render().
|
||||
*/
|
||||
function nodereference_uuid_node_features_export_alter(&$export, &$pipe, $node) {
|
||||
$types = content_types();
|
||||
if (!empty($types[$node->type])) {
|
||||
// Find CCK nodereference fields.
|
||||
foreach ($types[$node->type]['fields'] as $field) {
|
||||
if ($field['module'] == 'nodereference') {
|
||||
$field_name = $field['field_name'];
|
||||
|
||||
// If the content type has changed since the last export, this field
|
||||
// may not exist.
|
||||
if (isset($node->$field_name)) {
|
||||
// Loop through all values of the field.
|
||||
foreach ($node->$field_name as $delta => $data) {
|
||||
if (!empty($data['nid'])) {
|
||||
$uuid = uuid_get_uuid('node', 'nid', $data['nid']);
|
||||
// If the referenced node doesn't have a uuid, take this opportunity to
|
||||
// create one.
|
||||
if (empty($uuid)) {
|
||||
$uuid = uuid_set_uuid('node', 'nid', $data['nid']);
|
||||
}
|
||||
$pipe['uuid_node'][$uuid] = $uuid;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_uuid_node_features_export_render_alter().
|
||||
*/
|
||||
function nodereference_uuid_node_features_export_render_alter(&$export, $node, $module) {
|
||||
$types = content_types();
|
||||
if (!empty($types[$node->type])) {
|
||||
// Find CCK nodereference fields.
|
||||
foreach ($types[$node->type]['fields'] as $field) {
|
||||
if ($field['module'] == 'nodereference') {
|
||||
$field_name = $field['field_name'];
|
||||
$export->$field_name = array();
|
||||
|
||||
// Loop through all values of the field.
|
||||
foreach ($node->$field_name as $delta => $data) {
|
||||
if (!empty($data['nid'])) {
|
||||
$uuid = uuid_get_uuid('node', 'nid', $data['nid']);
|
||||
$export->{$field_name}[$delta] = $uuid;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_uuid_node_features_rebuild_alter().
|
||||
* Replace noderef uuid's with a field array suitable for node_save().
|
||||
*/
|
||||
function nodereference_uuid_node_features_rebuild_alter(&$node, $module) {
|
||||
$types = content_types();
|
||||
if (!empty($types[$node->type])) {
|
||||
// Find CCK nodereference fields.
|
||||
foreach ($types[$node->type]['fields'] as $field) {
|
||||
if ($field['module'] == 'nodereference') {
|
||||
$field_name = $field['field_name'];
|
||||
|
||||
// Loop through all values of the field.
|
||||
foreach ($node->$field_name as $delta => $uuid) {
|
||||
$nid = uuid_get_serial_id('node', 'nid', $uuid);
|
||||
$node->{$field_name}[$delta] = array('nid' => $nid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* uuid_node hooks on behalf of the taxonomy module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_uuid_node_features_export_render().
|
||||
*/
|
||||
function taxonomy_uuid_node_features_export_alter(&$export, &$pipe, $node) {
|
||||
if (!empty($node->taxonomy)) {
|
||||
foreach ($node->taxonomy as $term) {
|
||||
$vocabulary = taxonomy_vocabulary_load($term->vid);
|
||||
$voc_uuid = $vocabulary->machine_name;
|
||||
$pipe['uuid_vocabulary'][$voc_uuid] = $voc_uuid;
|
||||
|
||||
$term_uuid = $term->uuid;
|
||||
$pipe['uuid_term'][$term_uuid] = $term_uuid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_uuid_node_features_export_render_alter().
|
||||
*/
|
||||
function taxonomy_uuid_node_features_export_render_alter(&$export, &$node, $module) {
|
||||
if (!empty($node->taxonomy)) {
|
||||
$export->uuid_term = array();
|
||||
foreach ($node->taxonomy as $term) {
|
||||
$export->uuid_term[] = $term->uuid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_uuid_node_features_rebuild_alter().
|
||||
* Build a taxonomy array suitable for node_save() from the uuid_term array.
|
||||
*/
|
||||
function taxonomy_uuid_node_features_rebuild_alter(&$node, $module) {
|
||||
if (!empty($node->uuid_term)) {
|
||||
$node->taxonomy = array();
|
||||
foreach ($node->uuid_term as $uuid) {
|
||||
$tid = uuid_taxonomy_term_find($uuid);
|
||||
if (empty($tid)) {
|
||||
// If no tid was found, then the term doesn't exist, and most likely
|
||||
// the uuid_term rebuild needs to run first.
|
||||
// TODO: figure out how to weight feature components.
|
||||
uuid_term_features_rebuild($module);
|
||||
|
||||
// Now try again.
|
||||
$tid = uuid_taxonomy_term_find($uuid);
|
||||
if (empty($tid)) {
|
||||
watchdog('uuid_features', 'The term specified by %uuid could not be found.', array('%uuid' => $uuid));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$node->taxonomy[] = $tid;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* uuid_node hooks on behalf of the userreference module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_uuid_node_features_export_render().
|
||||
*/
|
||||
function userreference_uuid_node_features_export_render(&$export, &$pipe, $node) {
|
||||
// TODO: add user UUID's to pipe.
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_uuid_node_features_export_render_alter().
|
||||
*/
|
||||
function userreference_uuid_node_features_export_render_alter(&$export, $node, $module) {
|
||||
$types = content_types();
|
||||
if (!empty($types[$node->type])) {
|
||||
// Find CCK userreference fields.
|
||||
foreach ($types[$node->type]['fields'] as $field) {
|
||||
if ($field['module'] == 'userreference') {
|
||||
$field_name = $field['field_name'];
|
||||
$export->$field_name = array();
|
||||
|
||||
// TODO: Use user UUID's instead.
|
||||
|
||||
// If the content type has changed since the last export, this field
|
||||
// may not exist.
|
||||
if (isset($node->$field_name)) {
|
||||
// Loop through all values of the field.
|
||||
foreach ($node->$field_name as $delta => $data) {
|
||||
$export->{$field_name}[$delta] = array();
|
||||
|
||||
// Save the value of each column.
|
||||
foreach ($field['columns'] as $column => $column_data) {
|
||||
$export->{$field_name}[$delta][$column] = $data[$column];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
107
sites/all/modules/uuid_features/includes/uuid_features.drush.inc
Normal file
107
sites/all/modules/uuid_features/includes/uuid_features.drush.inc
Normal file
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* uuid_features module drush integration.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_drush_command().
|
||||
*
|
||||
* @See drush_parse_command() for a list of recognized keys.
|
||||
*
|
||||
* @return
|
||||
* An associative array describing your command(s).
|
||||
*/
|
||||
function uuid_features_drush_command() {
|
||||
$items = array();
|
||||
|
||||
$items['uuid-features-update-files'] = array(
|
||||
'callback' => 'uuid_features_command_update_files',
|
||||
'description' => "Update files for features modules that use the uuid_file component.",
|
||||
'arguments' => array(
|
||||
'feature' => 'Feature name to export.',
|
||||
),
|
||||
'drupal dependencies' => array('features', 'uuid', 'uuid_features', 'filefield'),
|
||||
'aliases' => array('ufuf'),
|
||||
);
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_drush_help().
|
||||
*/
|
||||
function uuid_features_drush_help($section) {
|
||||
switch ($section) {
|
||||
case 'drush:features':
|
||||
return dt("List all the available features for your site.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update files for features modules that use the uuid_file component.
|
||||
*/
|
||||
function uuid_features_command_update_files($feature = NULL) {
|
||||
if ($args = func_get_args()) {
|
||||
foreach ($args as $module) {
|
||||
if (($feature = feature_load($module, TRUE)) && module_exists($module)) {
|
||||
if (!empty($feature->info['features']['uuid_file'])) {
|
||||
$files = $feature->info['features']['uuid_file'];
|
||||
|
||||
$dest = drupal_get_path('module', $module) . '/uuid_file';
|
||||
file_prepare_directory($dest, FILE_CREATE_DIRECTORY);
|
||||
|
||||
foreach ($files as $uuid) {
|
||||
_uuid_features_drush_update_file($module, $uuid);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ($feature) {
|
||||
_features_drush_set_error($module, 'FEATURES_FEATURE_NOT_ENABLED');
|
||||
}
|
||||
else {
|
||||
_features_drush_set_error($module);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// By default just show contexts that are available.
|
||||
$rows = array(array(dt('Available features')));
|
||||
foreach (features_get_features(NULL, TRUE) as $name => $info) {
|
||||
$rows[] = array($name);
|
||||
}
|
||||
drush_print_table($rows, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy the file identified by $uuid into the feature specified by $module.
|
||||
*
|
||||
* @param string $module
|
||||
* @param string $uuid
|
||||
*/
|
||||
function _uuid_features_drush_update_file($module, $uuid) {
|
||||
$fid = uuid_get_serial_id('files', 'fid', $uuid);
|
||||
if (empty($fid) || !($file = field_file_load($fid))) {
|
||||
drush_set_error('UUID_FILE_NOT_FOUND', dt('The file specified by %uuid was not found.', array('%uuid' => $uuid)));
|
||||
}
|
||||
|
||||
$root = drush_get_option(array('r', 'root'), drush_locate_root());
|
||||
if ($root) {
|
||||
$directory = drupal_get_path('module', $module) . '/uuid_file';
|
||||
if (!is_dir($directory)) {
|
||||
drush_op('mkdir', $directory);
|
||||
}
|
||||
$source = $file['filepath'];
|
||||
$file_parts = explode('.', $file['filepath']);
|
||||
$extension = array_pop($file_parts);
|
||||
|
||||
$destination = $directory . '/' . $uuid . '.' . $extension;
|
||||
drush_op('copy', $source, $destination);
|
||||
drush_log(dt("Updated file: !uuid - !filename", array('!uuid' => $uuid, '!filename' => basename($destination))), 'ok');
|
||||
}
|
||||
else {
|
||||
drush_die(dt('Couldn\'t locate site root'));
|
||||
}
|
||||
}
|
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Features hooks for the uuid_file features component.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_features_export().
|
||||
*/
|
||||
function uuid_file_features_export($data, &$export, $module_name = '') {
|
||||
$pipe = array();
|
||||
|
||||
$export['dependencies']['uuid_features'] = 'uuid_features';
|
||||
|
||||
foreach ($data as $uuid) {
|
||||
$export['features']['uuid_file'][$uuid] = $uuid;
|
||||
}
|
||||
|
||||
return $pipe;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_features_export_render().
|
||||
*/
|
||||
function uuid_file_features_export_render($module, $data) {
|
||||
$translatables = $code = array();
|
||||
|
||||
$code[] = ' $files = array();';
|
||||
$code[] = '';
|
||||
foreach ($data as $uuid) {
|
||||
$fid = uuid_get_serial_id('files', 'fid', $uuid);
|
||||
if (!$fid) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$file = field_file_load($fid);
|
||||
$file_parts = explode('.', $file['filepath']);
|
||||
$extension = array_pop($file_parts);
|
||||
|
||||
$export = array(
|
||||
'uuid' => $uuid,
|
||||
'hash' => md5_file($file['filepath']),
|
||||
'extension' => $extension,
|
||||
);
|
||||
|
||||
$code[] = ' $files[] = ' . features_var_export($export, ' ') . ';';
|
||||
}
|
||||
if (!empty($translatables)) {
|
||||
$code[] = features_translatables_export($translatables, ' ');
|
||||
}
|
||||
$code[] = ' return $files;';
|
||||
$code = implode("\n", $code);
|
||||
return array('uuid_features_default_files' => $code);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_features_revert().
|
||||
*/
|
||||
function uuid_file_features_revert($module) {
|
||||
uuid_file_features_rebuild($module);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_features_rebuild().
|
||||
* Rebuilds files based on UUID from code defaults.
|
||||
*/
|
||||
function uuid_file_features_rebuild($module) {
|
||||
$files = module_invoke($module, 'uuid_features_default_files');
|
||||
if (!empty($files)) {
|
||||
$source_dir = drupal_get_path('module', $module) . '/uuid_file';
|
||||
foreach ($files as $data) {
|
||||
$source = $source_dir . '/' . $data['uuid'] . '.' . $data['extension'];
|
||||
$data = file_get_contents($source);
|
||||
|
||||
// Copy the file and save to db.
|
||||
$file = file_save_data($data, NULL, FILE_EXISTS_REPLACE);
|
||||
}
|
||||
}
|
||||
}
|
150
sites/all/modules/uuid_features/includes/uuid_node.features.inc
Normal file
150
sites/all/modules/uuid_features/includes/uuid_node.features.inc
Normal file
@@ -0,0 +1,150 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Features hooks for the uuid_node features component.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_features_export_options().
|
||||
*/
|
||||
function uuid_node_features_export_options() {
|
||||
$options = array();
|
||||
|
||||
$types = node_type_get_names();
|
||||
|
||||
$query = 'SELECT n.nid, n.title, n.type, n.uuid
|
||||
FROM {node} n ORDER BY n.type, n.title ASC';
|
||||
$results = db_query($query);
|
||||
foreach ($results as $node) {
|
||||
$options[$node->uuid] = t('@type: @title', array(
|
||||
'@type' => $types[$node->type],
|
||||
'@title' => $node->title,
|
||||
));
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_features_export().
|
||||
*/
|
||||
function uuid_node_features_export($data, &$export, $module_name = '') {
|
||||
$pipe = array();
|
||||
|
||||
$export['dependencies']['uuid_features'] = 'uuid_features';
|
||||
|
||||
uuid_features_load_module_includes();
|
||||
|
||||
$nids = entity_get_id_by_uuid('node', $data);
|
||||
foreach ($nids as $uuid => $nid) {
|
||||
// Load the existing node, with a fresh cache.
|
||||
$node = node_load($nid, NULL, TRUE);
|
||||
|
||||
$export['features']['uuid_node'][$uuid] = $uuid;
|
||||
$pipe['node'][$node->type] = $node->type;
|
||||
|
||||
// drupal_alter() normally supports just one byref parameter. Using
|
||||
// the __drupal_alter_by_ref key, we can store any additional parameters
|
||||
// that need to be altered, and they'll be split out into additional params
|
||||
// for the hook_*_alter() implementations. The hook_alter signature is
|
||||
// hook_uuid_node_features_export_alter(&$export, &$pipe, $node)
|
||||
$data = &$export;
|
||||
$data['__drupal_alter_by_ref'] = array(&$pipe);
|
||||
drupal_alter('uuid_node_features_export', $data, $node);
|
||||
}
|
||||
|
||||
return $pipe;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_features_export_render().
|
||||
*/
|
||||
function uuid_node_features_export_render($module, $data) {
|
||||
$translatables = $code = array();
|
||||
|
||||
uuid_features_load_module_includes();
|
||||
|
||||
$code[] = ' $nodes = array();';
|
||||
$code[] = '';
|
||||
$nids = entity_get_id_by_uuid('node', $data);
|
||||
foreach ($nids as $uuid => $nid) {
|
||||
// Only export the node if it exists.
|
||||
if ($nid === FALSE) {
|
||||
continue;
|
||||
}
|
||||
// Attempt to load the node, using a fresh cache.
|
||||
$node = node_load($nid, NULL, TRUE);
|
||||
if (empty($node)) {
|
||||
continue;
|
||||
}
|
||||
if (!empty($node->path)) {
|
||||
$node->pathauto_perform_alias = FALSE;
|
||||
}
|
||||
$export = $node;
|
||||
|
||||
// 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');
|
||||
|
||||
// Don't cause conflicts with nid/vid/revision_timestamp/changed fields.
|
||||
unset($export->nid);
|
||||
unset($export->vid);
|
||||
unset($export->revision_timestamp);
|
||||
unset($export->changed);
|
||||
unset($export->last_comment_timestamp);
|
||||
|
||||
// The hook_alter signature is:
|
||||
// hook_uuid_node_features_export_render_alter(&$export, $node, $module);
|
||||
drupal_alter('uuid_node_features_export_render', $export, $node, $module);
|
||||
|
||||
$code[] = ' $nodes[] = ' . features_var_export($export) . ';';
|
||||
}
|
||||
|
||||
if (!empty($translatables)) {
|
||||
$code[] = features_translatables_export($translatables, ' ');
|
||||
}
|
||||
|
||||
$code[] = ' return $nodes;';
|
||||
$code = implode("\n", $code);
|
||||
return array('uuid_features_default_content' => $code);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_features_revert().
|
||||
*/
|
||||
function uuid_node_features_revert($module) {
|
||||
uuid_node_features_rebuild($module);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_features_rebuild().
|
||||
* Rebuilds nodes based on UUID from code defaults.
|
||||
*/
|
||||
function uuid_node_features_rebuild($module) {
|
||||
$nodes = module_invoke($module, 'uuid_features_default_content');
|
||||
if (!empty($nodes)) {
|
||||
module_load_include('inc', 'node', 'node.pages');
|
||||
|
||||
foreach ($nodes as $data) {
|
||||
$node = (object) $data;
|
||||
node_object_prepare($node);
|
||||
|
||||
// Find the matching UUID, with a fresh cache.
|
||||
$nids = entity_get_id_by_uuid('node', array($node->uuid));
|
||||
if (isset($nids[$node->uuid])) {
|
||||
$nid = array_key_exists($node->uuid, $nids) ? $nids[$node->uuid] : FALSE;
|
||||
$existing = node_load($nid, NULL, TRUE);
|
||||
if (!empty($existing)) {
|
||||
$node->nid = $existing->nid;
|
||||
$node->vid = $existing->vid;
|
||||
}
|
||||
}
|
||||
|
||||
// The hook_alter signature is:
|
||||
// hook_uuid_node_features_rebuild_alter(&node, $module);
|
||||
drupal_alter('uuid_node_features_rebuild', $node, $module);
|
||||
|
||||
$node = node_submit($node);
|
||||
node_save($node);
|
||||
}
|
||||
}
|
||||
}
|
316
sites/all/modules/uuid_features/includes/uuid_term.features.inc
Normal file
316
sites/all/modules/uuid_features/includes/uuid_term.features.inc
Normal file
@@ -0,0 +1,316 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Features hooks for the uuid_term features component.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_features_export_options().
|
||||
*/
|
||||
function uuid_term_features_export_options() {
|
||||
$options = array();
|
||||
|
||||
$query = 'SELECT t.tid, t.name, v.name AS vname, t.uuid
|
||||
FROM {taxonomy_term_data} t
|
||||
INNER JOIN {taxonomy_vocabulary} v ON t.vid = v.vid
|
||||
ORDER BY v.name ASC, t.name ASC';
|
||||
$results = db_query($query);
|
||||
foreach ($results as $term) {
|
||||
$options[$term->uuid] = $term->vname . ' - ' . $term->name;
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_features_export().
|
||||
*/
|
||||
function uuid_term_features_export($data, &$export, $module_name = '') {
|
||||
$export['dependencies']['taxonomy'] = 'taxonomy';
|
||||
$export['dependencies']['uuid'] = 'uuid';
|
||||
$export['dependencies']['uuid_features'] = 'uuid_features';
|
||||
|
||||
foreach ($data as $uuid) {
|
||||
uuid_term_features_get_dependencies($export, $uuid);
|
||||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds terms and its dependencies to the export.
|
||||
*
|
||||
* Parents and term references are handled recrusively, other references are not
|
||||
* yet supported.
|
||||
*/
|
||||
function uuid_term_features_get_dependencies(&$export, $uuid) {
|
||||
$terms = entity_uuid_load('taxonomy_term', array($uuid));
|
||||
if (count($terms)) {
|
||||
$term = reset($terms);
|
||||
$export['features']['uuid_term'][$uuid] = $uuid;
|
||||
$export['features']['taxonomy'][$term->vocabulary_machine_name] = $term->vocabulary_machine_name;
|
||||
// Recursively add all parents and the references of the parents.
|
||||
foreach (taxonomy_get_parents($term->tid) as $parent) {
|
||||
if (!in_array($parent->uuid, $export['features']['uuid_term'])) {
|
||||
uuid_term_features_get_dependencies($export, $parent->uuid);
|
||||
}
|
||||
}
|
||||
// Get term references.
|
||||
$instances = field_info_instances('taxonomy_term', $term->vocabulary_machine_name);
|
||||
foreach ($instances as $field_name => $instance) {
|
||||
$field = field_info_field($field_name);
|
||||
if ($field['type'] == 'taxonomy_term_reference') {
|
||||
if (isset($term->$field_name)) {
|
||||
foreach ($term->$field_name as $lang => $values) {
|
||||
foreach ($values as $value) {
|
||||
// $value['tid'] already contains the UUID.
|
||||
if (!in_array($value['tid'], $export['features']['uuid_term'])) {
|
||||
uuid_term_features_get_dependencies($export, $value['tid']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_features_export_render().
|
||||
*/
|
||||
function uuid_term_features_export_render($module = 'foo', $data) {
|
||||
$translatables = $code = array();
|
||||
|
||||
$code[] = ' $terms = array();';
|
||||
$code[] = '';
|
||||
foreach ($data as $uuid) {
|
||||
// @todo reset = TRUE as otherwise references (parent, fields) were destroyed.
|
||||
$terms = entity_uuid_load('taxonomy_term', array($uuid), array(), TRUE);
|
||||
if (!count($terms)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Export the parent uuids.
|
||||
foreach ($terms as $term) {
|
||||
if($parents = taxonomy_get_parents($term->tid)) {
|
||||
foreach ($parents as $parent) {
|
||||
$term->parent[] = $parent->uuid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$export = reset($terms);
|
||||
|
||||
// Do not export ids.
|
||||
unset($export->vid);
|
||||
unset($export->tid);
|
||||
// No need to export the rdf mapping.
|
||||
unset($export->rdf_mapping);
|
||||
uuid_term_features_file_field_export($export);
|
||||
$code[] = ' $terms[] = ' . features_var_export($export, ' ') . ';';
|
||||
}
|
||||
|
||||
if (!empty($translatables)) {
|
||||
$code[] = features_translatables_export($translatables, ' ');
|
||||
}
|
||||
// Configuration settings need to be exported along with terms to
|
||||
// avoid diffs between the default and normal code returned by
|
||||
// this function.
|
||||
$code[] = ' variable_set(\'uuid_features_file_types\', ' . features_var_export(variable_get('uuid_features_file_types', array())) . ');';
|
||||
$code[] = ' variable_set(\'uuid_features_file_mode\', ' . features_var_export(variable_get('uuid_features_file_mode', 'inline')) . ');';
|
||||
$code[] = ' variable_set(\'uuid_features_file_assets_path\', ' . features_var_export(variable_get('uuid_features_file_assets_path', '')) . ');';
|
||||
$code[] = ' variable_set(\'uuid_features_file_supported_fields\', ' . features_var_export(variable_get('uuid_features_file_supported_fields', 'file, image')) . ');';
|
||||
$code[] = ' return $terms;';
|
||||
$code = implode("\n", $code);
|
||||
return array('uuid_features_default_terms' => $code);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_features_revert().
|
||||
*/
|
||||
function uuid_term_features_revert($module) {
|
||||
uuid_term_features_rebuild($module);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_features_rebuild().
|
||||
* Rebuilds terms based on UUID from code defaults.
|
||||
*/
|
||||
function uuid_term_features_rebuild($module) {
|
||||
// Import the vocabularies first.
|
||||
taxonomy_features_rebuild($module);
|
||||
field_features_rebuild($module);
|
||||
|
||||
$terms = module_invoke($module, 'uuid_features_default_terms');
|
||||
if (!empty($terms)) {
|
||||
// Verify that term objects is saved before any references are resolved.
|
||||
foreach ($terms as $data) {
|
||||
$existing = entity_get_id_by_uuid('taxonomy_term', array($data['uuid']));
|
||||
if (!count($existing)) {
|
||||
$voc = taxonomy_vocabulary_machine_name_load($data['vocabulary_machine_name']);
|
||||
// Only save the term, if the corresponding vocabulary already exisits.
|
||||
if ($voc) {
|
||||
$term = new stdClass;
|
||||
$term->uuid = $data['uuid'];
|
||||
$term->vid = $voc->vid;
|
||||
$term->name = $data['name'];
|
||||
taxonomy_term_save($term);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Save all other data and resolve references.
|
||||
foreach ($terms as $data) {
|
||||
$term = (object) $data;
|
||||
$voc = taxonomy_vocabulary_machine_name_load($term->vocabulary_machine_name);
|
||||
if ($voc) {
|
||||
$term->vid = $voc->vid;
|
||||
uuid_term_features_file_field_import($term, $voc);
|
||||
entity_uuid_save('taxonomy_term', $term);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle exporting file fields.
|
||||
*/
|
||||
function uuid_term_features_file_field_export(&$term) {
|
||||
$vocabularies = array_filter(variable_get('uuid_features_file_types', array()));
|
||||
if (in_array($term->vocabulary_machine_name, $vocabularies)) {
|
||||
$orig_assets_path = $assets_path = variable_get('uuid_features_file_assets_path', '');
|
||||
$export_mode = variable_get('uuid_features_file_mode', 'inline');
|
||||
|
||||
switch ($export_mode) {
|
||||
case 'local':
|
||||
$export_var = 'uuid_features_file_path';
|
||||
break;
|
||||
case 'remote':
|
||||
$export_var = 'uuid_features_file_url';
|
||||
break;
|
||||
default:
|
||||
case 'inline':
|
||||
$export_var = 'uuid_features_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)
|
||||
|| !is_writable($assets_path)
|
||||
) {
|
||||
// Try creating a public path if the local path isn't writeable.
|
||||
// This is a kludgy solution to allow writing file assets to places
|
||||
// such as the profiles/myprofile directory, which isn't supposed to
|
||||
// be writeable
|
||||
$new_assets_path = 'public://' . $assets_path;
|
||||
if (!is_dir($new_assets_path) && mkdir($new_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;
|
||||
}
|
||||
$assets_path = $new_assets_path;
|
||||
}
|
||||
}
|
||||
|
||||
// get all fields from this vocabulary
|
||||
$fields = field_info_instances('taxonomy_term', $term->vocabulary_machine_name);
|
||||
foreach ($fields as $field_instance) {
|
||||
// load field infos to check the type
|
||||
$field = &$term->{$field_instance['field_name']};
|
||||
$info = field_info_field($field_instance['field_name']);
|
||||
|
||||
$supported_fields = array_map('trim', explode(',', variable_get('uuid_features_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 uuid_features_file format
|
||||
$file = (object) $file;
|
||||
|
||||
// Check the file
|
||||
if (!isset($file->uri) || !is_file($file->uri)) {
|
||||
drupal_set_message(t("File field found on term, but file doesn't exist on disk? '!path'", array('!path' => $file->uri)), 'error');
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($export_mode == 'local') {
|
||||
if ($assets_path) {
|
||||
// The writeable path may be different from the path that gets saved
|
||||
// during the feature export to handle the public path/local path
|
||||
// dilemma mentioned above.
|
||||
$writeable_export_data = $assets_path . '/' . basename($file->uri);
|
||||
$export_data = $orig_assets_path . '/' . basename($file->uri);
|
||||
if (!copy($file->uri, $writeable_export_data)) {
|
||||
drupal_set_message(t("Export file error, could not copy '%filepath' to '%exportpath'.", array('%filepath' => $file->uri, '%exportpath' => $writeable_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]['timestamp'] = NULL;
|
||||
$field[$language][$i][$export_var] = $export_data;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle importing file fields.
|
||||
*/
|
||||
function uuid_term_features_file_field_import(&$term, $voc) {
|
||||
// Get all fields from this vocabulary.
|
||||
$fields = field_info_instances('taxonomy_term', $term->vocabulary_machine_name);
|
||||
|
||||
foreach($fields as $field_instance) {
|
||||
// Load field info to check the type.
|
||||
$field = &$term->{$field_instance['field_name']};
|
||||
$info = field_info_field($field_instance['field_name']);
|
||||
|
||||
$supported_fields = array_map('trim', explode(',', variable_get('uuid_features_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 term one.
|
||||
foreach($field as $language => $files) {
|
||||
if (is_array($files)) {
|
||||
foreach($files as $i => $file) {
|
||||
|
||||
// Convert file to array to stay into the default uuid_features_file format.
|
||||
$file = (object)$file;
|
||||
|
||||
$result = _uuid_features_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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user