Completed
Push — develop ( 3d8065...814bda )
by greg
02:22
created

GameController   F

Complexity

Total Complexity 200

Size/Duplication

Total Lines 1651
Duplicated Lines 8.18 %

Coupling/Cohesion

Components 1
Dependencies 19

Importance

Changes 0
Metric Value
wmc 200
lcom 1
cbo 19
dl 135
loc 1651
rs 0.8
c 0
b 0
f 0

47 Methods

Rating   Name   Duplication   Size   Complexity  
B addAdditionalView() 0 37 6
A addMetaBitly() 0 10 1
A addGaEvent() 0 8 1
A __construct() 0 4 1
A getServiceLocator() 0 4 1
F setEventManager() 0 131 23
A notFoundAction() 0 38 4
A homeAction() 0 34 3
A indexAction() 0 16 2
A leaderboardAction() 0 25 1
F registerAction() 0 123 18
A termsAction() 0 6 1
A conditionsAction() 0 6 1
A bounceAction() 0 19 2
A prizesAction() 0 10 2
A prizeAction() 0 14 2
A gameslistAction() 0 47 2
A shareAction() 10 29 4
B inviteToTeamAction() 0 48 6
A createTeamAction() 0 48 4
A fbshareAction() 20 20 4
A fbrequestAction() 0 22 4
A tweetAction() 0 19 4
A googleAction() 21 21 4
A optinAction() 0 18 4
B loginAction() 0 71 6
A logoutAction() 0 18 3
F userregisterAction() 11 252 38
A checkTokenAction() 19 19 3
A userProfileAction() 0 18 3
A userresetAction() 0 20 3
A ajaxforgotAction() 0 18 3
A cmsPageAction() 19 19 3
A cmsListAction() 19 19 3
B buildView() 0 47 10
A addMetaTitle() 0 20 1
A customizeGameDesign() 0 15 3
B getShareData() 0 96 4
A successJson() 8 8 1
A errorJson() 8 8 1
A getViewHelper() 0 4 1
A getGameService() 0 8 2
A setGameService() 0 6 1
A getPrizeService() 0 8 2
A setPrizeService() 0 6 1
A getOptions() 0 8 2
A setOptions() 0 6 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

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

Common duplication problems, and corresponding solutions are:

Complex Class

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

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

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

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

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
        'login',
45
        'logout',
46
        'ajaxforgot',
47
        'play',
48
        'result',
49
        'preview',
50
        'list',
51
        'comments',
52
    );
53
54
    protected $withOnlineGame = array(
55
        'leaderboard',
56
        'register',
57
        'bounce',
58
        'play',
59
        'result',
60
    );
61
62
    /**
63
     * These steps are available only when the game is started
64
     */
65
    protected $withStartedGame = array(
66
        'preview',
67
        'createTeam',
68
        'inviteToTeam',
69
        'register',
70
        'play',
71
    );
72
73
    protected $withAnyUser = array(
74
        'share',
75
        'result',
76
        'play',
77
        'logout',
78
        'createTeam',
79
        'inviteToTeam',
80
    );
81
82
    protected $isSoloGame = false;
83
84
    /**
85
     *
86
     * @var ServiceManager
87
     */
88
    protected $serviceLocator;
89
90
    public function __construct(ServiceLocatorInterface $locator)
91
    {
92
        $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...
93
    }
94
95
    public function getServiceLocator()
96
    {
97
        return $this->serviceLocator;
98
    }
99
100
    public function setEventManager(\Zend\EventManager\EventManagerInterface $events)
101
    {
102
        parent::setEventManager($events);
103
104
        $controller = $this;
105
106
        $events->attach('dispatch', function (\Zend\Mvc\MvcEvent $e) use ($controller) {
107
108
            $session = new Container('facebook');
109
            $identifier = $e->getRouteMatch()->getParam('id');
110
111
            // I set the right identifier if I come from FB
112
            // From FB, the games have all the same identifier. I use the FB Page Id to find the right game
113
            // So for 1 FB page, you can have only 1 game ;/
114
            if ($identifier === 'facebook' && $session->offsetExists('signed_request')) {
115
                $sr = $session->offsetGet('signed_request');
116
                $identifier = $controller->getGameService()->getGameIdentifierFromFacebook($sr['page']['id']);
117
            }
118
     
119
            $controller->game = $controller->getGameService()->checkGame($identifier, false);
120
121
            if (!$controller->game &&
122
                    in_array($controller->params('action'), $controller->withGame)
123
                ) {
124
                return $controller->notFoundAction();
125
            }
126
127
            if ($controller->game &&
128
                    $controller->game->isClosed() &&
129
                    in_array($controller->params('action'), $controller->withOnlineGame)
130
                ) {
131
                return $controller->notFoundAction();
132
            }
133
134
            $config = $this->getServiceLocator()->get('config');
135
            $customUrl = str_replace('frontend.', '', $e->getRouteMatch()->getMatchedRouteName());
136
            $customUrl = explode("/", $customUrl)[0];
137
138
            if (
139
                    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 (
157
                    $controller->game &&
158
                    !$controller->user &&
159
                    !$controller->game->getAnonymousAllowed() &&
160
                    in_array($controller->params('action'), $controller->withAnyUser)
161
                ) {
162
                // if the current game runs under Facebook
163
                if ($session->offsetExists('signed_request')) {
164
                    $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...
165
                    // Let's start the FB registration dance !
166
                    $controller->forward()->dispatch(
167
                        'playgrounduser_user',
168
                        array(
169
                            'controller' => 'playgrounduser_user',
170
                            'action'     => 'registerFacebookUser',
171
                            'provider'   => 'facebook',
172
                        )
173
                    );
174
                }
175
                $redirect = urlencode(
176
                    $controller->url()->fromRoute(
177
                        'frontend/'.$controller->game->getClassType().'/'.$controller->params('action'),
178
                        array('id'              => $controller->game->getIdentifier()),
179
                        array('force_canonical' => true)
180
                    )
181
                );
182
183
                if ($this->isSoloGame) {
184
                     $urlRegister = $controller->url()->fromRoute(
185
                         'frontend.'.$customUrl.'/'.$controller->game->getClassType().'/user-register',
186
                         array(),
187
                         array('force_canonical' => true)
188
                     ).'?redirect='.$redirect;
189
                } else {
190
                    $urlRegister = $controller->url()->fromRoute(
191
                        'frontend/zfcuser/register',
192
                        array(),
193
                        array('force_canonical' => true)
194
                    ).'?redirect='.$redirect;
195
                }
196
197
                // code permettant d'identifier un custom game
198
                // ligne $config = $controller->getGameService()->getServiceManager()->get('config');
199
                // ligne $customUrl = str_replace('frontend.', '', $e->getRouteMatch()->getParam('area', ''));
200
                // ligne if ($config['custom_games'][$controller->game->getIdentifier()] &&
201
                // ligne    $controller->getRequest()->getUri()->getHost() === $customUrl
202
                // ligne ) {
203
                return $controller->redirect()->toUrl($urlRegister);
204
            }
205
206
            // If the game is finished, I redirect some actions to result (you can't play it anymore)
207
            if (
208
                $controller->game &&
209
                $controller->game->isFinished() &&
210
                in_array($controller->params('action'), $controller->withStartedGame)
211
            ) {
212
                if ($this->isSoloGame) {
213
                    $urlResult = $controller->url()->fromRoute(
214
                        'frontend.'.$customUrl.'/'.$controller->game->getClassType().'/result',
215
                        array('id' => $controller->game->getIdentifier()),
216
                        array('force_canonical' => true)
217
                    );
218
                } else {
219
                    $urlResult = $controller->url()->fromRoute(
220
                        'frontend/'.$controller->game->getClassType().'/result',
221
                        array('id' => $controller->game->getIdentifier()),
222
                        array('force_canonical' => true)
223
                    );
224
                }
225
                return $controller->redirect()->toUrl($urlResult);
226
            }
227
228
                return;
229
        }, 100);// execute before executing action logic
230
    }
231
232
    /**
233
     * Action called if matched action does not exist
234
     * For this view not to be catched by Zend\Mvc\View\RouteNotFoundStrategy
235
     * it has to be rendered in the controller. Hence the code below.
236
     *
237
     * This action is injected as a catchall action for each custom_games definition
238
     * This way, when a custom_game is created, the 404 is it's responsability and the
239
     * view can be defined in design/frontend/default/custom/$slug/playground_game/$gametype/404.phtml
240
     *
241
     *
242
     * @return \Zend\Stdlib\ResponseInterface
243
     */
244
    public function notFoundAction()
245
    {
246
        $templatePathResolver = $this->getServiceLocator()->get('Zend\View\Resolver\TemplatePathStack');
247
248
        // I create a template path in which I can find a custom template
249
        $controller     = explode('\\', get_class($this));
250
        $controllerPath = str_replace('Controller', '', end($controller));
251
        $controllerPath = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '-\\1', $controllerPath));
