Completed
Pull Request — master (#268)
by greg
07:26 queued 04:08
created

PostVoteController   F

Complexity

Total Complexity 74

Size/Duplication

Total Lines 729
Duplicated Lines 5.62 %

Coupling/Cohesion

Components 1
Dependencies 13

Importance

Changes 21
Bugs 5 Features 1
Metric Value
wmc 74
c 21
b 5
f 1
lcom 1
cbo 13
dl 41
loc 729
rs 3.5556

11 Methods

Rating   Name   Duplication   Size   Complexity  
D playAction() 0 138 15
B previewAction() 9 47 6
C postAction() 8 113 12
B ajaxdeleteAction() 0 32 4
D listAction() 9 114 9
B captchaAction() 0 24 4
A getGameService() 0 8 2
B resultAction() 0 44 6
B ajaxuploadAction() 0 49 5
B ajaxVoteAction() 0 41 5
B shareAction() 15 73 6

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like PostVoteController often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use PostVoteController, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace PlaygroundGame\Controller\Frontend;
4
5
use Zend\Form\Form;
6
7
class PostVoteController extends GameController
8
{
9
    /**
10
     * @var gameService
11
     */
12
    protected $gameService;
13
14
    /**
15
     * --DONE-- 1. try to change the Game Id (on le redirige vers la home du jeu)
16
     * --DONE-- 2. try to modify questions (the form is recreated and verified in the controller)
17
     * --DONE-- 3. don't answer to questions (form is checked controller side)
18
     * 4. try to game the chrono
19
     * 5. try to play again
20
     * 6. try to change answers
21
     *  --DONE-- 7. essaie de répondre sans être inscrit (on le redirige vers la home du jeu)
22
     */
23
    public function playAction()
24
    {
25
        $redirectFb = $this->checkFbRegistration($this->user, $this->game);
26
        if ($redirectFb) {
27
            return $redirectFb;
28
        }
29
30
        $entry = $this->getGameService()->play($this->game, $this->user);
31
32
        if (!$entry) {
33
            $lastEntry = $this->getGameService()->findLastInactiveEntry($this->game, $this->user);
34
            if ($lastEntry === null) {
35
                return $this->redirect()->toUrl(
36
                    $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...end\PostVoteController>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
37
                        'postvote',
38
                        array(
39
                            'id' => $this->game->getIdentifier(),
40
                            
41
                        )
42
                    )
43
                );
44
            }
45
46
            $lastEntryId = $lastEntry->getId();
47
            $lastPost = $this->getGameService()->getPostVotePostMapper()->findOneBy(array('entry' => $lastEntryId));
48
            $postId = $lastPost->getId();
49
            if ($lastPost->getStatus() == 2) {
50
                // the user has already taken part of this game and the participation limit has been reached
51
                $this->flashMessenger()->addMessage(
52
                    $this->getServiceLocator()->get('translator')->translate('You have already a Post')
53
                );
54
55
                return $this->redirect()->toUrl(
56
                    $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...end\PostVoteController>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
57
                        'postvote/post',
58
                        array(
59
                            'id' => $this->game->getIdentifier(),
60
                            'post' => $postId,
61
                            
62
                        )
63
                    )
64
                );
65
            } else {
66
                $this->flashMessenger()->addMessage(
67
                    $this->getServiceLocator()->get('translator')->translate('Your Post is waiting for validation')
68
                );
69
70
                return $this->redirect()->toUrl(
71
                    $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...end\PostVoteController>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
72
                        'postvote/post',
73
                        array(
74
                            'id' => $this->game->getIdentifier(),
75
                            'post' => $postId,
76
                            
77
                        )
78
                    )
79
                );
80
            }
81
        }
82
83
        if (! $this->game->getForm()) {
84
            return $this->redirect()->toUrl(
85
                $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...end\PostVoteController>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
86
                    'postvote',
87
                    array(
88
                        'id' => $this->game->getIdentifier(),
89
                        
90
                    )
91
                )
92
            );
93
        }
94
95
        $form = $this->getGameService()->createFormFromJson($this->game->getForm()->getForm(), 'postvoteForm');
