GameController::registerAction()   F
last analyzed

Complexity

Conditions 21
Paths 129

Size

Total Lines 149

Duplication

Lines 36
Ratio 24.16 %

Importance

Changes 0
Metric Value
dl 36
loc 149
rs 3.14
c 0
b 0
f 0
cc 21
nc 129
nop 0

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
2
3
namespace PlaygroundGame\Controller\Frontend;
4
5
use PlaygroundGame\Service\GameService;
6
use PlaygroundGame\Service\Prize as PrizeService;
7
use Zend\Http\PhpEnvironment\Response;
8
use Zend\Mvc\Controller\AbstractActionController;
9
use Zend\ServiceManager\ServiceLocatorInterface;
10
use Zend\Session\Container;
11
use Zend\Stdlib\Parameters;
12
use Zend\View\Model\JsonModel;
13
use Zend\View\Model\ViewModel;
14
15
class GameController extends AbstractActionController
16
{
17
    /**
18
     * @var \PlaygroundGame\Service\GameService
19
     */
20
    protected $gameService;
21
22
    protected $prizeService;
23
24
    protected $options;
25
26
    protected $game;
27
28
    protected $user;
29
30
    protected $withGame = array(
31
        'home',
32
        'index',
33
        'terms',
34
        'conditions',
35
        'leaderboard',
36
        'register',
37
        'bounce',
38
        'createTeam',
39
        'inviteToTeam',
40
        'prizes',
41
        'prize',
42
        'share',
43
        'optin',
44
        'terms-optin',
45
        'login',
46
        'logout',
47
        'ajaxforgot',
48
        'play',
49
        'result',
50
        'preview',
51
        'list',
52
        'comments',
53
    );
54
55
    protected $withOnlineGame = array(
56
        'leaderboard',
57
        'register',
58
        'bounce',
59
        'play',
60
        'result',
61
    );
62
63
    /**
64
     * These steps are available only when the game is started
65
     */
66
    protected $withStartedGame = array(
67
        'preview',
68
        'createTeam',
69
        'inviteToTeam',
70
        'register',
71
        'play',
72
    );
73
74
    protected $withAnyUser = array(
75
        'share',
76
        'result',
77
        'play',
78
        'logout',
79
        'createTeam',
80
        'inviteToTeam',
81
    );
82
83
    protected $isSoloGame = false;
84
85
    /**
86
     *
87
     * @var ServiceManager
88
     */
89
    protected $serviceLocator;
90
91
    public function __construct(ServiceLocatorInterface $locator)
92
    {
93
        $this->serviceLocator = $locator;
0 ignored issues
show
Documentation Bug introduced by
It seems like $locator of type object<Zend\ServiceManag...erviceLocatorInterface> is incompatible with the declared type object<PlaygroundGame\Co...rontend\ServiceManager> of property $serviceLocator.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
94
    }
95
96
    public function getServiceLocator()
97
    {
98
        return $this->serviceLocator;
99
    }
100
101
    public function setEventManager(\Zend\EventManager\EventManagerInterface $events)
102
    {
103
        parent::setEventManager($events);
104
105
        $controller = $this;
106
107
        $events->attach('dispatch', function (\Zend\Mvc\MvcEvent $e) use ($controller) {
108
109
            $session = new Container('facebook');
110
            $identifier = $e->getRouteMatch()->getParam('id');
111
112
            // I set the right identifier if I come from FB
113
            // From FB, the games have all the same identifier. I use the FB Page Id to find the right game
114
            // So for 1 FB page, you can have only 1 game ;/
115
            if ($identifier === 'facebook' && $session->offsetExists('signed_request')) {
116
                $sr = $session->offsetGet('signed_request');
117
                $identifier = $controller->getGameService()->getGameIdentifierFromFacebook($sr['page']['id']);
118
            }
119
     
120
            $controller->game = $controller->getGameService()->checkGame($identifier, false);
121
122
            if (!$controller->game
123
                && in_array($controller->params('action'), $controller->withGame)
124
            ) {
125
                return $controller->notFoundAction();
126
            }
127
128
            if ($controller->game
129
                && $controller->game->isClosed()
130
                && in_array($controller->params('action'), $controller->withOnlineGame)
131
            ) {
132
                return $controller->notFoundAction();
133
            }
134
135
            $config = $this->getServiceLocator()->get('config');
136
            $customUrl = str_replace('frontend.', '', $e->getRouteMatch()->getMatchedRouteName());
137
            $customUrl = explode("/", $customUrl)[0];
138
139
            if (isset($config['custom_games'])
140
                && $controller->game !== false
141
                && isset($config['custom_games'][$controller->game->getIdentifier()])
142
                && $controller->getRequest()->getUri()->getHost() === $customUrl
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 getUri() does only exist in the following implementations of said interface: Zend\Http\PhpEnvironment\Request, Zend\Http\Request, Zend\Psr7Bridge\Zend\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...
143
            ) {
144
                $this->isSoloGame = true;
145
            }
146
147
            if ($controller->game) {
148
                // this is possible to create a specific game design in /design/frontend/default/custom.
149
                //It will precede all others templates.
150
                $templatePathResolver = $controller->getServiceLocator()->get('Zend\View\Resolver\TemplatePathStack');
151
                $l = $templatePathResolver->getPaths();
152
                $templatePathResolver->addPath($l[0].'custom/'.$controller->game->getIdentifier());
153
            }
154
155
            $controller->user = $controller->zfcUserAuthentication()->getIdentity();
0 ignored issues
show
Documentation Bug introduced by
The method zfcUserAuthentication does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
156
            if ($controller->game
157
                && !$controller->user
158
                && !$controller->game->getAnonymousAllowed()
159
                && in_array($controller->params('action'), $controller->withAnyUser)
160
            ) {
161
                // if the current game runs under Facebook
162
                if ($session->offsetExists('signed_request')) {
163
                    $session->offsetSet('fb-redirect', $controller->getRequest()->getUri());
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 getUri() does only exist in the following implementations of said interface: Zend\Http\PhpEnvironment\Request, Zend\Http\Request, Zend\Psr7Bridge\Zend\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...
164
                    // Let's start the FB registration dance !
165
                    $controller->forward()->dispatch(
166
                        'playgrounduser_user',
167
                        array(
168
                            'controller' => 'playgrounduser_user',
169
                            'action'     => 'registerFacebookUser',
170
                            'provider'   => 'facebook',
171
                        )
172
                    );
173
                }
174
                $redirect = urlencode(
175
                    $controller->url()->fromRoute(
176
                        'frontend/'.$controller->game->getClassType().'/'.$controller->params('action'),
177
                        array('id'              => $controller->game->getIdentifier()),
178
                        array('force_canonical' => true)
179
                    )
180
                );
181
182
                if ($this->isSoloGame) {
183
                     $urlRegister = $controller->url()->fromRoute(
184
                         'frontend.'.$customUrl.'/'.$controller->game->getClassType().'/user-register',
185
                         array(),
186
                         array('force_canonical' => true)
187
                     ).'?redirect='.$redirect;
188
                } else {
189
                    $urlRegister = $controller->url()->fromRoute(
190
                        'frontend/zfcuser/register',
191
                        array(),
192
                        array('force_canonical' => true)
193
                    ).'?redirect='.$redirect;
194
                }
195
196
                // code permettant d'identifier un custom game
197
                // ligne $config = $controller->getGameService()->getServiceManager()->get('config');
198
                // ligne $customUrl = str_replace('frontend.', '', $e->getRouteMatch()->getParam('area', ''));
199
                // ligne if ($config['custom_games'][$controller->game->getIdentifier()] &&
200
                // ligne    $controller->getRequest()->getUri()->getHost() === $customUrl
201
                // ligne ) {
202
                return $controller->redirect()->toUrl($urlRegister);
203
            }
204
205
            // If the game is finished, I redirect some actions to result (you can't play it anymore)
206
            if ($controller->game
207
                && $controller->game->isFinished()
208
                && in_array($controller->params('action'), $controller->withStartedGame)
209
            ) {
210
                if ($this->isSoloGame) {
211
                    $urlResult = $controller->url()->fromRoute(
212
                        'frontend.'.$customUrl.'/'.$controller->game->getClassType().'/result',
213
                        array('id' => $controller->game->getIdentifier()),
214
                        array('force_canonical' => true)
215
                    );
216
                } else {
217
                    $urlResult = $controller->url()->fromRoute(
218
                        'frontend/'.$controller->game->getClassType().'/result',
219
                        array('id' => $controller->game->getIdentifier()),
220
                        array('force_canonical' => true)
221
                    );
222
                }
223
                return $controller->redirect()->toUrl($urlResult);
224
            }
225
226
                return;
227
        }, 100);// execute before executing action logic
228
    }
229
230
    /**
231
     * Action called if matched action does not exist
232
     * For this view not to be catched by Zend\Mvc\View\RouteNotFoundStrategy
233
     * it has to be rendered in the controller. Hence the code below.
234
     *
235
     * This action is injected as a catchall action for each custom_games definition
236
     * This way, when a custom_game is created, the 404 is it's responsability and the
237
     * view can be defined in design/frontend/default/custom/$slug/playground_game/$gametype/404.phtml
238
     *
239
     *
240
     * @return \Zend\Stdlib\ResponseInterface
241
     */
242
    public function notFoundAction()
243
    {
244
        $templatePathResolver = $this->getServiceLocator()->get('Zend\View\Resolver\TemplatePathStack');
245
246
        // I create a template path in which I can find a custom template
247
        $controller     = explode('\\', get_class($this));
248
        $controllerPath = str_replace('Controller', '', end($controller));
249
        $controllerPath = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '-\\1', $controllerPath));
