Completed
Push — develop ( 0bc71f...f6430f )
by greg
41:42
created

GameController::createForm()   B

Complexity

Conditions 4
Paths 6

Size

Total Lines 29
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 29
rs 8.5806
cc 4
eloc 19
nc 6
nop 1
1
<?php
2
3
namespace PlaygroundGame\Controller\Admin;
4
5
use PlaygroundGame\Service\Game as AdminGameService;
6
use Zend\Mvc\Controller\AbstractActionController;
7
use PlaygroundGame\Options\ModuleOptions;
8
use Zend\Paginator\Paginator;
9
use DoctrineORMModule\Paginator\Adapter\DoctrinePaginator as DoctrineAdapter;
10
use PlaygroundCore\ORM\Pagination\LargeTablePaginator;
11
use Doctrine\ORM\Tools\Pagination\Paginator as ORMPaginator;
12
use Zend\Stdlib\ErrorHandler;
13
14
class GameController extends AbstractActionController
15
{
16
    protected $options;
17
18
    /**
19
     * @var \PlaygroundGame\Service\Game
20
     */
21
    protected $adminGameService;
22
23
    protected $game;
24
25
    public function checkGame(){
26
        $gameId = $this->getEvent()->getRouteMatch()->getParam('gameId');
27
        if (!$gameId) {
28
            return $this->redirect()->toRoute('admin/playgroundgame/list');
29
        }
30
        $service = $this->getAdminGameService();
31
        $game = $service->getGameMapper()->findById($gameId);
32
        if (!$game) {
33
            return $this->redirect()->toRoute('admin/playgroundgame/list');
34
        }
35
        $this->game = $game;
36
    }
37
38
    public function createForm($form){
39
        // I use the wonderful Form Generator to create the Post & Vote form
40
        $this->forward()->dispatch(
41
            'PlaygroundCore\Controller\Formgen',
42
            array(
43
                'controller' => 'PlaygroundCore\Controller\Formgen',
44
                'action' => 'create'
45
            )
46
        );
47
48
        if ($this->getRequest()->isPost()) {
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Zend\Stdlib\RequestInterface as the method isPost() does only exist in the following implementations of said interface: Zend\Http\PhpEnvironment\Request, Zend\Http\Request.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
49
            $data = $this->getRequest()->getPost()->toArray();
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Zend\Stdlib\RequestInterface as the method getPost() does only exist in the following implementations of said interface: Zend\Http\PhpEnvironment\Request, Zend\Http\Request.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
50
            $form = $service->createForm($data, $game, $form);
0 ignored issues
show
Bug introduced by
The variable $service does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Bug introduced by
The variable $game does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
51
            if ($form) {
52
                $this->flashMessenger()->setNamespace('playgroundgame')->addMessage('The form was created');
53
            }
54
        }
55
        $formTemplate='';
56
        if ($form) {
57
            $formTemplate = $form->getFormTemplate();
58
        }
59
60
        return array(
61
            'form' => $form,
62
            'formTemplate' => $formTemplate,
63
            'gameId' => $this->game->getId(),
64
            'game' => $this->game,
65
        );
66
    }
67
68
    public function listAction()
69
    {
70
        $filter    = $this->getEvent()->getRouteMatch()->getParam('filter');
71
        $type    = $this->getEvent()->getRouteMatch()->getParam('type');
72
73
        $service    = $this->getAdminGameService();
74
        $adapter = new DoctrineAdapter(new ORMPaginator($service->getQueryGamesOrderBy($type, $filter)));
75
        $paginator = new Paginator($adapter);
76
        $paginator->setItemCountPerPage(25);
77
        $paginator->setCurrentPageNumber($this->getEvent()->getRouteMatch()->getParam('p'));
78
79
        foreach ($paginator as $game) {
80
            $game->entry = $service->getEntryMapper()->countByGame($game);
81
        }
82
83
        return array(
84
            'games'    => $paginator,
85
            'type'        => $type,
86
            'filter'    => $filter,
87
        );
88
    }
89
90
    public function entryAction()
91
    {
92
        $this->checkGame();
93
94
        $adapter = new DoctrineAdapter(
95
            new LargeTablePaginator(
96
                $this->getAdminGameService()->getEntriesQuery($this->game)
97
            )
98
        );
99
        $paginator = new Paginator($adapter);
100
        $paginator->setItemCountPerPage(10);
101
        $paginator->setCurrentPageNumber($this->getEvent()->getRouteMatch()->getParam('p'));
102
103
        $header = $this->getAdminGameService()->getEntriesHeader($this->game);
104
        $entries = $this->getAdminGameService()->getGameEntries($header, $paginator, $this->game);
105
106
        return array(
107
            'paginator' => $paginator,
108
            'entries' => $entries,
109
            'header' => $header,
110
            'game' => $this->game,
111
            'gameId' => $this->game->getId()
112
        );
113
    }
114
115
    public function downloadAction()
116
    {
117
        $this->checkGame();
118
        $header = $this->getAdminGameService()->getEntriesHeader($this->game);
119
        $query = $this->getAdminGameService()->getEntriesQuery($this->game);
120
121
        $content = "\xEF\xBB\xBF"; // UTF-8 BOM
122
        $content .= $this->getAdminGameService()->getCSV(
123
            $this->getAdminGameService()->getGameEntries(
124
                $header,
125
                $query->getResult(),
126
                $this->game
127
            )
128
        );
129
130
        $response = $this->getResponse();
131
        $headers = $response->getHeaders();
132
        $headers->addHeaderLine('Content-Encoding: UTF-8');
133
        $headers->addHeaderLine('Content-Type', 'text/csv; charset=UTF-8');
134
        $headers->addHeaderLine('Content-Disposition', "attachment; filename=\"entry.csv\"");
135
        $headers->addHeaderLine('Accept-Ranges', 'bytes');
136
        $headers->addHeaderLine('Content-Length', strlen($content));
137
138
        $response->setContent($content);
139
140
        return $response;
141
    }
142
143
    // Only used for Quiz and Lottery
144
    public function drawAction()
145
    {
146
        $this->checkGame();
147
148
        $winningEntries = $this->getAdminGameService()->draw($this->game);
149
150
        $content = "\xEF\xBB\xBF"; // UTF-8 BOM
151
        $content .= "ID;Pseudo;Nom;Prenom;E-mail;Etat\n";
152
153
        foreach ($winningEntries as $e) {
154
            $etat = 'gagnant';
155
156
            $content   .= $e->getUser()->getId()
157
            . ";" . $e->getUser()->getUsername()
158
            . ";" . $e->getUser()->getLastname()
159
            . ";" . $e->getUser()->getFirstname()
160
            . ";" . $e->getUser()->getEmail()
161
            . ";" . $etat
162
            ."\n";
163
        }
164
165
        $response = $this->getResponse();
166
        $headers = $response->getHeaders();
167
        $headers->addHeaderLine('Content-Encoding: UTF-8');
168
        $headers->addHeaderLine('Content-Type', 'text/csv; charset=UTF-8');
169
        $headers->addHeaderLine('Content-Disposition', "attachment; filename=\"gagnants.csv\"");
170
        $headers->addHeaderLine('Accept-Ranges', 'bytes');
171
        $headers->addHeaderLine('Content-Length', strlen($content));
172
173
        $response->setContent($content);
174
175
        return $response;
176
    }
177
    
178
    /**
179
     * This method serialize a game an export it as a txt file
180
     * @return \Zend\Stdlib\ResponseInterface
181
     */
182
    public function exportAction()
183
    {
184
        $this->checkGame();
185
        $content = serialize($this->game);
186
187
        $response = $this->getResponse();
188
        $headers = $response->getHeaders();
189
        $headers->addHeaderLine('Content-Encoding: UTF-8');
190
        $headers->addHeaderLine('Content-Type', 'text/plain; charset=UTF-8');
191
        $headers->addHeaderLine('Content-Disposition', "attachment; filename=\"". $this->game->getIdentifier() .".txt\"");
192
        $headers->addHeaderLine('Accept-Ranges', 'bytes');
193
        $headers->addHeaderLine('Content-Length', strlen($content));
194
    
195
        $response->setContent($content);
196
    
197
        return $response;
198
    }
199
    
200
    /**
201
     * This method take an uploaded txt file containing a serialized game
202
     * and persist it in the database
203
     * @return unknown
204
     */
205
    public function importAction()
206
    {
207
        $form = $this->getServiceLocator()->get('playgroundgame_import_form');
208
        $form->setAttribute('action', $this->url()->fromRoute('admin/playgroundgame/import'));
209
        $form->setAttribute('method', 'post');
210
        
211
        if ($this->getRequest()->isPost()) {
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Zend\Stdlib\RequestInterface as the method isPost() does only exist in the following implementations of said interface: Zend\Http\PhpEnvironment\Request, Zend\Http\Request.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
212
            $data = array_replace_recursive(
213
                $this->getRequest()->getPost()->toArray(),
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Zend\Stdlib\RequestInterface as the method getPost() does only exist in the following implementations of said interface: Zend\Http\PhpEnvironment\Request, Zend\Http\Request.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
214
                $this->getRequest()->getFiles()->toArray()
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Zend\Stdlib\RequestInterface as the method getFiles() does only exist in the following implementations of said interface: Zend\Http\PhpEnvironment\Request, Zend\Http\Request.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
215
            );
216
            
217
            if (! empty($data['import_file']['tmp_name'])) {
218
                ErrorHandler::start();
219
                $game = unserialize(file_get_contents($data['import_file']['tmp_name']));
220
                $game->setId(null);
221
                if ($data['slug']) {
222
                    $game->setIdentifier($data['slug']);
223
                }
224
                $duplicate = $this->getAdminGameService()->getGameMapper()->findByIdentifier($game->getIdentifier());
225
                if (!$duplicate) {
226
                    $this->getAdminGameService()->getGameMapper()->insert($game);
227
                }
228
229
                ErrorHandler::stop(true);
230
            }
231
            
232
            return $this->redirect()->toRoute('admin/playgroundgame/list');
233
        }
234
        
235
        return array(
236
            'form' => $form,
237
        );
238
    }
239
240
    public function removeAction()
241
    {
242
        $this->checkGame();
243
244
        try {
245
            $this->getAdminGameService()->getGameMapper()->remove($this->game);
246
            $this->flashMessenger()->setNamespace('playgroundgame')->addMessage('The game has been edited');
247
        } catch (\Doctrine\DBAL\DBALException $e) {
248
            $this->flashMessenger()->setNamespace('playgroundgame')->addMessage(
249
                'Il y a déjà eu des participants à ce jeu. Vous ne pouvez plus le supprimer'
250
            );
251
        }
252
253
        return $this->redirect()->toRoute('admin/playgroundgame/list');
254
    }
255
256
    public function setActiveAction()
257
    {
258
        $this->checkGame();
259
260
        $this->game->setActive(!$this->game->getActive());
261
        $this->getAdminGameService()->getGameMapper()->update($game);
0 ignored issues
show
Bug introduced by
The variable $game does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
262
263
        return $this->redirect()->toRoute('admin/playgroundgame/list');
264
    }
265
266
    public function formAction()
267
    {
268
        $this->checkGame();
269
        
270
        $form = $this->game->getPlayerForm();
271
272
        return $this->createForm($form);
273
    }
274
275
    public function setOptions(ModuleOptions $options)
276
    {
277
        $this->options = $options;
278
279
        return $this;
280
    }
281
282
    public function getOptions()
283
    {
284
        if (!$this->options instanceof ModuleOptions) {
285
            $this->setOptions($this->getServiceLocator()->get('playgroundgame_module_options'));
0 ignored issues
show
Documentation introduced by
$this->getServiceLocator...ndgame_module_options') is of type object|array, but the function expects a object<PlaygroundGame\Options\ModuleOptions>.

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

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

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

function acceptsInteger($int) { }

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

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
286
        }
287
288
        return $this->options;
289
    }
290
291
    public function getAdminGameService()
292
    {
293
        if (!$this->adminGameService) {
294
            $this->adminGameService = $this->getServiceLocator()->get('playgroundgame_game_service');
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->getServiceLocator...oundgame_game_service') can also be of type array. However, the property $adminGameService is declared as type object<PlaygroundGame\Service\Game>. Maybe add an additional type check?

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

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

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

class Id
{
    public $id;

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

}

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

$account_id = false;

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

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
295
        }
296
297
        return $this->adminGameService;
298
    }
299
300
    public function setAdminGameService(AdminGameService $adminGameService)
301
    {
302
        $this->adminGameService = $adminGameService;
303
304
        return $this;
305
    }
306
}
307