Completed
Pull Request — master (#304)
by
unknown
04:10
created

LayoutLine::addClass()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
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 = 0., $startY = 0., $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
134
        return $frame->render($domDocument);
135
    }
136
137
    /**
138
     * @param Control $element
139
     * @return double
140
     */
141
    private function getRelativeStartPosition($element)
142
    {
143
        if (is_null($element)) {
144
            return 0;
145
        }
146
        switch ($element->getHorizontalAlign()) {
147
            case "left":
148
                return 0;
149
            case "center":
150
                return 0.5 * $element->getWidth();
151
            case "right":
152
                return $element->getWidth();
153
            default:
154
                return 0;
155
        }
156
    }
157
158
    /**
159
     * @return float
160
     */
161
    public function getMargin(): float
162
    {
163
        return $this->margin;
164
    }
165
166
    /**
167
     * @param float $margin
168
     */
169
    public function setMargin($margin)
170
    {
171
        $this->margin = (float)$margin;
172
    }
173
174
    /**
175
     * @param Control $element
176
     * @return float|int
177
     */
178
    private function getStartPosition($element)
179
    {
180
        if (is_null($element)) {
181
            return 0;
182
        }
183
184
        switch ($element->getHorizontalAlign()) {
185
            case "center":
186
                return $element->getX() - (0.5 * $element->getWidth());
187
            default:
188
                return $element->getX();
189
        }
190
    }
191
192
    /**
193
     * Get the Script Features
194
     *
195
     * @return ScriptFeature[]
196
     */
197 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...
198
    {
199
        $features = [];
200
        foreach ($this->elements as $element) {
201
            if ($element instanceof ScriptFeatureable) {
202
                $features[] = $element->getScriptFeatures();
203
            }
204
        }
205
206
        return ScriptFeature::collect($features);
207
    }
208
209
    /**
210
     * @param mixed $startX
211
     * @return LayoutLine
212
     */
213
    public function setX($startX)
214
    {
215
        $this->startX = $startX;
216
217
        return $this;
218
    }
219
220
    /**
221
     * @param mixed $startY
222
     * @return LayoutLine
223
     */
224
    public function setY($startY)
225
    {
226
        $this->startY = $startY;
227
228
        return $this;
229
    }
230
231
    /**
232
     * @return float
233
     */
234
    public function getX()
235
    {
236
        return $this->startX;
237
    }
238
239
    /**
240
     * @return double
241
     */
242
    public function getY()
243
    {
244
        return $this->startY;
245
    }
246
247
    /**
248
     * @return float
249
     */
250
    public function getWidth()
251
    {
252
        return $this->width;
253
    }
254
255
    /**
256
     * @param float $width
257
     */
258
    public function setWidth($width)
259
    {
260
        $this->width = $width;
261
    }
262
263
    /**
264
     * @return float
265
     */
266
    public function getHeight()
267
    {
268
        return $this->height;
269
    }
270
271
    /**
272
     * @param float $height
273
     */
274
    public function setHeight($height)
275
    {
276
        $this->height = $height;
277
    }
278
279
    /**
280
     * @param Renderable $element
281
     */
282
    public function addChild(Renderable $element)
