Completed
Push — develop ( b4a70c...d599ac )
by greg
02:19
created

GameController::logoutAction()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 26
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 26
rs 8.5806
cc 4
eloc 16
nc 4
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
        $events->attach('dispatch', function (\Zend\Mvc\MvcEvent $e) use ($controller) {
94
                $identifier = $e->getRouteMatch()->getParam('id');
95
                $controller->game = $controller->getGameService()->checkGame($identifier, false);
96
            if (!$controller->game &&
97
                    in_array($controller->params('action'), $controller->withGame)
98
                ) {
99
                return $controller->notFoundAction();
100
            }
101
102
                $config = $controller->getGameService()->getServiceManager()->get('config');
103
                $customUrl = str_replace('frontend.', '', $e->getRouteMatch()->getMatchedRouteName());
104
                $customUrl = explode("/", $customUrl)[0];
105
106
            if ($config['custom_games'][$controller->game->getIdentifier()] &&
107
                    $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...
108
                ) {
109
                $this->isSoloGame = true;
110
            }
111
112
            if ($controller->game &&
113
                    $controller->game->isClosed() &&
114
                    in_array($controller->params('action'), $controller->withOnlineGame)
115
                ) {
116
                return $controller->notFoundAction();
117
            }
118
119
            if ($controller->game) {
120
                // this is possible to create a specific game design in /design/frontend/default/custom.
121
                //It will precede all others templates.
122
                $templatePathResolver = $controller->getServiceLocator()->get('Zend\View\Resolver\TemplatePathStack');
123
                $l = $templatePathResolver->getPaths();
124
                $templatePathResolver->addPath($l[0].'custom/'.$controller->game->getIdentifier());
125
            }
126
127
                $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...
128
            if ($controller->game &&
129
                    !$controller->user &&
130
                    !$controller->game->getAnonymousAllowed() &&
131
                    in_array($controller->params('action'), $controller->withAnyUser)
132
                ) {
133
                $redirect = urlencode(
134
                    $controller->url()->fromRoute(
135
                        'frontend/'.$controller->game->getClassType().'/'.$controller->params('action'),
136
                        array('id'              => $controller->game->getIdentifier()),
137
                        array('force_canonical' => true)
138
                    )
139
                );
140
141
                // code permettant d'identifier un custom game
142
                if ($this->isSoloGame) {
143
                    $urlRegister = $controller->url()->fromRoute(
144
                        'frontend.'.$customUrl.'/'.$controller->game->getClassType().'/user-register',
145
                        array(),
146
                        array('force_canonical' => true)
147
                    ).'?redirect='.$redirect;
148
                } else {
149
                    $urlRegister = $controller->url()->fromRoute(
150
                        'frontend/zfcuser/register',
151
                        array(),
152
                        array('force_canonical' => true)
153
                    ).'?redirect='.$redirect;
154
                }
155
                return $controller->redirect()->toUrl($urlRegister);
156
            }
157
158
                return;
159
        }, 100);// execute before executing action logic
160
    }
161
162
    /**
163
     * Action called if matched action does not exist
164
     * For this view not to be catched by Zend\Mvc\View\RouteNotFoundStrategy
165
     * it has to be rendered in the controller. Hence the code below.
166
     *
167
     * This action is injected as a catchall action for each custom_games definition
168
     * This way, when a custom_game is created, the 404 is it's responsability and the
169
     * view can be defined in design/frontend/default/custom/$slug/playground_game/$gametype/404.phtml
170
     *
171
     *
172
     * @return \Zend\Stdlib\ResponseInterface
173
     */
174
    public function notFoundAction()
175
    {
176
        $templatePathResolver = $this->getServiceLocator()->get('Zend\View\Resolver\TemplatePathStack');
177
178
        // I create a template path in which I can find a custom template
179
        $controller     = explode('\\', get_class($this));
180
        $controllerPath = str_replace('Controller', '', end($controller));
181
        $controllerPath = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '-\\1', $controllerPath));
182
        $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...
183
        if ($this->game) {
184
            $uri = str_replace($controllerPath.'/'.$this->game->getIdentifier().'/', '', $uri);
185
        }
186
        $uri      = str_replace("/".$this->getEvent()->getRouteMatch()->getParam('locale')."/", "/", $uri);
187
        $template = 'playground-game/'.$controllerPath.'/custom'.$uri;
188
189
        if (false === $templatePathResolver->resolve($template)) {
190
            $viewRender = $this->getServiceLocator()->get('ViewRenderer');
191
192
            $this->getEvent()->getRouteMatch()->setParam('action', 'not-found');
193
            $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...
194
195
            $res = 'error/404';
196
197
            $viewModel = $this->buildView($this->game);
198
            $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...
199
200
            $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...
201
            $this->response->setContent($viewRender->render($this->layout()));
202
203
            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...
204
        }
205
206
        $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 209 which is incompatible with the return type documented by PlaygroundGame\Controlle...troller::notFoundAction of type Zend\Stdlib\ResponseInterface.
Loading history...
207
        $viewModel->setTemplate($template);
208
209
        return $viewModel;
210
    }
211
212
    /**
213
     * This action acts as a hub : Depending on the first step of the game, it will forward the action to this step
214
     */
215
    public function homeAction()
216
    {
217
        // This fix exists only for safari in FB on Windows : we need to redirect the user to the page
218
        // outside of iframe for the cookie to be accepted. PlaygroundCore redirects to the FB Iframed page when
219
        // it discovers that the user arrives for the first time on the game in FB.
220
        // When core redirects, it adds a 'redir_fb_page_id' var in the querystring
221
        // Here, we test if this var exist, and then send the user back to the game in FB.
222
        // Now the cookie will be accepted by Safari...
223
        $pageId = $this->params()->fromQuery('redir_fb_page_id');
224
        if (!empty($pageId)) {
225
            $appId = 'app_'.$this->game->getFbAppId();
226
            $url   = '//www.facebook.com/pages/game/'.$pageId.'?sk='.$appId;
227
228
            return $this->redirect()->toUrl($url);
229
        }
230
231
        // If an entry has already been done during this session, I reset the anonymous_identifier cookie
232
        // so that another person can play the same game (if game conditions are fullfilled)
233
        $session = new Container('anonymous_identifier');
234
        if ($session->offsetExists('anonymous_identifier')) {
235
            $session->offsetUnset('anonymous_identifier');
236
        }
237
238
        return $this->forward()->dispatch(
239
            'playgroundgame_'.$this->game->getClassType(),
240
            array(
241
                'controller' => 'playgroundgame_'.$this->game->getClassType(),
242
                'action'     => $this->game->firstStep(),
243
                'id'         => $this->game->getIdentifier()
244
            )
245
        );
246
    }