252
        $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...
253
        if ($this->game) {
254
            $uri = str_replace($controllerPath.'/'.$this->game->getIdentifier().'/', '', $uri);
255
        }
256
        $uri      = str_replace("/".$this->getEvent()->getRouteMatch()->getParam('locale')."/", "/", $uri);
257
        $template = 'playground-game/'.$controllerPath.'/custom'.$uri;
258
259
        $template = (substr($template, -strlen('.html')) === '.html') ? $template : $template . '.phtml';
260
        if (false === $templatePathResolver->resolve($template)) {
261
            $viewRender = $this->getServiceLocator()->get('ViewRenderer');
262
263
            $this->getEvent()->getRouteMatch()->setParam('action', 'not-found');
264
            $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...
265
266
            $res = 'error/404';
267
268
            $viewModel = $this->buildView($this->game);
269
            $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...
270
271
            $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...
272
            $this->response->setContent($viewRender->render($this->layout()));
273
274
            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...
275
        }
276
277
        $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 280 which is incompatible with the return type documented by PlaygroundGame\Controlle...troller::notFoundAction of type Zend\Stdlib\ResponseInterface.
Loading history...
278
        $viewModel->setTemplate($template);
279
280
        return $viewModel;
281
    }
282
283
    /**
284
     * This action acts as a hub : Depending on the first step of the game, it will forward the action to this step
285
     */
286
    public function homeAction()
287
    {
288
        // This fix exists only for safari in FB on Windows : we need to redirect the user to the page
289
        // outside of iframe for the cookie to be accepted. PlaygroundCore redirects to the FB Iframed page when
290
        // it discovers that the user arrives for the first time on the game in FB.
291
        // When core redirects, it adds a 'redir_fb_page_id' var in the querystring
292
        // Here, we test if this var exist, and then send the user back to the game in FB.
293
        // Now the cookie will be accepted by Safari...
294
        $pageId = $this->params()->fromQuery('redir_fb_page_id');
295
        if (!empty($pageId)) {
296
            $appId = 'app_'.$this->game->getFbAppId();
297
            $url   = '//www.facebook.com/pages/game/'.$pageId.'?sk='.$appId;
298
299
            return $this->redirect()->toUrl($url);
300
        }
301
302
        // If an entry has already been done during this session, I reset the anonymous_identifier cookie
303
        // so that another person can play the same game (if game conditions are fullfilled)
304
        // or the same person can play another game
305
        $session = new Container('anonymous_identifier');
306
        if ($session->offsetExists('anonymous_identifier')) {
307
            $session->offsetUnset('anonymous_identifier');
308
        }
309
310
        $classGame = __NAMESPACE__ . '\\' . ucfirst($this->game->getClassType());
311
        return $this->forward()->dispatch(
312
            $classGame,
313
            array(
314
                'controller' => $classGame,
315
                'action'     => $this->game->firstStep(),
316
                'id'         => $this->game->getIdentifier()
317
            )
318
        );
319
    }
320
321
    /**
322
     * Homepage of the game
323
     */
324
    public function indexAction()
325
    {
326
        $isSubscribed = false;
327
328
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
329
        if ($entry) {
330
            $isSubscribed = true;
331
        }
332
333
        $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 338 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...
334
        $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...
335
            'isSubscribed' => $isSubscribed,
336
        ));
337
338
        return $viewModel;
339
    }
340
341
    /**
342
     * leaderboardAction
343
     *
344
     * @return ViewModel $viewModel
345
     */
346
    public function leaderboardAction()
347
    {
348
        $filter = $this->getEvent()->getRouteMatch()->getParam('filter');
349
        $p      = $this->getEvent()->getRouteMatch()->getParam('p');
350
351
        $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...
352
        $subViewModel = $this->forward()->dispatch(
353
            'playgroundreward',
354
            array('action' => 'leaderboard', 'filter' => $filter, 'p' => $p)
355
        );
356
357
        // suite au forward, le template de layout a changé, je dois le rétablir...
358
        $this->layout()->setTemplate($beforeLayout);
359
        $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...
360
            array(
361
                'action' => $this->params('action'),
362
                'game'   => $this->game,
363
            )
364
        );
365
366
        $subViewModel->setVariables($this->getShareData($this->game));
367
        $subViewModel->setVariables(array('game' => $this->game, 'user' => $this->user));
368
369
        return $subViewModel;
370
    }
371
372
    /**
373
     * This action has been designed to be called by other controllers
374
     * It gives the ability to display an information form and persist it in the game entry
375
     *
376
     * @return \Zend\View\Model\ViewModel
377
     */
378
    public function registerAction()
