Completed
Pull Request — master (#308)
by greg
08:10 queued 04:55
created

GameController   F

Complexity

Total Complexity 177

Size/Duplication

Total Lines 1498
Duplicated Lines 14.29 %

Coupling/Cohesion

Components 1
Dependencies 18

Importance

Changes 32
Bugs 9 Features 1
Metric Value
wmc 177
c 32
b 9
f 1
lcom 1
cbo 18
dl 214
loc 1498
rs 0.6314

45 Methods

Rating   Name   Duplication   Size   Complexity  
C setEventManager() 0 62 11
B inviteToTeamAction() 0 31 4
A logoutAction() 18 18 3
A userProfileAction() 18 18 3
A userresetAction() 0 20 3
A ajaxforgotAction() 18 18 3
A cmsPageAction() 19 19 3
A cmsListAction() 19 19 3
A addGaEvent() 0 8 1
A customizeGameDesign() 0 15 3
A errorJson() 8 8 1
A getViewHelper() 0 4 1
A setOptions() 0 6 1
B notFoundAction() 0 35 2
B homeAction() 0 32 3
A indexAction() 0 16 2
A leaderboardAction() 0 22 1
C registerAction() 18 103 12
A termsAction() 0 6 1
A conditionsAction() 0 6 1
A bounceAction() 0 19 2
A prizesAction() 0 10 2
A prizeAction() 0 14 2
A gameslistAction() 0 47 2
A fangateAction() 0 6 1
C shareAction() 36 73 10
A fbshareAction() 20 20 4
B fbrequestAction() 0 22 4
A tweetAction() 0 19 4
A googleAction() 21 21 4
A optinAction() 0 18 4
B loginAction() 0 63 4
F userregisterAction() 0 227 32
B checkFbRegistration() 0 49 6
C buildView() 0 45 11
B addAdditionalView() 0 36 6
A addMetaBitly() 0 10 1
A addMetaTitle() 0 20 1
B getShareData() 10 86 6
A successJson() 8 8 1
A getGameService() 0 8 2
A setGameService() 0 6 1
A getPrizeService() 0 8 2
A setPrizeService() 0 6 1
A getOptions() 0 8 2

How to fix   Duplicated Code    Complexity   

Duplicated Code

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

Common duplication problems, and corresponding solutions are:

Complex Class

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

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

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

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

1
<?php
2
3
namespace PlaygroundGame\Controller\Frontend;
4
5
use Zend\Mvc\Controller\AbstractActionController;
6
use Zend\View\Model\ViewModel;
7
use Zend\Session\Container;
8
use PlaygroundGame\Service\GameService;
9
use PlaygroundGame\Service\Prize as PrizeService;
10
use Zend\View\Model\JsonModel;
11
use Zend\Http\PhpEnvironment\Response;
12
use Zend\Stdlib\Parameters;
13
14
class GameController extends AbstractActionController
15
{
16
    /**
17
     * @var \PlaygroundGame\Service\GameService
18
     */
19
    protected $gameService;
20
21
    protected $prizeService;
22
23
    protected $options;
24
25
    protected $game;
26
27
    protected $user;
28
29
    protected $withGame = array(
30
        'home',
31
        'index',
32
        'terms',
33
        'conditions',
34
        'leaderboard',
35
        'register',
36
        'bounce',
37
        'inviteToTeam',
38
        'prizes',
39
        'prize',
40
        'fangate',
41
        'share',
42
        'optin',
43
        'login',
44
        'logout',
45
        'ajaxforgot',
46
        'play',
47
        'result',
48
        'preview',
49
        'list'
50
    );
51
52
    protected $withOnlineGame = array(
53
        'leaderboard',
54
        'register',
55
        'bounce',
56
        'play',
57
        'result'
58
    );
59
60
    protected $withAnyUser = array(
61
        'share',
62
        'result',
63
        'play',
64
        'logout',
65
        'inviteToTeam'
66
    );
67
68
    public function setEventManager(\Zend\EventManager\EventManagerInterface $events)
69
    {
70
        parent::setEventManager($events);
71
72
        $controller = $this;
73
        $events->attach('dispatch', function (\Zend\Mvc\MvcEvent $e) use ($controller) {
74
75
            $identifier = $e->getRouteMatch()->getParam('id');
76
            $controller->game = $controller->getGameService()->checkGame($identifier, false);
77
            if (!$controller->game &&
78
                in_array($controller->params('action'), $controller->withGame)
79
            ) {
80
                return $controller->notFoundAction();
81
            }
82
83
            if ($controller->game &&
84
                $controller->game->isClosed() &&
85
                in_array($controller->params('action'), $controller->withOnlineGame)
86
            ) {
87
                return $controller->notFoundAction();
88
            }
89
90
            if ($controller->game) {
91
                // this is possible to create a specific game design in /design/frontend/default/custom.
92
                //It will precede all others templates.
93
                $templatePathResolver = $controller->getServiceLocator()->get('Zend\View\Resolver\TemplatePathStack');
94
                $l = $templatePathResolver->getPaths();
95
                $templatePathResolver->addPath($l[0].'custom/'.$controller->game->getIdentifier());
96
            }
97
98
            $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...
99
            if ($controller->game &&
100
                !$controller->user &&
101
                !$controller->game->getAnonymousAllowed() &&
102
                in_array($controller->params('action'), $controller->withAnyUser)
103
            ) {
104
                $redirect = urlencode(
105
                    $controller->url()->fromRoute(
106
                        'frontend/'.$controller->game->getClassType() . '/' . $controller->params('action'),
107
                        array('id' => $controller->game->getIdentifier()),
108
                        array('force_canonical' => true)
109
                    )
110
                );
111
112
                $urlRegister = $controller->url()->fromRoute(
113
                    'frontend/zfcuser/register',
114
                    array(),
115
                    array('force_canonical' => true)
116
                ) . '?redirect='.$redirect;
117
118
                // code permettant d'identifier un custom game
119
                // ligne $config = $controller->getGameService()->getServiceManager()->get('config');
120
                // ligne $customUrl = str_replace('frontend.', '', $e->getRouteMatch()->getParam('area', ''));
121
                // ligne if ($config['custom_games'][$controller->game->getIdentifier()] &&
122
                // ligne    $controller->getRequest()->getUri()->getHost() === $customUrl
123
                // ligne ) {
124
                return $controller->redirect()->toUrl($urlRegister);
125
            }
126
127
            return;
128
        }, 100); // execute before executing action logic
129
    }
130
131
    /**
132
     * Action called if matched action does not exist
133
     * For this view not to be catched by Zend\Mvc\View\RouteNotFoundStrategy
134
     * it has to be rendered in the controller. Hence the code below.
135
     *
136
     * This action is injected as a catchall action for each custom_games definition
137
     * This way, when a custom_game is created, the 404 is it's responsability and the
138
     * view can be defined in design/frontend/default/custom/$slug/playground_game/$gametype/404.phtml
139
     *
140
     *
141
     * @return \Zend\Stdlib\ResponseInterface
142
     */
143
    public function notFoundAction()
144
    {
145
146
        $templatePathResolver = $this->getServiceLocator()->get('Zend\View\Resolver\TemplatePathStack');
147
148
        // I create a template path in which I can find a custom template
149
        $controller = explode('\\', get_class($this));
150
        $controllerPath = str_replace('Controller', '', end($controller));
151
        $controllerPath = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '-\\1', $controllerPath));
152
        $uri = str_replace($controllerPath.'/'.$this->game->getIdentifier().'/','',$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...
153
        $uri = str_replace("/" . $this->getEvent()->getRouteMatch()->getParam('locale') . "/","/",$uri);
154
        $template = 'playground-game/'.$controllerPath . '/custom' . $uri;
155
156
        if (false === $templatePathResolver->resolve($template)) {
157
            $viewRender     = $this->getServiceLocator()->get('ViewRenderer');
158
159
            $this->getEvent()->getRouteMatch()->setParam('action', 'not-found');
160
            $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...
161
162
            $res = 'error/404';
163
164
            $viewModel = $this->buildView($this->game);
165
            $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...
166
167
            $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...
168
            $this->response->setContent($viewRender->render($this->layout()));
169
170
            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 array.

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...
171
        }
172
173
        $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 176 which is incompatible with the return type documented by PlaygroundGame\Controlle...troller::notFoundAction of type Zend\Stdlib\ResponseInterface.
Loading history...
174
        $viewModel->setTemplate($template);
175
176
        return $viewModel;
177
    }
178
179
    /**
180
     * This action acts as a hub : Depending on the first step of the game, it will forward the action to this step
181
     */
182
    public function homeAction()
183
    {
184
        // This fix exists only for safari in FB on Windows : we need to redirect the user to the page
185
        // outside of iframe for the cookie to be accepted. PlaygroundCore redirects to the FB Iframed page when
186
        // it discovers that the user arrives for the first time on the game in FB.
187
        // When core redirects, it adds a 'redir_fb_page_id' var in the querystring
188
        // Here, we test if this var exist, and then send the user back to the game in FB.
189
        // Now the cookie will be accepted by Safari...
190
        $pageId = $this->params()->fromQuery('redir_fb_page_id');
191
        if (!empty($pageId)) {
192
            $appId = 'app_'.$this->game->getFbAppId();
193
            $url = '//www.facebook.com/pages/game/'.$pageId.'?sk='.$appId;
194
195
            return $this->redirect()->toUrl($url);
196
        }
197
198
        // If an entry has already been done during this session, I reset the anonymous_identifier cookie
199
        // so that another person can play the same game (if game conditions are fullfilled)
200
        $session = new Container('anonymous_identifier');
201
        if ($session->offsetExists('anonymous_identifier')) {
202
            $session->offsetUnset('anonymous_identifier');
203
        }
204
        
205
        return $this->forward()->dispatch(
206
            'playgroundgame_'.$this->game->getClassType(),
207
            array(
208
                'controller' => 'playgroundgame_'.$this->game->getClassType(),
209
                'action' => $this->game->firstStep(),
210
                'id' => $this->game->getIdentifier()
211
            )
212
        );
213
    }
214
215
    /**
216
     * Homepage of the game
217
     */
218
    public function indexAction()
219
    {
220
        $isSubscribed = false;
221
222
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
223
        if ($entry) {
224
            $isSubscribed = true;
225
        }
226
227
        $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 232 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...
228
        $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...
229
            'isSubscribed' => $isSubscribed
230
        ));
