Completed
Push — master ( 996b0f...1206fe )
by greg
15:52 queued 12:06
created

Game::getAnonymousIdentifier()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 15
rs 9.4285
cc 3
eloc 8
nc 3
nop 0
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 $invitationMapper;
49
    
50
    protected $anonymousIdentifier = null;
51
52
    /**
53
     *
54
     *
55
     * This service is ready for all types of games
56
     *
57
     * @param array $data
58
     * @param string $formClass
59
     * @return \PlaygroundGame\Entity\Game
60
     */
61
    public function createOrUpdate(array $data, $game, $formClass)
62
    {
63
        $entityManager = $this->getServiceManager()->get('doctrine.entitymanager.orm_default');
64
65
        $form = $this->getServiceManager()->get($formClass);
66
        $form->get('publicationDate')->setOptions(array(
67
            'format' => 'Y-m-d H:i:s'
68
        ));
69
        $form->get('startDate')->setOptions(array(
70
            'format' => 'Y-m-d H:i:s'
71
        ));
72
        $form->get('endDate')->setOptions(array(
73
            'format' => 'Y-m-d H:i:s'
74
        ));
75
        $form->get('closeDate')->setOptions(array(
76
            'format' => 'Y-m-d H:i:s'
77
        ));
78
79
        $form->bind($game);
80
81
        $path = $this->getOptions()->getMediaPath() . '/';
82
        $media_url = $this->getOptions()->getMediaUrl() . '/';
83
84
        $identifierInput = $form->getInputFilter()->get('identifier');
85
        $noObjectExistsValidator = new NoObjectExistsValidator(array(
86
            'object_repository' => $entityManager->getRepository('PlaygroundGame\Entity\Game'),
87
            'fields' => 'identifier',
88
            'messages' => array(
89
                'objectFound' => 'This url already exists !'
90
            )
91
        ));
92
93
        if ($game->getIdentifier() != $data['identifier']) {
94
            $identifierInput->getValidatorChain()->addValidator($noObjectExistsValidator);
95
        }
96
97
        // I must switch from original format to the Y-m-d format because
98
        // this is the only one accepted by new DateTime($value)
99 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...
100
            $tmpDate = \DateTime::createFromFormat('d/m/Y H:i:s', $data['publicationDate']);
101
            $data['publicationDate'] = $tmpDate->format('Y-m-d H:i:s');
102
        }
103 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...
104
            $tmpDate = \DateTime::createFromFormat('d/m/Y H:i:s', $data['startDate']);
105
            $data['startDate'] = $tmpDate->format('Y-m-d H:i:s');
106
        }
107 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...
108
            $tmpDate = \DateTime::createFromFormat('d/m/Y H:i:s', $data['endDate']);
109
            $data['endDate'] = $tmpDate->format('Y-m-d H:i:s');
110
        }
111 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...
112
            $tmpDate = \DateTime::createFromFormat('d/m/Y H:i:s', $data['closeDate']);
113
            $data['closeDate'] = $tmpDate->format('Y-m-d H:i:s');
114
        }
115
116
        // If publicationDate is null, I update it with the startDate if not null neither
117
        if ((! isset($data['publicationDate']) || $data['publicationDate'] == '') &&
118
            (isset($data['startDate']) && $data['startDate'] != '')
119
        ) {
120
            $data['publicationDate'] = $data['startDate'];
121
        }
122
123
        // If the identifier has not been set, I use the title to create one.
124 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...
125
            $data['identifier'] = $data['title'];
126
        }
127
128
        $form->setData($data);
129
130
        // If someone want to claim... It's time to do it ! used for exemple by PlaygroundFacebook Module
131
        $result = $this->getEventManager()->trigger(__FUNCTION__ . '.validate', $this, array(
132
            'game' => $game,
133
            'data' => $data
134
        ));
135
        if (is_array($result) && ! $result[0]) {
136
            $form->get('fbAppId')->setMessages(array(
137
                'Vous devez d\'abord désinstaller l\'appli Facebook'
138
            ));
139
140
            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...
141
        }
142
143
        if (! $form->isValid()) {
144 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...
145
                $tmpDate = \DateTime::createFromFormat('Y-m-d H:i:s', $data['publicationDate']);
146
                $data['publicationDate'] = $tmpDate->format('d/m/Y H:i:s');
147
                $form->setData(array(
148
                    'publicationDate' => $data['publicationDate']
149
                ));
150
            }
151 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...
152
                $tmpDate = \DateTime::createFromFormat('Y-m-d H:i:s', $data['startDate']);
153
                $data['startDate'] = $tmpDate->format('d/m/Y H:i:s');
154
                $form->setData(array(
155
                    'startDate' => $data['startDate']
156
                ));
157
            }
158 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...
159
                $tmpDate = \DateTime::createFromFormat('Y-m-d H:i:s', $data['endDate']);
160
                $data['endDate'] = $tmpDate->format('d/m/Y H:i:s');
161
                $form->setData(array(
162
                    'endDate' => $data['endDate']
163
                ));
164
            }
165 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...
166
                $tmpDate = \DateTime::createFromFormat('Y-m-d H:i:s', $data['closeDate']);
167
                $data['closeDate'] = $tmpDate->format('d/m/Y H:i:s');
168
                $form->setData(array(
169
                    'closeDate' => $data['closeDate']
170
                ));
171
            }
172
            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...
173
        }
174
175
        $game = $form->getData();
176
        $game = $this->getGameMapper()->insert($game);
177
178
        // I wait for the game to be saved to obtain its ID.
179 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...
180
            ErrorHandler::start();
181
            $data['uploadMainImage']['name'] = $this->fileNewname(
182
                $path,
183
                $game->getId() . "-" . $data['uploadMainImage']['name']
184
            );
185
            move_uploaded_file($data['uploadMainImage']['tmp_name'], $path . $data['uploadMainImage']['name']);
186
            $game->setMainImage($media_url . $data['uploadMainImage']['name']);
187
            ErrorHandler::stop(true);
188
        }
189
190 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...
191
            $data['deleteMainImage'] &&
192
            empty($data['uploadMainImage']['tmp_name'])
193
        ) {
194
            ErrorHandler::start();
195
            $image = $game->getMainImage();
196
            $image = str_replace($media_url, '', $image);
197
            unlink($path . $image);
198
            $game->setMainImage(null);
199
            ErrorHandler::stop(true);
200
        }
201
202 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...
203
            ErrorHandler::start();
204
            $data['uploadSecondImage']['name'] = $this->fileNewname(
205
                $path,
206
                $game->getId() . "-" . $data['uploadSecondImage']['name']
207
            );
208
            move_uploaded_file($data['uploadSecondImage']['tmp_name'], $path . $data['uploadSecondImage']['name']);
209
            $game->setSecondImage($media_url . $data['uploadSecondImage']['name']);
210
            ErrorHandler::stop(true);
211
        }
212
213 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...
214
            $data['deleteSecondImage'] &&
215
            empty($data['uploadSecondImage']['tmp_name'])
216
        ) {
217
            ErrorHandler::start();
218
            $image = $game->getSecondImage();
219
            $image = str_replace($media_url, '', $image);
220
            unlink($path . $image);
221
            $game->setSecondImage(null);
222
            ErrorHandler::stop(true);
223
        }
224
225
        if (! empty($data['uploadStylesheet']['tmp_name'])) {
226
            ErrorHandler::start();
227
            move_uploaded_file($data['uploadStylesheet']['tmp_name'], $path . 'stylesheet_' . $game->getId() . '.css');
228
            $game->setStylesheet($media_url . 'stylesheet_' . $game->getId() . '.css');
229
            ErrorHandler::stop(true);
230
        }
231
232 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...
233
            ErrorHandler::start();
234
            $data['uploadFbShareImage']['name'] = $this->fileNewname(
235
                $path,
236
                $game->getId() . "-" . $data['uploadFbShareImage']['name']
237
            );
238
            move_uploaded_file($data['uploadFbShareImage']['tmp_name'], $path . $data['uploadFbShareImage']['name']);
239
            $game->setFbShareImage($media_url . $data['uploadFbShareImage']['name']);
240
            ErrorHandler::stop(true);
241
        }
242
243 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...
244
            $data['deleteFbShareImage'] &&
245
            empty($data['uploadFbShareImage']['tmp_name'])
246
        ) {
247
            ErrorHandler::start();
248
            $image = $game->getFbShareImage();
249
            $image = str_replace($media_url, '', $image);
250
            unlink($path . $image);
251
            $game->setFbShareImage(null);
252
            ErrorHandler::stop(true);
253
        }
