function wfSpecialAddSubpage($par) { global $wgOut, $wgRequest, $wgUser; $super = $wgRequest->getVal('super'); $sub = $wgRequest->getVal('sub'); $found = false; if ($super && $sub && $wgUser->isLoggedIn()) { $sub = mb_strtoupper(mb_substr($sub, 0, 1)) . mb_substr($sub, 1); $subTitle = Title::newFromText("{$super}/{$sub}"); if ($subTitle) { // add the page to the super page if it has a listsubpages tag $superTitle = Title::newFromText($super); if ($superTitle) { $r = Revision::newFromTitle($superTitle); if ($r) { $text =& $r->getText(); if ($subTitle->exists()) { $dbr =& wfGetDB(DB_SLAVE); $timestamp = $dbr->selectField(array('page', 'revision'), 'rev_timestamp', array('page_namespace' => $subTitle->getNamespace(), 'page_title' => $subTitle->getDBkey(), 'page_id = rev_page'), 'wfSpecialAddSubpage', array('order by rev_timestamp')); $d = new DateTime(substr($timestamp, 0, 8)); $date = $d->format('j M Y'); } else { $date = date('j M Y'); } $cnt = 0; $text = preg_replace('#(<listsubpages[^>]*>.*?)(</listsubpages>)#s', '${1}' . StructuredData::protectRegexReplace("{$sub}|{$date}") . "\n" . '${2}', $text, 1, $cnt); if ($cnt) { $a = StructuredData::getArticle($superTitle); $a->doEdit($text, 'Added ' . $sub, EDIT_UPDATE); } } } $wgOut->redirect($subTitle->getFullURL('action=edit')); $found = true; } } if (!$found) { $super = htmlspecialchars($super); $sub = htmlspecialchars($sub); $wgOut->addHTML("<p><font color=red>Cannot create page: {$super}/{$sub}</font></p>"); } }
private function updateImage($thisTitle, $imageTitle, $tag, $oldTitle, $newTitle, &$propagatedData, &$text, &$textChanged) { if (!PropagationManager::isPropagatablePage($imageTitle)) { return true; } $result = true; $article = StructuredData::getArticle($imageTitle, true); if ($article) { $content =& $article->fetchContent(); // fetches from master $updatedContent =& $this->updateImageContent($tag, $oldTitle, $newTitle, $propagatedData, $content); if ($updatedContent) { $result = $article->doEdit($updatedContent, self::PROPAGATE_MESSAGE . ' [[' . $thisTitle->getPrefixedText() . ']]', PROPAGATE_EDIT_FLAGS); } else { error_log("updateImage propagating nothing changed: " . $imageTitle->getText()); } // if we're not deleting this entry (newTitle is not empty), and the image being updated is a redirect (article title != pageToUpdate), // we need to update the page title in this page text if ($newTitle && $imageTitle->getText() != $article->getTitle()->getText()) { $old = ' filename="' . StructuredData::escapeXml($imageTitle->getText()) . '"'; $new = ' filename="' . StructuredData::escapeXml($article->getTitle()->getText()) . '"'; $text = str_replace($old, $new, $text); $textChanged = true; } } return $result; }
/** * Propagate data in xml property to other articles if necessary * @param string $oldText contains text being replaced * @param String $text which we never touch when propagating places * @param bool $textChanged which we never touch when propagating places * @return bool true if propagation was successful */ protected function propagateEditData($oldText, &$text, &$textChanged) { global $wrIsGedcomUpload, $wgESINHandler; $result = true; // cache new xml - it's used right away to generate family badges on the related person pages, // if you don't cache it, the badges pick up the old html $this->cachePageXml(); // update people that link to this family, because the family-badge contents could have changed // TODO this could be made more efficient by only invalidating if names, birthdates, or deathdates have changed $u = new HTMLCacheUpdate($this->title, 'pagelinks'); $u->doUpdate(); // get current info $propagatedData = Family::getPropagatedData($this->xml); $redirTitle = Title::newFromRedirect($text); // get original info $origPropagatedData = Family::getPropagatedData(null); // don't bother construction page text from WLH in a gedcom upload because nothing will link to this new page if (!@$wrIsGedcomUpload && (!$oldText || mb_strpos($oldText, '<family>') === false)) { // oldText contains MediaWiki:noarticletext if the article is being created // construct <family> text from What Links Here $oldText = $this->getPageTextFromWLH(false); } $origXml = null; if ($oldText) { $origXml = StructuredData::getXml('family', $oldText); if (isset($origXml)) { $origPropagatedData = Family::getPropagatedData($origXml); } } // TODO!!! // Revert, Unmerge, and eventually Undo should be getting the current attrs for existing people from origPropagatedData // and getting the current attrs and redirect-titles for newly-added people from the Person pages when adding the family title to them // then unmerge wouldn't need to get them in unmerge, and revert wouldn't be broken, and undo won't break things. // This duplicates the functionality found in fromEditFields, but it allows us to update the pages without going through fromEditFields // and it doesn't require reading any pages that we weren't reading already. // Also, instead of isMerging, if this Family page is on the propagation manager blacklist, then you can't trust the prior version // and we should get the person attrs from the Person pages for _all_ family members. // Finally, make sure that after redirects we don't have 2 links to the same Person (and also two links to the same Family on Person pages). // ignore changes of the husband <-> wife role for the same person $temp = array_diff($propagatedData['husbands'], $origPropagatedData['wives']); $origPropagatedData['wives'] = array_diff($origPropagatedData['wives'], $propagatedData['husbands']); $propagatedData['husbands'] = $temp; $temp = array_diff($propagatedData['wives'], $origPropagatedData['husbands']); $origPropagatedData['husbands'] = array_diff($origPropagatedData['husbands'], $propagatedData['wives']); $propagatedData['wives'] = $temp; $result = $result && $this->propagateFamilyMemberEditData($propagatedData['husbands'], $origPropagatedData['husbands'], 'husband', 'spouse_of_family', $text, $textChanged); $result = $result && $this->propagateFamilyMemberEditData($propagatedData['wives'], $origPropagatedData['wives'], 'wife', 'spouse_of_family', $text, $textChanged); $result = $result && $this->propagateFamilyMemberEditData($propagatedData['children'], $origPropagatedData['children'], 'child', 'child_of_family', $text, $textChanged); if (StructuredData::removeDuplicateLinks('husband|wife|child', $text)) { $textChanged = true; } $result = $result && $wgESINHandler->propagateSINEdit($this->title, 'family', $this->titleString, $propagatedData, $origPropagatedData, $text, $textChanged); // ensure footer tag is still there (might have been removed by editing the last section) if ($redirTitle == null && strpos($text, ESINHandler::ESIN_FOOTER_TAG) === false) { if (strlen($text) > 0 && substr($text, strlen($text) - 1) != "\n") { $text .= "\n"; } $text .= ESINHandler::ESIN_FOOTER_TAG; $textChanged = true; } // update watchlist summary if changed $summary = Family::getSummary($this->xml, $this->title); $origSummary = Family::getSummary($origXml, $this->title); if ($summary != $origSummary) { StructuredData::updateWatchlistSummary($this->title, $summary); } // if it's a redirect, add the people, families, and images that were on this page to the redirect target // but don't bother updating the redir target during a merge if ($redirTitle != null && PropagationManager::isPropagatablePage($redirTitle)) { // get the text of the redir page $article = StructuredData::getArticle($redirTitle, true); if ($article) { $content =& $article->fetchContent(); $updated = false; // add husbands from this page to the redir page foreach ($origPropagatedData['husbands'] as $p) { // get propagated data for p $pd = Person::getPropagatedData(StructuredData::getXmlForTitle('person', Title::newFromText($p, NS_PERSON))); Family::updatePersonLink('husband', $p, $p, $pd, 'spouse_of_family', $content, $updated); } // add wives from this page to the redir page foreach ($origPropagatedData['wives'] as $p) { $pd = Person::getPropagatedData(StructuredData::getXmlForTitle('person', Title::newFromText($p, NS_PERSON))); Family::updatePersonLink('wife', $p, $p, $pd, 'spouse_of_family', $content, $updated); } // add children from this page to the redir page foreach ($origPropagatedData['children'] as $p) { $pd = Person::getPropagatedData(StructuredData::getXmlForTitle('person', Title::newFromText($p, NS_PERSON))); Family::updatePersonLink('child', $p, $p, $pd, 'child_of_family', $content, $updated); } // add images from this page to the redir page foreach ($origPropagatedData['images'] as $i) { ESINHandler::updateImageLink('family', $i['filename'], $i['filename'], $i['caption'], $content, $updated); } // update the redir page if necessary if ($updated) { $result = $result && $article->doEdit($content, 'Copy data from [[' . $this->title->getPrefixedText() . ']]', PROPAGATE_EDIT_FLAGS); } } } if (!$result) { error_log("ERROR! Family edit/rollback not propagated: {$this->titleString}\n"); } return $result; }
/** * Propagate data in xml property to other articles if necessary * @param string $oldText contains text being replaced * @param String $text new text * @param bool $textChanged which we never touch when propagating places * @return bool true if propagation was successful */ protected function propagateEditData($oldText, &$text, &$textChanged) { global $wrIsGedcomUpload, $wgESINHandler; $result = true; // clear xml cache $this->clearPageXmlCache(); // get current info $propagatedData = Person::getPropagatedData($this->xml); $redirTitle = Title::newFromRedirect($text); // get original info $origPropagatedData = Person::getPropagatedData(null); // don't bother construction page text from WLH in a gedcom upload because nothing will link to this new page if (!@$wrIsGedcomUpload && (!$oldText || mb_strpos($oldText, '<person>') === false)) { // oldText contains MediaWiki:noarticletext if the article is being created // construct <person> text from What Links Here $oldText = $this->getPageTextFromWLH(false); } $origXml = null; if ($oldText) { $origXml = StructuredData::getXml('person', $oldText); if (isset($origXml)) { $origPropagatedData = Person::getPropagatedData($origXml); } } $result = $result && $this->propagateFamilyEditData($propagatedData['parentFamilies'], $origPropagatedData['parentFamilies'], 'child_of_family', 'child', 'child', $propagatedData, $origPropagatedData, $text, $textChanged); $oldTag = Person::getSpouseTagFromGender($origPropagatedData['gender']); $newTag = Person::getSpouseTagFromGender($propagatedData['gender']); $result = $result && $this->propagateFamilyEditData($propagatedData['spouseFamilies'], $origPropagatedData['spouseFamilies'], 'spouse_of_family', $oldTag, $newTag, $propagatedData, $origPropagatedData, $text, $textChanged); if (StructuredData::removeDuplicateLinks('child_of_family|spouse_of_family', $text)) { $textChanged = true; } $result = $result && $wgESINHandler->propagateSINEdit($this->title, 'person', $this->titleString, $propagatedData, $origPropagatedData, $text, $textChanged); // ensure footer tag is still there (might have been removed by editing the last section) if ($redirTitle == null && strpos($text, ESINHandler::ESIN_FOOTER_TAG) === false) { if (strlen($text) > 0 && substr($text, strlen($text) - 1) != "\n") { $text .= "\n"; } $text .= ESINHandler::ESIN_FOOTER_TAG; $textChanged = true; } // update watchlist summary if changed $summary = Person::getSummary($this->xml, $this->title); $origSummary = Person::getSummary($origXml, $this->title); if ($summary != $origSummary) { StructuredData::updateWatchlistSummary($this->title, $summary); } // if it's a redirect, add the people, families, and images that were on this page to the redirect target // but don't bother updating the redir target during a merge if ($redirTitle != null && PropagationManager::isPropagatablePage($redirTitle)) { // get the text of the redir page $article = StructuredData::getArticle($redirTitle, true); if ($article) { $content =& $article->fetchContent(); $updated = false; // add parent families from this page to the redir page foreach ($origPropagatedData['parentFamilies'] as $f) { Person::updateFamilyLink('child_of_family', $f, $f, $content, $updated); } // add spouse families from this page to the redir page foreach ($origPropagatedData['spouseFamilies'] as $f) { Person::updateFamilyLink('spouse_of_family', $f, $f, $content, $updated); } // add images from this page to the redir page foreach ($origPropagatedData['images'] as $i) { ESINHandler::updateImageLink('person', $i['filename'], $i['filename'], $i['caption'], $content, $updated); } // update the redir page if necessary if ($updated) { $result = $result && $article->doEdit($content, 'Copy data from [[' . $this->title->getPrefixedText() . ']]', PROPAGATE_EDIT_FLAGS); } } } if (!$result) { error_log("ERROR! Person edit/rollback not propagated: {$this->titleString}\n"); } return $result; }
/** * Run a refreshLinks job * @return boolean success */ function run() { global $wgTitle, $wgUser, $wgLang; $wgTitle = $this->title; // FakeTitle (the default) generates errors when accessed, and sometimes I log wgTitle, so set it to something else $wgUser = User::newFromName('WeRelate agent'); // set the user $oldTitle = Title::newFromText($this->params['old_title'], NS_PLACE); $newTitle = Title::newFromText($this->params['new_title'], NS_PLACE); $oldPlace = '<place>' . StructuredData::protectRegexSearch(StructuredData::escapeXml($oldTitle->getText())) . '((\\|[^<]*)?)</place>'; $newPlace = '<place>' . StructuredData::protectRegexReplace(StructuredData::escapeXml($newTitle->getText())) . '\\1</place>'; // get wlh pages $dbr =& wfGetDB(DB_SLAVE); $plConds = array('page_id=pl_from', 'pl_namespace' => $oldTitle->getNamespace(), 'pl_title' => $oldTitle->getDBkey(), 'page_is_redirect' => 0); $fields = array('page_namespace', 'page_title'); $plRes = $dbr->select(array('pagelinks', 'page'), $fields, $plConds, 'PlaceRedirectJob'); // for each wlh page in a target namespace while ($row = $dbr->fetchObject($plRes)) { if ($row->page_namespace == NS_SOURCE) { // update place title in page contents $article = StructuredData::getArticle(Title::newFromText($row->page_title, $row->page_namespace), true); $content =& $article->fetchContent(); $updatedContent = preg_replace('$' . $oldPlace . '$', $newPlace, $content); // save page if ($content != $updatedContent) { $article->doEdit($updatedContent, 'Redirect place', PROPAGATE_EDIT_FLAGS); } } } $dbr->freeResult($plRes); return true; }
private function updatePage($linkTitle, $tag, $newTitle, &$text, &$textChanged) { if (!PropagationManager::isPropagatablePage($linkTitle)) { return true; } $result = true; $article = StructuredData::getArticle($linkTitle, true); if ($article) { $content =& $article->fetchContent(); $updated = false; ESINHandler::updateImageLink($tag, $this->titleString, $newTitle, '', $content, $updated); if ($updated) { $result = $article->doEdit($content, self::PROPAGATE_MESSAGE . ' [[' . $this->title->getPrefixedText() . ']]', PROPAGATE_EDIT_FLAGS); } else { error_log("propagating image " . $this->titleString . " nothing changed in " . $linkTitle->getPrefixedText()); } // if we're not deleting this entry (newTitle is not empty), and the page to update is a redirect (article title != linkTitle), // we need to update the page title in the image page text if ($newTitle && $linkTitle->getText() != $article->getTitle()->getText()) { $old = 'title="' . StructuredData::escapeXml($linkTitle->getText()) . '"'; $new = 'title="' . StructuredData::escapeXml($article->getTitle()->getText()) . '"'; $text = str_replace($old, $new, $text); $textChanged = true; } } return $result; }