231
232
        return $viewModel;
233
    }
234
235
    /**
236
      * leaderboardAction
237
      *
238
      * @return ViewModel $viewModel
239
      */
240
    public function leaderboardAction()
241
    {
242
        $filter = $this->getEvent()->getRouteMatch()->getParam('filter');
243
        $p = $this->getEvent()->getRouteMatch()->getParam('p');
244
245
        $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...
246
        $subViewModel = $this->forward()->dispatch(
247
            'playgroundreward',
248
            array('action' => 'leaderboard', 'filter' => $filter, 'p' => $p)
249
        );
250
        
251
        // suite au forward, le template de layout a changé, je dois le rétablir...
252
        $this->layout()->setTemplate($beforeLayout);
253
254
        // give the ability to the game to have its customized look and feel.
255
        $templatePathResolver = $this->getServiceLocator()->get('Zend\View\Resolver\TemplatePathStack');
256
        $l = $templatePathResolver->getPaths();
257
258
        $templatePathResolver->addPath($l[0].'custom/'.$this->game->getIdentifier());
259
260
        return $subViewModel;
261
    }
262
263
    /**
264
     * This action has been designed to be called by other controllers
265
     * It gives the ability to display an information form and persist it in the game entry
266
     *
267
     * @return \Zend\View\Model\ViewModel
268
     */
269
    public function registerAction()
270
    {
271
        $form = $this->getGameService()->createFormFromJson($this->game->getPlayerForm()->getForm(), 'playerForm');
272
273
        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...
274
            // POST Request: Process form
275
            $data = array_merge_recursive(
276
                $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...
277
                $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...
278
            );
279
            
280
            $form->setData($data);
281
282
            if ($form->isValid()) {
283
                // steps of the game
284
                $steps = $this->game->getStepsArray();
285
                // sub steps of the game
286
                $viewSteps = $this->game->getStepsViewsArray();
287
288
                // register position
289
                $key = array_search($this->params('action'), $viewSteps);
290 View Code Duplication
                if (!$key) {
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...
291
                    // register is not a substep of the game so it's a step
292
                    $key = array_search($this->params('action'), $steps);
293
                    $keyStep = true;
294
                } else {
295
                    // register was a substep, i search the index of its parent
296
                    $key = array_search($key, $steps);
297
                    $keyStep = false;
298
                }
299
300
                // play position
301
                $keyplay = array_search('play', $viewSteps);
302
303 View Code Duplication
                if (!$keyplay) {
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...
304
                    // play is not a substep, so it's a step
305
                    $keyplay = array_search('play', $steps);
306
                    $keyplayStep = true;
307
                } else {
308
                    // play is a substep so I search the index of its parent
309
                    $keyplay = array_search($keyplay, $steps);
310
                    $keyplayStep = false;
311
                }
312
313
                // If register step before play, I don't have no entry yet. I have to create one
314
                // If register after play step, I search for the last entry created by play step.
315
316
                if ($key < $keyplay || ($keyStep && !$keyplayStep && $key <= $keyplay)) {
317
                    $entry = $this->getGameService()->play($this->game, $this->user);
318
                    if (!$entry) {
319
                        // the user has already taken part of this game and the participation limit has been reached
320
                        $this->flashMessenger()->addMessage('Vous avez déjà participé');
321
                    
322
                        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...
323
                            $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...
324
                                $this->game->getClassType().'/result',
325
                                array(
326
                                    'id' => $this->game->getIdentifier(),
327
                                    
328
                                )
329
                            )
330
                        );
331
                    }
332
                } else {
333
                    // I'm looking for an entry without anonymousIdentifier (the active entry in fact).
334
                    $entry = $this->getGameService()->findLastEntry($this->game, $this->user);
335
                    if ($this->getGameService()->hasReachedPlayLimit($this->game, $this->user)) {
336
                        // the user has already taken part of this game and the participation limit has been reached
337
                        $this->flashMessenger()->addMessage('Vous avez déjà participé');
338
                    
339
                        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...
340
                            $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...
341
                                $this->game->getClassType().'/result',
342
                                array(
343
                                    'id' => $this->game->getIdentifier(),
344
                                    
345
                                )
346
                            )
347
                        );