254
255
        if (! empty($data['uploadFbPageTabImage']['tmp_name'])) {
256
            ErrorHandler::start();
257
            $extension = $this->getExtension(strtolower($data['uploadFbPageTabImage']['name']));
258
            $src = $this->getSrc($extension, $data['uploadFbPageTabImage']['tmp_name']);
259
            $this->resize(
260
                $data['uploadFbPageTabImage']['tmp_name'],
261
                $extension,
262
                $path . $game->getId() . "-" . $data['uploadFbPageTabImage']['name'],
263
                $src,
264
                111,
265
                74
266
            );
267
268
            $game->setFbPageTabImage($media_url . $game->getId() . "-" . $data['uploadFbPageTabImage']['name']);
269
            ErrorHandler::stop(true);
270
        }
271
272 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...
273
            $data['deleteFbPageTabImage'] &&
274
            empty($data['uploadFbPageTabImage']['tmp_name'])
275
        ) {
276
            ErrorHandler::start();
277
            $image = $game->getFbPageTabImage();
278
            $image = str_replace($media_url, '', $image);
279
            unlink($path . $image);
280
            $game->setFbPageTabImage(null);
281
            ErrorHandler::stop(true);
282
        }
283
284
        $game = $this->getGameMapper()->update($game);
285
286
        $prize_mapper = $this->getServiceManager()->get('playgroundgame_prize_mapper');
287
        if (isset($data['prizes'])) {
288
            foreach ($data['prizes'] as $prize_data) {
289
                if (! empty($prize_data['picture_file']['tmp_name']) && ! $prize_data['picture_file']['error']) {
290
                    if ($prize_data['id']) {
291
                        $prize = $prize_mapper->findById($prize_data['id']);
292
                    } else {
293
                        $some_prizes = $prize_mapper->findBy(array(
294
                            'game' => $game,
295
                            'title' => $prize_data['title']
296
                        ));
297
                        if (count($some_prizes) == 1) {
298
                            $prize = $some_prizes[0];
299
                        } else {
300
                            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...
301
                        }
302
                    }
303
                    // Remove if existing image
304
                    if ($prize->getPicture() && file_exists($prize->getPicture())) {
305
                        unlink($prize->getPicture());
306
                        $prize->getPicture(null);
307
                    }
308
                    // Upload and set new
309
                    ErrorHandler::start();
310
                    $filename = "game-" . $game->getId() . "-prize-";
311
                    $filename .= $prize->getId() . "-" . $prize_data['picture_file']['name'];
312
                    move_uploaded_file($prize_data['picture_file']['tmp_name'], $path . $filename);
313
                    $prize->setPicture($media_url . $filename);
314
                    ErrorHandler::stop(true);
315
                    $prize_mapper->update($prize);
316
                }
317
            }
318
        }
319
        // If I receive false, it means that the FB Id was not available anymore
320
        $this->getEventManager()->trigger(__FUNCTION__ . '.post', $this, array(
321
            'game' => $game
322
        ));
323
324
        return $game;
325
    }
326
    
327
    /**
328
     * getActiveGames
329
     *
330
     * @return Array of PlaygroundGame\Entity\Game
331
     */
332
    public function getActiveGames($displayHome = true, $classType = '', $order = '')
333
    {
334
        $em = $this->getServiceManager()->get('doctrine.entitymanager.orm_default');
335
        $today = new \DateTime("now");
336
        $today = $today->format('Y-m-d H:i:s');
337
        $orderBy = 'g.publicationDate';
338
        if ($order != '') {
339
            $orderBy = 'g.'.$order;
340
        }
341
342
        $qb = $em->createQueryBuilder();
343
        $and = $qb->expr()->andx();
344
        $and->add(
345
            $qb->expr()->orX(
346
                $qb->expr()->lte('g.publicationDate', ':date'),
347
                $qb->expr()->isNull('g.publicationDate')
348
            )
349
        );
350
        $and->add(
351
            $qb->expr()->orX(
352
                $qb->expr()->gte('g.closeDate', ':date'),
353
                $qb->expr()->isNull('g.closeDate')
354
            )
355
        );
356
        $qb->setParameter('date', $today);
357
        
358
        $and->add($qb->expr()->eq('g.active', '1'));
359
        $and->add($qb->expr()->eq('g.broadcastPlatform', '1'));
360
        
361
        if ($classType != '') {
362
            $and->add($qb->expr()->eq('g.classType', ':classType'));
363
            $qb->setParameter('classType', $classType);
364
        }
365
        
366
        if ($displayHome) {
367
            $and->add($qb->expr()->eq('g.displayHome', true));
368
        }
369
        
370
        $qb->select('g')
371
        ->from('PlaygroundGame\Entity\Game', 'g')
372
        ->where($and)
373
        ->orderBy($orderBy, 'DESC');
374
        
375
        $query = $qb->getQuery();
376
        $games = $query->getResult();
377
        
378
        // je les classe par date de publication (date comme clé dans le tableau afin de pouvoir merger les objets
379
        // de type article avec le même procédé en les classant naturellement par date asc ou desc
380
        $arrayGames = array();
381 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...
382
            if ($game->getPublicationDate()) {
383
                $key = $game->getPublicationDate()->format('Ymd');
384
            } elseif ($game->getStartDate()) {
385
                $key = $game->getStartDate()->format('Ymd');
386
            } else {
387
                $key = $game->getUpdatedAt()->format('Ymd');
388
            }
389
            $key .= $game->getUpdatedAt()->format('Ymd') . '-' . $game->getId();
390
            $arrayGames[$key] = $game;
391
        }
392
393
        return $arrayGames;
394
    }
395
396
    /**
397
     * getAvailableGames : Games OnLine and not already played by $user
398
     *
399
     * @return Array of PlaygroundGame\Entity\Game
400
     */
401
    public function getAvailableGames($user, $maxResults = 2)
402
    {
403
        $em = $this->getServiceManager()->get('doctrine.entitymanager.orm_default');
404
        $today = new \DateTime("now");
405
        $today = $today->format('Y-m-d H:i:s');
406
407
        // Game active with a start_date before today (or without start_date)
408
        // and end_date after today (or without end-date)
409
        $query = $em->createQuery('SELECT g FROM PlaygroundGame\Entity\Game g
410
                WHERE NOT EXISTS (SELECT l FROM PlaygroundGame\Entity\Entry l WHERE l.game = g AND l.user = :user)
411
                AND (g.startDate <= :date OR g.startDate IS NULL)
412
                AND (g.endDate >= :date OR g.endDate IS NULL)
413
                AND g.active = 1 AND g.broadcastPlatform = 1
414
                ORDER BY g.startDate ASC');
415
        $query->setParameter('date', $today);
416
        $query->setParameter('user', $user);
417
        $query->setMaxResults($maxResults);
418
        $games = $query->getResult();
419
420
        return $games;
421
    }
422
423 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...
424
    {
425
        $em = $this->getServiceManager()->get('doctrine.entitymanager.orm_default');
426
427
        $qb = $em->createQueryBuilder();
428
        $qb->select('
429
            e.id,
430
            u.username,
431
            u.title,
432
            u.firstname,
433
            u.lastname,
434
            u.email,
435
            u.optin,
436
            u.optinPartner,
437
            u.address,
438
            u.address2,
439
            u.postalCode,
440
            u.city,
441
            u.telephone,
442
            u.mobile,
443
            u.created_at,
444
            u.dob,
445
            e.winner,
446
            e.socialShares,
447
            e.playerData,
448
            e.updated_at
449
            ')
450
            ->from('PlaygroundGame\Entity\Entry', 'e')
451
            ->leftJoin('e.user', 'u')
452
            ->where($qb->expr()->eq('e.game', ':game'));
453
        
454
        $qb->setParameter('game', $game);
455
456
        return $qb->getQuery();
457
    }
458
459
    public function getEntriesHeader($game)
460
    {
461
        if ($game->getPlayerForm()) {
462
            $formPV = json_decode($game->getPlayerForm()->getForm(), true);
463
            $header = array('id'=> 1);
464 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...
465
                foreach ($element as $k => $v) {
466
                    if ($k !== 'form_properties') {
467
                        $header[$v[0]['name']] = 1;
468
                    }
469
                }
470
            }
471
        } else {
472
            $header = array(
473
                'id' => 1,
474
                'username' => 1,
475
                'title' => 1,
476
                'firstname' => 1,
477
                'lastname' => 1,
478
                'email' => 1,
479
                'optin' => 1,
480
                'optinPartner' => 1,
481
                'address' => 1,
482
                'address2' => 1,
483
                'postalCode' => 1,
484
                'city' => 1,
485
                'telephone' => 1,
486
                'mobile' => 1,
487
                'created_at' => 1,
488
                'dob' => 1,
489
                'winner' => 1
490
            );
491
        }
492
        $header['winner'] = 1;
493
        $header['socialShares'] = 1;
494
        $header['updated_at'] = 1;
495
496
        return $header;
497
    }
498
499
    /**
500
    * getGameEntries : I create an array of entries based on playerData + header
501
    *
502
    * @return Array of PlaygroundGame\Entity\Game
503
    */
504
    public function getGameEntries($header, $entries, $game)
505
    {
506
        $header = $this->getEntriesHeader($game);
507
508
        $results = array();
509
510
        foreach ($entries as $k => $entry) {
511
            $entryData = json_decode($entry['playerData'], true);
512 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...
513
                if (isset($entryData[$key])) {
514
                    $results[$k][$key] = (is_array($entryData[$key]))?implode(', ', $entryData[$key]):$entryData[$key];
515
                } elseif (array_key_exists($key, $entry)) {
516
                    $results[$k][$key] = ($entry[$key] instanceof \DateTime)?
517
                        $entry[$key]->format('Y-m-d H:i:s'):
518
                        $entry[$key];
519
                } else {
520
                    $results[$k][$key] = '';
521
                }
522
            }
523
        }
524
525
        return $results;
526
    }
