1<?php
2
3namespace Wikimedia\Message;
4
5/**
6 * Value object representing a message for i18n with alternative
7 * machine-readable data.
8 *
9 * This augments a MessageValue with an additional machine-readable code and
10 * structured data. The intended use is to facilitate error reporting in APIs.
11 *
12 * For example, a MessageValue reporting an "integer out of range" error might
13 * use one of three message keys, depending on whether there is a minimum, a
14 * maximum, or both. But an API would likely want to use one code for all three
15 * cases, and would likely want the endpoints represented along the lines of
16 * `[ 'min' => 1, 'max' => 10 ]` rather than
17 * `[ 0 => new ScalarParam( ParamType::TEXT, 1 ), 1 => new ScalarParam( ParamType::TEXT, 10 ) ]`.
18 *
19 * DataMessageValues are pure value objects and are safely newable.
20 *
21 * @newable
22 */
23class DataMessageValue extends MessageValue {
24	/** @var string */
25	private $code;
26
27	/** @var array|null */
28	private $data;
29
30	/**
31	 * @stable to call
32	 *
33	 * @param string $key
34	 * @param (MessageParam|MessageValue|string|int|float)[] $params
35	 * @param string|null $code String representing the concept behind
36	 *  this message.
37	 * @param array|null $data Structured data representing the concept
38	 *  behind this message.
39	 */
40	public function __construct( $key, $params = [], $code = null, array $data = null ) {
41		parent::__construct( $key, $params );
42
43		$this->code = $code ?? $key;
44		$this->data = $data;
45	}
46
47	/**
48	 * Static constructor for easier chaining of `->params()` methods
49	 * @param string $key
50	 * @param (MessageParam|MessageValue|string|int|float)[] $params
51	 * @param string|null $code
52	 * @param array|null $data
53	 * @return DataMessageValue
54	 */
55	public static function new( $key, $params = [], $code = null, array $data = null ) {
56		return new DataMessageValue( $key, $params, $code, $data );
57	}
58
59	/**
60	 * Get the message code
61	 * @return string
62	 */
63	public function getCode() {
64		return $this->code;
65	}
66
67	/**
68	 * Get the message's structured data
69	 * @return array|null
70	 */
71	public function getData() {
72		return $this->data;
73	}
74
75	public function dump() {
76		$contents = '';
77		if ( $this->getParams() ) {
78			$contents = '<params>';
79			foreach ( $this->getParams() as $param ) {
80				$contents .= $param->dump();
81			}
82			$contents .= '</params>';
83		}
84
85		if ( $this->data !== null ) {
86			$contents .= '<data>' . htmlspecialchars( json_encode( $this->data ), ENT_NOQUOTES ) . '</data>';
87		}
88
89		return '<datamessage key="' . htmlspecialchars( $this->getKey() ) . '"'
90			. ' code="' . htmlspecialchars( $this->code ) . '">'
91			. $contents
92			. '</datamessage>';
93	}
94}
95