Completed
Push — develop ( 02d169...4593a9 )
by greg
02:27
created

Game::sendResultMail()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 29
rs 9.456
c 0
b 0
f 0
cc 3
nc 3
nop 5
1
<?php
2
namespace PlaygroundGame\Service;
3
4
use PlaygroundGame\Entity\Entry;
5
use Zend\Session\Container;
6
use Zend\ServiceManager\ServiceManager;
7
use Zend\EventManager\EventManagerAwareTrait;
8
use Zend\EventManager\EventManager;
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
use Zend\ServiceManager\ServiceLocatorInterface;
20
21
class Game
22
{
23
    use EventManagerAwareTrait;
24
25
    /**
26
     *
27
     * @var GameMapperInterface
28
     */
29
    protected $gameMapper;
30
31
    /**
32
     *
33
     * @var EntryMapperInterface
34
     */
35
    protected $entryMapper;
36
37
    /**
38
     *
39
     * @var UserServiceOptionsInterface
40
     */
41
    protected $options;
42
43
    protected $playerformMapper;
44
45
    protected $invitationMapper;
46
47
    protected $userMapper;
48
    
49
    protected $anonymousIdentifier = null;
50
51
    /**
52
     *
53
     * @var ServiceManager
54
     */
55
    protected $serviceLocator;
56
57
    protected $event;
58
59
    public function __construct(ServiceLocatorInterface $locator)
60
    {
61
        $this->serviceLocator = $locator;
0 ignored issues
show
Documentation Bug introduced by
$locator is of type object<Zend\ServiceManag...erviceLocatorInterface>, but the property $serviceLocator was declared to be of type object<Zend\ServiceManager\ServiceManager>. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof 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 given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
62
    }
63
64 View Code Duplication
    public function getEventManager() {
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...
65
        if (null === $this->event) {
66
            $this->event = new EventManager($this->serviceLocator->get('SharedEventManager'), [get_class($this)]);
67
        }
68
69
        return $this->event;
70
    }
71
72 View Code Duplication
    public function getGameUserPath($game, $user)
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...
73
    {
74
        $path = $this->getOptions()->getMediaPath() . DIRECTORY_SEPARATOR;
75
        $path .= 'game' . $game->getId() . DIRECTORY_SEPARATOR;
76
        if (!is_dir($path)) {
77
            mkdir($path, 0777, true);
78
        }
79
        $path .= 'user'. $user->getId() . DIRECTORY_SEPARATOR;
80
        if (!is_dir($path)) {
81
            mkdir($path, 0777, true);
82
        }
83
84
        return $path;
85
    }
86
87 View Code Duplication
    public function getGameUserMediaUrl($game, $user)
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...
88
    {
89
        $media_url = $this->getOptions()->getMediaUrl() . '/';
90
        $media_url .= 'game' . $game->getId() . '/' . 'user'. $user->getId() . '/';
91
92
        return $media_url;
93
    }
94
95
    /**
96
     *
97
     * This service is ready for all types of games
98
     *
99
     * @param array $data
100
     * @param string $formClass
101
     * @return \PlaygroundGame\Entity\Game
102
     */
103
    public function createOrUpdate(array $data, $game, $formClass)
104
    {
105
        $entityManager = $this->serviceLocator->get('doctrine.entitymanager.orm_default');
106
107
        $form = $this->serviceLocator->get($formClass);
108
        $form->get('publicationDate')->setOptions(array(
109
            'format' => 'Y-m-d H:i:s'
110
        ));
111
        $form->get('startDate')->setOptions(array(
112
            'format' => 'Y-m-d H:i:s'
113
        ));
114
        $form->get('endDate')->setOptions(array(
115
            'format' => 'Y-m-d H:i:s'
116
        ));
117
        $form->get('closeDate')->setOptions(array(
118
            'format' => 'Y-m-d H:i:s'
119
        ));
120
121
        $form->bind($game);
122
123
        $path = $this->getOptions()->getMediaPath() . '/';
124
        if (!is_dir($path)) {
125
            mkdir($path, 0777, true);
126
        }
127
        $media_url = $this->getOptions()->getMediaUrl() . '/';
128
129
        $identifierInput = $form->getInputFilter()->get('identifier');
130
        $noObjectExistsValidator = new NoObjectExistsValidator(array(
131
            'object_repository' => $entityManager->getRepository('PlaygroundGame\Entity\Game'),
132
            'fields' => 'identifier',
133
            'messages' => array(
134
                'objectFound' => 'This url already exists !'
135
            )
136
        ));
137
138
        if ($game->getIdentifier() != $data['identifier']) {
139
            $identifierInput->getValidatorChain()->addValidator($noObjectExistsValidator);
140
        }
141
142
        // I must switch from original format to the Y-m-d format because
143
        // this is the only one accepted by new DateTime($value)
144 View Code Duplication
        if (isset($data['publicationDate']) && $data['publicationDate']) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

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

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...
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...
924
925
        if (! $entry) {
926
            if ($this->hasReachedPlayLimit($game, $user)) {
927
                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...
928
            }
929
            if (!$this->payToPlay($game, $user)) {
930
                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...
931
            }
932
933
            $ip = $this->getIp();
934
            $geoloc = $this->getGeoloc($ip);
935
            $entry = new Entry();
936
            $entry->setGame($game);
0 ignored issues
show
Documentation introduced by
$game is of type object<PlaygroundGame\Entity\Game>, but the function expects a object<PlaygroundGame\Entity\field_type>.

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...
937
            $entry->setUser($user);
0 ignored issues
show
Documentation introduced by
$user is of type object<PlaygroundUser\Entity\UserInterface>, but the function expects a object<PlaygroundGame\Entity\field_type>.

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...
938
            $entry->setPoints(0);
939
            $entry->setIp($ip);
940
            $entry->setGeoloc($geoloc);
0 ignored issues
show
Documentation introduced by
$geoloc is of type string, but the function expects a object<PlaygroundGame\Entity\field_type>.

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...
941
            $entry->setAnonymousId($this->getAnonymousId());
942
            if ($this->getAnonymousIdentifier()) {
943
                $entry->setAnonymousIdentifier($this->getAnonymousIdentifier());
944
            }
945
946
            $entry = $this->getEntryMapper()->insert($entry);
947
            $this->getEventManager()->trigger(
948
                __FUNCTION__ . '.post',
949
                $this,
950
                [
951
                    'user' => $user,
952
                    'game' => $game,
953
                    'entry' => $entry,
954
                ]
955
            );
956
        }
957
958
        return $entry;
959
    }
960
961
    /**
962
     * @param \PlaygroundGame\Entity\Game $game
963
     * @param \PlaygroundUser\Entity\UserInterface $user
964
     */
965
    public function hasReachedPlayLimit($game, $user)
966
    {
967
        // Is there a limitation on the game ?
968
        $limitAmount = $game->getPlayLimit();
969
        if ($limitAmount) {
970
            $limitScale = $game->getPlayLimitScale();
971
            $userEntries = $this->findLastEntries($game, $user, $limitScale);
972
973
            // player has reached the game limit
974
            if ($userEntries >= $limitAmount) {
975
                return true;
976
            }
977
        }
978
        return false;
979
    }
980
981
    /**
982
     * If the game has a cost to be played (costToPlay>0)
983
     * I check and decrement the price from the leaderboard all of the user
984
     * 
985
     * @param \PlaygroundGame\Entity\Game $game
986
     * @param \PlaygroundUser\Entity\UserInterface $user
987
     */
988
    public function payToPlay($game, $user)
989
    {
990
        // Is there a limitation on the game ?
991
        $cost = $game->getCostToPlay();
992
        if ($cost && $cost > 0) {
993
            $availableAmount = $this->getEventManager()->trigger(
994
                'leaderboardUserTotal',
995
                $this,
996
                [
997
                    'user' => $user,
998
                ]
999
            )->last();
1000
            if ($availableAmount && $availableAmount >= $cost) {
1001
                $leaderboard = $this->getEventManager()->trigger(
1002
                    'leaderboardUserUpdate',
1003
                    $this,
1004
                    [
1005
                        'user' => $user,
1006
                        'points' => -$cost,
1007
                    ]
1008
                )->last();
1009
1010
                if ($leaderboard->getTotalPoints() === ($availableAmount - $cost)) {
1011
                    return true;
1012
                }
1013
            }
1014
        } else {
1015
            return true;
1016
        }
1017
1018
        return false;
1019
    }
1020
    
1021
    /**
1022
     * @param \PlaygroundGame\Entity\Game $game
1023
     * @param \PlaygroundUser\Entity\UserInterface $user
1024
     */
1025
    public function findLastEntries($game, $user, $limitScale)
1026
    {
1027
        $limitDate = $this->getLimitDate($limitScale);
1028
1029
        if ($user) {
1030
            return $this->getEntryMapper()->countLastEntriesByUser($game, $user, $limitDate);
1031
        } elseif ($this->getAnonymousIdentifier()) {
1032
            $entries = $this->getEntryMapper()->countLastEntriesByAnonymousIdentifier(
1033
                $game,
1034
                $this->getAnonymousIdentifier(),
1035
                $limitDate
1036
            );
1037
1038
            return $entries;
1039 View Code Duplication
        } else {
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...
1040
            // If the game is supposed to be a reguler user game or an anonymous identified game,
1041
            // it means that the registration/login is at the end of the game
1042
            if((!$user &&  !$game->getAnonymousAllowed()) || ($game->getAnonymousAllowed() && $game->getAnonymousIdentifier())) {
1043
                return 0;
1044
            }
1045
            return $this->getEntryMapper()->countLastEntriesByIp($game, $this->getIp(), $limitDate);
1046
        }
1047
    }
1048
1049
    /**
1050
    *
1051
    *
1052
    */
1053
    public function getLimitDate($limitScale)
1054
    {
1055
        $now = new \DateTime("now");
1056
        switch ($limitScale) {
1057
            case 'always':
1058
                $interval = 'P100Y';
1059
                $now->sub(new \DateInterval($interval));
1060
                $dateLimit = $now->format('Y-m-d') . ' 0:0:0';
1061
                break;
1062
            case 'day':
1063
                $dateLimit = $now->format('Y-m-d') . ' 0:0:0';
1064
                break;
1065 View Code Duplication
            case 'week':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
1066
                $interval = 'P7D';
1067
                $now->sub(new \DateInterval($interval));
1068
                $dateLimit = $now->format('Y-m-d') . ' 0:0:0';
1069
                break;
1070 View Code Duplication
            case 'month':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
1071
                $interval = 'P1M';
1072
                $now->sub(new \DateInterval($interval));
1073
                $dateLimit = $now->format('Y-m-d') . ' 0:0:0';
1074
                break;
1075 View Code Duplication
            case 'year':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
1076
                $interval = 'P1Y';
1077
                $now->sub(new \DateInterval($interval));
1078
                $dateLimit = $now->format('Y-m-d') . ' 0:0:0';
1079
                break;
1080 View Code Duplication
            default:
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...
1081
                $interval = 'P100Y';
1082
                $now->sub(new \DateInterval($interval));
1083
                $dateLimit = $now->format('Y-m-d') . ' 0:0:0';
1084
        }
1085
1086
        return $dateLimit;
1087
    }
1088
1089
    public function findLastActiveEntry($game, $user)
1090
    {
1091
        return $this->checkExistingEntry($game, $user, true);
1092
    }
1093
1094
    public function findLastInactiveEntry($game, $user)
1095
    {
1096
        return $this->checkExistingEntry($game, $user, false, false);
1097
    }
1098
1099
    public function findLastEntry($game, $user)
1100
    {
1101
        return $this->checkExistingEntry($game, $user, null, false);
1102
    }
1103
1104
    public function inviteToTeam($data, $game, $user)
1105
    {
1106
        $mailService = $this->serviceLocator->get('playgroundgame_message');
1107
        $invitationMapper = $this->serviceLocator->get('playgroundgame_invitation_mapper');
1108
1109
        $sentInvitations = $invitationMapper->findBy(array('host' => $user, 'game' => $game));
1110
        $nbInvitations = count($sentInvitations);
1111
        $to = $data['email'];
1112
        if (empty($to)) {
1113
            return ['result'=>false, 'message'=>'no email'];
1114
        }
1115
1116
        if ($nbInvitations < 20) {
1117
            $alreadyInvited = $invitationMapper->findBy(array('requestKey' => $to, 'game' => $game));
1118
            if (!$alreadyInvited) {
1119
                $alreadyInvited = $this->getUserMapper()->findByEmail($to);
1120
            }
1121
1122
            if (empty($alreadyInvited)) {
1123
                $invitation = new \PlaygroundGame\Entity\Invitation();
1124
                $invitation->setRequestKey($to);
1125
                $invitation->setGame($game);
1126
                $invitation->setHost($user);
1127
                $invitationMapper->insert($invitation);
1128
1129
                $from = $this->getOptions()->getEmailFromAddress();
1130
                $subject = $this->serviceLocator->get('MvcTranslator')->translate(
1131
                    $this->getOptions()->getInviteToTeamSubjectLine(),
1132
                    'playgroundgame'
1133
                );
1134
                $message = $mailService->createHtmlMessage(
1135
                    $from,
1136
                    $to,
1137
                    $subject,
1138
                    'playground-game/email/invite_team',
1139
                    array(
1140
                        'game' => $game,
1141
                        'user' => $user,
1142
                        'data' => $data,
1143
                        'from' => $from
1144
                    )
1145
                );
1146
                try {
1147
                    $mailService->send($message);
1148
                } catch (\Zend\Mail\Protocol\Exception\RuntimeException $e) {
0 ignored issues
show
Bug introduced by
The class Zend\Mail\Protocol\Exception\RuntimeException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
1149
                    return ['result' => true, 'message' => $this->serviceLocator->get('MvcTranslator')->translate(
1150
                        'mail error'
1151
                    )];
1152
                }
1153
1154
                return ['result' => true, 'message' => ''];
1155
            } else {
1156
                return ['result' => false, 'message' => 'already invited'];
1157
            }
1158
        } else {
1159
            return [
1160
                'result' => false,
1161
                'message' => $this->serviceLocator->get('MvcTranslator')->translate(
1162
                    'Too many invitations for this user'
1163
                )
1164
            ];
1165
        }
1166
    }
1167
1168
    public function sendShareMail(
1169
        $data,
1170
        $game,
1171
        $user,
1172
        $entry,
1173
        $template = 'share_game',
1174
        $subject = ''
1175
    ) {
1176
        $mailService = $this->serviceLocator->get('playgroundgame_message');
1177
        $mailSent = false;
1178
        $from = $this->getOptions()->getEmailFromAddress();
1179
1180
        if (empty($subject) && $game) {
1181
            $subject = $game->getEmailShareSubject();
1182
        }
1183
1184
        $message = '';
1185
        if ($game && !empty($game->getEmailShareMessage())) {
1186
            $message = $game->getEmailShareMessage();
1187
        }
1188
1189
        $renderer = $this->serviceLocator->get('Zend\View\Renderer\RendererInterface');
1190
        $skinUrl = $renderer->url(
1191
            'frontend',
1192
            array(),
1193
            array('force_canonical' => true)
1194
        );
1195
        $secretKey = strtoupper(substr(sha1(uniqid('pg_', true) . '####' . time()), 0, 15));
1196
1197
        if (isset($data['email']) && !is_array($data['email'])) {
1198
            $data['email'] = array($data['email']);
1199
        }
1200
        
1201
        foreach ($data['email'] as $to) {
1202
            $mailSent = true;
1203
            if (!empty($to)) {
1204
                $message = $mailService->createHtmlMessage(
1205
                    $from,
1206
                    $to,
1207
                    $subject,
1208
                    'playground-game/email/' . $template,
1209
                    array(
1210
                        'game' => $game,
1211
                        'data' => $data,
1212
                        'from' => $from,
1213
                        'to' => $to,
1214
                        'secretKey' => $secretKey,
1215
                        'skinUrl' => $skinUrl,
1216
                        'message' => $message,
1217
                    )
1218
                );
1219
                try {
1220
                    $mailService->send($message);
1221
                } catch (\Zend\Mail\Protocol\Exception\RuntimeException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
Bug introduced by
The class Zend\Mail\Protocol\Exception\RuntimeException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
1222
                }
1223
                
1224
                if ($entry) {
1225
                    $shares = json_decode($entry->getSocialShares(), true);
1226
                    (!isset($shares['mail']))? $shares['mail'] = 1:$shares['mail'] += 1;
1227
                }
1228
                $this->getEventManager()->trigger(
1229
                    __FUNCTION__ . '.post',
1230
                    $this, array(
1231
                        'user' => $user,
1232
                        'secretKey' => $secretKey,
1233
                        'data' => $data,
1234
                        'game' => $game,
1235
                        'entry' => $entry,
1236
                        'message' => $message,
1237
                        'to' => $to,
1238
                    )
1239
                );
1240
            }
1241
        }
1242
1243
        if ($mailSent) {
1244
            if ($entry) {
1245
                $sharesJson = json_encode($shares);
0 ignored issues
show
Bug introduced by
The variable $shares does not seem to be defined for all execution paths leading up to this point.

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

Let’s take a look at an example:

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

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

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

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

Available Fixes

  1. Check for existence of the variable explicitly:

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

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

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1246
                $entry->setSocialShares($sharesJson);
1247
                $entry = $this->getEntryMapper()->update($entry);
0 ignored issues
show
Unused Code introduced by
$entry is not used, you could remove the assignment.

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

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

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

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

Loading history...
1248
            }
1249
1250
            return true;
1251
        }
1252
1253
        return false;
1254
    }
1255
1256
    /**
1257
     * @param \PlaygroundGame\Entity\Game $game
1258
     * @param \PlaygroundUser\Entity\User $user
1259
     * @param Entry $entry
1260
     * @param \PlaygroundGame\Entity\Prize $prize
1261
     */
1262
    public function sendResultMail($game, $user, $entry, $template = 'entry', $prize = null)
1263
    {
1264
        $mailService = $this->serviceLocator->get('playgroundgame_message');
1265
        $from = $this->getOptions()->getEmailFromAddress();
1266
        if ($entry->getAnonymousIdentifier()) {
1267
            $to = $entry->getAnonymousIdentifier();
1268
        } elseif ($user) {
1269
            $to = $user->getEmail();
1270
        } else {
1271
            return false;
1272
        }
1273
        $subject = $this->serviceLocator->get('MvcTranslator')->translate(
1274
            $this->getOptions()->getParticipationSubjectLine(),
1275
            'playgroundgame'
1276
        );
1277
        $renderer = $this->serviceLocator->get('Zend\View\Renderer\RendererInterface');
1278
        $skinUrl = $renderer->url(
1279
            'frontend',
1280
            array(),
1281
            array('force_canonical' => true)
1282
        );
1283
        $message = $mailService->createHtmlMessage($from, $to, $subject, 'playground-game/email/' . $template, array(
1284
            'game' => $game,
1285
            'entry' => $entry,
1286
            'skinUrl' => $skinUrl,
1287
            'prize' => $prize
1288
        ));
1289
        $mailService->send($message);
1290
    }
1291
1292
    public function sendGameMail($game, $user, $post, $template = 'postvote')
1293
    {
1294
        $mailService = $this->serviceLocator->get('playgroundgame_message');
1295
        $from = $this->getOptions()->getEmailFromAddress();
1296
        $to = $user->getEmail();
1297
        $subject = $this->serviceLocator->get('MvcTranslator')->translate(
1298
            $this->getOptions()->getParticipationSubjectLine(),
1299
            'playgroundgame'
1300
        );
1301
        $renderer = $this->serviceLocator->get('Zend\View\Renderer\RendererInterface');
1302
        $skinUrl = $renderer->url(
1303
            'frontend',
1304
            array(),
1305
            array('force_canonical' => true)
1306
        );
1307
1308
        $message = $mailService->createHtmlMessage($from, $to, $subject, 'playground-game/email/' . $template, array(
1309
            'game' => $game,
1310
            'post' => $post,
1311
            'skinUrl' => $skinUrl
1312
        ));
1313
        $mailService->send($message);
1314
    }
1315
1316 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...
1317
    {
1318
        $topic = $game->getTitle();
1319
        
1320
        $shares = json_decode($entry->getSocialShares(), true);
1321
        if (!isset($shares['fbwall'])) {
1322
            $shares['fbwall'] = 1;
1323
        } else {
1324
            $shares['fbwall'] += 1;
1325
        }
1326
        $sharesJson = json_encode($shares);
1327
        $entry->setSocialShares($sharesJson);
1328
        $entry = $this->getEntryMapper()->update($entry);
1329
        
1330
        $this->getEventManager()->trigger(__FUNCTION__ . '.post', $this, array(
1331
            'user' => $user,
1332
            'game' => $game,
1333
            'secretKey' => $secretKey,
1334
            'topic' => $topic,
1335
            'entry' => $entry
1336
        ));
1337
1338
        return true;
1339
    }
1340
1341
    public function postFbRequest($secretKey, $game, $user, $entry, $to)
1342
    {
1343
        $shares = json_decode($entry->getSocialShares(), true);
1344
        $to = explode(',', $to);
1345
        if (!isset($shares['fbrequest'])) {
1346
            $shares['fbrequest'] = count($to);
1347
        } else {
1348
            $shares['fbrequest'] += count($to);
1349
        }
1350
        $sharesJson = json_encode($shares);
1351
        $entry->setSocialShares($sharesJson);
1352
        $entry = $this->getEntryMapper()->update($entry);
1353
        
1354
        $this->getEventManager()->trigger(__FUNCTION__ . '.post', $this, array(
1355
            'user' => $user,
1356
            'game' => $game,
1357
            'secretKey' => $secretKey,
1358
            'entry' => $entry,
1359
            'invites' => count($to)
1360
        ));
1361
1362
        return true;
1363
    }
1364
1365 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...
1366
    {
1367
        $topic = $game->getTitle();
1368
1369
        $shares = json_decode($entry->getSocialShares(), true);
1370
        if (!isset($shares['fbrequest'])) {
1371
            $shares['tweet'] = 1;
1372
        } else {
1373
            $shares['tweet'] += 1;
1374
        }
1375
        $sharesJson = json_encode($shares);
1376
        $entry->setSocialShares($sharesJson);
1377
        $entry = $this->getEntryMapper()->update($entry);
1378
        
1379
        $this->getEventManager()->trigger(__FUNCTION__ . '.post', $this, array(
1380
            'user' => $user,
1381
            'game' => $game,
1382
            'secretKey' => $secretKey,
1383
            'topic' => $topic,
1384
            'entry' => $entry
1385
        ));
1386
1387
        return true;
1388
    }
1389
1390 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...
1391
    {
1392
        $topic = $game->getTitle();
1393
        
1394
        $shares = json_decode($entry->getSocialShares(), true);
1395
        if (!isset($shares['fbrequest'])) {
1396
            $shares['google'] = 1;
1397
        } else {
1398
            $shares['google'] += 1;
1399
        }
1400
        $sharesJson = json_encode($shares);
1401
        $entry->setSocialShares($sharesJson);
1402
        $entry = $this->getEntryMapper()->update($entry);
1403
1404
        $this->getEventManager()->trigger(__FUNCTION__ . '.post', $this, array(
1405
            'user' => $user,
1406
            'game' => $game,
1407
            'secretKey' => $secretKey,
1408
            'topic' => $topic,
1409
            'entry' => $entry
1410
        ));
1411
1412
        return true;
1413
    }
1414
1415
    /**
1416
     * Is it possible to trigger a bonus entry ?
1417
     *
1418
     * @param unknown_type $game
1419
     * @param unknown_type $user
1420
     */
1421
    public function allowBonus($game, $user)
1422
    {
1423
        if (! $game->getPlayBonus() || $game->getPlayBonus() == 'none') {
1424
            return false;
1425
        } elseif ($game->getPlayBonus() == 'one') {
1426
            if ($this->getEntryMapper()->findOneBy(array(
1427
                'game' => $game,
1428
                'user' => $user,
1429
                'bonus' => 1
1430
            ))) {
1431
                return false;
1432
            } else {
1433
                return true;
1434
            }
1435
        } elseif ($game->getPlayBonus() == 'per_entry') {
1436
            return $this->getEntryMapper()->checkBonusEntry($game, $user);
1437
        }
1438
1439
        return false;
1440
    }
1441
1442
    public function addAnotherEntry($game, $user, $winner = 0)
1443
    {
1444
        $entry = new Entry();
1445
        $entry->setGame($game);
1446
        $entry->setUser($user);
1447
        $entry->setPoints(0);
1448
        $entry->setIp($this->getIp());
1449
        $entry->setActive(0);
1450
        $entry->setBonus(1);
1451
        $entry->setWinner($winner);
1452
        $entry = $this->getEntryMapper()->insert($entry);
1453
1454
        return $entry;
1455
    }
1456
1457
    /**
1458
     * This bonus entry doesn't give points nor badges
1459
     * It's just there to increase the chances during the Draw
1460
     * Old Name playBonus
1461
     *
1462
     * @param PlaygroundGame\Entity\Game $game
1463
     * @param unknown $user
1464
     * @return boolean unknown
1465
     */
1466
    public function addAnotherChance($game, $user, $winner = 0)
1467
    {
1468
        if ($this->allowBonus($game, $user)) {
1469
            $this->addAnotherEntry($game, $user, $winner);
1470
1471
            return true;
1472
        }
1473
1474
        return false;
1475
    }
1476
1477
    /**
1478
     * This bonus entry doesn't give points nor badges but can play again
1479
     *
1480
     * @param PlaygroundGame\Entity\Game $game
1481
     * @param user $user
1482
     * @return boolean unknown
1483
     */
1484
    public function playAgain($game, $user, $winner = 0)
1485
    {
1486
        if ($this->allowBonus($game, $user)) {
1487
            $entry = $this->addAnotherEntry($game, $user, $winner);
1488
            $entry->setActive(1);
1489
            $entry = $this->getEntryMapper()->update($entry);
1490
            if ($entry->getActive() == 1) {
1491
                return true;
1492
            }
1493
        }
1494
1495
        return false;
1496
    }
1497
1498
    /**
1499
     * @param string $path
1500
     * @param boolean $noReplace : If the image name already exist, don't replace it but change the name
1501
     */
1502
    public function uploadFile($path, $file, $noReplace = true)
1503
    {
1504
        $err = $file["error"];
1505
        $message = '';
1506
        if ($err > 0) {
1507
            switch ($err) {
1508
                case '1':
1509
                    $message .= 'Max file size exceeded. (php.ini)';
1510
                    break;
1511
                case '2':
1512
                    $message .= 'Max file size exceeded.';
1513
                    break;
1514
                case '3':
1515
                    $message .= 'File upload was only partial.';
1516
                    break;
1517
                case '4':
1518
                    $message .= 'No file was attached.';
1519
                    break;
1520
                case '7':
1521
                    $message .= 'File permission denied.';
1522
                    break;
1523
                default:
1524
                    $message .= 'Unexpected error occurs.';
1525
            }
1526
1527
            return $err;
1528
        } else {
1529
            $fileNewname = $this->fileNewname($path, $file['name'], $noReplace);
1530
1531
            if (isset($file["base64"])) {
1532
                list(, $img) = explode(',', $file["base64"]);
1533
                $img = str_replace(' ', '+', $img);
1534
                $im = base64_decode($img);
1535
                if ($im !== false) {
1536
                    // getimagesizefromstring
1537
                    file_put_contents($path . $fileNewname, $im);
1538
                } else {
1539
                    return 1;
1540
                }
1541
1542
                return $fileNewname;
1543
            } else {
1544
                $adapter = new \Zend\File\Transfer\Adapter\Http();
1545
                // 1Mo
1546
                $size = new Size(array(
1547
                    'max' => 1024000
1548
                ));
1549
                $is_image = new IsImage('jpeg,png,gif,jpg');
1550
                $adapter->setValidators(array(
1551
                    $size,
1552
                    $is_image
1553
                ), $fileNewname);
1554
1555
                if (! $adapter->isValid()) {
1556
                    return false;
1557
                }
1558
1559
                @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...
1560
            }
1561
1562
            
1563
            if (class_exists("Imagick")) {
1564
                $ext = pathinfo($fileNewname, PATHINFO_EXTENSION);
1565
                $img = new \Imagick($path . $fileNewname);
1566
                $img->cropThumbnailImage(100, 100);
1567
                $img->setImageCompression(\Imagick::COMPRESSION_JPEG);
1568
                $img->setImageCompressionQuality(75);
1569
                // Strip out unneeded meta data
1570
                $img->stripImage();
1571
                $img->writeImage($path . str_replace('.'.$ext, '-thumbnail.'.$ext, $fileNewname));
1572
                ErrorHandler::stop(true);
1573
            }
1574
        }
1575
1576
        return $fileNewname;
1577
    }
1578
1579
    /**
1580
     * @param string $path
1581
     */
1582
    public function fileNewname($path, $filename, $generate = false)
1583
    {
1584
        $sanitize = new Sanitize();
1585
        $name = $sanitize->filter($filename);
1586
        $newpath = $path . $name;
1587
1588
        if ($generate) {
1589
            if (file_exists($newpath)) {
1590
                $filename = pathinfo($name, PATHINFO_FILENAME);
1591
                $ext = pathinfo($name, PATHINFO_EXTENSION);
1592
1593
                $name = $filename . '_' . rand(0, 99) . '.' . $ext;
1594
            }
1595
        }
1596
1597
        unset($sanitize);
1598
1599
        return $name;
1600
    }
1601
1602
    /**
1603
     * This function returns the list of games, ordered by $type
1604
     */
1605
    public function getQueryGamesOrderBy($type = 'createdAt', $order = 'DESC')
1606
    {
1607
        $em = $this->serviceLocator->get('doctrine.entitymanager.orm_default');
1608
        $today = new \DateTime("now");
1609
        $today = $today->format('Y-m-d H:i:s');
1610
1611
        $onlineGames = '(
1612
            (
1613
                CASE WHEN (
1614
                    g.active = 1
1615
                    AND g.broadcastPlatform = 1
1616
                    AND (g.startDate <= :date OR g.startDate IS NULL)
1617
                    AND (g.closeDate >= :date OR g.closeDate IS NULL)
1618
                ) THEN 1 ELSE 0 END
1619
            ) +
1620
            (
1621
                CASE WHEN (
1622
                    g.active = 0
1623
                    AND (g.broadcastPlatform = 0 OR g.broadcastPlatform IS NULL)
1624
                    AND g.startDate > :date
1625
                    AND g.closeDate < :date
1626
                ) THEN 1 ELSE 0 END
1627
            )
1628
        )';
1629
1630
        $qb = $em->createQueryBuilder();
1631
        $qb->select('g')->from('PlaygroundGame\Entity\Game', 'g');
1632
        
1633
        switch ($type) {
1634
            case 'startDate':
1635
                $qb->orderBy('g.startDate', $order);
1636
                break;
1637
            case 'activeGames':
1638
                $qb->orderBy('g.active', $order);
1639
                break;
1640
            case 'onlineGames':
1641
                $qb->orderBy($onlineGames, $order);
1642
                $qb->setParameter('date', $today);
1643
                break;
1644
            case 'createdAt':
1645
                $qb->orderBy('g.createdAt', $order);
1646
                break;
1647
        }
1648
1649
        $query = $qb->getQuery();
1650
1651
        return $query;
1652
    }
