Completed
Pull Request — master (#130)
by De Cramer
02:47
created

WindowFrameFactory::build()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 87
Code Lines 67

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 87
rs 8.6296
cc 1
eloc 67
nc 1
nop 5

How to fix   Long Method   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
2
3
namespace eXpansion\Framework\Core\Model\Gui\Factory;
4
5
use eXpansion\Framework\Core\Model\Gui\ManialinkInterface;
6
use eXpansion\Framework\Core\Model\Gui\ManiaScriptFactory;
7
use eXpansion\Framework\Core\Model\Gui\WindowFrameFactoryInterface;
8
use eXpansion\Framework\Gui\Components\uiButton;
9
use FML\Controls\Control;
10
use FML\Controls\Frame;
11
use FML\Controls\Label;
12
use FML\Controls\Quad;
13
use FML\ManiaLink;
14
use FML\Types\Container;
15
16
/**
17
 * Class WindowFrameFactory
18
 *
19
 * @author    de Cramer Oliver<[email protected]>
20
 * @copyright 2017 Smile
21
 * @package eXpansion\Framework\Core\Model\Gui\Factory
22
 */
23
class WindowFrameFactory implements WindowFrameFactoryInterface
24
{
25
    /** @var ManiaScriptFactory */
26
    protected $windowManiaScriptFactory;
27
28
    /** @var ManialinkInterface */
29
    protected $manialinkInterface;
30
31
    /**
32
     * WindowFrameFactory constructor.
33
     *
34
     * @param ManiaScriptFactory $maniaScriptFactory
35
     */
36
    public function __construct(ManiaScriptFactory $maniaScriptFactory)
37
    {
38
        $this->windowManiaScriptFactory = $maniaScriptFactory;
39
    }
40
41
    /**
42
     * Build the window frame content.
43
     *
44
     * @param ManiaLink $manialink
45
     * @param Frame|Container $mainFrame to build into
46
     * @param $name
47
     * @param float $sizeX Size of the inner frame to build the window frame around
48
     * @param float $sizeY Size of the inner frame to build the window frame around
49
     *
50
     * @return Control
51
     */
52
    public function build(ManiaLink $manialink, Frame $mainFrame, $name, $sizeX, $sizeY)
53
    {
54
        $titleHeight = 5.5;
55
        $closeButtonWidth = 9.5;
56
        $titlebarColor = "000e";
57
        $titleTextColor = "eff";
58
59
        // Creating sub frame to keep all the pieces together.
60
        $frame = new Frame();
61
        $frame->setPosition(-2, ($titleHeight) + 2);
62
        $mainFrame->addChild($frame);
63
64
        // Size of the actual window.
65
        $sizeX += 4;
66
        $sizeY += $titleHeight + 2;
67
68
        // Title bar & title.
69
        $titleLabel = new Label();
70
        $titleLabel->setPosition(3, -$titleHeight / 3 - 1)
71
            ->setAlign(Label::LEFT, Label::CENTER2)
72
            ->setTextId($name)
73
            ->setTextColor($titleTextColor)
74
            ->setTextSize(2)
75
            ->setTranslate(true)
76
            ->setTextFont('RajdhaniMono')
77
            ->setId("TitleText");
78
        $frame->addChild($titleLabel);
79
80
        $titleBar = new Quad();
81
        $titleBar->setSize($sizeX, 0.33)
82
            ->setPosition(0, -$titleHeight)
83
            ->setBackgroundColor('fff');
84
        $frame->addChild($titleBar);
85
86
        $titleBar = new Quad();
87
        $titleBar->setSize($sizeX / 4, 0.5)
88
            ->setPosition(0, -$titleHeight)
89
            ->setBackgroundColor('fff');
90
        $frame->addChild($titleBar);
91
92
        $titleBar = new Quad('Title');
93
        $titleBar->setSize($sizeX - $closeButtonWidth, $titleHeight)
94
            ->setBackgroundColor($titlebarColor)
95
            ->setScriptEvents(true);
96
        $frame->addChild($titleBar);
97
98
        $closeButton = new Label('Close');
99
        $closeButton->setSize($closeButtonWidth, $titleHeight)
100
            ->setPosition($sizeX - $closeButtonWidth + ($closeButtonWidth / 2), -$titleHeight / 2)
101
            ->setAlign(Label::CENTER, Label::CENTER2)
102
            ->setText("✖")
103
            ->setTextColor('fff')
104
            ->setTextSize(2)
105
            ->setTextFont('OswaldMono')
106
            ->setScriptEvents(true)
107
            ->setAreaColor($titlebarColor)
108
            ->setAreaFocusColor('f22');
109
        $frame->addChild($closeButton);
110
111
112
        //body
113
        $body = new Quad();
114
        $body->setSize($sizeX, $sizeY - $titleHeight)
115
            ->setPosition(0, -$titleHeight)
116
            ->setBackgroundColor("222")
117
            ->setOpacity(0.8);
118
        $frame->addChild($body);
119
120
        $body = new Quad();
121
        $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, eXpansion\Framework\Gui\Components\uiLabel. 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...
122
            ->setPosition(0, -$titleHeight)
123
            ->setStyles('Bgs1', 'BgDialogBlur')
124
            ->setId('WindowBg')
125
            ->setScriptEvents(true);
126
        $frame->addChild($body);
127
128
        $body = new Quad();
129
        $body->setSize($sizeX + 10, $sizeY + 10)
130
            ->setPosition(-5, 5)
131
            ->setStyles('Bgs1InRace', 'BgButtonShadow');
132
        $frame->addChild($body);
133
134
        // Add maniascript for window handling.
135
        $manialink->addChild($this->windowManiaScriptFactory->createScript(['']));
136
137
        return $closeButton;
138
    }
139
140
    /**
141
     * @param ManialinkInterface $manialinkInterface
142
     */
143
    public function setManialinkInterface(ManialinkInterface $manialinkInterface)
144
    {
145
        $this->manialinkInterface = $manialinkInterface;
146
    }
147
}
148