527
528
    /**
529
     * getActiveSliderGames
530
     *
531
     * @return Array of PlaygroundGame\Entity\Game
532
     */
533
    public function getActiveSliderGames()
534
    {
535
        $em = $this->getServiceManager()->get('doctrine.entitymanager.orm_default');
536
        $today = new \DateTime("now");
537
        $today = $today->format('Y-m-d H:i:s');
538
539
        // Game active with a start_date before today (or without start_date)
540
        // and end_date after today (or without end-date)
541
        $query = $em->createQuery('SELECT g FROM PlaygroundGame\Entity\Game g
542
            WHERE (g.publicationDate <= :date OR g.publicationDate IS NULL)
543
            AND (g.closeDate >= :date OR g.closeDate IS NULL)
544
            AND g.active = true AND g.broadcastPlatform = 1 AND g.pushHome = true');
545
        $query->setParameter('date', $today);
546
        $games = $query->getResult();
547
548
        // je les classe par date de publication (date comme clé dans le tableau afin de pouvoir merger les objets
549
        // de type article avec le même procédé en les classant naturellement par date asc ou desc
550
        $arrayGames = array();
551 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...
552
            if ($game->getPublicationDate()) {
553
                $key = $game->getPublicationDate()->format('Ymd');
554
            } elseif ($game->getStartDate()) {
555
                $key = $game->getStartDate()->format('Ymd');
556
            } else {
557
                $key = $game->getUpdatedAt()->format('Ymd');
558
            }
559
            $key .= $game->getUpdatedAt()->format('Ymd') . '-' . $game->getId();
560
            $arrayGames[$key] = $game;
561
        }
562
563
        return $arrayGames;
564
    }
565
566
    /**
567
     * getPrizeCategoryGames
568
     *
569
     * @return Array of PlaygroundGame\Entity\Game
570
     */
571 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...
572
    {
573
        $em = $this->getServiceManager()->get('doctrine.entitymanager.orm_default');
574
575
        $query = $em->createQuery('SELECT g FROM PlaygroundGame\Entity\Game g
576
            WHERE (g.prizeCategory = :categoryid AND g.broadcastPlatform = 1)
577
            ORDER BY g.publicationDate DESC');
578
        $query->setParameter('categoryid', $categoryid);
579
        $games = $query->getResult();
580
581
        return $games;
582
    }
583
584
    public function checkGame($identifier, $checkIfStarted = true)
585
    {
586
        $gameMapper = $this->getGameMapper();
587
588
        if (! $identifier) {
589
            return false;
590
        }
591
592
        $game = $gameMapper->findByIdentifier($identifier);
593
594
        // the game has not been found
595
        if (! $game) {
596
            return false;
597
        }
598
599
        // for preview stuff as admin
600
        if ($this->isAllowed('game', 'edit')) {
601
            $r =$this->getServiceManager()->get('request');
602
            if ($r->getQuery()->get('preview')) {
603
                $game->setActive(true);
604
                $game->setStartDate(null);
605
                $game->setEndDate(null);
606
                $game->setPublicationDate(null);
607
                $game->setBroadcastPlatform(true);
608
609
                // I don't want the game to be updated through any update during the preview mode.
610
                // I mark it as readonly for Doctrine
611
                $this->getServiceManager()
612
                    ->get('doctrine.entitymanager.orm_default')
613
                    ->getUnitOfWork()
614
                    ->markReadOnly($game);
615
                    
616
                return $game;
617
            }
618
        }
619
620
        // The game is inactive
621
        if (! $game->getActive()) {
622
            return false;
623
        }
624
625
        // the game has not begun yet
626
        if (! $game->isOpen()) {
627
            return false;
628
        }
629
630
        // the game is finished and closed
631
        if (! $game->isStarted() && $checkIfStarted) {
632
            return false;
633
        }
634
635
        return $game;
636
    }
637
638
    /**
639
     * Return the last entry of the user on this game, if it exists.
640
     * An entry can be associated to :
641
     * - A user account (a real one, linked to PlaygroundUser
642
     * - An anonymous Identifier (based on one value of playerData (generally email))
643
     * - A cookie set on the player device (the less secure)
644
     * If the active param is set, it can check if the entry is active or not.
645
     * If the bonus param is set, it can check if the entry is a bonus or not.
646
     *
647
     * @param unknown $game
648
     * @param string $user
649
     * @param boolean $active
650
     * @param boolean $bonus
651
     * @return boolean
652
     */
653
    public function checkExistingEntry($game, $user = null, $active = null, $bonus = null)
654
    {
655
        $search = array('game'  => $game);
656
657
        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...
658
            $search['user'] = $user;
659
        } elseif ($this->getAnonymousIdentifier()) {
660
            $search['anonymousIdentifier'] = $this->getAnonymousIdentifier();
661
            $search['user'] = null;
662
        } else {
663
            $search['anonymousId'] = $this->getAnonymousId();
664
            $search['user'] = null;
665
        }
666
        
667
        if (! is_null($active)) {
668
            $search['active'] = $active;
669
        }
670
        if (! is_null($bonus)) {
671
            $search['bonus'] = $bonus;
672
        }
673
674
        $entry = $this->getEntryMapper()->findOneBy($search, array('updated_at' => 'desc'));
675
676
        return $entry;
677
    }
678
679
    /*
680
    * This function updates the entry with the player data after checking 
681
    * that the data are compliant with the formUser Game attribute
682
    *
683
    * The $data has to be a json object
684
    */
685
    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...
686
    {
687
        $form = $this->createFormFromJson($game->getPlayerForm()->getForm(), 'playerForm');
688
        $form->setData($data);
689
690
        if (!$mandatory) {
691
            $filter = $form->getInputFilter();
692
            foreach ($form->getElements() as $element) {
693
                try {
694
                    $elementInput = $filter->get($element->getName());
695
                    $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...
696
                    $form->get($element->getName())->setAttribute('required', false);
697
                } 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...
698
                }
699
            }
700
        }
701
702
        if ($form->isValid()) {
703
            $dataJson = json_encode($form->getData());
704
705
            if ($game->getAnonymousAllowed() &&
706
                $game->getAnonymousIdentifier() &&
707
                isset($data[$game->getAnonymousIdentifier()])
708
            ) {
709
                $session = new \Zend\Session\Container('anonymous_identifier');
710
                if (empty($session->offsetGet('anonymous_identifier'))) {
711
                    $anonymousIdentifier = $data[$game->getAnonymousIdentifier()];
712
                
713
                    $entry->setAnonymousIdentifier($anonymousIdentifier);
714
                
715
                    // I must transmit this info during the whole game workflow
716
                    $session->offsetSet('anonymous_identifier', $anonymousIdentifier);
717
                }
718
            }
719
720
            $entry->setPlayerData($dataJson);
721
            $this->getEntryMapper()->update($entry);
722
        } else {
723
            return false;
724
        }
725
726
        return true;
727
    }
728
729
730
    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...
731
    {
732
        // If on Facebook, check if you have to be a FB fan to play the game
733
        $session = new Container('facebook');
734
735
        if ($session->offsetExists('signed_request')) {
736
            // I'm on Facebook
737
            $sr = $session->offsetGet('signed_request');
738
            if ($sr['page']['liked'] == 1) {
739
                return true;
740
            }
741
        } else {
742
            // I'm not on Facebook
743
            return true;
744
        }
745
746
        return false;
747
    }
748
    
749
    public function getAnonymousIdentifier()
750
    {
751
        if (is_null($this->anonymousIdentifier)) {
752
            // If on Facebook, check if you have to be a FB fan to play the game
753
            $session = new Container('anonymous_identifier');
754
            
755
            if ($session->offsetExists('anonymous_identifier')) {
756
                $this->anonymousIdentifier = $session->offsetGet('anonymous_identifier');
757
            } else {
758
                $this->anonymousIdentifier = false;
759
            }
760
        }
761
    
762
        return $this->anonymousIdentifier;
763
    }