250
        $uri            = $this->getRequest()->getUri()->getPath();
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 getUri() does only exist in the following implementations of said interface: Zend\Http\PhpEnvironment\Request, Zend\Http\Request, Zend\Psr7Bridge\Zend\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...
251
        if ($this->game) {
252
            $uri = str_replace($controllerPath.'/'.$this->game->getIdentifier().'/', '', $uri);
253
        }
254
        $uri      = str_replace("/".$this->getEvent()->getRouteMatch()->getParam('locale')."/", "/", $uri);
255
        $template = 'playground-game/'.$controllerPath.'/custom'.$uri;
256
257
        $template = (substr($template, -strlen('.html')) === '.html') ? $template : $template . '.phtml';
258
        if (false === $templatePathResolver->resolve($template)) {
259
            $viewRender = $this->getServiceLocator()->get('ViewRenderer');
260
261
            $this->getEvent()->getRouteMatch()->setParam('action', 'not-found');
262
            $this->response->setStatusCode(404);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Zend\Stdlib\ResponseInterface as the method setStatusCode() does only exist in the following implementations of said interface: Zend\Http\PhpEnvironment\Response, Zend\Http\Response, Zend\Http\Response\Stream.

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...
263
264
            $res = 'error/404';
265
266
            $viewModel = $this->buildView($this->game);
267
            $viewModel->setTemplate($res);
0 ignored issues
show
Bug introduced by
The method setTemplate 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...
268
269
            $this->layout()->setVariable("content", $viewRender->render($viewModel));
0 ignored issues
show
Bug introduced by
The method setVariable does only exist in Zend\View\Model\ModelInterface, but not in Zend\Mvc\Controller\Plugin\Layout.

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...
270
            $this->response->setContent($viewRender->render($this->layout()));
271
272
            return $this->response;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->response; (Zend\Stdlib\ResponseInterface) is incompatible with the return type of the parent method Zend\Mvc\Controller\Abst...troller::notFoundAction of type Zend\View\Model\ViewModel.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
273
        }
274
275
        $viewModel = $this->buildView($this->game);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->buildView($this->game); of type Zend\Http\PhpEnvironment...nd\View\Model\ViewModel adds the type Zend\View\Model\ViewModel to the return on line 278 which is incompatible with the return type documented by PlaygroundGame\Controlle...troller::notFoundAction of type Zend\Stdlib\ResponseInterface.
Loading history...
276
        $viewModel->setTemplate($template);
277
278
        return $viewModel;
279
    }
280
281
    /**
282
     * This action acts as a hub : Depending on the first step of the game, it will forward the action to this step
283
     */
284
    public function homeAction()
285
    {
286
        // This fix exists only for safari in FB on Windows : we need to redirect the user to the page
287
        // outside of iframe for the cookie to be accepted. PlaygroundCore redirects to the FB Iframed page when
288
        // it discovers that the user arrives for the first time on the game in FB.
289
        // When core redirects, it adds a 'redir_fb_page_id' var in the querystring
290
        // Here, we test if this var exist, and then send the user back to the game in FB.
291
        // Now the cookie will be accepted by Safari...
292
        $pageId = $this->params()->fromQuery('redir_fb_page_id');
293
        if (!empty($pageId)) {
294
            $appId = 'app_'.$this->game->getFbAppId();
295
            $url   = '//www.facebook.com/pages/game/'.$pageId.'?sk='.$appId;
296
297
            return $this->redirect()->toUrl($url);
298
        }
299
300
        // If an entry has already been done during this session, I reset the anonymous_identifier cookie
301
        // so that another person can play the same game (if game conditions are fullfilled)
302
        // or the same person can play another game
303
        $session = new Container('anonymous_identifier');
304
        if ($session->offsetExists('anonymous_identifier')) {
305
            $session->offsetUnset('anonymous_identifier');
306
        }
307
308
        $classGame = __NAMESPACE__ . '\\' . ucfirst($this->game->getClassType());
309
        return $this->forward()->dispatch(
310
            $classGame,
311
            array(
312
                'controller' => $classGame,
313
                'action'     => $this->game->firstStep(),
314
                'id'         => $this->game->getIdentifier()
315
            )
316
        );
317
    }
318
319
    /**
320
     * Homepage of the game
321
     */
322
    public function indexAction()
323
    {
324
        $isSubscribed = false;
325
326
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
327
        if ($entry) {
328
            $isSubscribed = true;
329
        }
330
331
        $viewModel = $this->buildView($this->game);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->buildView($this->game); of type Zend\Http\PhpEnvironment...nd\View\Model\ViewModel adds the type Zend\Http\PhpEnvironment\Response to the return on line 336 which is incompatible with the return type of the parent method Zend\Mvc\Controller\Abst...Controller::indexAction of type Zend\View\Model\ViewModel.
Loading history...
332
        $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...
333
            'isSubscribed' => $isSubscribed,
334
        ));
335
336
        return $viewModel;
337
    }
338
339
    /**
340
     * leaderboardAction
341
     *
342
     * @return ViewModel $viewModel
343
     */
344
    public function leaderboardAction()
345
    {
346
        $filter = $this->getEvent()->getRouteMatch()->getParam('filter');
347
        $p      = $this->getEvent()->getRouteMatch()->getParam('p');
348
349
        $beforeLayout = $this->layout()->getTemplate();
0 ignored issues
show
Bug introduced by
The method getTemplate does only exist in Zend\View\Model\ModelInterface, but not in Zend\Mvc\Controller\Plugin\Layout.

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...
350
        $subViewModel = $this->forward()->dispatch(
351
            'playgroundreward',
352
            array('action' => 'leaderboard', 'filter' => $filter, 'p' => $p)
353
        );
354
355
        // suite au forward, le template de layout a changé, je dois le rétablir...
356
        $this->layout()->setTemplate($beforeLayout);
357
        $this->layout()->setVariables(
0 ignored issues
show
Bug introduced by
The method setVariables does only exist in Zend\View\Model\ModelInterface, but not in Zend\Mvc\Controller\Plugin\Layout.

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...
358
            array(
359
                'action' => $this->params('action'),
360
                'game'   => $this->game,
361
            )
362
        );
363
364
        $subViewModel->setVariables($this->getShareData($this->game));
365
        $subViewModel->setVariables(array('game' => $this->game, 'user' => $this->user));
366
367
        return $subViewModel;
368
    }
369
370
    /**
371
     * This action has been designed to be called by other controllers
372
     * It gives the ability to display an information form and persist it in the game entry
373
     *
374
     * @return \Zend\View\Model\ViewModel
375
     */
376
    public function registerAction()
