Completed
Push — master ( 7b5a30...07971e )
by greg
19:31 queued 16:50
created

GameController::checkTokenAction()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 19
Code Lines 12

Duplication

Lines 19
Ratio 100 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 19
loc 19
rs 9.4285
cc 3
eloc 12
nc 2
nop 0
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
        'inviteToTeam',
39
        'prizes',
40
        'prize',
41
        'fangate',
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
    protected $withAnyUser = array(
63
        'share',
64
        'result',
65
        'play',
66
        'logout',
67
        'inviteToTeam',
68
    );
69
70
    protected $isSoloGame = false;
71
72
    /**
73
     *
74
     * @var ServiceManager
75
     */
76
    protected $serviceLocator;
77
78
    public function __construct(ServiceLocatorInterface $locator)
79
    {
80
        $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...
81
    }
82
83
    public function getServiceLocator()
84
    {
85
        return $this->serviceLocator;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->serviceLocator; (PlaygroundGame\Controller\Frontend\ServiceManager) is incompatible with the return type of the parent method Zend\Mvc\Controller\Abst...ller::getServiceLocator of type Zend\ServiceManager\ServiceLocatorInterface.

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...
86
    }
87
88
    public function setEventManager(\Zend\EventManager\EventManagerInterface $events)
89
    {
90
        parent::setEventManager($events);
91
92
        $controller = $this;
93
94
        $events->attach('dispatch', function (\Zend\Mvc\MvcEvent $e) use ($controller) {
95
            $identifier = $e->getRouteMatch()->getParam('id');
96
            $controller->game = $controller->getGameService()->checkGame($identifier, false);
97
98
            if (!$controller->game &&
99
                    in_array($controller->params('action'), $controller->withGame)
100
                ) {
101
                return $controller->notFoundAction();
102
            }
103
104
            if ($controller->game &&
105
                    $controller->game->isClosed() &&
106
                    in_array($controller->params('action'), $controller->withOnlineGame)
107
                ) {
108
                return $controller->notFoundAction();
109
            }
110
111
            $config = $this->getServiceLocator()->get('config');
112
            $customUrl = str_replace('frontend.', '', $e->getRouteMatch()->getMatchedRouteName());
113
            $customUrl = explode("/", $customUrl)[0];
114
115
            if (isset($config['custom_games']) && isset($config['custom_games'][$controller->game->getIdentifier()]) &&
116
                    $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.

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...
117
                ) {
118
                $this->isSoloGame = true;
119
            }
120
121
            if ($controller->game) {
122
                // this is possible to create a specific game design in /design/frontend/default/custom.
123
                //It will precede all others templates.
124
                $templatePathResolver = $controller->getServiceLocator()->get('Zend\View\Resolver\TemplatePathStack');
125
                $l = $templatePathResolver->getPaths();
126
                $templatePathResolver->addPath($l[0].'custom/'.$controller->game->getIdentifier());
127
            }
128
129
                $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...
130
            if ($controller->game &&
131
                    !$controller->user &&
132
                    !$controller->game->getAnonymousAllowed() &&
133
                    in_array($controller->params('action'), $controller->withAnyUser)
134
                ) {
135
                $redirect = urlencode(
136
                    $controller->url()->fromRoute(
137
                        'frontend/'.$controller->game->getClassType().'/'.$controller->params('action'),
138
                        array('id'              => $controller->game->getIdentifier()),
139
                        array('force_canonical' => true)
140
                    )
141
                );
142
143
                if ($this->isSoloGame) {
144
                     $urlRegister = $controller->url()->fromRoute(
145
                         'frontend.'.$customUrl.'/'.$controller->game->getClassType().'/user-register',
146
                         array(),
147
                         array('force_canonical' => true)
148
                     ).'?redirect='.$redirect;
149
                } else {
150
                    $urlRegister = $controller->url()->fromRoute(
151
                        'frontend/zfcuser/register',
152
                        array(),
153
                        array('force_canonical' => true)
154
                    ).'?redirect='.$redirect;
155
                }
156
157
                // code permettant d'identifier un custom game
158
                // ligne $config = $controller->getGameService()->getServiceManager()->get('config');
159
                // ligne $customUrl = str_replace('frontend.', '', $e->getRouteMatch()->getParam('area', ''));
160
                // ligne if ($config['custom_games'][$controller->game->getIdentifier()] &&
161
                // ligne    $controller->getRequest()->getUri()->getHost() === $customUrl
162
                // ligne ) {
163
                return $controller->redirect()->toUrl($urlRegister);
164
            }
165
166
                return;
167
        }, 100);// execute before executing action logic
168
    }
169
170
    /**
171
     * Action called if matched action does not exist
172
     * For this view not to be catched by Zend\Mvc\View\RouteNotFoundStrategy
173
     * it has to be rendered in the controller. Hence the code below.
174
     *
175
     * This action is injected as a catchall action for each custom_games definition
176
     * This way, when a custom_game is created, the 404 is it's responsability and the
177
     * view can be defined in design/frontend/default/custom/$slug/playground_game/$gametype/404.phtml
178
     *
179
     *
180
     * @return \Zend\Stdlib\ResponseInterface
181
     */
182
    public function notFoundAction()
183
    {
184
        $templatePathResolver = $this->getServiceLocator()->get('Zend\View\Resolver\TemplatePathStack');
185
186
        // I create a template path in which I can find a custom template
187
        $controller     = explode('\\', get_class($this));
188
        $controllerPath = str_replace('Controller', '', end($controller));
189
        $controllerPath = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '-\\1', $controllerPath));
190
        $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.

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...
191
        if ($this->game) {
192
            $uri = str_replace($controllerPath.'/'.$this->game->getIdentifier().'/', '', $uri);
193
        }
194
        $uri      = str_replace("/".$this->getEvent()->getRouteMatch()->getParam('locale')."/", "/", $uri);
195
        $template = 'playground-game/'.$controllerPath.'/custom'.$uri;
196
197
        if (false === $templatePathResolver->resolve($template)) {
198
            $viewRender = $this->getServiceLocator()->get('ViewRenderer');
199
200
            $this->getEvent()->getRouteMatch()->setParam('action', 'not-found');
201
            $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...
202
203
            $res = 'error/404';
204
205
            $viewModel = $this->buildView($this->game);
206
            $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...
207
208
            $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...
209
            $this->response->setContent($viewRender->render($this->layout()));
210
211
            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\ViewMode...View\Model\ConsoleModel.

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...
212
        }
213
214
        $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 217 which is incompatible with the return type documented by PlaygroundGame\Controlle...troller::notFoundAction of type Zend\Stdlib\ResponseInterface.
Loading history...
215
        $viewModel->setTemplate($template);
216
217
        return $viewModel;
218
    }