764
765
    /**
766
     * errors :
767
     * -1 : user not connected
768
     * -2 : limit entry games for this user reached
769
     *
770
     * @param \PlaygroundGame\Entity\Game $game
771
     * @param \PlaygroundUser\Entity\UserInterface $user
772
     * @return number unknown
773
     */
774
    public function play($game, $user)
775
    {
776
777
        // certaines participations peuvent rester ouvertes.
778
        // On autorise alors le joueur à reprendre là ou il en était
779
        // par exemple les postvote...
780
        $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...
781
782
        if (! $entry) {
783
            if ($this->hasReachedPlayLimit($game, $user)) {
784
                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...
785
            }
786
787
            $entry = new Entry();
788
            $entry->setGame($game);
789
            $entry->setUser($user);
790
            $entry->setPoints(0);
791
            $entry->setIp($this->getIp());
792
            $entry->setAnonymousId($this->getAnonymousId());
793
            if ($this->getAnonymousIdentifier()) {
794
                $entry->setAnonymousIdentifier($this->getAnonymousIdentifier());
795
            }
796
797
            $entry = $this->getEntryMapper()->insert($entry);
798
            $this->getEventManager()->trigger(__FUNCTION__ . '.post', $this, array(
799
                'user' => $user,
800
                'game' => $game,
801
                'entry' => $entry
802
            ));
803
        }
804
805
        return $entry;
806
    }
807
808
    /**
809
     * @param \PlaygroundGame\Entity\Game $game
810
     * @param \PlaygroundUser\Entity\UserInterface $user
811
     */
812
    public function hasReachedPlayLimit($game, $user)
813
    {
814
        // Is there a limitation on the game ?
815
        $limitAmount = $game->getPlayLimit();
816
        if ($limitAmount) {
817
            $limitScale = $game->getPlayLimitScale();
818
            $userEntries = $this->findLastEntries($game, $user, $limitScale);
819
820
            // player has reached the game limit
821
            if ($userEntries >= $limitAmount) {
822
                return true;
823
            }
824
        }
825
        return false;
826
    }
827
    
828
    /**
829
     * @param \PlaygroundGame\Entity\Game $game
830
     * @param \PlaygroundUser\Entity\UserInterface $user
831
     */
832
    public function findLastEntries($game, $user, $limitScale)
833
    {
834
        $limitDate = $this->getLimitDate($limitScale);
835
836
        if ($user) {
837
            return $this->getEntryMapper()->findLastEntriesByUser($game, $user, $limitDate);
838
        } elseif ($this->getAnonymousIdentifier()) {
839
            return $this->getEntryMapper()->findLastEntriesByAnonymousIdentifier(
840
                $game,
841
                $this->getAnonymousIdentifier(),
842
                $limitDate
843
            );
844
        } else {
845
            return $this->getEntryMapper()->findLastEntriesByIp($game, $this->getIp(), $limitDate);
846
        }
847
    }
848
849
    /**
850
    *
851
    *
852
    */
853
    public function getLimitDate($limitScale)
854
    {
855
        $now = new \DateTime("now");
856
        switch ($limitScale) {
857
            case 'always':
858
                $interval = 'P100Y';
859
                $now->sub(new \DateInterval($interval));
860
                $dateLimit = $now->format('Y-m-d H:i:s');
861
                break;
862
            case 'day':
863
                $dateLimit = $now->format('Y-m-d H:i:s');
864
                break;
865 View Code Duplication
            case 'week':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
866
                $interval = 'P7D';
867
                $now->sub(new \DateInterval($interval));
868
                $dateLimit = $now->format('Y-m-d H:i:s');
869
                break;
870 View Code Duplication
            case 'month':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
871
                $interval = 'P1M';
872
                $now->sub(new \DateInterval($interval));
873
                $dateLimit = $now->format('Y-m-d H:i:s');
874
                break;
875 View Code Duplication
            case 'year':
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...
876
                $interval = 'P1Y';
877
                $now->sub(new \DateInterval($interval));
878
                $dateLimit = $now->format('Y-m-d H:i:s');
879
                break;
880
            default:
881
                $interval = 'P100Y';
882
                $now->sub(new \DateInterval($interval));
883
                $dateLimit = $now->format('Y-m-d H:i:s');
884
        }
885
886
        return $dateLimit;
887
    }
888
889
    public function findLastActiveEntry($game, $user)
890
    {
891
        return $this->checkExistingEntry($game, $user, true);
892
    }
893
894
    public function findLastInactiveEntry($game, $user)
895
    {
896
        return $this->checkExistingEntry($game, $user, false, false);
897
    }
898
899
    public function findLastEntry($game, $user)
900
    {
901
        return $this->checkExistingEntry($game, $user, null, false);
902
    }
903
904
    public function sendShareMail(
905
        $data,
906
        $game,
907
        $user,
908
        $entry,
909
        $template = 'share_game',
910
        $topic = null,
911
        $userTimer = array(),
912
        $subject = ''
913
    ) {
914
        $mailService = $this->getServiceManager()->get('playgroundgame_message');
915
        $mailSent = false;
916
        $from = $this->getOptions()->getEmailFromAddress();
917
918
        if(empty($subject)){ 
919
            $subject = $this->getServiceManager()->get('translator')->translate(
920
                $this->getOptions()->getShareSubjectLine(),
921
                'playgroundgame'
922
            );
923
        } else {
924
            $subject = $this->getServiceManager()->get('translator')->translate(
925
                $subject,
926
                'playgroundgame'
927
            );
928
        }
929
930
        $renderer = $this->getServiceManager()->get('Zend\View\Renderer\RendererInterface');
931
        $skinUrl = $renderer->url(
932
            'frontend',
933
            array(),
934
            array('force_canonical' => true)
935
        );
936
        $secretKey = strtoupper(substr(sha1(uniqid('pg_', true) . '####' . time()), 0, 15));
937
938
        if (! $topic) {
939
            $topic = $game->getTitle();
940
        }
941
942
        if(isset($data['email']) && !is_array($data['email'])) $data['email'] = array($data['email']);
943
        
944
        foreach ($data['email'] as $to) {
945
            $mailSent = true;
946
            if (!empty($to)) {
947
                $message = $mailService->createHtmlMessage(
948
                    $from,
949
                    $to,
950
                    $subject,
951
                    'playground-game/email/' . $template,
952
                    array(
953
                        'game' => $game,
954
                        'data' => $data,
955
                        'from' => $from,
956
                        'to' => $to,
957
                        'secretKey' => $secretKey,
958
                        'skinUrl' => $skinUrl,
959
                        'userTimer' => $userTimer
960
                    )
961
                );
962
                try {
963
                    $mailService->send($message);
964
                } catch (\Zend\Mail\Protocol\Exception\RuntimeException $e) {
965
                    //$mailSent = false;
966
                }
967
                
968
                if ($entry) {
969
                    $shares = json_decode($entry->getSocialShares(), true);
970
                    (!isset($shares['mail']))? $shares['mail'] = 1:$shares['mail'] += 1;
971
                }
972
            }
973
        }
974
975
        if ($mailSent) {
976
            if ($entry) {
977
                $sharesJson = json_encode($shares);
0 ignored issues
show
Bug introduced by
The variable $shares does not seem to be defined for all execution paths leading up to this point.

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

Let’s take a look at an example:

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

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

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

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

Available Fixes

  1. Check for existence of the variable explicitly:

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

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

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
978
                $entry->setSocialShares($sharesJson);
979
                $entry = $this->getEntryMapper()->update($entry);
980
            }
981
            
982
            $this->getEventManager()->trigger(__FUNCTION__ . '.post', $this, array(
983
                'user' => $user,
984
                'topic' => $topic,
985
                'secretKey' => $secretKey,
986
                'data' => $data,
987
                'game' => $game,
988
                'entry' => $entry
989
            ));
990
991
            return true;
992
        }
993
994
        return false;
995
    }
996
997
    /**
998
     * @param \PlaygroundGame\Entity\Game $game
999
     * @param \PlaygroundUser\Entity\User $user
1000
     * @param Entry $entry
1001
     * @param \PlaygroundGame\Entity\Prize $prize
1002
     */
1003
    public function sendResultMail($game, $user, $entry, $template = 'entry', $prize = null)