283
    {
284
        $this->elements[] = $element;
285
        $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\Bundle\Menu\Gui\Elements\MenuTabItem, eXpansion\Framework\Gui\Builders\WidgetBackground, eXpansion\Framework\Gui\Builders\WidgetLabel, eXpansion\Framework\Gui\...nents\AbstractUiElement, eXpansion\Framework\Gui\Components\Animation, eXpansion\Framework\Gui\Components\Button, eXpansion\Framework\Gui\Components\Checkbox, eXpansion\Framework\Gui\Components\ConfirmButton, eXpansion\Framework\Gui\Components\Dropdown, eXpansion\Framework\Gui\Components\Input, eXpansion\Framework\Gui\Components\InputMasked, eXpansion\Framework\Gui\Components\Label, eXpansion\Framework\Gui\Components\Line, eXpansion\Framework\Gui\Components\Scrollbar, eXpansion\Framework\Gui\Components\Textbox, eXpansion\Framework\Gui\Components\Tooltip, 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...
286
        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\Bundle\Menu\Gui\Elements\MenuTabItem, eXpansion\Framework\Gui\Builders\WidgetLabel, eXpansion\Framework\Gui\...nents\AbstractUiElement, eXpansion\Framework\Gui\Components\Animation, eXpansion\Framework\Gui\Components\Button, eXpansion\Framework\Gui\Components\Checkbox, eXpansion\Framework\Gui\Components\ConfirmButton, eXpansion\Framework\Gui\Components\Dropdown, eXpansion\Framework\Gui\Components\Input, eXpansion\Framework\Gui\Components\InputMasked, eXpansion\Framework\Gui\Components\Label, eXpansion\Framework\Gui\Components\Line, eXpansion\Framework\Gui\Components\Scrollbar, eXpansion\Framework\Gui\Components\Textbox, eXpansion\Framework\Gui\Components\Tooltip, 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\Bundle\Menu\Gui\Elements\MenuTabItem, eXpansion\Framework\Gui\Builders\WidgetBackground, eXpansion\Framework\Gui\Builders\WidgetLabel, eXpansion\Framework\Gui\...nents\AbstractUiElement, eXpansion\Framework\Gui\Components\Animation, eXpansion\Framework\Gui\Components\Button, eXpansion\Framework\Gui\Components\Checkbox, eXpansion\Framework\Gui\Components\ConfirmButton, eXpansion\Framework\Gui\Components\Dropdown, eXpansion\Framework\Gui\Components\Input, eXpansion\Framework\Gui\Components\InputMasked, eXpansion\Framework\Gui\Components\Label, eXpansion\Framework\Gui\Components\Line, eXpansion\Framework\Gui\Components\Scrollbar, eXpansion\Framework\Gui\Components\Textbox, eXpansion\Framework\Gui\Components\Tooltip, 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...
287
            $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\Bundle\Menu\Gui\Elements\MenuTabItem, eXpansion\Framework\Gui\Builders\WidgetLabel, eXpansion\Framework\Gui\...nents\AbstractUiElement, eXpansion\Framework\Gui\Components\Animation, eXpansion\Framework\Gui\Components\Button, eXpansion\Framework\Gui\Components\Checkbox, eXpansion\Framework\Gui\Components\ConfirmButton, eXpansion\Framework\Gui\Components\Dropdown, eXpansion\Framework\Gui\Components\Input, eXpansion\Framework\Gui\Components\InputMasked, eXpansion\Framework\Gui\Components\Label, eXpansion\Framework\Gui\Components\Line, eXpansion\Framework\Gui\Components\Scrollbar, eXpansion\Framework\Gui\Components\Textbox, eXpansion\Framework\Gui\Components\Tooltip, 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\Bundle\Menu\Gui\Elements\MenuTabItem, eXpansion\Framework\Gui\Builders\WidgetBackground, eXpansion\Framework\Gui\Builders\WidgetLabel, eXpansion\Framework\Gui\...nents\AbstractUiElement, eXpansion\Framework\Gui\Components\Animation, eXpansion\Framework\Gui\Components\Button, eXpansion\Framework\Gui\Components\Checkbox, eXpansion\Framework\Gui\Components\ConfirmButton, eXpansion\Framework\Gui\Components\Dropdown, eXpansion\Framework\Gui\Components\Input, eXpansion\Framework\Gui\Components\InputMasked, eXpansion\Framework\Gui\Components\Label, eXpansion\Framework\Gui\Components\Line, eXpansion\Framework\Gui\Components\Scrollbar, eXpansion\Framework\Gui\Components\Textbox, eXpansion\Framework\Gui\Components\Tooltip, 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...
288
        }
289
    }
290
291
    public function getChildren()
292
    {
293
        return $this->elements;
294
    }
295
296
297
    public function addClass($class)
298
    {
299
        $this->frameClasses [] = $class;
300
    }
301
302
    /**
303
     * Add a new child
304
     *
305
     * @api
306
     * @param Renderable $child Child Control to add
307
     * @return void
308
     * @deprecated Use addChild()
309
     * @see        Container::addChild()
310
     */
311
    public function add(Renderable $child)
312
    {
313
        // do nothing
314
    }
315
316
    /**
317
     * Add new children
318
     *
319
     * @api
320
     * @param Renderable[] $children Child Controls to add
321
     * @return void
322
     */
323
    public function addChildren(array $children)
324
    {
325
        foreach ($children as $child) {
326
            $this->addChild($child);
327
        }
328
    }
329
330
    /**
331
     * Remove all children
332
     *
333
     * @api
334
     * @return static
335
     */
336
    public function removeAllChildren()
337
    {
338
        $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...
339
        $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...
340
        $this->elements = [];
341
342
        return $this;
343
    }
344
345
    /**
346
     * Remove all children
347
     *
348
     * @api
349
     * @return void
350
     * @deprecated Use removeAllChildren()
351
     * @see        Container::removeAllChildren()
352
     */
353
    public function removeChildren()
354
    {
355
        // do nothing
356
    }
357
358
    /**
359
     * Get the Format
360
     *
361
     * @api
362
     * @param bool $createIfEmpty If the format should be created if it doesn't exist yet
363
     * @return void
364
     * @deprecated Use Style
365
     * @see        Style
366
     */
367
    public function getFormat($createIfEmpty = true)
368
    {
369
370
    }
371
372
    /**
373
     * Set the Format
374
     *
375
     * @api
376
     * @param Format $format New Format
377
     * @return void
378
     * @deprecated Use Style
379
     * @see        Style
380
     */
381
    public function setFormat(Format $format = null)
382
    {
383
384
    }
385
386
    public function setAlign($hAling = "left", $vAlign = "top")
387
    {
388
        $this->hAlign = $hAling;
389
        $this->vAlign = $vAlign;
390
391
        return $this;
392
    }
393
394
395
    public function setPosition($x, $y)
396
    {
397
        $this->setX($x);
398
        $this->setY($y);
399
400
        return $this;
401
    }
402
403
    /**
404
     * @return null|string
405
     */
406
    public function getId()
407
    {
408
        return $this->frameId;
409
    }
410
411
    /**
412
     * @param null|string $frameId
413
     * @return LayoutLine
414
     */
415
    public function setId($frameId)
416
    {
417
        $this->frameId = $frameId;
418
419
        return $this;
420
    }
421
422
    /**
423
     * @return string
424
     */
425
    public function getHorizontalAlign(): string
426
    {
427
        return $this->hAlign;
428
    }
429
430
    /**
431
     * @param string $hAlign
432
     * @return LayoutLine
433
     */
434
    public function setHorizontalAlign(string $hAlign)
435
    {
436
        $this->hAlign = $hAlign;
437
438
        return $this;
439
    }
440
441
}
442