Completed
Push — develop ( 1e7bd2...15a723 )
by greg
03:25
created

Game::setInvitationMapper()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 6
rs 9.4286
cc 1
eloc 3
nc 1
nop 1
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 $entity
0 ignored issues
show
Bug introduced by
There is no parameter named $entity. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
59
     * @param string $formClass
60
     * @return \PlaygroundGame\Entity\Game
61
     */
62
    public function createOrUpdate(array $data, $game, $formClass)
63
    {
64
        $entityManager = $this->getServiceManager()->get('doctrine.entitymanager.orm_default');
65
66
        $form = $this->getServiceManager()->get($formClass);
67
        $form->get('publicationDate')->setOptions(array(
68
            'format' => 'Y-m-d'
69
        ));
70
        $form->get('startDate')->setOptions(array(
71
            'format' => 'Y-m-d'
72
        ));
73
        $form->get('endDate')->setOptions(array(
74
            'format' => 'Y-m-d'
75
        ));
76
        $form->get('closeDate')->setOptions(array(
77
            'format' => 'Y-m-d'
78
        ));
79
80
        $form->bind($game);
81
82
        $path = $this->getOptions()->getMediaPath() . '/';
83
        $media_url = $this->getOptions()->getMediaUrl() . '/';
84
85
        $identifierInput = $form->getInputFilter()->get('identifier');
86
        $noObjectExistsValidator = new NoObjectExistsValidator(array(
87
            'object_repository' => $entityManager->getRepository('PlaygroundGame\Entity\Game'),
88
            'fields' => 'identifier',
89
            'messages' => array(
90
                'objectFound' => 'This url already exists !'
91
            )
92
        ));
93
94
        if ($game->getIdentifier() != $data['identifier']) {
95
            $identifierInput->getValidatorChain()->addValidator($noObjectExistsValidator);
96
        }
97
98
        // I must switch from original format to the Y-m-d format because
99
        // this is the only one accepted by new DateTime($value)
100 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...
101
            $tmpDate = \DateTime::createFromFormat('d/m/Y', $data['publicationDate']);
102
            $data['publicationDate'] = $tmpDate->format('Y-m-d');
103
        }
104 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...
105
            $tmpDate = \DateTime::createFromFormat('d/m/Y', $data['startDate']);
106
            $data['startDate'] = $tmpDate->format('Y-m-d');
107
        }
108 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...
109
            $tmpDate = \DateTime::createFromFormat('d/m/Y', $data['endDate']);
110
            $data['endDate'] = $tmpDate->format('Y-m-d');
111
        }
112 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...
113
            $tmpDate = \DateTime::createFromFormat('d/m/Y', $data['closeDate']);
114
            $data['closeDate'] = $tmpDate->format('Y-m-d');
115
        }
116
117
        // If publicationDate is null, I update it with the startDate if not null neither
118
        if ((! isset($data['publicationDate']) || $data['publicationDate'] == '') &&
119
            (isset($data['startDate']) && $data['startDate'] != '')
120
        ) {
121
            $data['publicationDate'] = $data['startDate'];
122
        }
123
124
        // If the identifier has not been set, I use the title to create one.
125 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...
126
            $data['identifier'] = $data['title'];
127
        }
128
129
        $form->setData($data);
130
131
        // If someone want to claim... It's time to do it ! used for exemple by PlaygroundFacebook Module
132
        $result = $this->getEventManager()->trigger(__FUNCTION__ . '.validate', $this, array(
133
            'game' => $game,
134
            'data' => $data
135
        ));
136
        if (is_array($result) && ! $result[0]) {
137
            $form->get('fbAppId')->setMessages(array(
138
                'Vous devez d\'abord désinstaller l\'appli Facebook'
139
            ));
140
141
            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...
142
        }
143
144
        if (! $form->isValid()) {
145
            if (isset($data['publicationDate']) && $data['publicationDate']) {
146
                $tmpDate = \DateTime::createFromFormat('Y-m-d', $data['publicationDate']);
147
                $data['publicationDate'] = $tmpDate->format('d/m/Y');
148
                $form->setData(array(
149
                    'publicationDate' => $data['publicationDate']
150
                ));
151
            }
152
            if (isset($data['startDate']) && $data['startDate']) {
153
                $tmpDate = \DateTime::createFromFormat('Y-m-d', $data['startDate']);
154
                $data['startDate'] = $tmpDate->format('d/m/Y');
155
                $form->setData(array(
156
                    'startDate' => $data['startDate']
157
                ));
158
            }
159
            if (isset($data['endDate']) && $data['endDate']) {
160
                $tmpDate = \DateTime::createFromFormat('Y-m-d', $data['endDate']);
161
                $data['endDate'] = $tmpDate->format('d/m/Y');
162
                $form->setData(array(
163
                    'endDate' => $data['endDate']
164
                ));
165
            }
166
            if (isset($data['closeDate']) && $data['closeDate']) {
167
                $tmpDate = \DateTime::createFromFormat('Y-m-d', $data['closeDate']);
168
                $data['closeDate'] = $tmpDate->format('d/m/Y');
169
                $form->setData(array(
170
                    'closeDate' => $data['closeDate']
171
                ));
172
            }
173
            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...
174
        }
175
176
        $game = $form->getData();
177
        $game = $this->getGameMapper()->insert($game);
178
179
        // I wait for the game to be saved to obtain its ID.
180 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...
181
            ErrorHandler::start();
182
            $data['uploadMainImage']['name'] = $this->fileNewname(
183
                $path,
184
                $game->getId() . "-" . $data['uploadMainImage']['name']
185
            );
186
            move_uploaded_file($data['uploadMainImage']['tmp_name'], $path . $data['uploadMainImage']['name']);
187
            $game->setMainImage($media_url . $data['uploadMainImage']['name']);
188
            ErrorHandler::stop(true);
189
        }
190
191 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...
192
            $data['deleteMainImage'] &&
193
            empty($data['uploadMainImage']['tmp_name'])
194
        ) {
195
            ErrorHandler::start();
196
            $image = $game->getMainImage();
197
            $image = str_replace($media_url, '', $image);
198
            unlink($path . $image);
199
            $game->setMainImage(null);
200
            ErrorHandler::stop(true);
201
        }
202
203 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...
204
            ErrorHandler::start();
205
            $data['uploadSecondImage']['name'] = $this->fileNewname(
206
                $path,
207
                $game->getId() . "-" . $data['uploadSecondImage']['name']
208
            );
209
            move_uploaded_file($data['uploadSecondImage']['tmp_name'], $path . $data['uploadSecondImage']['name']);
210
            $game->setSecondImage($media_url . $data['uploadSecondImage']['name']);
211
            ErrorHandler::stop(true);
212
        }
213
214 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...
215
            $data['deleteSecondImage'] &&
216
            empty($data['uploadSecondImage']['tmp_name'])
217
        ) {
218
            ErrorHandler::start();
219
            $image = $game->getSecondImage();
220
            $image = str_replace($media_url, '', $image);
221
            unlink($path . $image);
222
            $game->setSecondImage(null);
223
            ErrorHandler::stop(true);
224
        }
225
226
        if (! empty($data['uploadStylesheet']['tmp_name'])) {
227
            ErrorHandler::start();
228
            move_uploaded_file($data['uploadStylesheet']['tmp_name'], $path . 'stylesheet_' . $game->getId() . '.css');
229
            $game->setStylesheet($media_url . 'stylesheet_' . $game->getId() . '.css');
230
            ErrorHandler::stop(true);
231
        }
232
233 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...
234
            ErrorHandler::start();
235
            $data['uploadFbShareImage']['name'] = $this->fileNewname(
236
                $path,
237
                $game->getId() . "-" . $data['uploadFbShareImage']['name']
238
            );
239
            move_uploaded_file($data['uploadFbShareImage']['tmp_name'], $path . $data['uploadFbShareImage']['name']);
240
            $game->setFbShareImage($media_url . $data['uploadFbShareImage']['name']);
241
            ErrorHandler::stop(true);
242
        }
243
244 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...
245
            $data['deleteFbShareImage'] &&
246
            empty($data['uploadFbShareImage']['tmp_name'])
247
        ) {
248
            ErrorHandler::start();
249
            $image = $game->getFbShareImage();
250
            $image = str_replace($media_url, '', $image);
251
            unlink($path . $image);
252
            $game->setFbShareImage(null);
253
            ErrorHandler::stop(true);
254
        }
255
256
        if (! empty($data['uploadFbPageTabImage']['tmp_name'])) {
257
            ErrorHandler::start();
258
            $extension = $this->getExtension(strtolower($data['uploadFbPageTabImage']['name']));
259
            $src = $this->getSrc($extension, $data['uploadFbPageTabImage']['tmp_name']);
260
            $this->resize(
261
                $data['uploadFbPageTabImage']['tmp_name'],
262
                $extension,
263
                $path . $game->getId() . "-" . $data['uploadFbPageTabImage']['name'],
264
                $src,
265
                111,
266
                74
267
            );
268
269
            $game->setFbPageTabImage($media_url . $game->getId() . "-" . $data['uploadFbPageTabImage']['name']);
270
            ErrorHandler::stop(true);
271
        }
