FPDI::importPage()   D
last analyzed

Complexity

Conditions 18
Paths 91

Size

Total Lines 86
Code Lines 52

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 86
rs 4.7996
cc 18
eloc 52
nc 91
nop 2

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 20 and the first side effect is on line 27.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
//
3
//  FPDI - Version 1.2.1
4
//
5
//    Copyright 2004-2008 Setasign - Jan Slabon
6
//
7
//  Licensed under the Apache License, Version 2.0 (the "License");
8
//  you may not use this file except in compliance with the License.
9
//  You may obtain a copy of the License at
10
//
11
//      http://www.apache.org/licenses/LICENSE-2.0
12
//
13
//  Unless required by applicable law or agreed to in writing, software
14
//  distributed under the License is distributed on an "AS IS" BASIS,
15
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
//  See the License for the specific language governing permissions and
17
//  limitations under the License.
18
//
19
20
define('FPDI_VERSION','1.2.1');
21
22
// Check for TCPDF and remap TCPDF to FPDF
23
//if (class_exists('TCPDF')) {
24
  //  require_once('fpdi2tcpdf_bridge.php');
0 ignored issues
show
Unused Code Comprehensibility introduced by
75% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
25
//}
26
27
require_once("fpdf_tpl.php");
28
require_once("fpdi_pdf_parser.php");
29
30
31
class FPDI extends FPDF_TPL {
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
32
    /**
33
     * Actual filename
34
     * @var string
35
     */
36
    var $current_filename;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $current_filename.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
37
38
    /**
39
     * Parser-Objects
40
     * @var array
41
     */
42
    var $parsers;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $parsers.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
43
44
    /**
45
     * Current parser
46
     * @var object
47
     */
48
    var $current_parser;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $current_parser.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
49
50
    /**
51
     * object stack
52
     * @var array
53
     */
54
    var $_obj_stack;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $_obj_stack.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
55
56
    /**
57
     * done object stack
58
     * @var array
59
     */
60
    var $_don_obj_stack;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $_don_obj_stack.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
61
62
    /**
63
     * Current Object Id.
64
     * @var integer
65
     */
66
    var $_current_obj_id;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $_current_obj_id.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
67
68
    /**
69
     * The name of the last imported page box
70
     * @var string
71
     */
72
    var $lastUsedPageBox;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $lastUsedPageBox.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
73
74
    var $_importedPages = array();
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $_importedPages.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
75
76
77
    /**
78
     * Set a source-file
79
     *
80
     * @param string $filename a valid filename
81
     * @return int number of available pages
82
     */
83
    function setSourceFile($filename) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
84
        $this->current_filename = $filename;
85
        $fn =& $this->current_filename;
86
87
        if (!isset($this->parsers[$fn]))
88
            $this->parsers[$fn] = new fpdi_pdf_parser($fn,$this);
89
        $this->current_parser = $this->parsers[$fn];
90
91
        return $this->parsers[$fn]->getPageCount();
92
    }
93
94
    /**
95
     * Import a page
96
     *
97
     * @param int $pageno pagenumber
98
     * @return int Index of imported page - to use with fpdf_tpl::useTemplate()
99
     */