96
97
        // Je recherche le post associé à entry + status == 0. Si non trouvé, je redirige vers home du jeu.
98
        $post = $this->getGameService()->getPostVotePostMapper()->findOneBy(array('entry' => $entry, 'status' => 0));
99
        if ($post) {
100
            foreach ($post->getPostElements() as $element) {
101
                try {
102
                    $form->get($element->getName())->setValue($element->getValue());
103
104
                    $elementType = $form->get($element->getName())->getAttribute('type');
105
                    if ($elementType == 'file' && $element->getValue() != '') {
106
                        $filter = $form->getInputFilter();
107
                        $elementInput = $filter->get($element->getName());
108
                        $elementInput->setRequired(false);
109
                        $form->get($element->getName())->setAttribute('required', false);
110
                    }
111
                } 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...
112
                }
113
            }
114
        }
115
116
        $viewModel = $this->buildView($this->game);
117
118
        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...
119
            // POST Request: Process form
120
            $data = array_merge_recursive(
121
                $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...
122
                $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...
123
            );
124
125
            $form->setData($data);
126
127
            if ($form->isValid()) {
128
                $data = $form->getData();
129
                $post = $this->getGameService()->createPost($data, $this->game, $this->user, $form);
130
131
                if ($post && !empty($this->game->nextStep('play'))) {
132
                    // determine the route where the user should go
133
                    $redirectUrl = $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...end\PostVoteController>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
134
                        'postvote/'.$this->game->nextStep('play'),
135
                        array(
136
                            'id' => $this->game->getIdentifier(),
137
                            
138
                        )
139
                    );
140
141
                    return $this->redirect()->toUrl($redirectUrl);
142
                }
143
            } else {
144
                $messages = $form->getMessages();
145
                $viewModel = $this->buildView($this->game);
146
                $viewModel->setVariables(array(
0 ignored issues
show
Bug introduced by
The method setVariables does only exist in Zend\View\Model\ViewModel, but not in Zend\Http\PhpEnvironment\Response.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
147
                    'success' => false,
148
                    'message' => implode(',', $messages['title']),
149
                ));
150
            }
151
        }
152
153
        $viewModel->setVariables(array(
154
                'playerData' => $entry->getPlayerData(),
155
                'form' => $form,
156
                'post' => $post,
157
            ));
158
159
        return $viewModel;
160
    }
161
162
    public function previewAction()
163
    {
164
        $entry = $this->getGameService()->findLastActiveEntry($this->game, $this->user);
165
         
166 View Code Duplication
        if (!$entry) {
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...
167
            // the user has already taken part of this game and the participation limit has been reached
168
            return $this->redirect()->toUrl(
169
                $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...end\PostVoteController>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
170
                    'postvote/'.$this->game->nextStep('preview'),
171
                    array('id' => $this->game->getIdentifier())
172
                )
173
            );
174
        }
175
176
        // Je recherche le post associé à entry + status == 0. Si non trouvé, je redirige vers home du jeu.
177
        $post = $this->getGameService()->getPostVotePostMapper()->findOneBy(array('entry' => $entry, 'status' => 0));
178
179
        if (! $post) {
180
            return $this->redirect()->toUrl(
181
                $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...end\PostVoteController>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
182
                    'postvote',
183
                    array('id' => $this->game->getIdentifier())
184
                )
185
            );
186
        }
187
188
        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...
189
            $post = $this->getGameService()->confirmPost($this->game, $this->user);
190
191
            if ($post) {
192
                if (!($step = $this->game->nextStep('play'))) {
193
                    $step = 'result';
194
                }
195
                $redirectUrl = $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...end\PostVoteController>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
196
                    'postvote/'.$step,
197
                    array('id' => $this->game->getIdentifier())
198
                );
199
200
                return $this->redirect()->toUrl($redirectUrl);
201
            }
202
        }
203
204
        $viewModel = $this->buildView($this->game);
205
        $viewModel->setVariables(array('post' => $post));