272
273 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...
274
            $data['deleteFbPageTabImage'] &&
275
            empty($data['uploadFbPageTabImage']['tmp_name'])
276
        ) {
277
            ErrorHandler::start();
278
            $image = $game->getFbPageTabImage();
279
            $image = str_replace($media_url, '', $image);
280
            unlink($path . $image);
281
            $game->setFbPageTabImage(null);
282
            ErrorHandler::stop(true);
283
        }
284
285
        $game = $this->getGameMapper()->update($game);
286
287
        $prize_mapper = $this->getServiceManager()->get('playgroundgame_prize_mapper');
288
        if (isset($data['prizes'])) {
289
            foreach ($data['prizes'] as $prize_data) {
290
                if (! empty($prize_data['picture_file']['tmp_name']) && ! $prize_data['picture_file']['error']) {
291
                    if ($prize_data['id']) {
292
                        $prize = $prize_mapper->findById($prize_data['id']);
293
                    } else {
294
                        $some_prizes = $prize_mapper->findBy(array(
295
                            'game' => $game,
296
                            'title' => $prize_data['title']
297
                        ));
298
                        if (count($some_prizes) == 1) {
299
                            $prize = $some_prizes[0];
300
                        } else {
301
                            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...
302
                        }
303
                    }
304
                    // Remove if existing image
305
                    if ($prize->getPicture() && file_exists($prize->getPicture())) {
306
                        unlink($prize->getPicture());
307
                        $prize->getPicture(null);
308
                    }
309
                    // Upload and set new
310
                    ErrorHandler::start();
311
                    $filename = "game-" . $game->getId() . "-prize-";
312
                    $filename .= $prize->getId() . "-" . $prize_data['picture_file']['name'];
313
                    move_uploaded_file($prize_data['picture_file']['tmp_name'], $path . $filename);
314
                    $prize->setPicture($media_url . $filename);
315
                    ErrorHandler::stop(true);
316
                    $prize_mapper->update($prize);
317
                }
318
            }
319
        }
320
        // If I receive false, it means that the FB Id was not available anymore
321
        $this->getEventManager()->trigger(__FUNCTION__ . '.post', $this, array(
322
            'game' => $game
323
        ));
324
325
        return $game;
326
    }
327
    
328
    /**
329
     * getActiveGames
330
     *
331
     * @return Array of PlaygroundGame\Entity\Game
332
     */
333
    public function getActiveGames($displayHome = true, $classType = '', $order = '')
334
    {
335
        $em = $this->getServiceManager()->get('doctrine.entitymanager.orm_default');
336
        $today = new \DateTime("now");
337
        $today = $today->format('Y-m-d') . ' 23:59:59';
338
        $orderBy = 'g.publicationDate';
339
        if ($order != '') {
340
            $orderBy = 'g.'.$order;
341
        }
342
343
        $qb = $em->createQueryBuilder();
344
        $and = $qb->expr()->andx();
345
        $and->add(
346
            $qb->expr()->orX(
347
                $qb->expr()->lte('g.publicationDate', ':date'),
348
                $qb->expr()->isNull('g.publicationDate')
349
            )
350
        );
351
        $and->add(
352
            $qb->expr()->orX(
353
                $qb->expr()->gte('g.closeDate', ':date'),
354
                $qb->expr()->isNull('g.closeDate')
355
            )
356
        );
357
        $qb->setParameter('date', $today);
358
        
359
        $and->add($qb->expr()->eq('g.active', '1'));
360
        $and->add($qb->expr()->eq('g.broadcastPlatform', '1'));
361
        
362
        if ($classType != '') {
363
            $and->add($qb->expr()->eq('g.classType', ':classType'));
364
            $qb->setParameter('classType', $classType);
365
        }
366
        
367
        if ($displayHome) {
368
            $and->add($qb->expr()->eq('g.displayHome', true));
369
        }
370
        
371
        $qb->select('g')
372
        ->from('PlaygroundGame\Entity\Game', 'g')
373
        ->where($and)
374
        ->orderBy($orderBy, 'DESC');
375
        
376
        $query = $qb->getQuery();
377
        $games = $query->getResult();
378
        
379
        // je les classe par date de publication (date comme clé dans le tableau afin de pouvoir merger les objets
380
        // de type article avec le même procédé en les classant naturellement par date asc ou desc
381
        $arrayGames = array();
382 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...
383
            if ($game->getPublicationDate()) {
384
                $key = $game->getPublicationDate()->format('Ymd');
385
            } elseif ($game->getStartDate()) {
386
                $key = $game->getStartDate()->format('Ymd');
387
            } else {
388
                $key = $game->getUpdatedAt()->format('Ymd');
389
            }
390
            $key .= $game->getUpdatedAt()->format('Ymd') . '-' . $game->getId();
391
            $arrayGames[$key] = $game;
392
        }
393
394
        return $arrayGames;
395
    }
396
397
    /**
398
     * getAvailableGames : Games OnLine and not already played by $user
399
     *
400
     * @return Array of PlaygroundGame\Entity\Game
401
     */
402
    public function getAvailableGames($user, $maxResults = 2)
403
    {
404
        $em = $this->getServiceManager()->get('doctrine.entitymanager.orm_default');
405
        $today = new \DateTime("now");
406
        $today = $today->format('Y-m-d') . ' 23:59:59';
407
408
        // Game active with a start_date before today (or without start_date)
409
        // and end_date after today (or without end-date)
410
        $query = $em->createQuery('SELECT g FROM PlaygroundGame\Entity\Game g
411
                WHERE NOT EXISTS (SELECT l FROM PlaygroundGame\Entity\Entry l WHERE l.game = g AND l.user = :user)
412
                AND (g.startDate <= :date OR g.startDate IS NULL)
413
                AND (g.endDate >= :date OR g.endDate IS NULL)
414
                AND g.active = 1 AND g.broadcastPlatform = 1
415
                ORDER BY g.startDate ASC');
416
        $query->setParameter('date', $today);
417
        $query->setParameter('user', $user);
418
        $query->setMaxResults($maxResults);
419
        $games = $query->getResult();
420
421
        return $games;
422
    }
423
424 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...
425
    {
426
        $em = $this->getServiceManager()->get('doctrine.entitymanager.orm_default');
427
428
        $qb = $em->createQueryBuilder();
429
        $qb->select('
430
            e.id,
431
            u.username,
432
            u.title,
433
            u.firstname,
434
            u.lastname,
435
            u.email,
436
            u.optin,
437
            u.optinPartner,
438
            u.address,
439
            u.address2,
440
            u.postalCode,
441
            u.city,
442
            u.telephone,
443
            u.mobile,
444
            u.created_at,
445
            u.dob,
446
            e.winner,
447
            e.socialShares,
448
            e.playerData,
449
            e.updated_at
450
            ')
451
            ->from('PlaygroundGame\Entity\Entry', 'e')
452
            ->leftJoin('e.user', 'u')
453
            ->where($qb->expr()->eq('e.game', ':game'));
454
        
455
        $qb->setParameter('game', $game);
456
457
        return $qb->getQuery();
458
    }
459
460
    public function getEntriesHeader($game)
461
    {
462
        if ($game->getPlayerForm()) {
463
            $formPV = json_decode($game->getPlayerForm()->getForm(), true);
464
            $header = array('id'=> 1);
465 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...
466
                foreach ($element as $k => $v) {
467
                    if ($k !== 'form_properties') {
468
                        $header[$v[0]['name']] = 1;
469
                    }
470
                }
471
            }
472
        } else {
473
            $header = array(
474
                'id' => 1,
475
                'username' => 1,
476
                'title' => 1,
477
                'firstname' => 1,
478
                'lastname' => 1,
479
                'email' => 1,
480
                'optin' => 1,
481
                'optinPartner' => 1,
482
                'address' => 1,
483
                'address2' => 1,
484
                'postalCode' => 1,
485
                'city' => 1,
486
                'telephone' => 1,
487
                'mobile' => 1,
488
                'created_at' => 1,
489
                'dob' => 1,
490
                'winner' => 1
491
            );
492
        }
493
        $header['winner'] = 1;
494
        $header['socialShares'] = 1;
495
        $header['updated_at'] = 1;
496
497
        return $header;
498
    }
499
500
    /**
501
    * getGameEntries : I create an array of entries based on playerData + header
502
    *
503
    * @return Array of PlaygroundGame\Entity\Game
504
    */
505
    public function getGameEntries($header, $entries, $game)
506
    {
507
        $header = $this->getEntriesHeader($game);
508
509
        $results = array();
510
511
        foreach ($entries as $k => $entry) {
512
            $entryData = json_decode($entry['playerData'], true);
513 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...
514
                if (isset($entryData[$key])) {
515
                    $results[$k][$key] = (is_array($entryData[$key]))?implode(', ', $entryData[$key]):$entryData[$key];
516
                } elseif (array_key_exists($key, $entry)) {
517
                    $results[$k][$key] = ($entry[$key] instanceof \DateTime)?
518
                        $entry[$key]->format('Y-m-d'):
519
                        $entry[$key];
520
                } else {
521
                    $results[$k][$key] = '';
522
                }
523
            }
524
        }
525
526
        return $results;
527
    }
