Various additions and fixes
[mediawiki.git] / includes / SpecialIntl.php
blob8e366057e3226159843c06116eb89d46843ef127
1 <?
3 function wfSpecialIntl()
5 global $wgUser, $wgOut, $wgLang, $wgTitle;
6 global $limit, $offset; # From query string
7 global $wgDBconnection ;
8 $fname = "wfSpecialIntl";
9 $s = "" ;
11 if ( ! $limit ) {
12 $limit = $wgUser->getOption( "rclimit" );
13 if ( ! $limit ) { $limit = 50; }
15 if ( ! $offset ) { $offset = 0; }
17 # Connecting to the wiki-intl database
18 $c = $wgDBconnection ;
19 if ( !mysql_select_db ( $wgDBIntlName, $c ) ) {
20 $wgOut->addHTML( htmlspecialchars(mysql_error()) );
21 return ;
24 global $mode ;
25 $mode = strtolower ( trim ( $mode ) ) ;
26 if ( $mode == "" ) $mode = "main" ;
28 if ( $mode == "main" ) $s .= intl_main ( $c ) ;
29 else if ( $mode == "addlink" ) $s .= intl_add ( $c ) ;
30 else if ( $mode == "zoom" ) $s .= intl_zoom ( $c ) ;
31 else if ( $mode == "incominglinks" ) $s .= intl_incoming ( $c ) ;
32 else if ( $mode == "outgoinglinks" ) $s .= intl_outgoing ( $c ) ;
33 else if ( $mode == "alllinks" ) $s .= intl_all ( $c ) ;
34 else if ( $mode == "delete" ) $s .= intl_delete ( $c ) ;
35 else if ( $mode == "recentchanges" ) $s .= intl_recentchanges ( $c ) ;
37 $si = "Special:Intl" ;
38 $sk = $wgUser->getSkin();
39 if ( $mode != "" && $mode != "main" )
40 $s .= $sk->makeKnownLink($si,"International issues main menu") ;
42 $wgOut->addHTML( $s );
45 function appendRecentChanges ( $message ) {
46 global $wgDBconnection , $wgUser , $wgLanguageCode , $wgLang ;
47 $user_name = $wgLang->getNSText(Namespace::getUser()).":".$wgUser->getName() ;
48 $user_lang = $wgLanguageCode ;
49 $message = str_replace ( '"' , '\"' , $message ) ;
50 $sql = "INSERT INTO recentchanges (user_name,user_lang,message) VALUES (
51 \"{$user_name}\",
52 \"{$user_lang}\",
53 \"{$message}\")" ;
54 $res = mysql_query ( $sql , $wgDBconnection ) ;
57 function intl_recentchanges ( $c ) {
58 global $wgLang ;
59 $r = "<h2>Recent Link Changes</h2>\n" ;
61 $rc = array () ;
62 $sql = "SELECT * FROM recentchanges ORDER BY date DESC LIMIT 250" ;
63 $res = mysql_query ( $sql , $c ) ;
64 while ( $q = mysql_fetch_object ( $res ) ) $rc[] = $q ;
65 mysql_free_result ( $res ) ;
67 $r .= "<UL>\n" ;
68 foreach ( $rc AS $x ) {
69 $r .= "<li>" ;
70 $r .= getArticleLink ( $x->user_name , $x->user_lang ) ;
71 $h = $wgLang->time( $x->date, true );
72 $r .= " ({$h}) " ;
73 $r .= $x->message ;
74 $r .= "</li>\n" ;
76 $r .= "</UL>\n" ;
78 return $r ;
81 function getArticleLink ( $title , $lang = "" ) {
82 global $wgLanguageCode ;
83 $cl = "external" ;
84 if ( $lang == "" ) $lang = $wgLanguageCode ;
85 if ( $lang == $wgLanguageCode ) $cl = "internal" ;
86 $nt = Title::newFromText ( $title ) ;
87 $link = "http://".$lang.".wikipedia.org/wiki/".$title ;
88 $link = "<a class='{$cl}' href=\"{$link}\">".$nt->getText()."</a>" ;
89 return $link ;
92 function intl_main ( $c ) {
93 global $wgUser ;
94 $sk = $wgUser->getSkin();
95 $si = "Special:Intl" ;
97 $r = "<h2>International issues main menu</h2>" ;
98 $r .= "<UL>" ;
99 $r .= "<li>".$sk->makeKnownLink($si,"Add a link","mode=addlink")."</li>" ;
100 $r .= "<li>".$sk->makeKnownLink($si,"View incoming links","mode=incominglinks")."</li>" ;
101 $r .= "<li>".$sk->makeKnownLink($si,"View outgoing links","mode=outgoinglinks")."</li>" ;
102 $r .= "<li>".$sk->makeKnownLink($si,"View all links","mode=alllinks")."</li>" ;
103 $r .= "<li>".$sk->makeKnownLink($si,"Recent Link Changes","mode=recentchanges")."</li>" ;
104 $r .= "</UL>" ;
105 return $r ;
108 function intl_add_doit ( $c ) {
109 global $wgUser , $wgLang , $wgLanguageCode , $doit ;
110 global $l_f , $l_t , $t_f , $t_t , $backlink ;
111 $sk = $wgUser->getSkin();
112 $si = "Special:Intl" ;
114 # checking for language link
115 $q = explode ( ":" , $t_t , 2 ) ;
116 $ln = $wgLang->getLanguageNames();
117 if ( count ( $q ) == 2 ) {
118 $nl_t = trim ( array_shift ( $q ) ) ;
119 $nt_t = trim ( array_shift ( $q ) ) ;
120 if ( $nl_t != "" AND isset ( $ln[$nl_t] ) ) {
121 $l_t = $nl_t ;
122 $t_t = $nt_t ;
126 $nt = Title::newFromText ( $t_f ) ;
127 $t_f = $nt->getDBkey() ;
128 $nt = Title::newFromText ( $t_t ) ;
129 $t_t = $nt->getDBkey() ;
131 $r = "<h2>Creating/updating language links</h2>" ;
133 # Deleting forward link
134 $sql = "DELETE FROM ilinks WHERE
135 lang_from='{$l_f}' AND
136 lang_to='{$l_t}' AND
137 title_from='{$t_f}'
139 $res = mysql_query ( $sql , $c ) ;
141 $r .= "Executed {$sql}" ;
142 $r .= "<br>Result {$res}" ;
143 $r .= "<br>Error ". htmlspecialchars(mysql_error()) ;
144 $r .= "<br><br>" ;
146 # Adding link
147 $sql = "INSERT INTO ilinks (lang_from,lang_to,title_from,title_to) VALUES
148 ('{$l_f}','{$l_t}','{$t_f}','{$t_t}')" ;
149 $res = mysql_query ( $sql , $c ) ;
151 $r .= "Executed {$sql}" ;
152 $r .= "<br>Result {$res}" ;
153 $r .= "<br>Error ". htmlspecialchars(mysql_error()) ;
155 appendRecentChanges ( $ln[$l_f].":".getArticleLink($t_f,$l_f)." &rarr; ".
156 $ln[$l_t].":".getArticleLink($t_t,$l_t) ) ;
158 if ( $backlink == "on" ) {
159 $backlink = "" ;
160 $x = $l_f ; $l_f = $l_t ; $l_t = $x ;
161 $x = $t_f ; $t_f = $t_t ; $t_t = $x ;
162 intl_add_doit ( $c ) ; # Ugly recursion
165 return $r ;
168 function intl_add ( $c ) {
169 global $wgUser , $wgLang , $wgLanguageCode , $doit , $mode ;
170 global $xl , $xt , $yl , $yt ;
171 $r = "" ;
172 if ( isset ( $doit ) ) {
173 global $al_t , $at_t , $l_t , $t_t ;
174 for ( $x = 0 ; $x < 10 ; $x++ ) {
175 if ( trim($at_t[$x]) != "" ) {
176 $t_t = $at_t[$x] ;
177 $l_t = $al_t[$x] ;
178 $r .= "<font color=red size=+1>".
179 "The link ".
180 $l_f.":".$t_f." &harr; ".$l_t.":".$t_t.
181 " has been added.</font><br>" ;
182 intl_add_doit ( $c ) ;
185 $yt = "" ;
186 $yl = "" ;
189 $sk = $wgUser->getSkin();
190 $si = "Special:Intl" ;
192 if ( $xl == "" ) $xl = $wgLanguageCode ;
194 $oxt = $xt ;
195 $oyt = $yt ;
196 $nt = Title::newFromText ( $xt ) ;
197 $xt = $nt->getPrefixedText () ;
198 $nt = Title::newFromText ( $yt ) ;
199 $yt = $nt->getPrefixedText () ;
201 $ll1 = $ll2 = "" ;
202 $a = $wgLang->getLanguageNames();
203 $ak = array_keys ( $a ) ;
204 foreach ( $ak AS $k ) {
205 $sel = "" ;
206 if ( $k == $xl ) $sel = " SELECTED" ;
207 $ll1 .= "<option{$sel} value='{$k}'>{$a[$k]}</option>\n" ;
208 $sel = "" ;
209 if ( $k == $yl ) $sel = " SELECTED" ;
210 $ll2 .= "<option{$sel} value='{$k}'>{$a[$k]}</option>\n" ;
213 $r .= "<h2>Add or update a link</h2>" ;
215 if ( $oxt != "" ) {
216 $zl = "See the group of articles interlinked for ".$a[$xl].":".$xt ;
217 $zl = $sk->makeKnownLink($si,$zl,"mode=zoom&xl={$xl}&xt={$oxt}")."<br>\n" ;
218 $al = getArticleLink ( $oxt , $xl ) ;
219 $r .= $zl.$al ;
222 $r .= "Note: You can also type the language code before the target (e.g., 'en:target'). The selection of the drop down box will then be ignored.<br>\n" ;
224 $r .= "<FORM method=post>\n" ;
226 $r .= "<li>Source \n" ;
227 $r .= "<select name=l_f>\n{$ll1}</select>\n " ;
228 $r .= "<input type=text name=t_f value=\"{$xt}\">\n" ;
229 $r .= "</li>\n" ;
231 for ( $x = 0 ; $x < 10 ; $x++ ) {
232 $r .= "<li>Destin. \n" ;
233 $r .= "<select name='al_t[{$x}]'>\n{$ll2}</select>\n " ;
234 $r .= "<input type=text name='at_t[{$x}]' value=\"{$yt}\">\n" ;
235 $r .= "</li>\n" ;
238 $r .= "<INPUT type=checkbox name=backlink checked>Add link in both directions<br>\n" ;
240 $r .= "<INPUT type=submit name=doit value='Do it'>\n" ;
242 $r .= "</FORM>\n" ;
244 return $r ;
247 function eliminate_doubles ( &$list ) { # Real ugly
248 $ak = array_keys ( $list ) ;
249 foreach ( $ak AS $k1 ) {
250 if ( $list[$k1]->hidden ) continue ;
251 foreach ( $ak AS $k2 ) {
252 if ( $k1 != $k2 &&
253 $list[$k1]->title_from == $list[$k2]->title_to &&
254 $list[$k1]->title_to == $list[$k2]->title_from &&
255 $list[$k1]->lang_from == $list[$k2]->lang_to &&
256 $list[$k1]->lang_to == $list[$k2]->lang_from ) {
257 $list[$k1]->both = true ;
258 $list[$k2]->hidden = true ;
259 break ;
265 function displayLinks ( $list , $opt = "" ) {
266 eliminate_doubles ( $list ) ;
267 global $wgLang , $wgUser , $mode ;
268 $si = "Special:Intl" ;
269 $sk = $wgUser->getSkin();
270 $ln = $wgLang->getLanguageNames();
271 $r = "" ;
273 if ( !isset ( $opt->showdel ) ) $opt->showdel = true ;
275 global $limit , $offset , $intlparam ;
276 if ( $intlparam != "" ) {
277 $r .= wfShowingResults( $offset, $limit );
278 $sl = wfViewPrevNext( $offset, $limit,
279 $wgLang->specialPage( "Intl".$intlparam ) );
280 $r .= "<br>{$sl}\n" ;
283 $r .= "<table border=1 cellpadding=2 cellspacing=0>\n" ;
284 $r .= "<tr>\n" ;
285 $r .= "<th colspan=2>From</th>\n" ;
286 $r .= "<th>&nbsp;</th>\n" ;
287 $r .= "<th colspan=2>To</th>\n" ;
288 if ( $mode != "zoom" ) $r .= "<th>&nbsp;</th>\n" ;
289 if ( $opt->showdel ) $r .= "<th colspan=3>Delete</th>\n" ;
290 if ( $opt->display != "" ) $r .= "<th colspan=3>".$opt->display."</th>\n" ;
291 $r .= "</tr>\n" ;
293 foreach ( $list AS $q ) {
294 if ( $q->hidden ) continue ;
295 $zoom = "xl={$q->lang_from}&xt=".urlencode($q->title_from) ;
296 $zoom = $sk->makeKnownLink($si,"[&Sigma;]","mode=zoom&{$zoom}") ;
297 $del1 = "xl={$q->lang_from}&xt=".urlencode($q->title_from)."&yl={$q->lang_to}" ;
298 $del2 = $sk->makeKnownLink($si,"[&harr;]","mode=delete&{$del1}&back=yes") ;
299 $del1 = $sk->makeKnownLink($si,"[&rarr;]","mode=delete&{$del1}") ;
300 $del1a = "xl={$q->lang_to}&xt=".urlencode($q->title_to)."&yl={$q->lang_from}" ;
301 $del1a = $sk->makeKnownLink($si,"[&larr;]","mode=delete&{$del1a}") ;
302 $sign = "&rarr;" ;
303 if ( $q->both ) $sign = "&harr;" ;
304 else $del1a = "&nbsp;" ;
306 $r .= "<tr>\n" ;
307 $r .= "<td>".$ln[$q->lang_from]."</td>\n" ;
308 $r .= "<td>".getArticleLink($q->title_from,$q->lang_from)."</td>\n" ;
309 $r .= "<td> {$sign} </td>\n" ;
310 $r .= "<td>".$ln[$q->lang_to]."</td>\n" ;
311 $r .= "<td>".getArticleLink($q->title_to,$q->lang_to)."</td>\n" ;
312 if ( $mode != "zoom" ) $r .= "<td>{$zoom}</td>\n" ;
313 if ( $opt->showdel ) {
314 $r .= "<td>{$del1}</td>\n" ;
315 $r .= "<td>{$del1a}</td>\n" ;
316 $r .= "<td>{$del2}</td>\n" ;
318 if ( $opt->display != "" ) {
319 if ( $q->display == "" ) $q->display = "&nbsp;" ;
320 $r .= "<td>{$q->display}</td>\n" ;
322 $r .= "</tr>\n" ;
324 $r .= "</table>\n" ;
325 if ( $intlparam != "" )
326 $r .= "{$sl}<br>\n" ;
327 return $r ;
330 function intl_outgoing ( $c ) {
331 global $wgLanguageCode ;
332 global $limit , $offset , $intlparam ;
333 $intlparam = "&mode=outgoinglinks" ;
334 $list = array() ;
335 $r = "<h2>Outgoing links</h2>\n" ;
336 $sql = "SELECT * FROM ilinks WHERE lang_from='{$wgLanguageCode}' LIMIT {$offset}, {$limit}";
337 $res = mysql_query ( $sql , $c ) ;
338 while ( $q = mysql_fetch_object ( $res ) ) $list[] = $q ;
339 mysql_free_result ( $res ) ;
340 $r .= displayLinks ( $list ) ;
341 return $r ;
344 function intl_incoming ( $c ) {
345 global $wgLanguageCode ;
346 global $limit , $offset , $intlparam ;
347 $intlparam = "&mode=incominglinks" ;
348 $list = array() ;
349 $r = "<h2>Incoming links</h2>\n" ;
350 $sql="SELECT * FROM ilinks WHERE lang_to='{$wgLanguageCode}' LIMIT {$offset}, {$limit}";
351 $res = mysql_query ( $sql , $c ) ;
352 while ( $q = mysql_fetch_object ( $res ) ) $list[] = $q ;
353 mysql_free_result ( $res ) ;
354 $r .= displayLinks ( $list ) ;
355 return $r ;
358 function intl_all ( $c ) {
359 global $wgLanguageCode ;
360 global $limit , $offset , $intlparam ;
361 $intlparam = "&mode=alllinks" ;
362 $list = array() ;
363 $r = "<h2>All links</h2>\n" ;
364 $sql = "SELECT * FROM ilinks LIMIT {$offset}, {$limit}";
365 $res = mysql_query ( $sql , $c ) ;
366 while ( $q = mysql_fetch_object ( $res ) ) $list[] = $q ;
367 mysql_free_result ( $res ) ;
368 $r .= displayLinks ( $list ) ;
369 return $r ;
373 function do_zoom ( &$found , &$list , $c ) {
374 $news = array () ;
375 foreach ( $found AS $x ) {
376 if ( $x->new ) {
377 $sql = "SELECT * FROM ilinks WHERE
378 ( lang_from='{$x->lang}' AND title_from='{$x->title}' ) OR
379 ( lang_to='{$x->lang}' AND title_to='{$x->title}' )
381 $res = mysql_query ( $sql , $c ) ;
382 while ( $q = mysql_fetch_object ( $res ) ) {
383 $i->orig = $q ;
384 $i->lang = $q->lang_from ;
385 $i->title = $q->title_from ;
386 $news[] = $i ;
388 $i->lang = $q->lang_to ;
389 $i->title = $q->title_to ;
390 $news[] = $i ;
392 mysql_free_result ( $res ) ;
395 $ak = array_keys ( $found ) ;
396 foreach ( $ak AS $x ) $found[$x]->new = false ;
398 # Adding new ones
399 $isnewone = false ;
400 foreach ( $news AS $n ) {
401 $didfind = 0 ;
402 foreach ( $found AS $f ) {
403 if($n->lang==$f->lang AND $n->title==$f->title) {
404 $didfind=1;
405 if ( $f->new ) $list[] = $n->orig ;
408 if ( $didfind == 0 ) {
409 $i->lang = $n->lang ;
410 $i->title = $n->title ;
411 $i->new = true ;
412 $found[] = $i ;
413 $list[] = $n->orig ;
414 $isnewone = true ;
418 if ( $isnewone ) do_zoom ( $found , $list , $c ) ;
421 function getMissingLinks ( $found , $list ) {
422 $a = $r = array () ;
423 foreach ( $found AS $f1 ) {
424 foreach ( $found AS $f2 ) {
425 if ( $f1 != $f2 ) {
426 $i->lang_from = $f1->lang ;
427 $i->lang_to = $f2->lang ;
428 $i->title_from = $f1->title ;
429 $i->title_to = $f2->title ;
430 $a[] = $i ;
434 foreach ( $a AS $x ) {
435 $f = false ;
436 foreach ( $list AS $l ) {
437 if ( $x->lang_from == $l->lang_from &&
438 $x->lang_to == $l->lang_to &&
439 $x->title_from == $l->title_from &&
440 $x->title_to == $l->title_to ) {
441 $f = true ;
442 break ;
445 if ( !$f ) $r[] = $x ;
447 return $r ;
450 function intl_zoom2 ( $c ) {
451 global $doit , $ZLF , $ZLT , $ZTF , $ZTT , $ZCB ;
452 global $l_f , $l_t , $t_f , $t_t , $backlink ;
453 $r = "<h2>Adding selected language links</h2>\n" ;
454 $r .= "<OL>\n" ;
455 $ak = array_keys ( $ZCB ) ;
456 foreach ( $ak AS $cnt ) {
457 if ( $ZCB[$cnt] == "on" ) {
458 $l_f = $ZLF[$cnt] ;
459 $l_t = $ZLT[$cnt] ;
460 $t_f = $ZTF[$cnt] ;
461 $t_t = $ZTT[$cnt] ;
462 $backlink = "on" ;
463 intl_add_doit ( $c ) ;
464 $r .= "<li>$l_f:$t_f &harr; $l_t:$t_t</li>\n" ;
467 $r .= "</OL>\n" ;
468 return $r ;
471 function intl_zoom ( $c ) {
472 global $doit ;
473 global $wgLanguageCode , $wgLang ;
474 global $xl , $xt ;
475 if ( isset ( $doit ) ) return intl_zoom2 ( $c ) ;
476 $ln = $wgLang->getLanguageNames();
477 $list = array() ;
478 $found = array () ;
479 $r = "<h2>Interlinked articles group</h2>\n" ;
480 $initial->lang = $xl ;
481 $initial->title = urldecode ( $xt ) ;
482 $initial->new = true ;
483 $found[] = $initial ;
485 do_zoom ( $found , $list , $c ) ;
487 $involved = array() ;
488 foreach ( $found AS $f )
489 $involved[] = $ln[$f->lang].":".getArticleLink ( $f->title , $f->lang ) ;
490 $r .= "Involved are ".implode ( ", " , $involved )."<br>\n" ;
492 $r .= displayLinks ( $list ) ;
494 $list2 = getMissingLinks ( $found , $list ) ;
496 if ( count ( $list2 ) > 0 ) {
497 $r .= "<h3>Missing links</h3>\n" ;
498 $opt->showdel = false ;
499 $opt->display = "Create" ;
500 $ak = array_keys ( $list2 ) ;
501 $cnt = 1 ;
502 foreach ( $ak AS $a ) {
503 $b = $list2[$a] ;
504 $z = "<input type=checkbox name='ZCB[{$cnt}]' checked>\n" ;
505 $z.="<input type=hidden name='ZLF[{$cnt}]' value='{$b->lang_from}'>\n";
506 $z.="<input type=hidden name='ZLT[{$cnt}]' value='{$b->lang_to}'>\n";
507 $z.="<input type=hidden name='ZTF[{$cnt}]' value='{$b->title_from}'>\n";
508 $z.="<input type=hidden name='ZTT[{$cnt}]' value='{$b->title_to}'>\n";
509 $list2[$a]->display = $z ;
510 $cnt++ ;
512 $r .= "<FORM method=post>\n" ;
513 $r .= displayLinks ( $list2 , $opt ) ;
514 $r .= "<INPUT type=submit name=doit value='Create selected links'>\n" ;
515 $r .= " (Note: This is still buggy, I don't know why...)" ;
516 $r .= "</FORM>\n" ;
519 return $r ;
522 function intl_delete ( $c ) {
523 global $wgLang ;
524 global $xt , $xl , $yl , $back ;
525 $title = urldecode ( $xt ) ;
526 $ln = $wgLang->getLanguageNames();
528 $sql = "DELETE FROM ilinks WHERE
529 lang_from='{$xl}' AND
530 lang_to='{$yl}' AND
531 title_from='{$title}'
533 $res = mysql_query ( $sql , $c ) ;
535 $r = "<h2>Deletion</h2>" ;
536 $r .= "The link from ".$ln[$xl].":".$title." to ".$ln[$yl]." has been deleted.<br>" ;
538 appendRecentChanges ( "- ".$ln[$xl].":".getArticleLink($title,$xl)." &rarr;" ) ;
540 # Backlink?
541 if ( $back != "yes" ) return $r ;
543 $sql = "DELETE FROM ilinks WHERE
544 lang_to='{$xl}' AND
545 lang_from='{$yl}' AND
546 title_to='{$title}'
548 $res = mysql_query ( $sql , $c ) ;
550 appendRecentChanges ( "- &rarr;".$ln[$xl].":".getArticleLink($title,$xl) ) ;
552 $r .= "As was the backlink.<br>" ;
553 return $r ;