undo_change($cid, 0); } } write_changes(); $manual_save = false; echo '<b>', $pgv_lang['undo_successful'], '</b>'; break; case 'acceptall': //-- only save the file and changes once $manual_save = true; foreach ($pgv_changes as $cid => $changes) { if ($changes[0]['gedcom'] == $ged) { accept_changes($cid); } } write_changes(); $manual_save = false; if ($SYNC_GEDCOM_FILE) { write_file(); } echo '<b>', $pgv_lang['accept_successful'], '</b>'; break; } if (empty($pgv_changes)) { echo '<br /><br /><b>', $pgv_lang['no_changes'], '</b>'; } else { $output = '<br /><br /><table class="list_table"><tr><td class="list_value ' . $TEXT_DIRECTION . '">'; $changedgedcoms = array(); foreach ($pgv_changes as $cid => $changes) { foreach ($changes as $i => $change) { if ($i == 0) {
/** * Undo a change * this function will undo a change in the gedcom file * @param string $cid the change id of the form gid_gedcom * @param int $index the index of the change to undo * @return boolean true if undo successful */ function undo_change($cid, $index) { global $fcontents, $pgv_changes, $GEDCOM, $manual_save; if (isset($pgv_changes[$cid])) { $changes = $pgv_changes[$cid]; $change = $changes[$index]; if ($GEDCOM != $change["gedcom"]) { $GEDCOM = $change["gedcom"]; } if ($index == 0) { unset($pgv_changes[$cid]); } else { for ($i = $index; $i < count($pgv_changes[$cid]); $i++) { unset($pgv_changes[$cid][$i]); } if (count($pgv_changes[$cid]) == 0) { unset($pgv_changes[$cid]); } } AddToChangeLog("Undoing change {$cid} - {$index} " . $change["type"] . " ->" . PGV_USER_NAME . "<-"); if (!isset($manual_save) || $manual_save == false) { write_changes(); } return true; } return false; }
/** * Print Review Changes Block * * Prints a block allowing the user review all changes pending approval */ function review_changes_block($block = true, $config = "", $side, $index) { global $pgv_lang, $ctype, $QUERY_STRING, $factarray, $PGV_IMAGE_DIR, $PGV_IMAGES; global $pgv_changes, $TEXT_DIRECTION, $SHOW_SOURCES, $PGV_BLOCKS; global $PHPGEDVIEW_EMAIL; if (empty($config)) { $config = $PGV_BLOCKS["review_changes_block"]["config"]; } if ($pgv_changes) { //-- if the time difference from the last email is greater than 24 hours then send out another email $LAST_CHANGE_EMAIL = get_site_setting('LAST_CHANGE_EMAIL'); if (time() - $LAST_CHANGE_EMAIL > 60 * 60 * 24 * $config["days"]) { $LAST_CHANGE_EMAIL = time(); set_site_setting('LAST_CHANGE_EMAIL', $LAST_CHANGE_EMAIL); write_changes(); if ($config["sendmail"] == "yes") { // Which users have pending changes? $users_with_changes = array(); foreach (get_all_users() as $user_id => $user_name) { foreach (get_all_gedcoms() as $ged_id => $ged_name) { if (exists_pending_change($user_id, $ged_id)) { $users_with_changes[$user_id] = $user_name; break; } } } foreach ($users_with_changes as $user_id => $user_name) { //-- send message $message = array(); $message["to"] = $user_name; $message["from"] = $PHPGEDVIEW_EMAIL; $message["subject"] = $pgv_lang["review_changes_subject"]; $message["body"] = $pgv_lang["review_changes_body"]; $message["method"] = get_user_setting($user_id, 'contactmethod'); $message["url"] = PGV_SCRIPT_NAME . "?" . html_entity_decode($QUERY_STRING); $message["no_from"] = true; addMessage($message); } } } if (PGV_USER_CAN_EDIT) { $id = "review_changes_block"; $title = print_help_link("review_changes_help", "qm", "", false, true); if ($PGV_BLOCKS["review_changes_block"]["canconfig"]) { if ($ctype == "gedcom" && PGV_USER_GEDCOM_ADMIN || $ctype == "user" && PGV_USER_ID) { if ($ctype == "gedcom") { $name = PGV_GEDCOM; } else { $name = PGV_USER_NAME; } $title .= "<a href=\"javascript: configure block\" onclick=\"window.open('" . encode_url("index_edit.php?name={$name}&ctype={$ctype}&action=configure&side={$side}&index={$index}") . "', '_blank', 'top=50,left=50,width=600,height=350,scrollbars=1,resizable=1'); return false;\">"; $title .= "<img class=\"adminicon\" src=\"{$PGV_IMAGE_DIR}/" . $PGV_IMAGES["admin"]["small"] . "\" width=\"15\" height=\"15\" border=\"0\" alt=\"" . $pgv_lang["config_block"] . "\" /></a>"; } } $title .= $pgv_lang["review_changes"]; $content = ""; if (PGV_USER_CAN_ACCEPT) { $content .= "<a href=\"javascript:;\" onclick=\"window.open('edit_changes.php','_blank','width=600,height=500,resizable=1,scrollbars=1'); return false;\">" . $pgv_lang["accept_changes"] . "</a><br />"; } if ($config["sendmail"] == "yes") { $content .= $pgv_lang["last_email_sent"] . format_timestamp($LAST_CHANGE_EMAIL) . "<br />"; $content .= $pgv_lang["next_email_sent"] . format_timestamp($LAST_CHANGE_EMAIL + 60 * 60 * 24 * $config["days"]) . "<br /><br />"; } foreach ($pgv_changes as $cid => $changes) { $change = $changes[count($changes) - 1]; if ($change["gedcom"] == PGV_GEDCOM) { $record = GedcomRecord::getInstance($change['gid']); if ($record->getType() != 'SOUR' || $SHOW_SOURCES >= PGV_USER_ACCESS_LEVEL) { $content .= '<b>' . PrintReady($record->getFullName()) . '</b> ' . getLRM() . '(' . $record->getXref() . ')' . getLRM(); switch ($record->getType()) { case 'INDI': case 'FAM': case 'SOUR': case 'OBJE': $content .= $block ? '<br />' : ' '; $content .= '<a href="' . encode_url($record->getLinkUrl() . '&show_changes=yes') . '">' . $pgv_lang['view_change_diff'] . '</a>'; break; } $content .= '<br />'; } } } global $THEME_DIR; if ($block) { require $THEME_DIR . 'templates/block_small_temp.php'; } else { require $THEME_DIR . 'templates/block_main_temp.php'; } } } }
/** * Preforms a search and replace */ function SearchAndReplace() { global $GEDCOM, $pgv_changes, $manual_save, $STANDARD_NAME_FACTS, $ADVANCED_NAME_FACTS; $this->sgeds = array($GEDCOM); $this->srindi = "yes"; $this->srfams = "yes"; $this->srsour = "yes"; $this->srnote = "yes"; $oldquery = $this->query; $this->GeneralSearch(); //-- don't try to make any changes if nothing was found if (!$this->myindilist && !$this->myfamlist && !$this->mysourcelist && !$this->mynotelist) { return; } AddToLog("Search And Replace old:" . $oldquery . " new:" . $this->replace); $manual_save = true; // Include edit functions. include_once "includes/functions/functions_edit.php"; // These contain the search query and the replace string // $this->replace; // $this->query; // These contain the search results // We need to iterate through them and do the replaces //$this->myindilist; $adv_name_tags = preg_split("/[\\s,;: ]+/", $ADVANCED_NAME_FACTS); $name_tags = array_unique(array_merge($STANDARD_NAME_FACTS, $adv_name_tags)); $name_tags[] = "_MARNM"; foreach ($this->myindilist as $id => $individual) { if (isset($pgv_changes[$individual->getXref() . '_' . $GEDCOM])) { $indirec = find_updated_record($individual->getXref()); } else { $indirec = $individual->getGedcomRecord(); } $oldRecord = $indirec; $newRecord = $indirec; if ($this->replaceAll) { $newRecord = preg_replace("~" . $oldquery . "~i", $this->replace, $newRecord); } else { if ($this->replaceNames) { foreach ($name_tags as $f => $tag) { $newRecord = preg_replace("~(\\d) " . $tag . " (.*)" . $oldquery . "(.*)~i", "\$1 " . $tag . " \$2" . $this->replace . "\$3", $newRecord); } } if ($this->replacePlaces) { if ($this->replacePlacesWord) { $newRecord = preg_replace("~(\\d) PLAC (.*)([,\\W\\s])" . $oldquery . "([,\\W\\s])~i", "\$1 PLAC \$2\$3" . $this->replace . "\$4", $newRecord); } else { $newRecord = preg_replace("~(\\d) PLAC (.*)" . $oldquery . "(.*)~i", "\$1 PLAC \$2" . $this->replace . "\$3", $newRecord); } } } //-- if the record changed replace the record otherwise remove it from the search results if ($newRecord != $oldRecord) { replace_gedrec($individual->getXref(), $newRecord); } else { unset($this->myindilist[$id]); } } foreach ($this->myfamlist as $id => $family) { if (isset($pgv_changes[$family->getXref() . '_' . $GEDCOM])) { $indirec = find_updated_record($family->getXref()); } else { $indirec = $family->getGedcomRecord(); } $oldRecord = $indirec; $newRecord = $indirec; if ($this->replaceAll) { $newRecord = preg_replace("~" . $oldquery . "~i", $this->replace, $newRecord); } else { if ($this->replacePlaces) { if ($this->replacePlacesWord) { $newRecord = preg_replace("~(\\d) PLAC (.*)([,\\W\\s])" . $oldquery . "([,\\W\\s])~i", "\$1 PLAC \$2\$3" . $this->replace . "\$4", $newRecord); } else { $newRecord = preg_replace("~(\\d) PLAC (.*)" . $oldquery . "(.*)~i", "\$1 PLAC \$2" . $this->replace . "\$3", $newRecord); } } } //-- if the record changed replace the record otherwise remove it from the search results if ($newRecord != $oldRecord) { replace_gedrec($family->getXref(), $newRecord); } else { unset($this->myfamlist[$id]); } } foreach ($this->mysourcelist as $id => $source) { if (isset($pgv_changes[$source->getXref() . '_' . $GEDCOM])) { $indirec = find_updated_record($source->getXref()); } else { $indirec = $source->getGedcomRecord(); } $oldRecord = $indirec; $newRecord = $indirec; if ($this->replaceAll) { $newRecord = preg_replace("~" . $oldquery . "~i", $this->replace, $newRecord); } else { if ($this->replaceNames) { $newRecord = preg_replace("~(\\d) TITL (.*)" . $oldquery . "(.*)~i", "\$1 TITL \$2" . $this->replace . "\$3", $newRecord); $newRecord = preg_replace("~(\\d) ABBR (.*)" . $oldquery . "(.*)~i", "\$1 ABBR \$2" . $this->replace . "\$3", $newRecord); } if ($this->replacePlaces) { if ($this->replacePlacesWord) { $newRecord = preg_replace("~(\\d) PLAC (.*)([,\\W\\s])" . $oldquery . "([,\\W\\s])~i", "\$1 PLAC \$2\$3" . $this->replace . "\$4", $newRecord); } else { $newRecord = preg_replace("~(\\d) PLAC (.*)" . $oldquery . "(.*)~i", "\$1 PLAC \$2" . $this->replace . "\$3", $newRecord); } } } //-- if the record changed replace the record otherwise remove it from the search results if ($newRecord != $oldRecord) { replace_gedrec($source->getXref(), $newRecord); } else { unset($this->mysourcelist[$id]); } } foreach ($this->mynotelist as $id => $note) { if (isset($pgv_changes[$note->getXref() . '_' . $GEDCOM])) { $indirec = find_updated_record($note->getXref()); } else { $indirec = $note->getGedcomRecord(); } $oldRecord = $indirec; $newRecord = $indirec; if ($this->replaceAll) { $newRecord = preg_replace("~" . $oldquery . "~i", $this->replace, $newRecord); } //-- if the record changed replace the record otherwise remove it from the search results if ($newRecord != $oldRecord) { replace_gedrec($note->getXref(), $newRecord); } else { unset($this->mynotelist[$id]); } } write_changes(); }
/** * Accpet changed gedcom record into database * * This function gets an updated record from the gedcom file and replaces it in the database * @author John Finlay * @param string $cid The change id of the record to accept */ function accept_changes($cid) { global $pgv_changes, $GEDCOM, $TBLPREFIX, $FILE, $GEDCOMS; global $INDEX_DIRECTORY, $SYNC_GEDCOM_FILE, $fcontents, $manual_save; if (isset($pgv_changes[$cid])) { $changes = $pgv_changes[$cid]; $change = $changes[count($changes) - 1]; if ($GEDCOM != $change["gedcom"]) { $GEDCOM = $change["gedcom"]; } $FILE = $GEDCOM; $gid = $change["gid"]; $gedrec = $change["undo"]; if (empty($gedrec)) { $gedrec = find_gedcom_record($gid); } update_record($gedrec, $change["type"] == "delete"); //-- write the changes back to the gedcom file if ($SYNC_GEDCOM_FILE) { // TODO: We merge CONC lines on import, so need to add them back on export if (!isset($manual_save) || $manual_save == false) { //-- only allow one thread to accept changes at a time // $mutex = new Mutex("accept_changes"); // $mutex->Wait(); } if (empty($fcontents)) { read_gedcom_file(); } if ($change["type"] == "delete") { $pos1 = find_newline_string($fcontents, "0 @{$gid}@"); if ($pos1 !== false) { $pos2 = find_newline_string($fcontents, "0", $pos1 + 5); if ($pos2 === false) { $fcontents = substr($fcontents, 0, $pos1) . '0 TRLR' . PGV_EOL; AddToLog("Corruption found in GEDCOM {$GEDCOM} Attempted to correct"); } else { $fcontents = substr($fcontents, 0, $pos1) . substr($fcontents, $pos2); } } else { AddToLog("Corruption found in GEDCOM {$GEDCOM} Attempted to correct. Deleted gedcom record {$gid} was not found in the gedcom file."); } } elseif ($change["type"] == "append") { $pos1 = find_newline_string($fcontents, "0 TRLR"); $fcontents = substr($fcontents, 0, $pos1) . reformat_record_export($gedrec) . '0 TRLR' . PGV_EOL; } elseif ($change["type"] == "replace") { $pos1 = find_newline_string($fcontents, "0 @{$gid}@"); if ($pos1 !== false) { $pos2 = find_newline_string($fcontents, "0", $pos1 + 5); if ($pos2 === false) { $fcontents = substr($fcontents, 0, $pos1) . '0 TRLR' . PGV_EOL; AddToLog("Corruption found in GEDCOM {$GEDCOM} Attempted to correct"); } else { $fcontents = substr($fcontents, 0, $pos1) . reformat_record_export($gedrec) . substr($fcontents, $pos2); } } else { //-- attempted to replace a record that doesn't exist AddToLog("Corruption found in GEDCOM {$GEDCOM} Attempted to correct. Replaced gedcom record {$gid} was not found in the gedcom file."); $pos1 = find_newline_string($fcontents, "0 TRLR"); $fcontents = substr($fcontents, 0, $pos1) . reformat_record_export($gedrec) . '0 TRLR' . PGV_EOL; AddToLog("Gedcom record {$gid} was appended back to the GEDCOM file."); } } if (!isset($manual_save) || $manual_save == false) { write_file(); // $mutex->Release(); } } if ($change["type"] != "delete") { //-- synchronize the gedcom record with any user account $username = get_user_from_gedcom_xref($GEDCOM, $gid); if ($username && get_user_setting($username, 'sync_gedcom') == 'Y') { $firstname = get_gedcom_value("GIVN", 2, $gedrec); $lastname = get_gedcom_value("SURN", 2, $gedrec); if (empty($lastname)) { $fullname = get_gedcom_value("NAME", 1, $gedrec, "", false); $ct = preg_match("~(.*)/(.*)/~", $fullname, $match); if ($ct > 0) { $firstname = $match[1]; $lastname = $match[2]; } else { $firstname = $fullname; } } //-- SEE [ 1753047 ] Email/sync with account $email = get_gedcom_value("EMAIL", 1, $gedrec); if (empty($email)) { $email = get_gedcom_value("_EMAIL", 1, $gedrec); } if (!empty($email)) { set_user_setting($username, 'email', $email); } set_user_setting($username, 'firstname', $firstname); set_user_setting($username, 'lastname', $lastname); } } unset($pgv_changes[$cid]); if (!isset($manual_save) || $manual_save == false) { write_changes(); } $logline = AddToLog("Accepted change {$cid} " . $change["type"] . " into database"); check_in($logline, $GEDCOM, dirname($GEDCOMS[$GEDCOM]['path'])); if (isset($change["linkpid"])) { accept_changes($change["linkpid"] . "_" . $GEDCOM); } return true; } return false; }
/** * Delete a gedcom from the database and the system * Does not delete the file from the file system * @param string $ged the filename of the gedcom to delete */ function delete_gedcom($ged) { global $TBLPREFIX, $pgv_changes, $GEDCOMS, $gBitDb; if (!isset($GEDCOMS[$ged])) { return; } $ged_id = get_id_from_gedcom($ged); $gBitDb->query("DELETE FROM {$TBLPREFIX}blocks WHERE b_username=?", array($ged)); $gBitDb->query("DELETE FROM {$TBLPREFIX}dates WHERE d_file =?", array($ged_id)); $gBitDb->query("DELETE FROM {$TBLPREFIX}families WHERE f_file =?", array($ged_id)); $gBitDb->query("DELETE FROM {$TBLPREFIX}favorites WHERE fv_file =?", array($ged_id)); $gBitDb->query("DELETE FROM {$TBLPREFIX}individuals WHERE i_file =?", array($ged_id)); $gBitDb->query("DELETE FROM {$TBLPREFIX}link WHERE l_file =?", array($ged_id)); $gBitDb->query("DELETE FROM {$TBLPREFIX}media WHERE m_gedfile =?", array($ged_id)); $gBitDb->query("DELETE FROM {$TBLPREFIX}media_mapping WHERE mm_gedfile=?", array($ged_id)); $gBitDb->query("DELETE FROM {$TBLPREFIX}name WHERE n_file =?", array($ged_id)); $gBitDb->query("DELETE FROM {$TBLPREFIX}news WHERE n_username=?", array($ged)); $gBitDb->query("DELETE FROM {$TBLPREFIX}nextid WHERE ni_gedfile=?", array($ged_id)); $gBitDb->query("DELETE FROM {$TBLPREFIX}other WHERE o_file =?", array($ged_id)); $gBitDb->query("DELETE FROM {$TBLPREFIX}placelinks WHERE pl_file =?", array($ged_id)); $gBitDb->query("DELETE FROM {$TBLPREFIX}places WHERE p_file =?", array($ged_id)); $gBitDb->query("DELETE FROM {$TBLPREFIX}sources WHERE s_file =?", array($ged_id)); if (isset($pgv_changes)) { //-- erase any of the changes foreach ($pgv_changes as $cid => $changes) { if ($changes[0]["gedcom"] == $ged) { unset($pgv_changes[$cid]); } } write_changes(); } unset($GEDCOMS[$ged]); store_gedcoms(); if (get_site_setting('DEFAULT_GEDCOM') == $ged) { set_site_setting('DEFAULT_GEDCOM', ''); } }