100
    function importPage($pageno, $boxName='/CropBox') {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
101
        if ($this->_intpl) {
0 ignored issues
show
Bug introduced by
The property _intpl cannot be accessed from this context as it is declared private in class FPDF_TPL.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
102
            return $this->error("Please import the desired pages before creating a new template.");
103
        }
104
105
        $fn =& $this->current_filename;
106
107
        // check if page already imported
108
        $pageKey = $fn.((int)$pageno).$boxName;
109
        if (isset($this->_importedPages[$pageKey]))
110
            return $this->_importedPages[$pageKey];
111
112
        $parser =& $this->parsers[$fn];
113
        $parser->setPageno($pageno);
114
115
        $this->tpl++;
0 ignored issues
show
Bug introduced by
The property tpl cannot be accessed from this context as it is declared private in class FPDF_TPL.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
116
        $this->tpls[$this->tpl] = array();
0 ignored issues
show
Bug introduced by
The property tpls cannot be accessed from this context as it is declared private in class FPDF_TPL.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
Bug introduced by
The property tpl cannot be accessed from this context as it is declared private in class FPDF_TPL.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
117
        $tpl =& $this->tpls[$this->tpl];
0 ignored issues
show
Bug introduced by
The property tpls cannot be accessed from this context as it is declared private in class FPDF_TPL.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
Bug introduced by
The property tpl cannot be accessed from this context as it is declared private in class FPDF_TPL.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
118
        $tpl['parser'] =& $parser;
119
        $tpl['resources'] = $parser->getPageResources();
120
        $tpl['buffer'] = $parser->getContent();
121
122
        if (!in_array($boxName, $parser->availableBoxes))
123
            return $this->Error(sprintf("Unknown box: %s", $boxName));
124
        $pageboxes = $parser->getPageBoxes($pageno);
125
126
        /**
127
         * MediaBox
128
         * CropBox: Default -> MediaBox
129
         * BleedBox: Default -> CropBox
130
         * TrimBox: Default -> CropBox
131
         * ArtBox: Default -> CropBox
132
         */
133
        if (!isset($pageboxes[$boxName]) && ($boxName == "/BleedBox" || $boxName == "/TrimBox" || $boxName == "/ArtBox"))
134
            $boxName = "/CropBox";
135
        if (!isset($pageboxes[$boxName]) && $boxName == "/CropBox")
136
            $boxName = "/MediaBox";
137
138
        if (!isset($pageboxes[$boxName]))
139
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return false; (false) is incompatible with the return type documented by FPDI::importPage of type integer.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
140
        $this->lastUsedPageBox = $boxName;
141
142
        $box = $pageboxes[$boxName];
143
        $tpl['box'] = $box;
144
145
        // To build an array that can be used by PDF_TPL::useTemplate()
146
        $this->tpls[$this->tpl] = array_merge($this->tpls[$this->tpl],$box);
0 ignored issues
show
Bug introduced by
The property tpls cannot be accessed from this context as it is declared private in class FPDF_TPL.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
Bug introduced by
The property tpl cannot be accessed from this context as it is declared private in class FPDF_TPL.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
147
        // An imported page will start at 0,0 everytime. Translation will be set in _putformxobjects()
148
        $tpl['x'] = 0;
149
        $tpl['y'] = 0;
150
151
        $page =& $parser->pages[$parser->pageno];
152
153
        // fix for rotated pages
154
        $rotation = $parser->getPageRotation($pageno);
155
        if (isset($rotation[1]) && ($angle = $rotation[1] % 360) != 0) {
156
            $steps = $angle / 90;
157
158
            $_w = $tpl['w'];
159
            $_h = $tpl['h'];
160
            $tpl['w'] = $steps % 2 == 0 ? $_w : $_h;
161
            $tpl['h'] = $steps % 2 == 0 ? $_h : $_w;
162
163
            if ($steps % 2 != 0) {
164
                $x = $y = ($steps == 1 || $steps == -3) ? $tpl['h'] : $tpl['w'];
165
            } else {
166
                $x = $tpl['w'];
167
                $y = $tpl['h'];
168
            }
169
170
            $cx=($x/2+$tpl['box']['x'])*$this->k;
171
            $cy=($y/2+$tpl['box']['y'])*$this->k;
172
173
            $angle*=-1;
174
175
            $angle*=M_PI/180;
176
            $c=cos($angle);
177
            $s=sin($angle);
178
179
            $tpl['buffer'] = sprintf('q %.5f %.5f %.5f %.5f %.2f %.2f cm 1 0 0 1 %.2f %.2f cm %s Q',$c,$s,-$s,$c,$cx,$cy,-$cx,-$cy, $tpl['buffer']);
180
        }
181
182
        $this->_importedPages[$pageKey] = $this->tpl;
0 ignored issues
show
Bug introduced by
The property tpl cannot be accessed from this context as it is declared private in class FPDF_TPL.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
183
184
        return $this->tpl;
0 ignored issues
show
Bug introduced by
The property tpl cannot be accessed from this context as it is declared private in class FPDF_TPL.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
185
    }
