Completed
Push — master ( ccf562...798527 )
by greg
11:12 queued 10s
created

InstantWin::createRandomOccurrences()   B

Complexity

Conditions 9
Paths 48

Size

Total Lines 42

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 42
rs 7.6924
c 0
b 0
f 0
cc 9
nc 48
nop 4
1
<?php
2
3
namespace PlaygroundGame\Service;
4
5
use Zend\Stdlib\ErrorHandler;
6
7
class InstantWin extends Game
8
{
9
    /**
10
     * @var InstantWinOccurrenceMapperInterface
11
     */
12
    protected $instantWinOccurrenceMapper;
13
14
    protected $prizeMapper;
15
16
    /**
17
     *
18
     * saving an instantwin image if any
19
     *
20
     * @param  array                  $data
21
     * @param  string                 $formClass
22
     * @return \PlaygroundGame\Entity\Game
23
     */
24
    public function createOrUpdate(array $data, $game, $formClass)
25
    {
26
        $game = parent::createOrUpdate($data, $game, $formClass);
27
28
        if ($game) {
29
            $path = $this->getOptions()->getMediaPath() . DIRECTORY_SEPARATOR;
30
            $media_url = $this->getOptions()->getMediaUrl() . '/';
31
32
            if (!empty($data['uploadScratchcardImage']['tmp_name'])) {
33
                ErrorHandler::start();
34
                $data['uploadScratchcardImage']['name'] = $this->fileNewname(
35
                    $path,
36
                    $game->getId() . "-" . $data['uploadScratchcardImage']['name']
37
                );
38
                move_uploaded_file(
39
                    $data['uploadScratchcardImage']['tmp_name'],
40
                    $path . $data['uploadScratchcardImage']['name']
41
                );
42
                $game->setScratchcardImage($media_url . $data['uploadScratchcardImage']['name']);
43
                ErrorHandler::stop(true);
44
45
                $game = $this->getGameMapper()->update($game);
46
            }
47
48 View Code Duplication
            if (isset($data['deleteScratchcardImage']) &&
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
49
                $data['deleteScratchcardImage'] &&
50
                empty($data['uploadScratchcardImage']['tmp_name'])
51
            ) {
52
                ErrorHandler::start();
53
                $image = $game->getScratchcardImage();
54
                $image = str_replace($media_url, '', $image);
55
                unlink($path .$image);
56
                $game->setScratchcardImage(null);
57
                ErrorHandler::stop(true);
58
            }
59
60
            if ($game->getScheduleOccurrenceAuto()) {
61
                $this->scheduleOccurrences($game, $data);
62
            }
63
        }
64
65
        return $game;
66
    }
67
68
    /**
69
     * We can create Instant win occurrences dynamically
70
     *
71
     *
72
     * @param  array                  $data
73
     * @return boolean|null
74
     */
75
    public function scheduleOccurrences($game, array $data)
76
    {
77
        // It will be quite long to create these occurrences !
78
        set_time_limit(0);
79
        if ($game->getOccurrenceType() === 'code') {
80
            return $this->scheduleCodeOccurrences($game, $data);
81
        } elseif ($game->getOccurrenceType() === 'datetime') {
82
            return $this->scheduleDateOccurrences($game);
83
        }
84
    }
85
86
    public function scheduleCodeOccurrences($game, $data)
87
    {
88
        $available_characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-';
89
        $last_character_index = strlen($available_characters)-1;
90
        if (!$game->getWinningOccurrenceNumber()) {
91
            $game->setWinningOccurrenceNumber($game->getOccurrenceNumber());
92
        }
93
        if (empty($data['occurrenceValueSize'])) {
94
            $data['occurrenceValueSize'] = 8;
95
        }
96
        $created = 0;
97
        $numOccurrences = $game->getOccurrenceNumber();
98
        
99
        for ($i=0; $i < $numOccurrences; $i++) {
100
            $code = '';
101
            while (strlen($code)<$data['occurrenceValueSize']) {
102
                $code .= $available_characters[rand(0, $last_character_index)];
103
            }
104
            $occurrence = new \PlaygroundGame\Entity\InstantWinOccurrence();
105
            $occurrence->setInstantwin($game);
106
            $occurrence->setValue($code);
107
            $occurrence->setActive(1);
108
            $occurrence->setWinning($created < $game->getWinningOccurrenceNumber());
109
            if ($this->getInstantWinOccurrenceMapper()->insert($occurrence)) {
110
                $created++;
111
            }
112
        }
113
        return true;
114
    }
115
116
    public function createRandomOccurrences($game, $beginning, $end, $quantity)
117
    {
118
        $prizes = $game->getPrizes();
119
        $randomPrizes = [];
120
        $insertPrize = false;
121
        $exactCount = false;
122
        foreach ($prizes as $prize) {
123
            $qty = $prize->getQty();
124
            if ($qty > 0) {
125
                for ($i = 0; $i < $qty; $i++) {
126
                    $randomPrizes[] = $prize;
127
                }
128
            } 
129
        }
130
        $min = 0;
131
        $max = count($randomPrizes);
132
        if ($max > $min) {
133
            $insertPrize = true;
134
            if ($quantity === $max) {
135
                $exactCount = true;
136
            }
137
        }
138
139
        for ($i=1; $i<=$quantity; $i++) {
140
            $randomDate = $this->getRandomDate($beginning->format('U'), $end->format('U'));
141
            $randomDate = \DateTime::createFromFormat('Y-m-d H:i:s', $randomDate);
142
            $occurrence  = new \PlaygroundGame\Entity\InstantWinOccurrence();
143
            $occurrence->setInstantwin($game);
144
            $occurrence->setValue($randomDate->format('Y-m-d H:i:s'));
145
            $occurrence->setActive(1);
146
            if ($insertPrize) {
147
                $toPick = rand($min, $max - 1);
148
                $occurrence->setPrize($randomPrizes[$toPick]);
149
                if ($exactCount) {
150
                    array_splice($randomPrizes, $toPick, 1);
151
                    --$max;
152
                }
153
            }
154
155
            $this->getInstantWinOccurrenceMapper()->insert($occurrence);
156
        }
157
    }
158
159
    /**
160
     * Get the number of occurrences to create for the instantwin
161
     */
162
    public function getOccurrenceNumber($game)
163
    {
164
        $nb = 0;
165
        if ($game->getOccurrenceNumber() > 0) {
166
            $nb = $game->getOccurrenceNumber();
167
        } else {
168
            $prizes = $game->getPrizes();
169
            foreach ($prizes as $prize) {
170
                $nb += $prize->getQty();
171
            }
172
        }
173
174
        return $nb;
175
    }
176
177
    public function scheduleDateOccurrences($game)
178
    {
179
        $f = $game->getOccurrenceDrawFrequency();
180
        $today    = new \DateTime("now");
181
        $end      = new \DateTime("now");
182
        $interval = 'P10D';
183
        if ($game->getStartDate() && $game->getStartDate() > $today) {
184
            $beginning = $game->getStartDate();
185
        } else {
186
            $beginning = $today;
187
        }
188
189
        if ($game->getEndDate()) {
190
            $end = $game->getEndDate();
191
        } else {
192
            $end->add(new \DateInterval($interval));
193
        }
194
195
        // Summertimes timezone management
196
        $timezone = $today->getTimezone();
197
        $transitions = $timezone->getTransitions($beginning->getTimestamp(), $end->getTimestamp());
198
199
        // There is a time transition between these datetimes()
200
        if (count($transitions) == 2) {
201
            $shift = $transitions[0]['offset'] - $transitions[1]['offset'];
202
            if ($shift > 0) {
203
                $end->sub(new \DateInterval('PT'.abs($shift).'S'));
204
            } else {
205
                $end->add(new \DateInterval('PT'.abs($shift).'S'));
206
            }
207
        }
208
209
        // DateInterval takes the day @ 00:00 to calculate the difference between the dates, so 1 day is always missing
210
        // as we consider the last day @ 23:59:59 in Playground :)
211
        if ($end->format('His') == 0) {
212
            $end->add(new \DateInterval('P1D'));
213
        }
214
215
        $dateInterval = (int)(($end->getTimestamp() - $beginning->getTimestamp())/60);
216
217
        // Je recherche tous les IG non gagnés
218
        $occurrences = $this->getInstantWinOccurrenceMapper()->findBy(array('instantwin' => $game));
219
        $nbExistingOccurrences = count($occurrences);
220
        $nbOccurencesToCreate = 0;
221
222
        switch ($f) {
223
            case null:
224
            case 'game':
225
                $nbOccurencesToCreate = $this->getOccurrenceNumber($game) - $nbExistingOccurrences;
226
                if ($nbOccurencesToCreate > 0) {
227
                    $this->createRandomOccurrences($game, $beginning, $end, $nbOccurencesToCreate);
228
                }
229
230
                break;
231 View Code Duplication
            case 'hour':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
232
                $nbInterval = (int) ($dateInterval/60);
233
234
                // If a hour don't last 60min, I consider it as a hour anyway.
235
                if ($dateInterval%60 > 0) {
236
                    ++$nbInterval;
237
                }
238
                if ($nbInterval > 0) {
239
                    $nbOccurencesToCreate = $game->getOccurrenceNumber() - floor($nbExistingOccurrences/$nbInterval);
240
                }
241
242
                $beginningDrawDate = \DateTime::createFromFormat('m/d/Y H:i:s', $beginning->format('m/d/Y H:i:s'));
243
                $endDrawDate = \DateTime::createFromFormat('m/d/Y H:i:s', $beginning->format('m/d/Y H'). ':59:59');
244
                
245
                if ($nbOccurencesToCreate > 0) {
246
                    for ($d=1; $d<=$nbInterval; $d++) {
247
                        $this->createRandomOccurrences(
248
                            $game,
249
                            $beginningDrawDate,
250
                            $endDrawDate,
251
                            $nbOccurencesToCreate
252
                        );
253
                        $beginningDrawDate = \DateTime::createFromFormat(
254
                            'm/d/Y H:i:s',
255
                            $beginningDrawDate->format('m/d/Y H'). ':00:00'
256
                        );
257
                        $beginningDrawDate->add(new \DateInterval('PT1H'));
258
                        $endDrawDate->add(new \DateInterval('PT1H'));
259
                    }
260
                }
261
262
                break;
263 View Code Duplication
            case 'day':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
264
                $nbInterval = (int) ($dateInterval/(60*24));
265
266
                // Prise en compte des changements d'horaires
267
                // If a day don't last 24h, I consider it as a day anyway
268
269
                if ($dateInterval%(60*24) > 0) {
270
                    ++$nbInterval;
271
                }
272
273
                if ($nbInterval > 0) {
274
                    $nbOccurencesToCreate = $game->getOccurrenceNumber() - floor($nbExistingOccurrences/$nbInterval);
275
                }
276
277
                $beginningDrawDate = \DateTime::createFromFormat('m/d/Y H:i:s', $beginning->format('m/d/Y H:i:s'));
278
                $endDrawDate = \DateTime::createFromFormat('m/d/Y H:i:s', $beginning->format('m/d/Y'). ' 23:59:59');
279
                
280
                if ($nbOccurencesToCreate > 0) {
281
                    for ($d=1; $d<=$nbInterval; $d++) {
282
                        $this->createRandomOccurrences(
283
                            $game,
284
                            $beginningDrawDate,
285
                            $endDrawDate,
286
                            $nbOccurencesToCreate
287
                        );
288
                        // As the first beginning date was not @ midnight,
289
                        // I recreate the beginning date
290
                        $beginningDrawDate = \DateTime::createFromFormat(
291
                            'm/d/Y H:i:s',
292
                            $beginningDrawDate->format('m/d/Y'). ' 00:00:00'
293
                        );
294
                        $beginningDrawDate->add(new \DateInterval('P1D'));
295
                        $endDrawDate->add(new \DateInterval('P1D'));
296
                    }
297
                }
298
299
                break;
300 View Code Duplication
            case 'week':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
301
                $nbOccurencesToCreate = $game->getOccurrenceNumber() - $nbExistingOccurrences;
302
                $nbWeeksInterval = (int) ($dateInterval/(60*24*7));
303
                // If a week don't last 7d, I consider it as a week anyway.
304
                if ($dateInterval%(60*24*7) > 0) {
305
                    ++$nbWeeksInterval;
306
                }
307
                $beginningDrawDate = \DateTime::createFromFormat(
308
                    'm/d/Y H:i:s',
309
                    $beginning->format('m/d/Y'). ' 00:00:00'
310
                );
311
                $endDrawDate = \DateTime::createFromFormat(
312
                    'm/d/Y H:i:s',
313
                    $beginning->format('m/d/Y'). ' 23:59:59'
314
                );
315
                $endDrawDate->add(new \DateInterval('P6D'));
316
                if ($endDrawDate > $end) {
317
                    $endDrawDate = $end;
318
                }
319
320
                if ($nbOccurencesToCreate > 0) {
321
                    for ($d=1; $d<=$nbWeeksInterval; $d++) {
322
                        $this->createRandomOccurrences(
323
                            $game,
324
                            $beginningDrawDate,
325
                            $endDrawDate,
326
                            $nbOccurencesToCreate
327
                        );
328
                        $beginningDrawDate->add(new \DateInterval('P1W'));
329
                        $endDrawDate->add(new \DateInterval('P1W'));
330
                        if ($endDrawDate > $end) {
331
                            $endDrawDate = $end;
332
                        }
333
                    }
334
                }
335
336
                break;
337 View Code Duplication
            case 'month':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
338
                $nbOccurencesToCreate = $game->getOccurrenceNumber() - $nbExistingOccurrences;
339
                $nbMonthsInterval = (int) ($dateInterval/(60*24*30));
340
                // If a week don't last 30d, I consider it as a month anyway.
341
                if ($dateInterval%(60*24*30) > 0) {
342
                    ++$nbMonthsInterval;
343
                }
344
                $beginningDrawDate = \DateTime::createFromFormat(
345
                    'm/d/Y H:i:s',
346
                    $beginning->format('m/d/Y'). ' 00:00:00'
347
                );
348
                $endDrawDate = \DateTime::createFromFormat('m/d/Y H:i:s', $beginning->format('m/d/Y'). ' 23:59:59');
349
                $endDrawDate->add(new \DateInterval('P1M'));
350
                $endDrawDate->sub(new \DateInterval('P1D'));
351
                if ($endDrawDate > $end) {
352
                    $endDrawDate = $end;
353
                }
354
355
                if ($nbOccurencesToCreate > 0) {
356
                    for ($d=1; $d<=$nbMonthsInterval; $d++) {
357
                        $this->createRandomOccurrences(
358
                            $game,
359
                            $beginningDrawDate,
360
                            $endDrawDate,
361
                            $nbOccurencesToCreate
362
                        );
363
                        $beginningDrawDate->add(new \DateInterval('P1M'));
364
                        $endDrawDate->add(new \DateInterval('P1M'));
365
                        if ($endDrawDate > $end) {
366
                            $endDrawDate = $end;
367
                        }
368
                    }
369
                }
370
371
                break;
372
        }
373
374
        return true;
375
    }
376
377
    public function getRandomDate($min_date, $max_date)
378
    {
379
        $rand_epoch = rand($min_date, $max_date);
380
381
        return date('Y-m-d H:i:s', $rand_epoch);
382
    }
383
384
    /**
385
     * @param string $fileName
386
     */
387
    public function getOccurencesFromCSV($fileName)
388
    {
389
        if (file_exists($fileName)) {
390
            $csvFile = fopen($fileName, 'r');
391
            if ($csvFile) {
392
                while (!feof($csvFile)) {
393
                    $csvContent[] = fgetcsv($csvFile);
0 ignored issues
show
Coding Style Comprehensibility introduced by
$csvContent was never initialized. Although not strictly required by PHP, it is generally a good practice to add $csvContent = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
394
                }
395
                fclose($csvFile);
396
                return $csvContent;
0 ignored issues
show
Bug introduced by
The variable $csvContent 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...
397
            }
398
        }
399
        return false;
400
    }
401
402
    public function setOccurencesToCSV($game)
403
    {
404
        $path = $this->getOptions()->getMediaPath() . DIRECTORY_SEPARATOR;
405
        $fileName = $path.'occurences-'.$game->getId().'.csv';
406
        $csvFile = fopen($fileName, 'w');
407
        if ($csvFile) {
408
            $occurrences = $this->getInstantWinOccurrenceMapper()->findByGameId($game);
409
            foreach ($occurrences as $occurrence) {
410
                fputcsv($csvFile, array($occurrence->getValue(), $occurrence->getWinning()));
411
            }
412
            fclose($csvFile);
413
            return $fileName;
414
        }
415
        return false;
416
    }
417
418
    public function importOccurrences($data)
419
    {
420
        if (!empty($data['file']['tmp_name'])) {
421
            $path = $this->getOptions()->getMediaPath() . DIRECTORY_SEPARATOR;
422
            $real_media_path = realpath($path) . DIRECTORY_SEPARATOR;
423
424
            // upload the csv file
425
            ErrorHandler::start();
426
            $data['file']['name'] = $this->fileNewname($path, $data['instant_win_id'] . "-" . $data['file']['name']);
427
            move_uploaded_file($data['file']['tmp_name'], $path . $data['file']['name']);
428
            ErrorHandler::stop(true);
429
            $csv_content = $this->getOccurencesFromCSV($real_media_path.$data['file']['name']);
430
            if ($csv_content) {
431
                $created = 0;
432
                foreach ($csv_content as $line) {
433
                    if ($line) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $line of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

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.

Loading history...
434
                        $occurrence = $this->updateOccurrence(array(
435
                            'id' => '',
436
                            'instant_win_id' => $data['instant_win_id'],
437
                            'value' => $line[0],
438
                            'active' => $data['active'],
439
                            'winning' => ((bool) $line[1]) ? 1 : 0,
440
                            'prize_id' => $data['prize'],
441
                        ), null);
442
                        if ($occurrence) {
443
                            $created++;
444
                        }
445
                    }
446
                }
447
                // remove the csv file from folder
448
                unlink($real_media_path.$data['file']['name']);
449
                return $created;
450
            }
451
        }
452
        return false;
453
    }
