Passed
Pull Request — master (#53)
by Manuel
03:19
created

TcPdfOutput::addInformationContentReceipt()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 23
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 14
c 1
b 0
f 0
nc 2
nop 0
dl 0
loc 23
rs 9.7998
1
<?php
2
3
namespace Sprain\SwissQrBill\PaymentPart\Output\TcPdfOutput;
4
5
use Sprain\SwissQrBill\PaymentPart\Output\AbstractOutput;
6
use Sprain\SwissQrBill\PaymentPart\Output\Element\OutputElementInterface;
7
use Sprain\SwissQrBill\PaymentPart\Output\Element\Placeholder;
8
use Sprain\SwissQrBill\PaymentPart\Output\Element\Text;
9
use Sprain\SwissQrBill\PaymentPart\Output\Element\Title;
10
use Sprain\SwissQrBill\PaymentPart\Output\OutputInterface;
11
use Sprain\SwissQrBill\QrCode\Exception\UnsupportedFileExtensionException;
12
use Sprain\SwissQrBill\QrCode\QrCode;
13
use Sprain\SwissQrBill\PaymentPart\Translation\Translation;
14
use Sprain\SwissQrBill\QrBill;
15
use TCPDF;
16
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->addPrintableContent();
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
114
    {
115
        $x = self::TCPDF_LEFT_PART_X;
116
        $this->tcPdf->setCellHeightRatio(self::TCPDF_LEFT_CELL_HEIGHT_RATIO_COMMON);
117
118
        // Title
119
        $this->tcPdf->SetFont(self::TCPDF_FONT, 'B', 11);
120
        $this->SetY(self::TCPDF_TITLE_Y);
121
        $this->SetX($x);
122
        $this->printCell(Translation::get('receipt', $this->language), 0, 7);
123
124
        // Elements
125
        $this->SetY(204);
126
        foreach ($this->getInformationElementsOfReceipt() as $informationElement) {
127
            $this->SetX($x);
128
            $this->setContentElement($informationElement, true);
129
        }
130
131
        // Acceptance section
132
        $this->tcPdf->SetFont(self::TCPDF_FONT, 'B', 6);
133
        $this->SetY(273);
134
        $this->SetX($x);
135
        $this->printCell(Translation::get('acceptancePoint', $this->language), 54, 0, self::TCPDF_ALIGN_BELOW, self::TCPDF_ALIGN_RIGHT);
136
    }
137
138
    private function addInformationContent(): void
139
    {
140
        $x = self::TCPDF_RIGHT_PAR_X_INFO;
141
        $this->tcPdf->setCellHeightRatio(self::TCPDF_RIGHT_CELL_HEIGHT_RATIO_COMMON);
142
143
        // Title
144
        $this->tcPdf->SetFont(self::TCPDF_FONT, 'B', 11);
145
        $this->SetY(self::TCPDF_TITLE_Y);
146
        $this->SetX(self::TCPDF_RIGHT_PART_X);
147
        $this->printCell(Translation::get('paymentPart', $this->language), 48, 7);
148
149
        // Elements
150
        $this->SetY(197);
151
        foreach ($this->getInformationElements() as $informationElement) {
152
            $this->SetX($x);
153
            $this->setContentElement($informationElement, false);
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
        foreach ($this->getCurrencyElements() as $currencyElement) {
163
            $this->SetX($x);
164
            $this->setContentElement($currencyElement, true);
165
        }
166
    }
167
168
    private function addAmountContentReceipt(): void
169
    {
170
        $x = 16;
171
        $this->tcPdf->setCellHeightRatio(self::TCPDF_LEFT_CELL_HEIGHT_RATIO_CURRENCY_AMOUNT);
172
        $this->SetY(self::TCPDF_CURRENCY_AMOUNT_Y);
173
        foreach ($this->getAmountElementsReceipt() as $amountElement) {
174
            $this->SetX($x);
175
            $this->setContentElement($amountElement, true);
176
        }
177
    }
178
179
    private function addCurrencyContent(): void
180
    {
181
        $x = self::TCPDF_RIGHT_PART_X;
182
        $this->tcPdf->setCellHeightRatio(self::TCPDF_RIGHT_CELL_HEIGHT_RATIO_CURRENCY_AMOUNT);
183
        $this->SetY(self::TCPDF_CURRENCY_AMOUNT_Y);
184
        foreach ($this->getCurrencyElements() as $currencyElement) {
185
            $this->SetX($x);
186
            $this->setContentElement($currencyElement, false);
187
        }
188
    }
189
190
    private function addAmountContent(): void
191
    {
192
        $x = 80;
193
        $this->tcPdf->setCellHeightRatio(self::TCPDF_RIGHT_CELL_HEIGHT_RATIO_CURRENCY_AMOUNT);
194
        $this->SetY(self::TCPDF_CURRENCY_AMOUNT_Y);
195
        foreach ($this->getAmountElements() as $amountElement) {
196
            $this->SetX($x);
197
            $this->setContentElement($amountElement, false);
198
        }
199
    }
200
201
    private function addFurtherInformationContent(): void
202
    {
203
        $x = self::TCPDF_RIGHT_PART_X;
204
        $this->tcPdf->setCellHeightRatio(self::TCPDF_RIGHT_CELL_HEIGHT_RATIO_COMMON);
205
        $this->SetY(286);
206
        $this->tcPdf->SetFont(self::TCPDF_FONT, '', 7);
207
        foreach ($this->getFurtherInformationElements() as $furtherInformationElement) {
208
            $this->SetX($x);
209
            $this->setContentElement($furtherInformationElement, true);
210
        }
211
    }
212
213
    private function addPrintableContent(): void
214
    {
215
        if (!$this->isPrintable()) {
216
            $this->tcPdf->SetLineStyle(array('width' => 0.1, 'dash' => 4, 'color' => array(0, 0, 0)));
217
            $this->printLine(2, 193, 208, 193);
218
            $this->printLine(62, 193, 62, 296);
219
            $this->tcPdf->SetFont(self::TCPDF_FONT, '', 7);
220
            $this->SetY(188);
221
            $this->SetX(5);
222
            $this->printCell(Translation::get('separate', $this->language), 200, 0, 0, self::TCPDF_ALIGN_CENTER);
223
        }
224
    }
225
226
    private function setContentElement(OutputElementInterface $element, bool $isReceiptPart): void
227
    {
228
        if ($element instanceof Title) {
229
            $this->tcPdf->SetFont(self::TCPDF_FONT, 'B', $isReceiptPart ? 6 : 8);
230
            $this->printCell(Translation::get(str_replace("text.", "", $element->getTitle()), $this->language), 0, 0, self::TCPDF_ALIGN_BELOW);
231
        }
232
233
        if ($element instanceof Text) {
234
            $this->tcPdf->SetFont(self::TCPDF_FONT, '', $isReceiptPart ? 8 : 10);
235
            $this->printMultiCell(
236
                str_replace("text.", "", $element->getText()),
237
                $isReceiptPart ? 54 : 0,
238
                0,
239
                self::TCPDF_ALIGN_BELOW,
240
                self::TCPDF_ALIGN_LEFT
241
            );
242
            $this->tcPdf->Ln($isReceiptPart ? self::TCPDF_9PT : self::TCPDF_11PT);
243
        }
244
245
        if ($element instanceof Placeholder) {
246
            $type = $element->getType();
247
248
            if ($type === Placeholder::PLACEHOLDER_TYPE_AMOUNT['type']) {
249
                $y = $this->tcPdf->GetY() + 1;
250
                $x = $this->tcPdf->GetX() - 2;
251
            } elseif ($type === Placeholder::PLACEHOLDER_TYPE_AMOUNT_RECEIPT['type']) {
252
                $y = $this->tcPdf->GetY() - 2;
253
                $x = $this->tcPdf->GetX() + 11;
254
            } else {
255
                $y = $this->tcPdf->GetY() + 1;
256
                $x = $this->tcPdf->GetX() + 1;
257
            }
258
259
            $this->tcPdf->ImageSVG(
260
                $element->getFile(),
261
                $x,
262
                $y,
263
                $element->getWidth(),
264
                $element->getHeight()
265
            );
266
        }
267
    }
268
269
    private function setX(int $x) : void
270
    {
271
        $this->tcPdf->SetX($x+$this->offsetX);
272
    }
273
274
    private function setY(int $y) : void
275
    {
276
        $this->tcPdf->SetY($y+$this->offsetY);
277
    }
278
279
    private function printCell(
280
        string $text,
281
        int $w = 0,
282
        int $h = 0,
283
        int $nextLineAlign = 0,
284
        string $textAlign = self::TCPDF_ALIGN_LEFT
285
    ) : void {
286
        $this->tcPdf->Cell($w, $h, $text, self::TCPDF_BORDER, $nextLineAlign, $textAlign);
287
    }
288
289
    private function printMultiCell(
290
        string $text,
291
        int $w = 0,
292
        int $h = 0,
293
        int $nextLineAlign = 0,
294
        string $textAlign = self::TCPDF_ALIGN_LEFT
295
    ) : void {
296
        $this->tcPdf->MultiCell($w, $h, $text, self::TCPDF_BORDER, $textAlign, false, $nextLineAlign);
297
    }
298
299
    private function printLine(int $x1, int $y1, int $x2, int $y2) : void
300
    {
301
        $this->tcPdf->Line($x1+$this->offsetX, $y1+$this->offsetY, $x2+$this->offsetX, $y2+$this->offsetY);
302
    }
303
}
304