186
187
    function getLastUsedPageBox() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
188
        return $this->lastUsedPageBox;
189
    }
190
191
    function useTemplate($tplidx, $_x=null, $_y=null, $_w=0, $_h=0) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
192
        $this->_out('q 0 J 1 w 0 j 0 G 0 g'); // reset standard values
193
        $s = parent::useTemplate($tplidx, $_x, $_y, $_w, $_h);
194
        $this->_out('Q');
195
        return $s;
196
    }
197
198
    /**
199
     * Private method, that rebuilds all needed objects of source files
200
     */
201
    function _putimportedobjects() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
202
        if (is_array($this->parsers) && count($this->parsers) > 0) {
203
            foreach($this->parsers AS $filename => $p) {
204
                $this->current_parser =& $this->parsers[$filename];
205
                if (isset($this->_obj_stack[$filename]) && is_array($this->_obj_stack[$filename])) {
206
                    while($n = key($this->_obj_stack[$filename])) {
207
                        $nObj = $this->current_parser->pdf_resolve_object($this->current_parser->c,$this->_obj_stack[$filename][$n][1]);
208
209
                        $this->_newobj($this->_obj_stack[$filename][$n][0]);
210
211
                        if ($nObj[0] == PDF_TYPE_STREAM) {
212
							$this->pdf_write_value ($nObj);
213
                        } else {
214
                            $this->pdf_write_value ($nObj[1]);
215
                        }
216
217
                        $this->_out('endobj');
218
                        $this->_obj_stack[$filename][$n] = null; // free memory
219
                        unset($this->_obj_stack[$filename][$n]);
220
                        reset($this->_obj_stack[$filename]);
221
                    }
222
                }
223
            }
224
        }
225
    }
226
227
    /**
228
     * Put resources
229
     */
230 View Code Duplication
    function _putresources() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
231
        if (!is_subclass_of($this, 'TCPDF')) {
232
            $this->_putfonts();
233
        	$this->_putimages();
234
        	$this->_putformxobjects();
235
            $this->_putimportedobjects();
236
            //Resource dictionary
237
        	$this->offsets[2]=strlen($this->buffer);
238
        	$this->_out('2 0 obj');
239
        	$this->_out('<<');
240
        	$this->_putresourcedict();
241
        	$this->_out('>>');
242
        	$this->_out('endobj');
243
244
        } else { // TCPDF - Part
245
            $this->_putextgstates();
0 ignored issues
show
Bug introduced by
The method _putextgstates() does not seem to exist on object<FPDI>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
246
    		$this->_putocg();
0 ignored issues
show
Bug introduced by
The method _putocg() does not seem to exist on object<FPDI>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
247
    		$this->_putfonts();
248
    		$this->_putimages();
249
    	  	$this->_putshaders();
0 ignored issues
show
Bug introduced by
The method _putshaders() does not seem to exist on object<FPDI>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
250
    	  	$this->_putformxobjects();
251
            $this->_putimportedobjects();
252
            //Resource dictionary
253
    		$this->offsets[2]=strlen($this->buffer);
254
    		$this->_out('2 0 obj');
255
    		$this->_out('<<');
256
    		$this->_putresourcedict();
257
    		$this->_out('>>');
258
    		$this->_out('endobj');
259
    		$this->_putjavascript();
0 ignored issues
show
Bug introduced by
The method _putjavascript() does not seem to exist on object<FPDI>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
260
    		$this->_putbookmarks();
0 ignored issues
show
Bug introduced by
The method _putbookmarks() does not seem to exist on object<FPDI>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
261
    		// encryption
262
    		if ($this->encrypted) {
0 ignored issues
show
Bug introduced by
The property encrypted does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
263
    			$this->_newobj();
264
    			$this->enc_obj_id = $this->n;
0 ignored issues
show
Bug introduced by
The property enc_obj_id does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
265
    			$this->_out('<<');
266
    			$this->_putencryption();
0 ignored issues
show
Bug introduced by
The method _putencryption() does not seem to exist on object<FPDI>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
267
    			$this->_out('>>');
268
    			$this->_out('endobj');
269
    		}
270
        }
