first import
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Documents Node export dependency's hooks for api reference.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Handle dependencies not already handled.
|
||||
*
|
||||
* Let other modules alter this - for example to only allow some users to
|
||||
* export specific nodes or types.
|
||||
*
|
||||
* @param &$handled
|
||||
* Boolean indicating whether the dependency was handled, only set to TRUE,
|
||||
* never explicitly set it to FALSE. Only run code when it is already FALSE.
|
||||
* @param $node
|
||||
* The node to handle the dependency for.
|
||||
* @param $dependency
|
||||
* The dependency data.
|
||||
*/
|
||||
function hook_node_export_dependency_alter(&$handled, &$node, $dependency) {
|
||||
if (!$handled) {
|
||||
// Attempt to handle the dependency here.
|
||||
// If it's handled successfully set $handled to TRUE.
|
||||
}
|
||||
}
|
@@ -0,0 +1,222 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains hook implementations for all relevant core module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_node_export_dependency().
|
||||
*/
|
||||
function node_node_export_dependency($entity, $entity_type) {
|
||||
if ($entity_type == 'node') {
|
||||
$dependencies = array();
|
||||
// The node has a 'user' dependency through the 'uid' and
|
||||
// 'revision_uid' properties.
|
||||
node_export_dependency_add($dependencies, $entity, 'user', array('uid', 'revision_uid'));
|
||||
// The node has a 'node' dependency through the 'tnid' property.
|
||||
node_export_dependency_add($dependencies, $entity, 'node', 'tnid');
|
||||
return $dependencies;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_node_export_dependency()
|
||||
*/
|
||||
function taxonomy_node_export_dependency($entity, $entity_type) {
|
||||
if ($entity_type == 'taxonomy_term') {
|
||||
$dependencies = array();
|
||||
$terms = taxonomy_get_parents($entity->tid);
|
||||
$delta = 0;
|
||||
foreach ($terms as $tid => $term) {
|
||||
$dependencies[] = array(
|
||||
'type' => 'taxonomy_term',
|
||||
'id' => $tid,
|
||||
'property' => 'parent',
|
||||
'delta' => $delta++,
|
||||
);
|
||||
}
|
||||
return $dependencies;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_node_export_dependency().
|
||||
*/
|
||||
function book_node_export_dependency($entity, $entity_type) {
|
||||
if ($entity_type == 'node' && !empty($entity->book)) {
|
||||
$dependencies = array();
|
||||
|
||||
// Book page's root book node.
|
||||
if (!empty($entity->book['bid'])) {
|
||||
$dependencies[] = array(
|
||||
'type' => 'node',
|
||||
'id' => $entity->book['bid'],
|
||||
'property' => array(array('book', 'bid')),
|
||||
);
|
||||
}
|
||||
|
||||
// Book page's immediate parent.
|
||||
if (!empty($entity->book['plid'])) {
|
||||
$parent_nid = db_query(
|
||||
'SELECT nid FROM {book} WHERE mlid = :mlid',
|
||||
array(':mlid' => $entity->book['plid'])
|
||||
)->fetchField();
|
||||
$dependencies[] = array(
|
||||
'type' => 'node',
|
||||
'id' => $parent_nid,
|
||||
'property' => array(array('book', 'plid')),
|
||||
// Recognise the relationship is not done through the entity id key.
|
||||
'relationship' => array(
|
||||
'key' => array('menu', 'mlid'),
|
||||
'value' => $entity->book['plid'],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// Book page's immediate children.
|
||||
$flat = book_get_flat_menu($entity->book);
|
||||
$children = array();
|
||||
if ($entity->book['has_children']) {
|
||||
// Walk through the array until we find the current page.
|
||||
do {
|
||||
$link = array_shift($flat);
|
||||
} while ($link && ($link['mlid'] != $entity->book['mlid']));
|
||||
// Continue through the array and collect the links whose parent is this page.
|
||||
while (($link = array_shift($flat)) && $link['plid'] == $entity->book['mlid']) {
|
||||
$matches = array();
|
||||
if (preg_match('/^node\/([\d]+)$/', $link['href'], $matches)) {
|
||||
$dependencies[] = array(
|
||||
'type' => 'node',
|
||||
'id' => $matches[1],
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $dependencies;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_node_export_dependency().
|
||||
*/
|
||||
function og_node_export_dependency($entity, $entity_type) {
|
||||
if ($entity_type == 'node') {
|
||||
$dependencies = array();
|
||||
|
||||
if (!empty($entity->og_groups)) {
|
||||
foreach (array_keys($entity->og_groups) as $delta) {
|
||||
entity_dependency_add($dependencies, $entity, 'node', array(array('og_groups', $delta)));
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($entity->og_parent->nid)) {
|
||||
entity_dependency_add($dependencies, $entity, 'node', array(array('og_parent', 'nid')));
|
||||
}
|
||||
|
||||
if (!empty($dependencies)) {
|
||||
return $dependencies;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_node_export_dependency().
|
||||
*/
|
||||
function field_node_export_dependency($entity, $entity_type) {
|
||||
$dependencies = array();
|
||||
list(,, $bundle_name) = entity_extract_ids($entity_type, $entity);
|
||||
$instances = field_info_instances($entity_type, $bundle_name);
|
||||
|
||||
foreach ($instances as $field_name => $instance) {
|
||||
$field = field_info_field($field_name);
|
||||
foreach ($entity->{$field_name} as $langcode => $items) {
|
||||
$field_dependencies = module_invoke($field['module'], 'node_export_dependency_field', $entity_type, $entity, $field, $instance, $langcode, $items);
|
||||
|
||||
// Let other modules alter dependencies for this field.
|
||||
drupal_alter('node_export_dependency_field', $field_dependencies, $entity_type, $entity, $field, $instance, $langcode, $items);
|
||||
|
||||
if (!empty($field_dependencies)) {
|
||||
foreach ($field_dependencies as &$field_dependency) {
|
||||
if (empty($field_dependency['module'])) {
|
||||
$field_dependency['module'] = $field['module'];
|
||||
}
|
||||
if (empty($field_dependency['field_name'])) {
|
||||
$field_dependency['field_name'] = $field_name;
|
||||
}
|
||||
if (empty($field_dependency['langcode'])) {
|
||||
$field_dependency['langcode'] = $langcode;
|
||||
}
|
||||
}
|
||||
$dependencies = array_merge_recursive($dependencies, $field_dependencies);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $dependencies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_node_export_dependency_field().
|
||||
*/
|
||||
function taxonomy_node_export_dependency_field($entity_type, $entity, $field, $instance, $langcode, $items) {
|
||||
// No need to check for the field type here, since this hook is only called
|
||||
// for the owner of this field. Taxonomy module only owns one field.
|
||||
$dependencies = array();
|
||||
node_export_dependency_add($dependencies, $items, 'taxonomy_term', 'tid');
|
||||
return $dependencies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_node_export_dependency_field().
|
||||
*/
|
||||
function file_node_export_dependency_field($entity_type, $entity, $field, $instance, $langcode, $items) {
|
||||
$dependencies = array();
|
||||
node_export_dependency_add($dependencies, $items, 'file', 'fid');
|
||||
node_export_dependency_add($dependencies, $items, 'user', 'uid');
|
||||
return $dependencies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_node_export_dependency_field().
|
||||
*/
|
||||
function image_node_export_dependency_field($entity_type, $entity, $field, $instance, $langcode, $items) {
|
||||
return file_node_export_dependency_field($entity_type, $entity, $field, $instance, $langcode, $items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_node_export_dependency_field().
|
||||
*/
|
||||
function node_reference_node_export_dependency_field($entity_type, $entity, $field, $instance, $langcode, $items) {
|
||||
$dependencies = array();
|
||||
node_export_dependency_add($dependencies, $items, 'node', 'nid');
|
||||
return $dependencies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_node_export_dependency_field().
|
||||
*/
|
||||
function user_reference_node_export_dependency_field($entity_type, $entity, $field, $instance, $langcode, $items) {
|
||||
$dependencies = array();
|
||||
node_export_dependency_add($dependencies, $items, 'user', 'uid');
|
||||
return $dependencies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_node_export_dependency_field().
|
||||
*/
|
||||
function entityreference_node_export_dependency_field($entity_type, $entity, $field, $instance, $langcode, $items) {
|
||||
$dependencies = array();
|
||||
node_export_dependency_add($dependencies, $items, $field['settings']['target_type'], 'target_id');
|
||||
return $dependencies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_node_export_dependency_field().
|
||||
*/
|
||||
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');
|
||||
return $dependencies;
|
||||
}
|
||||
|
@@ -0,0 +1,12 @@
|
||||
name = Node export dependency (experimental)
|
||||
description = Helps maintain relationships to dependent entities. Intended to make Node export relation obsolete.
|
||||
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"
|
||||
core = "7.x"
|
||||
project = "node_export"
|
||||
datestamp = "1345435979"
|
||||
|
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* The Node export dependency install file.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_uninstall().
|
||||
*/
|
||||
function node_export_dependency_uninstall() {
|
||||
variable_del('node_export_dependency');
|
||||
variable_del('node_export_dependency_lock');
|
||||
variable_del('node_export_dependency_disable_modules');
|
||||
variable_del('node_export_dependency_attach_nodes');
|
||||
variable_del('node_export_dependency_abort');
|
||||
variable_del('node_export_dependency_existing');
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_requirements().
|
||||
*/
|
||||
function node_export_dependency_requirements($phase) {
|
||||
$requirements = array();
|
||||
if ($phase == 'install') {
|
||||
// Ensure translations don't break at install time
|
||||
$t = get_t();
|
||||
|
||||
if (module_exists('node_export_relation')) {
|
||||
$requirements['node_export_relation'] = array(
|
||||
'title' => 'Node export relation',
|
||||
'description' => $t(
|
||||
'Node export dependency cannot be installed when Node export relation is in use.'
|
||||
),
|
||||
'severity' => REQUIREMENT_ERROR,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $requirements;
|
||||
}
|
@@ -0,0 +1,411 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* The Node export dependency module.
|
||||
*
|
||||
* Helps maintain relationships to dependent entities.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Callback for node reference settings form.
|
||||
*/
|
||||
function node_export_dependency_form_node_export_settings_alter(&$form, &$form_state, $form_id) {
|
||||
// @todo: remove the node_export_dependency.core.inc file if solved: [#1590312]
|
||||
module_load_include('inc', 'node_export_dependency', 'node_export_dependency.core');
|
||||
|
||||
$form['node_export_dependency'] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('Dependencies'),
|
||||
);
|
||||
|
||||
$modules_options = array();
|
||||
$modules = module_implements('node_export_dependency');
|
||||
foreach ($modules as $module) {
|
||||
if ($module != 'field') {
|
||||
$module_info = system_get_info('module', $module);
|
||||
$modules_options[$module] = $module_info['name'];
|
||||
}
|
||||
}
|
||||
$modules = module_implements('node_export_dependency_field');
|
||||
foreach ($modules as $module) {
|
||||
$module_info = system_get_info('module', $module);
|
||||
$modules_options[$module] = t('Field') . ': ' . $module_info['name'];
|
||||
}
|
||||
|
||||
natcasesort($modules_options);
|
||||
|
||||
$form['node_export_dependency']['node_export_dependency_disable_modules'] = array(
|
||||
'#type' => 'checkboxes',
|
||||
'#title' => t('Disable dependencies by module'),
|
||||
'#default_value' => variable_get('node_export_dependency_disable_modules', array()),
|
||||
'#options' => $modules_options,
|
||||
'#description' => t('Choose modules for which to disable dependencies.'),
|
||||
);
|
||||
|
||||
$form['node_export_dependency']['node_export_dependency_attach_nodes'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Attach dependent nodes to export automatically.'),
|
||||
'#default_value' => variable_get('node_export_dependency_attach_nodes', 1),
|
||||
);
|
||||
|
||||
$form['node_export_dependency']['node_export_dependency_abort'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Abort the export when a dependent node cannot be exported.'),
|
||||
'#default_value' => variable_get('node_export_dependency_abort', 0),
|
||||
'#description' => t('Applies when attaching dependent nodes.'),
|
||||
);
|
||||
|
||||
$form['node_export_dependency']['node_export_dependency_existing'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Maintain dependency to original node.'),
|
||||
'#default_value' => variable_get('node_export_dependency_existing', 1),
|
||||
'#description' => t('Applies when <em>Create a new node</em> imports a duplicate dependent node.') . '<strong>' . t('Disabling this is not yet supported.') . '</strong>',
|
||||
'#disabled' => TRUE,
|
||||
);
|
||||
|
||||
$disabled_modules = variable_get('node_export_dependency_disable_modules', array());
|
||||
foreach (element_children($form['publishing']) as $type) {
|
||||
if (empty($disabled_modules['node'])) {
|
||||
$form['publishing'][$type]['node_export_reset_author_' . $type]['#disabled'] = TRUE;
|
||||
$form['publishing'][$type]['node_export_reset_author_' . $type]['#description'] .= ' <strong>' . t('Disabled by <em>Node export dependency</em> because <em>Node module</em> dependencies are enabled.') . '</strong>';
|
||||
$form['publishing'][$type]['node_export_reset_author_' . $type]['#default_value'] = FALSE;
|
||||
variable_set('node_export_reset_author_' . $type, FALSE);
|
||||
}
|
||||
if (empty($disabled_modules['book'])) {
|
||||
$form['publishing'][$type]['node_export_reset_book_mlid_' . $type]['#disabled'] = TRUE;
|
||||
$form['publishing'][$type]['node_export_reset_book_mlid_' . $type]['#description'] .= ' <strong>' . t('Disabled by <em>Node export dependency</em> because <em>Book module</em> dependencies are enabled.') . '</strong>';
|
||||
$form['publishing'][$type]['node_export_reset_book_mlid_' . $type]['#default_value'] = FALSE;
|
||||
variable_set('node_export_reset_book_mlid_' . $type, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_node_export_alter().
|
||||
*/
|
||||
function node_export_dependency_node_export_alter(&$nodes, $format) {
|
||||
// Keyed nodes are important for preventing duplicate nodes.
|
||||
$keyed_nodes = array();
|
||||
foreach ($nodes as $node) {
|
||||
$keyed_nodes[$node->nid] = $node;
|
||||
}
|
||||
foreach (array_keys($keyed_nodes) as $nid) {
|
||||
node_export_dependency_load_dependencies($keyed_nodes, $nid);
|
||||
}
|
||||
$nodes = array_values($keyed_nodes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively load dependencies.
|
||||
*/
|
||||
function node_export_dependency_load_dependencies(&$nodes, $nid) {
|
||||
$node = &$nodes[$nid];
|
||||
$dependencies = node_export_dependency_get_dependencies('node', $node);
|
||||
foreach ($dependencies as $dep_key => &$dependency) {
|
||||
$disabled_modules = variable_get('node_export_dependency_disable_modules', array());
|
||||
if (!empty($disabled_modules[$dependency['module']])) {
|
||||
unset($dependencies[$dep_key]);
|
||||
continue;
|
||||
}
|
||||
$uuid = node_export_dependency_get_uuid($dependency['type'], $dependency['id']);
|
||||
$dependency['uuid'] = $uuid;
|
||||
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_export_prepare_node($new_node);
|
||||
$nodes[$new_node->nid] = $new_node;
|
||||
// Recursively load dependent nodes.
|
||||
node_export_dependency_load_dependencies($nodes, $new_node->nid);
|
||||
}
|
||||
elseif (variable_get('node_export_dependency_abort', 0)) {
|
||||
// Set this node to FALSE to trigger an error in node export.
|
||||
// Do not use $new_node in this code in case there is a problem with it.
|
||||
$nodes[$dependency['id']] = FALSE;
|
||||
// Add a warning to watchdog.
|
||||
watchdog('node_export_dependency', 'No access to export node dependency %nid', array('%nid' => $dependency['id']), WATCHDOG_WARNING);
|
||||
drupal_set_message(t('No access to export node dependency %nid', array('%nid' => $dependency['id'])), 'error', FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty($dependencies)) {
|
||||
$node->node_export_dependency = $dependencies;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_node_export_import_alter().
|
||||
*/
|
||||
function node_export_dependency_node_export_import_alter($nodes, $format) {
|
||||
$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.
|
||||
// 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)
|
||||
) {
|
||||
unset($node->node_export_dependency[$dep_key]);
|
||||
}
|
||||
else {
|
||||
// Couldn't handle, store for later.
|
||||
$node_export_dependency[$node->uuid][] = $dependency;
|
||||
// Set the property to 0 to prevent database errors.
|
||||
node_export_dependency_set_property($node, $dependency, 0);
|
||||
}
|
||||
}
|
||||
unset($node->node_export_dependency);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($node_export_dependency)) {
|
||||
variable_set('node_export_dependency', $node_export_dependency);
|
||||
}
|
||||
else {
|
||||
variable_del('node_export_dependency');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to process outstanding dependencies.
|
||||
*
|
||||
* This should only be called when the parent node to fix is already saved.
|
||||
*
|
||||
* @param $iterations
|
||||
* How many iterations to run.
|
||||
* @param $seconds
|
||||
* How long to lock others from processing (will release upon completion).
|
||||
*/
|
||||
function node_export_dependency_process_outstanding_dependencies($iterations, $seconds = 240) {
|
||||
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());
|
||||
|
||||
// Iterate $node_export_dependency and try to handle any others.
|
||||
$node_export_dependency_keys = array_keys($node_export_dependency);
|
||||
// Shuffle so we don't get 'stuck' on a bunch of unsolvable cases.
|
||||
shuffle($node_export_dependency_keys);
|
||||
for ($count = 0; $count < $iterations; $count++) {
|
||||
$node_uuid = next($node_export_dependency_keys);
|
||||
if ($node_uuid === FALSE && empty($node_export_dependency_keys)) {
|
||||
break;
|
||||
}
|
||||
else {
|
||||
$node_uuid = reset($node_export_dependency_keys);
|
||||
}
|
||||
$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]);
|
||||
if (!empty($node)) {
|
||||
// Try to handle this dependency now, and unset if successfull.
|
||||
if (node_export_dependency_handle_dependency($node, $dependency)) {
|
||||
unset($dependencies[$dep_key]);
|
||||
node_save($node);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (empty($node_export_dependency[$node_uuid])) {
|
||||
unset($node_export_dependency[$node_uuid]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($node_export_dependency)) {
|
||||
variable_set('node_export_dependency', $node_export_dependency);
|
||||
}
|
||||
else {
|
||||
variable_del('node_export_dependency');
|
||||
}
|
||||
variable_del('node_export_dependency_lock');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_cron().
|
||||
*/
|
||||
function node_export_dependency_cron() {
|
||||
node_export_dependency_process_outstanding_dependencies(50);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_init().
|
||||
*/
|
||||
function node_export_dependency_init() {
|
||||
$node_export_dependency = variable_get('node_export_dependency', array());
|
||||
if (!empty($node_export_dependency)) {
|
||||
node_export_dependency_process_outstanding_dependencies(10);
|
||||
if (count($node_export_dependency) > 20) {
|
||||
drupal_set_message(
|
||||
t(
|
||||
'There are %num outstanding Node export dependencies, please complete the imports and run cron as soon as possible.',
|
||||
array('%num' => count($node_export_dependency))
|
||||
),
|
||||
'warning'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to handle a dependency.
|
||||
*
|
||||
* @return
|
||||
* TRUE or FALSE whether the dependency was handled.
|
||||
*/
|
||||
function node_export_dependency_handle_dependency(&$node, $dependency) {
|
||||
$handled = FALSE;
|
||||
$disabled_modules = variable_get('node_export_dependency_disable_modules', array());
|
||||
if (!empty($disabled_modules[$dependency['module']])) {
|
||||
// We're not handling it, so it is 'handled'.
|
||||
return TRUE;
|
||||
}
|
||||
if (!isset($dependency['relationship'])) {
|
||||
// Entity id.
|
||||
$entity_ids = entity_get_id_by_uuid($dependency['type'], array($dependency['uuid']));
|
||||
$entity_id = $entity_ids ? reset($entity_ids) : FALSE;
|
||||
if ($entity_id) {
|
||||
node_export_dependency_set_property($node, $dependency, $entity_id);
|
||||
}
|
||||
$handled = TRUE;
|
||||
}
|
||||
|
||||
drupal_alter('node_export_dependency', $handled, $node, $dependency);
|
||||
|
||||
return $handled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_node_export_dependency_alter().
|
||||
*/
|
||||
function node_export_dependency_node_export_dependency_alter(&$handled, &$node, $dependency) {
|
||||
|
||||
// @todo special fixing up for Book and OG nodes and other special cases?
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a property according to $dependency for the property location and $new_value
|
||||
* for the new value.
|
||||
*/
|
||||
function node_export_dependency_set_property(&$entity, $dependency, $new_value) {
|
||||
if (isset($dependency['field_name'])) {
|
||||
// This is a field.
|
||||
$entity->{$dependency['field_name']}[$dependency['langcode']]
|
||||
[$dependency['delta']][$dependency['property']] = $new_value;
|
||||
}
|
||||
else {
|
||||
// Some other property.
|
||||
if (isset($dependency['property'])) {
|
||||
$property_path = $dependency['property'];
|
||||
if (!is_array($property_path)) {
|
||||
$property_path = array($property_path);
|
||||
}
|
||||
$value = &$entity;
|
||||
foreach ($property_path as $p) {
|
||||
if (is_object($value) && isset($value->{$p})) {
|
||||
$value = &$value->{$p};
|
||||
}
|
||||
elseif (is_array($value) && isset($value[$p])) {
|
||||
$value = &$value[$p];
|
||||
}
|
||||
}
|
||||
$value = $new_value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to add entity dependencies to a dependency array.
|
||||
*
|
||||
* We never treat user UID 0 or 1 as dependencies. Those are low level user
|
||||
* accounts ("anonymous" and "root") that already exists in most systems.
|
||||
*
|
||||
* @param $dependencies
|
||||
* The dependency array.
|
||||
* @param $objects
|
||||
* Array of objects that should be checked for dependencies in $properties.
|
||||
* @param $entity_type
|
||||
* The type of entity that $properties will add dependency on.
|
||||
* @param $properties
|
||||
* An array of properties that adds dependencies to $objects. All properties
|
||||
* must only point to one entity type at the time. A property can be a key
|
||||
* on the object, or an array of parent keys to identify the property.
|
||||
* @todo remove if this is solved [#1590312]
|
||||
*/
|
||||
function node_export_dependency_add(&$dependencies, $objects, $entity_type, $properties) {
|
||||
if (!is_array($objects)) {
|
||||
$objects = array($objects);
|
||||
}
|
||||
if (!is_array($properties)) {
|
||||
$properties = array($properties);
|
||||
}
|
||||
|
||||
foreach ($objects as $delta => $object) {
|
||||
foreach ($properties as $property) {
|
||||
$property_path = $property;
|
||||
if (!is_array($property_path)) {
|
||||
$property_path = array($property_path);
|
||||
}
|
||||
$value = $object;
|
||||
foreach ($property_path as $p) {
|
||||
if (is_object($value) && isset($value->{$p})) {
|
||||
$value = $value->{$p};
|
||||
}
|
||||
elseif (is_array($value) && isset($value[$p])) {
|
||||
$value = $value[$p];
|
||||
}
|
||||
}
|
||||
if (!empty($value) && $value != $object && !($entity_type == 'user' && (int)$value == 1)) {
|
||||
$dependencies[] = array(
|
||||
'type' => $entity_type,
|
||||
'id' => $value,
|
||||
'delta' => $delta,
|
||||
'property' => $property,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get UUID based on entity id.
|
||||
*/
|
||||
function node_export_dependency_get_uuid($entity_type, $id) {
|
||||
$entity_info = entity_get_info($entity_type);
|
||||
$id_key = $entity_info['entity keys']['id'];
|
||||
return uuid_get_uuid($entity_type, $id_key, $id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get dependencies of an entity.
|
||||
*
|
||||
* @todo rewrite if this is solved [#1590312]
|
||||
*/
|
||||
function node_export_dependency_get_dependencies($entity_type, $entity) {
|
||||
// @todo: remove the node_export_dependency.core.inc file if solved: [#1590312]
|
||||
module_load_include('inc', 'node_export_dependency', 'node_export_dependency.core');
|
||||
$all_dependencies = array();
|
||||
foreach (module_implements('node_export_dependency') as $module) {
|
||||
$dependencies = module_invoke($module, 'node_export_dependency', $entity, $entity_type);
|
||||
if (isset($dependencies) && is_array($dependencies)) {
|
||||
foreach ($dependencies as &$dependency) {
|
||||
if (empty($dependency['module'])) {
|
||||
$dependency['module'] = $module;
|
||||
}
|
||||
}
|
||||
$all_dependencies = array_merge_recursive($all_dependencies, $dependencies);
|
||||
}
|
||||
}
|
||||
return $all_dependencies;
|
||||
}
|
||||
|
@@ -0,0 +1,13 @@
|
||||
name = Node export features
|
||||
description = Adds Features support to Node export, so you can put your exports into Features modules.
|
||||
dependencies[] = node_export
|
||||
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"
|
||||
core = "7.x"
|
||||
project = "node_export"
|
||||
datestamp = "1345435979"
|
||||
|
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implements hook_features_api().
|
||||
*/
|
||||
function node_export_features_features_api() {
|
||||
$features = array();
|
||||
$features['node_export_features'] = array(
|
||||
'name' => t('Node export'),
|
||||
'feature_source' => TRUE,
|
||||
'default_hook' => 'node_export_features_default',
|
||||
'default_file' => FEATURES_DEFAULTS_INCLUDED,
|
||||
);
|
||||
return $features;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_features_export_options().
|
||||
*/
|
||||
function node_export_features_features_export_options() {
|
||||
$options = array();
|
||||
|
||||
$query = db_select('node', 'n')
|
||||
->fields('n', array('nid', 'title', 'type'))
|
||||
->orderBy('type')
|
||||
->orderBy('title')
|
||||
->range(0, 250)
|
||||
->addTag('node_export_features');
|
||||
|
||||
$result = $query->execute();
|
||||
|
||||
foreach ($result as $row) {
|
||||
$uuid = uuid_get_uuid('node', 'nid', $row->nid);
|
||||
if (empty($uuid)) {
|
||||
drupal_set_message(
|
||||
t('Some nodes are <strong>not</strong> available for export' .
|
||||
' because of missing UUIDs. Ensure UUIDs are being generated for' .
|
||||
' all content types and click the <em>Create missing UUIDs</em>' .
|
||||
' button on the <a href="!url">UUID settings page</a> to help' .
|
||||
' resolve this issue.',
|
||||
array('!url' => url('admin/settings/uuid'))
|
||||
),
|
||||
'warning',
|
||||
FALSE
|
||||
);
|
||||
}
|
||||
else {
|
||||
$options[$uuid] = t('@type: @title', array(
|
||||
'@type' => node_type_get_name($row->type),
|
||||
'@title' => $row->title,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
if (count($options) == 250) {
|
||||
drupal_set_message(
|
||||
t('Due to limitations in Features only the first 250 nodes are available.'
|
||||
. ' The query is tagged <em>node_export_features</em> if you want to'
|
||||
. ' alter it.'),
|
||||
'warning'
|
||||
);
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_features_export().
|
||||
*/
|
||||
function node_export_features_features_export($data, &$export, $module_name = '') {
|
||||
$pipe = array();
|
||||
|
||||
$export['dependencies']['module'] = 'node_export_features';
|
||||
|
||||
foreach ($data as $uuid) {
|
||||
$query = db_select('node', 'n')
|
||||
->fields('n', array('type'))
|
||||
->condition('n.uuid', $uuid);
|
||||
$type = $query->execute()->fetchField();
|
||||
|
||||
$export['features']['node_export_features'][$uuid] = $uuid;
|
||||
$pipe['node'][$type] = $type;
|
||||
}
|
||||
|
||||
return $pipe;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_features_export_render().
|
||||
*/
|
||||
function node_export_features_features_export_render($module, $data, $export = NULL) {
|
||||
$nids = entity_get_id_by_uuid('node', $data);
|
||||
$result = node_export($nids);
|
||||
if ($result['success']) {
|
||||
$node_export['code_string'] = $result['output'];
|
||||
$node_export_code = ' $node_export = ' . features_var_export($node_export) . ';';
|
||||
}
|
||||
else {
|
||||
foreach ($result['output'] as $error) {
|
||||
$node_export_code = ' // ' . $error . PHP_EOL;
|
||||
}
|
||||
$node_export_code .= ' $node_export = array();';
|
||||
}
|
||||
$node_export_code .= PHP_EOL . ' return $node_export;';
|
||||
return array('node_export_features_default' => $node_export_code);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_features_revert().
|
||||
*/
|
||||
function node_export_features_features_revert($module = NULL) {
|
||||
node_export_features_features_rebuild($module);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_features_rebuild().
|
||||
*/
|
||||
function node_export_features_features_rebuild($module) {
|
||||
$node_export = features_get_default('node_export_features', $module);
|
||||
if (!empty($node_export)) {
|
||||
$result = node_export_import($node_export['code_string']);
|
||||
if (!$result['success']) {
|
||||
foreach ($result['output'] as $error) {
|
||||
drupal_set_message($error, 'error');
|
||||
}
|
||||
}
|
||||
else {
|
||||
foreach ($result['output'] as $status) {
|
||||
drupal_set_message($status);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,145 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Class definition of FeedsNodeExportParser.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Parses a given file as a node export file.
|
||||
*/
|
||||
class FeedsNodeExportParser extends FeedsParser {
|
||||
public $format = NULL;
|
||||
|
||||
/**
|
||||
* Implements FeedsParser::parse().
|
||||
*/
|
||||
public function parse(FeedsSource $source, FeedsFetcherResult $fetcher_result) {
|
||||
|
||||
if (!($source->importer->processor instanceOf FeedsNodeExportProcessor)) {
|
||||
drupal_set_message(
|
||||
t('Node export parser must be used with Node export processor. No nodes imported.'),
|
||||
'error'
|
||||
);
|
||||
return new FeedsParserResult(array());
|
||||
}
|
||||
|
||||
// Get the node export code.
|
||||
$code_string = $fetcher_result->getRaw();
|
||||
|
||||
// @todo: Do we need this stuff?
|
||||
//$source_config = $source->getConfigFor($this);
|
||||
//$state = $source->state(FEEDS_PARSE);
|
||||
|
||||
// Execute node_export_import() but don't have it save the nodes.
|
||||
$result = node_export_import($code_string, 't', FALSE);
|
||||
|
||||
// Handle failure.
|
||||
if (!$result['success']) {
|
||||
foreach ($result['output'] as $error) {
|
||||
// @todo: Is this what we should do with output messages?
|
||||
drupal_set_message($error, 'error');
|
||||
}
|
||||
// @todo: Is this the right thing to return for a failure?
|
||||
return new FeedsParserResult(array());
|
||||
}
|
||||
|
||||
|
||||
foreach ($result['output'] as $status) {
|
||||
// @todo: Is this what we should do with output messages?
|
||||
drupal_set_message($status);
|
||||
}
|
||||
|
||||
// Feeds needs the nodes to be arrays.
|
||||
// @todo: Should we try to get node_export_import() to return arrays in the
|
||||
// first place? Or perhaps have the processor accept objects?
|
||||
foreach ($result['nodes'] as $node) {
|
||||
$items[] = (array)$node;
|
||||
}
|
||||
|
||||
// Store the format that was used.
|
||||
$this->format = $result['format'];
|
||||
|
||||
/*
|
||||
|
||||
// Node export doesn't support batchy stuffs atm.
|
||||
|
||||
|
||||
// Determine section to parse, parse.
|
||||
$start = $state->pointer ? $state->pointer : $parser->lastLinePos();
|
||||
$limit = $source->importer->getLimit();
|
||||
$rows = $this->parseItems($parser, $iterator, $start, $limit);
|
||||
|
||||
// Report progress.
|
||||
$state->total = filesize($fetcher_result->getFilePath());
|
||||
$state->pointer = $parser->lastLinePos();
|
||||
$progress = $parser->lastLinePos() ? $parser->lastLinePos() : $state->total;
|
||||
$state->progress($state->total, $progress);
|
||||
*/
|
||||
|
||||
// Create a result object and return it.
|
||||
return new FeedsParserResult($items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Override parent::getMappingSources().
|
||||
*/
|
||||
public function getMappingSources() {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override parent::getSourceElement() to use only lower keys.
|
||||
*/
|
||||
public function getSourceElement(FeedsSource $source, FeedsParserResult $result, $element_key) {
|
||||
return parent::getSourceElement($source, $result, drupal_strtolower($element_key));
|
||||
}
|
||||
|
||||
/**
|
||||
* Define defaults.
|
||||
*/
|
||||
public function sourceDefaults() {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Source form.
|
||||
*
|
||||
* Show mapping configuration as a guidance for import form users.
|
||||
*/
|
||||
public function sourceForm($source_config) {
|
||||
$form = array();
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define default configuration.
|
||||
*/
|
||||
public function configDefaults() {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Build configuration form.
|
||||
*/
|
||||
public function configForm(&$form_state) {
|
||||
$form = array();
|
||||
$form['info'] = array(
|
||||
'#prefix' => '<p>',
|
||||
'#markup' => t(
|
||||
'This parser uses settings from <a href="!config">node export</a>.',
|
||||
array('!config' => url('admin/config/content/node_export'))
|
||||
),
|
||||
'#suffix' => '</p>',
|
||||
);
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function getTemplate() {
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Class definition of FeedsNodeExportProcessor.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Creates nodes from feed items.
|
||||
*/
|
||||
class FeedsNodeExportProcessor extends FeedsNodeProcessor {
|
||||
public $new_nodes = array();
|
||||
|
||||
/**
|
||||
* Process the result of the parsing stage.
|
||||
*
|
||||
* @param FeedsSource $source
|
||||
* Source information about this import.
|
||||
* @param FeedsParserResult $parser_result
|
||||
* The result of the parsing stage.
|
||||
*/
|
||||
public function process(FeedsSource $source, FeedsParserResult $parser_result) {
|
||||
|
||||
if (!($source->importer->parser instanceOf FeedsNodeExportParser)) {
|
||||
drupal_set_message(
|
||||
t('Node export processor must be used with Node export parser. No nodes imported.'),
|
||||
'error',
|
||||
FALSE
|
||||
);
|
||||
return new FeedsParserResult(array());
|
||||
}
|
||||
|
||||
parent::process($source, $parser_result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new node in memory and returns it.
|
||||
*/
|
||||
/*
|
||||
|
||||
@todo: Should we override this function?
|
||||
|
||||
protected function newEntity(FeedsSource $source) {
|
||||
$node = new stdClass();
|
||||
$node->type = $this->config['content_type'];
|
||||
$node->changed = REQUEST_TIME;
|
||||
$node->created = REQUEST_TIME;
|
||||
$node->language = LANGUAGE_NONE;
|
||||
node_object_prepare($node);
|
||||
// Populate properties that are set by node_object_prepare().
|
||||
$node->log = 'Created by FeedsNodeProcessor';
|
||||
$node->uid = $this->config['author'];
|
||||
return $node;
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Loads an existing node.
|
||||
*
|
||||
* If the update existing method is not FEEDS_UPDATE_EXISTING, only the node
|
||||
* table will be loaded, foregoing the node_load API for better performance.
|
||||
*/
|
||||
/*
|
||||
|
||||
@todo: Should we override this function?
|
||||
|
||||
protected function entityLoad(FeedsSource $source, $nid) {
|
||||
if ($this->config['update_existing'] == FEEDS_UPDATE_EXISTING) {
|
||||
$node = node_load($nid, NULL, TRUE);
|
||||
}
|
||||
else {
|
||||
// We're replacing the existing node. Only save the absolutely necessary.
|
||||
$node = db_query("SELECT created, nid, vid, type FROM {node} WHERE nid = :nid", array(':nid' => $nid))->fetchObject();
|
||||
$node->uid = $this->config['author'];
|
||||
}
|
||||
node_object_prepare($node);
|
||||
// Populate properties that are set by node_object_prepare().
|
||||
if ($this->config['update_existing'] == FEEDS_UPDATE_EXISTING) {
|
||||
$node->log = 'Updated by FeedsNodeProcessor';
|
||||
}
|
||||
else {
|
||||
$node->log = 'Replaced by FeedsNodeProcessor';
|
||||
}
|
||||
return $node;
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Save a node.
|
||||
*
|
||||
* This code is similar to some code in node_export_import()
|
||||
* which gets executed for each node when the $save param is TRUE.
|
||||
*
|
||||
* @todo: should we check to make sure FeedsNodeExportParser was used?
|
||||
*/
|
||||
public function entitySave($entity) {
|
||||
$node = &$entity;
|
||||
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))));
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,14 @@
|
||||
name = "Node export feeds"
|
||||
description = "Node export feeds importer. This is a more advanced importer than the one built into node export, but tricky to use."
|
||||
core = "7.x"
|
||||
package = "Node export"
|
||||
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"
|
||||
core = "7.x"
|
||||
project = "node_export"
|
||||
datestamp = "1345435979"
|
||||
|
@@ -0,0 +1,156 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Node export feeds importer.
|
||||
*/
|
||||
|
||||
/**
|
||||
* 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'))) {
|
||||
return array('version' => 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_feeds_plugins().
|
||||
*/
|
||||
function node_export_feeds_feeds_plugins() {
|
||||
$info = array();
|
||||
$info['FeedsNodeExportParser'] = array(
|
||||
'name' => 'Node export parser',
|
||||
'description' => 'Parse a node export.',
|
||||
'help' => 'Parses the output from the node export module.',
|
||||
'handler' => array(
|
||||
'parent' => 'FeedsParser',
|
||||
'class' => 'FeedsNodeExportParser',
|
||||
'file' => 'FeedsNodeExportParser.inc',
|
||||
'path' => drupal_get_path('module', 'node_export_feeds'),
|
||||
),
|
||||
);
|
||||
$info['FeedsNodeExportProcessor'] = array(
|
||||
'name' => 'Node Export Processor',
|
||||
'description' => 'Process a node export.',
|
||||
'help' => 'Processes the output from the node export module.',
|
||||
'handler' => array(
|
||||
'parent' => 'FeedsNodeProcessor',
|
||||
'class' => 'FeedsNodeExportProcessor',
|
||||
'file' => 'FeedsNodeExportProcessor.inc',
|
||||
'path' => drupal_get_path('module', 'node_export_feeds'),
|
||||
),
|
||||
);
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_feeds_importer_default().
|
||||
*/
|
||||
function node_export_feeds_feeds_importer_default() {
|
||||
$export = array();
|
||||
|
||||
// Commented out properties seem to be unsupported targets in feeds?
|
||||
$mappings_keys = array(
|
||||
//'vid',
|
||||
'uid',
|
||||
'title',
|
||||
//'log',
|
||||
'status',
|
||||
'comment',
|
||||
'promote',
|
||||
'sticky',
|
||||
//'vuuid',
|
||||
'nid',
|
||||
//'type',
|
||||
'language',
|
||||
'created',
|
||||
//'changed',
|
||||
//'tnid',
|
||||
//'translate',
|
||||
//'uuid',
|
||||
//'revision_timestamp',
|
||||
//'revision_uid',
|
||||
'body',
|
||||
//'rdf_mapping',
|
||||
//'cid',
|
||||
//'last_comment_timestamp',
|
||||
//'last_comment_name',
|
||||
//'last_comment_uid',
|
||||
//'comment_count',
|
||||
//'name',
|
||||
//'picture',
|
||||
//'data',
|
||||
//'path',
|
||||
//'menu',
|
||||
//'node_export_drupal_version',
|
||||
);
|
||||
$mappings = array();
|
||||
foreach ($mappings_keys as $mappings_key) {
|
||||
$mappings[] = array(
|
||||
'source' => $mappings_key,
|
||||
'target' => $mappings_key,
|
||||
'unique' => FALSE,
|
||||
);
|
||||
}
|
||||
$mappings[] = array(
|
||||
'source' => 'uuid',
|
||||
'target' => 'guid',
|
||||
'unique' => 1,
|
||||
);
|
||||
|
||||
$feeds_importer = new stdClass;
|
||||
$feeds_importer->disabled = FALSE;
|
||||
$feeds_importer->api_version = 1;
|
||||
$feeds_importer->id = 'node_export';
|
||||
$feeds_importer->config = array(
|
||||
'name' => 'Node export import',
|
||||
'description' => 'Import nodes from node export.',
|
||||
'fetcher' => array(
|
||||
'plugin_key' => 'FeedsFileFetcher',
|
||||
'config' => array(
|
||||
'allowed_extensions' => 'export txt csv tsv xml opml',
|
||||
'direct' => FALSE,
|
||||
),
|
||||
),
|
||||
'parser' => array(
|
||||
'plugin_key' => 'FeedsNodeExportParser',
|
||||
'config' => array(),
|
||||
),
|
||||
'processor' => array(
|
||||
'plugin_key' => 'FeedsNodeExportProcessor',
|
||||
'config' => array(
|
||||
'content_type' => 'article',
|
||||
'update_existing' => 1,
|
||||
'expire' => '-1',
|
||||
'mappings' => $mappings,
|
||||
'input_format' => 'plain_text',
|
||||
'author' => 0,
|
||||
),
|
||||
),
|
||||
'content_type' => '',
|
||||
'update' => 0,
|
||||
'import_period' => '-1',
|
||||
'expire_period' => 3600,
|
||||
'import_on_create' => 1,
|
||||
);
|
||||
$export['node_export'] = $feeds_importer;
|
||||
|
||||
return $export;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_feeds_after_import().
|
||||
*/
|
||||
function node_export_feeds_feeds_after_import($source) {
|
||||
if ($source->importer->processor instanceOf FeedsNodeExportProcessor && !empty($source->importer->processor->new_nodes)) {
|
||||
// This code is similar to some code in node_export_import()
|
||||
// which gets executed for all nodes when the $save param is TRUE.
|
||||
$save = TRUE;
|
||||
drupal_alter('node_export_after_import', $source->importer->processor->new_nodes, $source->importer->parser->format, $save);
|
||||
// @todo: Is this what we should do with output messages?
|
||||
drupal_set_message(("Some values may have been reset depending on Node export's configuration."));
|
||||
|
||||
// Clear the page and block caches.
|
||||
cache_clear_all();
|
||||
}
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
name = Node export relation (deprecated)
|
||||
description = Helps maintain relationships. Supports node references, taxonomy, and organic groups.
|
||||
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"
|
||||
core = "7.x"
|
||||
project = "node_export"
|
||||
datestamp = "1345435979"
|
||||
|
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* The Node export relation install file.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_uninstall().
|
||||
*/
|
||||
function node_export_relation_uninstall() {
|
||||
// Node reference.
|
||||
variable_del('node_export_node_reference_auto_inc');
|
||||
variable_del('node_export_node_reference_skip');
|
||||
|
||||
// Organic groups.
|
||||
variable_del('node_export_og_auto_inc');
|
||||
variable_del('node_export_og_skip');
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_requirements().
|
||||
*/
|
||||
function node_export_relation_requirements($phase) {
|
||||
$requirements = array();
|
||||
|
||||
// Ensure translations don't break at install time
|
||||
$t = get_t();
|
||||
|
||||
if (module_exists('node_export_dependency')) {
|
||||
$requirements['node_export_dependency'] = array(
|
||||
'title' => 'Node export dependency',
|
||||
'description' => $t(
|
||||
'Node export relation is deprecated in favour of Node export dependency. You cannot use both.'
|
||||
),
|
||||
'severity' => REQUIREMENT_ERROR,
|
||||
);
|
||||
}
|
||||
|
||||
return $requirements;
|
||||
}
|
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* The Node export relation module.
|
||||
*
|
||||
* Helps maintain relationships between nodes during node export operations.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Callback for node reference settings form.
|
||||
*/
|
||||
function node_export_relation_form_node_export_settings_alter(&$form, &$form_state, $form_id) {
|
||||
if (module_exists('node_reference')) {
|
||||
module_load_include('inc', 'node_export_relation', 'node_export_relation.node_reference');
|
||||
node_export_relation_settings_form_node_reference($form, $form_state, $form_id);
|
||||
}
|
||||
/*
|
||||
// None of the settings are supported yet.
|
||||
|
||||
if (module_exists('og')) {
|
||||
module_load_include('inc', 'node_export_relation', 'node_export_relation.og');
|
||||
node_export_relation_settings_form_og($form, $form_state, $form_id);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_node_export_alter().
|
||||
*/
|
||||
function node_export_relation_node_export_alter(&$nodes, $format) {
|
||||
|
||||
if (module_exists('node_reference')) {
|
||||
module_load_include('inc', 'node_export_relation', 'node_export_relation.node_reference');
|
||||
if (variable_get('node_export_node_reference_auto_inc', TRUE)) {
|
||||
$keyed_nodes = array();
|
||||
foreach ($nodes as $node) {
|
||||
$keyed_nodes[$node->nid] = $node;
|
||||
}
|
||||
// Keyed nodes are important for preventing same node loaded again via references.
|
||||
foreach (array_keys($keyed_nodes) as $nid) {
|
||||
node_export_relation_node_reference_load($keyed_nodes, $nid);
|
||||
}
|
||||
$nodes = array_values($keyed_nodes);
|
||||
}
|
||||
}
|
||||
|
||||
if (module_exists('og')) {
|
||||
module_load_include('inc', 'node_export_relation', 'node_export_relation.og');
|
||||
// Go through nodes and set UUIDs for their groups.
|
||||
node_export_relation_og_set_group_uuids($nodes);
|
||||
}
|
||||
|
||||
if (module_exists('taxonomy')) {
|
||||
module_load_include('inc', 'node_export_relation', 'node_export_relation.taxonomy');
|
||||
foreach ($nodes as $node) {
|
||||
node_export_relation_taxonomy_build_term_reference($node);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_node_export_import_alter().
|
||||
*/
|
||||
function node_export_relation_node_export_import_alter(&$nodes, $format) {
|
||||
|
||||
if (module_exists('node_reference')) {
|
||||
module_load_include('inc', 'node_export_relation', 'node_export_relation.node_reference');
|
||||
foreach ($nodes as $node) {
|
||||
node_export_relation_node_reference_map($node->nid, $node->uuid);
|
||||
}
|
||||
}
|
||||
|
||||
if (module_exists('og')) {
|
||||
module_load_include('inc', 'node_export_relation', 'node_export_relation.og');
|
||||
// Now go through the groupes and switch back the UUIDS to actual ids.
|
||||
node_export_relation_og_set_group_nids($nodes);
|
||||
}
|
||||
|
||||
if (module_exists('taxonomy')) {
|
||||
module_load_include('inc', 'node_export_relation', 'node_export_relation.taxonomy');
|
||||
foreach ($nodes as $node) {
|
||||
node_export_relation_taxonomy_restore_term_reference($node);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_node_export_after_import_alter().
|
||||
*/
|
||||
function node_export_relation_node_export_after_import_alter(&$nodes, $format) {
|
||||
|
||||
if (module_exists('node_reference')) {
|
||||
module_load_include('inc', 'node_export_relation', 'node_export_relation.node_reference');
|
||||
// Now that all nodes are imported/updated we can restore the node referenced from UUIDS
|
||||
// NOTE: This is done because if the node referenced node is new, they we have
|
||||
// to wait for node to be saved.
|
||||
node_export_relation_node_reference_update($nodes);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,143 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* The Node export relation node reference include.
|
||||
*
|
||||
* Helps maintain node reference relationships between nodes during node export operations.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_form_FORM_ID_alter().
|
||||
*/
|
||||
function node_export_relation_settings_form_node_reference(&$form, &$form_state, $form_id) {
|
||||
$form['node_reference'] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('Node references'),
|
||||
);
|
||||
|
||||
// Not supported yet.
|
||||
$form['node_reference']['node_export_node_reference_auto_inc'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Automatically include referenced nodes in exports'),
|
||||
'#default' => variable_get('node_export_node_reference_auto_inc', TRUE),
|
||||
);
|
||||
|
||||
$form['node_reference']['node_export_node_reference_skip'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Skip referenced nodes that cannot be exported'),
|
||||
'#default' => variable_get('node_export_node_reference_skip', TRUE),
|
||||
'#description' => t('If this is disabled, node exports will fail if a referenced node cannot be exported, for example if the user performing the export does not have access.'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update node references after import.
|
||||
*/
|
||||
function node_export_relation_node_reference_update($nodes) {
|
||||
foreach ($nodes as $node) {
|
||||
$uuid[$node->uuid] = $node->nid;
|
||||
}
|
||||
foreach ($nodes as $node) {
|
||||
$node_reference_fields = node_export_relation_node_reference_fields($node->type);
|
||||
if (!empty($node_reference_fields)) {
|
||||
foreach ($node_reference_fields as $node_reference_field) {
|
||||
$items = field_get_items('node', $node, $node_reference_field);
|
||||
$langcode = field_language('node', $node, $node_reference_field);
|
||||
if (!empty($items)) {
|
||||
foreach ($items as $key => &$node_reference) {
|
||||
if (!empty($node_reference['nid'])) {
|
||||
$node_uuid = node_export_relation_node_reference_map($node_reference['nid']);
|
||||
$node->{$node_reference_field}[$langcode][$key] = array('nid' => $uuid[$node_uuid]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
node_save($node);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively load node references.
|
||||
*/
|
||||
function node_export_relation_node_reference_load(&$nodes, $nid) {
|
||||
// Alias for easy referencing.
|
||||
$node = &$nodes[$nid];
|
||||
|
||||
// Get list of node reference fields for this node
|
||||
$node_reference_fields = node_export_relation_node_reference_fields($node->type);
|
||||
if (!empty($node_reference_fields)) {
|
||||
foreach ($node_reference_fields as $node_reference_field) {
|
||||
$items = field_get_items('node', $node, $node_reference_field);
|
||||
if (!empty($items)) {
|
||||
foreach ($items as &$node_reference) {
|
||||
if (!empty($node_reference['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_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);
|
||||
}
|
||||
elseif (!variable_get('node_export_node_reference_skip', TRUE)) {
|
||||
// Set this node to FALSE to trigger an error in node export.
|
||||
// Do not use $new_node in this code in case there is a problem with it.
|
||||
$nodes[$node_reference['nid']] = FALSE;
|
||||
// Add a warning to watchdog.
|
||||
watchdog('node_export_relation', 'No access to export node reference %nid', array('%nid' => $node_reference['nid']), WATCHDOG_WARNING);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Statically cache old node ids for mapping.
|
||||
*/
|
||||
function node_export_relation_node_reference_map($id, $uuid = NULL, $type = 'node') {
|
||||
static $map;
|
||||
if (isset($uuid)) {
|
||||
$map[$type][$id] = $uuid;
|
||||
}
|
||||
else {
|
||||
return $map[$type][$id];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array listing the names of all node reference fields.
|
||||
*
|
||||
* @return
|
||||
* Array of all created node reference fields.
|
||||
*/
|
||||
function node_export_relation_node_reference_fields($content_type_name) {
|
||||
// cache result
|
||||
static $node_reference_fields = array();
|
||||
|
||||
if (empty($node_reference_fields[$content_type_name])) {
|
||||
$fields = field_info_instances('node', $content_type_name);
|
||||
if (!empty($fields)) {
|
||||
foreach ($fields as $field) {
|
||||
|
||||
if (isset($field['widget']['module']) && $field['widget']['module'] == 'node_reference' && !empty($field['field_name'])) {
|
||||
$node_reference_fields[$content_type_name][$field['field_name']] = $field['field_name'];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists($content_type_name, $node_reference_fields)) {
|
||||
return $node_reference_fields[$content_type_name];
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* The Node export relation OG include.
|
||||
*
|
||||
* Helps maintain organic groups relationships between nodes during node export operations.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Callback for OG settings form.
|
||||
*/
|
||||
function node_export_relation_settings_form_og(&$form, &$form_state) {
|
||||
$form['og'] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('Organic groups'),
|
||||
);
|
||||
$form['og']['node_export_og_auto_inc'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Automatically OG related related nodes in exports'),
|
||||
'#default' => variable_get('node_export_og_auto_inc', TRUE),
|
||||
);
|
||||
$form['og']['node_export_og_skip'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Skip related OG nodes that cannot be exported'),
|
||||
'#default' => variable_get('node_export_og_skip', TRUE),
|
||||
'#description' => t('If this is disabled, node exports will fail if a related OG node cannot be exported, for example if the user performing the export does not have access.'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Go through group nids and put group UUIDs in their place.
|
||||
*/
|
||||
function node_export_relation_og_set_group_uuids(&$nodes) {
|
||||
foreach ($nodes as &$node) {
|
||||
if (!empty($node->og_groups)) {
|
||||
foreach ($node->og_groups as $key => $group_nid) {
|
||||
$group_uuid = uuid_get_uuid('node', 'nid', $group_nid);
|
||||
// Create uuid if it doesn't exists
|
||||
if (empty($group_uuid)) {
|
||||
$group_uuid = uuid_set_uuid('node', 'nid', $group_nid);
|
||||
}
|
||||
|
||||
$node->og_groups[$group_uuid] = $group_uuid;
|
||||
unset($node->og_groups[$key]);
|
||||
// Modify og_groups_both as well (gid => title).
|
||||
$group_title = $node->og_groups_both[$group_nid];
|
||||
$node->og_groups_both[$group_uuid] = $group_title;
|
||||
unset($node->og_groups_both[$group_nid]);
|
||||
}
|
||||
}
|
||||
|
||||
// Support for og_subgroups.
|
||||
if (!empty($node->og_parent)) {
|
||||
$group_uuid = uuid_get_uuid('node', 'nid', $node->og_parent->nid);
|
||||
// Create uuid if it doesn't exists
|
||||
if (empty($group_uuid)) {
|
||||
$group_uuid = uuid_set_uuid('node', 'nid', $node->og_parent->nid);
|
||||
}
|
||||
$node->og_parent = $group_uuid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Go through group UUIDs and put group nids in their place.
|
||||
*/
|
||||
function node_export_relation_og_set_group_nids(&$nodes) {
|
||||
foreach ($nodes as &$node) {
|
||||
if (!empty($node->og_groups)) {
|
||||
foreach ($node->og_groups as $key => $group_uuid) {
|
||||
// If this is really a UUID, find the matching nid.
|
||||
if (uuid_is_valid($group_uuid)) {
|
||||
$group_nids = entity_get_id_by_uuid(array($group_uuid));
|
||||
$group_nid = $group_nids[$group_uuid];
|
||||
$node->og_groups[$group_nid] = $group_nid;
|
||||
unset($node->og_groups[$key]);
|
||||
|
||||
// Modify og_groups_both as well (gid => title).
|
||||
$group_title = $node->og_groups_both[$group_uuid];
|
||||
$node->og_groups_both[$group_nid] = $group_title;
|
||||
unset($node->og_groups_both[$group_uuid]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Support for og_subgroups.
|
||||
if (!empty($node->og_parent) && is_string($node->og_parent)) {
|
||||
// Create uuid if it doesn't exists
|
||||
if (uuid_is_valid($node->og_parent)) {
|
||||
$group_nids = entity_get_id_by_uuid(array($group_uuid));
|
||||
$node->og_parent = $group_nids[$group_uuid];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* The Node export relation OG include.
|
||||
*
|
||||
* Helps maintain organic groups relationships between nodes during node export operations.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Add taxonomy term reference UUID.
|
||||
*/
|
||||
function node_export_relation_taxonomy_build_term_reference($node) {
|
||||
$reference_fields = node_export_relation_taxonomy_term_reference_fields($node);
|
||||
// Iterate through the class properties
|
||||
foreach ($reference_fields as $field => $val) {
|
||||
// There may be multiple languages
|
||||
foreach ($val as $lang => $values) {
|
||||
// Multi-value fields
|
||||
foreach ($values as $pos => $value) {
|
||||
$term = taxonomy_term_load($value['tid']);
|
||||
$new_field = $node->$field;
|
||||
$new_field[$lang][$pos]['uuid'] = $term->uuid;
|
||||
$node->$field = $new_field;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore the tid based on the term UUID.
|
||||
*/
|
||||
function node_export_relation_taxonomy_restore_term_reference($node) {
|
||||
$reference_fields = node_export_relation_taxonomy_term_reference_fields($node);
|
||||
// Iterate through the class properties
|
||||
foreach ($reference_fields as $field => $val) {
|
||||
// There may be multiple languages
|
||||
foreach ($val as $lang => $values) {
|
||||
// Multi-value fields
|
||||
foreach ($values as $pos => $value) {
|
||||
if (isset($value['uuid'])) {
|
||||
// @TODO load_by_uuid
|
||||
$tid = db_select('taxonomy_term_data', 'ttd')
|
||||
->fields('ttd', array('tid'))
|
||||
->condition('ttd.uuid', $value['uuid'])
|
||||
->execute()
|
||||
->fetchField();
|
||||
if ($tid) {
|
||||
$new_field[$lang][$pos]['tid'] = $tid;
|
||||
$node->$field = $new_field;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the term reference fields for a node.
|
||||
*/
|
||||
function node_export_relation_taxonomy_term_reference_fields($node) {
|
||||
$reference_fields = array();
|
||||
$instances = field_info_instances('node', $node->type);
|
||||
if (!empty($instances)) {
|
||||
foreach ($instances as $instance) {
|
||||
$field = field_info_field($instance['field_name']);
|
||||
if (isset($field['type']) && $field['type'] == 'taxonomy_term_reference') {
|
||||
$field_name = $instance['field_name'];
|
||||
$reference_fields[$field_name] = $node->$field_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $reference_fields;
|
||||
}
|
Reference in New Issue
Block a user