528
529
    /**
530
     * getActiveSliderGames
531
     *
532
     * @return Array of PlaygroundGame\Entity\Game
533
     */
534
    public function getActiveSliderGames()
535
    {
536
        $em = $this->getServiceManager()->get('doctrine.entitymanager.orm_default');
537
        $today = new \DateTime("now");
538
        $today = $today->format('Y-m-d') . ' 23:59:59';
539
540
        // Game active with a start_date before today (or without start_date)
541
        // and end_date after today (or without end-date)
542
        $query = $em->createQuery('SELECT g FROM PlaygroundGame\Entity\Game g
543
            WHERE (g.publicationDate <= :date OR g.publicationDate IS NULL)
544
            AND (g.closeDate >= :date OR g.closeDate IS NULL)
545
            AND g.active = true AND g.broadcastPlatform = 1 AND g.pushHome = true');
546
        $query->setParameter('date', $today);
547
        $games = $query->getResult();
548
549
        // je les classe par date de publication (date comme clé dans le tableau afin de pouvoir merger les objets
550
        // de type article avec le même procédé en les classant naturellement par date asc ou desc
551
        $arrayGames = array();
552 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...
553
            if ($game->getPublicationDate()) {
554
                $key = $game->getPublicationDate()->format('Ymd');
555
            } elseif ($game->getStartDate()) {
556
                $key = $game->getStartDate()->format('Ymd');
557
            } else {
558
                $key = $game->getUpdatedAt()->format('Ymd');
559
            }
560
            $key .= $game->getUpdatedAt()->format('Ymd') . '-' . $game->getId();
561
            $arrayGames[$key] = $game;
562
        }
563
564
        return $arrayGames;
565
    }
566
567
    /**
568
     * getPrizeCategoryGames
569
     *
570
     * @return Array of PlaygroundGame\Entity\Game
571
     */
572 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...
573
    {
574
        $em = $this->getServiceManager()->get('doctrine.entitymanager.orm_default');
575
576
        $query = $em->createQuery('SELECT g FROM PlaygroundGame\Entity\Game g
577
            WHERE (g.prizeCategory = :categoryid AND g.broadcastPlatform = 1)
578
            ORDER BY g.publicationDate DESC');
579
        $query->setParameter('categoryid', $categoryid);
580
        $games = $query->getResult();
581
582
        return $games;
583
    }
584
585
    public function checkGame($identifier, $checkIfStarted = true)
586
    {
587
        $gameMapper = $this->getGameMapper();
588
589
        if (! $identifier) {
590
            return false;
591
        }
592
593
        $game = $gameMapper->findByIdentifier($identifier);
594
595
        // the game has not been found
596
        if (! $game) {
597
            return false;
598
        }
599
600
        if ($this->isAllowed('game', 'edit')) {
601
            $game->setActive(true);
602
            $game->setStartDate(null);
603
            $game->setEndDate(null);
604
            $game->setPublicationDate(null);
605
            $game->setBroadcastPlatform(true);
606
607
            // I don't want the game to be updated through any update during the preview mode.
608
            // I mark it as readonly for Doctrine
609
            $this->getServiceManager()
610
                ->get('doctrine.entitymanager.orm_default')
611
                ->getUnitOfWork()
612
                ->markReadOnly($game);
613
            return $game;
614
        }
615
616
        // The game is inactive
617
        if (! $game->getActive()) {
618
            return false;
619
        }
620
621
        // the game has not begun yet
622
        if (! $game->isOpen()) {
623
            return false;
624
        }
625
626
        // the game is finished and closed
627
        if (! $game->isStarted() && $checkIfStarted) {
628
            return false;
629
        }
630
631
        return $game;
632
    }
633
634
    /**
635
     * Return the last entry of the user on this game, if it exists.
636
     * An entry can be associated to :
637
     * - A user account (a real one, linked to PlaygroundUser
638
     * - An anonymous Identifier (based on one value of playerData (generally email))
639
     * - A cookie set on the player device (the less secure)
640
     * If the active param is set, it can check if the entry is active or not.
641
     * If the bonus param is set, it can check if the entry is a bonus or not.
642
     *
643
     * @param unknown $game
644
     * @param string $user
645
     * @param boolean $active
646
     * @param boolean $bonus
647
     * @return boolean
648
     */
649
    public function checkExistingEntry($game, $user = null, $active = null, $bonus = null)
650
    {
651
        $search = array('game'  => $game);
652
653
        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...
654
            $search['user'] = $user;
655
        } elseif ($this->getAnonymousIdentifier()) {
656
            $search['anonymousIdentifier'] = $this->getAnonymousIdentifier();
657
            $search['user'] = null;
658
        } else {
659
            $search['anonymousId'] = $this->getAnonymousId();
660
            $search['user'] = null;
661
        }
662
        
663
        if (! is_null($active)) {
664
            $search['active'] = $active;
665
        }
666
        if (! is_null($bonus)) {
667
            $search['bonus'] = $bonus;
668
        }
669
670
        $entry = $this->getEntryMapper()->findOneBy($search, array('updated_at' => 'desc'));
671
672
        return $entry;
673
    }
674
675
    /*
676
    * This function updates the entry with the player data after checking 
677
    * that the data are compliant with the formUser Game attribute
678
    *
679
    * The $data has to be a json object
680
    */
681
    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...
682
    {
683
        $form = $this->createFormFromJson($game->getPlayerForm()->getForm(), 'playerForm');
684
        $form->setData($data);
685
686
        if (!$mandatory) {
687
            $filter = $form->getInputFilter();
688
            foreach ($form->getElements() as $element) {
689
                try {
690
                    $elementInput = $filter->get($element->getName());
691
                    $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...
692
                    $form->get($element->getName())->setAttribute('required', false);
693
                } 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...
694
                }
695
            }
696
        }
697
698
        if ($form->isValid()) {
699
            $dataJson = json_encode($form->getData());
700
701
            if ($game->getAnonymousAllowed() &&
702
                $game->getAnonymousIdentifier() &&
703
                isset($data[$game->getAnonymousIdentifier()])
704
            ) {
705
                $session = new \Zend\Session\Container('anonymous_identifier');
706
                if (empty($session->offsetGet('anonymous_identifier'))) {
707
                    $anonymousIdentifier = $data[$game->getAnonymousIdentifier()];
708
                
709
                    $entry->setAnonymousIdentifier($anonymousIdentifier);
710
                
711
                    // I must transmit this info during the whole game workflow
712
                    $session->offsetSet('anonymous_identifier', $anonymousIdentifier);
713
                }
714
            }
715
716
            $entry->setPlayerData($dataJson);
717
            $this->getEntryMapper()->update($entry);
718
        } else {
719
            return false;
720
        }
721
722
        return true;
723
    }
724
725
726
    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...
727
    {
728
        // If on Facebook, check if you have to be a FB fan to play the game
729
        $session = new Container('facebook');
730
731
        if ($session->offsetExists('signed_request')) {
732
            // I'm on Facebook
733
            $sr = $session->offsetGet('signed_request');
734
            if ($sr['page']['liked'] == 1) {
735
                return true;
736
            }
737
        } else {
738
            // I'm not on Facebook
739
            return true;
740
        }
741
742
        return false;
743
    }
744
    
745
    public function getAnonymousIdentifier()
746
    {
747
        if (is_null($this->anonymousIdentifier)) {
748
            // If on Facebook, check if you have to be a FB fan to play the game
749
            $session = new Container('anonymous_identifier');
750
            
751
            if ($session->offsetExists('anonymous_identifier')) {
752
                $this->anonymousIdentifier = $session->offsetGet('anonymous_identifier');
753
            } else {
754
                $this->anonymousIdentifier = false;
755
            }
756
        }
757
    
758
        return $this->anonymousIdentifier;
759
    }
760
761
    /**
762
     * errors :
763
     * -1 : user not connected
764
     * -2 : limit entry games for this user reached
765
     *
766
     * @param \PlaygroundGame\Entity\Game $game
767
     * @param \PlaygroundUser\Entity\UserInterface $user
768
     * @return number unknown
769
     */
770
    public function play($game, $user)
771
    {
772
773
        // certaines participations peuvent rester ouvertes.
774
        // On autorise alors le joueur à reprendre là ou il en était
775
        // par exemple les postvote...
776
        $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...
777
778
        if (! $entry) {
779
            if ($this->hasReachedPlayLimit($game, $user)) {
780
                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...
781
            }
782
783
            $entry = new Entry();
784
            $entry->setGame($game);
785
            $entry->setUser($user);
786
            $entry->setPoints(0);
787
            $entry->setIp($this->getIp());
788
            $entry->setAnonymousId($this->getAnonymousId());
789
            if ($this->getAnonymousIdentifier()) {
790
                $entry->setAnonymousIdentifier($this->getAnonymousIdentifier());
791
            }
792
793
            $entry = $this->getEntryMapper()->insert($entry);
794
            $this->getEventManager()->trigger(__FUNCTION__ . '.post', $this, array(
795
                'user' => $user,
796
                'game' => $game,
797
                'entry' => $entry
798
            ));
799
        }
800
801
        return $entry;
802
    }