377
    {
378
        $formDef = $this->game->getPlayerForm();
379
        if ($formDef !== null) {
380
            $form = $this->getGameService()->createFormFromJson($formDef->getForm(), 'playerForm');
381
        } else {
382
            return $this->notFoundAction();
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->notFoundAction(); (Zend\Stdlib\ResponseInterface) is incompatible with the return type documented by PlaygroundGame\Controlle...troller::registerAction of type Zend\View\Model\ViewModel.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
383
        }
384
385
        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, Zend\Psr7Bridge\Zend\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...
386
            // POST Request: Process form
387
            $data = array_merge_recursive(
388
                $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, Zend\Psr7Bridge\Zend\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...
389
                $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, Zend\Psr7Bridge\Zend\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...
390
            );
391
392
            $form->setData($data);
393
394
            if ($form->isValid()) {
395
                // steps of the game
396
                $steps = $this->game->getStepsArray();
397
                // sub steps of the game
398
                $viewSteps = $this->game->getStepsViewsArray();
399
                $keyStep = false;
400
401
                // register position
402
                $key = array_search($this->params('action'), $viewSteps);
403
                if ($key === false) {
404
                    // register is not a substep of the game so it's a step
405
                    $key     = array_search($this->params('action'), $steps);
406
                    if ($key !== false) {
407
                        $keyStep = true;
408
                    } else {
409
                        $key = -1;
410
                    }
411
                } else {
412
                    // register was a substep, I search the index of its parent
413
                    $key     = array_search($key, $steps);
414
                }
415
416
                // play position
417
                $keyplay = array_search('play', $viewSteps);
418
419
                if (!$keyplay) {
420
                    // play is not a substep, so it's a step
421
                    $keyplay     = array_search('play', $steps);
422
                    $keyplayStep = true;
423
                } else {
424
                    // play is a substep so I search the index of its parent
425
                    $keyplay     = array_search($keyplay, $steps);
426
                    $keyplayStep = false;
427
                }
428
429
                // If register step before play, I don't have no entry yet. I have to create one
430
                // If register after play step, I search for the last entry created by play step.
431
                if ($key < $keyplay || ($keyStep && !$keyplayStep && $key <= $keyplay)) {
432
                    // I need to check if this anonymous user has already played. This one is transmitted through
433
                    // a cookie... so I need to fill in this cookie if it's not already updated.
434
                    if ($this->game->getAnonymousAllowed() &&
435
                        $this->game->getAnonymousIdentifier() &&
436
                        isset($data[$this->game->getAnonymousIdentifier()])
437
                    ) {
438
                        $session = new \Zend\Session\Container('anonymous_identifier');
439
                        if (empty($session->offsetGet('anonymous_identifier'))) {
440
                            $anonymousIdentifier = $data[$this->game->getAnonymousIdentifier()];
441
                        
442
                            // I must transmit this info during the whole game workflow
443
                            $session->offsetSet('anonymous_identifier', $anonymousIdentifier);
444
                        }
445
                    }
446
                    $playError = null;
447
                    $entry = $this->getGameService()->play($this->game, $this->user, $playError);
448 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...
449
                        $reason = "";
0 ignored issues
show
Unused Code introduced by
$reason is not used, you could remove the assignment.

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

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

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

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

Loading history...
450
                        if ($playError === -1) {
451
                            // the user has already taken part to this game and the participation limit has been reached
452
                            $this->flashMessenger()->addMessage('Vous avez déjà participé');
0 ignored issues
show
Documentation Bug introduced by
The method flashMessenger does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
453
                            $reason = '?playLimitReached=1';
454
                            $noEntryRedirect = $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
455
                                $this->game->getClassType().'/result',
456
                                array(
457
                                    'id' => $this->game->getIdentifier(),
458
                                )
459
                            ) .$reason;
460
                        } elseif ($playError === -2) {
461
                            // the user has not accepted the mandatory rules of the game
462
                            $this->flashMessenger()->addMessage('Vous devez accepter le réglement');
0 ignored issues
show
Documentation Bug introduced by
The method flashMessenger does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
463
                            $reason = '?NoOptin=1';
464
                            $noEntryRedirect = $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
465
                                $this->game->getClassType(),
466
                                array(
467
                                    'id' => $this->game->getIdentifier(),
468
                                )
469
                            ) .$reason;
470
                        } elseif ($playError === -3) {
471
                            // the user has enough points to buy an entry to this game
472
                            $this->flashMessenger()->addMessage("Vous ne pouvez pas acheter la partie");
0 ignored issues
show
Documentation Bug introduced by
The method flashMessenger does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
473
                            $reason = '?NotPaid=1';
474
                            $noEntryRedirect = $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
475
                                $this->game->getClassType(),
476
                                array(
477
                                    'id' => $this->game->getIdentifier(),
478
                                )
479
                            ) .$reason;
480
                        }
481
482
                        return $this->redirect()->toUrl($noEntryRedirect);
0 ignored issues
show
Bug introduced by
The variable $noEntryRedirect 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...
Bug Best Practice introduced by
The return type of return $this->redirect()...oUrl($noEntryRedirect); (Zend\Http\Response) is incompatible with the return type documented by PlaygroundGame\Controlle...troller::registerAction of type Zend\View\Model\ViewModel.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
483
                    }
484
                } else {
485
                    // I'm looking for an entry without anonymousIdentifier (the active entry in fact).
486
                    $entry = $this->getGameService()->findLastEntry($this->game, $this->user);
487
                    if ($this->getGameService()->hasReachedPlayLimit($this->game, $this->user)) {
488
                        // the user has already taken part of this game and the participation limit has been reached
489
                        $this->flashMessenger()->addMessage('Vous avez déjà participé');
0 ignored issues
show
Documentation Bug introduced by
The method flashMessenger does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
490
491
                        return $this->redirect()->toUrl(
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->redirect()...me->getIdentifier()))); (Zend\Http\Response) is incompatible with the return type documented by PlaygroundGame\Controlle...troller::registerAction of type Zend\View\Model\ViewModel.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
492
                            $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
493
                                $this->game->getClassType().'/result',
494
                                array(
495
                                    'id' => $this->game->getIdentifier(),
496
                                )
497
                            )
498
                        );
499
                    }
500
                }
501
502
                $this->getGameService()->updateEntryPlayerForm($form->getData(), $this->game, $this->user, $entry);
503
504
                if (!empty($this->game->nextStep($this->params('action')))) {
505
                    return $this->redirect()->toUrl(
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->redirect()..._canonical' => true))); (Zend\Http\Response) is incompatible with the return type documented by PlaygroundGame\Controlle...troller::registerAction of type Zend\View\Model\ViewModel.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
506
                        $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
507
                            $this->game->getClassType().'/'.$this->game->nextStep($this->params('action')),
508
                            array('id'              => $this->game->getIdentifier()),
509
                            array('force_canonical' => true)
510
                        )
511
                    );
512
                }
513
            }
514
        }
515
516
        $viewModel = $this->buildView($this->game);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->buildView($this->game); of type Zend\Http\PhpEnvironment...nd\View\Model\ViewModel adds the type Zend\Http\PhpEnvironment\Response to the return on line 523 which is incompatible with the return type documented by PlaygroundGame\Controlle...troller::registerAction of type Zend\View\Model\ViewModel.
Loading history...
517
        $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...
518
            array(
519
                'form' => $form,
520
            )
521
        );
522
523
        return $viewModel;
524
    }
525
526
    /**
527
     * This action takes care of the terms of the game
528
     */
529
    public function termsAction()
530
    {
531
        $viewModel = $this->buildView($this->game);
532
533
        return $viewModel;
534
    }
535
536
    /**
537
     * This action takes care of the conditions of the game
538
     */
539
    public function conditionsAction()
540
    {
541
        $viewModel = $this->buildView($this->game);
542
543
        return $viewModel;
544
    }
545
546
    /**
547
     * This action takes care of bounce page of the game
548
     */
549
    public function bounceAction()
550
    {
551
        $availableGames = $this->getGameService()->getAvailableGames($this->user);
552
553
        $rssUrl = '';
554
        $config = $this->getGameService()->getServiceManager()->get('config');
555
        if (isset($config['rss']['url'])) {
556
            $rssUrl = $config['rss']['url'];
557
        }
558
559
        $viewModel = $this->buildView($this->game);
560
        $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...
561
                'rssUrl'         => $rssUrl,
562
                'user'           => $this->user,
563
                'availableGames' => $availableGames,
564
            ));
565
566
        return $viewModel;
567
    }
568
569
    /**
570
     * This action displays the Prizes page associated to the game
571
     */
572
    public function prizesAction()
573
    {
574
        if (count($this->game->getPrizes()) == 0) {
575
            return $this->notFoundAction();
576
        }
577
578
        $viewModel = $this->buildView($this->game);
579
580
        return $viewModel;
581
    }
582
583
    /**
584
     * This action displays a specific Prize page among those associated to the game
585
     */
586
    public function prizeAction()
587
    {
588
        $prizeIdentifier = $this->getEvent()->getRouteMatch()->getParam('prize');
589
        $prize           = $this->getPrizeService()->getPrizeMapper()->findByIdentifier($prizeIdentifier);
590
591
        if (!$prize) {
592
            return $this->notFoundAction();
593
        }
594
595
        $viewModel = $this->buildView($this->game);
596
        $viewModel->setVariables(array('prize' => $prize));
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...
597
598
        return $viewModel;
599
    }
600
601
    public function gameslistAction()
