diff options
author | Luke Shumaker <LukeShu@sbcglobal.net> | 2014-01-28 09:50:25 -0500 |
---|---|---|
committer | Luke Shumaker <LukeShu@sbcglobal.net> | 2014-01-28 09:50:25 -0500 |
commit | 5744df39e15f85c6cc8a9faf8924d77e76d2b216 (patch) | |
tree | a8c8dd40a94d1fa0d5377566aa5548ae55a163da /includes/GlobalFunctions.php | |
parent | 4bb2aeca1d198391ca856aa16c40b8559c68daec (diff) | |
parent | 224b22a051051f6c2e494c3a2fb4adb42898e2d1 (diff) |
Merge branch 'archwiki'
Conflicts:
extensions/FluxBBAuthPlugin.php
extensions/SyntaxHighlight_GeSHi/README
extensions/SyntaxHighlight_GeSHi/SyntaxHighlight_GeSHi.class.php
extensions/SyntaxHighlight_GeSHi/SyntaxHighlight_GeSHi.i18n.php
extensions/SyntaxHighlight_GeSHi/SyntaxHighlight_GeSHi.php
extensions/SyntaxHighlight_GeSHi/geshi/docs/CHANGES
extensions/SyntaxHighlight_GeSHi/geshi/docs/THANKS
extensions/SyntaxHighlight_GeSHi/geshi/docs/TODO
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/AbstractClass.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/AbstractClass_logo.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/AbstractMethod.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/AbstractPrivateClass.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/AbstractPrivateClass_logo.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/AbstractPrivateMethod.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Class.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Class_logo.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Constant.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Constructor.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Destructor.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Function.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Global.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/I.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Index.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Interface.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Interface_logo.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/L.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Lminus.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Lplus.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Method.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Page.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Page_logo.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/PrivateClass.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/PrivateClass_logo.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/PrivateMethod.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/PrivateVariable.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/StaticMethod.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/StaticVariable.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/T.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Tminus.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Tplus.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Variable.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/blank.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/class_folder.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/file.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/folder.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/function_folder.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/next_button.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/next_button_disabled.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/package.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/package_folder.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/previous_button.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/previous_button_disabled.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/private_class_logo.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/tutorial.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/tutorial_folder.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/up_button.png
extensions/SyntaxHighlight_GeSHi/geshi/docs/geshi-doc.html
extensions/SyntaxHighlight_GeSHi/geshi/docs/geshi-doc.txt
extensions/SyntaxHighlight_GeSHi/geshi/geshi.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/4cs.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/6502acme.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/6502kickass.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/6502tasm.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/68000devpac.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/abap.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/actionscript.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/actionscript3.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/ada.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/algol68.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/apache.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/applescript.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/apt_sources.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/asm.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/asp.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/autoconf.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/autohotkey.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/autoit.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/avisynth.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/awk.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/bascomavr.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/bash.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/basic4gl.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/bf.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/bibtex.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/blitzbasic.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/bnf.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/boo.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/c.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/c_loadrunner.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/c_mac.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/caddcl.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/cadlisp.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/cfdg.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/cfm.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/chaiscript.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/cil.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/clojure.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/cmake.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/cobol.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/coffeescript.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/cpp-qt.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/cpp.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/csharp.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/css.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/cuesheet.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/d.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/dcs.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/delphi.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/diff.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/div.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/dos.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/dot.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/e.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/ecmascript.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/eiffel.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/email.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/epc.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/erlang.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/euphoria.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/f1.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/falcon.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/fo.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/fortran.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/freebasic.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/fsharp.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/gambas.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/gdb.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/genero.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/genie.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/gettext.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/glsl.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/gml.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/gnuplot.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/go.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/groovy.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/gwbasic.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/haskell.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/hicest.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/hq9plus.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/html4strict.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/html5.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/icon.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/idl.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/ini.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/inno.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/intercal.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/io.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/j.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/java.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/java5.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/javascript.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/jquery.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/kixtart.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/klonec.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/klonecpp.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/latex.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/lb.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/lisp.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/llvm.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/locobasic.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/logtalk.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/lolcode.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/lotusformulas.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/lotusscript.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/lscript.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/lsl2.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/lua.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/m68k.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/magiksf.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/make.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/mapbasic.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/matlab.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/mirc.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/mmix.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/modula2.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/modula3.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/mpasm.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/mxml.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/mysql.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/newlisp.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/nsis.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/oberon2.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/objc.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/objeck.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/ocaml-brief.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/ocaml.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/oobas.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/oracle11.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/oracle8.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/oxygene.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/oz.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/pascal.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/pcre.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/per.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/perl.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/perl6.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/pf.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/php-brief.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/php.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/pic16.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/pike.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/pixelbender.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/pli.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/plsql.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/postgresql.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/povray.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/powerbuilder.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/powershell.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/proftpd.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/progress.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/prolog.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/properties.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/providex.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/purebasic.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/pycon.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/python.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/q.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/qbasic.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/rails.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/rebol.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/reg.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/robots.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/rpmspec.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/rsplus.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/ruby.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/sas.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/scala.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/scheme.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/scilab.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/sdlbasic.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/smalltalk.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/smarty.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/sql.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/systemverilog.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/tcl.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/teraterm.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/text.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/thinbasic.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/tsql.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/typoscript.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/unicon.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/uscript.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/vala.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/vb.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/vbnet.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/verilog.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/vhdl.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/vim.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/visualfoxpro.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/visualprolog.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/whitespace.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/whois.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/winbatch.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/xbasic.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/xml.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/xorg_conf.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/xpp.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/yaml.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/z80.php
extensions/SyntaxHighlight_GeSHi/geshi/geshi/zxbasic.php
Diffstat (limited to 'includes/GlobalFunctions.php')
-rw-r--r-- | includes/GlobalFunctions.php | 1063 |
1 files changed, 565 insertions, 498 deletions
diff --git a/includes/GlobalFunctions.php b/includes/GlobalFunctions.php index 50758c89..77c09e53 100644 --- a/includes/GlobalFunctions.php +++ b/includes/GlobalFunctions.php @@ -35,7 +35,7 @@ if ( !defined( 'MEDIAWIKI' ) ) { * PHP extensions may be included here. */ -if( !function_exists( 'iconv' ) ) { +if ( !function_exists( 'iconv' ) ) { /** * @codeCoverageIgnore * @return string @@ -50,7 +50,7 @@ if ( !function_exists( 'mb_substr' ) ) { * @codeCoverageIgnore * @return string */ - function mb_substr( $str, $start, $count='end' ) { + function mb_substr( $str, $start, $count = 'end' ) { return Fallback::mb_substr( $str, $start, $count ); } @@ -73,7 +73,7 @@ if ( !function_exists( 'mb_strlen' ) ) { } } -if( !function_exists( 'mb_strpos' ) ) { +if ( !function_exists( 'mb_strpos' ) ) { /** * @codeCoverageIgnore * @return int @@ -84,7 +84,7 @@ if( !function_exists( 'mb_strpos' ) ) { } -if( !function_exists( 'mb_strrpos' ) ) { +if ( !function_exists( 'mb_strrpos' ) ) { /** * @codeCoverageIgnore * @return int @@ -94,25 +94,16 @@ if( !function_exists( 'mb_strrpos' ) ) { } } - -// Support for Wietse Venema's taint feature -if ( !function_exists( 'istainted' ) ) { +// gzdecode function only exists in PHP >= 5.4.0 +// http://php.net/gzdecode +if ( !function_exists( 'gzdecode' ) ) { /** * @codeCoverageIgnore - * @return int + * @return string */ - function istainted( $var ) { - return 0; + function gzdecode( $data ) { + return gzinflate( substr( $data, 10, -8 ) ); } - /** @codeCoverageIgnore */ - function taint( $var, $level = 0 ) {} - /** @codeCoverageIgnore */ - function untaint( $var, $level = 0 ) {} - define( 'TC_HTML', 1 ); - define( 'TC_SHELL', 1 ); - define( 'TC_MYSQL', 1 ); - define( 'TC_PCRE', 1 ); - define( 'TC_SELF', 1 ); } /// @endcond @@ -127,19 +118,19 @@ function wfArrayDiff2( $a, $b ) { } /** - * @param $a - * @param $b + * @param $a array|string + * @param $b array|string * @return int */ function wfArrayDiff2_cmp( $a, $b ) { - if ( !is_array( $a ) ) { + if ( is_string( $a ) && is_string( $b ) ) { return strcmp( $a, $b ); } elseif ( count( $a ) !== count( $b ) ) { return count( $a ) < count( $b ) ? -1 : 1; } else { reset( $a ); reset( $b ); - while( ( list( , $valueA ) = each( $a ) ) && ( list( , $valueB ) = each( $b ) ) ) { + while ( ( list( , $valueA ) = each( $a ) ) && ( list( , $valueB ) = each( $b ) ) ) { $cmp = strcmp( $valueA, $valueB ); if ( $cmp !== 0 ) { return $cmp; @@ -151,14 +142,16 @@ function wfArrayDiff2_cmp( $a, $b ) { /** * Array lookup - * Returns an array where the values in the first array are replaced by the - * values in the second array with the corresponding keys + * Returns an array where the values in array $b are replaced by the + * values in array $a with the corresponding keys * + * @deprecated since 1.22; use array_intersect_key() * @param $a Array * @param $b Array * @return array */ function wfArrayLookup( $a, $b ) { + wfDeprecated( __FUNCTION__, '1.22' ); return array_flip( array_intersect( array_flip( $a ), array_keys( $b ) ) ); } @@ -168,7 +161,8 @@ function wfArrayLookup( $a, $b ) { * @param $key String|Int * @param $value Mixed * @param $default Mixed - * @param $changed Array to alter + * @param array $changed to alter + * @throws MWException */ function wfAppendToArrayIfNotDefault( $key, $value, $default, &$changed ) { if ( is_null( $changed ) ) { @@ -183,11 +177,13 @@ function wfAppendToArrayIfNotDefault( $key, $value, $default, &$changed ) { * Backwards array plus for people who haven't bothered to read the PHP manual * XXX: will not darn your socks for you. * + * @deprecated since 1.22; use array_replace() * @param $array1 Array * @param [$array2, [...]] Arrays * @return Array */ function wfArrayMerge( $array1/* ... */ ) { + wfDeprecated( __FUNCTION__, '1.22' ); $args = func_get_args(); $args = array_reverse( $args, true ); $out = array(); @@ -232,8 +228,8 @@ function wfMergeErrorArrays( /*...*/ ) { /** * Insert array into another array after the specified *KEY* * - * @param $array Array: The array. - * @param $insert Array: The array to insert. + * @param array $array The array. + * @param array $insert The array to insert. * @param $after Mixed: The key to insert after * @return Array */ @@ -262,7 +258,7 @@ function wfArrayInsertAfter( array $array, array $insert, $after ) { */ function wfObjectToArray( $objOrArray, $recursive = true ) { $array = array(); - if( is_object( $objOrArray ) ) { + if ( is_object( $objOrArray ) ) { $objOrArray = get_object_vars( $objOrArray ); } foreach ( $objOrArray as $key => $value ) { @@ -277,24 +273,6 @@ function wfObjectToArray( $objOrArray, $recursive = true ) { } /** - * Wrapper around array_map() which also taints variables - * - * @param $function Callback - * @param $input Array - * @return Array - */ -function wfArrayMap( $function, $input ) { - $ret = array_map( $function, $input ); - foreach ( $ret as $key => $value ) { - $taint = istainted( $input[$key] ); - if ( $taint ) { - taint( $ret[$key], $taint ); - } - } - return $ret; -} - -/** * Get a random decimal value between 0 and 1, in a way * not likely to give duplicate values for any realistic * number of articles. @@ -311,19 +289,19 @@ function wfRandom() { } /** - * Get a random string containing a number of pesudo-random hex + * Get a random string containing a number of pseudo-random hex * characters. * @note This is not secure, if you are trying to generate some sort * of token please use MWCryptRand instead. * - * @param $length int The length of the string to generate + * @param int $length The length of the string to generate * @return String * @since 1.20 */ function wfRandomString( $length = 32 ) { $str = ''; - while ( strlen( $str ) < $length ) { - $str .= dechex( mt_rand() ); + for ( $n = 0; $n < $length; $n += 7 ) { + $str .= sprintf( '%07x', mt_rand() & 0xfffffff ); } return substr( $str, 0, $length ); } @@ -349,7 +327,7 @@ function wfRandomString( $length = 32 ) { * * @param $s String: * @return string -*/ + */ function wfUrlencode( $s ) { static $needle; if ( is_null( $s ) ) { @@ -379,8 +357,8 @@ function wfUrlencode( $s ) { * "days=7&limit=100". Options in the first array override options in the second. * Options set to null or false will not be output. * - * @param $array1 Array ( String|Array ) - * @param $array2 Array ( String|Array ) + * @param array $array1 ( String|Array ) + * @param array $array2 ( String|Array ) * @param $prefix String * @return String */ @@ -391,7 +369,7 @@ function wfArrayToCgi( $array1, $array2 = null, $prefix = '' ) { $cgi = ''; foreach ( $array1 as $key => $value ) { - if ( !is_null($value) && $value !== false ) { + if ( !is_null( $value ) && $value !== false ) { if ( $cgi != '' ) { $cgi .= '&'; } @@ -422,11 +400,11 @@ function wfArrayToCgi( $array1, $array2 = null, $prefix = '' ) { /** * This is the logical opposite of wfArrayToCgi(): it accepts a query string as - * its argument and returns the same string in array form. This allows compa- - * tibility with legacy functions that accept raw query strings instead of nice + * its argument and returns the same string in array form. This allows compatibility + * with legacy functions that accept raw query strings instead of nice * arrays. Of course, keys and values are urldecode()d. * - * @param $query String: query string + * @param string $query query string * @return array Array version of input */ function wfCgiToArray( $query ) { @@ -480,8 +458,8 @@ function wfAppendQuery( $url, $query ) { if ( is_array( $query ) ) { $query = wfArrayToCgi( $query ); } - if( $query != '' ) { - if( false === strpos( $url, '?' ) ) { + if ( $query != '' ) { + if ( false === strpos( $url, '?' ) ) { $url .= '?'; } else { $url .= '&'; @@ -506,7 +484,7 @@ function wfAppendQuery( $url, $query ) { * @todo this won't work with current-path-relative URLs * like "subdir/foo.html", etc. * - * @param $url String: either fully-qualified or a local path + query + * @param string $url either fully-qualified or a local path + query * @param $defaultProto Mixed: one of the PROTO_* constants. Determines the * protocol to use if $url or $wgServer is * protocol-relative @@ -576,7 +554,7 @@ function wfExpandUrl( $url, $defaultProto = PROTO_CURRENT ) { * @todo Need to integrate this into wfExpandUrl (bug 32168) * * @since 1.19 - * @param $urlParts Array URL parts, as output from wfParseUrl + * @param array $urlParts URL parts, as output from wfParseUrl * @return string URL assembled from its component parts */ function wfAssembleUrl( $urlParts ) { @@ -628,7 +606,7 @@ function wfAssembleUrl( $urlParts ) { * * @todo Need to integrate this into wfExpandUrl (bug 32168) * - * @param $urlPath String URL path, potentially containing dot-segments + * @param string $urlPath URL path, potentially containing dot-segments * @return string URL path with all dot-segments removed */ function wfRemoveDotSegments( $urlPath ) { @@ -705,7 +683,7 @@ function wfRemoveDotSegments( $urlPath ) { /** * Returns a regular expression of url protocols * - * @param $includeProtocolRelative bool If false, remove '//' from the returned protocol list. + * @param bool $includeProtocolRelative If false, remove '//' from the returned protocol list. * DO NOT USE this directly, use wfUrlProtocolsWithoutProtRel() instead * @return String */ @@ -765,7 +743,7 @@ function wfUrlProtocolsWithoutProtRel() { * 2) Handles protocols that don't use :// (e.g., mailto: and news: , as well as protocol-relative URLs) correctly * 3) Adds a "delimiter" element to the array, either '://', ':' or '//' (see (2)) * - * @param $url String: a URL to parse + * @param string $url a URL to parse * @return Array: bits of the URL in an associative array, per PHP docs */ function wfParseUrl( $url ) { @@ -808,9 +786,14 @@ function wfParseUrl( $url ) { if ( !isset( $bits['host'] ) ) { $bits['host'] = ''; - /* parse_url loses the third / for file:///c:/ urls (but not on variants) */ - if ( substr( $bits['path'], 0, 1 ) !== '/' ) { - $bits['path'] = '/' . $bits['path']; + // bug 45069 + if ( isset( $bits['path'] ) ) { + /* parse_url loses the third / for file:///c:/ urls (but not on variants) */ + if ( substr( $bits['path'], 0, 1 ) !== '/' ) { + $bits['path'] = '/' . $bits['path']; + } + } else { + $bits['path'] = ''; } } @@ -845,8 +828,6 @@ function wfExpandIRI_callback( $matches ) { return urldecode( $matches[1] ); } - - /** * Make URL indexes, appropriate for the el_index field of externallinks. * @@ -903,17 +884,17 @@ function wfMakeUrlIndexes( $url ) { /** * Check whether a given URL has a domain that occurs in a given set of domains - * @param $url string URL - * @param $domains array Array of domains (strings) + * @param string $url URL + * @param array $domains Array of domains (strings) * @return bool True if the host part of $url ends in one of the strings in $domains */ function wfMatchesDomainList( $url, $domains ) { $bits = wfParseUrl( $url ); if ( is_array( $bits ) && isset( $bits['host'] ) ) { + $host = '.' . $bits['host']; foreach ( (array)$domains as $domain ) { - // FIXME: This gives false positives. http://nds-nl.wikipedia.org will match nl.wikipedia.org - // We should use something that interprets dots instead - if ( substr( $bits['host'], -strlen( $domain ) ) === $domain ) { + $domain = '.' . $domain; + if ( substr( $host, -strlen( $domain ) ) === $domain ) { return true; } } @@ -932,7 +913,7 @@ function wfMatchesDomainList( $url, $domains ) { * $wgDebugComments - if on, some debug items may appear in comments in the HTML output. * * @param $text String - * @param $logonly Bool: set true to avoid appearing in HTML when $wgDebugComments is set + * @param bool $logonly set true to avoid appearing in HTML when $wgDebugComments is set */ function wfDebug( $text, $logonly = false ) { global $wgDebugLogFile, $wgProfileOnly, $wgDebugRawPage, $wgDebugLogPrefix; @@ -950,14 +931,12 @@ function wfDebug( $text, $logonly = false ) { MWDebug::debugMsg( $text ); } - if ( wfRunHooks( 'Debug', array( $text, null /* no log group */ ) ) ) { - if ( $wgDebugLogFile != '' && !$wgProfileOnly ) { - # Strip unprintables; they can switch terminal modes when binary data - # gets dumped, which is pretty annoying. - $text = preg_replace( '![\x00-\x08\x0b\x0c\x0e-\x1f]!', ' ', $text ); - $text = $wgDebugLogPrefix . $text; - wfErrorLog( $text, $wgDebugLogFile ); - } + if ( $wgDebugLogFile != '' && !$wgProfileOnly ) { + # Strip unprintables; they can switch terminal modes when binary data + # gets dumped, which is pretty annoying. + $text = preg_replace( '![\x00-\x08\x0b\x0c\x0e-\x1f]!', ' ', $text ); + $text = $wgDebugLogPrefix . $text; + wfErrorLog( $text, $wgDebugLogFile ); } } @@ -1004,11 +983,11 @@ function wfDebugTimer() { /** * Send a line giving PHP memory usage. * - * @param $exact Bool: print exact values instead of kilobytes (default: false) + * @param bool $exact print exact values instead of kilobytes (default: false) */ function wfDebugMem( $exact = false ) { $mem = memory_get_usage(); - if( !$exact ) { + if ( !$exact ) { $mem = floor( $mem / 1024 ) . ' kilobytes'; } else { $mem .= ' bytes'; @@ -1022,28 +1001,26 @@ function wfDebugMem( $exact = false ) { * * @param $logGroup String * @param $text String - * @param $public Bool: whether to log the event in the public log if no private + * @param bool $public whether to log the event in the public log if no private * log file is specified, (default true) */ function wfDebugLog( $logGroup, $text, $public = true ) { global $wgDebugLogGroups; $text = trim( $text ) . "\n"; - if( isset( $wgDebugLogGroups[$logGroup] ) ) { + if ( isset( $wgDebugLogGroups[$logGroup] ) ) { $time = wfTimestamp( TS_DB ); $wiki = wfWikiID(); $host = wfHostname(); - if ( wfRunHooks( 'Debug', array( $text, $logGroup ) ) ) { - wfErrorLog( "$time $host $wiki: $text", $wgDebugLogGroups[$logGroup] ); - } + wfErrorLog( "$time $host $wiki: $text", $wgDebugLogGroups[$logGroup] ); } elseif ( $public === true ) { - wfDebug( $text, true ); + wfDebug( "[$logGroup] $text", false ); } } /** * Log for database errors * - * @param $text String: database error message. + * @param string $text database error message. */ function wfLogDBError( $text ) { global $wgDBerrorLog, $wgDBerrorLogTZ; @@ -1076,9 +1053,9 @@ function wfLogDBError( $text ) { * Throws a warning that $function is deprecated * * @param $function String - * @param $version String|bool: Version of MediaWiki that the function was deprecated in (Added in 1.19). - * @param $component String|bool: Added in 1.19. - * @param $callerOffset integer: How far up the callstack is the original + * @param string|bool $version Version of MediaWiki that the function was deprecated in (Added in 1.19). + * @param string|bool $component Added in 1.19. + * @param $callerOffset integer: How far up the call stack is the original * caller. 2 = function that called the function that called * wfDeprecated (Added in 1.20) * @@ -1090,16 +1067,29 @@ function wfDeprecated( $function, $version = false, $component = false, $callerO /** * Send a warning either to the debug log or in a PHP error depending on - * $wgDevelopmentWarnings + * $wgDevelopmentWarnings. To log warnings in production, use wfLogWarning() instead. * - * @param $msg String: message to send + * @param string $msg message to send * @param $callerOffset Integer: number of items to go back in the backtrace to * find the correct caller (1 = function calling wfWarn, ...) - * @param $level Integer: PHP error level; only used when $wgDevelopmentWarnings - * is true + * @param $level Integer: PHP error level; defaults to E_USER_NOTICE; + * only used when $wgDevelopmentWarnings is true */ function wfWarn( $msg, $callerOffset = 1, $level = E_USER_NOTICE ) { - MWDebug::warning( $msg, $callerOffset + 1, $level ); + MWDebug::warning( $msg, $callerOffset + 1, $level, 'auto' ); +} + +/** + * Send a warning as a PHP error and the debug log. This is intended for logging + * warnings in production. For logging development warnings, use WfWarn instead. + * + * @param $msg String: message to send + * @param $callerOffset Integer: number of items to go back in the backtrace to + * find the correct caller (1 = function calling wfLogWarning, ...) + * @param $level Integer: PHP error level; defaults to E_USER_WARNING + */ +function wfLogWarning( $msg, $callerOffset = 1, $level = E_USER_WARNING ) { + MWDebug::warning( $msg, $callerOffset + 1, $level, 'production' ); } /** @@ -1109,7 +1099,8 @@ function wfWarn( $msg, $callerOffset = 1, $level = E_USER_NOTICE ) { * send lines to the specified port, prefixed by the specified prefix and a space. * * @param $text String - * @param $file String filename + * @param string $file filename + * @throws MWException */ function wfErrorLog( $text, $file ) { if ( substr( $file, 0, 4 ) == 'udp:' ) { @@ -1173,6 +1164,8 @@ function wfLogProfilingData() { global $wgRequestTime, $wgDebugLogFile, $wgDebugRawPage, $wgRequest; global $wgProfileLimit, $wgUser; + StatCounter::singleton()->flush(); + $profiler = Profiler::instance(); # Profiling must actually be enabled... @@ -1212,9 +1205,18 @@ function wfLogProfilingData() { if ( $wgUser->isItemLoaded( 'id' ) && $wgUser->isAnon() ) { $forward .= ' anon'; } + + // Command line script uses a FauxRequest object which does not have + // any knowledge about an URL and throw an exception instead. + try { + $requestUrl = $wgRequest->getRequestURL(); + } catch ( MWException $e ) { + $requestUrl = 'n/a'; + } + $log = sprintf( "%s\t%04.3f\t%s\n", gmdate( 'YmdHis' ), $elapsed, - urldecode( $wgRequest->getRequestURL() . $forward ) ); + urldecode( $requestUrl . $forward ) ); wfErrorLog( $log . $profiler->getOutput(), $wgDebugLogFile ); } @@ -1224,83 +1226,38 @@ function wfLogProfilingData() { * * @param $key String * @param $count Int + * @return void */ function wfIncrStats( $key, $count = 1 ) { - global $wgStatsMethod; - - $count = intval( $count ); - - if( $wgStatsMethod == 'udp' ) { - global $wgUDPProfilerHost, $wgUDPProfilerPort, $wgDBname, $wgAggregateStatsID; - static $socket; - - $id = $wgAggregateStatsID !== false ? $wgAggregateStatsID : $wgDBname; - - if ( !$socket ) { - $socket = socket_create( AF_INET, SOCK_DGRAM, SOL_UDP ); - $statline = "stats/{$id} - 1 1 1 1 1 -total\n"; - socket_sendto( - $socket, - $statline, - strlen( $statline ), - 0, - $wgUDPProfilerHost, - $wgUDPProfilerPort - ); - } - $statline = "stats/{$id} - {$count} 1 1 1 1 {$key}\n"; - wfSuppressWarnings(); - socket_sendto( - $socket, - $statline, - strlen( $statline ), - 0, - $wgUDPProfilerHost, - $wgUDPProfilerPort - ); - wfRestoreWarnings(); - } elseif( $wgStatsMethod == 'cache' ) { - global $wgMemc; - $key = wfMemcKey( 'stats', $key ); - if ( is_null( $wgMemc->incr( $key, $count ) ) ) { - $wgMemc->add( $key, $count ); - } - } else { - // Disabled - } + StatCounter::singleton()->incr( $key, $count ); } /** - * Check if the wiki read-only lock file is present. This can be used to lock - * off editing functions, but doesn't guarantee that the database will not be - * modified. + * Check whether the wiki is in read-only mode. * * @return bool */ function wfReadOnly() { - global $wgReadOnlyFile, $wgReadOnly; - - if ( !is_null( $wgReadOnly ) ) { - return (bool)$wgReadOnly; - } - if ( $wgReadOnlyFile == '' ) { - return false; - } - // Set $wgReadOnly for faster access next time - if ( is_file( $wgReadOnlyFile ) ) { - $wgReadOnly = file_get_contents( $wgReadOnlyFile ); - } else { - $wgReadOnly = false; - } - return (bool)$wgReadOnly; + return wfReadOnlyReason() !== false; } /** - * @return bool + * Get the value of $wgReadOnly or the contents of $wgReadOnlyFile. + * + * @return string|bool: String when in read-only mode; false otherwise */ function wfReadOnlyReason() { - global $wgReadOnly; - wfReadOnly(); + global $wgReadOnly, $wgReadOnlyFile; + + if ( $wgReadOnly === null ) { + // Set $wgReadOnly for faster access next time + if ( is_file( $wgReadOnlyFile ) && filesize( $wgReadOnlyFile ) > 0 ) { + $wgReadOnly = file_get_contents( $wgReadOnlyFile ); + } else { + $wgReadOnly = false; + } + } + return $wgReadOnly; } @@ -1322,27 +1279,27 @@ function wfReadOnlyReason() { function wfGetLangObj( $langcode = false ) { # Identify which language to get or create a language object for. # Using is_object here due to Stub objects. - if( is_object( $langcode ) ) { + if ( is_object( $langcode ) ) { # Great, we already have the object (hopefully)! return $langcode; } global $wgContLang, $wgLanguageCode; - if( $langcode === true || $langcode === $wgLanguageCode ) { + if ( $langcode === true || $langcode === $wgLanguageCode ) { # $langcode is the language code of the wikis content language object. # or it is a boolean and value is true return $wgContLang; } global $wgLang; - if( $langcode === false || $langcode === $wgLang->getCode() ) { + if ( $langcode === false || $langcode === $wgLang->getCode() ) { # $langcode is the language code of user language object. # or it was a boolean and value is false return $wgLang; } $validCodes = array_keys( Language::fetchLanguageNames() ); - if( in_array( $langcode, $validCodes ) ) { + if ( in_array( $langcode, $validCodes ) ) { # $langcode corresponds to a valid language. return Language::factory( $langcode ); } @@ -1366,9 +1323,13 @@ function wfUILang() { } /** - * This is the new function for getting translated interface messages. - * See the Message class for documentation how to use them. - * The intention is that this function replaces all old wfMsg* functions. + * This is the function for getting translated interface messages. + * + * @see Message class for documentation how to use them. + * @see https://www.mediawiki.org/wiki/Manual:Messages_API + * + * This function replaces all old wfMsg* functions. + * * @param $key \string Message key. * Varargs: normal message parameters. * @return Message @@ -1393,7 +1354,7 @@ function wfMessage( $key /*...*/) { */ function wfMessageFallback( /*...*/ ) { $args = func_get_args(); - return MWFunction::callArray( 'Message::newFallbackSequence', $args ); + return call_user_func_array( 'Message::newFallbackSequence', $args ); } /** @@ -1404,7 +1365,7 @@ function wfMessageFallback( /*...*/ ) { * * @deprecated since 1.18 * - * @param $key String: lookup key for the message, usually + * @param string $key lookup key for the message, usually * defined in languages/Language.php * * Parameters to the message, which can be used to insert variable text into @@ -1416,6 +1377,8 @@ function wfMessageFallback( /*...*/ ) { * @return String */ function wfMsg( $key ) { + wfDeprecated( __METHOD__, '1.21' ); + $args = func_get_args(); array_shift( $args ); return wfMsgReal( $key, $args ); @@ -1430,6 +1393,8 @@ function wfMsg( $key ) { * @return String */ function wfMsgNoTrans( $key ) { + wfDeprecated( __METHOD__, '1.21' ); + $args = func_get_args(); array_shift( $args ); return wfMsgReal( $key, $args, true, false, false ); @@ -1456,16 +1421,18 @@ function wfMsgNoTrans( $key ) { * * @deprecated since 1.18 * - * @param $key String: lookup key for the message, usually + * @param string $key lookup key for the message, usually * defined in languages/Language.php * @return String */ function wfMsgForContent( $key ) { + wfDeprecated( __METHOD__, '1.21' ); + global $wgForceUIMsgAsContentMsg; $args = func_get_args(); array_shift( $args ); $forcontent = true; - if( is_array( $wgForceUIMsgAsContentMsg ) && + if ( is_array( $wgForceUIMsgAsContentMsg ) && in_array( $key, $wgForceUIMsgAsContentMsg ) ) { $forcontent = false; @@ -1482,11 +1449,13 @@ function wfMsgForContent( $key ) { * @return String */ function wfMsgForContentNoTrans( $key ) { + wfDeprecated( __METHOD__, '1.21' ); + global $wgForceUIMsgAsContentMsg; $args = func_get_args(); array_shift( $args ); $forcontent = true; - if( is_array( $wgForceUIMsgAsContentMsg ) && + if ( is_array( $wgForceUIMsgAsContentMsg ) && in_array( $key, $wgForceUIMsgAsContentMsg ) ) { $forcontent = false; @@ -1499,7 +1468,7 @@ function wfMsgForContentNoTrans( $key ) { * * @deprecated since 1.18 * - * @param $key String: key to get. + * @param string $key key to get. * @param $args * @param $useDB Boolean * @param $forContent Mixed: Language code, or false for user lang, true for content lang. @@ -1507,6 +1476,8 @@ function wfMsgForContentNoTrans( $key ) { * @return String: the requested message. */ function wfMsgReal( $key, $args, $useDB = true, $forContent = false, $transform = true ) { + wfDeprecated( __METHOD__, '1.21' ); + wfProfileIn( __METHOD__ ); $message = wfMsgGetKey( $key, $useDB, $forContent, $transform ); $message = wfMsgReplaceArgs( $message, $args ); @@ -1521,17 +1492,19 @@ function wfMsgReal( $key, $args, $useDB = true, $forContent = false, $transform * * @param $key String * @param $useDB Bool - * @param $langCode String: Code of the language to get the message for, or + * @param string $langCode Code of the language to get the message for, or * behaves as a content language switch if it is a boolean. * @param $transform Boolean: whether to parse magic words, etc. * @return string */ function wfMsgGetKey( $key, $useDB = true, $langCode = false, $transform = true ) { + wfDeprecated( __METHOD__, '1.21' ); + wfRunHooks( 'NormalizeMessageKey', array( &$key, &$useDB, &$langCode, &$transform ) ); $cache = MessageCache::singleton(); $message = $cache->get( $key, $useDB, $langCode ); - if( $message === false ) { + if ( $message === false ) { $message = '<' . htmlspecialchars( $key ) . '>'; } elseif ( $transform ) { $message = $cache->transform( $message ); @@ -1558,7 +1531,7 @@ function wfMsgReplaceArgs( $message, $args ) { $args = array_values( $args[0] ); } $replacementKeys = array(); - foreach( $args as $n => $param ) { + foreach ( $args as $n => $param ) { $replacementKeys['$' . ( $n + 1 )] = $param; } $message = strtr( $message, $replacementKeys ); @@ -1581,6 +1554,8 @@ function wfMsgReplaceArgs( $message, $args ) { * @return string */ function wfMsgHtml( $key ) { + wfDeprecated( __METHOD__, '1.21' ); + $args = func_get_args(); array_shift( $args ); return wfMsgReplaceArgs( htmlspecialchars( wfMsgGetKey( $key ) ), $args ); @@ -1600,6 +1575,8 @@ function wfMsgHtml( $key ) { * @return string */ function wfMsgWikiHtml( $key ) { + wfDeprecated( __METHOD__, '1.21' ); + $args = func_get_args(); array_shift( $args ); return wfMsgReplaceArgs( @@ -1613,8 +1590,8 @@ function wfMsgWikiHtml( $key ) { * * @deprecated since 1.18 * - * @param $key String: key of the message - * @param $options Array: processing rules. Can take the following options: + * @param string $key key of the message + * @param array $options processing rules. Can take the following options: * <i>parse</i>: parses wikitext to HTML * <i>parseinline</i>: parses wikitext to HTML and removes the surrounding * p's added by parser or tidy @@ -1625,22 +1602,24 @@ function wfMsgWikiHtml( $key ) { * <i>content</i>: fetch message for content language instead of interface * Also can accept a single associative argument, of the form 'language' => 'xx': * <i>language</i>: Language object or language code to fetch message for - * (overriden by <i>content</i>). + * (overridden by <i>content</i>). * Behavior for conflicting options (e.g., parse+parseinline) is undefined. * * @return String */ function wfMsgExt( $key, $options ) { + wfDeprecated( __METHOD__, '1.21' ); + $args = func_get_args(); array_shift( $args ); array_shift( $args ); $options = (array)$options; - foreach( $options as $arrayKey => $option ) { - if( !preg_match( '/^[0-9]+|language$/', $arrayKey ) ) { + foreach ( $options as $arrayKey => $option ) { + if ( !preg_match( '/^[0-9]+|language$/', $arrayKey ) ) { # An unknown index, neither numeric nor "language" wfWarn( "wfMsgExt called with incorrect parameter key $arrayKey", 1, E_USER_WARNING ); - } elseif( preg_match( '/^[0-9]+$/', $arrayKey ) && !in_array( $option, + } elseif ( preg_match( '/^[0-9]+$/', $arrayKey ) && !in_array( $option, array( 'parse', 'parseinline', 'escape', 'escapenoentities', 'replaceafter', 'parsemag', 'content' ) ) ) { # A numeric index with unknown value @@ -1648,11 +1627,11 @@ function wfMsgExt( $key, $options ) { } } - if( in_array( 'content', $options, true ) ) { + if ( in_array( 'content', $options, true ) ) { $forContent = true; $langCode = true; $langCodeObj = null; - } elseif( array_key_exists( 'language', $options ) ) { + } elseif ( array_key_exists( 'language', $options ) ) { $forContent = false; $langCode = wfGetLangObj( $options['language'] ); $langCodeObj = $langCode; @@ -1664,13 +1643,13 @@ function wfMsgExt( $key, $options ) { $string = wfMsgGetKey( $key, /*DB*/true, $langCode, /*Transform*/false ); - if( !in_array( 'replaceafter', $options, true ) ) { + if ( !in_array( 'replaceafter', $options, true ) ) { $string = wfMsgReplaceArgs( $string, $args ); } $messageCache = MessageCache::singleton(); $parseInline = in_array( 'parseinline', $options, true ); - if( in_array( 'parse', $options, true ) || $parseInline ) { + if ( in_array( 'parse', $options, true ) || $parseInline ) { $string = $messageCache->parse( $string, null, true, !$forContent, $langCodeObj ); if ( $string instanceof ParserOutput ) { $string = $string->getText(); @@ -1678,7 +1657,7 @@ function wfMsgExt( $key, $options ) { if ( $parseInline ) { $m = array(); - if( preg_match( '/^<p>(.*)\n?<\/p>\n?$/sU', $string, $m ) ) { + if ( preg_match( '/^<p>(.*)\n?<\/p>\n?$/sU', $string, $m ) ) { $string = $m[1]; } } @@ -1693,7 +1672,7 @@ function wfMsgExt( $key, $options ) { $string = Sanitizer::escapeHtmlAllowEntities( $string ); } - if( in_array( 'replaceafter', $options, true ) ) { + if ( in_array( 'replaceafter', $options, true ) ) { $string = wfMsgReplaceArgs( $string, $args ); } @@ -1702,8 +1681,8 @@ function wfMsgExt( $key, $options ) { /** * Since wfMsg() and co suck, they don't return false if the message key they - * looked up didn't exist but a XHTML string, this function checks for the - * nonexistance of messages by checking the MessageCache::get() result directly. + * looked up didn't exist but instead the key wrapped in <>'s, this function checks for the + * nonexistence of messages by checking the MessageCache::get() result directly. * * @deprecated since 1.18. Use Message::isDisabled(). * @@ -1711,6 +1690,8 @@ function wfMsgExt( $key, $options ) { * @return Boolean True if the message *doesn't* exist. */ function wfEmptyMsg( $key ) { + wfDeprecated( __METHOD__, '1.21' ); + return MessageCache::singleton()->get( $key, /*useDB*/true, /*content*/false ) === false; } @@ -1718,9 +1699,12 @@ function wfEmptyMsg( $key ) { * Throw a debugging exception. This function previously once exited the process, * but now throws an exception instead, with similar results. * - * @param $msg String: message shown when dying. + * @deprecated since 1.22; just throw an MWException yourself + * @param string $msg message shown when dying. + * @throws MWException */ function wfDebugDieBacktrace( $msg = '' ) { + wfDeprecated( __FUNCTION__, '1.22' ); throw new MWException( $msg ); } @@ -1737,7 +1721,7 @@ function wfHostname() { # Hostname overriding global $wgOverrideHostname; - if( $wgOverrideHostname !== false ) { + if ( $wgOverrideHostname !== false ) { # Set static and skip any detection $host = $wgOverrideHostname; return $host; @@ -1749,7 +1733,7 @@ function wfHostname() { } else { $uname = false; } - if( is_array( $uname ) && isset( $uname['nodename'] ) ) { + if ( is_array( $uname ) && isset( $uname['nodename'] ) ) { $host = $uname['nodename']; } elseif ( getenv( 'COMPUTERNAME' ) ) { # Windows computer name @@ -1783,20 +1767,20 @@ function wfReportTime() { * * With Zend Optimizer 3.2.0 loaded, this causes segfaults under somewhat * murky circumstances, which may be triggered in part by stub objects - * or other fancy talkin'. + * or other fancy talking'. * * Will return an empty array if Zend Optimizer is detected or if * debug_backtrace is disabled, otherwise the output from * debug_backtrace() (trimmed). * - * @param $limit int This parameter can be used to limit the number of stack frames returned + * @param int $limit This parameter can be used to limit the number of stack frames returned * * @return array of backtrace information */ function wfDebugBacktrace( $limit = 0 ) { static $disabled = null; - if( extension_loaded( 'Zend Optimizer' ) ) { + if ( extension_loaded( 'Zend Optimizer' ) ) { wfDebug( "Zend Optimizer detected; skipping debug_backtrace for safety.\n" ); return array(); } @@ -1836,14 +1820,14 @@ function wfBacktrace() { $msg = "<ul>\n"; } $backtrace = wfDebugBacktrace(); - foreach( $backtrace as $call ) { - if( isset( $call['file'] ) ) { + foreach ( $backtrace as $call ) { + if ( isset( $call['file'] ) ) { $f = explode( DIRECTORY_SEPARATOR, $call['file'] ); $file = $f[count( $f ) - 1]; } else { $file = '-'; } - if( isset( $call['line'] ) ) { + if ( isset( $call['line'] ) ) { $line = $call['line']; } else { $line = '-'; @@ -1853,7 +1837,7 @@ function wfBacktrace() { } else { $msg .= '<li>' . $file . ' line ' . $line . ' calls '; } - if( !empty( $call['class'] ) ) { + if ( !empty( $call['class'] ) ) { $msg .= $call['class'] . $call['type']; } $msg .= $call['function'] . '()'; @@ -1895,7 +1879,7 @@ function wfGetCaller( $level = 2 ) { * Return a string consisting of callers in the stack. Useful sometimes * for profiling specific points. * - * @param $limit int The maximum depth of the stack frame to return, or false for + * @param int $limit The maximum depth of the stack frame to return, or false for * the entire stack. * @return String */ @@ -1920,10 +1904,8 @@ function wfFormatStackFrame( $frame ) { $frame['function']; } - /* Some generic result counters, pulled out of SearchEngine */ - /** * @todo document * @@ -1941,8 +1923,8 @@ function wfShowingResults( $offset, $limit ) { * @param $offset String * @param $limit Integer * @param $link String - * @param $query String: optional URL query parameter string - * @param $atend Bool: optional param for specified if this is the last page + * @param string $query optional URL query parameter string + * @param bool $atend optional param for specified if this is the last page * @return String * @deprecated in 1.19; use Language::viewPrevNext() instead */ @@ -1953,11 +1935,11 @@ function wfViewPrevNext( $offset, $limit, $link, $query = '', $atend = false ) { $query = wfCgiToArray( $query ); - if( is_object( $link ) ) { + if ( is_object( $link ) ) { $title = $link; } else { $title = Title::newFromText( $link ); - if( is_null( $title ) ) { + if ( is_null( $title ) ) { return false; } } @@ -1966,23 +1948,6 @@ function wfViewPrevNext( $offset, $limit, $link, $query = '', $atend = false ) { } /** - * Make a list item, used by various special pages - * - * @param $page String Page link - * @param $details String Text between brackets - * @param $oppositedm Boolean Add the direction mark opposite to your - * language, to display text properly - * @return String - * @deprecated since 1.19; use Language::specialList() instead - */ -function wfSpecialList( $page, $details, $oppositedm = true ) { - wfDeprecated( __METHOD__, '1.19' ); - - global $wgLang; - return $wgLang->specialList( $page, $details, $oppositedm ); -} - -/** * @todo document * @todo FIXME: We may want to blacklist some broken browsers * @@ -1993,16 +1958,16 @@ function wfClientAcceptsGzip( $force = false ) { static $result = null; if ( $result === null || $force ) { $result = false; - if( isset( $_SERVER['HTTP_ACCEPT_ENCODING'] ) ) { + if ( isset( $_SERVER['HTTP_ACCEPT_ENCODING'] ) ) { # @todo FIXME: We may want to blacklist some broken browsers $m = array(); - if( preg_match( + if ( preg_match( '/\bgzip(?:;(q)=([0-9]+(?:\.[0-9]+)))?\b/', $_SERVER['HTTP_ACCEPT_ENCODING'], $m ) ) { - if( isset( $m[2] ) && ( $m[1] == 'q' ) && ( $m[2] == 0 ) ) { + if ( isset( $m[2] ) && ( $m[1] == 'q' ) && ( $m[2] == 0 ) ) { $result = false; return $result; } @@ -2018,8 +1983,8 @@ function wfClientAcceptsGzip( $force = false ) { * Obtain the offset and limit values from the request string; * used in special pages * - * @param $deflimit Int default limit if none supplied - * @param $optionname String Name of a user preference to check against + * @param int $deflimit default limit if none supplied + * @param string $optionname Name of a user preference to check against * @return array * */ @@ -2034,26 +1999,58 @@ function wfCheckLimits( $deflimit = 50, $optionname = 'rclimit' ) { * is achieved by substituting certain characters with HTML entities. * As required by the callers, "<nowiki>" is not used. * - * @param $text String: text to be escaped + * @param string $text text to be escaped * @return String */ function wfEscapeWikiText( $text ) { - $text = strtr( "\n$text", array( - '"' => '"', '&' => '&', "'" => ''', '<' => '<', - '=' => '=', '>' => '>', '[' => '[', ']' => ']', - '{' => '{', '|' => '|', '}' => '}', - "\n#" => "\n#", "\n*" => "\n*", - "\n:" => "\n:", "\n;" => "\n;", - '://' => '://', 'ISBN ' => 'ISBN ', 'RFC ' => 'RFC ', - ) ); - return substr( $text, 1 ); + static $repl = null, $repl2 = null; + if ( $repl === null ) { + $repl = array( + '"' => '"', '&' => '&', "'" => ''', '<' => '<', + '=' => '=', '>' => '>', '[' => '[', ']' => ']', + '{' => '{', '|' => '|', '}' => '}', ';' => ';', + "\n#" => "\n#", "\r#" => "\r#", + "\n*" => "\n*", "\r*" => "\r*", + "\n:" => "\n:", "\r:" => "\r:", + "\n " => "\n ", "\r " => "\r ", + "\n\n" => "\n ", "\r\n" => " \n", + "\n\r" => "\n ", "\r\r" => "\r ", + "\n\t" => "\n	", "\r\t" => "\r	", // "\n\t\n" is treated like "\n\n" + "\n----" => "\n----", "\r----" => "\r----", + '__' => '__', '://' => '://', + ); + + // We have to catch everything "\s" matches in PCRE + foreach ( array( 'ISBN', 'RFC', 'PMID' ) as $magic ) { + $repl["$magic "] = "$magic "; + $repl["$magic\t"] = "$magic	"; + $repl["$magic\r"] = "$magic "; + $repl["$magic\n"] = "$magic "; + $repl["$magic\f"] = "$magic"; + } + + // And handle protocols that don't use "://" + global $wgUrlProtocols; + $repl2 = array(); + foreach ( $wgUrlProtocols as $prot ) { + if ( substr( $prot, -1 ) === ':' ) { + $repl2[] = preg_quote( substr( $prot, 0, -1 ), '/' ); + } + } + $repl2 = $repl2 ? '/\b(' . join( '|', $repl2 ) . '):/i' : '/^(?!)/'; + } + $text = substr( strtr( "\n$text", $repl ), 1 ); + $text = preg_replace( $repl2, '$1:', $text ); + return $text; } /** - * Get the current unix timetstamp with microseconds. Useful for profiling + * Get the current unix timestamp with microseconds. Useful for profiling + * @deprecated since 1.22; call microtime() directly * @return Float */ function wfTime() { + wfDeprecated( __FUNCTION__, '1.22' ); return microtime( true ); } @@ -2155,14 +2152,14 @@ function wfHttpError( $code, $label, $desc ) { * @param $resetGzipEncoding Bool */ function wfResetOutputBuffers( $resetGzipEncoding = true ) { - if( $resetGzipEncoding ) { + if ( $resetGzipEncoding ) { // Suppress Content-Encoding and Content-Length // headers from 1.10+s wfOutputHandler global $wgDisableOutputCompression; $wgDisableOutputCompression = true; } - while( $status = ob_get_status() ) { - if( $status['type'] == 0 /* PHP_OUTPUT_HANDLER_INTERNAL */ ) { + while ( $status = ob_get_status() ) { + if ( $status['type'] == 0 /* PHP_OUTPUT_HANDLER_INTERNAL */ ) { // Probably from zlib.output_compression or other // PHP-internal setting which can't be removed. // @@ -2170,13 +2167,13 @@ function wfResetOutputBuffers( $resetGzipEncoding = true ) { // output behavior. break; } - if( !ob_end_clean() ) { + if ( !ob_end_clean() ) { // Could not remove output buffer handler; abort now // to avoid getting in some kind of infinite loop. break; } - if( $resetGzipEncoding ) { - if( $status['name'] == 'ob_gzhandler' ) { + if ( $resetGzipEncoding ) { + if ( $status['name'] == 'ob_gzhandler' ) { // Reset the 'Content-Encoding' field set by this handler // so we can start fresh. header_remove( 'Content-Encoding' ); @@ -2207,12 +2204,12 @@ function wfClearOutputBuffers() { * factors * * @param $accept String - * @param $def String default + * @param string $def default * @return Array */ function wfAcceptToPrefs( $accept, $def = '*/*' ) { # No arg means accept anything (per HTTP spec) - if( !$accept ) { + if ( !$accept ) { return array( $def => 1.0 ); } @@ -2220,7 +2217,7 @@ function wfAcceptToPrefs( $accept, $def = '*/*' ) { $parts = explode( ',', $accept ); - foreach( $parts as $part ) { + foreach ( $parts as $part ) { # @todo FIXME: Doesn't deal with params like 'text/html; level=1' $values = explode( ';', trim( $part ) ); $match = array(); @@ -2247,13 +2244,13 @@ function wfAcceptToPrefs( $accept, $def = '*/*' ) { * @private */ function mimeTypeMatch( $type, $avail ) { - if( array_key_exists( $type, $avail ) ) { + if ( array_key_exists( $type, $avail ) ) { return $type; } else { $parts = explode( '/', $type ); - if( array_key_exists( $parts[0] . '/*', $avail ) ) { + if ( array_key_exists( $parts[0] . '/*', $avail ) ) { return $parts[0] . '/*'; - } elseif( array_key_exists( '*/*', $avail ) ) { + } elseif ( array_key_exists( '*/*', $avail ) ) { return '*/*'; } else { return null; @@ -2267,8 +2264,8 @@ function mimeTypeMatch( $type, $avail ) { * array of type to preference (preference is a float between 0.0 and 1.0). * Wildcards in the types are acceptable. * - * @param $cprefs Array: client's acceptable type list - * @param $sprefs Array: server's offered types + * @param array $cprefs client's acceptable type list + * @param array $sprefs server's offered types * @return string * * @todo FIXME: Doesn't handle params like 'text/plain; charset=UTF-8' @@ -2277,21 +2274,21 @@ function mimeTypeMatch( $type, $avail ) { function wfNegotiateType( $cprefs, $sprefs ) { $combine = array(); - foreach( array_keys( $sprefs ) as $type ) { + foreach ( array_keys( $sprefs ) as $type ) { $parts = explode( '/', $type ); - if( $parts[1] != '*' ) { + if ( $parts[1] != '*' ) { $ckey = mimeTypeMatch( $type, $cprefs ); - if( $ckey ) { + if ( $ckey ) { $combine[$type] = $sprefs[$type] * $cprefs[$ckey]; } } } - foreach( array_keys( $cprefs ) as $type ) { + foreach ( array_keys( $cprefs ) as $type ) { $parts = explode( '/', $type ); - if( $parts[1] != '*' && !array_key_exists( $type, $sprefs ) ) { + if ( $parts[1] != '*' && !array_key_exists( $type, $sprefs ) ) { $skey = mimeTypeMatch( $type, $sprefs ); - if( $skey ) { + if ( $skey ) { $combine[$type] = $sprefs[$skey] * $cprefs[$type]; } } @@ -2300,8 +2297,8 @@ function wfNegotiateType( $cprefs, $sprefs ) { $bestq = 0; $besttype = null; - foreach( array_keys( $combine ) as $type ) { - if( $combine[$type] > $bestq ) { + foreach ( array_keys( $combine ) as $type ) { + if ( $combine[$type] > $bestq ) { $besttype = $type; $bestq = $combine[$type]; } @@ -2390,11 +2387,6 @@ define( 'TS_ORACLE', 6 ); define( 'TS_POSTGRES', 7 ); /** - * DB2 format time - */ -define( 'TS_DB2', 8 ); - -/** * ISO 8601 basic format with no timezone: 19860209T200000Z. This is used by ResourceLoader */ define( 'TS_ISO_8601_BASIC', 9 ); @@ -2405,15 +2397,15 @@ define( 'TS_ISO_8601_BASIC', 9 ); * @param $outputtype Mixed: A timestamp in one of the supported formats, the * function will autodetect which format is supplied and act * accordingly. - * @param $ts Mixed: the timestamp to convert or 0 for the current timestamp + * @param $ts Mixed: optional timestamp to convert, default 0 for the current time * @return Mixed: String / false The same date in the format specified in $outputtype or false */ function wfTimestamp( $outputtype = TS_UNIX, $ts = 0 ) { try { $timestamp = new MWTimestamp( $ts ); return $timestamp->getTimestamp( $outputtype ); - } catch( TimestampException $e ) { - wfDebug("wfTimestamp() fed bogus time value: TYPE=$outputtype; VALUE=$ts\n"); + } catch ( TimestampException $e ) { + wfDebug( "wfTimestamp() fed bogus time value: TYPE=$outputtype; VALUE=$ts\n" ); return false; } } @@ -2427,7 +2419,7 @@ function wfTimestamp( $outputtype = TS_UNIX, $ts = 0 ) { * @return String */ function wfTimestampOrNull( $outputtype = TS_UNIX, $ts = null ) { - if( is_null( $ts ) ) { + if ( is_null( $ts ) ) { return null; } else { return wfTimestamp( $outputtype, $ts ); @@ -2463,7 +2455,7 @@ function wfIsWindows() { * @return Bool */ function wfIsHipHop() { - return function_exists( 'hphp_thread_set_warmup_enabled' ); + return defined( 'HPHP_VERSION' ); } /** @@ -2498,8 +2490,8 @@ function wfTempDir() { $tmpDir = array_map( "getenv", array( 'TMPDIR', 'TMP', 'TEMP' ) ); - foreach( $tmpDir as $tmp ) { - if( $tmp && file_exists( $tmp ) && is_dir( $tmp ) && is_writable( $tmp ) ) { + foreach ( $tmpDir as $tmp ) { + if ( $tmp && file_exists( $tmp ) && is_dir( $tmp ) && is_writable( $tmp ) ) { return $tmp; } } @@ -2509,9 +2501,10 @@ function wfTempDir() { /** * Make directory, and make all parent directories if they don't exist * - * @param $dir String: full path to directory to create + * @param string $dir full path to directory to create * @param $mode Integer: chmod value to use, default is $wgDirectoryMode - * @param $caller String: optional caller param for debugging. + * @param string $caller optional caller param for debugging. + * @throws MWException * @return bool */ function wfMkdirParents( $dir, $mode = null, $caller = null ) { @@ -2525,7 +2518,7 @@ function wfMkdirParents( $dir, $mode = null, $caller = null ) { wfDebug( "$caller: called wfMkdirParents($dir)\n" ); } - if( strval( $dir ) === '' || file_exists( $dir ) ) { + if ( strval( $dir ) === '' || ( file_exists( $dir ) && is_dir( $dir ) ) ) { return true; } @@ -2540,10 +2533,14 @@ function wfMkdirParents( $dir, $mode = null, $caller = null ) { $ok = mkdir( $dir, $mode, true ); // PHP5 <3 wfRestoreWarnings(); - if( !$ok ) { + if ( !$ok ) { + //directory may have been created on another request since we last checked + if ( is_dir( $dir ) ) { + return true; + } + // PHP doesn't report the path in its warning message, so add our own to aid in diagnosis. - trigger_error( sprintf( "%s: failed to mkdir \"%s\" mode 0%o", __FUNCTION__, $dir, $mode ), - E_USER_WARNING ); + wfLogWarning( sprintf( "failed to mkdir \"%s\" mode 0%o", $dir, $mode ) ); } return $ok; } @@ -2585,14 +2582,18 @@ function wfPercent( $nr, $acc = 2, $round = true ) { /** * Find out whether or not a mixed variable exists in a string * + * @deprecated Just use str(i)pos * @param $needle String * @param $str String * @param $insensitive Boolean * @return Boolean */ function in_string( $needle, $str, $insensitive = false ) { + wfDeprecated( __METHOD__, '1.21' ); $func = 'strpos'; - if( $insensitive ) $func = 'stripos'; + if ( $insensitive ) { + $func = 'stripos'; + } return $func( $str, $needle ) !== false; } @@ -2621,48 +2622,15 @@ function in_string( $needle, $str, $insensitive = false ) { * @return Bool */ function wfIniGetBool( $setting ) { - $val = ini_get( $setting ); + $val = strtolower( ini_get( $setting ) ); // 'on' and 'true' can't have whitespace around them, but '1' can. - return strtolower( $val ) == 'on' - || strtolower( $val ) == 'true' - || strtolower( $val ) == 'yes' + return $val == 'on' + || $val == 'true' + || $val == 'yes' || preg_match( "/^\s*[+-]?0*[1-9]/", $val ); // approx C atoi() function } /** - * Wrapper function for PHP's dl(). This doesn't work in most situations from - * PHP 5.3 onward, and is usually disabled in shared environments anyway. - * - * @param $extension String A PHP extension. The file suffix (.so or .dll) - * should be omitted - * @param $fileName String Name of the library, if not $extension.suffix - * @return Bool - Whether or not the extension is loaded - */ -function wfDl( $extension, $fileName = null ) { - if( extension_loaded( $extension ) ) { - return true; - } - - $canDl = false; - $sapi = php_sapi_name(); - if( $sapi == 'cli' || $sapi == 'cgi' || $sapi == 'embed' ) { - $canDl = ( function_exists( 'dl' ) && is_callable( 'dl' ) - && wfIniGetBool( 'enable_dl' ) && !wfIniGetBool( 'safe_mode' ) ); - } - - if( $canDl ) { - $fileName = $fileName ? $fileName : $extension; - if( wfIsWindows() ) { - $fileName = 'php_' . $fileName; - } - wfSuppressWarnings(); - dl( $fileName . '.' . PHP_SHLIB_SUFFIX ); - wfRestoreWarnings(); - } - return extension_loaded( $extension ); -} - -/** * Windows-compatible version of escapeshellarg() * Windows doesn't recognise single-quotes in the shell, but the escapeshellarg() * function puts single quotes in regardless of OS. @@ -2673,7 +2641,7 @@ function wfDl( $extension, $fileName = null ) { * @param varargs * @return String */ -function wfEscapeShellArg( ) { +function wfEscapeShellArg() { wfInitShellLocale(); $args = func_get_args(); @@ -2727,24 +2695,15 @@ function wfEscapeShellArg( ) { } /** - * Execute a shell command, with time and memory limits mirrored from the PHP - * configuration if supported. - * @param $cmd String Command line, properly escaped for shell. - * @param &$retval null|Mixed optional, will receive the program's exit code. - * (non-zero is usually failure) - * @param $environ Array optional environment variables which should be - * added to the executed command environment. - * @param $limits Array optional array with limits(filesize, memory, time) - * this overwrites the global wgShellMax* limits. - * @return string collected stdout as a string (trailing newlines stripped) + * Check if wfShellExec() is effectively disabled via php.ini config + * @return bool|string False or one of (safemode,disabled) + * @since 1.22 */ -function wfShellExec( $cmd, &$retval = null, $environ = array(), $limits = array() ) { - global $IP, $wgMaxShellMemory, $wgMaxShellFileSize, $wgMaxShellTime; - - static $disabled; +function wfShellExecDisabled() { + static $disabled = null; if ( is_null( $disabled ) ) { $disabled = false; - if( wfIniGetBool( 'safe_mode' ) ) { + if ( wfIniGetBool( 'safe_mode' ) ) { wfDebug( "wfShellExec can't run in safe_mode, PHP's exec functions are too broken.\n" ); $disabled = 'safemode'; } else { @@ -2757,6 +2716,28 @@ function wfShellExec( $cmd, &$retval = null, $environ = array(), $limits = array } } } + return $disabled; +} + +/** + * Execute a shell command, with time and memory limits mirrored from the PHP + * configuration if supported. + * @param string $cmd Command line, properly escaped for shell. + * @param &$retval null|Mixed optional, will receive the program's exit code. + * (non-zero is usually failure) + * @param array $environ optional environment variables which should be + * added to the executed command environment. + * @param array $limits optional array with limits(filesize, memory, time, walltime) + * this overwrites the global wgShellMax* limits. + * @param array $options Array of options. Only one is "duplicateStderr" => true, which + * Which duplicates stderr to stdout, including errors from limit.sh + * @return string collected stdout as a string + */ +function wfShellExec( $cmd, &$retval = null, $environ = array(), $limits = array(), $options = array() ) { + global $IP, $wgMaxShellMemory, $wgMaxShellFileSize, $wgMaxShellTime, + $wgMaxShellWallClockTime, $wgShellCgroup; + + $disabled = wfShellExecDisabled(); if ( $disabled ) { $retval = 1; return $disabled == 'safemode' ? @@ -2764,10 +2745,12 @@ function wfShellExec( $cmd, &$retval = null, $environ = array(), $limits = array 'Unable to run external programs, passthru() is disabled.'; } + $includeStderr = isset( $options['duplicateStderr'] ) && $options['duplicateStderr']; + wfInitShellLocale(); $envcmd = ''; - foreach( $environ as $k => $v ) { + foreach ( $environ as $k => $v ) { if ( wfIsWindows() ) { /* Surrounding a set in quotes (method used by wfEscapeShellArg) makes the quotes themselves * appear in the environment variable, so we must use carat escaping as documented in @@ -2786,20 +2769,40 @@ function wfShellExec( $cmd, &$retval = null, $environ = array(), $limits = array $cmd = $envcmd . $cmd; if ( php_uname( 's' ) == 'Linux' ) { - $time = intval ( isset($limits['time']) ? $limits['time'] : $wgMaxShellTime ); - $mem = intval ( isset($limits['memory']) ? $limits['memory'] : $wgMaxShellMemory ); - $filesize = intval ( isset($limits['filesize']) ? $limits['filesize'] : $wgMaxShellFileSize ); - - if ( $time > 0 && $mem > 0 ) { - $script = "$IP/bin/ulimit4.sh"; - if ( is_executable( $script ) ) { - $cmd = '/bin/bash ' . escapeshellarg( $script ) . " $time $mem $filesize " . escapeshellarg( $cmd ); - } - } + $time = intval ( isset( $limits['time'] ) ? $limits['time'] : $wgMaxShellTime ); + if ( isset( $limits['walltime'] ) ) { + $wallTime = intval( $limits['walltime'] ); + } elseif ( isset( $limits['time'] ) ) { + $wallTime = $time; + } else { + $wallTime = intval( $wgMaxShellWallClockTime ); + } + $mem = intval ( isset( $limits['memory'] ) ? $limits['memory'] : $wgMaxShellMemory ); + $filesize = intval ( isset( $limits['filesize'] ) ? $limits['filesize'] : $wgMaxShellFileSize ); + + if ( $time > 0 || $mem > 0 || $filesize > 0 || $wallTime > 0 ) { + $cmd = '/bin/bash ' . escapeshellarg( "$IP/includes/limit.sh" ) . ' ' . + escapeshellarg( $cmd ) . ' ' . + escapeshellarg( + "MW_INCLUDE_STDERR=" . ( $includeStderr ? '1' : '' ) . ';' . + "MW_CPU_LIMIT=$time; " . + 'MW_CGROUP=' . escapeshellarg( $wgShellCgroup ) . '; ' . + "MW_MEM_LIMIT=$mem; " . + "MW_FILE_SIZE_LIMIT=$filesize; " . + "MW_WALL_CLOCK_LIMIT=$wallTime" + ); + } elseif ( $includeStderr ) { + $cmd .= ' 2>&1'; + } + } elseif ( $includeStderr ) { + $cmd .= ' 2>&1'; } wfDebug( "wfShellExec: $cmd\n" ); - $retval = 1; // error by default? + // Default to an unusual value that shouldn't happen naturally, + // so in the unlikely event of a weird php bug, it would be + // more obvious what happened. + $retval = 200; ob_start(); passthru( $cmd, $retval ); $output = ob_get_contents(); @@ -2812,6 +2815,24 @@ function wfShellExec( $cmd, &$retval = null, $environ = array(), $limits = array } /** + * Execute a shell command, returning both stdout and stderr. Convenience + * function, as all the arguments to wfShellExec can become unwieldy. + * + * @note This also includes errors from limit.sh, e.g. if $wgMaxShellFileSize is exceeded. + * @param string $cmd Command line, properly escaped for shell. + * @param &$retval null|Mixed optional, will receive the program's exit code. + * (non-zero is usually failure) + * @param array $environ optional environment variables which should be + * added to the executed command environment. + * @param array $limits optional array with limits(filesize, memory, time, walltime) + * this overwrites the global wgShellMax* limits. + * @return string collected stdout and stderr as a string + */ +function wfShellExecWithStderr( $cmd, &$retval = null, $environ = array(), $limits = array() ) { + return wfShellExec( $cmd, $retval, $environ, $limits, array( 'duplicateStderr' => true ) ); +} + +/** * Workaround for http://bugs.php.net/bug.php?id=45132 * escapeshellarg() destroys non-ASCII characters if LANG is not a UTF-8 locale */ @@ -2840,9 +2861,9 @@ function wfShellMaintenanceCmd( $script, array $parameters = array(), array $opt * Generate a shell-escaped command line string to run a MediaWiki cli script. * Note that $parameters should be a flat array and an option with an argument * should consist of two consecutive items in the array (do not use "--option value"). - * @param $script string MediaWiki cli script path - * @param $parameters Array Arguments and options to the script - * @param $options Array Associative array of options: + * @param string $script MediaWiki cli script path + * @param array $parameters Arguments and options to the script + * @param array $options Associative array of options: * 'php': The path to the php executable * 'wrapper': Path to a PHP wrapper to handle the maintenance script * @return Array @@ -2880,7 +2901,7 @@ function wfMerge( $old, $mine, $yours, &$result ) { $haveDiff3 = $wgDiff3 && file_exists( $wgDiff3 ); wfRestoreWarnings(); - if( !$haveDiff3 ) { + if ( !$haveDiff3 ) { wfDebug( "diff3 not found\n" ); return false; } @@ -2891,21 +2912,25 @@ function wfMerge( $old, $mine, $yours, &$result ) { $mytextFile = fopen( $mytextName = tempnam( $td, 'merge-mine-' ), 'w' ); $yourtextFile = fopen( $yourtextName = tempnam( $td, 'merge-your-' ), 'w' ); - fwrite( $oldtextFile, $old ); + # NOTE: diff3 issues a warning to stderr if any of the files does not end with + # a newline character. To avoid this, we normalize the trailing whitespace before + # creating the diff. + + fwrite( $oldtextFile, rtrim( $old ) . "\n" ); fclose( $oldtextFile ); - fwrite( $mytextFile, $mine ); + fwrite( $mytextFile, rtrim( $mine ) . "\n" ); fclose( $mytextFile ); - fwrite( $yourtextFile, $yours ); + fwrite( $yourtextFile, rtrim( $yours ) . "\n" ); fclose( $yourtextFile ); # Check for a conflict - $cmd = $wgDiff3 . ' -a --overlap-only ' . + $cmd = wfEscapeShellArg( $wgDiff3 ) . ' -a --overlap-only ' . wfEscapeShellArg( $mytextName ) . ' ' . wfEscapeShellArg( $oldtextName ) . ' ' . wfEscapeShellArg( $yourtextName ); $handle = popen( $cmd, 'r' ); - if( fgets( $handle, 1024 ) ) { + if ( fgets( $handle, 1024 ) ) { $conflict = true; } else { $conflict = false; @@ -2913,7 +2938,7 @@ function wfMerge( $old, $mine, $yours, &$result ) { pclose( $handle ); # Merge differences - $cmd = $wgDiff3 . ' -a -e --merge ' . + $cmd = wfEscapeShellArg( $wgDiff3 ) . ' -a -e --merge ' . wfEscapeShellArg( $mytextName, $oldtextName, $yourtextName ); $handle = popen( $cmd, 'r' ); $result = ''; @@ -2940,9 +2965,9 @@ function wfMerge( $old, $mine, $yours, &$result ) { * Returns unified plain-text diff of two texts. * Useful for machine processing of diffs. * - * @param $before String: the text before the changes. - * @param $after String: the text after the changes. - * @param $params String: command-line options for the diff command. + * @param string $before the text before the changes. + * @param string $after the text after the changes. + * @param string $params command-line options for the diff command. * @return String: unified diff of $before and $after */ function wfDiff( $before, $after, $params = '-u' ) { @@ -2957,7 +2982,7 @@ function wfDiff( $before, $after, $params = '-u' ) { # This check may also protect against code injection in # case of broken installations. - if( !$haveDiff ) { + if ( !$haveDiff ) { wfDebug( "diff executable not found\n" ); $diffs = new Diff( explode( "\n", $before ), explode( "\n", $after ) ); $format = new UnifiedDiffFormatter(); @@ -3022,6 +3047,7 @@ function wfDiff( $before, $after, $params = '-u' ) { * * @param $req_ver Mixed: the version to check, can be a string, an integer, or * a float + * @throws MWException */ function wfUsePHP( $req_ver ) { $php_ver = PHP_VERSION; @@ -3043,6 +3069,7 @@ function wfUsePHP( $req_ver ) { * * @param $req_ver Mixed: the version to check, can be a string, an integer, or * a float + * @throws MWException */ function wfUseMW( $req_ver ) { global $wgVersion; @@ -3061,7 +3088,7 @@ function wfUseMW( $req_ver ) { * We'll consider it so always, as we don't want '\s' in our Unix paths either. * * @param $path String - * @param $suffix String: to remove if present + * @param string $suffix to remove if present * @return String */ function wfBaseName( $path, $suffix = '' ) { @@ -3069,7 +3096,7 @@ function wfBaseName( $path, $suffix = '' ) { ? '' : ( '(?:' . preg_quote( $suffix, '#' ) . ')?' ); $matches = array(); - if( preg_match( "#([^/\\\\]*?){$encSuffix}[/\\\\]*$#", $path, $matches ) ) { + if ( preg_match( "#([^/\\\\]*?){$encSuffix}[/\\\\]*$#", $path, $matches ) ) { return $matches[1]; } else { return ''; @@ -3081,8 +3108,8 @@ function wfBaseName( $path, $suffix = '' ) { * May explode on non-matching case-insensitive paths, * funky symlinks, etc. * - * @param $path String: absolute destination path including target filename - * @param $from String: Absolute source path, directory only + * @param string $path absolute destination path including target filename + * @param string $from Absolute source path, directory only * @return String */ function wfRelativePath( $path, $from ) { @@ -3097,21 +3124,21 @@ function wfRelativePath( $path, $from ) { $pieces = explode( DIRECTORY_SEPARATOR, dirname( $path ) ); $against = explode( DIRECTORY_SEPARATOR, $from ); - if( $pieces[0] !== $against[0] ) { + if ( $pieces[0] !== $against[0] ) { // Non-matching Windows drive letters? // Return a full path. return $path; } // Trim off common prefix - while( count( $pieces ) && count( $against ) + while ( count( $pieces ) && count( $against ) && $pieces[0] == $against[0] ) { array_shift( $pieces ); array_shift( $against ); } // relative dots to bump us to the parent - while( count( $against ) ) { + while ( count( $against ) ) { array_unshift( $pieces, '..' ); array_shift( $against ); } @@ -3140,91 +3167,105 @@ function wfDoUpdates( $commit = '' ) { * Supports base 2 through 36; digit values 10-36 are represented * as lowercase letters a-z. Input is case-insensitive. * - * @param $input String: of digits - * @param $sourceBase Integer: 2-36 - * @param $destBase Integer: 2-36 - * @param $pad Integer: 1 or greater - * @param $lowercase Boolean - * @return String or false on invalid input - */ -function wfBaseConvert( $input, $sourceBase, $destBase, $pad = 1, $lowercase = true ) { - $input = strval( $input ); - if( $sourceBase < 2 || + * @param string $input Input number + * @param int $sourceBase Base of the input number + * @param int $destBase Desired base of the output + * @param int $pad Minimum number of digits in the output (pad with zeroes) + * @param bool $lowercase Whether to output in lowercase or uppercase + * @param string $engine Either "gmp", "bcmath", or "php" + * @return string|bool The output number as a string, or false on error + */ +function wfBaseConvert( $input, $sourceBase, $destBase, $pad = 1, $lowercase = true, $engine = 'auto' ) { + $input = (string)$input; + if ( + $sourceBase < 2 || $sourceBase > 36 || $destBase < 2 || $destBase > 36 || - $pad < 1 || - $sourceBase != intval( $sourceBase ) || - $destBase != intval( $destBase ) || - $pad != intval( $pad ) || - !is_string( $input ) || - $input == '' ) { + $sourceBase != (int)$sourceBase || + $destBase != (int)$destBase || + $pad != (int)$pad || + !preg_match( "/^[" . substr( '0123456789abcdefghijklmnopqrstuvwxyz', 0, $sourceBase ) . "]+$/i", $input ) + ) { return false; } - $digitChars = ( $lowercase ) ? '0123456789abcdefghijklmnopqrstuvwxyz' : '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; - $inDigits = array(); - $outChars = ''; - // Decode and validate input string - $input = strtolower( $input ); - for( $i = 0; $i < strlen( $input ); $i++ ) { - $n = strpos( $digitChars, $input[$i] ); - if( $n === false || $n > $sourceBase ) { - return false; + static $baseChars = array( + 10 => 'a', 11 => 'b', 12 => 'c', 13 => 'd', 14 => 'e', 15 => 'f', + 16 => 'g', 17 => 'h', 18 => 'i', 19 => 'j', 20 => 'k', 21 => 'l', + 22 => 'm', 23 => 'n', 24 => 'o', 25 => 'p', 26 => 'q', 27 => 'r', + 28 => 's', 29 => 't', 30 => 'u', 31 => 'v', 32 => 'w', 33 => 'x', + 34 => 'y', 35 => 'z', + + '0' => 0, '1' => 1, '2' => 2, '3' => 3, '4' => 4, '5' => 5, + '6' => 6, '7' => 7, '8' => 8, '9' => 9, 'a' => 10, 'b' => 11, + 'c' => 12, 'd' => 13, 'e' => 14, 'f' => 15, 'g' => 16, 'h' => 17, + 'i' => 18, 'j' => 19, 'k' => 20, 'l' => 21, 'm' => 22, 'n' => 23, + 'o' => 24, 'p' => 25, 'q' => 26, 'r' => 27, 's' => 28, 't' => 29, + 'u' => 30, 'v' => 31, 'w' => 32, 'x' => 33, 'y' => 34, 'z' => 35 + ); + + if ( extension_loaded( 'gmp' ) && ( $engine == 'auto' || $engine == 'gmp' ) ) { + $result = gmp_strval( gmp_init( $input, $sourceBase ), $destBase ); + } elseif ( extension_loaded( 'bcmath' ) && ( $engine == 'auto' || $engine == 'bcmath' ) ) { + $decimal = '0'; + foreach ( str_split( strtolower( $input ) ) as $char ) { + $decimal = bcmul( $decimal, $sourceBase ); + $decimal = bcadd( $decimal, $baseChars[$char] ); } - $inDigits[] = $n; - } - // Iterate over the input, modulo-ing out an output digit - // at a time until input is gone. - while( count( $inDigits ) ) { - $work = 0; - $workDigits = array(); + for ( $result = ''; bccomp( $decimal, 0 ); $decimal = bcdiv( $decimal, $destBase, 0 ) ) { + $result .= $baseChars[bcmod( $decimal, $destBase )]; + } + + $result = strrev( $result ); + } else { + $inDigits = array(); + foreach ( str_split( strtolower( $input ) ) as $char ) { + $inDigits[] = $baseChars[$char]; + } - // Long division... - foreach( $inDigits as $digit ) { - $work *= $sourceBase; - $work += $digit; + // Iterate over the input, modulo-ing out an output digit + // at a time until input is gone. + $result = ''; + while ( $inDigits ) { + $work = 0; + $workDigits = array(); - if( $work < $destBase ) { - // Gonna need to pull another digit. - if( count( $workDigits ) ) { - // Avoid zero-padding; this lets us find - // the end of the input very easily when - // length drops to zero. - $workDigits[] = 0; - } - } else { - // Finally! Actual division! - $workDigits[] = intval( $work / $destBase ); + // Long division... + foreach ( $inDigits as $digit ) { + $work *= $sourceBase; + $work += $digit; - // Isn't it annoying that most programming languages - // don't have a single divide-and-remainder operator, - // even though the CPU implements it that way? - $work = $work % $destBase; + if ( $workDigits || $work >= $destBase ) { + $workDigits[] = (int)( $work / $destBase ); + } + $work %= $destBase; } - } - // All that division leaves us with a remainder, - // which is conveniently our next output digit. - $outChars .= $digitChars[$work]; + // All that division leaves us with a remainder, + // which is conveniently our next output digit. + $result .= $baseChars[$work]; - // And we continue! - $inDigits = $workDigits; + // And we continue! + $inDigits = $workDigits; + } + + $result = strrev( $result ); } - while( strlen( $outChars ) < $pad ) { - $outChars .= '0'; + if ( !$lowercase ) { + $result = strtoupper( $result ); } - return strrev( $outChars ); + return str_pad( $result, $pad, '0', STR_PAD_LEFT ); } /** * Create an object with a given name and an array of construct parameters * * @param $name String - * @param $p Array: parameters + * @param array $p parameters * @return object * @deprecated since 1.18, warnings in 1.18, removal in 1.20 */ @@ -3239,9 +3280,9 @@ function wfCreateObject( $name, $p ) { function wfHttpOnlySafe() { global $wgHttpOnlyBlacklist; - if( isset( $_SERVER['HTTP_USER_AGENT'] ) ) { - foreach( $wgHttpOnlyBlacklist as $regex ) { - if( preg_match( $regex, $_SERVER['HTTP_USER_AGENT'] ) ) { + if ( isset( $_SERVER['HTTP_USER_AGENT'] ) ) { + foreach ( $wgHttpOnlyBlacklist as $regex ) { + if ( preg_match( $regex, $_SERVER['HTTP_USER_AGENT'] ) ) { return false; } } @@ -3251,7 +3292,7 @@ function wfHttpOnlySafe() { } /** - * Check if there is sufficent entropy in php's built-in session generation + * Check if there is sufficient entropy in php's built-in session generation * @return bool true = there is sufficient entropy */ function wfCheckEntropy() { @@ -3268,7 +3309,7 @@ function wfCheckEntropy() { */ function wfFixSessionID() { // If the cookie or session id is already set we already have a session and should abort - if ( isset( $_COOKIE[ session_name() ] ) || session_id() ) { + if ( isset( $_COOKIE[session_name()] ) || session_id() ) { return; } @@ -3286,6 +3327,27 @@ function wfFixSessionID() { } /** + * Reset the session_id + * @since 1.22 + */ +function wfResetSessionID() { + global $wgCookieSecure; + $oldSessionId = session_id(); + $cookieParams = session_get_cookie_params(); + if ( wfCheckEntropy() && $wgCookieSecure == $cookieParams['secure'] ) { + session_regenerate_id( false ); + } else { + $tmp = $_SESSION; + session_destroy(); + wfSetupSession( MWCryptRand::generateHex( 32 ) ); + $_SESSION = $tmp; + } + $newSessionId = session_id(); + wfRunHooks( 'ResetSessionID', array( $oldSessionId, $newSessionId ) ); +} + + +/** * Initialise php session * * @param $sessionId Bool @@ -3293,9 +3355,9 @@ function wfFixSessionID() { function wfSetupSession( $sessionId = false ) { global $wgSessionsInMemcached, $wgSessionsInObjectCache, $wgCookiePath, $wgCookieDomain, $wgCookieSecure, $wgCookieHttpOnly, $wgSessionHandler; - if( $wgSessionsInObjectCache || $wgSessionsInMemcached ) { + if ( $wgSessionsInObjectCache || $wgSessionsInMemcached ) { ObjectCacheSessionHandler::install(); - } elseif( $wgSessionHandler && $wgSessionHandler != ini_get( 'session.save_handler' ) ) { + } elseif ( $wgSessionHandler && $wgSessionHandler != ini_get( 'session.save_handler' ) ) { # Only set this if $wgSessionHandler isn't null and session.save_handler # hasn't already been set to the desired value (that causes errors) ini_set( 'session.save_handler', $wgSessionHandler ); @@ -3370,7 +3432,7 @@ function wfForeignMemcKey( $db, $prefix /*, ... */ ) { } else { $key = $db . ':' . implode( ':', $args ); } - return $key; + return str_replace( ' ', '_', $key ); } /** @@ -3414,7 +3476,7 @@ function wfSplitWikiID( $wiki ) { * belongs to. May contain a single string if the query is only * in one group. * - * @param $wiki String: the wiki ID, or false for the current wiki + * @param string $wiki the wiki ID, or false for the current wiki * * Note: multiple calls to wfGetDB(DB_SLAVE) during the course of one request * will always return the same object, unless the underlying connection or load @@ -3432,7 +3494,7 @@ function &wfGetDB( $db, $groups = array(), $wiki = false ) { /** * Get a load balancer object. * - * @param $wiki String: wiki ID, or false for the current wiki + * @param string $wiki wiki ID, or false for the current wiki * @return LoadBalancer */ function wfGetLB( $wiki = false ) { @@ -3452,8 +3514,8 @@ function &wfGetLBFactory() { * Find a file. * Shortcut for RepoGroup::singleton()->findFile() * - * @param $title String or Title object - * @param $options array Associative array of options: + * @param string $title or Title object + * @param array $options Associative array of options: * time: requested time for an archived image, or false for the * current version. An image object will be returned which was * created at the specified time. @@ -3511,14 +3573,14 @@ function wfQueriesMustScale() { * extensions; this is a wrapper around $wgScriptExtension etc. * except for 'index' and 'load' which use $wgScript/$wgLoadScript * - * @param $script String: script filename, sans extension + * @param string $script script filename, sans extension * @return String */ function wfScript( $script = 'index' ) { global $wgScriptPath, $wgScriptExtension, $wgScript, $wgLoadScript; if ( $script === 'index' ) { return $wgScript; - } else if ( $script === 'load' ) { + } elseif ( $script === 'load' ) { return $wgLoadScript; } else { return "{$wgScriptPath}/{$script}{$wgScriptExtension}"; @@ -3531,7 +3593,7 @@ function wfScript( $script = 'index' ) { * @return string script URL */ function wfGetScriptUrl() { - if( isset( $_SERVER['SCRIPT_NAME'] ) ) { + if ( isset( $_SERVER['SCRIPT_NAME'] ) ) { # # as it was called, minus the query string. # @@ -3560,16 +3622,6 @@ function wfBoolToStr( $value ) { } /** - * Load an extension messages file - * - * @deprecated since 1.16, warnings in 1.18, remove in 1.20 - * @codeCoverageIgnore - */ -function wfLoadExtensionMessages() { - wfDeprecated( __FUNCTION__, '1.16' ); -} - -/** * Get a platform-independent path to the null file, e.g. /dev/null * * @return string @@ -3589,15 +3641,22 @@ function wfGetNull() { * * @param $maxLag Integer (deprecated) * @param $wiki mixed Wiki identifier accepted by wfGetLB + * @param $cluster string cluster name accepted by LBFactory */ -function wfWaitForSlaves( $maxLag = false, $wiki = false ) { - $lb = wfGetLB( $wiki ); +function wfWaitForSlaves( $maxLag = false, $wiki = false, $cluster = false ) { + $lb = ( $cluster !== false ) + ? wfGetLBFactory()->getExternalLB( $cluster ) + : wfGetLB( $wiki ); // bug 27975 - Don't try to wait for slaves if there are none // Prevents permission error when getting master position if ( $lb->getServerCount() > 1 ) { - $dbw = $lb->getConnection( DB_MASTER ); + $dbw = $lb->getConnection( DB_MASTER, array(), $wiki ); $pos = $dbw->getMasterPos(); - $lb->waitForAll( $pos ); + // The DBMS may not support getMasterPos() or the whole + // load balancer might be fake (e.g. $wgAllDBsAreLocalhost). + if ( $pos !== false ) { + $lb->waitForAll( $pos ); + } } } @@ -3642,8 +3701,8 @@ function wfCountDown( $n ) { * characters before hashing. * @return string * @codeCoverageIgnore - * @deprecated since 1.20; Please use MWCryptRand for security purposes and wfRandomString for pesudo-random strings - * @warning This method is NOT secure. Additionally it has many callers that use it for pesudo-random purposes. + * @deprecated since 1.20; Please use MWCryptRand for security purposes and wfRandomString for pseudo-random strings + * @warning This method is NOT secure. Additionally it has many callers that use it for pseudo-random purposes. */ function wfGenerateToken( $salt = '' ) { wfDeprecated( __METHOD__, '1.20' ); @@ -3679,9 +3738,9 @@ function wfStripIllegalFilenameChars( $name ) { function wfMemoryLimit() { global $wgMemoryLimit; $memlimit = wfShorthandToInteger( ini_get( 'memory_limit' ) ); - if( $memlimit != -1 ) { + if ( $memlimit != -1 ) { $conflimit = wfShorthandToInteger( $wgMemoryLimit ); - if( $conflimit == -1 ) { + if ( $conflimit == -1 ) { wfDebug( "Removing PHP's memory limit\n" ); wfSuppressWarnings(); ini_set( 'memory_limit', $conflimit ); @@ -3706,12 +3765,12 @@ function wfMemoryLimit() { */ function wfShorthandToInteger( $string = '' ) { $string = trim( $string ); - if( $string === '' ) { + if ( $string === '' ) { return -1; } $last = $string[strlen( $string ) - 1]; $val = intval( $string ); - switch( $last ) { + switch ( $last ) { case 'g': case 'G': $val *= 1024; @@ -3732,29 +3791,24 @@ function wfShorthandToInteger( $string = '' ) { * Get the normalised IETF language tag * See unit test for examples. * - * @param $code String: The language code. + * @param string $code The language code. * @return String: The language code which complying with BCP 47 standards. */ function wfBCP47( $code ) { $codeSegment = explode( '-', $code ); $codeBCP = array(); foreach ( $codeSegment as $segNo => $seg ) { - if ( count( $codeSegment ) > 0 ) { - // when previous segment is x, it is a private segment and should be lc - if( $segNo > 0 && strtolower( $codeSegment[( $segNo - 1 )] ) == 'x' ) { - $codeBCP[$segNo] = strtolower( $seg ); - // ISO 3166 country code - } elseif ( ( strlen( $seg ) == 2 ) && ( $segNo > 0 ) ) { - $codeBCP[$segNo] = strtoupper( $seg ); - // ISO 15924 script code - } elseif ( ( strlen( $seg ) == 4 ) && ( $segNo > 0 ) ) { - $codeBCP[$segNo] = ucfirst( strtolower( $seg ) ); - // Use lowercase for other cases - } else { - $codeBCP[$segNo] = strtolower( $seg ); - } + // when previous segment is x, it is a private segment and should be lc + if ( $segNo > 0 && strtolower( $codeSegment[( $segNo - 1 )] ) == 'x' ) { + $codeBCP[$segNo] = strtolower( $seg ); + // ISO 3166 country code + } elseif ( ( strlen( $seg ) == 2 ) && ( $segNo > 0 ) ) { + $codeBCP[$segNo] = strtoupper( $seg ); + // ISO 15924 script code + } elseif ( ( strlen( $seg ) == 4 ) && ( $segNo > 0 ) ) { + $codeBCP[$segNo] = ucfirst( strtolower( $seg ) ); + // Use lowercase for other cases } else { - // Use lowercase for single segment $codeBCP[$segNo] = strtolower( $seg ); } } @@ -3815,20 +3869,20 @@ function wfGetLangConverterCacheStorage() { /** * Call hook functions defined in $wgHooks * - * @param $event String: event name - * @param $args Array: parameters passed to hook functions + * @param string $event event name + * @param array $args parameters passed to hook functions * @return Boolean True if no handler aborted the hook */ -function wfRunHooks( $event, $args = array() ) { +function wfRunHooks( $event, array $args = array() ) { return Hooks::run( $event, $args ); } /** * Wrapper around php's unpack. * - * @param $format String: The format string (See php's docs) + * @param string $format The format string (See php's docs) * @param $data: A binary string of binary data - * @param $length integer or false: The minimun length of $data. This is to + * @param $length integer or false: The minimum length of $data. This is to * prevent reading beyond the end of $data. false to disable the check. * * Also be careful when using this function to read unsigned 32 bit integer @@ -3837,7 +3891,7 @@ function wfRunHooks( $event, $args = array() ) { * @throws MWException if $data not long enough, or if unpack fails * @return array Associative array of the extracted data */ -function wfUnpack( $format, $data, $length=false ) { +function wfUnpack( $format, $data, $length = false ) { if ( $length !== false ) { $realLen = strlen( $data ); if ( $realLen < $length ) { @@ -3868,9 +3922,9 @@ function wfUnpack( $format, $data, $length=false ) { * * Any subsequent links on the same line are considered to be exceptions, * i.e. articles where the image may occur inline. * - * @param $name string the image name to check + * @param string $name the image name to check * @param $contextTitle Title|bool the page on which the image occurs, if known - * @param $blacklist string wikitext of a file blacklist + * @param string $blacklist wikitext of a file blacklist * @return bool */ function wfIsBadImage( $name, $contextTitle = false, $blacklist = null ) { @@ -3879,19 +3933,19 @@ function wfIsBadImage( $name, $contextTitle = false, $blacklist = null ) { # Handle redirects $redirectTitle = RepoGroup::singleton()->checkRedirect( Title::makeTitle( NS_FILE, $name ) ); - if( $redirectTitle ) { - $name = $redirectTitle->getDbKey(); + if ( $redirectTitle ) { + $name = $redirectTitle->getDBkey(); } # Run the extension hook $bad = false; - if( !wfRunHooks( 'BadImage', array( $name, &$bad ) ) ) { + if ( !wfRunHooks( 'BadImage', array( $name, &$bad ) ) ) { wfProfileOut( __METHOD__ ); return $bad; } $cacheable = ( $blacklist === null ); - if( $cacheable && $badImageCache !== null ) { + if ( $cacheable && $badImageCache !== null ) { $badImages = $badImageCache; } else { // cache miss if ( $blacklist === null ) { @@ -3900,7 +3954,7 @@ function wfIsBadImage( $name, $contextTitle = false, $blacklist = null ) { # Build the list now $badImages = array(); $lines = explode( "\n", $blacklist ); - foreach( $lines as $line ) { + foreach ( $lines as $line ) { # List items only if ( substr( $line, 0, 1 ) !== '*' ) { continue; @@ -3939,3 +3993,16 @@ function wfIsBadImage( $name, $contextTitle = false, $blacklist = null ) { wfProfileOut( __METHOD__ ); return $bad; } + +/** + * Determine whether the client at a given source IP is likely to be able to + * access the wiki via HTTPS. + * + * @param string $ip The IPv4/6 address in the normal human-readable form + * @return boolean + */ +function wfCanIPUseHTTPS( $ip ) { + $canDo = true; + wfRunHooks( 'CanIPUseHTTPS', array( $ip, &$canDo ) ); + return !!$canDo; +} |