803
804
    /**
805
     * @param \PlaygroundGame\Entity\Game $game
806
     * @param \PlaygroundUser\Entity\UserInterface $user
807
     */
808
    public function hasReachedPlayLimit($game, $user)
809
    {
810
        // Is there a limitation on the game ?
811
        $limitAmount = $game->getPlayLimit();
812
        if ($limitAmount) {
813
            $limitScale = $game->getPlayLimitScale();
814
            $userEntries = $this->findLastEntries($game, $user, $limitScale);
815
816
            // player has reached the game limit
817
            if ($userEntries >= $limitAmount) {
818
                return true;
819
            }
820
        }
821
        return false;
822
    }
823
    
824
    /**
825
     * @param \PlaygroundGame\Entity\Game $game
826
     * @param \PlaygroundUser\Entity\UserInterface $user
827
     */
828
    public function findLastEntries($game, $user, $limitScale)
829
    {
830
        $limitDate = $this->getLimitDate($limitScale);
831
832
        if ($user) {
833
            return $this->getEntryMapper()->findLastEntriesByUser($game, $user, $limitDate);
834
        } elseif ($this->getAnonymousIdentifier()) {
835
            return $this->getEntryMapper()->findLastEntriesByAnonymousIdentifier(
836
                $game,
837
                $this->getAnonymousIdentifier(),
838
                $limitDate
839
            );
840
        } else {
841
            return $this->getEntryMapper()->findLastEntriesByIp($game, $this->getIp(), $limitDate);
842
        }
843
    }
844
845
    /**
846
    *
847
    *
848
    */
849
    public function getLimitDate($limitScale)
850
    {
851
        $now = new \DateTime("now");
852
        switch ($limitScale) {
853
            case 'always':
854
                $interval = 'P100Y';
855
                $now->sub(new \DateInterval($interval));
856
                $dateLimit = $now->format('Y-m-d') . ' 0:0:0';
857
                break;
858
            case 'day':
859
                $dateLimit = $now->format('Y-m-d') . ' 0:0:0';
860
                break;
861
            case 'week':
862
                $interval = 'P7D';
863
                $now->sub(new \DateInterval($interval));
864
                $dateLimit = $now->format('Y-m-d') . ' 0:0:0';
865
                break;
866
            case 'month':
867
                $interval = 'P1M';
868
                $now->sub(new \DateInterval($interval));
869
                $dateLimit = $now->format('Y-m-d') . ' 0:0:0';
870
                break;
871
            case 'year':
872
                $interval = 'P1Y';
873
                $now->sub(new \DateInterval($interval));
874
                $dateLimit = $now->format('Y-m-d') . ' 0:0:0';
875
                break;
876
            default:
877
                $interval = 'P100Y';
878
                $now->sub(new \DateInterval($interval));
879
                $dateLimit = $now->format('Y-m-d') . ' 0:0:0';
880
        }
881
882
        return $dateLimit;
883
    }
884
885
    public function findLastActiveEntry($game, $user)
886
    {
887
        return $this->checkExistingEntry($game, $user, true);
888
    }
889
890
    public function findLastInactiveEntry($game, $user)
891
    {
892
        return $this->checkExistingEntry($game, $user, false, false);
893
    }
894
895
    public function findLastEntry($game, $user)
896
    {
897
        return $this->checkExistingEntry($game, $user, null, false);
898
    }
899
900
    public function sendShareMail(
901
        $data,
902
        $game,
903
        $user,
904
        $entry,
905
        $template = 'share_game',
906
        $topic = null,
907
        $userTimer = array()
908
    ) {
909
    
910
        $mailService = $this->getServiceManager()->get('playgroundgame_message');
911
        $mailSent = false;
912
        $from = $this->getOptions()->getEmailFromAddress();
913
        $subject = $this->getOptions()->getShareSubjectLine();
914
        $renderer = $this->getServiceManager()->get('Zend\View\Renderer\RendererInterface');
915
        if ($user) {
916
            $email = $user->getEmail();
917
        } elseif ($entry->getAnonymousIdentifier()) {
918
            $email = $entry->getAnonymousIdentifier();
919
        } else {
920
            $email = $from;
921
        }
922
        $skinUrl = $renderer->url(
923
            'frontend',
924
            array(),
925
            array('force_canonical' => true)
926
        );
927
        $secretKey = strtoupper(substr(sha1(uniqid('pg_', true) . '####' . time()), 0, 15));
928
929
        if (! $topic) {
930
            $topic = $game->getTitle();
931
        }
932
933
        $shares = json_decode($entry->getSocialShares(), true);
934
        
935
        if ($data['email1']) {
936
            $mailSent = true;
937
            $message = $mailService->createHtmlMessage(
938
                $from,
939
                $data['email1'],
940
                $subject,
941
                'playground-game/email/' . $template,
942
                array(
943
                    'game' => $game,
944
                    'email' => $email,
945
                    'secretKey' => $secretKey,
946
                    'skinUrl' => $skinUrl,
947
                    'userTimer' => $userTimer
948
                )
949
            );
950
            $mailService->send($message);
951
            
952
            if (!isset($shares['mail'])) {
953
                $shares['mail'] = 1;
954
            } else {
955
                $shares['mail'] += 1;
956
            }
957
        }
958
        if ($data['email2'] && $data['email2'] != $data['email1']) {
959
            $mailSent = true;
960
            $message = $mailService->createHtmlMessage(
961
                $from,
962
                $data['email2'],
963
                $subject,
964
                'playground-game/email/' . $template,
965
                array(
966
                    'game' => $game,
967
                    'email' => $email,
968
                    'secretKey' => $secretKey,
969
                    'skinUrl' => $skinUrl,
970
                    'userTimer' => $userTimer
971
                )
972
            );
973
            $mailService->send($message);
974
            
975
            if (!isset($shares['mail'])) {
976
                $shares['mail'] = 1;
977
            } else {
978
                $shares['mail'] += 1;
979
            }
980
        }
981
        if ($data['email3'] && $data['email3'] != $data['email2'] && $data['email3'] != $data['email1']) {
982
            $mailSent = true;
983
            $message = $mailService->createHtmlMessage(
984
                $from,
985
                $data['email3'],
986
                $subject,
987
                'playground-game/email/' . $template,
988
                array(
989
                    'game' => $game,
990
                    'email' => $email,
991
                    'secretKey' => $secretKey,
992
                    'skinUrl' => $skinUrl,
993
                    'userTimer' => $userTimer
994
                )
995
            );
996
            $mailService->send($message);
997
            
998
            if (!isset($shares['mail'])) {
999
                $shares['mail'] = 1;
1000
            } else {
1001
                $shares['mail'] += 1;
1002
            }
1003
        }
1004
        if ($data['email4'] &&
1005
            $data['email4'] != $data['email3'] &&
1006
            $data['email4'] != $data['email2'] &&
1007
            $data['email4'] != $data['email1']
1008
        ) {
1009
            $mailSent = true;
1010
            $message = $mailService->createHtmlMessage(
1011
                $from,
1012
                $data['email4'],
1013
                $subject,
1014
                'playground-game/email/' . $template,
1015
                array(
1016
                    'game' => $game,
1017
                    'email' => $email,
1018
                    'secretKey' => $secretKey,
1019
                    'skinUrl' => $skinUrl,
1020
                    'userTimer' => $userTimer
1021
                )
1022
            );
1023
            $mailService->send($message);
1024
        
1025
            if (!isset($shares['mail'])) {
1026
                $shares['mail'] = 1;
1027
            } else {
1028
                $shares['mail'] += 1;
1029
            }
1030
        }
1031
        if ($data['email5'] &&
1032
            $data['email5'] != $data['email4'] &&
1033
            $data['email5'] != $data['email3'] &&
1034
            $data['email5'] != $data['email2'] &&
1035
            $data['email5'] != $data['email1']
1036
        ) {
1037
            $mailSent = true;
1038
            $message = $mailService->createHtmlMessage(
1039
                $from,
1040
                $data['email5'],
1041
                $subject,
1042
                'playground-game/email/' . $template,
1043
                array(
1044
                    'game' => $game,
1045
                    'email' => $email,
1046
                    'secretKey' => $secretKey,
1047
                    'skinUrl' => $skinUrl,
1048
                    'userTimer' => $userTimer
1049
                )
1050
            );
1051
            $mailService->send($message);
1052
        
1053
            if (!isset($shares['mail'])) {
1054
                $shares['mail'] = 1;
1055
            } else {
1056
                $shares['mail'] += 1;
1057
            }
1058
        }
1059
        if ($mailSent) {
1060
            $sharesJson = json_encode($shares);
1061
            $entry->setSocialShares($sharesJson);
1062
            $entry = $this->getEntryMapper()->update($entry);
1063
            
1064
            $this->getEventManager()->trigger(__FUNCTION__ . '.post', $this, array(
1065
                'user' => $user,
1066
                'topic' => $topic,
1067
                'secretKey' => $secretKey,
1068
                'game' => $game,
1069
                'entry' => $entry
1070
            ));
1071
1072
            return true;
1073
        }
1074
1075
        return false;
1076
    }
