* @param $after Mixed: The key to insert after
* @return Array
*/
-function wfArrayInsertAfter( $array, $insert, $after ) {
+function wfArrayInsertAfter( array $array, array $insert, $after ) {
// Find the offset of the element to insert after.
$keys = array_keys( $array );
$offsetByKey = array_flip( $keys );
return $rand;
}
+/**
+ * Get a random string containing a number of pesudo-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
+ * @return String
+ * @since 1.20
+ */
+function wfRandomString( $length = 32 ) {
+ $str = '';
+ while ( strlen( $str ) < $length ) {
+ $str .= dechex( mt_rand() );
+ }
+ return substr( $str, 0, $length );
+}
+
/**
* We want some things to be included as literal characters in our title URLs
* for prettiness, which urlencode encodes by default. According to RFC 1738,
return $bits;
}
+/**
+ * Take a URL, make sure it's expanded to fully qualified, and replace any
+ * encoded non-ASCII Unicode characters with their UTF-8 original forms
+ * for more compact display and legibility for local audiences.
+ *
+ * @todo handle punycode domains too
+ *
+ * @param $url string
+ * @return string
+ */
+function wfExpandIRI( $url ) {
+ return preg_replace_callback( '/((?:%[89A-F][0-9A-F])+)/i', 'wfExpandIRI_callback', wfExpandUrl( $url ) );
+}
+
+/**
+ * Private callback for wfExpandIRI
+ * @param array $matches
+ * @return string
+ */
+function wfExpandIRI_callback( $matches ) {
+ return urldecode( $matches[1] );
+}
+
+
+
/**
* Make URL indexes, appropriate for the el_index field of externallinks.
*
global $wgDebugLogPrefix, $wgShowDebug;
static $cache = array(); // Cache of unoutputted messages
- $text = wfDebugTimer() . $text;
if ( !$wgDebugRawPage && wfIsDebugRawPage() ) {
return;
}
+ $timer = wfDebugTimer();
+ if ( $timer !== '' ) {
+ $text = preg_replace( '/[^\n]/', $timer . '\0', $text, 1 );
+ }
+
if ( ( $wgDebugComments || $wgShowDebug ) && !$logonly ) {
$cache[] = $text;
* @param $component String|bool: Added in 1.19.
* @param $callerOffset integer: How far up the callstack is the original
* caller. 2 = function that called the function that called
- * wfDeprecated (Added in 1.20)
- *
+ * wfDeprecated (Added in 1.20)
+ *
* @return null
*/
function wfDeprecated( $function, $version = false, $component = false, $callerOffset = 2 ) {
if ( !isset( $functionsWarned[$function] ) ) {
$functionsWarned[$function] = true;
-
+
if ( $version ) {
global $wgDeprecationReleaseLimit;
-
+
if ( $wgDeprecationReleaseLimit && $component === false ) {
# Strip -* off the end of $version so that branches can use the
# format #.##-branchname to avoid issues if the branch is merged into
# a version of MediaWiki later than what it was branched from
$comparableVersion = preg_replace( '/-.*$/', '', $version );
-
+
# If the comparableVersion is larger than our release limit then
# skip the warning message for the deprecation
if ( version_compare( $wgDeprecationReleaseLimit, $comparableVersion, '<' ) ) {
return;
}
}
-
+
$component = $component === false ? 'MediaWiki' : $component;
wfWarn( "Use of $function was deprecated in $component $version.", $callerOffset );
} else {
*/
function wfViewPrevNext( $offset, $limit, $link, $query = '', $atend = false ) {
wfDeprecated( __METHOD__, '1.19' );
-
+
global $wgLang;
$query = wfCgiToArray( $query );
}
/**
- * Generate a shell-escaped command line string to run a maintenance script.
+ * Alias to wfShellWikiCmd()
+ * @see wfShellWikiCmd()
+ */
+function wfShellMaintenanceCmd( $script, array $parameters = array(), array $options = array() ) {
+ return wfShellWikiCmd( $script, $parameters, $options );
+}
+
+/**
+ * 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 maintenance script path
+ * @param $script string MediaWiki cli script path
* @param $parameters Array Arguments and options to the script
* @param $options Array Associative array of options:
* 'php': The path to the php executable
* 'wrapper': Path to a PHP wrapper to handle the maintenance script
* @return Array
*/
-function wfShellMaintenanceCmd( $script, array $parameters = array(), array $options = array() ) {
+function wfShellWikiCmd( $script, array $parameters = array(), array $options = array() ) {
global $wgPhpCli;
// Give site config file a chance to run the script in a wrapper.
// The caller may likely want to call wfBasename() on $script.
- wfRunHooks( 'wfShellMaintenanceCmd', array( &$script, &$parameters, &$options ) );
+ wfRunHooks( 'wfShellWikiCmd', array( &$script, &$parameters, &$options ) );
$cmd = isset( $options['php'] ) ? array( $options['php'] ) : array( $wgPhpCli );
if ( isset( $options['wrapper'] ) ) {
$cmd[] = $options['wrapper'];
return true;
}
+/**
+ * Override session_id before session startup if php's built-in
+ * session generation code is not secure.
+ */
+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() ) {
+ return;
+ }
+
+ // PHP's built-in session entropy is enabled if:
+ // - entropy_file is set or you're on Windows with php 5.3.3+
+ // - AND entropy_length is > 0
+ // We treat it as disabled if it doesn't have an entropy length of at least 32
+ $entropyEnabled = (
+ ( wfIsWindows() && version_compare( PHP_VERSION, '5.3.3', '>=' ) )
+ || ini_get( 'session.entropy_file' )
+ )
+ && intval( ini_get( 'session.entropy_length' ) ) >= 32;
+
+ // If built-in entropy is not enabled or not sufficient override php's built in session id generation code
+ if ( !$entropyEnabled ) {
+ wfDebug( __METHOD__ . ": PHP's built in entropy is disabled or not sufficient, overriding session id generation using our cryptrand source.\n" );
+ session_id( MWCryptRand::generateHex( 32 ) );
+ }
+}
+
/**
* Initialise php session
*
session_cache_limiter( 'private, must-revalidate' );
if ( $sessionId ) {
session_id( $sessionId );
+ } else {
+ wfFixSessionID();
}
wfSuppressWarnings();
session_start();
* Returns a valid placeholder object if the file does not exist.
*
* @param $title Title|String
- * @return File|null A File, or null if passed an invalid Title
+ * @return LocalFile|null A File, or null if passed an invalid Title
*/
function wfLocalFile( $title ) {
return RepoGroup::singleton()->getLocalRepo()->newFile( $title );
* 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.
*/
function wfGenerateToken( $salt = '' ) {
+ wfDeprecated( __METHOD__, '1.20' );
$salt = serialize( $salt );
return md5( mt_rand( 0, 0x7fffffff ) . $salt );
}
return ObjectCache::getInstance( $wgParserCacheType );
}
+/**
+ * Get the cache object used by the language converter
+ *
+ * @return BagOStuff
+ */
+function wfGetLangConverterCacheStorage() {
+ global $wgLanguageConverterCacheType;
+ return ObjectCache::getInstance( $wgLanguageConverterCacheType );
+}
+
/**
* Call hook functions defined in $wgHooks
*
}
return $result;
}
+
+/**
+ * Determine if an image exists on the 'bad image list'.
+ *
+ * The format of MediaWiki:Bad_image_list is as follows:
+ * * Only list items (lines starting with "*") are considered
+ * * The first link on a line must be a link to a bad image
+ * * 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 $contextTitle Title|bool the page on which the image occurs, if known
+ * @param $blacklist string wikitext of a file blacklist
+ * @return bool
+ */
+function wfIsBadImage( $name, $contextTitle = false, $blacklist = null ) {
+ static $badImageCache = null; // based on bad_image_list msg
+ wfProfileIn( __METHOD__ );
+
+ # Handle redirects
+ $redirectTitle = RepoGroup::singleton()->checkRedirect( Title::makeTitle( NS_FILE, $name ) );
+ if( $redirectTitle ) {
+ $name = $redirectTitle->getDbKey();
+ }
+
+ # Run the extension hook
+ $bad = false;
+ if( !wfRunHooks( 'BadImage', array( $name, &$bad ) ) ) {
+ wfProfileOut( __METHOD__ );
+ return $bad;
+ }
+
+ $cacheable = ( $blacklist === null );
+ if( $cacheable && $badImageCache !== null ) {
+ $badImages = $badImageCache;
+ } else { // cache miss
+ if ( $blacklist === null ) {
+ $blacklist = wfMsgForContentNoTrans( 'bad_image_list' ); // site list
+ }
+ # Build the list now
+ $badImages = array();
+ $lines = explode( "\n", $blacklist );
+ foreach( $lines as $line ) {
+ # List items only
+ if ( substr( $line, 0, 1 ) !== '*' ) {
+ continue;
+ }
+
+ # Find all links
+ $m = array();
+ if ( !preg_match_all( '/\[\[:?(.*?)\]\]/', $line, $m ) ) {
+ continue;
+ }
+
+ $exceptions = array();
+ $imageDBkey = false;
+ foreach ( $m[1] as $i => $titleText ) {
+ $title = Title::newFromText( $titleText );
+ if ( !is_null( $title ) ) {
+ if ( $i == 0 ) {
+ $imageDBkey = $title->getDBkey();
+ } else {
+ $exceptions[$title->getPrefixedDBkey()] = true;
+ }
+ }
+ }
+
+ if ( $imageDBkey !== false ) {
+ $badImages[$imageDBkey] = $exceptions;
+ }
+ }
+ if ( $cacheable ) {
+ $badImageCache = $badImages;
+ }
+ }
+
+ $contextKey = $contextTitle ? $contextTitle->getPrefixedDBkey() : false;
+ $bad = isset( $badImages[$name] ) && !isset( $badImages[$name][$contextKey] );
+ wfProfileOut( __METHOD__ );
+ return $bad;
+}