454
455
    /**
456
     *
457
     *
458
     * @param  array                  $data
459
     * @return \PlaygroundGame\Entity\Game
460
     */
461
    public function updateOccurrence(array $data, $occurrence_id = null)
462
    {
463
        if (!$occurrence_id) {
464
            $occurrence  = new \PlaygroundGame\Entity\InstantWinOccurrence();
465
        } else {
466
            $occurrence = $this->getInstantWinOccurrenceMapper()->findById($occurrence_id);
467
        }
468
        $form  = $this->serviceLocator->get('playgroundgame_instantwinoccurrence_form');
469
        $form->bind($occurrence);
470
471
        $form->setData($data);
472
473
        $instantwin = $this->getGameMapper()->findById($data['instant_win_id']);
474
        $prize = null;
475
        if (isset($data['prize'])) {
476
            $prize = $this->getPrizeMapper()->findById($data['prize']);
477
        }
478
479
        if (!$form->isValid()) {
480
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return false; (false) is incompatible with the return type documented by PlaygroundGame\Service\I...ntWin::updateOccurrence of type PlaygroundGame\Entity\Game.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
481
        }
482
483
        $occurrence->setInstantWin($instantwin);
484
        $occurrence->setPrize($prize);
485
        $occurrence->populate($data);
486
487
        if ($occurrence_id) {
488
            $this->getInstantWinOccurrenceMapper()->insert($occurrence);
489
        } else {
490
            $this->getInstantWinOccurrenceMapper()->update($occurrence);
491
        }
492
493
        return $occurrence;
494
    }
