| Index: trunk/phase3/includes/specials/SpecialRecentchangeslinked.php |
| — | — | @@ -56,45 +56,94 @@ |
| 57 | 57 | |
| 58 | 58 | $wgOut->setPageTitle( wfMsg( 'recentchangeslinked-title', $title->getPrefixedText() ) ); |
| 59 | 59 | |
| | 60 | + /* |
| | 61 | + * Ordinary links are in the pagelinks table, while transclusions are |
| | 62 | + * in the templatelinks table, categorizations in categorylinks and |
| | 63 | + * image use in imagelinks. We need to somehow combine all these. |
| | 64 | + * Special:Whatlinkshere does this by firing multiple queries and |
| | 65 | + * merging the results, but the code we inherit from our parent class |
| | 66 | + * expects only one result set so we use UNION instead. |
| | 67 | + */ |
| | 68 | + |
| 60 | 69 | $dbr = wfGetDB( DB_SLAVE, 'recentchangeslinked' ); |
| 61 | 70 | $id = $title->getArticleId(); |
| | 71 | + $ns = $title->getNamespace(); |
| | 72 | + $dbkey = $title->getDBkey(); |
| 62 | 73 | |
| 63 | 74 | $tables = array( 'recentchanges' ); |
| 64 | 75 | $select = array( $dbr->tableName( 'recentchanges' ) . '.*' ); |
| 65 | 76 | $join_conds = array(); |
| 66 | 77 | |
| 67 | | - if( $title->getNamespace() == NS_CATEGORY ) { |
| 68 | | - $tables[] = 'categorylinks'; |
| 69 | | - $conds['cl_to'] = $title->getDBkey(); |
| 70 | | - $join_conds['categorylinks'] = array( 'LEFT JOIN', 'cl_from=rc_cur_id' ); |
| | 78 | + // left join with watchlist table to highlight watched rows |
| | 79 | + if( $uid = $wgUser->getId() ) { |
| | 80 | + $tables[] = 'watchlist'; |
| | 81 | + $select[] = 'wl_user'; |
| | 82 | + $join_conds['watchlist'] = array( 'LEFT JOIN', "wl_user={$uid} AND wl_title=rc_title AND wl_namespace=rc_namespace" ); |
| | 83 | + } |
| | 84 | + |
| | 85 | + // XXX: parent class does this, should we too? |
| | 86 | + // wfRunHooks('SpecialRecentChangesQuery', array( &$conds, &$tables, &$join_conds, $opts ) ); |
| | 87 | + |
| | 88 | + if( $ns == NS_CATEGORY && !$showlinkedto ) { |
| | 89 | + // special handling for categories |
| | 90 | + // XXX: should try to make this less klugy |
| | 91 | + $link_tables = array( 'categorylinks' ); |
| | 92 | + $showlinkedto = true; |
| 71 | 93 | } else { |
| | 94 | + // for now, always join on these tables; really should be configurable as in whatlinkshere |
| | 95 | + $link_tables = array( 'pagelinks', 'templatelinks' ); |
| | 96 | + // imagelinks only contains links to pages in NS_IMAGE |
| | 97 | + if( $ns == NS_IMAGE || !$showlinkedto ) $link_tables[] = 'imagelinks'; |
| | 98 | + } |
| | 99 | + |
| | 100 | + // field name prefixes for all the various tables we might want to join with |
| | 101 | + $prefix = array( 'pagelinks' => 'pl', 'templatelinks' => 'tl', 'categorylinks' => 'cl', 'imagelinks' => 'il' ); |
| | 102 | + |
| | 103 | + $subsql = array(); // SELECT statements to combine with UNION |
| | 104 | + |
| | 105 | + foreach( $link_tables as $link_table ) { |
| | 106 | + $pfx = $prefix[$link_table]; |
| | 107 | + |
| | 108 | + // imagelinks and categorylinks tables have no xx_namespace field, and have xx_to instead of xx_title |
| | 109 | + if( $link_table == 'imagelinks' ) $link_ns = NS_IMAGE; |
| | 110 | + else if( $link_table == 'categorylinks' ) $link_ns = NS_CATEGORY; |
| | 111 | + else $link_ns = 0; |
| | 112 | + |
| 72 | 113 | if( $showlinkedto ) { |
| 73 | | - if( $title->getNamespace() == NS_TEMPLATE ){ |
| 74 | | - $tables[] = 'templatelinks'; |
| 75 | | - $conds['tl_namespace'] = $title->getNamespace(); |
| 76 | | - $conds['tl_title'] = $title->getDBkey(); |
| 77 | | - $join_conds['templatelinks'] = array( 'LEFT JOIN', 'tl_from=rc_cur_id' ); |
| | 114 | + // find changes to pages linking to this page |
| | 115 | + if( $link_ns ) { |
| | 116 | + if( $ns != $link_ns ) continue; // should never happen, but check anyway |
| | 117 | + $subconds = array( "{$pfx}_to" => $dbkey ); |
| 78 | 118 | } else { |
| 79 | | - $tables[] = 'pagelinks'; |
| 80 | | - $conds['pl_namespace'] = $title->getNamespace(); |
| 81 | | - $conds['pl_title'] = $title->getDBkey(); |
| 82 | | - $join_conds['pagelinks'] = array( 'LEFT JOIN', 'pl_from=rc_cur_id' ); |
| | 119 | + $subconds = array( "{$pfx}_namespace" => $ns, "{$pfx}_title" => $dbkey ); |
| 83 | 120 | } |
| | 121 | + $subjoin = "rc_cur_id = {$pfx}_from"; |
| 84 | 122 | } else { |
| 85 | | - $tables[] = 'pagelinks'; |
| 86 | | - $conds['pl_from'] = $id; |
| 87 | | - $join_conds['pagelinks'] = array( 'LEFT JOIN', 'pl_namespace = rc_namespace AND pl_title = rc_title' ); |
| | 123 | + // find changes to pages linked from this page |
| | 124 | + $subconds = array( "{$pfx}_from" => $id ); |
| | 125 | + if( $link_table == 'imagelinks' || $link_table == 'categorylinks' ) { |
| | 126 | + $subconds["rc_namespace"] = $link_ns; |
| | 127 | + $subjoin = "rc_title = {$pfx}_to"; |
| | 128 | + } else { |
| | 129 | + $subjoin = "rc_namespace = {$pfx}_namespace AND rc_title = {$pfx}_title"; |
| | 130 | + } |
| 88 | 131 | } |
| | 132 | + |
| | 133 | + $subsql[] = $dbr->selectSQLText( array_merge( $tables, array( $link_table ) ), $select, $conds + $subconds, |
| | 134 | + __METHOD__, array( 'ORDER BY' => 'rc_timestamp DESC', 'LIMIT' => $limit ), |
| | 135 | + $join_conds + array( $link_table => array( 'INNER JOIN', $subjoin ) ) ); |
| 89 | 136 | } |
| 90 | 137 | |
| 91 | | - if( $uid = $wgUser->getId() ) { |
| 92 | | - $tables[] = 'watchlist'; |
| 93 | | - $join_conds['watchlist'] = array( 'LEFT JOIN', "wl_user={$uid} AND wl_title=rc_title AND wl_namespace=rc_namespace" ); |
| 94 | | - $select[] = 'wl_user'; |
| | 138 | + if( count($subsql) == 0 ) |
| | 139 | + return false; // should never happen |
| | 140 | + if( count($subsql) == 1 ) |
| | 141 | + $sql = $subsql[0]; |
| | 142 | + else { |
| | 143 | + // need to resort and relimit after union |
| | 144 | + $sql = "(" . implode( ") UNION (", $subsql ) . ") ORDER BY rc_timestamp DESC LIMIT {$limit}"; |
| 95 | 145 | } |
| 96 | 146 | |
| 97 | | - $res = $dbr->select( $tables, $select, $conds, __METHOD__, |
| 98 | | - array( 'ORDER BY' => 'rc_timestamp DESC', 'LIMIT' => $limit ), $join_conds ); |
| | 147 | + $res = $dbr->query( $sql, __METHOD__ ); |
| 99 | 148 | |
| 100 | 149 | if( $dbr->numRows( $res ) == 0 ) |
| 101 | 150 | $this->mResultEmpty = true; |
| Index: trunk/phase3/RELEASE-NOTES |
| — | — | @@ -191,7 +191,10 @@ |
| 192 | 192 | * (bug 9736) Redirects on Special:Fewestrevisions are now marked as such. |
| 193 | 193 | * New date/time formats in Cs localization according to ČSN and PČP. |
| 194 | 194 | * (bug 14883) Create hook AlternateSkinPreferences to alternate skin section in user preferences |
| 195 | | - |
| | 195 | +* Special:Recentchangeslinked now includes changes to transcluded pages and |
| | 196 | + displayed images; also, the "Show changes to pages linked" checkbox now works on |
| | 197 | + category pages too, showing all links that are not categorizations |
| | 198 | + |
| 196 | 199 | === Bug fixes in 1.13 === |
| 197 | 200 | |
| 198 | 201 | * (bug 10677) Add link to the file description page on the shared repository |