379
    {
380
        $formDef = $this->game->getPlayerForm();
381
        if ($formDef !== null) {
382
            $form = $this->getGameService()->createFormFromJson($formDef->getForm(), 'playerForm');
383
        } else {
384
            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...
385
        }
386
387
        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...
388
            // POST Request: Process form
389
            $data = array_merge_recursive(
390
                $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...
391
                $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...
392
            );
393
394
            $form->setData($data);
395
396
            if ($form->isValid()) {
397
                // steps of the game
398
                $steps = $this->game->getStepsArray();
399
                // sub steps of the game
400
                $viewSteps = $this->game->getStepsViewsArray();
401
                $keyStep = false;
402
403
                // register position
404
                $key = array_search($this->params('action'), $viewSteps);
405
                if ($key === false) {
406
                    // register is not a substep of the game so it's a step
407
                    $key     = array_search($this->params('action'), $steps);
408
                    if ($key !== false) {
409
                        $keyStep = true;
410
                    } else {
411
                        $key = -1;
412
                    }
413
                } else {
414
                    // register was a substep, I search the index of its parent
415
                    $key     = array_search($key, $steps);
416
                }
417
418
                // play position
419
                $keyplay = array_search('play', $viewSteps);
420
421
                if (!$keyplay) {
422
                    // play is not a substep, so it's a step
423
                    $keyplay     = array_search('play', $steps);
424
                    $keyplayStep = true;
425
                } else {
426
                    // play is a substep so I search the index of its parent
427
                    $keyplay     = array_search($keyplay, $steps);
428
                    $keyplayStep = false;
429
                }
430
431
                // If register step before play, I don't have no entry yet. I have to create one
432
                // If register after play step, I search for the last entry created by play step.
433
                if ($key < $keyplay || ($keyStep && !$keyplayStep && $key <= $keyplay)) {
434
                    // I need to check if this anonymous user has already played. This one is transmitted through
435
                    // a cookie... so I need to fill in this cookie if it's not already updated.
436
                    if ($this->game->getAnonymousAllowed() &&
437
                        $this->game->getAnonymousIdentifier() &&
438
                        isset($data[$this->game->getAnonymousIdentifier()])
439
                    ) {
440
                        $session = new \Zend\Session\Container('anonymous_identifier');
441
                        if (empty($session->offsetGet('anonymous_identifier'))) {
442
                            $anonymousIdentifier = $data[$this->game->getAnonymousIdentifier()];
443
                        
444
                            // I must transmit this info during the whole game workflow
445
                            $session->offsetSet('anonymous_identifier', $anonymousIdentifier);
446
                        }
447
                    }
448
                    $entry = $this->getGameService()->play($this->game, $this->user);
449
                    if (!$entry) {
450
                        // the user has already taken part to this game and the participation limit has been reached
451
                        $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...
452
453
                        return $this->redirect()->toUrl(
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->redirect()...'?playLimitReached=1'); (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...
454
                            $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
                            ) .'?playLimitReached=1'
460
                        );
461
                    }
462
                } else {
463
                    // I'm looking for an entry without anonymousIdentifier (the active entry in fact).
464
                    $entry = $this->getGameService()->findLastEntry($this->game, $this->user);
465
                    if ($this->getGameService()->hasReachedPlayLimit($this->game, $this->user)) {
466
                        // the user has already taken part of this game and the participation limit has been reached
467
                        $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...
468
469
                        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...
470
                            $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...
471
                                $this->game->getClassType().'/result',
472
                                array(
473
                                    'id' => $this->game->getIdentifier(),
474
                                )
475
                            )
476
                        );
477
                    }
478
                }
479
480
                $this->getGameService()->updateEntryPlayerForm($form->getData(), $this->game, $this->user, $entry);
481
482
                if (!empty($this->game->nextStep($this->params('action')))) {
483
                    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...
484
                        $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...
485
                            $this->game->getClassType().'/'.$this->game->nextStep($this->params('action')),
486
                            array('id'              => $this->game->getIdentifier()),
487
                            array('force_canonical' => true)
488
                        )
489
                    );
490
                }
491
            }
492
        }
493
494
        $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 499 which is incompatible with the return type documented by PlaygroundGame\Controlle...troller::registerAction of type Zend\View\Model\ViewModel.
Loading history...
495
        $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...
496
                'form' => $form,
497
            ));
498
499
        return $viewModel;
500
    }
501
502
    /**
503
     * This action takes care of the terms of the game
504
     */
505
    public function termsAction()
506
    {
507
        $viewModel = $this->buildView($this->game);
508
509
        return $viewModel;
510
    }
511
512
    /**
513
     * This action takes care of the conditions of the game
514
     */
515
    public function conditionsAction()
516
    {
517
        $viewModel = $this->buildView($this->game);
518
519
        return $viewModel;
520
    }
521
522
    /**
523
     * This action takes care of bounce page of the game
524
     */
525
    public function bounceAction()
526
    {
527
        $availableGames = $this->getGameService()->getAvailableGames($this->user);
528
529
        $rssUrl = '';
530
        $config = $this->getGameService()->getServiceManager()->get('config');
531
        if (isset($config['rss']['url'])) {
532
            $rssUrl = $config['rss']['url'];
533
        }
534
535
        $viewModel = $this->buildView($this->game);
536
        $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...
537
                'rssUrl'         => $rssUrl,
538
                'user'           => $this->user,
539
                'availableGames' => $availableGames,
540
            ));
541
542
        return $viewModel;
543
    }
544
545
    /**
546
     * This action displays the Prizes page associated to the game
547
     */
548
    public function prizesAction()
549
    {
550
        if (count($this->game->getPrizes()) == 0) {
551
            return $this->notFoundAction();
552
        }
553
554
        $viewModel = $this->buildView($this->game);
555
556
        return $viewModel;
557
    }
558
559
    /**
560
     * This action displays a specific Prize page among those associated to the game
561
     */
562
    public function prizeAction()
563
    {
564
        $prizeIdentifier = $this->getEvent()->getRouteMatch()->getParam('prize');
565
        $prize           = $this->getPrizeService()->getPrizeMapper()->findByIdentifier($prizeIdentifier);
566
567
        if (!$prize) {
568
            return $this->notFoundAction();
569
        }
570
571
        $viewModel = $this->buildView($this->game);
572
        $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...
573
574
        return $viewModel;
575
    }
576
577
    public function gameslistAction()
578
    {
579
        $layoutViewModel = $this->layout();
580
581
        $slider = new ViewModel();
582
        $slider->setTemplate('playground-game/common/top_promo');
583
584
        $sliderItems = $this->getGameService()->getActiveSliderGames();
585
586
        $slider->setVariables(array('sliderItems' => $sliderItems));
587
588
        $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...
589
590
        $games = $this->getGameService()->getActiveGames(false, '', 'endDate');
591
        if (is_array($games)) {
592
            $paginator = new \Zend\Paginator\Paginator(new \Zend\Paginator\Adapter\ArrayAdapter($games));
593
        } else {
594
            $paginator = $games;
595
        }
596
597
        $paginator->setItemCountPerPage(7);
598
        $paginator->setCurrentPageNumber($this->getEvent()->getRouteMatch()->getParam('p'));
599
600
        $bitlyclient = $this->getOptions()->getBitlyUrl();
601
        $bitlyuser   = $this->getOptions()->getBitlyUsername();
602
        $bitlykey    = $this->getOptions()->getBitlyApiKey();
603
604
        $this->getViewHelper('HeadMeta')->setProperty('bt:client', $bitlyclient);
605
        $this->getViewHelper('HeadMeta')->setProperty('bt:user', $bitlyuser);
606
        $this->getViewHelper('HeadMeta')->setProperty('bt:key', $bitlykey);
607
608
        $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...
609
            array(
610
                'sliderItems'  => $sliderItems,
611
                'currentPage'  => array(
612
                    'pageGames'   => 'games',
613
                    'pageWinners' => '',
614
                ),
615
            )
616
        );