271
    }
272
273
    /**
274
     * Private Method that writes the form xobjects
275
     */
276
    function _putformxobjects() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
277
        $filter=($this->compress) ? '/Filter /FlateDecode ' : '';
278
	    reset($this->tpls);
0 ignored issues
show
Bug introduced by
The property tpls cannot be accessed from this context as it is declared private in class FPDF_TPL.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
279
        foreach($this->tpls AS $tplidx => $tpl) {
0 ignored issues
show
Bug introduced by
The property tpls cannot be accessed from this context as it is declared private in class FPDF_TPL.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
280
            $p=($this->compress) ? gzcompress($tpl['buffer']) : $tpl['buffer'];
281
    		$this->_newobj();
282
    		$cN = $this->n; // TCPDF/Protection: rem current "n"
283
284
    		$this->tpls[$tplidx]['n'] = $this->n;
0 ignored issues
show
Bug introduced by
The property tpls cannot be accessed from this context as it is declared private in class FPDF_TPL.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
285
    		$this->_out('<<'.$filter.'/Type /XObject');
286
            $this->_out('/Subtype /Form');
287
            $this->_out('/FormType 1');
288
289
            $this->_out(sprintf('/BBox [%.2f %.2f %.2f %.2f]',
290
                ($tpl['x'] + (isset($tpl['box']['x'])?$tpl['box']['x']:0))*$this->k,
291
                ($tpl['h'] + (isset($tpl['box']['y'])?$tpl['box']['y']:0) - $tpl['y'])*$this->k,
292
                ($tpl['w'] + (isset($tpl['box']['x'])?$tpl['box']['x']:0))*$this->k,
293
                ($tpl['h'] + (isset($tpl['box']['y'])?$tpl['box']['y']:0) - $tpl['y']-$tpl['h'])*$this->k)
294
            );
295
296
            if (isset($tpl['box']))
297
                $this->_out(sprintf('/Matrix [1 0 0 1 %.5f %.5f]',-$tpl['box']['x']*$this->k, -$tpl['box']['y']*$this->k));
298
299
            $this->_out('/Resources ');
300
301
            if (isset($tpl['resources'])) {
302
                $this->current_parser =& $tpl['parser'];
303
                $this->pdf_write_value($tpl['resources']); // "n" will be changed
304
            } else {
305
                $this->_out('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
306 View Code Duplication
            	if (isset($this->_res['tpl'][$tplidx]['fonts']) && count($this->_res['tpl'][$tplidx]['fonts'])) {
0 ignored issues
show
Bug introduced by
The property _res cannot be accessed from this context as it is declared private in class FPDF_TPL.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
307
                	$this->_out('/Font <<');
308
                    foreach($this->_res['tpl'][$tplidx]['fonts'] as $font)
0 ignored issues
show
Bug introduced by
The property _res cannot be accessed from this context as it is declared private in class FPDF_TPL.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
309
                		$this->_out('/F'.$font['i'].' '.$font['n'].' 0 R');
310
                	$this->_out('>>');
311
                }
312 View Code Duplication
            	if(isset($this->_res['tpl'][$tplidx]['images']) && count($this->_res['tpl'][$tplidx]['images']) ||
0 ignored issues
show
Bug introduced by
The property _res cannot be accessed from this context as it is declared private in class FPDF_TPL.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
313
            	   isset($this->_res['tpl'][$tplidx]['tpls']) && count($this->_res['tpl'][$tplidx]['tpls']))
0 ignored issues
show
Bug introduced by
The property _res cannot be accessed from this context as it is declared private in class FPDF_TPL.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
314
            	{
315
                    $this->_out('/XObject <<');
316
                    if (isset($this->_res['tpl'][$tplidx]['images']) && count($this->_res['tpl'][$tplidx]['images'])) {
0 ignored issues
show
Bug introduced by
The property _res cannot be accessed from this context as it is declared private in class FPDF_TPL.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
317
                        foreach($this->_res['tpl'][$tplidx]['images'] as $image)
0 ignored issues
show
Bug introduced by
The property _res cannot be accessed from this context as it is declared private in class FPDF_TPL.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
318
                  			$this->_out('/I'.$image['i'].' '.$image['n'].' 0 R');
319
                    }
320
                    if (isset($this->_res['tpl'][$tplidx]['tpls']) && count($this->_res['tpl'][$tplidx]['tpls'])) {
0 ignored issues
show
Bug introduced by
The property _res cannot be accessed from this context as it is declared private in class FPDF_TPL.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
321
                        foreach($this->_res['tpl'][$tplidx]['tpls'] as $i => $tpl)
0 ignored issues
show
Bug introduced by
The property _res cannot be accessed from this context as it is declared private in class FPDF_TPL.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
322
                            $this->_out($this->tplprefix.$i.' '.$tpl['n'].' 0 R');
0 ignored issues
show
Bug introduced by
The property tplprefix cannot be accessed from this context as it is declared private in class FPDF_TPL.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
323
                    }
324
                    $this->_out('>>');
325
            	}
326
            	$this->_out('>>');
327
            }
328
329
            $nN = $this->n; // TCPDF: rem new "n"
0 ignored issues
show
Unused Code Comprehensibility introduced by
38% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
330
            $this->n = $cN; // TCPDF: reset to current "n"
331
            $this->_out('/Length '.strlen($p).' >>');
332
    		$this->_putstream($p);
333
    		$this->_out('endobj');
334
    		$this->n = $nN; // TCPDF: reset to new "n"
335
        }
336
    }
