/** * Performs a search and replace * * @param Tree $tree */ private function searchAndReplace(Tree $tree) { $this->generalSearch(); //-- don't try to make any changes if nothing was found if (!$this->myindilist && !$this->myfamlist && !$this->mysourcelist && !$this->mynotelist) { return; } Log::addEditLog("Search And Replace old:" . $this->query . " new:" . $this->replace); $adv_name_tags = preg_split("/[\\s,;: ]+/", $tree->getPreference('ADVANCED_NAME_FACTS')); $name_tags = array_unique(array_merge(Config::standardNameFacts(), $adv_name_tags)); $name_tags[] = '_MARNM'; $records_updated = 0; foreach ($this->myindilist as $id => $record) { $old_record = $record->getGedcom(); $new_record = $old_record; if ($this->replaceAll) { $new_record = preg_replace("~" . $this->query . "~i", $this->replace, $new_record); } else { if ($this->replaceNames) { foreach ($name_tags as $tag) { $new_record = preg_replace("~(\\d) " . $tag . " (.*)" . $this->query . "(.*)~i", "\$1 " . $tag . " \$2" . $this->replace . "\$3", $new_record); } } if ($this->replacePlaces) { if ($this->replacePlacesWord) { $new_record = preg_replace('~(\\d) PLAC (.*)([,\\W\\s])' . $this->query . '([,\\W\\s])~i', "\$1 PLAC \$2\$3" . $this->replace . "\$4", $new_record); } else { $new_record = preg_replace("~(\\d) PLAC (.*)" . $this->query . "(.*)~i", "\$1 PLAC \$2" . $this->replace . "\$3", $new_record); } } } //-- if the record changed replace the record otherwise remove it from the search results if ($new_record !== $old_record) { $record->updateRecord($new_record, true); $records_updated++; } else { unset($this->myindilist[$id]); } } if ($records_updated) { FlashMessages::addMessage(I18N::plural('%s individual has been updated.', '%s individuals have been updated.', $records_updated, I18N::number($records_updated))); } $records_updated = 0; foreach ($this->myfamlist as $id => $record) { $old_record = $record->getGedcom(); $new_record = $old_record; if ($this->replaceAll) { $new_record = preg_replace("~" . $this->query . "~i", $this->replace, $new_record); } else { if ($this->replacePlaces) { if ($this->replacePlacesWord) { $new_record = preg_replace('~(\\d) PLAC (.*)([,\\W\\s])' . $this->query . '([,\\W\\s])~i', "\$1 PLAC \$2\$3" . $this->replace . "\$4", $new_record); } else { $new_record = preg_replace("~(\\d) PLAC (.*)" . $this->query . "(.*)~i", "\$1 PLAC \$2" . $this->replace . "\$3", $new_record); } } } //-- if the record changed replace the record otherwise remove it from the search results if ($new_record !== $old_record) { $record->updateRecord($new_record, true); $records_updated++; } else { unset($this->myfamlist[$id]); } } if ($records_updated) { FlashMessages::addMessage(I18N::plural('%s family has been updated.', '%s families have been updated.', $records_updated, I18N::number($records_updated))); } $records_updated = 0; foreach ($this->mysourcelist as $id => $record) { $old_record = $record->getGedcom(); $new_record = $old_record; if ($this->replaceAll) { $new_record = preg_replace("~" . $this->query . "~i", $this->replace, $new_record); } else { if ($this->replaceNames) { $new_record = preg_replace("~(\\d) TITL (.*)" . $this->query . "(.*)~i", "\$1 TITL \$2" . $this->replace . "\$3", $new_record); $new_record = preg_replace("~(\\d) ABBR (.*)" . $this->query . "(.*)~i", "\$1 ABBR \$2" . $this->replace . "\$3", $new_record); } if ($this->replacePlaces) { if ($this->replacePlacesWord) { $new_record = preg_replace('~(\\d) PLAC (.*)([,\\W\\s])' . $this->query . '([,\\W\\s])~i', "\$1 PLAC \$2\$3" . $this->replace . "\$4", $new_record); } else { $new_record = preg_replace("~(\\d) PLAC (.*)" . $this->query . "(.*)~i", "\$1 PLAC \$2" . $this->replace . "\$3", $new_record); } } } //-- if the record changed replace the record otherwise remove it from the search results if ($new_record !== $old_record) { $record->updateRecord($new_record, true); $records_updated++; } else { unset($this->mysourcelist[$id]); } } if ($records_updated) { FlashMessages::addMessage(I18N::plural('%s source has been updated.', '%s sources have been updated.', $records_updated, I18N::number($records_updated))); } $records_updated = 0; foreach ($this->mynotelist as $id => $record) { $old_record = $record->getGedcom(); $new_record = $old_record; if ($this->replaceAll) { $new_record = preg_replace("~" . $this->query . "~i", $this->replace, $new_record); } //-- if the record changed replace the record otherwise remove it from the search results if ($new_record != $old_record) { $record->updateRecord($new_record, true); $records_updated++; } else { unset($this->mynotelist[$id]); } } if ($records_updated) { FlashMessages::addMessage(I18N::plural('%s note has been updated.', '%s notes have been updated.', $records_updated, I18N::number($records_updated))); } }
$tag = array_merge(array('FILE'), $tag); $islink = array_merge(array(0), $islink); $text = array_merge(array($newFilename), $text); $record = GedcomRecord::getInstance($pid, $WT_TREE); $newrec = "0 @{$pid}@ OBJE\n"; $newrec = FunctionsEdit::handleUpdates($newrec); $record->updateRecord($newrec, $update_CHAN); if ($move_file) { // We've moved a file. Therefore we must approve the change, as rejecting // the change will create broken references. FunctionsImport::acceptAllChanges($record->getXref(), $record->getTree()->getTreeId()); } if ($pid && $linktoid) { $record = GedcomRecord::getInstance($linktoid, $WT_TREE); $record->createFact('1 OBJE @' . $pid . '@', true); Log::addEditLog('Media ID ' . $pid . " successfully added to {$linktoid}."); } $controller->pageHeader(); if ($messages) { echo '<button onclick="closePopupAndReloadParent();">', I18N::translate('close'), '</button>'; } else { $controller->addInlineJavascript('closePopupAndReloadParent();'); } return; case 'showmediaform': $controller->setPageTitle(I18N::translate('Create a new media object')); $action = 'create'; break; case 'editmedia': $controller->setPageTitle(I18N::translate('Edit media object')); $action = 'update';
/** * Create a new record from GEDCOM data. * * @param string $gedcom * * @throws \Exception * * @return GedcomRecord */ public function createRecord($gedcom) { if (preg_match('/^0 @(' . WT_REGEX_XREF . ')@ (' . WT_REGEX_TAG . ')/', $gedcom, $match)) { $xref = $match[1]; $type = $match[2]; } else { throw new \Exception('Invalid argument to GedcomRecord::createRecord(' . $gedcom . ')'); } if (strpos("\r", $gedcom) !== false) { // MSDOS line endings will break things in horrible ways throw new \Exception('Evil line endings found in GedcomRecord::createRecord(' . $gedcom . ')'); } // webtrees creates XREFs containing digits. Anything else (e.g. “new”) is just a placeholder. if (!preg_match('/\\d/', $xref)) { $xref = $this->getNewXref($type); $gedcom = preg_replace('/^0 @(' . WT_REGEX_XREF . ')@/', '0 @' . $xref . '@', $gedcom); } // Create a change record, if not already present if (!preg_match('/\\n1 CHAN/', $gedcom)) { $gedcom .= "\n1 CHAN\n2 DATE " . date('d M Y') . "\n3 TIME " . date('H:i:s') . "\n2 _WT_USER " . Auth::user()->getUserName(); } // Create a pending change Database::prepare("INSERT INTO `##change` (gedcom_id, xref, old_gedcom, new_gedcom, user_id) VALUES (?, ?, '', ?, ?)")->execute(array($this->tree_id, $xref, $gedcom, Auth::id())); Log::addEditLog('Create: ' . $type . ' ' . $xref); // Accept this pending change if (Auth::user()->getPreference('auto_accept')) { FunctionsImport::acceptAllChanges($xref, $this->tree_id); } // Return the newly created record. Note that since GedcomRecord // has a cache of pending changes, we cannot use it to create a // record with a newly created pending change. return GedcomRecord::getInstance($xref, $this, $gedcom); }
break; case 'undoall': Database::prepare("UPDATE `##change`" . " SET status='rejected'" . " WHERE status='pending' AND gedcom_id=?")->execute(array($WT_TREE->getTreeId())); break; case 'acceptall': $changes = Database::prepare("SELECT change_id, gedcom_id, gedcom_name, xref, old_gedcom, new_gedcom" . " FROM `##change` c" . " JOIN `##gedcom` g USING (gedcom_id)" . " WHERE c.status='pending' AND gedcom_id=?" . " ORDER BY change_id")->execute(array($WT_TREE->getTreeId()))->fetchAll(); foreach ($changes as $change) { if (empty($change->new_gedcom)) { // delete FunctionsImport::updateRecord($change->old_gedcom, $change->gedcom_id, true); } else { // add/update FunctionsImport::updateRecord($change->new_gedcom, $change->gedcom_id, false); } Database::prepare("UPDATE `##change` SET status='accepted' WHERE change_id=?")->execute(array($change->change_id)); Log::addEditLog("Accepted change {$change->change_id} for {$change->xref} / {$change->gedcom_name} into database"); } break; } $changed_gedcoms = Database::prepare("SELECT g.gedcom_name" . " FROM `##change` c" . " JOIN `##gedcom` g USING (gedcom_id)" . " WHERE c.status='pending'" . " GROUP BY g.gedcom_name")->fetchOneColumn(); if ($changed_gedcoms) { $changes = Database::prepare("SELECT c.*, u.user_name, u.real_name, g.gedcom_name, new_gedcom, old_gedcom" . " FROM `##change` c" . " JOIN `##user` u USING (user_id)" . " JOIN `##gedcom` g USING (gedcom_id)" . " WHERE c.status='pending'" . " ORDER BY gedcom_id, c.xref, c.change_id")->fetchAll(); $output = '<br><br><table class="list_table">'; $prev_xref = null; $prev_gedcom_id = null; foreach ($changes as $change) { $tree = Tree::findById($change->gedcom_id); preg_match('/^0 @' . WT_REGEX_XREF . '@ (' . WT_REGEX_TAG . ')/', $change->old_gedcom . $change->new_gedcom, $match); switch ($match[1]) { case 'INDI': $record = new Individual($change->xref, $change->old_gedcom, $change->new_gedcom, $tree);
/** * Delete this record */ public function deleteRecord() { // Create a pending change if (!$this->isPendingDeletion()) { Database::prepare("INSERT INTO `##change` (gedcom_id, xref, old_gedcom, new_gedcom, user_id) VALUES (?, ?, ?, '', ?)")->execute(array($this->tree->getTreeId(), $this->xref, $this->getGedcom(), Auth::id())); } // Auto-accept this pending change if (Auth::user()->getPreference('auto_accept')) { FunctionsImport::acceptAllChanges($this->xref, $this->tree->getTreeId()); } // Clear the cache self::$gedcom_record_cache = null; self::$pending_record_cache = null; Log::addEditLog('Delete: ' . static::RECORD_TYPE . ' ' . $this->xref); }
/** * Accept all pending changes for a specified record. * * @param string $xref * @param int $ged_id */ public static function acceptAllChanges($xref, $ged_id) { $changes = Database::prepare("SELECT change_id, gedcom_name, old_gedcom, new_gedcom" . " FROM `##change` c" . " JOIN `##gedcom` g USING (gedcom_id)" . " WHERE c.status='pending' AND xref=? AND gedcom_id=?" . " ORDER BY change_id")->execute(array($xref, $ged_id))->fetchAll(); foreach ($changes as $change) { if (empty($change->new_gedcom)) { // delete self::updateRecord($change->old_gedcom, $ged_id, true); } else { // add/update self::updateRecord($change->new_gedcom, $ged_id, false); } Database::prepare("UPDATE `##change`" . " SET status='accepted'" . " WHERE status='pending' AND xref=? AND gedcom_id=?")->execute(array($xref, $ged_id)); Log::addEditLog("Accepted change {$change->change_id} for {$xref} / {$change->gedcom_name} into database"); } }