219
220
    /**
221
     * This action acts as a hub : Depending on the first step of the game, it will forward the action to this step
222
     */
223
    public function homeAction()
224
    {
225
        // This fix exists only for safari in FB on Windows : we need to redirect the user to the page
226
        // outside of iframe for the cookie to be accepted. PlaygroundCore redirects to the FB Iframed page when
227
        // it discovers that the user arrives for the first time on the game in FB.
228
        // When core redirects, it adds a 'redir_fb_page_id' var in the querystring
229
        // Here, we test if this var exist, and then send the user back to the game in FB.
230
        // Now the cookie will be accepted by Safari...
231
        $pageId = $this->params()->fromQuery('redir_fb_page_id');
232
        if (!empty($pageId)) {
233
            $appId = 'app_'.$this->game->getFbAppId();
234
            $url   = '//www.facebook.com/pages/game/'.$pageId.'?sk='.$appId;
235
236
            return $this->redirect()->toUrl($url);
237
        }
238
239
        // If an entry has already been done during this session, I reset the anonymous_identifier cookie
240
        // so that another person can play the same game (if game conditions are fullfilled)
241
        $session = new Container('anonymous_identifier');
242
        if ($session->offsetExists('anonymous_identifier')) {
243
            $session->offsetUnset('anonymous_identifier');
244
        }
245
246
        return $this->forward()->dispatch(
247
            'playgroundgame_'.$this->game->getClassType(),
248
            array(
249
                'controller' => 'playgroundgame_'.$this->game->getClassType(),
250
                'action'     => $this->game->firstStep(),
251
                'id'         => $this->game->getIdentifier()
252
            )
253
        );
254
    }
255
256
    /**
257
     * Homepage of the game
258
     */
259
    public function indexAction()
260
    {
261
        $isSubscribed = false;
262
263
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
264
        if ($entry) {
265
            $isSubscribed = true;
266
        }
267
268
        $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 273 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...
269
        $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...
270
            'isSubscribed' => $isSubscribed,
271
        ));
272
273
        return $viewModel;
274
    }
275
276
    /**
277
     * leaderboardAction
278
     *
279
     * @return ViewModel $viewModel
280
     */
281
    public function leaderboardAction()
282
    {
283
        $filter = $this->getEvent()->getRouteMatch()->getParam('filter');
284
        $p      = $this->getEvent()->getRouteMatch()->getParam('p');
285
286
        $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...
287
        $subViewModel = $this->forward()->dispatch(
288
            'playgroundreward',
289
            array('action' => 'leaderboard', 'filter' => $filter, 'p' => $p)
290
        );
291
292
        // suite au forward, le template de layout a changé, je dois le rétablir...
293
        $this->layout()->setTemplate($beforeLayout);
294
        $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...
295
            array(
296
                'action' => $this->params('action'),
297
                'game'   => $this->game,
298
            )
299
        );
300
301
        $subViewModel->setVariables($this->getShareData($this->game));
302
        $subViewModel->setVariables(array('game' => $this->game, 'user' => $this->user));
303
304
        return $subViewModel;
305
    }
306
307
    /**
308
     * This action has been designed to be called by other controllers
309
     * It gives the ability to display an information form and persist it in the game entry
310
     *
311
     * @return \Zend\View\Model\ViewModel
312
     */
313
    public function registerAction()
314
    {
315
        $formDef = $this->game->getPlayerForm();
316
        if ($formDef !== null) {
317
            $form = $this->getGameService()->createFormFromJson($formDef->getForm(), 'playerForm');
318
        } else {
319
            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...
320
        }
321
322
        if ($this->getRequest()->isPost()) {
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Zend\Stdlib\RequestInterface as the method isPost() does only exist in the following implementations of said interface: Zend\Http\PhpEnvironment\Request, Zend\Http\Request.

Let’s take a look at an example:

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

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

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

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

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

Available Fixes

  1. Change the type-hint for the parameter:

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

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

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

Let’s take a look at an example:

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

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

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

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

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

Available Fixes

  1. Change the type-hint for the parameter:

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

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

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

Let’s take a look at an example:

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

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

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

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

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

Available Fixes

  1. Change the type-hint for the parameter:

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

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

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
327
            );
328
329
            $form->setData($data);
330
331
            if ($form->isValid()) {
332
                // steps of the game
333
                $steps = $this->game->getStepsArray();
334
                // sub steps of the game
335
                $viewSteps = $this->game->getStepsViewsArray();
336
337
                // register position
338
                $key = array_search($this->params('action'), $viewSteps);
339
                if (!$key) {
340
                    // register is not a substep of the game so it's a step
341
                    $key     = array_search($this->params('action'), $steps);
342
                    $keyStep = true;
343
                } else {
344
                    // register was a substep, i search the index of its parent
345
                    $key     = array_search($key, $steps);
346
                    $keyStep = false;
347
                }
348
349
                // play position
350
                $keyplay = array_search('play', $viewSteps);
351
352
                if (!$keyplay) {
353
                    // play is not a substep, so it's a step
354
                    $keyplay     = array_search('play', $steps);
355
                    $keyplayStep = true;
356
                } else {
357
                    // play is a substep so I search the index of its parent
358
                    $keyplay     = array_search($keyplay, $steps);
359
                    $keyplayStep = false;
360
                }
361
362
                // If register step before play, I don't have no entry yet. I have to create one
363
                // If register after play step, I search for the last entry created by play step.
364
365
                if ($key < $keyplay || ($keyStep && !$keyplayStep && $key <= $keyplay)) {
366
                    $entry = $this->getGameService()->play($this->game, $this->user);
367
                    if (!$entry) {
368
                        // the user has already taken part of this game and the participation limit has been reached
369
                        $this->flashMessenger()->addMessage('Vous avez déjà participé');
370
371
                        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...
372
                            $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...
373
                                $this->game->getClassType().'/result',
374
                                array(
375
                                    'id' => $this->game->getIdentifier(),
376
                                )
377
                            )
378
                        );
379
                    }
380
                } else {
381
                    // I'm looking for an entry without anonymousIdentifier (the active entry in fact).
382
                    $entry = $this->getGameService()->findLastEntry($this->game, $this->user);
383
                    if ($this->getGameService()->hasReachedPlayLimit($this->game, $this->user)) {
384
                        // the user has already taken part of this game and the participation limit has been reached
385
                        $this->flashMessenger()->addMessage('Vous avez déjà participé');
386
387
                        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...
388
                            $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...
389
                                $this->game->getClassType().'/result',
390
                                array(
391
                                    'id' => $this->game->getIdentifier(),
392
                                )
393
                            )
394
                        );
395
                    }
396
                }
397
398
                $this->getGameService()->updateEntryPlayerForm($form->getData(), $this->game, $this->user, $entry);