1653
1654
    public function draw($game)
1655
    {
1656
        $total = $game->getWinners();
1657
1658
        // I Have to know what is the User Class used
1659
        $zfcUserOptions = $this->serviceLocator->get('zfcuser_module_options');
1660
        $userClass = $zfcUserOptions->getUserEntityClass();
1661
1662
        $result = $this->getEntryMapper()->draw($game, $userClass, $total);
1663
1664
        foreach ($result as $e) {
1665
            $e->setWinner(1);
1666
            $e = $this->getEntryMapper()->update($e);
1667
            $this->getEventManager()->trigger('win_lottery.post', $this, array(
1668
                'user' => $e->getUser(),
1669
                'game' => $game,
1670
                'entry' => $e
1671
            ));
1672
        }
1673
1674
        return $result;
1675
    }
1676
1677
    /**
1678
     * getGameMapper
1679
     *
1680
     * @return GameMapperInterface
1681
     */
1682 View Code Duplication
    public function getGameMapper()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
1683
    {
1684
        if (null === $this->gameMapper) {
1685
            $this->gameMapper = $this->serviceLocator->get('playgroundgame_game_mapper');
1686
        }
1687
1688
        return $this->gameMapper;
1689
    }
1690
1691
    /**
1692
     * setGameMapper
1693
     *
1694
     * @param GameMapperInterface $gameMapper
1695
     * @return Game
1696
     */