1004
    {
1005
        $mailService = $this->getServiceManager()->get('playgroundgame_message');
1006
        $from = $this->getOptions()->getEmailFromAddress();
1007
        if ($user) {
1008
            $to = $user->getEmail();
1009
        } elseif ($entry->getAnonymousIdentifier()) {
1010
            $to = $entry->getAnonymousIdentifier();
1011
        } else {
1012
            return false;
1013
        }
1014
        $subject = $game->getTitle();
1015
        $renderer = $this->getServiceManager()->get('Zend\View\Renderer\RendererInterface');
1016
        $skinUrl = $renderer->url(
1017
            'frontend',
1018
            array(),
1019
            array('force_canonical' => true)
1020
        );
1021
        $message = $mailService->createHtmlMessage($from, $to, $subject, 'playground-game/email/' . $template, array(
1022
            'game' => $game,
1023
            'entry' => $entry,
1024
            'skinUrl' => $skinUrl,
1025
            'prize' => $prize
1026
        ));
1027
        $mailService->send($message);
1028
    }
1029
1030
    public function sendGameMail($game, $user, $post, $template = 'postvote')
1031
    {
1032
        $mailService = $this->getServiceManager()->get('playgroundgame_message');
1033
        $from = $this->getOptions()->getEmailFromAddress();
1034
        $to = $user->getEmail();
1035
        $subject = $this->getServiceManager()->get('translator')->translate(
1036
            $this->getOptions()->getParticipationSubjectLine(), 'playgroundgame'
1037
        );
1038
        $renderer = $this->getServiceManager()->get('Zend\View\Renderer\RendererInterface');
1039
        $skinUrl = $renderer->url(
1040
            'frontend',
1041
            array(),
1042
            array('force_canonical' => true)
1043
        );
1044
1045
        $message = $mailService->createHtmlMessage($from, $to, $subject, 'playground-game/email/' . $template, array(
1046
            'game' => $game,
1047
            'post' => $post,
1048
            'skinUrl' => $skinUrl
1049
        ));
1050
        $mailService->send($message);
1051
    }
1052
1053 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...
1054
    {
1055
        $topic = $game->getTitle();
1056
        
1057
        $shares = json_decode($entry->getSocialShares(), true);
1058
        if (!isset($shares['fbwall'])) {
1059
            $shares['fbwall'] = 1;
1060
        } else {
1061
            $shares['fbwall'] += 1;
1062
        }
1063
        $sharesJson = json_encode($shares);
1064
        $entry->setSocialShares($sharesJson);
1065
        $entry = $this->getEntryMapper()->update($entry);
1066
        
1067
        $this->getEventManager()->trigger(__FUNCTION__ . '.post', $this, array(
1068
            'user' => $user,
1069
            'game' => $game,
1070
            'secretKey' => $secretKey,
1071
            'topic' => $topic,
1072
            'entry' => $entry
1073
        ));
1074
1075
        return true;
1076
    }
1077
1078
    public function postFbRequest($secretKey, $game, $user, $entry, $to)
1079
    {
1080
        $shares = json_decode($entry->getSocialShares(), true);
1081
        $to = explode(',', $to);
1082
        if (!isset($shares['fbrequest'])) {
1083
            $shares['fbrequest'] = count($to);
1084
        } else {
1085
            $shares['fbrequest'] += count($to);
1086
        }
1087
        $sharesJson = json_encode($shares);
1088
        $entry->setSocialShares($sharesJson);
1089
        $entry = $this->getEntryMapper()->update($entry);
1090
        
1091
        $this->getEventManager()->trigger(__FUNCTION__ . '.post', $this, array(
1092
            'user' => $user,
1093
            'game' => $game,
1094
            'secretKey' => $secretKey,
1095
            'entry' => $entry,
1096
            'invites' => count($to)
1097
        ));
1098
1099
        return true;
1100
    }
1101
1102 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...
1103
    {
1104
        $topic = $game->getTitle();
1105
1106
        $shares = json_decode($entry->getSocialShares(), true);
1107
        if (!isset($shares['fbrequest'])) {
1108
            $shares['tweet'] = 1;
1109
        } else {
1110
            $shares['tweet'] += 1;
1111
        }
1112
        $sharesJson = json_encode($shares);
1113
        $entry->setSocialShares($sharesJson);
1114
        $entry = $this->getEntryMapper()->update($entry);
1115
        
1116
        $this->getEventManager()->trigger(__FUNCTION__ . '.post', $this, array(
1117
            'user' => $user,
1118
            'game' => $game,
1119
            'secretKey' => $secretKey,
1120
            'topic' => $topic,
1121
            'entry' => $entry
1122
        ));
1123
1124
        return true;
1125
    }
1126
1127 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...
1128
    {
1129
        $topic = $game->getTitle();
1130
        
1131
        $shares = json_decode($entry->getSocialShares(), true);
1132
        if (!isset($shares['fbrequest'])) {
1133
            $shares['google'] = 1;
1134
        } else {
1135
            $shares['google'] += 1;
1136
        }
1137
        $sharesJson = json_encode($shares);
1138
        $entry->setSocialShares($sharesJson);
1139
        $entry = $this->getEntryMapper()->update($entry);
1140
1141
        $this->getEventManager()->trigger(__FUNCTION__ . '.post', $this, array(
1142
            'user' => $user,
1143
            'game' => $game,
1144
            'secretKey' => $secretKey,
1145
            'topic' => $topic,
1146
            'entry' => $entry
1147
        ));
1148
1149
        return true;
1150
    }
1151
1152
    /**
1153
     * Is it possible to trigger a bonus entry ?
1154
     *
1155
     * @param unknown_type $game
1156
     * @param unknown_type $user
1157
     */
1158
    public function allowBonus($game, $user)
1159
    {
1160
        if (! $game->getPlayBonus() || $game->getPlayBonus() == 'none') {
1161
            return false;
1162
        } elseif ($game->getPlayBonus() == 'one') {
1163
            if ($this->getEntryMapper()->findOneBy(array(
1164
                'game' => $game,
1165
                'user' => $user,
1166
                'bonus' => 1
1167
            ))) {
1168
                return false;
1169
            } else {
1170
                return true;
1171
            }
1172
        } elseif ($game->getPlayBonus() == 'per_entry') {
1173
            return $this->getEntryMapper()->checkBonusEntry($game, $user);
1174
        }
1175
1176
        return false;
1177
    }
1178
1179
    public function addAnotherEntry($game, $user, $winner = 0)
1180
    {
1181
        $entry = new Entry();
1182
        $entry->setGame($game);
1183
        $entry->setUser($user);
1184
        $entry->setPoints(0);
1185
        $entry->setIp($this->getIp());
1186
        $entry->setActive(0);
1187
        $entry->setBonus(1);
1188
        $entry->setWinner($winner);
1189
        $entry = $this->getEntryMapper()->insert($entry);
1190
1191
        return $entry;
1192
    }
1193
1194
    /**
1195
     * This bonus entry doesn't give points nor badges
1196
     * It's just there to increase the chances during the Draw
1197
     * Old Name playBonus
1198
     *
1199
     * @param PlaygroundGame\Entity\Game $game
1200
     * @param unknown $user
1201
     * @return boolean unknown
1202
     */
1203
    public function addAnotherChance($game, $user, $winner = 0)
1204
    {
1205
        if ($this->allowBonus($game, $user)) {
1206
            $this->addAnotherEntry($game, $user, $winner);
1207
1208
            return true;
1209
        }
1210
1211
        return false;
1212
    }
1213
1214
    /**
1215
     * This bonus entry doesn't give points nor badges but can play again
1216
     *
1217
     * @param PlaygroundGame\Entity\Game $game
1218
     * @param user $user
1219
     * @return boolean unknown
1220
     */
1221
    public function playAgain($game, $user, $winner = 0)
1222
    {
1223
        if ($this->allowBonus($game, $user)) {
1224
            $entry = $this->addAnotherEntry($game, $user, $winner);
1225
            $entry->setActive(1);
1226
            $entry = $this->getEntryMapper()->update($entry);
1227
            if ($entry->getActive() == 1) {
1228
                return true;
1229
            }
1230
        }
1231
1232
        return false;
1233
    }
1234
1235
    /**
1236
     * @param string $path
1237
     */
1238
    public function uploadFile($path, $file)