0 ignored issues
show
Bug introduced by
The method setVariables does only exist in Zend\View\Model\ViewModel, but not in Zend\Http\PhpEnvironment\Response.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
206
207
        return $viewModel;
208
    }
209
210
    /**
211
     * View the Post page
212
     * @return multitype:|\Zend\Http\Response|\Zend\View\Model\ViewModel
0 ignored issues
show
Documentation introduced by
The doc-type multitype:|\Zend\Http\Re...nd\View\Model\ViewModel could not be parsed: Unknown type name "multitype:" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
213
     */
214
    public function postAction()
215
    {
216
        $postId = $this->getEvent()->getRouteMatch()->getParam('post');
217
        $voted = false;
218
        $statusMail = false;
219
        $mailService = $this->getServiceLocator()->get('playgroundgame_message');
220
        $to = '';
221
        $skinUrl = $this->getGameService()->getServiceManager()->get('ViewRenderer')->url(
222
            'frontend',
223
            array(),
224
            array('force_canonical' => true)
225
        );
226
        $config = $this->getGameService()->getServiceManager()->get('config');
227
        if (isset($config['moderation']['email'])) {
228
            $to = $config['moderation']['email'];
229
        }
230
231
        if (! $postId) {
232
            return $this->notFoundAction();
233
        }
234
235
        // Je recherche le post associé à entry + status == 0. Si non trouvé, je redirige vers home du jeu.
236
        $post = $this->getGameService()->getPostVotePostMapper()->findById($postId);
237
238 View Code Duplication
        if (! $post || $post->getStatus() === 9) {
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...
239
            return $this->redirect()->toUrl(
240
                $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...end\PostVoteController>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
241
                    'postvote',
242
                    array('id' => $this->game->getIdentifier())
243
                )
244
            );
245
        }
246
247
        $formModeration = new Form();
248
        $formModeration->setAttribute('method', 'post');
249
250
        $formModeration->add(array(
251
            'name' => 'moderation',
252
            'attributes' => array(
253
                'type' => 'hidden',
254
                'value' => '1'
255
            ),
256
        ));
257
258
        $form = new \PlaygroundGame\Form\Frontend\PostVoteVote(
259
            $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...end\PostVoteController>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
260
                'postvote/post/captcha',
261
                array(
262
                    'id' => $this->game->getIdentifier(),
263
                    'post' => $postId,
264
                )
265
            )
266
        );
267
268
        if ($this->user) {
269
            $form->remove('captcha');
270
        }
271
272
        $alreadyVoted = '';
273
        $reportId = '';
274
275
        $request = $this->getRequest();
276
        if ($request->isPost()) {
277
            $data = $request->getPost()->toArray();
278
            if (isset($data['moderation'])) {
279
                $formModeration->setData($data);
280
                if ($formModeration->isValid()) {
281
                    $from = $to;
282
                    $subject= 'Moderation Post and Vote';
283
                    $result = $mailService->createHtmlMessage(
284
                        $from,
285
                        $to,
286
                        $subject,
287
                        'playground-game/email/moderation',
288
                        array('data' => $data, 'skinUrl' => $skinUrl)
289
                    );
290
                    $mailService->send($result);
291
                    if ($result) {
292
                        $statusMail = true;
293
                        $reportId = $data['reportid'];
294
                    }
295
                }
296
            } else {
297
                $form->setData($request->getPost());
298
                if ($form->isValid()) {
299
                    if ($this->getGameService()->addVote(
300
                        $this->user,
301
                        $this->getRequest()->getServer('REMOTE_ADDR'),
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 getServer() does only exist in the following implementations of said interface: Zend\Http\PhpEnvironment\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...
302
                        $post
303
                    )) {
304
                        $voted = true;
305
                    } else {
306
                        $alreadyVoted = 'Vous avez déjà voté!';
307
                    }
308
                }
309
            }
310
        }
311
312
        $viewModel = $this->buildView($this->game);