247
248
    /**
249
     * Homepage of the game
250
     */
251
    public function indexAction()
252
    {
253
        $isSubscribed = false;
254
255
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
256
        if ($entry) {
257
            $isSubscribed = true;
258
        }
259
260
        $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 265 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...
261
        $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...
262
                'isSubscribed' => $isSubscribed,
263
            ));
264
265
        return $viewModel;
266
    }
267
268
    /**
269
     * leaderboardAction
270
     *
271
     * @return ViewModel $viewModel
272
     */
273
    public function leaderboardAction()
274
    {
275
        $filter = $this->getEvent()->getRouteMatch()->getParam('filter');
276
        $p      = $this->getEvent()->getRouteMatch()->getParam('p');
277
278
        $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...
279
        $subViewModel = $this->forward()->dispatch(
280
            'playgroundreward',
281
            array('action' => 'leaderboard', 'filter' => $filter, 'p' => $p)
282
        );
283
284
        // suite au forward, le template de layout a changé, je dois le rétablir...
285
        $this->layout()->setTemplate($beforeLayout);
286
        $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...
287
            array(
288
                'action' => $this->params('action'),
289
                'game'   => $this->game,
290
            )
291
        );
292
293
        $subViewModel->setVariables($this->getShareData($this->game));
294
        $subViewModel->setVariables(array('game' => $this->game, 'user' => $this->user));
295
296
        return $subViewModel;
297
    }
298
299
    /**
300
     * This action has been designed to be called by other controllers
301
     * It gives the ability to display an information form and persist it in the game entry
302
     *
303
     * @return \Zend\View\Model\ViewModel
304
     */
305
    public function registerAction()
306
    {
307
        $formDef = $this->game->getPlayerForm();
308
        if ($formDef !== null) {
309
            $form = $this->getGameService()->createFormFromJson($formDef->getForm(), 'playerForm');
310
        } else {
311
            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...
312
        }
313
314
        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...
315
            // POST Request: Process form
316
            $data = array_merge_recursive(
317
                $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...
318
                $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...
319
            );
320
321
            $form->setData($data);
322
323
            if ($form->isValid()) {
324
                // steps of the game
325
                $steps = $this->game->getStepsArray();
326
                // sub steps of the game
327
                $viewSteps = $this->game->getStepsViewsArray();
328
329
                // register position
330
                $key = array_search($this->params('action'), $viewSteps);
331
                if (!$key) {
332
                    // register is not a substep of the game so it's a step
333
                    $key     = array_search($this->params('action'), $steps);
334
                    $keyStep = true;
335
                } else {
336
                    // register was a substep, i search the index of its parent
337
                    $key     = array_search($key, $steps);
338
                    $keyStep = false;
339
                }
340
341
                // play position
342
                $keyplay = array_search('play', $viewSteps);
343
344
                if (!$keyplay) {
345
                    // play is not a substep, so it's a step
346
                    $keyplay     = array_search('play', $steps);
347
                    $keyplayStep = true;
348
                } else {
349
                    // play is a substep so I search the index of its parent
350
                    $keyplay     = array_search($keyplay, $steps);
351
                    $keyplayStep = false;
352
                }
353
354
                // If register step before play, I don't have no entry yet. I have to create one
355
                // If register after play step, I search for the last entry created by play step.
356
357
                if ($key < $keyplay || ($keyStep && !$keyplayStep && $key <= $keyplay)) {
358
                    $entry = $this->getGameService()->play($this->game, $this->user);
359
                    if (!$entry) {
360
                        // the user has already taken part of this game and the participation limit has been reached
361
                        $this->flashMessenger()->addMessage('Vous avez déjà participé');
362
363
                        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...
364
                            $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...
365
                                $this->game->getClassType().'/result',
366
                                array(
367
                                    'id' => $this->game->getIdentifier(),
368
                                )
369
                            )
370
                        );
371
                    }
372
                } else {
373
                    // I'm looking for an entry without anonymousIdentifier (the active entry in fact).
374
                    $entry = $this->getGameService()->findLastEntry($this->game, $this->user);
375
                    if ($this->getGameService()->hasReachedPlayLimit($this->game, $this->user)) {
376
                        // the user has already taken part of this game and the participation limit has been reached
377
                        $this->flashMessenger()->addMessage('Vous avez déjà participé');
378
379
                        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...
380
                            $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...
381
                                $this->game->getClassType().'/result',
382
                                array(
383
                                    'id' => $this->game->getIdentifier(),
384
                                )
385
                            )
386
                        );
387
                    }
388
                }
389
390
                $this->getGameService()->updateEntryPlayerForm($form->getData(), $this->game, $this->user, $entry);
391
392
                if (!empty($this->game->nextStep($this->params('action')))) {
393
                    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...
394
                        $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...
395
                            $this->game->getClassType().'/'.$this->game->nextStep($this->params('action')),
396
                            array('id'              => $this->game->getIdentifier()),
397
                            array('force_canonical' => true)
398
                        )
399
                    );
400
                }
401
            }
402
        }
403
404
        $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 409 which is incompatible with the return type documented by PlaygroundGame\Controlle...troller::registerAction of type Zend\View\Model\ViewModel.
Loading history...
405
        $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...
406
                'form' => $form,
407
            ));
408
409
        return $viewModel;
410
    }
411
412
    /**
413
     * This action takes care of the terms of the game
414
     */
415
    public function termsAction()
416
    {
417
        $viewModel = $this->buildView($this->game);
418
419
        return $viewModel;
420
    }
421
422
    /**
423
     * This action takes care of the conditions of the game
424
     */