348
                    }
349
                }
350
351
                $this->getGameService()->updateEntryPlayerForm($form->getData(), $this->game, $this->user, $entry);
352
353
                if (!empty($this->game->nextStep($this->params('action')))) {
354
                    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...
355
                        $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...
356
                            $this->game->getClassType() .'/' . $this->game->nextStep($this->params('action')),
357
                            array('id' => $this->game->getIdentifier()),
358
                            array('force_canonical' => true)
359
                        )
360
                    );
361
                }
362
            }
363
        }
364
365
        $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 370 which is incompatible with the return type documented by PlaygroundGame\Controlle...troller::registerAction of type Zend\View\Model\ViewModel.
Loading history...
366
        $viewModel->setVariables(array(
0 ignored issues
show
Bug introduced by
The method setVariables does only exist in Zend\View\Model\ViewModel, but not in Zend\Http\PhpEnvironment\Response.

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

Let’s take a look at an example:

class A
{
    public function foo() { }
}

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

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

Available Fixes

  1. Add an additional type-check:

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

    function someFunction(B $x) { /** ... */ }
    
Loading history...
367
            'form' => $form
368
        ));
369
370
        return $viewModel;
371
    }
372
373
    /**
374
     * This action takes care of the terms of the game
375
     */
376
    public function termsAction()
377
    {
378
        $viewModel = $this->buildView($this->game);
379
380
        return $viewModel;
381
    }
382
383
    /**
384
     * This action takes care of the conditions of the game
385
     */
386
    public function conditionsAction()
387
    {
388
        $viewModel = $this->buildView($this->game);
389
390
        return $viewModel;
391
    }
392
393
    /**
394
     * This action takes care of bounce page of the game
395
     */
396
    public function bounceAction()
397
    {
398
        $availableGames = $this->getGameService()->getAvailableGames($this->user);
399
400
        $rssUrl = '';
401
        $config = $this->getGameService()->getServiceManager()->get('config');
402
        if (isset($config['rss']['url'])) {
403
            $rssUrl = $config['rss']['url'];
404
        }
405
406
        $viewModel = $this->buildView($this->game);
407
        $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...
408
            'rssUrl'         => $rssUrl,
409
            'user'           => $this->user,
410
            'availableGames' => $availableGames,
411
        ));
412
413
        return $viewModel;
414
    }
415
416
417
    /**
418
     * This action displays the Prizes page associated to the game
419
     */
420
    public function prizesAction()
421
    {
422
        if (count($this->game->getPrizes()) == 0) {
423
            return $this->notFoundAction();
424
        }
425
426
        $viewModel = $this->buildView($this->game);
427
428
        return $viewModel;
429
    }
430
431
    /**
432
     * This action displays a specific Prize page among those associated to the game
433
     */
434
    public function prizeAction()
435
    {
436
        $prizeIdentifier = $this->getEvent()->getRouteMatch()->getParam('prize');
437
        $prize = $this->getPrizeService()->getPrizeMapper()->findByIdentifier($prizeIdentifier);
438
        
439
        if (!$prize) {
440
            return $this->notFoundAction();
441
        }
442
443
        $viewModel = $this->buildView($this->game);
444
        $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...
445
446
        return $viewModel;
447
    }
448
449
    public function gameslistAction()
450
    {
451
        $layoutViewModel = $this->layout();
452
453
        $slider = new ViewModel();
454
        $slider->setTemplate('playground-game/common/top_promo');
455
456
        $sliderItems = $this->getGameService()->getActiveSliderGames();
457
458
        $slider->setVariables(array('sliderItems' => $sliderItems));
459
460
        $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...
461
462
        $games = $this->getGameService()->getActiveGames(false, '', 'endDate');
463
        if (is_array($games)) {
464
            $paginator = new \Zend\Paginator\Paginator(new \Zend\Paginator\Adapter\ArrayAdapter($games));
465
        } else {
466
            $paginator = $games;
467
        }
468
469
        $paginator->setItemCountPerPage(7);
470
        $paginator->setCurrentPageNumber($this->getEvent()->getRouteMatch()->getParam('p'));
471
472
        $bitlyclient = $this->getOptions()->getBitlyUrl();
473
        $bitlyuser = $this->getOptions()->getBitlyUsername();
474
        $bitlykey = $this->getOptions()->getBitlyApiKey();
475
476
        $this->getViewHelper('HeadMeta')->setProperty('bt:client', $bitlyclient);
477
        $this->getViewHelper('HeadMeta')->setProperty('bt:user', $bitlyuser);
478
        $this->getViewHelper('HeadMeta')->setProperty('bt:key', $bitlykey);
479
480
        $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...
481
            array(
482
            'sliderItems'   => $sliderItems,
483
            'currentPage' => array(
484
                'pageGames' => 'games',
485
                'pageWinners' => ''
486
            ),
487
            )
488
        );
489
490
        return new ViewModel(
491
            array(
492
                'games' => $paginator
493
            )
494
        );
495
    }
496
497
    public function fangateAction()
498
    {
499
        $viewModel = $this->buildView($this->game);
500
501
        return $viewModel;
502
    }
503
    
504
    public function shareAction()