399
400
                if (!empty($this->game->nextStep($this->params('action')))) {
401
                    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...
402
                        $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...
403
                            $this->game->getClassType().'/'.$this->game->nextStep($this->params('action')),
404
                            array('id'              => $this->game->getIdentifier()),
405
                            array('force_canonical' => true)
406
                        )
407
                    );
408
                }
409
            }
410
        }
411
412
        $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 417 which is incompatible with the return type documented by PlaygroundGame\Controlle...troller::registerAction of type Zend\View\Model\ViewModel.
Loading history...
413
        $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...
414
                'form' => $form,
415
            ));
416
417
        return $viewModel;
418
    }
419
420
    /**
421
     * This action takes care of the terms of the game
422
     */
423
    public function termsAction()
424
    {
425
        $viewModel = $this->buildView($this->game);
426
427
        return $viewModel;
428
    }
429
430
    /**
431
     * This action takes care of the conditions of the game
432
     */
433
    public function conditionsAction()
434
    {
435
        $viewModel = $this->buildView($this->game);
436
437
        return $viewModel;
438
    }
439
440
    /**
441
     * This action takes care of bounce page of the game
442
     */
443
    public function bounceAction()
444
    {
445
        $availableGames = $this->getGameService()->getAvailableGames($this->user);
446
447
        $rssUrl = '';
448
        $config = $this->getGameService()->getServiceManager()->get('config');
449
        if (isset($config['rss']['url'])) {
450
            $rssUrl = $config['rss']['url'];
451
        }
452
453
        $viewModel = $this->buildView($this->game);
454
        $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...
455
                'rssUrl'         => $rssUrl,
456
                'user'           => $this->user,
457
                'availableGames' => $availableGames,
458
            ));
459
460
        return $viewModel;
461
    }
462
463
    /**
464
     * This action displays the Prizes page associated to the game
465
     */
466
    public function prizesAction()
467
    {
468
        if (count($this->game->getPrizes()) == 0) {
469
            return $this->notFoundAction();
470
        }
471
472
        $viewModel = $this->buildView($this->game);
473
474
        return $viewModel;
475
    }
476
477
    /**
478
     * This action displays a specific Prize page among those associated to the game
479
     */
480
    public function prizeAction()
481
    {
482
        $prizeIdentifier = $this->getEvent()->getRouteMatch()->getParam('prize');
483
        $prize           = $this->getPrizeService()->getPrizeMapper()->findByIdentifier($prizeIdentifier);
484
485
        if (!$prize) {
486
            return $this->notFoundAction();
487
        }
488
489
        $viewModel = $this->buildView($this->game);
490
        $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...
491
492
        return $viewModel;
493
    }
494
495
    public function gameslistAction()
496
    {
497
        $layoutViewModel = $this->layout();
498
499
        $slider = new ViewModel();
500
        $slider->setTemplate('playground-game/common/top_promo');
501
502
        $sliderItems = $this->getGameService()->getActiveSliderGames();
503
504
        $slider->setVariables(array('sliderItems' => $sliderItems));
505
506
        $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...
507
508
        $games = $this->getGameService()->getActiveGames(false, '', 'endDate');
509
        if (is_array($games)) {
510
            $paginator = new \Zend\Paginator\Paginator(new \Zend\Paginator\Adapter\ArrayAdapter($games));
511
        } else {
512
            $paginator = $games;
513
        }
514
515
        $paginator->setItemCountPerPage(7);
516
        $paginator->setCurrentPageNumber($this->getEvent()->getRouteMatch()->getParam('p'));
517
518
        $bitlyclient = $this->getOptions()->getBitlyUrl();
519
        $bitlyuser   = $this->getOptions()->getBitlyUsername();
520
        $bitlykey    = $this->getOptions()->getBitlyApiKey();
521
522
        $this->getViewHelper('HeadMeta')->setProperty('bt:client', $bitlyclient);
523
        $this->getViewHelper('HeadMeta')->setProperty('bt:user', $bitlyuser);
524
        $this->getViewHelper('HeadMeta')->setProperty('bt:key', $bitlykey);
525
526
        $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...
527
            array(
528
                'sliderItems'  => $sliderItems,
529
                'currentPage'  => array(
530
                    'pageGames'   => 'games',
531
                    'pageWinners' => '',
532
                ),
533
            )
534
        );
535
536
        return new ViewModel(
537
            array(
538
                'games' => $paginator,
539
            )
540
        );
541
    }
542
543
    public function fangateAction()
544
    {
545
        $viewModel = $this->buildView($this->game);
546
547
        return $viewModel;
548
    }
549
550
    public function shareAction()
551
    {
552
        $statusMail = null;
553
        $lastEntry  = null;
554
555
        // steps of the game
556
        $steps = $this->game->getStepsArray();
557
        // sub steps of the game
558
        $viewSteps = $this->game->getStepsViewsArray();
559
560
        // share position
561
        $key = array_search($this->params('action'), $viewSteps);
562
        if (!$key) {
563
            // share is not a substep of the game so it's a step
564
            $key = array_search($this->params('action'), $steps);
565
        } else {
566
            // share was a substep, I search the index of its parent
567
            $key = array_search($key, $steps);
568
        }
569
570
        // play position
571
        $keyplay = array_search('play', $viewSteps);
572
573
        if (!$keyplay) {
574
            // play is not a substep, so it's a step
575
            $keyplay = array_search('play', $steps);
576
        } else {
577
            // play is a substep so I search the index of its parent
578
            $keyplay = array_search($keyplay, $steps);
579
        }
580
581
        if ($key && $keyplay && $keyplay <= $key) {
582
            // Has the user finished the game ?
583
            $lastEntry = $this->getGameService()->findLastInactiveEntry($this->game, $this->user);
584
585
            if ($lastEntry === null) {
586
                return $this->redirect()->toUrl(
587
                    $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...
588
                        $this->game->getClassType(),
589
                        array('id' => $this->game->getIdentifier())
590
                    )
591
                );
592
            }
593
        }
594
595
        $form = $this->getServiceLocator()->get('playgroundgame_sharemail_form');
596
        $form->setAttribute('method', 'post');
597
598
        // buildView must be before sendMail because it adds the game template path to the templateStack
599
        $viewModel = $this->buildView($this->game);
600
601 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.

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...
602
            $data = $this->getRequest()->getPost()->toArray();
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Zend\Stdlib\RequestInterface as the method getPost() does only exist in the following implementations of said interface: Zend\Http\PhpEnvironment\Request, Zend\Http\Request.

Let’s take a look at an example:

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

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

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

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

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

Available Fixes

  1. Change the type-hint for the parameter:

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

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

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
603
            $form->setData($data);
604
            if ($form->isValid()) {
605
                $result = $this->getGameService()->sendShareMail($data, $this->game, $this->user, $lastEntry);
606
                if ($result) {
607
                    $statusMail = true;
608
                }
609
            }