495
496
    /**
497
     * return true if the player has won. False otherwise.
498
     *
499
     * @param \PlaygroundGame\Entity\Game $game
500
     * @param \PlaygroundUser\Entity\UserInterface $user
501
     *
502
     * @return boolean
503
     */
504
    public function isInstantWinner($game, $user, $value = null)
505
    {
506
        $occurrenceMapper = $this->getInstantWinOccurrenceMapper();
507
508
        if ($game->getOccurrenceType()=='datetime') {
509
            $entry = $this->findLastActiveEntry($game, $user);
510
511
            // si date après date de gain et date de gain encore active alors desactive date de gain, et winner !
512
            $occurrence = $occurrenceMapper->checkDateOccurrenceByGameId($game);
513
        } elseif ($game->getOccurrenceType()=='code') {
514
            $occurrence = $occurrenceMapper->checkCodeOccurrenceByGameId($game, $value);
515
            if (!$occurrence) {
516
                return false;
517
            }
518
            $entry = $this->play($game, $user);
519
        }
520
521
        if (!$entry) {
0 ignored issues
show
Bug introduced by
The variable $entry 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...
522
            return false;
523
        }
524
        $this->getEventManager()->trigger(
525
            __FUNCTION__ . '.pre',
526
            $this,
527
            array('user' => $user, 'game' => $game, 'entry' => $entry)
528
        );
529
        $occurrence = $this->setOccurrenceEntry($game, $user, $entry, $occurrence);
0 ignored issues
show
Bug introduced by
The variable $occurrence 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...
530
        $this->getEventManager()->trigger(
531
            __FUNCTION__ . '.post',
532
            $this,
533
            array('user' => $user, 'game' => $game, 'entry' => $entry, 'occurrence' => $occurrence)
534
        );
535
        return $occurrence;
536
    }
