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

FPDF::SetSubject()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
c 0
b 0
f 0
rs 10
cc 1
nc 1
nop 2
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