1077
1078
    /**
1079
     * @param \PlaygroundGame\Entity\Game $game
1080
     * @param \PlaygroundUser\Entity\User $user
1081
     * @param Entry $entry
1082
     * @param \PlaygroundGame\Entity\Prize $prize
1083
     */
1084
    public function sendResultMail($game, $user, $entry, $template = 'entry', $prize = null)
1085
    {
1086
        $mailService = $this->getServiceManager()->get('playgroundgame_message');
1087
        $from = $this->getOptions()->getEmailFromAddress();
1088
        if ($user) {
1089
            $to = $user->getEmail();
1090
        } elseif ($entry->getAnonymousIdentifier()) {
1091
            $to = $entry->getAnonymousIdentifier();
1092
        } else {
1093
            return false;
1094
        }
1095
        $subject = $game->getTitle();
1096
        $renderer = $this->getServiceManager()->get('Zend\View\Renderer\RendererInterface');
1097
        $skinUrl = $renderer->url(
1098
            'frontend',
1099
            array(),
1100
            array('force_canonical' => true)
1101
        );
1102
        $message = $mailService->createHtmlMessage($from, $to, $subject, 'playground-game/email/' . $template, array(
1103
            'game' => $game,
1104
            'entry' => $entry,
1105
            'skinUrl' => $skinUrl,
1106
            'prize' => $prize
1107
        ));
1108
        $mailService->send($message);
1109
    }
1110
1111
    public function sendGameMail($game, $user, $post, $template = 'postvote')
1112
    {
1113
        $mailService = $this->getServiceManager()->get('playgroundgame_message');
1114
        $from = $this->getOptions()->getEmailFromAddress();
1115
        $to = $user->getEmail();
1116
        $subject = $this->getOptions()->getParticipationSubjectLine();
1117
        $renderer = $this->getServiceManager()->get('Zend\View\Renderer\RendererInterface');
1118
        $skinUrl = $renderer->url(
1119
            'frontend',
1120
            array(),
1121
            array('force_canonical' => true)
1122
        );
1123
1124
        $message = $mailService->createHtmlMessage($from, $to, $subject, 'playground-game/email/' . $template, array(
1125
            'game' => $game,
1126
            'post' => $post,
1127
            'skinUrl' => $skinUrl
1128
        ));
1129
        $mailService->send($message);
1130
    }
1131
1132 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...
1133
    {
1134
        $topic = $game->getTitle();
1135
        
1136
        $shares = json_decode($entry->getSocialShares(), true);
1137
        if (!isset($shares['fbwall'])) {
1138
            $shares['fbwall'] = 1;
1139
        } else {
1140
            $shares['fbwall'] += 1;
1141
        }
1142
        $sharesJson = json_encode($shares);
1143
        $entry->setSocialShares($sharesJson);
1144
        $entry = $this->getEntryMapper()->update($entry);
1145
        
1146
        $this->getEventManager()->trigger(__FUNCTION__ . '.post', $this, array(
1147
            'user' => $user,
1148
            'game' => $game,
1149
            'secretKey' => $secretKey,
1150
            'topic' => $topic,
1151
            'entry' => $entry
1152
        ));
1153
1154
        return true;
1155
    }
1156
1157
    public function postFbRequest($secretKey, $game, $user, $entry, $to)
1158
    {
1159
        $shares = json_decode($entry->getSocialShares(), true);
1160
        $to = explode(',', $to);
1161
        if (!isset($shares['fbrequest'])) {
1162
            $shares['fbrequest'] = count($to);
1163
        } else {
1164
            $shares['fbrequest'] += count($to);
1165
        }
1166
        $sharesJson = json_encode($shares);
1167
        $entry->setSocialShares($sharesJson);
1168
        $entry = $this->getEntryMapper()->update($entry);
1169
        
1170
        $this->getEventManager()->trigger(__FUNCTION__ . '.post', $this, array(
1171
            'user' => $user,
1172
            'game' => $game,
1173
            'secretKey' => $secretKey,
1174
            'entry' => $entry,
1175
            'invites' => count($to)
1176
        ));
1177
1178
        return true;
1179
    }
1180
1181 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...
1182
    {
1183
        $topic = $game->getTitle();
1184
1185
        $shares = json_decode($entry->getSocialShares(), true);
1186
        if (!isset($shares['fbrequest'])) {
1187
            $shares['tweet'] = 1;
1188
        } else {
1189
            $shares['tweet'] += 1;
1190
        }
1191
        $sharesJson = json_encode($shares);
1192
        $entry->setSocialShares($sharesJson);
1193
        $entry = $this->getEntryMapper()->update($entry);
1194
        
1195
        $this->getEventManager()->trigger(__FUNCTION__ . '.post', $this, array(
1196
            'user' => $user,
1197
            'game' => $game,
1198
            'secretKey' => $secretKey,
1199
            'topic' => $topic,
1200
            'entry' => $entry
1201
        ));
1202
1203
        return true;
1204
    }
1205
1206 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...
1207
    {
1208
        $topic = $game->getTitle();
1209
        
1210
        $shares = json_decode($entry->getSocialShares(), true);
1211
        if (!isset($shares['fbrequest'])) {
1212
            $shares['google'] = 1;
1213
        } else {
1214
            $shares['google'] += 1;
1215
        }
1216
        $sharesJson = json_encode($shares);
1217
        $entry->setSocialShares($sharesJson);
1218
        $entry = $this->getEntryMapper()->update($entry);
1219
1220
        $this->getEventManager()->trigger(__FUNCTION__ . '.post', $this, array(
1221
            'user' => $user,
1222
            'game' => $game,
1223
            'secretKey' => $secretKey,
1224
            'topic' => $topic,
1225
            'entry' => $entry
1226
        ));
1227
1228
        return true;
1229
    }
1230
1231
    /**
1232
     * Is it possible to trigger a bonus entry ?
1233
     *
1234
     * @param unknown_type $game
1235
     * @param unknown_type $user
1236
     */
1237
    public function allowBonus($game, $user)
1238
    {
1239
        if (! $game->getPlayBonus() || $game->getPlayBonus() == 'none') {
1240
            return false;
1241
        } elseif ($game->getPlayBonus() == 'one') {
1242
            if ($this->getEntryMapper()->findOneBy(array(
1243
                'game' => $game,
1244
                'user' => $user,
1245
                'bonus' => 1
1246
            ))) {
1247
                return false;
1248
            } else {
1249
                return true;
1250
            }
1251
        } elseif ($game->getPlayBonus() == 'per_entry') {
1252
            return $this->getEntryMapper()->checkBonusEntry($game, $user);
1253
        }
1254
1255
        return false;
1256
    }
1257
1258
    public function addAnotherEntry($game, $user, $winner = 0)
1259
    {
1260
        $entry = new Entry();
1261
        $entry->setGame($game);
1262
        $entry->setUser($user);
1263
        $entry->setPoints(0);
1264
        $entry->setIp($this->getIp());
1265
        $entry->setActive(0);
1266
        $entry->setBonus(1);
1267
        $entry->setWinner($winner);
1268
        $entry = $this->getEntryMapper()->insert($entry);
1269
1270
        return $entry;
1271
    }
1272
1273
    /**
1274
     * This bonus entry doesn't give points nor badges
1275
     * It's just there to increase the chances during the Draw
1276
     * Old Name playBonus
1277
     *
1278
     * @param PlaygroundGame\Entity\Game $game
1279
     * @param unknown $user
1280
     * @return boolean unknown
1281
     */
1282
    public function addAnotherChance($game, $user, $winner = 0)
1283
    {
1284
        if ($this->allowBonus($game, $user)) {
1285
            $this->addAnotherEntry($game, $user, $winner);
1286
1287
            return true;
1288
        }
1289
1290
        return false;
1291
    }
1292
1293
    /**
1294
     * This bonus entry doesn't give points nor badges but can play again
1295
     *
1296
     * @param PlaygroundGame\Entity\Game $game
1297
     * @param user $user
1298
     * @return boolean unknown
1299
     */
1300
    public function playAgain($game, $user, $winner = 0)
1301
    {
1302
        if ($this->allowBonus($game, $user)) {
1303
            $entry = $this->addAnotherEntry($game, $user, $winner);
1304
            $entry->setActive(1);
1305
            $entry = $this->getEntryMapper()->update($entry);
1306
            if ($entry->getActive() == 1) {
1307
                return true;
1308
            }
1309
        }
1310
1311
        return false;
1312
    }
1313
1314
    /**
1315
     * @param string $path
1316
     */
