Completed
Push — master ( 89a93b...fdbd87 )
by greg
06:17 queued 03:15
created

Game::sendShareMail()   C

Complexity

Conditions 8
Paths 42

Size

Total Lines 74
Code Lines 54

Duplication

Lines 0
Ratio 0 %

Importance

Changes 8
Bugs 1 Features 0
Metric Value
c 8
b 1
f 0
dl 0
loc 74
rs 6.2895
cc 8
eloc 54
nc 42
nop 7

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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'
68
        ));
69
        $form->get('startDate')->setOptions(array(
70
            'format' => 'Y-m-d'
71
        ));
72
        $form->get('endDate')->setOptions(array(
73
            'format' => 'Y-m-d'
74
        ));
75
        $form->get('closeDate')->setOptions(array(
76
            'format' => 'Y-m-d'
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', $data['publicationDate']);
101
            $data['publicationDate'] = $tmpDate->format('Y-m-d');
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', $data['startDate']);
105
            $data['startDate'] = $tmpDate->format('Y-m-d');
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', $data['endDate']);
109
            $data['endDate'] = $tmpDate->format('Y-m-d');
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', $data['closeDate']);
113
            $data['closeDate'] = $tmpDate->format('Y-m-d');
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
            if (isset($data['publicationDate']) && $data['publicationDate']) {
145
                $tmpDate = \DateTime::createFromFormat('Y-m-d', $data['publicationDate']);
146
                $data['publicationDate'] = $tmpDate->format('d/m/Y');
147
                $form->setData(array(
148
                    'publicationDate' => $data['publicationDate']
149
                ));
150
            }
151
            if (isset($data['startDate']) && $data['startDate']) {
152
                $tmpDate = \DateTime::createFromFormat('Y-m-d', $data['startDate']);
153
                $data['startDate'] = $tmpDate->format('d/m/Y');
154
                $form->setData(array(
155
                    'startDate' => $data['startDate']
156
                ));
157
            }
158
            if (isset($data['endDate']) && $data['endDate']) {
159
                $tmpDate = \DateTime::createFromFormat('Y-m-d', $data['endDate']);
160
                $data['endDate'] = $tmpDate->format('d/m/Y');
161
                $form->setData(array(
162
                    'endDate' => $data['endDate']
163
                ));
164
            }
165
            if (isset($data['closeDate']) && $data['closeDate']) {
166
                $tmpDate = \DateTime::createFromFormat('Y-m-d', $data['closeDate']);
167
                $data['closeDate'] = $tmpDate->format('d/m/Y');
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') . ' 23:59:59';
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') . ' 23:59:59';
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'):
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') . ' 23:59:59';
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') . ' 0:0:0';
861
                break;
862
            case 'day':
863
                $dateLimit = $now->format('Y-m-d') . ' 0:0:0';
864
                break;
865
            case 'week':
866
                $interval = 'P7D';
867
                $now->sub(new \DateInterval($interval));
868
                $dateLimit = $now->format('Y-m-d') . ' 0:0:0';
869
                break;
870
            case 'month':
871
                $interval = 'P1M';
872
                $now->sub(new \DateInterval($interval));
873
                $dateLimit = $now->format('Y-m-d') . ' 0:0:0';
874
                break;
875
            case 'year':
876
                $interval = 'P1Y';
877
                $now->sub(new \DateInterval($interval));
878
                $dateLimit = $now->format('Y-m-d') . ' 0:0:0';
879
                break;
880
            default:
881
                $interval = 'P100Y';
882
                $now->sub(new \DateInterval($interval));
883
                $dateLimit = $now->format('Y-m-d') . ' 0:0:0';
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
    ) {
913
        $mailService = $this->getServiceManager()->get('playgroundgame_message');
914
        $mailSent = false;
915
        $from = $this->getOptions()->getEmailFromAddress();
916
        $subject = $this->getOptions()->getShareSubjectLine();
917
        $renderer = $this->getServiceManager()->get('Zend\View\Renderer\RendererInterface');
918
        $skinUrl = $renderer->url(
919
            'frontend',
920
            array(),
921
            array('force_canonical' => true)
922
        );
923
        $secretKey = strtoupper(substr(sha1(uniqid('pg_', true) . '####' . time()), 0, 15));
924
925
        if (! $topic) {
926
            $topic = $game->getTitle();
927
        }
928
929
        foreach ($data['email'] as $to) {
930
            $mailSent = true;
931
            $message = $mailService->createHtmlMessage(
932
                $from,
933
                $to,
934
                $subject,
935
                'playground-game/email/' . $template,
936
                array(
937
                    'game' => $game,
938
                    'from' => $from,
939
                    'to' => $to,
940
                    'secretKey' => $secretKey,
941
                    'skinUrl' => $skinUrl,
942
                    'userTimer' => $userTimer
943
                )
944
            );
945
            try {
946
                $mailService->send($message);
947
            } catch (\Zend\Mail\Protocol\Exception\RuntimeException $e) {
948
                //$mailSent = false;
949
            }
950
            
951
            if ($entry) {
952
                $shares = json_decode($entry->getSocialShares(), true);
953
                (!isset($shares['mail']))? $shares['mail'] = 1:$shares['mail'] += 1;
954
            }
955
        }
956
957
        if ($mailSent) {
958
            if ($entry) {
959
                $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...
960
                $entry->setSocialShares($sharesJson);
961
                $entry = $this->getEntryMapper()->update($entry);
962
            }
963
            
964
            $this->getEventManager()->trigger(__FUNCTION__ . '.post', $this, array(
965
                'user' => $user,
966
                'topic' => $topic,
967
                'secretKey' => $secretKey,
968
                'data' => $data,
969
                'game' => $game,
970
                'entry' => $entry
971
            ));
972
973
            return true;
974
        }
975
976
        return false;
977
    }
978
979
    /**
980
     * @param \PlaygroundGame\Entity\Game $game
981
     * @param \PlaygroundUser\Entity\User $user
982
     * @param Entry $entry
983
     * @param \PlaygroundGame\Entity\Prize $prize
984
     */
985
    public function sendResultMail($game, $user, $entry, $template = 'entry', $prize = null)
986
    {
987
        $mailService = $this->getServiceManager()->get('playgroundgame_message');
988
        $from = $this->getOptions()->getEmailFromAddress();
989
        if ($user) {
990
            $to = $user->getEmail();
991
        } elseif ($entry->getAnonymousIdentifier()) {
992
            $to = $entry->getAnonymousIdentifier();
993
        } else {
994
            return false;
995
        }
996
        $subject = $game->getTitle();
997
        $renderer = $this->getServiceManager()->get('Zend\View\Renderer\RendererInterface');
998
        $skinUrl = $renderer->url(
999
            'frontend',
1000
            array(),
1001
            array('force_canonical' => true)
1002
        );
1003
        $message = $mailService->createHtmlMessage($from, $to, $subject, 'playground-game/email/' . $template, array(
1004
            'game' => $game,
1005
            'entry' => $entry,
1006
            'skinUrl' => $skinUrl,
1007
            'prize' => $prize
1008
        ));
1009
        $mailService->send($message);
1010
    }
1011
1012
    public function sendGameMail($game, $user, $post, $template = 'postvote')
1013
    {
1014
        $mailService = $this->getServiceManager()->get('playgroundgame_message');
1015
        $from = $this->getOptions()->getEmailFromAddress();
1016
        $to = $user->getEmail();
1017
        $subject = $this->getOptions()->getParticipationSubjectLine();
1018
        $renderer = $this->getServiceManager()->get('Zend\View\Renderer\RendererInterface');
1019
        $skinUrl = $renderer->url(
1020
            'frontend',
1021
            array(),
1022
            array('force_canonical' => true)
1023
        );
1024
1025
        $message = $mailService->createHtmlMessage($from, $to, $subject, 'playground-game/email/' . $template, array(
1026
            'game' => $game,
1027
            'post' => $post,
1028
            'skinUrl' => $skinUrl
1029
        ));
1030
        $mailService->send($message);
1031
    }
1032
1033 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...
1034
    {
1035
        $topic = $game->getTitle();
1036
        
1037
        $shares = json_decode($entry->getSocialShares(), true);
1038
        if (!isset($shares['fbwall'])) {
1039
            $shares['fbwall'] = 1;
1040
        } else {
1041
            $shares['fbwall'] += 1;
1042
        }
1043
        $sharesJson = json_encode($shares);
1044
        $entry->setSocialShares($sharesJson);
1045
        $entry = $this->getEntryMapper()->update($entry);
1046
        
1047
        $this->getEventManager()->trigger(__FUNCTION__ . '.post', $this, array(
1048
            'user' => $user,
1049
            'game' => $game,
1050
            'secretKey' => $secretKey,
1051
            'topic' => $topic,
1052
            'entry' => $entry
1053
        ));
1054
1055
        return true;
1056
    }
1057
1058
    public function postFbRequest($secretKey, $game, $user, $entry, $to)
1059
    {
1060
        $shares = json_decode($entry->getSocialShares(), true);
1061
        $to = explode(',', $to);
1062
        if (!isset($shares['fbrequest'])) {
1063
            $shares['fbrequest'] = count($to);
1064
        } else {
1065
            $shares['fbrequest'] += count($to);
1066
        }
1067
        $sharesJson = json_encode($shares);
1068
        $entry->setSocialShares($sharesJson);
1069
        $entry = $this->getEntryMapper()->update($entry);
1070
        
1071
        $this->getEventManager()->trigger(__FUNCTION__ . '.post', $this, array(
1072
            'user' => $user,
1073
            'game' => $game,
1074
            'secretKey' => $secretKey,
1075
            'entry' => $entry,
1076
            'invites' => count($to)
1077
        ));
1078
1079
        return true;
1080
    }
1081
1082 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...
1083
    {
1084
        $topic = $game->getTitle();
1085
1086
        $shares = json_decode($entry->getSocialShares(), true);
1087
        if (!isset($shares['fbrequest'])) {
1088
            $shares['tweet'] = 1;
1089
        } else {
1090
            $shares['tweet'] += 1;
1091
        }
1092
        $sharesJson = json_encode($shares);
1093
        $entry->setSocialShares($sharesJson);
1094
        $entry = $this->getEntryMapper()->update($entry);
1095
        
1096
        $this->getEventManager()->trigger(__FUNCTION__ . '.post', $this, array(
1097
            'user' => $user,
1098
            'game' => $game,
1099
            'secretKey' => $secretKey,
1100
            'topic' => $topic,
1101
            'entry' => $entry
1102
        ));
1103
1104
        return true;
1105
    }
1106
1107 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...
1108
    {
1109
        $topic = $game->getTitle();
1110
        
1111
        $shares = json_decode($entry->getSocialShares(), true);
1112
        if (!isset($shares['fbrequest'])) {
1113
            $shares['google'] = 1;
1114
        } else {
1115
            $shares['google'] += 1;
1116
        }
1117
        $sharesJson = json_encode($shares);
1118
        $entry->setSocialShares($sharesJson);
1119
        $entry = $this->getEntryMapper()->update($entry);
1120
1121
        $this->getEventManager()->trigger(__FUNCTION__ . '.post', $this, array(
1122
            'user' => $user,
1123
            'game' => $game,
1124
            'secretKey' => $secretKey,
1125
            'topic' => $topic,
1126
            'entry' => $entry
1127
        ));
1128
1129
        return true;
1130
    }
1131
1132
    /**
1133
     * Is it possible to trigger a bonus entry ?
1134
     *
1135
     * @param unknown_type $game
1136
     * @param unknown_type $user
1137
     */
1138
    public function allowBonus($game, $user)
1139
    {
1140
        if (! $game->getPlayBonus() || $game->getPlayBonus() == 'none') {
1141
            return false;
1142
        } elseif ($game->getPlayBonus() == 'one') {
1143
            if ($this->getEntryMapper()->findOneBy(array(
1144
                'game' => $game,
1145
                'user' => $user,
1146
                'bonus' => 1
1147
            ))) {
1148
                return false;
1149
            } else {
1150
                return true;
1151
            }
1152
        } elseif ($game->getPlayBonus() == 'per_entry') {
1153
            return $this->getEntryMapper()->checkBonusEntry($game, $user);
1154
        }
1155
1156
        return false;
1157
    }
1158
1159
    public function addAnotherEntry($game, $user, $winner = 0)
1160
    {
1161
        $entry = new Entry();
1162
        $entry->setGame($game);
1163
        $entry->setUser($user);
1164
        $entry->setPoints(0);
1165
        $entry->setIp($this->getIp());
1166
        $entry->setActive(0);
1167
        $entry->setBonus(1);
1168
        $entry->setWinner($winner);
1169
        $entry = $this->getEntryMapper()->insert($entry);
1170
1171
        return $entry;
1172
    }
1173
1174
    /**
1175
     * This bonus entry doesn't give points nor badges
1176
     * It's just there to increase the chances during the Draw
1177
     * Old Name playBonus
1178
     *
1179
     * @param PlaygroundGame\Entity\Game $game
1180
     * @param unknown $user
1181
     * @return boolean unknown
1182
     */
1183
    public function addAnotherChance($game, $user, $winner = 0)
1184
    {
1185
        if ($this->allowBonus($game, $user)) {
1186
            $this->addAnotherEntry($game, $user, $winner);
1187
1188
            return true;
1189
        }
1190
1191
        return false;
1192
    }
1193
1194
    /**
1195
     * This bonus entry doesn't give points nor badges but can play again
1196
     *
1197
     * @param PlaygroundGame\Entity\Game $game
1198
     * @param user $user
1199
     * @return boolean unknown
1200
     */
1201
    public function playAgain($game, $user, $winner = 0)
1202
    {
1203
        if ($this->allowBonus($game, $user)) {
1204
            $entry = $this->addAnotherEntry($game, $user, $winner);
1205
            $entry->setActive(1);
1206
            $entry = $this->getEntryMapper()->update($entry);
1207
            if ($entry->getActive() == 1) {
1208
                return true;
1209
            }
1210
        }
1211
1212
        return false;
1213
    }
1214
1215
    /**
1216
     * @param string $path
1217
     */
1218
    public function uploadFile($path, $file)
1219
    {
1220
        $err = $file["error"];
1221
        $message = '';
1222
        if ($err > 0) {
1223
            switch ($err) {
1224
                case '1':
1225
                    $message .= 'Max file size exceeded. (php.ini)';
1226
                    break;
1227
                case '2':
1228
                    $message .= 'Max file size exceeded.';
1229
                    break;
1230
                case '3':
1231
                    $message .= 'File upload was only partial.';
1232
                    break;
1233
                case '4':
1234
                    $message .= 'No file was attached.';
1235
                    break;
1236
                case '7':
1237
                    $message .= 'File permission denied.';
1238
                    break;
1239
                default:
1240
                    $message .= 'Unexpected error occurs.';
1241
            }
1242
1243
            return $err;
1244
        } else {
1245
            $fileNewname = $this->fileNewname($path, $file['name'], true);
1246
1247
            if (isset($file["base64"])) {
1248
                list(, $img) = explode(',', $file["base64"]);
1249
                $img = str_replace(' ', '+', $img);
1250
                $im = base64_decode($img);
1251
                if ($im !== false) {
1252
                    // getimagesizefromstring
1253
                    file_put_contents($path . $fileNewname, $im);
1254
                } else {
1255
                    return 1;
1256
                }
1257
1258
                return $fileNewname;
1259
            } else {
1260
                $adapter = new \Zend\File\Transfer\Adapter\Http();
1261
                // 1Mo
1262
                $size = new Size(array(
1263
                    'max' => 1024000
1264
                ));
1265
                $is_image = new IsImage('jpeg,png,gif,jpg');
1266
                $adapter->setValidators(array(
1267
                    $size,
1268
                    $is_image
1269
                ), $fileNewname);
1270
1271
                if (! $adapter->isValid()) {
1272
                    return false;
1273
                }
1274
1275
                @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...
1276
            }
1277
1278
            
1279
            if (class_exists("Imagick")) {
1280
                $ext = pathinfo($fileNewname, PATHINFO_EXTENSION);
1281
                $img = new \Imagick($path . $fileNewname);
1282
                $img->cropThumbnailImage(100, 100);
1283
                $img->setImageCompression(\Imagick::COMPRESSION_JPEG);
1284
                $img->setImageCompressionQuality(75);
1285
                // Strip out unneeded meta data
1286
                $img->stripImage();
1287
                $img->writeImage($path . str_replace('.'.$ext, '-thumbnail.'.$ext, $fileNewname));
1288
                ErrorHandler::stop(true);
1289
            }
1290
        }
1291
1292
        return $fileNewname;
1293
    }
1294
1295
    /**
1296
     * @param string $path
1297
     */
1298
    public function fileNewname($path, $filename, $generate = false)
1299
    {
1300
        $sanitize = new Sanitize();
1301
        $name = $sanitize->filter($filename);
1302
        $newpath = $path . $name;
1303
1304
        if ($generate) {
1305
            if (file_exists($newpath)) {
1306
                $filename = pathinfo($name, PATHINFO_FILENAME);
1307
                $ext = pathinfo($name, PATHINFO_EXTENSION);
1308
1309
                $name = $filename . '_' . rand(0, 99) . '.' . $ext;
1310
            }
1311
        }
1312
1313
        unset($sanitize);
1314
1315
        return $name;
1316
    }
1317
1318
    /**
1319
     * This function returns the list of games, order by $type
1320
     */
1321
    public function getQueryGamesOrderBy($type = 'createdAt', $order = 'DESC')
1322
    {
1323
        $em = $this->getServiceManager()->get('doctrine.entitymanager.orm_default');
1324
        $today = new \DateTime("now");
1325
        $today = $today->format('Y-m-d') . ' 23:59:59';
1326
1327
        $onlineGames = '(
1328
            (
1329
                CASE WHEN (
1330
                    g.active = 1
1331
                    AND g.broadcastPlatform = 1
1332
                    AND (g.startDate <= :date OR g.startDate IS NULL)
1333
                    AND (g.closeDate >= :date OR g.closeDate IS NULL)
1334
                ) THEN 1 ELSE 0 END
1335
            ) +
1336
            (
1337
                CASE WHEN (
1338
                    g.active = 0
1339
                    AND (g.broadcastPlatform = 0 OR g.broadcastPlatform IS NULL)
1340
                    AND g.startDate > :date
1341
                    AND g.closeDate < :date
1342
                ) THEN 1 ELSE 0 END
1343
            )
1344
        )';
1345
1346
        $qb = $em->createQueryBuilder();
1347
        $qb->select('g')->from('PlaygroundGame\Entity\Game', 'g');
1348
        
1349
        switch ($type) {
1350
            case 'startDate':
1351
                $qb->orderBy('g.startDate', $order);
1352
                break;
1353
            case 'activeGames':
1354
                $qb->orderBy('g.active', $order);
1355
                break;
1356
            case 'onlineGames':
1357
                $qb->orderBy($onlineGames, $order);
1358
                $qb->setParameter('date', $today);
1359
                break;
1360
            case 'createdAt':
1361
                $qb->orderBy('g.createdAt', $order);
1362
                break;
1363
        }
1364
1365
        $query = $qb->getQuery();
1366
1367
        return $query;
1368
    }
1369
1370
    public function draw($game)
1371
    {
1372
        $total = $game->getWinners();
1373
1374
        // I Have to know what is the User Class used
1375
        $zfcUserOptions = $this->getServiceManager()->get('zfcuser_module_options');
1376
        $userClass = $zfcUserOptions->getUserEntityClass();
1377
1378
        $result = $this->getEntryMapper()->draw($game, $userClass, $total);
1379
1380
        foreach ($result as $e) {
1381
            $e->setWinner(1);
1382
            $e = $this->getEntryMapper()->update($e);
1383
            $this->getEventManager()->trigger('win_lottery.post', $this, array(
1384
                'user' => $e->getUser(),
1385
                'game' => $game,
1386
                'entry' => $e
1387
            ));
1388
        }
1389
1390
        return $result;
1391
    }
1392
1393
    /**
1394
     * getGameMapper
1395
     *
1396
     * @return GameMapperInterface
1397
     */
1398 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...
1399
    {
1400
        if (null === $this->gameMapper) {
1401
            $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...
1402
        }
1403
1404
        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 1404 which is incompatible with the return type documented by PlaygroundGame\Service\Game::getGameMapper of type PlaygroundGame\Mapper\GameInterface.
Loading history...
1405
    }
1406
1407
    /**
1408
     * setGameMapper
1409
     *
1410
     * @param GameMapperInterface $gameMapper
1411
     * @return Game
1412
     */
1413
    public function setGameMapper(GameMapperInterface $gameMapper)
1414
    {
1415
        $this->gameMapper = $gameMapper;
1416
1417
        return $this;
1418
    }
1419
1420
    /**
1421
     * getEntryMapper
1422
     *
1423
     * @return EntryMapperInterface
1424
     */
1425
    public function getEntryMapper()
1426
    {
1427
        if (null === $this->entryMapper) {
1428
            $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...
1429
        }
1430
1431
        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 1431 which is incompatible with the return type documented by PlaygroundGame\Service\Game::getEntryMapper of type PlaygroundGame\Service\EntryMapperInterface.
Loading history...
1432
    }
1433
1434
    /**
1435
     * setEntryMapper
1436
     *
1437
     * @param EntryMapperInterface $entryMapper
1438
     * @return Game
1439
     */
1440
    public function setEntryMapper($entryMapper)
1441
    {
1442
        $this->entryMapper = $entryMapper;
1443
1444
        return $this;
1445
    }
1446
1447
    public function setOptions(ModuleOptions $options)
1448
    {
1449
        $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...
1450
1451
        return $this;
1452
    }
1453
1454
    public function getOptions()
1455
    {
1456
        if (! $this->options instanceof ModuleOptions) {
1457
            $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...
1458
                ->get('playgroundgame_module_options'));
1459
        }
1460
1461
        return $this->options;
1462
    }
