Completed
Pull Request — master (#51)
by
unknown
02:35
created

Window::addChildren()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
ccs 3
cts 3
cp 1
cc 1
eloc 3
nc 1
nop 1
crap 1
1
<?php
2
3
namespace eXpansion\Framework\Core\Model\Gui;
4
5
use eXpansion\Framework\Core\Exceptions\Gui\MissingCloseActionException;
6
use eXpansion\Framework\Core\Model\UserGroups\Group;
7
use FML\Controls\Frame;
8
use FML\Controls\Label;
9
use FML\Controls\Quad;
10
use FML\Controls\Quads\Quad_Bgs1;
11
use FML\Controls\Quads\Quad_Bgs1InRace;
12
use FML\Elements\Format;
13
use FML\Types\Container;
14
use FML\Types\Renderable;
15
16
class Window extends Manialink implements Container
17
{
18
    /** @var \FML\ManiaLink */
19
    protected $manialink;
20
21
    /** @var Label */
22
    protected $closeButton;
23
24
    /** @var Frame */
25
    protected $contentFrame;
26
27 3
    public function __construct(
28
        Group $group,
29
        ManiaScriptFactory $windowManiaScriptFactory,
30
        $name,
31
        $sizeX,
32
        $sizeY,
33
        $posX = null,
34
        $posY = null
35
    )
36
    {
37 3
        parent::__construct($group, $name, $sizeX, $sizeY, $posX, $posY);
38
39 3
        $titleHeight = 5.5;
40 3
        $closeButtonWidth = 9.5;
41 3
        $titlebarColor = "3afe";
42
43
        // Manialink containing everything
44 3
        $this->manialink = new \FML\ManiaLink();
45 3
        $this->manialink->setId($this->getId())
46 3
            ->setName($name)
47 3
            ->setVersion(\FML\ManiaLink::VERSION_3);
48 3
        $windowFrame = new Frame('Window');
49 3
        $windowFrame->setPosition($posX, $posY);
50 3
        $this->manialink->addChild($windowFrame);
51
52
        // Frame to handle the content of the window.
53 3
        $this->contentFrame = new Frame();
54 3
        $this->contentFrame->setPosition(2, -$titleHeight - 2);
55 3
        $this->contentFrame->setSize($sizeX - 4, $sizeY - $titleHeight - 4);
56 3
        $windowFrame->addChild($this->contentFrame);
57
58
        // Title bar & title.
59 3
        $titleLabel = new Label();
60 3
        $titleLabel->setPosition(3, -$titleHeight / 3 - 1)
61 3
            ->setAlign(Label::LEFT, Label::CENTER2)
62 3
            ->setText($name)
63 3
            ->setTextColor('fff')
64 3
            ->setTextSize(2)
65 3
            ->setTextFont('RajdhaniMono')
66 3
            ->setId("TitleText");
67 3
        $windowFrame->addChild($titleLabel);
68
69 3
        $titleBar = new Quad();
70 3
        $titleBar->setSize($sizeX, 0.33)
71 3
            ->setPosition(0, -$titleHeight)
72 3
            ->setBackgroundColor('fff');
73 3
        $windowFrame->addChild($titleBar);
74
75 3
        $titleBar = new Quad();
76 3
        $titleBar->setSize($sizeX / 4, 0.5)
77 3
            ->setPosition(0, -$titleHeight)
78 3
            ->setBackgroundColor('fff');
79 3
        $windowFrame->addChild($titleBar);
80
81 3
        $titleBar = new Quad('Title');
82 3
        $titleBar->setSize($sizeX - $closeButtonWidth, $titleHeight)
83 3
            ->setBackgroundColor($titlebarColor)
84 3
            ->setScriptEvents(true);
85 3
        $windowFrame->addChild($titleBar);
86
87 3
        $this->closeButton = new Label('Close');
88 3
        $this->closeButton->setSize($closeButtonWidth, $titleHeight)
89 3
            ->setPosition($sizeX - $closeButtonWidth + ($closeButtonWidth / 2), -$titleHeight / 2)
90 3
            ->setAlign(Label::CENTER, Label::CENTER2)
91 3
            ->setText("✖")
92 3
            ->setTextColor('fff')
93 3
            ->setTextSize(2)
94 3
            ->setTextFont('OswaldMono')
95 3
            ->setScriptEvents(true)
96 3
            ->setAreaColor('d00')
97 3
            ->setAreaFocusColor('f22');
98 3
        $windowFrame->addChild($this->closeButton);
99
100
        //body
101 3
        $body = new Quad_Bgs1();
102 3
        $body->setSize($sizeX, $sizeY - $titleHeight)
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class FML\Controls\Control as the method setScriptEvents() does only exist in the following sub-classes of FML\Controls\Control: FML\Controls\Audio, FML\Controls\Entry, FML\Controls\FileEntry, FML\Controls\Frame3d, 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. 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...
103 3
            ->setPosition(0, -$titleHeight)
104 3
            ->setSubStyle(Quad_Bgs1::SUBSTYLE_BgWindow3)
105 3
            ->setId('WindowBg')
106 3
            ->setScriptEvents(true);
107 3
        $windowFrame->addChild($body);
108
109 3
        $body = new Quad_Bgs1InRace();
110 3
        $body->setSize($sizeX + 10, $sizeY + 10)
111 3
            ->setPosition(-5, 5)
112 3
            ->setSubStyle(Quad_Bgs1InRace::SUBSTYLE_BgButtonShadow);
113 3
        $windowFrame->addChild($body);
114
115
        // Add maniascript for window handling.
116 3
        $this->manialink->addChild($windowManiaScriptFactory->createScript(['']));
117 3
    }
118
119
    /**
120
     * Set action to close the window.
121
     *
122
     * @param $actionId
123
     */
124 1
    public function setCloseAction($actionId)
125
    {
126 1
        $this->closeButton->setDataAttributes(['action' => $actionId]);
127 1
    }
128
129
    /**
130
     * @inheritdoc
131
     */
132 2
    public function getXml()
133
    {
134 2
        if (empty($this->closeButton->getDataAttribute('action'))) {
135 1
            throw new MissingCloseActionException("Close action is missing for window. Check if you are using the proper factory.");
136
        }
137
138 1
        return $this->manialink->__toString();
139
    }
140
141
    /**
142
     * Get the children
143
     *
144
     * @api
145
     * @return Renderable[]
146
     */
147 1
    public function getChildren()
148
    {
149 1
        return $this->contentFrame->getChildren();
150
    }
151
152
    /**
153
     * Add a new child
154
     *
155
     * @api
156
     *
157
     * @param Renderable $child Child Control to add
158
     *
159
     * @return static
160
     */
161 1
    public function addChild(Renderable $child)
162
    {
163 1
        $this->contentFrame->addChild($child);
164
165 1
        return $this;
166
    }
167
168
    /**
169
     * Add a new child
170
     *
171
     * @api
172
     *
173
     * @param Renderable $child Child Control to add
174
     *
175
     * @return static
176
     * @deprecated Use addChild()
177
     * @see        Container::addChild()
178
     */
179 1
    public function add(Renderable $child)
180
    {
181 1
        $this->contentFrame->addChild($child);
182
183 1
        return $this;
184
    }
185
186
    /**
187
     * Add new children
188
     *
189
     * @api
190
     *
191
     * @param Renderable[] $children Child Controls to add
192
     *
193
     * @return static
194
     */
195 1
    public function addChildren(array $children)
196
    {
197 1
        $this->contentFrame->addChildren($children);
198
199 1
        return $this;
200
    }
201
202
    /**
203
     * Remove all children
204
     *
205
     * @api
206
     * @return static
207
     */
208 1
    public function removeAllChildren()
209
    {
210 1
        $this->contentFrame->removeAllChildren();
211
212 1
        return $this;
213
    }
214
215
    /**
216
     * Remove all children
217
     *
218
     * @api
219
     * @return static
220
     * @deprecated Use removeAllChildren()
221
     * @see        Container::removeAllChildren()
222
     */
223 1
    public function removeChildren()
224
    {
225 1
        $this->contentFrame->removeAllChildren();
226
227 1
        return $this;
228
    }
229
230
    /**
231
     * Get the Format
232
     *
233
     * @api
234
     *
235
     * @param bool $createIfEmpty If the format should be created if it doesn't exist yet
236
     *
237
     * @return Format
238
     * @deprecated Use Style
239
     * @see        Style
240
     */
241 1
    public function getFormat($createIfEmpty = true)
242
    {
243 1
        return $this->contentFrame->getFormat($createIfEmpty);
0 ignored issues
show
Deprecated Code introduced by
The method FML\Controls\Frame::getFormat() has been deprecated with message: Use Style

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
244
    }
245
246
    /**
247
     * Set the Format
248
     *
249
     * @api
250
     *
251
     * @param Format $format New Format
252
     *
253
     * @return static
254
     * @deprecated Use Style
255
     * @see        Style
256
     */
257 1
    public function setFormat(Format $format = null)
258
    {
259 1
        return $this->contentFrame->setFormat($format);
0 ignored issues
show
Deprecated Code introduced by
The method FML\Controls\Frame::setFormat() has been deprecated with message: Use Style

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
260
    }
261
262
    /**
263
     * @return Frame
264
     */
265
    public function getContentFrame()
266
    {
267
        return $this->contentFrame;
268
    }
269
}
270