425
    public function conditionsAction()
426
    {
427
        $viewModel = $this->buildView($this->game);
428
429
        return $viewModel;
430
    }
431
432
    /**
433
     * This action takes care of bounce page of the game
434
     */
435
    public function bounceAction()
436
    {
437
        $availableGames = $this->getGameService()->getAvailableGames($this->user);
438
439
        $rssUrl = '';
440
        $config = $this->getGameService()->getServiceManager()->get('config');
441
        if (isset($config['rss']['url'])) {
442
            $rssUrl = $config['rss']['url'];
443
        }
444
445
        $viewModel = $this->buildView($this->game);
446
        $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...
447
                'rssUrl'         => $rssUrl,
448
                'user'           => $this->user,
449
                'availableGames' => $availableGames,
450
            ));
451
452
        return $viewModel;
453
    }
454
455
    /**
456
     * This action displays the Prizes page associated to the game
457
     */
458
    public function prizesAction()
459
    {
460
        if (count($this->game->getPrizes()) == 0) {
461
            return $this->notFoundAction();
462
        }
463
464
        $viewModel = $this->buildView($this->game);
465
466
        return $viewModel;
467
    }
468
469
    /**
470
     * This action displays a specific Prize page among those associated to the game
471
     */
472
    public function prizeAction()
473
    {
474
        $prizeIdentifier = $this->getEvent()->getRouteMatch()->getParam('prize');
475
        $prize           = $this->getPrizeService()->getPrizeMapper()->findByIdentifier($prizeIdentifier);
476
477
        if (!$prize) {
478
            return $this->notFoundAction();
479
        }
480
481
        $viewModel = $this->buildView($this->game);
482
        $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...
483
484
        return $viewModel;
485
    }
486
487
    public function gameslistAction()
488
    {
489
        $layoutViewModel = $this->layout();
490
491
        $slider = new ViewModel();
492
        $slider->setTemplate('playground-game/common/top_promo');
493
494
        $sliderItems = $this->getGameService()->getActiveSliderGames();
495
496
        $slider->setVariables(array('sliderItems' => $sliderItems));
497
498
        $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...
499
500
        $games = $this->getGameService()->getActiveGames(false, '', 'endDate');
501
        if (is_array($games)) {
502
            $paginator = new \Zend\Paginator\Paginator(new \Zend\Paginator\Adapter\ArrayAdapter($games));
503
        } else {
504
            $paginator = $games;
505
        }
506
507
        $paginator->setItemCountPerPage(7);
508
        $paginator->setCurrentPageNumber($this->getEvent()->getRouteMatch()->getParam('p'));
509
510
        $bitlyclient = $this->getOptions()->getBitlyUrl();
511
        $bitlyuser   = $this->getOptions()->getBitlyUsername();
512
        $bitlykey    = $this->getOptions()->getBitlyApiKey();
513
514
        $this->getViewHelper('HeadMeta')->setProperty('bt:client', $bitlyclient);
515
        $this->getViewHelper('HeadMeta')->setProperty('bt:user', $bitlyuser);
516
        $this->getViewHelper('HeadMeta')->setProperty('bt:key', $bitlykey);
517
518
        $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...
519
            array(
520
                'sliderItems'  => $sliderItems,
521
                'currentPage'  => array(
522
                    'pageGames'   => 'games',
523
                    'pageWinners' => '',
524
                ),
525
            )
526
        );
527
528
        return new ViewModel(
529
            array(
530
                'games' => $paginator,
531
            )
532
        );
533
    }
534
535
    public function fangateAction()
536
    {
537
        $viewModel = $this->buildView($this->game);
538
539
        return $viewModel;
540
    }
541
542
    public function shareAction()
543
    {
544
        $statusMail = null;
545
        $lastEntry  = null;
546
547
        // steps of the game
548
        $steps = $this->game->getStepsArray();
549
        // sub steps of the game
550
        $viewSteps = $this->game->getStepsViewsArray();
551
552
        // share position
553
        $key = array_search($this->params('action'), $viewSteps);
554
        if (!$key) {
555
            // share is not a substep of the game so it's a step
556
            $key = array_search($this->params('action'), $steps);
557
        } else {
558
            // share was a substep, I search the index of its parent
559
            $key = array_search($key, $steps);
560
        }
561
562
        // play position
563
        $keyplay = array_search('play', $viewSteps);
564
565
        if (!$keyplay) {
566
            // play is not a substep, so it's a step
567
            $keyplay = array_search('play', $steps);
568
        } else {
569
            // play is a substep so I search the index of its parent
570
            $keyplay = array_search($keyplay, $steps);
571
        }
572
573
        if ($key && $keyplay && $keyplay <= $key) {
574
            // Has the user finished the game ?
575
            $lastEntry = $this->getGameService()->findLastInactiveEntry($this->game, $this->user);
576
577
            if ($lastEntry === null) {
578
                return $this->redirect()->toUrl(
579
                    $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...
580
                        $this->game->getClassType(),
581
                        array('id' => $this->game->getIdentifier())
582
                    )
583
                );
584
            }
585
        }
586
587
        $form = $this->getServiceLocator()->get('playgroundgame_sharemail_form');
588
        $form->setAttribute('method', 'post');
589
590
        // buildView must be before sendMail because it adds the game template path to the templateStack
591
        $viewModel = $this->buildView($this->game);
592
593 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...
594
            $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...
595
            $form->setData($data);
596
            if ($form->isValid()) {
597
                $result = $this->getGameService()->sendShareMail($data, $this->game, $this->user, $lastEntry);
598
                if ($result) {
599
                    $statusMail = true;
600
                }
601
            }
602
        }
603
604
        $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...
605
                'statusMail' => $statusMail,
606
                'form'       => $form,
607
            ));
608
609
        return $viewModel;
610
    }
611
612
    public function inviteToTeamAction()
