Total Complexity | 184 |
Total Lines | 1596 |
Duplicated Lines | 0 % |
Changes | 0 |
Complex classes like XPDF 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 XPDF, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
30 | class XPDF extends FPDF |
||
31 | { |
||
32 | /** predifined Col-ID for automated row number */ |
||
33 | const COL_ROW_NR = 1000; |
||
34 | |||
35 | /** Bottom margin for trigger of the auto pagebreak */ |
||
36 | const BOTTOM_MARGIN = 12; |
||
37 | |||
38 | /** totals info */ |
||
39 | const FLAG_TOTALS = 0x0007; |
||
40 | /** calc total for column */ |
||
41 | const FLAG_TOTALS_CALC = 0x0001; |
||
42 | /** print text in totals row */ |
||
43 | const FLAG_TOTALS_TEXT = 0x0002; |
||
44 | /** leave empty in totals row */ |
||
45 | const FLAG_TOTALS_EMPTY = 0x0004; |
||
46 | /** create internal link */ |
||
47 | const FLAG_INT_LINK = 0x0008; |
||
48 | /** special format for the cell */ |
||
49 | const FLAG_FORMAT = 0x00F0; |
||
50 | /** format cell as currency with symbol */ |
||
51 | const FLAG_CUR_SYMBOL = 0x0010; |
||
52 | /** format cell as currency without symbol */ |
||
53 | const FLAG_CUR_PLAIN = 0x0020; |
||
54 | /** format cell as date/time */ |
||
55 | const FLAG_DATE = 0x0030; |
||
56 | /** format cell as date/time */ |
||
57 | const FLAG_TIME = 0x0040; |
||
58 | /** format cell as date/time */ |
||
59 | const FLAG_DATE_TIME = 0x0050; |
||
60 | /** format cell as number */ |
||
61 | const FLAG_NUMBER = 0x0060; |
||
62 | /** cell containes image */ |
||
63 | const FLAG_IMAGE = 0x0100; |
||
64 | /** suppress zero values */ |
||
65 | const FLAG_NO_ZERO = 0x0200; |
||
66 | |||
67 | |||
68 | /** crate totals row on the end of report */ |
||
69 | const TOTALS = 0x01; |
||
70 | /** create totals row on each pagebreak */ |
||
71 | const PAGE_TOTALS = 0x02; |
||
72 | /** create carry over on the beginning of each new page */ |
||
73 | const CARRY_OVER = 0x04; |
||
74 | /** create */ |
||
75 | const SUB_TOTALS = 0x08; |
||
76 | |||
77 | /** @var string pageheader */ |
||
78 | protected string $strPageTitle; |
||
79 | /** @var string logo */ |
||
80 | protected string $strLogo; |
||
81 | /** @var float height of the loge in user units */ |
||
82 | protected float $fltLogoHeight; |
||
83 | /** @var string subject in page header */ |
||
84 | protected string $strPageSubject; |
||
85 | /** @var string pagefooter */ |
||
86 | protected string $strPageFooter; |
||
87 | /** @var XPDFFont font to use in header of the document */ |
||
88 | protected ?XPDFFont $fontHeader; |
||
89 | /** @var XPDFFont font to use for subject in the header of the document */ |
||
90 | protected ?XPDFFont $fontSubject; |
||
91 | /** @var XPDFFont font to use in footer of the document */ |
||
92 | protected ?XPDFFont $fontFooter; |
||
93 | /** @var XPDFFont font to use in col headers of the grid */ |
||
94 | protected ?XPDFFont $fontColHeader; |
||
95 | /** @var XPDFFont font to use in sub headers of the grid */ |
||
96 | protected ?XPDFFont $fontSubHeader; |
||
97 | /** @var XPDFFont font to use in rows of a grid */ |
||
98 | protected ?XPDFFont $fontRows; |
||
99 | /** @var string textcolor to use in header of the document */ |
||
100 | protected string $strHeaderTextColor = '#000000'; |
||
101 | /** @var string textcolor to use in footer of the document */ |
||
102 | protected string $strFooterTextColor = '#000000'; |
||
103 | /** @var string textcolor to use in colheader of the document */ |
||
104 | protected string $strColHeaderTextColor = '#00007F'; |
||
105 | /** @var string textcolor to use in subheader of the document */ |
||
106 | protected string $strSubHeaderTextColor = '#000000'; |
||
107 | /** @var string textcolor to use in rows of the document */ |
||
108 | protected string $strRowTextColor = '#000000'; |
||
109 | /** @var string textcolor to use for internal links */ |
||
110 | protected string $strLinkTextColor = '#0000FF'; |
||
111 | /** @var string drawcolor to use in header of the document */ |
||
112 | protected string $strHeaderDrawColor = '#404040'; |
||
113 | /** @var string drawcolor to use in footer of the document */ |
||
114 | protected string $strFooterDrawColor = '#404040'; |
||
115 | /** @var string fillcolor to use in colheader of the document */ |
||
116 | protected string $strColHeaderFillColor = '#D7D7D7'; |
||
117 | /** @var string fillcolor to use in subheader of the document */ |
||
118 | protected string $strSubHeaderFillColor = '#A7A7A7'; |
||
119 | /** @var bool strip datarows for better contrast */ |
||
120 | protected bool $bStripped = true; |
||
121 | /** @var string drawcolor to use in rows of the document (striped) */ |
||
122 | protected string $strRowDrawColor = '#404040'; |
||
123 | /** @var string fillcolor to use in rows of the document (striped) */ |
||
124 | protected string $strRowFillColor = '#E0EBFF'; |
||
125 | /** @var bool currently inside of of grid */ |
||
126 | protected bool $bInGrid = false; |
||
127 | /** @var int|string border */ |
||
128 | protected $border = 1; |
||
129 | /** @var int index of last col */ |
||
130 | protected int $iMaxCol = -1; |
||
131 | /** @var int index of last title col (in case of colspans in header < $iMaxCol */ |
||
132 | protected int $iMaxColHeader = -1; |
||
133 | /** @var array titles for the table header */ |
||
134 | protected array $aColHeader = Array(); |
||
135 | /** @var array width of each col in percent */ |
||
136 | protected array $aColWidth = Array(); |
||
137 | /** @var array align of each datacol (header always center) */ |
||
138 | protected array $aColAlign = Array(); |
||
139 | /** @var array flags for each datacol */ |
||
140 | protected array $aColFlags = Array(); |
||
141 | /** @var array fieldname or number of each datacol */ |
||
142 | protected array $aColField = Array(); |
||
143 | /** @var array colspan of the headercols */ |
||
144 | protected array $aColSpan = Array(); |
||
145 | /** @var array info for image cols */ |
||
146 | protected array $aImgInfo = Array(); |
||
147 | /** @var bool enable automatic calculation of totals */ |
||
148 | protected bool $bCalcTotals = false; |
||
149 | /** @var string text for totals */ |
||
150 | protected string $strTotals = 'Total:'; |
||
151 | /** @var bool print subtotals on each pagebreak */ |
||
152 | protected bool $bPageTotals = false; |
||
153 | /** @var string text for subtotals */ |
||
154 | protected string $strPageTotals = ''; |
||
155 | /** @var bool print carry over on top of each new page */ |
||
156 | protected bool $bCarryOver = false; |
||
157 | /** @var string text for carry over */ |
||
158 | protected string $strCarryOver = 'Carry over:'; |
||
159 | /** @var string text for subtotals */ |
||
160 | protected string $strSubTotals = 'Subtotal:'; |
||
161 | /** @var int index of last totals col */ |
||
162 | protected int $iMaxColTotals = -1; |
||
163 | /** @var array calculated totals */ |
||
164 | protected array $aTotals = Array(); |
||
165 | /** @var array calculated subtotals */ |
||
166 | protected array $aSubTotals = Array(); |
||
167 | /** @var array colspan of the totals */ |
||
168 | protected array $aTotalsColSpan = Array(); |
||
169 | /** @var int current rownumber */ |
||
170 | protected int $iRow; |
||
171 | /** @var float lineheight in mm */ |
||
172 | protected float $fltLineHeight = 8.0; |
||
173 | /** @var string */ |
||
174 | protected string $strCharset = 'UTF-8'; |
||
175 | /** @var string */ |
||
176 | protected string $strLocale = ''; |
||
177 | /** @var string format for Date cell */ |
||
178 | protected string $strFormatD = '%Y-%d-%m'; |
||
179 | /** @var string format for Time cell */ |
||
180 | protected string $strFormatT = '%H:%M'; |
||
181 | /** @var string format for Datetime cell */ |
||
182 | protected string $strFormatDT = '%Y-%d-%m %H:%M'; |
||
183 | /** @var int decimals for number format */ |
||
184 | protected int $iNumberDecimals = 2; |
||
185 | /** @var string prefix for number format */ |
||
186 | protected string $strNumberPrefix = ''; |
||
187 | /** @var string suffix for number format */ |
||
188 | protected string $strNumberSuffix = ''; |
||
189 | /** @var bool setlocale() not called or returned false! */ |
||
190 | protected bool $bInvalidLocale = true; |
||
191 | |||
192 | /** |
||
193 | * class constructor. |
||
194 | * allows to set up the page size, the orientation and the unit of measure used in all methods (except for font sizes). |
||
195 | * @param string $orientation |
||
196 | * @param string $unit |
||
197 | * @param string|array $size |
||
198 | * @see FPDF::__construct() |
||
199 | */ |
||
200 | public function __construct(string $orientation = 'P', string $unit = 'mm', $size = 'A4') |
||
201 | { |
||
202 | parent::__construct($orientation, $unit, $size); |
||
203 | |||
204 | $this->setDisplayMode('fullpage', 'single'); |
||
205 | $this->setAutoPageBreak(true, self::BOTTOM_MARGIN); |
||
206 | $this->aliasNbPages('{NP}'); |
||
207 | $this->setLocale("en_US.utf8, en_US"); |
||
208 | |||
209 | |||
210 | $this->strPageTitle = ''; |
||
211 | $this->strPageFooter = "{PN}/{NP}\t{D} {T}"; |
||
212 | $this->strLogo = ''; |
||
213 | $this->fltLogoHeight = 8.0; |
||
214 | |||
215 | $this->iRow = 0; |
||
216 | |||
217 | $this->fontHeader = new XPDFFont('Arial', 'B', 12); |
||
218 | $this->fontSubject = new XPDFFont('Arial', 'I', 8); |
||
219 | $this->fontFooter = new XPDFFont('Arial', 'I', 8); |
||
220 | $this->fontColHeader = new XPDFFont('Arial', 'B', 10); |
||
221 | $this->fontSubHeader = new XPDFFont('Arial', 'B', 10); |
||
222 | $this->fontRows = new XPDFFont('Arial', '', 10); |
||
223 | } |
||
224 | |||
225 | /** |
||
226 | * Set information for document to create. |
||
227 | * @param string $strTitle |
||
228 | * @param string $strSubject |
||
229 | * @param string $strAuthor |
||
230 | * @param string $strKeywords |
||
231 | * @param bool $isUTF8 Indicates if the strings encoded in ISO-8859-1 (false) or UTF-8 (true). (Default: false) |
||
232 | */ |
||
233 | public function setInfo(string $strTitle, string $strSubject, string $strAuthor, string $strKeywords = '', bool $isUTF8 = false) : void |
||
234 | { |
||
235 | $this->setTitle($strTitle, $isUTF8); |
||
236 | $this->setSubject($strSubject, $isUTF8); |
||
237 | $this->setAuthor($strAuthor, $isUTF8); |
||
238 | $this->setKeywords($strKeywords, $isUTF8); |
||
239 | $this->setCreator('FPDF - Dokument Generator'); |
||
240 | } |
||
241 | |||
242 | /** |
||
243 | * Set charset. |
||
244 | * for europe/germany should be set to 'windows-1252//TRANSLIT' to support |
||
245 | * proper Euro-sign and umlauts. <br/> |
||
246 | * <br/> |
||
247 | * Can be controled through JSON-Format in InitGrid() |
||
248 | * @param string $strCharset |
||
249 | * @see XPDF::InitGrid() |
||
250 | * @link http://www.php.net/manual/en/function.iconv.php |
||
251 | */ |
||
252 | public function setCharset(string $strCharset) : void |
||
253 | { |
||
254 | $this->strCharset = $strCharset; |
||
255 | } |
||
256 | |||
257 | /** |
||
258 | * Set locale for formating. |
||
259 | * If $strLocale is an comma separated list each value is tried to be |
||
260 | * set as new locale until success. <br/> |
||
261 | * Example: <i>"de_DE.utf8, de_DE, de, DE"</i><br/> |
||
262 | * <br/> |
||
263 | * <b>!! Can be controled/overwritten through JSON-Format in InitGrid() !!</b> |
||
264 | * @param string $strLocale |
||
265 | * @see XPDF::InitGrid() |
||
266 | * @link http://www.php.net/manual/en/function.setlocale.php |
||
267 | */ |
||
268 | public function setLocale(string $strLocale) : void |
||
269 | { |
||
270 | if ($this->strLocale != $strLocale) { |
||
271 | $this->strLocale = $strLocale; |
||
272 | |||
273 | // if locale contains multiple coma separated values, just explode and trim... |
||
274 | $locale = $this->strLocale; |
||
275 | if (strpos($this->strLocale, ',')) { |
||
276 | $locale = array_map('trim', explode(',', $this->strLocale)); |
||
277 | } |
||
278 | $this->bInvalidLocale = false; |
||
279 | if (setlocale(LC_ALL, $locale) === false) { |
||
280 | trigger_error('setlocale("' . $this->strLocale . '") failed!', E_USER_NOTICE); |
||
281 | // TODO: obsolete? |
||
282 | $this->bInvalidLocale = true; |
||
283 | } |
||
284 | } |
||
285 | } |
||
286 | |||
287 | /** |
||
288 | * Set the pageheader of the document. |
||
289 | * The title is printed in the left of the pageheader using the font set with XPDF:SetHeaderFont() <br/> |
||
290 | * Optional the subject and/or the logo can be set. |
||
291 | * Subject and logo can also be set using XPDF:SetSubject() and XPDF:SetLogo() <br/> |
||
292 | * The page header is separated from the report by a double line. |
||
293 | * @param string $strTitle Title of the Report |
||
294 | * @param string $strHeaderSubject Subject of the Report |
||
295 | * @param string $strLogo Logo to print. |
||
296 | * @see XPDF:SetHeaderFont() |
||
297 | * @see XPDF:SetSubject() |
||
298 | * @see XPDF:SetLogo() |
||
299 | */ |
||
300 | public function setPageHeader(string $strTitle, string $strHeaderSubject = '', string $strLogo = '') : void |
||
301 | { |
||
302 | $this->strPageTitle = $strTitle; |
||
303 | if (strlen($strLogo) > 0) { |
||
304 | $this->strLogo = $strLogo; |
||
305 | } |
||
306 | $this->strPageSubject = $strHeaderSubject; |
||
307 | } |
||
308 | |||
309 | /** |
||
310 | * Set the subject in the pageheader of the document. |
||
311 | * The subject is printed in the left of the pageheader in the 2'nd line using the font set |
||
312 | * with XPDF:SetSubjectFont() <br/> |
||
313 | * @param string $strPageSubject |
||
314 | * @see XPDF:SetSubjectFont() |
||
315 | */ |
||
316 | public function setPageSubject(string $strPageSubject) : void |
||
317 | { |
||
318 | $this->strPageSubject = $strPageSubject; |
||
319 | } |
||
320 | |||
321 | /** |
||
322 | * Set logo printed in the document header. |
||
323 | * The logo is printed right-aligned in the header, and by default, the logo will be |
||
324 | * scaled to a height of 8mm. Another height can be set with XPDF::SetLogoHeight(). <br/> |
||
325 | * For convinience, the loge can be set directly within XPDF::SetPageHeader(). |
||
326 | * @param string $strLogo image file to print. |
||
327 | * @see XPDF::SetLogoHeight() |
||
328 | * @see XPDF::SetPageHeader() |
||
329 | */ |
||
330 | public function setLogo(string $strLogo) : void |
||
331 | { |
||
332 | $this->strLogo = $strLogo; |
||
333 | } |
||
334 | |||
335 | /** |
||
336 | * Set height of the logo in the document header. |
||
337 | * @param float $fltLogoHeight height of the logo image |
||
338 | */ |
||
339 | public function setLogoHeight(float $fltLogoHeight) : void |
||
340 | { |
||
341 | $this->fltLogoHeight = $fltLogoHeight; |
||
342 | } |
||
343 | |||
344 | /** |
||
345 | * Set the pagefooter of the document. |
||
346 | * @param string $strFooter The footer can consist of up to three sections delimitet by TAB <b>('\t')</b><br/> |
||
347 | * possible placeholders are <ul> |
||
348 | * <li> '{D}' -> current date (DD.MM.YYYY) </li> |
||
349 | * <li> '{T}' -> current time (HH:ii) </li> |
||
350 | * <li> '{PN}' -> pagenumber </li> |
||
351 | * <li> '{NP}' -> total number of pages </li></ul> |
||
352 | * default footer is: <b>'Page {PN}/{NP}\t{D} {T}' </b> |
||
353 | */ |
||
354 | public function setPageFooter($strFooter) : void |
||
355 | { |
||
356 | $this->strPageFooter = $strFooter; |
||
357 | } |
||
358 | |||
359 | /** |
||
360 | * Initialisation of grid. <ul> |
||
361 | * <li> fonts </li> |
||
362 | * <li> colors </li> |
||
363 | * <li> totals/subtotals/carry over text </li> |
||
364 | * <li> charset </li> |
||
365 | * <li> formating </li></ul> |
||
366 | * See xfpdf-sample.json for more information about this file. |
||
367 | * @param string $strFilename |
||
368 | */ |
||
369 | public function initGrid(string $strFilename) : void |
||
370 | { |
||
371 | if (file_exists($strFilename)) { |
||
372 | $strJSON = file_get_contents($strFilename); |
||
373 | $jsonData = json_decode($strJSON); |
||
374 | if ($jsonData) { |
||
375 | $this->fontHeader = $this->propertyFont($jsonData, 'fontHeader', $this->fontHeader); |
||
|
|||
376 | $this->fontSubject = $this->propertyFont($jsonData, 'fontSubject', $this->fontSubject); |
||
377 | $this->fontFooter = $this->propertyFont($jsonData, 'fontFooter', $this->fontFooter); |
||
378 | $this->fontColHeader = $this->propertyFont($jsonData, 'fontColHeader', $this->fontColHeader); |
||
379 | $this->fontSubHeader = $this->propertyFont($jsonData, 'fontSubHeader', $this->fontSubHeader); |
||
380 | $this->fontRows = $this->propertyFont($jsonData, 'fontRows', $this->fontRows); |
||
381 | |||
382 | $this->fltLineHeight = $this->property($jsonData, 'dblLineHeight', $this->fltLineHeight); |
||
383 | $this->fltLineHeight = $this->property($jsonData, 'fltLineHeight', $this->fltLineHeight); |
||
384 | |||
385 | $this->strHeaderTextColor = $this->property($jsonData, 'strHeaderTextColor', $this->strHeaderTextColor); |
||
386 | $this->strHeaderDrawColor = $this->property($jsonData, 'strHeaderDrawColor', $this->strHeaderDrawColor); |
||
387 | |||
388 | $this->strFooterTextColor = $this->property($jsonData, 'strFooterTextColor', $this->strFooterTextColor); |
||
389 | $this->strFooterDrawColor = $this->property($jsonData, 'strFooterDrawColor', $this->strFooterDrawColor); |
||
390 | |||
391 | $this->strColHeaderTextColor = $this->property($jsonData, 'strColHeaderTextColor', $this->strColHeaderTextColor); |
||
392 | $this->strColHeaderFillColor = $this->property($jsonData, 'strColHeaderFillColor', $this->strColHeaderFillColor); |
||
393 | $this->strSubHeaderTextColor = $this->property($jsonData, 'strSubHeaderTextColor', $this->strSubHeaderTextColor); |
||
394 | $this->strSubHeaderFillColor = $this->property($jsonData, 'strSubHeaderFillColor', $this->strSubHeaderFillColor); |
||
395 | $this->strRowTextColor = $this->property($jsonData, 'strRowTextColor', $this->strRowTextColor); |
||
396 | $this->strRowDrawColor = $this->property($jsonData, 'strRowDrawColor', $this->strRowDrawColor); |
||
397 | $this->strRowFillColor = $this->property($jsonData, 'strRowFillColor', $this->strRowFillColor); |
||
398 | $this->strLinkTextColor = $this->property($jsonData, 'strLinkTextColor', $this->strLinkTextColor); |
||
399 | |||
400 | $this->bStripped = $this->property($jsonData, 'bStripped', $this->bStripped); |
||
401 | $this->border = $this->property($jsonData, 'border', $this->border); |
||
402 | |||
403 | $this->bCalcTotals = $this->property($jsonData, 'bCalcTotals', $this->bCalcTotals); |
||
404 | $this->bPageTotals = $this->property($jsonData, 'bPageTotals', $this->bPageTotals); |
||
405 | $this->bCarryOver = $this->property($jsonData, 'bCarryOver', $this->bCarryOver); |
||
406 | |||
407 | $this->strTotals = $this->property($jsonData, 'strTotals', $this->strTotals); |
||
408 | $this->strPageTotals = $this->property($jsonData, 'strPageTotals', $this->strPageTotals); |
||
409 | $this->strCarryOver = $this->property($jsonData, 'strCarryOver', $this->strCarryOver); |
||
410 | |||
411 | $this->strCharset = $this->property($jsonData, 'strCharset', $this->strCharset); |
||
412 | $this->setLocale($this->property($jsonData, 'strLocale', $this->strLocale)); |
||
413 | $this->strFormatD = $this->property($jsonData, 'strFormatD', $this->strFormatD); |
||
414 | $this->strFormatT = $this->property($jsonData, 'strFormatT', $this->strFormatT); |
||
415 | $this->strFormatDT = $this->property($jsonData, 'strFormatDT', $this->strFormatDT); |
||
416 | } else { |
||
417 | trigger_error('unable to decode contents of JSON file [' . $strFilename . ']', E_USER_NOTICE); |
||
418 | } |
||
419 | } |
||
420 | } |
||
421 | |||
422 | /** |
||
423 | * Set the Date Format to use. |
||
424 | * Format string corresponds to strftime() function. <br/> |
||
425 | * <br/> |
||
426 | * <b>!! Can be controled/overwritten through JSON-Format in InitGrid() !!</b> |
||
427 | * @param string $strFormatD |
||
428 | * @see XPDF::InitGrid() |
||
429 | * @link http://www.php.net/manual/en/function.strftime.php |
||
430 | */ |
||
431 | public function setDateFormat(string $strFormatD) : void |
||
432 | { |
||
433 | $this->strFormatD = $strFormatD; |
||
434 | } |
||
435 | |||
436 | /** |
||
437 | * Set the Time Format to use. |
||
438 | * Format string corresponds to strftime() function. <br/> |
||
439 | * <br/> |
||
440 | * <b>!! Can be controled/overwritten through JSON-Format in InitGrid() !!</b> |
||
441 | * @param string $strFormatT |
||
442 | * @see XPDF::InitGrid() |
||
443 | * @link http://www.php.net/manual/en/function.strftime.php |
||
444 | */ |
||
445 | public function setTimeFormat(string $strFormatT) : void |
||
446 | { |
||
447 | $this->strFormatT = $strFormatT; |
||
448 | } |
||
449 | |||
450 | /** |
||
451 | * Set the DateTime Format to use. |
||
452 | * Format string corresponds to strftime() function. <br/> |
||
453 | * <br/> |
||
454 | * <b>!! Can be controled/overwritten through JSON-Format in InitGrid() !!</b> |
||
455 | * @param string $strFormatDT |
||
456 | * @see XPDF::InitGrid() |
||
457 | * @link http://www.php.net/manual/en/function.strftime.php |
||
458 | */ |
||
459 | public function setDateTimeFormat(string $strFormatDT) : void |
||
460 | { |
||
461 | $this->strFormatDT = $strFormatDT; |
||
462 | } |
||
463 | |||
464 | /** |
||
465 | * Set format for numbers. |
||
466 | * Decimal point and thousands separator from locale settings is used if available. <br/> |
||
467 | * <br/> |
||
468 | * <b>!! Can be controled/overwritten through JSON-Format in InitGrid() !!</b> |
||
469 | * @param int $iDecimals |
||
470 | * @param string $strPrefix |
||
471 | * @param string $strSuffix |
||
472 | * @see XPDF::InitGrid() |
||
473 | */ |
||
474 | public function setNumberFormat(int $iDecimals, string $strPrefix = '', string $strSuffix = '') : void |
||
475 | { |
||
476 | $this->iNumberDecimals = $iDecimals; |
||
477 | $this->strNumberPrefix = $strPrefix; |
||
478 | $this->strNumberSuffix = $strSuffix; |
||
479 | } |
||
480 | |||
481 | /** |
||
482 | * Set font for page header. |
||
483 | * <b>!! Can be controled/overwritten through JSON-Format in InitGrid() !!</b> |
||
484 | * @see XPDF::InitGrid() |
||
485 | * @param string $strFontname |
||
486 | * @param string $strStyle |
||
487 | * @param int $iSize |
||
488 | */ |
||
489 | public function setHeaderFont(string $strFontname, string $strStyle, int $iSize) : void |
||
490 | { |
||
491 | $this->fontHeader = new XPDFFont($strFontname, $strStyle, $iSize); |
||
492 | } |
||
493 | |||
494 | /** |
||
495 | * Set font for subject in the page header. |
||
496 | * <b>!! Can be controled/overwritten through JSON-Format in InitGrid() !!</b> |
||
497 | * @see XPDF::InitGrid() |
||
498 | * @param string $strFontname |
||
499 | * @param string $strStyle |
||
500 | * @param int $iSize |
||
501 | */ |
||
502 | public function setSubjectFont(string $strFontname, string $strStyle, int $iSize) : void |
||
503 | { |
||
504 | $this->fontSubject = new XPDFFont($strFontname, $strStyle, $iSize); |
||
505 | } |
||
506 | |||
507 | /** |
||
508 | * Set font for page footer. |
||
509 | * <b>!! Can be controled/overwritten through JSON-Format in InitGrid() !!</b> |
||
510 | * @see XPDF::InitGrid() |
||
511 | * @param string $strFontname |
||
512 | * @param string $strStyle |
||
513 | * @param int $iSize |
||
514 | */ |
||
515 | public function setFooterFont(string $strFontname, string $strStyle, int $iSize) : void |
||
516 | { |
||
517 | $this->fontFooter = new XPDFFont($strFontname, $strStyle, $iSize); |
||
518 | } |
||
519 | |||
520 | /** |
||
521 | * Set font for col headers. |
||
522 | * <b>!! Can be controled/overwritten through JSON-Format in InitGrid() !!</b> |
||
523 | * @see XPDF::InitGrid() |
||
524 | * @param string $strFontname |
||
525 | * @param string $strStyle |
||
526 | * @param int $iSize |
||
527 | */ |
||
528 | public function setColHeaderFont(string $strFontname, string $strStyle, int $iSize) : void |
||
529 | { |
||
530 | $this->fontColHeader = new XPDFFont($strFontname, $strStyle, $iSize); |
||
531 | } |
||
532 | |||
533 | /** |
||
534 | * Set font for sub headers. |
||
535 | * <b>!! Can be controled/overwritten through JSON-Format in InitGrid() !!</b> |
||
536 | * @see XPDF::InitGrid() |
||
537 | * @param string $strFontname |
||
538 | * @param string $strStyle |
||
539 | * @param int $iSize |
||
540 | */ |
||
541 | public function setSubHeaderFont(string $strFontname, string $strStyle, int $iSize) : void |
||
542 | { |
||
543 | $this->fontSubHeader = new XPDFFont($strFontname, $strStyle, $iSize); |
||
544 | } |
||
545 | |||
546 | /** |
||
547 | * Set font for data rows. |
||
548 | * <b>!! Can be controled/overwritten through JSON-Format in InitGrid() !!</b> |
||
549 | * @see XPDF::InitGrid() |
||
550 | * @param string $strFontname |
||
551 | * @param string $strStyle |
||
552 | * @param int $iSize |
||
553 | */ |
||
554 | public function setRowFont(string $strFontname, string $strStyle, int $iSize) : void |
||
555 | { |
||
556 | $this->fontRows = new XPDFFont($strFontname, $strStyle, $iSize); |
||
557 | $this->selectFont($this->fontRows); |
||
558 | } |
||
559 | |||
560 | /** |
||
561 | * Set lineheight. |
||
562 | * <b>!! Can be controled/overwritten through JSON-Format in InitGrid() !!</b> |
||
563 | * @see XPDF::InitGrid() |
||
564 | * @param float $fltLineHeight lineheight in mm |
||
565 | */ |
||
566 | public function setLineHeight(float $fltLineHeight) : void |
||
567 | { |
||
568 | $this->fltLineHeight = $fltLineHeight; |
||
569 | } |
||
570 | |||
571 | /** |
||
572 | * Set colors for text and drawing in the pageheader. |
||
573 | * <b>!! Can be controled/overwritten through JSON-Format in InitGrid() !!</b> |
||
574 | * @see XPDF::InitGrid() |
||
575 | * @param string $strTextColor |
||
576 | * @param string $strDrawColor |
||
577 | */ |
||
578 | public function setHeaderColors(string $strTextColor, string $strDrawColor) : void |
||
579 | { |
||
580 | $this->strHeaderTextColor = $strTextColor; |
||
581 | $this->strHeaderDrawColor = $strDrawColor; |
||
582 | } |
||
583 | |||
584 | /** |
||
585 | * Set colors for text and drawing in the colheader. |
||
586 | * <b>!! Can be controled/overwritten through JSON-Format in InitGrid() !!</b> |
||
587 | * @see XPDF::InitGrid() |
||
588 | * @param string $strTextColor |
||
589 | * @param string $strFillColor |
||
590 | */ |
||
591 | public function setColHeaderColors(string $strTextColor, string $strFillColor) : void |
||
592 | { |
||
593 | $this->strColHeaderTextColor = $strTextColor; |
||
594 | $this->strColHeaderFillColor = $strFillColor; |
||
595 | } |
||
596 | |||
597 | /** |
||
598 | * Set colors for text and drawing in the grid. |
||
599 | * <b>!! Can be controled/overwritten through JSON-Format in InitGrid() !!</b> |
||
600 | * @see XPDF::InitGrid() |
||
601 | * @param string $strTextColor |
||
602 | * @param string $strDrawColor |
||
603 | * @param string $strFillColor |
||
604 | * @param bool $bStripped |
||
605 | */ |
||
606 | public function setRowColors(string $strTextColor, string $strDrawColor, string $strFillColor, bool $bStripped = true) : void |
||
607 | { |
||
608 | $this->strRowTextColor = $strTextColor; |
||
609 | $this->strRowDrawColor = $strDrawColor; |
||
610 | $this->strRowFillColor = $strFillColor; |
||
611 | $this->bStripped = $bStripped; |
||
612 | } |
||
613 | |||
614 | /** |
||
615 | * Set colors for text and drawing in the pagefooter. |
||
616 | * <b>!! Can be controled/overwritten through JSON-Format in InitGrid() !!</b> |
||
617 | * @see XPDF::InitGrid() |
||
618 | * @param string $strTextColor |
||
619 | * @param string $strDrawColor |
||
620 | */ |
||
621 | public function setFooterColors(string $strTextColor, string $strDrawColor) : void |
||
622 | { |
||
623 | $this->strFooterTextColor = $strTextColor; |
||
624 | $this->strFooterDrawColor = $strDrawColor; |
||
625 | } |
||
626 | |||
627 | /** |
||
628 | * Enables automatic calclation of totals. |
||
629 | * <ul> |
||
630 | * <li> totals over all at end of grid (self::TOTALS) </li> |
||
631 | * <li> subtotals at end of each page (self::PAGE_TOTALS) </li> |
||
632 | * <li> carry over at beginning of new page (self::CARRY_OVER) </li></ul> |
||
633 | * <b>!! Can be controled/overwritten through JSON-Format in InitGrid() !!</b> |
||
634 | * @see XPDF::InitGrid() |
||
635 | * @param int $iTotals combination of |
||
636 | */ |
||
637 | public function enableTotals(int $iTotals=self::TOTALS) : void |
||
638 | { |
||
639 | $this->bCalcTotals = ($iTotals & self::TOTALS) != 0; |
||
640 | $this->bPageTotals = ($iTotals & self::PAGE_TOTALS) != 0; |
||
641 | $this->bCarryOver = ($iTotals & self::CARRY_OVER) != 0; |
||
642 | if ($this->bPageTotals) { |
||
643 | // we must increase the bottom margin to trigger the pagebreak |
||
644 | $this->setAutoPageBreak(true, self::BOTTOM_MARGIN + $this->fltLineHeight); |
||
645 | } |
||
646 | } |
||
647 | |||
648 | /** |
||
649 | * Set text for totals, subtotals and carry over row. |
||
650 | * Following placeholders will be replaced: <ul> |
||
651 | * <li> {PN} -> current page </li> |
||
652 | * <li> {PN-1} -> previous page </li></ul> |
||
653 | * <b>!! Can be controled/overwritten through JSON-Format in InitGrid() !!</b> |
||
654 | * @see XPDF::InitGrid() |
||
655 | * @param string $strTotals |
||
656 | * @param string $strPageTotals |
||
657 | * @param string $strCarryOver |
||
658 | */ |
||
659 | public function setTotalsText(string $strTotals, string $strPageTotals = '', string $strCarryOver = '') : void |
||
660 | { |
||
661 | $this->strTotals = $strTotals; |
||
662 | if (strlen($strPageTotals) > 0) { |
||
663 | $this->strPageTotals = $strPageTotals; |
||
664 | } |
||
665 | if (strlen($strCarryOver) > 0) { |
||
666 | $this->strCarryOver = $strCarryOver; |
||
667 | } |
||
668 | } |
||
669 | |||
670 | /** |
||
671 | * Add Column to the Grid. |
||
672 | * String is directly mapped to field in datarow, number is requested through Col() method |
||
673 | * @param string $strColHeader title text in the header, if equal -1, colspan of previous col ist increased |
||
674 | * @param float $fltWidth width in mm (if -1, col is enhanced so table uses on full page width) |
||
675 | * @param string $strAlign alignment of datacol 'L', 'C' or 'R' - headerer cells allways centered |
||
676 | * @param string $strField data-field or Column ID. |
||
677 | * @param int $wFlags Flags to define behaviour for column |
||
678 | * @return int Index of the inserted col |
||
679 | */ |
||
680 | public function addCol(string $strColHeader, float $fltWidth, string $strAlign, string $strField, int $wFlags = 0) : int |
||
681 | { |
||
682 | $this->iMaxCol++; |
||
683 | $this->aColWidth[$this->iMaxCol] = $fltWidth; |
||
684 | $this->aColAlign[$this->iMaxCol] = $strAlign; |
||
685 | $this->aColFlags[$this->iMaxCol] = $wFlags; |
||
686 | $this->aColField[$this->iMaxCol] = $strField; |
||
687 | if ($strColHeader != -1) { |
||
688 | $this->iMaxColHeader++; |
||
689 | $this->aColHeader[$this->iMaxColHeader] = $strColHeader; |
||
690 | $this->aColSpan[$this->iMaxColHeader] = 1; |
||
691 | } else { |
||
692 | $this->aColSpan[$this->iMaxColHeader]++; |
||
693 | } |
||
694 | if ($this->iMaxCol == 0 || ($wFlags & self::FLAG_TOTALS) != 0) { |
||
695 | $this->iMaxColTotals++; |
||
696 | $this->aTotals[$this->iMaxCol] = 0.0; |
||
697 | $this->aSubTotals[$this->iMaxCol] = 0.0; |
||
698 | $this->aTotalsColSpan[$this->iMaxColTotals] = 1; |
||
699 | } else { |
||
700 | $this->aTotalsColSpan[$this->iMaxColTotals]++; |
||
701 | } |
||
702 | return $this->iMaxCol; |
||
703 | } |
||
704 | |||
705 | /** |
||
706 | * Set infos for image col. |
||
707 | * Set the margin from the top left corner of the cell and the height/width of the image. <ul> |
||
708 | * <li> If no height and width specified, the image is printed in its origin size </li> |
||
709 | * <li> If only one of both is specified, the image is scaled and the aspect ratio is retained </li></ul> |
||
710 | * @param int $iCol index of the col (usually the return value of the AddCol() Method) |
||
711 | * @param float $fltTop top margin from row in user units |
||
712 | * @param float $fltLeft left margin from cell in user units |
||
713 | * @param float $fltHeight height of the image in user units |
||
714 | * @param float $fltWidth width of the image in user units |
||
715 | */ |
||
716 | public function setColImageInfo(int $iCol, float $fltTop, float $fltLeft, float $fltHeight = -1, float $fltWidth = -1) : void |
||
717 | { |
||
718 | if ($this->aColFlags[$iCol] & self::FLAG_IMAGE == 0) { |
||
719 | trigger_error('Col #' . $iCol . ' is not defined as image col!', E_USER_WARNING); |
||
720 | } |
||
721 | $this->aImgInfo[$iCol] = array( |
||
722 | 'fltTop' => $fltTop, |
||
723 | 'fltLeft' => $fltLeft, |
||
724 | 'fltWidth' => $fltHeight, |
||
725 | 'fltHeight' => $fltWidth); |
||
726 | } |
||
727 | |||
728 | /** |
||
729 | * Have to be called once before datarows be added to the document. |
||
730 | */ |
||
731 | public function prepare() : void |
||
732 | { |
||
733 | $this->calcColWidth(); |
||
734 | $this->bInGrid = true; |
||
735 | $this->addPage(); |
||
736 | |||
737 | $this->selectDrawColor($this->strRowDrawColor); |
||
738 | $this->selectFillColor($this->strRowFillColor); |
||
739 | $this->selectTextColor($this->strRowTextColor); |
||
740 | $this->selectFont($this->fontRows); |
||
741 | $this->setLineWidth(0.2); |
||
742 | } |
||
743 | |||
744 | /** |
||
745 | * Build row. |
||
746 | * If fieldname specified in AddCol(), directly the value from the associative array is inserted |
||
747 | * (in case of DATE-Field value is formated d.m.Y) |
||
748 | * all other columns are requested through GetCol() - method |
||
749 | * @param array $row current row as associative array (may comes from DB query) |
||
750 | */ |
||
751 | public function row(array $row) : void |
||
752 | { |
||
753 | $a = $this->saveSettings(); |
||
754 | $this->iRow++; |
||
755 | if (($strPreRow = $this->preRow($row)) != '') { |
||
756 | $this->subHeader($strPreRow); |
||
757 | } |
||
758 | if (!$this->isRowVisible($row)) { |
||
759 | return; |
||
760 | } |
||
761 | $this->rowInner($row); |
||
762 | $this->postRow($row); |
||
763 | $this->restoreSettings($a); |
||
764 | } |
||
765 | |||
766 | /** |
||
767 | * Mark the end of the grid. |
||
768 | * If totals enabled, total row will be printed. <br/> |
||
769 | */ |
||
770 | public function endGrid() : void |
||
771 | { |
||
772 | $this->totalsRow(self::TOTALS); |
||
773 | // Internal flag is needed to suppress any printing of colheaders or subtotals after end of grid! |
||
774 | $this->bInGrid = false; |
||
775 | } |
||
776 | |||
777 | /** |
||
778 | * Starts group for new subtotals. |
||
779 | * Reset calculated subtotals and print subheader if strHeader is set |
||
780 | * @param string $strTotals |
||
781 | * @param string $strHeader |
||
782 | */ |
||
783 | public function startGroup(string $strTotals, ?string $strHeader = null) : void |
||
784 | { |
||
785 | $this->strSubTotals = $strTotals; |
||
786 | $iCount = count($this->aSubTotals); |
||
787 | for ($i = 0; $i < $iCount; $i++) { |
||
788 | $this->aSubTotals[$i] = 0.0; |
||
789 | } |
||
790 | if ($strHeader) { |
||
791 | $this->subHeader($strHeader); |
||
792 | } |
||
793 | } |
||
794 | |||
795 | /** |
||
796 | * End group and print subtotals row. |
||
797 | */ |
||
798 | public function endGroup() : void |
||
799 | { |
||
800 | $this->totalsRow(self::SUB_TOTALS); |
||
801 | $this->strSubTotals = ''; |
||
802 | } |
||
803 | |||
804 | /** |
||
805 | * Selects given font. |
||
806 | * @param XPDFFont $font |
||
807 | */ |
||
808 | public function selectFont(?XPDFFont $font) : void |
||
809 | { |
||
810 | if ($font !== null) { |
||
811 | $this->setFont($font->strFontname, $font->strStyle, $font->iSize); |
||
812 | } |
||
813 | } |
||
814 | |||
815 | /** |
||
816 | * Set color for text. |
||
817 | * @param string $strColor color to select in HTML-Format #RRGGBB |
||
818 | */ |
||
819 | public function selectTextColor(string $strColor) : void |
||
820 | { |
||
821 | $r = 0; $g = 0; $b = 0; |
||
822 | $this->getRGB($strColor, $r, $g, $b); |
||
823 | $this->setTextColor($r, $g, $b); |
||
824 | } |
||
825 | |||
826 | /** |
||
827 | * Set color for drawing. |
||
828 | * @param string $strColor color to select in HTML-Format #RRGGBB |
||
829 | */ |
||
830 | public function selectDrawColor(string $strColor) : void |
||
831 | { |
||
832 | $r=0; $g=0; $b=0; |
||
833 | $this->getRGB($strColor, $r, $g, $b); |
||
834 | $this->setDrawColor($r, $g, $b); |
||
835 | } |
||
836 | |||
837 | /** |
||
838 | * Set fillcolor. |
||
839 | * @param string $strColor color to select in HTML-Format #RRGGBB |
||
840 | */ |
||
841 | public function selectFillColor(string $strColor) : void |
||
842 | { |
||
843 | $r = 0; $g = 0; $b = 0; |
||
844 | $this->getRGB($strColor, $r, $g, $b); |
||
845 | $this->setFillColor($r, $g, $b); |
||
846 | } |
||
847 | |||
848 | /** |
||
849 | * Get the height of the current font in user units. |
||
850 | * @return float |
||
851 | */ |
||
852 | public function getTextHeight() : float |
||
853 | { |
||
854 | // TODO: ??? |
||
855 | return 1.0; |
||
856 | } |
||
857 | |||
858 | /** |
||
859 | * Last step: create the document. |
||
860 | * If nor filename is given, the title set with SetInfo() or SetTitle() |
||
861 | * method is used (or 'XFPDF.pdf' if no title set so far). |
||
862 | * If the filename not ending with .pdf (case insensitive), the extension ist appended. |
||
863 | * @param string $strFilename Filename |
||
864 | */ |
||
865 | public function createPDF(string $strFilename = '') : void |
||
866 | { |
||
867 | if (empty($strFilename)) { |
||
868 | $strFilename = isset($this->metadata['Title']) ? $this->metadata['Title'] : 'XFPDF.pdf'; |
||
869 | } |
||
870 | if (strtolower(substr($strFilename, -4)) !== '.pdf') { |
||
871 | $strFilename .= '.pdf'; |
||
872 | } |
||
873 | $this->output($strFilename, 'I'); |
||
874 | } |
||
875 | |||
876 | /** |
||
877 | * Print pageheader / logo / colheaders. |
||
878 | * {@inheritDoc} |
||
879 | * @see \OPlathey\FPDF\FPDF::Header() |
||
880 | */ |
||
881 | public function header() : void |
||
882 | { |
||
883 | if (!empty($this->strPageTitle)) { |
||
884 | $fltLogoHeight = 0.0; |
||
885 | if (!empty($this->strLogo)) { |
||
886 | list($iWidth, $iHeight) = getimagesize($this->strLogo); |
||
887 | if ($iWidth > 0 && $iHeight > 0) { |
||
888 | // scale image to desired high |
||
889 | $iWidth *= $this->fltLogoHeight / $iHeight; |
||
890 | $x = $this->w - $this->rMargin - $iWidth - 1; |
||
891 | $y = $this->tMargin + 0.5; |
||
892 | $this->Image($this->strLogo, $x, $y, $iWidth); |
||
893 | $fltLogoHeight = $this->fltLogoHeight; |
||
894 | } |
||
895 | } |
||
896 | |||
897 | $this->selectDrawColor($this->strHeaderDrawColor); |
||
898 | $this->selectFont($this->fontHeader); |
||
899 | $this->selectTextColor($this->strHeaderTextColor); |
||
900 | $this->setLineWidth(0.2); |
||
901 | $strPageTitle = $this->replacePlaceholder($this->strPageTitle); |
||
902 | $strPageSubject = $this->replacePlaceholder($this->strPageSubject); |
||
903 | $this->cell(0, $this->FontSize, $strPageTitle, 0, 0, 'L'); |
||
904 | $this->ln(); |
||
905 | if (strlen($strPageSubject) > 0) { |
||
906 | $this->selectFont($this->fontSubject); |
||
907 | $this->cell(0, $this->FontSize, $strPageSubject, 0, 0, 'L'); |
||
908 | $this->ln(); |
||
909 | } |
||
910 | |||
911 | $y = $this->getY(); |
||
912 | if (($fltLogoHeight + $this->tMargin) > $y) { |
||
913 | $y = $fltLogoHeight + $this->tMargin; |
||
914 | $this->setY($y); |
||
915 | } |
||
916 | $y += 2.0; |
||
917 | $this->line($this->lMargin, $y, $this->w - $this->rMargin, $y); |
||
918 | $y += 0.5; |
||
919 | $this->line($this->lMargin, $y, $this->w - $this->rMargin, $y); |
||
920 | $this->ln(6); |
||
921 | } |
||
922 | if ($this->iMaxCol > 0 && $this->bInGrid) { |
||
923 | $this->colHeader(); |
||
924 | if ($this->bCarryOver && $this->page > 1) { |
||
925 | $this->totalsRow(self::CARRY_OVER); |
||
926 | } |
||
927 | } |
||
928 | } |
||
929 | |||
930 | /** |
||
931 | * Print pagefooter. |
||
932 | * {@inheritDoc} |
||
933 | * @see \OPlathey\FPDF\FPDF::Footer() |
||
934 | */ |
||
935 | public function footer() : void |
||
936 | { |
||
937 | if ($this->bPageTotals) { |
||
938 | $this->totalsRow(self::PAGE_TOTALS); |
||
939 | } |
||
940 | if (!empty($this->strPageFooter)) { |
||
941 | $this->selectDrawColor($this->strFooterDrawColor); |
||
942 | $this->selectFont($this->fontFooter); |
||
943 | $this->selectTextColor($this->strFooterTextColor); |
||
944 | $this->setLineWidth(0.2); |
||
945 | |||
946 | // Position 2mm from the bottom border |
||
947 | $this->setY(-self::BOTTOM_MARGIN + 2); |
||
948 | $this->line($this->lMargin, $this->GetY() - 0.5, $this->w - $this->rMargin, $this->getY() - 0.5); |
||
949 | $iWidth = $this->w - $this->rMargin - $this->lMargin; |
||
950 | $aCell = explode("\t", $this->strPageFooter, 3); |
||
951 | $aAlign = array('', '', ''); |
||
952 | switch (count($aCell)) { |
||
953 | case 1: |
||
954 | $aAlign = array('C', '', ''); |
||
955 | break; |
||
956 | case 2: |
||
957 | $aAlign = array('L', 'R', ''); |
||
958 | break; |
||
959 | case 3: |
||
960 | $aAlign = array('L', 'C', 'R'); |
||
961 | break; |
||
962 | } |
||
963 | $i = 0; |
||
964 | foreach ($aCell as $strCell) { |
||
965 | $strCell = $this->replacePlaceholder($strCell); |
||
966 | $this->cell($iWidth / count($aCell), 7, $strCell, 'T', 0, $aAlign[$i++]); |
||
967 | } |
||
968 | } |
||
969 | } |
||
970 | |||
971 | /** |
||
972 | * Create headercols for grid. |
||
973 | */ |
||
974 | protected function colHeader() : void |
||
975 | { |
||
976 | $this->selectFillColor($this->strColHeaderFillColor); |
||
977 | $this->selectTextColor($this->strColHeaderTextColor); |
||
978 | $this->setLineWidth(0.2); |
||
979 | $this->selectFont($this->fontColHeader); |
||
980 | |||
981 | $iCol = 0; |
||
982 | for ($i = 0; $i <= $this->iMaxColHeader; $i++) { |
||
983 | $iWidth = 0; |
||
984 | if ($this->aColSpan[$i] > 1) { |
||
985 | $j = 0; |
||
986 | while ($j < $this->aColSpan[$i]) { |
||
987 | $iWidth += $this->aColWidth[$iCol++]; |
||
988 | $j++; |
||
989 | } |
||
990 | } else { |
||
991 | $iWidth = $this->aColWidth[$iCol++]; |
||
992 | } |
||
993 | |||
994 | $strHeader = $this->aColHeader[$i]; |
||
995 | $this->cell($iWidth, $this->fltLineHeight, $strHeader, 1, 0, 'C', true); |
||
996 | } |
||
997 | $this->ln(); |
||
998 | } |
||
999 | |||
1000 | /** |
||
1001 | * Insert Subheader into the grid. |
||
1002 | * @param string $strText |
||
1003 | */ |
||
1004 | protected function subHeader(string $strText) : void |
||
1005 | { |
||
1006 | $a = $this->saveSettings(); |
||
1007 | |||
1008 | $this->selectFillColor($this->strSubHeaderFillColor); |
||
1009 | $this->selectTextColor($this->strSubHeaderTextColor); |
||
1010 | $this->selectFont($this->fontSubHeader); |
||
1011 | |||
1012 | // increase pagebreak trigger to ensure not only subheader fits on current page |
||
1013 | $iBottomMargin = $this->bMargin; |
||
1014 | $this->setAutoPageBreak(true, $iBottomMargin + $this->fltLineHeight); |
||
1015 | $iWidth = $this->w - $this->lMargin - $this->rMargin; |
||
1016 | $this->cell($iWidth, $this->fltLineHeight, $strText, $this->border, 0, 'L', true); |
||
1017 | $this->ln(); |
||
1018 | $this->restoreSettings($a); |
||
1019 | // reset pagebreak trigger |
||
1020 | $this->setAutoPageBreak(true, $iBottomMargin); |
||
1021 | } |
||
1022 | |||
1023 | /** |
||
1024 | * Calculates width for dynamic col. |
||
1025 | * Dynamic col is specified with a width of -1. <br/> |
||
1026 | * <b>Only one col with width of -1 is allowed!</b> <br/> |
||
1027 | * If no dyn. Col is specified, last col is assumed as dynamic. <br/><br/> |
||
1028 | * Sum of all other cols is subtracted from page width. <br/> |
||
1029 | */ |
||
1030 | protected function calcColWidth() : void |
||
1031 | { |
||
1032 | $iGridWidth = $this->w - $this->lMargin - $this->rMargin; |
||
1033 | $iCol = -1; |
||
1034 | for ($i = 0; $i <= $this->iMaxCol; $i++) { |
||
1035 | if ($this->aColWidth[$i] < 0) { |
||
1036 | if ($iCol >= 0) { |
||
1037 | trigger_error('Only one dynamic col is allowed!', E_USER_WARNING); |
||
1038 | } |
||
1039 | $iCol = $i; |
||
1040 | } |
||
1041 | } |
||
1042 | if ($iCol < 0) { |
||
1043 | $iCol = $this->iMaxCol; |
||
1044 | } |
||
1045 | $iWidth = 0; |
||
1046 | for ($i = 0; $i <= $this->iMaxCol; $i++) { |
||
1047 | if ($i != $iCol) { |
||
1048 | $iWidth += $this->aColWidth[$i]; |
||
1049 | } |
||
1050 | } |
||
1051 | $this->aColWidth[$iCol] = $iGridWidth - $iWidth; |
||
1052 | } |
||
1053 | |||
1054 | /** |
||
1055 | * Inner 'pure' function to build the row. |
||
1056 | * @param array $row |
||
1057 | */ |
||
1058 | protected function rowInner(array $row) : void |
||
1059 | { |
||
1060 | $this->bInGrid = true; |
||
1061 | for ($i = 0; $i <= $this->iMaxCol; $i++) { |
||
1062 | $strCell = ''; |
||
1063 | $field = $this->aColField[$i]; |
||
1064 | $wFlags = $this->aColFlags[$i]; |
||
1065 | $bFill = $this->bStripped && (($this->iRow % 2) == 0); |
||
1066 | |||
1067 | // calc totals if enabled |
||
1068 | if ($this->bCalcTotals && ($wFlags & self::FLAG_TOTALS_CALC) != 0) { |
||
1069 | if (is_numeric($row[$field]) || is_float($row[$field])) { |
||
1070 | $this->aTotals[$i] += $row[$field]; |
||
1071 | $this->aSubTotals[$i] += $row[$field]; |
||
1072 | } |
||
1073 | } |
||
1074 | |||
1075 | // save for restore, if changed for current col |
||
1076 | $a = $this->saveSettings(); |
||
1077 | |||
1078 | if (is_numeric($field)) { |
||
1079 | // get value from derived class |
||
1080 | $strCell = $this->col($field, $row, $bFill); |
||
1081 | } else { |
||
1082 | // directly get value from row data |
||
1083 | if (!isset($row[$field])) { |
||
1084 | $strCell = ''; |
||
1085 | } else { |
||
1086 | $strCell = $row[$field]; |
||
1087 | } |
||
1088 | $strCell = $this->formatValue($strCell, $wFlags); |
||
1089 | } |
||
1090 | $link = ''; |
||
1091 | if (($wFlags & self::FLAG_INT_LINK) != 0) { |
||
1092 | $link = $this->internalLink($i, $row); |
||
1093 | $this->setFont('', 'U'); |
||
1094 | $this->selectTextColor($this->strLinkTextColor); |
||
1095 | } |
||
1096 | |||
1097 | $iWidth = $this->aColWidth[$i]; |
||
1098 | $strAlign = $this->aColAlign[$i]; |
||
1099 | if (($wFlags & self::FLAG_IMAGE) != 0) { |
||
1100 | $fltTop = $this->getY(); |
||
1101 | $fltLeft = $this->getX(); |
||
1102 | $fltHeight = 0; |
||
1103 | $fltWidth = 0; |
||
1104 | if (isset($this->aImgInfo[$i])) { |
||
1105 | $fltTop += $this->aImgInfo[$i]['fltTop']; |
||
1106 | $fltLeft += $this->aImgInfo[$i]['fltLeft']; |
||
1107 | if ($this->aImgInfo[$i]['fltHeight'] > 0) { |
||
1108 | $fltHeight = $this->aImgInfo[$i]['fltHeight']; |
||
1109 | } |
||
1110 | if ($this->aImgInfo[$i]['fltWidth'] > 0) { |
||
1111 | $fltWidth = $this->aImgInfo[$i]['fltWidth']; |
||
1112 | } |
||
1113 | } |
||
1114 | $this->cell($iWidth, $this->fltLineHeight, '', $this->border, 0, $strAlign, $bFill, $link); |
||
1115 | $this->image($strCell, $fltLeft, $fltTop, $fltWidth, $fltHeight); |
||
1116 | } else { |
||
1117 | $strCell = $this->convText($strCell); |
||
1118 | $this->cell($iWidth, $this->fltLineHeight, $strCell, $this->border, 0, $strAlign, $bFill, $link); |
||
1119 | } |
||
1120 | |||
1121 | $this->restoreSettings($a); |
||
1122 | } |
||
1123 | $this->ln(); |
||
1124 | } |
||
1125 | |||
1126 | /** |
||
1127 | * Print totals/subtotals row. |
||
1128 | * @param int $iTotals |
||
1129 | */ |
||
1130 | protected function totalsRow(int $iTotals) : void |
||
1131 | { |
||
1132 | if ($this->bInGrid && $this->bCalcTotals) { |
||
1133 | $a = $this->saveSettings(); |
||
1134 | $this->setTotalsRowFormat($iTotals); |
||
1135 | $aTotals = $this->getTotalsRowValues($iTotals); |
||
1136 | $strText = $this->getTotalsRowText($iTotals); |
||
1137 | $iCol = 0; |
||
1138 | for ($iTotalsCol = 0; $iTotalsCol <= $this->iMaxColTotals; $iTotalsCol++) { |
||
1139 | $strCol = ''; |
||
1140 | $strAlign = 'C'; |
||
1141 | |||
1142 | if ($this->isTotalsTextCol($iCol)) { |
||
1143 | $strCol = $this->convText($strText); |
||
1144 | $strAlign = 'L'; |
||
1145 | } elseif ($this->isTotalsCalcCol($iCol)) { |
||
1146 | $strCol = $this->formatValue($aTotals[$iCol], $this->aColFlags[$iCol]); |
||
1147 | $strAlign = 'R'; |
||
1148 | } |
||
1149 | $iWidth = $this->calcTotalsColWidth($iTotalsCol, $iCol); |
||
1150 | $this->cell($iWidth, $this->fltLineHeight, $this->convText($strCol), 1, 0, $strAlign, true); |
||
1151 | $iCol += $this->aTotalsColSpan[$iTotalsCol]; |
||
1152 | } |
||
1153 | $this->ln(); |
||
1154 | $this->restoreSettings($a); |
||
1155 | } |
||
1156 | } |
||
1157 | |||
1158 | /** |
||
1159 | * Set the format for the requested totals row. |
||
1160 | * - totals and pagetotals use colors and font from ColHeader <br/> |
||
1161 | * - all other types uses format from subheader <br/> |
||
1162 | * @param int $iTotals |
||
1163 | */ |
||
1164 | protected function setTotalsRowFormat(int $iTotals) : void |
||
1165 | { |
||
1166 | if ($iTotals == self::TOTALS || $iTotals == self::PAGE_TOTALS) { |
||
1167 | $this->selectFillColor($this->strColHeaderFillColor); |
||
1168 | $this->selectTextColor($this->strColHeaderTextColor); |
||
1169 | $this->setLineWidth(0.2); |
||
1170 | $this->selectFont($this->fontColHeader); |
||
1171 | } else { |
||
1172 | $this->selectFillColor($this->strSubHeaderFillColor); |
||
1173 | $this->selectTextColor($this->strSubHeaderTextColor); |
||
1174 | $this->setLineWidth(0.2); |
||
1175 | $this->selectFont($this->fontSubHeader); |
||
1176 | } |
||
1177 | } |
||
1178 | |||
1179 | /** |
||
1180 | * Get the tect for requested totals row. |
||
1181 | * Get the text dependent on the type of the totals row and replaace |
||
1182 | * all supported placeholders. |
||
1183 | * @param int $iTotals |
||
1184 | * @return string |
||
1185 | */ |
||
1186 | protected function getTotalsRowText(int $iTotals) : string |
||
1187 | { |
||
1188 | $strText = ''; |
||
1189 | switch ($iTotals) { |
||
1190 | case self::TOTALS: |
||
1191 | $strText = $this->strTotals; |
||
1192 | break; |
||
1193 | case self::PAGE_TOTALS: |
||
1194 | $strText = $this->strPageTotals; |
||
1195 | break; |
||
1196 | case self::CARRY_OVER: |
||
1197 | $strText = $this->strCarryOver; |
||
1198 | break; |
||
1199 | case self::SUB_TOTALS: |
||
1200 | $strText = $this->strSubTotals; |
||
1201 | break; |
||
1202 | default: |
||
1203 | break; |
||
1204 | } |
||
1205 | // replace supported placeholders |
||
1206 | $strText = str_replace('{PN}', strval($this->page), $strText); |
||
1207 | $strText = str_replace('{PN-1}', strval($this->page - 1), $strText); |
||
1208 | return $strText; |
||
1209 | } |
||
1210 | |||
1211 | /** |
||
1212 | * Get the calculated values for the requested totals row. |
||
1213 | * @param int $iTotals |
||
1214 | * @return array |
||
1215 | */ |
||
1216 | protected function getTotalsRowValues(int $iTotals) : array |
||
1217 | { |
||
1218 | if ($iTotals == self::SUB_TOTALS) { |
||
1219 | return $this->aSubTotals; |
||
1220 | } else { |
||
1221 | return $this->aTotals; |
||
1222 | } |
||
1223 | } |
||
1224 | |||
1225 | /** |
||
1226 | * Check, if requested col is set for the output of totals text. |
||
1227 | * @param int $iCol |
||
1228 | * @return bool |
||
1229 | */ |
||
1230 | protected function isTotalsTextCol(int $iCol) : bool |
||
1231 | { |
||
1232 | return ($this->aColFlags[$iCol] & self::FLAG_TOTALS_TEXT) != 0; |
||
1233 | } |
||
1234 | |||
1235 | /** |
||
1236 | * Check, if requested col is defined for totals calculation. |
||
1237 | * @param int $iCol |
||
1238 | * @return bool |
||
1239 | */ |
||
1240 | protected function isTotalsCalcCol(int $iCol) : bool |
||
1241 | { |
||
1242 | return ($this->aColFlags[$iCol] & self::FLAG_TOTALS_CALC) != 0; |
||
1243 | } |
||
1244 | |||
1245 | /** |
||
1246 | * Calculates the width of the requested totals col. |
||
1247 | * |
||
1248 | * @param int $iTotalsCol |
||
1249 | * @param int $iCol |
||
1250 | * @return float |
||
1251 | */ |
||
1252 | protected function calcTotalsColWidth(int $iTotalsCol, int $iCol) : float |
||
1253 | { |
||
1254 | $fltWidth = 0; |
||
1255 | if ($this->aTotalsColSpan[$iTotalsCol] > 1) { |
||
1256 | $j = 0; |
||
1257 | while ($j < $this->aTotalsColSpan[$iTotalsCol]) { |
||
1258 | $fltWidth += $this->aColWidth[$iCol++]; |
||
1259 | $j++; |
||
1260 | } |
||
1261 | } else { |
||
1262 | $fltWidth = $this->aColWidth[$iCol++]; |
||
1263 | } |
||
1264 | return $fltWidth; |
||
1265 | } |
||
1266 | |||
1267 | /** |
||
1268 | * Hook to hide a row dependend on row data. |
||
1269 | * Can be overloaded in subclass to hide a row. |
||
1270 | * @param array $row |
||
1271 | * @return bool function must return false, if row should not be printed |
||
1272 | */ |
||
1273 | protected function isRowVisible(/** @scrutinizer ignore-unused */ array $row) : bool |
||
1274 | { |
||
1275 | return true; |
||
1276 | } |
||
1277 | |||
1278 | /** |
||
1279 | * Called before next row is printed. |
||
1280 | * This function can be overloaded in derived class to <ul> |
||
1281 | * <li> change row data or add values </li> |
||
1282 | * <li> specify text for subtitle before row is printed </li></ul> |
||
1283 | * The $row parameter is defined as reference so $row may be changed within function in derived class. <br/> |
||
1284 | * If the method returns a non-empty string, a subtitle containing the text is printed before the row |
||
1285 | * @param array $row |
||
1286 | * @return string |
||
1287 | */ |
||
1288 | protected function preRow(/** @scrutinizer ignore-unused */ array &$row) : string |
||
1289 | { |
||
1290 | return ''; |
||
1291 | } |
||
1292 | |||
1293 | /** |
||
1294 | * Called after the output of a row. |
||
1295 | * To be overloaded in derived class |
||
1296 | * @param array $row |
||
1297 | */ |
||
1298 | protected function postRow(/** @scrutinizer ignore-unused */ array $row) : void |
||
1299 | { |
||
1300 | } |
||
1301 | |||
1302 | /** |
||
1303 | * Get content of a col for current row - to overide in derived class. |
||
1304 | * @param int $iCol requested colnumber defined in AddCol() |
||
1305 | * @param array $row current record from DB |
||
1306 | * @param bool $bFill |
||
1307 | * @return string |
||
1308 | */ |
||
1309 | protected function col(int $iCol, array $row, /** @scrutinizer ignore-unused */ bool &$bFill) : string |
||
1320 | } |
||
1321 | |||
1322 | /** |
||
1323 | * @param int $iCol |
||
1324 | * @param array $row |
||
1325 | * @return int |
||
1326 | */ |
||
1327 | protected function internalLink(/** @scrutinizer ignore-unused */ int $iCol, /** @scrutinizer ignore-unused */ array $row) : int |
||
1328 | { |
||
1329 | return $this->addLink(); |
||
1330 | } |
||
1331 | |||
1332 | /** |
||
1333 | * Divides color in HTML notation into red, green and blue component |
||
1334 | * @param string $strColor color in HTML notation #RRGGBB |
||
1335 | * @param int $r red component of color |
||
1336 | * @param int $g green component of color |
||
1337 | * @param int $b blue component of color |
||
1338 | */ |
||
1339 | protected function getRGB(string $strColor, int &$r, int &$g, int &$b) : void |
||
1340 | { |
||
1341 | if ($strColor[0] == '#') { |
||
1342 | if (strlen($strColor) == 7) { |
||
1343 | $r = intval(substr($strColor, 1, 2), 16); |
||
1344 | $g = intval(substr($strColor, 3, 2), 16); |
||
1345 | $b = intval(substr($strColor, 5, 2), 16); |
||
1346 | } elseif (strlen($strColor) == 4) { |
||
1347 | $r = intval(substr($strColor, 1, 1), 16); |
||
1348 | $g = intval(substr($strColor, 2, 1), 16); |
||
1349 | $b = intval(substr($strColor, 3, 1), 16); |
||
1350 | $r = $r + (16 * $r); |
||
1351 | $g = $g + (16 * $g); |
||
1352 | $b = $b + (16 * $b); |
||
1353 | } |
||
1354 | } |
||
1355 | } |
||
1356 | |||
1357 | /** |
||
1358 | * Save some setting to restore after operations changing settings. |
||
1359 | * @return array |
||
1360 | */ |
||
1361 | protected function saveSettings() : array |
||
1362 | { |
||
1363 | $a = array(); |
||
1364 | |||
1365 | $a['family'] = $this->FontFamily; |
||
1366 | $a['style'] = $this->FontStyle; |
||
1367 | $a['size'] = $this->FontSizePt; |
||
1368 | $a['ul'] = $this->underline; |
||
1369 | $a['lw'] = $this->LineWidth; |
||
1370 | $a['dc'] = $this->DrawColor; |
||
1371 | $a['fc'] = $this->FillColor; |
||
1372 | $a['tc'] = $this->TextColor; |
||
1373 | $a['cf'] = $this->ColorFlag; |
||
1374 | |||
1375 | return $a; |
||
1376 | } |
||
1377 | |||
1378 | /** |
||
1379 | * Restore settings. |
||
1380 | * Restore only values differing |
||
1381 | * @param array $a |
||
1382 | */ |
||
1383 | protected function restoreSettings(array $a) : void |
||
1384 | { |
||
1385 | // Restore line width |
||
1386 | if ($this->LineWidth != $a['lw']) { |
||
1387 | $this->LineWidth = $a['lw']; |
||
1388 | $this->out(sprintf( '%.2F w', $a['lw'] * $this->k)); |
||
1389 | } |
||
1390 | // Restore font |
||
1391 | if (($a['family'] != $this->FontFamily) || |
||
1392 | $a['style'] != $this->FontStyle || |
||
1393 | $a['size'] != $this->FontSizePt) { |
||
1394 | $this->setFont($a['family'], $a['style'], $a['size']); |
||
1395 | } |
||
1396 | $this->underline = $a['ul']; |
||
1397 | |||
1398 | // Restore colors |
||
1399 | if ($this->DrawColor != $a['dc']) { |
||
1400 | $this->DrawColor = $a['dc']; |
||
1401 | $this->out($a['dc']); |
||
1402 | } |
||
1403 | if ($this->FillColor != $a['fc']) { |
||
1404 | $this->FillColor = $a['fc']; |
||
1405 | $this->out($a['fc']); |
||
1406 | } |
||
1407 | $this->TextColor = $a['tc']; |
||
1408 | $this->ColorFlag = $a['cf']; |
||
1409 | } |
||
1410 | |||
1411 | /** |
||
1412 | * Checks if object contains property with given name. |
||
1413 | * If object doesn't have requested property, default value will be returned |
||
1414 | * @param \stdClass $obj from JSON-Data |
||
1415 | * @param string $strName |
||
1416 | * @param mixed $default |
||
1417 | * @return mixed |
||
1418 | */ |
||
1419 | protected function property(\stdClass $obj, string $strName, $default = '') |
||
1420 | { |
||
1421 | $value = $default; |
||
1422 | if (property_exists($obj, $strName)) { |
||
1423 | $value = $obj->$strName; |
||
1424 | } |
||
1425 | return $value; |
||
1426 | } |
||
1427 | |||
1428 | /** |
||
1429 | * Checks if object contains font property with given name. |
||
1430 | * If object doesn't have requested property, default font will be returned |
||
1431 | * @param \stdClass $obj |
||
1432 | * @param string $strName |
||
1433 | * @param XPDFFont $fontDefault |
||
1434 | * @return XPDFFont |
||
1435 | */ |
||
1436 | protected function propertyFont(\stdClass $obj, string $strName, XPDFFont $fontDefault) : XPDFFont |
||
1437 | { |
||
1438 | $font = $fontDefault; |
||
1439 | if (property_exists($obj, $strName)) { |
||
1440 | $oFont = $obj->$strName; |
||
1441 | $font = new XPDFFont($oFont->name, $oFont->style, $oFont->size); |
||
1442 | } |
||
1443 | return $font; |
||
1444 | } |
||
1445 | |||
1446 | /** |
||
1447 | * @param string $strText |
||
1448 | * @return string |
||
1449 | */ |
||
1450 | protected function convText(string $strText) : string |
||
1451 | { |
||
1452 | // $strCharset = mb_detect_encoding($strText); |
||
1453 | if ($this->strCharset != 'UTF-8') { |
||
1454 | $strText = iconv('UTF-8', $this->strCharset, $strText); |
||
1455 | } |
||
1456 | return html_entity_decode($strText, ENT_QUOTES, 'UTF-8'); |
||
1457 | } |
||
1458 | |||
1459 | /** |
||
1460 | * Formatting of the cell data. |
||
1461 | * @param mixed $value |
||
1462 | * @param int $iFormat |
||
1463 | * @return string |
||
1464 | */ |
||
1465 | protected function formatValue($value, int $iFormat) : string |
||
1466 | { |
||
1467 | $strValue = strval($value); |
||
1468 | if (($iFormat & self::FLAG_NO_ZERO) && floatval($value) != 0.0) { |
||
1469 | // suppress zero values... |
||
1470 | $strValue = ''; |
||
1471 | } else { |
||
1472 | switch ($iFormat & self::FLAG_FORMAT) { |
||
1473 | case self::FLAG_CUR_SYMBOL: |
||
1474 | $strValue = $this->formatCurrency(floatval($value), true); |
||
1475 | break; |
||
1476 | case self::FLAG_CUR_PLAIN: |
||
1477 | $strValue = $this->formatCurrency(floatval($value), false); |
||
1478 | break; |
||
1479 | case self::FLAG_DATE: |
||
1480 | $strValue = $this->formatDate($value); |
||
1481 | break; |
||
1482 | case self::FLAG_TIME: |
||
1483 | $strValue = $this->formatTime($value); |
||
1484 | break; |
||
1485 | case self::FLAG_DATE_TIME: |
||
1486 | $strValue = $this->formatDateTime($value); |
||
1487 | break; |
||
1488 | case self::FLAG_NUMBER: |
||
1489 | $strValue = $this->formatNumber(floatval($value)); |
||
1490 | break; |
||
1491 | } |
||
1492 | } |
||
1493 | return $strValue; |
||
1494 | } |
||
1495 | |||
1496 | /** |
||
1497 | * Formats value as number according to locale settings on system. |
||
1498 | * @param float $fltValue |
||
1499 | * @param int $iDecimals |
||
1500 | * @param string $strPrefix |
||
1501 | * @param string $strSuffix |
||
1502 | * @return string |
||
1503 | */ |
||
1504 | protected function formatNumber(float $fltValue, ?int $iDecimals = null, ?string $strPrefix = null, ?string $strSuffix = null) : string |
||
1505 | { |
||
1506 | if (!$this->bInvalidLocale) { |
||
1507 | $li = localeconv(); |
||
1508 | } else { |
||
1509 | $li = array('decimal_point' => '.', 'thousands_sep' => ','); |
||
1510 | } |
||
1511 | $iDecimals ??= $this->iNumberDecimals; |
||
1512 | $strPrefix ??= $this->strNumberPrefix; |
||
1513 | $strSuffix ??= $this->strNumberSuffix; |
||
1514 | $strValue = number_format($fltValue, $iDecimals, $li['decimal_point'], $li['thousands_sep']); |
||
1515 | if (strlen($strPrefix) > 0) { |
||
1516 | $strValue .= $strPrefix . $strValue; |
||
1517 | } |
||
1518 | if (strlen($strSuffix) > 0) { |
||
1519 | $strValue = $strValue . $strSuffix; |
||
1520 | } |
||
1521 | return $strValue; |
||
1522 | } |
||
1523 | |||
1524 | /** |
||
1525 | * Formats value as localized currency. |
||
1526 | * money_format($format, $number) has been DEPRECATED as of PHP 7.4.0. |
||
1527 | * @param float $fltValue |
||
1528 | * @param bool $bSymbol |
||
1529 | * @return string |
||
1530 | */ |
||
1531 | protected function formatCurrency(float $fltValue, bool $bSymbol = true) : string |
||
1532 | { |
||
1533 | if (!$this->bInvalidLocale) { |
||
1534 | $li = localeconv(); |
||
1535 | } else { |
||
1536 | $li = array('mon_decimal_point' => '.', 'mon_thousands_sep' => ','); |
||
1537 | $bSymbol = false; |
||
1538 | } |
||
1539 | $strValue = number_format($fltValue, 2, $li['mon_decimal_point'], $li['mon_thousands_sep']); |
||
1540 | if ($bSymbol) { |
||
1541 | $bPrecedes = ($fltValue >= 0 ? $li['p_cs_precedes'] : $li['n_cs_precedes']); |
||
1542 | $bSpace = ($fltValue >= 0 ? $li['p_sep_by_space'] : $li['n_sep_by_space']); |
||
1543 | $strSep = $bSpace ? ' ' : ''; |
||
1544 | if ($bPrecedes) { |
||
1545 | $strValue = $li['currency_symbol'] . $strSep . $strValue; |
||
1546 | } else { |
||
1547 | $strValue = $strValue . $strSep . $li['currency_symbol']; |
||
1548 | } |
||
1549 | } |
||
1550 | return $strValue; |
||
1551 | } |
||
1552 | |||
1553 | /** |
||
1554 | * Format date. |
||
1555 | * uses strftime() |
||
1556 | * @param mixed $Date DateTime-Object, unix timestamp or valid Date string |
||
1557 | * @return string |
||
1558 | */ |
||
1559 | protected function formatDate($Date) : string |
||
1560 | { |
||
1561 | $strDate = ''; |
||
1562 | if (is_object($Date) && get_class($Date) == 'DateTime') { |
||
1563 | // DateTime-object |
||
1564 | $strDate = strftime($this->strFormatD, $Date->getTimestamp()); |
||
1565 | } else if (is_numeric($Date)) { |
||
1566 | $strDate = strftime($this->strFormatD, $Date); |
||
1567 | } else { |
||
1568 | $unixtime = strtotime($Date); |
||
1569 | $strDate = ($unixtime === false) ? 'invalid' : strftime($this->strFormatD, $unixtime); |
||
1570 | } |
||
1571 | return $strDate; |
||
1572 | } |
||
1573 | |||
1574 | /** |
||
1575 | * Format time. |
||
1576 | * uses strftime() |
||
1577 | * @param mixed $Time DateTime-Object, unix timestamp or valid Time string |
||
1578 | * @return string |
||
1579 | */ |
||
1580 | protected function formatTime($Time) : string |
||
1581 | { |
||
1582 | $strTime = ''; |
||
1583 | if (is_object($Time) && get_class($Time) == 'DateTime') { |
||
1584 | // DateTime-object |
||
1585 | $strTime = strftime($this->strFormatT, $Time->getTimestamp()); |
||
1586 | } else if (is_numeric($Time)) { |
||
1587 | $strTime = strftime($this->strFormatT, $Time); |
||
1588 | } else { |
||
1589 | $strTime = strftime($this->strFormatT, strtotime($Time)); |
||
1590 | } |
||
1591 | return $strTime; |
||
1592 | } |
||
1593 | |||
1594 | /** |
||
1595 | * Format date time. |
||
1596 | * uses strftime() |
||
1597 | * @param mixed $DT DateTime-Object, unix timestamp or valid DateTime string |
||
1598 | * @return string |
||
1599 | */ |
||
1600 | protected function formatDateTime($DT) : string |
||
1601 | { |
||
1602 | $strDT = ''; |
||
1603 | if (is_object($DT) && get_class($DT) == 'DateTime') { |
||
1604 | // DateTime-object |
||
1605 | $strDT = strftime($this->strFormatDT, $DT->getTimestamp()); |
||
1606 | } else if (is_numeric($DT)) { |
||
1607 | $strDT = strftime($this->strFormatDT, $DT); |
||
1608 | } else { |
||
1609 | $strDT = strftime($this->strFormatDT, strtotime($DT)); |
||
1610 | } |
||
1611 | return $strDT; |
||
1612 | } |
||
1613 | |||
1614 | /** |
||
1615 | * Replace the placeholders that can be used in header and footer. |
||
1616 | * @param string $strText |
||
1617 | * @return string |
||
1618 | */ |
||
1619 | protected function replacePlaceholder(string $strText) : string |
||
1626 | } |
||
1627 | } |
||
1628 |