ReportPdfTextbox::render()   F
last analyzed

Complexity

Conditions 65
Paths 0

Size

Total Lines 299
Code Lines 182

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 65
eloc 182
nc 0
nop 1
dl 0
loc 299
rs 3.3333
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * webtrees: online genealogy
4
 * Copyright (C) 2019 webtrees development team
5
 * This program is free software: you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation, either version 3 of the License, or
8
 * (at your option) any later version.
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
 * GNU General Public License for more details.
13
 * You should have received a copy of the GNU General Public License
14
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15
 */
16
namespace Fisharebest\Webtrees\Report;
17
18
/**
19
 * Class ReportPdfTextbox
20
 */
21
class ReportPdfTextbox extends ReportBaseTextbox
22
{
23
    /**
24
     * PDF Text Box renderer
25
     *
26
     * @param ReportTcpdf $renderer
27
     *
28
     * @return bool|int
29
     */
30
    public function render($renderer)
31
    {
32
33
        $newelements      = array();
34
        $lastelement      = "";
35
        $footnote_element = array();
36
        // Element counter
37
        $cE = count($this->elements);
38
        //-- collapse duplicate elements
39
        for ($i = 0; $i < $cE; $i++) {
40
            $element = $this->elements[$i];
41
            if (is_object($element)) {
42
                if ($element instanceof ReportBaseText) {
43
                    if (!empty($footnote_element)) {
44
                        ksort($footnote_element);
45
                        foreach ($footnote_element as $links) {
46
                            $newelements[] = $links;
47
                        }
48
                        $footnote_element = array();
49
                    }
50
                    if (empty($lastelement)) {
51
                        $lastelement = $element;
52
                    } else {
53
                        // Checking if the Text has the same style
54
                        if ($element->getStyleName() == $lastelement->getStyleName()) {
55
                            $lastelement->addText(str_replace("\n", "<br>", $element->getValue()));
56
                        } elseif (!empty($lastelement)) {
57
                            $newelements[] = $lastelement;
58
                            $lastelement   = $element;
59
                        }
60
                    }
61
                } // Collect the Footnote links
62
                elseif ($element instanceof ReportBaseFootnote) {
63
                    // Check if the Footnote has been set with it’s link number
64
                    $renderer->checkFootnote($element);
65
                    // Save first the last element if any
66
                    if (!empty($lastelement)) {
67
                        $newelements[] = $lastelement;
68
                        $lastelement   = array();
69
                    }
70
                    // Save the Footnote with it’s link number as key for sorting later
71
                    $footnote_element[$element->num] = $element;
72
                } //-- do not keep empty footnotes
73
                elseif (!($element instanceof ReportBaseFootnote) || trim($element->getValue()) != "") {
74
                    if (!empty($footnote_element)) {
75
                        ksort($footnote_element);
76
                        foreach ($footnote_element as $links) {
77
                            $newelements[] = $links;
78
                        }
79
                        $footnote_element = array();
80
                    }
81
                    if (!empty($lastelement)) {
82
                        $newelements[] = $lastelement;
83
                        $lastelement   = array();
84
                    }
85
                    $newelements[] = $element;
86
                }
87
            } else {
88
                if (!empty($lastelement)) {
89
                    $newelements[] = $lastelement;
90
                    $lastelement   = array();
91
                }
92
                if (!empty($footnote_element)) {
93
                    ksort($footnote_element);
94
                    foreach ($footnote_element as $links) {
95
                        $newelements[] = $links;
96
                    }
97
                    $footnote_element = array();
98
                }
99
                $newelements[] = $element;
100
            }
101
        }
102
        if (!empty($lastelement)) {
103
            $newelements[] = $lastelement;
104
        }
105
        if (!empty($footnote_element)) {
106
            ksort($footnote_element);
107
            foreach ($footnote_element as $links) {
108
                $newelements[] = $links;
109
            }
110
        }
111
        $this->elements = $newelements;
112
        unset($footnote_element, $lastelement, $links, $newelements);
113
114
        // Used with line breaks and cell height calculation within this box
115
        $renderer->largestFontHeight = 0;
116
117
        // If current position (left)
118
        if ($this->left == ".") {
119
            $cX = $renderer->GetX();
120
        } else {
121
            // For static position add margin (returns and updates X)
122
            $cX = $renderer->addMarginX($this->left);
123
        }
124
125
        // If current position (top)
126
        if ($this->top == ".") {
127
            $cY = $renderer->GetY();
128
        } else {
129
            $cY = $this->top;
130
            $renderer->SetY($cY);
131
        }
132
133
        // Check the width if set to page wide OR set by xml to larger then page width (margin)
134
        if ($this->width == 0 || $this->width > $renderer->getRemainingWidthPDF()) {
135
            $cW = $renderer->getRemainingWidthPDF();
136
        } else {
137
            $cW = $this->width;
138
        }
139
140
        // Save the original margins
141
        $cM = $renderer->getMargins();
142
        // Use cell padding to wrap the width
143
        // Temp Width with cell padding
144
        if (is_array($cM['cell'])) {
145
            $cWT = $cW - ($cM['padding_left'] + $cM['padding_right']);
146
        } else {
147
            $cWT = $cW - ($cM['cell'] * 2);
148
        }
149
        // Element height (exept text)
150
        $eH = 0;
151
        $w  = 0;
152
        // Temp Height
153
        $cHT = 0;
154
        //-- $lw is an array
155
        // 0 => last line width
156
        // 1 => 1 if text was wrapped, 0 if text did not wrap
157
        // 2 => number of LF
158
        $lw = array();
159
        // Element counter
160
        $cE = count($this->elements);
161
        //-- calculate the text box height + width
162
        for ($i = 0; $i < $cE; $i++) {
163
            if (is_object($this->elements[$i])) {
164
                $ew = $this->elements[$i]->setWrapWidth($cWT - $w, $cWT);
165
                if ($ew == $cWT) {
166
                    $w = 0;
167
                }
168
                $lw = $this->elements[$i]->getWidth($renderer);
169
                // Text is already gets the # LF
170
                $cHT += $lw[2];
171
                if ($lw[1] == 1) {
172
                    $w = $lw[0];
173
                } elseif ($lw[1] == 2) {
174
                    $w = 0;
175
                } else {
176
                    $w += $lw[0];
177
                }
178
                if ($w > $cWT) {
179
                    $w = $lw[0];
180
                }
181
                // Footnote is at the bottom of the page. No need to calculate it’s height or wrap the text!
182
                // We are changing the margins anyway!
183
                // For anything else but text (images), get the height
184
                $eH += $this->elements[$i]->getHeight($renderer);
185
            }
186
        }
187
188
        // Add up what’s the final height
189
        $cH = $this->height;
190
        // If any element exist
191
        if ($cE > 0) {
192
            // Check if this is text or some other element, like images
193
            if ($eH == 0) {
194
                // This is text elements. Number of LF but at least one line
195
                $cHT = ($cHT + 1) * $renderer->getCellHeightRatio();
196
                // Calculate the cell hight with the largest font size used within this Box
197
                $cHT = $cHT * $renderer->largestFontHeight;
198
                // Add cell padding
199
                if ($this->padding) {
200
                    if (is_array($cM['cell'])) {
201
                        $cHT += ($cM['padding_bottom'] + $cM['padding_top']);
202
                    } else {
203
                        $cHT += ($cM['cell'] * 2);
204
                    }
205
                }
206
                if ($cH < $cHT) {
207
                    $cH = $cHT;
208
                }
209
            } // This is any other element
210
            elseif ($cH < $eH) {
211
                $cH = $eH;
212
            }
213
        }
214
        // Finaly, check the last cells height
215
        if ($cH < $renderer->lastCellHeight) {
216
            $cH = $renderer->lastCellHeight;
217
        }
218
        // Add a new page if needed
219
        if ($this->pagecheck) {
220
            // Reset last cell height or Header/Footer will inherit it, in case of pagebreak
221
            $renderer->lastCellHeight = 0;
222
            if ($renderer->checkPageBreakPDF($cH)) {
223
                $cY = $renderer->GetY();
224
            }
225
        }
226
227
        // Setup the border and background color
228
        $cS = ""; // Class Style
229
        if ($this->border) {
230
            $cS = "D";
231
        } // D or empty string: Draw (default)
232
        $match = array();
233
        // Fill the background
234
        if ($this->fill) {
235
            if (!empty($this->bgcolor)) {
236
                if (preg_match("/#?(..)(..)(..)/", $this->bgcolor, $match)) {
237
                    $cS .= "F"; // F: Fill the background
238
                    $r = hexdec($match[1]);
239
                    $g = hexdec($match[2]);
240
                    $b = hexdec($match[3]);
241
                    $renderer->SetFillColor($r, $g, $b);
242
                }
243
            }
244
        }
245
        // Clean up a bit
246
        unset($lw, $w, $match, $cE, $eH);
247
        // Draw the border
248
        if (!empty($cS)) {
249
            if (!$renderer->getRTL()) {
250
                $cXM = $cX;
251
            } else {
252
                $cXM = ($renderer->getPageWidth()) - $cX - $cW;
253
            }
254
            $renderer->Rect($cXM, $cY, $cW, $cH, $cS);
255
        }
256
        // Add cell padding if set and if any text (element) exist
257
        if ($this->padding) {
258
            if ($cHT > 0) {
259
                if (is_array($cM['cell'])) {
260
                    $renderer->SetY($cY + $cM['padding_top']);
261
                } else {
262
                    $renderer->SetY($cY + $cM['cell']);
263
                }
264
            }
265
        }
266
        // Change the margins X, Width
267
        if (!$renderer->getRTL()) {
268
            if ($this->padding) {
269
                if (is_array($cM['cell'])) {
270
                    $renderer->SetLeftMargin($cX + $cM['padding_left']);
271
                } else {
272
                    $renderer->SetLeftMargin($cX + $cM['cell']);
273
                }
274
                $renderer->SetRightMargin($renderer->getRemainingWidthPDF() - $cW + $cM['right']);
275
            } else {
276
                $renderer->SetLeftMargin($cX);
277
                $renderer->SetRightMargin($renderer->getRemainingWidthPDF() - $cW + $cM['right']);
278
            }
279
        } else {
280
            if ($this->padding) {
281
                if (is_array($cM['cell'])) {
282
                    $renderer->SetRightMargin($cX + $cM['padding_right']);
283
                } else {
284
                    $renderer->SetRightMargin($cX + $cM['cell']);
285
                }
286
                $renderer->SetLeftMargin($renderer->getRemainingWidthPDF() - $cW + $cM['left']);
287
            } else {
288
                $renderer->SetRightMargin($cX);
289
                $renderer->SetLeftMargin($renderer->getRemainingWidthPDF() - $cW + $cM['left']);
290
            }
291
        }
292
        // Save the current page number
293
        $cPN = $renderer->getPage();
294
295
        // Render the elements (write text, print picture...)
296
        foreach ($this->elements as $element) {
297
            if (is_object($element)) {
298
                $element->render($renderer);
299
            } elseif (is_string($element) && $element == 'footnotetexts') {
300
                $renderer->footnotes();
301
            } elseif (is_string($element) && $element == 'addpage') {
302
                $renderer->newPage();
303
            }
304
        }
305
        // Restore the margins
306
        $renderer->SetLeftMargin($cM['left']);
307
        $renderer->SetRightMargin($cM['right']);
308
309
        // This will be mostly used to trick the multiple images last height
310
        if ($this->reseth) {
311
            $cH = 0;
312
            // This can only happen with multiple images and with pagebreak
313
            if ($cPN != $renderer->getPage()) {
314
                $renderer->setPage($cPN);
315
            }
316
        }
317
        // New line and some clean up
318
        if (!$this->newline) {
319
            $renderer->SetXY(($cX + $cW), $cY);
320
            $renderer->lastCellHeight = $cH;
321
        } else {
322
            // addMarginX() also updates X
323
            $renderer->addMarginX(0);
324
            $renderer->SetY($cY + $cH);
325
            $renderer->lastCellHeight = 0;
326
        }
327
328
        return true;
329
    }
330
}
331