537
538
    /**
539
     * @param \PlaygroundGame\Entity\Game $game
540
     * @param \PlaygroundUser\Entity\UserInterface $user
541
     */
542
    public function setOccurrenceEntry($game, $user, $entry, $occurrence = null)
0 ignored issues
show
Unused Code introduced by
The parameter $game is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
543
    {
544
        $entryMapper = $this->getEntryMapper();
545
        $occurrenceMapper = $this->getInstantWinOccurrenceMapper();
546
547
        $entry->setActive(0);
548
        if ($occurrence) {
549
            $occurrence->setEntry($entry);
550
            $occurrence->setUser($user);
551
            $occurrence->setActive(0);
552
            $occurrence = $occurrenceMapper->update($occurrence);
553
            if ($occurrence->getWinning()) {
554
                $entry->setWinner(true);
555
            } else {
556
                $entry->setPoints(0);
557
                $entry->setWinner(false);
558
            }
559
        } else {
560
            $entry->setPoints(0);
561
            $entry->setWinner(false);
562
        }
563
        $entry = $entryMapper->update($entry);
0 ignored issues
show
Unused Code introduced by
$entry is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
564
565
        return $occurrence;
566
    }
567
568
    public function getEntriesHeader($game)
569
    {
570
        $header = parent::getEntriesHeader($game);
571
        $header['value'] = 1;
572
        $header['prize'] = 1;
573
574
        return $header;
575
    }
