Completed
Pull Request — master (#292)
by De Cramer
04:21
created

ScriptVariableUpdateFactory::create()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 2
cp 0
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
crap 2
1
<?php
2
3
namespace eXpansion\Framework\Core\Plugins\Gui;
4
5
use eXpansion\Framework\Core\DataProviders\Listener\ListenerInterfaceExpTimer;
6
use eXpansion\Framework\Core\DataProviders\Listener\ListenerInterfaceExpUserGroup;
7
use eXpansion\Framework\Core\Model\Gui\ManialinkFactoryContext;
8
use eXpansion\Framework\Core\Model\Gui\ManialinkInterface;
9
use eXpansion\Framework\Core\Model\Gui\Script\Variable;
10
use eXpansion\Framework\Core\Model\Gui\WidgetFactoryContext;
11
use eXpansion\Framework\Core\Model\UserGroups\Group;
12
use FML\Script\Script;
13
use FML\Script\ScriptLabel;
14
15
/**
16
 * Class ScriptVariableUpdateFactory
17
 *
18
 * @author    de Cramer Oliver<[email protected]>
19
 * @copyright 2018 eXpansion
20
 * @package eXpansion\Framework\Core\Plugins\Gui
21
 */
22
class ScriptVariableUpdateFactory extends WidgetFactory implements ListenerInterfaceExpTimer, ListenerInterfaceExpUserGroup
23
{
24
    /** @var Variable[] */
25
    protected $variables = [];
26
27
    /** @var Variable */
28
    protected $checkVariable;
29
30
    /** @var int */
31
    protected $maxUpdateFrequency;
32
33
    /** @var Variable */
34
    protected $checkOldVariable;
35
36
    /** @var mixed[][] */
37
    protected $queuedForUpdate = [];
38
39
    /**
40
     * ScriptVariableUpdateFactory constructor.
41
     *
42
     * @param                      $name
43
     * @param array                $variables
44
     * @param int                  $maxUpdateFrequency
45
     * @param Group                $playerGroup
0 ignored issues
show
Bug introduced by
There is no parameter named $playerGroup. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
46
     * @param WidgetFactoryContext $context
47
     */
48
    public function __construct($name, array  $variables, int $maxUpdateFrequency = 1, WidgetFactoryContext $context)
49
    {
50
        parent::__construct($name, 0, 0, 0, 0, $context);
51
        $this->maxUpdateFrequency = $maxUpdateFrequency;
52
53
        foreach ($variables as $variable) {
54
            $this->variables[$variable['name']] = new Variable(
55
                $variable['name'],
56
                $variable['type'],
57
                'This',
58
                $variable['default']
59
            );
60
        }
61
62
        $uniqueId = uniqid('exp_',true);
63
        $this->checkVariable = new Variable('check', 'Text', 'This', "\"$uniqueId\"");
64
        $this->checkOldVariable = new Variable('check_old', 'Text', 'Page', "\"$uniqueId\"");
65
    }
66
67
    /**
68
     * Update script value.
69
     *
70
     * @param Group  $group
71
     * @param string $variableCode
72
     * @param string $newValue
73
     */
74
    public function updateValue($group, $variableCode, $newValue)
75
    {
76
        $variable = clone $this->getVariable($variableCode);
77
        $variable->setValue($newValue);
78
79
        if (!isset($this->queuedForUpdate[$group->getName()])) {
80
            $checkVariable = clone $this->checkVariable;
81
            $uniqueId = uniqid('exp_',true);
82
            $checkVariable->setValue($uniqueId);
83
84
            $this->queuedForUpdate[$group->getName()]['group'] = $group;
85
            $this->queuedForUpdate[$group->getName()]['time'] = time();
86
            $this->queuedForUpdate[$group->getName()]['variables'][$variableCode] = $variable;
87
            $this->queuedForUpdate[$group->getName()]['check'] = $checkVariable;
88
        }
89
    }
90
91
    /**
92
     * Get a variable.
93
     *
94
     * @param $variable
95
     *
96
     * @return Variable
97
     */
98
    public function getVariable($variable)
99
    {
100
        return $this->variables[$variable];
101
    }
102
103
    /**
104
     * Get variable to use to check if data needs to be updated.
105
     *
106
     * @return Variable
107
     */
108
    public function getCheckVariable()
109
    {
110
        return $this->checkVariable;
111
    }
112
113
    /**
114
     * Get script to execute when there is a change.
115
     *
116
     * @param string $toExecute Script to execute.
117
     *
118
     * @return string
119
     */
120
    public function getScriptOnChange($toExecute)
121
    {
122
        return <<<EOL
123
            if ({$this->checkVariable->getVariableName()} != {$this->checkOldVariable->getVariableName()}) {
124
                {$this->checkOldVariable->getVariableName()} = {$this->checkVariable->getVariableName()};
125
                $toExecute
126
            }
127
EOL;
128
    }
129
130
    /**
131
     * Get initialization script.
132
     *
133
     * @param bool $defaultValues
134
     * @return string
135
     */
136
    public function getScriptInitialization($defaultValues = false)
137
    {
138
        $scriptContent = '';
139
        foreach ($this->variables as $variable) {
140
            $scriptContent .= $variable->getScriptDeclaration() . "\n";
141
            if ($defaultValues) {
142
                $scriptContent .= $variable->getScriptValueSet() . "\n";
143
            }
144
        }
145
        $scriptContent .= $this->checkVariable->getScriptDeclaration() . "\n";
146
        $scriptContent .= $this->checkOldVariable->getScriptDeclaration() . "\n";
147
        if ($defaultValues) {
148
            $scriptContent .= $this->checkVariable->getScriptValueSet() . "\n";
149
            $scriptContent .= $this->checkOldVariable->getVariableName() . ' = "";';
150
        }
151
152
        return $scriptContent;
153
    }
154
155
    /**
156
     * @inheritdoc
157
     */
158
    protected function updateContent(ManialinkInterface $manialink)
159
    {
160
        // Empty existing script.
161
        parent::updateContent($manialink);
162
        $manialink->getFmlManialink()->removeAllChildren();
163
164
        // Get script with new values.
165
        $scriptContent = $this->getScriptInitialization(true);
166
167
        // Update FML Manialink
168
        $script = new Script();
169
        $script->addCustomScriptLabel(ScriptLabel::OnInit, $scriptContent);
170
        $manialink->getFmlManialink()->setScript($script);
171
172
        $this->queuedForUpdate = null;
0 ignored issues
show
Documentation Bug introduced by
It seems like null of type null is incompatible with the declared type array<integer,array<integer,*>> of property $queuedForUpdate.

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

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

Loading history...
173
    }
174
175
    /**
176
     * @inheritdoc
177
     */
178
    public function onPreLoop()
179
    {
180
        // Nothing
181
    }
182
183
    /**
184
     * @inheritdoc
185
     */
186
    public function onPostLoop()
187
    {
188
        // Nothing
189
    }
190
191
    /**
192
     * @inheritdoc
193
     */
194
    public function onEverySecond()
195
    {
196
        if (!empty($this->queuedForUpdate)) {
197
            foreach ($this->queuedForUpdate as $groupName => $updateData) {
198
                if (time() - $updateData['time'] > $this->maxUpdateFrequency) {
199
                    $variables = $this->variables;
200
                    $checkVariable = $this->checkVariable;
201
202
                    // Update variables temporarily with player data.
203
                    $this->variables = [];
204
                    foreach ($updateData['variables'] as $variableCode => $variable) {
205
                        $this->variables[$variableCode] = $variable;
206
                    }
207
                    $this->checkVariable = $updateData['check'];
208
                    $this->update($updateData['group']);
209
210
                    // Put back original data.
211
                    $this->variables = $variables;
212
                    $this->checkVariable = $checkVariable;
213
214
                    unset($this->queuedForUpdate[$groupName]);
215
                }
216
            }
217
        }
218
    }
219
220
    /**
221
     * @inheritdoc
222
     */
223
    public function onExpansionGroupAddUser(Group $group, $loginAdded)
224
    {
225
        // This will be handled by the gui handler.
226
    }
227
228
    /**
229
     * @inheritdoc
230
     */
231
    public function onExpansionGroupRemoveUser(Group $group, $loginRemoved)
232
    {
233
        // This will be handled by the gui handler.
234
    }
235
236
    /**
237
     * @inheritdoc
238
     */
239
    public function onExpansionGroupDestroy(Group $group, $lastLogin)
240
    {
241
        if (isset($this->queuedForUpdate[$group->getName()])) {
242
            unset($this->queuedForUpdate[$group->getName()]);
243
        }
244
    }
245
}
246