313
        $viewModel->setVariables(
0 ignored issues
show
Bug introduced by
The method setVariables does only exist in Zend\View\Model\ViewModel, but not in Zend\Http\PhpEnvironment\Response.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
314
            array(
315
                'post'  => $post,
316
                'voted' => $voted,
317
                'form'  => $form,
318
                'formModeration' => $formModeration,
319
                'statusMail' => $statusMail,
320
                'alreadyVoted' => $alreadyVoted,
321
                'reportId' => $reportId,
322
            )
323
        );
324
325
        return $viewModel;
326
    }
327
328
    /**
329
     *
330
     */
331
    public function resultAction()
332
    {
333
        // Je recherche le post associé à entry + status == 0. Si non trouvé, je redirige vers home du jeu.
334
        $post = $this->getGameService()->getPostVotePostMapper()->findOneBy(array('entry' => $lastEntry));
0 ignored issues
show
Bug introduced by
The variable $lastEntry 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...
335
336
        if (! $post) {
337
            return $this->redirect()->toUrl(
338
                $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...end\PostVoteController>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
339
                    'postvote',
340
                    array('id' => $this->game->getIdentifier())
341
                )
342
            );
343
        }
344
345
        $view = $this->forward()->dispatch(
346
            'playgroundgame_'.$this->game->getClassType(),
347
            array(
348
                'controller' => 'playgroundgame_'.$this->game->getClassType(),
349
                'action' => 'share',
350
                'id' => $this->game->getIdentifier()
351
            )
352
        );
353
354
        if ($view && $view instanceof \Zend\View\Model\ViewModel) {
355
            $view->setVariables(array('post' => $post));
356
357
            return $view;
358
        } elseif ($view && $view instanceof \Zend\Http\PhpEnvironment\Response) {
359
            return $view;
360
        } else {
361
            $form = $this->getServiceLocator()->get('playgroundgame_sharemail_form');
362
            $form->setAttribute('method', 'post');
363
364
            $viewModel = $this->buildView($this->game);
365
366
            $viewModel->setVariables(array(
0 ignored issues
show
Bug introduced by
The method setVariables does only exist in Zend\View\Model\ViewModel, but not in Zend\Http\PhpEnvironment\Response.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
367
                    'statusMail' => null,
368
                    'post' => $post,
369
                    'form' => $form,
370
                ));
371
372
            return $viewModel;
373
        }
374
    }
375
376
    /**
377
     * Example of AJAX File Upload with Session Progress and partial validation.
378
     * It's now possible to send a base64 image in this case the call is the form :
379
     * this._ajax(
380
     * {
381
     *   url: url.dataset.url,
382
     *    method: 'post',
383
     *    body: 'photo=' + image
384
     * },
385
     *
386
     * @return \Zend\Stdlib\ResponseInterface
387
     */
388
    public function ajaxuploadAction()
389
    {
390
        // Call this for the session lock to be released (other ajax calls can then be made)
391
        session_write_close();
392
393
        if (! $this->game) {
394
            $this->getResponse()->setContent(\Zend\Json\Json::encode(array(
395
                'success' => 0
396
            )));
397
398
            return $this->getResponse();
399
        }
400
401
        $entry = $this->getGameService()->findLastActiveEntry(
402
            $this->game,
403
            $this->user
404
        );
405
        if (!$entry) {
406
            // the user has already taken part of this game and the participation limit has been reached
407
            $this->getResponse()->setContent(\Zend\Json\Json::encode(array(
408
                'success' => 0
409
            )));
410
411
            return $this->getResponse();
412
        }
413
414
        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...
415
            $data = $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...
416
417
            if (empty($data)) {
418
                $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...
419
                $key = key($data);
420
                $uploadImage = array('name' => $key.'.png', 'error' => 0, 'base64' => $data[$key]);
421
                $data = array($key => $uploadImage);
422
            }
423
            $uploadFile = $this->getGameService()->uploadFileToPost(
424
                $data,
425
                $this->game,
426
                $this->user
427
            );
428
        }
429
430
        $this->getResponse()->setContent(\Zend\Json\Json::encode(array(
431
            'success' => true,
432
            'fileUrl' => $uploadFile
0 ignored issues
show
Bug introduced by
The variable $uploadFile 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...
433
        )));
