Completed
Push — master ( 32ec36...4a8d0f )
by Konstantinos
04:36
created

Server::getQueryBuilder()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 6

Duplication

Lines 10
Ratio 100 %
Metric Value
dl 10
loc 10
rs 9.4286
cc 1
eloc 6
nc 1
nop 0
1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 15 and the first side effect is on line 9.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
/**
3
 * This file contains functionality relating to the official BZFlag match servers for the league
4
 *
5
 * @package    BZiON\Models
6
 * @license    https://github.com/allejo/bzion/blob/master/LICENSE.md GNU General Public License Version 3
7
 */
8
9
include_once DOC_ROOT . "/includes/bzfquery.php";
10
11
/**
12
 * A BZFlag server
13
 * @package    BZiON\Models
14
 */
15
class Server extends UrlModel implements NamedModel
16
{
17
    /**
18
     * The name of the server
19
     * @var string
20
     */
21
    protected $name;
22
23
    /**
24
     * The domain of the server
25
     * @var string
26
     */
27
    protected $domain;
28
29
    /**
30
     * The port of the server
31
     * @var int
32
     */
33
    protected $port;
34
35
    /**
36
     * The id of the country the server is located in
37
     * @var int
38
     */
39
    protected $country;
40
41
    /**
42
     * The id of the owner of the server
43
     * @var int
44
     */
45
    protected $owner;
46
47
    /**
48
     * Whether the server is listed on the public list server
49
     * @var bool
50
     */
51
    protected $online;
52
53
    /**
54
     * The server's bzfquery information
55
     * @var array
56
     */
57
    protected $info;
58
59
    /**
60
     * The ID of the API key assigned to this server
61
     * @var ApiKey
62
     */
63
    protected $api_key;
64
65
    /**
66
     * The date of the last bzfquery of the server
67
     * @var TimeDate
68
     */
69
    protected $updated;
70
71
    /**
72
     * The server's status
73
     * @var string
74
     */
75
    protected $status;
76
77
    /**
78
     * The name of the database table used for queries
79
     */
80
    const TABLE = "servers";
81
82
    const CREATE_PERMISSION = Permission::ADD_SERVER;
83
    const EDIT_PERMISSION = Permission::EDIT_SERVER;
84
    const SOFT_DELETE_PERMISSION = Permission::SOFT_DELETE_SERVER;
85
    const HARD_DELETE_PERMISSION = Permission::HARD_DELETE_SERVER;
86
87
    /**
88
     * {@inheritdoc}
89
     */
90
    protected function assignResult($server)
91
    {
92
        $this->name = $server['name'];
93
        $this->domain = $server['domain'];
94
        $this->port = $server['port'];
95
        $this->country = $server['country'];
96
        $this->owner = $server['owner'];
97
        $this->online = $server['online'];
98
        $this->info = unserialize($server['info']);
99
        $this->api_key = ApiKey::get($server['api_key']);
100
        $this->updated = TimeDate::fromMysql($server['updated']);
101
        $this->status = $server['status'];
102
    }
103
104
    /**
105
     * Add a new server
106
     *
107
     * @param string $name    The name of the server
108
     * @param string $domain  The domain of the server (e.g. server.com)
109
     * @param string $port    The port of the server (e.g. 5154)
110
     * @param int    $country The ID of the country
111
     * @param int    $owner   The ID of the server owner
112
     *
113
     * @return Server An object that represents the sent message
114
     */
115
    public static function addServer($name, $domain, $port, $country, $owner)
116
    {
117
        $key = ApiKey::getKeyByOwner($owner);
118
119
        $server = self::create(array(
120
            'name'    => $name,
121
            'domain'  => $domain,
122
            'port'    => $port,
123
            'country' => $country,
124
            'owner'   => $owner,
125
            'api_key' => $key->getId(),
126
            'status'  => 'active',
127
        ), 'ssiiiis', 'updated');
128
        $server->forceUpdate();
129
130
        return $server;
131
    }
132
133
    /**
134
     * Update the server with current bzfquery information
135
     * return self
136
     */
137
    public function forceUpdate()
138
    {
139
        $this->info = bzfquery($this->getAddress());
140
        $this->updated = TimeDate::now();
141
        $this->online = !isset($this->info['error']);
142
143
        $this->db->query(
144
	    "UPDATE servers SET info = ?, online = ?, updated = UTC_TIMESTAMP() WHERE id = ?",
145
	    "sii",
146
	    array(serialize($this->info), $this->online, $this->id)
147
	);
148
149
	// If a server is offline, log it
150
        if (!$this->online) {
151
	    if ($logger = \Service::getContainer()->get('logger')) {
152
		$id = $this->getId();
153
		$address = $this->getAddress();
154
		$reason = $this->info['error'];
155
156
		$logger->notice("Connection to server #$id ($address) failed: $reason");
157
	    }
158
        }
159
160
        return $this;
161
    }
162
163
    /**
164
     * Checks if the server is online (listed on the public list server)
165
     * @return bool Whether the server is online
166
     */
167
    public function isOnline()
168
    {
169
        return $this->online;
170
    }
171
172
    /**
173
     * Checks if the server has players
174
     * @return bool Whether the server has any players
175
     */
176
    public function hasPlayers()
177
    {
178
        return $this->info['numPlayers'] > 0;
179
    }
180
181
    /**
182
     * Gets the number of players on the server
183
     * @return int The number of players
184
     */
185
    public function numPlayers()
186
    {
187
        return (isset($this->info['numPlayers'])) ? $this->info['numPlayers'] : 0;
188
    }
189
190
    /**
191
     * Gets the players on the server
192
     * @return array The players on the server
193
     */
194
    public function getPlayers()
195
    {
196
        if (isset($this->info['player'])) {
197
            return $this->info['player'];
198
        }
199
200
        return array();
201
    }
202
203
    /**
204
     * Checks if the last update is older than or equal to the update interval
205
     * @return bool Whether the information is older than the update interval
206
     */
207
    public function staleInfo()
208
    {
209
        $update_time = $this->updated->copy();
210
        $update_time->modify(Service::getParameter('bzion.miscellaneous.update_interval'));
211
212
        return TimeDate::now() >= $update_time;
213
    }
214
215
    /**
216
     * The ApiKey assigned to this server
217
     *
218
     * @return \CachedModel|int|null|static
219
     */
220
    public function getApiKey()
221
    {
222
        return $this->api_key;
223
    }
224
225
    /**
226
     * Gets the server's ip address
227
     * @return string The server's ip address
228
     */
229
    public function getServerIp()
230
    {
231
        return $this->info['ip'];
232
    }
233
234
    /**
235
     * Get the server's name
236
     * @return string
237
     */
238
    public function getName()
239
    {
240
        return $this->name;
241
    }
242
243
    /**
244
     * Get the domain of the server
245
     *
246
     * @return string The server's domain
247
     */
248
    public function getDomain()
249
    {
250
        return $this->domain;
251
    }
252
253
    /**
254
     * Get the port of the server
255
     *
256
     * @return int The port number
257
     */
258
    public function getPort()
259
    {
260
        return $this->port;
261
    }
262
263
    /**
264
     * Get the server's IP address or hostname
265
     * @return string
266
     */
267
    public function getAddress()
268
    {
269
        return $this->domain . ":" . $this->port;
270
    }
271
272
    /**
273
     * Get when the server information was last updated
274
     * @return TimeDate
275
     */
276
    public function getUpdated()
277
    {
278
        return $this->updated;
279
    }
280
281
    /**
282
     * Get the country the server is in
283
     * @return Country The country the server is located in
284
     */
285
    public function getCountry()
286
    {
287
        return Country::get($this->country);
288
    }
289
290
    /**
291
     * Get the owner of the server
292
     * @return Player
293
     */
294
    public function getOwner()
295
    {
296
        return Player::get($this->owner);
297
    }
298
299
    /**
300
     * Returns the amount of time passed since the server was last updated
301
     * @return TimeDate
302
     */
303
    public function getLastUpdate()
304
    {
305
        return $this->updated;
306
    }
307
308
    /**
309
     * Set the name of the server
310
     *
311
     * @param string $name The new name of the server
312
     *
313
     * @return self
314
     */
315
    public function setName($name)
316
    {
317
        return $this->updateProperty($this->name, 'name', $name, 's');
318
    }
319
320
    /**
321
     * Set the address of the server
322
     *
323
     * @param string $address The new address of the server
324
     *
325
     * @deprecated Use setDomain() and setPort() instead
326
     *
327
     * @return self
328
     */
329
    public function setAddress($address)
330
    {
331
        list($domain, $port) = explode(":", $address);
332
333
        $this->setDomain($domain);
334
        $this->setPort($port);
335
336
        return $this;
337
    }
338
339
    /**
340
     * Set the domain of the server
341
     *
342
     * @param $domain string The new domain of the server
343
     *
344
     * @return self
345
     */
346
    public function setDomain($domain)
347
    {
348
        return $this->updateProperty($this->domain, 'domain', $domain, 's');
349
    }
350
351
    /**
352
     * Set the port of the server
353
     *
354
     * @param $port int The new port of the server
355
     *
356
     * @return self
357
     */
358
    public function setPort($port)
359
    {
360
        return $this->updateProperty($this->port, 'port', $port, 'i');
361
    }
362
363
    /**
364
     * Set the id of the owner of the server
365
     *
366
     * @param int $ownerId The ID of the new owner of the server
367
     *
368
     * @return self
369
     */
370
    public function setOwner($ownerId)
371
    {
372
        return $this->updateProperty($this->owner, 'owner', $ownerId, 'i');
373
    }
374
375
    /**
376
     * Set the id of the country of the server
377
     *
378
     * @param int $countryId The ID of the new country of the server
379
     *
380
     * @return self
381
     */
382
    public function setCountry($countryId)
383
    {
384
        return $this->updateProperty($this->country, 'country', $countryId, 'i');
385
    }
386
387
    /**
388
     * Get all the servers in the database that have an active status
389
     * @return Server[] An array of server objects
390
     */
391
    public static function getServers()
392
    {
393
        return self::arrayIdToModel(self::fetchIdsFrom("status", array("active"), "s", false, "ORDER BY name"));
394
    }
395
396
    /**
397
     * Get a query builder for servers
398
     * @return QueryBuilder
399
     */
400 View Code Duplication
    public static function getQueryBuilder()
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...
401
    {
402
        return new QueryBuilder('Server', array(
403
            'columns' => array(
404
                'name'   => 'name',
405
                'status' => 'status'
406
            ),
407
            'name' => 'name'
408
        ));
409
    }
410
}
411