1463
1464
    /**
1465
     * Retrieve service manager instance
1466
     *
1467
     * @return ServiceManager
1468
     */
1469
    public function getServiceManager()
1470
    {
1471
        return $this->serviceManager;
1472
    }
1473
1474
    /**
1475
     * Set service manager instance
1476
     *
1477
     * @param ServiceManager $serviceManager
1478
     * @return Game
1479
     */
1480
    public function setServiceManager(ServiceManager $serviceManager)
1481
    {
1482
        $this->serviceManager = $serviceManager;
1483
1484
        return $this;
1485
    }
1486
1487
    /**
1488
     * @param string $str
1489
     */
1490
    public function getExtension($str)
1491
    {
1492
        $i = strrpos($str, '.');
1493
1494
        $l = strlen($str) - $i;
1495
        $ext = substr($str, $i + 1, $l);
1496
1497
        return $ext;
1498
    }
1499
1500
    /**
1501
     * @param string $extension
1502
     */
1503
    public function getSrc($extension, $temp_path)
1504
    {
1505
        $image_src = '';
1506
        switch ($extension) {
1507
            case 'jpg':
1508
                $image_src = imagecreatefromjpeg($temp_path);
1509
                break;
1510
            case 'jpeg':
1511
                $image_src = imagecreatefromjpeg($temp_path);
1512
                break;
1513
            case 'png':
1514
                $image_src = imagecreatefrompng($temp_path);
1515
                break;
1516
            case 'gif':
1517
                $image_src = imagecreatefromgif($temp_path);
1518
                break;
1519
        }
1520
1521
        return $image_src;
1522
    }