576
577
    /**
578
    * getGameEntries : All entries of a game
579
    *
580
    * @return Array of PlaygroundGame\Entity\Game
581
    */
582
    public function getGameEntries($header, $entries, $game)
583
    {
584
        $results = array();
585
586
        foreach ($entries as $k => $entry) {
587
            $entryData = json_decode($entry['playerData'], true);
588
            $winner = $entry['winner'];
589
590 View Code Duplication
            foreach ($header as $key => $v) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
591
                if (isset($entryData[$key]) && $key !=='id') {
592
                    $results[$k][$key] = (is_array($entryData[$key]))?implode(', ', $entryData[$key]):$entryData[$key];
593
                } elseif (array_key_exists($key, $entry)) {
594
                    $results[$k][$key] = ($entry[$key] instanceof \DateTime)?
595
                        $entry[$key]->format('Y-m-d'):
596
                        $entry[$key];
597
                } else {
598
                    $results[$k][$key] = '';
599
                }
600
            }
601
            // If the occurrenceType is code, this will be triggered for every entry. To be improved.
602
            if ($game->getOccurrenceType() === 'code' || ($game->getOccurrenceType() === 'datetime' && $winner)) {
603
                $entry = $this->getEntryMapper()->findById($entry['id']);
604
                $occurrence = $this->getInstantWinOccurrenceMapper()->findByEntry($entry);
605
                if ($occurrence !== null) {
606
                    $results[$k]['value'] = $occurrence->getValue();
607
                    if ($occurrence->getPrize()) {
608
                        $results[$k]['prize'] = $occurrence->getPrize()->getTitle();
609
                    }
610
                }
611
            }
612
        }