617
618
        return new ViewModel(
619
            array(
620
                'games' => $paginator,
621
            )
622
        );
623
    }
624
625
    public function shareAction()
626
    {
627
        $statusMail = null;
628
        $lastEntry = $this->getGameService()->findLastInactiveEntry($this->game, $this->user);
629
630
        $form = $this->getServiceLocator()->get('playgroundgame_sharemail_form');
631
        $form->setAttribute('method', 'post');
632
633
        // buildView must be before sendMail because it adds the game template path to the templateStack
634
        $viewModel = $this->buildView($this->game);
635
636 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...
637
            $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...
638
            $form->setData($data);
639
            if ($form->isValid()) {
640
                $result = $this->getGameService()->sendShareMail($data, $this->game, $this->user, $lastEntry);
641
                if ($result) {
642
                    $statusMail = true;
643
                }
644
            }
645
        }
646
647
        $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...
648
                'statusMail' => $statusMail,
649
                'form'       => $form,
650
            ));
651
652
        return $viewModel;
653
    }
654
655
    public function inviteToTeamAction()
656
    {
657
658
        if (count($this->user->getTeams()) == 0) {
659
            return $this->redirect()->toUrl(
660
                $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...
661
                    $this->game->getClassType().'/create-team',
662
                    array('id' => $this->game->getIdentifier())
663
                )
664
            );
665
        }
666
667
        $team = $this->user->getTeams()->first(); 
668
        $invitationMapper = $this->getServiceLocator()->get('playgroundgame_invitation_mapper');
669
        $invitations = $invitationMapper->findBy(array('host' => $this->user, 'game' => $this->game));
670
        $statusMail = null;
671
        $message = '';
672
        $isHost = ($this->user->getId() === $team->getHost()->getId()) ? true : false;
673
674
        $form = $this->getServiceLocator()->get('playgroundgame_sharemail_form');
675
        $form->setAttribute('method', 'post');
676
677
        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...
678
            $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...
679
            $form->setData($data);
680
            if ($form->isValid()) {
681
                $result = $this->getGameService()->inviteToTeam($data, $this->game, $this->user);
682
                if ($result['result']) {
683
                    $statusMail = true;
684
                } else {
685
                    $statusMail = false;
686
                    $message    = $result['message'];
687
                }
688
            }
689
        }
690
691
        $viewModel = $this->buildView($this->game);
692
        $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...
693
            'team'       => $team,
694
            'invitations'=> $invitations,
695
            'message'    => $message,
696
            'statusMail' => $statusMail,
697
            'form'       => $form,
698
            'isHost'     => $isHost,
699
        ));
700
701
        return $viewModel;
702
    }
703
704
    public function createTeamAction()
705
    {
706
        if (count($this->user->getTeams()) > 0) {
707
            return $this->redirect()->toUrl(
708
                $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...
709
                    $this->game->getClassType().'/invite-to-team',
710
                    array('id' => $this->game->getIdentifier())
711
                )
712
            );
713
        }
714
715
        $form = $this->getServiceLocator()->get('playgroundgame_createteam_form');
716
        $form->setAttribute('method', 'post');
717
718
        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...
719
            $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...
720
            $form->setData($data);
721
            if ($form->isValid()) {
722
                $teamMapper = $this->getServiceLocator()->get('playgrounduser_team_mapper');
723
                $users = new \Doctrine\Common\Collections\ArrayCollection();
724
                $users->add($this->user);
725
                $teamName = $data['name'];
726
                $slugify = new \PlaygroundCore\Filter\Slugify;
727
728
                $team = new \PlaygroundUser\Entity\Team();
729
                $team->setName($teamName);
730
                $team->setIdentifier($slugify($teamName));
731
                $team->setHost($this->user);
732
                $team->addUsers($users);
733
734
                $teamMapper->insert($team);
735
736
                return $this->redirect()->toUrl(
737
                    $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...
738
                        $this->game->getClassType().'/invite-to-team',
739
                        array('id' => $this->game->getIdentifier())
740
                    )
741
                );
742
            }
743
        }
744
745
        $viewModel = $this->buildView($this->game);
746
        $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...
747
            'form'       => $form,
748
        ));
749
750
        return $viewModel;
751
    }
752
753 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...
754
    {
755
        $viewModel = new JsonModel();
756
        $viewModel->setTerminal(true);
757
        $fbId = $this->params()->fromQuery('fbId');
758
        if (!$this->game) {
759
            return $this->errorJson();
760
        }
761
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
762
        if (!$entry) {
763
            return $this->errorJson();
764
        }
765
        if (!$fbId) {
766
            return $this->errorJson();
767
        }
768
769
        $this->getGameService()->postFbWall($fbId, $this->game, $this->user, $entry);
770
771
        return $this->successJson();
772
    }
773
774
    public function fbrequestAction()
775
    {
776
        $viewModel = new ViewModel();
777
        $viewModel->setTerminal(true);
778
        $fbId = $this->params()->fromQuery('fbId');
779
        $to   = $this->params()->fromQuery('to');
780
781
        if (!$this->game) {
782
            return $this->errorJson();
783
        }
784
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
785
        if (!$entry) {
786
            return $this->errorJson();
787
        }
788
        if (!$fbId) {
789
            return $this->errorJson();
790
        }
791
792
        $this->getGameService()->postFbRequest($fbId, $this->game, $this->user, $entry, $to);
793
794
        return $this->successJson();
795
    }
796
797
    public function tweetAction()
798
    {
799
        $tweetId = $this->params()->fromQuery('tweetId');
800
801
        if (!$this->game) {
802
            return $this->errorJson();
803
        }
804
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
805
        if (!$entry) {
806
            return $this->errorJson();
807
        }
808
        if (!$tweetId) {
809
            return $this->errorJson();
810
        }
811
812
        $this->getGameService()->postTwitter($tweetId, $this->game, $this->user, $entry);
813
814
        return $this->successJson();
815
    }
816
817 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...
818
    {
819
        $viewModel = new ViewModel();
820
        $viewModel->setTerminal(true);
821
        $googleId = $this->params()->fromQuery('googleId');
822
823
        if (!$this->game) {
824
            return $this->errorJson();
825
        }
826
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
827
        if (!$entry) {
828
            return $this->errorJson();
829
        }
830
        if (!$googleId) {
831
            return $this->errorJson();
832
        }
833
834
        $this->getGameService()->postGoogle($googleId, $this->game, $this->user, $entry);
835
836
        return $this->successJson();
837
    }
838
839
    public function optinAction()
840
    {
841
        $userService = $this->getServiceLocator()->get('zfcuser_user_service');
842
843
        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...
844
            $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...
845
            $data['optinPartner'] = ($this->params()->fromPost('optinPartner'))?1:0;
846
847
            $userService->updateNewsletter($data);
848
        }