613
    {
614
        $statusMail = null;
615
        $message    = '';
616
617
        $form = $this->getServiceLocator()->get('playgroundgame_sharemail_form');
618
        $form->setAttribute('method', 'post');
619
620
        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...
621
            $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...
622
            $form->setData($data);
623
            if ($form->isValid()) {
624
                $result = $this->getGameService()->inviteToTeam($data, $this->game, $this->user);
625
                if ($result['result']) {
626
                    $statusMail = true;
627
                } else {
628
                    $statusMail = false;
629
                    $message    = $result['message'];
630
                }
631
            }
632
        }
633
634
        $viewModel = $this->buildView($this->game);
635
        $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...
636
                'message'    => $message,
637
                'statusMail' => $statusMail,
638
                'form'       => $form,
639
            ));
640
641
        return $viewModel;
642
    }
643
644 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...
645
    {
646
        $viewModel = new JsonModel();
647
        $viewModel->setTerminal(true);
648
        $fbId = $this->params()->fromQuery('fbId');
649
        if (!$this->game) {
650
            return $this->errorJson();
651
        }
652
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
653
        if (!$entry) {
654
            return $this->errorJson();
655
        }
656
        if (!$fbId) {
657
            return $this->errorJson();
658
        }
659
660
        $this->getGameService()->postFbWall($fbId, $this->game, $this->user, $entry);
661
662
        return $this->successJson();
663
    }
664
665
    public function fbrequestAction()
666
    {
667
        $viewModel = new ViewModel();
668
        $viewModel->setTerminal(true);
669
        $fbId = $this->params()->fromQuery('fbId');
670
        $to   = $this->params()->fromQuery('to');
671
672
        if (!$this->game) {
673
            return $this->errorJson();
674
        }
675
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
676
        if (!$entry) {
677
            return $this->errorJson();
678
        }
679
        if (!$fbId) {
680
            return $this->errorJson();
681
        }
682
683
        $this->getGameService()->postFbRequest($fbId, $this->game, $this->user, $entry, $to);
684
685
        return $this->successJson();
686
    }
687
688
    public function tweetAction()
689
    {
690
        $tweetId = $this->params()->fromQuery('tweetId');
691
692
        if (!$this->game) {
693
            return $this->errorJson();
694
        }
695
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
696
        if (!$entry) {
697
            return $this->errorJson();
698
        }
699
        if (!$tweetId) {
700
            return $this->errorJson();
701
        }
702
703
        $this->getGameService()->postTwitter($tweetId, $this->game, $this->user, $entry);
704
705
        return $this->successJson();
706
    }
707
708 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...
709
    {
710
        $viewModel = new ViewModel();
711
        $viewModel->setTerminal(true);
712
        $googleId = $this->params()->fromQuery('googleId');
713
714
        if (!$this->game) {
715
            return $this->errorJson();
716
        }
717
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
718
        if (!$entry) {
719
            return $this->errorJson();
720
        }
721
        if (!$googleId) {
722
            return $this->errorJson();
723
        }
724
725
        $this->getGameService()->postGoogle($googleId, $this->game, $this->user, $entry);
726
727
        return $this->successJson();
728
    }
729
730
    public function optinAction()
731
    {
732
        $userService = $this->getServiceLocator()->get('zfcuser_user_service');
733
734
        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...
735
            $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...
736
            $data['optinPartner'] = ($this->params()->fromPost('optinPartner'))?1:0;
737
738
            $userService->updateNewsletter($data);
739
        }
740
741
        return $this->redirect()->toUrl(
742
            $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...
743
                $this->game->getClassType(),
744
                array('id' => $this->game->getIdentifier())
745
            )
746
        );
747
    }
748
749
    public function loginAction()
750
    {
751
        $request = $this->getRequest();
752
        $form    = $this->getServiceLocator()->get('zfcuser_login_form');
753
754
        if ($request->isPost()) {
755
            $form->setData($request->getPost());
756
757
            if (!$form->isValid()) {
758
                $this->flashMessenger()->addMessage(
759
                    'Authentication failed. Please try again.'
760
                );
761
762
                $viewModel = $this->buildView($this->game);
763
                $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...
764
                        'form'          => $form,
765
                        'flashMessages' => $this->flashMessenger()->getMessages(),
766
                    ));
767
768
                return $viewModel;
769
            }
770
771
            // clear adapters
772
            $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...
773
            $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...
774
775
            $logged = $this->forward()->dispatch('playgrounduser_user', array('action' => 'ajaxauthenticate'));
776
777 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...
778
                $this->flashMessenger()->addMessage(
779
                    'Authentication failed. Please try again.'
780
                );
781
782
                return $this->redirect()->toUrl(
783
                    $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...
784
                        $this->game->getClassType().'/login',
785
                        array('id' => $this->game->getIdentifier())
786
                    )
787
                );
788
            } else {
789
                return $this->redirect()->toUrl(
790
                    $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...
791
                        $this->game->getClassType().'/index',
792
                        array('id' => $this->game->getIdentifier())
793
                    )
794
                );
795
            }
796
        }
797
798
        $form->setAttribute(
799
            'action',
800
            $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...
801
                $this->game->getClassType().'/login',
802
                array('id' => $this->game->getIdentifier())
803
            )
804
        );
805
        $viewModel = $this->buildView($this->game);
806
        $viewModel->setVariables(array(
807
                'form'          => $form,
808
                'flashMessages' => $this->flashMessenger()->getMessages(),
809
            ));
810
        return $viewModel;
811
    }
812
813
    public function logoutAction()
814
    {
815
        $viewModel = $this->forward()->dispatch(
816
            'playgrounduser_user',
817
            array(
818
                'controller' => 'playgrounduser_user',
819
                'action'     => 'logout',
820
                'id'         => $this->game->getIdentifier()
821
            )
822
        );
823
824
        if ($viewModel && $viewModel instanceof \Zend\View\Model\ViewModel) {
825
            $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...
826
            $viewModel->setVariables(array('game'      => $this->game));
827
        }
828
829
        if ($this->isSoloGame) {
830
            return $this->redirect()->toUrl(
831
                $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...
832
                    $this->game->getClassType(),
833
                    array('id' => $this->game->getIdentifier())
834
                )
835
            );
836
        }
837
        return $viewModel;
838
    }
839
840
    public function userregisterAction()