505
    {
506
        $statusMail = null;
507
        $lastEntry = null;
508
    
509
        // steps of the game
510
        $steps = $this->game->getStepsArray();
511
        // sub steps of the game
512
        $viewSteps = $this->game->getStepsViewsArray();
513
514
        // share position
515
        $key = array_search($this->params('action'), $viewSteps);
516 View Code Duplication
        if (!$key) {
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...
517
            // share is not a substep of the game so it's a step
518
            $key = array_search($this->params('action'), $steps);
519
            $keyStep = true;
0 ignored issues
show
Unused Code introduced by
$keyStep is not used, you could remove the assignment.

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

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

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

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

Loading history...
520
        } else {
521
            // share was a substep, I search the index of its parent
522
            $key = array_search($key, $steps);
523
            $keyStep = false;
0 ignored issues
show
Unused Code introduced by
$keyStep is not used, you could remove the assignment.

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

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

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

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

Loading history...
524
        }
525
526
        // play position
527
        $keyplay = array_search('play', $viewSteps);
528
529 View Code Duplication
        if (!$keyplay) {
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...
530
            // play is not a substep, so it's a step
531
            $keyplay = array_search('play', $steps);
532
            $keyplayStep = true;
0 ignored issues
show
Unused Code introduced by
$keyplayStep is not used, you could remove the assignment.

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

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

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

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

Loading history...
533
        } else {
534
            // play is a substep so I search the index of its parent
535
            $keyplay = array_search($keyplay, $steps);
536
            $keyplayStep = false;
0 ignored issues
show
Unused Code introduced by
$keyplayStep is not used, you could remove the assignment.

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

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

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

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

Loading history...
537
        }
538
539
        if ($key && $keyplay && $keyplay <= $key) {
540
            // Has the user finished the game ?
541
            $lastEntry = $this->getGameService()->findLastInactiveEntry($this->game, $this->user);
542
    
543 View Code Duplication
            if ($lastEntry === null) {
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...
544
                return $this->redirect()->toUrl(
545
                    $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...
546
                        $this->game->getClassType(),
547
                        array('id' => $this->game->getIdentifier())
548
                    )
549
                );
550
            }
551
        }
552
    
553
        $form = $this->getServiceLocator()->get('playgroundgame_sharemail_form');
554
        $form->setAttribute('method', 'post');
555
556
        // buildView must be before sendMail because it adds the game template path to the templateStack
557
        $viewModel = $this->buildView($this->game);
558
    
559 View Code Duplication
        if ($this->getRequest()->isPost()) {
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...
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...
560
            $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...
561
            $form->setData($data);
562
            if ($form->isValid()) {
563
                $result = $this->getGameService()->sendShareMail($data, $this->game, $this->user, $lastEntry);
564
                if ($result) {
565
                    $statusMail = true;
566
                }
567
            }
568
        }
569
570
        $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...
571
            'statusMail'       => $statusMail,
572
            'form'             => $form,
573
        ));
574
    
575
        return $viewModel;
576
    }
577
    
578
    public function inviteToTeamAction()
579
    {
580
        $statusMail = null;
581
        $message = '';
582
    
583
        $form = $this->getServiceLocator()->get('playgroundgame_sharemail_form');
584
        $form->setAttribute('method', 'post');
585
586
        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...
587
            $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...
588
            $form->setData($data);
589
            if ($form->isValid()) {
590
                $result = $this->getGameService()->inviteToTeam($data, $this->game, $this->user);
591
                if ($result['result']) {
592
                    $statusMail = true;
593
                } else {
594
                    $statusMail = false;
595
                    $message = $result['message'];
596
                }
597
            }
598
        }
599
600
        $viewModel = $this->buildView($this->game);
601
        $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...
602
            'message' => $message,
603
            'statusMail' => $statusMail,
604
            'form' => $form,
605
        ));
606
    
607
        return $viewModel;
608
    }
609
610 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...
611
    {
612
        $viewModel = new JsonModel();
613
        $viewModel->setTerminal(true);
614
        $fbId = $this->params()->fromQuery('fbId');
615
        if (!$this->game) {
616
            return $this->errorJson();
617
        }
618
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
619
        if (! $entry) {
620
            return $this->errorJson();
621
        }
622
        if (!$fbId) {
623
            return $this->errorJson();
624
        }
625
    
626
        $this->getGameService()->postFbWall($fbId, $this->game, $this->user, $entry);
627
    
628
        return $this->successJson();
629
    }
630
    
631
    public function fbrequestAction()
632
    {
633
        $viewModel = new ViewModel();
634
        $viewModel->setTerminal(true);
635
        $fbId = $this->params()->fromQuery('fbId');
636
        $to = $this->params()->fromQuery('to');
637
    
638
        if (!$this->game) {
639
            return $this->errorJson();
640
        }
641
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
642
        if (! $entry) {
643
            return $this->errorJson();
644
        }
645
        if (!$fbId) {
646
            return $this->errorJson();
647
        }
648
    
649
        $this->getGameService()->postFbRequest($fbId, $this->game, $this->user, $entry, $to);
650
    
651
        return $this->successJson();
652
    }
653
    
654
    public function tweetAction()
655
    {
656
        $tweetId = $this->params()->fromQuery('tweetId');
657
    
658
        if (!$this->game) {
659
            return $this->errorJson();
660
        }
661
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
662
        if (! $entry) {
663
            return $this->errorJson();
664
        }
665
        if (!$tweetId) {
666
            return $this->errorJson();
667
        }
668
    
669
        $this->getGameService()->postTwitter($tweetId, $this->game, $this->user, $entry);
670
    
671
        return $this->successJson();
672
    }
673
    
674 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...
675
    {
676
        $viewModel = new ViewModel();
677
        $viewModel->setTerminal(true);
678
        $googleId = $this->params()->fromQuery('googleId');
679
680
        if (!$this->game) {
681
            return $this->errorJson();
682
        }
683
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
684
        if (! $entry) {
685
            return $this->errorJson();
686
        }
687
        if (!$googleId) {
688
            return $this->errorJson();
689
        }
690
    
691
        $this->getGameService()->postGoogle($googleId, $this->game, $this->user, $entry);
692
    
693
        return $this->successJson();
694
    }
695
696
    public function optinAction()
697
    {
698
        $userService = $this->getServiceLocator()->get('zfcuser_user_service');
699
700
        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...
701
            $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...
702
            $data['optinPartner'] = ($this->params()->fromPost('optinPartner'))? 1:0;
703
704
            $userService->updateNewsletter($data);
705
        }
706
707
        return $this->redirect()->toUrl(
708
            $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
709
                'frontend/' . $this->game->getClassType() . '/index',
710
                array('id' => $this->game->getIdentifier())
711
            )
712
        );
713
    }
714
    
715
    public function loginAction()
