Index: branches/querypage-work/phase3/includes/Linker.php |
— | — | @@ -275,7 +275,7 @@ |
276 | 276 | } |
277 | 277 | |
278 | 278 | # Note that redirects never count as stubs here. |
279 | | - if ( $target->isRedirect() ) { |
| 279 | + if ( !in_array( 'broken', $options ) && $target->isRedirect() ) { |
280 | 280 | $classes[] = 'mw-redirect'; |
281 | 281 | } elseif( $target->isContentPage() ) { |
282 | 282 | # Check for stub. |
Index: branches/querypage-work/phase3/includes/specials/SpecialDisambiguations.php |
— | — | @@ -21,63 +21,6 @@ |
22 | 22 | return wfMsgExt( 'disambiguations-text', array( 'parse' ) ); |
23 | 23 | } |
24 | 24 | |
25 | | - function getSQL() { |
26 | | - $dbr = wfGetDB( DB_SLAVE ); |
27 | | - |
28 | | - $dMsgText = wfMsgForContent('disambiguationspage'); |
29 | | - |
30 | | - $linkBatch = new LinkBatch; |
31 | | - |
32 | | - # If the text can be treated as a title, use it verbatim. |
33 | | - # Otherwise, pull the titles from the links table |
34 | | - $dp = Title::newFromText($dMsgText); |
35 | | - if( $dp ) { |
36 | | - if($dp->getNamespace() != NS_TEMPLATE) { |
37 | | - # FIXME we assume the disambiguation message is a template but |
38 | | - # the page can potentially be from another namespace :/ |
39 | | - wfDebug("Mediawiki:disambiguationspage message does not refer to a template!\n"); |
40 | | - } |
41 | | - $linkBatch->addObj( $dp ); |
42 | | - } else { |
43 | | - # Get all the templates linked from the Mediawiki:Disambiguationspage |
44 | | - $disPageObj = Title::makeTitleSafe( NS_MEDIAWIKI, 'disambiguationspage' ); |
45 | | - $res = $dbr->select( |
46 | | - array('pagelinks', 'page'), |
47 | | - 'pl_title', |
48 | | - array('page_id = pl_from', 'pl_namespace' => NS_TEMPLATE, |
49 | | - 'page_namespace' => $disPageObj->getNamespace(), 'page_title' => $disPageObj->getDBkey()), |
50 | | - __METHOD__ ); |
51 | | - |
52 | | - while ( $row = $dbr->fetchObject( $res ) ) { |
53 | | - $linkBatch->addObj( Title::makeTitle( NS_TEMPLATE, $row->pl_title )); |
54 | | - } |
55 | | - |
56 | | - $dbr->freeResult( $res ); |
57 | | - } |
58 | | - |
59 | | - $set = $linkBatch->constructSet( 'lb.tl', $dbr ); |
60 | | - if( $set === false ) { |
61 | | - # We must always return a valid sql query, but this way DB will always quicly return an empty result |
62 | | - $set = 'FALSE'; |
63 | | - wfDebug("Mediawiki:disambiguationspage message does not link to any templates!\n"); |
64 | | - } |
65 | | - |
66 | | - list( $page, $pagelinks, $templatelinks) = $dbr->tableNamesN( 'page', 'pagelinks', 'templatelinks' ); |
67 | | - |
68 | | - $sql = "SELECT 'Disambiguations' AS \"type\", pb.page_namespace AS namespace," |
69 | | - ." pb.page_title AS title, la.pl_from AS value" |
70 | | - ." FROM {$templatelinks} AS lb, {$page} AS pb, {$pagelinks} AS la, {$page} AS pa" |
71 | | - ." WHERE $set" # disambiguation template(s) |
72 | | - .' AND pa.page_id = la.pl_from' |
73 | | - .' AND pa.page_namespace = ' . NS_MAIN # Limit to just articles in the main namespace |
74 | | - .' AND pb.page_id = lb.tl_from' |
75 | | - .' AND pb.page_namespace = la.pl_namespace' |
76 | | - .' AND pb.page_title = la.pl_title' |
77 | | - .' ORDER BY lb.tl_namespace, lb.tl_title'; |
78 | | - |
79 | | - return $sql; |
80 | | - } |
81 | | - |
82 | 25 | function getQueryInfo() { |
83 | 26 | $dbr = wfGetDB( DB_SLAVE ); |
84 | 27 | $dMsgText = wfMsgForContent('disambiguationspage'); |
— | — | @@ -139,7 +82,23 @@ |
140 | 83 | function sortDescending() { |
141 | 84 | return false; |
142 | 85 | } |
| 86 | + |
| 87 | + /** |
| 88 | + * Fetch links and cache their existence |
| 89 | + */ |
| 90 | + function preprocessResults( $db, $res ) { |
| 91 | + $batch = new LinkBatch; |
| 92 | + while ( $row = $db->fetchObject( $res ) ) |
| 93 | + $batch->add( $row->namespace, $row->title ); |
| 94 | + $batch->execute(); |
143 | 95 | |
| 96 | + // Back to start for display |
| 97 | + if ( $db->numRows( $res ) > 0 ) |
| 98 | + // If there are no rows we get an error seeking. |
| 99 | + $db->dataSeek( $res, 0 ); |
| 100 | + } |
| 101 | + |
| 102 | + |
144 | 103 | function formatResult( $skin, $result ) { |
145 | 104 | global $wgContLang; |
146 | 105 | $title = Title::newFromID( $result->value ); |
Index: branches/querypage-work/phase3/includes/specials/SpecialBrokenRedirects.php |
— | — | @@ -16,8 +16,10 @@ |
17 | 17 | return 'BrokenRedirects'; |
18 | 18 | } |
19 | 19 | |
| 20 | + // inexpensive? |
20 | 21 | function isExpensive() { return true; } |
21 | 22 | function isSyndicated() { return false; } |
| 23 | + function sortDescending() { return false; } |
22 | 24 | |
23 | 25 | function getPageHeader() { |
24 | 26 | return wfMsgExt( 'brokenredirectstext', array( 'parse' ) ); |
— | — | @@ -46,8 +48,7 @@ |
47 | 49 | } |
48 | 50 | |
49 | 51 | function getOrderFields() { |
50 | | - // FIXME: really? |
51 | | - return array (); |
| 52 | + return array ( 'rd_namespace', 'rd_title', 'rd_from' ); |
52 | 53 | } |
53 | 54 | |
54 | 55 | function formatResult( $skin, $result ) { |
Index: branches/querypage-work/phase3/includes/specials/SpecialUnwatchedpages.php |
— | — | @@ -16,6 +16,7 @@ |
17 | 17 | class UnwatchedpagesPage extends QueryPage { |
18 | 18 | |
19 | 19 | function getName() { return 'Unwatchedpages'; } |
| 20 | + // inexpensive? |
20 | 21 | function isExpensive() { return true; } |
21 | 22 | function isSyndicated() { return false; } |
22 | 23 | |
— | — | @@ -36,6 +37,9 @@ |
37 | 38 | } |
38 | 39 | |
39 | 40 | function sortDescending() { return false; } |
| 41 | + |
| 42 | + function getOrderFields() { |
| 43 | + return array( 'page_namespace', 'page_title' ); |
40 | 44 | |
41 | 45 | function formatResult( $skin, $result ) { |
42 | 46 | global $wgContLang; |
Index: branches/querypage-work/phase3/includes/specials/SpecialLonelypages.php |
— | — | @@ -22,6 +22,7 @@ |
23 | 23 | return false; |
24 | 24 | } |
25 | 25 | |
| 26 | + // inexpensive? |
26 | 27 | function isExpensive() { |
27 | 28 | return true; |
28 | 29 | } |
— | — | @@ -49,6 +50,15 @@ |
50 | 51 | 'tl_title = page_title' ) ) ) |
51 | 52 | ); |
52 | 53 | } |
| 54 | + |
| 55 | + function getOrderFields() { |
| 56 | + // For some crazy reason ordering by a constant |
| 57 | + // causes a filesort |
| 58 | + if( count( MWNamespace::getContentNamespaces() ) > 1 ) |
| 59 | + return array( 'page_namespace', 'page_title' ); |
| 60 | + else |
| 61 | + return array( 'page_title' ); |
| 62 | + } |
53 | 63 | } |
54 | 64 | |
55 | 65 | /** |
Index: branches/querypage-work/phase3/includes/specials/SpecialUncategorizedpages.php |
— | — | @@ -20,6 +20,7 @@ |
21 | 21 | return false; |
22 | 22 | } |
23 | 23 | |
| 24 | + // inexpensive? |
24 | 25 | function isExpensive() { |
25 | 26 | return true; |
26 | 27 | } |
— | — | @@ -40,6 +41,14 @@ |
41 | 42 | 'LEFT JOIN', 'cl_from = page_id' ) ) |
42 | 43 | ); |
43 | 44 | } |
| 45 | + |
| 46 | + function getOrderFields() { |
| 47 | + // For some crazy reason ordering by a constant |
| 48 | + // causes a filesort |
| 49 | + if( $this->requestedNamespace === false && count( MWNamespace::getContentNamespaces() ) > 1 ) |
| 50 | + return array( 'page_namespace', 'page_title' ); |
| 51 | + return array( 'page_title' ); |
| 52 | + } |
44 | 53 | } |
45 | 54 | |
46 | 55 | /** |
Index: branches/querypage-work/phase3/includes/specials/SpecialMostlinkedtemplates.php |
— | — | @@ -84,7 +84,7 @@ |
85 | 85 | * @return string |
86 | 86 | */ |
87 | 87 | public function formatResult( $skin, $result ) { |
88 | | - $title = Title::makeTitleSafe( $result->namespace, $result->title ); |
| 88 | + $title = Title::makeTitle( $result->namespace, $result->title ); |
89 | 89 | |
90 | 90 | $skin->link( $title ); |
91 | 91 | return wfSpecialList( |
Index: branches/querypage-work/phase3/includes/specials/SpecialUnusedcategories.php |
— | — | @@ -9,6 +9,7 @@ |
10 | 10 | */ |
11 | 11 | class UnusedCategoriesPage extends QueryPage { |
12 | 12 | |
| 13 | + // inexpensive? |
13 | 14 | function isExpensive() { return true; } |
14 | 15 | |
15 | 16 | function getName() { |
— | — | @@ -35,7 +36,7 @@ |
36 | 37 | |
37 | 38 | function formatResult( $skin, $result ) { |
38 | 39 | $title = Title::makeTitle( NS_CATEGORY, $result->title ); |
39 | | - return $skin->link( $title, $title->getText() ); |
| 40 | + return $skin->makeKnownLinkObj( $title, $title->getText() ); |
40 | 41 | } |
41 | 42 | } |
42 | 43 | |
Index: branches/querypage-work/phase3/includes/specials/SpecialShortpages.php |
— | — | @@ -15,9 +15,9 @@ |
16 | 16 | return 'Shortpages'; |
17 | 17 | } |
18 | 18 | |
| 19 | + // inexpensive? |
19 | 20 | /** |
20 | 21 | * This query is indexed as of 1.5 |
21 | | - * FIXME: Mark as inexpensive |
22 | 22 | */ |
23 | 23 | function isExpensive() { |
24 | 24 | return true; |
— | — | @@ -60,7 +60,7 @@ |
61 | 61 | global $wgLang, $wgContLang; |
62 | 62 | $dm = $wgContLang->getDirMark(); |
63 | 63 | |
64 | | - $title = Title::makeTitleSafe( $result->namespace, $result->title ); |
| 64 | + $title = Title::makeTitle( $result->namespace, $result->title ); |
65 | 65 | if ( !$title ) { |
66 | 66 | return '<!-- Invalid title ' . htmlspecialchars( "{$result->namespace}:{$result->title}" ). '-->'; |
67 | 67 | } |
— | — | @@ -70,9 +70,9 @@ |
71 | 71 | : $skin->makeKnownLinkObj( $title ); |
72 | 72 | $size = wfMsgExt( 'nbytes', array( 'parsemag', 'escape' ), $wgLang->formatNum( htmlspecialchars( $result->value ) ) ); |
73 | 73 | |
74 | | - return $title->exists() |
75 | | - ? "({$hlink}) {$dm}{$plink} {$dm}[{$size}]" |
76 | | - : "<s>({$hlink}) {$dm}{$plink} {$dm}[{$size}]</s>"; |
| 74 | + return ($this->isCached() && !$title->exists()) |
| 75 | + ? "<s>({$hlink}) {$dm}{$plink} {$dm}[{$size}]</s>" |
| 76 | + : "({$hlink}) {$dm}{$plink} {$dm}[{$size}]"; |
77 | 77 | } |
78 | 78 | } |
79 | 79 | |
Index: branches/querypage-work/phase3/includes/specials/SpecialUnusedtemplates.php |
— | — | @@ -14,6 +14,7 @@ |
15 | 15 | class UnusedtemplatesPage extends QueryPage { |
16 | 16 | |
17 | 17 | function getName() { return( 'Unusedtemplates' ); } |
| 18 | + // inexpensive? |
18 | 19 | function isExpensive() { return true; } |
19 | 20 | function isSyndicated() { return false; } |
20 | 21 | function sortDescending() { return false; } |
— | — | @@ -23,7 +24,7 @@ |
24 | 25 | 'tables' => array ( 'page', 'templatelinks' ), |
25 | 26 | 'fields' => array ( 'page_namespace AS namespace', |
26 | 27 | 'page_title AS title', |
27 | | - '0 AS value' ), |
| 28 | + 'page_title AS value' ), |
28 | 29 | 'conds' => array ( 'page_namespace' => NS_TEMPLATE, |
29 | 30 | 'tl_from IS NULL', |
30 | 31 | 'page_is_redirect' => 0 ), |
— | — | @@ -32,7 +33,7 @@ |
33 | 34 | 'tl_namespace = page_namespace' ) ) ) |
34 | 35 | ); |
35 | 36 | } |
36 | | - |
| 37 | + |
37 | 38 | function formatResult( $skin, $result ) { |
38 | 39 | $title = Title::makeTitle( NS_TEMPLATE, $result->title ); |
39 | 40 | $pageLink = $skin->makeKnownLinkObj( $title, '', 'redirect=no' ); |
Index: branches/querypage-work/phase3/includes/specials/SpecialWithoutinterwiki.php |
— | — | @@ -41,7 +41,12 @@ |
42 | 42 | function sortDescending() { |
43 | 43 | return false; |
44 | 44 | } |
| 45 | + |
| 46 | + function getOrderFields() { |
| 47 | + return array( 'page_namespace', 'page_title' ); |
| 48 | + } |
45 | 49 | |
| 50 | + // inexpensive? |
46 | 51 | function isExpensive() { |
47 | 52 | return true; |
48 | 53 | } |
Index: branches/querypage-work/phase3/includes/specials/SpecialUnusedimages.php |
— | — | @@ -10,6 +10,7 @@ |
11 | 11 | */ |
12 | 12 | class UnusedimagesPage extends ImageQueryPage { |
13 | 13 | |
| 14 | + // inexpensive? |
14 | 15 | function isExpensive() { return true; } |
15 | 16 | |
16 | 17 | function getName() { |
Index: branches/querypage-work/phase3/includes/specials/SpecialUncategorizedimages.php |
— | — | @@ -21,6 +21,7 @@ |
22 | 22 | return false; |
23 | 23 | } |
24 | 24 | |
| 25 | + // inexpensive? |
25 | 26 | function isExpensive() { |
26 | 27 | return true; |
27 | 28 | } |
— | — | @@ -28,17 +29,6 @@ |
29 | 30 | function isSyndicated() { |
30 | 31 | return false; |
31 | 32 | } |
32 | | - |
33 | | - function getSQL() { |
34 | | - $dbr = wfGetDB( DB_SLAVE ); |
35 | | - list( $page, $categorylinks ) = $dbr->tableNamesN( 'page', 'categorylinks' ); |
36 | | - $ns = NS_FILE; |
37 | | - |
38 | | - return "SELECT 'Uncategorizedimages' AS type, page_namespace AS namespace, |
39 | | - page_title AS title, page_title AS value |
40 | | - FROM {$page} LEFT JOIN {$categorylinks} ON page_id = cl_from |
41 | | - WHERE cl_from IS NULL AND page_namespace = {$ns} AND page_is_redirect = 0"; |
42 | | - } |
43 | 33 | |
44 | 34 | function getQueryInfo() { |
45 | 35 | return array ( |
Index: branches/querypage-work/phase3/includes/specials/SpecialDeadendpages.php |
— | — | @@ -17,13 +17,14 @@ |
18 | 18 | return wfMsgExt( 'deadendpagestext', array( 'parse' ) ); |
19 | 19 | } |
20 | 20 | |
| 21 | + // inexpensive? |
21 | 22 | /** |
22 | 23 | * LEFT JOIN is expensive |
23 | 24 | * |
24 | 25 | * @return true |
25 | 26 | */ |
26 | 27 | function isExpensive() { |
27 | | - return 1; |
| 28 | + return true; |
28 | 29 | } |
29 | 30 | |
30 | 31 | function isSyndicated() { return false; } |
— | — | @@ -51,6 +52,15 @@ |
52 | 53 | ) ) ) |
53 | 54 | ); |
54 | 55 | } |
| 56 | + |
| 57 | + function getOrderFields() { |
| 58 | + // For some crazy reason ordering by a constant |
| 59 | + // causes a filesort |
| 60 | + if( count( MWNamespace::getContentNamespaces() ) > 1 ) |
| 61 | + return array( 'page_namespace', 'page_title' ); |
| 62 | + else |
| 63 | + return array( 'page_title' ); |
| 64 | + } |
55 | 65 | } |
56 | 66 | |
57 | 67 | /** |
Index: branches/querypage-work/phase3/includes/specials/SpecialDoubleRedirects.php |
— | — | @@ -15,14 +15,16 @@ |
16 | 16 | return 'DoubleRedirects'; |
17 | 17 | } |
18 | 18 | |
19 | | - function isExpensive( ) { return true; } |
| 19 | + // inexpensive? |
| 20 | + function isExpensive() { return true; } |
20 | 21 | function isSyndicated() { return false; } |
| 22 | + function sortDescending() { return false; } |
21 | 23 | |
22 | | - function getPageHeader( ) { |
| 24 | + function getPageHeader() { |
23 | 25 | return wfMsgExt( 'doubleredirectstext', array( 'parse' ) ); |
24 | 26 | } |
25 | 27 | |
26 | | - function reallyGetQueryInfo($namespace = null, $title = null) { |
| 28 | + function reallyGetQueryInfo( $namespace = null, $title = null ) { |
27 | 29 | $limitToTitle = !( $namespace === null && $title === null ); |
28 | 30 | $retval = array ( |
29 | 31 | 'tables' => array ( 'redirect AS ra', 'redirect AS rb', |
— | — | @@ -36,7 +38,7 @@ |
37 | 39 | 'pc.page_title AS tc' ), |
38 | 40 | 'conds' => array ( 'ra.rd_from = pa.page_id', |
39 | 41 | 'pb.page_namespace = ra.rd_namespace', |
40 | | - 'pb.page_title = rb.rd_title', |
| 42 | + 'pb.page_title = ra.rd_title', |
41 | 43 | 'rb.rd_from = pb.page_id', |
42 | 44 | 'pc.page_namespace = rb.rd_namespace', |
43 | 45 | 'pc.page_title = rb.rd_title' ) |
— | — | @@ -53,8 +55,7 @@ |
54 | 56 | } |
55 | 57 | |
56 | 58 | function getOrderFields() { |
57 | | - // FIXME: really? |
58 | | - return array (); |
| 59 | + return array ( 'ra.rd_namespace', 'ra.rd_title' ); |
59 | 60 | } |
60 | 61 | |
61 | 62 | function formatResult( $skin, $result ) { |
Index: branches/querypage-work/phase3/includes/specials/SpecialListredirects.php |
— | — | @@ -15,22 +15,30 @@ |
16 | 16 | class ListredirectsPage extends QueryPage { |
17 | 17 | |
18 | 18 | function getName() { return 'Listredirects'; } |
| 19 | + // inexpensive? |
19 | 20 | function isExpensive() { return true; } |
20 | 21 | function isSyndicated() { return false; } |
21 | 22 | function sortDescending() { return false; } |
22 | 23 | |
23 | 24 | function getQueryInfo() { |
24 | | - return array ( |
25 | | - 'tables' => array ( 'page' ), |
26 | | - 'fields' => array ( 'page_namespace AS namespace', |
27 | | - 'page_title AS title' ), |
28 | | - 'conds' => array ( 'page_is_redirect' => 1 ) |
| 25 | + return array( |
| 26 | + 'tables' => array( 'page AS p1', 'redirect', 'page AS p2' ), |
| 27 | + 'fields' => array( 'p1.page_namespace AS namespace', |
| 28 | + 'p1.page_title AS title', |
| 29 | + 'rd_namespace', |
| 30 | + 'rd_title', |
| 31 | + 'p2.page_id AS redirid' ), |
| 32 | + 'conds' => array( 'p1.page_is_redirect' => 1 ), |
| 33 | + 'join_conds' => array( 'redirect' => array( |
| 34 | + 'LEFT JOIN', 'rd_from=p1.page_id' ), |
| 35 | + 'page AS p2' => array( 'LEFT JOIN', array( |
| 36 | + 'p2.page_namespace=rd_namespace', |
| 37 | + 'p2.page_title=rd_title' ) ) ) |
29 | 38 | ); |
30 | 39 | } |
31 | 40 | |
32 | 41 | function getOrderFields() { |
33 | | - // FIXME: really? |
34 | | - return array (); |
| 42 | + return array ( 'namespace', 'title' ); |
35 | 43 | } |
36 | 44 | |
37 | 45 | function formatResult( $skin, $result ) { |
— | — | @@ -38,25 +46,33 @@ |
39 | 47 | |
40 | 48 | # Make a link to the redirect itself |
41 | 49 | $rd_title = Title::makeTitle( $result->namespace, $result->title ); |
42 | | - $rd_link = $skin->link( |
| 50 | + $rd_link = $skin->makeKnownLinkObj( |
43 | 51 | $rd_title, |
44 | 52 | null, |
45 | | - array(), |
46 | | - array( 'redirect' => 'no' ) |
| 53 | + 'redirect=no' |
47 | 54 | ); |
48 | 55 | |
49 | 56 | # Find out where the redirect leads |
50 | | - $revision = Revision::newFromTitle( $rd_title ); |
51 | | - if( $revision ) { |
52 | | - # Make a link to the destination page |
53 | | - $target = Title::newFromRedirect( $revision->getText() ); |
54 | | - if( $target ) { |
55 | | - $arr = $wgContLang->getArrow() . $wgContLang->getDirMark(); |
| 57 | + $target = null; |
| 58 | + if( !is_null( $result->rd_namespace ) ) { |
| 59 | + $target = Title::makeTitle( $result->rd_namespace, $result->rd_title ); |
| 60 | + } else { |
| 61 | + $revision = Revision::newFromTitle( $rd_title ); |
| 62 | + if( $revision ) { |
| 63 | + $target = Title::newFromRedirect( $revision->getText() ); |
| 64 | + } |
| 65 | + } |
| 66 | + |
| 67 | + # Make a link to the destination page |
| 68 | + if( $target ) { |
| 69 | + $arr = $wgContLang->getArrow() . $wgContLang->getDirMark(); |
| 70 | + if( !is_null ( $result->redirid ) ) |
| 71 | + $targetLink = $skin->makeKnownLinkObj( $target ); |
| 72 | + else if( !is_null( $result->rd_namespace ) ) |
| 73 | + $targetLink = $skin->makeBrokenLinkObj( $target ); |
| 74 | + else |
56 | 75 | $targetLink = $skin->link( $target ); |
57 | | - return "$rd_link $arr $targetLink"; |
58 | | - } else { |
59 | | - return "<s>$rd_link</s>"; |
60 | | - } |
| 76 | + return "$rd_link $arr $targetLink"; |
61 | 77 | } else { |
62 | 78 | return "<s>$rd_link</s>"; |
63 | 79 | } |
Index: branches/querypage-work/phase3/includes/QueryPage.php |
— | — | @@ -162,7 +162,7 @@ |
163 | 163 | * don't let it run in miser mode. $wgDisableQueryPages causes all query |
164 | 164 | * pages to be declared expensive. Some query pages are always expensive. |
165 | 165 | */ |
166 | | - function isExpensive( ) { |
| 166 | + function isExpensive() { |
167 | 167 | global $wgDisableQueryPages; |
168 | 168 | return $wgDisableQueryPages; |
169 | 169 | } |