1523
1524
    /**
1525
     * @param string $extension
1526
     * @param string $rep
1527
     * @param integer $mini_width
1528
     * @param integer $mini_height
1529
     */
1530
    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...
1531
    {
1532
        list($src_width, $src_height) = getimagesize($tmp_file);
1533
1534
        $ratio_src = $src_width / $src_height;
1535
        $ratio_mini = $mini_width / $mini_height;
1536
1537
        if ($ratio_src >= $ratio_mini) {
1538
            $new_height_mini = $mini_height;
1539
            $new_width_mini = $src_width / ($src_height / $mini_height);
1540
        } else {
1541
            $new_width_mini = $mini_width;
1542
            $new_height_mini = $src_height / ($src_width / $mini_width);
1543
        }
1544
1545
        $new_image_mini = imagecreatetruecolor($mini_width, $mini_height);
1546
1547
        imagecopyresampled(
1548
            $new_image_mini,
1549
            $src,
1550
            0 - ($new_width_mini - $mini_width) / 2,
1551
            0 - ($new_height_mini - $mini_height) / 2,
1552
            0,
1553
            0,
1554
            $new_width_mini,
1555
            $new_height_mini,
1556
            $src_width,
1557
            $src_height
1558
        );
1559
        imagejpeg($new_image_mini, $rep);
1560
1561
        imagedestroy($new_image_mini);
1562
    }
