Passed
Push — master ( 23273c...605cd0 )
by
unknown
03:28
created

_get_collapsed_margin_length()   B

Complexity

Conditions 5
Paths 3

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 12
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 6
nc 3
nop 2
1
<?php
2
/**
3
 * @package dompdf
4
 * @link    http://dompdf.github.com/
5
 * @author  Benj Carson <[email protected]>
6
 * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
7
 */
8
namespace Dompdf\FrameReflower;
9
10
use Dompdf\Adapter\CPDF;
11
use Dompdf\Css\Style;
12
use Dompdf\Dompdf;
13
use Dompdf\Helpers;
14
use Dompdf\Frame;
15
use Dompdf\FrameDecorator\Block;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, Dompdf\FrameReflower\Block.

Let’s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let’s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
16
use Dompdf\Frame\Factory;
17
18
/**
19
 * Base reflower class
20
 *
21
 * Reflower objects are responsible for determining the width and height of
22
 * individual frames.  They also create line and page breaks as necessary.
23
 *
24
 * @package dompdf
25
 */
26
abstract class AbstractFrameReflower
27
{
28
29
    /**
30
     * Frame for this reflower
31
     *
32
     * @var Frame
33
     */
34
    protected $_frame;
35
36
    /**
37
     * Cached min/max size
38
     *
39
     * @var array
40
     */
41
    protected $_min_max_cache;
42
43
    /**
44
     * AbstractFrameReflower constructor.
45
     * @param Frame $frame
46
     */
47
    function __construct(Frame $frame)
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...
48
    {
49
        $this->_frame = $frame;
50
        $this->_min_max_cache = null;
0 ignored issues
show
Documentation Bug introduced by
It seems like null of type null is incompatible with the declared type array of property $_min_max_cache.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
51
    }
52
53
    function dispose()
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...
54
    {
55
    }
56
57
    /**
58
     * @return Dompdf
59
     */
60
    function get_dompdf()
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...
61
    {
62
        return $this->_frame->get_dompdf();
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Dompdf\Frame as the method get_dompdf() does only exist in the following sub-classes of Dompdf\Frame: Dompdf\FrameDecorator\AbstractFrameDecorator, Dompdf\FrameDecorator\Block, Dompdf\FrameDecorator\Image, Dompdf\FrameDecorator\Inline, Dompdf\FrameDecorator\ListBullet, Dompdf\FrameDecorator\ListBulletImage, Dompdf\FrameDecorator\NullFrameDecorator, Dompdf\FrameDecorator\Page, Dompdf\FrameDecorator\Table, Dompdf\FrameDecorator\TableCell, Dompdf\FrameDecorator\TableRow, Dompdf\FrameDecorator\TableRowGroup, Dompdf\FrameDecorator\Text. 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...
63
    }
64
65
    /**
66
     * Collapse frames margins
67
     * http://www.w3.org/TR/CSS2/box.html#collapsing-margins
68
     */
69
    protected function _collapse_margins()
70
    {
71
        $frame = $this->_frame;
72
        $cb = $frame->get_containing_block();
73
        $style = $frame->get_style();
74
75
        // Margins of float/absolutely positioned/inline-block elements do not collapse.
76
        if (!$frame->is_in_flow() || $frame->is_inline_block()) {
77
            return;
78
        }
79
80
        $t = $style->length_in_pt($style->margin_top, $cb["h"]);
0 ignored issues
show
Documentation introduced by
The property margin_top does not exist on object<Dompdf\Css\Style>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
81
        $b = $style->length_in_pt($style->margin_bottom, $cb["h"]);
0 ignored issues
show
Documentation introduced by
The property margin_bottom does not exist on object<Dompdf\Css\Style>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
82
83
        // Handle 'auto' values
84
        if ($t === "auto") {
85
            $style->margin_top = "0pt";
0 ignored issues
show
Documentation introduced by
The property margin_top does not exist on object<Dompdf\Css\Style>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
86
            $t = 0;
87
        }
88
89
        if ($b === "auto") {
90
            $style->margin_bottom = "0pt";
0 ignored issues
show
Documentation introduced by
The property margin_bottom does not exist on object<Dompdf\Css\Style>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
91
            $b = 0;
92
        }
93
94
        // Collapse vertical margins:
95
        $n = $frame->get_next_sibling();
96
        if ( $n && !$n->is_block() & !$n->is_table() ) {
97
            while ($n = $n->get_next_sibling()) {
98
                if ($n->is_block() || $n->is_table()) {
99
                    break;
100
                }
101
102
                if (!$n->get_first_child()) {
103
                    $n = null;
104
                    break;
105
                }
106
            }
107
        }
108
109
        if ($n) {
110
            $n_style = $n->get_style();
111
            $n_t = (float)$n_style->length_in_pt($n_style->margin_top, $cb["h"]);
0 ignored issues
show
Documentation introduced by
The property margin_top does not exist on object<Dompdf\Css\Style>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
112
113
            $b = $this->_get_collapsed_margin_length($b, $n_t);
114
            $style->margin_bottom = $b . "pt";
0 ignored issues
show
Documentation introduced by
The property margin_bottom does not exist on object<Dompdf\Css\Style>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
115
            $n_style->margin_top = "0pt";
0 ignored issues
show
Documentation introduced by
The property margin_top does not exist on object<Dompdf\Css\Style>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
116
        }
117
118
        // Collapse our first child's margin, if there is no border or padding
119 View Code Duplication
        if ($style->get_border_top_width() == 0 && $style->length_in_pt($style->padding_top) == 0) {
0 ignored issues
show
Documentation introduced by
The property padding_top does not exist on object<Dompdf\Css\Style>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

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...
120
            $f = $this->_frame->get_first_child();
121
            if ( $f && !$f->is_block() && !$f->is_table() ) {
122
                while ( $f = $f->get_next_sibling() ) {
123
                    if ( $f->is_block() || $f->is_table() ) {
124
                        break;
125
                    }
126
127
                    if ( !$f->get_first_child() ) {
128
                        $f = null;
129
                        break;
130
                    }
131
                }
132
            }
133
134
            // Margin are collapsed only between block-level boxes
135
            if ($f) {
136
                $f_style = $f->get_style();
137
                $f_t = (float)$f_style->length_in_pt($f_style->margin_top, $cb["h"]);
0 ignored issues
show
Documentation introduced by
The property margin_top does not exist on object<Dompdf\Css\Style>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
138
139
                $t = $this->_get_collapsed_margin_length($t, $f_t);
140
                $style->margin_top = $t."pt";
0 ignored issues
show
Documentation introduced by
The property margin_top does not exist on object<Dompdf\Css\Style>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
141
                $f_style->margin_top = "0pt";
0 ignored issues
show
Documentation introduced by
The property margin_top does not exist on object<Dompdf\Css\Style>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
142
            }
143
        }
144
145
        // Collapse our last child's margin, if there is no border or padding
146 View Code Duplication
        if ($style->get_border_bottom_width() == 0 && $style->length_in_pt($style->padding_bottom) == 0) {
0 ignored issues
show
Documentation introduced by
The property padding_bottom does not exist on object<Dompdf\Css\Style>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

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...
147
            $l = $this->_frame->get_last_child();
148
            if ( $l && !$l->is_block() && !$l->is_table() ) {
149
                while ( $l = $l->get_prev_sibling() ) {
150
                    if ( $l->is_block() || $l->is_table() ) {
151
                        break;
152
                    }
153
154
                    if ( !$l->get_last_child() ) {
155
                        $l = null;
156
                        break;
157
                    }
158
                }
159
            }
160
161
            // Margin are collapsed only between block-level boxes
162
            if ($l) {
163
                $l_style = $l->get_style();
164
                $l_b = (float)$l_style->length_in_pt($l_style->margin_bottom, $cb["h"]);
0 ignored issues
show
Documentation introduced by
The property margin_bottom does not exist on object<Dompdf\Css\Style>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
165
166
                $b = $this->_get_collapsed_margin_length($b, $l_b);
167
                $style->margin_bottom = $b."pt";
0 ignored issues
show
Documentation introduced by
The property margin_bottom does not exist on object<Dompdf\Css\Style>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
168
                $l_style->margin_bottom = "0pt";
0 ignored issues
show
Documentation introduced by
The property margin_bottom does not exist on object<Dompdf\Css\Style>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
169
            }
170
        }
171
    }
172
173
    /**
174
     * Get the combined (collapsed) length of two adjoining margins.
175
     * 
176
     * See http://www.w3.org/TR/CSS2/box.html#collapsing-margins.
177
     * 
178
     * @param number $length1
179
     * @param number $length2
180
     * @return number
181
     */
182
    private function _get_collapsed_margin_length($length1, $length2)
183
    {
184
        if ($length1 < 0 && $length2 < 0) {
185
            return min($length1, $length2); // min(x, y) = - max(abs(x), abs(y)), if x < 0 && y < 0
186
        }
187
        
188
        if ($length1 < 0 || $length2 < 0) {
189
            return $length1 + $length2; // x + y = x - abs(y), if y < 0
190
        }
191
        
192
        return max($length1, $length2);
193
    }
194
195
    /**
196
     * @param Block|null $block
197
     * @return mixed
198
     */
199
    abstract function reflow(Block $block = null);
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...
200
201
    /**
202
     * Required for table layout: Returns an array(0 => min, 1 => max, "min"
203
     * => min, "max" => max) of the minimum and maximum widths of this frame.
204
     * This provides a basic implementation.  Child classes should override
205
     * this if necessary.
206
     *
207
     * @return array|null
208
     */
209
    function get_min_max_width()
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...
210
    {
211
        if (!is_null($this->_min_max_cache)) {
212
            return $this->_min_max_cache;
213
        }
214
215
        $style = $this->_frame->get_style();
216
217
        // Account for margins & padding
218
        $dims = array($style->padding_left,
0 ignored issues
show
Documentation introduced by
The property padding_left does not exist on object<Dompdf\Css\Style>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
219
            $style->padding_right,
0 ignored issues
show
Documentation introduced by
The property padding_right does not exist on object<Dompdf\Css\Style>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
220
            $style->border_left_width,
0 ignored issues
show
Documentation introduced by
The property border_left_width does not exist on object<Dompdf\Css\Style>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
221
            $style->border_right_width,
0 ignored issues
show
Documentation introduced by
The property border_right_width does not exist on object<Dompdf\Css\Style>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
222
            $style->margin_left,
0 ignored issues
show
Documentation introduced by
The property margin_left does not exist on object<Dompdf\Css\Style>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
223
            $style->margin_right);
0 ignored issues
show
Documentation introduced by
The property margin_right does not exist on object<Dompdf\Css\Style>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
224
225
        $cb_w = $this->_frame->get_containing_block("w");
226
        $delta = (float)$style->length_in_pt($dims, $cb_w);
0 ignored issues
show
Bug introduced by
It seems like $cb_w defined by $this->_frame->get_containing_block('w') on line 225 can also be of type array<integer,double>; however, Dompdf\Css\Style::length_in_pt() does only seem to accept double|null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
227
228
        // Handle degenerate case
229
        if (!$this->_frame->get_first_child()) {
230
            return $this->_min_max_cache = array(
231
                $delta, $delta,
232
                "min" => $delta,
233
                "max" => $delta,
234
            );
235
        }
236
237
        $low = array();
238
        $high = array();
239
240
        for ($iter = $this->_frame->get_children()->getIterator(); $iter->valid(); $iter->next()) {
241
            $inline_min = 0;
242
            $inline_max = 0;
243
244
            // Add all adjacent inline widths together to calculate max width
245
            while ($iter->valid() && in_array($iter->current()->get_style()->display, Style::$INLINE_TYPES)) {
0 ignored issues
show
Documentation introduced by
The property $INLINE_TYPES is declared private in Dompdf\Css\Style. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
246
                $child = $iter->current();
247
248
                $minmax = $child->get_min_max_width();
249
250
                if (in_array($iter->current()->get_style()->white_space, array("pre", "nowrap"))) {
251
                    $inline_min += $minmax["min"];
252
                } else {
253
                    $low[] = $minmax["min"];
254
                }
255
256
                $inline_max += $minmax["max"];
257
                $iter->next();
258
            }
259
260
            if ($inline_max > 0) {
261
                $high[] = $inline_max;
262
            }
263
            if ($inline_min > 0) {
264
                $low[] = $inline_min;
265
            }
266
267
            if ($iter->valid()) {
268
                list($low[], $high[]) = $iter->current()->get_min_max_width();
269
                continue;
270
            }
271
        }
272
        $min = count($low) ? max($low) : 0;
273
        $max = count($high) ? max($high) : 0;
274
275
        // Use specified width if it is greater than the minimum defined by the
276
        // content.  If the width is a percentage ignore it for now.
277
        $width = $style->width;
0 ignored issues
show
Documentation introduced by
The property width does not exist on object<Dompdf\Css\Style>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
278
        if ($width !== "auto" && !Helpers::is_percent($width)) {
279
            $width = (float)$style->length_in_pt($width, $cb_w);
0 ignored issues
show
Bug introduced by
It seems like $cb_w defined by $this->_frame->get_containing_block('w') on line 225 can also be of type array<integer,double>; however, Dompdf\Css\Style::length_in_pt() does only seem to accept double|null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
280
            if ($min < $width) {
281
                $min = $width;
282
            }
283
            if ($max < $width) {
284
                $max = $width;
285
            }
286
        }
287
288
        $min += $delta;
289
        $max += $delta;
290
        return $this->_min_max_cache = array($min, $max, "min" => $min, "max" => $max);
291
    }
292
293
    /**
294
     * Parses a CSS string containing quotes and escaped hex characters
295
     *
296
     * @param $string string The CSS string to parse
297
     * @param $single_trim
298
     * @return string
299
     */
300
    protected function _parse_string($string, $single_trim = false)
301
    {
302
        if ($single_trim) {
303
            $string = preg_replace('/^[\"\']/', "", $string);
304
            $string = preg_replace('/[\"\']$/', "", $string);
305
        } else {
306
            $string = trim($string, "'\"");
307
        }
308
309
        $string = str_replace(array("\\\n", '\\"', "\\'"),
310
            array("", '"', "'"), $string);
311
312
        // Convert escaped hex characters into ascii characters (e.g. \A => newline)
313
        $string = preg_replace_callback("/\\\\([0-9a-fA-F]{0,6})/",
314
            function ($matches) { return \Dompdf\Helpers::unichr(hexdec($matches[1])); },
315
            $string);
316
        return $string;
317
    }
318
319
    /**
320
     * Parses a CSS "quotes" property
321
     *
322
     * @return array|null An array of pairs of quotes
323
     */
324
    protected function _parse_quotes()
325
    {
326
        // Matches quote types
327
        $re = '/(\'[^\']*\')|(\"[^\"]*\")/';
328
329
        $quotes = $this->_frame->get_style()->quotes;
0 ignored issues
show
Documentation introduced by
The property quotes does not exist on object<Dompdf\Css\Style>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
330
331
        // split on spaces, except within quotes
332
        if (!preg_match_all($re, "$quotes", $matches, PREG_SET_ORDER)) {
333
            return null;
334
        }
335
336
        $quotes_array = array();
337
        foreach ($matches as $_quote) {
338
            $quotes_array[] = $this->_parse_string($_quote[0], true);
339
        }
340
341
        if (empty($quotes_array)) {
342
            $quotes_array = array('"', '"');
343
        }
344
345
        return array_chunk($quotes_array, 2);
346
    }
347
348
    /**
349
     * Parses the CSS "content" property
350
     *
351
     * @return string|null The resulting string
352
     */
353
    protected function _parse_content()
354
    {
355
        // Matches generated content
356
        $re = "/\n" .
357
            "\s(counters?\\([^)]*\\))|\n" .
358
            "\A(counters?\\([^)]*\\))|\n" .
359
            "\s([\"']) ( (?:[^\"']|\\\\[\"'])+ )(?<!\\\\)\\3|\n" .
360
            "\A([\"']) ( (?:[^\"']|\\\\[\"'])+ )(?<!\\\\)\\5|\n" .
361
            "\s([^\s\"']+)|\n" .
362
            "\A([^\s\"']+)\n" .
363
            "/xi";
364
365
        $content = $this->_frame->get_style()->content;
0 ignored issues
show
Documentation introduced by
The property content does not exist on object<Dompdf\Css\Style>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
366
367
        $quotes = $this->_parse_quotes();
368
369
        // split on spaces, except within quotes
370
        if (!preg_match_all($re, $content, $matches, PREG_SET_ORDER)) {
371
            return null;
372
        }
373
374
        $text = "";
375
376
        foreach ($matches as $match) {
377 View Code Duplication
            if (isset($match[2]) && $match[2] !== "") {
0 ignored issues
show
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...
378
                $match[1] = $match[2];
379
            }
380
381 View Code Duplication
            if (isset($match[6]) && $match[6] !== "") {
0 ignored issues
show
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...
382
                $match[4] = $match[6];
383
            }
384
385 View Code Duplication
            if (isset($match[8]) && $match[8] !== "") {
0 ignored issues
show
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...
386
                $match[7] = $match[8];
387
            }
388
389
            if (isset($match[1]) && $match[1] !== "") {
390
                // counters?(...)
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% 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...
391
                $match[1] = mb_strtolower(trim($match[1]));
392
393
                // Handle counter() references:
394
                // http://www.w3.org/TR/CSS21/generate.html#content
395
396
                $i = mb_strpos($match[1], ")");
397
                if ($i === false) {
398
                    continue;
399
                }
400
401
                preg_match('/(counters?)(^\()*?\(\s*([^\s,]+)\s*(,\s*["\']?([^"\'\)]+)["\']?\s*(,\s*([^\s)]+)\s*)?)?\)/i', $match[1], $args);
402
                $counter_id = $args[3];
403
                if (strtolower($args[1]) == 'counter') {
404
                    // counter(name [,style])
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% 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...
405 View Code Duplication
                    if (isset($args[5])) {
0 ignored issues
show
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...
406
                        $type = trim($args[5]);
407
                    } else {
408
                        $type = null;
409
                    }
410
                    $p = $this->_frame->lookup_counter_frame($counter_id);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Dompdf\Frame as the method lookup_counter_frame() does only exist in the following sub-classes of Dompdf\Frame: Dompdf\FrameDecorator\AbstractFrameDecorator, Dompdf\FrameDecorator\Block, Dompdf\FrameDecorator\Image, Dompdf\FrameDecorator\Inline, Dompdf\FrameDecorator\ListBullet, Dompdf\FrameDecorator\ListBulletImage, Dompdf\FrameDecorator\NullFrameDecorator, Dompdf\FrameDecorator\Page, Dompdf\FrameDecorator\Table, Dompdf\FrameDecorator\TableCell, Dompdf\FrameDecorator\TableRow, Dompdf\FrameDecorator\TableRowGroup, Dompdf\FrameDecorator\Text. 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...
411
412
                    $text .= $p->counter_value($counter_id, $type);
413
414
                } else if (strtolower($args[1]) == 'counters') {
415
                    // counters(name, string [,style])
0 ignored issues
show
Unused Code Comprehensibility introduced by
47% 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...
416
                    if (isset($args[5])) {
417
                        $string = $this->_parse_string($args[5]);
418
                    } else {
419
                        $string = "";
420
                    }
421
422 View Code Duplication
                    if (isset($args[7])) {
0 ignored issues
show
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...
423
                        $type = trim($args[7]);
424
                    } else {
425
                        $type = null;
426
                    }
427
428
                    $p = $this->_frame->lookup_counter_frame($counter_id);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Dompdf\Frame as the method lookup_counter_frame() does only exist in the following sub-classes of Dompdf\Frame: Dompdf\FrameDecorator\AbstractFrameDecorator, Dompdf\FrameDecorator\Block, Dompdf\FrameDecorator\Image, Dompdf\FrameDecorator\Inline, Dompdf\FrameDecorator\ListBullet, Dompdf\FrameDecorator\ListBulletImage, Dompdf\FrameDecorator\NullFrameDecorator, Dompdf\FrameDecorator\Page, Dompdf\FrameDecorator\Table, Dompdf\FrameDecorator\TableCell, Dompdf\FrameDecorator\TableRow, Dompdf\FrameDecorator\TableRowGroup, Dompdf\FrameDecorator\Text. 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...
429
                    $tmp = array();
430
                    while ($p) {
431
                        // We only want to use the counter values when they actually increment the counter
432
                        if (array_key_exists($counter_id, $p->_counters)) {
433
                            array_unshift($tmp, $p->counter_value($counter_id, $type));
434
                        }
435
                        $p = $p->lookup_counter_frame($counter_id);
436
                    }
437
                    $text .= implode($string, $tmp);
438
                } else {
439
                    // countertops?
440
                    continue;
441
                }
442
443
            } else if (isset($match[4]) && $match[4] !== "") {
444
                // String match
445
                $text .= $this->_parse_string($match[4]);
446
            } else if (isset($match[7]) && $match[7] !== "") {
447
                // Directive match
448
449
                if ($match[7] === "open-quote") {
450
                    // FIXME: do something here
451
                    $text .= $quotes[0][0];
452
                } else if ($match[7] === "close-quote") {
453
                    // FIXME: do something else here
454
                    $text .= $quotes[0][1];
455
                } else if ($match[7] === "no-open-quote") {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
456
                    // FIXME:
457
                } else if ($match[7] === "no-close-quote") {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
458
                    // FIXME:
459
                } else if (mb_strpos($match[7], "attr(") === 0) {
460
                    $i = mb_strpos($match[7], ")");
461
                    if ($i === false) {
462
                        continue;
463
                    }
464
465
                    $attr = mb_substr($match[7], 5, $i - 5);
466
                    if ($attr == "") {
467
                        continue;
468
                    }
469
470
                    $text .= $this->_frame->get_parent()->get_node()->getAttribute($attr);
0 ignored issues
show
Bug introduced by
The method getAttribute does only exist in DOMElement, but not in DOMText.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
471
                } else {
472
                    continue;
473
                }
474
            }
475
        }
476
477
        return $text;
478
    }
479
480
    /**
481
     * Sets the generated content of a generated frame
482
     */
483
    protected function _set_content()
484
    {
485
        $frame = $this->_frame;
486
        $style = $frame->get_style();
487
488
        // if the element was pushed to a new page use the saved counter value, otherwise use the CSS reset value
489
        if ($style->counter_reset && ($reset = $style->counter_reset) !== "none") {
0 ignored issues
show
Documentation introduced by
The property counter_reset does not exist on object<Dompdf\Css\Style>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
Documentation introduced by
The property counter_reset does not exist on object<Dompdf\Css\Style>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
490
            $vars = preg_split('/\s+/', trim($reset), 2);
491
            $frame->reset_counter($vars[0], (isset($frame->_counters['__' . $vars[0]]) ? $frame->_counters['__' . $vars[0]] : (isset($vars[1]) ? $vars[1] : 0)));
0 ignored issues
show
Bug introduced by
The property _counters does not seem to exist in Dompdf\Frame.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Dompdf\Frame as the method reset_counter() does only exist in the following sub-classes of Dompdf\Frame: Dompdf\FrameDecorator\AbstractFrameDecorator, Dompdf\FrameDecorator\Block, Dompdf\FrameDecorator\Image, Dompdf\FrameDecorator\Inline, Dompdf\FrameDecorator\ListBullet, Dompdf\FrameDecorator\ListBulletImage, Dompdf\FrameDecorator\NullFrameDecorator, Dompdf\FrameDecorator\Page, Dompdf\FrameDecorator\Table, Dompdf\FrameDecorator\TableCell, Dompdf\FrameDecorator\TableRow, Dompdf\FrameDecorator\TableRowGroup, Dompdf\FrameDecorator\Text. 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...
492
        }
493
494
        if ($style->counter_increment && ($increment = $style->counter_increment) !== "none") {
0 ignored issues
show
Documentation introduced by
The property counter_increment does not exist on object<Dompdf\Css\Style>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
Documentation introduced by
The property counter_increment does not exist on object<Dompdf\Css\Style>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
495
            $frame->increment_counters($increment);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Dompdf\Frame as the method increment_counters() does only exist in the following sub-classes of Dompdf\Frame: Dompdf\FrameDecorator\AbstractFrameDecorator, Dompdf\FrameDecorator\Block, Dompdf\FrameDecorator\Image, Dompdf\FrameDecorator\Inline, Dompdf\FrameDecorator\ListBullet, Dompdf\FrameDecorator\ListBulletImage, Dompdf\FrameDecorator\NullFrameDecorator, Dompdf\FrameDecorator\Page, Dompdf\FrameDecorator\Table, Dompdf\FrameDecorator\TableCell, Dompdf\FrameDecorator\TableRow, Dompdf\FrameDecorator\TableRowGroup, Dompdf\FrameDecorator\Text. 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...
496
        }
497
498
        if ($style->content && $frame->get_node()->nodeName === "dompdf_generated") {
0 ignored issues
show
Documentation introduced by
The property content does not exist on object<Dompdf\Css\Style>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
499
            $content = $this->_parse_content();
500
            // add generated content to the font subset
501
            // FIXME: This is currently too late because the font subset has already been generated.
502
            //        See notes in issue #750.
503
            if ($frame->get_dompdf()->getOptions()->getIsFontSubsettingEnabled() && $frame->get_dompdf()->get_canvas() instanceof CPDF) {
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Dompdf\Frame as the method get_dompdf() does only exist in the following sub-classes of Dompdf\Frame: Dompdf\FrameDecorator\AbstractFrameDecorator, Dompdf\FrameDecorator\Block, Dompdf\FrameDecorator\Image, Dompdf\FrameDecorator\Inline, Dompdf\FrameDecorator\ListBullet, Dompdf\FrameDecorator\ListBulletImage, Dompdf\FrameDecorator\NullFrameDecorator, Dompdf\FrameDecorator\Page, Dompdf\FrameDecorator\Table, Dompdf\FrameDecorator\TableCell, Dompdf\FrameDecorator\TableRow, Dompdf\FrameDecorator\TableRowGroup, Dompdf\FrameDecorator\Text. 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...
504
                $frame->get_dompdf()->get_canvas()->register_string_subset($style->font_family, $content);
0 ignored issues
show
Bug introduced by
The property font_family does not seem to exist. Did you mean _font_family?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Dompdf\Frame as the method get_dompdf() does only exist in the following sub-classes of Dompdf\Frame: Dompdf\FrameDecorator\AbstractFrameDecorator, Dompdf\FrameDecorator\Block, Dompdf\FrameDecorator\Image, Dompdf\FrameDecorator\Inline, Dompdf\FrameDecorator\ListBullet, Dompdf\FrameDecorator\ListBulletImage, Dompdf\FrameDecorator\NullFrameDecorator, Dompdf\FrameDecorator\Page, Dompdf\FrameDecorator\Table, Dompdf\FrameDecorator\TableCell, Dompdf\FrameDecorator\TableRow, Dompdf\FrameDecorator\TableRowGroup, Dompdf\FrameDecorator\Text. 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...
505
            }
506
507
            $node = $frame->get_node()->ownerDocument->createTextNode($content);
508
509
            $new_style = $style->get_stylesheet()->create_style();
510
            $new_style->inherit($style);
511
512
            $new_frame = new Frame($node);
513
            $new_frame->set_style($new_style);
514
515
            Factory::decorate_frame($new_frame, $frame->get_dompdf(), $frame->get_root());
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Dompdf\Frame as the method get_dompdf() does only exist in the following sub-classes of Dompdf\Frame: Dompdf\FrameDecorator\AbstractFrameDecorator, Dompdf\FrameDecorator\Block, Dompdf\FrameDecorator\Image, Dompdf\FrameDecorator\Inline, Dompdf\FrameDecorator\ListBullet, Dompdf\FrameDecorator\ListBulletImage, Dompdf\FrameDecorator\NullFrameDecorator, Dompdf\FrameDecorator\Page, Dompdf\FrameDecorator\Table, Dompdf\FrameDecorator\TableCell, Dompdf\FrameDecorator\TableRow, Dompdf\FrameDecorator\TableRowGroup, Dompdf\FrameDecorator\Text. 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...
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Dompdf\Frame as the method get_root() does only exist in the following sub-classes of Dompdf\Frame: Dompdf\FrameDecorator\AbstractFrameDecorator, Dompdf\FrameDecorator\Block, Dompdf\FrameDecorator\Image, Dompdf\FrameDecorator\Inline, Dompdf\FrameDecorator\ListBullet, Dompdf\FrameDecorator\ListBulletImage, Dompdf\FrameDecorator\NullFrameDecorator, Dompdf\FrameDecorator\Page, Dompdf\FrameDecorator\Table, Dompdf\FrameDecorator\TableCell, Dompdf\FrameDecorator\TableRow, Dompdf\FrameDecorator\TableRowGroup, Dompdf\FrameDecorator\Text. 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...
516
            $frame->append_child($new_frame);
517
        }
518
    }
519
520
    /**
521
     * Determine current frame width based on contents
522
     *
523
     * @return float
524
     */
525
    public function calculate_auto_width()
526
    {
527
        return $this->_frame->get_margin_width();
528
    }
529
}
530