/** * Populates the search index with content from all pages */ protected function populateSearchIndex() { $res = $this->db->select('page', 'MAX(page_id) AS count'); $s = $this->db->fetchObject($res); $count = $s->count; $this->output("Rebuilding index fields for {$count} pages...\n"); $n = 0; while ($n < $count) { $this->output($n . "\n"); $end = $n + self::RTI_CHUNK_SIZE - 1; $res = $this->db->select(array('page', 'revision', 'text'), array('page_id', 'page_namespace', 'page_title', 'old_flags', 'old_text'), array("page_id BETWEEN {$n} AND {$end}", 'page_latest = rev_id', 'rev_text_id = old_id'), __METHOD__); foreach ($res as $s) { $revtext = Revision::getRevisionText($s); $u = new SearchUpdate($s->page_id, $s->page_title, $revtext); $u->doUpdate(); } $this->db->freeResult($res); $n += self::RTI_CHUNK_SIZE; } }
/** * Populates the search index with content from all pages */ protected function populateSearchIndex() { $res = $this->db->select('page', 'MAX(page_id) AS count'); $s = $this->db->fetchObject($res); $count = $s->count; $this->output("Rebuilding index fields for {$count} pages...\n"); $n = 0; $fields = array_merge(Revision::selectPageFields(), Revision::selectFields(), Revision::selectTextFields()); while ($n < $count) { if ($n) { $this->output($n . "\n"); } $end = $n + self::RTI_CHUNK_SIZE - 1; $res = $this->db->select(['page', 'revision', 'text'], $fields, ["page_id BETWEEN {$n} AND {$end}", 'page_latest = rev_id', 'rev_text_id = old_id'], __METHOD__); foreach ($res as $s) { try { $title = Title::makeTitle($s->page_namespace, $s->page_title); $rev = new Revision($s); $content = $rev->getContent(); $u = new SearchUpdate($s->page_id, $title, $content); $u->doUpdate(); } catch (MWContentSerializationException $ex) { $this->output("Failed to deserialize content of revision {$s->rev_id} of page " . "`" . $title->getPrefixedDBkey() . "`!\n"); } } $n += self::RTI_CHUNK_SIZE; } }
/** * Move a title to a new location * @param Title &$nt the new title * @param bool $auth indicates whether $wgUser's permissions * should be checked * @return mixed true on success, message name on failure */ public function moveTo(&$nt, $auth = true, $reason = '') { $err = $this->isValidMoveOperation($nt, $auth); if (is_string($err)) { return $err; } $pageid = $this->getArticleID(); if ($nt->exists()) { $this->moveOverExistingRedirect($nt, $reason); $pageCountChange = 0; } else { # Target didn't exist, do normal move. $this->moveToNewTitle($nt, $reason); $pageCountChange = 1; } $redirid = $this->getArticleID(); # Fixing category links (those without piped 'alternate' names) to be sorted under the new title $dbw = wfGetDB(DB_MASTER); $categorylinks = $dbw->tableName('categorylinks'); $sql = "UPDATE {$categorylinks} SET cl_sortkey=" . $dbw->addQuotes($nt->getPrefixedText()) . " WHERE cl_from=" . $dbw->addQuotes($pageid) . " AND cl_sortkey=" . $dbw->addQuotes($this->getPrefixedText()); $dbw->query($sql, 'SpecialMovepage::doSubmit'); # Update watchlists $oldnamespace = $this->getNamespace() & ~1; $newnamespace = $nt->getNamespace() & ~1; $oldtitle = $this->getDBkey(); $newtitle = $nt->getDBkey(); if ($oldnamespace != $newnamespace || $oldtitle != $newtitle) { WatchedItem::duplicateEntries($this, $nt); } # Update search engine $u = new SearchUpdate($pageid, $nt->getPrefixedDBkey()); $u->doUpdate(); $u = new SearchUpdate($redirid, $this->getPrefixedDBkey(), ''); $u->doUpdate(); # Update site_stats if ($this->isContentPage() && !$nt->isContentPage()) { # No longer a content page # Not viewed, edited, removing $u = new SiteStatsUpdate(0, 1, -1, $pageCountChange); } elseif (!$this->isContentPage() && $nt->isContentPage()) { # Now a content page # Not viewed, edited, adding $u = new SiteStatsUpdate(0, 1, +1, $pageCountChange); } elseif ($pageCountChange) { # Redirect added $u = new SiteStatsUpdate(0, 0, 0, 1); } else { # Nothing special $u = false; } if ($u) { $u->doUpdate(); } global $wgUser; wfRunHooks('TitleMoveComplete', array(&$this, &$nt, &$wgUser, $pageid, $redirid)); return true; }
/** * Move a title to a new location * * @param $nt Title the new title * @param $auth Bool indicates whether $wgUser's permissions * should be checked * @param $reason String the reason for the move * @param $createRedirect Bool Whether to create a redirect from the old title to the new title. * Ignored if the user doesn't have the suppressredirect right. * @return Mixed true on success, getUserPermissionsErrors()-like array on failure */ public function moveTo(&$nt, $auth = true, $reason = '', $createRedirect = true) { global $wgUser; $err = $this->isValidMoveOperation($nt, $auth, $reason); if (is_array($err)) { // Auto-block user's IP if the account was "hard" blocked $wgUser->spreadAnyEditBlock(); return $err; } // If it is a file, move it first. It is done before all other moving stuff is // done because it's hard to revert $dbw = wfGetDB(DB_MASTER); if ($this->getNamespace() == NS_FILE) { $file = wfLocalFile($this); if ($file->exists()) { $status = $file->move($nt); if (!$status->isOk()) { return $status->getErrorsArray(); } } } $dbw->begin(); # If $file was a LocalFile, its transaction would have closed our own. $pageid = $this->getArticleID(self::GAID_FOR_UPDATE); $protected = $this->isProtected(); $pageCountChange = ($createRedirect ? 1 : 0) - ($nt->exists() ? 1 : 0); // Do the actual move $err = $this->moveToInternal($nt, $reason, $createRedirect); if (is_array($err)) { # @todo FIXME: What about the File we have already moved? $dbw->rollback(); return $err; } $redirid = $this->getArticleID(); // Refresh the sortkey for this row. Be careful to avoid resetting // cl_timestamp, which may disturb time-based lists on some sites. $prefixes = $dbw->select('categorylinks', array('cl_sortkey_prefix', 'cl_to'), array('cl_from' => $pageid), __METHOD__); foreach ($prefixes as $prefixRow) { $prefix = $prefixRow->cl_sortkey_prefix; $catTo = $prefixRow->cl_to; $dbw->update('categorylinks', array('cl_sortkey' => Collation::singleton()->getSortKey($nt->getCategorySortkey($prefix)), 'cl_timestamp=cl_timestamp'), array('cl_from' => $pageid, 'cl_to' => $catTo), __METHOD__); } if ($protected) { # Protect the redirect title as the title used to be... $dbw->insertSelect('page_restrictions', 'page_restrictions', array('pr_page' => $redirid, 'pr_type' => 'pr_type', 'pr_level' => 'pr_level', 'pr_cascade' => 'pr_cascade', 'pr_user' => 'pr_user', 'pr_expiry' => 'pr_expiry'), array('pr_page' => $pageid), __METHOD__, array('IGNORE')); # Update the protection log $log = new LogPage('protect'); $comment = wfMsgForContent('prot_1movedto2', $this->getPrefixedText(), $nt->getPrefixedText()); if ($reason) { $comment .= wfMsgForContent('colon-separator') . $reason; } // @todo FIXME: $params? $log->addEntry('move_prot', $nt, $comment, array($this->getPrefixedText())); } # Update watchlists $oldnamespace = $this->getNamespace() & ~1; $newnamespace = $nt->getNamespace() & ~1; $oldtitle = $this->getDBkey(); $newtitle = $nt->getDBkey(); if ($oldnamespace != $newnamespace || $oldtitle != $newtitle) { WatchedItem::duplicateEntries($this, $nt); } # Update search engine $u = new SearchUpdate($pageid, $nt->getPrefixedDBkey()); $u->doUpdate(); $u = new SearchUpdate($redirid, $this->getPrefixedDBkey(), ''); $u->doUpdate(); $dbw->commit(); # Update site_stats if ($this->isContentPage() && !$nt->isContentPage()) { # No longer a content page # Not viewed, edited, removing $u = new SiteStatsUpdate(0, 1, -1, $pageCountChange); } elseif (!$this->isContentPage() && $nt->isContentPage()) { # Now a content page # Not viewed, edited, adding $u = new SiteStatsUpdate(0, 1, +1, $pageCountChange); } elseif ($pageCountChange) { # Redirect added $u = new SiteStatsUpdate(0, 0, 0, 1); } else { # Nothing special $u = false; } if ($u) { $u->doUpdate(); } # Update message cache for interface messages if ($this->getNamespace() == NS_MEDIAWIKI) { # @bug 17860: old article can be deleted, if this the case, # delete it from message cache if ($this->getArticleID() === 0) { MessageCache::singleton()->replace($this->getDBkey(), false); } else { $oldarticle = new Article($this); MessageCache::singleton()->replace($this->getDBkey(), $oldarticle->getContent()); } } if ($nt->getNamespace() == NS_MEDIAWIKI) { $newarticle = new Article($nt); MessageCache::singleton()->replace($nt->getDBkey(), $newarticle->getContent()); } global $wgUser; wfRunHooks('TitleMoveComplete', array(&$this, &$nt, &$wgUser, $pageid, $redirid)); return true; }
/** * Move a title to a new location * @param Title &$nt the new title * @param bool $auth indicates whether $wgUser's permissions * should be checked * @param string $reason The reason for the move * @param bool $createRedirect Whether to create a redirect from the old title to the new title. * Ignored if the user doesn't have the suppressredirect right. * @return mixed true on success, message name on failure */ public function moveTo(&$nt, $auth = true, $reason = '', $createRedirect = true) { $err = $this->isValidMoveOperation($nt, $auth); if (is_string($err)) { return $err; } $pageid = $this->getArticleID(); if ($nt->exists()) { $this->moveOverExistingRedirect($nt, $reason, $createRedirect); $pageCountChange = $createRedirect ? 0 : -1; } else { # Target didn't exist, do normal move. $this->moveToNewTitle($nt, $reason, $createRedirect); $pageCountChange = $createRedirect ? 1 : 0; } $redirid = $this->getArticleID(); // Category memberships include a sort key which may be customized. // If it's left as the default (the page title), we need to update // the sort key to match the new title. // // Be careful to avoid resetting cl_timestamp, which may disturb // time-based lists on some sites. // // Warning -- if the sort key is *explicitly* set to the old title, // we can't actually distinguish it from a default here, and it'll // be set to the new title even though it really shouldn't. // It'll get corrected on the next edit, but resetting cl_timestamp. $dbw = wfGetDB(DB_MASTER); $dbw->update('categorylinks', array('cl_sortkey' => $nt->getPrefixedText(), 'cl_timestamp=cl_timestamp'), array('cl_from' => $pageid, 'cl_sortkey' => $this->getPrefixedText()), __METHOD__); # Update watchlists $oldnamespace = $this->getNamespace() & ~1; $newnamespace = $nt->getNamespace() & ~1; $oldtitle = $this->getDBkey(); $newtitle = $nt->getDBkey(); if ($oldnamespace != $newnamespace || $oldtitle != $newtitle) { WatchedItem::duplicateEntries($this, $nt); } # Update search engine $u = new SearchUpdate($pageid, $nt->getPrefixedDBkey()); $u->doUpdate(); $u = new SearchUpdate($redirid, $this->getPrefixedDBkey(), ''); $u->doUpdate(); # Update site_stats if ($this->isContentPage() && !$nt->isContentPage()) { # No longer a content page # Not viewed, edited, removing $u = new SiteStatsUpdate(0, 1, -1, $pageCountChange); } elseif (!$this->isContentPage() && $nt->isContentPage()) { # Now a content page # Not viewed, edited, adding $u = new SiteStatsUpdate(0, 1, +1, $pageCountChange); } elseif ($pageCountChange) { # Redirect added $u = new SiteStatsUpdate(0, 0, 0, 1); } else { # Nothing special $u = false; } if ($u) { $u->doUpdate(); } # Update message cache for interface messages if ($nt->getNamespace() == NS_MEDIAWIKI) { global $wgMessageCache; $oldarticle = new Article($this); $wgMessageCache->replace($this->getDBkey(), $oldarticle->getContent()); $newarticle = new Article($nt); $wgMessageCache->replace($nt->getDBkey(), $newarticle->getContent()); } global $wgUser; wfRunHooks('TitleMoveComplete', array(&$this, &$nt, &$wgUser, $pageid, $redirid)); return true; }
/** * Update the searchindex table for a given pageid * @param $dbw DatabaseBase a database write handle * @param $pageId Integer: the page ID to update. * @return null|string */ public function updateSearchIndexForPage($dbw, $pageId) { // Get current revision $rev = Revision::loadFromPageId($dbw, $pageId); $title = null; if ($rev) { $titleObj = $rev->getTitle(); $title = $titleObj->getPrefixedDBkey(); $this->output("{$title}..."); # Update searchindex # TODO: pass the Content object to SearchUpdate, let the search engine decide how to deal with it. $u = new SearchUpdate($pageId, $titleObj->getText(), $rev->getContent()->getTextForSearchIndex()); $u->doUpdate(); $this->output("\n"); } return $title; }
public function searchIndexUpdateCallback($dbw, $row) { if ($row->rc_type == RC_MOVE || $row->rc_type == RC_MOVE_OVER_REDIRECT) { # Rename searchindex entry $titleObj = Title::makeTitle($row->rc_moved_to_ns, $row->rc_moved_to_title); $title = $titleObj->getPrefixedDBkey(); $this->output("{$title}..."); $u = new SearchUpdate($row->rc_cur_id, $title, false); $u->doUpdate(); $this->output("\n"); } elseif ($row->rc_type !== RC_LOG) { $this->updateSearchIndexForPage($dbw, $row->rc_cur_id); } }
function update($text, $title = 'Test', $id = 1) { $u = new SearchUpdate($id, $title, $text); $u->doUpdate(); return array(MockSearch::$title, MockSearch::$text); }
/** * Update the searchindex table for a given pageid * @param $dbw Database: a database write handle * @param $pageId Integer: the page ID to update. */ public function updateSearchIndexForPage($dbw, $pageId) { // Get current revision $rev = Revision::loadFromPageId($dbw, $pageId); $title = null; if ($rev) { $titleObj = $rev->getTitle(); $title = $titleObj->getPrefixedDBkey(); $this->output("{$title}..."); # Update searchindex $u = new SearchUpdate($pageId, $titleObj->getText(), $rev->getText()); $u->doUpdate(); $this->output("\n"); } return $title; }
/** * Move a title to a new location * @param &$nt \type{Title} the new title * @param $auth \type{\bool} indicates whether $wgUser's permissions * should be checked * @param $reason \type{\string} The reason for the move * @param $createRedirect \type{\bool} Whether to create a redirect from the old title to the new title. * Ignored if the user doesn't have the suppressredirect right. * @return \type{\mixed} true on success, getUserPermissionsErrors()-like array on failure */ public function moveTo(&$nt, $auth = true, $reason = '', $createRedirect = true) { $err = $this->isValidMoveOperation($nt, $auth, $reason); if (is_array($err)) { return $err; } // If it is a file, move it first. It is done before all other moving stuff is done because it's hard to revert $dbw = wfGetDB(DB_MASTER); if ($this->getNamespace() == NS_FILE) { $file = wfLocalFile($this); if ($file->exists()) { $status = $file->move($nt); if (!$status->isOk()) { return $status->getErrorsArray(); } } } $pageid = $this->getArticleID(); $protected = $this->isProtected(); if ($nt->exists()) { $err = $this->moveOverExistingRedirect($nt, $reason, $createRedirect); $pageCountChange = $createRedirect ? 0 : -1; } else { # Target didn't exist, do normal move. $err = $this->moveToNewTitle($nt, $reason, $createRedirect); $pageCountChange = $createRedirect ? 1 : 0; } if (is_array($err)) { return $err; } $redirid = $this->getArticleID(); // Category memberships include a sort key which may be customized. // If it's left as the default (the page title), we need to update // the sort key to match the new title. // // Be careful to avoid resetting cl_timestamp, which may disturb // time-based lists on some sites. // // Warning -- if the sort key is *explicitly* set to the old title, // we can't actually distinguish it from a default here, and it'll // be set to the new title even though it really shouldn't. // It'll get corrected on the next edit, but resetting cl_timestamp. $dbw->update('categorylinks', array('cl_sortkey' => $nt->getPrefixedText(), 'cl_timestamp=cl_timestamp'), array('cl_from' => $pageid, 'cl_sortkey' => $this->getPrefixedText()), __METHOD__); if ($protected) { # Protect the redirect title as the title used to be... $dbw->insertSelect('page_restrictions', 'page_restrictions', array('pr_page' => $redirid, 'pr_type' => 'pr_type', 'pr_level' => 'pr_level', 'pr_cascade' => 'pr_cascade', 'pr_user' => 'pr_user', 'pr_expiry' => 'pr_expiry'), array('pr_page' => $pageid), __METHOD__, array('IGNORE')); # Update the protection log $log = new LogPage('protect'); $comment = wfMsgForContent('prot_1movedto2', $this->getPrefixedText(), $nt->getPrefixedText()); if ($reason) { $comment .= wfMsgForContent('colon-separator') . $reason; } $log->addEntry('move_prot', $nt, $comment, array($this->getPrefixedText())); // FIXME: $params? } # Update watchlists $oldnamespace = $this->getNamespace() & ~1; $newnamespace = $nt->getNamespace() & ~1; $oldtitle = $this->getDBkey(); $newtitle = $nt->getDBkey(); if ($oldnamespace != $newnamespace || $oldtitle != $newtitle) { WatchedItem::duplicateEntries($this, $nt); } # Update search engine $u = new SearchUpdate($pageid, $nt->getPrefixedDBkey()); $u->doUpdate(); $u = new SearchUpdate($redirid, $this->getPrefixedDBkey(), ''); $u->doUpdate(); # Update site_stats if ($this->isContentPage() && !$nt->isContentPage()) { # No longer a content page # Not viewed, edited, removing $u = new SiteStatsUpdate(0, 1, -1, $pageCountChange); } elseif (!$this->isContentPage() && $nt->isContentPage()) { # Now a content page # Not viewed, edited, adding $u = new SiteStatsUpdate(0, 1, +1, $pageCountChange); } elseif ($pageCountChange) { # Redirect added $u = new SiteStatsUpdate(0, 0, 0, 1); } else { # Nothing special $u = false; } if ($u) { $u->doUpdate(); } # Update message cache for interface messages if ($nt->getNamespace() == NS_MEDIAWIKI) { global $wgMessageCache; # @bug 17860: old article can be deleted, if this the case, # delete it from message cache if ($this->getArticleID() === 0) { $wgMessageCache->replace($this->getDBkey(), false); } else { $oldarticle = new Article($this); $wgMessageCache->replace($this->getDBkey(), $oldarticle->getContent()); } $newarticle = new Article($nt); $wgMessageCache->replace($nt->getDBkey(), $newarticle->getContent()); } global $wgUser; wfRunHooks('TitleMoveComplete', array(&$this, &$nt, &$wgUser, $pageid, $redirid)); return true; }
function poArticleProtectComplete(&$article, &$user, $protect, $reason) { // MediaWiki documentation indicates a fifth argument $moveonly (boolean whether it was // for move only or not), but there are only four args $title = $article->getTitle(); wfDebugLog('ProtectOwn', 'ArticleProtectComplete: purging title cache' . ' title="' . $title->getPrefixedDBkey() . '"[' . $title->getArticleId() . ']'); # purge page's restrictions $article->getTitle()->mRestrictions = array(); $article->getTitle()->mRestrictionsLoaded = false; //$article->getTitle()->loadRestrictions(); // Purge caches on page update etc WikiPage::onArticleEdit($title); // this put update in $wgDeferredUpdateList wfDoUpdates(); // this execute all updates in $wgDeferredUpdateList // Update page_touched, this is usually implicit in the page update $title->invalidateCache(); // ask mediawiki to reload search engine cache $u = new SearchUpdate($title->getArticleId(), $title->getPrefixedDBkey(), Revision::newFromTitle($title)->getText()); $u->doUpdate(); // will call wfRunHooks( 'SearchUpdate', array( $this->mId, $this->mNamespace, $this->mTitle, &$text ) ); // continue hook processing return true; }
private function doUpdateSearchIndex($start, $end, $maxLockTime) { global $wgDisableSearchUpdate; $wgDisableSearchUpdate = false; $dbw = wfGetDB(DB_MASTER); $recentchanges = $dbw->tableName('recentchanges'); $this->output("Updating searchindex between {$start} and {$end}\n"); # Select entries from recentchanges which are on top and between the specified times $start = $dbw->timestamp($start); $end = $dbw->timestamp($end); $page = $dbw->tableName('page'); $sql = "SELECT rc_cur_id,rc_type,rc_moved_to_ns,rc_moved_to_title FROM {$recentchanges}\n\t\t JOIN {$page} ON rc_cur_id=page_id AND rc_this_oldid=page_latest\n\t\t WHERE rc_timestamp BETWEEN '{$start}' AND '{$end}'\n\t\t "; $res = $dbw->query($sql, __METHOD__); # Lock searchindex if ($maxLockTime) { $this->output(" --- Waiting for lock ---"); $this->lockSearchindex($dbw); $lockTime = time(); $this->output("\n"); } # Loop through the results and do a search update foreach ($res as $row) { # Allow reads to be processed if ($maxLockTime && time() > $lockTime + $maxLockTime) { $this->output(" --- Relocking ---"); $this->relockSearchindex($dbw); $lockTime = time(); $this->output("\n"); } if ($row->rc_type == RC_LOG) { continue; } elseif ($row->rc_type == RC_MOVE || $row->rc_type == RC_MOVE_OVER_REDIRECT) { # Rename searchindex entry $titleObj = Title::makeTitle($row->rc_moved_to_ns, $row->rc_moved_to_title); $title = $titleObj->getPrefixedDBkey(); $this->output("{$title}..."); $u = new SearchUpdate($row->rc_cur_id, $title, false); $this->output("\n"); } else { // Get current revision $rev = Revision::loadFromPageId($dbw, $row->rc_cur_id); if ($rev) { $titleObj = $rev->getTitle(); $title = $titleObj->getPrefixedDBkey(); $this->output($title); # Update searchindex $u = new SearchUpdate($row->rc_cur_id, $titleObj->getText(), $rev->getText()); $u->doUpdate(); $this->output("\n"); } } } # Unlock searchindex if ($maxLockTime) { $this->output(" --- Unlocking --"); $this->unlockSearchindex($dbw); $this->output("\n"); } $this->output("Done\n"); }