849
850
        return $this->redirect()->toUrl(
851
            $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...
852
                $this->game->getClassType(),
853
                array('id' => $this->game->getIdentifier())
854
            )
855
        );
856
    }
857
858
    public function loginAction()
859
    {
860
        $request = $this->getRequest();
861
        $redirect = "";
862
        if ($request->getQuery()->get('redirect') != '') {
863
            $redirect = $request->getQuery()->get('redirect');
864
        }
865
        $form    = $this->getServiceLocator()->get('zfcuser_login_form');
866
867
        if ($request->isPost()) {
868
            $form->setData($request->getPost());
869
870
            if (!$form->isValid()) {
871
                $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...
872
                    'Authentication failed. Please try again.'
873
                );
874
875
                $viewModel = $this->buildView($this->game);
876
                $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...
877
                        'form'          => $form,
878
                        '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...
879
                    ));
880
881
                return $viewModel;
882
            }
883
884
            // clear adapters
885
            $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...
886
            $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...
887
888
            $logged = $this->forward()->dispatch('playgrounduser_user', array('action' => 'ajaxauthenticate'));
889
890
            if (!$logged) {
891
                $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...
892
                    'Authentication failed. Please try again.'
893
                );
894
895
                return $this->redirect()->toUrl(
896
                    $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...
897
                        $this->game->getClassType().'/login',
898
                        array('id' => $this->game->getIdentifier())
899
                    )
900
                );
901
            } else {
902
                if ($redirect != "") {
903
                    return $this->redirect()->toUrl($redirect);
904
                } else {
905
                    return $this->redirect()->toUrl(
906
                        $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...
907
                            $this->game->getClassType().'/'.$this->game->nextStep('index'),
908
                            array('id' => $this->game->getIdentifier())
909
                        )
910
                    );
911
                }
912
            }
913
        }
914
915
        $form->setAttribute(
916
            'action',
917
            $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...
918
                $this->game->getClassType().'/login',
919
                array('id' => $this->game->getIdentifier())
920
            )
921
        );
922
        $viewModel = $this->buildView($this->game);
923
        $viewModel->setVariables(array(
924
                'form'          => $form,
925
                '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...
926
            ));
927
        return $viewModel;
928
    }
929
930
    public function logoutAction()
931
    {
932
        $viewModel = $this->forward()->dispatch(
933
            'playgrounduser_user',
934
            array(
935
                'controller' => 'playgrounduser_user',
936
                'action'     => 'logout',
937
                'id'         => $this->game->getIdentifier()
938
            )
939
        );
940
941
        if ($viewModel && $viewModel instanceof \Zend\View\Model\ViewModel) {
942
            $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...
943
            $viewModel->setVariables(array('game'      => $this->game));
944
        }
945
946
        return $viewModel;
947
    }
948
949
    public function userregisterAction()
950
    {
951
        $pguserOptions = $this->getServiceLocator()->get('playgrounduser_module_options');
952
        $userOptions = $this->getServiceLocator()->get('zfcuser_module_options');
953
954
        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...
955
            return $this->redirect()->toUrl(
956
                $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...
957
                    $this->game->getClassType().'/'.$this->game->nextStep('index'),
958
                    array('id' => $this->game->getIdentifier())
959
                )
960
            );
961
        }
962
        $request       = $this->getRequest();
963
        $service       = $this->getServiceLocator()->get('zfcuser_user_service');
964
        $form          = $this->getServiceLocator()->get('playgroundgame_register_form');
965
        $socialnetwork = $this->params()->fromRoute('socialnetwork', false);
966
        $form->setAttribute(
967
            'action',
968
            $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...
969
                $this->game->getClassType().'/user-register',
970
                array('id' => $this->game->getIdentifier())
971
            )
972
        );
973
        $params            = array();
974
        $socialCredentials = array();
975
976
        if ($userOptions->getUseRedirectParameterIfPresent() && $request->getQuery()->get('redirect')) {
977
            $redirect = $request->getQuery()->get('redirect');
978
        } else {
979
            $redirect = false;
980
        }
981
982
        if ($socialnetwork) {
983
            $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...
984
985
            if (!empty($infoMe)) {
986
                $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...
987
                    $infoMe->identifier,
988
                    $socialnetwork
989
                );
990
991
                if ($user || $service->getOptions()->getCreateUserAutoSocial() === true) {
992
                    //on le dirige vers l'action d'authentification
993
                    if (!$redirect && $userOptions->getLoginRedirectRoute() != '') {
994
                        $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...
995
                            $this->game->getClassType().'/login',
996
                            array('id' => $this->game->getIdentifier())
997
                        );
998
                    }
999
                    $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...
1000
                        $this->game->getClassType().'/login',
1001
                        array('id' => $this->game->getIdentifier())
1002
                    ).'/'.$socialnetwork.($redirect?'?redirect='.$redirect:'');
1003
1004
                    return $this->redirect()->toUrl($redir);
1005
                }
1006
1007
                // Je retire la saisie du login/mdp
1008
                $form->setAttribute(
1009
                    'action',
1010
                    $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...
1011
                        $this->game->getClassType().'/user-register',
1012
                        array(
1013
                            'id'            => $this->game->getIdentifier(),
1014
                            'socialnetwork' => $socialnetwork,
1015
1016
                        )
1017
                    )
1018
                );
1019
                $form->remove('password');
1020
                $form->remove('passwordVerify');
1021
1022
                $birthMonth = $infoMe->birthMonth;
1023
                if (strlen($birthMonth) <= 1) {
1024
                    $birthMonth = '0'.$birthMonth;
1025
                }
1026
                $birthDay = $infoMe->birthDay;
1027
                if (strlen($birthDay) <= 1) {
1028
                    $birthDay = '0'.$birthDay;
1029
                }
1030
1031
                $gender = $infoMe->gender;
1032
                if ($gender == 'female') {
1033
                    $title = 'Me';
1034
                } else {
1035
                    $title = 'M';
1036
                }
1037
1038
                $params = array(
1039
                    //'birth_year'  => $infoMe->birthYear,
1040
                    'title'      => $title,
1041
                    'dob'        => $birthDay.'/'.$birthMonth.'/'.$infoMe->birthYear,
1042
                    'firstname'  => $infoMe->firstName,
1043
                    'lastname'   => $infoMe->lastName,
1044
                    'email'      => $infoMe->email,
1045
                    'postalCode' => $infoMe->zip,
1046
                );
1047
                $socialCredentials = array(
1048
                    'socialNetwork' => strtolower($socialnetwork),
1049
                    'socialId'      => $infoMe->identifier,
1050
                );
1051
            }
1052
        }
1053
1054
        $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...
1055
            $this->game->getClassType().'/user-register',
1056
            array('id' => $this->game->getIdentifier())
1057
        ).($socialnetwork?'/'.$socialnetwork:'').($redirect?'?redirect='.$redirect:'');
1058
        $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...
1059
1060
        if ($prg instanceof Response) {
1061
            return $prg;
1062
        } elseif ($prg === false) {
1063
            $form->setData($params);
1064
            $viewModel = $this->buildView($this->game);
1065
            $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...
1066
                'registerForm'       => $form,
1067
                'enableRegistration' => $userOptions->getEnableRegistration(),
1068
                'redirect'           => $redirect,
1069
            ));