716
    {
717
        $request = $this->getRequest();
718
        $form = $this->getServiceLocator()->get('zfcuser_login_form');
719
    
720
        if ($request->isPost()) {
721
            $form->setData($request->getPost());
722
            
723
            if (!$form->isValid()) {
724
                $this->flashMessenger()->addMessage(
725
                    'Authentication failed. Please try again.'
726
                );
727
728
                $viewModel = $this->buildView($this->game);
729
                $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...
730
                    'form' => $form,
731
                    'flashMessages' => $this->flashMessenger()->getMessages(),
732
                ));
733
                
734
                return $viewModel;
735
            }
736
            
737
            // clear adapters
738
            $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...
739
            $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...
740
741
            $logged = $this->forward()->dispatch('playgrounduser_user', array('action' => 'ajaxauthenticate'));
742
743
            if (!$logged) {
744
                $this->flashMessenger()->addMessage(
745
                    'Authentication failed. Please try again.'
746
                );
747
                
748
                return $this->redirect()->toUrl(
749
                    $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...
750
                        $this->game->getClassType() . '/login',
751
                        array('id' => $this->game->getIdentifier())
752
                    )
753
                );
754
            } else {
755
                return $this->redirect()->toUrl(
756
                    $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...
757
                        $this->game->getClassType() . '/index',
758
                        array('id' => $this->game->getIdentifier())
759
                    )
760
                );
761
            }
762
        }
763
        
764
        $form->setAttribute(
765
            'action',
766
            $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...
767
                $this->game->getClassType().'/login',
768
                array('id' => $this->game->getIdentifier())
769
            )
770
        );
771
        $viewModel = $this->buildView($this->game);
772
        $viewModel->setVariables(array(
773
            'form' => $form,
774
            'flashMessages' => $this->flashMessenger()->getMessages(),
775
        ));
776
        return $viewModel;
777
    }
778
779 View Code Duplication
    public function logoutAction()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
780
    {
781
        $viewModel = $this->forward()->dispatch(
782
            'playgrounduser_user',
783
            array(
784
                'controller' => 'playgrounduser_user',
785
                'action' => 'logout',
786
                'id' => $this->game->getIdentifier()
787
            )
788
        );
789
790
        if ($viewModel && $viewModel instanceof \Zend\View\Model\ViewModel) {
791
            $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...
792
            $viewModel->setVariables(array('game' => $this->game));
793
        }
794
795
        return $viewModel;
796
    }
797
798
    public function userregisterAction()
799
    {
800
        $userOptions = $this->getServiceLocator()->get('zfcuser_module_options');
801
802
        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...
803
            return $this->redirect()->toUrl(
804
                $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...
805
                    $this->game->getClassType().'/'.$this->game->nextStep('index'),
806
                    array('id' => $this->game->getIdentifier())
807
                )
808
            );
809
        }
810
        $request = $this->getRequest();
811
        $service = $this->getServiceLocator()->get('zfcuser_user_service');
812
        $form = $this->getServiceLocator()->get('playgroundgame_register_form');
813
        $socialnetwork = $this->params()->fromRoute('socialnetwork', false);
814
        $form->setAttribute(
815
            'action',
816
            $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...
817
                $this->game->getClassType().'/user-register',
818
                array('id' => $this->game->getIdentifier())
819
            )
820
        );
821
        $params = array();
822
        $socialCredentials = array();
823
824
        if ($userOptions->getUseRedirectParameterIfPresent() && $request->getQuery()->get('redirect')) {
825
            $redirect = $request->getQuery()->get('redirect');
826
        } else {
827
            $redirect = false;
828
        }
829
830
        if ($socialnetwork) {
831
            $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...
832
833
            if (!empty($infoMe)) {
834
                $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...
835
                    $infoMe->identifier,
836
                    $socialnetwork
837
                );
838
839
                if ($user || $service->getOptions()->getCreateUserAutoSocial() === true) {
840
                    //on le dirige vers l'action d'authentification
841
                    if (! $redirect && $userOptions->getLoginRedirectRoute() != '') {
842
                        $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...
843
                            $this->game->getClassType().'/login',
844
                            array('id' => $this->game->getIdentifier())
845
                        );
846
                    }
847
                    $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...
848
                        $this->game->getClassType().'/login',
849
                        array('id' => $this->game->getIdentifier())
850
                    ) .'/' . $socialnetwork . ($redirect ? '?redirect=' . $redirect : '');
851
852
                    return $this->redirect()->toUrl($redir);
853
                }
854
855
                // Je retire la saisie du login/mdp
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(
861
                            'id' => $this->game->getIdentifier(),
862
                            'socialnetwork' => $socialnetwork,
863
                            
864
                        )
865
                    )
866
                );
867
                $form->remove('password');
868
                $form->remove('passwordVerify');
869
870
                $birthMonth = $infoMe->birthMonth;
871
                if (strlen($birthMonth) <= 1) {
872
                    $birthMonth = '0'.$birthMonth;
873
                }
874
                $birthDay = $infoMe->birthDay;
875
                if (strlen($birthDay) <= 1) {
876
                    $birthDay = '0'.$birthDay;
877
                }
878
879
                $gender = $infoMe->gender;
880
                if ($gender == 'female') {
881
                    $title = 'Me';
882
                } else {
883
                    $title = 'M';
884
                }
885
886
                $params = array(
887
                    //'birth_year'  => $infoMe->birthYear,
888
                    'title'      => $title,
889
                    'dob'      => $birthDay.'/'.$birthMonth.'/'.$infoMe->birthYear,
890
                    'firstname'   => $infoMe->firstName,
891
                    'lastname'    => $infoMe->lastName,
892
                    'email'       => $infoMe->email,
893
                    'postalCode' => $infoMe->zip,
894
                );
895
                $socialCredentials = array(
896
                    'socialNetwork' => strtolower($socialnetwork),
897
                    'socialId'      => $infoMe->identifier,
898
                );
899
            }
900
        }
901
902
        $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...
903
            $this->game->getClassType().'/user-register',
904
            array('id' => $this->game->getIdentifier())
905
        ) .($socialnetwork ? '/' . $socialnetwork : ''). ($redirect ? '?redirect=' . $redirect : '');
906
        $prg = $this->prg($redirectUrl, true);
907
908
        if ($prg instanceof Response) {
909
            return $prg;
910
        } elseif ($prg === false) {
911
            $form->setData($params);
912
            $viewModel = $this->buildView($this->game);
913
            $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...
914
                'registerForm' => $form,
915
                'enableRegistration' => $userOptions->getEnableRegistration(),
916
                'redirect' => $redirect,
917
            ));
918
            return $viewModel;
919
        }
920
921
        $post = $prg;
922
        $post = array_merge(
923
            $post,
924
            $socialCredentials
925
        );
