'DeleteDefaultMessages' => __DIR__ . '/maintenance/deleteDefaultMessages.php',
'DeleteEqualMessages' => __DIR__ . '/maintenance/deleteEqualMessages.php',
'DeleteFileOp' => __DIR__ . '/includes/filebackend/FileOp.php',
+ 'DeleteLinksJob' => __DIR__ . '/includes/jobqueue/jobs/DeleteLinksJob.php',
'DeleteLogFormatter' => __DIR__ . '/includes/logging/DeleteLogFormatter.php',
'DeleteOldRevisions' => __DIR__ . '/maintenance/deleteOldRevisions.php',
'DeleteOrphanedRevisions' => __DIR__ . '/maintenance/deleteOrphanedRevisions.php',
*/
$wgJobClasses = array(
'refreshLinks' => 'RefreshLinksJob',
+ 'deleteLinks' => 'DeleteLinksJob',
'htmlCacheUpdate' => 'HTMLCacheUpdateJob',
'sendMail' => 'EmaillingJob',
'enotifNotify' => 'EnotifNotifyJob',
*
* @file
*/
-
/**
* Update object handling the cleanup of links tables after a page was deleted.
**/
-class LinksDeletionUpdate extends SqlDataUpdate {
- /** @var WikiPage The WikiPage that was deleted */
- protected $mPage;
+class LinksDeletionUpdate extends SqlDataUpdate implements EnqueueableDataUpdate {
+ /** @var WikiPage */
+ protected $page;
+ /** @var integer */
+ protected $pageId;
/**
- * Constructor
- *
* @param WikiPage $page Page we are updating
+ * @param integer|null $pageId ID of the page we are updating [optional]
* @throws MWException
*/
- function __construct( WikiPage $page ) {
+ function __construct( WikiPage $page, $pageId = null ) {
parent::__construct( false ); // no implicit transaction
- $this->mPage = $page;
-
- if ( !$page->exists() ) {
+ $this->page = $page;
+ if ( $page->exists() ) {
+ $this->pageId = $page->getId();
+ } elseif ( $pageId ) {
+ $this->pageId = $pageId;
+ } else {
throw new MWException( "Page ID not known, perhaps the page doesn't exist?" );
}
}
- /**
- * Do some database updates after deletion
- */
public function doUpdate() {
- $title = $this->mPage->getTitle();
- $id = $this->mPage->getId();
+ # Page may already be deleted, so don't just getId()
+ $id = $this->pageId;
# Delete restrictions for it
$this->mDb->delete( 'page_restrictions', array( 'pr_page' => $id ), __METHOD__ );
# Fix category table counts
- $cats = array();
- $res = $this->mDb->select( 'categorylinks', 'cl_to', array( 'cl_from' => $id ), __METHOD__ );
-
- foreach ( $res as $row ) {
- $cats[] = $row->cl_to;
- }
-
- $this->mPage->updateCategoryCounts( array(), $cats );
+ $cats = $this->mDb->selectFieldValues(
+ 'categorylinks',
+ 'cl_to',
+ array( 'cl_from' => $id ),
+ __METHOD__
+ );
+ $this->page->updateCategoryCounts( array(), $cats );
# If using cascading deletes, we can skip some explicit deletes
if ( !$this->mDb->cascadingDeletes() ) {
# If using cleanup triggers, we can skip some manual deletes
if ( !$this->mDb->cleanupTriggers() ) {
+ $title = $this->page->getTitle();
# Find recentchanges entries to clean up...
$rcIdsForTitle = $this->mDb->selectFieldValues( 'recentchanges',
'rc_id',
}
}
}
+
+ public function getAsJobSpecification() {
+ return array(
+ 'wiki' => $this->mDb->getWikiID(),
+ 'job' => new JobSpecification(
+ 'deleteLinks',
+ array( 'pageId' => $this->page->getId() ),
+ array( 'removeDuplicates' => true ),
+ $this->page->getTitle()
+ )
+ );
+ }
}
--- /dev/null
+<?php
+/**
+ * Job to update link tables for pages
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup JobQueue
+ */
+
+/**
+ * Job to prune link tables for pages that were deleted
+ *
+ * Only DataUpdate classes should construct these jobs
+ *
+ * @ingroup JobQueue
+ * @since 1.26
+ */
+class DeleteLinksJob extends Job {
+ function __construct( Title $title, array $params ) {
+ parent::__construct( 'deleteLinks', $title, $params );
+ $this->removeDuplicates = true;
+ }
+
+ function run() {
+ if ( is_null( $this->title ) ) {
+ $this->setLastError( "deleteLinks: Invalid title" );
+ return false;
+ }
+
+ $pageId = $this->params['pageId'];
+ if ( WikiPage::newFromID( $pageId, WikiPage::READ_LATEST ) ) {
+ // The page was restored somehow or something went wrong
+ $this->setLastError( "deleteLinks: Page #$pageId exists" );
+ return false;
+ }
+
+ $page = WikiPage::factory( $this->title ); // title when deleted
+ $update = new LinksDeletionUpdate( $page, $pageId );
+ DataUpdate::runUpdates( array( $update ) );
+
+ return true;
+ }
+}
* may already return null when the page proper was deleted.
*/
public function doDeleteUpdates( $id, Content $content = null ) {
- // update site status
+ // Update site status
DeferredUpdates::addUpdate( new SiteStatsUpdate( 0, 1, - (int)$this->isCountable(), -1 ) );
- // remove secondary indexes, etc
+ // Delete pagelinks, update secondary indexes, etc
$updates = $this->getDeletionUpdates( $content );
- DataUpdate::runUpdates( $updates, 'enqueue' );
+ // Make sure an enqueued jobs run after commit so they see the deletion
+ wfGetDB( DB_MASTER )->onTransactionIdle( function() use ( $updates ) {
+ DataUpdate::runUpdates( $updates, 'enqueue' );
+ } );
// Reparse any pages transcluding this page
LinksUpdate::queueRecursiveJobsForTable( $this->mTitle, 'templatelinks' );
"Title::exists should return false after page was deleted"
);
+ // Run the job queue
+ JobQueueGroup::destroySingletons();
+ $jobs = new RunJobs;
+ $jobs->loadParamsAndArgs( null, array( 'quiet' => true ), null );
+ $jobs->execute();
+
# ------------------------
$dbr = wfGetDB( DB_SLAVE );
$res = $dbr->select( 'pagelinks', '*', array( 'pl_from' => $id ) );
);
$id = $page->getId();
+ // Similar to MovePage logic
+ wfGetDB( DB_MASTER )->delete( 'page', array( 'page_id' => $id ), __METHOD__ );
$page->doDeleteUpdates( $id );
+ // Run the job queue
+ JobQueueGroup::destroySingletons();
+ $jobs = new RunJobs;
+ $jobs->loadParamsAndArgs( null, array( 'quiet' => true ), null );
+ $jobs->execute();
+
# ------------------------
$dbr = wfGetDB( DB_SLAVE );
$res = $dbr->select( 'pagelinks', '*', array( 'pl_from' => $id ) );