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

ReportTcpdf   D

Complexity

Total Complexity 61

Size/Duplication

Total Lines 373
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 373
rs 4.054
c 0
b 0
f 0
wmc 61

26 Methods

Rating   Name   Duplication   Size   Complexity  
A clearPageHeader() 0 3 1
A getFootnotesHeight() 0 7 2
A getMaxLineWidth() 0 6 2
A checkPageBreakPDF() 0 2 1
A addBody() 0 4 1
A addFooter() 0 4 1
A setCurrentStyle() 0 4 1
A clearHeader() 0 3 1
A removeHeader() 0 2 1
B body() 0 12 7
A getCurrentStyle() 0 2 1
A setReport() 0 2 1
A newPage() 0 5 2
A footnotes() 0 8 4
A addMarginX() 0 10 2
A addPageHeader() 0 4 1
A removePageHeader() 0 2 1
A addHeader() 0 4 1
A removeBody() 0 2 1
A getRemainingWidthPDF() 0 2 1
A removeFooter() 0 2 1
A getStyle() 0 7 2
B header() 0 17 13
A checkFootnote() 0 20 3
B footer() 0 8 7
A getCurrentStyleHeight() 0 7 2

How to fix   Complexity   

Complex Class

Complex classes like ReportTcpdf 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 ReportTcpdf, and based on these observations, apply Extract Interface, too.

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
use TCPDF;
19
20
/**
21
 * WT Report PDF Class
22
 *
23
 * This class inherits from the TCPDF class and is used to generate the PDF document
24
 */