926
927
        if ($this->game->getOnInvitation()) {
928
            $credential = trim(
929
                $post[$this->getGameService()->getOptions()->getOnInvitationField()]
930
            );
931
            if (!$credential) {
932
                $credential = $this->params()->fromQuery(
933
                    $this->getGameService()->getOptions()->getOnInvitationField()
934
                );
935
            }
936
            $found = $this->getGameService()->getInvitationMapper()->findOneBy(array('requestKey'=>$credential));
937
938
            if (!$found || !empty($found->getUser())) {
939
                $this->flashMessenger()->addMessage(
940
                    'Authentication failed. Please try again.'
941
                );
942
                $form->setData($post);
943
                $viewModel = $this->buildView($this->game);
944
                $viewModel->setVariables(array(
945
                    'registerForm' => $form,
946
                    'enableRegistration' => $userOptions->getEnableRegistration(),
947
                    'redirect' => $redirect,
948
                    'flashMessages'    => $this->flashMessenger()->getMessages(),
949
                    'flashErrors'      => $this->flashMessenger()->getErrorMessages(),
950
                ));
951
952
                return $viewModel;
953
            }
954
        }
955
956
        $user = $service->register($post, 'playgroundgame_register_form');
957
958
        if (! $user) {
959
            $viewModel = $this->buildView($this->game);
960
            $viewModel->setVariables(array(
961
                'registerForm' => $form,
962
                'enableRegistration' => $userOptions->getEnableRegistration(),
963
                'redirect' => $redirect,
964
                'flashMessages'    => $this->flashMessenger()->getMessages(),
965
                'flashErrors'      => $this->flashMessenger()->getErrorMessages(),
966
            ));
967
            
968
            return $viewModel;
969
        }
970
971
        if ($this->game->getOnInvitation()) {
972
            // user has been created, associate the code with the userId
973
            $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...
974
            $this->getGameService()->getInvitationMapper()->update($found);
975
        }
976
977
        if ($service->getOptions()->getEmailVerification()) {
978
            $vm = new ViewModel(array('userEmail' => $user->getEmail()));
979
            $vm->setTemplate('playground-user/register/registermail');
980
981
            return $vm;
982
        } elseif ($service->getOptions()->getLoginAfterRegistration()) {
983
            $identityFields = $service->getOptions()->getAuthIdentityFields();
984
            if (in_array('email', $identityFields)) {
985
                $post['identity'] = $user->getEmail();
986
            } elseif (in_array('username', $identityFields)) {
987
                $post['identity'] = $user->getUsername();
988
            }
989
            $post['credential'] = isset($post['password'])?$post['password']:'';
990
            $request->setPost(new Parameters($post));
991
992
            // clear adapters
993
            $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...
994
            $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...
995
996
            $logged = $this->forward()->dispatch('playgrounduser_user', array('action' => 'ajaxauthenticate'));
997
998
            if ($logged) {
999
                return $this->redirect()->toUrl(
1000
                    $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...
1001
                        $this->game->getClassType(),
1002
                        array('id' => $this->game->getIdentifier())
1003
                    )
1004
                );
1005
            } else {
1006
                $this->flashMessenger()->setNamespace('zfcuser-login-form')->addMessage(
1007
                    'Authentication failed. Please try again.'
1008
                );
1009
                return $this->redirect()->toUrl(
1010
                    $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
1011
                        $this->game->getClassType() . '/login',
1012
                        array('id' => $this->game->getIdentifier())
1013
                    )
1014
                );
1015
            }
1016
        }
1017
1018
        $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...
1019
            $this->game->getClassType().'/login',
1020
            array('id' => $this->game->getIdentifier())
1021
        ) . ($socialnetwork ? '/' . $socialnetwork : ''). ($redirect ? '?redirect=' . $redirect : '');
1022
1023
        return $this->redirect()->toUrl($redirect);
1024
    }
1025
1026 View Code Duplication
    public function userProfileAction()
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...
1027
    {
1028
        $viewModel = $this->forward()->dispatch(
1029
            'playgrounduser_user',
1030
            array(
1031
                'controller' => 'playgrounduser_user',
1032
                'action' => 'profile',
1033
                'id' => $this->game->getIdentifier()
1034
            )
1035
        );
1036
1037
        if ($viewModel && $viewModel instanceof \Zend\View\Model\ViewModel) {
1038
            $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...
1039
            $viewModel->setVariables(array('game' => $this->game));
1040
        }
1041
1042
        return $viewModel;
1043
    }
1044
1045
    public function userresetAction()
1046
    {
1047
        $viewModel = $this->forward()->dispatch(
1048
            'playgrounduser_forgot',
1049
            array(
1050
                'controller' => 'playgrounduser_forgot',
1051
                'action' => 'reset',
1052
                'id' => $this->game->getIdentifier(),
1053
                'userId' => $this->params()->fromRoute('userId', null),
1054
                'token' => $this->params()->fromRoute('token', null),
1055
            )
1056
        );
1057
1058
        if ($viewModel && $viewModel instanceof \Zend\View\Model\ViewModel) {
1059
            $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...
1060
            $viewModel->setVariables(array('game' => $this->game));
1061
        }
1062
1063
        return $viewModel;
1064
    }
1065
1066 View Code Duplication
    public function ajaxforgotAction()
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...
1067
    {
1068
        $view = $this->forward()->dispatch(
1069
            'playgrounduser_forgot',
1070
            array(
1071
                'controller' => 'playgrounduser_forgot',
1072
                'action' => 'ajaxforgot',
1073
                'id' => $this->game->getIdentifier()
1074
            )
1075
        );
1076
1077
        if ($view && $view instanceof \Zend\View\Model\ViewModel) {
1078
            $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...
1079
            $view->setVariables(array('game' => $this->game));
1080
        }
1081
1082
        return $view;
1083
    }
1084
1085 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...
1086
    {
1087
        $viewModel = $this->forward()->dispatch(
1088
            'playgroundcms',
1089
            array(
1090
                'controller' => 'playgroundcms',
1091
                'action' => 'index',
1092
                'id' => $this->game->getIdentifier(),
1093
                'pid' => $this->getEvent()->getRouteMatch()->getParam('pid')
1094
            )
1095
        );
1096
1097
        if ($viewModel && $viewModel instanceof \Zend\View\Model\ViewModel) {
1098
            $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...
1099
            $viewModel->setVariables(array('game' => $this->game));
1100
        }
1101
1102
        return $viewModel;
1103
    }
1104
1105 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...
1106
    {
1107
        $viewModel = $this->forward()->dispatch(
1108
            'playgroundcms',
1109
            array(
1110
                'controller' => 'playgroundcms',
1111
                'action' => 'list',
1112
                'id' => $this->game->getIdentifier(),
1113
                'category' => $this->game->getIdentifier()
1114
            )
1115
        );
1116
1117
        if ($viewModel && $viewModel instanceof \Zend\View\Model\ViewModel) {
1118
            $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...
1119
            $viewModel->setVariables(array('game' => $this->game));
1120
        }
1121
1122
        return $viewModel;
1123
    }