434
435
        return $this->getResponse();
436
    }
437
438
    public function ajaxdeleteAction()
439
    {
440
        $response = $this->getResponse();
441
442
        if (! $this->game) {
443
            $response->setContent(\Zend\Json\Json::encode(array(
444
                'success' => 0
445
            )));
446
447
            return $response;
448
        }
449
450
        $entry = $this->getGameService()->findLastActiveEntry($this->game, $this->user);
451
        if (!$entry) {
452
            // the user has already taken part of this game and the participation limit has been reached
453
            $response->setContent(\Zend\Json\Json::encode(array(
454
                'success' => 0
455
            )));
456
457
            return $response;
458
        }
459
        if ($request->isPost()) {
460
            $data = $request->getPost()->toArray();
0 ignored issues
show
Bug introduced by
The variable $request 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...
461
            $this->getGameService()->deleteFilePosted($data, $this->game, $this->user);
462
        }
463
464
        $response->setContent(\Zend\Json\Json::encode(array(
465
            'success' => true,
466
        )));
467
468
        return $response;
469
    }
470
471
    public function listAction()
472
    {
473
        $filter = $this->getEvent()->getRouteMatch()->getParam('filter');
474
        $search = $this->params()->fromQuery('name');
475
        $postId = $this->params()->fromQuery('id');
476
        $statusMail = false;
477
        $mailService = $this->getServiceLocator()->get('playgroundgame_message');
478
        $to = '';
479
        $skinUrl = $this->getGameService()->getServiceManager()->get('ViewRenderer')->url(
480
            'frontend',
481
            array(),
482
            array('force_canonical' => true)
483
        );
484
        $config = $this->getGameService()->getServiceManager()->get('config');
485
        if (isset($config['moderation']['email'])) {
486
            $to = $config['moderation']['email'];
487
        }
488
489
        $request = $this->getRequest();
490
491
        // Je recherche les posts validés associés à ce jeu
492
        $posts = $this->getGameService()->findArrayOfValidatedPosts($this->game, $filter, $search);
493
494
        if (is_array($posts)) {
495
            $paginator = new \Zend\Paginator\Paginator(new \Zend\Paginator\Adapter\ArrayAdapter($posts));
496
            $paginator->setItemCountPerPage($this->game->getPostDisplayNumber());
497
            $paginator->setCurrentPageNumber($this->getEvent()->getRouteMatch()->getParam('p'));
498
        } else {
499
            $paginator = $posts;
500
        }
501
502
        $form = new Form();
503
        $form->setAttribute('method', 'post');
504
505
        $form->add(array(
506
            'name' => 'moderation',
507
            'attributes' => array(
508
                'type' => 'hidden',
509
                'value' => '1'
510
            ),
511
        ));
512
513
        $reportId ='';
514
515
        if ($request->isPost()) {
516
            $data = $request->getPost()->toArray();
517
518
            if (isset($data['moderation'])) {
519
                $from = $to;
520
                $subject= 'Moderation Post and Vote';
521
                $result = $mailService->createHtmlMessage(
522
                    $from,
523
                    $to,
524
                    $subject,
525
                    'playground-game/email/moderation',
526
                    array('data' => $data, 'skinUrl' => $skinUrl)
527
                );
528
                $mailService->send($result);
529
                if ($result) {
530
                    $statusMail = true;
531
                    $reportId = $data['reportid'];
532
                }
533
            }
534
        }
535
536
        $viewModel = $this->buildView($this->game);
537
        
538
        if ($postId) {
539
            $postTarget = $this->getGameService()->getPostVotePostMapper()->findById($postId);
540
            if ($postTarget) {
541 View Code Duplication
                foreach ($postTarget->getPostElements() 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...
542
                    $fbShareImage = $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...end\PostVoteController>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
543
                        '',
544
                        array(),
545
                        array('force_canonical' => true),
546
                        false
547
                    ) . $element->getValue();
548
                    break;
549
                }
550
                
551
                $secretKey = strtoupper(substr(sha1(uniqid('pg_', true).'####'.time()), 0, 15));
552
                
553
                // Without bit.ly shortener
554
                $socialLinkUrl = $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...end\PostVoteController>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
555
                    'postvote/list',
556
                    array(
557
                        'id' => $this->game->getIdentifier(),
558
                        'filter' => 'date'),
559
                    array('force_canonical' => true)
560
                ).'?id='.$postTarget->getId().'&key='.$secretKey;
561
                // With core shortener helper
562
                $socialLinkUrl = $this->shortenUrl()->shortenUrl($socialLinkUrl);
0 ignored issues
show
Documentation Bug introduced by
The method shortenUrl does not exist on object<PlaygroundGame\Co...end\PostVoteController>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
563
                
564
                $this->getViewHelper('HeadMeta')->setProperty('og:image', $fbShareImage);
0 ignored issues
show
Bug introduced by
The variable $fbShareImage 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...
565
                $this->getViewHelper('HeadMeta')->setProperty('twitter:card', "photo");
566
                $this->getViewHelper('HeadMeta')->setProperty('twitter:site', "@alfie_selfie");
567
                $this->getViewHelper('HeadMeta')->setProperty('twitter:title', $this->game->getTwShareMessage());
568
                $this->getViewHelper('HeadMeta')->setProperty('twitter:description', "");
569
                $this->getViewHelper('HeadMeta')->setProperty('twitter:image', $fbShareImage);
570
                $this->getViewHelper('HeadMeta')->setProperty('twitter:url', $socialLinkUrl);
571
            }