841
    {
842
        $userOptions = $this->getServiceLocator()->get('zfcuser_module_options');
843
844
        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...
845
            return $this->redirect()->toUrl(
846
                $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...
847
                    $this->game->getClassType().'/'.$this->game->nextStep('index'),
848
                    array('id' => $this->game->getIdentifier())
849
                )
850
            );
851
        }
852
        $request       = $this->getRequest();
853
        $service       = $this->getServiceLocator()->get('zfcuser_user_service');
854
        $form          = $this->getServiceLocator()->get('playgroundgame_register_form');
855
        $socialnetwork = $this->params()->fromRoute('socialnetwork', false);
856
        $form->setAttribute(
857
            'action',
858
            $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...
859
                $this->game->getClassType().'/user-register',
860
                array('id' => $this->game->getIdentifier())
861
            )
862
        );
863
        $params            = array();
864
        $socialCredentials = array();
865
866
        if ($userOptions->getUseRedirectParameterIfPresent() && $request->getQuery()->get('redirect')) {
867
            $redirect = $request->getQuery()->get('redirect');
868
        } else {
869
            $redirect = false;
870
        }
871
872
        if ($socialnetwork) {
873
            $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...
874
875
            if (!empty($infoMe)) {
876
                $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...
877
                    $infoMe->identifier,
878
                    $socialnetwork
879
                );
880
881
                if ($user || $service->getOptions()->getCreateUserAutoSocial() === true) {
882
                    //on le dirige vers l'action d'authentification
883
                    if (!$redirect && $userOptions->getLoginRedirectRoute() != '') {
884
                        $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...
885
                            $this->game->getClassType().'/login',
886
                            array('id' => $this->game->getIdentifier())
887
                        );
888
                    }
889
                    $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...
890
                        $this->game->getClassType().'/login',
891
                        array('id' => $this->game->getIdentifier())
892
                    ).'/'.$socialnetwork.($redirect?'?redirect='.$redirect:'');
893
894
                    return $this->redirect()->toUrl($redir);
895
                }
896
897
                // Je retire la saisie du login/mdp
898
                $form->setAttribute(
899
                    'action',
900
                    $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...
901
                        $this->game->getClassType().'/user-register',
902
                        array(
903
                            'id'            => $this->game->getIdentifier(),
904
                            'socialnetwork' => $socialnetwork,
905
906
                        )
907
                    )
908
                );
909
                $form->remove('password');
910
                $form->remove('passwordVerify');
911
912
                $birthMonth = $infoMe->birthMonth;
913
                if (strlen($birthMonth) <= 1) {
914
                    $birthMonth = '0'.$birthMonth;
915
                }
916
                $birthDay = $infoMe->birthDay;
917
                if (strlen($birthDay) <= 1) {
918
                    $birthDay = '0'.$birthDay;
919
                }
920
921
                $gender = $infoMe->gender;
922
                if ($gender == 'female') {
923
                    $title = 'Me';
924
                } else {
925
                    $title = 'M';
926
                }
927
928
                $params = array(
929
                    //'birth_year'  => $infoMe->birthYear,
930
                    'title'      => $title,
931
                    'dob'        => $birthDay.'/'.$birthMonth.'/'.$infoMe->birthYear,
932
                    'firstname'  => $infoMe->firstName,
933
                    'lastname'   => $infoMe->lastName,
934
                    'email'      => $infoMe->email,
935
                    'postalCode' => $infoMe->zip,
936
                );
937
                $socialCredentials = array(
938
                    'socialNetwork' => strtolower($socialnetwork),
939
                    'socialId'      => $infoMe->identifier,
940
                );
941
            }
942
        }
943
944
        $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...
945
            $this->game->getClassType().'/user-register',
946
            array('id' => $this->game->getIdentifier())
947
        ).($socialnetwork?'/'.$socialnetwork:'').($redirect?'?redirect='.$redirect:'');
948
        $prg = $this->prg($redirectUrl, true);
949
950
        if ($prg instanceof Response) {
951
            return $prg;
952
        } elseif ($prg === false) {
953
            $form->setData($params);
954
            $viewModel = $this->buildView($this->game);
955
            $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...
956
                    'registerForm'       => $form,
957
                    'enableRegistration' => $userOptions->getEnableRegistration(),
958
                    'redirect'           => $redirect,
959
                ));
960
            return $viewModel;
961
        }
962
963
        $post = $prg;
964
        $post = array_merge(
965
            $post,
966
            $socialCredentials
967
        );
968
969
        if ($this->game->getOnInvitation()) {
970
            $credential = trim(
971
                $post[$this->getGameService()->getOptions()->getOnInvitationField()]
972
            );
973
            if (!$credential) {
974
                $credential = $this->params()->fromQuery(
975
                    $this->getGameService()->getOptions()->getOnInvitationField()
976
                );
977
            }
978
            $found = $this->getGameService()->getInvitationMapper()->findOneBy(array('requestKey' => $credential));
979
980
            if (!$found || !empty($found->getUser())) {
981
                $this->flashMessenger()->addMessage(
982
                    'Authentication failed. Please try again.'
983
                );
984
                $form->setData($post);
985
                $viewModel = $this->buildView($this->game);
986
                $viewModel->setVariables(array(
987
                        'registerForm'       => $form,
988
                        'enableRegistration' => $userOptions->getEnableRegistration(),
989
                        'redirect'           => $redirect,
990
                        'flashMessages'      => $this->flashMessenger()->getMessages(),
991
                        'flashErrors'        => $this->flashMessenger()->getErrorMessages(),
992
                    ));
993
994
                return $viewModel;
995
            }
996
        }
997
998
        $user = $service->register($post, 'playgroundgame_register_form');
999
1000
        if (!$user) {
1001
            $viewModel = $this->buildView($this->game);
1002
            $viewModel->setVariables(array(
1003
                    'registerForm'       => $form,
1004
                    'enableRegistration' => $userOptions->getEnableRegistration(),
1005
                    'redirect'           => $redirect,
1006
                    'flashMessages'      => $this->flashMessenger()->getMessages(),
1007
                    'flashErrors'        => $this->flashMessenger()->getErrorMessages(),
1008
                ));
1009
1010
            return $viewModel;
1011
        }