1239
    {
1240
        $err = $file["error"];
1241
        $message = '';
1242
        if ($err > 0) {
1243
            switch ($err) {
1244
                case '1':
1245
                    $message .= 'Max file size exceeded. (php.ini)';
1246
                    break;
1247
                case '2':
1248
                    $message .= 'Max file size exceeded.';
1249
                    break;
1250
                case '3':
1251
                    $message .= 'File upload was only partial.';
1252
                    break;
1253
                case '4':
1254
                    $message .= 'No file was attached.';
1255
                    break;
1256
                case '7':
1257
                    $message .= 'File permission denied.';
1258
                    break;
1259
                default:
1260
                    $message .= 'Unexpected error occurs.';
1261
            }
1262
1263
            return $err;
1264
        } else {
1265
            $fileNewname = $this->fileNewname($path, $file['name'], true);
1266
1267
            if (isset($file["base64"])) {
1268
                list(, $img) = explode(',', $file["base64"]);
1269
                $img = str_replace(' ', '+', $img);
1270
                $im = base64_decode($img);
1271
                if ($im !== false) {
1272
                    // getimagesizefromstring
1273
                    file_put_contents($path . $fileNewname, $im);
1274
                } else {
1275
                    return 1;
1276
                }
1277
1278
                return $fileNewname;
1279
            } else {
1280
                $adapter = new \Zend\File\Transfer\Adapter\Http();
1281
                // 1Mo
1282
                $size = new Size(array(
1283
                    'max' => 1024000
1284
                ));
1285
                $is_image = new IsImage('jpeg,png,gif,jpg');
1286
                $adapter->setValidators(array(
1287
                    $size,
1288
                    $is_image
1289
                ), $fileNewname);
1290
1291
                if (! $adapter->isValid()) {
1292
                    return false;
1293
                }
1294
1295
                @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...
1296
            }
1297
1298
            
1299
            if (class_exists("Imagick")) {
1300
                $ext = pathinfo($fileNewname, PATHINFO_EXTENSION);
1301
                $img = new \Imagick($path . $fileNewname);
1302
                $img->cropThumbnailImage(100, 100);
1303
                $img->setImageCompression(\Imagick::COMPRESSION_JPEG);
1304
                $img->setImageCompressionQuality(75);
1305
                // Strip out unneeded meta data
1306
                $img->stripImage();
1307
                $img->writeImage($path . str_replace('.'.$ext, '-thumbnail.'.$ext, $fileNewname));
1308
                ErrorHandler::stop(true);
1309
            }
1310
        }
1311
1312
        return $fileNewname;
1313
    }
1314
1315
    /**
1316
     * @param string $path
1317
     */
1318
    public function fileNewname($path, $filename, $generate = false)
1319
    {
1320
        $sanitize = new Sanitize();
1321
        $name = $sanitize->filter($filename);
1322
        $newpath = $path . $name;
1323
1324
        if ($generate) {
1325
            if (file_exists($newpath)) {
1326
                $filename = pathinfo($name, PATHINFO_FILENAME);
1327
                $ext = pathinfo($name, PATHINFO_EXTENSION);
1328
1329
                $name = $filename . '_' . rand(0, 99) . '.' . $ext;
1330
            }
1331
        }
1332
1333
        unset($sanitize);
1334
1335
        return $name;
1336
    }
1337
1338
    /**
1339
     * This function returns the list of games, order by $type
1340
     */
1341
    public function getQueryGamesOrderBy($type = 'createdAt', $order = 'DESC')
1342
    {
1343
        $em = $this->getServiceManager()->get('doctrine.entitymanager.orm_default');
1344
        $today = new \DateTime("now");
1345
        $today = $today->format('Y-m-d H:i:s');
1346
1347
        $onlineGames = '(
1348
            (
1349
                CASE WHEN (
1350
                    g.active = 1
1351
                    AND g.broadcastPlatform = 1
1352
                    AND (g.startDate <= :date OR g.startDate IS NULL)
1353
                    AND (g.closeDate >= :date OR g.closeDate IS NULL)
1354
                ) THEN 1 ELSE 0 END
1355
            ) +
1356
            (
1357
                CASE WHEN (
1358
                    g.active = 0
1359
                    AND (g.broadcastPlatform = 0 OR g.broadcastPlatform IS NULL)
1360
                    AND g.startDate > :date
1361
                    AND g.closeDate < :date
1362
                ) THEN 1 ELSE 0 END
1363
            )
1364
        )';
1365
1366
        $qb = $em->createQueryBuilder();
1367
        $qb->select('g')->from('PlaygroundGame\Entity\Game', 'g');
1368
        
1369
        switch ($type) {
1370
            case 'startDate':
1371
                $qb->orderBy('g.startDate', $order);
1372
                break;
1373
            case 'activeGames':
1374
                $qb->orderBy('g.active', $order);
1375
                break;
1376
            case 'onlineGames':
1377
                $qb->orderBy($onlineGames, $order);
1378
                $qb->setParameter('date', $today);
1379
                break;
1380
            case 'createdAt':
1381
                $qb->orderBy('g.createdAt', $order);
1382
                break;
1383
        }
1384
1385
        $query = $qb->getQuery();
1386
1387
        return $query;
1388
    }
1389
1390
    public function draw($game)
1391
    {
1392
        $total = $game->getWinners();
1393
1394
        // I Have to know what is the User Class used
1395
        $zfcUserOptions = $this->getServiceManager()->get('zfcuser_module_options');
1396
        $userClass = $zfcUserOptions->getUserEntityClass();
1397
1398
        $result = $this->getEntryMapper()->draw($game, $userClass, $total);
1399
1400
        foreach ($result as $e) {
1401
            $e->setWinner(1);
1402
            $e = $this->getEntryMapper()->update($e);
1403
            $this->getEventManager()->trigger('win_lottery.post', $this, array(
1404
                'user' => $e->getUser(),
1405
                'game' => $game,
1406
                'entry' => $e
1407
            ));
1408
        }
1409
1410
        return $result;
1411
    }
1412
1413
    /**
1414
     * getGameMapper
1415
     *
1416
     * @return GameMapperInterface
1417
     */
1418 View Code Duplication
    public function getGameMapper()
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...
1419
    {
1420
        if (null === $this->gameMapper) {
1421
            $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...
1422
        }
1423
1424
        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 1424 which is incompatible with the return type documented by PlaygroundGame\Service\Game::getGameMapper of type PlaygroundGame\Mapper\GameInterface.
Loading history...
1425
    }
1426
1427
    /**
1428
     * setGameMapper
1429
     *
1430
     * @param GameMapperInterface $gameMapper
1431
     * @return Game
1432
     */
1433
    public function setGameMapper(GameMapperInterface $gameMapper)
1434
    {
1435
        $this->gameMapper = $gameMapper;
1436
1437
        return $this;
1438
    }
1439
1440
    /**
1441
     * getEntryMapper
1442
     *
1443
     * @return EntryMapperInterface
1444
     */
1445
    public function getEntryMapper()
1446
    {
1447
        if (null === $this->entryMapper) {
1448
            $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...
1449
        }
1450
1451
        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 1451 which is incompatible with the return type documented by PlaygroundGame\Service\Game::getEntryMapper of type PlaygroundGame\Service\EntryMapperInterface.
Loading history...
1452
    }
1453
1454
    /**
1455
     * setEntryMapper
1456
     *
1457
     * @param EntryMapperInterface $entryMapper
1458
     * @return Game
1459
     */
1460
    public function setEntryMapper($entryMapper)
1461
    {
1462
        $this->entryMapper = $entryMapper;
1463
1464
        return $this;
1465
    }
1466
1467
    public function setOptions(ModuleOptions $options)
1468
    {
1469
        $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...
1470
1471
        return $this;
1472
    }
1473
1474
    public function getOptions()
1475
    {
1476
        if (! $this->options instanceof ModuleOptions) {
1477
            $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...
1478
                ->get('playgroundgame_module_options'));
1479
        }
1480
1481
        return $this->options;
1482
    }
1483
1484
    /**
1485
     * Retrieve service manager instance
1486
     *
1487
     * @return ServiceManager
1488
     */
1489
    public function getServiceManager()
1490
    {
1491
        return $this->serviceManager;
1492
    }
1493
1494
    /**
1495
     * Set service manager instance
1496
     *
1497
     * @param ServiceManager $serviceManager
1498
     * @return Game
1499
     */
1500
    public function setServiceManager(ServiceManager $serviceManager)
1501
    {
1502
        $this->serviceManager = $serviceManager;
1503
1504
        return $this;
1505
    }
1506
1507
    /**
1508
     * @param string $str
1509
     */
1510
    public function getExtension($str)
1511
    {
1512
        $i = strrpos($str, '.');
1513
1514
        $l = strlen($str) - $i;
1515
        $ext = substr($str, $i + 1, $l);
1516
1517
        return $ext;
1518
    }
1519
1520
    /**
1521
     * @param string $extension
1522
     */
1523
    public function getSrc($extension, $temp_path)
1524
    {
1525
        $image_src = '';
1526
        switch ($extension) {
1527
            case 'jpg':
1528
                $image_src = imagecreatefromjpeg($temp_path);
1529
                break;
1530
            case 'jpeg':
1531
                $image_src = imagecreatefromjpeg($temp_path);
1532
                break;
1533
            case 'png':
1534
                $image_src = imagecreatefrompng($temp_path);
1535
                break;
1536
            case 'gif':
1537
                $image_src = imagecreatefromgif($temp_path);
1538
                break;
1539
        }
1540
1541
        return $image_src;
1542
    }
