Completed
Pull Request — master (#264)
by greg
02:58
created

Game::allowBonus()   B

Complexity

Conditions 6
Paths 5

Size

Total Lines 20
Code Lines 14

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 20
rs 8.8571
cc 6
eloc 14
nc 5
nop 2
1
<?php
2
namespace PlaygroundGame\Service;
3
4
use PlaygroundGame\Entity\Entry;
5
use Zend\Session\Container;
6
use Zend\ServiceManager\ServiceManagerAwareInterface;
7
use Zend\ServiceManager\ServiceManager;
8
use ZfcBase\EventManager\EventProvider;
9
use PlaygroundGame\Options\ModuleOptions;
10
use PlaygroundGame\Mapper\GameInterface as GameMapperInterface;
11
use DoctrineModule\Validator\NoObjectExists as NoObjectExistsValidator;
12
use Zend\Validator\File\Size;
13
use Zend\Validator\File\IsImage;
14
use Zend\Stdlib\ErrorHandler;
15
use PlaygroundCore\Filter\Sanitize;
16
use Zend\Form\Element;
17
use Zend\Form\Form;
18
use Zend\InputFilter\Factory as InputFactory;
19
20
class Game extends EventProvider implements ServiceManagerAwareInterface
21
{
22
    /**
23
     *
24
     * @var GameMapperInterface
25
     */
26
    protected $gameMapper;
27
28
    /**
29
     *
30
     * @var EntryMapperInterface
31
     */
32
    protected $entryMapper;
33
34
    /**
35
     *
36
     * @var ServiceManager
37
     */
38
    protected $serviceManager;
39
40
    /**
41
     *
42
     * @var UserServiceOptionsInterface
43
     */
44
    protected $options;
45
46
    protected $playerformMapper;
47
    
48
    protected $anonymousIdentifier = null;
49
50
    /**
51
     *
52
     *
53
     * This service is ready for all types of games
54
     *
55
     * @param array $data
56
     * @param string $entity
0 ignored issues
show
Bug introduced by
There is no parameter named $entity. 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...
57
     * @param string $formClass
58
     * @return \PlaygroundGame\Entity\Game
59
     */
60
    public function createOrUpdate(array $data, $game, $formClass)
61
    {
62
        $entityManager = $this->getServiceManager()->get('doctrine.entitymanager.orm_default');
63
64
        $form = $this->getServiceManager()->get($formClass);
65
        $form->get('publicationDate')->setOptions(array(
66
            'format' => 'Y-m-d'
67
        ));
68
        $form->get('startDate')->setOptions(array(
69
            'format' => 'Y-m-d'
70
        ));
71
        $form->get('endDate')->setOptions(array(
72
            'format' => 'Y-m-d'
73
        ));
74
        $form->get('closeDate')->setOptions(array(
75
            'format' => 'Y-m-d'
76
        ));
77
78
        $form->bind($game);
79
80
        $path = $this->getOptions()->getMediaPath() . '/';
81
        $media_url = $this->getOptions()->getMediaUrl() . '/';
82
83
        $identifierInput = $form->getInputFilter()->get('identifier');
84
        $noObjectExistsValidator = new NoObjectExistsValidator(array(
85
            'object_repository' => $entityManager->getRepository('PlaygroundGame\Entity\Game'),
86
            'fields' => 'identifier',
87
            'messages' => array(
88
                'objectFound' => 'This url already exists !'
89
            )
90
        ));
91
92
        if ($game->getIdentifier() != $data['identifier']) {
93
            $identifierInput->getValidatorChain()->addValidator($noObjectExistsValidator);
94
        }
95
96
        // I must switch from original format to the Y-m-d format because
97
        // this is the only one accepted by new DateTime($value)
98 View Code Duplication
        if (isset($data['publicationDate']) && $data['publicationDate']) {
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...
99
            $tmpDate = \DateTime::createFromFormat('d/m/Y', $data['publicationDate']);
100
            $data['publicationDate'] = $tmpDate->format('Y-m-d');
101
        }
102 View Code Duplication
        if (isset($data['startDate']) && $data['startDate']) {
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...
103
            $tmpDate = \DateTime::createFromFormat('d/m/Y', $data['startDate']);
104
            $data['startDate'] = $tmpDate->format('Y-m-d');
105
        }
106 View Code Duplication
        if (isset($data['endDate']) && $data['endDate']) {
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...
107
            $tmpDate = \DateTime::createFromFormat('d/m/Y', $data['endDate']);
108
            $data['endDate'] = $tmpDate->format('Y-m-d');
109
        }
110 View Code Duplication
        if (isset($data['closeDate']) && $data['closeDate']) {
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...
111
            $tmpDate = \DateTime::createFromFormat('d/m/Y', $data['closeDate']);
112
            $data['closeDate'] = $tmpDate->format('Y-m-d');
113
        }
114
115
        // If publicationDate is null, I update it with the startDate if not null neither
116
        if ((! isset($data['publicationDate']) || $data['publicationDate'] == '') &&
117
            (isset($data['startDate']) && $data['startDate'] != '')
118
        ) {
119
            $data['publicationDate'] = $data['startDate'];
120
        }
121
122
        // If the identifier has not been set, I use the title to create one.
123 View Code Duplication
        if ((! isset($data['identifier']) || empty($data['identifier'])) && isset($data['title'])) {
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...
124
            $data['identifier'] = $data['title'];
125
        }
126
127
        $form->setData($data);
128
129
        // If someone want to claim... It's time to do it ! used for exemple by PlaygroundFacebook Module
130
        $result = $this->getEventManager()->trigger(__FUNCTION__ . '.validate', $this, array(
131
            'game' => $game,
132
            'data' => $data
133
        ));
134
        if (is_array($result) && ! $result[0]) {
135
            $form->get('fbAppId')->setMessages(array(
136
                'Vous devez d\'abord désinstaller l\'appli Facebook'
137
            ));
138
139
            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\Game::createOrUpdate 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...
140
        }
141
142
        if (! $form->isValid()) {
143
            if (isset($data['publicationDate']) && $data['publicationDate']) {
144
                $tmpDate = \DateTime::createFromFormat('Y-m-d', $data['publicationDate']);
145
                $data['publicationDate'] = $tmpDate->format('d/m/Y');
146
                $form->setData(array(
147
                    'publicationDate' => $data['publicationDate']
148
                ));
149
            }
150
            if (isset($data['startDate']) && $data['startDate']) {
151
                $tmpDate = \DateTime::createFromFormat('Y-m-d', $data['startDate']);
152
                $data['startDate'] = $tmpDate->format('d/m/Y');
153
                $form->setData(array(
154
                    'startDate' => $data['startDate']
155
                ));
156
            }
157
            if (isset($data['endDate']) && $data['endDate']) {
158
                $tmpDate = \DateTime::createFromFormat('Y-m-d', $data['endDate']);
159
                $data['endDate'] = $tmpDate->format('d/m/Y');
160
                $form->setData(array(
161
                    'endDate' => $data['endDate']
162
                ));
163
            }
164
            if (isset($data['closeDate']) && $data['closeDate']) {
165
                $tmpDate = \DateTime::createFromFormat('Y-m-d', $data['closeDate']);
166
                $data['closeDate'] = $tmpDate->format('d/m/Y');
167
                $form->setData(array(
168
                    'closeDate' => $data['closeDate']
169
                ));
170
            }
171
            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\Game::createOrUpdate 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...
172
        }
173
174
        $game = $form->getData();
175
        $game = $this->getGameMapper()->insert($game);
176
177
        // I wait for the game to be saved to obtain its ID.
178 View Code Duplication
        if (! empty($data['uploadMainImage']['tmp_name'])) {
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...
179
            ErrorHandler::start();
180
            $data['uploadMainImage']['name'] = $this->fileNewname(
181
                $path,
182
                $game->getId() . "-" . $data['uploadMainImage']['name']
183
            );
184
            move_uploaded_file($data['uploadMainImage']['tmp_name'], $path . $data['uploadMainImage']['name']);
185
            $game->setMainImage($media_url . $data['uploadMainImage']['name']);
186
            ErrorHandler::stop(true);
187
        }
188
189 View Code Duplication
        if (isset($data['deleteMainImage']) &&
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...
190
            $data['deleteMainImage'] &&
191
            empty($data['uploadMainImage']['tmp_name'])
192
        ) {
193
            ErrorHandler::start();
194
            $image = $game->getMainImage();
195
            $image = str_replace($media_url, '', $image);
196
            unlink($path . $image);
197
            $game->setMainImage(null);
198
            ErrorHandler::stop(true);
199
        }
200
201 View Code Duplication
        if (! empty($data['uploadSecondImage']['tmp_name'])) {
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...
202
            ErrorHandler::start();
203
            $data['uploadSecondImage']['name'] = $this->fileNewname(
204
                $path,
205
                $game->getId() . "-" . $data['uploadSecondImage']['name']
206
            );
207
            move_uploaded_file($data['uploadSecondImage']['tmp_name'], $path . $data['uploadSecondImage']['name']);
208
            $game->setSecondImage($media_url . $data['uploadSecondImage']['name']);
209
            ErrorHandler::stop(true);
210
        }
211
212 View Code Duplication
        if (isset($data['deleteSecondImage']) &&
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...
213
            $data['deleteSecondImage'] &&
214
            empty($data['uploadSecondImage']['tmp_name'])
215
        ) {
216
            ErrorHandler::start();
217
            $image = $game->getSecondImage();
218
            $image = str_replace($media_url, '', $image);
219
            unlink($path . $image);
220
            $game->setSecondImage(null);
221
            ErrorHandler::stop(true);
222
        }
223
224
        if (! empty($data['uploadStylesheet']['tmp_name'])) {
225
            ErrorHandler::start();
226
            move_uploaded_file($data['uploadStylesheet']['tmp_name'], $path . 'stylesheet_' . $game->getId() . '.css');
227
            $game->setStylesheet($media_url . 'stylesheet_' . $game->getId() . '.css');
228
            ErrorHandler::stop(true);
229
        }
230
231 View Code Duplication
        if (! empty($data['uploadFbShareImage']['tmp_name'])) {
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
            ErrorHandler::start();
233
            $data['uploadFbShareImage']['name'] = $this->fileNewname(
234
                $path,
235
                $game->getId() . "-" . $data['uploadFbShareImage']['name']
236
            );
237
            move_uploaded_file($data['uploadFbShareImage']['tmp_name'], $path . $data['uploadFbShareImage']['name']);
238
            $game->setFbShareImage($media_url . $data['uploadFbShareImage']['name']);
239
            ErrorHandler::stop(true);
240
        }
241
242 View Code Duplication
        if (isset($data['deleteFbShareImage']) &&
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...
243
            $data['deleteFbShareImage'] &&
244
            empty($data['uploadFbShareImage']['tmp_name'])
245
        ) {
246
            ErrorHandler::start();
247
            $image = $game->getFbShareImage();
248
            $image = str_replace($media_url, '', $image);
249
            unlink($path . $image);
250
            $game->setFbShareImage(null);
251
            ErrorHandler::stop(true);
252
        }
253
254
        if (! empty($data['uploadFbPageTabImage']['tmp_name'])) {
255
            ErrorHandler::start();
256
            $extension = $this->getExtension(strtolower($data['uploadFbPageTabImage']['name']));
257
            $src = $this->getSrc($extension, $data['uploadFbPageTabImage']['tmp_name']);
258
            $this->resize(
259
                $data['uploadFbPageTabImage']['tmp_name'],
260
                $extension,
261
                $path . $game->getId() . "-" . $data['uploadFbPageTabImage']['name'],
262
                $src,
263
                111,
264
                74
265
            );
266
267
            $game->setFbPageTabImage($media_url . $game->getId() . "-" . $data['uploadFbPageTabImage']['name']);
268
            ErrorHandler::stop(true);
269
        }
270
271 View Code Duplication
        if (isset($data['deleteFbPageTabImage']) &&
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...
272
            $data['deleteFbPageTabImage'] &&
273
            empty($data['uploadFbPageTabImage']['tmp_name'])
274
        ) {
275
            ErrorHandler::start();
276
            $image = $game->getFbPageTabImage();
277
            $image = str_replace($media_url, '', $image);
278
            unlink($path . $image);
279
            $game->setFbPageTabImage(null);
280
            ErrorHandler::stop(true);
281
        }
282
283
        $game = $this->getGameMapper()->update($game);
284
285
        $prize_mapper = $this->getServiceManager()->get('playgroundgame_prize_mapper');
286
        if (isset($data['prizes'])) {
287
            foreach ($data['prizes'] as $prize_data) {
288
                if (! empty($prize_data['picture_file']['tmp_name']) && ! $prize_data['picture_file']['error']) {
289
                    if ($prize_data['id']) {
290
                        $prize = $prize_mapper->findById($prize_data['id']);
291
                    } else {
292
                        $some_prizes = $prize_mapper->findBy(array(
293
                            'game' => $game,
294
                            'title' => $prize_data['title']
295
                        ));
296
                        if (count($some_prizes) == 1) {
297
                            $prize = $some_prizes[0];
298
                        } else {
299
                            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\Game::createOrUpdate 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...
300
                        }
301
                    }
302
                    // Remove if existing image
303
                    if ($prize->getPicture() && file_exists($prize->getPicture())) {
304
                        unlink($prize->getPicture());
305
                        $prize->getPicture(null);
306
                    }
307
                    // Upload and set new
308
                    ErrorHandler::start();
309
                    $filename = "game-" . $game->getId() . "-prize-";
310
                    $filename .= $prize->getId() . "-" . $prize_data['picture_file']['name'];
311
                    move_uploaded_file($prize_data['picture_file']['tmp_name'], $path . $filename);
312
                    $prize->setPicture($media_url . $filename);
313
                    ErrorHandler::stop(true);
314
                    $prize = $prize_mapper->update($prize);
0 ignored issues
show
Unused Code introduced by
$prize 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...
315
                }
316
            }
317
        }
318
        // If I receive false, it means that the FB Id was not available anymore
319
        $result = $this->getEventManager()->trigger(__FUNCTION__ . '.post', $this, array(
0 ignored issues
show
Unused Code introduced by
$result 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...
320
            'game' => $game
321
        ));
322
323
        return $game;
324
    }
325
    
326
    /**
327
     * getActiveGames
328
     *
329
     * @return Array of PlaygroundGame\Entity\Game
330
     */
331
    public function getActiveGames($displayHome = true, $classType = '', $order = '')
332
    {
333
        $em = $this->getServiceManager()->get('doctrine.entitymanager.orm_default');
334
        $today = new \DateTime("now");
335
        $today = $today->format('Y-m-d') . ' 23:59:59';
336
        $orderBy = 'g.publicationDate';
337
        if ($order != '') {
338
            $orderBy = 'g.'.$order;
339
        }
340
341
        $qb = $em->createQueryBuilder();
342
        $and = $qb->expr()->andx();
343
        $and->add(
344
            $qb->expr()->orX(
345
                $qb->expr()->lte('g.publicationDate', ':date'),
346
                $qb->expr()->isNull('g.publicationDate')
347
            )
348
        );
349
        $and->add(
350
            $qb->expr()->orX(
351
                $qb->expr()->gte('g.closeDate', ':date'),
352
                $qb->expr()->isNull('g.closeDate')
353
            )
354
        );
355
        $qb->setParameter('date', $today);
356
        
357
        $and->add($qb->expr()->eq('g.active', '1'));
358
        $and->add($qb->expr()->eq('g.broadcastPlatform', '1'));
359
        
360
        if ($classType != '') {
361
            $and->add($qb->expr()->eq('g.classType', ':classType'));
362
            $qb->setParameter('classType', $classType);
363
        }
364
        
365
        if ($displayHome) {
366
            $and->add($qb->expr()->eq('g.displayHome', true));
367
        }
368
        
369
        $qb->select('g')
370
        ->from('PlaygroundGame\Entity\Game', 'g')
371
        ->where($and)
372
        ->orderBy($orderBy, 'DESC');
373
        
374
        $query = $qb->getQuery();
375
        $games = $query->getResult();
376
        
377
        // je les classe par date de publication (date comme clé dans le tableau afin de pouvoir merger les objets
378
        // de type article avec le même procédé en les classant naturellement par date asc ou desc
379
        $arrayGames = array();
380 View Code Duplication
        foreach ($games as $game) {
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...
381
            if ($game->getPublicationDate()) {
382
                $key = $game->getPublicationDate()->format('Ymd');
383
            } elseif ($game->getStartDate()) {
384
                $key = $game->getStartDate()->format('Ymd');
385
            } else {
386
                $key = $game->getUpdatedAt()->format('Ymd');
387
            }
388
            $key .= $game->getUpdatedAt()->format('Ymd') . '-' . $game->getId();
389
            $arrayGames[$key] = $game;
390
        }
391
392
        return $arrayGames;
393
    }
394
395
    /**
396
     * getAvailableGames : Games OnLine and not already played by $user
397
     *
398
     * @return Array of PlaygroundGame\Entity\Game
399
     */
400
    public function getAvailableGames($user, $maxResults = 2)
401
    {
402
        $em = $this->getServiceManager()->get('doctrine.entitymanager.orm_default');
403
        $today = new \DateTime("now");
404
        $today = $today->format('Y-m-d') . ' 23:59:59';
405
406
        // Game active with a start_date before today (or without start_date)
407
        // and end_date after today (or without end-date)
408
        $query = $em->createQuery('SELECT g FROM PlaygroundGame\Entity\Game g
409
                WHERE NOT EXISTS (SELECT l FROM PlaygroundGame\Entity\Entry l WHERE l.game = g AND l.user = :user)
410
                AND (g.startDate <= :date OR g.startDate IS NULL)
411
                AND (g.endDate >= :date OR g.endDate IS NULL)
412
                AND g.active = 1 AND g.broadcastPlatform = 1
413
                ORDER BY g.startDate ASC');
414
        $query->setParameter('date', $today);
415
        $query->setParameter('user', $user);
416
        $query->setMaxResults($maxResults);
417
        $games = $query->getResult();
418
419
        return $games;
420
    }
421
422 View Code Duplication
    public function getEntriesQuery($game)
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...
423
    {
424
        $em = $this->getServiceManager()->get('doctrine.entitymanager.orm_default');
425
426
        $qb = $em->createQueryBuilder();
427
        $qb->select('
428
            e.id,
429
            u.username,
430
            u.title,
431
            u.firstname,
432
            u.lastname,
433
            u.email,
434
            u.optin,
435
            u.optinPartner,
436
            u.address,
437
            u.address2,
438
            u.postalCode,
439
            u.city,
440
            u.telephone,
441
            u.mobile,
442
            u.created_at,
443
            u.dob,
444
            e.winner,
445
            e.socialShares,
446
            e.playerData,
447
            e.updated_at
448
            ')
449
            ->from('PlaygroundGame\Entity\Entry', 'e')
450
            ->leftJoin('e.user', 'u')
451
            ->where($qb->expr()->eq('e.game', ':game'));
452
        
453
        $qb->setParameter('game', $game);
454
455
        return $qb->getQuery();
456
    }
457
458
    public function getEntriesHeader($game)
459
    {
460
        if ($game->getPlayerForm()) {
461
            $formPV = json_decode($game->getPlayerForm()->getForm(), true);
462
            $header = array('id'=> 1);
463 View Code Duplication
            foreach ($formPV as $element) {
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...
464
                foreach ($element as $k => $v) {
465
                    if ($k !== 'form_properties') {
466
                        $header[$v[0]['name']] = 1;
467
                    }
468
                }
469
            }
470
        } else {
471
            $header = array(
472
                'id' => 1,
473
                'username' => 1,
474
                'title' => 1,
475
                'firstname' => 1,
476
                'lastname' => 1,
477
                'email' => 1,
478
                'optin' => 1,
479
                'optinPartner' => 1,
480
                'address' => 1,
481
                'address2' => 1,
482
                'postalCode' => 1,
483
                'city' => 1,
484
                'telephone' => 1,
485
                'mobile' => 1,
486
                'created_at' => 1,
487
                'dob' => 1,
488
                'winner' => 1
489
            );
490
        }
491
        $header['winner'] = 1;
492
        $header['socialShares'] = 1;
493
        $header['updated_at'] = 1;
494
495
        return $header;
496
    }
497
498
    /**
499
    * getGameEntries : I create an array of entries based on playerData + header
500
    *
501
    * @return Array of PlaygroundGame\Entity\Game
502
    */
503
    public function getGameEntries($header, $entries, $game)
504
    {
505
        $header = $this->getEntriesHeader($game);
506
507
        $results = array();
508
509
        foreach ($entries as $k => $entry) {
510
            $entryData = json_decode($entry['playerData'], true);
511 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...
512
                if (isset($entryData[$key])) {
513
                    $results[$k][$key] = (is_array($entryData[$key]))?implode(', ', $entryData[$key]):$entryData[$key];
514
                } elseif (array_key_exists($key, $entry)) {
515
                    $results[$k][$key] = ($entry[$key] instanceof \DateTime)?
516
                        $entry[$key]->format('Y-m-d'):
517
                        $entry[$key];
518
                } else {
519
                    $results[$k][$key] = '';
520
                }
521
            }
522
        }
523
524
        return $results;
525
    }
526
527
    /**
528
     * getActiveSliderGames
529
     *
530
     * @return Array of PlaygroundGame\Entity\Game
531
     */
532
    public function getActiveSliderGames()
533
    {
534
        $em = $this->getServiceManager()->get('doctrine.entitymanager.orm_default');
535
        $today = new \DateTime("now");
536
        $today = $today->format('Y-m-d') . ' 23:59:59';
537
538
        // Game active with a start_date before today (or without start_date)
539
        // and end_date after today (or without end-date)
540
        $query = $em->createQuery('SELECT g FROM PlaygroundGame\Entity\Game g
541
            WHERE (g.publicationDate <= :date OR g.publicationDate IS NULL)
542
            AND (g.closeDate >= :date OR g.closeDate IS NULL)
543
            AND g.active = true AND g.broadcastPlatform = 1 AND g.pushHome = true');
544
        $query->setParameter('date', $today);
545
        $games = $query->getResult();
546
547
        // je les classe par date de publication (date comme clé dans le tableau afin de pouvoir merger les objets
548
        // de type article avec le même procédé en les classant naturellement par date asc ou desc
549
        $arrayGames = array();
550 View Code Duplication
        foreach ($games as $game) {
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...
551
            if ($game->getPublicationDate()) {
552
                $key = $game->getPublicationDate()->format('Ymd');
553
            } elseif ($game->getStartDate()) {
554
                $key = $game->getStartDate()->format('Ymd');
555
            } else {
556
                $key = $game->getUpdatedAt()->format('Ymd');
557
            }
558
            $key .= $game->getUpdatedAt()->format('Ymd') . '-' . $game->getId();
559
            $arrayGames[$key] = $game;
560
        }
561
562
        return $arrayGames;
563
    }
564
565
    /**
566
     * getPrizeCategoryGames
567
     *
568
     * @return Array of PlaygroundGame\Entity\Game
569
     */
570 View Code Duplication
    public function getPrizeCategoryGames($categoryid)
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...
571
    {
572
        $em = $this->getServiceManager()->get('doctrine.entitymanager.orm_default');
573
574
        $query = $em->createQuery('SELECT g FROM PlaygroundGame\Entity\Game g
575
            WHERE (g.prizeCategory = :categoryid AND g.broadcastPlatform = 1)
576
            ORDER BY g.publicationDate DESC');
577
        $query->setParameter('categoryid', $categoryid);
578
        $games = $query->getResult();
579
580
        return $games;
581
    }
582
583
    public function checkGame($identifier, $checkIfStarted = true)
584
    {
585
        $gameMapper = $this->getGameMapper();
586
587
        if (! $identifier) {
588
            return false;
589
        }
590
591
        $game = $gameMapper->findByIdentifier($identifier);
592
593
        // the game has not been found
594
        if (! $game) {
595
            return false;
596
        }
597
598
        if ($this->isAllowed('game', 'edit')) {
599
            $game->setActive(true);
600
            $game->setStartDate(null);
601
            $game->setEndDate(null);
602
            $game->setPublicationDate(null);
603
            $game->setBroadcastPlatform(true);
604
605
            // I don't want the game to be updated through any update during the preview mode.
606
            // I mark it as readonly for Doctrine
607
            $this->getServiceManager()
608
                ->get('doctrine.entitymanager.orm_default')
609
                ->getUnitOfWork()
610
                ->markReadOnly($game);
611
            return $game;
612
        }
613
614
        // The game is inactive
615
        if (! $game->getActive()) {
616
            return false;
617
        }
618
619
        // the game has not begun yet
620
        if (! $game->isOpen()) {
621
            return false;
622
        }
623
624
        // the game is finished and closed
625
        if (! $game->isStarted() && $checkIfStarted) {
626
            return false;
627
        }
628
629
        return $game;
630
    }
631
632
    /**
633
     * Return the last entry of the user on this game, if it exists.
634
     * An entry can be associated to :
635
     * - A user account (a real one, linked to PlaygroundUser
636
     * - An anonymous Identifier (based on one value of playerData (generally email))
637
     * - A cookie set on the player device (the less secure)
638
     * If the active param is set, it can check if the entry is active or not.
639
     * If the bonus param is set, it can check if the entry is a bonus or not.
640
     *
641
     * @param unknown $game
642
     * @param string $user
643
     * @param boolean $active
644
     * @param boolean $bonus
645
     * @return boolean
646
     */
647
    public function checkExistingEntry($game, $user = null, $active = null, $bonus = null)
648
    {
649
        $entry = false;
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...
650
        $search = array('game'  => $game);
651
652
        if ($user) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $user of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
653
            $search['user'] = $user;
654
        } elseif ($this->getAnonymousIdentifier()) {
655
            $search['anonymousIdentifier'] = $this->getAnonymousIdentifier();
656
            $search['user'] = null;
657
        } else {
658
            $search['anonymousId'] = $this->getAnonymousId();
659
            $search['user'] = null;
660
        }
661
        
662
        if (! is_null($active)) {
663
            $search['active'] = $active;
664
        }
665
        if (! is_null($bonus)) {
666
            $search['bonus'] = $bonus;
667
        }
668
669
        $entry = $this->getEntryMapper()->findOneBy($search, array('updated_at' => 'desc'));
670
671
        return $entry;
672
    }
673
674
    /*
675
    * This function updates the entry with the player data after checking 
676
    * that the data are compliant with the formUser Game attribute
677
    *
678
    * The $data has to be a json object
679
    */
680
    public function updateEntryPlayerForm($data, $game, $user, $entry, $mandatory = true)
0 ignored issues
show
Unused Code introduced by
The parameter $user 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...
681
    {
682
        $form = $this->createFormFromJson($game->getPlayerForm()->getForm(), 'playerForm');
683
        $form->setData($data);
684
685
        if (!$mandatory) {
686
            $filter = $form->getInputFilter();
687
            foreach ($form->getElements() as $element) {
688
                try {
689
                    $elementInput = $filter->get($element->getName());
690
                    $elementInput->setRequired(false);
0 ignored issues
show
Bug introduced by
The method setRequired does only exist in Zend\InputFilter\InputInterface, but not in Zend\InputFilter\InputFilterInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
691
                    $form->get($element->getName())->setAttribute('required', false);
692
                } catch (\Zend\Form\Exception\InvalidElementException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
693
                }
694
            }
695
        }
696
697
        if ($form->isValid()) {
698
            $dataJson = json_encode($form->getData());
699
700
            if ($game->getAnonymousAllowed() &&
701
                $game->getAnonymousIdentifier() &&
702
                isset($data[$game->getAnonymousIdentifier()])
703
            ) {
704
                $session = new \Zend\Session\Container('anonymous_identifier');
705
                if (empty($session->offsetGet('anonymous_identifier'))) {
706
                    $anonymousIdentifier = $data[$game->getAnonymousIdentifier()];
707
                
708
                    $entry->setAnonymousIdentifier($anonymousIdentifier);
709
                
710
                    // I must transmit this info during the whole game workflow
711
                    $session->offsetSet('anonymous_identifier', $anonymousIdentifier);
712
                }
713
            }
714
715
            $entry->setPlayerData($dataJson);
716
            $this->getEntryMapper()->update($entry);
717
        } else {
718
            return false;
719
        }
720
721
        return true;
722
    }
723
724
725
    public function checkIsFan($game)
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...
726
    {
727
        // If on Facebook, check if you have to be a FB fan to play the game
728
        $session = new Container('facebook');
729
730
        if ($session->offsetExists('signed_request')) {
731
            // I'm on Facebook
732
            $sr = $session->offsetGet('signed_request');
733
            if ($sr['page']['liked'] == 1) {
734
                return true;
735
            }
736
        } else {
737
            // I'm not on Facebook
738
            return true;
739
        }
740
741
        return false;
742
    }
743
    
744
    public function getAnonymousIdentifier()
745
    {
746
        if (is_null($this->anonymousIdentifier)) {
747
            // If on Facebook, check if you have to be a FB fan to play the game
748
            $session = new Container('anonymous_identifier');
749
            
750
            if ($session->offsetExists('anonymous_identifier')) {
751
                $this->anonymousIdentifier = $session->offsetGet('anonymous_identifier');
752
            } else {
753
                $this->anonymousIdentifier = false;
754
            }
755
        }
756
    
757
        return $this->anonymousIdentifier;
758
    }
759
760
    /**
761
     * errors :
762
     * -1 : user not connected
763
     * -2 : limit entry games for this user reached
764
     *
765
     * @param \PlaygroundGame\Entity\Game $game
766
     * @param \PlaygroundUser\Entity\UserInterface $user
767
     * @return number unknown
768
     */
769
    public function play($game, $user)
770
    {
771
772
        // certaines participations peuvent rester ouvertes.
773
        // On autorise alors le joueur à reprendre là ou il en était
774
        // par exemple les postvote...
775
        $entry = $this->checkExistingEntry($game, $user, true);
0 ignored issues
show
Documentation introduced by
$user is of type object<PlaygroundUser\Entity\UserInterface>, but the function expects a string|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
776
777
        if (! $entry) {
778
            if ($this->hasReachedPlayLimit($game, $user)) {
779
                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\Game::play of type integer|double.

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...
780
            }
781
782
            $entry = new Entry();
783
            $entry->setGame($game);
784
            $entry->setUser($user);
785
            $entry->setPoints(0);
786
            $entry->setIp($this->getIp());
787
            $entry->setAnonymousId($this->getAnonymousId());
788
            if ($this->getAnonymousIdentifier()) {
789
                $entry->setAnonymousIdentifier($this->getAnonymousIdentifier());
790
            }
791
792
            $entry = $this->getEntryMapper()->insert($entry);
793
            $this->getEventManager()->trigger(__FUNCTION__ . '.post', $this, array(
794
                'user' => $user,
795
                'game' => $game,
796
                'entry' => $entry
797
            ));
798
        }
799
800
        return $entry;
801
    }
802
803
    /**
804
     * @param \PlaygroundGame\Entity\Game $game
805
     * @param \PlaygroundUser\Entity\UserInterface $user
806
     */
807
    public function hasReachedPlayLimit($game, $user)
808
    {
809
        // Is there a limitation on the game ?
810
        $limitAmount = $game->getPlayLimit();
811
        if ($limitAmount) {
812
            $limitScale = $game->getPlayLimitScale();
813
            $userEntries = $this->findLastEntries($game, $user, $limitScale);
814
815
            // player has reached the game limit
816
            if ($userEntries >= $limitAmount) {
817
                return true;
818
            }
819
        }
820
        return false;
821
    }
822
    
823
    /**
824
     * @param \PlaygroundGame\Entity\Game $game
825
     * @param \PlaygroundUser\Entity\UserInterface $user
826
     */
827
    public function findLastEntries($game, $user, $limitScale)
828
    {
829
        $limitDate = $this->getLimitDate($limitScale);
830
831
        if ($user) {
832
            return $this->getEntryMapper()->findLastEntriesByUser($game, $user, $limitDate);
833
        } elseif ($this->getAnonymousIdentifier()) {
834
            return $this->getEntryMapper()->findLastEntriesByAnonymousIdentifier(
835
                $game,
836
                $this->getAnonymousIdentifier(),
837
                $limitDate
838
            );
839
        } else {
840
            return $this->getEntryMapper()->findLastEntriesByIp($game, $this->getIp(), $limitDate);
841
        }
842
    }
843
844
    /**
845
    *
846
    *
847
    */
848
    public function getLimitDate($limitScale)
849
    {
850
        $now = new \DateTime("now");
851
        switch ($limitScale) {
852
            case 'always':
853
                $interval = 'P100Y';
854
                $now->sub(new \DateInterval($interval));
855
                $dateLimit = $now->format('Y-m-d') . ' 0:0:0';
856
                break;
857
            case 'day':
858
                $dateLimit = $now->format('Y-m-d') . ' 0:0:0';
859
                break;
860
            case 'week':
861
                $interval = 'P7D';
862
                $now->sub(new \DateInterval($interval));
863
                $dateLimit = $now->format('Y-m-d') . ' 0:0:0';
864
                break;
865
            case 'month':
866
                $interval = 'P1M';
867
                $now->sub(new \DateInterval($interval));
868
                $dateLimit = $now->format('Y-m-d') . ' 0:0:0';
869
                break;
870
            case 'year':
871
                $interval = 'P1Y';
872
                $now->sub(new \DateInterval($interval));
873
                $dateLimit = $now->format('Y-m-d') . ' 0:0:0';
874
                break;
875
            default:
876
                $interval = 'P100Y';
877
                $now->sub(new \DateInterval($interval));
878
                $dateLimit = $now->format('Y-m-d') . ' 0:0:0';
879
        }
880
881
        return $dateLimit;
882
    }
883
884
    public function findLastActiveEntry($game, $user)
885
    {
886
        return $this->checkExistingEntry($game, $user, true);
887
    }
888
889
    public function findLastInactiveEntry($game, $user)
890
    {
891
        return $this->checkExistingEntry($game, $user, false, false);
892
    }
893
894
    public function findLastEntry($game, $user)
895
    {
896
        return $this->checkExistingEntry($game, $user, null, false);
897
    }
898
899
    public function sendShareMail(
900
        $data,
901
        $game,
902
        $user,
903
        $entry,
904
        $template = 'share_game',
905
        $topic = null,
906
        $userTimer = array()
907
    ) {
908
    
909
        $mailService = $this->getServiceManager()->get('playgroundgame_message');
910
        $mailSent = false;
911
        $from = $this->getOptions()->getEmailFromAddress();
912
        $subject = $this->getOptions()->getShareSubjectLine();
913
        $renderer = $this->getServiceManager()->get('Zend\View\Renderer\RendererInterface');
914
        if ($user) {
915
            $email = $user->getEmail();
916
        } elseif ($entry->getAnonymousIdentifier()) {
917
            $email = $entry->getAnonymousIdentifier();
918
        } else {
919
            $email = $from;
920
        }
921
        $skinUrl = $renderer->url(
922
            'frontend',
923
            array(),
924
            array('force_canonical' => true)
925
        );
926
        $secretKey = strtoupper(substr(sha1(uniqid('pg_', true) . '####' . time()), 0, 15));
927
928
        if (! $topic) {
929
            $topic = $game->getTitle();
930
        }
931
932
        $shares = json_decode($entry->getSocialShares(), true);
933
        
934
        if ($data['email1']) {
935
            $mailSent = true;
936
            $message = $mailService->createHtmlMessage(
937
                $from,
938
                $data['email1'],
939
                $subject,
940
                'playground-game/email/' . $template,
941
                array(
942
                    'game' => $game,
943
                    'email' => $email,
944
                    'secretKey' => $secretKey,
945
                    'skinUrl' => $skinUrl,
946
                    'userTimer' => $userTimer
947
                )
948
            );
949
            $mailService->send($message);
950
            
951
            if (!isset($shares['mail'])) {
952
                $shares['mail'] = 1;
953
            } else {
954
                $shares['mail'] += 1;
955
            }
956
        }
957
        if ($data['email2'] && $data['email2'] != $data['email1']) {
958
            $mailSent = true;
959
            $message = $mailService->createHtmlMessage(
960
                $from,
961
                $data['email2'],
962
                $subject,
963
                'playground-game/email/' . $template,
964
                array(
965
                    'game' => $game,
966
                    'email' => $email,
967
                    'secretKey' => $secretKey,
968
                    'skinUrl' => $skinUrl,
969
                    'userTimer' => $userTimer
970
                )
971
            );
972
            $mailService->send($message);
973
            
974
            if (!isset($shares['mail'])) {
975
                $shares['mail'] = 1;
976
            } else {
977
                $shares['mail'] += 1;
978
            }
979
        }
980
        if ($data['email3'] && $data['email3'] != $data['email2'] && $data['email3'] != $data['email1']) {
981
            $mailSent = true;
982
            $message = $mailService->createHtmlMessage(
983
                $from,
984
                $data['email3'],
985
                $subject,
986
                'playground-game/email/' . $template,
987
                array(
988
                    'game' => $game,
989
                    'email' => $email,
990
                    'secretKey' => $secretKey,
991
                    'skinUrl' => $skinUrl,
992
                    'userTimer' => $userTimer
993
                )
994
            );
995
            $mailService->send($message);
996
            
997
            if (!isset($shares['mail'])) {
998
                $shares['mail'] = 1;
999
            } else {
1000
                $shares['mail'] += 1;
1001
            }
1002
        }
1003
        if ($data['email4'] &&
1004
            $data['email4'] != $data['email3'] &&
1005
            $data['email4'] != $data['email2'] &&
1006
            $data['email4'] != $data['email1']
1007
        ) {
1008
            $mailSent = true;
1009
            $message = $mailService->createHtmlMessage(
1010
                $from,
1011
                $data['email4'],
1012
                $subject,
1013
                'playground-game/email/' . $template,
1014
                array(
1015
                    'game' => $game,
1016
                    'email' => $email,
1017
                    'secretKey' => $secretKey,
1018
                    'skinUrl' => $skinUrl,
1019
                    'userTimer' => $userTimer
1020
                )
1021
            );
1022
            $mailService->send($message);
1023
        
1024
            if (!isset($shares['mail'])) {
1025
                $shares['mail'] = 1;
1026
            } else {
1027
                $shares['mail'] += 1;
1028
            }
1029
        }
1030
        if ($data['email5'] &&
1031
            $data['email5'] != $data['email4'] &&
1032
            $data['email5'] != $data['email3'] &&
1033
            $data['email5'] != $data['email2'] &&
1034
            $data['email5'] != $data['email1']
1035
        ) {
1036
            $mailSent = true;
1037
            $message = $mailService->createHtmlMessage(
1038
                $from,
1039
                $data['email5'],
1040
                $subject,
1041
                'playground-game/email/' . $template,
1042
                array(
1043
                    'game' => $game,
1044
                    'email' => $email,
1045
                    'secretKey' => $secretKey,
1046
                    'skinUrl' => $skinUrl,
1047
                    'userTimer' => $userTimer
1048
                )
1049
            );
1050
            $mailService->send($message);
1051
        
1052
            if (!isset($shares['mail'])) {
1053
                $shares['mail'] = 1;
1054
            } else {
1055
                $shares['mail'] += 1;
1056
            }
1057
        }
1058
        if ($mailSent) {
1059
            $sharesJson = json_encode($shares);
1060
            $entry->setSocialShares($sharesJson);
1061
            $entry = $this->getEntryMapper()->update($entry);
1062
            
1063
            $this->getEventManager()->trigger(__FUNCTION__ . '.post', $this, array(
1064
                'user' => $user,
1065
                'topic' => $topic,
1066
                'secretKey' => $secretKey,
1067
                'game' => $game,
1068
                'entry' => $entry
1069
            ));
1070
1071
            return true;
1072
        }
1073
1074
        return false;
1075
    }
1076
1077
    /**
1078
     * @param \PlaygroundGame\Entity\Game $game
1079
     * @param \PlaygroundUser\Entity\User $user
1080
     * @param Entry $entry
1081
     * @param \PlaygroundGame\Entity\Prize $prize
1082
     */
1083
    public function sendResultMail($game, $user, $entry, $template = 'entry', $prize = null)
1084
    {
1085
        $mailService = $this->getServiceManager()->get('playgroundgame_message');
1086
        $from = $this->getOptions()->getEmailFromAddress();
1087
        if ($user) {
1088
            $to = $user->getEmail();
1089
        } elseif ($entry->getAnonymousIdentifier()) {
1090
            $to = $entry->getAnonymousIdentifier();
1091
        } else {
1092
            return false;
1093
        }
1094
        $subject = $game->getTitle();
1095
        $renderer = $this->getServiceManager()->get('Zend\View\Renderer\RendererInterface');
1096
        $skinUrl = $renderer->url(
1097
            'frontend',
1098
            array(),
1099
            array('force_canonical' => true)
1100
        );
1101
        $message = $mailService->createHtmlMessage($from, $to, $subject, 'playground-game/email/' . $template, array(
1102
            'game' => $game,
1103
            'entry' => $entry,
1104
            'skinUrl' => $skinUrl,
1105
            'prize' => $prize
1106
        ));
1107
        $mailService->send($message);
1108
    }
1109
1110
    public function sendGameMail($game, $user, $post, $template = 'postvote')
1111
    {
1112
        $mailService = $this->getServiceManager()->get('playgroundgame_message');
1113
        $from = $this->getOptions()->getEmailFromAddress();
1114
        $to = $user->getEmail();
1115
        $subject = $this->getOptions()->getParticipationSubjectLine();
1116
        $renderer = $this->getServiceManager()->get('Zend\View\Renderer\RendererInterface');
1117
        $skinUrl = $renderer->url(
1118
            'frontend',
1119
            array(),
1120
            array('force_canonical' => true)
1121
        );
1122
1123
        $message = $mailService->createHtmlMessage($from, $to, $subject, 'playground-game/email/' . $template, array(
1124
            'game' => $game,
1125
            'post' => $post,
1126
            'skinUrl' => $skinUrl
1127
        ));
1128
        $mailService->send($message);
1129
    }
1130
1131 View Code Duplication
    public function postFbWall($secretKey, $game, $user, $entry)
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...
1132
    {
1133
        $topic = $game->getTitle();
1134
        
1135
        $shares = json_decode($entry->getSocialShares(), true);
1136
        if (!isset($shares['fbwall'])) {
1137
            $shares['fbwall'] = 1;
1138
        } else {
1139
            $shares['fbwall'] += 1;
1140
        }
1141
        $sharesJson = json_encode($shares);
1142
        $entry->setSocialShares($sharesJson);
1143
        $entry = $this->getEntryMapper()->update($entry);
1144
        
1145
        $this->getEventManager()->trigger(__FUNCTION__ . '.post', $this, array(
1146
            'user' => $user,
1147
            'game' => $game,
1148
            'secretKey' => $secretKey,
1149
            'topic' => $topic,
1150
            'entry' => $entry
1151
        ));
1152
1153
        return true;
1154
    }
1155
1156
    public function postFbRequest($secretKey, $game, $user, $entry, $to)
1157
    {
1158
        $shares = json_decode($entry->getSocialShares(), true);
1159
        $to = explode(',', $to);
1160
        if (!isset($shares['fbrequest'])) {
1161
            $shares['fbrequest'] = count($to);
1162
        } else {
1163
            $shares['fbrequest'] += count($to);
1164
        }
1165
        $sharesJson = json_encode($shares);
1166
        $entry->setSocialShares($sharesJson);
1167
        $entry = $this->getEntryMapper()->update($entry);
1168
        
1169
        $this->getEventManager()->trigger(__FUNCTION__ . '.post', $this, array(
1170
            'user' => $user,
1171
            'game' => $game,
1172
            'secretKey' => $secretKey,
1173
            'entry' => $entry,
1174
            'invites' => count($to)
1175
        ));
1176
1177
        return true;
1178
    }
1179
1180 View Code Duplication
    public function postTwitter($secretKey, $game, $user, $entry)
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...
1181
    {
1182
        $topic = $game->getTitle();
1183
1184
        $shares = json_decode($entry->getSocialShares(), true);
1185
        if (!isset($shares['fbrequest'])) {
1186
            $shares['tweet'] = 1;
1187
        } else {
1188
            $shares['tweet'] += 1;
1189
        }
1190
        $sharesJson = json_encode($shares);
1191
        $entry->setSocialShares($sharesJson);
1192
        $entry = $this->getEntryMapper()->update($entry);
1193
        
1194
        $this->getEventManager()->trigger(__FUNCTION__ . '.post', $this, array(
1195
            'user' => $user,
1196
            'game' => $game,
1197
            'secretKey' => $secretKey,
1198
            'topic' => $topic,
1199
            'entry' => $entry
1200
        ));
1201
1202
        return true;
1203
    }
1204
1205 View Code Duplication
    public function postGoogle($secretKey, $game, $user, $entry)
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...
1206
    {
1207
        $topic = $game->getTitle();
1208
        
1209
        $shares = json_decode($entry->getSocialShares(), true);
1210
        if (!isset($shares['fbrequest'])) {
1211
            $shares['google'] = 1;
1212
        } else {
1213
            $shares['google'] += 1;
1214
        }
1215
        $sharesJson = json_encode($shares);
1216
        $entry->setSocialShares($sharesJson);
1217
        $entry = $this->getEntryMapper()->update($entry);
1218
1219
        $this->getEventManager()->trigger(__FUNCTION__ . '.post', $this, array(
1220
            'user' => $user,
1221
            'game' => $game,
1222
            'secretKey' => $secretKey,
1223
            'topic' => $topic,
1224
            'entry' => $entry
1225
        ));
1226
1227
        return true;
1228
    }
1229
1230
    /**
1231
     * Is it possible to trigger a bonus entry ?
1232
     *
1233
     * @param unknown_type $game
1234
     * @param unknown_type $user
1235
     */
1236
    public function allowBonus($game, $user)
1237
    {
1238
        if (! $game->getPlayBonus() || $game->getPlayBonus() == 'none') {
1239
            return false;
1240
        } elseif ($game->getPlayBonus() == 'one') {
1241
            if ($this->getEntryMapper()->findOneBy(array(
1242
                'game' => $game,
1243
                'user' => $user,
1244
                'bonus' => 1
1245
            ))) {
1246
                return false;
1247
            } else {
1248
                return true;
1249
            }
1250
        } elseif ($game->getPlayBonus() == 'per_entry') {
1251
            return $this->getEntryMapper()->checkBonusEntry($game, $user);
1252
        }
1253
1254
        return false;
1255
    }
1256
1257
    public function addAnotherEntry($game, $user, $winner = 0)
1258
    {
1259
        $entry = new Entry();
1260
        $entry->setGame($game);
1261
        $entry->setUser($user);
1262
        $entry->setPoints(0);
1263
        $entry->setIp($this->getIp());
1264
        $entry->setActive(0);
1265
        $entry->setBonus(1);
1266
        $entry->setWinner($winner);
1267
        $entry = $this->getEntryMapper()->insert($entry);
1268
1269
        return $entry;
1270
    }
1271
1272
    /**
1273
     * This bonus entry doesn't give points nor badges
1274
     * It's just there to increase the chances during the Draw
1275
     * Old Name playBonus
1276
     *
1277
     * @param PlaygroundGame\Entity\Game $game
1278
     * @param unknown $user
1279
     * @return boolean unknown
1280
     */
1281
    public function addAnotherChance($game, $user, $winner = 0)
1282
    {
1283
        if ($this->allowBonus($game, $user)) {
1284
            $this->addAnotherEntry($game, $user, $winner);
1285
1286
            return true;
1287
        }
1288
1289
        return false;
1290
    }
1291
1292
    /**
1293
     * This bonus entry doesn't give points nor badges but can play again
1294
     *
1295
     * @param PlaygroundGame\Entity\Game $game
1296
     * @param user $user
1297
     * @return boolean unknown
1298
     */
1299
    public function playAgain($game, $user, $winner = 0)
1300
    {
1301
        if ($this->allowBonus($game, $user)) {
1302
            $entry = $this->addAnotherEntry($game, $user, $winner);
1303
            $entry->setActive(1);
1304
            $entry = $this->getEntryMapper()->update($entry);
1305
            if ($entry->getActive() == 1) {
1306
                return true;
1307
            }
1308
        }
1309
1310
        return false;
1311
    }
1312
1313
    /**
1314
     * @param string $path
1315
     */
1316
    public function uploadFile($path, $file)
1317
    {
1318
        $err = $file["error"];
1319
        $message = '';
1320
        if ($err > 0) {
1321
            switch ($err) {
1322
                case '1':
1323
                    $message .= 'Max file size exceeded. (php.ini)';
1324
                    break;
1325
                case '2':
1326
                    $message .= 'Max file size exceeded.';
1327
                    break;
1328
                case '3':
1329
                    $message .= 'File upload was only partial.';
1330
                    break;
1331
                case '4':
1332
                    $message .= 'No file was attached.';
1333
                    break;
1334
                case '7':
1335
                    $message .= 'File permission denied.';
1336
                    break;
1337
                default:
1338
                    $message .= 'Unexpected error occurs.';
1339
            }
1340
1341
            return $err;
1342
        } else {
1343
            $fileNewname = $this->fileNewname($path, $file['name'], true);
1344
1345
            if (isset($file["base64"])) {
1346
                list(, $img) = explode(',', $file["base64"]);
1347
                $img = str_replace(' ', '+', $img);
1348
                $im = base64_decode($img);
1349
                if ($im !== false) {
1350
                    // getimagesizefromstring
1351
                    file_put_contents($path . $fileNewname, $im);
1352
                } else {
1353
                    return 1;
1354
                }
1355
1356
                return $fileNewname;
1357
            } else {
1358
                $adapter = new \Zend\File\Transfer\Adapter\Http();
1359
                // 1Mo
1360
                $size = new Size(array(
1361
                    'max' => 1024000
1362
                ));
1363
                $is_image = new IsImage('jpeg,png,gif,jpg');
1364
                $adapter->setValidators(array(
1365
                    $size,
1366
                    $is_image
1367
                ), $fileNewname);
1368
1369
                if (! $adapter->isValid()) {
1370
                    return false;
1371
                }
1372
1373
                @move_uploaded_file($file["tmp_name"], $path . $fileNewname);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
1374
            }
1375
1376
            
1377
            if (class_exists("Imagick")) {
1378
                $ext = pathinfo($fileNewname, PATHINFO_EXTENSION);
1379
                $img = new \Imagick($path . $fileNewname);
1380
                $img->cropThumbnailImage(100, 100);
1381
                $img->setImageCompression(\Imagick::COMPRESSION_JPEG);
1382
                $img->setImageCompressionQuality(75);
1383
                // Strip out unneeded meta data
1384
                $img->stripImage();
1385
                $img->writeImage($path . str_replace('.'.$ext, '-thumbnail.'.$ext, $fileNewname));
1386
                ErrorHandler::stop(true);
1387
            }
1388
        }
1389
1390
        return $fileNewname;
1391
    }
1392
1393
    /**
1394
     * @param string $path
1395
     */
1396
    public function fileNewname($path, $filename, $generate = false)
1397
    {
1398
        $sanitize = new Sanitize();
1399
        $name = $sanitize->filter($filename);
1400
        $newpath = $path . $name;
1401
1402
        if ($generate) {
1403
            if (file_exists($newpath)) {
1404
                $filename = pathinfo($name, PATHINFO_FILENAME);
1405
                $ext = pathinfo($name, PATHINFO_EXTENSION);
1406
1407
                $name = $filename . '_' . rand(0, 99) . '.' . $ext;
1408
            }
1409
        }
1410
1411
        unset($sanitize);
1412
1413
        return $name;
1414
    }
1415
1416
    /**
1417
     * This function returns the list of games, order by $type
1418
     */
1419
    public function getQueryGamesOrderBy($type = 'createdAt', $order = 'DESC')
1420
    {
1421
        $em = $this->getServiceManager()->get('doctrine.entitymanager.orm_default');
1422
        $today = new \DateTime("now");
1423
        $today = $today->format('Y-m-d') . ' 23:59:59';
1424
1425
        $onlineGames = '(
1426
            (
1427
                CASE WHEN (
1428
                    g.active = 1
1429
                    AND g.broadcastPlatform = 1
1430
                    AND (g.startDate <= :date OR g.startDate IS NULL)
1431
                    AND (g.closeDate >= :date OR g.closeDate IS NULL)
1432
                ) THEN 1 ELSE 0 END
1433
            ) +
1434
            (
1435
                CASE WHEN (
1436
                    g.active = 0
1437
                    AND (g.broadcastPlatform = 0 OR g.broadcastPlatform IS NULL)
1438
                    AND g.startDate > :date
1439
                    AND g.closeDate < :date
1440
                ) THEN 1 ELSE 0 END
1441
            )
1442
        )';
1443
1444
        $qb = $em->createQueryBuilder();
1445
        $qb->select('g')->from('PlaygroundGame\Entity\Game', 'g');
1446
        
1447
        switch ($type) {
1448
            case 'startDate':
1449
                $qb->orderBy('g.startDate', $order);
1450
                break;
1451
            case 'activeGames':
1452
                $qb->orderBy('g.active', $order);
1453
                break;
1454
            case 'onlineGames':
1455
                $qb->orderBy($onlineGames, $order);
1456
                $qb->setParameter('date', $today);
1457
                break;
1458
            case 'createdAt':
1459
                $qb->orderBy('g.createdAt', $order);
1460
                break;
1461
        }
1462
1463
        $query = $qb->getQuery();
1464
1465
        return $query;
1466
    }
1467
1468
    public function draw($game)
1469
    {
1470
        $total = $game->getWinners();
1471
1472
        // I Have to know what is the User Class used
1473
        $zfcUserOptions = $this->getServiceManager()->get('zfcuser_module_options');
1474
        $userClass = $zfcUserOptions->getUserEntityClass();
1475
1476
        $result = $this->getEntryMapper()->draw($game, $userClass, $total);
1477
1478
        foreach ($result as $e) {
1479
            $e->setWinner(1);
1480
            $e = $this->getEntryMapper()->update($e);
1481
            $this->getEventManager()->trigger('win_lottery.post', $this, array(
1482
                'user' => $e->getUser(),
1483
                'game' => $game,
1484
                'entry' => $e
1485
            ));
1486
        }
1487
1488
        return $result;
1489
    }
1490
1491
    /**
1492
     * getGameMapper
1493
     *
1494
     * @return GameMapperInterface
1495
     */
1496
    public function getGameMapper()
1497
    {
1498
        if (null === $this->gameMapper) {
1499
            $this->gameMapper = $this->getServiceManager()->get('playgroundgame_game_mapper');
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->getServiceManager...roundgame_game_mapper') can also be of type array. However, the property $gameMapper is declared as type object<PlaygroundGame\Mapper\GameInterface>. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

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

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
1500
        }
1501
1502
        return $this->gameMapper;
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->gameMapper; of type object|array adds the type array to the return on line 1502 which is incompatible with the return type documented by PlaygroundGame\Service\Game::getGameMapper of type PlaygroundGame\Mapper\GameInterface.
Loading history...
1503
    }
1504
1505
    /**
1506
     * setGameMapper
1507
     *
1508
     * @param GameMapperInterface $gameMapper
1509
     * @return Game
1510
     */
1511
    public function setGameMapper(GameMapperInterface $gameMapper)
1512
    {
1513
        $this->gameMapper = $gameMapper;
1514
1515
        return $this;
1516
    }
1517
1518
    /**
1519
     * getEntryMapper
1520
     *
1521
     * @return EntryMapperInterface
1522
     */
1523
    public function getEntryMapper()
1524
    {
1525
        if (null === $this->entryMapper) {
1526
            $this->entryMapper = $this->getServiceManager()->get('playgroundgame_entry_mapper');
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->getServiceManager...oundgame_entry_mapper') can also be of type array. However, the property $entryMapper is declared as type object<PlaygroundGame\Se...e\EntryMapperInterface>. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

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

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
1527
        }
1528
1529
        return $this->entryMapper;
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->entryMapper; of type object|array adds the type array to the return on line 1529 which is incompatible with the return type documented by PlaygroundGame\Service\Game::getEntryMapper of type PlaygroundGame\Service\EntryMapperInterface.
Loading history...
1530
    }
1531
1532
    /**
1533
     * setEntryMapper
1534
     *
1535
     * @param EntryMapperInterface $entryMapper
1536
     * @return Game
1537
     */
1538
    public function setEntryMapper($entryMapper)
1539
    {
1540
        $this->entryMapper = $entryMapper;
1541
1542
        return $this;
1543
    }
1544
1545
    public function setOptions(ModuleOptions $options)
1546
    {
1547
        $this->options = $options;
0 ignored issues
show
Documentation Bug introduced by
It seems like $options of type object<PlaygroundGame\Options\ModuleOptions> is incompatible with the declared type object<PlaygroundGame\Se...erviceOptionsInterface> of property $options.

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...
1548
1549
        return $this;
1550
    }
1551
1552
    public function getOptions()
1553
    {
1554
        if (! $this->options instanceof ModuleOptions) {
1555
            $this->setOptions($this->getServiceManager()
0 ignored issues
show
Documentation introduced by
$this->getServiceManager...ndgame_module_options') is of type object|array, but the function expects a object<PlaygroundGame\Options\ModuleOptions>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1556
                ->get('playgroundgame_module_options'));
1557
        }
1558
1559
        return $this->options;
1560
    }
1561
1562
    /**
1563
     * Retrieve service manager instance
1564
     *
1565
     * @return ServiceManager
1566
     */
1567
    public function getServiceManager()
1568
    {
1569
        return $this->serviceManager;
1570
    }
1571
1572
    /**
1573
     * Set service manager instance
1574
     *
1575
     * @param ServiceManager $serviceManager
1576
     * @return Game
1577
     */
1578
    public function setServiceManager(ServiceManager $serviceManager)
1579
    {
1580
        $this->serviceManager = $serviceManager;
1581
1582
        return $this;
1583
    }
1584
1585
    /**
1586
     * @param string $str
1587
     */
1588
    public function getExtension($str)
1589
    {
1590
        $i = strrpos($str, '.');
1591
1592
        $l = strlen($str) - $i;
1593
        $ext = substr($str, $i + 1, $l);
1594
1595
        return $ext;
1596
    }
1597
1598
    /**
1599
     * @param string $extension
1600
     */
1601
    public function getSrc($extension, $temp_path)
1602
    {
1603
        $image_src = '';
1604
        switch ($extension) {
1605
            case 'jpg':
1606
                $image_src = imagecreatefromjpeg($temp_path);
1607
                break;
1608
            case 'jpeg':
1609
                $image_src = imagecreatefromjpeg($temp_path);
1610
                break;
1611
            case 'png':
1612
                $image_src = imagecreatefrompng($temp_path);
1613
                break;
1614
            case 'gif':
1615
                $image_src = imagecreatefromgif($temp_path);
1616
                break;
1617
        }
1618
1619
        return $image_src;
1620
    }
1621
1622
    /**
1623
     * @param string $extension
1624
     * @param string $rep
1625
     * @param integer $mini_width
1626
     * @param integer $mini_height
1627
     */
1628
    public function resize($tmp_file, $extension, $rep, $src, $mini_width, $mini_height)
0 ignored issues
show
Unused Code introduced by
The parameter $extension 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...
1629
    {
1630
        list($src_width, $src_height) = getimagesize($tmp_file);
1631
1632
        $ratio_src = $src_width / $src_height;
1633
        $ratio_mini = $mini_width / $mini_height;
1634
1635
        if ($ratio_src >= $ratio_mini) {
1636
            $new_height_mini = $mini_height;
1637
            $new_width_mini = $src_width / ($src_height / $mini_height);
1638
        } else {
1639
            $new_width_mini = $mini_width;
1640
            $new_height_mini = $src_height / ($src_width / $mini_width);
1641
        }
1642
1643
        $new_image_mini = imagecreatetruecolor($mini_width, $mini_height);
1644
1645
        imagecopyresampled(
1646
            $new_image_mini,
1647
            $src,
1648
            0 - ($new_width_mini - $mini_width) / 2,
1649
            0 - ($new_height_mini - $mini_height) / 2,
1650
            0,
1651
            0,
1652
            $new_width_mini,
1653
            $new_height_mini,
1654
            $src_width,
1655
            $src_height
1656
        );
1657
        imagejpeg($new_image_mini, $rep);
1658
1659
        imagedestroy($new_image_mini);
1660
    }
1661
1662
    public function getGameEntity()
1663
    {
1664
        return new \PlaygroundGame\Entity\Game();
1665
    }
1666
1667
    /**
1668
     * @param string $resource
1669
     * @param string $privilege
1670
     */
1671
    public function isAllowed($resource, $privilege = null)
1672
    {
1673
        $auth = $this->getServiceManager()->get('BjyAuthorize\Service\Authorize');
1674
1675
        return $auth->isAllowed($resource, $privilege);
1676
    }
1677
1678
    public function getIp()
1679
    {
1680
        $ipaddress = '';
0 ignored issues
show
Unused Code introduced by
$ipaddress 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...
1681
        if (isset($_SERVER['HTTP_CLIENT_IP'])) {
1682
            $ipaddress = $_SERVER['HTTP_CLIENT_IP'];
1683
        } elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
1684
            $ipaddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
1685
        } elseif (isset($_SERVER['HTTP_X_FORWARDED'])) {
1686
            $ipaddress = $_SERVER['HTTP_X_FORWARDED'];
1687
        } elseif (isset($_SERVER['HTTP_FORWARDED_FOR'])) {
1688
            $ipaddress = $_SERVER['HTTP_FORWARDED_FOR'];
1689
        } elseif (isset($_SERVER['HTTP_FORWARDED'])) {
1690
            $ipaddress = $_SERVER['HTTP_FORWARDED'];
1691
        } elseif (isset($_SERVER['REMOTE_ADDR'])) {
1692
            $ipaddress = $_SERVER['REMOTE_ADDR'];
1693
        } else {
1694
            $ipaddress = 'UNKNOWN';
1695
        }
1696
1697
        return $ipaddress;
1698
    }
1699
1700
    public function getAnonymousId()
1701
    {
1702
        $anonymousId = '';
1703
        if ($_COOKIE && array_key_exists('pg_anonymous', $_COOKIE)) {
1704
            $anonymousId = $_COOKIE['pg_anonymous'];
1705
        }
1706
1707
        return $anonymousId;
1708
    }
1709
1710
    /**
1711
     *
1712
     *
1713
     * This service is ready for all types of games
1714
     *
1715
     * @param array $data
1716
     * @return \PlaygroundGame\Entity\Game
1717
     */
1718 View Code Duplication
    public function createForm(array $data, $game, $form = null)
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...
1719
    {
1720
        $title = '';
1721
        $description = '';
1722
1723
        if ($data['form_jsonified']) {
1724
            $jsonPV = json_decode($data['form_jsonified']);
1725
            foreach ($jsonPV as $element) {
1726
                if ($element->form_properties) {
1727
                    $attributes = $element->form_properties[0];
1728
                    $title = $attributes->title;
1729
                    $description = $attributes->description;
1730
1731
                    break;
1732
                }
1733
            }
1734
        }
1735
        if (! $form) {
1736
            $form = new \PlaygroundGame\Entity\PlayerForm();
1737
        }
1738
        $form->setGame($game);
1739
        $form->setTitle($title);
1740
        $form->setDescription($description);
1741
        $form->setForm($data['form_jsonified']);
1742
        $form->setFormTemplate($data['form_template']);
1743
1744
        $form = $this->getPlayerFormMapper()->insert($form);
1745
1746
        return $form;
1747
    }
1748
1749
    /**
1750
     *  getCSV creates lines of CSV and returns it.
1751
     */
1752
    public function getCSV($array)
1753
    {
1754
        ob_start(); // buffer the output ...
1755
        $out = fopen('php://output', 'w');
1756
        fputcsv($out, array_keys($array[0]), ";");
1757
        foreach ($array as $line) {
1758
            fputcsv($out, $line, ";");
1759
        }
1760
        fclose($out);
1761
        return ob_get_clean(); // ... then return it as a string!
1762
    }
1763
    
1764
    public function getAttributes($attributes)
1765
    {
1766
        $a = array();
1767
1768
        $a['name']          = isset($attributes->name)? $attributes->name : '';
1769
        $a['placeholder']   = isset($attributes->data->placeholder)? $attributes->data->placeholder : '';
1770
        $a['label']         = isset($attributes->data->label)? $attributes->data->label : '';
1771
        $a['required']      = (isset($attributes->data->required) && $attributes->data->required == 'true')?
1772
            true:
1773
            false;
1774
        $a['class']         = isset($attributes->data->class)? $attributes->data->class : '';
1775
        $a['id']            = isset($attributes->data->id)? $attributes->data->id : '';
1776
        $a['lengthMin']     = isset($attributes->data->length)? $attributes->data->length->min : '';
1777
        $a['lengthMax']     = isset($attributes->data->length)? $attributes->data->length->max : '';
1778
        $a['validator']     = isset($attributes->data->validator)? $attributes->data->validator : '';
1779
        $a['innerData']     = isset($attributes->data->innerData)? $attributes->data->innerData : array();
1780
        $a['dropdownValues']= isset($attributes->data->dropdownValues)?
1781
            $attributes->data->dropdownValues :
1782
            array();
1783
        $a['filesizeMin']   = isset($attributes->data->filesize)? $attributes->data->filesize->min : 0;
1784
        $a['filesizeMax']   = isset($attributes->data->filesize)? $attributes->data->filesize->max : 10*1024*1024;
1785
1786
        return $a;
1787
    }
1788
1789
    public function decorate($element, $attr, $inputFilter)
1790
    {
1791
        $factory = new InputFactory();
1792
        $element->setAttributes(
1793
            array(
1794
                'placeholder'   => $attr['placeholder'],
1795
                'required'      => $attr['required'],
1796
                'class'         => $attr['class'],
1797
                'id'            => $attr['id']
1798
            )
1799
        );
1800
1801
        $options = array();
1802
        $options['encoding'] = 'UTF-8';
1803
        if ($attr['lengthMin'] && $attr['lengthMin'] > 0) {
1804
            $options['min'] = $attr['lengthMin'];
1805
        }
1806
        if ($attr['lengthMax'] && $attr['lengthMax'] > $attr['lengthMin']) {
1807
            $options['max'] = $attr['lengthMax'];
1808
            $element->setAttribute('maxlength', $attr['lengthMax']);
1809
            $options['messages'] = array(
1810
                \Zend\Validator\StringLength::TOO_LONG => sprintf(
1811
                    $this->getServiceLocator()->get('translator')->translate(
0 ignored issues
show
Bug introduced by
The method getServiceLocator() does not seem to exist on object<PlaygroundGame\Service\Game>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
1812
                        'This field contains more than %s characters',
1813
                        'playgroundgame'
1814
                    ),
1815
                    $attr['lengthMax']
1816
                )
1817
            );
1818
        }
1819
1820
        $validators = array(
1821
            array(
1822
                'name'    => 'StringLength',
1823
                'options' => $options,
1824
            ),
1825
        );
1826
        if ($attr['validator']) {
1827
            $regex = "/.*\(([^)]*)\)/";
1828
            preg_match($regex, $attr['validator'], $matches);
1829
            $valArray = array(
1830
                'name' => str_replace(
1831
                    '('.$matches[1].')',
1832
                    '',
1833
                    $attr['validator']
1834
                ),
1835
                'options' => array($matches[1])
1836
            );
1837
            $validators[] = $valArray;
1838
        }
1839
1840
        $inputFilter->add($factory->createInput(array(
1841
            'name'     => $attr['name'],
1842
            'required' => $attr['required'],
1843
            'filters'  => array(
1844
                array('name' => 'StripTags'),
1845
                array('name' => 'StringTrim'),
1846
            ),
1847
            'validators' => $validators,
1848
        )));
1849
1850
        return $element;
1851
    }
1852
    /**
1853
     * Create a ZF2 Form from json data
1854
     * @return Form
1855
     */
1856
    public function createFormFromJson($jsonForm, $id = 'jsonForm')
1857
    {
1858
        $formPV = json_decode($jsonForm);
1859
        
1860
        $form = new Form();
1861
        $form->setAttribute('id', $id);
1862
        $form->setAttribute('enctype', 'multipart/form-data');
1863
        
1864
        $inputFilter = new \Zend\InputFilter\InputFilter();
1865
        $factory = new InputFactory();
1866
        
1867
        foreach ($formPV as $element) {
1868 View Code Duplication
            if (isset($element->line_text)) {
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...
1869
                $attr  = $this->getAttributes($element->line_text[0]);
1870
                $element = new Element\Text($attr['name']);
1871
                $element = $this->decorate($element, $attr, $inputFilter);
1872
                $form->add($element);
1873
            }
1874 View Code Duplication
            if (isset($element->line_password)) {
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...
1875
                $attr = $this->getAttributes($element->line_password[0]);
1876
                $element = new Element\Password($attr['name']);
1877
                $element = $this->decorate($element, $attr, $inputFilter);
1878
                $form->add($element);
1879
            }
1880 View Code Duplication
            if (isset($element->line_hidden)) {
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...
1881
                $attr = $this->getAttributes($element->line_hidden[0]);
1882
                $element = new Element\Hidden($attr['name']);
1883
                $element = $this->decorate($element, $attr, $inputFilter);
1884
                $form->add($element);
1885
            }
1886 View Code Duplication
            if (isset($element->line_email)) {
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...
1887
                $attr = $this->getAttributes($element->line_email[0]);
1888
                $element = new Element\Email($attr['name']);
1889
                $element = $this->decorate($element, $attr, $inputFilter);
1890
                $form->add($element);
1891
            }
1892 View Code Duplication
            if (isset($element->line_radio)) {
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...
1893
                $attr = $this->getAttributes($element->line_radio[0]);
1894
                $element = new Element\Radio($attr['name']);
1895
1896
                $element->setLabel($attr['label']);
1897
                $element->setAttributes(
1898
                    array(
1899
                        'name'      => $attr['name'],
1900
                        'required'  => $attr['required'],
1901
                        'allowEmpty'=> !$attr['required'],
1902
                        'class'     => $attr['class'],
1903
                        'id'        => $attr['id']
1904
                    )
1905
                );
1906
                $values = array();
1907
                foreach ($attr['innerData'] as $value) {
1908
                    $values[] = $value->label;
1909
                }
1910
                $element->setValueOptions($values);
1911
        
1912
                $options = array();
1913
                $options['encoding'] = 'UTF-8';
1914
                $options['disable_inarray_validator'] = true;
1915
        
1916
                $element->setOptions($options);
1917
        
1918
                $form->add($element);
1919
        
1920
                $inputFilter->add($factory->createInput(array(
1921
                    'name'     => $attr['name'],
1922
                    'required' => $attr['required'],
1923
                    'allowEmpty' => !$attr['required'],
1924
                )));
1925
            }
1926 View Code Duplication
            if (isset($element->line_checkbox)) {
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...
1927
                $attr = $this->getAttributes($element->line_checkbox[0]);
1928
                $element = new Element\MultiCheckbox($attr['name']);
1929
        
1930
                $element->setLabel($attr['label']);
1931
                $element->setAttributes(
1932
                    array(
1933
                        'name'      => $attr['name'],
1934
                        'required'  => $attr['required'],
1935
                        'allowEmpty'=> !$attr['required'],
1936
                        'class'     => $attr['class'],
1937
                        'id'        => $attr['id']
1938
                    )
1939
                );
1940
1941
                $values = array();
1942
                foreach ($attr['innerData'] as $value) {
1943
                    $values[] = $value->label;
1944
                }
1945
                $element->setValueOptions($values);
1946
                $form->add($element);
1947
        
1948
                $options = array();
1949
                $options['encoding'] = 'UTF-8';
1950
                $options['disable_inarray_validator'] = true;
1951
        
1952
                $element->setOptions($options);
1953
        
1954
                $inputFilter->add($factory->createInput(array(
1955
                    'name'      => $attr['name'],
1956
                    'required'  => $attr['required'],
1957
                    'allowEmpty'=> !$attr['required'],
1958
                )));
1959
            }
1960 View Code Duplication
            if (isset($element->line_dropdown)) {
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...
1961
                $attr = $this->getAttributes($element->line_dropdown[0]);
1962
                $element = new Element\Select($attr['name']);
1963
1964
                $element->setLabel($attr['label']);
1965
                $element->setAttributes(
1966
                    array(
1967
                        'name'      => $attr['name'],
1968
                        'required'  => $attr['required'],
1969
                        'allowEmpty'=> !$attr['required'],
1970
                        'class'     => $attr['class'],
1971
                        'id'        => $attr['id']
1972
                    )
1973
                );
1974
                $values = array();
1975
                foreach ($attr['dropdownValues'] as $value) {
1976
                    $values[] = $value->dropdown_label;
1977
                }
1978
                $element->setValueOptions($values);
1979
                $form->add($element);
1980
        
1981
                $options = array();
1982
                $options['encoding'] = 'UTF-8';
1983
                $options['disable_inarray_validator'] = true;
1984
        
1985
                $element->setOptions($options);
1986
        
1987
                $inputFilter->add($factory->createInput(array(
1988
                    'name'     => $attr['name'],
1989
                    'required' => $attr['required'],
1990
                    'allowEmpty' => !$attr['required'],
1991
                )));
1992
            }
1993 View Code Duplication
            if (isset($element->line_paragraph)) {
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...
1994
                $attr = $this->getAttributes($element->line_paragraph[0]);
1995
                $element = new Element\Textarea($attr['name']);
1996
                $element = $this->decorate($element, $attr, $inputFilter);
1997
                $form->add($element);
1998
            }
1999
            if (isset($element->line_upload)) {
2000
                $attr = $this->getAttributes($element->line_upload[0]);
2001
                $element = new Element\File($attr['name']);
2002
2003
                $element->setLabel($attr['label']);
2004
                $element->setAttributes(
2005
                    array(
2006
                        'name'      => $attr['name'],
2007
                        'required'  => $attr['required'],
2008
                        'class'     => $attr['class'],
2009
                        'id'        => $attr['id']
2010
                    )
2011
                );
2012
                $form->add($element);
2013
        
2014
                $inputFilter->add($factory->createInput(array(
2015
                    'name'     => $attr['name'],
2016
                    'required' => $attr['required'],
2017
                    'validators' => array(
2018
                        array(
2019
                            'name' => '\Zend\Validator\File\Size',
2020
                            'options' => array('min' => $attr['filesizeMin'], 'max' => $attr['filesizeMax'])
2021
                        ),
2022
                        array(
2023
                            'name' => '\Zend\Validator\File\Extension',
2024
                            'options'  => array(
2025
                                'png,PNG,jpg,JPG,jpeg,JPEG,gif,GIF',
2026
                                'messages' => array(
2027
                                    \Zend\Validator\File\Extension::FALSE_EXTENSION =>'Veuillez télécharger une image'
2028
                                )
2029
                            )
2030
                        ),
2031
                    ),
2032
                )));
2033
            }
2034
        }
2035
        
2036
        $form->setInputFilter($inputFilter);
2037
        
2038
        return $form;
2039
    }
2040
2041
    /**
2042
     * Send mail for winner and/or loser
2043
     * @param \PlaygroundGame\Entity\Game $game
2044
     * @param \PlaygroundUser\Entity\User $user
2045
     * @param \PlaygroundGame\Entity\Entry $lastEntry
2046
     * @param \PlaygroundGame\Entity\Prize $prize
2047
     */
2048
    public function sendMail($game, $user, $lastEntry, $prize = null)
2049
    {
2050 View Code Duplication
        if (($user || ($game->getAnonymousAllowed() && $game->getAnonymousIdentifier())) &&
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...
2051
            $game->getMailWinner() &&
2052
            $lastEntry->getWinner()
2053
        ) {
2054
            $this->sendResultMail($game, $user, $lastEntry, 'winner', $prize);
2055
        }
2056
2057 View Code Duplication
        if (($user || ($game->getAnonymousAllowed() && $game->getAnonymousIdentifier())) &&
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...
2058
            $game->getMailLooser() &&
2059
            !$lastEntry->getWinner()
2060
        ) {
2061
            $this->sendResultMail($game, $user, $lastEntry, 'looser');
2062
        }
2063
    }
2064
2065
    public function getPlayerFormMapper()
2066
    {
2067
        if (null === $this->playerformMapper) {
2068
            $this->playerformMapper = $this->getServiceManager()->get('playgroundgame_playerform_mapper');
2069
        }
2070
2071
        return $this->playerformMapper;
2072
    }
2073
2074
    public function setPlayerFormMapper($playerformMapper)
2075
    {
2076
        $this->playerformMapper = $playerformMapper;
2077
2078
        return $this;
2079
    }
2080
}
2081