1070
            return $viewModel;
1071
        }
1072
1073
        $post = $prg;
1074
        if (isset($post['optin'])) {
1075
            $post['optin'] = 1;
1076
        }
1077
        if (isset($post['optinPartner'])) {
1078
            $post['optinPartner'] = 1;
1079
        }
1080
        $post = array_merge(
1081
            $post,
1082
            $socialCredentials
1083
        );
1084
1085
        if ($pguserOptions->getUseRecaptcha()) {
1086
            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...
1087
                $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...
1088
                $form->setData($post);
1089
                $viewModel = $this->buildView($this->game);
1090
                $viewModel->setVariables(array(
1091
                        'registerForm'       => $form,
1092
                        'enableRegistration' => $userOptions->getEnableRegistration(),
1093
                        'redirect'           => $redirect,
1094
                        'bah'                => 'coco',
1095
                        '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...
1096
                        '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...
1097
                    ));
1098
1099
                return $viewModel;
1100
            }
1101
        }
1102
1103
        if ($this->game->getOnInvitation()) {
1104
            $credential = trim(
1105
                $post[$this->getGameService()->getOptions()->getOnInvitationField()]
1106
            );
1107
            if (!$credential) {
1108
                $credential = $this->params()->fromQuery(
1109
                    $this->getGameService()->getOptions()->getOnInvitationField()
1110
                );
1111
            }
1112
            $found = $this->getGameService()->getInvitationMapper()->findOneBy(array('requestKey' => $credential));
1113
1114
            if (!$found || !empty($found->getUser())) {
1115
                $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...
1116
                    'Authentication failed. Please try again.'
1117
                );
1118
                $form->setData($post);
1119
                $viewModel = $this->buildView($this->game);
1120
                $viewModel->setVariables(array(
1121
                        'registerForm'       => $form,
1122
                        'enableRegistration' => $userOptions->getEnableRegistration(),
1123
                        'redirect'           => $redirect,
1124
                        '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...
1125
                        '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...
1126
                    ));
1127
1128
                return $viewModel;
1129
            }
1130
        }
1131
1132
        $user = $service->register($post, 'playgroundgame_register_form');
1133
1134
        if (!$user) {
1135
            $viewModel = $this->buildView($this->game);
1136
            $viewModel->setVariables(array(
1137
                    'registerForm'       => $form,
1138
                    'enableRegistration' => $userOptions->getEnableRegistration(),
1139
                    'redirect'           => $redirect,
1140
                    '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...
1141
                    '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...
1142
                ));
1143
1144
            return $viewModel;
1145
        }
1146
1147
        if ($this->game->getOnInvitation()) {
1148
            // user has been created, associate the code with the userId
1149
            $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...
1150
            $this->getGameService()->getInvitationMapper()->update($found);
1151
        }
1152
1153
        if ($service->getOptions()->getEmailVerification()) {
1154
            $vm = new ViewModel(array('userEmail' => $user->getEmail()));
1155
            $vm->setTemplate('playground-user/register/registermail');
1156
1157
            return $vm;
1158
        } elseif ($service->getOptions()->getLoginAfterRegistration()) {
1159
            $identityFields = $service->getOptions()->getAuthIdentityFields();
1160
            if (in_array('email', $identityFields)) {
1161
                $post['identity'] = $user->getEmail();
1162
            } elseif (in_array('username', $identityFields)) {
1163
                $post['identity'] = $user->getUsername();
1164
            }
1165
            $post['credential'] = isset($post['password'])?$post['password']:'';
1166
            $request->setPost(new Parameters($post));
1167
1168
            // clear adapters
1169
            $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...
1170
            $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...
1171
1172
            $logged = $this->forward()->dispatch('playgrounduser_user', array('action' => 'ajaxauthenticate'));
1173
1174
            if ($logged) {
1175
                return $this->redirect()->toUrl(
1176
                    $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...
1177
                        $this->game->getClassType().'/'.$this->game->nextStep('index'),
1178
                        array('id' => $this->game->getIdentifier())
1179
                    )
1180
                );
1181 View Code Duplication
            } else {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
1182
                $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...
1183
                    'Authentication failed. Please try again.'
1184
                );
1185
                return $this->redirect()->toUrl(
1186
                    $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...
1187
                        $this->game->getClassType().'/login',
1188
                        array('id' => $this->game->getIdentifier())
1189
                    )
1190
                );
1191
            }
1192
        }
1193
1194
        $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...
1195
            $this->game->getClassType().'/login',
1196
            array('id' => $this->game->getIdentifier())
1197
        ).($socialnetwork?'/'.$socialnetwork:'').($redirect?'?redirect='.$redirect:'');
1198
1199
        return $this->redirect()->toUrl($redirect);
1200
    }
1201
1202 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...
1203
    {
1204
        $viewModel = $this->forward()->dispatch(
1205
            'playgrounduser_user',
1206
            array(
1207
                'controller' => 'playgrounduser_user',
1208
                'action' => 'check-token',
1209
                'id' => $this->game->getIdentifier(),
1210
                'token' => $this->params()->fromRoute('token', null)
1211
            )
1212
        );
1213
1214
        if ($viewModel && $viewModel instanceof \Zend\View\Model\ViewModel) {
1215
            $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...
1216
            $viewModel->setVariables(array('game' => $this->game));
1217
        }
1218
1219
        return $viewModel;
1220
    }
1221
1222
    public function userProfileAction()
1223
    {
1224
        $viewModel = $this->forward()->dispatch(
1225
            'playgrounduser_user',
1226
            array(
1227
                'controller' => 'playgrounduser_user',
1228
                'action'     => 'profile',
1229
                'id'         => $this->game->getIdentifier()
1230
            )
1231
        );
1232
1233
        if ($viewModel && $viewModel instanceof \Zend\View\Model\ViewModel) {
1234
            $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...
1235
            $viewModel->setVariables(array('game'      => $this->game));
1236
        }
1237
1238
        return $viewModel;
1239
    }
1240
1241
    public function userresetAction()
1242
    {
1243
        $viewModel = $this->forward()->dispatch(
1244
            'playgrounduser_forgot',
1245
            array(
1246
                'controller' => 'playgrounduser_forgot',
1247
                'action'     => 'reset',
1248
                'id'         => $this->game->getIdentifier(),
1249
                'userId'     => $this->params()->fromRoute('userId', null),
1250
                'token'      => $this->params()->fromRoute('token', null),
1251
            )
1252
        );
1253
1254
        if ($viewModel && $viewModel instanceof \Zend\View\Model\ViewModel) {
1255
            $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...
1256
            $viewModel->setVariables(array('game'      => $this->game));
1257
        }
1258
1259
        return $viewModel;
1260
    }
1261
1262
    public function ajaxforgotAction()
