/** * Run a refreshLinks job * @return boolean success */ function run() { global $wgUser, $wgTitle; $status = FTE_SUCCESS; $user = $this->params['user']; $wgUser = User::newFromName($user); $treeId = $this->params['tree_id']; $wgTitle = $this->title; // FakeTitle (the default) generates errors when accessed, and sometimes I log wgTitle, so set it to something else $dbw =& wfGetDB(DB_MASTER); $dbw->begin(); $dbw->ignoreErrors(true); $rows = $dbw->select('familytree_page', array('fp_namespace', 'fp_title'), array('fp_tree_id' => $treeId)); $errno = $dbw->lastErrno(); if ($errno > 0) { $status = FTE_DB_ERROR; } else { if ($rows !== false) { while ($row = $dbw->fetchObject($rows)) { $title = Title::makeTitle($row->fp_namespace, $row->fp_title); if ($title) { // watch article StructuredData::addWatch($wgUser, new Article($title, 0)); } } $dbw->freeResult($rows); } } if ($errno == 0) { $dbw->commit(); return true; } else { $dbw->rollback(); $this->error = "Error watching pages; db_errno={$errno}\n"; return false; } }
public function doMerge() { global $wgOut, $wgUser; $skin =& $wgUser->getSkin(); if ($this->isGedcom()) { $editFlags = EDIT_UPDATE; $mergeText = 'updated'; } else { // create a mergelog record $mergeScore = $this->getMergeScore(); $isTrustedUser = CompareForm::isTrustedMerger($wgUser, false); $isTrustedMerge = MergeForm::isTrustedMerge($mergeScore, $isTrustedUser); $mergeLogId = $this->logMerge($mergeScore, $isTrustedMerge); wfDebug("MERGESCORE mergeLogId={$mergeLogId} total score={$mergeScore}\n"); if (!$isTrustedUser && $mergeScore < self::$LOW_MATCH_THRESHOLD) { error_log("WARNING suspect merge: id={$mergeLogId} user={$wgUser->getName()} score={$mergeScore}"); } $editFlags = EDIT_UPDATE | EDIT_FORCE_BOT; $mergeText = 'merged'; } // get merging people and families // add merging people and families to blacklist so propagation doesn't also try to update them $mergingPeople = array(); $mergingFamilies = array(); for ($m = 0; $m < count($this->data); $m++) { for ($p = 0; $p < count($this->data[$m]); $p++) { $titleString = $this->data[$m][$p]['title']; if ($this->namespace == 'Family' && $m == 0) { if ($p > 0) { $mergingFamilies[$titleString] = $this->data[$m][0]['title']; } $ns = NS_FAMILY; } else { if ($p > 0) { $mergingPeople[$titleString] = $this->data[$m][0]['title']; } $ns = NS_PERSON; } if (!GedcomUtil::isGedcomTitle($titleString)) { $title = Title::newFromText($titleString, $ns); PropagationManager::addBlacklistPage($title); } } } $output = "<H2>Pages {$mergeText} successfully</H2>"; $output .= $this->getWarnings(); $output .= '<ul>'; $outputRows = array(); $emptyRequest = new FauxRequest(array(), true); $mergeCmtSuffix = $this->isGedcom() ? '' : " - [[Special:ReviewMerge/{$mergeLogId}|review/undo]]"; if ($this->namespace == 'Family' && !$this->isGedcom()) { $t = Title::newFromText($this->data[0][0]['title'], NS_FAMILY); $mergeCmtFamily = $this->namespace == 'Family' ? " in merge of [[{$t->getPrefixedText()}]]" : ''; } else { $mergeCmtFamily = ''; } // backwards, because you must merge family last, so that propagated person data in family xml is correct // and so that mergeCmtFamily can be cleared at the end and mergeSummary and mergeTargetTitle are correct after the for loop for ($m = count($this->data) - 1; $m >= 0; $m--) { $requestData = array(); $contents = ''; $talkContents = ''; $outputRow = ''; $mainOutput = ''; $talkOutput = ''; $nameCount = $eventCount = $sourceCount = $imageCount = $noteCount = $husbandCount = $wifeCount = $childrenCount = $parentFamilyCount = $spouseFamilyCount = 0; $primaryNameFound = $primaryImageFound = $birthFound = $christeningFound = $deathFound = $burialFound = $marriageFound = false; if ($this->namespace == 'Family' && $m == 0) { $mergeTargetNs = NS_FAMILY; $mergeTargetTalkNs = NS_FAMILY_TALK; $mergeCmtFamily = ''; } else { $mergeTargetNs = NS_PERSON; $mergeTargetTalkNs = NS_PERSON_TALK; } $mergeTargetTitle = Title::newFromText($this->data[$m][0]['title'], $mergeTargetNs); if ($mergeTargetTitle->getNamespace() != $mergeTargetNs) { error_log("Merge glitch:{$mergeTargetNs}:{$this->data[$m][0]['title']}:{$mergeTargetTitle->getNamespace()}:"); } $mergeTargetTalkTitle = Title::newFromText($this->data[$m][0]['title'], $mergeTargetTalkNs); $mergeSummary = ''; $talkMergeSummary = ''; $keepKeys = $this->generateKeepKeys($this->data[$m], $this->add[$m], $this->key[$m]); $notesMap = array(); $noteAdoptions = array(); $this->generateMapAdoptions('notes', 'N', $mergeTargetNs, $this->data[$m], $this->add[$m], $this->key[$m], $keepKeys, $notesMap, $noteAdoptions); $sourcesMap = array(); $sourceAdoptions = array(); $this->generateMapAdoptions('sources', 'S', $mergeTargetNs, $this->data[$m], $this->add[$m], $this->key[$m], $keepKeys, $sourcesMap, $sourceAdoptions); $imagesMap = array(); $imageAdoptions = array(); $this->generateMapAdoptions('images', 'I', $mergeTargetNs, $this->data[$m], $this->add[$m], $this->key[$m], $keepKeys, $imagesMap, $imageAdoptions); // get request data for merge target for ($p = 0; $p < count($this->data[$m]); $p++) { if ($this->isMergeable($this->data[$m][$p])) { $this->addNotesToRequestData($requestData, $keepKeys[$p], $noteCount, $notesMap[$p], $this->data[$m][$p]['notes']); $this->addImagesToRequestData($requestData, $keepKeys[$p], $imageCount, $imagesMap[$p], $primaryImageFound, $this->data[$m][$p]['images']); $this->addSourcesToRequestData($requestData, $keepKeys[$p], $sourceCount, $sourcesMap[$p], $notesMap[$p], $imagesMap[$p], $this->data[$m][$p]['sources'], $noteAdoptions, $imageAdoptions); $this->addEventsToRequestData($requestData, $keepKeys[$p], $eventCount, $mergeTargetNs == NS_PERSON ? Person::$STD_EVENT_TYPES : Family::$STD_EVENT_TYPES, $birthFound, $christeningFound, $deathFound, $burialFound, $marriageFound, $notesMap[$p], $imagesMap[$p], $sourcesMap[$p], $this->data[$m][$p]['events'], $noteAdoptions, $sourceAdoptions, $imageAdoptions); if ($mergeTargetNs == NS_PERSON) { $this->addNamesToRequestData($requestData, $keepKeys[$p], $nameCount, $primaryNameFound, $notesMap[$p], $sourcesMap[$p], $this->data[$m][$p]['names'], $noteAdoptions, $sourceAdoptions); $this->addFamilyToRequestData($requestData, $mergingFamilies, 'child_of_family', $parentFamilyCount, $this->data[$m][$p]['child_of_families']); $this->addFamilyToRequestData($requestData, $mergingFamilies, 'spouse_of_family', $spouseFamilyCount, $this->data[$m][$p]['spouse_of_families']); } else { $this->addFamilyMembersToRequestData($requestData, $mergingPeople, 'husband', $husbandCount, $this->data[$m][$p]['husbands']); $this->addFamilyMembersToRequestData($requestData, $mergingPeople, 'wife', $wifeCount, $this->data[$m][$p]['wives']); $this->addFamilyMembersToRequestData($requestData, $mergingPeople, 'child', $childrenCount, $this->data[$m][$p]['children']); } $pageContents = $this->mapContents($sourcesMap[$p], $imagesMap[$p], $notesMap[$p], $this->data[$m][$p]['contents']); $this->addContents($contents, $keepKeys[$p], $pageContents); if ($p > 0) { if ($mergeSummary) { $mergeSummary .= ', '; } if ($mainOutput) { $mainOutput .= ', '; } if ($this->data[$m][$p]['gedcom']) { $mergeSummary .= 'gedcom'; $mainOutput .= htmlspecialchars(($mergeTargetNs == NS_FAMILY ? 'Family:' : 'Person:') . $this->data[$m][$p]['title']); } else { $title = Title::newFromText($this->data[$m][$p]['title'], $mergeTargetNs); $mergeSummary .= "[[" . $title->getPrefixedText() . "]]"; $mainOutput .= $skin->makeKnownLinkObj($title, htmlspecialchars($title->getPrefixedText()), 'redirect=no'); } } } } // redirect other pages to merge target $redir = "#REDIRECT [[" . $mergeTargetTitle->getPrefixedText() . "]]"; $talkRedir = "#REDIRECT [[" . $mergeTargetTalkTitle->getPrefixedText() . "]]"; for ($p = 1; $p < count($this->data[$m]); $p++) { if (!$this->data[$m][$p]['gedcom']) { $obj = $this->data[$m][$p]['object']; $comment = $this->makeComment($this->userComment, "merge into [[" . $mergeTargetTitle->getPrefixedText() . "]]" . $mergeCmtFamily, $mergeCmtSuffix); $obj->editPage($emptyRequest, $redir, $comment, $editFlags, false); // redir talk page as well if ($this->data[$m][$p]['talkrevid']) { // if talk page exists $talkTitle = Title::newFromText($this->data[$m][$p]['title'], $mergeTargetTalkNs); $article = new Article($talkTitle, 0); if ($article) { $this->addTalkContents($talkContents, $talkTitle, $article->fetchContent()); if ($talkMergeSummary) { $talkMergeSummary .= ', '; } if ($talkOutput) { $talkOutput .= ', '; } $talkMergeSummary .= "[[" . $talkTitle->getPrefixedText() . "]]"; $talkOutput .= $skin->makeKnownLinkObj($talkTitle, htmlspecialchars($talkTitle->getPrefixedText()), 'redirect=no'); $comment = $this->makeComment($this->userComment, "merge into [[" . $mergeTargetTalkTitle->getPrefixedText() . "]]" . $mergeCmtFamily, $mergeCmtSuffix); $article->doEdit($talkRedir, $comment, $editFlags); } } } } // update merge target talk if ($talkContents) { $article = new Article($mergeTargetTalkTitle, 0); if ($article) { $mergeTargetTalkContents = $article->fetchContent(); if ($mergeTargetTalkContents) { $mergeTargetTalkContents = rtrim($mergeTargetTalkContents) . "\n\n"; } $comment = $this->makeComment($this->userComment, 'merged with ' . $talkMergeSummary . $mergeCmtFamily, $mergeCmtSuffix); $article->doEdit($mergeTargetTalkContents . $talkContents, $comment, $editFlags); if ($this->addWatches) { StructuredData::addWatch($wgUser, $article, true); } } $outputRow .= '<li>Merged ' . $talkOutput . ' into ' . $skin->makeKnownLinkObj($mergeTargetTalkTitle, htmlspecialchars($mergeTargetTalkTitle->getPrefixedText())) . "</li>"; } $obj = $this->data[$m][0]['object']; if ($mergeTargetNs == NS_PERSON) { Person::addGenderToRequestData($requestData, $this->data[$m][0]['gender']); } else { // family $obj->isMerging(true); // to read propagated data from person pages, not from prev family revision } // update merge target $req = new FauxRequest($requestData, true); $comment = $this->makeComment($this->userComment, ($mergeSummary == 'gedcom' ? 'Add data from gedcom' : 'merged with ' . $mergeSummary) . $mergeCmtFamily, $mergeCmtSuffix); $obj->editPage($req, $contents, $comment, $editFlags, $this->addWatches); $outputRow .= '<li>Merged ' . $mainOutput . ' into ' . $skin->makeKnownLinkObj($mergeTargetTitle, htmlspecialchars($mergeTargetTitle->getPrefixedText())) . "</li>"; $outputRows[] = $outputRow; } // add log and recent changes if (!$this->isGedcom()) { if (!$mergeSummary) { $mergeSummary = 'members of other families'; } $mergeComment = 'Merge [[' . $mergeTargetTitle->getPrefixedText() . ']] and ' . $mergeSummary; $log = new LogPage('merge', false); $t = Title::makeTitle(NS_SPECIAL, "ReviewMerge/{$mergeLogId}"); $log->addEntry('merge', $t, $mergeComment); RecentChange::notifyLog(wfTimestampNow(), $t, $wgUser, $mergeComment, '', 'merge', 'merge', $t->getPrefixedText(), $mergeComment, '', $isTrustedMerge, 0); } $nonmergedPages = $this->getNonmergedPages(); $output .= join("\n", array_reverse($outputRows)) . '</ul>' . ($nonmergedPages ? '<p>In addition to the people listed above, the following have also been included in the target family' . ($this->isGedcom() ? '<br/>(GEDCOM people listed will be added when the GEDCOM is imported)' : '') . $nonmergedPages . "</p>\n" : '') . ($this->isGedcom() ? '' : '<p>' . $skin->makeKnownLinkObj(Title::makeTitle(NS_SPECIAL, 'ReviewMerge/' . $mergeLogId), htmlspecialchars("Review/undo merge")) . '<br>' . $skin->makeKnownLinkObj(Title::makeTitle(NS_SPECIAL, 'ShowDuplicates'), htmlspecialchars("Show more duplicates")) . '</p>'); return $output; }
public static function updateGedcomMatch($dbw, $treeId, $gedcomId, $key, $matchTitle, $merged, $gedcomUser) { $newTitle = $matchTitle == '#nomatch#' ? null : Title::newFromText($matchTitle); $oldTitle = null; // read old match_namespace and title $row = $dbw->selectRow('familytree_gedcom_data', array('fgd_match_namespace', 'fgd_match_title'), array('fgd_gedcom_id' => $gedcomId, 'fgd_gedcom_key' => $key)); if ($row && $row->fgd_match_namespace > 0) { $oldTitle = Title::makeTitle($row->fgd_match_namespace, $row->fgd_match_title); if ($oldTitle && ($oldTitle->getNamespace() == NS_PERSON || $oldTitle->getNamespace() == NS_FAMILY || $oldTitle->getNamespace() == NS_MYSOURCE) && (!$newTitle || $oldTitle->getPrefixedText() != $newTitle->getPrefixedText())) { // remove match title from tree if (!FamilyTreeUtil::removePage($dbw, $treeId, $oldTitle)) { return false; } // unwatch match title if no other trees contain it if (!$dbw->selectField('familytree_page', 'fp_tree_id', array('fp_namespace' => $row->fgd_match_namespace, 'fp_title' => $row->fgd_match_title, 'fp_user_id' => $gedcomUser->getID()))) { $article = new Article($oldTitle, 0); StructuredData::removeWatch($gedcomUser, $article); } } } if ($newTitle) { $matchTitle = $newTitle->getDBkey(); $matchNamespace = $newTitle->getNamespace(); $potentialMatchesAttr = ''; $potentialMatchesValue = ''; $potentialMatchesUpdate = ''; if (($newTitle->getNamespace() == NS_PERSON || $newTitle->getNamespace() == NS_FAMILY || $newTitle->getNamespace() == NS_MYSOURCE) && (!$oldTitle || $oldTitle->getPrefixedText() != $newTitle->getPrefixedText())) { // add match title to tree if (!FamilyTreeUtil::addPage($dbw, $gedcomUser, $treeId, $newTitle, 0, 0)) { return false; } // watch match title $article = new Article($newTitle, 0); StructuredData::addWatch($gedcomUser, $article); } } else { $matchTitle = ''; $matchNamespace = -1; $merged = 0; $potentialMatchesAttr = ', fgd_potential_matches'; // reset potential matches to what's in the gedcom $potentialMatchesValue = ", ''"; $potentialMatchesUpdate = ", fgd_potential_matches=''"; } $matchTitle = $dbw->addQuotes($matchTitle); $sql = "INSERT INTO familytree_gedcom_data (fgd_gedcom_id, fgd_gedcom_key, fgd_match_namespace, fgd_match_title, fgd_merged{$potentialMatchesAttr})" . " VALUES({$gedcomId}," . $dbw->addQuotes($key) . ",{$matchNamespace},{$matchTitle},{$merged}{$potentialMatchesValue})" . " ON DUPLICATE KEY UPDATE fgd_match_namespace={$matchNamespace}, fgd_match_title={$matchTitle}, fgd_merged={$merged}{$potentialMatchesUpdate}"; $dbw->query($sql); return $dbw->lastErrno() == 0; }
/** * editPage * * @param unknown_type $request * @param unknown_type $text * @return unknown */ public function editPage(&$request, &$text, $summary, $flags = 0, $addWatch = false) { global $wgUser; if (!$this->title || !$this->title->exists()) { return false; } $article = new Article($this->title, 0); if (!$article) { return false; } $oldContent = $article->getContent(); $content = $this->getEditText($request, $text); if ($content != $oldContent) { $result = $article->doEdit($content, $summary, $flags); if ($result && $addWatch) { StructuredData::addWatch($wgUser, $article, true); } } else { $result = true; } return $result; }
/** * Create family tree page * * @param unknown_type $args user, name, ns, title * @return FTE_SUCCESS, FTE_INVALID_ARG, FTE_NOT_LOGGED_IN, FTE_NOT_AUTHORIZED, FTE_NOT_FOUND, FTE_DUP_KEY, FTE_DB_ERROR */ function wfCreateFamilyTreePage($args) { global $wgUser, $wgAjaxCachePolicy, $wrBotUserID, $wgArticle, $wgTitle; // set cache policy $wgAjaxCachePolicy->setPolicy(0); $status = FTE_SUCCESS; $ns = ''; $titleString = ''; $revid = 0; $xml = simplexml_load_string($args); $userName = (string) $xml['user']; $treeName = (string) $xml['name']; $ns = (int) $xml['ns']; $titleString = (string) $xml['title']; $text = (string) $xml; if (!$userName || !$treeName || !$titleString || !($ns == NS_PERSON || $ns == NS_FAMILY)) { $status = FTE_INVALID_ARG; } else { if (!$wgUser->isLoggedIn()) { $status = FTE_NOT_LOGGED_IN; } else { if ($userName != $wgUser->getName() || $wgUser->isBlocked() || wfReadOnly()) { $status = FTE_NOT_AUTHORIZED; } } } if ($status == FTE_SUCCESS) { // get tree id $treeId = 0; $status = ftGetTreeId($userName, $treeName, $treeId); if ($status == FTE_SUCCESS && !$treeId) { $status = FTE_NOT_FOUND; } } if ($status == FTE_SUCCESS) { $dbw =& wfGetDB(DB_MASTER); $dbw->ignoreErrors(true); $dbw->begin(); $title = Title::newFromText($titleString, $ns); if ($title == null) { $status = FTE_INVALID_ARG; } else { if (!StructuredData::titleStringHasId($titleString)) { $title = StructuredData::appendUniqueId($title, $dbw); } $article = new Article($title, 0); if ($article->exists()) { $status = FTE_DUP_KEY; } } if ($status == FTE_SUCCESS) { // set the global article and title to this, so that propagation works ok $wgArticle = $article; $wgTitle = $article->getTitle(); // NOTE: This doesn't execute the code in FamilyTreePropagator to update familytree_page and add page to tree, but we don't want that to be called // because we add the page to the tree below if (!$article->doEdit($text, 'creating initial family tree', EDIT_NEW)) { $status = FTE_WIKI_ERROR; } else { $revid = $article->mRevIdEdited; } } // add the page to the tree if ($status == FTE_SUCCESS) { if (!FamilyTreeUtil::addPage($dbw, $wgUser, $treeId, $title, $revid, 0)) { $status = FTE_DB_ERROR; } } // watch the page if ($status == FTE_SUCCESS) { StructuredData::addWatch($wgUser, $article, true); } if ($status == FTE_SUCCESS) { $dbw->commit(); } else { $dbw->rollback(); } } // return status $titleString = StructuredData::escapeXml($title->getText()); return "<create status=\"{$status}\" ns=\"{$ns}\" title=\"{$titleString}\" latest=\"{$revid}\"></create>"; }
/** * Create family tree page * * This is also called by search.js * * @param unknown_type $args * @return GE_SUCCESS, GE_INVALID_ARG, GE_NOT_LOGGED_IN, GE_NOT_AUTHORIZED, GE_NOT_FOUND, GE_DUP_KEY, GE_DB_ERROR */ function wfAddPage($args) { global $wgUser, $wgAjaxCachePolicy, $wgArticle, $wgTitle, $wgLang; // set cache policy $wgAjaxCachePolicy->setPolicy(0); $status = GE_SUCCESS; $title = null; $titleString = null; $error = ''; $args = AjaxUtil::getArgs($args); $ns = $wgLang->getNsIndex($args['ns']); $titleString = @$args['title']; $update = $args['update'] == 'true'; if (!$wgUser->isLoggedIn()) { $status = GE_NOT_LOGGED_IN; } else { if ($wgUser->isBlocked() || wfReadOnly()) { $status = GE_NOT_AUTHORIZED; } } if ($status == GE_SUCCESS) { $dbw =& wfGetDB(DB_MASTER); $dbw->ignoreErrors(true); $dbw->begin(); $text = ''; if ($titleString) { // user passed in existing title; just add to watchlist and trees $title = Title::newFromText($titleString, $ns); } else { if ($ns == NS_PERSON) { if (ESINHandler::isLivingDates($args['bd'], null, $args['dd'], $args['dp'])) { $error = 'Living people cannot be added to WeRelate. People born in the last 110 years must have a death date'; } else { if (ESINHandler::isAmbiguousDate($args['bd']) || ESINHandler::isAmbiguousDate($args['dd'])) { $error = "Please write dates in D MMM YYYY format so they are unambiguous (ie 5 Jan 1900)"; } else { if (!$title) { $title = StructuredData::constructPersonTitle($args['g'], $args['s']); } if ($title) { if ($args['bt'] == 'chr') { $bird = ''; $birp = ''; $chrd = $args['bd']; $chrp = $args['bp']; } else { $bird = $args['bd']; $birp = $args['bp']; $chrd = ''; $chrp = ''; } if ($args['dt'] == 'bur') { $dead = ''; $deap = ''; $burd = $args['dd']; $burp = $args['dp']; } else { $dead = $args['dd']; $deap = $args['dp']; $burd = ''; $burp = ''; } $text = Person::getPageText($args['g'], $args['s'], $args['gnd'], $bird, $birp, $dead, $deap, $title->getText(), null, @$args['pf'], @$args['sf'], $chrd, $chrp, $burd, $burp); } } } } else { if ($ns == NS_FAMILY) { if (ESINHandler::isAmbiguousDate($args['md'])) { $error = "Please write dates in D MMM YYYY format so they are unambiguous (ie 5 Jan 1900)"; } else { $title = StructuredData::constructFamilyTitle($args['hg'], $args['hs'], $args['wg'], $args['ws']); if ($title) { $text = Family::getPageText($args['md'], $args['mp'], $title->getText(), null, @$args['ht'], @$args['wt'], @$args['ct']); } } } else { if ($ns == NS_SOURCE) { $title = StructuredData::constructSourceTitle($args['sty'], $args['st'], $args['a'], $args['p'], $args['pi'], $args['pu']); if ($title) { $text = Source::getPageText($args['sty'], $args['st'], $args['a'], $args['p'], $args['pi'], $args['pu']); } else { $error = 'Required source fields are missing; please press the Back button on your browser to enter the required fields.'; } } else { if ($ns == NS_MYSOURCE) { $t = $args['t']; if (mb_strpos($t, $wgUser->getName() . '/') != 0) { $t = $wgUser->getName() . '/' . $t; } $title = Title::newFromText($t, NS_MYSOURCE); if ($title) { $text = MySource::getPageText($args['a'], $args['p'], $args['s']); } } else { if ($ns == NS_PLACE) { $title = StructuredData::constructPlaceTitle($args['pn'], $args['li']); $text = Place::getPageText(); // check existing located-in, not root $titleText = $title->getFullText(); $pos = mb_strpos($titleText, ','); if ($pos === false) { $title = null; $error = 'You need to fill in the country'; } else { $locatedIn = Title::newFromText(trim(mb_substr($titleText, $pos + 1)), NS_PLACE); if (!$locatedIn->exists()) { $title = null; $error = 'Before you can add this place, you must first add ' . $locatedIn->getFullText(); } } } } } } } } if ($status == GE_SUCCESS && $title == null) { $status = GE_INVALID_ARG; if (!$error) { $error = 'Invalid page title; unable to create page'; } } // don't update in the case of the user passing in a non-existing titleString if ($update && !($titleString && !$title->exists())) { if ($status == GE_SUCCESS) { $article = new Article($title, 0); // don't set the global article and title to this; we don't need to propagate -- but we do for places // NOTE: This doesn't execute the code in FamilyTreePropagator to update familytree_page and add page to tree, but we don't want that to be called // because we add the page to the tree below if ($title->exists()) { // don't update the page if it already exists, except to add a spouse-family if ($ns == NS_PERSON && @$args['sf']) { $content =& $article->fetchContent(); $updated = false; Person::updateFamilyLink('spouse_of_family', '', $args['sf'], $content, $updated); if ($updated) { $article->doEdit($content, 'Add spouse family: [[Family:' . $args['sf'] . ']]', EDIT_UPDATE); StructuredData::purgeTitle($title, +1); // purge person with a fudge factor so family link will be blue } } $revid = 0; // ok for revid to be 0 if page exists because we no longer use revid } else { if (!$article->doEdit($text, '')) { $status = GE_WIKI_ERROR; } else { $revid = $article->mRevIdEdited; } } } if ($status == GE_SUCCESS) { // add the page to the trees (or to no trees) $allTrees = FamilyTreeUtil::getFamilyTrees($wgUser->getName()); $trees = explode('|', @$args['tree']); $checkedTreeIds = array(); foreach ($allTrees as $tree) { if (in_array(FamilyTreeUtil::toInputName($tree['name']), $trees)) { $checkedTreeIds[] = $tree['id']; // if (!FamilyTreeUtil::addPage($dbw, $wgUser, $tree['id'], $title, $revid, 0)) { // $status = GE_DB_ERROR; // } } } // update which trees are checked FamilyTreeUtil::updateTrees($dbw, $title, $revid, $allTrees, array(), $checkedTreeIds); } // watch the page if ($status == GE_SUCCESS) { StructuredData::addWatch($wgUser, $article, true); } } if ($status == GE_SUCCESS) { $dbw->commit(); } else { $dbw->rollback(); if (!$error) { $error = 'Unable to create page'; } } } // return status $titleString = ''; if ($title) { $titleString = StructuredData::escapeXml($title->getText()); } return "<addpage status=\"{$status}\" title=\"{$titleString}\" error=\"{$error}\"></addpage>"; }
public static function updateTrees($dbw, $title, $revId, $allTrees, $treeOwnerIds, $checkedTreeIds, $updateChecked = true, $addWatch = true) { global $wgUser; $talkRevid = -1; $result = true; $added = false; $removed = false; foreach ($allTrees as $tree) { $treeId = $tree['id']; if (in_array($treeId, $checkedTreeIds) && !in_array($treeId, $treeOwnerIds)) { // add the page to the tree //wfDebug("updateTrees add " . $tree['name'] . "\n"); if ($talkRevid == -1) { $talkRevision = Revision::newFromTitle($title->getTalkPage()); if ($talkRevision) { $talkRevid = $talkRevision->getId(); } else { $talkRevid = 0; } } $result = $result && FamilyTreeUtil::addPage($dbw, $wgUser, $treeId, $title, $revId, $talkRevid); $added = true; } else { if (!in_array($treeId, $checkedTreeIds) && in_array($treeId, $treeOwnerIds)) { // remove the page from the tree //wfDebug("updateTrees remove\n"); $result = $result && FamilyTreeUtil::removePage($dbw, $treeId, $title); $removed = true; } } if ($updateChecked) { $checked = !$tree['checked'] && in_array($treeId, $checkedTreeIds); $unchecked = $tree['checked'] && !in_array($treeId, $checkedTreeIds); if ($checked || $unchecked) { $dbw->update('familytree', array('ft_checked' => $checked ? 1 : 0), array('ft_tree_id' => $treeId)); FamilyTreeUtil::deleteFamilyTreesCache($wgUser->getName()); } } } if ($added && !$wgUser->isWatched($title)) { //wfDebug("updateTrees - addWatch: ".$title->getPrefixedText()."\n"); if ($addWatch) { StructuredData::addWatch($wgUser, new Article($title, 0)); } } else { if ($added || $removed) { // purge the article and re-index it StructuredData::purgeTitle($title); StructuredData::requestIndex($title); } } return $result; }