You are here

clone.module in Node clone 6

Same filename and directory in other branches
  1. 5.2 clone.module
  2. 5 clone.module
  3. 7 clone.module

Allow users to make a copy of an item of content (a node) and then edit that copy.

File

clone.module
View source
<?php

/**
 * @file
 * Allow users to make a copy of an item of content (a node) and then edit that copy.
 */

/**
 * Implementation of hook_help().
 */
function clone_help($path, $arg) {
  switch ($path) {
    case 'admin/help#clone':
      $output = '<p>' . t('The clone module allows users to make a copy of an existing node and then edit that copy. The authorship is set to the current user, the menu and url aliases are reset, and the words "Clone of" are inserted into the title to remind you that you are not editing the original node.') . '</p>';
      $output .= '<p>' . t('Users with the "clone node" permission can utilize this functionality. A new tab will appear on node pages with the word "Clone".') . '</p>';
      return $output;
    case 'node/%/clone':
      $method = variable_get('clone_method', 'prepopulate');
      if ($method == 'prepopulate') {
        return t('This clone will not be saved to the database until you submit.');
      }
  }
}

/**
 * Implementation of hook_perm().
 */
function clone_perm() {
  return array(
    'clone node',
    'clone own nodes',
  );
}

/**
 * Implementation of hook_menu().
 */
function clone_menu() {
  $items['admin/settings/clone'] = array(
    'access arguments' => array(
      'administer site configuration',
    ),
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'clone_settings',
    ),
    'title' => 'Clone module',
    'file' => 'clone.pages.inc',
    'description' => 'Allows users to clone (copy then edit) an existing node.',
  );
  $items['node/%node/clone'] = array(
    'access callback' => 'clone_access_cloning',
    'access arguments' => array(
      1,
    ),
    'page callback' => 'clone_node_check',
    'page arguments' => array(
      1,
    ),
    'title' => 'Clone',
    'weight' => 5,
    'file' => 'clone.pages.inc',
    'type' => MENU_LOCAL_TASK,
  );
  return $items;
}
function clone_access_cloning($node) {
  global $user;

  // Check basic permissions first.
  $access = clone_is_permitted($node->type) && (user_access('clone node') || $user->uid && $node->uid == $user->uid && user_access('clone own nodes'));

  // Check additional conditions
  $access = $access && (filter_access($node->format) && node_access('create', $node->type));

  // Make sure the user can view the original node content.
  $access = $access && node_access('view', $node);

  // Let other modules alter access.
  drupal_alter("clone_access", $access, $node);
  return $access;
}
function clone_is_permitted($type) {
  $omitted = variable_get('clone_omitted', array());
  return empty($omitted[$type]);
}

/**
 * Implementation of hook_mode_type().
 */
function clone_node_type($op, $type_obj) {
  switch ($op) {
    case 'delete':
      variable_del('clone_reset_' . $type_obj->type);
      break;
    case 'update':
      if (!empty($type_obj->old_type) && $type_obj->old_type != $type_obj->type) {
        if (variable_get('clone_reset_' . $type_obj->old_type, FALSE)) {
          variable_del('clone_reset_' . $type_obj->old_type);
          variable_set('clone_reset_' . $type_obj->type, TRUE);
        }
      }
      break;
  }
}

/**
* Implementation of hook_views_api.
*/
function clone_views_api() {
  return array(
    'api' => 2,
    'path' => drupal_get_path('module', 'clone') . '/views',
  );
}

/**
 * Implementation of hook_init().
 */
function clone_init() {

  // Support admin theme setting, based on system_init().
  // Only affect the menu path created by this module, and only if the node admin theme checkbox is set.
  if (variable_get('node_admin_theme', '0') && arg(0) == 'node' && arg(2) == 'clone') {
    global $custom_theme;

    // Use the chosen theme ID, or the front-end theme if one hasn't been selected.
    $custom_theme = variable_get('admin_theme', '0');

    // From system.module, this css file is required in the admin view.
    drupal_add_css(drupal_get_path('module', 'system') . '/admin.css', 'module');
  }
}

/**
 * Implementation of hook_form_alter().
 */
function clone_form_alter(&$form, $form_state, $form_id) {

  // Add the clone_from_original_nid value for node forms triggered by cloning.
  // This will make sure the clone_from_original_nid property is still
  // attached to the node when passing through hook_nodeapi($op = insert).
  if (isset($form['#node']) && $form['#node']->type . '_node_form' == $form_id) {
    if (!empty($form['#node']->clone_from_original_nid)) {
      $form['clone_from_original_nid'] = array(
        '#type' => 'value',
        '#value' => $form['#node']->clone_from_original_nid,
      );
    }
  }
}

/**
 * Implementation of hook_nodeapi().
 */
function clone_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {

  // Handle the core bugginess in node_object_prepare() that overwrites the
  // publishing options.
  if ($op == 'prepare' && isset($node->clone_from_original_nid)) {
    if (variable_get('clone_reset_' . $node->type, FALSE)) {
      $node_options = variable_get('node_options_' . $node->type, array(
        'status',
        'promote',
      ));

      // Fill in the default values.
      foreach (array(
        'status',
        'moderate',
        'promote',
        'sticky',
        'revision',
      ) as $key) {
        $node->{$key} = in_array($key, $node_options);
      }
    }
    else {
      $original_node = node_load($node->clone_from_original_nid);
      foreach (array(
        'status',
        'moderate',
        'promote',
        'sticky',
        'revision',
      ) as $key) {
        $node->{$key} = isset($original_node->{$key}) ? $original_node->{$key} : NULL;
      }
    }
  }
}

Functions

Namesort descending Description
clone_access_cloning
clone_form_alter Implementation of hook_form_alter().
clone_help Implementation of hook_help().
clone_init Implementation of hook_init().
clone_is_permitted
clone_menu Implementation of hook_menu().
clone_nodeapi Implementation of hook_nodeapi().
clone_node_type Implementation of hook_mode_type().
clone_perm Implementation of hook_perm().
clone_views_api Implementation of hook_views_api.