1263
    {
1264
        $view = $this->forward()->dispatch(
1265
            'playgrounduser_forgot',
1266
            array(
1267
                'controller' => 'playgrounduser_forgot',
1268
                'action'     => 'ajaxforgot',
1269
                'id'         => $this->game->getIdentifier()
1270
            )
1271
        );
1272
1273
        if ($view && $view instanceof \Zend\View\Model\ViewModel) {
1274
            $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...
1275
            $view->setVariables(array('game'           => $this->game));
1276
        }
1277
1278
        return $view;
1279
    }
1280
1281 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...
1282
    {
1283
        $viewModel = $this->forward()->dispatch(
1284
            'playgroundcms',
1285
            array(
1286
                'controller' => 'playgroundcms',
1287
                'action'     => 'index',
1288
                'id'         => $this->game->getIdentifier(),
1289
                'pid'        => $this->getEvent()->getRouteMatch()->getParam('pid')
1290
            )
1291
        );
1292
1293
        if ($viewModel && $viewModel instanceof \Zend\View\Model\ViewModel) {
1294
            $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...
1295
            $viewModel->setVariables(array('game'      => $this->game));
1296
        }
1297
1298
        return $viewModel;
1299
    }
1300
1301 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...
1302
    {
1303
        $viewModel = $this->forward()->dispatch(
1304
            'playgroundcms',
1305
            array(
1306
                'controller' => 'playgroundcms',
1307
                'action'     => 'list',
1308
                'id'         => $this->game->getIdentifier(),
1309
                'category'   => $this->game->getIdentifier()
1310
            )
1311
        );
1312
1313
        if ($viewModel && $viewModel instanceof \Zend\View\Model\ViewModel) {
1314
            $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...
1315
            $viewModel->setVariables(array('game'      => $this->game));
1316
        }
1317
1318
        return $viewModel;
1319
    }
1320
1321
    /**
1322
     * This method create the basic Game view
1323
     * @param \PlaygroundGame\Entity\Game $game
1324
     */
1325
    public function buildView($game)
1326
    {
1327
        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...
1328
            $viewModel = new JsonModel();
1329
            if ($game) {
1330
                $view = $this->addAdditionalView($game);
1331
                if ($view && $view instanceof \Zend\View\Model\ViewModel) {
1332
                    $viewModel->setVariables($view->getVariables());
1333
                }
1334
            }
1335
        } else {
1336
            $viewModel = new ViewModel();
1337
1338
            if ($game) {
1339
                $this->addMetaTitle($game);
1340
                //$this->addMetaBitly();
1341
                $this->addGaEvent($game);
1342
1343
                $this->customizeGameDesign($game);
1344
1345
                $view = $this->addAdditionalView($game);
1346
                if ($view && $view instanceof \Zend\View\Model\ViewModel) {
1347
                    $viewModel->addChild($view, 'additional');
1348
                } elseif ($view && $view instanceof \Zend\Http\PhpEnvironment\Response) {
1349
                    return $view;
1350
                }
1351
1352
                $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...
1353
                    array(
1354
                        'action'        => $this->params('action'),
1355
                        'game'          => $game,
1356
                        '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...
1357
                    )
1358
                );
1359
1360
                $viewModel->setVariables($this->getShareData($game));
1361
                $viewModel->setVariables(
1362
                    array(
1363
                        'game' => $game,
1364
                        'user' => $this->user
1365
                    )
1366
                );
1367
            }
1368
        }
1369
1370
        return $viewModel;
1371
    }
1372
1373
    /**
1374
     * @param \PlaygroundGame\Entity\Game $game
1375
     */
1376
    public function addAdditionalView($game)
1377
    {
1378
        $view = false;
1379
1380
        $actionName = $this->getEvent()->getRouteMatch()->getParam('action', 'not-found');
1381
        $stepsViews = json_decode($game->getStepsViews(), true);
1382
        if ($stepsViews && isset($stepsViews[$actionName])) {
1383
            $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...
1384
            $actionData   = $stepsViews[$actionName];
1385
            if (is_string($actionData)) {
1386
                $action     = $actionData;
1387
                $classGame = __NAMESPACE__ . '\\' . ucfirst($this->game->getClassType());
1388
                $controller = $this->getEvent()->getRouteMatch()->getParam('controller', $classGame);
1389
                $view       = $this->forward()->dispatch(
1390
                    $controller,
1391
                    array(
1392
                        'action' => $action,
1393
                        'id'     => $game->getIdentifier()
1394
                    )
1395
                );
1396
            } elseif (is_array($actionData) && count($actionData) > 0) {
1397
                $action     = key($actionData);
1398
                $controller = __NAMESPACE__ . '\\' . ucfirst($actionData[$action]);
1399
                $view       = $this->forward()->dispatch(
1400
                    $controller,
1401
                    array(
1402
                        'action' => $action,
1403
                        'id'     => $game->getIdentifier()
1404
                    )
1405
                );
1406
            }
1407
            // suite au forward, le template de layout a changé, je dois le rétablir...
1408
            $this->layout()->setTemplate($beforeLayout);
1409
        }
1410
1411
        return $view;
1412
    }
1413
1414
    public function addMetaBitly()
1415
    {
1416
        $bitlyclient = $this->getOptions()->getBitlyUrl();
1417
        $bitlyuser   = $this->getOptions()->getBitlyUsername();
1418
        $bitlykey    = $this->getOptions()->getBitlyApiKey();
1419
1420
        $this->getViewHelper('HeadMeta')->setProperty('bt:client', $bitlyclient);
1421
        $this->getViewHelper('HeadMeta')->setProperty('bt:user', $bitlyuser);
1422
        $this->getViewHelper('HeadMeta')->setProperty('bt:key', $bitlykey);
1423
    }
1424
1425
    /**
1426
     * @param \PlaygroundGame\Entity\Game $game
1427
     */
1428
    public function addGaEvent($game)
1429
    {
1430
        // Google Analytics event
1431
        $ga    = $this->getServiceLocator()->get('google-analytics');
1432
        $event = new \PlaygroundCore\Analytics\Event($game->getClassType(), $this->params('action'));
1433
        $event->setLabel(str_replace("'", "\'", $game->getTitle()));
1434
        $ga->addEvent($event);
1435
    }
1436
1437
    /**
1438
     * @param \PlaygroundGame\Entity\Game $game
1439
     */
1440
    public function addMetaTitle($game)
1441
    {
1442
        $title = $game->getTitle();
1443
        $this->getGameService()->getServiceManager()->get('ViewHelperManager')->get('HeadTitle')->set($title);
1444
        // Meta set in the layout
1445
        $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...
1446
            array(
1447
                'breadcrumbTitle' => $title,
1448
                'currentPage'     => array(
1449
                    'pageGames'      => 'games',
1450
                    'pageWinners'    => '',
1451
                ),
1452
                'headParams'       => array(
1453
                    'headTitle'       => $title,
1454
                    'headDescription' => $title,
1455
                ),
1456
                'bodyCss' => $game->getIdentifier()
1457
            )
1458
        );
1459
    }
1460
1461
    /**
1462
     * @param \PlaygroundGame\Entity\Game $game
1463
     */
1464
    public function customizeGameDesign($game)
