1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Created by PhpStorm. |
4
|
|
|
* User: wechsler |
5
|
|
|
* Date: 03/09/15 |
6
|
|
|
* Time: 20:45 |
7
|
|
|
*/ |
8
|
|
|
|
9
|
|
|
namespace Phase\TakeATicket\DataSource; |
10
|
|
|
|
11
|
|
|
use Doctrine\DBAL\Connection; |
12
|
|
|
use PDO; |
13
|
|
|
use Phase\TakeATicket\Model\Instrument; |
14
|
|
|
use Phase\TakeATicket\Model\Platform; |
15
|
|
|
use Phase\TakeATicket\Model\Song; |
16
|
|
|
use Phase\TakeATicket\Model\Source; |
17
|
|
|
use Psr\Log\LoggerInterface; |
18
|
|
|
use Psr\Log\NullLogger; |
19
|
|
|
|
20
|
|
|
/** |
21
|
|
|
* Base Datasource |
22
|
|
|
* |
23
|
|
|
* Onward naming convention for methods (note that some are currently misnamed) |
24
|
|
|
* |
25
|
|
|
* get*() property getter |
26
|
|
|
* set*() property setter |
27
|
|
|
* |
28
|
|
|
* fetch*Row() Returns raw DB content as array |
29
|
|
|
* fetch*Data() Returns non-object data that's not just homogenous rows |
30
|
|
|
* fetch[ModelName]() Returns model objects |
31
|
|
|
* |
32
|
|
|
* protected build[ModelName]FromDbRow() Return single model object from array |
33
|
|
|
* protected [modelName]ToDbRow() Return single array suitable for DB insertion from model object |
34
|
|
|
*/ |
35
|
|
|
abstract class AbstractSql |
36
|
|
|
{ |
37
|
|
|
const TICKETS_TABLE = 'tickets'; |
38
|
|
|
const PERFORMERS_TABLE = 'performers'; |
39
|
|
|
const TICKETS_X_PERFORMERS_TABLE = 'tickets_x_performers'; |
40
|
|
|
const CODE_LENGTH = 6; |
41
|
|
|
|
42
|
|
|
/** |
43
|
|
|
* @var Connection |
44
|
|
|
*/ |
45
|
|
|
protected $dbConn; |
46
|
|
|
/** |
47
|
|
|
* @var int |
48
|
|
|
*/ |
49
|
|
|
protected $upcomingCount = 3; |
50
|
|
|
|
51
|
|
|
/** |
52
|
|
|
* @var LoggerInterface |
53
|
|
|
*/ |
54
|
|
|
protected $logger; |
55
|
|
|
|
56
|
|
|
/** |
57
|
|
|
* DataSource constructor. |
58
|
|
|
* |
59
|
|
|
* @param $dbConn |
60
|
|
|
*/ |
61
|
|
|
public function __construct(Connection $dbConn) |
62
|
|
|
{ |
63
|
|
|
$this->dbConn = $dbConn; |
64
|
|
|
} |
65
|
|
|
|
66
|
|
|
/** |
67
|
|
|
* @return Connection |
68
|
|
|
*/ |
69
|
|
|
public function getDbConn() |
70
|
|
|
{ |
71
|
|
|
return $this->dbConn; |
72
|
|
|
} |
73
|
|
|
|
74
|
|
|
/** |
75
|
|
|
* @return int |
76
|
|
|
*/ |
77
|
|
|
public function getUpcomingCount() |
78
|
|
|
{ |
79
|
|
|
return $this->upcomingCount; |
80
|
|
|
} |
81
|
|
|
|
82
|
|
|
/** |
83
|
|
|
* @param int $upcomingCount |
84
|
|
|
*/ |
85
|
|
|
public function setUpcomingCount($upcomingCount) |
86
|
|
|
{ |
87
|
|
|
$this->upcomingCount = $upcomingCount; |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
/** |
91
|
|
|
* @return LoggerInterface |
92
|
|
|
*/ |
93
|
|
|
public function getLogger() |
94
|
|
|
{ |
95
|
|
|
if (!$this->logger) { |
96
|
|
|
$this->logger = new NullLogger(); |
97
|
|
|
} |
98
|
|
|
|
99
|
|
|
return $this->logger; |
100
|
|
|
} |
101
|
|
|
|
102
|
|
|
/** |
103
|
|
|
* @param LoggerInterface $logger |
104
|
|
|
*/ |
105
|
|
|
public function setLogger(LoggerInterface $logger) |
106
|
|
|
{ |
107
|
|
|
$this->logger = $logger; |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
/** |
111
|
|
|
* @param $songId |
112
|
|
|
* |
113
|
|
|
* @return array |
114
|
|
|
*/ |
115
|
|
|
public function fetchSongRowById($songId) |
116
|
|
|
{ |
117
|
|
|
$song = $this->getDbConn()->fetchAssoc('SELECT * FROM songs WHERE id = :code', ['code' => $songId]); |
118
|
|
|
if ($song) { |
|
|
|
|
119
|
|
|
$song = $this->normaliseSongRecord($song); |
120
|
|
|
} |
121
|
|
|
|
122
|
|
|
return $song; |
123
|
|
|
} |
124
|
|
|
|
125
|
|
|
/** |
126
|
|
|
* Fill out names of linked object ids for given ticket |
127
|
|
|
* |
128
|
|
|
* @param $ticket |
129
|
|
|
* |
130
|
|
|
* @return mixed |
131
|
|
|
*/ |
132
|
|
|
public function expandTicketData($ticket) |
133
|
|
|
{ |
134
|
|
|
$ticket = $this->normaliseTicketRecord($ticket); |
135
|
|
|
|
136
|
|
|
if ($ticket['songId']) { |
137
|
|
|
$ticket['song'] = $this->expandSongData($this->fetchSongRowById($ticket['songId'])); |
138
|
|
|
} |
139
|
|
|
//FIXED inefficient, but different pages expect different structure while we refactor |
140
|
|
|
$ticket['band'] = $this->fetchPerformersWithInstrumentByTicketId($ticket['id']); |
141
|
|
|
|
142
|
|
|
return $ticket; |
143
|
|
|
} |
144
|
|
|
|
145
|
|
|
/** |
146
|
|
|
* expandTicketData for multiple tickets |
147
|
|
|
* |
148
|
|
|
* @param $tickets |
149
|
|
|
* |
150
|
|
|
* @return mixed |
151
|
|
|
*/ |
152
|
|
|
public function expandTicketsData($tickets) |
153
|
|
|
{ |
154
|
|
|
foreach ($tickets as &$ticket) { |
155
|
|
|
$ticket = $this->expandTicketData($ticket); |
156
|
|
|
} |
157
|
|
|
|
158
|
|
|
return $tickets; |
159
|
|
|
} |
160
|
|
|
|
161
|
|
|
|
162
|
|
|
/** |
163
|
|
|
* Fill out names of linked object ids for given song |
164
|
|
|
* |
165
|
|
|
* @param $song |
166
|
|
|
* @return mixed |
167
|
|
|
*/ |
168
|
|
|
public function expandSongData($song) |
169
|
|
|
{ |
170
|
|
|
$dataStore = $this; |
171
|
|
|
$instruments = $dataStore->fetchInstrumentsForSongId($song['id']); |
172
|
|
|
$instruments = array_map( |
173
|
|
|
function (Instrument $instrument) { |
174
|
|
|
return $instrument->getName(); |
175
|
|
|
}, |
176
|
|
|
$instruments |
177
|
|
|
); |
178
|
|
|
$song['instruments'] = $instruments; |
179
|
|
|
|
180
|
|
|
$source = $dataStore->fetchSourceById($song['sourceId']); |
181
|
|
|
if ($source) { |
182
|
|
|
$song['source'] = $source->getName(); |
183
|
|
|
} |
184
|
|
|
|
185
|
|
|
$platforms = $dataStore->fetchPlatformsForSongId($song['id']); |
186
|
|
|
$platforms = array_map( |
187
|
|
|
function (Platform $platform) { |
188
|
|
|
return $platform->getName(); |
189
|
|
|
}, |
190
|
|
|
$platforms |
191
|
|
|
); |
192
|
|
|
$song['platforms'] = $platforms; |
193
|
|
|
//Legacy format - TODO remove this, use ['song']['platforms'] |
|
|
|
|
194
|
|
|
$song['inRb3'] = in_array('RB3', $song['platforms']); |
195
|
|
|
$song['inRb4'] = in_array('RB4', $song['platforms']); |
196
|
|
|
return $song; |
197
|
|
|
} |
198
|
|
|
|
199
|
|
|
public function isPotentialCodeNumber($searchString) |
200
|
|
|
{ |
201
|
|
|
$codeLength = (int)self::CODE_LENGTH; |
202
|
|
|
$regexp = '/^[a-f0-9]{' . $codeLength . '}$/i'; |
203
|
|
|
|
204
|
|
|
return preg_match($regexp, $searchString); |
205
|
|
|
} |
206
|
|
|
|
207
|
|
|
/** |
208
|
|
|
* Get performed, pending data for all performers |
209
|
|
|
* |
210
|
|
|
* @return array |
211
|
|
|
*/ |
212
|
|
|
public function generatePerformerStats() |
213
|
|
|
{ |
214
|
|
|
$conn = $this->getDbConn(); |
215
|
|
|
$sql = 'SELECT p.id AS performerId, p.name AS performerName, |
216
|
|
|
sum(CASE WHEN t.id IS NOT NULL AND t.used=0 AND t.deleted=0 THEN 1 ELSE 0 END) AS songsPending, |
217
|
|
|
sum(CASE WHEN t.id IS NOT NULL AND t.used=1 AND t.deleted=0 THEN 1 ELSE 0 END) AS songsDone, |
218
|
|
|
sum(CASE WHEN t.id IS NOT NULL AND t.deleted=0 THEN 1 ELSE 0 END) AS songsTotal |
219
|
|
|
FROM performers p |
220
|
|
|
LEFT OUTER JOIN tickets_x_performers txp ON p.id=txp.performerId |
221
|
|
|
LEFT OUTER JOIN tickets t ON txp.ticketId = t.id |
222
|
|
|
GROUP BY p.id ORDER BY p.name'; |
223
|
|
|
|
224
|
|
|
return $conn->fetchAll($sql); |
225
|
|
|
} |
226
|
|
|
|
227
|
|
|
/** |
228
|
|
|
* Save band to ticket |
229
|
|
|
* |
230
|
|
|
* @param $ticketId |
231
|
|
|
* @param array $band ['instrumentCode' => 'name'] FIXME update |
232
|
|
|
*/ |
233
|
|
|
public function storeBandToTicket($ticketId, $band) |
234
|
|
|
{ |
235
|
|
|
if (!is_array($band)) { |
236
|
|
|
throw new \InvalidArgumentException('Band must be array'); |
237
|
|
|
} |
238
|
|
|
|
239
|
|
|
// remove existing performers |
240
|
|
|
$this->getDbConn()->delete(self::TICKETS_X_PERFORMERS_TABLE, ['ticketId' => $ticketId]); |
241
|
|
|
|
242
|
|
|
foreach ($band as $instrumentCode => $performers) { |
243
|
|
|
$instrument = $this->fetchInstrumentByAbbreviation($instrumentCode); |
244
|
|
|
if ($instrument) { |
245
|
|
|
$instrumentId = $instrument->getId(); |
246
|
|
|
|
247
|
|
|
foreach ($performers as $performerName) { |
248
|
|
|
$performerName = trim($performerName); |
249
|
|
|
$performerId = $this->fetchPerformerIdByName($performerName, true); |
250
|
|
|
if ($performerId) { |
251
|
|
|
$link = [ |
252
|
|
|
'ticketId' => $ticketId, |
253
|
|
|
'performerId' => $performerId, |
254
|
|
|
'instrumentId' => $instrumentId |
255
|
|
|
]; |
256
|
|
|
$this->getDbConn()->insert(self::TICKETS_X_PERFORMERS_TABLE, $link); |
257
|
|
|
} |
258
|
|
|
} |
259
|
|
|
} else { |
260
|
|
|
throw new \UnexpectedValueException("Unknown instrument abbreviation '$instrumentCode'"); |
261
|
|
|
} |
262
|
|
|
} |
263
|
|
|
} |
264
|
|
|
|
265
|
|
|
public function fetchPerformerIdByName($performerName, $createMissing = false) |
266
|
|
|
{ |
267
|
|
|
$conn = $this->getDbConn(); |
268
|
|
|
$sql = 'SELECT id FROM performers p WHERE p.name LIKE :name LIMIT 1'; |
269
|
|
|
$performerId = $conn->fetchColumn($sql, ['name' => $performerName]); |
270
|
|
|
|
271
|
|
|
if ($createMissing && !$performerId) { |
272
|
|
|
$max = $conn->fetchColumn('SELECT max(id) FROM performers'); |
273
|
|
|
$performerId = $max + 1; |
274
|
|
|
$conn->insert(self::PERFORMERS_TABLE, ['id' => $performerId, 'name' => ucwords($performerName)]); |
275
|
|
|
//add new performer row |
276
|
|
|
} |
277
|
|
|
|
278
|
|
|
return $performerId; |
279
|
|
|
} |
280
|
|
|
|
281
|
|
|
/** |
282
|
|
|
* Fetch all performers on a song with their stats |
283
|
|
|
* |
284
|
|
|
* @deprecated Use fetchPerformersWithInstrumentByTicketId() |
285
|
|
|
* |
286
|
|
|
* @param $ticketId |
287
|
|
|
* |
288
|
|
|
* @return array[] |
289
|
|
|
*/ |
290
|
|
|
public function fetchPerformersByTicketId($ticketId) |
291
|
|
|
{ |
292
|
|
|
$ticketPerformerSql = 'SELECT performerId FROM tickets_x_performers WHERE ticketId = :ticketId'; |
293
|
|
|
$performerRows = $this->getDbConn()->fetchAll($ticketPerformerSql, ['ticketId' => $ticketId]); |
294
|
|
|
$performerIds = []; |
295
|
|
|
foreach ($performerRows as $row) { |
296
|
|
|
$performerIds[] = $row['performerId']; |
297
|
|
|
} |
298
|
|
|
|
299
|
|
|
$allPerformers = $this->generatePerformerStats(); |
300
|
|
|
$trackPerformers = []; |
301
|
|
|
foreach ($allPerformers as $performer) { |
302
|
|
|
if (in_array($performer['performerId'], $performerIds)) { |
303
|
|
|
$trackPerformers[] = $performer; |
304
|
|
|
} |
305
|
|
|
} |
306
|
|
|
|
307
|
|
|
return $trackPerformers; |
308
|
|
|
} |
309
|
|
|
|
310
|
|
|
public function fetchPerformersWithInstrumentByTicketId($ticketId) |
311
|
|
|
{ |
312
|
|
|
$ticketPerformerSql = 'SELECT x.performerId, i.abbreviation AS instrument |
313
|
|
|
FROM tickets_x_performers x INNER JOIN instruments i ON x.instrumentId = i.id |
314
|
|
|
WHERE x.ticketId = :ticketId'; |
315
|
|
|
$performerRows = $this->getDbConn()->fetchAll($ticketPerformerSql, ['ticketId' => $ticketId]); |
316
|
|
|
$performerIds = []; |
317
|
|
|
$instrumentsByPerformer = []; |
318
|
|
|
foreach ($performerRows as $row) { |
319
|
|
|
$performerId = $row['performerId']; |
320
|
|
|
$performerIds[] = $performerId; |
321
|
|
|
$instrumentsByPerformer[$performerId] = $row['instrument']; |
322
|
|
|
} |
323
|
|
|
|
324
|
|
|
//todo Can probably clean up this algorithm |
325
|
|
|
$allPerformers = $this->generatePerformerStats(); |
326
|
|
|
$trackPerformersByInstrument = []; |
327
|
|
|
foreach ($allPerformers as $performer) { |
328
|
|
|
$performerId = $performer['performerId']; |
329
|
|
|
if (in_array($performerId, $performerIds)) { |
330
|
|
|
$instrument = $instrumentsByPerformer[$performerId]; |
331
|
|
|
if (!isset($trackPerformersByInstrument[$instrument])) { |
332
|
|
|
$trackPerformersByInstrument[$instrument] = []; |
333
|
|
|
} |
334
|
|
|
$trackPerformersByInstrument[$instrument][] = $performer; |
335
|
|
|
} |
336
|
|
|
} |
337
|
|
|
|
338
|
|
|
return $trackPerformersByInstrument; |
339
|
|
|
} |
340
|
|
|
|
341
|
|
|
/** |
342
|
|
|
* @param $searchString |
343
|
|
|
* @param $howMany |
344
|
|
|
* |
345
|
|
|
* @return array |
346
|
|
|
*/ |
347
|
|
|
public function findSongsBySearchString($searchString, $howMany = 10) |
348
|
|
|
{ |
349
|
|
|
$howMany += 0; // force int |
350
|
|
|
|
351
|
|
|
$conn = $this->getDbConn(); |
352
|
|
|
$leadingPattern = implode('%', preg_split('/\s+/', $searchString)) . '%'; |
353
|
|
|
$internalPattern = '%' . $leadingPattern; |
354
|
|
|
$params = [ |
355
|
|
|
'internalPattern' => $internalPattern, |
356
|
|
|
'leadingPattern' => $leadingPattern, |
357
|
|
|
'searchString' => $searchString, |
358
|
|
|
]; |
359
|
|
|
|
360
|
|
|
// this may be unnecessary - chances of a code number hitting anything else is minimal |
361
|
|
|
if ($this->isPotentialCodeNumber($searchString)) { |
362
|
|
|
$sql = "SELECT s.*, max(CASE WHEN t.id IS NOT NULL THEN 1 ELSE 0 END) as queued |
363
|
|
|
FROM songs s |
364
|
|
|
LEFT OUTER JOIN tickets t ON s.id = t.songId AND t.deleted=0 |
365
|
|
|
WHERE (s.title = :searchString) |
366
|
|
|
OR (codeNumber = :searchString) |
367
|
|
|
GROUP BY s.id |
368
|
|
|
ORDER BY artist, title |
369
|
|
|
LIMIT $howMany"; |
370
|
|
|
//allow title just in case |
371
|
|
|
} else { |
372
|
|
|
$matchingTokens = ['s.title', '" "', 's.artist']; |
373
|
|
|
$concatSearchFields = $this->concatenateEscapedFields($matchingTokens); |
374
|
|
|
$concatSearchFieldsReverse = $this->concatenateEscapedFields(array_reverse($matchingTokens)); |
375
|
|
|
$sql = "SELECT s.*, max(CASE WHEN t.id IS NOT NULL THEN 1 ELSE 0 END) as queued |
376
|
|
|
FROM songs s |
377
|
|
|
LEFT OUTER JOIN tickets t ON s.id = t.songId AND t.deleted=0 |
378
|
|
|
WHERE ( $concatSearchFields LIKE :internalPattern) |
379
|
|
|
OR ($concatSearchFieldsReverse LIKE :internalPattern) |
380
|
|
|
OR (codeNumber LIKE :leadingPattern) |
381
|
|
|
OR (s.id = :searchString) |
382
|
|
|
GROUP BY s.id |
383
|
|
|
ORDER BY artist, title |
384
|
|
|
LIMIT $howMany"; |
385
|
|
|
} |
386
|
|
|
|
387
|
|
|
$songs = $conn->fetchAll($sql, $params); |
388
|
|
|
|
389
|
|
|
// normalise data types |
390
|
|
|
foreach ($songs as &$song) { |
391
|
|
|
$song = $this->normaliseSongRecord($song); |
392
|
|
|
} |
393
|
|
|
|
394
|
|
|
return $songs; |
395
|
|
|
} |
396
|
|
|
|
397
|
|
|
/** |
398
|
|
|
* @param $id |
399
|
|
|
* |
400
|
|
|
* @return int |
401
|
|
|
*/ |
402
|
|
|
public function markTicketUsedById($id) |
403
|
|
|
{ |
404
|
|
|
$conn = $this->getDbConn(); |
405
|
|
|
return $conn->update(self::TICKETS_TABLE, ['used' => 1, 'startTime' => time()], ['id' => $id]); |
406
|
|
|
} |
407
|
|
|
|
408
|
|
|
/** |
409
|
|
|
* @param $id |
410
|
|
|
* |
411
|
|
|
* @return int |
412
|
|
|
*/ |
413
|
|
|
public function deleteTicketById($id) |
414
|
|
|
{ |
415
|
|
|
$conn = $this->getDbConn(); |
416
|
|
|
return $conn->update(self::TICKETS_TABLE, ['deleted' => 1], ['id' => $id]); |
417
|
|
|
} |
418
|
|
|
|
419
|
|
|
/** |
420
|
|
|
* @param $id |
421
|
|
|
* @param $offset |
422
|
|
|
* |
423
|
|
|
* @return mixed |
424
|
|
|
*/ |
425
|
|
|
public function updateTicketOffsetById($id, $offset) |
426
|
|
|
{ |
427
|
|
|
$id = (int)$id; |
428
|
|
|
$offset = (int)$offset; |
429
|
|
|
$fields = ['offset' => $offset]; |
430
|
|
|
$currentTrack = $this->fetchTicketById($id); |
431
|
|
|
$oldOffset = (int)$currentTrack['offset']; |
432
|
|
|
$ok = ($oldOffset === $offset); |
433
|
|
|
|
434
|
|
|
$this->getLogger()->debug( |
435
|
|
|
"Update track $id offset: $oldOffset => $offset: " . |
436
|
|
|
($ok ? ' already set' : ' will update') |
437
|
|
|
); |
438
|
|
|
|
439
|
|
|
if (!$ok) { |
440
|
|
|
$ok = $this->updateTicketById($id, $fields); |
441
|
|
|
} |
442
|
|
|
|
443
|
|
|
return $ok; |
444
|
|
|
} |
445
|
|
|
|
446
|
|
|
/** |
447
|
|
|
* @param $songKey |
448
|
|
|
* |
449
|
|
|
* @return array |
450
|
|
|
*/ |
451
|
|
|
public function fetchSongByKey($songKey) |
452
|
|
|
{ |
453
|
|
|
$conn = $this->getDbConn(); |
454
|
|
|
|
455
|
|
|
$song = $conn->fetchAssoc('SELECT * FROM songs WHERE codeNumber = :code', ['code' => $songKey]); |
456
|
|
|
if ($song) { |
|
|
|
|
457
|
|
|
$song = $this->normaliseSongRecord($song); |
458
|
|
|
} |
459
|
|
|
|
460
|
|
|
return $song; |
461
|
|
|
} |
462
|
|
|
|
463
|
|
|
/** |
464
|
|
|
* @param bool $includePrivate |
465
|
|
|
* |
466
|
|
|
* @return array|mixed |
467
|
|
|
* |
468
|
|
|
* @throws \Doctrine\DBAL\DBALException |
469
|
|
|
*/ |
470
|
|
|
public function fetchUpcomingTickets($includePrivate = false) |
471
|
|
|
{ |
472
|
|
|
$conn = $this->getDbConn(); |
473
|
|
|
$privateClause = $includePrivate ? '' : ' AND private = 0 '; |
474
|
|
|
$statement = $conn->prepare( |
475
|
|
|
'SELECT * FROM tickets WHERE deleted=0 AND used=0 ' . |
476
|
|
|
$privateClause . |
477
|
|
|
'ORDER BY OFFSET ASC LIMIT ' . (int)$this->upcomingCount |
478
|
|
|
); |
479
|
|
|
$statement->execute(); |
480
|
|
|
$next = $statement->fetchAll(); |
481
|
|
|
$next = $this->expandTicketsData($next); |
482
|
|
|
|
483
|
|
|
return $next; |
484
|
|
|
} |
485
|
|
|
|
486
|
|
|
/** |
487
|
|
|
* Fetch all non-deleted tickets in offset order |
488
|
|
|
* |
489
|
|
|
* @return array|mixed |
490
|
|
|
* |
491
|
|
|
* @throws \Doctrine\DBAL\DBALException |
492
|
|
|
*/ |
493
|
|
View Code Duplication |
public function fetchUndeletedTickets() |
|
|
|
|
494
|
|
|
{ |
495
|
|
|
$conn = $this->getDbConn(); |
496
|
|
|
$statement = $conn->prepare('SELECT * FROM tickets WHERE deleted=0 ORDER BY offset ASC'); |
497
|
|
|
$statement->execute(); |
498
|
|
|
$tickets = $statement->fetchAll(); |
499
|
|
|
$tickets = $this->expandTicketsData($tickets); |
500
|
|
|
|
501
|
|
|
return $tickets; |
502
|
|
|
} |
503
|
|
|
|
504
|
|
|
/** |
505
|
|
|
* Fetch all performed tickets in offset order |
506
|
|
|
* |
507
|
|
|
* @return array |
508
|
|
|
* |
509
|
|
|
* @throws \Doctrine\DBAL\DBALException |
510
|
|
|
*/ |
511
|
|
View Code Duplication |
public function fetchPerformedTickets() |
|
|
|
|
512
|
|
|
{ |
513
|
|
|
$conn = $this->getDbConn(); |
514
|
|
|
$statement = $conn->prepare('SELECT * FROM tickets WHERE deleted=0 AND used=1 ORDER BY offset ASC'); |
515
|
|
|
$statement->execute(); |
516
|
|
|
$tickets = $statement->fetchAll(); |
517
|
|
|
$tickets = $this->expandTicketsData($tickets); |
518
|
|
|
|
519
|
|
|
return $tickets; |
520
|
|
|
} |
521
|
|
|
|
522
|
|
|
/** |
523
|
|
|
* @param $title |
524
|
|
|
* @param $songId |
525
|
|
|
* |
526
|
|
|
* @return int|false Row ID |
527
|
|
|
*/ |
528
|
|
|
public function storeNewTicket($title, $songId) |
529
|
|
|
{ |
530
|
|
|
$conn = $this->getDbConn(); |
531
|
|
|
$max = $conn->fetchAssoc('SELECT max(offset) AS o, max(id) AS i FROM tickets'); |
532
|
|
|
|
533
|
|
|
$maxOffset = $max['o']; |
534
|
|
|
$maxId = $max['i']; |
535
|
|
|
$ticket = [ |
536
|
|
|
'title' => $title, |
537
|
|
|
'id' => $maxId + 1, |
538
|
|
|
'offset' => $maxOffset + 1, |
539
|
|
|
'songId' => $songId, |
540
|
|
|
]; |
541
|
|
|
$res = $conn->insert(self::TICKETS_TABLE, $ticket); |
542
|
|
|
|
543
|
|
|
return $res ? $ticket['id'] : false; |
544
|
|
|
} |
545
|
|
|
|
546
|
|
|
/** |
547
|
|
|
* Normalise datatypes returned in song query |
548
|
|
|
* |
549
|
|
|
* @param $song |
550
|
|
|
* |
551
|
|
|
* @return mixed |
552
|
|
|
*/ |
553
|
|
|
public function normaliseSongRecord($song) |
554
|
|
|
{ |
555
|
|
|
$boolFields = []; |
556
|
|
|
$intFields = ['id', 'duration', 'sourceId']; |
557
|
|
|
|
558
|
|
View Code Duplication |
foreach ($intFields as $k) { |
|
|
|
|
559
|
|
|
$song[$k] = is_null($song[$k]) ? null : (int)$song[$k]; |
560
|
|
|
} |
561
|
|
|
|
562
|
|
|
foreach ($boolFields as $k) { |
563
|
|
|
$song[$k] = (bool)$song[$k]; |
564
|
|
|
} |
565
|
|
|
|
566
|
|
|
// Search API adds a 'queued' parameter to show if song is taken |
567
|
|
|
if (isset($song['queued'])) { //TODO see if this is safe to move to $boolFields |
568
|
|
|
$song['queued'] = (bool)$song['queued']; |
569
|
|
|
} |
570
|
|
|
|
571
|
|
|
return $song; |
572
|
|
|
} |
573
|
|
|
|
574
|
|
|
/** |
575
|
|
|
* @param $id |
576
|
|
|
* @param $fields |
577
|
|
|
* |
578
|
|
|
* @return int Number of updated rows |
579
|
|
|
*/ |
580
|
|
|
public function updateTicketById($id, $fields) |
581
|
|
|
{ |
582
|
|
|
if (isset($fields['id'])) { |
583
|
|
|
throw new \InvalidArgumentException('Fields must not include id'); |
584
|
|
|
} |
585
|
|
|
|
586
|
|
|
return $this->getDbConn()->update(self::TICKETS_TABLE, $fields, ['id' => $id]); |
587
|
|
|
} |
588
|
|
|
|
589
|
|
|
/** |
590
|
|
|
* Fetch core ticket data (not band, etc) by ticket id |
591
|
|
|
* |
592
|
|
|
* @param $id |
593
|
|
|
* |
594
|
|
|
* @return array |
595
|
|
|
*/ |
596
|
|
|
public function fetchTicketById($id) |
597
|
|
|
{ |
598
|
|
|
$conn = $this->getDbConn(); |
599
|
|
|
$song = $conn->fetchAssoc('SELECT * FROM ' . self::TICKETS_TABLE . ' WHERE id = :id', ['id' => $id]); |
600
|
|
|
|
601
|
|
|
return $song; |
602
|
|
|
} |
603
|
|
|
|
604
|
|
|
/** |
605
|
|
|
* Get current value of a named setting, NULL if missing |
606
|
|
|
* |
607
|
|
|
* @param $key |
608
|
|
|
* @return mixed|null |
609
|
|
|
*/ |
610
|
|
|
public function fetchSetting($key) |
611
|
|
|
{ |
612
|
|
|
$conn = $this->getDbConn(); |
613
|
|
|
$query = $conn->executeQuery('SELECT settingValue FROM settings WHERE settingKey=:key', ['key' => $key]); |
614
|
|
|
|
615
|
|
|
return $query->rowCount() ? $query->fetchColumn() : null; |
616
|
|
|
} |
617
|
|
|
|
618
|
|
|
|
619
|
|
|
public function settingExists($key) |
620
|
|
|
{ |
621
|
|
|
$conn = $this->getDbConn(); |
622
|
|
|
$value = $conn->fetchColumn('SELECT 1 FROM settings WHERE settingKey=:key', ['key' => $key]); |
623
|
|
|
|
624
|
|
|
return (bool)$value; |
625
|
|
|
} |
626
|
|
|
|
627
|
|
|
public function updateSetting($k, $v) |
628
|
|
|
{ |
629
|
|
|
$conn = $this->getDbConn(); |
630
|
|
|
if ($this->settingExists($k)) { |
631
|
|
|
$conn->update('settings', ['settingValue' => $v], ['settingKey' => $k]); |
632
|
|
|
} else { |
633
|
|
|
$conn->insert('settings', ['settingValue' => $v, 'settingKey' => $k]); |
634
|
|
|
} |
635
|
|
|
return $this->fetchSetting($k); |
636
|
|
|
} |
637
|
|
|
|
638
|
|
|
/** |
639
|
|
|
* Return SQL in appropriate dialect to concatenate the listed values |
640
|
|
|
* |
641
|
|
|
* @param array $fields |
642
|
|
|
* |
643
|
|
|
* @return string |
644
|
|
|
*/ |
645
|
|
|
abstract protected function concatenateEscapedFields($fields); |
646
|
|
|
|
647
|
|
|
/** |
648
|
|
|
* Return ticket array with fields converted to correct datatype |
649
|
|
|
* |
650
|
|
|
* @param $ticket |
651
|
|
|
* |
652
|
|
|
* @return mixed |
653
|
|
|
*/ |
654
|
|
|
protected function normaliseTicketRecord($ticket) |
655
|
|
|
{ |
656
|
|
|
$boolFields = ['used', 'deleted', 'private', 'blocking']; |
657
|
|
|
$intFields = ['id', 'songId']; |
658
|
|
|
|
659
|
|
View Code Duplication |
foreach ($intFields as $k) { |
|
|
|
|
660
|
|
|
$ticket[$k] = is_null($ticket[$k]) ? null : (int)$ticket[$k]; |
661
|
|
|
} |
662
|
|
|
|
663
|
|
|
foreach ($boolFields as $k) { |
664
|
|
|
$ticket[$k] = (bool)$ticket[$k]; |
665
|
|
|
} |
666
|
|
|
|
667
|
|
|
return $ticket; |
668
|
|
|
} |
669
|
|
|
|
670
|
|
|
/** |
671
|
|
|
* Delete all song & performer data |
672
|
|
|
* |
673
|
|
|
* @throws \Doctrine\DBAL\DBALException |
674
|
|
|
*/ |
675
|
|
|
public function resetAllSessionData() |
676
|
|
|
{ |
677
|
|
|
$truncateTables = [ |
678
|
|
|
'tickets_x_performers', |
679
|
|
|
'performers', |
680
|
|
|
'tickets' |
681
|
|
|
]; |
682
|
|
|
|
683
|
|
|
$connection = $this->getDbConn(); |
684
|
|
|
|
685
|
|
|
foreach ($truncateTables as $table) { |
686
|
|
|
$connection->query( |
687
|
|
|
'TRUNCATE TABLE ' . $connection->quoteIdentifier($table) |
688
|
|
|
); |
689
|
|
|
} |
690
|
|
|
} |
691
|
|
|
|
692
|
|
|
/** |
693
|
|
|
* Delete all catalogue data |
694
|
|
|
* |
695
|
|
|
* @throws \Doctrine\DBAL\DBALException |
696
|
|
|
*/ |
697
|
|
|
public function resetCatalogue() |
698
|
|
|
{ |
699
|
|
|
$dbConn = $this->getDbConn(); |
700
|
|
|
$driverType = $dbConn->getDriver()->getName(); |
701
|
|
|
$sqlite = (stripos($driverType, 'sqlite') !== false); |
702
|
|
|
// FIXME refactor to subclasses |
703
|
|
|
|
704
|
|
|
$truncateTables = [ |
705
|
|
|
'songs_x_instruments', |
706
|
|
|
'songs_x_platforms', |
707
|
|
|
'songs', |
708
|
|
|
'instruments', |
709
|
|
|
'platforms' |
710
|
|
|
]; |
711
|
|
|
foreach ($truncateTables as $table) { |
712
|
|
|
$dbConn->exec( |
713
|
|
|
($sqlite ? 'DELETE FROM ' : 'TRUNCATE TABLE ') . |
714
|
|
|
$this->dbConn->quoteIdentifier($table) |
715
|
|
|
); |
716
|
|
|
} |
717
|
|
|
} |
718
|
|
|
|
719
|
|
|
/** |
720
|
|
|
* Store an instrument to DB |
721
|
|
|
* |
722
|
|
|
* @param Instrument $instrument |
723
|
|
|
*/ |
724
|
|
|
public function storeInstrument(Instrument $instrument) |
725
|
|
|
{ |
726
|
|
|
$asArray = $this->instrumentToDbRow($instrument); |
727
|
|
|
if ($this->getDbConn()->insert('instruments', $asArray)) { |
728
|
|
|
$instrument->setId($this->dbConn->lastInsertId()); |
729
|
|
|
} |
730
|
|
|
} |
731
|
|
|
|
732
|
|
|
/** |
733
|
|
|
* Store a platform to DB |
734
|
|
|
* |
735
|
|
|
* @param Platform $platform |
736
|
|
|
*/ |
737
|
|
|
public function storePlatform(Platform $platform) |
738
|
|
|
{ |
739
|
|
|
$asArray = $this->platformToDbRow($platform); |
740
|
|
|
if ($this->getDbConn()->insert('platforms', $asArray)) { |
741
|
|
|
$platform->setId($this->dbConn->lastInsertId()); |
742
|
|
|
} |
743
|
|
|
} |
744
|
|
|
|
745
|
|
|
/** |
746
|
|
|
* Store a source to DB |
747
|
|
|
* |
748
|
|
|
* @param Source $source |
749
|
|
|
*/ |
750
|
|
|
public function storeSource(Source $source) |
751
|
|
|
{ |
752
|
|
|
$asArray = $this->sourceToDbRow($source); |
753
|
|
|
if ($this->getDbConn()->insert('sources', $asArray)) { |
754
|
|
|
$source->setId($this->dbConn->lastInsertId()); |
755
|
|
|
} |
756
|
|
|
} |
757
|
|
|
|
758
|
|
|
/** |
759
|
|
|
* Store a song to DB |
760
|
|
|
* |
761
|
|
|
* @param Song $song |
762
|
|
|
*/ |
763
|
|
|
public function storeSong(Song $song) |
764
|
|
|
{ |
765
|
|
|
$asArray = $this->songToDbRow($song); |
766
|
|
|
if ($this->getDbConn()->insert('songs', $asArray)) { |
767
|
|
|
$song->setId($this->dbConn->lastInsertId()); |
768
|
|
|
} |
769
|
|
|
} |
770
|
|
|
|
771
|
|
|
/** |
772
|
|
|
* @param string $sourceName |
773
|
|
|
* |
774
|
|
|
* @return null|Source |
775
|
|
|
*/ |
776
|
|
View Code Duplication |
public function fetchSourceByName($sourceName) |
|
|
|
|
777
|
|
|
{ |
778
|
|
|
$source = null; |
779
|
|
|
$query = $this->dbConn->createQueryBuilder() |
780
|
|
|
->select('*') |
781
|
|
|
->from('sources') |
782
|
|
|
->where('name = :name') |
783
|
|
|
->setParameter(':name', $sourceName); |
784
|
|
|
|
785
|
|
|
$row = $query->execute()->fetch(PDO::FETCH_ASSOC); |
786
|
|
|
|
787
|
|
|
if ($row) { |
788
|
|
|
$source = $this->buildSourceFromDbRow($row); |
789
|
|
|
} |
790
|
|
|
|
791
|
|
|
return $source; |
792
|
|
|
} |
793
|
|
|
|
794
|
|
|
|
795
|
|
|
/** |
796
|
|
|
* @param $sourceId |
797
|
|
|
* @return null|Source |
798
|
|
|
*/ |
799
|
|
View Code Duplication |
public function fetchSourceById($sourceId) |
|
|
|
|
800
|
|
|
{ |
801
|
|
|
$source = null; |
802
|
|
|
$query = $this->dbConn->createQueryBuilder() |
803
|
|
|
->select('*') |
804
|
|
|
->from('sources') |
805
|
|
|
->where('id = :id') |
806
|
|
|
->setParameter(':id', $sourceId); |
807
|
|
|
|
808
|
|
|
$row = $query->execute()->fetch(PDO::FETCH_ASSOC); |
809
|
|
|
|
810
|
|
|
if ($row) { |
811
|
|
|
$source = $this->buildSourceFromDbRow($row); |
812
|
|
|
} |
813
|
|
|
|
814
|
|
|
return $source; |
815
|
|
|
} |
816
|
|
|
|
817
|
|
View Code Duplication |
public function fetchPlatformByName($platformName) |
|
|
|
|
818
|
|
|
{ |
819
|
|
|
$platform = null; |
820
|
|
|
$query = $this->dbConn->createQueryBuilder() |
821
|
|
|
->select('*') |
822
|
|
|
->from('platforms') |
823
|
|
|
->where('name = :name') |
824
|
|
|
->setParameter(':name', $platformName); |
825
|
|
|
|
826
|
|
|
$row = $query->execute()->fetch(PDO::FETCH_ASSOC); |
827
|
|
|
|
828
|
|
|
if ($row) { |
829
|
|
|
$platform = $this->buildPlatformFromDbRow($row); |
830
|
|
|
} |
831
|
|
|
|
832
|
|
|
return $platform; |
833
|
|
|
} |
834
|
|
|
|
835
|
|
|
/** |
836
|
|
|
* Fetch all available platforms |
837
|
|
|
* |
838
|
|
|
* @return Platform[] |
839
|
|
|
*/ |
840
|
|
|
public function fetchAllPlatforms() |
841
|
|
|
{ |
842
|
|
|
$query = $this->dbConn->createQueryBuilder() |
843
|
|
|
->select('*') |
844
|
|
|
->from('platforms') |
845
|
|
|
->orderBy('id'); |
846
|
|
|
|
847
|
|
|
$rows = $query->execute()->fetchAll(PDO::FETCH_ASSOC); |
848
|
|
|
|
849
|
|
|
$platforms = []; |
850
|
|
|
foreach ($rows as $row) { |
851
|
|
|
$platforms[] = $this->buildPlatformFromDbRow($row); |
852
|
|
|
} |
853
|
|
|
|
854
|
|
|
return $platforms; |
855
|
|
|
} |
856
|
|
|
|
857
|
|
|
/** |
858
|
|
|
* @param $songId |
859
|
|
|
* @param array $platformIds |
860
|
|
|
*/ |
861
|
|
View Code Duplication |
public function storeSongPlatformLinks($songId, array $platformIds) |
|
|
|
|
862
|
|
|
{ |
863
|
|
|
$this->dbConn->delete('songs_x_platforms', ['songId' => $songId]); |
864
|
|
|
|
865
|
|
|
foreach ($platformIds as $platformId) { |
866
|
|
|
$this->dbConn->insert('songs_x_platforms', ['songId' => $songId, 'platformId' => $platformId]); |
867
|
|
|
} |
868
|
|
|
} |
869
|
|
|
|
870
|
|
|
/** |
871
|
|
|
* @param $name |
872
|
|
|
* @return null|Instrument |
873
|
|
|
*/ |
874
|
|
View Code Duplication |
public function fetchInstrumentByName($name) |
|
|
|
|
875
|
|
|
{ |
876
|
|
|
$instrument = null; |
877
|
|
|
$query = $this->dbConn->createQueryBuilder() |
878
|
|
|
->select('*') |
879
|
|
|
->from('instruments') |
880
|
|
|
->where('name = :name') |
881
|
|
|
->setParameter(':name', $name); |
882
|
|
|
|
883
|
|
|
$row = $query->execute()->fetch(PDO::FETCH_ASSOC); |
884
|
|
|
|
885
|
|
|
if ($row) { |
886
|
|
|
$instrument = $this->buildInstrumentFromDbRow($row); |
887
|
|
|
} |
888
|
|
|
|
889
|
|
|
return $instrument; |
890
|
|
|
} |
891
|
|
|
|
892
|
|
View Code Duplication |
protected function fetchInstrumentByAbbreviation($abbreviation) |
|
|
|
|
893
|
|
|
{ |
894
|
|
|
$instrument = null; |
895
|
|
|
$query = $this->dbConn->createQueryBuilder() |
896
|
|
|
->select('*') |
897
|
|
|
->from('instruments') |
898
|
|
|
->where('abbreviation = :abbreviation') |
899
|
|
|
->setParameter(':abbreviation', $abbreviation); |
900
|
|
|
|
901
|
|
|
$row = $query->execute()->fetch(PDO::FETCH_ASSOC); |
902
|
|
|
|
903
|
|
|
if ($row) { |
904
|
|
|
$instrument = $this->buildInstrumentFromDbRow($row); |
905
|
|
|
} |
906
|
|
|
|
907
|
|
|
return $instrument; |
908
|
|
|
} |
909
|
|
|
|
910
|
|
|
|
911
|
|
|
/** |
912
|
|
|
* @param $songId |
913
|
|
|
* @param array $instrumentIds |
914
|
|
|
* @throws \Doctrine\DBAL\Exception\InvalidArgumentException |
915
|
|
|
*/ |
916
|
|
View Code Duplication |
public function storeSongInstrumentLinks($songId, array $instrumentIds) |
|
|
|
|
917
|
|
|
{ |
918
|
|
|
$this->dbConn->delete('songs_x_instruments', ['songId' => $songId]); |
919
|
|
|
|
920
|
|
|
foreach ($instrumentIds as $instrumentId) { |
921
|
|
|
$this->dbConn->insert('songs_x_instruments', ['songId' => $songId, 'instrumentId' => $instrumentId]); |
922
|
|
|
} |
923
|
|
|
} |
924
|
|
|
|
925
|
|
|
/** |
926
|
|
|
* @param $songId |
927
|
|
|
* @return Instrument[] |
928
|
|
|
*/ |
929
|
|
View Code Duplication |
public function fetchInstrumentsForSongId($songId) |
|
|
|
|
930
|
|
|
{ |
931
|
|
|
$instrumentRows = $this->dbConn->fetchAll( |
932
|
|
|
'SELECT i.* FROM songs_x_instruments si |
933
|
|
|
INNER JOIN instruments i ON si.instrumentId = i.id WHERE si.songId = :songId', |
934
|
|
|
['songId' => $songId] |
935
|
|
|
); |
936
|
|
|
|
937
|
|
|
$dbConn = $this; |
938
|
|
|
$instruments = array_map( |
939
|
|
|
function ($row) use ($dbConn) { |
940
|
|
|
return $dbConn->buildInstrumentFromDbRow($row); |
941
|
|
|
}, |
942
|
|
|
$instrumentRows |
943
|
|
|
); |
944
|
|
|
|
945
|
|
|
return $instruments; |
946
|
|
|
} |
947
|
|
|
|
948
|
|
|
/** |
949
|
|
|
* @param $songId |
950
|
|
|
* @return Platform[] |
951
|
|
|
*/ |
952
|
|
View Code Duplication |
public function fetchPlatformsForSongId($songId) |
|
|
|
|
953
|
|
|
{ |
954
|
|
|
$platformRows = $this->dbConn->fetchAll( |
955
|
|
|
'SELECT p.* FROM songs_x_platforms sp |
956
|
|
|
INNER JOIN platforms p ON sp.platformId = p.id WHERE sp.songId = :songId', |
957
|
|
|
['songId' => $songId] |
958
|
|
|
); |
959
|
|
|
|
960
|
|
|
$dbConn = $this; |
961
|
|
|
$platforms = array_map( |
962
|
|
|
function ($row) use ($dbConn) { |
963
|
|
|
return $dbConn->buildPlatformFromDbRow($row); |
964
|
|
|
}, |
965
|
|
|
$platformRows |
966
|
|
|
); |
967
|
|
|
|
968
|
|
|
return $platforms; |
969
|
|
|
} |
970
|
|
|
|
971
|
|
|
/** |
972
|
|
|
* @param $row |
973
|
|
|
* @return Instrument |
974
|
|
|
*/ |
975
|
|
|
protected function buildInstrumentFromDbRow($row) |
976
|
|
|
{ |
977
|
|
|
$instrument = new Instrument(); |
978
|
|
|
$instrument |
979
|
|
|
->setId($row['id']) |
980
|
|
|
->setName($row['name']) |
981
|
|
|
->setAbbreviation($row['abbreviation']) |
982
|
|
|
->setIconHtml($row['iconHtml']); |
983
|
|
|
return $instrument; |
984
|
|
|
} |
985
|
|
|
|
986
|
|
|
/** |
987
|
|
|
* @param $row |
988
|
|
|
* @return Platform |
989
|
|
|
*/ |
990
|
|
|
protected function buildPlatformFromDbRow($row) |
991
|
|
|
{ |
992
|
|
|
$platform = new Platform(); |
993
|
|
|
$platform |
994
|
|
|
->setId($row['id']) |
995
|
|
|
->setName($row['name']); |
996
|
|
|
return $platform; |
997
|
|
|
} |
998
|
|
|
|
999
|
|
|
/** |
1000
|
|
|
* @param $row |
1001
|
|
|
* @return Source |
1002
|
|
|
*/ |
1003
|
|
|
protected function buildSourceFromDbRow($row) |
1004
|
|
|
{ |
1005
|
|
|
$source = new Source(); |
1006
|
|
|
$source |
1007
|
|
|
->setId($row['id']) |
1008
|
|
|
->setName($row['name']); |
1009
|
|
|
return $source; |
1010
|
|
|
} |
1011
|
|
|
|
1012
|
|
|
/** |
1013
|
|
|
* @param Song $song |
1014
|
|
|
* @return array |
1015
|
|
|
*/ |
1016
|
|
|
protected function songToDbRow(Song $song) |
1017
|
|
|
{ |
1018
|
|
|
$asArray = []; |
1019
|
|
|
if ($song->getId()) { |
1020
|
|
|
$asArray['id'] = $song->getId(); |
1021
|
|
|
} |
1022
|
|
|
|
1023
|
|
|
$asArray['artist'] = $song->getArtist(); |
1024
|
|
|
$asArray['title'] = $song->getTitle(); |
1025
|
|
|
$asArray['duration'] = $song->getDuration(); |
1026
|
|
|
$asArray['sourceId'] = $song->getSourceId(); |
1027
|
|
|
$asArray['codeNumber'] = $song->getCodeNumber(); |
1028
|
|
|
return $asArray; |
1029
|
|
|
} |
1030
|
|
|
|
1031
|
|
|
/** |
1032
|
|
|
* @param Source $source |
1033
|
|
|
* @return array |
1034
|
|
|
*/ |
1035
|
|
|
protected function sourceToDbRow(Source $source) |
1036
|
|
|
{ |
1037
|
|
|
$asArray = []; |
1038
|
|
|
if ($source->getId()) { |
1039
|
|
|
$asArray['id'] = $source->getId(); |
1040
|
|
|
} |
1041
|
|
|
|
1042
|
|
|
$asArray['name'] = $source->getName(); |
1043
|
|
|
return $asArray; |
1044
|
|
|
} |
1045
|
|
|
|
1046
|
|
|
/** |
1047
|
|
|
* @param Instrument $instrument |
1048
|
|
|
* @return array |
1049
|
|
|
*/ |
1050
|
|
|
protected function instrumentToDbRow(Instrument $instrument) |
1051
|
|
|
{ |
1052
|
|
|
$asArray = []; |
1053
|
|
|
if ($instrument->getId()) { |
1054
|
|
|
$asArray['id'] = $instrument->getId(); |
1055
|
|
|
} |
1056
|
|
|
|
1057
|
|
|
$asArray['name'] = $instrument->getName(); |
1058
|
|
|
$asArray['abbreviation'] = $instrument->getAbbreviation(); |
1059
|
|
|
$asArray['iconHtml'] = $instrument->getIconHtml(); |
1060
|
|
|
return $asArray; |
1061
|
|
|
} |
1062
|
|
|
|
1063
|
|
|
/** |
1064
|
|
|
* @param Platform $platform |
1065
|
|
|
* @return array |
1066
|
|
|
*/ |
1067
|
|
|
protected function platformToDbRow(Platform $platform) |
1068
|
|
|
{ |
1069
|
|
|
$asArray = []; |
1070
|
|
|
if ($platform->getId()) { |
1071
|
|
|
$asArray['id'] = $platform->getId(); |
1072
|
|
|
} |
1073
|
|
|
|
1074
|
|
|
$asArray['name'] = $platform->getName(); |
1075
|
|
|
return $asArray; |
1076
|
|
|
} |
1077
|
|
|
} |
1078
|
|
|
|
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.