1124
1125
    /**
1126
     *
1127
     * @param \PlaygroundGame\Entity\Game $game
1128
     * @param \PlaygroundUser\Entity\User $user
1129
     */
1130
    public function checkFbRegistration($user, $game)
1131
    {
1132
        $redirect = false;
1133
        $session = new Container('facebook');
1134
        if ($session->offsetExists('signed_request')) {
1135
            if (!$user) {
1136
                // Get Playground user from Facebook info
1137
                $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...
1138
                $view = $this->forward()->dispatch(
1139
                    'playgrounduser_user',
1140
                    array(
1141
                        'controller' => 'playgrounduser_user',
1142
                        'action' => 'registerFacebookUser',
1143
                        'provider' => 'facebook'
1144
                    )
1145
                );
1146
1147
                $this->layout()->setTemplate($beforeLayout);
1148
                $user = $view->user;
1149
1150
                // If the user can not be created/retrieved from Facebook info, redirect to login/register form
1151
                if (!$user) {
1152
                    $redirectUrl = urlencode(
1153
                        $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...
1154
                            $game->getClassType() .'/play',
1155
                            array('id' => $game->getIdentifier()),
1156
                            array('force_canonical' => true)
1157
                        )
1158
                    );
1159
                    $redirect =  $this->redirect()->toUrl(
1160
                        $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...
1161
                            'zfcuser/register'
1162
                        ) . '?redirect='.$redirectUrl
1163
                    );
1164
                }
1165
            }
1166
1167
            if ($game->getFbFan()) {
1168
                if ($this->getGameService()->checkIsFan($game) === false) {
1169
                    $redirect =  $this->redirect()->toRoute(
1170
                        $game->getClassType().'/fangate',
1171
                        array('id' => $game->getIdentifier())
1172
                    );
1173
                }
1174
            }
1175
        }
1176
1177
        return $redirect;
1178
    }
1179
1180
    /**
1181
     * This method create the basic Game view
1182
     * @param \PlaygroundGame\Entity\Game $game
1183
     */
1184
    public function buildView($game)
1185
    {
1186
        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...
1187
            $viewModel = new JsonModel();
1188
            if ($game) {
1189
                $view = $this->addAdditionalView($game);
1190
                if ($view && $view instanceof \Zend\View\Model\ViewModel) {
1191
                    $viewModel->setVariables($view->getVariables());
1192
                }
1193
            }
1194
        } else {
1195
            $viewModel = new ViewModel();
1196
1197
            if ($game) {
1198
                $this->addMetaTitle($game);
1199
                $this->addMetaBitly();
1200
                $this->addGaEvent($game);
1201
1202
                $this->customizeGameDesign($game);
1203
                
1204
                $view = $this->addAdditionalView($game);
1205
                if ($view && $view instanceof \Zend\View\Model\ViewModel) {
1206
                    $viewModel->addChild($view, 'additional');
1207
                } elseif ($view && $view instanceof \Zend\Http\PhpEnvironment\Response) {
1208
                    return $view;
1209
                }
1210
1211
                $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...
1212
                    array(
1213
                        'action' => $this->params('action'),
1214
                        'game' => $game,
1215
                        'flashMessages'    => $this->flashMessenger()->getMessages(),
1216
                        
1217
                    )
1218
                );
1219
            }
1220
        }
1221
        
1222
        if ($game) {
1223
            $viewModel->setVariables($this->getShareData($game));
1224
            $viewModel->setVariables(array('game' => $game, 'user' => $this->user));
1225
        }
1226
1227
        return $viewModel;
1228
    }
1229
1230
    /**
1231
     * @param \PlaygroundGame\Entity\Game $game
1232
     */
1233
    public function addAdditionalView($game)
1234
    {
1235
        $view = false;
1236
1237
        $actionName = $this->getEvent()->getRouteMatch()->getParam('action', 'not-found');
1238
        $stepsViews = json_decode($game->getStepsViews(), true);
1239
        if ($stepsViews && isset($stepsViews[$actionName])) {
1240
            $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...
1241
            $actionData = $stepsViews[$actionName];
1242
            if (is_string($actionData)) {
1243
                $action = $actionData;
1244
                $controller = $this->getEvent()->getRouteMatch()->getParam('controller', 'playgroundgame_game');
1245
                $view = $this->forward()->dispatch(
1246
                    $controller,
1247
                    array(
1248
                        'action' => $action,
1249
                        'id' => $game->getIdentifier()
1250
                    )
1251
                );
1252
            } elseif (is_array($actionData) && count($actionData)>0) {
1253
                $action = key($actionData);
1254
                $controller = $actionData[$action];
1255
                $view = $this->forward()->dispatch(
1256
                    $controller,
1257
                    array(
1258
                        'action' => $action,
1259
                        'id' => $game->getIdentifier()
1260
                    )
1261
                );
1262
            }
1263
            // suite au forward, le template de layout a changé, je dois le rétablir...
1264
            $this->layout()->setTemplate($beforeLayout);
1265
        }
1266
1267
        return $view;
1268
    }
1269
1270
    public function addMetaBitly()
1271
    {
1272
        $bitlyclient = $this->getOptions()->getBitlyUrl();
1273
        $bitlyuser = $this->getOptions()->getBitlyUsername();
1274
        $bitlykey = $this->getOptions()->getBitlyApiKey();
1275
1276
        $this->getViewHelper('HeadMeta')->setProperty('bt:client', $bitlyclient);
1277
        $this->getViewHelper('HeadMeta')->setProperty('bt:user', $bitlyuser);
1278
        $this->getViewHelper('HeadMeta')->setProperty('bt:key', $bitlykey);
1279
    }
1280
1281
    /**
1282
     * @param \PlaygroundGame\Entity\Game $game
1283
     */
1284
    public function addGaEvent($game)
1285
    {
1286
        // Google Analytics event
1287
        $ga = $this->getServiceLocator()->get('google-analytics');
1288
        $event = new \PlaygroundCore\Analytics\Event($game->getClassType(), $this->params('action'));
1289
        $event->setLabel($game->getTitle());
1290
        $ga->addEvent($event);
1291
    }
1292
1293
    /**
1294
     * @param \PlaygroundGame\Entity\Game $game
1295
     */
1296
    public function addMetaTitle($game)