1563
1564
    public function getGameEntity()
1565
    {
1566
        return new \PlaygroundGame\Entity\Game();
1567
    }
1568
1569
    /**
1570
     * @param string $resource
1571
     * @param string $privilege
1572
     */
1573
    public function isAllowed($resource, $privilege = null)
1574
    {
1575
        $auth = $this->getServiceManager()->get('BjyAuthorize\Service\Authorize');
1576
1577
        return $auth->isAllowed($resource, $privilege);
1578
    }
1579
1580
    public function getIp()
1581
    {
1582
        $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...
1583
        if (isset($_SERVER['HTTP_CLIENT_IP'])) {
1584
            $ipaddress = $_SERVER['HTTP_CLIENT_IP'];
1585
        } elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
1586
            $ipaddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
1587
        } elseif (isset($_SERVER['HTTP_X_FORWARDED'])) {
1588
            $ipaddress = $_SERVER['HTTP_X_FORWARDED'];
1589
        } elseif (isset($_SERVER['HTTP_FORWARDED_FOR'])) {
1590
            $ipaddress = $_SERVER['HTTP_FORWARDED_FOR'];
1591
        } elseif (isset($_SERVER['HTTP_FORWARDED'])) {
1592
            $ipaddress = $_SERVER['HTTP_FORWARDED'];
1593
        } elseif (isset($_SERVER['REMOTE_ADDR'])) {
1594
            $ipaddress = $_SERVER['REMOTE_ADDR'];
1595
        } else {
1596
            $ipaddress = 'UNKNOWN';
1597
        }
