Index: trunk/extensions/Interlanguage/InterlanguageCentral.php |
— | — | @@ -1,24 +1,27 @@ |
2 | 2 | <?php |
3 | | -# MediaWiki InterlanguageCentral extension v1.0 |
4 | | -# |
5 | | -# Copyright © 2010 Nikola Smolenski <smolensk@eunet.rs> |
6 | | -# |
7 | | -# This program is free software; you can redistribute it and/or modify |
8 | | -# it under the terms of the GNU General Public License as published by |
9 | | -# the Free Software Foundation; either version 2 of the License, or |
10 | | -# (at your option) any later version. |
11 | | -# |
12 | | -# This program is distributed in the hope that it will be useful, |
13 | | -# but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | | -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | | -# GNU General Public License for more details. |
16 | | -# |
17 | | -# You should have received a copy of the GNU General Public License |
18 | | -# along with this program; if not, write to the Free Software |
19 | | -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
20 | | -# |
21 | | -# For more information see |
22 | | -# http://www.mediawiki.org/wiki/Extension:Interlanguage |
| 3 | +/** |
| 4 | + * MediaWiki InterlanguageCentral extension v1.1 |
| 5 | + * |
| 6 | + * Copyright © 2010 Nikola Smolenski <smolensk@eunet.rs> |
| 7 | + * @version 1.1 |
| 8 | + * |
| 9 | + * This program is free software; you can redistribute it and/or modify |
| 10 | + * it under the terms of the GNU General Public License as published by |
| 11 | + * the Free Software Foundation; either version 2 of the License, or |
| 12 | + * (at your option) any later version. |
| 13 | + * |
| 14 | + * This program is distributed in the hope that it will be useful, |
| 15 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 16 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 17 | + * GNU General Public License for more details. |
| 18 | + * |
| 19 | + * You should have received a copy of the GNU General Public License |
| 20 | + * along with this program; if not, write to the Free Software |
| 21 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| 22 | + * |
| 23 | + * For more information, |
| 24 | + * @see http://www.mediawiki.org/wiki/Extension:Interlanguage |
| 25 | + */ |
23 | 26 | |
24 | 27 | $wgExtensionFunctions[]="wfInterlanguageCentralExtension"; |
25 | 28 | $wgJobClasses['purgeDependentWikis'] = 'InterlanguageCentralExtensionPurgeJob'; |
— | — | @@ -26,7 +29,7 @@ |
27 | 30 | 'name' => 'Interlanguage Central', |
28 | 31 | 'author' => 'Nikola Smolenski', |
29 | 32 | 'url' => 'http://www.mediawiki.org/wiki/Extension:Interlanguage', |
30 | | - 'version' => '1.0', |
| 33 | + 'version' => '1.1', |
31 | 34 | 'descriptionmsg' => 'interlanguagecentral-desc', |
32 | 35 | ); |
33 | 36 | $wgExtensionMessagesFiles['Interlanguagecentral'] = dirname(__FILE__) . '/InterlanguageCentral.i18n.php'; |
— | — | @@ -44,17 +47,14 @@ |
45 | 48 | //ILL = InterLanguageLinks |
46 | 49 | var $oldILL = array(); |
47 | 50 | |
48 | | - function onArticleSave() { |
49 | | - global $wgTitle; |
50 | | - $this->oldILL = $this->getILL($wgTitle); |
| 51 | + function onArticleSave( $article ) { |
| 52 | + $this->oldILL = $this->getILL($article->mTitle); |
51 | 53 | return true; |
52 | 54 | } |
53 | 55 | |
54 | | - function onArticleSaveComplete() { |
55 | | - global $wgTitle; |
| 56 | + function onArticleSaveComplete( $article ) { |
| 57 | + $newILL = $this->getILL($article->mTitle); |
56 | 58 | |
57 | | - $newILL = $this->getILL($wgTitle); |
58 | | - |
59 | 59 | //Compare ILLs before and after the save; if nothing changed, there is no need to purge |
60 | 60 | if( |
61 | 61 | count(array_udiff_assoc( |
— | — | @@ -68,7 +68,7 @@ |
69 | 69 | )) |
70 | 70 | ) { |
71 | 71 | $ill = array_merge_recursive($this->oldILL, $newILL); |
72 | | - $job = new InterlanguageCentralExtensionPurgeJob( $wgTitle, array('ill' => $ill) ); |
| 72 | + $job = new InterlanguageCentralExtensionPurgeJob( $article->mTitle, array('ill' => $ill) ); |
73 | 73 | $job->insert(); |
74 | 74 | } |
75 | 75 | |
— | — | @@ -80,14 +80,12 @@ |
81 | 81 | $dbr = wfGetDB( DB_SLAVE ); |
82 | 82 | $res = $dbr->select( 'langlinks', array( 'll_lang', 'll_title' ), array( 'll_from' => $title->mArticleID), __FUNCTION__); |
83 | 83 | $a = array(); |
84 | | - while ( $row = $dbr->fetchObject( $res ) ) { |
| 84 | + foreach( $res as $row ) { |
85 | 85 | if(!isset($a[$row->ll_lang])) { |
86 | 86 | $a[$row->ll_lang] = array(); |
87 | 87 | } |
88 | 88 | $a[$row->ll_lang][$row->ll_title] = true; |
89 | 89 | } |
90 | | - $dbr->freeResult( $res ); |
91 | | - |
92 | 90 | return $a; |
93 | 91 | } |
94 | 92 | |
— | — | @@ -117,10 +115,18 @@ |
118 | 116 | //TODO: error handling |
119 | 117 | $baseURL = sprintf($wgInterlanguageCentralExtensionIndexUrl, $lang) . |
120 | 118 | "?action=purge&title="; |
121 | | - foreach($pages as $page => $dummy) { |
| 119 | + foreach($pages as $page => $dummy) { |
122 | 120 | $url = $baseURL . urlencode(strtr($page, ' ', '_')); |
123 | 121 | Http::post( $url ); |
124 | 122 | } |
| 123 | + //TODO: activate when becomes possible |
| 124 | + /* |
| 125 | + global $wgInterlanguageCentralExtensionApiUrl; |
| 126 | + $url = sprintf($wgInterlanguageCentralExtensionApiUrl, $lang) . |
| 127 | + "?action=purge&title=" . |
| 128 | + implode( "|", array_walk( array_keys( $pages ), 'urlencode' ) ); |
| 129 | + Http::post( $url ); |
| 130 | + */ |
125 | 131 | } |
126 | 132 | |
127 | 133 | return true; |
Index: trunk/extensions/Interlanguage/Interlanguage.i18n.magic.php |
— | — | @@ -77,6 +77,16 @@ |
78 | 78 | 'interlanguage' => array( 0, 'межязык', 'interlanguage' ), |
79 | 79 | ); |
80 | 80 | |
| 81 | +/** Serbian Cyrillic ekavian (Српски (ћирилица)>) */ |
| 82 | +$messages['sr-ec'] = array( |
| 83 | + 'interlanguage' => array( '0', 'међујезичје', 'interlanguage' ), |
| 84 | +); |
| 85 | + |
| 86 | +/** Serbian Latin ekavian (Srpski (latinica)) */ |
| 87 | +$messages['sr-el'] = array( |
| 88 | + 'interlanguage' => array( '0', 'меđujezičje', 'interlanguage' ), |
| 89 | +); |
| 90 | + |
81 | 91 | /** Ukrainian (Українська) */ |
82 | 92 | $magicWords['uk'] = array( |
83 | 93 | 'interlanguage' => array( 0, 'міжмова', 'межязык', 'interlanguage' ), |
— | — | @@ -85,4 +95,4 @@ |
86 | 96 | /** Vietnamese (Tiếng Việt) */ |
87 | 97 | $magicWords['vi'] = array( |
88 | 98 | 'interlanguage' => array( 0, 'liênngônngữ' ), |
89 | | -); |
\ No newline at end of file |
| 99 | +); |
Index: trunk/extensions/Interlanguage/Interlanguage.i18n.php |
— | — | @@ -401,6 +401,7 @@ |
402 | 402 | */ |
403 | 403 | $messages['sr-ec'] = array( |
404 | 404 | 'interlanguage-desc' => 'Преузима међувики са другог пројекта', |
| 405 | + 'interlanguage-pagelinksexplanation' => 'Странице са међујезичким везама:', |
405 | 406 | ); |
406 | 407 | |
407 | 408 | /** Serbian Latin ekavian (Srpski (latinica)) */ |
Index: trunk/extensions/Interlanguage/Interlanguage.php |
— | — | @@ -1,9 +1,9 @@ |
2 | 2 | <?php |
3 | 3 | /** |
4 | | - * MediaWiki Interlanguage extension v1.3 |
| 4 | + * MediaWiki Interlanguage extension v1.4 |
5 | 5 | * |
6 | 6 | * Copyright © 2008-2010 Nikola Smolenski <smolensk@eunet.rs> and others |
7 | | - * @version 1.3 |
| 7 | + * @version 1.4 |
8 | 8 | * |
9 | 9 | * This program is free software; you can redistribute it and/or modify |
10 | 10 | * it under the terms of the GNU General Public License as published by |
— | — | @@ -29,7 +29,7 @@ |
30 | 30 | 'name' => 'Interlanguage', |
31 | 31 | 'author' => 'Nikola Smolenski', |
32 | 32 | 'url' => 'http://www.mediawiki.org/wiki/Extension:Interlanguage', |
33 | | - 'version' => '1.3', |
| 33 | + 'version' => '1.4', |
34 | 34 | 'descriptionmsg' => 'interlanguage-desc', |
35 | 35 | ); |
36 | 36 | $wgExtensionMessagesFiles['Interlanguage'] = dirname(__FILE__) . '/Interlanguage.i18n.php'; |
— | — | @@ -39,14 +39,15 @@ |
40 | 40 | global $wgParser, $wgHooks, $wgInterlanguageExtension; |
41 | 41 | |
42 | 42 | $wgInterlanguageExtension = new InterlanguageExtension(); |
43 | | - $wgHooks['LanguageGetMagic'][] = array( &$wgInterlanguageExtension, 'onLanguageGetMagic' ); |
44 | | - $wgHooks['EditPage::showEditForm:fields'][] = array( &$wgInterlanguageExtension, 'pageLinks' ); |
| 43 | + $wgHooks['LanguageGetMagic'][] = $wgInterlanguageExtension; |
| 44 | + $wgHooks['EditPage::showEditForm:fields'][] = array( $wgInterlanguageExtension, 'pageLinks' ); |
45 | 45 | $wgHooks['ArticleSaveComplete'][] = $wgInterlanguageExtension; |
46 | | - $wgParser->setFunctionHook( 'interlanguage', array( &$wgInterlanguageExtension, 'interlanguage' ), SFH_NO_HASH ); |
| 46 | + $wgParser->setFunctionHook( 'interlanguage', array( $wgInterlanguageExtension, 'interlanguage' ), SFH_NO_HASH ); |
47 | 47 | } |
48 | 48 | |
49 | 49 | class InterlanguageExtension { |
50 | 50 | var $pageLinks = array(); |
| 51 | + var $foreignDbr = false; |
51 | 52 | |
52 | 53 | function onLanguageGetMagic( &$magicWords, $langCode ) { |
53 | 54 | $magicWords['interlanguage'] = array(0, 'interlanguage'); |
— | — | @@ -60,30 +61,90 @@ |
61 | 62 | * @param $param - parameter passed to {{interlanguage:}}. |
62 | 63 | */ |
63 | 64 | function interlanguage( &$parser, $param ) { |
64 | | - global $wgInterlanguageExtensionApiUrl, $wgInterlanguageExtensionSort, |
65 | | - $wgInterlanguageExtensionPrefix, $wgInterlanguageExtensionInterwiki, |
66 | | - $wgLanguageCode, $wgTitle, $wgMemc; |
67 | | - |
68 | | - if(isset($wgInterlanguageExtensionPrefix)) { |
69 | | - $param = "$wgInterlanguageExtensionPrefix$param"; |
70 | | - } |
| 65 | + global $wgInterlanguageExtensionApiUrl, $wgInterlanguageExtensionDB, |
| 66 | + $wgInterlanguageExtensionSort, $wgInterlanguageExtensionInterwiki, $wgLanguageCode, $wgTitle, $wgMemc; |
71 | 67 | |
72 | 68 | //This will later be used by pageLinks() and onArticleSave() |
73 | 69 | $this->pageLinks[$param] = true; |
74 | 70 | |
75 | | - $url = $wgInterlanguageExtensionApiUrl . "?action=query&prop=langlinks&" . |
76 | | - "lllimit=500&format=php&redirects&titles=" . urlencode(strtr( $param, ' ', '_' )); |
77 | 71 | $key = wfMemcKey( 'Interlanguage', md5( $param ) ); |
78 | 72 | $res = $wgMemc->get( $key ); |
79 | 73 | |
80 | 74 | if ( !$res ) { |
81 | | - // be sure to set $res back to bool false, we do a strict compare below |
| 75 | + // Be sure to set $res back to bool false, we do a strict compare below |
82 | 76 | $res = false; |
83 | | - $a = Http::get( $url ); |
84 | | - $a = @unserialize( $a ); |
| 77 | + |
| 78 | + if ( isset( $wgInterlanguageExtensionDB ) ) { |
| 79 | + // Get the links from a foreign database |
| 80 | + if( !$this->foreignDbr ) { |
| 81 | + $foreignDbrClass = 'Database' . ucfirst( $wgInterlanguageExtensionDB['dbType'] ); |
| 82 | + $this->foreignDbr = new $foreignDbrClass( |
| 83 | + $wgInterlanguageExtensionDB['dbServer'], |
| 84 | + $wgInterlanguageExtensionDB['dbUser'], |
| 85 | + $wgInterlanguageExtensionDB['dbPassword'], |
| 86 | + $wgInterlanguageExtensionDB['dbName'], |
| 87 | + $wgInterlanguageExtensionDB['dbFlags'], |
| 88 | + $wgInterlanguageExtensionDB['tablePrefix'] |
| 89 | + ); |
| 90 | + } |
| 91 | + |
| 92 | + $paramTitle = Title::newFromText( $param ); |
| 93 | + if( $paramTitle ) { |
| 94 | + $dbKey = $paramTitle->mDbkeyform; |
| 95 | + $namespace = $paramTitle->mNamespace; |
| 96 | + } else { |
| 97 | + //If the title is malformed, try at least this |
| 98 | + $dbKey = strtr( $param, ' ', '_' ); |
| 99 | + $namespace = 0; |
| 100 | + } |
| 101 | + |
| 102 | + $a = array( 'query' => array( 'pages' => array() ) ); |
| 103 | + |
| 104 | + $res = $this->foreignDbr->select( |
| 105 | + 'page', |
| 106 | + array( 'page_id', 'page_is_redirect' ), |
| 107 | + array( |
| 108 | + 'page_title' => $dbKey, |
| 109 | + 'page_namespace' => $namespace |
| 110 | + ), |
| 111 | + __FUNCTION__ |
| 112 | + ); |
| 113 | + $res = $res->fetchObject(); |
| 114 | + |
| 115 | + if( $res === false ) { |
| 116 | + // There is no such article on the central wiki |
| 117 | + $a['query']['pages'][-1] = array( 'missing' => "" ); |
| 118 | + } else { |
| 119 | + if( $res->page_is_redirect ) { |
| 120 | + $res = $this->foreignDbr->select( |
| 121 | + array( 'redirect', 'page' ), |
| 122 | + 'page_id', |
| 123 | + array( |
| 124 | + 'rd_title = page_title', |
| 125 | + 'rd_from' => $res->page_id |
| 126 | + ), |
| 127 | + __FUNCTION__ |
| 128 | + ); |
| 129 | + $res = $res->fetchObject(); |
| 130 | + } |
| 131 | + |
| 132 | + $a['query']['pages'][0] = array( 'langlinks' => $this->readLinksFromDB( $this->foreignDbr, $res->page_id ) ); |
| 133 | + } |
| 134 | + } else { |
| 135 | + // Get the links from an API |
| 136 | + $title = $this->translateNamespace( $param ); |
| 137 | + |
| 138 | + $url = $wgInterlanguageExtensionApiUrl . |
| 139 | + "?action=query&prop=langlinks&" . |
| 140 | + "lllimit=500&format=php&redirects&titles=" . |
| 141 | + urlencode( $title ); |
| 142 | + $a = Http::get( $url ); |
| 143 | + $a = @unserialize( $a ); |
| 144 | + } |
| 145 | + |
85 | 146 | if(isset($a['query']['pages']) && is_array($a['query']['pages'])) { |
86 | 147 | $a = array_shift($a['query']['pages']); |
87 | | - |
| 148 | + |
88 | 149 | if(isset($a['missing'])) { |
89 | 150 | // There is no such article on the central wiki |
90 | 151 | $linker = new Linker(); |
— | — | @@ -101,16 +162,11 @@ |
102 | 163 | } |
103 | 164 | } |
104 | 165 | } |
105 | | - |
| 166 | + |
106 | 167 | if($res === false) { |
107 | 168 | // An API error has occured; preserve the links that are in the article |
108 | 169 | $dbr = wfGetDB( DB_SLAVE ); |
109 | | - $res = $dbr->select( 'langlinks', array( 'll_lang', 'll_title' ), array( 'll_from' => $wgTitle->mArticleID), __FUNCTION__); |
110 | | - $a = array(); |
111 | | - while ( $row = $dbr->fetchObject( $res ) ) { |
112 | | - $a[] = array( 'lang' => $row->ll_lang, '*' => $row->ll_title ); |
113 | | - } |
114 | | - $dbr->freeResult( $res ); |
| 170 | + $a = $this->readLinksFromDB( $dbr, $wgTitle->mArticleID ); |
115 | 171 | $res = true; |
116 | 172 | } |
117 | 173 | |
— | — | @@ -159,7 +215,7 @@ |
160 | 216 | if( count( $pagelinks ) ) { |
161 | 217 | $linker = new Linker(); $pagelinktexts = array(); |
162 | 218 | foreach( $pagelinks as $page => $dummy ) { |
163 | | - $title = Title::newFromText( $wgInterlanguageExtensionInterwiki . strtr($page,'_',' ') ); |
| 219 | + $title = Title::newFromText( $wgInterlanguageExtensionInterwiki . strtr($this->translateNamespace( $page ),'_',' ') ); |
164 | 220 | $link = $linker->link( $title ); |
165 | 221 | if( strlen( $link ) ) { |
166 | 222 | $pagelinktexts[] = $link; |
— | — | @@ -188,6 +244,23 @@ |
189 | 245 | } |
190 | 246 | |
191 | 247 | /** |
| 248 | + * Translate namespace from localized to the canonical form. |
| 249 | + * |
| 250 | + * @param $param - Page title |
| 251 | + */ |
| 252 | + function translateNamespace( $param ) { |
| 253 | + $paramTitle = Title::newFromText( $param ); |
| 254 | + if( $paramTitle ) { |
| 255 | + $canonicalNamespaces = MWNamespace::getCanonicalNamespaces(); |
| 256 | + $title = $canonicalNamespaces[$paramTitle->mNamespace] . ":" . $paramTitle->mDbkeyform; |
| 257 | + } else { |
| 258 | + //If the title is malformed, try at least this |
| 259 | + $title = strtr( $param, ' ', '_' ); |
| 260 | + } |
| 261 | + return $title; |
| 262 | + } |
| 263 | + |
| 264 | + /** |
192 | 265 | * Saves names of pages on the central wiki which are linked to from the saved page |
193 | 266 | * by {{interlanguage:}} magic. |
194 | 267 | * |
— | — | @@ -221,14 +294,38 @@ |
222 | 295 | $dbr = wfGetDB( DB_SLAVE ); |
223 | 296 | $res = $dbr->select( 'page_props', 'pp_value', array( 'pp_page' => $articleid, 'pp_propname' => 'interlanguage_pages' ), __FUNCTION__); |
224 | 297 | $pagelinks = array(); |
225 | | - if ( $row = $dbr->fetchObject( $res ) ) { |
| 298 | + $row = $res->fetchObject(); |
| 299 | + if ( $row ) { |
226 | 300 | $pagelinks = @unserialize( $row->pp_value ); |
227 | 301 | } |
228 | | - $dbr->freeResult( $res ); |
| 302 | + |
229 | 303 | return $pagelinks; |
230 | 304 | } |
231 | 305 | |
232 | 306 | /** |
| 307 | + * Read interlanguage links from a database, and return them in the same format that API |
| 308 | + * uses. |
| 309 | + * |
| 310 | + * @param $dbr - Database. |
| 311 | + * @param $articleid - ID of the article whose links should be returned. |
| 312 | + * @returns The array with the links. If there are no links, an empty array is returned. |
| 313 | + */ |
| 314 | + function readLinksFromDB( $dbr, $articleid ) { |
| 315 | + $res = $dbr->select( |
| 316 | + array( 'langlinks' ), |
| 317 | + array( 'll_lang', 'll_title' ), |
| 318 | + array( 'll_from' => $articleid ), |
| 319 | + __FUNCTION__ |
| 320 | + ); |
| 321 | + $a = array(); |
| 322 | + foreach( $res as $row ) { |
| 323 | + $a[] = array( 'lang' => $row->ll_lang, '*' => $row->ll_title ); |
| 324 | + } |
| 325 | + $res->free(); |
| 326 | + return $a; |
| 327 | + } |
| 328 | + |
| 329 | + /** |
233 | 330 | * Compare two interlanguage links by order of alphabet, based on language code. |
234 | 331 | */ |
235 | 332 | static function compareCode($a, $b) { |