1317
    public function uploadFile($path, $file)
1318
    {
1319
        $err = $file["error"];
1320
        $message = '';
1321
        if ($err > 0) {
1322
            switch ($err) {
1323
                case '1':
1324
                    $message .= 'Max file size exceeded. (php.ini)';
1325
                    break;
1326
                case '2':
1327
                    $message .= 'Max file size exceeded.';
1328
                    break;
1329
                case '3':
1330
                    $message .= 'File upload was only partial.';
1331
                    break;
1332
                case '4':
1333
                    $message .= 'No file was attached.';
1334
                    break;
1335
                case '7':
1336
                    $message .= 'File permission denied.';
1337
                    break;
1338
                default:
1339
                    $message .= 'Unexpected error occurs.';
1340
            }
1341
1342
            return $err;
1343
        } else {
1344
            $fileNewname = $this->fileNewname($path, $file['name'], true);
1345
1346
            if (isset($file["base64"])) {
1347
                list(, $img) = explode(',', $file["base64"]);
1348
                $img = str_replace(' ', '+', $img);
1349
                $im = base64_decode($img);
1350
                if ($im !== false) {
1351
                    // getimagesizefromstring
1352
                    file_put_contents($path . $fileNewname, $im);
1353
                } else {
1354
                    return 1;
1355
                }
1356
1357
                return $fileNewname;
1358
            } else {
1359
                $adapter = new \Zend\File\Transfer\Adapter\Http();
1360
                // 1Mo
1361
                $size = new Size(array(
1362
                    'max' => 1024000
1363
                ));
1364
                $is_image = new IsImage('jpeg,png,gif,jpg');
1365
                $adapter->setValidators(array(
1366
                    $size,
1367
                    $is_image
1368
                ), $fileNewname);
1369
1370
                if (! $adapter->isValid()) {
1371
                    return false;
1372
                }
1373
1374
                @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...
1375
            }
1376
1377
            
1378
            if (class_exists("Imagick")) {
1379
                $ext = pathinfo($fileNewname, PATHINFO_EXTENSION);
1380
                $img = new \Imagick($path . $fileNewname);
1381
                $img->cropThumbnailImage(100, 100);
1382
                $img->setImageCompression(\Imagick::COMPRESSION_JPEG);
1383
                $img->setImageCompressionQuality(75);
1384
                // Strip out unneeded meta data
1385
                $img->stripImage();
1386
                $img->writeImage($path . str_replace('.'.$ext, '-thumbnail.'.$ext, $fileNewname));
1387
                ErrorHandler::stop(true);
1388
            }
1389
        }
1390
1391
        return $fileNewname;
1392
    }
1393
1394
    /**
1395
     * @param string $path
1396
     */
1397
    public function fileNewname($path, $filename, $generate = false)
1398
    {
1399
        $sanitize = new Sanitize();
1400
        $name = $sanitize->filter($filename);
1401
        $newpath = $path . $name;
1402
1403
        if ($generate) {
1404
            if (file_exists($newpath)) {
1405
                $filename = pathinfo($name, PATHINFO_FILENAME);
1406
                $ext = pathinfo($name, PATHINFO_EXTENSION);
1407
1408
                $name = $filename . '_' . rand(0, 99) . '.' . $ext;
1409
            }
1410
        }
1411
1412
        unset($sanitize);
1413
1414
        return $name;
1415
    }
1416
1417
    /**
1418
     * This function returns the list of games, order by $type
1419
     */
1420
    public function getQueryGamesOrderBy($type = 'createdAt', $order = 'DESC')
1421
    {
1422
        $em = $this->getServiceManager()->get('doctrine.entitymanager.orm_default');
1423
        $today = new \DateTime("now");
1424
        $today = $today->format('Y-m-d') . ' 23:59:59';
1425
1426
        $onlineGames = '(
1427
            (
1428
                CASE WHEN (
1429
                    g.active = 1
1430
                    AND g.broadcastPlatform = 1
1431
                    AND (g.startDate <= :date OR g.startDate IS NULL)
1432
                    AND (g.closeDate >= :date OR g.closeDate IS NULL)
1433
                ) THEN 1 ELSE 0 END
1434
            ) +
1435
            (
1436
                CASE WHEN (
1437
                    g.active = 0
1438
                    AND (g.broadcastPlatform = 0 OR g.broadcastPlatform IS NULL)
1439
                    AND g.startDate > :date
1440
                    AND g.closeDate < :date
1441
                ) THEN 1 ELSE 0 END
1442
            )
1443
        )';
1444
1445
        $qb = $em->createQueryBuilder();
1446
        $qb->select('g')->from('PlaygroundGame\Entity\Game', 'g');
1447
        
1448
        switch ($type) {
1449
            case 'startDate':
1450
                $qb->orderBy('g.startDate', $order);
1451
                break;
1452
            case 'activeGames':
1453
                $qb->orderBy('g.active', $order);
1454
                break;
1455
            case 'onlineGames':
1456
                $qb->orderBy($onlineGames, $order);
1457
                $qb->setParameter('date', $today);
1458
                break;
1459
            case 'createdAt':
1460
                $qb->orderBy('g.createdAt', $order);
1461
                break;
1462
        }
1463
1464
        $query = $qb->getQuery();
1465
1466
        return $query;
1467
    }
1468
1469
    public function draw($game)
1470
    {
1471
        $total = $game->getWinners();
1472
1473
        // I Have to know what is the User Class used
1474
        $zfcUserOptions = $this->getServiceManager()->get('zfcuser_module_options');
1475
        $userClass = $zfcUserOptions->getUserEntityClass();
1476
1477
        $result = $this->getEntryMapper()->draw($game, $userClass, $total);
1478
1479
        foreach ($result as $e) {
1480
            $e->setWinner(1);
1481
            $e = $this->getEntryMapper()->update($e);
1482
            $this->getEventManager()->trigger('win_lottery.post', $this, array(
1483
                'user' => $e->getUser(),
1484
                'game' => $game,
1485
                'entry' => $e
1486
            ));
1487
        }
1488
1489
        return $result;
1490
    }
1491
1492
    /**
1493
     * getGameMapper
1494
     *
1495
     * @return GameMapperInterface
1496
     */
1497
    public function getGameMapper()
1498
    {
1499
        if (null === $this->gameMapper) {
1500
            $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...
1501
        }
1502
1503
        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 1503 which is incompatible with the return type documented by PlaygroundGame\Service\Game::getGameMapper of type PlaygroundGame\Mapper\GameInterface.
Loading history...
1504
    }
1505
1506
    /**
1507
     * setGameMapper
1508
     *
1509
     * @param GameMapperInterface $gameMapper
1510
     * @return Game
1511
     */
1512
    public function setGameMapper(GameMapperInterface $gameMapper)
1513
    {
1514
        $this->gameMapper = $gameMapper;
1515
1516
        return $this;
1517
    }
1518
1519
    /**
1520
     * getEntryMapper
1521
     *
1522
     * @return EntryMapperInterface
1523
     */
1524
    public function getEntryMapper()
1525
    {
1526
        if (null === $this->entryMapper) {
1527
            $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...
1528
        }
1529
1530
        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 1530 which is incompatible with the return type documented by PlaygroundGame\Service\Game::getEntryMapper of type PlaygroundGame\Service\EntryMapperInterface.
Loading history...
1531
    }
1532
1533
    /**
1534
     * setEntryMapper
1535
     *
1536
     * @param EntryMapperInterface $entryMapper
1537
     * @return Game
1538
     */
1539
    public function setEntryMapper($entryMapper)
1540
    {
1541
        $this->entryMapper = $entryMapper;
1542
1543
        return $this;
1544
    }
1545
1546
    public function setOptions(ModuleOptions $options)
1547
    {
1548
        $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...
1549
1550
        return $this;
1551
    }
1552
1553
    public function getOptions()
1554
    {
1555
        if (! $this->options instanceof ModuleOptions) {
1556
            $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...
1557
                ->get('playgroundgame_module_options'));
1558
        }
1559
1560
        return $this->options;
1561
    }
1562
1563
    /**
1564
     * Retrieve service manager instance
1565
     *
1566
     * @return ServiceManager
1567
     */
1568
    public function getServiceManager()
1569
    {
1570
        return $this->serviceManager;
1571
    }
1572
1573
    /**
1574
     * Set service manager instance
1575
     *
1576
     * @param ServiceManager $serviceManager
1577
     * @return Game
1578
     */
1579
    public function setServiceManager(ServiceManager $serviceManager)
1580
    {
1581
        $this->serviceManager = $serviceManager;
1582
1583
        return $this;
1584
    }
1585
1586
    /**
1587
     * @param string $str
1588
     */
1589
    public function getExtension($str)
1590
    {
1591
        $i = strrpos($str, '.');
1592
1593
        $l = strlen($str) - $i;
1594
        $ext = substr($str, $i + 1, $l);
1595
1596
        return $ext;
1597
    }
1598
1599
    /**
1600
     * @param string $extension
1601
     */
1602
    public function getSrc($extension, $temp_path)