1012
1013
        if ($this->game->getOnInvitation()) {
1014
            // user has been created, associate the code with the userId
1015
            $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...
1016
            $this->getGameService()->getInvitationMapper()->update($found);
1017
        }
1018
1019
        if ($service->getOptions()->getEmailVerification()) {
1020
            $vm = new ViewModel(array('userEmail' => $user->getEmail()));
1021
            $vm->setTemplate('playground-user/register/registermail');
1022
1023
            return $vm;
1024
        } elseif ($service->getOptions()->getLoginAfterRegistration()) {
1025
            $identityFields = $service->getOptions()->getAuthIdentityFields();
1026
            if (in_array('email', $identityFields)) {
1027
                $post['identity'] = $user->getEmail();
1028
            } elseif (in_array('username', $identityFields)) {
1029
                $post['identity'] = $user->getUsername();
1030
            }
1031
            $post['credential'] = isset($post['password'])?$post['password']:'';
1032
            $request->setPost(new Parameters($post));
1033
1034
            // clear adapters
1035
            $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...
1036
            $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...
1037
1038
            $logged = $this->forward()->dispatch('playgrounduser_user', array('action' => 'ajaxauthenticate'));
1039
1040 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...
1041
                return $this->redirect()->toUrl(
1042
                    $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...
1043
                        $this->game->getClassType(),
1044
                        array('id' => $this->game->getIdentifier())
1045
                    )
1046
                );
1047
            } else {
1048
                $this->flashMessenger()->setNamespace('zfcuser-login-form')->addMessage(
1049
                    'Authentication failed. Please try again.'
1050
                );
1051
                return $this->redirect()->toUrl(
1052
                    $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...
1053
                        $this->game->getClassType().'/login',
1054
                        array('id' => $this->game->getIdentifier())
1055
                    )
1056
                );
1057
            }
1058
        }
1059
1060
        $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...
1061
            $this->game->getClassType().'/login',
1062
            array('id' => $this->game->getIdentifier())
1063
        ).($socialnetwork?'/'.$socialnetwork:'').($redirect?'?redirect='.$redirect:'');
1064
1065
        return $this->redirect()->toUrl($redirect);
1066
    }
1067
1068
    public function userProfileAction()
1069
    {
1070
        $viewModel = $this->forward()->dispatch(
1071
            'playgrounduser_user',
1072
            array(
1073
                'controller' => 'playgrounduser_user',
1074
                'action'     => 'profile',
1075
                'id'         => $this->game->getIdentifier()
1076
            )
1077
        );
1078
1079
        if ($viewModel && $viewModel instanceof \Zend\View\Model\ViewModel) {
1080
            $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...
1081
            $viewModel->setVariables(array('game'      => $this->game));
1082
        }
1083
1084
        return $viewModel;
1085
    }
1086
1087
    public function userresetAction()
1088
    {
1089
        $viewModel = $this->forward()->dispatch(
1090
            'playgrounduser_forgot',
1091
            array(
1092
                'controller' => 'playgrounduser_forgot',
1093
                'action'     => 'reset',
1094
                'id'         => $this->game->getIdentifier(),
1095
                'userId'     => $this->params()->fromRoute('userId', null),
1096
                'token'      => $this->params()->fromRoute('token', null),
1097
            )
1098
        );
1099
1100
        if ($viewModel && $viewModel instanceof \Zend\View\Model\ViewModel) {
1101
            $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...
1102
            $viewModel->setVariables(array('game'      => $this->game));
1103
        }
1104
1105
        return $viewModel;
1106
    }
1107
1108
    public function ajaxforgotAction()
1109
    {
1110
        $view = $this->forward()->dispatch(
1111
            'playgrounduser_forgot',
1112
            array(
1113
                'controller' => 'playgrounduser_forgot',
1114
                'action'     => 'ajaxforgot',
1115
                'id'         => $this->game->getIdentifier()
1116
            )
1117
        );
1118
1119
        if ($view && $view instanceof \Zend\View\Model\ViewModel) {
1120
            $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...
1121
            $view->setVariables(array('game'           => $this->game));
1122
        }
1123
1124
        return $view;
1125
    }
1126
1127 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...
1128
    {
1129
        $viewModel = $this->forward()->dispatch(
1130
            'playgroundcms',
1131
            array(
1132
                'controller' => 'playgroundcms',
1133
                'action'     => 'index',
1134
                'id'         => $this->game->getIdentifier(),
1135
                'pid'        => $this->getEvent()->getRouteMatch()->getParam('pid')
1136
            )
1137
        );
1138
1139
        if ($viewModel && $viewModel instanceof \Zend\View\Model\ViewModel) {
1140
            $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...
1141
            $viewModel->setVariables(array('game'      => $this->game));
1142
        }
1143
1144
        return $viewModel;
1145
    }
1146
1147 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...
1148
    {
1149
        $viewModel = $this->forward()->dispatch(
1150
            'playgroundcms',
1151
            array(
1152
                'controller' => 'playgroundcms',
1153
                'action'     => 'list',
1154
                'id'         => $this->game->getIdentifier(),
1155
                'category'   => $this->game->getIdentifier()
1156
            )
1157
        );
1158
1159
        if ($viewModel && $viewModel instanceof \Zend\View\Model\ViewModel) {
1160
            $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...
1161
            $viewModel->setVariables(array('game'      => $this->game));
1162
        }
1163
1164
        return $viewModel;
1165
    }
1166
1167
    /**
1168
     *
1169
     * @param \PlaygroundGame\Entity\Game $game
1170
     * @param \PlaygroundUser\Entity\User $user
1171
     */
1172
    public function checkFbRegistration($user, $game)