1697
    public function setGameMapper(GameMapperInterface $gameMapper)
1698
    {
1699
        $this->gameMapper = $gameMapper;
1700
1701
        return $this;
1702
    }
1703
1704
    /**
1705
     * getEntryMapper
1706
     *
1707
     * @return EntryMapperInterface
1708
     */
1709
    public function getEntryMapper()
1710
    {
1711
        if (null === $this->entryMapper) {
1712
            $this->entryMapper = $this->serviceLocator->get('playgroundgame_entry_mapper');
1713
        }
1714
1715
        return $this->entryMapper;
1716
    }
1717
1718
    /**
1719
     * setEntryMapper
1720
     *
1721
     * @param EntryMapperInterface $entryMapper
1722
     * @return Game
1723
     */
1724
    public function setEntryMapper($entryMapper)
1725
    {
1726
        $this->entryMapper = $entryMapper;
1727
1728
        return $this;
1729
    }
1730
1731
    public function setOptions(ModuleOptions $options)
1732
    {
1733
        $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...
1734
1735
        return $this;
1736
    }
1737
1738
    public function getOptions()
1739
    {
1740
        if (! $this->options instanceof ModuleOptions) {
1741
            $this->setOptions($this->serviceLocator
1742
                ->get('playgroundgame_module_options'));
1743
        }
1744
1745
        return $this->options;
1746
    }
