Complex classes like MessageFormatter often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use MessageFormatter, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
46 | class MessageFormatter extends Component |
||
47 | { |
||
48 | private $_errorCode = 0; |
||
49 | private $_errorMessage = ''; |
||
50 | |||
51 | |||
52 | /** |
||
53 | * Get the error code from the last operation |
||
54 | * @link http://php.net/manual/en/messageformatter.geterrorcode.php |
||
55 | * @return string Code of the last error. |
||
56 | */ |
||
57 | public function getErrorCode() |
||
61 | |||
62 | /** |
||
63 | * Get the error text from the last operation |
||
64 | * @link http://php.net/manual/en/messageformatter.geterrormessage.php |
||
65 | * @return string Description of the last error. |
||
66 | */ |
||
67 | 47 | public function getErrorMessage() |
|
71 | |||
72 | /** |
||
73 | * Formats a message via [ICU message format](http://userguide.icu-project.org/formatparse/messages) |
||
74 | * |
||
75 | * It uses the PHP intl extension's [MessageFormatter](http://www.php.net/manual/en/class.messageformatter.php) |
||
76 | * and works around some issues. |
||
77 | * If PHP intl is not installed a fallback will be used that supports a subset of the ICU message format. |
||
78 | * |
||
79 | * @param string $pattern The pattern string to insert parameters into. |
||
80 | * @param array $params The array of name value pairs to insert into the format string. |
||
81 | * @param string $language The locale to use for formatting locale-dependent parts |
||
82 | * @return string|false The formatted pattern string or `false` if an error occurred |
||
83 | */ |
||
84 | 152 | public function format($pattern, $params, $language) |
|
85 | { |
||
86 | 152 | $this->_errorCode = 0; |
|
87 | 152 | $this->_errorMessage = ''; |
|
88 | |||
89 | 152 | if ($params === []) { |
|
90 | 4 | return $pattern; |
|
91 | } |
||
92 | |||
93 | 148 | if (!class_exists('MessageFormatter', false)) { |
|
94 | return $this->fallbackFormat($pattern, $params, $language); |
||
95 | } |
||
96 | |||
97 | // replace named arguments (https://github.com/yiisoft/yii2/issues/9678) |
||
98 | 148 | $newParams = []; |
|
99 | 148 | $pattern = $this->replaceNamedArguments($pattern, $params, $newParams); |
|
100 | 148 | $params = $newParams; |
|
101 | |||
102 | try { |
||
103 | 148 | $formatter = new \MessageFormatter($language, $pattern); |
|
104 | |||
105 | 147 | if ($formatter === null) { |
|
106 | // formatter may be null in PHP 5.x |
||
107 | $this->_errorCode = intl_get_error_code(); |
||
108 | $this->_errorMessage = 'Message pattern is invalid: ' . intl_get_error_message(); |
||
109 | 147 | return false; |
|
110 | } |
||
111 | 1 | } catch (\IntlException $e) { |
|
|
|||
112 | // IntlException is thrown since PHP 7 |
||
113 | 1 | $this->_errorCode = $e->getCode(); |
|
114 | 1 | $this->_errorMessage = 'Message pattern is invalid: ' . $e->getMessage(); |
|
115 | 1 | return false; |
|
116 | } catch (\Exception $e) { |
||
117 | // Exception is thrown by HHVM |
||
118 | $this->_errorCode = $e->getCode(); |
||
119 | $this->_errorMessage = 'Message pattern is invalid: ' . $e->getMessage(); |
||
120 | return false; |
||
121 | } |
||
122 | |||
123 | 147 | $result = $formatter->format($params); |
|
124 | |||
125 | 147 | if ($result === false) { |
|
126 | $this->_errorCode = $formatter->getErrorCode(); |
||
127 | $this->_errorMessage = $formatter->getErrorMessage(); |
||
128 | return false; |
||
129 | } |
||
130 | |||
131 | 147 | return $result; |
|
132 | } |
||
133 | |||
134 | /** |
||
135 | * Parses an input string according to an [ICU message format](http://userguide.icu-project.org/formatparse/messages) pattern. |
||
136 | * |
||
137 | * It uses the PHP intl extension's [MessageFormatter::parse()](http://www.php.net/manual/en/messageformatter.parsemessage.php) |
||
138 | * and adds support for named arguments. |
||
139 | * Usage of this method requires PHP intl extension to be installed. |
||
140 | * |
||
141 | * @param string $pattern The pattern to use for parsing the message. |
||
142 | * @param string $message The message to parse, conforming to the pattern. |
||
143 | * @param string $language The locale to use for formatting locale-dependent parts |
||
144 | * @return array|bool An array containing items extracted, or `FALSE` on error. |
||
145 | * @throws \yii\base\NotSupportedException when PHP intl extension is not installed. |
||
146 | */ |
||
147 | 7 | public function parse($pattern, $message, $language) |
|
148 | { |
||
149 | 7 | $this->_errorCode = 0; |
|
150 | 7 | $this->_errorMessage = ''; |
|
151 | |||
152 | 7 | if (!class_exists('MessageFormatter', false)) { |
|
153 | throw new NotSupportedException('You have to install PHP intl extension to use this feature.'); |
||
154 | } |
||
155 | |||
156 | // replace named arguments |
||
157 | 7 | if (($tokens = self::tokenizePattern($pattern)) === false) { |
|
158 | $this->_errorCode = -1; |
||
159 | $this->_errorMessage = 'Message pattern is invalid.'; |
||
160 | |||
161 | return false; |
||
162 | } |
||
163 | 7 | $map = []; |
|
164 | 7 | foreach ($tokens as $i => $token) { |
|
165 | 7 | if (is_array($token)) { |
|
166 | 7 | $param = trim($token[0]); |
|
167 | 7 | if (!isset($map[$param])) { |
|
168 | 7 | $map[$param] = count($map); |
|
169 | } |
||
170 | 7 | $token[0] = $map[$param]; |
|
171 | 7 | $tokens[$i] = '{' . implode(',', $token) . '}'; |
|
172 | } |
||
173 | } |
||
174 | 7 | $pattern = implode('', $tokens); |
|
175 | 7 | $map = array_flip($map); |
|
176 | |||
177 | 7 | $formatter = new \MessageFormatter($language, $pattern); |
|
178 | 7 | if ($formatter === null) { |
|
179 | $this->_errorCode = -1; |
||
180 | $this->_errorMessage = 'Message pattern is invalid.'; |
||
181 | |||
182 | return false; |
||
183 | } |
||
184 | 7 | $result = $formatter->parse($message); |
|
185 | 7 | if ($result === false) { |
|
186 | $this->_errorCode = $formatter->getErrorCode(); |
||
187 | $this->_errorMessage = $formatter->getErrorMessage(); |
||
188 | |||
189 | return false; |
||
190 | } |
||
191 | |||
192 | 7 | $values = []; |
|
193 | 7 | foreach ($result as $key => $value) { |
|
194 | 7 | $values[$map[$key]] = $value; |
|
195 | } |
||
196 | |||
197 | 7 | return $values; |
|
198 | } |
||
199 | |||
200 | /** |
||
201 | * Replace named placeholders with numeric placeholders and quote unused. |
||
202 | * |
||
203 | * @param string $pattern The pattern string to replace things into. |
||
204 | * @param array $givenParams The array of values to insert into the format string. |
||
205 | * @param array $resultingParams Modified array of parameters. |
||
206 | * @param array $map |
||
207 | * @return string The pattern string with placeholders replaced. |
||
208 | */ |
||
209 | 148 | private function replaceNamedArguments($pattern, $givenParams, &$resultingParams = [], &$map = []) |
|
256 | |||
257 | /** |
||
258 | * Fallback implementation for MessageFormatter::formatMessage |
||
259 | * @param string $pattern The pattern string to insert things into. |
||
260 | * @param array $args The array of values to insert into the format string |
||
261 | * @param string $locale The locale to use for formatting locale-dependent parts |
||
262 | * @return false|string The formatted pattern string or `false` if an error occurred |
||
263 | */ |
||
264 | 18 | protected function fallbackFormat($pattern, $args, $locale) |
|
265 | { |
||
266 | 18 | if (($tokens = self::tokenizePattern($pattern)) === false) { |
|
267 | $this->_errorCode = -1; |
||
268 | $this->_errorMessage = 'Message pattern is invalid.'; |
||
269 | |||
270 | return false; |
||
271 | } |
||
272 | 18 | foreach ($tokens as $i => $token) { |
|
273 | 18 | if (is_array($token)) { |
|
274 | 18 | if (($tokens[$i] = $this->parseToken($token, $args, $locale)) === false) { |
|
275 | $this->_errorCode = -1; |
||
276 | $this->_errorMessage = 'Message pattern is invalid.'; |
||
277 | |||
278 | 18 | return false; |
|
279 | } |
||
280 | } |
||
281 | } |
||
282 | |||
283 | 16 | return implode('', $tokens); |
|
284 | } |
||
285 | |||
286 | /** |
||
287 | * Tokenizes a pattern by separating normal text from replaceable patterns |
||
288 | * @param string $pattern patter to tokenize |
||
289 | * @return array|bool array of tokens or false on failure |
||
290 | */ |
||
291 | 173 | private static function tokenizePattern($pattern) |
|
328 | |||
329 | /** |
||
330 | * Parses a token |
||
331 | * @param array $token the token to parse |
||
332 | * @param array $args arguments to replace |
||
333 | * @param string $locale the locale |
||
334 | * @return bool|string parsed token or false on failure |
||
335 | * @throws \yii\base\NotSupportedException when unsupported formatting is used. |
||
336 | */ |
||
337 | 18 | private function parseToken($token, $args, $locale) |
|
435 | } |
||
436 |
Scrutinizer analyzes your
composer.json
/composer.lock
file if available to determine the classes, and functions that are defined by your dependencies.It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.