Completed
Push — master ( 29e8d2...f3f56a )
by De Cramer
03:28
created

layoutLine   C

Complexity

Total Complexity 66

Size/Duplication

Total Lines 433
Duplicated Lines 6.24 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 66
lcom 1
cbo 3
dl 27
loc 433
rs 5.7474
c 0
b 0
f 0

29 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 7 19 4
C render() 9 56 21
B getRelativeStartPosition() 0 16 5
B getRelativeWidth() 0 16 5
A getStartPosition() 0 13 3
A getScriptFeatures() 11 11 3
A setX() 0 6 1
A setY() 0 6 1
A getX() 0 4 1
A getY() 0 4 1
A getWidth() 0 4 1
A setWidth() 0 4 1
A getHeight() 0 4 1
A setHeight() 0 4 1
A addChild() 0 8 2
A getChildren() 0 4 1
A addClass() 0 4 1
A add() 0 4 1
A addChildren() 0 6 2
A removeAllChildren() 0 8 1
A removeChildren() 0 4 1
A getFormat() 0 4 1
A setFormat() 0 4 1
A setAlign() 0 7 1
A setPosition() 0 7 1
A getId() 0 4 1
A setId() 0 6 1
A getHorizontalAlign() 0 4 1
A setHorizontalAlign() 0 6 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like layoutLine often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use layoutLine, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace eXpansion\Framework\Gui\Layouts;
4
5
use FML\Controls\Control;
6
use FML\Controls\Frame;
7
use FML\Elements\Format;
8
use FML\Script\Features\ScriptFeature;
9
use FML\Types\Container;
10
use FML\Types\Renderable;
11
use FML\Types\ScriptFeatureable;
12
13
class layoutLine implements Renderable, ScriptFeatureable, Container
14
{
15
    protected $frameClasses = [];
16
17
    protected $frameId = null;
18
19
    /** @var float */
20
    protected $width = 0.;
21
22
    /** @var float */
23
    protected $height = 0.;
24
25
    /** @var Control[] */
26
    protected $elements = [];
27
28
    /** @var float */
29
    private $margin = 2.;
30
    /**
31
     * @var float
32
     */
33
    protected $startX = 0.;
34
    /**
35
     * @var float
36
     */
37
    protected $startY = 0.;
38
39
    /** @var string */
40
    protected $hAlign = "left";
41
42
    /** @var string */
43
    protected $vAlign = "top";
44
45
    /**
46
     * layoutLine constructor.
47
     * @param float    $startX
48
     * @param float    $startY
49
     * @param object[] $elements
50
     * @param float    $margin
51
     * @throws \Exception
52
     */
53
    public function __construct($startX, $startY, $elements = [], $margin = 0.)
54
    {
55
        if (!is_array($elements)) {
56
            throw new \Exception('not an array');
57
        }
58
        $this->margin = $margin;
59
        $this->elements = $elements;
60
        $this->startX = $startX;
61
        $this->startY = $startY;
62
        $sizeY = 0;
63 View Code Duplication
        foreach ($this->elements as $idx => $element) {
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...
64
            $this->width += $element->getWidth() + $this->margin;
65
            if ((abs($element->getY()) + $element->getHeight()) > $sizeY) {
66
                $sizeY = abs($element->getY()) + $element->getHeight();
67
                $this->setHeight($sizeY);
68
            }
69
        }
70
71
    }
72
73
    /**
74
     * Render the XML element
75
     *
76
     * @param \DOMDocument $domDocument DOMDocument for which the XML element should be rendered
77
     * @return \DOMElement
78
     */
79
    public function render(\DOMDocument $domDocument)
80
    {
81
        $frame = new Frame();
82
        $frame->setId($this->frameId);
83
        $frame->setAlign($this->hAlign, $this->vAlign);
84
        $frame->setPosition($this->startX, $this->startY);
85
        $frame->addClasses($this->frameClasses);
86
        $sizeY = 0;
87
        $sizeX = 0;
88
        /** @var Control $oldElement */
89
        $oldElement = null;
90
        foreach ($this->elements as $idx => $element) {
91
92
            if ($idx === 0) {
93
                $start = $this->getRelativeStartPosition($element);
94
            } else {
95
                $start = $this->getStartPosition($oldElement) + $this->margin;
96
            }
97
98
            if ($oldElement) {
99
100
                if ($oldElement->getHorizontalAlign() == "center" && $element->getHorizontalAlign() == "center") {
101
                    $element->setX($start + $oldElement->getWidth() + ($element->getWidth() / 2));
102 View Code Duplication
                } elseif ($oldElement->getHorizontalAlign() == "left" && $element->getHorizontalAlign() == "center") {
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...
103
                    $element->setX($start + $oldElement->getWidth() + ($element->getWidth() / 2));
104
                } elseif ($oldElement->getHorizontalAlign() == "center" && $element->getHorizontalAlign() == "left") {
105
                    $element->setX($start + $oldElement->getWidth());
106 View Code Duplication
                } elseif ($oldElement->getHorizontalAlign() == "center" && $element->getHorizontalAlign() == "right") {
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...
107
                    $element->setX($start + $oldElement->getWidth() + $element->getWidth());
108
                } elseif ($oldElement->getHorizontalAlign() == "right" && $element->getHorizontalAlign() == "right") {
109
                    $element->setX($start + $element->getWidth());
110 View Code Duplication
                } elseif ($oldElement->getHorizontalAlign() == "right" && $element->getHorizontalAlign() == "center") {
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...
111
                    $element->setX($start + ($element->getWidth() / 2));
112
                } elseif ($oldElement->getHorizontalAlign() == "left" && $element->getHorizontalAlign() == "right") {
113
                    $element->setX($start + $oldElement->getWidth() + $element->getWidth());
114
                } elseif ($oldElement->getHorizontalAlign() == "right" && $element->getHorizontalAlign() == "left") {
115
                    $element->setX($start);
116
                } else {
117
                    $element->setX($start + $oldElement->getWidth());
118
                }
119
            } else {
120
                $element->setX($start);
121
            }
122
123
            if ((abs($element->getY()) + $element->getHeight()) > $sizeY) {
124
                $sizeY = abs($element->getY()) + $element->getHeight();
125
                $this->setHeight($sizeY);
126
            }
127
            $frame->addChild($element);
128
            $oldElement = $element;
129
            $sizeX += $element->getWidth() + $this->margin;
130
        }
131
132
        $this->setWidth($sizeX);
133
        return $frame->render($domDocument);
134
    }
135
136
    /**
137
     * @param Control $element
138
     * @return double
139
     */
140
    private function getRelativeStartPosition($element)
141
    {
142
        if (is_null($element)) {
143
            return 0;
144
        }
145
        switch ($element->getHorizontalAlign()) {
146
            case "left":
147
                return 0;
148
            case "center":
149
                return 0.5 * $element->getWidth();
150
            case "right":
151
                return $element->getWidth();
152
            default:
153
                return 0;
154
        }
155
    }
156
157
    /**
158
     * @param Control $element
159
     * @return float|int
160
     */
161
    private function getRelativeWidth($element)
0 ignored issues
show
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
162
    {
163
        if (is_null($element)) {
164
            return 0;
165
        }
166
        switch ($element->getHorizontalAlign()) {
167
            case "right":
168
                return $element->getWidth();
169
            case "center":
170
                return $element->getWidth();
171
            case "left":
172
                return $element->getWidth();
173
            default :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a DEFAULT statement

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

switch ($expr) {
    default : //wrong
        doSomething();
        break;
}

switch ($expr) {
    default: //right
        doSomething();
        break;
}

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

Loading history...
174
                return $element->getWidth();
175
        }
176
    }
177
178
    /**
179
     * @param Control $element
180
     * @return float|int
181
     */
182
    private function getStartPosition($element)
183
    {
184
        if (is_null($element)) {
185
            return 0;
186
        }
187
188
        switch ($element->getHorizontalAlign()) {
189
            case "center":
190
                return $element->getX() - (0.5 * $element->getWidth());
191
            default:
192
                return $element->getX();
193
        }
194
    }
195
196
    /**
197
     * Get the Script Features
198
     *
199
     * @return ScriptFeature[]
200
     */
201 View Code Duplication
    public function getScriptFeatures()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
202
    {
203
        $features = [];
204
        foreach ($this->elements as $element) {
205
            if ($element instanceof ScriptFeatureable) {
206
                $features[] = $element->getScriptFeatures();
207
            }
208
        }
209
210
        return ScriptFeature::collect($features);
211
    }
212
213
    /**
214
     * @param mixed $startX
215
     * @return layoutLine
216
     */
217
    public function setX($startX)
218
    {
219
        $this->startX = $startX;
220
221
        return $this;
222
    }
223
224
    /**
225
     * @param mixed $startY
226
     * @return layoutLine
227
     */
228
    public function setY($startY)
229
    {
230
        $this->startY = $startY;
231
232
        return $this;
233
    }
234
235
    /**
236
     * @return float
237
     */
238
    public function getX()
239
    {
240
        return $this->startX;
241
    }
242
243
    /**
244
     * @return double
245
     */
246
    public function getY()
247
    {
248
        return $this->startY;
249
    }
250
251
    /**
252
     * @return float
253
     */
254
    public function getWidth()
255
    {
256
        return $this->width;
257
    }
258
259
    /**
260
     * @param float $width
261
     */
262
    public function setWidth($width)
263
    {
264
        $this->width = $width;
265
    }
266
267
    /**
268
     * @return float
269
     */
270
    public function getHeight()
271
    {
272
        return $this->height;
273
    }
274
275
    /**
276
     * @param float $height
277
     */
278
    public function setHeight($height)
279
    {
280
        $this->height = $height;
281
    }
282
283
    /**
284
     * @param Renderable $element
285
     */
286
    public function addChild(Renderable $element)
287
    {
288
        $this->elements[] = $element;
289
        $this->width += $element->getWidth() + $this->margin;
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface FML\Types\Renderable as the method getWidth() does only exist in the following implementations of said interface: ControlStub, FML\Controls\Audio, FML\Controls\Control, FML\Controls\Entry, FML\Controls\FileEntry, FML\Controls\Frame, FML\Controls\Frame3d, FML\Controls\FrameInstance, FML\Controls\Gauge, FML\Controls\Graph, FML\Controls\Label, FML\Controls\Labels\Label_Button, FML\Controls\Labels\Label_Text, FML\Controls\Quad, FML\Controls\Quads\Quad_321Go, FML\Controls\Quads\Quad_BgRaceScore2, FML\Controls\Quads\Quad_Bgs1, FML\Controls\Quads\Quad_Bgs1InRace, FML\Controls\Quads\Quad_BgsButtons, FML\Controls\Quads\Quad_BgsChallengeMedals, FML\Controls\Quads\Quad_BgsPlayerCard, FML\Controls\Quads\Quad_Copilot, FML\Controls\Quads\Quad_Emblems, FML\Controls\Quads\Quad_EnergyBar, FML\Controls\Quads\Quad_Hud3dEchelons, FML\Controls\Quads\Quad_Hud3dIcons, FML\Controls\Quads\Quad_Icons128x128_1, FML\Controls\Quads\Quad_Icons128x128_Blink, FML\Controls\Quads\Quad_Icons128x32_1, FML\Controls\Quads\Quad_Icons64x64_1, FML\Controls\Quads\Quad_Icons64x64_2, FML\Controls\Quads\Quad_ManiaPlanetLogos, FML\Controls\Quads\Quad_ManiaPlanetMainMenu, FML\Controls\Quads\Quad_ManiaplanetSystem, FML\Controls\Quads\Quad_MedalsBig, FML\Controls\Quads\Quad_TitleLogos, FML\Controls\Quads\Quad_...structionBullet_Buttons, FML\Controls\Quads\Quad_UIConstruction_Buttons, FML\Controls\Quads\Quad_UIConstruction_Buttons2, FML\Controls\Quads\Quad_UiSMSpectatorScoreBig, FML\Controls\TextEdit, FML\Controls\Video, eXpansion\Framework\Gui\Builders\WidgetBackground, eXpansion\Framework\Gui\Builders\WidgetLabel, eXpansion\Framework\Gui\...nents\abstractUiElement, eXpansion\Framework\Gui\Components\uiAnimation, eXpansion\Framework\Gui\Components\uiButton, eXpansion\Framework\Gui\Components\uiCheckbox, eXpansion\Framework\Gui\Components\uiConfirmButton, eXpansion\Framework\Gui\Components\uiDropdown, eXpansion\Framework\Gui\Components\uiInput, eXpansion\Framework\Gui\Components\uiInputMasked, eXpansion\Framework\Gui\Components\uiLabel, eXpansion\Framework\Gui\Components\uiLine, eXpansion\Framework\Gui\Components\uiScrollbar, eXpansion\Framework\Gui\Components\uiTextbox, eXpansion\Framework\Gui\Components\uiTooltip, eXpansion\Framework\Gui\Layouts\layoutLine, eXpansion\Framework\Gui\Layouts\layoutRow, eXpansion\Framework\Gui\Layouts\layoutScrollable.

Let’s take a look at an example:

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

class MyUser implements 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 implementation 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 interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
290
        if ((abs($element->getY()) + $element->getHeight()) > $this->getHeight()) {
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface FML\Types\Renderable as the method getY() does only exist in the following implementations of said interface: ControlStub, FML\Controls\Audio, FML\Controls\Control, FML\Controls\Entry, FML\Controls\FileEntry, FML\Controls\Frame, FML\Controls\Frame3d, FML\Controls\FrameInstance, FML\Controls\Gauge, FML\Controls\Graph, FML\Controls\Label, FML\Controls\Labels\Label_Button, FML\Controls\Labels\Label_Text, FML\Controls\Quad, FML\Controls\Quads\Quad_321Go, FML\Controls\Quads\Quad_BgRaceScore2, FML\Controls\Quads\Quad_Bgs1, FML\Controls\Quads\Quad_Bgs1InRace, FML\Controls\Quads\Quad_BgsButtons, FML\Controls\Quads\Quad_BgsChallengeMedals, FML\Controls\Quads\Quad_BgsPlayerCard, FML\Controls\Quads\Quad_Copilot, FML\Controls\Quads\Quad_Emblems, FML\Controls\Quads\Quad_EnergyBar, FML\Controls\Quads\Quad_Hud3dEchelons, FML\Controls\Quads\Quad_Hud3dIcons, FML\Controls\Quads\Quad_Icons128x128_1, FML\Controls\Quads\Quad_Icons128x128_Blink, FML\Controls\Quads\Quad_Icons128x32_1, FML\Controls\Quads\Quad_Icons64x64_1, FML\Controls\Quads\Quad_Icons64x64_2, FML\Controls\Quads\Quad_ManiaPlanetLogos, FML\Controls\Quads\Quad_ManiaPlanetMainMenu, FML\Controls\Quads\Quad_ManiaplanetSystem, FML\Controls\Quads\Quad_MedalsBig, FML\Controls\Quads\Quad_TitleLogos, FML\Controls\Quads\Quad_...structionBullet_Buttons, FML\Controls\Quads\Quad_UIConstruction_Buttons, FML\Controls\Quads\Quad_UIConstruction_Buttons2, FML\Controls\Quads\Quad_UiSMSpectatorScoreBig, FML\Controls\TextEdit, FML\Controls\Video, eXpansion\Framework\Gui\Builders\WidgetLabel, eXpansion\Framework\Gui\...nents\abstractUiElement, eXpansion\Framework\Gui\Components\uiAnimation, eXpansion\Framework\Gui\Components\uiButton, eXpansion\Framework\Gui\Components\uiCheckbox, eXpansion\Framework\Gui\Components\uiConfirmButton, eXpansion\Framework\Gui\Components\uiDropdown, eXpansion\Framework\Gui\Components\uiInput, eXpansion\Framework\Gui\Components\uiInputMasked, eXpansion\Framework\Gui\Components\uiLabel, eXpansion\Framework\Gui\Components\uiLine, eXpansion\Framework\Gui\Components\uiScrollbar, eXpansion\Framework\Gui\Components\uiTextbox, eXpansion\Framework\Gui\Components\uiTooltip, eXpansion\Framework\Gui\Layouts\layoutLine, eXpansion\Framework\Gui\Layouts\layoutRow, eXpansion\Framework\Gui\Layouts\layoutScrollable.

Let’s take a look at an example:

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

class MyUser implements 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 implementation 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 interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
Bug introduced by
It seems like you code against a concrete implementation and not the interface FML\Types\Renderable as the method getHeight() does only exist in the following implementations of said interface: ControlStub, FML\Controls\Audio, FML\Controls\Control, FML\Controls\Entry, FML\Controls\FileEntry, FML\Controls\Frame, FML\Controls\Frame3d, FML\Controls\FrameInstance, FML\Controls\Gauge, FML\Controls\Graph, FML\Controls\Label, FML\Controls\Labels\Label_Button, FML\Controls\Labels\Label_Text, FML\Controls\Quad, FML\Controls\Quads\Quad_321Go, FML\Controls\Quads\Quad_BgRaceScore2, FML\Controls\Quads\Quad_Bgs1, FML\Controls\Quads\Quad_Bgs1InRace, FML\Controls\Quads\Quad_BgsButtons, FML\Controls\Quads\Quad_BgsChallengeMedals, FML\Controls\Quads\Quad_BgsPlayerCard, FML\Controls\Quads\Quad_Copilot, FML\Controls\Quads\Quad_Emblems, FML\Controls\Quads\Quad_EnergyBar, FML\Controls\Quads\Quad_Hud3dEchelons, FML\Controls\Quads\Quad_Hud3dIcons, FML\Controls\Quads\Quad_Icons128x128_1, FML\Controls\Quads\Quad_Icons128x128_Blink, FML\Controls\Quads\Quad_Icons128x32_1, FML\Controls\Quads\Quad_Icons64x64_1, FML\Controls\Quads\Quad_Icons64x64_2, FML\Controls\Quads\Quad_ManiaPlanetLogos, FML\Controls\Quads\Quad_ManiaPlanetMainMenu, FML\Controls\Quads\Quad_ManiaplanetSystem, FML\Controls\Quads\Quad_MedalsBig, FML\Controls\Quads\Quad_TitleLogos, FML\Controls\Quads\Quad_...structionBullet_Buttons, FML\Controls\Quads\Quad_UIConstruction_Buttons, FML\Controls\Quads\Quad_UIConstruction_Buttons2, FML\Controls\Quads\Quad_UiSMSpectatorScoreBig, FML\Controls\TextEdit, FML\Controls\Video, eXpansion\Framework\Gui\Builders\WidgetBackground, eXpansion\Framework\Gui\Builders\WidgetLabel, eXpansion\Framework\Gui\...nents\abstractUiElement, eXpansion\Framework\Gui\Components\uiAnimation, eXpansion\Framework\Gui\Components\uiButton, eXpansion\Framework\Gui\Components\uiCheckbox, eXpansion\Framework\Gui\Components\uiConfirmButton, eXpansion\Framework\Gui\Components\uiDropdown, eXpansion\Framework\Gui\Components\uiInput, eXpansion\Framework\Gui\Components\uiInputMasked, eXpansion\Framework\Gui\Components\uiLabel, eXpansion\Framework\Gui\Components\uiLine, eXpansion\Framework\Gui\Components\uiScrollbar, eXpansion\Framework\Gui\Components\uiTextbox, eXpansion\Framework\Gui\Components\uiTooltip, eXpansion\Framework\Gui\Layouts\layoutLine, eXpansion\Framework\Gui\Layouts\layoutRow, eXpansion\Framework\Gui\Layouts\layoutScrollable.

Let’s take a look at an example:

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

class MyUser implements 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 implementation 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 interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
291
            $this->setHeight(abs($element->getY()) + $element->getHeight());
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface FML\Types\Renderable as the method getY() does only exist in the following implementations of said interface: ControlStub, FML\Controls\Audio, FML\Controls\Control, FML\Controls\Entry, FML\Controls\FileEntry, FML\Controls\Frame, FML\Controls\Frame3d, FML\Controls\FrameInstance, FML\Controls\Gauge, FML\Controls\Graph, FML\Controls\Label, FML\Controls\Labels\Label_Button, FML\Controls\Labels\Label_Text, FML\Controls\Quad, FML\Controls\Quads\Quad_321Go, FML\Controls\Quads\Quad_BgRaceScore2, FML\Controls\Quads\Quad_Bgs1, FML\Controls\Quads\Quad_Bgs1InRace, FML\Controls\Quads\Quad_BgsButtons, FML\Controls\Quads\Quad_BgsChallengeMedals, FML\Controls\Quads\Quad_BgsPlayerCard, FML\Controls\Quads\Quad_Copilot, FML\Controls\Quads\Quad_Emblems, FML\Controls\Quads\Quad_EnergyBar, FML\Controls\Quads\Quad_Hud3dEchelons, FML\Controls\Quads\Quad_Hud3dIcons, FML\Controls\Quads\Quad_Icons128x128_1, FML\Controls\Quads\Quad_Icons128x128_Blink, FML\Controls\Quads\Quad_Icons128x32_1, FML\Controls\Quads\Quad_Icons64x64_1, FML\Controls\Quads\Quad_Icons64x64_2, FML\Controls\Quads\Quad_ManiaPlanetLogos, FML\Controls\Quads\Quad_ManiaPlanetMainMenu, FML\Controls\Quads\Quad_ManiaplanetSystem, FML\Controls\Quads\Quad_MedalsBig, FML\Controls\Quads\Quad_TitleLogos, FML\Controls\Quads\Quad_...structionBullet_Buttons, FML\Controls\Quads\Quad_UIConstruction_Buttons, FML\Controls\Quads\Quad_UIConstruction_Buttons2, FML\Controls\Quads\Quad_UiSMSpectatorScoreBig, FML\Controls\TextEdit, FML\Controls\Video, eXpansion\Framework\Gui\Builders\WidgetLabel, eXpansion\Framework\Gui\...nents\abstractUiElement, eXpansion\Framework\Gui\Components\uiAnimation, eXpansion\Framework\Gui\Components\uiButton, eXpansion\Framework\Gui\Components\uiCheckbox, eXpansion\Framework\Gui\Components\uiConfirmButton, eXpansion\Framework\Gui\Components\uiDropdown, eXpansion\Framework\Gui\Components\uiInput, eXpansion\Framework\Gui\Components\uiInputMasked, eXpansion\Framework\Gui\Components\uiLabel, eXpansion\Framework\Gui\Components\uiLine, eXpansion\Framework\Gui\Components\uiScrollbar, eXpansion\Framework\Gui\Components\uiTextbox, eXpansion\Framework\Gui\Components\uiTooltip, eXpansion\Framework\Gui\Layouts\layoutLine, eXpansion\Framework\Gui\Layouts\layoutRow, eXpansion\Framework\Gui\Layouts\layoutScrollable.

Let’s take a look at an example:

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

class MyUser implements 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 implementation 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 interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
Bug introduced by
It seems like you code against a concrete implementation and not the interface FML\Types\Renderable as the method getHeight() does only exist in the following implementations of said interface: ControlStub, FML\Controls\Audio, FML\Controls\Control, FML\Controls\Entry, FML\Controls\FileEntry, FML\Controls\Frame, FML\Controls\Frame3d, FML\Controls\FrameInstance, FML\Controls\Gauge, FML\Controls\Graph, FML\Controls\Label, FML\Controls\Labels\Label_Button, FML\Controls\Labels\Label_Text, FML\Controls\Quad, FML\Controls\Quads\Quad_321Go, FML\Controls\Quads\Quad_BgRaceScore2, FML\Controls\Quads\Quad_Bgs1, FML\Controls\Quads\Quad_Bgs1InRace, FML\Controls\Quads\Quad_BgsButtons, FML\Controls\Quads\Quad_BgsChallengeMedals, FML\Controls\Quads\Quad_BgsPlayerCard, FML\Controls\Quads\Quad_Copilot, FML\Controls\Quads\Quad_Emblems, FML\Controls\Quads\Quad_EnergyBar, FML\Controls\Quads\Quad_Hud3dEchelons, FML\Controls\Quads\Quad_Hud3dIcons, FML\Controls\Quads\Quad_Icons128x128_1, FML\Controls\Quads\Quad_Icons128x128_Blink, FML\Controls\Quads\Quad_Icons128x32_1, FML\Controls\Quads\Quad_Icons64x64_1, FML\Controls\Quads\Quad_Icons64x64_2, FML\Controls\Quads\Quad_ManiaPlanetLogos, FML\Controls\Quads\Quad_ManiaPlanetMainMenu, FML\Controls\Quads\Quad_ManiaplanetSystem, FML\Controls\Quads\Quad_MedalsBig, FML\Controls\Quads\Quad_TitleLogos, FML\Controls\Quads\Quad_...structionBullet_Buttons, FML\Controls\Quads\Quad_UIConstruction_Buttons, FML\Controls\Quads\Quad_UIConstruction_Buttons2, FML\Controls\Quads\Quad_UiSMSpectatorScoreBig, FML\Controls\TextEdit, FML\Controls\Video, eXpansion\Framework\Gui\Builders\WidgetBackground, eXpansion\Framework\Gui\Builders\WidgetLabel, eXpansion\Framework\Gui\...nents\abstractUiElement, eXpansion\Framework\Gui\Components\uiAnimation, eXpansion\Framework\Gui\Components\uiButton, eXpansion\Framework\Gui\Components\uiCheckbox, eXpansion\Framework\Gui\Components\uiConfirmButton, eXpansion\Framework\Gui\Components\uiDropdown, eXpansion\Framework\Gui\Components\uiInput, eXpansion\Framework\Gui\Components\uiInputMasked, eXpansion\Framework\Gui\Components\uiLabel, eXpansion\Framework\Gui\Components\uiLine, eXpansion\Framework\Gui\Components\uiScrollbar, eXpansion\Framework\Gui\Components\uiTextbox, eXpansion\Framework\Gui\Components\uiTooltip, eXpansion\Framework\Gui\Layouts\layoutLine, eXpansion\Framework\Gui\Layouts\layoutRow, eXpansion\Framework\Gui\Layouts\layoutScrollable.

Let’s take a look at an example:

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

class MyUser implements 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 implementation 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 interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
292
        }
293
    }
294
295
    public function getChildren()
296
    {
297
        return $this->elements;
298
    }
299
300
301
    public function addClass($class)
302
    {
303
        $this->frameClasses [] = $class;
304
    }
305
306
    /**
307
     * Add a new child
308
     *
309
     * @api
310
     * @param Renderable $child Child Control to add
311
     * @return void
312
     * @deprecated Use addChild()
313
     * @see        Container::addChild()
314
     */
315
    public function add(Renderable $child)
316
    {
317
        // do nothing
318
    }
319
320
    /**
321
     * Add new children
322
     *
323
     * @api
324
     * @param Renderable[] $children Child Controls to add
325
     * @return void
326
     */
327
    public function addChildren(array $children)
328
    {
329
        foreach ($children as $child) {
330
            $this->addChild($child);
331
        }
332
    }
333
334
    /**
335
     * Remove all children
336
     *
337
     * @api
338
     * @return static
339
     */
340
    public function removeAllChildren()
341
    {
342
        $this->width = 0;
0 ignored issues
show
Documentation Bug introduced by
The property $width was declared of type double, but 0 is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
343
        $this->height = 0;
0 ignored issues
show
Documentation Bug introduced by
The property $height was declared of type double, but 0 is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
344
        $this->elements = [];
345
346
        return $this;
347
    }
348
349
    /**
350
     * Remove all children
351
     *
352
     * @api
353
     * @return void
354
     * @deprecated Use removeAllChildren()
355
     * @see        Container::removeAllChildren()
356
     */
357
    public function removeChildren()
358
    {
359
        // do nothing
360
    }
361
362
    /**
363
     * Get the Format
364
     *
365
     * @api
366
     * @param bool $createIfEmpty If the format should be created if it doesn't exist yet
367
     * @return void
368
     * @deprecated Use Style
369
     * @see        Style
370
     */
371
    public function getFormat($createIfEmpty = true)
372
    {
373
374
    }
375
376
    /**
377
     * Set the Format
378
     *
379
     * @api
380
     * @param Format $format New Format
381
     * @return void
382
     * @deprecated Use Style
383
     * @see        Style
384
     */
385
    public function setFormat(Format $format = null)
386
    {
387
388
    }
389
390
    public function setAlign($hAling = "left", $vAlign = "top")
391
    {
392
        $this->hAlign = $hAling;
393
        $this->vAlign = $vAlign;
394
395
        return $this;
396
    }
397
398
399
    public function setPosition($x, $y)
400
    {
401
        $this->setX($x);
402
        $this->setY($y);
403
404
        return $this;
405
    }
406
407
    /**
408
     * @return null|string
409
     */
410
    public function getId()
411
    {
412
        return $this->frameId;
413
    }
414
415
    /**
416
     * @param null|string $frameId
417
     * @return layoutLine
418
     */
419
    public function setId($frameId)
420
    {
421
        $this->frameId = $frameId;
422
423
        return $this;
424
    }
425
426
    /**
427
     * @return string
428
     */
429
    public function getHorizontalAlign(): string
430
    {
431
        return $this->hAlign;
432
    }
433
434
    /**
435
     * @param string $hAlign
436
     * @return layoutLine
437
     */
438
    public function setHorizontalAlign(string $hAlign)
439
    {
440
        $this->hAlign = $hAlign;
441
442
        return $this;
443
    }
444
445
}
446