610
        }
611
612
        $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...
613
                'statusMail' => $statusMail,
614
                'form'       => $form,
615
            ));
616
617
        return $viewModel;
618
    }
619
620
    public function inviteToTeamAction()
621
    {
622
        $statusMail = null;
623
        $message    = '';
624
625
        $form = $this->getServiceLocator()->get('playgroundgame_sharemail_form');
626
        $form->setAttribute('method', 'post');
627
628
        if ($this->getRequest()->isPost()) {
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Zend\Stdlib\RequestInterface as the method isPost() does only exist in the following implementations of said interface: Zend\Http\PhpEnvironment\Request, Zend\Http\Request.

Let’s take a look at an example:

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

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

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

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

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

Available Fixes

  1. Change the type-hint for the parameter:

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

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

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

Let’s take a look at an example:

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

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

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

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

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

Available Fixes

  1. Change the type-hint for the parameter:

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

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

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
630
            $form->setData($data);
631
            if ($form->isValid()) {
632
                $result = $this->getGameService()->inviteToTeam($data, $this->game, $this->user);
633
                if ($result['result']) {
634
                    $statusMail = true;
635
                } else {
636
                    $statusMail = false;
637
                    $message    = $result['message'];
638
                }
639
            }
640
        }
641
642
        $viewModel = $this->buildView($this->game);
643
        $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...
644
                'message'    => $message,
645
                'statusMail' => $statusMail,
646
                'form'       => $form,
647
            ));
648
649
        return $viewModel;
650
    }
651
652 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...
653
    {
654
        $viewModel = new JsonModel();
655
        $viewModel->setTerminal(true);
656
        $fbId = $this->params()->fromQuery('fbId');
657
        if (!$this->game) {
658
            return $this->errorJson();
659
        }
660
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
661
        if (!$entry) {
662
            return $this->errorJson();
663
        }
664
        if (!$fbId) {
665
            return $this->errorJson();
666
        }
667
668
        $this->getGameService()->postFbWall($fbId, $this->game, $this->user, $entry);
669
670
        return $this->successJson();
671
    }
672
673
    public function fbrequestAction()
674
    {
675
        $viewModel = new ViewModel();
676
        $viewModel->setTerminal(true);
677
        $fbId = $this->params()->fromQuery('fbId');
678
        $to   = $this->params()->fromQuery('to');
679
680
        if (!$this->game) {
681
            return $this->errorJson();
682
        }
683
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
684
        if (!$entry) {
685
            return $this->errorJson();
686
        }
687
        if (!$fbId) {
688
            return $this->errorJson();
689
        }
690
691
        $this->getGameService()->postFbRequest($fbId, $this->game, $this->user, $entry, $to);
692
693
        return $this->successJson();
694
    }
695
696
    public function tweetAction()
697
    {
698
        $tweetId = $this->params()->fromQuery('tweetId');
699
700
        if (!$this->game) {
701
            return $this->errorJson();
702
        }
703
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
704
        if (!$entry) {
705
            return $this->errorJson();
706
        }
707
        if (!$tweetId) {
708
            return $this->errorJson();
709
        }
710
711
        $this->getGameService()->postTwitter($tweetId, $this->game, $this->user, $entry);
712
713
        return $this->successJson();
714
    }
715
716 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...
717
    {
718
        $viewModel = new ViewModel();
719
        $viewModel->setTerminal(true);
720
        $googleId = $this->params()->fromQuery('googleId');
721
722
        if (!$this->game) {
723
            return $this->errorJson();
724
        }
725
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
726
        if (!$entry) {
727
            return $this->errorJson();
728
        }
729
        if (!$googleId) {
730
            return $this->errorJson();
731
        }
732
733
        $this->getGameService()->postGoogle($googleId, $this->game, $this->user, $entry);
734
735
        return $this->successJson();
736
    }
737
738
    public function optinAction()
739
    {
740
        $userService = $this->getServiceLocator()->get('zfcuser_user_service');
741
742
        if ($this->getRequest()->isPost()) {
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Zend\Stdlib\RequestInterface as the method isPost() does only exist in the following implementations of said interface: Zend\Http\PhpEnvironment\Request, Zend\Http\Request.

Let’s take a look at an example:

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

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

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

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

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

Available Fixes

  1. Change the type-hint for the parameter:

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

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

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
743
            $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...
744
            $data['optinPartner'] = ($this->params()->fromPost('optinPartner'))?1:0;
745
746
            $userService->updateNewsletter($data);
747
        }
748
749
        return $this->redirect()->toUrl(
750
            $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...
751
                $this->game->getClassType(),
752
                array('id' => $this->game->getIdentifier())
753
            )
754
        );
755
    }
756
757
    public function loginAction()
758
    {
759
        $request = $this->getRequest();
760
        $form    = $this->getServiceLocator()->get('zfcuser_login_form');
761
762
        if ($request->isPost()) {
763
            $form->setData($request->getPost());
764
765
            if (!$form->isValid()) {
766
                $this->flashMessenger()->addMessage(
767
                    'Authentication failed. Please try again.'
768
                );
769
770
                $viewModel = $this->buildView($this->game);
771
                $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...
772
                        'form'          => $form,
773
                        'flashMessages' => $this->flashMessenger()->getMessages(),
774
                    ));
775
776
                return $viewModel;
777
            }
778
779
            // clear adapters
780
            $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...
781
            $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...
782
783
            $logged = $this->forward()->dispatch('playgrounduser_user', array('action' => 'ajaxauthenticate'));
784
785 View Code Duplication
            if (!$logged) {
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...
786
                $this->flashMessenger()->addMessage(
787
                    'Authentication failed. Please try again.'
788
                );
789
790
                return $this->redirect()->toUrl(
791
                    $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...
792
                        $this->game->getClassType().'/login',
793
                        array('id' => $this->game->getIdentifier())
794
                    )
795
                );
796
            } else {
797
                return $this->redirect()->toUrl(
798
                    $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...
799
                        $this->game->getClassType().'/'.$this->game->nextStep('index'),
800
                        array('id' => $this->game->getIdentifier())
801
                    )
802
                );
803
            }
804
        }
805
806
        $form->setAttribute(
807
            'action',
808
            $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...
809
                $this->game->getClassType().'/login',
810
                array('id' => $this->game->getIdentifier())
811
            )
812
        );
813
        $viewModel = $this->buildView($this->game);
814
        $viewModel->setVariables(array(
815
                'form'          => $form,
816
                'flashMessages' => $this->flashMessenger()->getMessages(),
817
            ));
818
        return $viewModel;
819
    }
820
821
    public function logoutAction()
