Completed
Push — develop ( 9087a8...c9b4ef )
by Greg
16:31 queued 05:44
created

ReportPdfTextbox::render()   F

Complexity

Conditions 65
Paths 0

Size

Total Lines 297
Code Lines 182

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 65
eloc 182
nc 0
nop 1
dl 0
loc 297
rs 2
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) 2018 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
	 * PDF Text Box renderer
24
	 *
25
	 * @param ReportTcpdf $renderer
26
	 *
27
	 * @return bool|int
28
	 */
29
	public function render($renderer) {
30
		$newelements      = [];
31
		$lastelement      = '';
32
		$footnote_element = [];
33
		// Element counter
34
		$cE = count($this->elements);
35
		//-- collapse duplicate elements
36
		for ($i = 0; $i < $cE; $i++) {
37
			$element = $this->elements[$i];
38
			if (is_object($element)) {
39
				if ($element instanceof ReportBaseText) {
40
					if (!empty($footnote_element)) {
41
						ksort($footnote_element);
42
						foreach ($footnote_element as $links) {
43
							$newelements[] = $links;
44
						}
45
						$footnote_element = [];
46
					}
47
					if (empty($lastelement)) {
48
						$lastelement = $element;
49
					} else {
50
						// Checking if the Text has the same style
51
						if ($element->getStyleName() == $lastelement->getStyleName()) {
52
							$lastelement->addText(str_replace("\n", '<br>', $element->getValue()));
53
						} elseif (!empty($lastelement)) {
54
							$newelements[] = $lastelement;
55
							$lastelement   = $element;
56
						}
57
					}
58
				} // Collect the Footnote links
59
				elseif ($element instanceof ReportBaseFootnote) {
60
					// Check if the Footnote has been set with it’s link number
61
					$renderer->checkFootnote($element);
62
					// Save first the last element if any
63
					if (!empty($lastelement)) {
64
						$newelements[] = $lastelement;
65
						$lastelement   = [];
66
					}
67
					// Save the Footnote with it’s link number as key for sorting later
68
					$footnote_element[$element->num] = $element;
69
				} //-- do not keep empty footnotes
70
				elseif (!($element instanceof ReportBaseFootnote) || trim($element->getValue()) != '') {
71
					if (!empty($footnote_element)) {
72
						ksort($footnote_element);
73
						foreach ($footnote_element as $links) {
74
							$newelements[] = $links;
75
						}
76
						$footnote_element = [];
77
					}
78
					if (!empty($lastelement)) {
79
						$newelements[] = $lastelement;
80
						$lastelement   = [];
81
					}
82
					$newelements[] = $element;
83
				}
84
			} else {
85
				if (!empty($lastelement)) {
86
					$newelements[] = $lastelement;
87
					$lastelement   = [];
88
				}
89
				if (!empty($footnote_element)) {
90
					ksort($footnote_element);
91
					foreach ($footnote_element as $links) {
92
						$newelements[] = $links;
93
					}
94
					$footnote_element = [];
95
				}
96
				$newelements[] = $element;
97
			}
98
		}
99
		if (!empty($lastelement)) {
100
			$newelements[] = $lastelement;
101
		}
102
		if (!empty($footnote_element)) {
103
			ksort($footnote_element);
104
			foreach ($footnote_element as $links) {
105
				$newelements[] = $links;
106
			}
107
		}
108
		$this->elements = $newelements;
109
		unset($footnote_element, $lastelement, $links, $newelements);
110
111
		// Used with line breaks and cell height calculation within this box
112
		$renderer->largestFontHeight = 0;
113
114
		// If current position (left)
115
		if ($this->left == '.') {
116
			$cX = $renderer->GetX();
117
		} else {
118
			// For static position add margin (returns and updates X)
119
			$cX = $renderer->addMarginX($this->left);
120
		}
121
122
		// If current position (top)
123
		if ($this->top == '.') {
124
			$cY = $renderer->GetY();
125
		} else {
126
			$cY = $this->top;
127
			$renderer->SetY($cY);
128
		}
129
130
		// Check the width if set to page wide OR set by xml to larger then page width (margin)
131
		if ($this->width == 0 || $this->width > $renderer->getRemainingWidthPDF()) {
132
			$cW = $renderer->getRemainingWidthPDF();
133
		} else {
134
			$cW = $this->width;
135
		}
136
137
		// Save the original margins
138
		$cM = $renderer->getMargins();
139
		// Use cell padding to wrap the width
140
		// Temp Width with cell padding
141
		if (is_array($cM['cell'])) {
142
			$cWT = $cW - ($cM['padding_left'] + $cM['padding_right']);
143
		} else {
144
			$cWT = $cW - ($cM['cell'] * 2);
145
		}
146
		// Element height (exept text)
147
		$eH = 0;
148
		$w  = 0;
149
		// Temp Height
150
		$cHT = 0;
151
		//-- $lw is an array
152
		// 0 => last line width
153
		// 1 => 1 if text was wrapped, 0 if text did not wrap
154
		// 2 => number of LF
155
		$lw = [];
156
		// Element counter
157
		$cE = count($this->elements);
158
		//-- calculate the text box height + width
159
		for ($i = 0; $i < $cE; $i++) {
160
			if (is_object($this->elements[$i])) {
161
				$ew = $this->elements[$i]->setWrapWidth($cWT - $w, $cWT);
162
				if ($ew == $cWT) {
163
					$w = 0;
164
				}
165
				$lw = $this->elements[$i]->getWidth($renderer);
166
				// Text is already gets the # LF
167
				$cHT += $lw[2];
168
				if ($lw[1] == 1) {
169
					$w = $lw[0];
170
				} elseif ($lw[1] == 2) {
171
					$w = 0;
172
				} else {
173
					$w += $lw[0];
174
				}
175
				if ($w > $cWT) {
176
					$w = $lw[0];
177
				}
178
				// Footnote is at the bottom of the page. No need to calculate it’s height or wrap the text!
179
				// We are changing the margins anyway!
180
				// For anything else but text (images), get the height
181
				$eH += $this->elements[$i]->getHeight($renderer);
182
			}
183
		}
184
185
		// Add up what’s the final height
186
		$cH = $this->height;
187
		// If any element exist
188
		if ($cE > 0) {
189
			// Check if this is text or some other element, like images
190
			if ($eH == 0) {
191
				// This is text elements. Number of LF but at least one line
192
				$cHT = ($cHT + 1) * $renderer->getCellHeightRatio();
193
				// Calculate the cell hight with the largest font size used within this Box
194
				$cHT = $cHT * $renderer->largestFontHeight;
195
				// Add cell padding
196
				if ($this->padding) {
197
					if (is_array($cM['cell'])) {
198
						$cHT += ($cM['padding_bottom'] + $cM['padding_top']);
199
					} else {
200
						$cHT += ($cM['cell'] * 2);
201
					}
202
				}
203
				if ($cH < $cHT) {
204
					$cH = $cHT;
205
				}
206
			} // This is any other element
207
			elseif ($cH < $eH) {
208
				$cH = $eH;
209
			}
210
		}
211
		// Finaly, check the last cells height
212
		if ($cH < $renderer->lastCellHeight) {
213
			$cH = $renderer->lastCellHeight;
214
		}
215
		// Add a new page if needed
216
		if ($this->pagecheck) {
217
			// Reset last cell height or Header/Footer will inherit it, in case of pagebreak
218
			$renderer->lastCellHeight = 0;
219
			if ($renderer->checkPageBreakPDF($cH)) {
220
				$cY = $renderer->GetY();
221
			}
222
		}
223
224
		// Setup the border and background color
225
		$cS = ''; // Class Style
226
		if ($this->border) {
227
			$cS = 'D';
228
		} // D or empty string: Draw (default)
0 ignored issues
show
Unused Code Comprehensibility introduced by
36% of this comment could be valid code. Did you maybe forget this after debugging?

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.

Loading history...
229
		$match = [];
230
		// Fill the background
231
		if ($this->fill) {
232
			if (!empty($this->bgcolor)) {
233
				if (preg_match('/#?(..)(..)(..)/', $this->bgcolor, $match)) {
234
					$cS .= 'F'; // F: Fill the background
235
					$r = hexdec($match[1]);
236
					$g = hexdec($match[2]);
237
					$b = hexdec($match[3]);
238
					$renderer->SetFillColor($r, $g, $b);
239
				}
240
			}
241
		}
242
		// Clean up a bit
243
		unset($lw, $w, $match, $cE, $eH);
244
		// Draw the border
245
		if (!empty($cS)) {
246
			if (!$renderer->getRTL()) {
247
				$cXM = $cX;
248
			} else {
249
				$cXM = ($renderer->getPageWidth()) - $cX - $cW;
250
			}
251
			$renderer->Rect($cXM, $cY, $cW, $cH, $cS);
252
		}
253
		// Add cell padding if set and if any text (element) exist
254
		if ($this->padding) {
255
			if ($cHT > 0) {
256
				if (is_array($cM['cell'])) {
257
					$renderer->SetY($cY + $cM['padding_top']);
258
				} else {
259
					$renderer->SetY($cY + $cM['cell']);
260
				}
261
			}
262
		}
263
		// Change the margins X, Width
264
		if (!$renderer->getRTL()) {
265
			if ($this->padding) {
266
				if (is_array($cM['cell'])) {
267
					$renderer->SetLeftMargin($cX + $cM['padding_left']);
268
				} else {
269
					$renderer->SetLeftMargin($cX + $cM['cell']);
270
				}
271
				$renderer->SetRightMargin($renderer->getRemainingWidthPDF() - $cW + $cM['right']);
272
			} else {
273
				$renderer->SetLeftMargin($cX);
274
				$renderer->SetRightMargin($renderer->getRemainingWidthPDF() - $cW + $cM['right']);
275
			}
276
		} else {
277
			if ($this->padding) {
278
				if (is_array($cM['cell'])) {
279
					$renderer->SetRightMargin($cX + $cM['padding_right']);
280
				} else {
281
					$renderer->SetRightMargin($cX + $cM['cell']);
282
				}
283
				$renderer->SetLeftMargin($renderer->getRemainingWidthPDF() - $cW + $cM['left']);
284
			} else {
285
				$renderer->SetRightMargin($cX);
286
				$renderer->SetLeftMargin($renderer->getRemainingWidthPDF() - $cW + $cM['left']);
287
			}
288
		}
289
		// Save the current page number
290
		$cPN = $renderer->getPage();
291
292
		// Render the elements (write text, print picture...)
293
		foreach ($this->elements as $element) {
294
			if (is_object($element)) {
295
				$element->render($renderer);
296
			} elseif (is_string($element) && $element == 'footnotetexts') {
297
				$renderer->footnotes();
298
			} elseif (is_string($element) && $element == 'addpage') {
299
				$renderer->newPage();
300
			}
301
		}
302
		// Restore the margins
303
		$renderer->SetLeftMargin($cM['left']);
304
		$renderer->SetRightMargin($cM['right']);
305
306
		// This will be mostly used to trick the multiple images last height
307
		if ($this->reseth) {
308
			$cH = 0;
309
			// This can only happen with multiple images and with pagebreak
310
			if ($cPN != $renderer->getPage()) {
311
				$renderer->setPage($cPN);
312
			}
313
		}
314
		// New line and some clean up
315
		if (!$this->newline) {
316
			$renderer->SetXY(($cX + $cW), $cY);
317
			$renderer->lastCellHeight = $cH;
318
		} else {
319
			// addMarginX() also updates X
320
			$renderer->addMarginX(0);
321
			$renderer->SetY($cY + $cH);
322
			$renderer->lastCellHeight = 0;
323
		}
324
325
		return true;
326
	}
327
}
328