'node_type_get_type', 'bundle_save_callback' => 'node_type_save', 'export_menu' => array( 'path' => 'admin/structure/types/export', 'access arguments' => 'administer content types', ), 'import_menu' => array( 'path' => 'admin/structure/types/import', 'access arguments' => 'administer content types', ), ); $info['user'] = array( 'bundle_export_callback' => '_bc_bundle_export_ignore', 'bundle_save_callback' => '_bc_bundle_save_ignore', 'export_menu' => array( 'path' => 'admin/config/people/accounts/export', 'access arguments' => 'administer users', ), 'import_menu' => array( 'path' => 'admin/config/people/accounts/import', 'access arguments' => 'administer users', ), ); if (module_exists('taxonomy')) { $info['taxonomy_term'] = array( 'bundle_export_callback' => '_bc_copy_taxonomy_load', 'bundle_save_callback' => '_bc_copy_taxonomy_save', 'export_menu' => array( 'path' => 'admin/structure/taxonomy/export', 'access arguments' => 'administer taxonomy', ), 'import_menu' => array( 'path' => 'admin/structure/taxonomy/import', 'access arguments' => 'administer taxonomy', ), ); } return $info; } /** * Implements hook_menu(). */ function bundle_copy_menu() { $items = array(); $bc_info = bundle_copy_get_info(); foreach ($bc_info as $entity_type => $info) { $items[$info['export_menu']['path']] = array( 'title' => 'Export', 'page callback' => 'drupal_get_form', 'page arguments' => array('bundle_copy_export', $entity_type), 'access arguments' => array($info['export_menu']['access arguments']), 'type' => MENU_LOCAL_TASK ); $items[$info['import_menu']['path']] = array( 'title' => 'Import', 'page callback' => 'drupal_get_form', 'page arguments' => array('bundle_copy_import', $entity_type), 'access callback' => 'bundle_copy_import_access', 'access arguments' => array($info['import_menu']['access arguments']), 'type' => MENU_LOCAL_TASK ); } return $items; } /** * Bundle copy import access callback. * * Bundle copy imports require an additional access check because they are PHP * code and PHP is more locked down than the general permission. */ function bundle_copy_import_access($permission) { return user_access($permission) && user_access('use PHP for settings'); } /** * Menu callback: present the export page. */ function bundle_copy_export($form, &$form_state, $entity_type = 'node') { if (isset($form_state['step'])) { $step = $form_state['step']; } else { $step = 1; $form_state['step'] = $step; } switch ($step) { // Select the bundles. case 1: $bundles = _bundle_copy_bundle_info($entity_type, TRUE); $form['bundle-info'] = array( '#markup' => t('Select bundles you want to export.'), ); $form['bundles'] = array( '#type' => 'tableselect', '#header' => array('label' => t('Bundle')), '#options' => $bundles, '#required' => TRUE, '#empty' => t('No bundles found.'), ); $form['next'] = array( '#type' => 'submit', '#value' => t('Next'), ); break; // List the fields / field groups. case 2: // Field group. $all_groups = function_exists('field_group_info_groups') ? field_group_info_groups() : array(); // Fields. $field_options = $instances = array(); $selected_bundles = $form_state['page_values'][1]['bundles']; foreach ($selected_bundles as $key => $bundle) { if ($key === $bundle) { $instances += field_info_instances($entity_type, $bundle); } } ksort($instances); foreach ($instances as $key => $info) { $field_options[$key]['field'] = $info['field_name']; // Same as $key. $field_options[$key]['label'] = $info['label']; } $form['fields-info'] = array( '#markup' => t('Select fields you want to export.'), ); $form['fields'] = array( '#type' => 'tableselect', '#header' => array('field' => t('Field name'), 'label' => t('Label')), '#options' => $field_options, '#empty' => t('No fields found.'), ); // Field group support. if (!empty($all_groups)) { $group_options = $fieldgroups = array(); if (isset($all_groups[$entity_type])) { foreach ($selected_bundles as $key => $bundle) { if ($key === $bundle) { if (!isset($all_groups[$entity_type][$key])) { continue; } foreach ($all_groups[$entity_type][$key] as $view_mode => $groups) { foreach ($groups as $field_group) { $group_options[$field_group->id]['fieldgroup'] = $field_group->label . ' (' . $field_group->bundle . ' - ' . $field_group->mode .')'; $fieldgroups[$field_group->id] = $field_group; } } } } } if (!empty($group_options)) { $form['fieldgroups-info'] = array( '#markup' => t('Select field groups you want to export.'), ); $form['fieldgroups'] = array( '#type' => 'tableselect', '#header' => array('fieldgroup' => t('Field group name')), '#options' => $group_options, ); $form['fieldgroups-full'] = array( '#type' => 'value', '#value' => $fieldgroups, ); } } $form['actions'] = array('#type' => 'actions'); $form['actions']['next'] = array( '#type' => 'submit', '#value' => t('Export'), ); $bc_info = bundle_copy_get_info(); $form['actions']['cancel'] = array( '#markup' => l(t('Cancel'), $bc_info[$entity_type]['export_menu']['path']), ); break; // Export data. case 3: $data = _bundle_copy_export_data($entity_type, $form_state['page_values']); $form['export'] = array( '#title' => t('Export data'), '#type' => 'textarea', '#cols' => 60, '#value' => $data, '#rows' => 40, '#description' => t('Copy the export text and paste it into another bundle using the import function.'), ); break; } return $form; } /** * Submit callback: export data. */ function bundle_copy_export_submit($form, &$form_state) { // Save the form state values. $step = $form_state['step']; $form_state['page_values'][$step] = $form_state['values']; // Add step and rebuild. $form_state['step'] = $form_state['step'] + 1; $form_state['rebuild'] = TRUE; } /** * Menu callback: present the import page. */ function bundle_copy_import($form, $form_state, $entity_type = 'node') { $form['entity_type'] = array('#type' => 'value', '#value' => $entity_type); $form['info'] = array( '#markup' => t('This form will import bundle and field definitions.'), ); //$form['type_name'] = array( // '#title' => t('Bundle'), // '#description' => t('Select the bundle to import these fields into.
Select <Create> to create a new bundle to contain the fields.'), // '#type' => 'select', // '#options' => array('' => t('')) + _bundle_copy_bundle_info($entity_type), //); $form['macro'] = array( '#type' => 'textarea', '#rows' => 10, '#title' => t('Import data'), '#required' => TRUE, '#description' => t('Paste the text created by a bundle export into this field.'), ); $form['submit'] = array( '#type' => 'submit', '#value' => t('Import'), ); return $form; } /** * Submit callback: import data. */ function bundle_copy_import_submit($form, &$form_state) { // Evaluate data. eval($form_state['values']['macro']); if (isset($data) && is_array($data)) { $modules = module_list(); $bc_info = bundle_copy_get_info(); // Create bundles. foreach ($data['bundles'] as $key => $bundle) { $entity_type = ''; if (is_object($bundle)) { $entity_type = $bundle->bc_entity_type; } elseif (is_array($bundle)) { $entity_type = $bundle['bc_entity_type']; } if (!empty($entity_type)) { $existing_bundles = _bundle_copy_bundle_info($entity_type); $bundle_save_callback = $bc_info[$entity_type]['bundle_save_callback']; $bundle_info = $bundle_save_callback($bundle); if (!isset($existing_bundles[$key])) { drupal_set_message(t('%bundle bundle has been created.', array('%bundle' => $bundle->name))); } else { drupal_set_message(t('%bundle bundle has been updated.', array('%bundle' => $bundle->name))); } } } // Create or update fields and their instances if (isset($data['fields'])) { foreach ($data['fields'] as $key => $field) { // Check if the field module exists. $module = $field['module']; if (!isset($modules[$module])) { drupal_set_message(t('%field_name field could not be created because the module %module is disabled or missing.', array('%field_name' => $key, '%module' => $module)), 'error'); continue; } if (isset($data['instances'][$key])) { // Create or update field. $prior_field = field_read_field($field['field_name'], array('include_inactive' => TRUE)); if (!$prior_field) { field_create_field($field); drupal_set_message(t('%field_name field has been created.', array('%field_name' => $key))); } else { $field['id'] = $prior_field['id']; field_update_field($field); drupal_set_message(t('%field_name field has been updated.', array('%field_name' => $key))); } // Create or update field instances. foreach ($data['instances'][$key] as $ikey => $instance) { // Make sure the needed key exists. if (!isset($instance['field_name'])) { continue; } $prior_instance = field_read_instance($instance['entity_type'], $instance['field_name'], $instance['bundle']); if (!$prior_instance) { field_create_instance($instance); drupal_set_message(t('%field_name instance has been created for @bundle in @entity_type.', array('%field_name' => $key, '@bundle' => $instance['bundle'], '@entity_type' => $instance['entity_type']))); } else { $instance['id'] = $prior_instance['id']; $instance['field_id'] = $prior_instance['field_id']; field_update_instance($instance); drupal_set_message(t('%field_name instance has been updated for @bundle in @entity_type.', array('%field_name' => $key, '@bundle' => $instance['bundle'], '@entity_type' => $instance['entity_type']))); } } } } } // Create / update fieldgroups. if (isset($data['fieldgroups'])) { if (module_exists('field_group')) { ctools_include('export'); $existing_field_groups = field_group_info_groups(); foreach ($data['fieldgroups'] as $identifier => $fieldgroup) { if (isset($existing_field_groups[$fieldgroup->entity_type][$fieldgroup->bundle][$fieldgroup->mode][$fieldgroup->group_name])) { $existing = $existing_field_groups[$fieldgroup->entity_type][$fieldgroup->bundle][$fieldgroup->mode][$fieldgroup->group_name]; $fieldgroup->id = $existing->id; if (!isset($fieldgroup->disabled)) { $fieldgroup->disabled = FALSE; } ctools_export_crud_save('field_group', $fieldgroup); ctools_export_crud_set_status('field_group', $fieldgroup, $fieldgroup->disabled); drupal_set_message(t('%fieldgroup fieldgroup has been updated for @bundle in @entity_type.', array('%fieldgroup' => $fieldgroup->label, '@bundle' => $fieldgroup->bundle, '@entity_type' => $fieldgroup->entity_type))); } else { unset($fieldgroup->id); unset($fieldgroup->export_type); if (!isset($fieldgroup->disabled)) { $fieldgroup->disabled = FALSE; } ctools_export_crud_save('field_group', $fieldgroup); $fieldgroup->export_type = 1; ctools_export_crud_set_status('field_group', $fieldgroup, $fieldgroup->disabled); drupal_set_message(t('%fieldgroup fieldgroup has been saved for @bundle in @entity_type.', array('%fieldgroup' => $fieldgroup->label, '@bundle' => $fieldgroup->bundle, '@entity_type' => $fieldgroup->entity_type))); } } } else { drupal_set_message(t('The fieldgroups could not be saved because the Field group module is disabled or missing.'), 'error'); } } // Clear caches. field_info_cache_clear(); if (module_exists('field_group')) { cache_clear_all('field_groups', 'cache_field'); } } else { drupal_set_message(t('The pasted text did not contain any valid export data.'), 'error'); } } /** * Return bundles for a certain entity type. * * @param $entity_type * The name of the entity type. * @param $table_select * Whether we're returning for the table select or not. */ function _bundle_copy_bundle_info($entity_type, $table_select = FALSE) { static $bundles = array(); if (!isset($bundles[$entity_type])) { $bundles[$entity_type] = array(); $entity_info = entity_get_info($entity_type); $entity_bundles = $entity_info['bundles']; ksort($entity_bundles); foreach ($entity_bundles as $key => $info) { $label = isset($info['label']) ? $info['label'] : drupal_ucfirst(str_replace('_', ' ', $key)); if ($table_select) { $bundles[$entity_type][$key]['label'] = $label; } else { $bundles[$entity_type][$key] = $label; } } } return $bundles[$entity_type]; } /** * Creates export data * * @param $entity_type * The name of the entity_type * @param $selected_data * The selected data. */ function _bundle_copy_export_data($entity_type, $selected_data) { ctools_include('export'); $bc_info = bundle_copy_get_info(); $selected_bundles = $selected_data[1]['bundles']; $selected_fields = $selected_data[2]['fields']; $selected_fieldgroups = isset($selected_data[2]['fieldgroups']) ? $selected_data[2]['fieldgroups'] : array(); $full_fieldgroups = isset($selected_data[2]['fieldgroups-full']) ? $selected_data[2]['fieldgroups-full'] : array(); $data = $instances = array(); $fields = field_info_fields(); foreach ($selected_bundles as $bkey => $binfo) { if ($bkey !== $binfo) { continue; } $field_instances = field_info_instances($entity_type, $bkey); ksort($field_instances); // Bundles export data. $bundle_info_callback = $bc_info[$entity_type]['bundle_export_callback']; $bundle_info = $bundle_info_callback($bkey, $entity_type); if (is_object($bundle_info)) { $bundle_info->bc_entity_type = $entity_type; } elseif (is_array($bundle_info)) { $bundle_info['bc_entity_type'] = $entity_type; } $data['bundles'][$bkey] = $bundle_info; // Fields export data. foreach ($selected_fields as $fkey => $finfo) { if ($fkey === $finfo) { if (!isset($data['fields'][$fkey])) { unset($fields[$fkey]['id']); $data['fields'][$fkey] = $fields[$fkey]; } if (isset($field_instances[$fkey])) { unset($field_instances[$fkey]['id']); unset($field_instances[$fkey]['field_id']); $instances[$fkey][] = $field_instances[$fkey]; } } } } ksort($instances); $data['instances'] = $instances; // Field group export data. if (!empty($selected_fieldgroups)) { foreach ($selected_fieldgroups as $key => $value) { if ($value !== 0) { $data['fieldgroups'][$full_fieldgroups[$key]->identifier] = $full_fieldgroups[$key]; } } } return '$data = ' . ctools_var_export($data) . ';'; } /** * Helper function to load the taxonomy, but remove the vid on the object. * * @param $name * The name of the bundle. */ function _bc_copy_taxonomy_load($name) { $bundle = taxonomy_vocabulary_machine_name_load($name); return $bundle; } /** * Helper function to save the taxonomy. */ function _bc_copy_taxonomy_save($bundle) { if ($bundle->vid) { unset($bundle->vid); } $vid = db_query('SELECT vid FROM {taxonomy_vocabulary} WHERE machine_name = :machine_name', array(':machine_name' => $bundle->machine_name))->fetchField(); if ($vid) { $bundle->vid = $vid; } taxonomy_vocabulary_save($bundle); } /** * Helper function to ignore a bundle on export. */ function _bc_bundle_export_ignore($name) { } /** * Helper function to ignore a bundle save. */ function _bc_bundle_save_ignore($bundle) { }