572
        }
573
        
574
        $viewModel->setVariables(array(
0 ignored issues
show
Bug introduced by
The method setVariables does only exist in Zend\View\Model\ViewModel, but not in Zend\Http\PhpEnvironment\Response.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
575
                'posts' => $paginator,
576
                'form' => $form,
577
                'statusMail' => $statusMail,
578
                'reportId' => $reportId,
579
                'filter' => $filter,
580
                'search' => $search,
581
            ));
582
583
        return $viewModel;
584
    }
585
586
    public function ajaxVoteAction()
587
    {
588
        // Call this for the session lock to be released (other ajax calls can then be made)
589
        session_write_close();
590
        $postId = $this->getEvent()->getRouteMatch()->getParam('post');
591
        $request = $this->getRequest();
592
        $response = $this->getResponse();
593
594
        if (! $this->game) {
595
            $response->setContent(\Zend\Json\Json::encode(array(
596
                'success' => 0
597
            )));
598
599
            return $response;
600
        }
601
602
        if (!$this->zfcUserAuthentication()->hasIdentity()) {
0 ignored issues
show
Documentation Bug introduced by
The method zfcUserAuthentication does not exist on object<PlaygroundGame\Co...end\PostVoteController>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
603
            $response->setContent(\Zend\Json\Json::encode(array(
604
                'success' => 0
605
            )));
606
        } else {
607
            if ($request->isPost()) {
608
                $post = $this->getGameService()->getPostvotePostMapper()->findById($postId);
609
                if ($this->getGameService()->addVote(
610
                    $this->user,
611
                    $this->getRequest()->getServer('REMOTE_ADDR'),
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 getServer() does only exist in the following implementations of said interface: Zend\Http\PhpEnvironment\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...
612
                    $post
613
                )) {
614
                    $response->setContent(\Zend\Json\Json::encode(array(
615
                        'success' => 1
616
                    )));
617
                } else {
618
                    $response->setContent(\Zend\Json\Json::encode(array(
619
                        'success' => 0
620
                    )));
621
                }
622
            }
623
        }
624
625
        return $response;
626
    }
627
628
    public function captchaAction()
629
    {
630
        $response = $this->getResponse();
631
        $response->getHeaders()->addHeaderLine('Content-Type', "image/png");
632
633
        $id = $this->params('id', false);
634
635
        if ($id) {
636
            $image = './data/captcha/' . $id;
637
638
            if (file_exists($image) !== false) {
639
                $imagegetcontent = file_get_contents($image);
640
641
                $response->setStatusCode(200);
642
                $response->setContent($imagegetcontent);
643
644
                if (file_exists($image) === true) {
645
                    unlink($image);
646
                }
647
            }
648
        }
649
650
        return $response;
651
    }
