function duplicateDocument($docid, $parent = null, $_toplevel = 0)
{
    global $modx;
    $myChildren = array();
    $userID = $modx->getLoginUserID();
    $tblsc = $modx->getFullTableName('site_content');
    // Grab the original document
    $rs = $modx->db->select('*', $tblsc, 'id=' . $docid);
    $content = $modx->db->getRow($rs);
    unset($content['id']);
    // remove the current id.
    // Once we've grabbed the document object, start doing some modifications
    if ($_toplevel == 0) {
        $content['pagetitle'] = 'Duplicate of ' . $content['pagetitle'];
        $content['alias'] = null;
    }
    // change the parent accordingly
    if ($parent !== null) {
        $content['parent'] = $parent;
    }
    // Change the author
    $content['createdby'] = $userID;
    $content['createdon'] = time();
    // Remove other modification times
    $content['editedby'] = $content['editedon'] = $content['deleted'] = $content['deletedby'] = $content['deletedon'] = 0;
    // [FS#922] Should the published status be honored? - sirlancelot
    //	if ($modx->hasPermission('publish_document')) {
    //		if ($modx->config['publish_default'])
    //			$content['pub_date'] = $content['pub_date']; // should this be changed to 1?
    //		else	$content['pub_date'] = 0;
    //	} else {
    // User can't publish documents
    //		$content['published'] = $content['pub_date'] = 0;
    //	}
    // Set the published status to unpublished by default (see above ... commit #3388)
    $content['published'] = $content['pub_date'] = 0;
    // Escape the proper strings
    $content['pagetitle'] = $modx->db->escape($content['pagetitle']);
    $content['longtitle'] = $modx->db->escape($content['longtitle']);
    $content['description'] = $modx->db->escape($content['description']);
    $content['introtext'] = $modx->db->escape($content['introtext']);
    $content['content'] = $modx->db->escape($content['content']);
    $content['menutitle'] = $modx->db->escape($content['menutitle']);
    // Duplicate the Document
    $newparent = $modx->db->insert($content, $tblsc);
    // duplicate document's TVs & Keywords
    duplicateKeywords($docid, $newparent);
    duplicateTVs($docid, $newparent);
    duplicateAccess($docid, $newparent);
    // Start duplicating all the child documents that aren't deleted.
    $_toplevel++;
    $rs = $modx->db->select('id', $tblsc, 'parent=' . $docid . ' AND deleted=0', 'id ASC');
    if (mysql_num_rows($rs)) {
        while ($row = mysql_fetch_assoc($rs)) {
            duplicateDocument($row['id'], $newparent, $_toplevel);
        }
    }
    // return the new doc id
    return $newparent;
}
function duplicateDocument($docid, $parent = null, $_toplevel = 0)
{
    global $modx;
    // invoke OnBeforeDocDuplicate event
    $evtOut = $modx->invokeEvent('OnBeforeDocDuplicate', array('id' => $docid));
    // if( !in_array( 'false', array_values( $evtOut ) ) ){}
    // TODO: Determine necessary handling for duplicateDocument "return $newparent" if OnBeforeDocDuplicate were able to conditially control duplication
    // [DISABLED]: Proceed with duplicateDocument if OnBeforeDocDuplicate did not return false via: $event->output('false');
    $userID = $modx->getLoginUserID();
    $tblsc = $modx->getFullTableName('site_content');
    // Grab the original document
    $rs = $modx->db->select('*', $tblsc, "id='{$docid}'");
    $content = $modx->db->getRow($rs);
    unset($content['id']);
    // remove the current id.
    // Once we've grabbed the document object, start doing some modifications
    if ($_toplevel == 0) {
        $content['pagetitle'] = 'Duplicate of ' . $content['pagetitle'];
        $content['alias'] = null;
    } elseif ($modx->config['friendly_urls'] == 0 || $modx->config['allow_duplicate_alias'] == 0) {
        $content['alias'] = null;
    }
    // change the parent accordingly
    if ($parent !== null) {
        $content['parent'] = $parent;
    }
    // Change the author
    $content['createdby'] = $userID;
    $content['createdon'] = time();
    // Remove other modification times
    $content['editedby'] = $content['editedon'] = $content['deleted'] = $content['deletedby'] = $content['deletedon'] = 0;
    // [FS#922] Should the published status be honored? - sirlancelot
    //	if ($modx->hasPermission('publish_document')) {
    //		if ($modx->config['publish_default'])
    //			$content['pub_date'] = $content['pub_date']; // should this be changed to 1?
    //		else	$content['pub_date'] = 0;
    //	} else {
    // User can't publish documents
    //		$content['published'] = $content['pub_date'] = 0;
    //	}
    // Set the published status to unpublished by default (see above ... commit #3388)
    $content['published'] = $content['pub_date'] = 0;
    // Escape the proper strings
    $content = $modx->db->escape($content);
    // Duplicate the Document
    $newparent = $modx->db->insert($content, $tblsc);
    // duplicate document's TVs & Keywords
    duplicateKeywords($docid, $newparent);
    duplicateTVs($docid, $newparent);
    duplicateAccess($docid, $newparent);
    // invoke OnDocDuplicate event
    $evtOut = $modx->invokeEvent('OnDocDuplicate', array('id' => $docid, 'new_id' => $newparent));
    // Start duplicating all the child documents that aren't deleted.
    $_toplevel++;
    $rs = $modx->db->select('id', $tblsc, "parent='{$docid}' AND deleted=0", 'id ASC');
    while ($row = $modx->db->getRow($rs)) {
        duplicateDocument($row['id'], $newparent, $_toplevel);
    }
    // return the new doc id
    return $newparent;
}
function duplicateDocument($docid, $parent = null, $_toplevel = 0, $reset_alias = true)
{
    global $modx, $_lang;
    // invoke OnBeforeDocDuplicate event
    $evtOut = $modx->invokeEvent('OnBeforeDocDuplicate', array('id' => $docid));
    // if( !in_array( 'false', array_values( $evtOut ) ) ){}
    // TODO: Determine necessary handling for duplicateDocument "return $newparent" if OnBeforeDocDuplicate were able to conditially control duplication
    // [DISABLED]: Proceed with duplicateDocument if OnBeforeDocDuplicate did not return false via: $event->output('false');
    $myChildren = array();
    $userID = $modx->getLoginUserID();
    // Grab the original document
    $rs = $modx->db->select('*', '[+prefix+]site_content', "id='{$docid}'");
    $content = $modx->db->getRow($rs);
    $content['id'] = set_new_id();
    // Once we've grabbed the document object, start doing some modifications
    if ($_toplevel == 0 && $reset_alias === true) {
        $content['pagetitle'] = str_replace('[+title+]', $content['pagetitle'], $_lang['duplicate_title_string']);
        $content['alias'] = null;
    } elseif (($modx->config['friendly_urls'] == 0 || $modx->config['allow_duplicate_alias'] == 0) && $reset_alias === true) {
        $content['alias'] = null;
    }
    // change the parent accordingly
    if ($parent !== null) {
        $content['parent'] = $parent;
    }
    // Change the author
    $content['createdby'] = $userID;
    $content['createdon'] = time();
    // Remove other modification times
    $content['editedby'] = 0;
    $content['editedon'] = 0;
    $content['deleted'] = 0;
    $content['deletedby'] = 0;
    $content['deletedon'] = 0;
    // Set the published status to unpublished by default (see above ... commit #3388)
    $content['published'] = 0;
    $content['pub_date'] = 0;
    $content['unpub_date'] = 0;
    $content['publishedon'] = 0;
    // Escape the proper strings
    $content['pagetitle'] = $modx->db->escape($content['pagetitle']);
    $content['longtitle'] = $modx->db->escape($content['longtitle']);
    $content['description'] = $modx->db->escape($content['description']);
    $content['introtext'] = $modx->db->escape($content['introtext']);
    $content['content'] = $modx->db->escape($content['content']);
    $content['menutitle'] = $modx->db->escape($content['menutitle']);
    // increase menu index
    if ($_toplevel == 0 && $modx->config['auto_menuindex'] === '1') {
        $pid = $content['parent'];
        $pid = intval($content['parent']);
        $content['menuindex'] = $modx->db->getValue($modx->db->select('max(menuindex)', '[+prefix+]site_content', "parent='{$pid}'")) + 1;
    }
    // Duplicate the Document
    $new_id = $modx->db->insert($content, '[+prefix+]site_content');
    // duplicate document's TVs & Keywords
    duplicateKeywords($docid, $new_id);
    duplicateTVs($docid, $new_id);
    duplicateAccess($docid, $new_id);
    // invoke OnDocDuplicate event
    $evtOut = $modx->invokeEvent('OnDocDuplicate', array('id' => $docid, 'new_id' => $new_id));
    // Start duplicating all the child documents that aren't deleted.
    $rs = $modx->db->select('id', '[+prefix+]site_content', "parent='{$docid}' AND deleted=0", 'id ASC');
    if ($modx->db->getRecordCount($rs)) {
        $_toplevel++;
        while ($row = $modx->db->getRow($rs)) {
            duplicateDocument($row['id'], $new_id, $_toplevel, $reset_alias === false);
        }
    }
    // return the new doc id
    return $new_id;
}