From 9db190c7e736ec8d063187d4241b59feaf7dc2d1 Mon Sep 17 00:00:00 2001 From: Pierre Schmitz Date: Wed, 22 Jun 2011 11:28:20 +0200 Subject: update to MediaWiki 1.17.0 --- includes/LinksUpdate.php | 164 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 120 insertions(+), 44 deletions(-) (limited to 'includes/LinksUpdate.php') diff --git a/includes/LinksUpdate.php b/includes/LinksUpdate.php index ef3374d9..b86ea565 100644 --- a/includes/LinksUpdate.php +++ b/includes/LinksUpdate.php @@ -26,11 +26,11 @@ class LinksUpdate { /** * Constructor * - * @param Title $title Title of the page we're updating - * @param ParserOutput $parserOutput Output from a full parse of this page - * @param bool $recursive Queue jobs for recursive updates? + * @param $title Title of the page we're updating + * @param $parserOutput ParserOutput: output from a full parse of this page + * @param $recursive Boolean: queue jobs for recursive updates? */ - function LinksUpdate( $title, $parserOutput, $recursive = true ) { + function __construct( $title, $parserOutput, $recursive = true ) { global $wgAntiLockFlags; if ( $wgAntiLockFlags & ALF_NO_LINK_LOCK ) { @@ -54,6 +54,7 @@ class LinksUpdate { $this->mExternals = $parserOutput->getExternalLinks(); $this->mCategories = $parserOutput->getCategories(); $this->mProperties = $parserOutput->getProperties(); + $this->mInterwikis = $parserOutput->getInterwikiLinks(); # Convert the format of the interlanguage links # I didn't want to change it in the ParserOutput, because that array is passed all @@ -66,8 +67,18 @@ class LinksUpdate { $this->mInterlangs[$key] = $title; } + foreach ( $this->mCategories as $cat => &$sortkey ) { + # If the sortkey is longer then 255 bytes, + # it truncated by DB, and then doesn't get + # matched when comparing existing vs current + # categories, causing bug 25254. + # Also. substr behaves weird when given "". + if ( $sortkey !== '' ) { + $sortkey = substr( $sortkey, 0, 255 ); + } + } + $this->mRecursive = $recursive; - $this->mTouchTmplLinks = false; wfRunHooks( 'LinksUpdateConstructed', array( &$this ) ); } @@ -115,6 +126,11 @@ class LinksUpdate { $this->incrTableUpdate( 'langlinks', 'll', $this->getInterlangDeletions( $existing ), $this->getInterlangInsertions( $existing ) ); + # Inline interwiki links + $existing = $this->getExistingInterwikis(); + $this->incrTableUpdate( 'iwlinks', 'iwl', $this->getInterwikiDeletions( $existing ), + $this->getInterwikiInsertions( $existing ) ); + # Template links $existing = $this->getExistingTemplates(); $this->incrTableUpdate( 'templatelinks', 'tl', $this->getTemplateDeletions( $existing ), @@ -175,6 +191,7 @@ class LinksUpdate { $this->dumbTableUpdate( 'templatelinks', $this->getTemplateInsertions(), 'tl_from' ); $this->dumbTableUpdate( 'externallinks', $this->getExternalInsertions(), 'el_from' ); $this->dumbTableUpdate( 'langlinks', $this->getInterlangInsertions(),'ll_from' ); + $this->dumbTableUpdate( 'iwlinks', $this->getInterwikiInsertions(),'iwl_from' ); $this->dumbTableUpdate( 'page_props', $this->getPropertyInsertions(), 'pp_page' ); # Update the cache of all the category pages and image description @@ -219,8 +236,8 @@ class LinksUpdate { /** * Invalidate the cache of a list of pages from a single namespace * - * @param integer $namespace - * @param array $dbkeys + * @param $namespace Integer + * @param $dbkeys Array */ function invalidatePages( $namespace, $dbkeys ) { if ( !count( $dbkeys ) ) { @@ -241,7 +258,7 @@ class LinksUpdate { 'page_touched < ' . $this->mDb->addQuotes( $now ) ), __METHOD__ ); - while ( $row = $this->mDb->fetchObject( $res ) ) { + foreach ( $res as $row ) { $ids[] = $row->page_id; } if ( !count( $ids ) ) { @@ -291,18 +308,6 @@ class LinksUpdate { } } - /** - * Make a WHERE clause from a 2-d NS/dbkey array - * - * @param array $arr 2-d array indexed by namespace and DB key - * @param string $prefix Field name prefix, without the underscore - */ - function makeWhereFrom2d( &$arr, $prefix ) { - $lb = new LinkBatch; - $lb->setArray( $arr ); - return $lb->constructSet( $prefix, $this->mDb ); - } - /** * Update a table by doing a delete query then an insert query * @private @@ -314,8 +319,13 @@ class LinksUpdate { $fromField = "{$prefix}_from"; } $where = array( $fromField => $this->mId ); - if ( $table == 'pagelinks' || $table == 'templatelinks' ) { - $clause = $this->makeWhereFrom2d( $deletions, $prefix ); + if ( $table == 'pagelinks' || $table == 'templatelinks' || $table == 'iwlinks' ) { + if ( $table == 'iwlinks' ) { + $baseKey = 'iwl_prefix'; + } else { + $baseKey = "{$prefix}_namespace"; + } + $clause = $this->mDb->makeWhereFrom2d( $deletions, $baseKey, "{$prefix}_title" ); if ( $clause ) { $where[] = $clause; } else { @@ -352,8 +362,6 @@ class LinksUpdate { function getLinkInsertions( $existing = array() ) { $arr = array(); foreach( $this->mLinks as $ns => $dbkeys ) { - # array_diff_key() was introduced in PHP 5.1, there is a compatibility function - # in GlobalFunctions.php $diffs = isset( $existing[$ns] ) ? array_diff_key( $dbkeys, $existing[$ns] ) : $dbkeys; foreach ( $diffs as $dbk => $id ) { $arr[] = array( @@ -421,22 +429,42 @@ class LinksUpdate { /** * Get an array of category insertions - * @param array $existing Array mapping existing category names to sort keys. If both + * + * @param $existing Array mapping existing category names to sort keys. If both * match a link in $this, the link will be omitted from the output * @private */ function getCategoryInsertions( $existing = array() ) { - global $wgContLang; + global $wgContLang, $wgCategoryCollation; $diffs = array_diff_assoc( $this->mCategories, $existing ); $arr = array(); - foreach ( $diffs as $name => $sortkey ) { + foreach ( $diffs as $name => $prefix ) { $nt = Title::makeTitleSafe( NS_CATEGORY, $name ); $wgContLang->findVariantLink( $name, $nt, true ); + + if ( $this->mTitle->getNamespace() == NS_CATEGORY ) { + $type = 'subcat'; + } elseif ( $this->mTitle->getNamespace() == NS_FILE ) { + $type = 'file'; + } else { + $type = 'page'; + } + + # Treat custom sortkeys as a prefix, so that if multiple + # things are forced to sort as '*' or something, they'll + # sort properly in the category rather than in page_id + # order or such. + $sortkey = Collation::singleton()->getSortKey( + $this->mTitle->getCategorySortkey( $prefix ) ); + $arr[] = array( 'cl_from' => $this->mId, 'cl_to' => $name, 'cl_sortkey' => $sortkey, - 'cl_timestamp' => $this->mDb->timestamp() + 'cl_timestamp' => $this->mDb->timestamp(), + 'cl_sortkey_prefix' => $prefix, + 'cl_collation' => $wgCategoryCollation, + 'cl_type' => $type, ); } return $arr; @@ -444,7 +472,8 @@ class LinksUpdate { /** * Get an array of interlanguage link insertions - * @param array $existing Array mapping existing language codes to titles + * + * @param $existing Array mapping existing language codes to titles * @private */ function getInterlangInsertions( $existing = array() ) { @@ -476,6 +505,25 @@ class LinksUpdate { return $arr; } + /** + * Get an array of interwiki insertions for passing to the DB + * Skips the titles specified by the 2-D array $existing + * @private + */ + function getInterwikiInsertions( $existing = array() ) { + $arr = array(); + foreach( $this->mInterwikis as $prefix => $dbkeys ) { + $diffs = isset( $existing[$prefix] ) ? array_diff_key( $dbkeys, $existing[$prefix] ) : $dbkeys; + foreach ( $diffs as $dbk => $id ) { + $arr[] = array( + 'iwl_from' => $this->mId, + 'iwl_prefix' => $prefix, + 'iwl_title' => $dbk + ); + } + } + return $arr; + } /** * Given an array of existing links, returns those links which are not in $this @@ -555,6 +603,23 @@ class LinksUpdate { return array_diff_assoc( $existing, $this->mProperties ); } + /** + * Given an array of existing interwiki links, returns those links which are not in $this + * and thus should be deleted. + * @private + */ + function getInterwikiDeletions( $existing ) { + $del = array(); + foreach ( $existing as $prefix => $dbkeys ) { + if ( isset( $this->mInterwikis[$prefix] ) ) { + $del[$prefix] = array_diff_key( $existing[$prefix], $this->mInterwikis[$prefix] ); + } else { + $del[$prefix] = $existing[$prefix]; + } + } + return $del; + } + /** * Get an array of existing links, as a 2-D array * @private @@ -563,13 +628,12 @@ class LinksUpdate { $res = $this->mDb->select( 'pagelinks', array( 'pl_namespace', 'pl_title' ), array( 'pl_from' => $this->mId ), __METHOD__, $this->mOptions ); $arr = array(); - while ( $row = $this->mDb->fetchObject( $res ) ) { + foreach ( $res as $row ) { if ( !isset( $arr[$row->pl_namespace] ) ) { $arr[$row->pl_namespace] = array(); } $arr[$row->pl_namespace][$row->pl_title] = 1; } - $this->mDb->freeResult( $res ); return $arr; } @@ -581,13 +645,12 @@ class LinksUpdate { $res = $this->mDb->select( 'templatelinks', array( 'tl_namespace', 'tl_title' ), array( 'tl_from' => $this->mId ), __METHOD__, $this->mOptions ); $arr = array(); - while ( $row = $this->mDb->fetchObject( $res ) ) { + foreach ( $res as $row ) { if ( !isset( $arr[$row->tl_namespace] ) ) { $arr[$row->tl_namespace] = array(); } $arr[$row->tl_namespace][$row->tl_title] = 1; } - $this->mDb->freeResult( $res ); return $arr; } @@ -599,10 +662,9 @@ class LinksUpdate { $res = $this->mDb->select( 'imagelinks', array( 'il_to' ), array( 'il_from' => $this->mId ), __METHOD__, $this->mOptions ); $arr = array(); - while ( $row = $this->mDb->fetchObject( $res ) ) { + foreach ( $res as $row ) { $arr[$row->il_to] = 1; } - $this->mDb->freeResult( $res ); return $arr; } @@ -614,10 +676,9 @@ class LinksUpdate { $res = $this->mDb->select( 'externallinks', array( 'el_to' ), array( 'el_from' => $this->mId ), __METHOD__, $this->mOptions ); $arr = array(); - while ( $row = $this->mDb->fetchObject( $res ) ) { + foreach ( $res as $row ) { $arr[$row->el_to] = 1; } - $this->mDb->freeResult( $res ); return $arr; } @@ -626,13 +687,12 @@ class LinksUpdate { * @private */ function getExistingCategories() { - $res = $this->mDb->select( 'categorylinks', array( 'cl_to', 'cl_sortkey' ), + $res = $this->mDb->select( 'categorylinks', array( 'cl_to', 'cl_sortkey_prefix' ), array( 'cl_from' => $this->mId ), __METHOD__, $this->mOptions ); $arr = array(); - while ( $row = $this->mDb->fetchObject( $res ) ) { - $arr[$row->cl_to] = $row->cl_sortkey; + foreach ( $res as $row ) { + $arr[$row->cl_to] = $row->cl_sortkey_prefix; } - $this->mDb->freeResult( $res ); return $arr; } @@ -645,12 +705,29 @@ class LinksUpdate { $res = $this->mDb->select( 'langlinks', array( 'll_lang', 'll_title' ), array( 'll_from' => $this->mId ), __METHOD__, $this->mOptions ); $arr = array(); - while ( $row = $this->mDb->fetchObject( $res ) ) { + foreach ( $res as $row ) { $arr[$row->ll_lang] = $row->ll_title; } return $arr; } + /** + * Get an array of existing inline interwiki links, as a 2-D array + * @return array (prefix => array(dbkey => 1)) + */ + protected function getExistingInterwikis() { + $res = $this->mDb->select( 'iwlinks', array( 'iwl_prefix', 'iwl_title' ), + array( 'iwl_from' => $this->mId ), __METHOD__, $this->mOptions ); + $arr = array(); + foreach ( $res as $row ) { + if ( !isset( $arr[$row->iwl_prefix] ) ) { + $arr[$row->iwl_prefix] = array(); + } + $arr[$row->iwl_prefix][$row->iwl_title] = 1; + } + return $arr; + } + /** * Get an array of existing categories, with the name in the key and sort key in the value. * @private @@ -659,10 +736,9 @@ class LinksUpdate { $res = $this->mDb->select( 'page_props', array( 'pp_propname', 'pp_value' ), array( 'pp_page' => $this->mId ), __METHOD__, $this->mOptions ); $arr = array(); - while ( $row = $this->mDb->fetchObject( $res ) ) { + foreach ( $res as $row ) { $arr[$row->pp_propname] = $row->pp_value; } - $this->mDb->freeResult( $res ); return $arr; } -- cgit v1.2.2