822
    {
823
        $viewModel = $this->forward()->dispatch(
824
            'playgrounduser_user',
825
            array(
826
                'controller' => 'playgrounduser_user',
827
                'action'     => 'logout',
828
                'id'         => $this->game->getIdentifier()
829
            )
830
        );
831
832
        if ($viewModel && $viewModel instanceof \Zend\View\Model\ViewModel) {
833
            $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...
834
            $viewModel->setVariables(array('game'      => $this->game));
835
        }
836
837
        return $viewModel;
838
    }
839
840
    public function userregisterAction()
841
    {
842
        $pguserOptions = $this->getServiceLocator()->get('playgrounduser_module_options');
843
        $userOptions = $this->getServiceLocator()->get('zfcuser_module_options');
844
845
        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...
846
            return $this->redirect()->toUrl(
847
                $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...
848
                    $this->game->getClassType().'/'.$this->game->nextStep('index'),
849
                    array('id' => $this->game->getIdentifier())
850
                )
851
            );
852
        }
853
        $request       = $this->getRequest();
854
        $service       = $this->getServiceLocator()->get('zfcuser_user_service');
855
        $form          = $this->getServiceLocator()->get('playgroundgame_register_form');
856
        $socialnetwork = $this->params()->fromRoute('socialnetwork', false);
857
        $form->setAttribute(
858
            'action',
859
            $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...
860
                $this->game->getClassType().'/user-register',
861
                array('id' => $this->game->getIdentifier())
862
            )
863
        );
864
        $params            = array();
865
        $socialCredentials = array();
866
867
        if ($userOptions->getUseRedirectParameterIfPresent() && $request->getQuery()->get('redirect')) {
868
            $redirect = $request->getQuery()->get('redirect');
869
        } else {
870
            $redirect = false;
871
        }
872
873
        if ($socialnetwork) {
874
            $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...
875
876
            if (!empty($infoMe)) {
877
                $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...
878
                    $infoMe->identifier,
879
                    $socialnetwork
880
                );
881
882
                if ($user || $service->getOptions()->getCreateUserAutoSocial() === true) {
883
                    //on le dirige vers l'action d'authentification
884
                    if (!$redirect && $userOptions->getLoginRedirectRoute() != '') {
885
                        $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...
886
                            $this->game->getClassType().'/login',
887
                            array('id' => $this->game->getIdentifier())
888
                        );
889
                    }
890
                    $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...
891
                        $this->game->getClassType().'/login',
892
                        array('id' => $this->game->getIdentifier())
893
                    ).'/'.$socialnetwork.($redirect?'?redirect='.$redirect:'');
894
895
                    return $this->redirect()->toUrl($redir);
896
                }
897
898
                // Je retire la saisie du login/mdp
899
                $form->setAttribute(
900
                    'action',
901
                    $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...
902
                        $this->game->getClassType().'/user-register',
903
                        array(
904
                            'id'            => $this->game->getIdentifier(),
905
                            'socialnetwork' => $socialnetwork,
906
907
                        )
908
                    )
909
                );
910
                $form->remove('password');
911
                $form->remove('passwordVerify');
912
913
                $birthMonth = $infoMe->birthMonth;
914
                if (strlen($birthMonth) <= 1) {
915
                    $birthMonth = '0'.$birthMonth;
916
                }
917
                $birthDay = $infoMe->birthDay;
918
                if (strlen($birthDay) <= 1) {
919
                    $birthDay = '0'.$birthDay;
920
                }
921
922
                $gender = $infoMe->gender;
923
                if ($gender == 'female') {
924
                    $title = 'Me';
925
                } else {
926
                    $title = 'M';
927
                }
928
929
                $params = array(
930
                    //'birth_year'  => $infoMe->birthYear,
931
                    'title'      => $title,
932
                    'dob'        => $birthDay.'/'.$birthMonth.'/'.$infoMe->birthYear,
933
                    'firstname'  => $infoMe->firstName,
934
                    'lastname'   => $infoMe->lastName,
935
                    'email'      => $infoMe->email,
936
                    'postalCode' => $infoMe->zip,
937
                );
938
                $socialCredentials = array(
939
                    'socialNetwork' => strtolower($socialnetwork),
940
                    'socialId'      => $infoMe->identifier,
941
                );
942
            }
943
        }
944
945
        $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...
946
            $this->game->getClassType().'/user-register',
947
            array('id' => $this->game->getIdentifier())
948
        ).($socialnetwork?'/'.$socialnetwork:'').($redirect?'?redirect='.$redirect:'');
949
        $prg = $this->prg($redirectUrl, true);
950
951
        if ($prg instanceof Response) {
952
            return $prg;
953
        } elseif ($prg === false) {
954
            $form->setData($params);
955
            $viewModel = $this->buildView($this->game);
956
            $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...
957
                'registerForm'       => $form,
958
                'enableRegistration' => $userOptions->getEnableRegistration(),
959
                'redirect'           => $redirect,
960
            ));
961
            return $viewModel;
962
        }
963
964
        $post = $prg;
965
        if(isset($post['optin'])) $post['optin'] = 1;
966
        if(isset($post['optinPartner'])) $post['optinPartner'] = 1;
967
        $post = array_merge(
968
            $post,
969
            $socialCredentials
970
        );
971
972
        if($pguserOptions->getUseRecaptcha()) {
973
            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...
974
                $this->flashMessenger()->addErrorMessage('Invalid Captcha. Please try again.');
975
                $form->setData($post);
976
                $viewModel = $this->buildView($this->game);
977
                $viewModel->setVariables(array(
978
                        'registerForm'       => $form,
979
                        'enableRegistration' => $userOptions->getEnableRegistration(),
980
                        'redirect'           => $redirect,
981
                        'bah'                => 'coco',
982
                        'flashMessages'      => $this->flashMessenger()->getMessages(),
983
                        'flashErrors'        => $this->flashMessenger()->getErrorMessages(),
984
                    ));
985
986
                return $viewModel;
987
            }
988
        }
989
990
        if ($this->game->getOnInvitation()) {
991
            $credential = trim(
992
                $post[$this->getGameService()->getOptions()->getOnInvitationField()]
993
            );
994
            if (!$credential) {
995
                $credential = $this->params()->fromQuery(
996
                    $this->getGameService()->getOptions()->getOnInvitationField()
997
                );
998
            }
999
            $found = $this->getGameService()->getInvitationMapper()->findOneBy(array('requestKey' => $credential));
1000
1001
            if (!$found || !empty($found->getUser())) {
1002
                $this->flashMessenger()->addMessage(
1003
                    'Authentication failed. Please try again.'
1004
                );
1005
                $form->setData($post);
1006
                $viewModel = $this->buildView($this->game);
1007
                $viewModel->setVariables(array(
1008
                        'registerForm'       => $form,
1009
                        'enableRegistration' => $userOptions->getEnableRegistration(),
1010
                        'redirect'           => $redirect,
1011
                        'flashMessages'      => $this->flashMessenger()->getMessages(),
1012
                        'flashErrors'        => $this->flashMessenger()->getErrorMessages(),
1013
                    ));
1014
1015
                return $viewModel;
1016
            }
1017
        }
