'. 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.') .'

'; $output .= '

'. t('Users with the "clone node" permission can utilize this functionality. A new tab will appear on node pages with the word "Clone".') .'

'; 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_permission(). */ function clone_permission() { return array( 'clone node' => array('title' => t('Clone any node')), 'clone own nodes' => array('title' => t('Clone own nodes.')), ); } /** * Implementation of hook_menu(). */ function clone_menu() { $items['admin/config/content/clone'] = array( 'access arguments' => array('administer site configuration'), 'page callback' => 'drupal_get_form', 'page arguments' => array('clone_settings'), 'title' => 'Node 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 content', 'weight' => 5, 'file' => 'clone.pages.inc', 'type' => MENU_LOCAL_ACTION, ); 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'))); // Make sure the user can view the original node content, and create a new one.. $access = $access && node_access('view', $node) && node_access('create', $node->type); // Let other modules alter this - for exmple to only allow some users // to clone specific nodes or types. 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() { //TODO return; return array( 'api' => 2, 'path' => drupal_get_path('module', 'clone') .'/views', ); } /** * Implementation of hook_admin_paths(). */ function clone_admin_paths() { if (variable_get('node_admin_theme')) { $paths = array( 'node/*/clone' => TRUE, ); return $paths; } }