1603
    {
1604
        $image_src = '';
1605
        switch ($extension) {
1606
            case 'jpg':
1607
                $image_src = imagecreatefromjpeg($temp_path);
1608
                break;
1609
            case 'jpeg':
1610
                $image_src = imagecreatefromjpeg($temp_path);
1611
                break;
1612
            case 'png':
1613
                $image_src = imagecreatefrompng($temp_path);
1614
                break;
1615
            case 'gif':
1616
                $image_src = imagecreatefromgif($temp_path);
1617
                break;
1618
        }
1619
1620
        return $image_src;
1621
    }
1622
1623
    /**
1624
     * @param string $extension
1625
     * @param string $rep
1626
     * @param integer $mini_width
1627
     * @param integer $mini_height
1628
     */
1629
    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...
1630
    {
1631
        list($src_width, $src_height) = getimagesize($tmp_file);
1632
1633
        $ratio_src = $src_width / $src_height;
1634
        $ratio_mini = $mini_width / $mini_height;
1635
1636
        if ($ratio_src >= $ratio_mini) {
1637
            $new_height_mini = $mini_height;
1638
            $new_width_mini = $src_width / ($src_height / $mini_height);
1639
        } else {
1640
            $new_width_mini = $mini_width;
1641
            $new_height_mini = $src_height / ($src_width / $mini_width);
1642
        }
1643
1644
        $new_image_mini = imagecreatetruecolor($mini_width, $mini_height);
1645
1646
        imagecopyresampled(
1647
            $new_image_mini,
1648
            $src,
1649
            0 - ($new_width_mini - $mini_width) / 2,
1650
            0 - ($new_height_mini - $mini_height) / 2,
1651
            0,
1652
            0,
1653
            $new_width_mini,
1654
            $new_height_mini,
1655
            $src_width,
1656
            $src_height
1657
        );
1658
        imagejpeg($new_image_mini, $rep);
1659
1660
        imagedestroy($new_image_mini);
1661
    }
1662
1663
    public function getGameEntity()
1664
    {
1665
        return new \PlaygroundGame\Entity\Game();
1666
    }
1667
1668
    /**
1669
     * @param string $resource
1670
     * @param string $privilege
1671
     */
1672
    public function isAllowed($resource, $privilege = null)
1673
    {
1674
        $auth = $this->getServiceManager()->get('BjyAuthorize\Service\Authorize');
1675
1676
        return $auth->isAllowed($resource, $privilege);
1677
    }
1678
1679
    public function getIp()
1680
    {
1681
        $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...
1682
        if (isset($_SERVER['HTTP_CLIENT_IP'])) {
1683
            $ipaddress = $_SERVER['HTTP_CLIENT_IP'];
1684
        } elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
1685
            $ipaddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
1686
        } elseif (isset($_SERVER['HTTP_X_FORWARDED'])) {
1687
            $ipaddress = $_SERVER['HTTP_X_FORWARDED'];
1688
        } elseif (isset($_SERVER['HTTP_FORWARDED_FOR'])) {
1689
            $ipaddress = $_SERVER['HTTP_FORWARDED_FOR'];
1690
        } elseif (isset($_SERVER['HTTP_FORWARDED'])) {
1691
            $ipaddress = $_SERVER['HTTP_FORWARDED'];
1692
        } elseif (isset($_SERVER['REMOTE_ADDR'])) {
1693
            $ipaddress = $_SERVER['REMOTE_ADDR'];
1694
        } else {
1695
            $ipaddress = 'UNKNOWN';
1696
        }
1697
1698
        return $ipaddress;
1699
    }
1700
1701
    public function getAnonymousId()
1702
    {
1703
        $anonymousId = '';
1704
        if ($_COOKIE && array_key_exists('pg_anonymous', $_COOKIE)) {
1705
            $anonymousId = $_COOKIE['pg_anonymous'];
1706
        }
1707
1708
        return $anonymousId;
1709
    }
1710
1711
    /**
1712
     *
1713
     *
1714
     * This service is ready for all types of games
1715
     *
1716
     * @param array $data
1717
     * @return \PlaygroundGame\Entity\Game
1718
     */
1719 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...
1720
    {
1721
        $title = '';
1722
        $description = '';
1723
1724
        if ($data['form_jsonified']) {
1725
            $jsonPV = json_decode($data['form_jsonified']);
1726
            foreach ($jsonPV as $element) {
1727
                if ($element->form_properties) {
1728
                    $attributes = $element->form_properties[0];
1729
                    $title = $attributes->title;
1730
                    $description = $attributes->description;
1731
1732
                    break;
1733
                }
1734
            }
1735
        }
1736
        if (! $form) {
1737
            $form = new \PlaygroundGame\Entity\PlayerForm();
1738
        }
1739
        $form->setGame($game);
1740
        $form->setTitle($title);
1741
        $form->setDescription($description);
1742
        $form->setForm($data['form_jsonified']);
1743
        $form->setFormTemplate($data['form_template']);
1744
1745
        $form = $this->getPlayerFormMapper()->insert($form);
1746
1747
        return $form;
1748
    }
1749
1750
    /**
1751
     *  getCSV creates lines of CSV and returns it.
1752
     */
1753
    public function getCSV($array)
1754
    {
1755
        ob_start(); // buffer the output ...
1756
        $out = fopen('php://output', 'w');
1757
        fputcsv($out, array_keys($array[0]), ";");
1758
        foreach ($array as $line) {
1759
            fputcsv($out, $line, ";");
1760
        }
1761
        fclose($out);
1762
        return ob_get_clean(); // ... then return it as a string!
1763
    }
1764
    
1765
    public function getAttributes($attributes)
1766
    {
1767
        $a = array();
1768
1769
        $a['name']          = isset($attributes->name)? $attributes->name : '';
1770
        $a['placeholder']   = isset($attributes->data->placeholder)? $attributes->data->placeholder : '';
1771
        $a['label']         = isset($attributes->data->label)? $attributes->data->label : '';
1772
        $a['required']      = (isset($attributes->data->required) && $attributes->data->required == 'true')?
1773
            true:
1774
            false;
1775
        $a['class']         = isset($attributes->data->class)? $attributes->data->class : '';
1776
        $a['id']            = isset($attributes->data->id)? $attributes->data->id : '';
1777
        $a['lengthMin']     = isset($attributes->data->length)? $attributes->data->length->min : '';
1778
        $a['lengthMax']     = isset($attributes->data->length)? $attributes->data->length->max : '';
1779
        $a['validator']     = isset($attributes->data->validator)? $attributes->data->validator : '';
1780
        $a['innerData']     = isset($attributes->data->innerData)? $attributes->data->innerData : array();
1781
        $a['dropdownValues']= isset($attributes->data->dropdownValues)?
1782
            $attributes->data->dropdownValues :
1783
            array();
1784
        $a['filesizeMin']   = isset($attributes->data->filesize)? $attributes->data->filesize->min : 0;
1785
        $a['filesizeMax']   = isset($attributes->data->filesize)? $attributes->data->filesize->max : 10*1024*1024;
1786
1787
        return $a;
1788
    }
1789
1790
    public function decorate($element, $attr, $inputFilter)
1791
    {
1792
        $factory = new InputFactory();
1793
        $element->setAttributes(
1794
            array(
1795
                'placeholder'   => $attr['placeholder'],
1796
                'required'      => $attr['required'],
1797
                'class'         => $attr['class'],
1798
                'id'            => $attr['id']
1799
            )
1800
        );
1801
1802
        $options = array();
1803
        $options['encoding'] = 'UTF-8';
1804
        if ($attr['lengthMin'] && $attr['lengthMin'] > 0) {
1805
            $options['min'] = $attr['lengthMin'];
1806
        }
1807
        if ($attr['lengthMax'] && $attr['lengthMax'] > $attr['lengthMin']) {
1808
            $options['max'] = $attr['lengthMax'];
1809
            $element->setAttribute('maxlength', $attr['lengthMax']);
1810
            $options['messages'] = array(
1811
                \Zend\Validator\StringLength::TOO_LONG => sprintf(
1812
                    $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...
1813
                        'This field contains more than %s characters',
1814
                        'playgroundgame'
1815
                    ),
1816
                    $attr['lengthMax']
1817
                )
1818
            );
1819
        }
1820
1821
        $validators = array(
1822
            array(
1823
                'name'    => 'StringLength',
1824
                'options' => $options,
1825
            ),
1826
        );
1827
        if ($attr['validator']) {
1828
            $regex = "/.*\(([^)]*)\)/";
1829
            preg_match($regex, $attr['validator'], $matches);
1830
            $valArray = array(
1831
                'name' => str_replace(
1832
                    '('.$matches[1].')',
1833
                    '',
1834
                    $attr['validator']
1835
                ),
1836
                'options' => array($matches[1])
1837
            );
1838
            $validators[] = $valArray;
1839
        }
1840
1841
        $inputFilter->add($factory->createInput(array(
1842
            'name'     => $attr['name'],
1843
            'required' => $attr['required'],
1844
            'filters'  => array(
1845
                array('name' => 'StripTags'),
1846
                array('name' => 'StringTrim'),
1847
            ),
1848
            'validators' => $validators,
1849
        )));