1018
1019
        $user = $service->register($post, 'playgroundgame_register_form');
1020
1021
        if (!$user) {
1022
            $viewModel = $this->buildView($this->game);
1023
            $viewModel->setVariables(array(
1024
                    'registerForm'       => $form,
1025
                    'enableRegistration' => $userOptions->getEnableRegistration(),
1026
                    'redirect'           => $redirect,
1027
                    'flashMessages'      => $this->flashMessenger()->getMessages(),
1028
                    'flashErrors'        => $this->flashMessenger()->getErrorMessages(),
1029
                ));
1030
1031
            return $viewModel;
1032
        }
1033
1034
        if ($this->game->getOnInvitation()) {
1035
            // user has been created, associate the code with the userId
1036
            $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...
1037
            $this->getGameService()->getInvitationMapper()->update($found);
1038
        }
1039
1040
        if ($service->getOptions()->getEmailVerification()) {
1041
            $vm = new ViewModel(array('userEmail' => $user->getEmail()));
1042
            $vm->setTemplate('playground-user/register/registermail');
1043
1044
            return $vm;
1045
        } elseif ($service->getOptions()->getLoginAfterRegistration()) {
1046
            $identityFields = $service->getOptions()->getAuthIdentityFields();
1047
            if (in_array('email', $identityFields)) {
1048
                $post['identity'] = $user->getEmail();
1049
            } elseif (in_array('username', $identityFields)) {
1050
                $post['identity'] = $user->getUsername();
1051
            }
1052
            $post['credential'] = isset($post['password'])?$post['password']:'';
1053
            $request->setPost(new Parameters($post));
1054
1055
            // clear adapters
1056
            $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...
1057
            $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...
1058
1059
            $logged = $this->forward()->dispatch('playgrounduser_user', array('action' => 'ajaxauthenticate'));
1060
1061 View Code Duplication
            if ($logged) {
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...
1062
                return $this->redirect()->toUrl(
1063
                    $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...
1064
                        $this->game->getClassType().'/'.$this->game->nextStep('index'),
1065
                        array('id' => $this->game->getIdentifier())
1066
                    )
1067
                );
1068
            } else {
1069
                $this->flashMessenger()->setNamespace('zfcuser-login-form')->addMessage(
1070
                    'Authentication failed. Please try again.'
1071
                );
1072
                return $this->redirect()->toUrl(
1073
                    $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...
1074
                        $this->game->getClassType().'/login',
1075
                        array('id' => $this->game->getIdentifier())
1076
                    )
1077
                );
1078
            }
1079
        }
1080
1081
        $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...
1082
            $this->game->getClassType().'/login',
1083
            array('id' => $this->game->getIdentifier())
1084
        ).($socialnetwork?'/'.$socialnetwork:'').($redirect?'?redirect='.$redirect:'');
1085
1086
        return $this->redirect()->toUrl($redirect);
1087
    }
1088
1089 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...
1090
    {
1091
        $viewModel = $this->forward()->dispatch(
1092
            'playgrounduser_user',
1093
            array(
1094
                'controller' => 'playgrounduser_user',
1095
                'action' => 'check-token',
1096
                'id' => $this->game->getIdentifier(),
1097
                'token' => $this->params()->fromRoute('token', null)
1098
            )
1099
        );
1100
1101
        if ($viewModel && $viewModel instanceof \Zend\View\Model\ViewModel) {
1102
            $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...
1103
            $viewModel->setVariables(array('game' => $this->game));
1104
        }
1105
1106
        return $viewModel;
1107
    }
1108
1109
    public function userProfileAction()
1110
    {
1111
        $viewModel = $this->forward()->dispatch(
1112
            'playgrounduser_user',
1113
            array(
1114
                'controller' => 'playgrounduser_user',
1115
                'action'     => 'profile',
1116
                'id'         => $this->game->getIdentifier()
1117
            )
1118
        );
1119
1120
        if ($viewModel && $viewModel instanceof \Zend\View\Model\ViewModel) {
1121
            $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...
1122
            $viewModel->setVariables(array('game'      => $this->game));
1123
        }
1124
1125
        return $viewModel;
1126
    }
1127
1128
    public function userresetAction()
1129
    {
1130
        $viewModel = $this->forward()->dispatch(
1131
            'playgrounduser_forgot',
1132
            array(
1133
                'controller' => 'playgrounduser_forgot',
1134
                'action'     => 'reset',
1135
                'id'         => $this->game->getIdentifier(),
1136
                'userId'     => $this->params()->fromRoute('userId', null),
1137
                'token'      => $this->params()->fromRoute('token', null),
1138
            )
1139
        );
1140
1141
        if ($viewModel && $viewModel instanceof \Zend\View\Model\ViewModel) {
1142
            $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...
1143
            $viewModel->setVariables(array('game'      => $this->game));
1144
        }
1145
1146
        return $viewModel;
1147
    }
1148
1149
    public function ajaxforgotAction()
1150
    {
1151
        $view = $this->forward()->dispatch(
1152
            'playgrounduser_forgot',
1153
            array(
1154
                'controller' => 'playgrounduser_forgot',
1155
                'action'     => 'ajaxforgot',
1156
                'id'         => $this->game->getIdentifier()
1157
            )
1158
        );
1159
1160
        if ($view && $view instanceof \Zend\View\Model\ViewModel) {
1161
            $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...
1162
            $view->setVariables(array('game'           => $this->game));
1163
        }
1164
1165
        return $view;
1166
    }
1167
1168 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...
1169
    {
1170
        $viewModel = $this->forward()->dispatch(
1171
            'playgroundcms',
1172
            array(
1173
                'controller' => 'playgroundcms',
1174
                'action'     => 'index',
1175
                'id'         => $this->game->getIdentifier(),
1176
                'pid'        => $this->getEvent()->getRouteMatch()->getParam('pid')
1177
            )
1178
        );
1179
1180
        if ($viewModel && $viewModel instanceof \Zend\View\Model\ViewModel) {
1181
            $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...
1182
            $viewModel->setVariables(array('game'      => $this->game));
1183
        }
1184
1185
        return $viewModel;
1186
    }