1297
    {
1298
        $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...
1299
        $this->getGameService()->getServiceManager()->get('ViewHelperManager')->get('HeadTitle')->set($title);
1300
        // Meta set in the layout
1301
        $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...
1302
            array(
1303
                'breadcrumbTitle' => $title,
1304
                'currentPage' => array(
1305
                    'pageGames' => 'games',
1306
                    'pageWinners' => ''
1307
                ),
1308
                'headParams' => array(
1309
                    'headTitle' => $title,
1310
                    'headDescription' => $title,
1311
                ),
1312
                'bodyCss' => $game->getIdentifier()
1313
            )
1314
        );
1315
    }
1316
1317
    /**
1318
     * @param \PlaygroundGame\Entity\Game $game
1319
     */
1320
    public function customizeGameDesign($game)
1321
    {
1322
        // If this game has a specific layout...
1323
        if ($game->getLayout()) {
1324
            $layoutViewModel = $this->layout();
1325
            $layoutViewModel->setTemplate($game->getLayout());
1326
        }
1327
1328
        // If this game has a specific stylesheet...
1329
        if ($game->getStylesheet()) {
1330
            $this->getViewHelper('HeadLink')->appendStylesheet(
1331
                $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...
1332
            );
1333
        }
1334
    }
1335
1336
    /**
1337
     * @param \PlaygroundGame\Entity\Game $game
1338
     */
1339
    public function getShareData($game)
1340
    {
1341
        $fo = $this->getServiceLocator()->get('facebook-opengraph');
1342
        $session = new Container('facebook');
1343
1344
        // I change the fbappid if i'm in fb
1345
        if ($session->offsetExists('signed_request')) {
1346
            $fo->setId($game->getFbAppId());
1347
        }
1348
1349
        // If I want to add a share block in my view
1350 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...
1351
            $fbShareMessage = $game->getFbShareMessage();
1352
        } else {
1353
            $fbShareMessage = str_replace(
1354
                '__placeholder__',
1355
                $game->getTitle(),
1356
                $this->getOptions()->getDefaultShareMessage()
1357
            );
1358
        }
1359
1360
        if ($game->getFbShareImage()) {
1361
            $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...
1362
                '',
1363
                array(),
1364
                array('force_canonical' => true),
1365
                false
1366
            ) . $game->getFbShareImage();
1367
        } else {
1368
            $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...
1369
                '',
1370
                array(),
1371
                array('force_canonical' => true),
1372
                false
1373
            ) . $game->getMainImage();
1374
        }
1375
1376
        $secretKey = strtoupper(substr(sha1(uniqid('pg_', true).'####'.time()), 0, 15));
1377
1378
        // Without bit.ly shortener
1379
        $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...
1380
            $game->getClassType(),
1381
            array('id' => $game->getIdentifier()),
1382
            array('force_canonical' => true)
1383
        );
1384
        // With core shortener helper
1385
        $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...
1386
1387
        // FB Requests only work when it's a FB app
1388
        if ($game->getFbRequestMessage()) {
1389
            $fbRequestMessage = urlencode($game->getFbRequestMessage());
1390
        } else {
1391
            $fbRequestMessage = str_replace(
1392
                '__placeholder__',
1393
                $game->getTitle(),
1394
                $this->getOptions()->getDefaultShareMessage()
1395
            );
1396
        }
1397
1398 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...
1399
            $twShareMessage = $game->getTwShareMessage() . $socialLinkUrl;
1400
        } else {
1401
            $twShareMessage = str_replace(
1402
                '__placeholder__',
1403
                $game->getTitle(),
1404
                $this->getOptions()->getDefaultShareMessage()
1405
            ) . $socialLinkUrl;
1406
        }
1407
1408
        $ogTitle = new \PlaygroundCore\Opengraph\Tag('og:title', $fbShareMessage);
1409
        $ogImage = new \PlaygroundCore\Opengraph\Tag('og:image', $fbShareImage);
1410
        
1411
        $fo->addTag($ogTitle);
1412
        $fo->addTag($ogImage);
1413
        
1414
        $data = array(
1415
            'socialLinkUrl'       => $socialLinkUrl,
1416
            'secretKey'           => $secretKey,
1417
            'fbShareMessage'      => $fbShareMessage,
1418
            'fbShareImage'        => $fbShareImage,
1419
            'fbRequestMessage'    => $fbRequestMessage,
1420
            'twShareMessage'      => $twShareMessage,
1421
        );
1422
1423
        return $data;
1424
    }
1425
    
1426
    /**
1427
     * return ajax response in json format
1428
     *
1429
     * @param array $data
1430
     * @return \Zend\View\Model\JsonModel
1431
     */
1432 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...
1433
    {
1434
        $model = new JsonModel(array(
1435
            'success' => true,
1436
            'data' => $data
1437
        ));
1438
        return $model->setTerminal(true);
1439
    }
1440
    
1441
    /**
1442
     * return ajax response in json format
1443
     *
1444
     * @param string $message
1445
     * @return \Zend\View\Model\JsonModel
1446
     */
1447 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...
1448
    {
1449
        $model = new JsonModel(array(
1450
            'success' => false,
1451
            'message' => $message
1452
        ));
1453
        return $model->setTerminal(true);
1454
    }
1455
1456
    /**
1457
     * @param string $helperName
1458
     */
1459
    protected function getViewHelper($helperName)
1460
    {
1461
        return $this->getServiceLocator()->get('viewhelpermanager')->get($helperName);
1462
    }
1463
1464
    public function getGameService()
1465
    {
1466
        if (!$this->gameService) {
1467
            $this->gameService = $this->getServiceLocator()->get('playgroundgame_lottery_service');
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->getServiceLocator...dgame_lottery_service') can also be of type array. However, the property $gameService is declared as type object<PlaygroundGame\Service\GameService>. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

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

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
1468
        }
1469
1470
        return $this->gameService;
1471
    }
1472
1473
    public function setGameService(GameService $gameService)
1474
    {
1475
        $this->gameService = $gameService;
1476
1477
        return $this;
1478
    }
1479
1480
    public function getPrizeService()
1481
    {
1482
        if (!$this->prizeService) {
1483
            $this->prizeService = $this->getServiceLocator()->get('playgroundgame_prize_service');
1484
        }
1485
1486
        return $this->prizeService;
1487
    }
1488
1489
    public function setPrizeService(PrizeService $prizeService)
1490
    {
1491
        $this->prizeService = $prizeService;
1492
1493
        return $this;
1494
    }
1495
1496
    public function getOptions()
1497
    {
1498
        if (!$this->options) {
1499
            $this->setOptions($this->getServiceLocator()->get('playgroundcore_module_options'));
1500
        }
1501
1502
        return $this->options;
1503
    }
1504
1505
    public function setOptions($options)
1506
    {
1507
        $this->options = $options;
1508
1509
        return $this;
1510
    }
1511
}
1512