1465
    {
1466
        // If this game has a specific layout...
1467
        if ($game->getLayout()) {
1468
            $layoutViewModel = $this->layout();
1469
            $layoutViewModel->setTemplate($game->getLayout());
1470
        }
1471
1472
        // If this game has a specific stylesheet...
1473
        if ($game->getStylesheet()) {
1474
            $this->getViewHelper('HeadLink')->appendStylesheet(
1475
                $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...
1476
            );
1477
        }
1478
    }
1479
1480
    /**
1481
     * @param \PlaygroundGame\Entity\Game $game
1482
     */
1483
    public function getShareData($game)
1484
    {
1485
        $fo      = $this->getServiceLocator()->get('facebook-opengraph');
1486
        $session = new Container('facebook');
1487
1488
        // I change the fbappid if i'm in fb
1489
        if ($session->offsetExists('signed_request')) {
1490
            $fo->setId($game->getFbAppId());
1491
        }
1492
1493
        $fbShareDescription = $game->getFbShareDescription();
1494
1495
        if ($game->getFbShareImage()) {
1496
            $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...
1497
                '',
1498
                array(),
1499
                array('force_canonical' => true),
1500
                false
1501
            ).$game->getFbShareImage();
1502
        } else {
1503
            $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...
1504
                '',
1505
                array(),
1506
                array('force_canonical' => true),
1507
                false
1508
            ).$game->getMainImage();
1509
        }
1510
1511
        $secretKey = strtoupper(substr(sha1(uniqid('pg_', true).'####'.time()), 0, 15));
1512
        $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...
1513
            $game->getClassType(),
1514
            array('id' => $this->game->getIdentifier()),
1515
            array('force_canonical' => true)
1516
        ).'?key='.$secretKey;
1517
        // With core shortener helper
1518
        $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...
1519
1520
        $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...
1521
            $game->getClassType().'/fbshare',
1522
            array('id' => $this->game->getIdentifier()),
1523
            array('force_canonical' => true)
1524
        ).'?fbId='.$secretKey;
1525
1526
        $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...
1527
            $game->getClassType().'/tweet',
1528
            array('id' => $this->game->getIdentifier()),
1529
            array('force_canonical' => true)
1530
        ).'?fbId='.$secretKey;
1531
1532
        // FB Requests only work when it's a FB app
1533
        if ($game->getFbRequestMessage()) {
1534
            $fbRequestMessage = urlencode($game->getFbRequestMessage());
1535
        } else {
1536
            $fbRequestMessage = str_replace(
1537
                '__placeholder__',
1538
                $game->getTitle(),
1539
                $this->getOptions()->getDefaultShareMessage()
1540
            );
1541
        }
1542
1543
        $twShareMessage = $game->getTwShareMessage().$socialLinkUrl;
1544
1545
        // I add OG tags to the meta
1546
        $ogTitle = new \PlaygroundCore\Opengraph\Tag('og:title', $game->getTitle());
1547
        $ogDescription = new \PlaygroundCore\Opengraph\Tag('og:description', $fbShareDescription);
1548
        $ogImage = new \PlaygroundCore\Opengraph\Tag('og:image', $fbShareImage);
1549
        $twTitle = new \PlaygroundCore\Opengraph\Tag('twitter:title', $game->getTitle());
1550
        $twDescription =  new \PlaygroundCore\Opengraph\Tag('twitter:description', $this->game->getTwShareMessage());
1551
        $twImage =  new \PlaygroundCore\Opengraph\Tag('twitter:image', $fbShareImage);
1552
        $twUrl = new \PlaygroundCore\Opengraph\Tag('twitter:url', $socialLinkUrl);
1553
1554
        $fo->addTag($ogTitle);
1555
        $fo->addTag($ogDescription);
1556
        $fo->addTag($ogImage);
1557
        $fo->addTag($twTitle);
1558
        $fo->addTag($twDescription);
1559
        $fo->addTag($twImage);
1560
        $fo->addTag($twUrl);
1561
        
1562
        // I add variables + js to make the share easy
1563
        $renderer = $this->serviceLocator->get('Zend\View\Renderer\RendererInterface');
1564
        $headScript = $this->getServiceLocator()->get('ViewHelperManager')->get('HeadScript');
1565
        $headScript->appendScript("var pgGameUrl = '" . $socialLinkUrl . "';\nvar pgFbShareUrl = '" . $fbShareUrl . "';\nvar pgTwShareUrl = '" . $twShareUrl . "';");
1566
        $headScript->appendFile($renderer->frontendAssetPath() . '/js/pg/share.js');
1567
1568
        $data = array(
1569
            'socialLinkUrl'         => $socialLinkUrl,
1570
            'secretKey'             => $secretKey,
1571
            'fbShareDescription'    => $fbShareDescription,
1572
            'fbShareImage'          => $fbShareImage,
1573
            'fbRequestMessage'      => $fbRequestMessage,
1574
            'twShareMessage'        => $twShareMessage,
1575
        );
1576
1577
        return $data;
1578
    }
1579
1580
    /**
1581
     * return ajax response in json format
1582
     *
1583
     * @param array $data
1584
     * @return \Zend\View\Model\JsonModel
1585
     */
1586 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...
1587
    {
1588
        $model = new JsonModel(array(
1589
                'success' => true,
1590
                'data'    => $data,
1591
            ));
1592
        return $model->setTerminal(true);
1593
    }
1594
1595
    /**
1596
     * return ajax response in json format
1597
     *
1598
     * @param string $message
1599
     * @return \Zend\View\Model\JsonModel
1600
     */
1601 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...
1602
    {
1603
        $model = new JsonModel(array(
1604
                'success' => false,
1605
                'message' => $message,
1606
            ));
1607
        return $model->setTerminal(true);
1608
    }
1609
1610
    /**
1611
     * @param string $helperName
1612
     */
1613
    protected function getViewHelper($helperName)
1614
    {
1615
        return $this->getServiceLocator()->get('ViewHelperManager')->get($helperName);
1616
    }
1617
1618
    public function getGameService()
1619
    {
1620
        if (!$this->gameService) {
1621
            $this->gameService = $this->getServiceLocator()->get('playgroundgame_lottery_service');
1622
        }
1623
1624
        return $this->gameService;
1625
    }
1626
1627
    public function setGameService(GameService $gameService)
1628
    {
1629
        $this->gameService = $gameService;
1630
1631
        return $this;
1632
    }
1633
1634
    public function getPrizeService()
1635
    {
1636
        if (!$this->prizeService) {
1637
            $this->prizeService = $this->getServiceLocator()->get('playgroundgame_prize_service');
1638
        }
1639
1640
        return $this->prizeService;
1641
    }
1642
1643
    public function setPrizeService(PrizeService $prizeService)
1644
    {
1645
        $this->prizeService = $prizeService;
1646
1647
        return $this;
1648
    }
1649
1650
    public function getOptions()
1651
    {
1652
        if (!$this->options) {
1653
            $this->setOptions($this->getServiceLocator()->get('playgroundcore_module_options'));
1654
        }
1655
1656
        return $this->options;
1657
    }
1658
1659
    public function setOptions($options)
1660
    {
1661
        $this->options = $options;
1662
1663
        return $this;
1664
    }
1665
}
1666