Completed
Pull Request — master (#104)
by
unknown
03:06
created

Connection   B

Complexity

Total Complexity 41

Size/Duplication

Total Lines 315
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 41
lcom 1
cbo 2
dl 0
loc 315
ccs 0
cts 210
cp 0
rs 8.2769
c 0
b 0
f 0

14 Methods

Rating   Name   Duplication   Size   Complexity  
A xActivate() 0 18 4
A getRatings() 0 23 2
B saveVotes() 0 26 2
A xSaveVotes() 0 15 3
A xGetRatings() 0 18 3
A getGameMode() 0 10 2
A getObject() 0 11 2
C handleErrors() 0 56 16
A __construct() 0 5 1
A connect() 0 15 1
A xConnect() 0 23 2
A buildUrl() 0 6 1
A isConnected() 0 4 1
A httpGet() 0 10 1

How to fix   Complexity   

Complex Class

Complex classes like Connection 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 Connection, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/*
4
 * Copyright (C) 2014 Reaby
5
 *
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
 */
19
20
namespace eXpansion\Bundle\MxKarma\Plugins;
21
22
use eXpansion\Bundle\MxKarma\Entity\MxRating;
23
use eXpansion\Framework\Core\Helpers\Http;
24
use eXpansion\Framework\Core\Services\Application\Dispatcher;
25
use Maniaplanet\DedicatedServer\Structures\GameInfos;
26
use oliverde8\AsynchronousJobs\Job\CallbackCurl;
27
28
/**
29
 * Description of Connection
30
 *
31
 * @author Reaby
32
 */
33
class Connection
34
{
35
36
   // private $address = "http://karma.mania-exchange.com/api2/";
0 ignored issues
show
Unused Code Comprehensibility introduced by
45% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
37
    private $address = "http://localhost/index.html?";
38
39
    private $connected = false;
40
41
    private $sessionKey = null;
42
43
    private $sessionSeed = null;
44
45
    private $apiKey = "";
46
47
    /** @var MXRating */
48
    private $ratings = null;
49
    /**
50
     * @var Dispatcher
51
     */
52
    private $dispatcher;
53
54
    /**
55
     * Connection constructor.
56
     *
57
     * @param Dispatcher $dispatcher
58
     */
59
    public function __construct(Dispatcher $dispatcher, Http $http)
60
    {
61
        $this->dispatcher = $dispatcher;
62
        $this->http = $http;
0 ignored issues
show
Bug introduced by
The property http does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
63
    }
64
65
66
    /**
67
     * connect to MX karma
68
     *
69
     * @param string $serverLogin
70
     * @param string $apiKey
71
     */
72
    public function connect($serverLogin, $apiKey)
73
    {
74
        $this->apiKey = $apiKey;
75
76
        $params = array(
77
            "serverLogin" => $serverLogin,
78
            "applicationIdentifier" => "eXpansion 2.0.0.0",
79
            "testMode" => "true",
80
        );
81
82
        $this->http->get(
83
            $this->buildUrl("startSession", $params),
84
            array($this, "xConnect")
85
        );
86
    }
87
88
    public function xConnect( $answer)
89
    {
90
91
        $data = $this->getObject($answer);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $data is correct as $this->getObject($answer) (which targets eXpansion\Bundle\MxKarma...Connection::getObject()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
92
93
        if ($data === null) {
94
            return;
95
        }
96
97
        $this->sessionKey = $data->sessionKey;
98
        $this->sessionSeed = $data->sessionSeed;
99
100
        $outHash = hash("sha512", ($this->apiKey.$this->sessionSeed));
101
102
        $params = array("sessionKey" => $this->sessionKey, "activationHash" => $outHash);
103
        $this->http->call(
104
            $this->buildUrl("activateSession", $params),
105
            array($this, "xActivate"),
106
            array(),
107
            "ManiaLive - eXpansionPluginPack",
108
            "application/json"
109
        );
110
    }
111
112
    public function xActivate($answer, $httpCode)
113
    {
114
115
        if ($httpCode != 200) {
116
            return;
117
        }
118
119
        $data = $this->getObject($answer, "onActivate");
0 ignored issues
show
Unused Code introduced by
The call to Connection::getObject() has too many arguments starting with 'onActivate'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
Bug introduced by
Are you sure the assignment to $data is correct as $this->getObject($answer, 'onActivate') (which targets eXpansion\Bundle\MxKarma...Connection::getObject()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
120
121
        if ($data === null) {
122
            return;
123
        }
124
125
        if ($data->activated) {
126
            $this->connected = true;
127
            //  Dispatcher::dispatch(new MXKarmaEvent(MXKarmaEvent::ON_CONNECTED));
0 ignored issues
show
Unused Code Comprehensibility introduced by
54% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
128
        }
129
    }
130
131
    public function getRatings($players = array(), $getVotesOnly = false)
132
    {
133
        if (!$this->connected) {
134
            return;
135
        }
136
137
        $params = array("sessionKey" => $this->sessionKey);
138
        $postData = array(
139
            "gamemode" => $this->getGameMode(),
140
            "titleid" => $this->expStorage->titleId,
0 ignored issues
show
Bug introduced by
The property expStorage does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
141
            "mapuid" => $this->storage->currentMap->uId,
0 ignored issues
show
Bug introduced by
The property storage does not seem to exist. Did you mean expStorage?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
142
            "getvotesonly" => $getVotesOnly,
143
            "playerlogins" => $players,
144
        );
145
        $this->dataAccess->httpPost(
0 ignored issues
show
Bug introduced by
The property dataAccess does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
146
            $this->buildUrl("getMapRating", $params),
147
            json_encode($postData),
148
            array($this, "xGetRatings"),
149
            array(),
150
            "ManiaLive - eXpansionPluginPack",
151
            "application/json"
152
        );
153
    }
154
155
    public function saveVotes(\Maniaplanet\DedicatedServer\Structures\Map $map, $time, $votes)
156
    {
157
        if (!$this->connected) {
158
            return;
159
        }
160
161
        $params = array("sessionKey" => $this->sessionKey);
162
        $postData = array(
163
            "gamemode" => $this->getGameMode(),
164
            "titleid" => $this->expStorage->titleId,
165
            "mapuid" => $map->uId,
166
            "mapname" => $map->name,
167
            "mapauthor" => $map->author,
168
            "isimport" => false,
169
            "maptime" => $time,
170
            "votes" => $votes,
171
        );
172
        $this->dataAccess->httpPost(
173
            $this->buildUrl("saveVotes", $params),
174
            json_encode($postData),
175
            array($this, "xSaveVotes"),
176
            array(),
177
            "ManiaLive - eXpansionPluginPack",
178
            "application/json"
179
        );
180
    }
181
182
    public function xSaveVotes($answer, $httpCode)
183
    {
184
185
        if ($httpCode != 200) {
186
            return;
187
        }
188
189
        $data = $this->getObject($answer);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $data is correct as $this->getObject($answer) (which targets eXpansion\Bundle\MxKarma...Connection::getObject()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
190
191
        if ($data === null) {
192
            return;
193
        }
194
195
        //  Dispatcher::dispatch(new MXKarmaEvent(MXKarmaEvent::ON_VOTE_SAVE, $data->updated));
0 ignored issues
show
Unused Code Comprehensibility introduced by
56% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
196
    }
197
198
    /**
199
     * @param $answer
200
     * @param $httpCode
201
     *
202
     * @return MxRating|null
203
     */
204
    public function xGetRatings($answer, $httpCode)
205
    {
206
207
        if ($httpCode != 200) {
208
            return null;
209
        }
210
211
        $data = $this->getObject($answer);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $data is correct as $this->getObject($answer) (which targets eXpansion\Bundle\MxKarma...Connection::getObject()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
212
213
        if ($data === null) {
214
            return null;
215
        }
216
217
        $this->ratings = new MXRating();
0 ignored issues
show
Documentation Bug introduced by
It seems like new \eXpansion\Bundle\MxKarma\Entity\MxRating() of type object<eXpansion\Bundle\MxKarma\Entity\MxRating> is incompatible with the declared type object<eXpansion\Bundle\MxKarma\Plugins\MXRating> of property $ratings.

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...
218
        $this->ratings->append($data);
219
220
        return $this->ratings;
221
    }
222
223
    public function getGameMode()
224
    {
225
        switch ($this->storage->gameInfos->gameMode) {
0 ignored issues
show
Bug introduced by
The property storage does not seem to exist. Did you mean expStorage?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
226
            case GameInfos::GAMEMODE_SCRIPT:
227
                $gamemode = strtolower($this->storage->gameInfos->scriptName);
0 ignored issues
show
Bug introduced by
The property storage does not seem to exist. Did you mean expStorage?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
228
                break;
229
        }
230
231
        return $gamemode;
0 ignored issues
show
Bug introduced by
The variable $gamemode does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
232
    }
233
234
    /**
235
     * @param string $data json data
236
     *
237
     * @return null
238
     */
239
    public function getObject($data)
240
    {
241
        $obj = (object)json_decode($data);
242
        if ($obj->success === false) {
243
            $this->handleErrors($obj);
244
245
            return null;
246
        }
247
248
        return $obj->data;
249
    }
250
251
    /**
252
     * @param object $object
0 ignored issues
show
Bug introduced by
There is no parameter named $object. 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...
253
     */
254
    public function handleErrors($obj)
255
    {
256
        switch ($obj->data->code) {
257
            case 1:
258
                echo "internal server error";
259
                break;
260
            case 2:
261
                echo "Session key is invalid (not activated, experied or got disabled).";
262
                break;
263
            case 4:
264
                echo "Some parameters are not provided.";
265
                break;
266
            case 5:
267
                echo "API key not found or suspended.";
268
                break;
269
            case 6:
270
                echo "Server not found or suspended.";
271
                break;
272
            case 7:
273
                echo "Cross-server call rejected.";
274
                break;
275
            case 8:
276
                echo "Invalid activation hash provided, session closed.";
277
                $this->connected = false;
278
                break;
279
            case 9:
280
                echo "Session already active.";
281
                break;
282
            case 10:
283
                echo "Unsupported Content-Type.";
284
                break;
285
            case 11:
286
                echo "Too many logins requested.";
287
                break;
288
            case 12:
289
                echo "Invalid JSON or invalid structure.";
290
                break;
291
            case 13:
292
                echo "Malformed vote request.";
293
                break;
294
            case 14:
295
                echo "no votes cast - please do not make requests if there are no votes!";
296
                break;
297
            case 15:
298
                echo "too many import votes - request a limit raise if needed";
299
                break;
300
            case 16:
301
                echo "Import rejected.";
302
                break;
303
            default:
304
                echo "unknown error";
305
                break;
306
        }
307
308
        //   Dispatcher::dispatch(new MXKarmaEvent(MXKarmaEvent::ON_ERROR, $origin, $obj->data->code, $obj->data->message));
0 ignored issues
show
Unused Code Comprehensibility introduced by
57% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
309
    }
310
311
    /**
312
     * @param string $method
313
     * @param array $params
314
     *
315
     * @return string
316
     */
317
    private function buildUrl($method, $params)
318
    {
319
        $url = $this->address.$method;
320
321
        return $url."?".http_build_query($params);
322
    }
323
324
    /**
325
     * @return bool
326
     */
327
    public function isConnected()
328
    {
329
        return $this->connected;
330
    }
331
332
    /**
333
     * @param $url
334
     * @param callable $callback
335
     */
336
    public function httpGet($url, callable $callback)
337
    {
338
        $ch = curl_init($url);
339
        curl_setopt($ch, CURLOPT_HEADER, "application/json");
340
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
341
        $output = curl_exec($ch);
342
        $httpCode = curl_getinfo($ch)["http_code"];
343
        curl_close($ch);
344
        call_user_func($callback, $output, $httpCode);
345
    }
346
347
}
348