00001 <?php
00002
# Global functions used everywhere
00003
00004 $wgNumberOfArticles = -1; # Unset
00005 $wgTotalViews = -1;
00006 $wgTotalEdits = -1;
00007
00008 require_once( 'DatabaseFunctions.php' );
00009 require_once( 'UpdateClasses.php' );
00010 require_once( '
LogPage.php' );
00011
00012
00013
00014
00015
00016
# PHP <4.3.x is not actively supported; 4.1.x and 4.2.x might or might not work.
00017
# <4.1.x will not work, as we use a number of features introduced in 4.1.0
00018
# such as the new autoglobals.
00019
00020
if( !function_exists('iconv') ) {
00021
# iconv support is not in the default configuration and so may not be present.
00022
# Assume will only ever use utf-8 and iso-8859-1.
00023
# This will *not* work in all circumstances.
00024
function iconv( $from, $to, $string ) {
00025
if(strcasecmp( $from, $to ) == 0)
return $string;
00026
if(strcasecmp( $from, 'utf-8' ) == 0)
return utf8_decode( $string );
00027
if(strcasecmp( $to, 'utf-8' ) == 0)
return utf8_encode( $string );
00028 return $string;
00029 }
00030 }
00031
00032
if( !function_exists('file_get_contents') ) {
00033
# Exists in PHP 4.3.0+
00034
function file_get_contents( $filename ) {
00035
return implode( '', file( $filename ) );
00036 }
00037 }
00038
00039
if( !function_exists('is_a') ) {
00040
# Exists in PHP 4.2.0+
00041
function is_a( $object, $class_name ) {
00042
return
00043 (strcasecmp( get_class( $object, $class_name ) == 0) ||
00044 is_subclass_of( $object, $class_name ) );
00045 }
00046 }
00047
00048
# html_entity_decode exists in PHP 4.3.0+ but is FATALLY BROKEN even then,
00049
# with no UTF-8 support.
00050 function
do_html_entity_decode( $string, $quote_style=ENT_COMPAT, $charset='ISO-8859-1' ) {
00051
static $trans;
00052
if( !isset( $trans ) ) {
00053 $trans = array_flip( get_html_translation_table( HTML_ENTITIES, $quote_style ) );
00054
# Assumes $charset will always be the same through a run, and only understands
00055
# utf-8 or default. Note - mixing latin1 named entities and unicode numbered
00056
# ones will result in a bad link.
00057
if( strcasecmp( 'utf-8', $charset ) == 0 ) {
00058 $trans = array_map( 'utf8_encode', $trans );
00059 }
00060 }
00061
return strtr( $string, $trans );
00062 }
00063
00064 $wgRandomSeeded =
false;
00065
00066 function
wfSeedRandom()
00067 {
00068 global
$wgRandomSeeded;
00069
00070
if ( !
$wgRandomSeeded ) {
00071 $seed = hexdec(substr(md5(microtime()),-8)) & 0x7fffffff;
00072 mt_srand( $seed );
00073
$wgRandomSeeded =
true;
00074 }
00075 }
00076
00077
# Generates a URL from a URL-encoded title and a query string
00078
# Title::getLocalURL() is preferred in most cases
00079
#
00080 function
wfLocalUrl( $a, $q = '' )
00081 {
00082 global $wgServer,
$wgScript,
$wgArticlePath;
00083
00084 $a = str_replace(
' ',
'_', $a );
00085
00086
if ( '' == $a ) {
00087
if( '' == $q ) {
00088 $a =
$wgScript;
00089 }
else {
00090 $a =
"{$wgScript}?{$q}";
00091 }
00092 }
else if ( '' == $q ) {
00093 $a = str_replace(
"$1", $a, $wgArticlePath );
00094 }
else if (
$wgScript != '' ) {
00095 $a =
"{$wgScript}?title={$a}&{$q}";
00096 }
else {
00097 $a =
"/{$a}?{$q}";
00098 }
00099
return $a;
00100 }
00101
00102 function
wfLocalUrlE( $a, $q = '' )
00103 {
00104
return wfEscapeHTML(
wfLocalUrl( $a, $q ) );
00105
# die( "Call to obsolete function wfLocalUrlE()" );
00106
}
00107
00108 function
wfFullUrl( $a, $q = '' ) {
00109
wfDebugDieBacktrace( 'Call to
obsolete function
wfFullUrl(); use Title::getFullURL' );
00110 }
00111
00112 function
wfFullUrlE( $a, $q = '' ) {
00113
wfDebugDieBacktrace( 'Call to
obsolete function
wfFullUrlE(); use Title::getFullUrlE' );
00114
00115 }
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133 function
wfImageArchiveUrl( $name )
00134 {
00135 global
$wgUploadPath;
00136
00137 $hash = md5( substr( $
name, 15) );
00138
$url =
"{$wgUploadPath}/archive/" . $hash{0} .
"/" .
00139 substr( $hash, 0, 2 ) .
"/{$name}";
00140
return wfUrlencode($url);
00141 }
00142
00143 function
wfUrlencode ( $s )
00144 {
00145
$s = urlencode( $s );
00146
$s = preg_replace( '/%3[Aa]/',
':', $s );
00147
$s = preg_replace( '/%2[Ff]/',
'/', $s );
00148
00149
return $s;
00150 }
00151
00152 function
wfUtf8Sequence($codepoint) {
00153
if($codepoint < 0x80)
return chr($codepoint);
00154
if($codepoint < 0x800) return chr($codepoint >> 6 & 0x3f | 0xc0) .
00155 chr($codepoint & 0x3f | 0x80);
00156
if($codepoint < 0x10000) return chr($codepoint >> 12 & 0x0f | 0xe0) .
00157 chr($codepoint >> 6 & 0x3f | 0x80) .
00158 chr($codepoint & 0x3f | 0x80);
00159
if($codepoint < 0x100000) return chr($codepoint >> 18 & 0x07 | 0xf0) . # Double-
check this
00160 chr($codepoint >> 12 & 0x3f | 0x80) .
00161 chr($codepoint >> 6 & 0x3f | 0x80) .
00162 chr($codepoint & 0x3f | 0x80);
00163
# Doesn't yet handle outside the BMP
00164
return "&#$codepoint;";
00165 }
00166
00167
# Converts numeric character entities to UTF-8
00168 function
wfMungeToUtf8($string) {
00169 global
$wgInputEncoding; # This
is debatable
00170
#$string = iconv($wgInputEncoding, "UTF-8", $string);
00171
$string = preg_replace ( '/&#([0-9]+);/e', '
wfUtf8Sequence($1)', $string );
00172
$string = preg_replace ( '/&#x([0-9a-f]+);/ie', '
wfUtf8Sequence(0x$1)', $string );
00173
# Should also do named entities here
00174
return $string;
00175 }
00176
00177
# Converts a single UTF-8 character into the corresponding HTML character entity
00178 function
wfUtf8Entity( $matches ) {
00179 $char = $matches[0];
00180
# Find the length
00181
$z = ord( $
char{0} );
00182
if ( $z & 0x80 ) {
00183 $length = 0;
00184
while ( $z & 0x80 ) {
00185 $length++;
00186 $z <<= 1;
00187 }
00188 }
else {
00189 $length = 1;
00190 }
00191
00192
if ( $length != strlen( $
char ) ) {
00193
return '';
00194 }
00195
if ( $length == 1 ) {
00196
return $char;
00197 }
00198
00199
# Mask off the length-determining bits and shift back to the original location
00200
$z &= 0xff;
00201 $z >>= $length;
00202
00203
# Add in the free bits from subsequent bytes
00204
for (
$i=1;
$i<$length;
$i++ ) {
00205 $z <<= 6;
00206 $z |= ord( $
char{$i} ) & 0x3f;
00207 }
00208
00209
# Make entity
00210
return "&#$z;";
00211 }
00212
00213
# Converts all multi-byte characters in a UTF-8 string into the appropriate character entity
00214 function
wfUtf8ToHTML($string) {
00215
return preg_replace_callback( '/[\\xc0-\\xfd][\\x80-\\xbf]*/', '
wfUtf8Entity', $string );
00216 }
00217
00218 function
wfDebug( $text, $logonly =
false )
00219 {
00220 global
$wgOut,
$wgDebugLogFile,
$wgDebugComments,
$wgProfileOnly;
00221
00222
if ( isset( $wgOut ) &&
$wgDebugComments && !$logonly ) {
00223
$wgOut->debug( $text );
00224 }
00225
if (
"" !=
$wgDebugLogFile && !
$wgProfileOnly ) {
00226 error_log( $text, 3, $wgDebugLogFile );
00227 }
00228 }
00229
00230 function
logProfilingData()
00231 {
00232 global
$wgRequestTime,
$wgDebugLogFile;
00233 global
$wgProfiling, $wgProfileStack,
$wgProfileLimit,
$wgUser;
00234 $now =
wfTime();
00235
00236 list( $usec, $sec ) = explode(
" ", $wgRequestTime );
00237 $start = (
float)$sec + (
float)$usec;
00238 $elapsed = $now - $start;
00239
if (
$wgProfiling ) {
00240 $prof =
wfGetProfilingOutput( $start, $elapsed );
00241 $forward = '';
00242
if( !empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) )
00243 $forward = ' forwarded
for ' . $_SERVER['HTTP_X_FORWARDED_FOR'];
00244
if( !empty( $_SERVER['HTTP_CLIENT_IP'] ) )
00245 $forward .= ' client
IP ' . $_SERVER['HTTP_CLIENT_IP'];
00246
if( !empty( $_SERVER['HTTP_FROM'] ) )
00247 $forward .= ' from ' . $_SERVER['HTTP_FROM'];
00248
if( $forward )
00249 $forward =
"\t(proxied via {$_SERVER['REMOTE_ADDR']}{$forward})";
00250
if(
$wgUser->getId() == 0)
00251 $forward .= ' anon';
00252 $log = sprintf(
"%s\t%04.3f\t%s\n",
00253 gmdate( 'YmdHis' ), $elapsed,
00254 urldecode( $_SERVER['REQUEST_URI'] . $forward ) );
00255
if ( '' !=
$wgDebugLogFile ) {
00256 error_log( $log . $prof, 3, $wgDebugLogFile );
00257 }
00258 }
00259 }
00260
00261
00262 function
wfReadOnly()
00263 {
00264 global
$wgReadOnlyFile;
00265
00266
if (
"" ==
$wgReadOnlyFile ) {
return false; }
00267
return is_file( $wgReadOnlyFile );
00268 }
00269
00270 $wgReplacementKeys = array(
"$1",
"$2",
"$3",
"$4",
"$5",
"$6",
"$7",
"$8",
"$9" );
00271
00272
# Get a message from anywhere
00273 function
wfMsg( $key ) {
00274
$args = func_get_args();
00275
if ( count( $args ) ) {
00276 array_shift( $args );
00277 }
00278
return wfMsgReal( $key, $args,
true );
00279 }
00280
00281
# Get a message from the language file
00282 function
wfMsgNoDB( $key ) {
00283
$args = func_get_args();
00284
if ( count( $args ) ) {
00285 array_shift( $args );
00286 }
00287
return wfMsgReal( $key, $args,
false );
00288 }
00289
00290
# Really get a message
00291 function
wfMsgReal( $key, $args, $useDB ) {
00292 global
$wgReplacementKeys,
$wgMessageCache,
$wgLang;
00293
00294 $fname = '
wfMsg';
00295
wfProfileIn( $fname );
00296
if (
$wgMessageCache ) {
00297 $message =
$wgMessageCache->get( $key, $useDB );
00298 } elseif ( $wgLang ) {
00299 $message =
$wgLang->getMessage( $key );
00300 }
else {
00301
wfDebug(
"No language object when getting $key\n" );
00302 $message =
"<$key>";
00303 }
00304
00305
# Replace arguments
00306
if( count( $args ) ) {
00307 $message = str_replace( $wgReplacementKeys, $args, $message );
00308 }
00309
wfProfileOut( $fname );
00310
return $message;
00311 }
00312
00313 function
wfCleanFormFields( $fields )
00314 {
00315
wfDebugDieBacktrace( 'Call to
obsolete wfCleanFormFields(). Use wgRequest instead...' );
00316 }
00317
00318 function
wfMungeQuotes( $in )
00319 {
00320 $out = str_replace(
'%', '%25', $in );
00321 $out = str_replace(
"'", '%27', $out );
00322 $out = str_replace(
'"', '%22', $out );
00323
return $out;
00324 }
00325
00326 function
wfDemungeQuotes( $in )
00327 {
00328 $out = str_replace( '%22',
'"', $in );
00329 $out = str_replace( '%27',
"'", $out );
00330 $out = str_replace( '%25',
'%', $out );
00331
return $out;
00332 }
00333
00334 function
wfCleanQueryVar( $var )
00335 {
00336
wfDebugDieBacktrace( 'Call to
obsolete function
wfCleanQueryVar(); use wgRequest instead' );
00337 }
00338
00339 function
wfSearch( $s )
00340 {
00341 $se =
new SearchEngine( $s );
00342 $se->showResults();
00343 }
00344
00345 function
wfGo( $s )
00346 { # pick the nearest match
00347 $se =
new SearchEngine( $s );
00348 $se->goResult();
00349 }
00350
00351
# Just like exit() but makes a note of it.
00352 function
wfAbruptExit(){
00353
static $called =
false;
00354
if ( $called ){
00355
exit();
00356 }
00357 $called =
true;
00358
00359
if( function_exists( 'debug_backtrace' ) ){
00360 $bt = debug_backtrace();
00361
for(
$i = 0;
$i < count($bt) ;
$i++){
00362 $file = $bt[
$i]['file'];
00363
$line = $bt[
$i]['line'];
00364
wfDebug(
"WARNING: Abrupt exit in $file at line $line\n");
00365 }
00366 }
else {
00367
wfDebug('WARNING: Abrupt
exit\
n');
00368 }
00369
exit();
00370 }
00371
00372 function
wfDebugDieBacktrace( $msg = '' ) {
00373
if ( function_exists( 'debug_backtrace' ) ) {
00374 $msg .=
"\n<p>Backtrace:</p>\n<ul>\n";
00375 $backtrace = debug_backtrace();
00376 foreach( $backtrace as $call ) {
00377 $f = explode( DIRECTORY_SEPARATOR, $call['file'] );
00378 $file = $f[count($f)-1];
00379 $msg .= '<li>' . $file .
" line " . $call['line'] . ', in ';
00380
if( !empty( $call['
class'] ) ) $msg .= $call['
class'] . '::';
00381 $msg .= $call['function'] .
"()</li>\n";
00382 }
00383 }
00384 die( $msg );
00385 }
00386
00387 function
wfNumberOfArticles()
00388 {
00389 global
$wgNumberOfArticles;
00390
00391
wfLoadSiteStats();
00392
return $wgNumberOfArticles;
00393 }
00394
00395 function
wfLoadSiteStats()
00396 {
00397 global
$wgNumberOfArticles,
$wgTotalViews,
$wgTotalEdits;
00398
if ( -1 !=
$wgNumberOfArticles )
return;
00399
00400
$sql = 'SELECT ss_total_views, ss_total_edits, ss_good_articles ' .
00401 'FROM site_stats WHERE ss_row_id=1';
00402
$res =
wfQuery( $sql,
DB_READ, '
wfLoadSiteStats' );
00403
00404
if ( 0 ==
wfNumRows( $res ) ) {
return; }
00405
else {
00406
$s =
wfFetchObject( $res );
00407
$wgTotalViews =
$s->ss_total_views;
00408
$wgTotalEdits =
$s->ss_total_edits;
00409
$wgNumberOfArticles =
$s->ss_good_articles;
00410 }
00411 }
00412
00413 function
wfEscapeHTML( $in )
00414 {
00415
return str_replace(
00416 array(
'&',
'"',
'>',
'<' ),
00417 array( '&', '"', '>', '<' ),
00418 $in );
00419 }
00420
00421 function
wfEscapeHTMLTagsOnly( $in ) {
00422
return str_replace(
00423 array(
'"',
'>',
'<' ),
00424 array( '"', '>', '<' ),
00425 $in );
00426 }
00427
00428 function
wfUnescapeHTML( $in )
00429 {
00430 $in = str_replace( '<',
'<', $in );
00431 $in = str_replace( '>',
'>', $in );
00432 $in = str_replace( '"',
'"', $in );
00433 $in = str_replace( '&',
'&', $in );
00434
return $in;
00435 }
00436
00437 function
wfImageDir( $fname )
00438 {
00439 global
$wgUploadDirectory;
00440
00441 $hash = md5( $fname );
00442 $oldumask = umask(0);
00443 $dest =
$wgUploadDirectory .
'/' . $hash{0};
00444
if ( ! is_dir( $dest ) ) { mkdir( $dest, 0777 ); }
00445 $dest .=
'/' . substr( $hash, 0, 2 );
00446
if ( ! is_dir( $dest ) ) { mkdir( $dest, 0777 ); }
00447
00448 umask( $oldumask );
00449
return $dest;
00450 }
00451
00452 function
wfImageThumbDir( $fname , $subdir='thumb')
00453 {
00454
return wfImageArchiveDir( $fname, $subdir );
00455 }
00456
00457 function
wfImageArchiveDir( $fname , $subdir='archive')
00458 {
00459 global
$wgUploadDirectory;
00460
00461 $hash = md5( $fname );
00462 $oldumask = umask(0);
00463
00464
# Suppress warning messages here; if the file itself can't
00465
# be written we'll worry about it then.
00466
$archive =
"{$wgUploadDirectory}/{$subdir}";
00467
if ( ! is_dir( $archive ) ) { @mkdir( $archive, 0777 ); }
00468 $archive .=
'/' . $hash{0};
00469
if ( ! is_dir( $archive ) ) { @mkdir( $archive, 0777 ); }
00470 $archive .=
'/' . substr( $hash, 0, 2 );
00471
if ( ! is_dir( $archive ) ) { @mkdir( $archive, 0777 ); }
00472
00473 umask( $oldumask );
00474
return $archive;
00475 }
00476
00477 function
wfRecordUpload( $name, $oldver, $size, $desc, $copyStatus =
"", $source =
"" )
00478 {
00479 global
$wgUser,
$wgLang,
$wgTitle,
$wgOut,
$wgDeferredUpdateList;
00480 global $wgUseCopyrightUpload;
00481
00482 $fname = '
wfRecordUpload';
00483
00484
$sql = 'SELECT img_name,img_size,img_timestamp,img_description,img_user,' .
00485
"img_user_text FROM image WHERE img_name='" .
wfStrencode( $
name ) .
"'";
00486
$res =
wfQuery( $sql,
DB_READ, $fname );
00487
00488 $now =
wfTimestampNow();
00489 $won =
wfInvertTimestamp( $now );
00490 $size = IntVal( $size );
00491
00492
if ( $wgUseCopyrightUpload )
00493 {
00494 $textdesc = '== ' .
wfMsg ( 'filedesc' ) .
" ==\n" . $desc .
"\n" .
00495 '== ' .
wfMsg ( 'filestatus' ) .
" ==\n" . $copyStatus .
"\n" .
00496 '== ' .
wfMsg ( 'filesource' ) .
" ==\n" . $source ;
00497 }
00498
else $textdesc = $desc ;
00499
00500 $now =
wfTimestampNow();
00501 $won =
wfInvertTimestamp( $now );
00502
00503
if ( 0 ==
wfNumRows( $res ) ) {
00504
$sql = 'INSERT INTO image (img_name,img_size,img_timestamp,' .
00505
"img_description,img_user,img_user_text) VALUES ('" .
00506
wfStrencode( $
name ) .
"',$size,'{$now}','" .
00507
wfStrencode( $desc ) .
"', '" . $wgUser->getID() .
00508
"', '" .
wfStrencode( $wgUser->getName() ) .
"')";
00509
wfQuery( $sql,
DB_WRITE, $fname );
00510
00511
$sql = 'SELECT
cur_id,cur_text FROM cur WHERE cur_namespace=' .
00512
Namespace::getImage() .
" AND cur_title='" .
00513
wfStrencode( $
name ) .
"'";
00514
$res =
wfQuery( $sql,
DB_READ, $fname );
00515
if ( 0 ==
wfNumRows( $res ) ) {
00516 $common =
00517
Namespace::getImage() .
",'" .
00518
wfStrencode( $
name ) .
"','" .
00519
wfStrencode( $desc ) .
"','" .
$wgUser->getID() .
"','" .
00520
wfStrencode( $wgUser->getName() ) .
"','" . $now .
00521
"',1";
00522
$sql = 'INSERT INTO cur (cur_namespace,cur_title,' .
00523 'cur_comment,cur_user,cur_user_text,cur_timestamp,cur_is_new,' .
00524 'cur_text,inverse_timestamp,cur_touched) VALUES (' .
00525 $common .
00526
",'" .
wfStrencode( $textdesc ) .
"','{$won}','{$now}')";
00527
wfQuery( $sql,
DB_WRITE, $fname );
00528 $
id =
wfInsertId() or 0; # We should
throw an error instead
00529
00530 $titleObj = Title::makeTitle(
NS_IMAGE, $
name );
00531 RecentChange::notifyNew( $now, $titleObj, 0, $wgUser, $desc );
00532
00533 $u =
new SearchUpdate( $
id, $
name, $desc );
00534 $u->doUpdate();
00535 }
00536 }
else {
00537
$s =
wfFetchObject( $res );
00538
00539
$sql = 'INSERT INTO oldimage (oi_name,oi_archive_name,oi_size,' .
00540
"oi_timestamp,oi_description,oi_user,oi_user_text) VALUES ('" .
00541
wfStrencode( $s->img_name ) .
"','" .
00542
wfStrencode( $oldver ) .
00543
"',{$s->img_size},'{$s->img_timestamp}','" .
00544
wfStrencode( $s->img_description ) .
"','" .
00545
wfStrencode( $s->img_user ) .
"','" .
00546
wfStrencode( $s->img_user_text) .
"')";
00547
wfQuery( $sql,
DB_WRITE, $fname );
00548
00549 $sql =
"UPDATE image SET img_size={$size}," .
00550
"img_timestamp='" .
wfTimestampNow() .
"',img_user='" .
00551 $wgUser->getID() .
"',img_user_text='" .
00552
wfStrencode( $wgUser->getName() ) .
"', img_description='" .
00553
wfStrencode( $desc ) .
"' WHERE img_name='" .
00554
wfStrencode( $
name ) .
"'";
00555
wfQuery( $sql,
DB_WRITE, $fname );
00556
00557
$sql =
"UPDATE cur SET cur_touched='{$now}' WHERE cur_namespace=" .
00558
Namespace::getImage() .
" AND cur_title='" .
00559
wfStrencode( $
name ) .
"'";
00560
wfQuery( $sql,
DB_WRITE, $fname );
00561 }
00562
00563 $log =
new LogPage(
wfMsg( 'uploadlogpage' ),
wfMsg( 'uploadlogpagetext' ) );
00564 $da =
wfMsg( 'uploadedimage', '[[:' . $wgLang->getNsText(
00565 Namespace::getImage() ) .
":{$name}|{$name}]]" );
00566 $ta =
wfMsg( 'uploadedimage', $
name );
00567 $log->addEntry( $da, $desc, $
ta );
00568 }
00569
00570
00571
00572
00573 function
wfShowingResults( $offset, $limit )
00574 {
00575 global
$wgLang;
00576
return wfMsg( 'showingresults', $wgLang->formatNum( $limit ),
$wgLang->formatNum( $offset+1 ) );
00577 }
00578
00579 function
wfShowingResultsNum( $offset, $limit, $num )
00580 {
00581 global
$wgLang;
00582
return wfMsg( 'showingresultsnum', $wgLang->formatNum( $limit ),
$wgLang->formatNum( $offset+1 ),
$wgLang->formatNum( $num ) );
00583 }
00584
00585 function
wfViewPrevNext( $offset, $limit, $link, $query = '', $atend =
false )
00586 {
00587 global
$wgUser,
$wgLang;
00588 $fmtLimit =
$wgLang->formatNum( $limit );
00589 $prev =
wfMsg( 'prevn', $fmtLimit );
00590 $next =
wfMsg( 'nextn', $fmtLimit );
00591 $link =
wfUrlencode( $link );
00592
00593 $sk =
$wgUser->getSkin();
00594
if ( 0 != $offset ) {
00595 $po = $offset - $limit;
00596
if ( $po < 0 ) { $po = 0; }
00597 $q =
"limit={$limit}&offset={$po}";
00598
if ( '' != $query ) { $q .=
"&{$query}"; }
00599 $plink = '<a href=
"' . wfLocalUrlE( $link, $q ) . "\
">{$prev}</a>";
00600 }
else { $plink = $prev; }
00601
00602 $no = $offset + $limit;
00603 $q =
"limit={$limit}&offset={$no}";
00604
if (
"" != $query ) { $q .=
"&{$query}"; }
00605
00606
if ( $atend ) {
00607 $nlink = $next;
00608 }
else {
00609 $nlink = '<a href=
"' . wfLocalUrlE( $link, $q ) . "\
">{$next}</a>";
00610 }
00611 $nums =
wfNumLink( $offset, 20, $link , $query ) . ' | ' .
00612
wfNumLink( $offset, 50, $link, $query ) . ' | ' .
00613
wfNumLink( $offset, 100, $link, $query ) . ' | ' .
00614
wfNumLink( $offset, 250, $link, $query ) . ' | ' .
00615
wfNumLink( $offset, 500, $link, $query );
00616
00617
return wfMsg( 'viewprevnext', $plink, $nlink, $nums );
00618 }
00619
00620 function
wfNumLink( $offset, $limit, $link, $query = '' )
00621 {
00622 global
$wgUser,
$wgLang;
00623
if ( '' == $query ) { $q = ''; }
00624
else { $q =
"{$query}&"; }
00625 $q .=
"limit={$limit}&offset={$offset}";
00626
00627 $fmtLimit =
$wgLang->formatNum( $limit );
00628
$s = '<a href=
"' . wfLocalUrlE( $link, $q ) . "\
">{$fmtLimit}</a>";
00629
return $s;
00630 }
00631
00632 function
wfClientAcceptsGzip() {
00633 global
$wgUseGzip;
00634
if(
$wgUseGzip ) {
00635
# FIXME: we may want to blacklist some broken browsers
00636
if( preg_match(
00637 '/\bgzip(?:;(q)=([0-9]+(?:\.[0-9]+)))?\b/',
00638 $_SERVER['HTTP_ACCEPT_ENCODING'],
00639 $m ) ) {
00640
if( ( $m[1] ==
'q' ) && ( $m[2] == 0 ) )
return false;
00641
wfDebug(
" accepts gzip\n" );
00642
return true;
00643 }
00644 }
00645
return false;
00646 }
00647
00648
# Yay, more global functions!
00649 function
wfCheckLimits( $deflimit = 50, $optionname = 'rclimit' ) {
00650 global
$wgUser,
$wgRequest;
00651
00652 $limit =
$wgRequest->getInt( 'limit', 0 );
00653
if( $limit < 0 ) $limit = 0;
00654
if( ( $limit == 0 ) && ( $optionname != '' ) ) {
00655 $limit = (
int)
$wgUser->getOption( $optionname );
00656 }
00657
if( $limit <= 0 ) $limit = $deflimit;
00658
if( $limit > 5000 ) $limit = 5000; # We have *some* limits...
00659
00660 $offset =
$wgRequest->getInt( 'offset', 0 );
00661
if( $offset < 0 ) $offset = 0;
00662
if( $offset > 65000 ) $offset = 65000; #
do we need a max? what?
00663
00664
return array( $limit, $offset );
00665 }
00666
00667
# Escapes the given text so that it may be output using addWikiText()
00668
# without any linking, formatting, etc. making its way through. This
00669
# is achieved by substituting certain characters with HTML entities.
00670
# As required by the callers, <nowiki> is not used. It currently does
00671
# not filter out characters which have special meaning only at the
00672
# start of a line, such as "*".
00673 function
wfEscapeWikiText( $text )
00674 {
00675 $text = str_replace(
00676 array(
'[',
'|',
"'", 'ISBN ' , ':
00677 array( '[', '|', ''', 'ISBN ', ':
00678 htmlspecialchars($text) );
00679
return $text;
00680 }
00681
00682 function
wfQuotedPrintable( $string, $charset = '' )
00683 {
00684 # Probably incomplete; see RFC 2045
00685
if( empty( $charset ) ) {
00686 global $wgInputEncoding;
00687 $charset = $wgInputEncoding;
00688 }
00689 $charset = strtoupper( $charset );
00690 $charset = str_replace( 'ISO-8859', 'ISO8859', $charset );
00691
00692 $illegal = '\x00-\x08\x0b\x0c\x0e-\x1f\x7f-\xff=';
00693 $replace = $illegal . '\t ?_';
00694
if( !preg_match(
"/[$illegal]/", $string ) )
return $string;
00695 $out =
"=?$charset?Q?";
00696 $out .= preg_replace(
"/([$replace])/e", 'sprintf(
"=%02X",ord(
"$1"))', $string );
00697 $out .= '?=';
00698
return $out;
00699 }
00700
00701 function
wfTime(){
00702 $st = explode(
' ', microtime() );
00703
return (
float)$st[0] + (
float)$st[1];
00704 }
00705
00706 # Changes the first character to an HTML entity
00707 function
wfHtmlEscapeFirst( $text ) {
00708 $ord = ord($text);
00709 $newText = substr($text, 1);
00710
return "&#$ord;$newText";
00711 }
00712
00713 # Sets dest to source and returns the original value of dest
00714 function
wfSetVar( &$dest, $source )
00715 {
00716 $temp = $dest;
00717 $dest = $source;
00718
return $temp;
00719 }
00720
00721 # Sets dest to a reference to source and returns the original dest
00722 # Pity that doesn't work in PHP
00723 function &
wfSetRef( &$dest, &$source )
00724 {
00725 die(
"You can't rebind a variable in the caller's scope" );
00726 }
00727
00728 # This function takes two arrays as input, and returns a CGI-style string, e.g.
00729 #
"days=7&limit=100". Options in the first array override options in the second.
00730 # Options set to
"" will not be output.
00731 function
wfArrayToCGI( $array1, $array2 = NULL )
00732 {
00733
if ( !is_null( $array2 ) ) {
00734 $array1 = $array1 + $array2;
00735 }
00736
00737 $cgi = '';
00738 foreach ( $array1 as $key => $value ) {
00739
if ( '' !== $value ) {
00740
if ( '' != $cgi ) {
00741 $cgi .=
'&';
00742 }
00743 $cgi .=
"{$key}={$value}";
00744 }
00745 }
00746
return $cgi;
00747 }
00748
00749 # This is obsolete, use SquidUpdate::purge()
00750 function wfPurgeSquidServers ($urlArr) {
00751 SquidUpdate::purge( $urlArr );
00752 }
00753
00754 # Windows-compatible version of escapeshellarg()
00755 function
wfEscapeShellArg( )
00756 {
00757 $args = func_get_args();
00758 $first =
true;
00759 $retVal = '';
00760 foreach ( $args as $arg ) {
00761
if ( !$first ) {
00762 $retVal .=
' ';
00763 }
else {
00764 $first =
false;
00765 }
00766
00767
if (
wfIsWindows() ) {
00768 $retVal .=
'"' . str_replace(
'"',
'\"', $arg ) .
'"';
00769 }
else {
00770 $retVal .= escapeshellarg( $arg );
00771 }
00772 }
00773
return $retVal;
00774 }
00775
00776 # wfMerge attempts to merge differences between three texts.
00777 # Returns
true for a clean merge and
false for failure or a conflict.
00778
00779 function
wfMerge( $old, $mine, $yours, &$result ){
00780 global $wgDiff3;
00781
00782 # This check may also protect against code injection in
00783 #
case of broken installations.
00784
if(! file_exists( $wgDiff3 ) ){
00785
return false;
00786 }
00787
00788 # Make temporary files
00789 $td = '/tmp/';
00790 $oldtextFile = fopen( $oldtextName = tempnam( $td, 'merge-old-' ),
'w' );
00791 $mytextFile = fopen( $mytextName = tempnam( $td, 'merge-mine-' ),
'w' );
00792 $yourtextFile = fopen( $yourtextName = tempnam( $td, 'merge-your-' ),
'w' );
00793
00794 fwrite( $oldtextFile, $old ); fclose( $oldtextFile );
00795 fwrite( $mytextFile, $mine ); fclose( $mytextFile );
00796 fwrite( $yourtextFile, $yours ); fclose( $yourtextFile );
00797
00798 # Check
for a conflict
00799 $cmd =
wfEscapeShellArg( $wgDiff3 ) . ' -a --overlap-only ' .
00800
wfEscapeShellArg( $mytextName ) .
' ' .
00801
wfEscapeShellArg( $oldtextName ) .
' ' .
00802
wfEscapeShellArg( $yourtextName );
00803 $handle = popen( $cmd,
'r' );
00804
00805
if( fgets( $handle ) ){
00806 $conflict =
true;
00807 }
else {
00808 $conflict =
false;
00809 }
00810 pclose( $handle );
00811
00812 # Merge differences
00813 $cmd =
wfEscapeShellArg( $wgDiff3 ) . ' -a -e --merge ' .
00814
wfEscapeShellArg( $mytextName, $oldtextName, $yourtextName );
00815 $handle = popen( $cmd,
'r' );
00816 $result = '';
00817
do {
00818 $data = fread( $handle, 8192 );
00819
if ( strlen( $data ) == 0 ) {
00820
break;
00821 }
00822 $result .= $data;
00823 }
while (
true );
00824 pclose( $handle );
00825 unlink( $mytextName ); unlink( $oldtextName ); unlink( $yourtextName );
00826
return ! $conflict;
00827 }
00828
00829 function
wfVarDump( $var )
00830 {
00831 global $wgOut;
00832 $s = str_replace(
"\n",
"<br>\n", var_export( $var,
true ) .
"\n");
00833
if ( headers_sent() || !@is_object( $wgOut ) ) {
00834 print $s;
00835 }
else {
00836 $wgOut->addHTML( $s );
00837 }
00838 }
00839
00840
# Provide a simple HTTP error.
00841 function
wfHttpError( $code, $label, $desc ) {
00842 global
$wgOut;
00843
$wgOut->disable();
00844 header(
"HTTP/1.0 $code $label" );
00845 header(
"Status: $code $label" );
00846
$wgOut->sendCacheControl();
00847
00848
# Don't send content if it's a HEAD request.
00849
if( $_SERVER['REQUEST_METHOD'] == 'HEAD' ) {
00850 header( 'Content-type: text/plain' );
00851 print
"$desc\n";
00852 }
00853 }
00854
00855
# Converts an Accept-* header into an array mapping string values to quality factors
00856 function
wfAcceptToPrefs( $accept, $def = '*
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879 function
mimeTypeMatch( $type, $avail ) {
00880
if( array_key_exists($type, $avail) ) {
00881
return $type;
00882 }
else {
00883 $parts = explode(
'/', $type );
00884
if( array_key_exists( $parts[0] . '
00885
00886 *', $avail ) ) {
00887
return '*
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950