Total Complexity | 41 |
Total Lines | 315 |
Duplicated Lines | 0 % |
Changes | 6 | ||
Bugs | 0 | Features | 0 |
Complex classes like TcPdfOutput 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 TcPdfOutput, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
17 | final class TcPdfOutput extends AbstractOutput implements OutputInterface |
||
18 | { |
||
19 | // TCPDF constants |
||
20 | private const TCPDF_BORDER = 0; |
||
21 | private const TCPDF_ALIGN_BELOW = 2; |
||
22 | private const TCPDF_ALIGN_LEFT = 'L'; |
||
23 | private const TCPDF_ALIGN_RIGHT = 'R'; |
||
24 | private const TCPDF_ALIGN_CENTER = 'C'; |
||
25 | private const TCPDF_FONT = 'Helvetica'; |
||
26 | |||
27 | // Ratio constants |
||
28 | private const TCPDF_LEFT_CELL_HEIGHT_RATIO_COMMON = 1.2; |
||
29 | private const TCPDF_RIGHT_CELL_HEIGHT_RATIO_COMMON = 1.1; |
||
30 | private const TCPDF_LEFT_CELL_HEIGHT_RATIO_CURRENCY_AMOUNT = 1.5; |
||
31 | private const TCPDF_RIGHT_CELL_HEIGHT_RATIO_CURRENCY_AMOUNT = 1.5; |
||
32 | |||
33 | // Location constants |
||
34 | private const TCPDF_CURRENCY_AMOUNT_Y = 259; |
||
35 | private const TCPDF_LEFT_PART_X = 4; |
||
36 | private const TCPDF_RIGHT_PART_X = 66; |
||
37 | private const TCPDF_RIGHT_PAR_X_INFO = 117; |
||
38 | private const TCPDF_TITLE_Y = 195; |
||
39 | |||
40 | // Line spacing constants |
||
41 | private const TCPDF_9PT = 3.5; |
||
42 | private const TCPDF_11PT = 4.8; |
||
43 | |||
44 | /** @var string */ |
||
45 | protected $language; |
||
46 | |||
47 | /** @var QrBill */ |
||
48 | protected $qrBill; |
||
49 | |||
50 | /* @var TCPDF $tcPdf */ |
||
51 | private $tcPdf; |
||
52 | |||
53 | /* @var int $offsetX */ |
||
54 | private $offsetX; |
||
55 | |||
56 | /* @var int $offsetY */ |
||
57 | private $offsetY; |
||
58 | |||
59 | public function __construct( |
||
60 | QrBill $qrBill, |
||
61 | string $language, |
||
62 | TCPDF $tcPdf, |
||
63 | int $offsetX = 0, |
||
64 | int $offsetY = 0 |
||
65 | ) { |
||
66 | parent::__construct($qrBill, $language); |
||
67 | $this->tcPdf = $tcPdf; |
||
68 | $this->offsetX = $offsetX; |
||
69 | $this->offsetY = $offsetY; |
||
70 | $this->setQrCodeImageFormat(QrCode::FILE_FORMAT_SVG); |
||
71 | } |
||
72 | |||
73 | public function getPaymentPart(): void |
||
74 | { |
||
75 | $this->tcPdf->SetAutoPageBreak(false); |
||
76 | |||
77 | $this->addSeparatorContentIfNotPrintable(); |
||
78 | |||
79 | $this->addInformationContentReceipt(); |
||
80 | $this->addCurrencyContentReceipt(); |
||
81 | $this->addAmountContentReceipt(); |
||
82 | |||
83 | $this->addSwissQrCodeImage(); |
||
84 | $this->addInformationContent(); |
||
85 | $this->addCurrencyContent(); |
||
86 | $this->addAmountContent(); |
||
87 | $this->addFurtherInformationContent(); |
||
88 | } |
||
89 | |||
90 | private function addSwissQrCodeImage(): void |
||
91 | { |
||
92 | $qrCode = $this->getQrCode(); |
||
93 | |||
94 | switch ($this->getQrCodeImageFormat()) { |
||
95 | case QrCode::FILE_FORMAT_SVG: |
||
96 | $format = QrCode::FILE_FORMAT_SVG; |
||
97 | $method = "ImageSVG"; |
||
98 | break; |
||
99 | case QrCode::FILE_FORMAT_PNG: |
||
100 | default: |
||
101 | $format = QrCode::FILE_FORMAT_PNG; |
||
102 | $method = "Image"; |
||
103 | } |
||
104 | |||
105 | $yPosQrCode = 209.5 + $this->offsetY; |
||
106 | $xPosQrCode = self::TCPDF_RIGHT_PART_X + 1 + $this->offsetX; |
||
107 | |||
108 | $qrCode->setWriterByExtension($format); |
||
109 | $img = base64_decode(preg_replace('#^data:image/[^;]+;base64,#', '', $qrCode->writeDataUri())); |
||
110 | $this->tcPdf->$method("@".$img, $xPosQrCode, $yPosQrCode, 46, 46); |
||
111 | } |
||
112 | |||
113 | private function addInformationContentReceipt(): void |
||
136 | } |
||
137 | |||
138 | private function addInformationContent(): void |
||
154 | } |
||
155 | } |
||
156 | |||
157 | private function addCurrencyContentReceipt(): void |
||
158 | { |
||
159 | $x = self::TCPDF_LEFT_PART_X; |
||
160 | $this->tcPdf->setCellHeightRatio(self::TCPDF_LEFT_CELL_HEIGHT_RATIO_CURRENCY_AMOUNT); |
||
161 | $this->SetY(self::TCPDF_CURRENCY_AMOUNT_Y); |
||
162 | |||
163 | foreach ($this->getCurrencyElements() as $currencyElement) { |
||
164 | $this->SetX($x); |
||
165 | $this->setContentElement($currencyElement, true); |
||
166 | } |
||
167 | } |
||
168 | |||
169 | private function addAmountContentReceipt(): void |
||
170 | { |
||
171 | $x = 16; |
||
172 | $this->tcPdf->setCellHeightRatio(self::TCPDF_LEFT_CELL_HEIGHT_RATIO_CURRENCY_AMOUNT); |
||
173 | $this->SetY(self::TCPDF_CURRENCY_AMOUNT_Y); |
||
174 | |||
175 | foreach ($this->getAmountElementsReceipt() as $amountElement) { |
||
176 | $this->SetX($x); |
||
177 | $this->setContentElement($amountElement, true); |
||
178 | } |
||
179 | } |
||
180 | |||
181 | private function addCurrencyContent(): void |
||
190 | } |
||
191 | } |
||
192 | |||
193 | private function addAmountContent(): void |
||
194 | { |
||
195 | $x = 80; |
||
196 | $this->tcPdf->setCellHeightRatio(self::TCPDF_RIGHT_CELL_HEIGHT_RATIO_CURRENCY_AMOUNT); |
||
197 | $this->SetY(self::TCPDF_CURRENCY_AMOUNT_Y); |
||
198 | |||
199 | foreach ($this->getAmountElements() as $amountElement) { |
||
200 | $this->SetX($x); |
||
201 | $this->setContentElement($amountElement, false); |
||
202 | } |
||
203 | } |
||
204 | |||
205 | private function addFurtherInformationContent(): void |
||
206 | { |
||
207 | $x = self::TCPDF_RIGHT_PART_X; |
||
208 | $this->tcPdf->setCellHeightRatio(self::TCPDF_RIGHT_CELL_HEIGHT_RATIO_COMMON); |
||
209 | $this->SetY(286); |
||
210 | $this->tcPdf->SetFont(self::TCPDF_FONT, '', 7); |
||
211 | |||
212 | foreach ($this->getFurtherInformationElements() as $furtherInformationElement) { |
||
213 | $this->SetX($x); |
||
214 | $this->setContentElement($furtherInformationElement, true); |
||
215 | } |
||
216 | } |
||
217 | |||
218 | private function addSeparatorContentIfNotPrintable(): void |
||
228 | } |
||
229 | } |
||
230 | |||
231 | private function setContentElement(OutputElementInterface $element, bool $isReceiptPart): void |
||
232 | { |
||
233 | if ($element instanceof Title) { |
||
234 | $this->setTitleElement($element, $isReceiptPart); |
||
235 | } |
||
236 | |||
237 | if ($element instanceof Text) { |
||
238 | $this->setTextElement($element, $isReceiptPart); |
||
239 | } |
||
240 | |||
241 | if ($element instanceof Placeholder) { |
||
242 | $this->setPlaceholderElement($element, $isReceiptPart); |
||
243 | } |
||
244 | } |
||
245 | |||
246 | private function setTitleElement(Title $element, bool $isReceiptPart): void |
||
247 | { |
||
248 | $this->tcPdf->SetFont(self::TCPDF_FONT, 'B', $isReceiptPart ? 6 : 8); |
||
249 | $this->printCell( |
||
250 | Translation::get(str_replace("text.", "", $element->getTitle()), $this->language), |
||
251 | 0, |
||
252 | 0, |
||
253 | self::TCPDF_ALIGN_BELOW |
||
254 | ); |
||
255 | } |
||
256 | |||
257 | private function setTextElement(Text $element, bool $isReceiptPart): void |
||
258 | { |
||
259 | $this->tcPdf->SetFont(self::TCPDF_FONT, '', $isReceiptPart ? 8 : 10); |
||
260 | $this->printMultiCell( |
||
261 | str_replace("text.", "", $element->getText()), |
||
262 | $isReceiptPart ? 54 : 0, |
||
263 | 0, |
||
264 | self::TCPDF_ALIGN_BELOW, |
||
265 | self::TCPDF_ALIGN_LEFT |
||
266 | ); |
||
267 | $this->tcPdf->Ln($isReceiptPart ? self::TCPDF_9PT : self::TCPDF_11PT); |
||
268 | } |
||
269 | |||
270 | private function setPlaceholderElement(Placeholder $element): void |
||
271 | { |
||
272 | $type = $element->getType(); |
||
273 | |||
274 | switch ($type) { |
||
275 | case Placeholder::PLACEHOLDER_TYPE_AMOUNT['type']: |
||
276 | $y = $this->tcPdf->GetY() + 1; |
||
277 | $x = $this->tcPdf->GetX() - 2; |
||
278 | break; |
||
279 | case Placeholder::PLACEHOLDER_TYPE_AMOUNT_RECEIPT['type']: |
||
280 | $y = $this->tcPdf->GetY() - 2; |
||
281 | $x = $this->tcPdf->GetX() + 11; |
||
282 | break; |
||
283 | case Placeholder::PLACEHOLDER_TYPE_PAYABLE_BY['type']: |
||
284 | case Placeholder::PLACEHOLDER_TYPE_PAYABLE_BY_RECEIPT['type']: |
||
285 | default: |
||
286 | $y = $this->tcPdf->GetY() + 1; |
||
287 | $x = $this->tcPdf->GetX() + 1; |
||
288 | } |
||
289 | |||
290 | $this->tcPdf->ImageSVG( |
||
291 | $element->getFile(), |
||
292 | $x, |
||
293 | $y, |
||
294 | $element->getWidth(), |
||
295 | $element->getHeight() |
||
296 | ); |
||
297 | } |
||
298 | |||
299 | private function setX(int $x) : void |
||
300 | { |
||
301 | $this->tcPdf->SetX($x+$this->offsetX); |
||
302 | } |
||
303 | |||
304 | private function setY(int $y) : void |
||
307 | } |
||
308 | |||
309 | private function printCell( |
||
310 | string $text, |
||
311 | int $w = 0, |
||
312 | int $h = 0, |
||
313 | int $nextLineAlign = 0, |
||
314 | string $textAlign = self::TCPDF_ALIGN_LEFT |
||
315 | ) : void { |
||
316 | $this->tcPdf->Cell($w, $h, $text, self::TCPDF_BORDER, $nextLineAlign, $textAlign); |
||
317 | } |
||
318 | |||
319 | private function printMultiCell( |
||
320 | string $text, |
||
321 | int $w = 0, |
||
322 | int $h = 0, |
||
323 | int $nextLineAlign = 0, |
||
324 | string $textAlign = self::TCPDF_ALIGN_LEFT |
||
325 | ) : void { |
||
326 | $this->tcPdf->MultiCell($w, $h, $text, self::TCPDF_BORDER, $textAlign, false, $nextLineAlign); |
||
327 | } |
||
328 | |||
329 | private function printLine(int $x1, int $y1, int $x2, int $y2) : void |
||
332 | } |
||
333 | } |
||
334 |