1173
    {
1174
        $redirect = false;
1175
        $session  = new Container('facebook');
1176
        if ($session->offsetExists('signed_request')) {
1177
            if (!$user) {
1178
                // Get Playground user from Facebook info
1179
                $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...
1180
                $view         = $this->forward()->dispatch(
1181
                    'playgrounduser_user',
1182
                    array(
1183
                        'controller' => 'playgrounduser_user',
1184
                        'action'     => 'registerFacebookUser',
1185
                        'provider'   => 'facebook',
1186
                    )
1187
                );
1188
1189
                $this->layout()->setTemplate($beforeLayout);
1190
                $user = $view->user;
1191
1192
                // If the user can not be created/retrieved from Facebook info, redirect to login/register form
1193
                if (!$user) {
1194
                    $redirectUrl = urlencode(
1195
                        $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...
1196
                            $game->getClassType().'/play',
1197
                            array('id'              => $game->getIdentifier()),
1198
                            array('force_canonical' => true)
1199
                        )
1200
                    );
1201
                    $redirect = $this->redirect()->toUrl(
1202
                        $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...
1203
                            'zfcuser/register'
1204
                        ).'?redirect='.$redirectUrl
1205
                    );
1206
                }
1207
            }
1208
1209
            if ($game->getFbFan()) {
1210
                if ($this->getGameService()->checkIsFan($game) === false) {
1211
                    $redirect = $this->redirect()->toRoute(
1212
                        $game->getClassType().'/fangate',
1213
                        array('id' => $game->getIdentifier())
1214
                    );
1215
                }
1216
            }
1217
        }
1218
1219
        return $redirect;
1220
    }
1221
1222
    /**
1223
     * This method create the basic Game view
1224
     * @param \PlaygroundGame\Entity\Game $game
1225
     */
1226
    public function buildView($game)
1227
    {
1228
        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...
1229
            $viewModel = new JsonModel();
1230
            if ($game) {
1231
                $view = $this->addAdditionalView($game);
1232
                if ($view && $view instanceof \Zend\View\Model\ViewModel) {
1233
                    $viewModel->setVariables($view->getVariables());
1234
                }
1235
            }
1236
        } else {
1237
            $viewModel = new ViewModel();
1238
1239
            if ($game) {
1240
                $this->addMetaTitle($game);
1241
                $this->addMetaBitly();
1242
                $this->addGaEvent($game);
1243
1244
                $this->customizeGameDesign($game);
1245
1246
                $view = $this->addAdditionalView($game);
1247
                if ($view && $view instanceof \Zend\View\Model\ViewModel) {
1248
                    $viewModel->addChild($view, 'additional');
1249
                } elseif ($view && $view instanceof \Zend\Http\PhpEnvironment\Response) {
1250
                    return $view;
1251
                }
1252
1253
                $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...
1254
                    array(
1255
                        'action'        => $this->params('action'),
1256
                        'game'          => $game,
1257
                        'flashMessages' => $this->flashMessenger()->getMessages(),
1258
1259
                    )
1260
                );
1261
1262
                $viewModel->setVariables($this->getShareData($game));
1263
                $viewModel->setVariables(array('game' => $game, 'user' => $this->user));
1264
            }
1265
        }
1266
1267
        return $viewModel;
1268
    }
1269
1270
    /**
1271
     * @param \PlaygroundGame\Entity\Game $game
1272
     */
1273
    public function addAdditionalView($game)
1274
    {
1275
        $view = false;
1276
1277
        $actionName = $this->getEvent()->getRouteMatch()->getParam('action', 'not-found');
1278
        $stepsViews = json_decode($game->getStepsViews(), true);
1279
        if ($stepsViews && isset($stepsViews[$actionName])) {
1280
            $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...
1281
            $actionData   = $stepsViews[$actionName];
1282
            if (is_string($actionData)) {
1283
                $action     = $actionData;
1284
                $controller = $this->getEvent()->getRouteMatch()->getParam('controller', 'playgroundgame_game');
1285
                $view       = $this->forward()->dispatch(
1286
                    $controller,
1287
                    array(
1288
                        'action' => $action,
1289
                        'id'     => $game->getIdentifier()
1290
                    )
1291
                );
1292
            } elseif (is_array($actionData) && count($actionData) > 0) {
1293
                $action     = key($actionData);
1294
                $controller = $actionData[$action];
1295
                $view       = $this->forward()->dispatch(
1296
                    $controller,
1297
                    array(
1298
                        'action' => $action,
1299
                        'id'     => $game->getIdentifier()
1300
                    )
1301
                );
1302
            }
1303
            // suite au forward, le template de layout a changé, je dois le rétablir...
1304
            $this->layout()->setTemplate($beforeLayout);
1305
        }
1306
1307
        return $view;
1308
    }
1309
1310
    public function addMetaBitly()
1311
    {
1312
        $bitlyclient = $this->getOptions()->getBitlyUrl();
1313
        $bitlyuser   = $this->getOptions()->getBitlyUsername();
1314
        $bitlykey    = $this->getOptions()->getBitlyApiKey();
1315
1316
        $this->getViewHelper('HeadMeta')->setProperty('bt:client', $bitlyclient);
1317
        $this->getViewHelper('HeadMeta')->setProperty('bt:user', $bitlyuser);
1318
        $this->getViewHelper('HeadMeta')->setProperty('bt:key', $bitlykey);
1319
    }
1320
1321
    /**
1322
     * @param \PlaygroundGame\Entity\Game $game
1323
     */
1324
    public function addGaEvent($game)
1325
    {
1326
        // Google Analytics event
1327
        $ga    = $this->getServiceLocator()->get('google-analytics');
1328
        $event = new \PlaygroundCore\Analytics\Event($game->getClassType(), $this->params('action'));
1329
        $event->setLabel($game->getTitle());
1330
        $ga->addEvent($event);
1331
    }
1332
1333
    /**
1334
     * @param \PlaygroundGame\Entity\Game $game
1335
     */
1336
    public function addMetaTitle($game)
1337
    {
1338
        $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...
1339
        $this->getGameService()->getServiceManager()->get('ViewHelperManager')->get('HeadTitle')->set($title);
1340
        // Meta set in the layout
1341
        $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...
1342
            array(
1343
                'breadcrumbTitle' => $title,
1344
                'currentPage'     => array(
1345
                    'pageGames'      => 'games',
1346
                    'pageWinners'    => '',
1347
                ),
1348
                'headParams'       => array(
1349
                    'headTitle'       => $title,
1350
                    'headDescription' => $title,
1351
                ),
1352
                'bodyCss' => $game->getIdentifier()
1353
            )
1354
        );