1187
1188 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...
1189
    {
1190
        $viewModel = $this->forward()->dispatch(
1191
            'playgroundcms',
1192
            array(
1193
                'controller' => 'playgroundcms',
1194
                'action'     => 'list',
1195
                'id'         => $this->game->getIdentifier(),
1196
                'category'   => $this->game->getIdentifier()
1197
            )
1198
        );
1199
1200
        if ($viewModel && $viewModel instanceof \Zend\View\Model\ViewModel) {
1201
            $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...
1202
            $viewModel->setVariables(array('game'      => $this->game));
1203
        }
1204
1205
        return $viewModel;
1206
    }
1207
1208
    /**
1209
     *
1210
     * @param \PlaygroundGame\Entity\Game $game
1211
     * @param \PlaygroundUser\Entity\User $user
1212
     */
1213
    public function checkFbRegistration($user, $game)
1214
    {
1215
        $redirect = false;
1216
        $session  = new Container('facebook');
1217
        if ($session->offsetExists('signed_request')) {
1218
            if (!$user) {
1219
                // Get Playground user from Facebook info
1220
                $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...
1221
                $view         = $this->forward()->dispatch(
1222
                    'playgrounduser_user',
1223
                    array(
1224
                        'controller' => 'playgrounduser_user',
1225
                        'action'     => 'registerFacebookUser',
1226
                        'provider'   => 'facebook',
1227
                    )
1228
                );
1229
1230
                $this->layout()->setTemplate($beforeLayout);
1231
                $user = $view->user;
1232
1233
                // If the user can not be created/retrieved from Facebook info, redirect to login/register form
1234
                if (!$user) {
1235
                    $redirectUrl = urlencode(
1236
                        $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...
1237
                            $game->getClassType().'/play',
1238
                            array('id'              => $game->getIdentifier()),
1239
                            array('force_canonical' => true)
1240
                        )
1241
                    );
1242
                    $redirect = $this->redirect()->toUrl(
1243
                        $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...
1244
                            'zfcuser/register'
1245
                        ).'?redirect='.$redirectUrl
1246
                    );
1247
                }
1248
            }
1249
1250
            if ($game->getFbFan()) {
1251
                if ($this->getGameService()->checkIsFan($game) === false) {
1252
                    $redirect = $this->redirect()->toRoute(
1253
                        $game->getClassType().'/fangate',
1254
                        array('id' => $game->getIdentifier())
1255
                    );
1256
                }
1257
            }
1258
        }
1259
1260
        return $redirect;
1261
    }
1262
1263
    /**
1264
     * This method create the basic Game view
1265
     * @param \PlaygroundGame\Entity\Game $game
1266
     */
1267
    public function buildView($game)
1268
    {
1269
        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.

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...
1270
            $viewModel = new JsonModel();
1271
            if ($game) {
1272
                $view = $this->addAdditionalView($game);
1273
                if ($view && $view instanceof \Zend\View\Model\ViewModel) {
1274
                    $viewModel->setVariables($view->getVariables());
1275
                }
1276
            }
1277
        } else {
1278
            $viewModel = new ViewModel();
1279
1280
            if ($game) {
1281
                $this->addMetaTitle($game);
1282
                $this->addMetaBitly();
1283
                $this->addGaEvent($game);
1284
1285
                $this->customizeGameDesign($game);
1286
1287
                $view = $this->addAdditionalView($game);
1288
                if ($view && $view instanceof \Zend\View\Model\ViewModel) {
1289
                    $viewModel->addChild($view, 'additional');
1290
                } elseif ($view && $view instanceof \Zend\Http\PhpEnvironment\Response) {
1291
                    return $view;
1292
                }
1293
1294
                $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...
1295
                    array(
1296
                        'action'        => $this->params('action'),
1297
                        'game'          => $game,
1298
                        'flashMessages' => $this->flashMessenger()->getMessages(),
1299
1300
                    )
1301
                );
1302
1303
                $viewModel->setVariables($this->getShareData($game));
1304
                $viewModel->setVariables(array('game' => $game, 'user' => $this->user));
1305
            }
1306
        }
1307
1308
        return $viewModel;
1309
    }
1310
1311
    /**
1312
     * @param \PlaygroundGame\Entity\Game $game
1313
     */
1314
    public function addAdditionalView($game)
1315
    {
1316
        $view = false;
1317
1318
        $actionName = $this->getEvent()->getRouteMatch()->getParam('action', 'not-found');
1319
        $stepsViews = json_decode($game->getStepsViews(), true);
1320
        if ($stepsViews && isset($stepsViews[$actionName])) {
1321
            $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...
1322
            $actionData   = $stepsViews[$actionName];
1323
            if (is_string($actionData)) {
1324
                $action     = $actionData;
1325
                $controller = $this->getEvent()->getRouteMatch()->getParam('controller', 'playgroundgame_game');
1326
                $view       = $this->forward()->dispatch(
1327
                    $controller,
1328
                    array(
1329
                        'action' => $action,
1330
                        'id'     => $game->getIdentifier()
1331
                    )
1332
                );
1333
            } elseif (is_array($actionData) && count($actionData) > 0) {
1334
                $action     = key($actionData);
1335
                $controller = $actionData[$action];
1336
                $view       = $this->forward()->dispatch(
1337
                    $controller,
1338
                    array(
1339
                        'action' => $action,
1340
                        'id'     => $game->getIdentifier()
1341
                    )
1342
                );
1343
            }
1344
            // suite au forward, le template de layout a changé, je dois le rétablir...
1345
            $this->layout()->setTemplate($beforeLayout);
1346
        }
1347
1348
        return $view;
1349
    }
1350
1351
    public function addMetaBitly()
1352
    {
1353
        $bitlyclient = $this->getOptions()->getBitlyUrl();
1354
        $bitlyuser   = $this->getOptions()->getBitlyUsername();
1355
        $bitlykey    = $this->getOptions()->getBitlyApiKey();
1356
1357
        $this->getViewHelper('HeadMeta')->setProperty('bt:client', $bitlyclient);
1358
        $this->getViewHelper('HeadMeta')->setProperty('bt:user', $bitlyuser);
1359
        $this->getViewHelper('HeadMeta')->setProperty('bt:key', $bitlykey);
1360
    }
1361
1362
    /**
1363
     * @param \PlaygroundGame\Entity\Game $game
1364
     */
1365
    public function addGaEvent($game)
1366
    {
1367
        // Google Analytics event
1368
        $ga    = $this->getServiceLocator()->get('google-analytics');
1369
        $event = new \PlaygroundCore\Analytics\Event($game->getClassType(), $this->params('action'));
1370
        $event->setLabel($game->getTitle());
1371
        $ga->addEvent($event);
1372
    }
1373
1374
    /**
1375
     * @param \PlaygroundGame\Entity\Game $game
1376
     */
1377
    public function addMetaTitle($game)