1850
1851
        return $element;
1852
    }
1853
    /**
1854
     * Create a ZF2 Form from json data
1855
     * @return Form
1856
     */
1857
    public function createFormFromJson($jsonForm, $id = 'jsonForm')
1858
    {
1859
        $formPV = json_decode($jsonForm);
1860
        
1861
        $form = new Form();
1862
        $form->setAttribute('id', $id);
1863
        $form->setAttribute('enctype', 'multipart/form-data');
1864
        
1865
        $inputFilter = new \Zend\InputFilter\InputFilter();
1866
        $factory = new InputFactory();
1867
        
1868
        foreach ($formPV as $element) {
1869 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...
1870
                $attr  = $this->getAttributes($element->line_text[0]);
1871
                $element = new Element\Text($attr['name']);
1872
                $element = $this->decorate($element, $attr, $inputFilter);
1873
                $form->add($element);
1874
            }
1875 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...
1876
                $attr = $this->getAttributes($element->line_password[0]);
1877
                $element = new Element\Password($attr['name']);
1878
                $element = $this->decorate($element, $attr, $inputFilter);
1879
                $form->add($element);
1880
            }
1881 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...
1882
                $attr = $this->getAttributes($element->line_hidden[0]);
1883
                $element = new Element\Hidden($attr['name']);
1884
                $element = $this->decorate($element, $attr, $inputFilter);
1885
                $form->add($element);
1886
            }
1887 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...
1888
                $attr = $this->getAttributes($element->line_email[0]);
1889
                $element = new Element\Email($attr['name']);
1890
                $element = $this->decorate($element, $attr, $inputFilter);
1891
                $form->add($element);
1892
            }
1893 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...
1894
                $attr = $this->getAttributes($element->line_radio[0]);
1895
                $element = new Element\Radio($attr['name']);
1896
1897
                $element->setLabel($attr['label']);
1898
                $element->setAttributes(
1899
                    array(
1900
                        'name'      => $attr['name'],
1901
                        'required'  => $attr['required'],
1902
                        'allowEmpty'=> !$attr['required'],
1903
                        'class'     => $attr['class'],
1904
                        'id'        => $attr['id']
1905
                    )
1906
                );
1907
                $values = array();
1908
                foreach ($attr['innerData'] as $value) {
1909
                    $values[] = $value->label;
1910
                }
1911
                $element->setValueOptions($values);
1912
        
1913
                $options = array();
1914
                $options['encoding'] = 'UTF-8';
1915
                $options['disable_inarray_validator'] = true;
1916
        
1917
                $element->setOptions($options);
1918
        
1919
                $form->add($element);
1920
        
1921
                $inputFilter->add($factory->createInput(array(
1922
                    'name'     => $attr['name'],
1923
                    'required' => $attr['required'],
1924
                    'allowEmpty' => !$attr['required'],
1925
                )));
1926
            }
1927 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...
1928
                $attr = $this->getAttributes($element->line_checkbox[0]);
1929
                $element = new Element\MultiCheckbox($attr['name']);
1930
        
1931
                $element->setLabel($attr['label']);
1932
                $element->setAttributes(
1933
                    array(
1934
                        'name'      => $attr['name'],
1935
                        'required'  => $attr['required'],
1936
                        'allowEmpty'=> !$attr['required'],
1937
                        'class'     => $attr['class'],
1938
                        'id'        => $attr['id']
1939
                    )
1940
                );
1941
1942
                $values = array();
1943
                foreach ($attr['innerData'] as $value) {
1944
                    $values[] = $value->label;
1945
                }
1946
                $element->setValueOptions($values);
1947
                $form->add($element);
1948
        
1949
                $options = array();
1950
                $options['encoding'] = 'UTF-8';
1951
                $options['disable_inarray_validator'] = true;
1952
        
1953
                $element->setOptions($options);
1954
        
1955
                $inputFilter->add($factory->createInput(array(
1956
                    'name'      => $attr['name'],
1957
                    'required'  => $attr['required'],
1958
                    'allowEmpty'=> !$attr['required'],
1959
                )));
1960
            }
1961 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...
1962
                $attr = $this->getAttributes($element->line_dropdown[0]);
1963
                $element = new Element\Select($attr['name']);
1964
1965
                $element->setLabel($attr['label']);
1966
                $element->setAttributes(
1967
                    array(
1968
                        'name'      => $attr['name'],
1969
                        'required'  => $attr['required'],
1970
                        'allowEmpty'=> !$attr['required'],
1971
                        'class'     => $attr['class'],
1972
                        'id'        => $attr['id']
1973
                    )
1974
                );
1975
                $values = array();
1976
                foreach ($attr['dropdownValues'] as $value) {
1977
                    $values[] = $value->dropdown_label;
1978
                }
1979
                $element->setValueOptions($values);
1980
                $form->add($element);
1981
        
1982
                $options = array();
1983
                $options['encoding'] = 'UTF-8';
1984
                $options['disable_inarray_validator'] = true;
1985
        
1986
                $element->setOptions($options);
1987
        
1988
                $inputFilter->add($factory->createInput(array(
1989
                    'name'     => $attr['name'],
1990
                    'required' => $attr['required'],
1991
                    'allowEmpty' => !$attr['required'],
1992
                )));
1993
            }
1994 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...
1995
                $attr = $this->getAttributes($element->line_paragraph[0]);
1996
                $element = new Element\Textarea($attr['name']);
1997
                $element = $this->decorate($element, $attr, $inputFilter);
1998
                $form->add($element);
1999
            }
2000
            if (isset($element->line_upload)) {
2001
                $attr = $this->getAttributes($element->line_upload[0]);
2002
                $element = new Element\File($attr['name']);
2003
2004
                $element->setLabel($attr['label']);
2005
                $element->setAttributes(
2006
                    array(
2007
                        'name'      => $attr['name'],
2008
                        'required'  => $attr['required'],
2009
                        'class'     => $attr['class'],
2010
                        'id'        => $attr['id']
2011
                    )
2012
                );
2013
                $form->add($element);
2014
        
2015
                $inputFilter->add($factory->createInput(array(
2016
                    'name'     => $attr['name'],
2017
                    'required' => $attr['required'],
2018
                    'validators' => array(
2019
                        array(
2020
                            'name' => '\Zend\Validator\File\Size',
2021
                            'options' => array('min' => $attr['filesizeMin'], 'max' => $attr['filesizeMax'])
2022
                        ),
2023
                        array(
2024
                            'name' => '\Zend\Validator\File\Extension',
2025
                            'options'  => array(
2026
                                'png,PNG,jpg,JPG,jpeg,JPEG,gif,GIF',
2027
                                'messages' => array(
2028
                                    \Zend\Validator\File\Extension::FALSE_EXTENSION =>'Veuillez télécharger une image'
2029
                                )
2030
                            )
2031
                        ),
2032
                    ),
2033
                )));
2034
            }
2035
        }
2036
        
2037
        $form->setInputFilter($inputFilter);
2038
        
2039
        return $form;
2040
    }
2041
2042
    /**
2043
     * Send mail for winner and/or loser
2044
     * @param \PlaygroundGame\Entity\Game $game
2045
     * @param \PlaygroundUser\Entity\User $user
2046
     * @param \PlaygroundGame\Entity\Entry $lastEntry
2047
     * @param \PlaygroundGame\Entity\Prize $prize
2048
     */
2049
    public function sendMail($game, $user, $lastEntry, $prize = null)
2050
    {
2051 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...
2052
            $game->getMailWinner() &&
2053
            $lastEntry->getWinner()
2054
        ) {
2055
            $this->sendResultMail($game, $user, $lastEntry, 'winner', $prize);
2056
        }
2057
2058 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...
2059
            $game->getMailLooser() &&
2060
            !$lastEntry->getWinner()
2061
        ) {
2062
            $this->sendResultMail($game, $user, $lastEntry, 'looser');
2063
        }
2064
    }
2065
2066
    public function getPlayerFormMapper()
2067
    {
2068
        if (null === $this->playerformMapper) {
2069
            $this->playerformMapper = $this->getServiceManager()->get('playgroundgame_playerform_mapper');
2070
        }
2071
2072
        return $this->playerformMapper;
2073
    }
2074
2075
    public function setPlayerFormMapper($playerformMapper)
2076
    {
2077
        $this->playerformMapper = $playerformMapper;
2078
2079
        return $this;
2080
    }
2081
2082
    public function getInvitationMapper()
2083
    {
2084
        if (null === $this->invitationMapper) {
2085
            $this->invitationMapper = $this->getServiceManager()->get('playgroundgame_invitation_mapper');
2086
        }
2087
2088
        return $this->invitationMapper;
2089
    }
2090
2091
    public function setInvitationMapper($invitationMapper)
2092
    {
2093
        $this->invitationMapper = $invitationMapper;
2094
2095
        return $this;
2096
    }
2097
}
2098