602
    {
603
        $layoutViewModel = $this->layout();
604
605
        $slider = new ViewModel();
606
        $slider->setTemplate('playground-game/common/top_promo');
607
608
        $sliderItems = $this->getGameService()->getActiveSliderGames();
609
610
        $slider->setVariables(array('sliderItems' => $sliderItems));
611
612
        $layoutViewModel->addChild($slider, 'slider');
0 ignored issues
show
Bug introduced by
The method addChild does only exist in Zend\View\Model\ModelInterface, but not in Zend\Mvc\Controller\Plugin\Layout.

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...
613
614
        $games = $this->getGameService()->getActiveGames(false, '', 'endDate');
615
        if (is_array($games)) {
616
            $paginator = new \Zend\Paginator\Paginator(new \Zend\Paginator\Adapter\ArrayAdapter($games));
617
        } else {
618
            $paginator = $games;
619
        }
620
621
        $paginator->setItemCountPerPage(7);
622
        $paginator->setCurrentPageNumber($this->getEvent()->getRouteMatch()->getParam('p'));
623
624
        $bitlyclient = $this->getOptions()->getBitlyUrl();
625
        $bitlyuser   = $this->getOptions()->getBitlyUsername();
626
        $bitlykey    = $this->getOptions()->getBitlyApiKey();
627
628
        $this->getViewHelper('HeadMeta')->setProperty('bt:client', $bitlyclient);
629
        $this->getViewHelper('HeadMeta')->setProperty('bt:user', $bitlyuser);
630
        $this->getViewHelper('HeadMeta')->setProperty('bt:key', $bitlykey);
631
632
        $this->layout()->setVariables(
0 ignored issues
show
Bug introduced by
The method setVariables does only exist in Zend\View\Model\ModelInterface, but not in Zend\Mvc\Controller\Plugin\Layout.

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...
633
            array(
634
                'sliderItems'  => $sliderItems,
635
                'currentPage'  => array(
636
                    'pageGames'   => 'games',
637
                    'pageWinners' => '',
638
                ),
639
            )
640
        );
641
642
        return new ViewModel(
643
            array(
644
                'games' => $paginator,
645
            )
646
        );
647
    }
648
649
    public function shareAction()
650
    {
651
        $statusMail = null;
652
        $lastEntry = $this->getGameService()->findLastInactiveEntry($this->game, $this->user);
653
654
        $form = $this->getServiceLocator()->get('playgroundgame_sharemail_form');
655
        $form->setAttribute('method', 'post');
656
657
        // buildView must be before sendMail because it adds the game template path to the templateStack
658
        $viewModel = $this->buildView($this->game);
659
660 View Code Duplication
        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, Zend\Psr7Bridge\Zend\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...
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...
661
            $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, Zend\Psr7Bridge\Zend\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...
662
            $form->setData($data);
663
            if ($form->isValid()) {
664
                $result = $this->getGameService()->sendShareMail($data, $this->game, $this->user, $lastEntry);
665
                if ($result) {
666
                    $statusMail = true;
667
                }
668
            }
669
        }
670
671
        $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...
672
            [
673
                'statusMail' => $statusMail,
674
                'form'       => $form,
675
            ]
676
        );
677
678
        return $viewModel;
679
    }
680
681
    public function inviteToTeamAction()
682
    {
683
684
        if (count($this->user->getTeams()) == 0) {
685
            return $this->redirect()->toUrl(
686
                $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
687
                    $this->game->getClassType().'/create-team',
688
                    array('id' => $this->game->getIdentifier())
689
                )
690
            );
691
        }
692
693
        $team = $this->user->getTeams()->first();
694
        $invitationMapper = $this->getServiceLocator()->get('playgroundgame_invitation_mapper');
695
        $invitations = $invitationMapper->findBy(array('host' => $this->user, 'game' => $this->game));
696
        $statusMail = null;
697
        $message = '';
698
        $isHost = ($this->user->getId() === $team->getHost()->getId()) ? true : false;
699
700
        $form = $this->getServiceLocator()->get('playgroundgame_sharemail_form');
701
        $form->setAttribute('method', 'post');
702
703
        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, Zend\Psr7Bridge\Zend\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...
704
            $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, Zend\Psr7Bridge\Zend\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...
705
            $form->setData($data);
706
            if ($form->isValid()) {
707
                $result = $this->getGameService()->inviteToTeam($data, $this->game, $this->user);
708
                if ($result['result']) {
709
                    $statusMail = true;
710
                } else {
711
                    $statusMail = false;
712
                    $message    = $result['message'];
713
                }
714
            }
715
        }
716
717
        $viewModel = $this->buildView($this->game);
718
        $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...
719
            'team'       => $team,
720
            'invitations'=> $invitations,
721
            'message'    => $message,
722
            'statusMail' => $statusMail,
723
            'form'       => $form,
724
            'isHost'     => $isHost,
725
        ));
726
727
        return $viewModel;
728
    }
729
730
    public function createTeamAction()
731
    {
732
        if (count($this->user->getTeams()) > 0) {
733
            return $this->redirect()->toUrl(
734
                $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
735
                    $this->game->getClassType().'/invite-to-team',
736
                    array('id' => $this->game->getIdentifier())
737
                )
738
            );
739
        }
740
741
        $form = $this->getServiceLocator()->get('playgroundgame_createteam_form');
742
        $form->setAttribute('method', 'post');
743
744
        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, Zend\Psr7Bridge\Zend\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...
745
            $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, Zend\Psr7Bridge\Zend\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...
746
            $form->setData($data);
747
            if ($form->isValid()) {
748
                $teamMapper = $this->getServiceLocator()->get('playgrounduser_team_mapper');
749
                $users = new \Doctrine\Common\Collections\ArrayCollection();
750
                $users->add($this->user);
751
                $teamName = $data['name'];
752
                $slugify = new \PlaygroundCore\Filter\Slugify;
753
754
                $team = new \PlaygroundUser\Entity\Team();
755
                $team->setName($teamName);
756
                $team->setIdentifier($slugify($teamName));
757
                $team->setHost($this->user);
758
                $team->addUsers($users);
759
760
                $teamMapper->insert($team);
761
762
                return $this->redirect()->toUrl(
763
                    $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
764
                        $this->game->getClassType().'/invite-to-team',
765
                        array('id' => $this->game->getIdentifier())
766
                    )
767
                );
768
            }
769
        }
770
771
        $viewModel = $this->buildView($this->game);
772
        $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...
773
            'form'       => $form,
774
        ));
775
776
        return $viewModel;
777
    }
778
779 View Code Duplication
    public function fbshareAction()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
780
    {
781
        $viewModel = new JsonModel();
782
        $viewModel->setTerminal(true);
783
        $fbId = $this->params()->fromQuery('fbId');
784
        if (!$this->game) {
785
            return $this->errorJson();
786
        }
787
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
788
        if (!$entry) {
789
            return $this->errorJson();
790
        }
791
        if (!$fbId) {
792
            return $this->errorJson();
793
        }
794
795
        $this->getGameService()->postFbWall($fbId, $this->game, $this->user, $entry);
796
797
        return $this->successJson();
798
    }
799
800
    public function fbrequestAction()
801
    {
802
        $viewModel = new ViewModel();
803
        $viewModel->setTerminal(true);
804
        $fbId = $this->params()->fromQuery('fbId');
805
        $to   = $this->params()->fromQuery('to');
806
807
        if (!$this->game) {
808
            return $this->errorJson();
809
        }
810
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
811
        if (!$entry) {
812
            return $this->errorJson();
813
        }
814
        if (!$fbId) {
815
            return $this->errorJson();
816
        }
817
818
        $this->getGameService()->postFbRequest($fbId, $this->game, $this->user, $entry, $to);
819
820
        return $this->successJson();
821
    }
822
823
    public function tweetAction()
824
    {
825
        $tweetId = $this->params()->fromQuery('tweetId');
826
827
        if (!$this->game) {
828
            return $this->errorJson();
829
        }
830
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
831
        if (!$entry) {
832
            return $this->errorJson();
833
        }
834
        if (!$tweetId) {
835
            return $this->errorJson();
836
        }
837
838
        $this->getGameService()->postTwitter($tweetId, $this->game, $this->user, $entry);
839
840
        return $this->successJson();
841
    }
842
843 View Code Duplication
    public function googleAction()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
844
    {
845
        $viewModel = new ViewModel();
846
        $viewModel->setTerminal(true);
847
        $googleId = $this->params()->fromQuery('googleId');
848
849
        if (!$this->game) {
850
            return $this->errorJson();
851
        }
852
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
853
        if (!$entry) {
854
            return $this->errorJson();
855
        }
856
        if (!$googleId) {
857
            return $this->errorJson();
858
        }
859
860
        $this->getGameService()->postGoogle($googleId, $this->game, $this->user, $entry);
861
862
        return $this->successJson();
863
    }
864
865
    public function optinAction()
866
    {
867
        $userService = $this->getServiceLocator()->get('zfcuser_user_service');
868
869
        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, Zend\Psr7Bridge\Zend\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...
870
            $data['optin']        = ($this->params()->fromPost('optin'))?1:0;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$data was never initialized. Although not strictly required by PHP, it is generally a good practice to add $data = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
871
            $data['optinPartner'] = ($this->params()->fromPost('optinPartner'))?1:0;
872
873
            $userService->updateNewsletter($data);
874
        }
875
876
        return $this->redirect()->toUrl(
877
            $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
878
                $this->game->getClassType(),
879
                array('id' => $this->game->getIdentifier())
880
            )
881
        );
882
    }
883
884
    public function termsOptinAction()