1747
1748
    /**
1749
     * @param string $str
1750
     */
1751
    public function getExtension($str)
1752
    {
1753
        $i = strrpos($str, '.');
1754
1755
        $l = strlen($str) - $i;
1756
        $ext = substr($str, $i + 1, $l);
1757
1758
        return $ext;
1759
    }
1760
1761
    /**
1762
     * @param string $extension
1763
     */
1764
    public function getSrc($extension, $temp_path)
1765
    {
1766
        $image_src = '';
1767
        switch ($extension) {
1768
            case 'jpg':
1769
                $image_src = imagecreatefromjpeg($temp_path);
1770
                break;
1771
            case 'jpeg':
1772
                $image_src = imagecreatefromjpeg($temp_path);
1773
                break;
1774
            case 'png':
1775
                $image_src = imagecreatefrompng($temp_path);
1776
                break;
1777
            case 'gif':
1778
                $image_src = imagecreatefromgif($temp_path);
1779
                break;
1780
        }
1781
1782
        return $image_src;
1783
    }
1784
1785
    /**
1786
     * @param string $extension
1787
     * @param string $rep
1788
     * @param integer $mini_width
1789
     * @param integer $mini_height
1790
     */
1791
    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...
1792
    {
1793
        list($src_width, $src_height) = getimagesize($tmp_file);
1794
1795
        $ratio_src = $src_width / $src_height;
1796
        $ratio_mini = $mini_width / $mini_height;
1797
1798
        if ($ratio_src >= $ratio_mini) {
1799
            $new_height_mini = $mini_height;
1800
            $new_width_mini = $src_width / ($src_height / $mini_height);
1801
        } else {
1802
            $new_width_mini = $mini_width;
1803
            $new_height_mini = $src_height / ($src_width / $mini_width);
1804
        }
1805
1806
        $new_image_mini = imagecreatetruecolor($mini_width, $mini_height);
1807
1808
        imagecopyresampled(
1809
            $new_image_mini,
1810
            $src,
1811
            0 - ($new_width_mini - $mini_width) / 2,
1812
            0 - ($new_height_mini - $mini_height) / 2,
1813
            0,
1814
            0,
1815
            $new_width_mini,
1816
            $new_height_mini,
1817
            $src_width,
1818
            $src_height
1819
        );
1820
        imagejpeg($new_image_mini, $rep);
1821
1822
        imagedestroy($new_image_mini);
1823
    }
