Total Complexity | 45 |
Total Lines | 279 |
Duplicated Lines | 0 % |
Changes | 7 | ||
Bugs | 0 | Features | 1 |
Complex classes like PoCompiler 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.
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 PoCompiler, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
9 | class PoCompiler |
||
10 | { |
||
11 | /** @var string */ |
||
12 | const TOKEN_OBSOLETE = '#~ '; |
||
13 | |||
14 | /** @var int */ |
||
15 | protected $wrappingColumn; |
||
16 | |||
17 | /** @var string */ |
||
18 | protected $lineEnding; |
||
19 | |||
20 | /** @var string */ |
||
21 | protected $tokenCarriageReturn; |
||
22 | |||
23 | /** |
||
24 | * PoCompiler constructor. |
||
25 | * |
||
26 | * @param int $wrappingColumn |
||
27 | * @param string $lineEnding |
||
28 | */ |
||
29 | public function __construct($wrappingColumn = 80, $lineEnding = "\n") |
||
30 | { |
||
31 | $this->wrappingColumn = $wrappingColumn; |
||
32 | $this->lineEnding = $lineEnding; |
||
33 | $this->tokenCarriageReturn = chr(13); |
||
34 | } |
||
35 | |||
36 | /** |
||
37 | * Compiles entries into a string |
||
38 | * |
||
39 | * @param Catalog $catalog |
||
40 | * |
||
41 | * @return string |
||
42 | * @throws \Exception |
||
43 | * @todo Write obsolete messages at the end of the file. |
||
44 | */ |
||
45 | public function compile(Catalog $catalog) |
||
46 | { |
||
47 | $output = ''; |
||
48 | |||
49 | if (\count($catalog->getHeaders()) > 0) { |
||
50 | $output .= 'msgid ""'.$this->eol(); |
||
51 | $output .= 'msgstr ""'.$this->eol(); |
||
52 | foreach ($catalog->getHeaders() as $header) { |
||
53 | $output .= '"'.$header.'\n"'.$this->eol(); |
||
54 | } |
||
55 | $output .= $this->eol(); |
||
56 | } |
||
57 | |||
58 | |||
59 | $entriesCount = \count($catalog->getEntries()); |
||
60 | $counter = 0; |
||
61 | foreach ($catalog->getEntries() as $entry) { |
||
62 | if ($entry->isObsolete() === false) { |
||
63 | $output .= $this->buildPreviousEntry($entry); |
||
64 | $output .= $this->buildTranslatorComment($entry); |
||
65 | $output .= $this->buildDeveloperComment($entry); |
||
66 | $output .= $this->buildReference($entry); |
||
67 | } |
||
68 | |||
69 | $output .= $this->buildFlags($entry); |
||
70 | |||
71 | // if (isset($entry['@'])) { |
||
|
|||
72 | // $output .= "#@ ".$entry['@'].$this->eol(); |
||
73 | // } |
||
74 | |||
75 | $output .= $this->buildContext($entry); |
||
76 | $output .= $this->buildMsgId($entry); |
||
77 | $output .= $this->buildMsgIdPlural($entry); |
||
78 | $output .= $this->buildMsgStr($entry, $catalog->getHeader()); |
||
79 | |||
80 | |||
81 | $counter++; |
||
82 | // Avoid inserting an extra newline at end of file |
||
83 | if ($counter < $entriesCount) { |
||
84 | $output .= $this->eol(); |
||
85 | } |
||
86 | } |
||
87 | |||
88 | return $output; |
||
89 | } |
||
90 | |||
91 | /** |
||
92 | * @return string |
||
93 | */ |
||
94 | protected function eol() |
||
95 | { |
||
96 | return $this->lineEnding; |
||
97 | } |
||
98 | |||
99 | /** |
||
100 | * @param $entry |
||
101 | * |
||
102 | * @return string |
||
103 | */ |
||
104 | protected function buildPreviousEntry(Entry $entry) |
||
105 | { |
||
106 | $previous = $entry->getPreviousEntry(); |
||
107 | if ($previous === null) { |
||
108 | return ''; |
||
109 | } |
||
110 | |||
111 | return '#| msgid '.$this->cleanExport($previous->getMsgId()).$this->eol(); |
||
112 | } |
||
113 | |||
114 | /** |
||
115 | * @param $entry |
||
116 | * |
||
117 | * @return string |
||
118 | */ |
||
119 | protected function buildTranslatorComment(Entry $entry) |
||
120 | { |
||
121 | if ($entry->getTranslatorComments() === null) { |
||
122 | return ''; |
||
123 | } |
||
124 | |||
125 | $output = ''; |
||
126 | foreach ($entry->getTranslatorComments() as $comment) { |
||
127 | $output .= '# '.$comment.$this->eol(); |
||
128 | } |
||
129 | |||
130 | return $output; |
||
131 | } |
||
132 | |||
133 | protected function buildDeveloperComment(Entry $entry) |
||
134 | { |
||
135 | if ($entry->getDeveloperComments() === null) { |
||
136 | return ''; |
||
137 | } |
||
138 | |||
139 | $output = ''; |
||
140 | foreach ($entry->getDeveloperComments() as $comment) { |
||
141 | $output .= '#. '.$comment.$this->eol(); |
||
142 | } |
||
143 | |||
144 | return $output; |
||
145 | } |
||
146 | |||
147 | protected function buildReference(Entry $entry) |
||
148 | { |
||
149 | $reference = $entry->getReference(); |
||
150 | if ($reference === null || \count($reference) === 0) { |
||
151 | return ''; |
||
152 | } |
||
153 | |||
154 | $output = ''; |
||
155 | foreach ($reference as $ref) { |
||
156 | $output .= '#: '.$ref.$this->eol(); |
||
157 | } |
||
158 | |||
159 | return $output; |
||
160 | } |
||
161 | |||
162 | protected function buildFlags(Entry $entry) |
||
163 | { |
||
164 | $flags = $entry->getFlags(); |
||
165 | if ($flags === null || \count($flags) === 0) { |
||
166 | return ''; |
||
167 | } |
||
168 | |||
169 | return '#, '.\implode(', ', $flags).$this->eol(); |
||
170 | } |
||
171 | |||
172 | protected function buildContext(Entry $entry) |
||
173 | { |
||
174 | if ($entry->getMsgCtxt() === null) { |
||
175 | return ''; |
||
176 | } |
||
177 | |||
178 | return |
||
179 | ($entry->isObsolete() ? '#~ ' : ''). |
||
180 | 'msgctxt '.$this->cleanExport($entry->getMsgCtxt()).$this->eol(); |
||
181 | } |
||
182 | |||
183 | protected function buildMsgId(Entry $entry) |
||
184 | { |
||
185 | if ($entry->getMsgId() === null) { |
||
186 | return ''; |
||
187 | } |
||
188 | |||
189 | return $this->buildProperty('msgid', $entry->getMsgId(), $entry->isObsolete()); |
||
190 | } |
||
191 | |||
192 | protected function buildMsgStr(Entry $entry, Header $headers) |
||
216 | } |
||
217 | |||
218 | /** |
||
219 | * @param Entry $entry |
||
220 | * |
||
221 | * @return string |
||
222 | */ |
||
223 | protected function buildMsgIdPlural(Entry $entry) |
||
234 | } |
||
235 | |||
236 | protected function buildProperty($property, $value, $obsolete = false) |
||
237 | { |
||
238 | $tokens = $this->wrapString($value); |
||
239 | |||
240 | $output = ''; |
||
241 | if (\count($tokens) > 1) { |
||
242 | \array_unshift($tokens, ''); |
||
243 | } |
||
244 | |||
245 | foreach ($tokens as $i => $token) { |
||
246 | $output .= $obsolete ? self::TOKEN_OBSOLETE : ''; |
||
247 | $output .= ($i === 0) ? $property.' ' : ''; |
||
248 | $output .= $this->cleanExport($token).$this->eol(); |
||
249 | } |
||
250 | |||
251 | return $output; |
||
252 | } |
||
253 | |||
254 | /** |
||
255 | * Prepares a string to be outputed into a file. |
||
256 | * |
||
257 | * @param string $string The string to be converted. |
||
258 | * |
||
259 | * @return string |
||
260 | */ |
||
261 | protected function cleanExport($string) |
||
268 | } |
||
269 | |||
270 | /** |
||
271 | * @param string $value |
||
272 | * @return array |
||
273 | */ |
||
274 | private function wrapString($value) |
||
288 | } |
||
289 | } |
||
290 |
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.