885
    {
886
        $viewModel = $this->buildView($this->game);
887
888
        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, Zend\Psr7Bridge\Zend\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...
889
            $optin = $this->params()->fromPost('termsOptin');
890
            $result = $this->getGameService()->setTermsOptin($optin, $this->game, $this->user);
891
            $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...
892
                ['success' => $result]
893
            );
894
        }
895
896
        return $viewModel;
897
    }
898
899
    public function loginAction()
900
    {
901
        $request = $this->getRequest();
902
        $redirect = "";
903
        if ($request->getQuery()->get('redirect') != '') {
904
            $redirect = $request->getQuery()->get('redirect');
905
        }
906
        $form    = $this->getServiceLocator()->get('zfcuser_login_form');
907
908
        if ($request->isPost()) {
909
            $form->setData($request->getPost());
910
911
            if (!$form->isValid()) {
912
                $this->flashMessenger()->addMessage(
0 ignored issues
show
Documentation Bug introduced by
The method flashMessenger does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
913
                    'Authentication failed. Please try again.'
914
                );
915
916
                $viewModel = $this->buildView($this->game);
917
                $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...
918
                        'form'          => $form,
919
                        'flashMessages' => $this->flashMessenger()->getMessages(),
0 ignored issues
show
Documentation Bug introduced by
The method flashMessenger does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
920
                    ));
921
922
                return $viewModel;
923
            }
924
925
            // clear adapters
926
            $this->zfcUserAuthentication()->getAuthAdapter()->resetAdapters();
0 ignored issues
show
Documentation Bug introduced by
The method zfcUserAuthentication does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
927
            $this->zfcUserAuthentication()->getAuthService()->clearIdentity();
0 ignored issues
show
Documentation Bug introduced by
The method zfcUserAuthentication does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
928
929
            $logged = $this->forward()->dispatch('playgrounduser_user', array('action' => 'ajaxauthenticate'));
930
931
            if (!$logged) {
932
                $this->flashMessenger()->addMessage(
0 ignored issues
show
Documentation Bug introduced by
The method flashMessenger does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
933
                    'Authentication failed. Please try again.'
934
                );
935
936
                return $this->redirect()->toUrl(
937
                    $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
938
                        $this->game->getClassType().'/login',
939
                        array('id' => $this->game->getIdentifier())
940
                    )
941
                );
942
            } else {
943
                if ($redirect != "") {
944
                    return $this->redirect()->toUrl($redirect);
945
                } else {
946
                    return $this->redirect()->toUrl(
947
                        $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
948
                            $this->game->getClassType().'/'.$this->game->nextStep('index'),
949
                            array('id' => $this->game->getIdentifier())
950
                        )
951
                    );
952
                }
953
            }
954
        }
955
956
        $form->setAttribute(
957
            'action',
958
            $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
959
                $this->game->getClassType().'/login',
960
                array('id' => $this->game->getIdentifier())
961
            )
962
        );
963
        $viewModel = $this->buildView($this->game);
964
        $viewModel->setVariables(array(
965
                'form'          => $form,
966
                'flashMessages' => $this->flashMessenger()->getMessages(),
0 ignored issues
show
Documentation Bug introduced by
The method flashMessenger does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
967
            ));
968
        return $viewModel;
969
    }
970
971
    public function logoutAction()
972
    {
973
        $viewModel = $this->forward()->dispatch(
974
            'playgrounduser_user',
975
            array(
976
                'controller' => 'playgrounduser_user',
977
                'action'     => 'logout',
978
                'id'         => $this->game->getIdentifier()
979
            )
980
        );
981
982
        if ($viewModel && $viewModel instanceof \Zend\View\Model\ViewModel) {
983
            $this->layout()->setVariables(array('game' => $this->game));
0 ignored issues
show
Bug introduced by
The method setVariables does only exist in Zend\View\Model\ModelInterface, but not in Zend\Mvc\Controller\Plugin\Layout.

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...
984
            $viewModel->setVariables(array('game'      => $this->game));
985
        }
986
987
        return $viewModel;
988
    }
989
990
    public function userregisterAction()
991
    {
992
        $pguserOptions = $this->getServiceLocator()->get('playgrounduser_module_options');
993
        $userOptions = $this->getServiceLocator()->get('zfcuser_module_options');
994
995
        if ($this->zfcUserAuthentication()->hasIdentity()) {
0 ignored issues
show
Documentation Bug introduced by
The method zfcUserAuthentication does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
996
            return $this->redirect()->toUrl(
997
                $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
998
                    $this->game->getClassType().'/'.$this->game->nextStep('index'),
999
                    array('id' => $this->game->getIdentifier())
1000
                )
1001
            );
1002
        }
1003
        $request       = $this->getRequest();
1004
        $service       = $this->getServiceLocator()->get('zfcuser_user_service');
1005
        $form          = $this->getServiceLocator()->get('playgroundgame_register_form');
1006
        $socialnetwork = $this->params()->fromRoute('socialnetwork', false);
1007
        $form->setAttribute(
1008
            'action',
1009
            $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
1010
                $this->game->getClassType().'/user-register',
1011
                array('id' => $this->game->getIdentifier())
1012
            )
1013
        );
1014
        $params            = array();
1015
        $socialCredentials = array();
1016
1017
        if ($userOptions->getUseRedirectParameterIfPresent() && $request->getQuery()->get('redirect')) {
1018
            $redirect = $request->getQuery()->get('redirect');
1019
        } else {
1020
            $redirect = false;
1021
        }
1022
1023
        if ($socialnetwork) {
1024
            $infoMe = $this->getProviderService()->getInfoMe($socialnetwork);
0 ignored issues
show
Documentation Bug introduced by
The method getProviderService does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
1025
1026
            if (!empty($infoMe)) {
1027
                $user = $this->getProviderService()->getUserProviderMapper()->findUserByProviderId(
0 ignored issues
show
Documentation Bug introduced by
The method getProviderService does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
1028
                    $infoMe->identifier,
1029
                    $socialnetwork
1030
                );
1031
1032
                if ($user || $service->getOptions()->getCreateUserAutoSocial() === true) {
1033
                    //on le dirige vers l'action d'authentification
1034 View Code Duplication
                    if (!$redirect && $userOptions->getLoginRedirectRoute() != '') {
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...
1035
                        $redirect = $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
1036
                            $this->game->getClassType().'/login',
1037
                            array('id' => $this->game->getIdentifier())
1038
                        );
1039
                    }
1040
                    $redir = $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
1041
                        $this->game->getClassType().'/login',
1042
                        array('id' => $this->game->getIdentifier())
1043
                    ).'/'.$socialnetwork.($redirect?'?redirect='.$redirect:'');
1044
1045
                    return $this->redirect()->toUrl($redir);
1046
                }
1047
1048
                // Je retire la saisie du login/mdp
1049
                $form->setAttribute(
1050
                    'action',
1051
                    $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
1052
                        $this->game->getClassType().'/user-register',
1053
                        array(
1054
                            'id'            => $this->game->getIdentifier(),
1055
                            'socialnetwork' => $socialnetwork,
1056
1057
                        )
1058
                    )
1059
                );
1060
                $form->remove('password');
1061
                $form->remove('passwordVerify');
1062
1063
                $birthMonth = $infoMe->birthMonth;
1064
                if (strlen($birthMonth) <= 1) {
1065
                    $birthMonth = '0'.$birthMonth;
1066
                }
1067
                $birthDay = $infoMe->birthDay;
1068
                if (strlen($birthDay) <= 1) {
1069
                    $birthDay = '0'.$birthDay;
1070
                }
1071
1072
                $gender = $infoMe->gender;
1073
                if ($gender == 'female') {
1074
                    $title = 'Me';
1075
                } else {
1076
                    $title = 'M';
1077
                }
1078
1079
                $params = array(
1080
                    //'birth_year'  => $infoMe->birthYear,
1081
                    'title'      => $title,
1082
                    'dob'        => $birthDay.'/'.$birthMonth.'/'.$infoMe->birthYear,
1083
                    'firstname'  => $infoMe->firstName,
1084
                    'lastname'   => $infoMe->lastName,
1085
                    'email'      => $infoMe->email,
1086
                    'postalCode' => $infoMe->zip,
1087
                );
1088
                $socialCredentials = array(
1089
                    'socialNetwork' => strtolower($socialnetwork),
1090
                    'socialId'      => $infoMe->identifier,
1091
                );
1092
            }
1093
        }
1094
1095
        $redirectUrl = $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
1096
            $this->game->getClassType().'/user-register',
1097
            array('id' => $this->game->getIdentifier())
1098
        ).($socialnetwork?'/'.$socialnetwork:'').($redirect?'?redirect='.$redirect:'');
1099
        $prg = $this->prg($redirectUrl, true);