337
338
    /**
339
     * Rewritten to handle existing own defined objects
340
     */
341
    function _newobj($obj_id=false,$onlynewobj=false) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
342
        if (!$obj_id) {
343
            $obj_id = ++$this->n;
344
        }
345
346
    	//Begin a new object
347
        if (!$onlynewobj) {
348
            $this->offsets[$obj_id] = strlen($this->buffer);
349
            $this->_out($obj_id.' 0 obj');
350
            $this->_current_obj_id = $obj_id; // for later use with encryption
0 ignored issues
show
Documentation Bug introduced by
It seems like $obj_id can also be of type boolean. However, the property $_current_obj_id is declared as type integer. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
351
        }
352
    }
353
354
    /**
355
     * Writes a value
356
     * Needed to rebuild the source document
357
     *
358
     * @param mixed $value A PDF-Value. Structure of values see cases in this method
359
     */
360
    function pdf_write_value(&$value)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
361
    {
362
        if (is_subclass_of($this, 'TCPDF')) {
363
            parent::pdf_write_value($value);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class FPDF_TPL as the method pdf_write_value() does only exist in the following sub-classes of FPDF_TPL: FPDF_FPDI, FPDI. 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...
364
        }
365
366
        switch ($value[0]) {
367
368
    		case PDF_TYPE_NUMERIC :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
369
    		case PDF_TYPE_TOKEN :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
370
    		case PDF_TYPE_REAL :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
371
                // A numeric value or a token.
372
    			// Simply output them
373
                $this->_out($value[1]." ", false);
374
    			break;
375
376
    		case PDF_TYPE_ARRAY :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
377
378
    			// An array. Output the proper
379
    			// structure and move on.
380
381
    			$this->_out("[",false);
382
                for ($i = 0; $i < count($value[1]); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
383
    				$this->pdf_write_value($value[1][$i]);
384
    			}
385
386
    			$this->_out("]");
387
    			break;
388
389
    		case PDF_TYPE_DICTIONARY :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
390
391
    			// A dictionary.
392
    			$this->_out("<<",false);
393
394
    			reset ($value[1]);
395
396
    			while (list($k, $v) = each($value[1])) {
397
    				$this->_out($k . " ",false);
398
    				$this->pdf_write_value($v);
399
    			}
400
401
    			$this->_out(">>");
402
    			break;
403
404
    		case PDF_TYPE_OBJREF :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
405
406
    			// An indirect object reference
407
    			// Fill the object stack if needed
408
    			$cpfn =& $this->current_parser->filename;
409
    			if (!isset($this->_don_obj_stack[$cpfn][$value[1]])) {
410
                    $this->_newobj(false,true);
411
                    $this->_obj_stack[$cpfn][$value[1]] = array($this->n, $value);
412
                    $this->_don_obj_stack[$cpfn][$value[1]] = array($this->n, $value); // Value is maybee obsolete!!!
413
                }
414
                $objid = $this->_don_obj_stack[$cpfn][$value[1]][0];
415
416
    			$this->_out("{$objid} 0 R");
417
    			break;
418
419
    		case PDF_TYPE_STRING :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
420
421
    			// A string.
422
                $this->_out('('.$value[1].')');
423
424
    			break;
425
426
    		case PDF_TYPE_STREAM :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
427
428
    			// A stream. First, output the
429
    			// stream dictionary, then the
430
    			// stream data itself.
431
                $this->pdf_write_value($value[1]);
432
    			$this->_out("stream");
433
    			$this->_out($value[2][1]);
434
    			$this->_out("endstream");
435
    			break;
436
            case PDF_TYPE_HEX :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
437
438
                $this->_out("<".$value[1].">");
439
                break;
440
441
            case PDF_TYPE_BOOLEAN :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
442
    		    $this->_out($value[1] ? 'true ' : 'false ', false);
443
    		    break;
444
445
    		case PDF_TYPE_NULL :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
446
                // The null object.
447
448
    			$this->_out("null");
449
    			break;
450
    	}
451
    }
