1<?php 2 3namespace Wikimedia\Message; 4 5/** 6 * Value object representing a message for i18n. 7 * 8 * A MessageValue holds a key and an array of parameters. It can be converted 9 * to a string in a particular language using formatters obtained from an 10 * IMessageFormatterFactory. 11 * 12 * MessageValues are pure value objects and are safely newable. 13 * 14 * @newable 15 */ 16class MessageValue { 17 /** @var string */ 18 private $key; 19 20 /** @var MessageParam[] */ 21 private $params; 22 23 /** 24 * @stable to call 25 * 26 * @param string $key 27 * @param (MessageParam|MessageValue|string|int|float)[] $params Values that are not instances 28 * of MessageParam are wrapped using ParamType::TEXT. 29 */ 30 public function __construct( $key, $params = [] ) { 31 $this->key = $key; 32 $this->params = []; 33 $this->params( ...$params ); 34 } 35 36 /** 37 * Static constructor for easier chaining of `->params()` methods 38 * @param string $key 39 * @param (MessageParam|MessageValue|string|int|float)[] $params 40 * @return MessageValue 41 */ 42 public static function new( $key, $params = [] ) { 43 return new MessageValue( $key, $params ); 44 } 45 46 /** 47 * Get the message key 48 * 49 * @return string 50 */ 51 public function getKey() { 52 return $this->key; 53 } 54 55 /** 56 * Get the parameter array 57 * 58 * @return MessageParam[] 59 */ 60 public function getParams() { 61 return $this->params; 62 } 63 64 /** 65 * Chainable mutator which adds text parameters and MessageParam parameters 66 * 67 * @param MessageParam|MessageValue|string|int|float ...$values 68 * @return $this 69 */ 70 public function params( ...$values ) { 71 foreach ( $values as $value ) { 72 if ( $value instanceof MessageParam ) { 73 $this->params[] = $value; 74 } else { 75 $this->params[] = new ScalarParam( ParamType::TEXT, $value ); 76 } 77 } 78 return $this; 79 } 80 81 /** 82 * Chainable mutator which adds text parameters with a common type 83 * 84 * @param string $type One of the ParamType constants 85 * @param MessageValue|string|int|float ...$values Scalar values 86 * @return $this 87 */ 88 public function textParamsOfType( $type, ...$values ) { 89 foreach ( $values as $value ) { 90 $this->params[] = new ScalarParam( $type, $value ); 91 } 92 return $this; 93 } 94 95 /** 96 * Chainable mutator which adds list parameters with a common type 97 * 98 * @param string $listType One of the ListType constants 99 * @param (MessageParam|MessageValue|string|int|float)[] ...$values Each value 100 * is an array of items suitable to pass as $params to ListParam::__construct() 101 * @return $this 102 */ 103 public function listParamsOfType( $listType, ...$values ) { 104 foreach ( $values as $value ) { 105 $this->params[] = new ListParam( $listType, $value ); 106 } 107 return $this; 108 } 109 110 /** 111 * Chainable mutator which adds parameters of type text (ParamType::TEXT). 112 * 113 * @param MessageValue|string|int|float ...$values 114 * @return $this 115 */ 116 public function textParams( ...$values ) { 117 return $this->textParamsOfType( ParamType::TEXT, ...$values ); 118 } 119 120 /** 121 * Chainable mutator which adds numeric parameters (ParamType::NUM). 122 * 123 * @param int|float ...$values 124 * @return $this 125 */ 126 public function numParams( ...$values ) { 127 return $this->textParamsOfType( ParamType::NUM, ...$values ); 128 } 129 130 /** 131 * Chainable mutator which adds parameters which are a duration specified 132 * in seconds (ParamType::DURATION_LONG). 133 * 134 * This is similar to shorDurationParams() except that the result will be 135 * more verbose. 136 * 137 * @param int|float ...$values 138 * @return $this 139 */ 140 public function longDurationParams( ...$values ) { 141 return $this->textParamsOfType( ParamType::DURATION_LONG, ...$values ); 142 } 143 144 /** 145 * Chainable mutator which adds parameters which are a duration specified 146 * in seconds (ParamType::DURATION_SHORT). 147 * 148 * This is similar to longDurationParams() except that the result will be more 149 * compact. 150 * 151 * @param int|float ...$values 152 * @return $this 153 */ 154 public function shortDurationParams( ...$values ) { 155 return $this->textParamsOfType( ParamType::DURATION_SHORT, ...$values ); 156 } 157 158 /** 159 * Chainable mutator which adds parameters which are an expiry timestamp (ParamType::EXPIRY). 160 * 161 * @param string ...$values Timestamp as accepted by the Wikimedia\Timestamp library, 162 * or "infinity" 163 * @return $this 164 */ 165 public function expiryParams( ...$values ) { 166 return $this->textParamsOfType( ParamType::EXPIRY, ...$values ); 167 } 168 169 /** 170 * Chainable mutator which adds parameters which are a date-time timestamp (ParamType::DATETIME). 171 * 172 * @since 1.36 173 * @param string ...$values Timestamp as accepted by the Wikimedia\Timestamp library. 174 * @return $this 175 */ 176 public function dateTimeParams( ...$values ) { 177 return $this->textParamsOfType( ParamType::DATETIME, ...$values ); 178 } 179 180 /** 181 * Chainable mutator which adds parameters which are a date timestamp (ParamType::DATE). 182 * 183 * @since 1.36 184 * @param string ...$values Timestamp as accepted by the Wikimedia\Timestamp library. 185 * @return $this 186 */ 187 public function dateParams( ...$values ) { 188 return $this->textParamsOfType( ParamType::DATE, ...$values ); 189 } 190 191 /** 192 * Chainable mutator which adds parameters which are a time timestamp (ParamType::TIME). 193 * 194 * @since 1.36 195 * @param string ...$values Timestamp as accepted by the Wikimedia\Timestamp library. 196 * @return $this 197 */ 198 public function timeParams( ...$values ) { 199 return $this->textParamsOfType( ParamType::TIME, ...$values ); 200 } 201 202 /** 203 * Chainable mutator which adds parameters which are a number of bytes (ParamType::SIZE). 204 * 205 * @param int ...$values 206 * @return $this 207 */ 208 public function sizeParams( ...$values ) { 209 return $this->textParamsOfType( ParamType::SIZE, ...$values ); 210 } 211 212 /** 213 * Chainable mutator which adds parameters which are a number of bits per 214 * second (ParamType::BITRATE). 215 * 216 * @param int|float ...$values 217 * @return $this 218 */ 219 public function bitrateParams( ...$values ) { 220 return $this->textParamsOfType( ParamType::BITRATE, ...$values ); 221 } 222 223 /** 224 * Chainable mutator which adds "raw" parameters (ParamType::RAW). 225 * 226 * Raw parameters are substituted after formatter processing. The caller is responsible 227 * for ensuring that the value will be safe for the intended output format, and 228 * documenting what that intended output format is. 229 * 230 * @param string ...$values 231 * @return $this 232 */ 233 public function rawParams( ...$values ) { 234 return $this->textParamsOfType( ParamType::RAW, ...$values ); 235 } 236 237 /** 238 * Chainable mutator which adds plaintext parameters (ParamType::PLAINTEXT). 239 * 240 * Plaintext parameters are substituted after formatter processing. The value 241 * will be escaped by the formatter as appropriate for the target output format 242 * so as to be represented as plain text rather than as any sort of markup. 243 * 244 * @param string ...$values 245 * @return $this 246 */ 247 public function plaintextParams( ...$values ) { 248 return $this->textParamsOfType( ParamType::PLAINTEXT, ...$values ); 249 } 250 251 /** 252 * Chainable mutator which adds comma lists (ListType::COMMA). 253 * 254 * The list parameters thus created are formatted as a comma-separated list, 255 * or some local equivalent. 256 * 257 * @param (MessageParam|MessageValue|string|int|float)[] ...$values Each value 258 * is an array of items suitable to pass as $params to ListParam::__construct() 259 * @return $this 260 */ 261 public function commaListParams( ...$values ) { 262 return $this->listParamsOfType( ListType::COMMA, ...$values ); 263 } 264 265 /** 266 * Chainable mutator which adds semicolon lists (ListType::SEMICOLON). 267 * 268 * The list parameters thus created are formatted as a semicolon-separated 269 * list, or some local equivalent. 270 * 271 * @param (MessageParam|MessageValue|string|int|float)[] ...$values Each value 272 * is an array of items suitable to pass as $params to ListParam::__construct() 273 * @return $this 274 */ 275 public function semicolonListParams( ...$values ) { 276 return $this->listParamsOfType( ListType::SEMICOLON, ...$values ); 277 } 278 279 /** 280 * Chainable mutator which adds pipe lists (ListType::PIPE). 281 * 282 * The list parameters thus created are formatted as a pipe ("|") -separated 283 * list, or some local equivalent. 284 * 285 * @param (MessageParam|MessageValue|string|int|float)[] ...$values Each value 286 * is an array of items suitable to pass as $params to ListParam::__construct() 287 * @return $this 288 */ 289 public function pipeListParams( ...$values ) { 290 return $this->listParamsOfType( ListType::PIPE, ...$values ); 291 } 292 293 /** 294 * Chainable mutator which adds natural-language lists (ListType::AND). 295 * 296 * The list parameters thus created, when formatted, are joined as in natural 297 * language. In English, this means a comma-separated list, with the last 298 * two elements joined with "and". 299 * 300 * @param (MessageParam|string)[] ...$values 301 * @return $this 302 */ 303 public function textListParams( ...$values ) { 304 return $this->listParamsOfType( ListType::AND, ...$values ); 305 } 306 307 /** 308 * Dump the object for testing/debugging 309 * 310 * @return string 311 */ 312 public function dump() { 313 $contents = ''; 314 foreach ( $this->params as $param ) { 315 $contents .= $param->dump(); 316 } 317 return '<message key="' . htmlspecialchars( $this->key ) . '">' . 318 $contents . '</message>'; 319 } 320} 321