0 ignored issues
show
Documentation Bug introduced by
The method prg does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
1100
1101
        if ($prg instanceof Response) {
1102
            return $prg;
1103
        } elseif ($prg === false) {
1104
            $form->setData($params);
1105
            $viewModel = $this->buildView($this->game);
1106
            $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...
1107
                'registerForm'       => $form,
1108
                'enableRegistration' => $userOptions->getEnableRegistration(),
1109
                'redirect'           => $redirect,
1110
            ));
1111
            return $viewModel;
1112
        }
1113
1114
        $post = $prg;
1115
        if (isset($post['optin'])) {
1116
            $post['optin'] = 1;
1117
        }
1118
        if (isset($post['optinPartner'])) {
1119
            $post['optinPartner'] = 1;
1120
        }
1121
        $post = array_merge(
1122
            $post,
1123
            $socialCredentials
1124
        );
1125
1126
        if ($pguserOptions->getUseRecaptcha()) {
1127
            if (!isset($post['g-recaptcha-response']) || $post['g-recaptcha-response'] == '' || !$this->recaptcha()->recaptcha($post['g-recaptcha-response'])) {
0 ignored issues
show
Documentation Bug introduced by
The method recaptcha does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
1128
                $this->flashMessenger()->addErrorMessage('Invalid Captcha. Please try again.');
0 ignored issues
show
Documentation Bug introduced by
The method flashMessenger does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
1129
                $form->setData($post);
1130
                $viewModel = $this->buildView($this->game);
1131
                $viewModel->setVariables(array(
1132
                        'registerForm'       => $form,
1133
                        'enableRegistration' => $userOptions->getEnableRegistration(),
1134
                        'redirect'           => $redirect,
1135
                        'bah'                => 'coco',
1136
                        'flashMessages'      => $this->flashMessenger()->getMessages(),
0 ignored issues
show
Documentation Bug introduced by
The method flashMessenger does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
1137
                        'flashErrors'        => $this->flashMessenger()->getErrorMessages(),
0 ignored issues
show
Documentation Bug introduced by
The method flashMessenger does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
1138
                    ));
1139
1140
                return $viewModel;
1141
            }
1142
        }
1143
1144
        if ($this->game->getOnInvitation()) {
1145
            $credential = trim(
1146
                $post[$this->getGameService()->getOptions()->getOnInvitationField()]
1147
            );
1148
            if (!$credential) {
1149
                $credential = $this->params()->fromQuery(
1150
                    $this->getGameService()->getOptions()->getOnInvitationField()
1151
                );
1152
            }
1153
            $found = $this->getGameService()->getInvitationMapper()->findOneBy(array('requestKey' => $credential));
1154
1155
            if (!$found || !empty($found->getUser())) {
1156
                $this->flashMessenger()->addMessage(
0 ignored issues
show
Documentation Bug introduced by
The method flashMessenger does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
1157
                    'Authentication failed. Please try again.'
1158
                );
1159
                $form->setData($post);
1160
                $viewModel = $this->buildView($this->game);
1161
                $viewModel->setVariables(array(
1162
                        'registerForm'       => $form,
1163
                        'enableRegistration' => $userOptions->getEnableRegistration(),
1164
                        'redirect'           => $redirect,
1165
                        'flashMessages'      => $this->flashMessenger()->getMessages(),
0 ignored issues
show
Documentation Bug introduced by
The method flashMessenger does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
1166
                        'flashErrors'        => $this->flashMessenger()->getErrorMessages(),
0 ignored issues
show
Documentation Bug introduced by
The method flashMessenger does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
1167
                    ));
1168
1169
                return $viewModel;
1170
            }
1171
        }
1172
1173
        $user = $service->register($post, 'playgroundgame_register_form');
1174
1175
        if (!$user) {
1176
            $viewModel = $this->buildView($this->game);
1177
            $viewModel->setVariables(array(
1178
                    'registerForm'       => $form,
1179
                    'enableRegistration' => $userOptions->getEnableRegistration(),
1180
                    'redirect'           => $redirect,
1181
                    'flashMessages'      => $this->flashMessenger()->getMessages(),
0 ignored issues
show
Documentation Bug introduced by
The method flashMessenger does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
1182
                    'flashErrors'        => $this->flashMessenger()->getErrorMessages(),
0 ignored issues
show
Documentation Bug introduced by
The method flashMessenger does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
1183
                ));
1184
1185
            return $viewModel;
1186
        }
1187
1188
        if ($this->game->getOnInvitation()) {
1189
            // user has been created, associate the code with the userId
1190
            $found->setUser($user);
0 ignored issues
show
Bug introduced by
The variable $found 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...
1191
            $this->getGameService()->getInvitationMapper()->update($found);
1192
        }
1193
1194
        if ($service->getOptions()->getEmailVerification()) {
1195
            $vm = new ViewModel(array('userEmail' => $user->getEmail()));
1196
            $vm->setTemplate('playground-user/register/registermail');
1197
1198
            return $vm;
1199
        } elseif ($service->getOptions()->getLoginAfterRegistration()) {
1200
            $identityFields = $service->getOptions()->getAuthIdentityFields();
1201
            if (in_array('email', $identityFields)) {
1202
                $post['identity'] = $user->getEmail();
1203
            } elseif (in_array('username', $identityFields)) {
1204
                $post['identity'] = $user->getUsername();
1205
            }
1206
            $post['credential'] = isset($post['password'])?$post['password']:'';
1207
            $request->setPost(new Parameters($post));
1208
1209
            // clear adapters
1210
            $this->zfcUserAuthentication()->getAuthAdapter()->resetAdapters();
0 ignored issues
show
Documentation Bug introduced by
The method zfcUserAuthentication does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
1211
            $this->zfcUserAuthentication()->getAuthService()->clearIdentity();
0 ignored issues
show
Documentation Bug introduced by
The method zfcUserAuthentication does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
1212
1213
            $logged = $this->forward()->dispatch('playgrounduser_user', array('action' => 'ajaxauthenticate'));
1214
1215
            if ($logged) {
1216
                return $this->redirect()->toUrl(
1217
                    $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
1218
                        $this->game->getClassType().'/'.$this->game->nextStep('index'),
1219
                        array('id' => $this->game->getIdentifier())
1220
                    )
1221
                );
1222
            } else {
1223
                $this->flashMessenger()->setNamespace('zfcuser-login-form')->addMessage(
0 ignored issues
show
Documentation Bug introduced by
The method flashMessenger does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
1224
                    'Authentication failed. Please try again.'
1225
                );
1226
                return $this->redirect()->toUrl(
1227
                    $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
1228
                        $this->game->getClassType().'/login',
1229
                        array('id' => $this->game->getIdentifier())
1230
                    )
1231
                );
1232
            }
1233
        }
1234
1235
        $redirect = $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
1236
            $this->game->getClassType().'/login',
1237
            array('id' => $this->game->getIdentifier())
1238
        ).($socialnetwork?'/'.$socialnetwork:'').($redirect?'?redirect='.$redirect:'');
1239
1240
        return $this->redirect()->toUrl($redirect);
1241
    }
1242
1243 View Code Duplication
    public function checkTokenAction()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
1244
    {
1245
        $viewModel = $this->forward()->dispatch(
1246
            'playgrounduser_user',
1247
            array(
1248
                'controller' => 'playgrounduser_user',
1249
                'action' => 'check-token',
1250
                'id' => $this->game->getIdentifier(),
1251
                'token' => $this->params()->fromRoute('token', null)
1252
            )
1253
        );
1254
1255
        if ($viewModel && $viewModel instanceof \Zend\View\Model\ViewModel) {
1256
            $this->layout()->setVariables(array('game' => $this->game));
0 ignored issues
show
Bug introduced by
The method setVariables does only exist in Zend\View\Model\ModelInterface, but not in Zend\Mvc\Controller\Plugin\Layout.

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...
1257
            $viewModel->setVariables(array('game' => $this->game));
1258
        }
1259
1260
        return $viewModel;
1261
    }
1262
1263
    public function userProfileAction()
1264
    {
1265
        $viewModel = $this->forward()->dispatch(
1266
            'playgrounduser_user',
1267
            array(
1268
                'controller' => 'playgrounduser_user',
1269
                'action'     => 'profile',
1270
                'id'         => $this->game->getIdentifier()
1271
            )
1272
        );
1273
1274
        if ($viewModel && $viewModel instanceof \Zend\View\Model\ViewModel) {
1275
            $this->layout()->setVariables(array('game' => $this->game));
0 ignored issues
show
Bug introduced by
The method setVariables does only exist in Zend\View\Model\ModelInterface, but not in Zend\Mvc\Controller\Plugin\Layout.

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...
1276
            $viewModel->setVariables(array('game'      => $this->game));
1277
        }
1278
1279
        return $viewModel;
1280
    }
1281
1282
    public function userresetAction()