1598
1599
        return $ipaddress;
1600
    }
1601
1602
    public function getAnonymousId()
1603
    {
1604
        $anonymousId = '';
1605
        if ($_COOKIE && array_key_exists('pg_anonymous', $_COOKIE)) {
1606
            $anonymousId = $_COOKIE['pg_anonymous'];
1607
        }
1608
1609
        return $anonymousId;
1610
    }
1611
1612
    /**
1613
     *
1614
     *
1615
     * This service is ready for all types of games
1616
     *
1617
     * @param array $data
1618
     * @return \PlaygroundGame\Entity\Game
1619
     */
1620 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...
1621
    {
1622
        $title = '';
1623
        $description = '';
1624
1625
        if ($data['form_jsonified']) {
1626
            $jsonPV = json_decode($data['form_jsonified']);
1627
            foreach ($jsonPV as $element) {
1628
                if ($element->form_properties) {
1629
                    $attributes = $element->form_properties[0];
1630
                    $title = $attributes->title;
1631
                    $description = $attributes->description;
1632
1633
                    break;
1634
                }
1635
            }
1636
        }
1637
        if (! $form) {
1638
            $form = new \PlaygroundGame\Entity\PlayerForm();
1639
        }
1640
        $form->setGame($game);
1641
        $form->setTitle($title);
1642
        $form->setDescription($description);
1643
        $form->setForm($data['form_jsonified']);
1644
        $form->setFormTemplate($data['form_template']);
1645
1646
        $form = $this->getPlayerFormMapper()->insert($form);
1647
1648
        return $form;
1649
    }
