Index: trunk/extensions/CategoryIntersection/CategoryIntersection.alias.php |
— | — | @@ -10,7 +10,7 @@ |
11 | 11 | |
12 | 12 | /** English */ |
13 | 13 | $aliases['en'] = array( |
14 | | - 'CategoryIntersection'=> array( 'Category intersection', 'CategoryIntersection' ), |
| 14 | + 'CategoryIntersection' => array( 'Category intersection', 'CategoryIntersection' ), |
15 | 15 | ); |
16 | 16 | |
17 | 17 | /** Arabic (العربية) */ |
Index: trunk/extensions/CategoryIntersection/CategoryIntersection_body.php |
— | — | @@ -8,8 +8,8 @@ |
9 | 9 | |
10 | 10 | # Constructor |
11 | 11 | function CategoryIntersection() { |
12 | | - SpecialPage::SpecialPage("CategoryIntersection"); |
13 | | - wfLoadExtensionMessages('CategoryIntersection'); |
| 12 | + SpecialPage::SpecialPage( "CategoryIntersection" ); |
| 13 | + wfLoadExtensionMessages( 'CategoryIntersection' ); |
14 | 14 | |
15 | 15 | # Limits |
16 | 16 | $this->max_categories = 5; |
— | — | @@ -19,23 +19,23 @@ |
20 | 20 | } |
21 | 21 | |
22 | 22 | # Here plays the music |
23 | | - function execute($par) { |
| 23 | + function execute( $par ) { |
24 | 24 | global $wgRequest, $wgOut; |
25 | 25 | |
26 | 26 | $this->setHeaders(); |
27 | 27 | |
28 | 28 | # Get request data |
29 | | - $lines = $wgRequest->getText('lines'); |
30 | | - $doit = $wgRequest->getText('doit'); |
| 29 | + $lines = $wgRequest->getText( 'lines' ); |
| 30 | + $doit = $wgRequest->getText( 'doit' ); |
31 | 31 | |
32 | | - if ($doit == '') { |
| 32 | + if ( $doit == '' ) { |
33 | 33 | $output = $this->getForm(); |
34 | 34 | } else { |
35 | | - $output = $this->run($lines); |
| 35 | + $output = $this->run( $lines ); |
36 | 36 | } |
37 | 37 | |
38 | 38 | # Output |
39 | | - $wgOut->addHTML($output); |
| 39 | + $wgOut->addHTML( $output ); |
40 | 40 | } |
41 | 41 | |
42 | 42 | # Generate the submission form |
— | — | @@ -43,93 +43,99 @@ |
44 | 44 | $ret = ''; |
45 | 45 | $ret .= "<form method='post'>"; |
46 | 46 | $ret .= "<textarea name='lines' rows='10' cols='50' style='width:100%'></textarea><br />"; |
47 | | - $ret .= "<input type='submit' name='doit' value='" . wfMsgHtml('categoryintersection-doit') . "' />"; |
| 47 | + $ret .= "<input type='submit' name='doit' value='" . wfMsgHtml( 'categoryintersection-doit' ) . "' />"; |
48 | 48 | $ret .= "</form>"; |
49 | 49 | return $ret; |
50 | 50 | } |
51 | 51 | |
52 | 52 | # Do the actual work |
53 | | - function run($lines) { |
| 53 | + function run( $lines ) { |
54 | 54 | global $wgOut; |
55 | 55 | |
56 | 56 | $fname = 'CategoryIntersection::run'; |
57 | 57 | |
58 | | - $dbr = wfGetDB (DB_SLAVE); |
59 | | - $table_categoryintersections = $dbr->tableName ('categoryintersections'); |
60 | | - $table_categorylinks = $dbr->tableName ('categorylinks'); |
| 58 | + $dbr = wfGetDB ( DB_SLAVE ); |
| 59 | + $table_categoryintersections = $dbr->tableName ( 'categoryintersections' ); |
| 60 | + $table_categorylinks = $dbr->tableName ( 'categorylinks' ); |
61 | 61 | |
62 | 62 | # Parse list of categories |
63 | | - $lines = explode ("\n", $lines); |
| 63 | + $lines = explode ( "\n", $lines ); |
64 | 64 | $arr = array(); |
65 | | - foreach ($lines AS $l) { |
66 | | - $l = trim ($l); |
67 | | - if ($l == '') continue; |
68 | | - $t = Title::newFromText ($l); |
| 65 | + foreach ( $lines AS $l ) { |
| 66 | + $l = trim ( $l ); |
| 67 | + if ( $l == '' ) continue; |
| 68 | + $t = Title::newFromText ( $l ); |
69 | 69 | $arr[] = $t->getDBkey(); |
70 | 70 | } |
71 | 71 | |
72 | | - if (count ($arr) > $this->max_categories) { |
73 | | - return wfMsg('categoryintersection-maxcategories',$this->max_categories); |
| 72 | + if ( count ( $arr ) > $this->max_categories ) { |
| 73 | + return wfMsgExt( 'categoryintersection-maxcategories', 'parsemag', $this->max_categories ); |
74 | 74 | } |
75 | 75 | |
76 | 76 | # Generate hash values for all combinations |
77 | | - $hashes = CategoryIntersectionGetHashValues ($arr); |
78 | | - |
| 77 | + $hashes = CategoryIntersectionGetHashValues ( $arr ); |
| 78 | + |
79 | 79 | # Generate (sub)query chain |
80 | 80 | # TODO : Do we really need all combinations? |
81 | 81 | $query = ""; |
82 | | - foreach ($hashes AS $hash) { |
| 82 | + foreach ( $hashes AS $hash ) { |
83 | 83 | $q2 = "SELECT ci_page FROM {$table_categoryintersections} WHERE ci_hash = \"{$hash}\""; # FIXME : table/field name |
84 | | - if ($query != "") $q2 .= " AND ci_page IN ({$query})"; |
| 84 | + if ( $query != "" ) $q2 .= " AND ci_page IN ({$query})"; |
85 | 85 | $query = $q2; |
86 | 86 | } |
87 | 87 | $query .= " LIMIT " . $this->max_hash_results; # Max number of hash results |
88 | 88 | |
89 | 89 | # This is safe, as the only parameters used are hash values generated by CategoryIntersectionGetHashValues() |
90 | | - $res = $dbr->query($query, $fname); |
| 90 | + $res = $dbr->query( $query, $fname ); |
91 | 91 | |
92 | | - if (!$res) { |
| 92 | + if ( !$res ) { |
93 | 93 | return ''; |
94 | 94 | } |
95 | 95 | |
96 | 96 | # page_ids will contain the /candidates/ for results. Remember: Hashes are not necessarily unique! |
97 | 97 | $page_ids = array (); |
98 | | - while ($row = $dbr->fetchObject($res)) { |
| 98 | + while ( $row = $dbr->fetchObject( $res ) ) { |
99 | 99 | $page_ids[] = $row->ci_page; |
100 | 100 | } |
101 | 101 | |
102 | 102 | # Now check which of these are real - or don't |
103 | 103 | $titles = array (); |
104 | | - if ($this->second_check) { |
105 | | - $carr = count ($arr); |
106 | | - foreach ($page_ids AS $id) { |
107 | | - # This is safe; $arr contains only DB keys generated by Title; $id is a number from the last query |
108 | | - $query = "SELECT count(cl_to) AS x FROM {$table_categorylinks} WHERE cl_from = {$id} AND cl_to IN (\"" . implode ("\",\"", $arr) . "\") LIMIT $carr"; |
109 | | - $res = $dbr->query($query, $fname); |
110 | | - if (!$res) continue; |
111 | | - $row = $dbr->fetchObject($res); |
112 | | - $count = $row->x; |
113 | | - if ($count < $carr) continue; # This is not the article you are looking for... |
114 | | - $titles[] = Title::newFromID ($id); |
115 | | - if (count ($titles) >= $this->max_real_results) break; |
116 | | - } |
117 | | - } else { |
118 | | - foreach ($page_ids AS $id) { |
119 | | - $titles[] = Title::newFromID ( $id ) ; |
120 | | - } |
121 | | - } |
| 104 | + if ( $this->second_check ) { |
| 105 | + $carr = count ( $arr ); |
| 106 | + foreach ( $page_ids AS $id ) { |
| 107 | + # This is safe; $arr contains only DB keys generated by Title; $id is a number from the last query |
| 108 | + $query = "SELECT count(cl_to) AS x FROM {$table_categorylinks} WHERE cl_from = {$id} AND cl_to IN (\"" . implode ( "\",\"", $arr ) . "\") LIMIT $carr"; |
| 109 | + $res = $dbr->query( $query, $fname ); |
| 110 | + if ( !$res ) { |
| 111 | + continue; |
| 112 | + } |
| 113 | + $row = $dbr->fetchObject( $res ); |
| 114 | + $count = $row->x; |
| 115 | + if ( $count < $carr ) { |
| 116 | + continue; # This is not the article you are looking for... |
| 117 | + } |
| 118 | + $titles[] = Title::newFromID ( $id ); |
| 119 | + if ( count ( $titles ) >= $this->max_real_results ) { |
| 120 | + break; |
| 121 | + } |
| 122 | + } |
| 123 | + } else { |
| 124 | + foreach ( $page_ids AS $id ) { |
| 125 | + $titles[] = Title::newFromID ( $id ) ; |
| 126 | + } |
| 127 | + } |
122 | 128 | |
123 | 129 | # Generate title list in wiki markup |
124 | 130 | $wiki = ''; |
125 | | - foreach ($titles AS $t) { |
| 131 | + foreach ( $titles AS $t ) { |
126 | 132 | $ft = $t->getFullText(); |
127 | 133 | $wiki .= "# [[:{$ft}|{$ft}]]\n"; |
128 | 134 | } |
129 | | - $wgOut->addWikiText ($wiki); |
| 135 | + $wgOut->addWikiText ( $wiki ); |
130 | 136 | |
131 | 137 | # Final message |
132 | 138 | global $wgLang; |
133 | | - $count = $wgLang->formatNum( count($titles) ); |
134 | | - return '<hr/>' . wfMsgExt('categoryintersection-results', 'parse', $count); |
| 139 | + $count = $wgLang->formatNum( count( $titles ) ); |
| 140 | + return '<hr/>' . wfMsgExt( 'categoryintersection-results', 'parse', $count ); |
135 | 141 | } |
136 | 142 | } |
Index: trunk/extensions/CategoryIntersection/CategoryIntersection.i18n.php |
— | — | @@ -24,6 +24,8 @@ |
25 | 25 | */ |
26 | 26 | $messages['qqq'] = array( |
27 | 27 | 'categoryintersection-desc' => 'Shown in [[Special:Version]]. Do not translate links.', |
| 28 | + 'categoryintersection-maxcategories' => 'Parameters: |
| 29 | +* $1 is the maximum allowed number of intersecting categories. Supports plural.', |
28 | 30 | ); |
29 | 31 | |
30 | 32 | /** Afrikaans (Afrikaans) |
Index: trunk/extensions/CategoryIntersection/CategoryIntersection.php |
— | — | @@ -6,6 +6,7 @@ |
7 | 7 | * @copyright (c) 2008 by Magnus Manske |
8 | 8 | * @license Released under GPL |
9 | 9 | |
| 10 | + // FIXME: creation of table should be done through hook. |
10 | 11 | SQL for creating categoryintersections table: |
11 | 12 | |
12 | 13 | CREATE TABLE `categoryintersections` ( |
— | — | @@ -17,12 +18,12 @@ |
18 | 19 | **/ |
19 | 20 | |
20 | 21 | # Alert the user that this is not a valid entry point to MediaWiki if they try to access the skin file directly. |
21 | | -if (!defined('MEDIAWIKI')) { |
| 22 | +if ( !defined( 'MEDIAWIKI' ) ) { |
22 | 23 | echo <<<EOT |
23 | 24 | To install my extension, put the following line in LocalSettings.php: |
24 | 25 | require_once("\$IP/extensions/CategoryIntersection/CategoryIntersection.php"); |
25 | 26 | EOT; |
26 | | - exit(1); |
| 27 | + exit( 1 ); |
27 | 28 | } |
28 | 29 | |
29 | 30 | $wgExtensionCredits['other'][] = array( |
— | — | @@ -33,7 +34,7 @@ |
34 | 35 | 'descriptionmsg' => 'categoryintersection-desc', |
35 | 36 | ); |
36 | 37 | |
37 | | -$dir = dirname(__FILE__) . '/'; |
| 38 | +$dir = dirname( __FILE__ ) . '/'; |
38 | 39 | |
39 | 40 | $wgHooks['LinksUpdate'][] = 'CategoryIntersectionLinksUpdate'; |
40 | 41 | $wgHooks['ArticleDelete'][] = 'CategoryIntersectionArticleDelete'; |
— | — | @@ -43,23 +44,23 @@ |
44 | 45 | $wgExtensionAliasesFiles['CategoryIntersection'] = $dir . 'CategoryIntersection.alias.php'; |
45 | 46 | $wgSpecialPages['CategoryIntersection'] = 'CategoryIntersection'; # Let MediaWiki know about your new special page. |
46 | 47 | |
47 | | -function CategoryIntersectionGetHashValues ($categories) { |
48 | | - sort ($categories); |
| 48 | +function CategoryIntersectionGetHashValues ( $categories ) { |
| 49 | + sort ( $categories ); |
49 | 50 | $hash = array (); |
50 | 51 | $hv = array (); |
51 | | - foreach ($categories AS $k => $c1) { |
52 | | - foreach ($categories AS $c2) { |
53 | | - if ($c1 == $c2) continue; |
54 | | - if ($c1 < $c2) $key = $c1 . '|' . $c2; |
| 52 | + foreach ( $categories AS $k => $c1 ) { |
| 53 | + foreach ( $categories AS $c2 ) { |
| 54 | + if ( $c1 == $c2 ) continue; |
| 55 | + if ( $c1 < $c2 ) $key = $c1 . '|' . $c2; |
55 | 56 | else $key = $c2 . '|' . $c1; |
56 | | - if (isset ($hash[$key])) continue; // This combination was already done |
57 | | - $m = md5 ($key); |
| 57 | + if ( isset ( $hash[$key] ) ) continue; // This combination was already done |
| 58 | + $m = md5 ( $key ); |
58 | 59 | $m = hexdec ( substr ( $m , 0 , 8 ) ) ; |
59 | | - if (isset ($hv[$m])) continue; // This hash value is already in there, prevent unique index conflict |
| 60 | + if ( isset ( $hv[$m] ) ) continue; // This hash value is already in there, prevent unique index conflict |
60 | 61 | $hash[$key] = $m; |
61 | 62 | $hv[$m] = 1; |
62 | 63 | } |
63 | | - unset ($categories[$k]); // No more combinations with this |
| 64 | + unset ( $categories[$k] ); // No more combinations with this |
64 | 65 | } |
65 | 66 | return $hash; |
66 | 67 | } |
— | — | @@ -68,16 +69,15 @@ |
69 | 70 | * Updates the category intersection table for a page. |
70 | 71 | * Called by LinksUpdate hook. |
71 | 72 | */ |
72 | | -function CategoryIntersectionLinksUpdate (&$linksUpdate) { |
73 | | - |
| 73 | +function CategoryIntersectionLinksUpdate ( &$linksUpdate ) { |
74 | 74 | // Get categories |
75 | 75 | $categories = $linksUpdate->mCategories; // The keys of this array are the categories of this page, without cateogry prefix, ucfirst, underscores |
76 | | - $categories = array_keys ($categories); |
77 | | - $hash = CategoryIntersectionGetHashValues ($categories); |
| 76 | + $categories = array_keys ( $categories ); |
| 77 | + $hash = CategoryIntersectionGetHashValues ( $categories ); |
78 | 78 | |
79 | 79 | // Prepare new hash values for table insertion |
80 | 80 | $arr = array (); |
81 | | - foreach ($hash AS $k => $v) { |
| 81 | + foreach ( $hash AS $k => $v ) { |
82 | 82 | $arr[] = array ( |
83 | 83 | 'ci_page' => $linksUpdate->mId , |
84 | 84 | 'ci_hash' => $v |
— | — | @@ -85,13 +85,13 @@ |
86 | 86 | } |
87 | 87 | |
88 | 88 | // Update hash table |
89 | | - $linksUpdate->dumbTableUpdate ('categoryintersections', $arr, 'ci_page'); |
| 89 | + $linksUpdate->dumbTableUpdate ( 'categoryintersections', $arr, 'ci_page' ); |
90 | 90 | |
91 | 91 | return true; // My work here is done |
92 | 92 | } |
93 | 93 | |
94 | | -function CategoryIntersectionArticleDelete (&$article, &$user, &$reason) { |
95 | | - $dbw = wfGetDB( DB_MASTER ); |
96 | | - $dbw->delete ( 'categoryintersections' , array ( "ci_page" => $article->getID() ) ) ; |
97 | | - return true ; |
| 94 | +function CategoryIntersectionArticleDelete ( &$article, &$user, &$reason ) { |
| 95 | + $dbw = wfGetDB( DB_MASTER ); |
| 96 | + $dbw->delete ( 'categoryintersections' , array ( "ci_page" => $article->getID() ) ) ; |
| 97 | + return true ; |
98 | 98 | } |