1824
1825
    public function getGameEntity()
1826
    {
1827
        return new \PlaygroundGame\Entity\Game();
1828
    }
1829
1830
    /**
1831
     * @param string $resource
1832
     * @param string $privilege
1833
     */
1834
    public function isAllowed($resource, $privilege = null)
1835
    {
1836
        $auth = $this->serviceLocator->get('BjyAuthorize\Service\Authorize');
1837
1838
        return $auth->isAllowed($resource, $privilege);
1839
    }
1840
1841
    public function getIp()
1842
    {
1843
        $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...
1844
        if (isset($_SERVER['HTTP_CLIENT_IP'])) {
1845
            $ipaddress = $_SERVER['HTTP_CLIENT_IP'];
1846
        } elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
1847
            $ipaddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
1848
        } elseif (isset($_SERVER['HTTP_X_FORWARDED'])) {
1849
            $ipaddress = $_SERVER['HTTP_X_FORWARDED'];
1850
        } elseif (isset($_SERVER['HTTP_FORWARDED_FOR'])) {
1851
            $ipaddress = $_SERVER['HTTP_FORWARDED_FOR'];
1852
        } elseif (isset($_SERVER['HTTP_FORWARDED'])) {
1853
            $ipaddress = $_SERVER['HTTP_FORWARDED'];
1854
        } elseif (isset($_SERVER['REMOTE_ADDR'])) {
1855
            $ipaddress = $_SERVER['REMOTE_ADDR'];
1856
        } else {
1857
            $ipaddress = 'UNKNOWN';
1858
        }