613
614
        return $results;
615
    }
616
617
    public function getGameEntity()
618
    {
619
        return new \PlaygroundGame\Entity\InstantWin;
620
    }
621
622
    /**
623
     * getInstantWinOccurrenceMapper
624
     *
625
     * @return InstantWinOccurrenceMapperInterface
626
     */
627
    public function getInstantWinOccurrenceMapper()
628
    {
629
        if (null === $this->instantWinOccurrenceMapper) {
630
            $this->instantWinOccurrenceMapper = $this->serviceLocator->get(
631
                'playgroundgame_instantwinoccurrence_mapper'
632
            );
633
        }
634
635
        return $this->instantWinOccurrenceMapper;
636
    }
637
638
    /**
639
     * setInstantWinOccurrenceMapper
640
     *
641
     * @return InstantWin
642
     */
643
    public function setInstantWinOccurrenceMapper($instantWinOccurrenceMapper)
644
    {
645
        $this->instantWinOccurrenceMapper = $instantWinOccurrenceMapper;
646
647
        return $this;
648
    }
649
650
    /**
651
     * getPrizeMapper
652
     *
653
     * @return PrizeMapperInterface
654
     */
655 View Code Duplication
    public function getPrizeMapper()
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...
656
    {
657
        if (null === $this->prizeMapper) {
658
            $this->prizeMapper = $this->serviceLocator->get('playgroundgame_prize_mapper');
659
        }
660
661
        return $this->prizeMapper;
662
    }
663
664
    /**
665
     * setInstantWinOccurrenceMapper
666
     *
667
     * @param  PrizeMapperInterface $prizeMapper
668
     * @return InstantWin
669
     */
670
    public function setPrizeMapper($prizeMapper)
671
    {
672
        $this->prizeMapper = $prizeMapper;
673
674
        return $this;
675
    }
676
}
677