X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2FMessage.php;h=fd67613e28d2ab7faf73d5e3866ff48fcf20c4bf;hb=680de1a04acdbe56a7173aed6df684268f499ed3;hp=85c78d640cc86566ee02fbec4f82c713cfe44a79;hpb=8ae056613d8fcf9f1d34c0c3241d0731a7ec0f5e;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/Message.php b/includes/Message.php index 85c78d640c..fd67613e28 100644 --- a/includes/Message.php +++ b/includes/Message.php @@ -168,6 +168,17 @@ class Message implements MessageSpecifier, Serializable { /** Transform {{..}} constructs, HTML-escape the result */ const FORMAT_ESCAPED = 'escaped'; + /** + * Mapping from Message::listParam() types to Language methods. + * @var array + */ + protected static $listTypeMap = [ + 'comma' => 'commaList', + 'semicolon' => 'semicolonList', + 'pipe' => 'pipeList', + 'text' => 'listToText', + ]; + /** * In which language to get this message. True, which is the default, * means the current user language, false content language. @@ -477,18 +488,32 @@ class Message implements MessageSpecifier, Serializable { * * @since 1.17 * - * @param mixed ... Parameters as strings, or a single argument that is - * an array of strings. + * @param mixed ... Parameters as strings or arrays from + * Message::numParam() and the like, or a single array of parameters. * * @return Message $this */ public function params( /*...*/ ) { $args = func_get_args(); - if ( isset( $args[0] ) && is_array( $args[0] ) ) { - $args = $args[0]; + + // If $args has only one entry and it's an array, then it's either a + // non-varargs call or it happens to be a call with just a single + // "special" parameter. Since the "special" parameters don't have any + // numeric keys, we'll test that to differentiate the cases. + if ( count( $args ) === 1 && isset( $args[0] ) && is_array( $args[0] ) ) { + if ( $args[0] === [] ) { + $args = []; + } else { + foreach ( $args[0] as $key => $value ) { + if ( is_int( $key ) ) { + $args = $args[0]; + break; + } + } + } } - $args_values = array_values( $args ); - $this->parameters = array_merge( $this->parameters, $args_values ); + + $this->parameters = array_merge( $this->parameters, array_values( $args ) ); return $this; } @@ -1029,9 +1054,9 @@ class Message implements MessageSpecifier, Serializable { /** * @since 1.22 * - * @param number $period + * @param int $period * - * @return number[] Array with a single "period" key. + * @return int[] Array with a single "period" key. */ public static function timeperiodParam( $period ) { return [ 'period' => $period ]; @@ -1070,6 +1095,22 @@ class Message implements MessageSpecifier, Serializable { return [ 'plaintext' => $plaintext ]; } + /** + * @since 1.29 + * + * @param array $list + * @param string $type 'comma', 'semicolon', 'pipe', 'text' + * @return array Array with "list" and "type" keys. + */ + public static function listParam( array $list, $type = 'text' ) { + if ( !isset( self::$listTypeMap[$type] ) ) { + throw new InvalidArgumentException( + "Invalid type '$type'. Known types are: " . join( ', ', array_keys( self::$listTypeMap ) ) + ); + } + return [ 'list' => $list, 'type' => $type ]; + } + /** * Substitutes any parameters into the message text. * @@ -1123,6 +1164,8 @@ class Message implements MessageSpecifier, Serializable { return [ 'before', $this->getLanguage()->formatBitrate( $param['bitrate'] ) ]; } elseif ( isset( $param['plaintext'] ) ) { return [ 'after', $this->formatPlaintext( $param['plaintext'], $format ) ]; + } elseif ( isset( $param['list'] ) ) { + return $this->formatListParam( $param['list'], $param['type'], $format ); } else { $warning = 'Invalid parameter for message "' . $this->getKey() . '": ' . htmlspecialchars( serialize( $param ) ); @@ -1251,6 +1294,55 @@ class Message implements MessageSpecifier, Serializable { } } + + /** + * Formats a list of parameters as a concatenated string. + * @since 1.29 + * @param array $params + * @param string $listType + * @param string $format One of the FORMAT_* constants. + * @return array Array with the parameter type (either "before" or "after") and the value. + */ + protected function formatListParam( array $params, $listType, $format ) { + if ( !isset( self::$listTypeMap[$listType] ) ) { + $warning = 'Invalid list type for message "' . $this->getKey() . '": ' + . htmlspecialchars( $listType ) + . ' (params are ' . htmlspecialchars( serialize( $params ) ) . ')'; + trigger_error( $warning, E_USER_WARNING ); + $e = new Exception; + wfDebugLog( 'Bug58676', $warning . "\n" . $e->getTraceAsString() ); + return [ 'before', '[INVALID]' ]; + } + $func = self::$listTypeMap[$listType]; + + // Handle an empty list sensibly + if ( !$params ) { + return [ 'before', $this->getLanguage()->$func( [] ) ]; + } + + // First, determine what kinds of list items we have + $types = []; + $vars = []; + $list = []; + foreach ( $params as $n => $p ) { + list( $type, $value ) = $this->extractParam( $p, $format ); + $types[$type] = true; + $list[] = $value; + $vars[] = '$' . ( $n + 1 ); + } + + // Easy case: all are 'before' or 'after', so just join the + // values and use the same type. + if ( count( $types ) === 1 ) { + return [ key( $types ), $this->getLanguage()->$func( $list ) ]; + } + + // Hard case: We need to process each value per its type, then + // return the concatenated values as 'after'. We handle this by turning + // the list into a RawMessage and processing that as a parameter. + $vars = $this->getLanguage()->$func( $vars ); + return $this->extractParam( new RawMessage( $vars, $params ), $format ); + } } /**