1859
1860
        return $ipaddress;
1861
    }
1862
1863
    public function getGeoloc($ip)
1864
    {
1865
        $geoloc = '';
1866
        try {
1867
            $res = unserialize(file_get_contents('http://www.geoplugin.net/php.gp?ip='.$ip));
1868
            if($res['geoplugin_latitude'] != '') {
1869
                $geoloc = $res['geoplugin_latitude'] . ',' . $res['geoplugin_longitude'];
1870
            }
1871
        } catch (\Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
1872
1873
        } 
1874
1875
        return $geoloc;
1876
    }
1877
1878
    public function getAnonymousId()
1879
    {
1880
        $anonymousId = '';
1881
        if ($_COOKIE && array_key_exists('pg_anonymous', $_COOKIE)) {
1882
            $anonymousId = $_COOKIE['pg_anonymous'];
1883
        }
1884
1885
        return $anonymousId;
1886
    }
1887
1888
    /**
1889
     *
1890
     *
1891
     * This service is ready for all types of games
1892
     *
1893
     * @param array $data
1894
     * @return \PlaygroundGame\Entity\Game
1895
     */
1896 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...
1897
    {
1898
        $title = '';
1899
        $description = '';
1900
1901
        if ($data['form_jsonified']) {
1902
            $jsonPV = json_decode($data['form_jsonified']);
1903
            foreach ($jsonPV as $element) {
1904
                if ($element->form_properties) {
1905
                    $attributes = $element->form_properties[0];
1906
                    $title = $attributes->title;
1907
                    $description = $attributes->description;
1908
1909
                    break;
1910
                }
1911
            }
1912
        }
1913
        if (! $form) {
1914
            $form = new \PlaygroundGame\Entity\PlayerForm();
1915
        }
1916
        $form->setGame($game);
1917
        $form->setTitle($title);
1918
        $form->setDescription($description);
1919
        $form->setForm($data['form_jsonified']);
1920
        $form->setFormTemplate($data['form_template']);
1921
1922
        $form = $this->getPlayerFormMapper()->insert($form);
1923
1924
        return $form;
1925
    }
1926
1927
    /**
1928
     *  getCSV creates lines of CSV and returns it.
1929
     */
1930
    public function getCSV($array)
1931
    {
1932
        ob_start(); // buffer the output ...
1933
        $out = fopen('php://output', 'w');
1934
        fputcsv($out, array_keys($array[0]), ";");
1935
        foreach ($array as $line) {
1936
            fputcsv($out, $line, ";");
1937
        }
1938
        fclose($out);
1939
        return ob_get_clean(); // ... then return it as a string!
1940
    }
1941
    
1942
    public function getAttributes($attributes)
