Completed
Push — master ( b96a07...d3cdb3 )
by Hannes
04:22 queued 03:33
created

FPDF::Cell()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 13
c 0
b 0
f 0
rs 9.8333
cc 1
nc 1
nop 8

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
/**
3
 *
4
 * Copyright (c) 2011, Hannes Forsgård
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software to use, copy, modify, distribute, sublicense, and/or sell
8
 * copies of the software, and to permit persons to whom the software is
9
 * furnished to do so.
10
 *
11
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12
 * IMPLIED.
13
 *
14
 * @author Hannes Forsgård <[email protected]>
15
 *
16
 */
17
namespace byrokrat\paperinvoice;
18
19
use FPDF as BaseFPDF;
20
21
22
/**
23
 *
24
 * FPDF extension class.
25
 *
26
 */
27
class FPDF extends BaseFPDF
28
{
29
    /**
30
     *
31
     * Current count of pages.
32
     *
33
     * @var int $nrOfPages
34
     *
35
     */
36
    private $nrOfPages = 0;
37
38
    /**
39
     *
40
     * Path to search for images in.
41
     *
42
     * @var string $imagePath
43
     *
44
     */
45
    private $imagePath = "";
46
47
    /**
48
     *
49
     * Keep track of added fonts.
50
     *
51
     * @var array $addedFonts
52
     *
53
     */
54
    private $addedFonts = array();
55
56
    /**
57
     *
58
     * Set standard margin, orientation, units used and paper size
59
     *
60
     * @param int $margin Marginsize in user units.
61
     *
62
     * @param char $orientation Default page orientation. 'P' for portrait or
63
     * 'L' for landscape
64
     *
65
     * @param string $unit User units. 'pt' for points, 'mm' for millimeters,
66
     * 'cm' for centimetera or 'in' for inches
67
     *
68
     * @param string|array $format The size used for pages. 'A3', 'A4', 'A5',
69
     * 'Letter' or 'Legal'. May also be an array of height and width specified
70
     * in user units.
71
     *
72
     */
73
    public function __construct(
74
        $margin = 20,
75
        $orientation = 'P',
76
        $unit = 'mm',
77
        $format = 'A4'
78
    ) {
79
        parent::__construct($orientation, $unit, $format);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class FPDF as the method __construct() does only exist in the following sub-classes of FPDF: byrokrat\paperinvoice\FPDF, byrokrat\paperinvoice\PaperInvoice. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
80
        $this->AliasNbPages('{{{nb}}}');
81
        $this->SetMargins($margin, $margin);
82
        $this->SetAutoPageBreak(TRUE, $margin);
83
    }
84
85
    /**
86
     *
87
     * Adds a new page to the document.
88
     *
89
     * Extends FPDF by keeping track of number of pages added.
90
     *
91
     * @param string $orientation Page orientation. 'P' for portrait or 'L' for
92
     * landscape. The default value is the one passed to the constructor.
93
     *
94
     * @param string $format The size used for pages. 'A3', 'A4', 'A5',
95
     * 'Letter' or 'Legal'. May also be an array of height and width specified
96
     * in user units. The default value is the one passed to the constructor.
97
     *
98
     * @return void
99
     *
100
     */
101
    public function AddPage($orientation = '', $format = '')
102
    {
103
        $this->nrOfPages++;
104
        parent::AddPage($orientation, $format);
105
    }
106
107
    /**
108
     *
109
     * Get the current number of pages added with AddPage().
110
     *
111
     * Note that this number will increase as you add more pages. Should not be
112
     * used to print the total number of pages in document. For this use
113
     * TotalPagesNo().
114
     *
115
     * @return int Number of pages currently in document
116
     *
117
     */
118
    public function PagesAdded()
119
    {
120
        return $this->nrOfPages;
121
    }
122
123
    /**
124
     *
125
     * Shorthand to get total number of pages in pdf
126
     *
127
     * @return string Returns a string that will be replaced with the total
128
     * number of pages when pdf is rendered
129
     *
130
     */
131
    public function TotalPagesNo()
132
    {
133
        return $this->AliasNbPages;
134
    }
135
136
    /**
137
     *
138
     * Shorthand to get current page/total pages.
139
     *
140
     * @param string $delim Delimiter used between current and page number and
141
     * total pages number.
142
     *
143
     * @return string Returns a string that will be replaced with current page
144
     * number, then delimiter, then the total number of pages.
145
     *
146
     */
147
    public function PaginationStr($delim = '/')
148
    {
149
        return $this->PageNo() . $delim . $this->TotalPagesNo();
150
    }
151
152
    /**
153
     *
154
     * Increase the abscissa of the current position.
155
     *
156
     * @param int $x
157
     *
158
     * @return void
159
     *
160
     */
161
    public function moveX($x)
162
    {
163
        $posX = $this->GetX();
164
        $posX += $x;
165
        $this->SetX($posX);
166
    }
167
168
    /**
169
     *
170
     * Increase the ordinate of the current position.
171
     *
172
     * @param int $y
173
     *
174
     * @return void
175
     *
176
     */
177
    public function moveY($y)
178
    {
179
        $posX = $this->GetX();
180
        $posY = $this->GetY();
181
        $posY += $y;
182
        $this->SetXY($posX, $posY);
183
    }
184
185
    /**
186
     *
187
     * Wrapper to solve utf-8 issues.
188
     *
189
     * @param string $title
190
     *
191
     * @param bool $isUTF8 Defaults to TRUE.
192
     *
193
     * @return void
194
     *
195
     */
196
    public function SetTitle($title, $isUTF8 = TRUE)
197
    {
198
        parent::SetTitle($title, $isUTF8);
199
    }
200
201
    /**
202
     *
203
     * Wrapper to solve utf-8 issues.
204
     *
205
     * @param string $subject
206
     *
207
     * @param bool $isUTF8 Defaults to TRUE.
208
     *
209
     * @return void
210
     *
211
     */
212
    public function SetSubject($subject, $isUTF8 = TRUE)
213
    {
214
        parent::SetSubject($subject, $isUTF8);
215
    }
216
217
    /**
218
     *
219
     * Wrapper to solve utf-8 issues.
220
     *
221
     * @param string $author
222
     *
223
     * @param bool $isUTF8 Defaults to TRUE.
224
     *
225
     * @return void
226
     *
227
     */
228
    public function SetAuthor($author, $isUTF8 = TRUE)
229
    {
230
        parent::SetAuthor($author, $isUTF8);
231
    }
232
233
    /**
234
     *
235
     * Wrapper to solve utf-8 issues.
236
     *
237
     * @param string $keywords
238
     *
239
     * @param bool $isUTF8 Defaults to TRUE.
240
     *
241
     * @return void
242
     *
243
     */
244
    public function SetKeywords($keywords, $isUTF8 = TRUE)
245
    {
246
        parent::SetKeywords($keywords, $isUTF8);
247
    }
248
249
    /**
250
     *
251
     * Wrapper to solve utf-8 issues.
252
     *
253
     * @param string $creator
254
     *
255
     * @param bool $isUTF8 Defaults to TRUE.
256
     *
257
     * @return void
258
     *
259
     */
260
    public function SetCreator($creator, $isUTF8 = TRUE)
261
    {
262
        parent::SetCreator($creator, $isUTF8);
263
    }
264
265
    /**
266
     *
267
     * Print text in cell. Solves utf-8 issues.
268
     *
269
     * Prints a cell (rectangular area) with optional borders, background color
270
     * and character string. The upper-left corner of the cell corresponds to
271
     * the current position. The text can be aligned or centered. After the
272
     * call, the current position moves to the right or to the next line. It is
273
     * possible to put a link on the text.
274
     *
275
     * If automatic page breaking is enabled (witch is it by default) and the
276
     * cell goes beyond the limit, a page break is done before outputting.
277
     *
278
     * @param int $width Cell width. If 0, the cell extends up to the right
279
     * margin.
280
     *
281
     * @param int $height Cell height. Default value: 0.
282
     *
283
     * @param string $txt String to print. Default value: empty string.
284
     *
285
     * @param string|int $border Indicates if borders must be drawn around the
286
     * cell. The value can be either a number: 0 for no border, 1 for a frame.
287
     * Or a string containing some or all of the following characters (in any
288
     * order): 'L' for left, 'T' for top, 'R' for right or 'B' for bottom.
289
     *
290
     * @param int $ln Indicates where the current position should go after the
291
     * call. Possible values are: 0 - to the rigth, 1 - to the beginning of the
292
     * next line or 2 - below.
293
     *
294
     * @param char $align Allows to center or align the tex. 'L', 'C' or 'R'.
295
     *
296
     * @param bool $fill Indicates if the cell background must be painted (TRUE)
297
     * or transparent (FALSE). Default value: FALSE.
298
     *
299
     * @param string|identifier $link URL or identifier returned by AddLink().
300
     *
301
     * @return void
302
     *
303
     */
304
    public function Cell(
305
        $width,
306
        $height = 0,
307
        $txt = '',
308
        $border = 0,
309
        $ln = 0,
310
        $align = '',
311
        $fill = FALSE,
312
        $link = ''
313
    ) {
314
        $txt = utf8_decode($txt);
315
        parent::Cell($width, $height, $txt, $border, $ln, $align, $fill, $link);
316
    }
317
318
    /**
319
     *
320
     * Prints a character string. Solves utf-8 issues.
321
     *
322
     * The origin is on the left of the first character, on the baseline. This
323
     * method allows to place a string precisely on the page, but it is usually
324
     * easier to use Cell(), MultiCell() or Write() which are the standard
325
     * methods to print text.
326
     *
327
     * @param int $x Abscissa of the origin.
328
     *
329
     * @param int $y Ordinate of the origin.
330
     *
331
     * @param string $txt String to print.
332
     *
333
     * @return void
334
     *
335
     */
336
    public function Text($x, $y, $txt)
337
    {
338
        $txt = utf8_decode($txt);
339
        parent::Text($x, $y, $txt);
340
    }
341
342
    /**
343
     *
344
     * Print text from the current position.
345
     *
346
     * Fix positioning errors when using non-english characters (eg. åäö).
347
     *
348
     * When the right margin is reached (or the \n character is met) a line
349
     * break occurs and text continues from the left margin. Upon method exit,
350
     * the current position is left just at the end of the text.
351
     *
352
     * @param string $lineHeight Line height.
353
     *
354
     * @param string $txt String to print.
355
     *
356
     * @param string|identifier $link URL or identifier returned by AddLink().
357
     *
358
     * @return void
359
     *
360
     * @todo Fix positioning hack..
361
     *
362
     */
363
    public function Write($lineHeight, $txt, $link = '')
364
    {
365
        parent::Write($lineHeight, $txt, $link);
366
        // Uggly hack to help fix positions
367
        $specChars = preg_replace("/[^åäöÅÄÖ]/", '', $txt);
368
        $specChars = strlen($specChars)*1.75;
369
        if ( $specChars ) $this->moveX($specChars*-1);
370
    }
371
372
    /**
373
     * Write to position
374
     *
375
     * @param  string $x
376
     * @param  string $y
377
     * @param  string $line
378
     * @param  string $txt
379
     * @param  string|identifier $link URL or identifier returned by AddLink().
380
     * @return void
381
     */
382
    public function WriteXY($x, $y, $line, $txt, $link = '')
383
    {
384
        $this->SetXY($x, $y);
385
        $this->Write($line, $txt, $link);
386
    }
387
388
    /**
389
     *
390
     * Set image path. Enables image() to understand relative paths.
391
     *
392
     * @param string $path
393
     *
394
     * @return void
395
     *
396
     */
397
    public function setImagePath($path)
398
    {
399
        $this->imagePath = realpath($path);
400
    }
401
402
    /**
403
     *
404
     * Output an image.
405
     *
406
     * @param string $file Path or URL of the image. May be relative to
407
     * path set using setImagePath()
408
     *
409
     * @param int $x Abscissa of the upper-left corner. If not specified or
410
     * equal to NULL, the current abscissa is used.
411
     *
412
     * @param int $y Ordinate of the upper-left corner. If not specified or
413
     * equal to NULL, the current ordinate is used; moreover, a page break is
414
     * triggered first if necessary (in case automatic page breaking is enabled)
415
     * and, after the call, the current ordinate is moved to the bottom of the
416
     * image.
417
     *
418
     * @param int $width Width of the image in the page.
419
     *
420
     * @param int $height Height of the image in the page.
421
     *
422
     * @param string $type JPG|JPEG|PNG|GIF
423
     *
424
     * @param string|identifier $link URL or identifier returned by AddLink().
425
     *
426
     * @return void
427
     *
428
     */
429
    public function Image(
430
        $file,
431
        $x = NULL,
432
        $y = NULL,
433
        $width = 0,
434
        $height = 0,
435
        $type = '',
436
        $link = ''
437
    ) {
438
        $absolute = $this->imagePath . DIRECTORY_SEPARATOR . $file;
439
        if (!is_readable($file) && is_readable($absolute)) {
440
            $file = $absolute;
441
        }
442
        parent::Image($file, $x, $y, $width, $height, $type, $link);
443
    }
444
445
    /**
446
     *
447
     * Import a TrueType or Type1 font and make it available.
448
     *
449
     * @param string $family
450
     *
451
     * @param string $style 'B', 'I' or 'IB'
452
     *
453
     * @param string $file The font definition file. By default, the name is
454
     * built from the family and style, in lower case with no space.
455
     *
456
     * @return void
457
     *
458
     */
459
    public function AddFont($family, $style = '', $file = '')
460
    {
461
        parent::AddFont($family, $style, $file);
462
        if (!isset($this->addedFonts[$family])) {
463
            $this->addedFonts[$family] = array();
464
        }
465
        $this->addedFonts[$family][] = $style;
466
    }
467
468
    /**
469
     *
470
     * Sets the font used to print character strings.
471
     *
472
     * @param string $family Family font. It can be either a name defined by
473
     * AddFont() or one of the standard families (case insensitive): Courier,
474
     * Helvetica or Arial, Times, Symbol or ZapfDingbats.
475
     *
476
     * @param string $style 'B', 'I', 'U' or any combination.
477
     *
478
     * @param int $size Font size in points. The default value is the current
479
     * size. If no size has been specified since the beginning of the document,
480
     * the value taken is 12.
481
     *
482
     * @return void
483
     *
484
     */
485
    public function SetFont($family, $style = '', $size = 0)
486
    {
487
        $style = strtoupper($style);
488
489
        // U is not handled by AddFont(), hence needs special treatment
490
        $addU = '';
491
        if (strpos($style, 'U') !== FALSE) {
492
            $addU = 'U';
493
            $style = str_replace('U', '', $style);
494
        }
495
496
        if (isset($this->addedFonts[$family])) {
497
            if (!in_array($style, $this->addedFonts[$family]) ) {
498
                // Requested style is missing
499
                if (in_array('', $this->addedFonts[$family])) {
500
                    // Using no style
501
                    $style = '';
502
                } else {
503
                    // Use first added style
504
                    $style = $this->addedFonts[$family][0];
505
                }
506
            }
507
        }
508
509
        $style = $style.$addU;
510
        parent::SetFont($family, $style, $size);
511
    }
512
513
    /**
514
     *
515
     * Send the document to a given destination
516
     *
517
     * @param string $name The name of the file. If not specified, the document
518
     * will be sent to the browser (destination I) with the name doc.pdf.
519
     *
520
     * @param char $dest Destination where to send the document. It can take one
521
     * of the following values: 'I' - send the file inline to the browser.
522
     * 'D' - send to the browser and force a file download with the name given
523
     * by name. 'F' - save to a local file with the name given by name (may
524
     * include a path). 'S' - return the document as a string. name is ignored.
525
     *
526
     * @return string
527
     *
528
     */
529
    public function Output($name = '', $dest = '')
530
    {
531
        $this->draw();
532
        return parent::Output($name, $dest);
533
    }
534
535
    /**
536
     *
537
     * Shorthand for direct string output
538
     *
539
     * @return string Raw PDF
540
     *
541
     */
542
    public function GetPdf()
543
    {
544
        return $this->Output('', 'S');
545
    }
546
547
    /**
548
     *
549
     * Perform actions just before Output
550
     *
551
     * @return void
552
     *
553
     */
554
    protected function draw(){}
555
556
}
557