Complex classes like MessageController 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 MessageController, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
38 | class MessageController extends Controller |
||
39 | { |
||
40 | /** |
||
41 | * @var string controller default action ID. |
||
42 | */ |
||
43 | public $defaultAction = 'extract'; |
||
44 | /** |
||
45 | * @var string required, root directory of all source files. |
||
46 | */ |
||
47 | public $sourcePath = '@yii'; |
||
48 | /** |
||
49 | * @var string required, root directory containing message translations. |
||
50 | */ |
||
51 | public $messagePath = '@yii/messages'; |
||
52 | /** |
||
53 | * @var array required, list of language codes that the extracted messages |
||
54 | * should be translated to. For example, ['zh-CN', 'de']. |
||
55 | */ |
||
56 | public $languages = []; |
||
57 | /** |
||
58 | * @var string the name of the function for translating messages. |
||
59 | * Defaults to 'Yii::t'. This is used as a mark to find the messages to be |
||
60 | * translated. You may use a string for single function name or an array for |
||
61 | * multiple function names. |
||
62 | */ |
||
63 | public $translator = 'Yii::t'; |
||
64 | /** |
||
65 | * @var boolean whether to sort messages by keys when merging new messages |
||
66 | * with the existing ones. Defaults to false, which means the new (untranslated) |
||
67 | * messages will be separated from the old (translated) ones. |
||
68 | */ |
||
69 | public $sort = false; |
||
70 | /** |
||
71 | * @var boolean whether the message file should be overwritten with the merged messages |
||
72 | */ |
||
73 | public $overwrite = true; |
||
74 | /** |
||
75 | * @var boolean whether to remove messages that no longer appear in the source code. |
||
76 | * Defaults to false, which means these messages will NOT be removed. |
||
77 | */ |
||
78 | public $removeUnused = false; |
||
79 | /** |
||
80 | * @var boolean whether to mark messages that no longer appear in the source code. |
||
81 | * Defaults to true, which means each of these messages will be enclosed with a pair of '@@' marks. |
||
82 | */ |
||
83 | public $markUnused = true; |
||
84 | /** |
||
85 | * @var array list of patterns that specify which files/directories should NOT be processed. |
||
86 | * If empty or not set, all files/directories will be processed. |
||
87 | * A path matches a pattern if it contains the pattern string at its end. For example, |
||
88 | * '/a/b' will match all files and directories ending with '/a/b'; |
||
89 | * the '*.svn' will match all files and directories whose name ends with '.svn'. |
||
90 | * and the '.svn' will match all files and directories named exactly '.svn'. |
||
91 | * Note, the '/' characters in a pattern matches both '/' and '\'. |
||
92 | * See helpers/FileHelper::findFiles() description for more details on pattern matching rules. |
||
93 | */ |
||
94 | public $except = [ |
||
95 | '.svn', |
||
96 | '.git', |
||
97 | '.gitignore', |
||
98 | '.gitkeep', |
||
99 | '.hgignore', |
||
100 | '.hgkeep', |
||
101 | '/messages', |
||
102 | '/BaseYii.php', // contains examples about Yii:t() |
||
103 | ]; |
||
104 | /** |
||
105 | * @var array list of patterns that specify which files (not directories) should be processed. |
||
106 | * If empty or not set, all files will be processed. |
||
107 | * Please refer to "except" for details about the patterns. |
||
108 | * If a file/directory matches both a pattern in "only" and "except", it will NOT be processed. |
||
109 | */ |
||
110 | public $only = ['*.php']; |
||
111 | /** |
||
112 | * @var string generated file format. Can be "php", "db" or "po". |
||
113 | */ |
||
114 | public $format = 'php'; |
||
115 | /** |
||
116 | * @var string connection component ID for "db" format. |
||
117 | */ |
||
118 | public $db = 'db'; |
||
119 | /** |
||
120 | * @var string custom name for source message table for "db" format. |
||
121 | */ |
||
122 | public $sourceMessageTable = '{{%source_message}}'; |
||
123 | /** |
||
124 | * @var string custom name for translation message table for "db" format. |
||
125 | */ |
||
126 | public $messageTable = '{{%message}}'; |
||
127 | /** |
||
128 | * @var string name of the file that will be used for translations for "po" format. |
||
129 | */ |
||
130 | public $catalog = 'messages'; |
||
131 | /** |
||
132 | * @var array message categories to ignore. For example, 'yii', 'app*', 'widgets/menu', etc. |
||
133 | * @see isCategoryIgnored |
||
134 | */ |
||
135 | public $ignoreCategories = []; |
||
136 | |||
137 | |||
138 | /** |
||
139 | * @inheritdoc |
||
140 | */ |
||
141 | 22 | public function options($actionID) |
|
142 | { |
||
143 | 22 | return array_merge(parent::options($actionID), [ |
|
144 | 22 | 'sourcePath', |
|
145 | 22 | 'messagePath', |
|
146 | 22 | 'languages', |
|
147 | 22 | 'translator', |
|
148 | 22 | 'sort', |
|
149 | 22 | 'overwrite', |
|
150 | 22 | 'removeUnused', |
|
151 | 22 | 'markUnused', |
|
152 | 22 | 'except', |
|
153 | 22 | 'only', |
|
154 | 22 | 'format', |
|
155 | 22 | 'db', |
|
156 | 22 | 'sourceMessageTable', |
|
157 | 22 | 'messageTable', |
|
158 | 22 | 'catalog', |
|
159 | 22 | 'ignoreCategories', |
|
160 | 22 | ]); |
|
161 | } |
||
162 | |||
163 | /** |
||
164 | * @inheritdoc |
||
165 | * @since 2.0.8 |
||
166 | */ |
||
167 | public function optionAliases() |
||
168 | { |
||
169 | return array_merge(parent::optionAliases(), [ |
||
170 | 'c' => 'catalog', |
||
171 | 'e' => 'except', |
||
172 | 'f' => 'format', |
||
173 | 'i' => 'ignoreCategories', |
||
174 | 'l' => 'languages', |
||
175 | 'u' => 'markUnused', |
||
176 | 'p' => 'messagePath', |
||
177 | 'o' => 'only', |
||
178 | 'w' => 'overwrite', |
||
179 | 'S' => 'sort', |
||
180 | 't' => 'translator', |
||
181 | 'm' => 'sourceMessageTable', |
||
182 | 's' => 'sourcePath', |
||
183 | 'r' => 'removeUnused', |
||
184 | ]); |
||
185 | } |
||
186 | |||
187 | /** |
||
188 | * Creates a configuration file for the "extract" command using command line options specified |
||
189 | * |
||
190 | * The generated configuration file contains parameters required |
||
191 | * for source code messages extraction. |
||
192 | * You may use this configuration file with the "extract" command. |
||
193 | * |
||
194 | * @param string $filePath output file name or alias. |
||
195 | * @return integer CLI exit code |
||
196 | * @throws Exception on failure. |
||
197 | */ |
||
198 | 2 | public function actionConfig($filePath) |
|
232 | |||
233 | /** |
||
234 | * Creates a configuration file template for the "extract" command. |
||
235 | * |
||
236 | * The created configuration file contains detailed instructions on |
||
237 | * how to customize it to fit for your needs. After customization, |
||
238 | * you may use this configuration file with the "extract" command. |
||
239 | * |
||
240 | * @param string $filePath output file name or alias. |
||
241 | * @return integer CLI exit code |
||
242 | * @throws Exception on failure. |
||
243 | */ |
||
244 | public function actionConfigTemplate($filePath) |
||
260 | |||
261 | /** |
||
262 | * Extracts messages to be translated from source code. |
||
263 | * |
||
264 | * This command will search through source code files and extract |
||
265 | * messages that need to be translated in different languages. |
||
266 | * |
||
267 | * @param string $configFile the path or alias of the configuration file. |
||
268 | * You may use the "yii message/config" command to generate |
||
269 | * this file and then customize it for your needs. |
||
270 | * @throws Exception on failure. |
||
271 | */ |
||
272 | 20 | public function actionExtract($configFile = null) |
|
352 | |||
353 | /** |
||
354 | * Saves messages to database |
||
355 | * |
||
356 | * @param array $messages |
||
357 | * @param \yii\db\Connection $db |
||
358 | * @param string $sourceMessageTable |
||
359 | * @param string $messageTable |
||
360 | * @param boolean $removeUnused |
||
361 | * @param array $languages |
||
362 | * @param boolean $markUnused |
||
363 | */ |
||
364 | protected function saveMessagesToDb($messages, $db, $sourceMessageTable, $messageTable, $removeUnused, $languages, $markUnused) |
||
439 | |||
440 | /** |
||
441 | * Extracts messages from a file |
||
442 | * |
||
443 | * @param string $fileName name of the file to extract messages from |
||
444 | * @param string $translator name of the function used to translate messages |
||
445 | * @param array $ignoreCategories message categories to ignore. |
||
446 | * This parameter is available since version 2.0.4. |
||
447 | * @return array |
||
448 | */ |
||
449 | 18 | protected function extractMessages($fileName, $translator, $ignoreCategories = []) |
|
467 | |||
468 | /** |
||
469 | * Extracts messages from a parsed PHP tokens list. |
||
470 | * @param array $tokens tokens to be processed. |
||
471 | * @param array $translatorTokens translator tokens. |
||
472 | * @param array $ignoreCategories message categories to ignore. |
||
473 | * @return array messages. |
||
474 | */ |
||
475 | 18 | private function extractMessagesFromTokens(array $tokens, array $translatorTokens, array $ignoreCategories) |
|
546 | |||
547 | /** |
||
548 | * The method checks, whether the $category is ignored according to $ignoreCategories array. |
||
549 | * Examples: |
||
550 | * |
||
551 | * - `myapp` - will be ignored only `myapp` category; |
||
552 | * - `myapp*` - will be ignored by all categories beginning with `myapp` (`myapp`, `myapplication`, `myapprove`, `myapp/widgets`, `myapp.widgets`, etc). |
||
553 | * |
||
554 | * @param string $category category that is checked |
||
555 | * @param array $ignoreCategories message categories to ignore. |
||
556 | * @return boolean |
||
557 | * @since 2.0.7 |
||
558 | */ |
||
559 | 18 | protected function isCategoryIgnored($category, array $ignoreCategories) |
|
578 | |||
579 | /** |
||
580 | * Finds out if two PHP tokens are equal |
||
581 | * |
||
582 | * @param array|string $a |
||
583 | * @param array|string $b |
||
584 | * @return boolean |
||
585 | * @since 2.0.1 |
||
586 | */ |
||
587 | 18 | protected function tokensEqual($a, $b) |
|
596 | |||
597 | /** |
||
598 | * Finds out a line of the first non-char PHP token found |
||
599 | * |
||
600 | * @param array $tokens |
||
601 | * @return integer|string |
||
602 | * @since 2.0.1 |
||
603 | */ |
||
604 | protected function getLine($tokens) |
||
613 | |||
614 | /** |
||
615 | * Writes messages into PHP files |
||
616 | * |
||
617 | * @param array $messages |
||
618 | * @param string $dirName name of the directory to write to |
||
619 | * @param boolean $overwrite if existing file should be overwritten without backup |
||
620 | * @param boolean $removeUnused if obsolete translations should be removed |
||
621 | * @param boolean $sort if translations should be sorted |
||
622 | * @param boolean $markUnused if obsolete translations should be marked |
||
623 | */ |
||
624 | 9 | protected function saveMessagesToPHP($messages, $dirName, $overwrite, $removeUnused, $sort, $markUnused) |
|
636 | |||
637 | /** |
||
638 | * Writes category messages into PHP file |
||
639 | * |
||
640 | * @param array $messages |
||
641 | * @param string $fileName name of the file to write to |
||
642 | * @param boolean $overwrite if existing file should be overwritten without backup |
||
643 | * @param boolean $removeUnused if obsolete translations should be removed |
||
644 | * @param boolean $sort if translations should be sorted |
||
645 | * @param string $category message category |
||
646 | * @param boolean $markUnused if obsolete translations should be marked |
||
647 | */ |
||
648 | 9 | protected function saveMessagesCategoryToPHP($messages, $fileName, $overwrite, $removeUnused, $sort, $category, $markUnused) |
|
734 | |||
735 | /** |
||
736 | * Writes messages into PO file |
||
737 | * |
||
738 | * @param array $messages |
||
739 | * @param string $dirName name of the directory to write to |
||
740 | * @param boolean $overwrite if existing file should be overwritten without backup |
||
741 | * @param boolean $removeUnused if obsolete translations should be removed |
||
742 | * @param boolean $sort if translations should be sorted |
||
743 | * @param string $catalog message catalog |
||
744 | * @param boolean $markUnused if obsolete translations should be marked |
||
745 | */ |
||
746 | 9 | protected function saveMessagesToPO($messages, $dirName, $overwrite, $removeUnused, $sort, $catalog, $markUnused) |
|
831 | |||
832 | /** |
||
833 | * Writes messages into POT file |
||
834 | * |
||
835 | * @param array $messages |
||
836 | * @param string $dirName name of the directory to write to |
||
837 | * @param string $catalog message catalog |
||
838 | * @since 2.0.6 |
||
839 | */ |
||
840 | protected function saveMessagesToPOT($messages, $dirName, $catalog) |
||
869 | } |
||
870 |
If an expression can have both
false
, andnull
as possible values. It is generally a good practice to always use strict comparison to clearly distinguish between those two values.