452
453
454
    /**
455
     * Modified so not each call will add a newline to the output.
456
     */
457
    function _out($s, $ln=true) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
458
        //Add a line to the document
459
        if ($this->state==2) {
460
            if (!$this->_intpl) {
0 ignored issues
show
Bug introduced by
The property _intpl cannot be accessed from this context as it is declared private in class FPDF_TPL.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
461
                if (is_subclass_of($this, 'TCPDF') && isset($this->footerlen[$this->page]) AND ($this->footerlen[$this->page] > 0)) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and instead of && is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
462
					// puts data before page footer
463
					$page = substr($this->pages[$this->page], 0, -$this->footerlen[$this->page]);
0 ignored issues
show
Bug introduced by
The property footerlen does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
464
					$footer = substr($this->pages[$this->page], -$this->footerlen[$this->page]);
465
					$this->pages[$this->page] = $page." ".$s."\n".$footer;
466
				} else {
467
                    $this->pages[$this->page] .= $s.($ln == true ? "\n" : '');
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
468
                }
469
            } else
470
                $this->tpls[$this->tpl]['buffer'] .= $s.($ln == true ? "\n" : '');
0 ignored issues
show
Bug introduced by
The property tpls cannot be accessed from this context as it is declared private in class FPDF_TPL.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
Bug introduced by
The property tpl cannot be accessed from this context as it is declared private in class FPDF_TPL.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
471
        } else {
472
	 	    $this->buffer.=$s.($ln == true ? "\n" : '');
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
473
        }
474
    }
475
476
    /**
477
     * rewritten to close opened parsers
478
     *
479
     */
480
    function _enddoc() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
481
        parent::_enddoc();
482
        $this->_closeParsers();
483
    }
484
485
    /**
486
     * close all files opened by parsers
487
     */
488
    function _closeParsers() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
489
        if ($this->state > 2 && count($this->parsers) > 0) {
490
          	foreach ($this->parsers as $k => $_){
491
            	$this->parsers[$k]->closeFile();
492
            	$this->parsers[$k] = null;
493
            	unset($this->parsers[$k]);
494
            }
495
            return true;
496
        }
497
        return false;
498
    }
499
500
}