652
    
653
    public function shareAction()
654
    {
655
        $statusMail = null;
656
    
657
        // Has the user finished the game ?
658
        $lastEntry = $this->getGameService()->findLastInactiveEntry($this->game, $this->user);
659
    
660
        if ($lastEntry === null) {
661
            return $this->redirect()->toUrl(
662
                $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...end\PostVoteController>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
663
                    'postvote',
664
                    array('id' => $this->game->getIdentifier())
665
                )
666
            );
667
        }
668
    
669
        $post = $this->getGameService()->getPostVotePostMapper()->findOneBy(array('entry' => $lastEntry));
670
    
671
        $secretKey = strtoupper(substr(sha1(uniqid('pg_', true).'####'.time()), 0, 15));
672
        $socialLinkUrl = $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...end\PostVoteController>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
673
            'postvote/post',
674
            array(
675
                'id' => $this->game->getIdentifier(),
676
                'post' => $post->getId(),
677
            ),
678
            array('force_canonical' => true)
679
        ).'?key='.$secretKey;
680
        // With core shortener helper
681
        $socialLinkUrl = $this->shortenUrl()->shortenUrl($socialLinkUrl);
0 ignored issues
show
Documentation Bug introduced by
The method shortenUrl does not exist on object<PlaygroundGame\Co...end\PostVoteController>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
682
    
683
        $form = $this->getServiceLocator()->get('playgroundgame_sharemail_form');
684
        $form->setAttribute('method', 'post');
685
    
686
        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...
687
            $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...
688
            $form->setData($data);
689 View Code Duplication
            if ($form->isValid()) {
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...
690
                $result = $this->getGameService()->sendShareMail($data, $this->game, $this->user, $lastEntry);
691
                if ($result) {
692
                    $statusMail = true;
693
                }
694
            }
695
        }
696
697
        $viewModel = $this->buildView($this->game);
698
    
699 View Code Duplication
        foreach ($post->getPostElements() 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...
700
            $fbShareImage = $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...end\PostVoteController>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
701
                '',
702
                array(),
703
                array('force_canonical' => true),
704
                false
705
            ) . $element->getValue();
706
            break;
707
        }
708
709
        $this->getViewHelper('HeadMeta')->setProperty('og:image', $fbShareImage);
0 ignored issues
show
Bug introduced by
The variable $fbShareImage 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...
710
        $this->getViewHelper('HeadMeta')->setProperty('twitter:card', "photo");
711
        $this->getViewHelper('HeadMeta')->setProperty('twitter:site', "@playground");
712
        $this->getViewHelper('HeadMeta')->setProperty('twitter:title', $this->game->getTwShareMessage());
713
        $this->getViewHelper('HeadMeta')->setProperty('twitter:description', "");
714
        $this->getViewHelper('HeadMeta')->setProperty('twitter:image', $fbShareImage);
715
        $this->getViewHelper('HeadMeta')->setProperty('twitter:url', $socialLinkUrl);
716
            
717
        $viewModel->setVariables(array(
0 ignored issues
show
Bug introduced by
The method setVariables does only exist in Zend\View\Model\ViewModel, but not in Zend\Http\PhpEnvironment\Response.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
718
            'statusMail'       => $statusMail,
719
            'form'             => $form,
720
            'socialLinkUrl'    => $socialLinkUrl,
721
            'post'             => $post
722
        ));
723
    
724
        return $viewModel;
725
    }
726
727
    public function getGameService()
728
    {
729
        if (!$this->gameService) {
730
            $this->gameService = $this->getServiceLocator()->get('playgroundgame_postvote_service');
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->getServiceLocator...game_postvote_service') can also be of type array. However, the property $gameService is declared as type object<PlaygroundGame\Co...r\Frontend\gameService>. 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...
731
        }
732
733
        return $this->gameService;
734
    }
735
}
736