1378
    {
1379
        $title = $this->translate($game->getTitle());
0 ignored issues
show
Documentation Bug introduced by
The method translate 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...
1380
        $this->getGameService()->getServiceManager()->get('ViewHelperManager')->get('HeadTitle')->set($title);
1381
        // Meta set in the layout
1382
        $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...
1383
            array(
1384
                'breadcrumbTitle' => $title,
1385
                'currentPage'     => array(
1386
                    'pageGames'      => 'games',
1387
                    'pageWinners'    => '',
1388
                ),
1389
                'headParams'       => array(
1390
                    'headTitle'       => $title,
1391
                    'headDescription' => $title,
1392
                ),
1393
                'bodyCss' => $game->getIdentifier()
1394
            )
1395
        );
1396
    }
1397
1398
    /**
1399
     * @param \PlaygroundGame\Entity\Game $game
1400
     */
1401
    public function customizeGameDesign($game)
1402
    {
1403
        // If this game has a specific layout...
1404
        if ($game->getLayout()) {
1405
            $layoutViewModel = $this->layout();
1406
            $layoutViewModel->setTemplate($game->getLayout());
1407
        }
1408
1409
        // If this game has a specific stylesheet...
1410
        if ($game->getStylesheet()) {
1411
            $this->getViewHelper('HeadLink')->appendStylesheet(
1412
                $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.

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...
1413
            );
1414
        }
1415
    }
1416
1417
    /**
1418
     * @param \PlaygroundGame\Entity\Game $game
1419
     */
1420
    public function getShareData($game)
1421
    {
1422
        $fo      = $this->getServiceLocator()->get('facebook-opengraph');
1423
        $session = new Container('facebook');
1424
1425
        // I change the fbappid if i'm in fb
1426
        if ($session->offsetExists('signed_request')) {
1427
            $fo->setId($game->getFbAppId());
1428
        }
1429
1430
        // If I want to add a share block in my view
1431 View Code Duplication
        if ($game->getFbShareMessage()) {
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...
1432
            $fbShareMessage = $game->getFbShareMessage();
1433
        } else {
1434
            $fbShareMessage = str_replace(
1435
                '__placeholder__',
1436
                $game->getTitle(),
1437
                $this->getOptions()->getDefaultShareMessage()
1438
            );
1439
        }
1440
1441
        if ($game->getFbShareImage()) {
1442
            $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...
1443
                '',
1444
                array(),
1445
                array('force_canonical' => true),
1446
                false
1447
            ).$game->getFbShareImage();
1448
        } else {
1449
            $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...
1450
                '',
1451
                array(),
1452
                array('force_canonical' => true),
1453
                false
1454
            ).$game->getMainImage();
1455
        }
1456
1457
        $secretKey = strtoupper(substr(sha1(uniqid('pg_', true).'####'.time()), 0, 15));
1458
1459
        // Without bit.ly shortener
1460
        $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...
1461
            $game->getClassType(),
1462
            array('id'              => $game->getIdentifier()),
1463
            array('force_canonical' => true)
1464
        );
1465
        // With core shortener helper
1466
        $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...
1467
1468
        // FB Requests only work when it's a FB app
1469
        if ($game->getFbRequestMessage()) {
1470
            $fbRequestMessage = urlencode($game->getFbRequestMessage());
1471
        } else {
1472
            $fbRequestMessage = str_replace(
1473
                '__placeholder__',
1474
                $game->getTitle(),
1475
                $this->getOptions()->getDefaultShareMessage()
1476
            );
1477
        }
1478
1479 View Code Duplication
        if ($game->getTwShareMessage()) {
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...
1480
            $twShareMessage = $game->getTwShareMessage().$socialLinkUrl;
1481
        } else {
1482
            $twShareMessage = str_replace(
1483
                '__placeholder__',
1484
                $game->getTitle(),
1485
                $this->getOptions()->getDefaultShareMessage()
1486
            ).$socialLinkUrl;
1487
        }
1488
1489
        $ogTitle = new \PlaygroundCore\Opengraph\Tag('og:title', $fbShareMessage);
1490
        $ogImage = new \PlaygroundCore\Opengraph\Tag('og:image', $fbShareImage);
1491
1492
        $fo->addTag($ogTitle);
1493
        $fo->addTag($ogImage);
1494
1495
        $data = array(
1496
            'socialLinkUrl'    => $socialLinkUrl,
1497
            'secretKey'        => $secretKey,
1498
            'fbShareMessage'   => $fbShareMessage,
1499
            'fbShareImage'     => $fbShareImage,
1500
            'fbRequestMessage' => $fbRequestMessage,
1501
            'twShareMessage'   => $twShareMessage,
1502
        );
1503
1504
        return $data;
1505
    }
1506
1507
    /**
1508
     * return ajax response in json format
1509
     *
1510
     * @param array $data
1511
     * @return \Zend\View\Model\JsonModel
1512
     */
1513 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...
1514
    {
1515
        $model = new JsonModel(array(
1516
                'success' => true,
1517
                'data'    => $data,
1518
            ));
1519
        return $model->setTerminal(true);
1520
    }
1521
1522
    /**
1523
     * return ajax response in json format
1524
     *
1525
     * @param string $message
1526
     * @return \Zend\View\Model\JsonModel
1527
     */
1528 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...
1529
    {
1530
        $model = new JsonModel(array(
1531
                'success' => false,
1532
                'message' => $message,
1533
            ));
1534
        return $model->setTerminal(true);
1535
    }
1536
1537
    /**
1538
     * @param string $helperName
1539
     */
1540
    protected function getViewHelper($helperName)
1541
    {
1542
        return $this->getServiceLocator()->get('viewhelpermanager')->get($helperName);
1543
    }
1544
1545
    public function getGameService()
1546
    {
1547
        if (!$this->gameService) {
1548
            $this->gameService = $this->getServiceLocator()->get('playgroundgame_lottery_service');
1549
        }
1550
1551
        return $this->gameService;
1552
    }
1553
1554
    public function setGameService(GameService $gameService)
1555
    {
1556
        $this->gameService = $gameService;
1557
1558
        return $this;
1559
    }
1560
1561
    public function getPrizeService()
1562
    {
1563
        if (!$this->prizeService) {
1564
            $this->prizeService = $this->getServiceLocator()->get('playgroundgame_prize_service');
1565
        }
1566
1567
        return $this->prizeService;
1568
    }
1569
1570
    public function setPrizeService(PrizeService $prizeService)
1571
    {
1572
        $this->prizeService = $prizeService;
1573
1574
        return $this;
1575
    }
1576
1577
    public function getOptions()
1578
    {
1579
        if (!$this->options) {
1580
            $this->setOptions($this->getServiceLocator()->get('playgroundcore_module_options'));
1581
        }
1582
1583
        return $this->options;
1584
    }
1585
1586
    public function setOptions($options)
1587
    {
1588
        $this->options = $options;
1589
1590
        return $this;
1591
    }
1592
}
1593