25
class ReportTcpdf extends TCPDF {
26
	/** @var ReportBaseElement[] Array of elements in the header */
27
	public $headerElements = [];
28
29
	/** @var ReportBaseElement[] Array of elements in the page header */
30
	public $pageHeaderElements = [];
31
32
	/** @var ReportBaseElement[] Array of elements in the footer */
33
	public $footerElements = [];
34
35
	/** @var ReportBaseElement[] Array of elements in the body */
36
	public $bodyElements = [];
37
38
	/** @var ReportBaseFootnote[] Array of elements in the footer notes */
39
	public $printedfootnotes = [];
40
41
	/** @var string Currently used style name */
42
	public $currentStyle;
43
44
	/** @var int The last cell height */
45
	public $lastCellHeight = 0;
46
47
	/** @var int The largest font size within a TextBox to calculate the height */
48
	public $largestFontHeight = 0;
49
50
	/** @var int The last pictures page number */
51
	public $lastpicpage = 0;
52
53
	/** @var ReportBase The current report. */
54
	public $wt_report;
55
56
	/**
57
	 * PDF Header -PDF
58
	 */
59
	public function header() {
60
		foreach ($this->headerElements as $element) {
61
			if (is_object($element)) {
62
				$element->render($this);
63
			} elseif (is_string($element) && $element == 'footnotetexts') {
64
				$this->footnotes();
65
			} elseif (is_string($element) && $element == 'addpage') {
66
				$this->newPage();
67
			}
68
		}
69
		foreach ($this->pageHeaderElements as $element) {
70
			if (is_object($element)) {
71
				$element->render($this);
72
			} elseif (is_string($element) && $element == 'footnotetexts') {
73
				$this->footnotes();
74
			} elseif (is_string($element) && $element == 'addpage') {
75
				$this->newPage();
76
			}
77
		}
78
	}
79
80
	/**
81
	 * PDF Body -PDF
82
	 */
83
	public function body() {
84
		$this->AddPage();
85
		foreach ($this->bodyElements as $key => $element) {
86
			if (is_object($element)) {
87
				$element->render($this);
88
			} elseif (is_string($element) && $element == 'footnotetexts') {
89
				$this->footnotes();
90
			} elseif (is_string($element) && $element == 'addpage') {
91
				$this->newPage();
92
			}
93
			// Delete used elements in hope to reduce 'some' memory usage
94
			unset($this->bodyElements[$key]);
95
		}
96
	}
97
98
	/**
99
	 * PDF Footnotes -PDF
100
	 */
101
	public function footnotes() {
102
		foreach ($this->printedfootnotes as $element) {
103
			if (($this->GetY() + $element->getFootnoteHeight($this)) > $this->getPageHeight()) {
104
				$this->AddPage();
105
			}
106
			$element->renderFootnote($this);
107
			if ($this->GetY() > $this->getPageHeight()) {
108
				$this->AddPage();
109
			}
110
		}
111
	}
112
113
	/**
114
	 * PDF Footer -PDF
115
	 */
116
	public function footer() {
117
		foreach ($this->footerElements as $element) {
118
			if (is_object($element)) {
119
				$element->render($this);
120
			} elseif (is_string($element) && $element == 'footnotetexts') {
121
				$this->footnotes();
122
			} elseif (is_string($element) && $element == 'addpage') {
123
				$this->newPage();
124
			}
125
		}
126
	}
127
128
	/**
129
	 * Add an element to the Header -PDF
130
	 *
131
	 * @param object|string $element
132
	 *
133
	 * @return int The number of the Header elements
134
	 */
135
	public function addHeader($element) {
136
		$this->headerElements[] = $element;
137
138
		return count($this->headerElements) - 1;
139
	}
140
141
	/**
142
	 * Add an element to the Page Header -PDF
143
	 *
144
	 * @param object|string $element
145
	 *
146
	 * @return int The number of the Page Header elements
147
	 */
148
	public function addPageHeader($element) {
149
		$this->pageHeaderElements[] = $element;
150
151
		return count($this->pageHeaderElements) - 1;
152
	}
153
154
	/**
155
	 * Add an element to the Body -PDF
156
	 *
157
	 * @param object|string $element
158
	 *
159
	 * @return int The number of the Body elements
160
	 */
161
	public function addBody($element) {
162
		$this->bodyElements[] = $element;
163
164
		return count($this->bodyElements) - 1;
165
	}
166
167
	/**
168
	 * Add an element to the Footer -PDF
169
	 *
170
	 * @param object|string $element
171
	 *
172
	 * @return int The number of the Footer elements
173
	 */
174
	public function addFooter($element) {
175
		$this->footerElements[] = $element;
176
177
		return count($this->footerElements) - 1;
178
	}
179
180
	/**
181
	 * Remove the header.
182
	 *
183
	 * @param $index
184
	 */
185
	public function removeHeader($index) {
186
		unset($this->headerElements[$index]);
187
	}
188
189
	/**
190
	 * Remove the page header.
191
	 *
192
	 * @param $index
193
	 */
194
	public function removePageHeader($index) {
195
		unset($this->pageHeaderElements[$index]);
196
	}
197
198
	/**
199
	 * Remove the body.
200
	 *
201
	 * @param $index
202
	 */
203
	public function removeBody($index) {
204
		unset($this->bodyElements[$index]);
205
	}
206
207
	/**
208
	 * Remove the footer.
209
	 *
210
	 * @param $index
211
	 */
212
	public function removeFooter($index) {
213
		unset($this->footerElements[$index]);
214
	}
215
216
	/**
217
	 * Clear the Header -PDF
218
	 */
219
	public function clearHeader() {
220
		unset($this->headerElements);
221
		$this->headerElements = [];
222
	}
223
224
	/**
225
	 * Clear the Page Header -PDF
226
	 */
227
	public function clearPageHeader() {
228
		unset($this->pageHeaderElements);
229
		$this->pageHeaderElements = [];
230
	}
231
232
	/**
233
	 * Set the report.
234
	 *
235
	 * @param $r
236
	 */
237
	public function setReport($r) {
238
		$this->wt_report = $r;
239
	}
240
241
	/**
242
	 * Get the currently used style name -PDF
243
	 *
244
	 * @return string
245
	 */
246
	public function getCurrentStyle() {
247
		return $this->currentStyle;
248
	}
249
250
	/**
251
	 * Setup a style for usage -PDF
252
	 *
253
	 * @param string $s Style name
254
	 */
255
	public function setCurrentStyle($s) {
256
		$this->currentStyle = $s;
257
		$style              = $this->wt_report->getStyle($s);
258
		$this->SetFont($style['font'], $style['style'], $style['size']);
259
	}
260
261
	/**
262
	 * Get the style -PDF
263
	 *
264
	 * @param string $s Style name
265
	 *
266
	 * @return array
267
	 */
268
	public function getStyle($s) {
269
		if (!isset($this->wt_report->Styles[$s])) {
270
			$s                           = $this->getCurrentStyle();
271
			$this->wt_report->Styles[$s] = $s;
272
		}
273
274
		return $this->wt_report->Styles[$s];
275
	}
276
277
	/**
278
	 * Add margin when static horizontal position is used -PDF
279
	 * RTL supported
280
	 *
281
	 * @param float $x Static position
282
	 *
283
	 * @return float
284
	 */
285
	public function addMarginX($x) {
286
		$m = $this->getMargins();
287
		if ($this->getRTL()) {
288
			$x += $m['right'];
289
		} else {
290
			$x += $m['left'];
291
		}
292
		$this->SetX($x);
293
294
		return $x;
295
	}
296
297
	/**
298
	 * Get the maximum line width to draw from the curren position -PDF
299
	 * RTL supported
300
	 *
301
	 * @return float
302
	 */
303
	public function getMaxLineWidth() {
304
		$m = $this->getMargins();
305
		if ($this->getRTL()) {
306
			return ($this->getRemainingWidth() + $m['right']);
307
		} else {
308
			return ($this->getRemainingWidth() + $m['left']);
309
		}
310
	}
311
312
	/**
313
	 * Get the height of the footnote.
314
	 *
315
	 * @return int
316
	 */
317
	public function getFootnotesHeight() {
318
		$h = 0;
319
		foreach ($this->printedfootnotes as $element) {
320
			$h += $element->getHeight($this);
321
		}
322
323
		return $h;
324
	}
325
326
	/**
327
	 * Returns the the current font size height -PDF
328
	 *
329
	 * @return int
330
	 */
331
	public function getCurrentStyleHeight() {
332
		if (empty($this->currentStyle)) {
333
			return $this->wt_report->defaultFontSize;
334
		}
335
		$style = $this->wt_report->getStyle($this->currentStyle);
336
337
		return $style['size'];
338
	}
339
340
	/**
341
	 * Checks the Footnote and numbers them
342
	 *
343
	 * @param object $footnote
344
	 *
345
	 * @return bool false if not numbered befor | object if already numbered
346
	 */
347
	public function checkFootnote($footnote) {
348
		$ct  = count($this->printedfootnotes);
349
		$val = $footnote->getValue();
350
		$i   = 0;
351
		while ($i < $ct) {
352
			if ($this->printedfootnotes[$i]->getValue() == $val) {
353
				// If this footnote already exist then set up the numbers for this object
354
				$footnote->setNum($i + 1);
355
				$footnote->setAddlink($i + 1);
356
357
				return $this->printedfootnotes[$i];
358
			}
359
			$i++;
360
		}
361
		// If this Footnote has not been set up yet
362
		$footnote->setNum($ct + 1);
363
		$footnote->setAddlink($this->AddLink());
364
		$this->printedfootnotes[] = $footnote;
365
366
		return false;
367
	}
368
369
	/**
370
	 * Used this function instead of AddPage()
371
	 * This function will make sure that images will not be overwritten
372
	 */
373
	public function newPage() {
374
		if ($this->lastpicpage > $this->getPage()) {
375
			$this->setPage($this->lastpicpage);
376
		}
377
		$this->AddPage();
378
	}
379
380
	/**
381
	 * Add a page if needed -PDF
382
	 *
383
	 * @param int $height Cell height
384
	 *
385
	 * @return bool true in case of page break, false otherwise
386
	 */
387
	public function checkPageBreakPDF($height) {
388
		return $this->checkPageBreak($height);
389
	}
390
391
	/**
392
	 * Returns the remaining width between the current position and margins -PDF
393
	 *
394
	 * @return float Remaining width
395
	 */
396
	public function getRemainingWidthPDF() {
397
		return $this->getRemainingWidth();
398
	}
399
}
400