1943
    {
1944
        $a = array();
1945
1946
        $a['name']          = isset($attributes->name)? $attributes->name : '';
1947
        $a['placeholder']   = isset($attributes->data->placeholder)? $attributes->data->placeholder : '';
1948
        $a['label']         = isset($attributes->data->label)? $attributes->data->label : '';
1949
        $a['required']      = (isset($attributes->data->required) && $attributes->data->required == 'true')?
1950
            true:
1951
            false;
1952
        $a['class']         = isset($attributes->data->class)? $attributes->data->class : '';
1953
        $a['id']            = isset($attributes->data->id)? $attributes->data->id : '';
1954
        $a['lengthMin']     = isset($attributes->data->length)? $attributes->data->length->min : '';
1955
        $a['lengthMax']     = isset($attributes->data->length)? $attributes->data->length->max : '';
1956
        $a['validator']     = isset($attributes->data->validator)? $attributes->data->validator : '';
1957
        $a['innerData']     = isset($attributes->data->innerData)? $attributes->data->innerData : array();
1958
        $a['dropdownValues']= isset($attributes->data->dropdownValues)?
1959
            $attributes->data->dropdownValues :
1960
            array();
1961
        $a['filesizeMin']   = isset($attributes->data->filesize)? $attributes->data->filesize->min : 0;
1962
        $a['filesizeMax']   = isset($attributes->data->filesize)? $attributes->data->filesize->max : 10*1024*1024;
1963
        $a['fileextension']   = isset($attributes->data->fileextension)?
1964
            str_replace(', ', ',', $attributes->data->fileextension) :
1965
            'png,jpg,jpeg,gif';
1966
1967
        // hiddenRequired('fileexcludeextension', '').appendTo(li);
1968
        // hiddenRequired('filemimetype', '').appendTo(li);
1969
        // hiddenRequired('fileexcludemimetype', '').appendTo(li);
1970
        // hiddenRequired('fileexists', '').appendTo(li);
1971
        // hiddenRequired('fileimagesize_minheight', '').appendTo(li);
1972
        // hiddenRequired('fileimagesize_maxheight', '').appendTo(li);
1973
        // hiddenRequired('fileimagesize_minwidth', '').appendTo(li);
1974
        // hiddenRequired('fileimagesize_maxwidth', '').appendTo(li);
1975
        // hiddenRequired('fileiscompressed', '').appendTo(li);
1976
        // hiddenRequired('fileisimage', '').appendTo(li);
1977
        // hiddenRequired('filewordcount_min', '').appendTo(li);
1978
        // hiddenRequired('filewordcount_max', '').appendTo(li);
1979
1980
        return $a;
1981
    }
1982
1983
    /**
1984
     * @param \Zend\InputFilter\InputFilter $inputFilter
1985
     */
1986
    public function decorate($element, $attr, $inputFilter)
1987
    {
1988
        $factory = new InputFactory();
1989
        $element->setAttributes(
1990
            array(
1991
                'placeholder'   => $attr['placeholder'],
1992
                'required'      => $attr['required'],
1993
                'class'         => $attr['class'],
1994
                'id'            => $attr['id']
1995
            )
1996
        );
1997
1998
        $options = array();
1999
        $options['encoding'] = 'UTF-8';
2000
        if ($attr['lengthMin'] && $attr['lengthMin'] > 0) {
2001
            $options['min'] = $attr['lengthMin'];
2002
        }
2003
        if ($attr['lengthMax'] && $attr['lengthMax'] > $attr['lengthMin']) {
2004
            $options['max'] = $attr['lengthMax'];
2005
            $element->setAttribute('maxlength', $attr['lengthMax']);
2006
            $options['messages'] = array(
2007
                \Zend\Validator\StringLength::TOO_LONG => sprintf(
2008
                    $this->serviceLocator->get('MvcTranslator')->translate(
2009
                        'This field contains more than %s characters',
2010
                        'playgroundgame'
2011
                    ),
2012
                    $attr['lengthMax']
2013
                )
2014
            );
2015
        }
2016
2017
        $validators = array(
2018
            array(
2019
                'name'    => 'StringLength',
2020
                'options' => $options,
2021
            ),
2022
        );
2023
        if ($attr['validator']) {
2024
            $regex = "/.*\(([^)]*)\)/";
2025
            preg_match($regex, $attr['validator'], $matches);
2026
            $valArray = array(
2027
                'name' => str_replace(
2028
                    '('.$matches[1].')',
2029
                    '',
2030
                    $attr['validator']
2031
                ),
2032
                'options' => array($matches[1])
2033
            );
2034
            $validators[] = $valArray;
2035
        }
2036
2037
        $inputFilter->add($factory->createInput(array(
2038
            'name'     => $attr['name'],
2039
            'required' => $attr['required'],
2040
            'filters'  => array(
2041
                array('name' => 'StripTags'),
2042
                array('name' => 'StringTrim'),
2043
            ),
2044
            'validators' => $validators,
2045
        )));
2046
2047
        return $element;
2048
    }
2049
    /**
2050
     * Create a ZF2 Form from json data
2051
     * @return Form
2052
     */
2053
    public function createFormFromJson($jsonForm, $id = 'jsonForm')
2054
    {
2055
        $formPV = json_decode($jsonForm);
2056
        
2057
        $form = new Form();
2058
        $form->setAttribute('id', $id);
2059
        $form->setAttribute('enctype', 'multipart/form-data');
2060
        
2061
        $inputFilter = new \Zend\InputFilter\InputFilter();
2062
        $factory = new InputFactory();
2063
        
2064
        foreach ($formPV as $element) {
2065 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...
2066
                $attr  = $this->getAttributes($element->line_text[0]);
2067
                $element = new Element\Text($attr['name']);
2068
                $element = $this->decorate($element, $attr, $inputFilter);
2069
                $form->add($element);
2070
            }
2071 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...
2072
                $attr = $this->getAttributes($element->line_password[0]);
2073
                $element = new Element\Password($attr['name']);
2074
                $element = $this->decorate($element, $attr, $inputFilter);
2075
                $form->add($element);
2076
            }
2077 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...
2078
                $attr = $this->getAttributes($element->line_hidden[0]);
2079
                $element = new Element\Hidden($attr['name']);
2080
                $element = $this->decorate($element, $attr, $inputFilter);
2081
                $form->add($element);
2082
            }
2083 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...
2084
                $attr = $this->getAttributes($element->line_email[0]);
2085
                $element = new Element\Email($attr['name']);
2086
                $element = $this->decorate($element, $attr, $inputFilter);
2087
                $form->add($element);
2088
            }
2089 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...
2090
                $attr = $this->getAttributes($element->line_radio[0]);
2091
                $element = new Element\Radio($attr['name']);
2092
2093
                $element->setLabel($attr['label']);
2094
                $element->setAttributes(
2095
                    array(
2096
                        'name'      => $attr['name'],
2097
                        'required'  => $attr['required'],
2098
                        'allowEmpty'=> !$attr['required'],
2099
                        'class'     => $attr['class'],
2100
                        'id'        => $attr['id']
2101
                    )
2102
                );
2103
                $values = array();
2104
                foreach ($attr['innerData'] as $value) {
2105
                    $values[] = $value->label;
2106
                }
2107
                $element->setValueOptions($values);
2108
        
2109
                $options = array();
2110
                $options['encoding'] = 'UTF-8';
2111
                $options['disable_inarray_validator'] = true;
2112
        
2113
                $element->setOptions($options);
2114
        
2115
                $form->add($element);
2116
        
2117
                $inputFilter->add($factory->createInput(array(
2118
                    'name'     => $attr['name'],
2119
                    'required' => $attr['required'],
2120
                    'allowEmpty' => !$attr['required'],
2121
                )));