1543
1544
    /**
1545
     * @param string $extension
1546
     * @param string $rep
1547
     * @param integer $mini_width
1548
     * @param integer $mini_height
1549
     */
1550
    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...
1551
    {
1552
        list($src_width, $src_height) = getimagesize($tmp_file);
1553
1554
        $ratio_src = $src_width / $src_height;
1555
        $ratio_mini = $mini_width / $mini_height;
1556
1557
        if ($ratio_src >= $ratio_mini) {
1558
            $new_height_mini = $mini_height;
1559
            $new_width_mini = $src_width / ($src_height / $mini_height);
1560
        } else {
1561
            $new_width_mini = $mini_width;
1562
            $new_height_mini = $src_height / ($src_width / $mini_width);
1563
        }
1564
1565
        $new_image_mini = imagecreatetruecolor($mini_width, $mini_height);
1566
1567
        imagecopyresampled(
1568
            $new_image_mini,
1569
            $src,
1570
            0 - ($new_width_mini - $mini_width) / 2,
1571
            0 - ($new_height_mini - $mini_height) / 2,
1572
            0,
1573
            0,
1574
            $new_width_mini,
1575
            $new_height_mini,
1576
            $src_width,
1577
            $src_height
1578
        );
1579
        imagejpeg($new_image_mini, $rep);
1580
1581
        imagedestroy($new_image_mini);
1582
    }
1583
1584
    public function getGameEntity()
1585
    {
1586
        return new \PlaygroundGame\Entity\Game();
1587
    }
1588
1589
    /**
1590
     * @param string $resource
1591
     * @param string $privilege
1592
     */
1593
    public function isAllowed($resource, $privilege = null)
1594
    {
1595
        $auth = $this->getServiceManager()->get('BjyAuthorize\Service\Authorize');
1596
1597
        return $auth->isAllowed($resource, $privilege);
1598
    }
1599
1600
    public function getIp()
1601
    {
1602
        $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...
1603
        if (isset($_SERVER['HTTP_CLIENT_IP'])) {
1604
            $ipaddress = $_SERVER['HTTP_CLIENT_IP'];
1605
        } elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
1606
            $ipaddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
1607
        } elseif (isset($_SERVER['HTTP_X_FORWARDED'])) {
1608
            $ipaddress = $_SERVER['HTTP_X_FORWARDED'];
1609
        } elseif (isset($_SERVER['HTTP_FORWARDED_FOR'])) {
1610
            $ipaddress = $_SERVER['HTTP_FORWARDED_FOR'];
1611
        } elseif (isset($_SERVER['HTTP_FORWARDED'])) {
1612
            $ipaddress = $_SERVER['HTTP_FORWARDED'];
1613
        } elseif (isset($_SERVER['REMOTE_ADDR'])) {
1614
            $ipaddress = $_SERVER['REMOTE_ADDR'];
1615
        } else {
1616
            $ipaddress = 'UNKNOWN';
1617
        }
1618
1619
        return $ipaddress;
1620
    }
1621
1622
    public function getAnonymousId()
1623
    {
1624
        $anonymousId = '';
1625
        if ($_COOKIE && array_key_exists('pg_anonymous', $_COOKIE)) {
1626
            $anonymousId = $_COOKIE['pg_anonymous'];
1627
        }
1628
1629
        return $anonymousId;
1630
    }
1631
1632
    /**
1633
     *
1634
     *
1635
     * This service is ready for all types of games
1636
     *
1637
     * @param array $data
1638
     * @return \PlaygroundGame\Entity\Game
1639
     */
1640 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...
1641
    {
1642
        $title = '';
1643
        $description = '';
1644
1645
        if ($data['form_jsonified']) {
1646
            $jsonPV = json_decode($data['form_jsonified']);
1647
            foreach ($jsonPV as $element) {
1648
                if ($element->form_properties) {
1649
                    $attributes = $element->form_properties[0];
1650
                    $title = $attributes->title;
1651
                    $description = $attributes->description;
1652
1653
                    break;
1654
                }
1655
            }
1656
        }
1657
        if (! $form) {
1658
            $form = new \PlaygroundGame\Entity\PlayerForm();
1659
        }
1660
        $form->setGame($game);
1661
        $form->setTitle($title);
1662
        $form->setDescription($description);
1663
        $form->setForm($data['form_jsonified']);
1664
        $form->setFormTemplate($data['form_template']);
1665
1666
        $form = $this->getPlayerFormMapper()->insert($form);
1667
1668
        return $form;
1669
    }
1670
1671
    /**
1672
     *  getCSV creates lines of CSV and returns it.
1673
     */
1674
    public function getCSV($array)
1675
    {
1676
        ob_start(); // buffer the output ...
1677
        $out = fopen('php://output', 'w');
1678
        fputcsv($out, array_keys($array[0]), ";");
1679
        foreach ($array as $line) {
1680
            fputcsv($out, $line, ";");
1681
        }
1682
        fclose($out);
1683
        return ob_get_clean(); // ... then return it as a string!
1684
    }
1685
    
1686
    public function getAttributes($attributes)
1687
    {
1688
        $a = array();
1689
1690
        $a['name']          = isset($attributes->name)? $attributes->name : '';
1691
        $a['placeholder']   = isset($attributes->data->placeholder)? $attributes->data->placeholder : '';
1692
        $a['label']         = isset($attributes->data->label)? $attributes->data->label : '';
1693
        $a['required']      = (isset($attributes->data->required) && $attributes->data->required == 'true')?
1694
            true:
1695
            false;
1696
        $a['class']         = isset($attributes->data->class)? $attributes->data->class : '';
1697
        $a['id']            = isset($attributes->data->id)? $attributes->data->id : '';
1698
        $a['lengthMin']     = isset($attributes->data->length)? $attributes->data->length->min : '';
1699
        $a['lengthMax']     = isset($attributes->data->length)? $attributes->data->length->max : '';
1700
        $a['validator']     = isset($attributes->data->validator)? $attributes->data->validator : '';
1701
        $a['innerData']     = isset($attributes->data->innerData)? $attributes->data->innerData : array();
1702
        $a['dropdownValues']= isset($attributes->data->dropdownValues)?
1703
            $attributes->data->dropdownValues :
1704
            array();
1705
        $a['filesizeMin']   = isset($attributes->data->filesize)? $attributes->data->filesize->min : 0;
1706
        $a['filesizeMax']   = isset($attributes->data->filesize)? $attributes->data->filesize->max : 10*1024*1024;
1707
1708
        return $a;
1709
    }
1710
1711
    /**
1712
     * @param \Zend\InputFilter\InputFilter $inputFilter
1713
     */
1714
    public function decorate($element, $attr, $inputFilter)
1715
    {
1716
        $factory = new InputFactory();
1717
        $element->setAttributes(
1718
            array(
1719
                'placeholder'   => $attr['placeholder'],
1720
                'required'      => $attr['required'],
1721
                'class'         => $attr['class'],
1722
                'id'            => $attr['id']
1723
            )
1724
        );
1725
1726
        $options = array();
1727
        $options['encoding'] = 'UTF-8';
1728
        if ($attr['lengthMin'] && $attr['lengthMin'] > 0) {
1729
            $options['min'] = $attr['lengthMin'];
1730
        }
1731
        if ($attr['lengthMax'] && $attr['lengthMax'] > $attr['lengthMin']) {
1732
            $options['max'] = $attr['lengthMax'];
1733
            $element->setAttribute('maxlength', $attr['lengthMax']);
1734
            $options['messages'] = array(
1735
                \Zend\Validator\StringLength::TOO_LONG => sprintf(
1736
                    $this->getServiceManager()->get('translator')->translate(
1737
                        'This field contains more than %s characters',
1738
                        'playgroundgame'
1739
                    ),
1740
                    $attr['lengthMax']
1741
                )
1742
            );
1743
        }
1744
1745
        $validators = array(
1746
            array(
1747
                'name'    => 'StringLength',
1748
                'options' => $options,
1749
            ),
1750
        );
1751
        if ($attr['validator']) {
1752
            $regex = "/.*\(([^)]*)\)/";
1753
            preg_match($regex, $attr['validator'], $matches);
1754
            $valArray = array(
1755
                'name' => str_replace(
1756
                    '('.$matches[1].')',
1757
                    '',
1758
                    $attr['validator']
1759
                ),
1760
                'options' => array($matches[1])
1761
            );
1762
            $validators[] = $valArray;
1763
        }
1764
1765
        $inputFilter->add($factory->createInput(array(
1766
            'name'     => $attr['name'],
1767
            'required' => $attr['required'],
1768
            'filters'  => array(
1769
                array('name' => 'StripTags'),
1770
                array('name' => 'StringTrim'),
1771
            ),
1772
            'validators' => $validators,
1773
        )));
1774
1775
        return $element;
1776
    }