1650
1651
    /**
1652
     *  getCSV creates lines of CSV and returns it.
1653
     */
1654
    public function getCSV($array)
1655
    {
1656
        ob_start(); // buffer the output ...
1657
        $out = fopen('php://output', 'w');
1658
        fputcsv($out, array_keys($array[0]), ";");
1659
        foreach ($array as $line) {
1660
            fputcsv($out, $line, ";");
1661
        }
1662
        fclose($out);
1663
        return ob_get_clean(); // ... then return it as a string!
1664
    }
1665
    
1666
    public function getAttributes($attributes)
1667
    {
1668
        $a = array();
1669
1670
        $a['name']          = isset($attributes->name)? $attributes->name : '';
1671
        $a['placeholder']   = isset($attributes->data->placeholder)? $attributes->data->placeholder : '';
1672
        $a['label']         = isset($attributes->data->label)? $attributes->data->label : '';
1673
        $a['required']      = (isset($attributes->data->required) && $attributes->data->required == 'true')?
1674
            true:
1675
            false;
1676
        $a['class']         = isset($attributes->data->class)? $attributes->data->class : '';
1677
        $a['id']            = isset($attributes->data->id)? $attributes->data->id : '';
1678
        $a['lengthMin']     = isset($attributes->data->length)? $attributes->data->length->min : '';
1679
        $a['lengthMax']     = isset($attributes->data->length)? $attributes->data->length->max : '';
1680
        $a['validator']     = isset($attributes->data->validator)? $attributes->data->validator : '';
1681
        $a['innerData']     = isset($attributes->data->innerData)? $attributes->data->innerData : array();
1682
        $a['dropdownValues']= isset($attributes->data->dropdownValues)?
1683
            $attributes->data->dropdownValues :
1684
            array();
1685
        $a['filesizeMin']   = isset($attributes->data->filesize)? $attributes->data->filesize->min : 0;
1686
        $a['filesizeMax']   = isset($attributes->data->filesize)? $attributes->data->filesize->max : 10*1024*1024;
1687
1688
        return $a;
1689
    }
1690
1691
    /**
1692
     * @param \Zend\InputFilter\InputFilter $inputFilter
1693
     */
1694
    public function decorate($element, $attr, $inputFilter)
