New message class up for discussion and development.
[lhc/web/wiklou.git] / includes / Message.php
1 <?php
2
3 /**
4 OBS!!! *EXPERIMENTAL* This class is still under discussion.
5
6 This class provides methods for fetching interface messages and
7 processing them into variety of formats that are needed in MediaWiki.
8
9 It is intented to replace the old wfMsg* functions that over time grew
10 unusable.
11
12 Examples:
13
14 Use full parsing.
15 Would correspond to wfMsgExt( 'key', array( 'parseinline' ), 'apple' );
16 $parsed = Message::key( 'key' ).param( 'apple' ).parse();
17 Parseinline is used because it is more useful when pre-building html.
18 In normal use it is better to use OutputPage::(add|wrap)WikiMsg.
19
20 Places where html cannot be used. {{-transformation is done.
21 Would correspond to wfMsgExt( 'key', array( 'parsemag' ), 'apple', 'pear' );
22 $plain = Message::key( 'key' ).params( 'apple', 'pear' ).text();
23
24 Shortcut for escaping the message too, similar to wfMsgHTML, but
25 parameters are not replaced after escaping by default.
26 $escaped = Message::key( 'key' ).rawParam( 'apple' ).escaped();
27
28 TODO:
29 * document everything
30 * test, can we have tests?
31 * sort out the details marked with fixme
32 * should we have _m() or similar global wrapper?
33
34 @since 1.17
35 */
36 class Message {
37 // FIXME: public or protected?
38
39 // FIXME: handle language properly
40 public $language;
41 public $key;
42 public $parameters = array();
43
44 /**
45 * Constructor.
46 * @param $key String: message key
47 */
48 public function __construct( $key ) {
49 $this->key = $key;
50 }
51
52 /**
53 * Factory function that is just wrapper for the real constructor. It is
54 * intented to be used instead of the real constructor, because it allows
55 * chaining method calls, while new objects don't.
56 * //FIXME: key or get or something else?
57 * @param $key String: message key
58 * @return Message: reference to the object
59 */
60 public function key( $key ) {
61 return new Message( $key );
62 }
63
64 /**
65 * Adds parameters to the paramater list of this message.
66 * @params String: parameter
67 * @return Message: reference to the object
68 */
69 public function param( $value ) {
70 $this->parameters[] = $value;
71 return $this;
72 }
73
74 /**
75 * Adds parameters to the paramater list of this message.
76 * @params Vargars: parameters
77 * @return Message: reference to the object
78 */
79 public function params( /*...*/ ) {
80 $this->paramList( func_get_args() );
81 return $this;
82 }
83
84 /**
85 * Adds a list of parameters to the parameter list of this message.
86 * @param $value Array: list of parameters, array keys will be ignored.
87 * @return Message: reference to the object
88 */
89
90 public function paramList( array $values ) {
91 $this->parameters += array_values( $values );
92 return $this;
93 }
94
95 /**
96 *
97 */
98 public function rawParam( $value ) {
99 $this->parameters[] = array( 'raw' => $value );
100 return $this;
101 }
102
103 public function parse() {
104 $string = $this->parseAsBlock( $string );
105 $m = array();
106 if( preg_match( '/^<p>(.*)\n?<\/p>\n?$/sU', $string, $m ) ) {
107 $string = $m[1];
108 }
109 return $string;
110 }
111
112 public function text() {
113 $string = $this->getMessageText();
114 $string = $this->replaceParameters( 'before' );
115 $string = $this->parseText( $string );
116 $string = $this->replaceParameters( 'after' );
117 $m = array();
118 if( preg_match( '/^<p>(.*)\n?<\/p>\n?$/sU', $string, $m ) ) {
119 $string = $m[1];
120 }
121 return $string;
122 }
123
124 public function plain() {
125 $string = $this->getMessageText();
126 $string = $this->replaceParameters( 'before' );
127 $string = $this->transformText( $string );
128 $string = $this->replaceParameters( 'after' );
129 return $string;
130 }
131
132 public function parseAsBlock() {
133 $string = $this->getMessageText();
134 $string = $this->replaceParameters( 'before' );
135 $string = $this->parseText( $string );
136 $string = $this->replaceParameters( 'after' );
137 return $string;
138 }
139
140 public function escaped() {
141 return htmlspecialchars( $this->plain() );
142 }
143
144 protected function replaceParamaters( $type = 'before' ) {
145 $replacementKeys = array();
146 foreach( $args as $n => $param ) {
147 if ( $type === 'before' && !isset( $param['raw'] ) ) {
148 $replacementKeys['$' . ($n + 1)] = $param;
149 } elseif ( $type === 'after' && isset( $param['raw'] ) ) {
150 $replacementKeys['$' . ($n + 1)] = $param['raw'];
151 }
152 }
153 $message = strtr( $message, $replacementKeys );
154 return $message;
155 }
156
157 // FIXME: handle properly
158 protected function getLanguage() {
159 return $this->language === null ? true : $this->language;
160 }
161
162 protected function parseText( $string ) {
163 global $wgOut;
164 return $wgOut->parse( $string, true, (bool) $this->getLanguage() );
165 }
166
167 protected function transformText( $string ) {
168 global $wgMessageCache;
169 if ( !isset( $wgMessageCache ) ) return $string;
170 // FIXME: handle second param correctly
171 return $wgMessageCache->transform( $string, true, $this->getLanguage() );
172 }
173
174 protected function getMessageText() {
175 return wfMsgGetKey( $this->key, /*DB*/true, $this->getLanguage(), /*Transform*/false );
176 }
177
178 }