'Clone a project', 'page callback' => 'stormproject_clone_run', 'page arguments' => array(2), 'access arguments' => array('Storm project: clone projects'), 'type' => MENU_CALLBACK, ); return $items; } function stormproject_clone_link($type, $node = NULL, $teaser = FALSE) { $links = array(); if (!empty($node) && $node->type == 'stormproject' && isset($node->book) && !$teaser && user_access('Storm project: clone projects')) { $links['stormproject_clone_run'] = array( 'title' => t('Clone entire project'), 'href' => 'project/clonex/' . $node->book['bid'], ); } return $links; } /** * This function is responsible for cloning an entire project. * This will also maintain book hierarchy in the new project. */ function stormproject_clone_run($project) { $newbid = 0; if (!isset($project->book)) { return; } $bid = $project->book['bid']; $project = node_load(array('nid' => $bid)); if ($project->type != 'stormproject') { return; } module_load_include('inc', 'clone', 'clone.pages'); $result = db_query("SELECT ml.menu_name, ml.mlid, ml.plid, ml.link_path, ml.router_path, ml.link_title, ml.module, b.nid FROM {menu_links} ml LEFT JOIN {book} b ON b.mlid = ml.mlid WHERE b.bid = %d ORDER BY ml.depth", array($bid)); if (!$result) { return; } $nidmap = array(); $mlidmap = array(); $tasksmap = array(); while ($row = db_fetch_array($result)) { $plid = $row['plid']; $mlid = $row['mlid']; // Copy each node keeping reference to new nid via old nid. // clone_node_save() returns the nid of the new node: $nidmap[$row['nid']] = clone_node_save($row['nid']); $node = node_load(array('nid' => $nidmap[$row['nid']])); $mlidmap[$mlid] = $node->book['mlid']; if ($newbid == 0) { // Project cloned: $newbid = $nidmap[$row['nid']]; // Cloning tasks: $taskstree = _stormtask_get_tree($row['nid']); foreach ($taskstree as $task) { $tasksmap[$task->nid] = clone_node_save($task->nid); $tasknode = node_load(array('nid' => $tasksmap[$task->nid])); $tasknode->project_nid = $node->nid; $tasknode->project_title = $node->title; $tasknode->parent_nid = empty($tasksmap[$tasknode->parent_nid]) ? 0 : $tasksmap[$tasknode->parent_nid]; node_save($tasknode); } # } else { // Document cloned: } if ($node->nid != $newbid) { $node->book['bid'] = $newbid; node_save($node); } // Fix lower level nested links: if (isset($mlidmap[$plid])) { $node->book['plid'] = $mlidmap[$plid]; menu_link_save($node->book); } } // Viewing new project: drupal_set_message(t('Successfully cloned "%message", now viewing copy.', array('%message' => $project->title))); drupal_goto("node/$newbid"); } /** * Implements hook_clone_node_alter(). */ function stormproject_clone_clone_node_alter(&$node, $original_node, $method) { if ($method == 'save-edit') { // Remove "Clone of" text: $node->title = str_replace(t('Clone of') . ' ', '', $node->title); if (isset($node->book)) { if ($node->book['plid'] == 0) { unset($node->book['nid']); $node->book['bid'] = 'new'; } } } }