1777
    /**
1778
     * Create a ZF2 Form from json data
1779
     * @return Form
1780
     */
1781
    public function createFormFromJson($jsonForm, $id = 'jsonForm')
1782
    {
1783
        $formPV = json_decode($jsonForm);
1784
        
1785
        $form = new Form();
1786
        $form->setAttribute('id', $id);
1787
        $form->setAttribute('enctype', 'multipart/form-data');
1788
        
1789
        $inputFilter = new \Zend\InputFilter\InputFilter();
1790
        $factory = new InputFactory();
1791
        
1792
        foreach ($formPV as $element) {
1793 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...
1794
                $attr  = $this->getAttributes($element->line_text[0]);
1795
                $element = new Element\Text($attr['name']);
1796
                $element = $this->decorate($element, $attr, $inputFilter);
1797
                $form->add($element);
1798
            }
1799 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...
1800
                $attr = $this->getAttributes($element->line_password[0]);
1801
                $element = new Element\Password($attr['name']);
1802
                $element = $this->decorate($element, $attr, $inputFilter);
1803
                $form->add($element);
1804
            }
1805 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...
1806
                $attr = $this->getAttributes($element->line_hidden[0]);
1807
                $element = new Element\Hidden($attr['name']);
1808
                $element = $this->decorate($element, $attr, $inputFilter);
1809
                $form->add($element);
1810
            }
1811 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...
1812
                $attr = $this->getAttributes($element->line_email[0]);
1813
                $element = new Element\Email($attr['name']);
1814
                $element = $this->decorate($element, $attr, $inputFilter);
1815
                $form->add($element);
1816
            }
1817 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...
1818
                $attr = $this->getAttributes($element->line_radio[0]);
1819
                $element = new Element\Radio($attr['name']);
1820
1821
                $element->setLabel($attr['label']);
1822
                $element->setAttributes(
1823
                    array(
1824
                        'name'      => $attr['name'],
1825
                        'required'  => $attr['required'],
1826
                        'allowEmpty'=> !$attr['required'],
1827
                        'class'     => $attr['class'],
1828
                        'id'        => $attr['id']
1829
                    )
1830
                );
1831
                $values = array();
1832
                foreach ($attr['innerData'] as $value) {
1833
                    $values[] = $value->label;
1834
                }
1835
                $element->setValueOptions($values);
1836
        
1837
                $options = array();
1838
                $options['encoding'] = 'UTF-8';
1839
                $options['disable_inarray_validator'] = true;
1840
        
1841
                $element->setOptions($options);
1842
        
1843
                $form->add($element);
1844
        
1845
                $inputFilter->add($factory->createInput(array(
1846
                    'name'     => $attr['name'],
1847
                    'required' => $attr['required'],
1848
                    'allowEmpty' => !$attr['required'],
1849
                )));
1850
            }
1851 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...
1852
                $attr = $this->getAttributes($element->line_checkbox[0]);
1853
                $element = new Element\MultiCheckbox($attr['name']);
1854
        
1855
                $element->setLabel($attr['label']);
1856
                $element->setAttributes(
1857
                    array(
1858
                        'name'      => $attr['name'],
1859
                        'required'  => $attr['required'],
1860
                        'allowEmpty'=> !$attr['required'],
1861
                        'class'     => $attr['class'],
1862
                        'id'        => $attr['id']
1863
                    )
1864
                );
1865
1866
                $values = array();
1867
                foreach ($attr['innerData'] as $value) {
1868
                    $values[] = $value->label;
1869
                }
1870
                $element->setValueOptions($values);
1871
                $form->add($element);
1872
        
1873
                $options = array();
1874
                $options['encoding'] = 'UTF-8';
1875
                $options['disable_inarray_validator'] = true;
1876
        
1877
                $element->setOptions($options);
1878
        
1879
                $inputFilter->add($factory->createInput(array(
1880
                    'name'      => $attr['name'],
1881
                    'required'  => $attr['required'],
1882
                    'allowEmpty'=> !$attr['required'],
1883
                )));
1884
            }
1885 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...
1886
                $attr = $this->getAttributes($element->line_dropdown[0]);
1887
                $element = new Element\Select($attr['name']);
1888
1889
                $element->setLabel($attr['label']);
1890
                $element->setAttributes(
1891
                    array(
1892
                        'name'      => $attr['name'],
1893
                        'required'  => $attr['required'],
1894
                        'allowEmpty'=> !$attr['required'],
1895
                        'class'     => $attr['class'],
1896
                        'id'        => $attr['id']
1897
                    )
1898
                );
1899
                $values = array();
1900
                foreach ($attr['dropdownValues'] as $value) {
1901
                    $values[] = $value->dropdown_label;
1902
                }
1903
                $element->setValueOptions($values);
1904
                $form->add($element);
1905
        
1906
                $options = array();
1907
                $options['encoding'] = 'UTF-8';
1908
                $options['disable_inarray_validator'] = true;
1909
        
1910
                $element->setOptions($options);
1911
        
1912
                $inputFilter->add($factory->createInput(array(
1913
                    'name'     => $attr['name'],
1914
                    'required' => $attr['required'],
1915
                    'allowEmpty' => !$attr['required'],
1916
                )));
1917
            }
1918 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...
1919
                $attr = $this->getAttributes($element->line_paragraph[0]);
1920
                $element = new Element\Textarea($attr['name']);
1921
                $element = $this->decorate($element, $attr, $inputFilter);
1922
                $form->add($element);
1923
            }
1924
            if (isset($element->line_upload)) {
1925
                $attr = $this->getAttributes($element->line_upload[0]);
1926
                $element = new Element\File($attr['name']);
1927
1928
                $element->setLabel($attr['label']);
1929
                $element->setAttributes(
1930
                    array(
1931
                        'name'      => $attr['name'],
1932
                        'required'  => $attr['required'],
1933
                        'class'     => $attr['class'],
1934
                        'id'        => $attr['id']
1935
                    )
1936
                );
1937
                $form->add($element);
1938
        
1939
                $inputFilter->add($factory->createInput(array(
1940
                    'name'     => $attr['name'],
1941
                    'required' => $attr['required'],
1942
                    'validators' => array(
1943
                        array(
1944
                            'name' => '\Zend\Validator\File\Size',
1945
                            'options' => array('min' => $attr['filesizeMin'], 'max' => $attr['filesizeMax'])
1946
                        ),
1947
                        array(
1948
                            'name' => '\Zend\Validator\File\Extension',
1949
                            'options'  => array(
1950
                                'png,PNG,jpg,JPG,jpeg,JPEG,gif,GIF',
1951
                                'messages' => array(
1952
                                    \Zend\Validator\File\Extension::FALSE_EXTENSION =>'Veuillez télécharger une image'
1953
                                )
1954
                            )
1955
                        ),
1956
                    ),
1957
                )));
1958
            }
1959
        }
1960
        
1961
        $form->setInputFilter($inputFilter);
1962
        
1963
        return $form;
1964
    }
1965
1966
    /**
1967
     * Send mail for winner and/or loser
1968
     * @param \PlaygroundGame\Entity\Game $game
1969
     * @param \PlaygroundUser\Entity\User $user
1970
     * @param \PlaygroundGame\Entity\Entry $lastEntry
1971
     * @param \PlaygroundGame\Entity\Prize $prize
1972
     */
1973
    public function sendMail($game, $user, $lastEntry, $prize = null)
1974
    {
1975 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...
1976
            $game->getMailWinner() &&
1977
            $lastEntry->getWinner()
1978
        ) {
1979
            $this->sendResultMail($game, $user, $lastEntry, 'winner', $prize);
1980
        }
1981
1982 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...
1983
            $game->getMailLooser() &&
1984
            !$lastEntry->getWinner()
1985
        ) {
1986
            $this->sendResultMail($game, $user, $lastEntry, 'looser');
1987
        }
1988
    }
1989
1990
    public function getPlayerFormMapper()
1991
    {
1992
        if (null === $this->playerformMapper) {
1993
            $this->playerformMapper = $this->getServiceManager()->get('playgroundgame_playerform_mapper');
1994
        }
1995
1996
        return $this->playerformMapper;
1997
    }
1998
1999
    public function setPlayerFormMapper($playerformMapper)
2000
    {
2001
        $this->playerformMapper = $playerformMapper;
2002
2003
        return $this;
2004
    }
2005
2006
    public function getInvitationMapper()
2007
    {
2008
        if (null === $this->invitationMapper) {
2009
            $this->invitationMapper = $this->getServiceManager()->get('playgroundgame_invitation_mapper');
2010
        }
2011
2012
        return $this->invitationMapper;
2013
    }
2014
2015
    public function setInvitationMapper($invitationMapper)
2016
    {
2017
        $this->invitationMapper = $invitationMapper;
2018
2019
        return $this;
2020
    }
2021
}
2022