2122
            }
2123 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...
2124
                $attr = $this->getAttributes($element->line_checkbox[0]);
2125
                $element = new Element\MultiCheckbox($attr['name']);
2126
        
2127
                $element->setLabel($attr['label']);
2128
                $element->setAttributes(
2129
                    array(
2130
                        'name'      => $attr['name'],
2131
                        'required'  => $attr['required'],
2132
                        'allowEmpty'=> !$attr['required'],
2133
                        'class'     => $attr['class'],
2134
                        'id'        => $attr['id']
2135
                    )
2136
                );
2137
2138
                $values = array();
2139
                foreach ($attr['innerData'] as $value) {
2140
                    $values[] = $value->label;
2141
                }
2142
                $element->setValueOptions($values);
2143
                $form->add($element);
2144
        
2145
                $options = array();
2146
                $options['encoding'] = 'UTF-8';
2147
                $options['disable_inarray_validator'] = true;
2148
        
2149
                $element->setOptions($options);
2150
        
2151
                $inputFilter->add($factory->createInput(array(
2152
                    'name'      => $attr['name'],
2153
                    'required'  => $attr['required'],
2154
                    'allowEmpty'=> !$attr['required'],
2155
                )));
2156
            }
2157 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...
2158
                $attr = $this->getAttributes($element->line_dropdown[0]);
2159
                $element = new Element\Select($attr['name']);
2160
2161
                $element->setLabel($attr['label']);
2162
                $element->setAttributes(
2163
                    array(
2164
                        'name'      => $attr['name'],
2165
                        'required'  => $attr['required'],
2166
                        'allowEmpty'=> !$attr['required'],
2167
                        'class'     => $attr['class'],
2168
                        'id'        => $attr['id']
2169
                    )
2170
                );
2171
                $values = array();
2172
                foreach ($attr['dropdownValues'] as $value) {
2173
                    $values[] = $value->dropdown_label;
2174
                }
2175
                $element->setValueOptions($values);
2176
                $form->add($element);
2177
        
2178
                $options = array();
2179
                $options['encoding'] = 'UTF-8';
2180
                $options['disable_inarray_validator'] = true;
2181
        
2182
                $element->setOptions($options);
2183
        
2184
                $inputFilter->add($factory->createInput(array(
2185
                    'name'     => $attr['name'],
2186
                    'required' => $attr['required'],
2187
                    'allowEmpty' => !$attr['required'],
2188
                )));
2189
            }
2190 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...
2191
                $attr = $this->getAttributes($element->line_paragraph[0]);
2192
                $element = new Element\Textarea($attr['name']);
2193
                $element = $this->decorate($element, $attr, $inputFilter);
2194
                $form->add($element);
2195
            }
2196
            if (isset($element->line_upload)) {
2197
                $attr = $this->getAttributes($element->line_upload[0]);
2198
                $element = new Element\File($attr['name']);
2199
2200
                $element->setLabel($attr['label']);
2201
                $element->setAttributes(
2202
                    array(
2203
                        'name'      => $attr['name'],
2204
                        'required'  => $attr['required'],
2205
                        'class'     => $attr['class'],
2206
                        'id'        => $attr['id']
2207
                    )
2208
                );
2209
                $form->add($element);
2210
2211
                $inputFilter->add($factory->createInput(array(
2212
                    'name'     => $attr['name'],
2213
                    'required' => $attr['required'],
2214
                    'validators' => array(
2215
                        array(
2216
                            'name' => '\Zend\Validator\File\Size',
2217
                            'options' => array('min' => $attr['filesizeMin'], 'max' => $attr['filesizeMax'])
2218
                        ),
2219
                        array(
2220
                            'name' => '\Zend\Validator\File\Extension',
2221
                            'options'  => array(
2222
                                $attr['fileextension'],
2223
                                'messages' => array(
2224
                                    \Zend\Validator\File\Extension::FALSE_EXTENSION =>'Veuillez télécharger un fichier avec la bonne extension'
2225
                                )
2226
                            )
2227
                        ),
2228
                    ),
2229
                )));
2230
            }
2231
        }
2232
        
2233
        $form->setInputFilter($inputFilter);
2234
        
2235
        return $form;
2236
    }
2237
2238
    /**
2239
     * Send mail for winner and/or loser
2240
     * @param \PlaygroundGame\Entity\Game $game
2241
     * @param \PlaygroundUser\Entity\User $user
2242
     * @param \PlaygroundGame\Entity\Entry $lastEntry
2243
     * @param \PlaygroundGame\Entity\Prize $prize
2244
     */
2245
    public function sendMail($game, $user, $lastEntry, $prize = null)
2246
    {
2247 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...
2248
            $game->getMailWinner() &&
2249
            $lastEntry->getWinner()
2250
        ) {
2251
            $this->sendResultMail($game, $user, $lastEntry, 'winner', $prize);
2252
        }
2253
2254 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...
2255
            $game->getMailLooser() &&
2256
            !$lastEntry->getWinner()
2257
        ) {
2258
            $this->sendResultMail($game, $user, $lastEntry, 'looser');
2259
        }
2260
2261
        if (($user || ($game->getAnonymousAllowed() && $game->getAnonymousIdentifier())) &&
2262
            $game->getMailEntry()
2263
        ) {
2264
            $this->sendResultMail($game, $user, $lastEntry);
2265
        }
2266
    }
2267
2268
    public function getPlayerFormMapper()
2269
    {
2270
        if (null === $this->playerformMapper) {
2271
            $this->playerformMapper = $this->serviceLocator->get('playgroundgame_playerform_mapper');
2272
        }
2273
2274
        return $this->playerformMapper;
2275
    }
2276
2277
    public function setPlayerFormMapper($playerformMapper)
2278
    {
2279
        $this->playerformMapper = $playerformMapper;
2280
2281
        return $this;
2282
    }
2283
2284
    public function getInvitationMapper()
2285
    {
2286
        if (null === $this->invitationMapper) {
2287
            $this->invitationMapper = $this->serviceLocator->get('playgroundgame_invitation_mapper');
2288
        }
2289
2290
        return $this->invitationMapper;
2291
    }
2292
2293
    public function setInvitationMapper($invitationMapper)
2294
    {
2295
        $this->invitationMapper = $invitationMapper;
2296
2297
        return $this;
2298
    }
2299
2300
    /**
2301
     * getUserMapper
2302
     *
2303
     * @return UserMapperInterface
2304
     */
2305
    public function getUserMapper()
2306
    {
2307
        if (null === $this->userMapper) {
2308
            $this->userMapper = $this->serviceLocator->get('zfcuser_user_mapper');
2309
        }
2310
2311
        return $this->userMapper;
2312
    }
2313
2314
    /**
2315
     * getUserMapper
2316
     *
2317
     * @return ServiceManager
2318
     */
2319
    public function getServiceManager()
2320
    {
2321
        return $this->serviceLocator;
2322
    }
2323
}
2324