1695
    {
1696
        $factory = new InputFactory();
1697
        $element->setAttributes(
1698
            array(
1699
                'placeholder'   => $attr['placeholder'],
1700
                'required'      => $attr['required'],
1701
                'class'         => $attr['class'],
1702
                'id'            => $attr['id']
1703
            )
1704
        );
1705
1706
        $options = array();
1707
        $options['encoding'] = 'UTF-8';
1708
        if ($attr['lengthMin'] && $attr['lengthMin'] > 0) {
1709
            $options['min'] = $attr['lengthMin'];
1710
        }
1711
        if ($attr['lengthMax'] && $attr['lengthMax'] > $attr['lengthMin']) {
1712
            $options['max'] = $attr['lengthMax'];
1713
            $element->setAttribute('maxlength', $attr['lengthMax']);
1714
            $options['messages'] = array(
1715
                \Zend\Validator\StringLength::TOO_LONG => sprintf(
1716
                    $this->getServiceLocator()->get('translator')->translate(
0 ignored issues
show
Bug introduced by
The method getServiceLocator() does not seem to exist on object<PlaygroundGame\Service\Game>.

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

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

Loading history...
1717
                        'This field contains more than %s characters',
1718
                        'playgroundgame'
1719
                    ),
1720
                    $attr['lengthMax']
1721
                )
1722
            );
1723
        }
1724
1725
        $validators = array(
1726
            array(
1727
                'name'    => 'StringLength',
1728
                'options' => $options,
1729
            ),
1730
        );
1731
        if ($attr['validator']) {
1732
            $regex = "/.*\(([^)]*)\)/";
1733
            preg_match($regex, $attr['validator'], $matches);
1734
            $valArray = array(
1735
                'name' => str_replace(
1736
                    '('.$matches[1].')',
1737
                    '',
1738
                    $attr['validator']
1739
                ),
1740
                'options' => array($matches[1])
1741
            );
1742
            $validators[] = $valArray;
1743
        }
1744
1745
        $inputFilter->add($factory->createInput(array(
1746
            'name'     => $attr['name'],
1747
            'required' => $attr['required'],
1748
            'filters'  => array(
1749
                array('name' => 'StripTags'),
1750
                array('name' => 'StringTrim'),
1751
            ),
1752
            'validators' => $validators,
1753
        )));
1754
1755
        return $element;
1756
    }
1757
    /**
1758
     * Create a ZF2 Form from json data
1759
     * @return Form
1760
     */
1761
    public function createFormFromJson($jsonForm, $id = 'jsonForm')
1762
    {
1763
        $formPV = json_decode($jsonForm);
1764
        
1765
        $form = new Form();
1766
        $form->setAttribute('id', $id);
1767
        $form->setAttribute('enctype', 'multipart/form-data');
1768
        
1769
        $inputFilter = new \Zend\InputFilter\InputFilter();
1770
        $factory = new InputFactory();
1771
        
1772
        foreach ($formPV as $element) {
1773 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...
1774
                $attr  = $this->getAttributes($element->line_text[0]);
1775
                $element = new Element\Text($attr['name']);
1776
                $element = $this->decorate($element, $attr, $inputFilter);
1777
                $form->add($element);
1778
            }
1779 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...
1780
                $attr = $this->getAttributes($element->line_password[0]);
1781
                $element = new Element\Password($attr['name']);
1782
                $element = $this->decorate($element, $attr, $inputFilter);
1783
                $form->add($element);
1784
            }
1785 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...
1786
                $attr = $this->getAttributes($element->line_hidden[0]);
1787
                $element = new Element\Hidden($attr['name']);
1788
                $element = $this->decorate($element, $attr, $inputFilter);
1789
                $form->add($element);
1790
            }
1791 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...
1792
                $attr = $this->getAttributes($element->line_email[0]);
1793
                $element = new Element\Email($attr['name']);
1794
                $element = $this->decorate($element, $attr, $inputFilter);
1795
                $form->add($element);
1796
            }
1797 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...
1798
                $attr = $this->getAttributes($element->line_radio[0]);
1799
                $element = new Element\Radio($attr['name']);
1800
1801
                $element->setLabel($attr['label']);
1802
                $element->setAttributes(
1803
                    array(
1804
                        'name'      => $attr['name'],
1805
                        'required'  => $attr['required'],
1806
                        'allowEmpty'=> !$attr['required'],
1807
                        'class'     => $attr['class'],
1808
                        'id'        => $attr['id']
1809
                    )
1810
                );
1811
                $values = array();
1812
                foreach ($attr['innerData'] as $value) {
1813
                    $values[] = $value->label;
1814
                }
1815
                $element->setValueOptions($values);
1816
        
1817
                $options = array();
1818
                $options['encoding'] = 'UTF-8';
1819
                $options['disable_inarray_validator'] = true;
1820
        
1821
                $element->setOptions($options);
1822
        
1823
                $form->add($element);
1824
        
1825
                $inputFilter->add($factory->createInput(array(
1826
                    'name'     => $attr['name'],
1827
                    'required' => $attr['required'],
1828
                    'allowEmpty' => !$attr['required'],
1829
                )));
1830
            }
1831 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...
1832
                $attr = $this->getAttributes($element->line_checkbox[0]);
1833
                $element = new Element\MultiCheckbox($attr['name']);
1834
        
1835
                $element->setLabel($attr['label']);
1836
                $element->setAttributes(
1837
                    array(
1838
                        'name'      => $attr['name'],
1839
                        'required'  => $attr['required'],
1840
                        'allowEmpty'=> !$attr['required'],
1841
                        'class'     => $attr['class'],
1842
                        'id'        => $attr['id']
1843
                    )
1844
                );
1845
1846
                $values = array();
1847
                foreach ($attr['innerData'] as $value) {
1848
                    $values[] = $value->label;
1849
                }
1850
                $element->setValueOptions($values);
1851
                $form->add($element);
1852
        
1853
                $options = array();
1854
                $options['encoding'] = 'UTF-8';