1355
    }
1356
1357
    /**
1358
     * @param \PlaygroundGame\Entity\Game $game
1359
     */
1360
    public function customizeGameDesign($game)
1361
    {
1362
        // If this game has a specific layout...
1363
        if ($game->getLayout()) {
1364
            $layoutViewModel = $this->layout();
1365
            $layoutViewModel->setTemplate($game->getLayout());
1366
        }
1367
1368
        // If this game has a specific stylesheet...
1369
        if ($game->getStylesheet()) {
1370
            $this->getViewHelper('HeadLink')->appendStylesheet(
1371
                $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...
1372
            );
1373
        }
1374
    }
1375
1376
    /**
1377
     * @param \PlaygroundGame\Entity\Game $game
1378
     */
1379
    public function getShareData($game)
1380
    {
1381
        $fo      = $this->getServiceLocator()->get('facebook-opengraph');
1382
        $session = new Container('facebook');
1383
1384
        // I change the fbappid if i'm in fb
1385
        if ($session->offsetExists('signed_request')) {
1386
            $fo->setId($game->getFbAppId());
1387
        }
1388
1389
        // If I want to add a share block in my view
1390 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...
1391
            $fbShareMessage = $game->getFbShareMessage();
1392
        } else {
1393
            $fbShareMessage = str_replace(
1394
                '__placeholder__',
1395
                $game->getTitle(),
1396
                $this->getOptions()->getDefaultShareMessage()
1397
            );
1398
        }
1399
1400
        if ($game->getFbShareImage()) {
1401
            $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...
1402
                '',
1403
                array(),
1404
                array('force_canonical' => true),
1405
                false
1406
            ).$game->getFbShareImage();
1407
        } else {
1408
            $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...
1409
                '',
1410
                array(),
1411
                array('force_canonical' => true),
1412
                false
1413
            ).$game->getMainImage();
1414
        }
1415
1416
        $secretKey = strtoupper(substr(sha1(uniqid('pg_', true).'####'.time()), 0, 15));
1417
1418
        // Without bit.ly shortener
1419
        $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...
1420
            $game->getClassType(),
1421
            array('id'              => $game->getIdentifier()),
1422
            array('force_canonical' => true)
1423
        );
1424
        // With core shortener helper
1425
        $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...
1426
1427
        // FB Requests only work when it's a FB app
1428
        if ($game->getFbRequestMessage()) {
1429
            $fbRequestMessage = urlencode($game->getFbRequestMessage());
1430
        } else {
1431
            $fbRequestMessage = str_replace(
1432
                '__placeholder__',
1433
                $game->getTitle(),
1434
                $this->getOptions()->getDefaultShareMessage()
1435
            );
1436
        }
1437
1438 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...
1439
            $twShareMessage = $game->getTwShareMessage().$socialLinkUrl;
1440
        } else {
1441
            $twShareMessage = str_replace(
1442
                '__placeholder__',
1443
                $game->getTitle(),
1444
                $this->getOptions()->getDefaultShareMessage()
1445
            ).$socialLinkUrl;
1446
        }
1447
1448
        $ogTitle = new \PlaygroundCore\Opengraph\Tag('og:title', $fbShareMessage);
1449
        $ogImage = new \PlaygroundCore\Opengraph\Tag('og:image', $fbShareImage);
1450
1451
        $fo->addTag($ogTitle);
1452
        $fo->addTag($ogImage);
1453
1454
        $data = array(
1455
            'socialLinkUrl'    => $socialLinkUrl,
1456
            'secretKey'        => $secretKey,
1457
            'fbShareMessage'   => $fbShareMessage,
1458
            'fbShareImage'     => $fbShareImage,
1459
            'fbRequestMessage' => $fbRequestMessage,
1460
            'twShareMessage'   => $twShareMessage,
1461
        );
1462
1463
        return $data;
1464
    }
1465
1466
    /**
1467
     * return ajax response in json format
1468
     *
1469
     * @param array $data
1470
     * @return \Zend\View\Model\JsonModel
1471
     */
1472 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...
1473
    {
1474
        $model = new JsonModel(array(
1475
                'success' => true,
1476
                'data'    => $data,
1477
            ));
1478
        return $model->setTerminal(true);
1479
    }
1480
1481
    /**
1482
     * return ajax response in json format
1483
     *
1484
     * @param string $message
1485
     * @return \Zend\View\Model\JsonModel
1486
     */
1487 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...
1488
    {
1489
        $model = new JsonModel(array(
1490
                'success' => false,
1491
                'message' => $message,
1492
            ));
1493
        return $model->setTerminal(true);
1494
    }
1495
1496
    /**
1497
     * @param string $helperName
1498
     */
1499
    protected function getViewHelper($helperName)
1500
    {
1501
        return $this->getServiceLocator()->get('viewhelpermanager')->get($helperName);
1502
    }
1503
1504
    public function getGameService()
1505
    {
1506
        if (!$this->gameService) {
1507
            $this->gameService = $this->getServiceLocator()->get('playgroundgame_lottery_service');
1508
        }
1509
1510
        return $this->gameService;
1511
    }
1512
1513
    public function setGameService(GameService $gameService)
1514
    {
1515
        $this->gameService = $gameService;
1516
1517
        return $this;
1518
    }
1519
1520
    public function getPrizeService()
1521
    {
1522
        if (!$this->prizeService) {
1523
            $this->prizeService = $this->getServiceLocator()->get('playgroundgame_prize_service');
1524
        }
1525
1526
        return $this->prizeService;
1527
    }
1528
1529
    public function setPrizeService(PrizeService $prizeService)
1530
    {
1531
        $this->prizeService = $prizeService;
1532
1533
        return $this;
1534
    }
1535
1536
    public function getOptions()
1537
    {
1538
        if (!$this->options) {
1539
            $this->setOptions($this->getServiceLocator()->get('playgroundcore_module_options'));
1540
        }
1541
1542
        return $this->options;
1543
    }
1544
1545
    public function setOptions($options)
1546
    {
1547
        $this->options = $options;
1548
1549
        return $this;
1550
    }
1551
}
1552