1283
    {
1284
        $viewModel = $this->forward()->dispatch(
1285
            'playgrounduser_forgot',
1286
            array(
1287
                'controller' => 'playgrounduser_forgot',
1288
                'action'     => 'reset',
1289
                'id'         => $this->game->getIdentifier(),
1290
                'userId'     => $this->params()->fromRoute('userId', null),
1291
                'token'      => $this->params()->fromRoute('token', null),
1292
            )
1293
        );
1294
1295
        if ($viewModel && $viewModel instanceof \Zend\View\Model\ViewModel) {
1296
            $this->layout()->setVariables(array('game' => $this->game));
0 ignored issues
show
Bug introduced by
The method setVariables does only exist in Zend\View\Model\ModelInterface, but not in Zend\Mvc\Controller\Plugin\Layout.

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...
1297
            $viewModel->setVariables(array('game'      => $this->game));
1298
        }
1299
1300
        return $viewModel;
1301
    }
1302
1303
    public function ajaxforgotAction()
1304
    {
1305
        $view = $this->forward()->dispatch(
1306
            'playgrounduser_forgot',
1307
            array(
1308
                'controller' => 'playgrounduser_forgot',
1309
                'action'     => 'ajaxforgot',
1310
                'id'         => $this->game->getIdentifier()
1311
            )
1312
        );
1313
1314
        if ($view && $view instanceof \Zend\View\Model\ViewModel) {
1315
            $this->layout()->setVariables(array('game' => $this->game));
0 ignored issues
show
Bug introduced by
The method setVariables does only exist in Zend\View\Model\ModelInterface, but not in Zend\Mvc\Controller\Plugin\Layout.

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...
1316
            $view->setVariables(array('game'           => $this->game));
1317
        }
1318
1319
        return $view;
1320
    }
1321
1322 View Code Duplication
    public function cmsPageAction()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
1323
    {
1324
        $viewModel = $this->forward()->dispatch(
1325
            'playgroundcms',
1326
            array(
1327
                'controller' => 'playgroundcms',
1328
                'action'     => 'index',
1329
                'id'         => $this->game->getIdentifier(),
1330
                'pid'        => $this->getEvent()->getRouteMatch()->getParam('pid')
1331
            )
1332
        );
1333
1334
        if ($viewModel && $viewModel instanceof \Zend\View\Model\ViewModel) {
1335
            $this->layout()->setVariables(array('game' => $this->game));
0 ignored issues
show
Bug introduced by
The method setVariables does only exist in Zend\View\Model\ModelInterface, but not in Zend\Mvc\Controller\Plugin\Layout.

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...
1336
            $viewModel->setVariables(array('game'      => $this->game));
1337
        }
1338
1339
        return $viewModel;
1340
    }
1341
1342 View Code Duplication
    public function cmsListAction()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
1343
    {
1344
        $viewModel = $this->forward()->dispatch(
1345
            'playgroundcms',
1346
            array(
1347
                'controller' => 'playgroundcms',
1348
                'action'     => 'list',
1349
                'id'         => $this->game->getIdentifier(),
1350
                'category'   => $this->game->getIdentifier()
1351
            )
1352
        );
1353
1354
        if ($viewModel && $viewModel instanceof \Zend\View\Model\ViewModel) {
1355
            $this->layout()->setVariables(array('game' => $this->game));
0 ignored issues
show
Bug introduced by
The method setVariables does only exist in Zend\View\Model\ModelInterface, but not in Zend\Mvc\Controller\Plugin\Layout.

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...
1356
            $viewModel->setVariables(array('game'      => $this->game));
1357
        }
1358
1359
        return $viewModel;
1360
    }
1361
1362
    /**
1363
     * This method create the basic Game view
1364
     * @param \PlaygroundGame\Entity\Game $game
1365
     */
1366
    public function buildView($game)
1367
    {
1368
        if ($this->getRequest()->isXmlHttpRequest()) {
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 isXmlHttpRequest() does only exist in the following implementations of said interface: Zend\Http\PhpEnvironment\Request, Zend\Http\Request, Zend\Psr7Bridge\Zend\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...
1369
            $viewModel = new JsonModel();
1370
            if ($game) {
1371
                $view = $this->addAdditionalView($game);
1372
                if ($view && $view instanceof \Zend\View\Model\ViewModel) {
1373
                    $viewModel->setVariables($view->getVariables());
1374
                }
1375
            }
1376
        } else {
1377
            $viewModel = new ViewModel();
1378
1379
            if ($game) {
1380
                $this->addMetaTitle($game);
1381
                //$this->addMetaBitly();
1382
                $this->addGaEvent($game);
1383
1384
                $this->customizeGameDesign($game);
1385
1386
                $view = $this->addAdditionalView($game);
1387
                if ($view && $view instanceof \Zend\View\Model\ViewModel) {
1388
                    $viewModel->addChild($view, 'additional');
1389
                } elseif ($view && $view instanceof \Zend\Http\PhpEnvironment\Response) {
1390
                    return $view;
1391
                }
1392
1393
                $this->layout()->setVariables(
0 ignored issues
show
Bug introduced by
The method setVariables does only exist in Zend\View\Model\ModelInterface, but not in Zend\Mvc\Controller\Plugin\Layout.

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...
1394
                    array(
1395
                        'action'        => $this->params('action'),
1396
                        'game'          => $game,
1397
                        'flashMessages' => $this->flashMessenger()->getMessages(),
0 ignored issues
show
Documentation Bug introduced by
The method flashMessenger does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
1398
                    )
1399
                );
1400
1401
                $viewModel->setVariables($this->getShareData($game));
1402
                $viewModel->setVariables(
1403
                    array(
1404
                        'game' => $game,
1405
                        'user' => $this->user
1406
                    )
1407
                );
1408
            }
1409
        }
1410
1411
        return $viewModel;
1412
    }
1413
1414
    /**
1415
     * @param \PlaygroundGame\Entity\Game $game
1416
     */
1417
    public function addAdditionalView($game)
1418
    {
1419
        $view = false;
1420
1421
        $actionName = $this->getEvent()->getRouteMatch()->getParam('action', 'not-found');
1422
        $stepsViews = json_decode($game->getStepsViews(), true);
1423
        if ($stepsViews && isset($stepsViews[$actionName])) {
1424
            $beforeLayout = $this->layout()->getTemplate();
0 ignored issues
show
Bug introduced by
The method getTemplate does only exist in Zend\View\Model\ModelInterface, but not in Zend\Mvc\Controller\Plugin\Layout.

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...
1425
            $actionData   = $stepsViews[$actionName];
1426
            if (is_string($actionData)) {
1427
                $action     = $actionData;
1428
                $classGame = __NAMESPACE__ . '\\' . ucfirst($this->game->getClassType());
1429
                $controller = $this->getEvent()->getRouteMatch()->getParam('controller', $classGame);
1430
                $view       = $this->forward()->dispatch(
1431
                    $controller,
1432
                    array(
1433
                        'action' => $action,
1434
                        'id'     => $game->getIdentifier()
1435
                    )
1436
                );
1437
            } elseif (is_array($actionData) && count($actionData) > 0) {
1438
                $action     = key($actionData);
1439
                $controller = __NAMESPACE__ . '\\' . ucfirst($actionData[$action]);
1440
                $view       = $this->forward()->dispatch(
1441
                    $controller,
1442
                    array(
1443
                        'action' => $action,
1444
                        'id'     => $game->getIdentifier()
1445
                    )
1446
                );
1447
            }
1448
            // suite au forward, le template de layout a changé, je dois le rétablir...
1449
            $this->layout()->setTemplate($beforeLayout);
1450
        }
1451
1452
        return $view;
1453
    }
1454
1455
    public function addMetaBitly()
1456
    {
1457
        $bitlyclient = $this->getOptions()->getBitlyUrl();
1458
        $bitlyuser   = $this->getOptions()->getBitlyUsername();
1459
        $bitlykey    = $this->getOptions()->getBitlyApiKey();
1460
1461
        $this->getViewHelper('HeadMeta')->setProperty('bt:client', $bitlyclient);
1462
        $this->getViewHelper('HeadMeta')->setProperty('bt:user', $bitlyuser);
1463
        $this->getViewHelper('HeadMeta')->setProperty('bt:key', $bitlykey);
1464
    }
1465
1466
    /**
1467
     * @param \PlaygroundGame\Entity\Game $game
1468
     */
1469
    public function addGaEvent($game)
1470
    {
1471
        // Google Analytics event
1472
        $ga    = $this->getServiceLocator()->get('google-analytics');
1473
        $event = new \PlaygroundCore\Analytics\Event($game->getClassType(), $this->params('action'));
1474
        $event->setLabel(str_replace("'", "\'", $game->getTitle()));
1475
        $ga->addEvent($event);
1476
    }
1477
1478
    /**
1479
     * @param \PlaygroundGame\Entity\Game $game
1480
     */