1855
                $options['disable_inarray_validator'] = true;
1856
        
1857
                $element->setOptions($options);
1858
        
1859
                $inputFilter->add($factory->createInput(array(
1860
                    'name'      => $attr['name'],
1861
                    'required'  => $attr['required'],
1862
                    'allowEmpty'=> !$attr['required'],
1863
                )));
1864
            }
1865 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...
1866
                $attr = $this->getAttributes($element->line_dropdown[0]);
1867
                $element = new Element\Select($attr['name']);
1868
1869
                $element->setLabel($attr['label']);
1870
                $element->setAttributes(
1871
                    array(
1872
                        'name'      => $attr['name'],
1873
                        'required'  => $attr['required'],
1874
                        'allowEmpty'=> !$attr['required'],
1875
                        'class'     => $attr['class'],
1876
                        'id'        => $attr['id']
1877
                    )
1878
                );
1879
                $values = array();
1880
                foreach ($attr['dropdownValues'] as $value) {
1881
                    $values[] = $value->dropdown_label;
1882
                }
1883
                $element->setValueOptions($values);
1884
                $form->add($element);
1885
        
1886
                $options = array();
1887
                $options['encoding'] = 'UTF-8';
1888
                $options['disable_inarray_validator'] = true;
1889
        
1890
                $element->setOptions($options);
1891
        
1892
                $inputFilter->add($factory->createInput(array(
1893
                    'name'     => $attr['name'],
1894
                    'required' => $attr['required'],
1895
                    'allowEmpty' => !$attr['required'],
1896
                )));
1897
            }
1898 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...
1899
                $attr = $this->getAttributes($element->line_paragraph[0]);
1900
                $element = new Element\Textarea($attr['name']);
1901
                $element = $this->decorate($element, $attr, $inputFilter);
1902
                $form->add($element);
1903
            }
1904
            if (isset($element->line_upload)) {
1905
                $attr = $this->getAttributes($element->line_upload[0]);
1906
                $element = new Element\File($attr['name']);
1907
1908
                $element->setLabel($attr['label']);
1909
                $element->setAttributes(
1910
                    array(
1911
                        'name'      => $attr['name'],
1912
                        'required'  => $attr['required'],
1913
                        'class'     => $attr['class'],
1914
                        'id'        => $attr['id']
1915
                    )
1916
                );
1917
                $form->add($element);
1918
        
1919
                $inputFilter->add($factory->createInput(array(
1920
                    'name'     => $attr['name'],
1921
                    'required' => $attr['required'],
1922
                    'validators' => array(
1923
                        array(
1924
                            'name' => '\Zend\Validator\File\Size',
1925
                            'options' => array('min' => $attr['filesizeMin'], 'max' => $attr['filesizeMax'])
1926
                        ),
1927
                        array(
1928
                            'name' => '\Zend\Validator\File\Extension',
1929
                            'options'  => array(
1930
                                'png,PNG,jpg,JPG,jpeg,JPEG,gif,GIF',
1931
                                'messages' => array(
1932
                                    \Zend\Validator\File\Extension::FALSE_EXTENSION =>'Veuillez télécharger une image'
1933
                                )
1934
                            )
1935
                        ),
1936
                    ),
1937
                )));
1938
            }
1939
        }
1940
        
1941
        $form->setInputFilter($inputFilter);
1942
        
1943
        return $form;
1944
    }
1945
1946
    /**
1947
     * Send mail for winner and/or loser
1948
     * @param \PlaygroundGame\Entity\Game $game
1949
     * @param \PlaygroundUser\Entity\User $user
1950
     * @param \PlaygroundGame\Entity\Entry $lastEntry
1951
     * @param \PlaygroundGame\Entity\Prize $prize
1952
     */
1953
    public function sendMail($game, $user, $lastEntry, $prize = null)
1954
    {
1955 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...
1956
            $game->getMailWinner() &&
1957
            $lastEntry->getWinner()
1958
        ) {
1959
            $this->sendResultMail($game, $user, $lastEntry, 'winner', $prize);
1960
        }
1961
1962 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...
1963
            $game->getMailLooser() &&
1964
            !$lastEntry->getWinner()
1965
        ) {
1966
            $this->sendResultMail($game, $user, $lastEntry, 'looser');
1967
        }
1968
    }
1969
1970
    public function getPlayerFormMapper()
1971
    {
1972
        if (null === $this->playerformMapper) {
1973
            $this->playerformMapper = $this->getServiceManager()->get('playgroundgame_playerform_mapper');
1974
        }
1975
1976
        return $this->playerformMapper;
1977
    }
1978
1979
    public function setPlayerFormMapper($playerformMapper)
1980
    {
1981
        $this->playerformMapper = $playerformMapper;
1982
1983
        return $this;
1984
    }
1985
1986
    public function getInvitationMapper()
1987
    {
1988
        if (null === $this->invitationMapper) {
1989
            $this->invitationMapper = $this->getServiceManager()->get('playgroundgame_invitation_mapper');
1990
        }
1991
1992
        return $this->invitationMapper;
1993
    }
1994
1995
    public function setInvitationMapper($invitationMapper)
1996
    {
1997
        $this->invitationMapper = $invitationMapper;
1998
1999
        return $this;
2000
    }
2001
}
2002