1481
    public function addMetaTitle($game)
1482
    {
1483
        $title = $game->getTitle();
1484
        $this->getGameService()->getServiceManager()->get('ViewHelperManager')->get('HeadTitle')->set($title);
1485
        // Meta set in the layout
1486
        $this->layout()->setVariables(
0 ignored issues
show
Bug introduced by
The method setVariables does only exist in Zend\View\Model\ModelInterface, but not in Zend\Mvc\Controller\Plugin\Layout.

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...
1487
            array(
1488
                'breadcrumbTitle' => $title,
1489
                'currentPage'     => array(
1490
                    'pageGames'      => 'games',
1491
                    'pageWinners'    => '',
1492
                ),
1493
                'headParams'       => array(
1494
                    'headTitle'       => $title,
1495
                    'headDescription' => $title,
1496
                ),
1497
                'bodyCss' => $game->getIdentifier()
1498
            )
1499
        );
1500
    }
1501
1502
    /**
1503
     * @param \PlaygroundGame\Entity\Game $game
1504
     */
1505
    public function customizeGameDesign($game)
1506
    {
1507
        // If this game has a specific layout...
1508
        if ($game->getLayout()) {
1509
            $layoutViewModel = $this->layout();
1510
            $layoutViewModel->setTemplate($game->getLayout());
1511
        }
1512
1513
        // If this game has a specific stylesheet...
1514
        if ($game->getStylesheet()) {
1515
            $this->getViewHelper('HeadLink')->appendStylesheet(
1516
                $this->getRequest()->getBaseUrl().'/'.$game->getStylesheet()
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 getBaseUrl() does only exist in the following implementations of said interface: Zend\Http\PhpEnvironment\Request, Zend\Psr7Bridge\Zend\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...
1517
            );
1518
        }
1519
    }
1520
1521
    /**
1522
     * @param \PlaygroundGame\Entity\Game $game
1523
     */
1524
    public function getShareData($game)
1525
    {
1526
        $fo      = $this->getServiceLocator()->get('facebook-opengraph');
1527
        $session = new Container('facebook');
1528
1529
        // I change the fbappid if i'm in fb
1530
        if ($session->offsetExists('signed_request')) {
1531
            $fo->setId($game->getFbAppId());
1532
        }
1533
1534
        $fbShareDescription = $game->getFbShareDescription();
1535
1536
        if ($game->getFbShareImage()) {
1537
            $fbShareImage = $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
1538
                '',
1539
                array(),
1540
                array('force_canonical' => true),
1541
                false
1542
            ).$game->getFbShareImage();
1543
        } else {
1544
            $fbShareImage = $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
1545
                '',
1546
                array(),
1547
                array('force_canonical' => true),
1548
                false
1549
            ).$game->getMainImage();
1550
        }
1551
1552
        $secretKey = strtoupper(substr(sha1(uniqid('pg_', true).'####'.time()), 0, 15));
1553
        $socialLinkUrl = $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
1554
            $game->getClassType(),
1555
            array('id' => $this->game->getIdentifier()),
1556
            array('force_canonical' => true)
1557
        ).'?key='.$secretKey;
1558
        // With core shortener helper
1559
        $socialLinkUrl = $this->shortenUrl()->shortenUrl($socialLinkUrl);
0 ignored issues
show
Documentation Bug introduced by
The method shortenUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
1560
1561
        $fbShareUrl = $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
1562
            $game->getClassType().'/fbshare',
1563
            array('id' => $this->game->getIdentifier()),
1564
            array('force_canonical' => true)
1565
        ).'?fbId='.$secretKey;
1566
1567
        $twShareUrl = $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? 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...
1568
            $game->getClassType().'/tweet',
1569
            array('id' => $this->game->getIdentifier()),
1570
            array('force_canonical' => true)
1571
        ).'?fbId='.$secretKey;
1572
1573
        // FB Requests only work when it's a FB app
1574
        if ($game->getFbRequestMessage()) {
1575
            $fbRequestMessage = urlencode($game->getFbRequestMessage());
1576
        } else {
1577
            $fbRequestMessage = str_replace(
1578
                '__placeholder__',
1579
                $game->getTitle(),
1580
                $this->getOptions()->getDefaultShareMessage()
1581
            );
1582
        }
1583
1584
        $twShareMessage = $game->getTwShareMessage().$socialLinkUrl;
1585
1586
        // I add OG tags to the meta
1587
        $ogTitle = new \PlaygroundCore\Opengraph\Tag('og:title', $game->getTitle());
1588
        $ogDescription = new \PlaygroundCore\Opengraph\Tag('og:description', $fbShareDescription);
1589
        $ogImage = new \PlaygroundCore\Opengraph\Tag('og:image', $fbShareImage);
1590
        $twTitle = new \PlaygroundCore\Opengraph\Tag('twitter:title', $game->getTitle());
1591
        $twDescription =  new \PlaygroundCore\Opengraph\Tag('twitter:description', $this->game->getTwShareMessage());
1592
        $twImage =  new \PlaygroundCore\Opengraph\Tag('twitter:image', $fbShareImage);
1593
        $twUrl = new \PlaygroundCore\Opengraph\Tag('twitter:url', $socialLinkUrl);
1594
1595
        $fo->addTag($ogTitle);
1596
        $fo->addTag($ogDescription);
1597
        $fo->addTag($ogImage);
1598
        $fo->addTag($twTitle);
1599
        $fo->addTag($twDescription);
1600
        $fo->addTag($twImage);
1601
        $fo->addTag($twUrl);
1602
        
1603
        // I add variables + js to make the share easy
1604
        $renderer = $this->serviceLocator->get('Zend\View\Renderer\RendererInterface');
1605
        $headScript = $this->getServiceLocator()->get('ViewHelperManager')->get('HeadScript');
1606
        $headScript->appendScript("var pgGameUrl = '" . $socialLinkUrl . "';\nvar pgFbShareUrl = '" . $fbShareUrl . "';\nvar pgTwShareUrl = '" . $twShareUrl . "';");
1607
        $headScript->appendFile($renderer->frontendAssetPath() . '/js/pg/share.js');
1608
1609
        $data = array(
1610
            'socialLinkUrl'         => $socialLinkUrl,
1611
            'secretKey'             => $secretKey,
1612
            'fbShareDescription'    => $fbShareDescription,
1613
            'fbShareImage'          => $fbShareImage,
1614
            'fbRequestMessage'      => $fbRequestMessage,
1615
            'twShareMessage'        => $twShareMessage,
1616
        );
1617
1618
        return $data;
1619
    }
1620
1621
    /**
1622
     * return ajax response in json format
1623
     *
1624
     * @param array $data
1625
     * @return \Zend\View\Model\JsonModel
1626
     */
1627 View Code Duplication
    protected function successJson($data = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
1628
    {
1629
        $model = new JsonModel(array(
1630
                'success' => true,
1631
                'data'    => $data,
1632
            ));
1633
        return $model->setTerminal(true);
1634
    }
1635
1636
    /**
1637
     * return ajax response in json format
1638
     *
1639
     * @param string $message
1640
     * @return \Zend\View\Model\JsonModel
1641
     */
1642 View Code Duplication
    protected function errorJson($message = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
1643
    {
1644
        $model = new JsonModel(array(
1645
                'success' => false,
1646
                'message' => $message,
1647
            ));
1648
        return $model->setTerminal(true);
1649
    }
1650
1651
    /**
1652
     * @param string $helperName
1653
     */
1654
    protected function getViewHelper($helperName)
1655
    {
1656
        return $this->getServiceLocator()->get('ViewHelperManager')->get($helperName);
1657
    }
1658
1659
    public function getGameService()
1660
    {
1661
        if (!$this->gameService) {
1662
            $this->gameService = $this->getServiceLocator()->get('playgroundgame_lottery_service');
1663
        }
1664
1665
        return $this->gameService;
1666
    }
1667
1668
    public function setGameService(GameService $gameService)
1669
    {
1670
        $this->gameService = $gameService;
1671
1672
        return $this;
1673
    }
1674
1675
    public function getPrizeService()
1676
    {
1677
        if (!$this->prizeService) {
1678
            $this->prizeService = $this->getServiceLocator()->get('playgroundgame_prize_service');
1679
        }
1680
1681
        return $this->prizeService;
1682
    }
1683
1684
    public function setPrizeService(PrizeService $prizeService)
1685
    {
1686
        $this->prizeService = $prizeService;
1687
1688
        return $this;
1689
    }
1690
1691
    public function getOptions()
1692
    {
1693
        if (!$this->options) {
1694
            $this->setOptions($this->getServiceLocator()->get('playgroundcore_module_options'));
1695
        }
1696
1697
        return $this->options;
1698
    }
1699
1700
    public function setOptions($options)
1701
    {
1702
        $this->options = $options;
1703
1704
        return $this;
1705
    }
1706
}
1707