Completed
Pull Request — master (#332)
by greg
02:27
created

GameController   F

Complexity

Total Complexity 184

Size/Duplication

Total Lines 1536
Duplicated Lines 14 %

Coupling/Cohesion

Components 1
Dependencies 17

Importance

Changes 14
Bugs 5 Features 0
Metric Value
wmc 184
c 14
b 5
f 0
lcom 1
cbo 17
dl 215
loc 1536
rs 0.6314

47 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A getServiceLocator() 0 4 1
C setEventManager() 0 80 15
B notFoundAction() 0 37 3
B homeAction() 0 32 3
A indexAction() 0 16 2
B leaderboardAction() 0 25 1
D registerAction() 0 106 13
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() 10 69 10
B inviteToTeamAction() 0 31 4
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() 19 63 4
A logoutAction() 18 18 3
F userregisterAction() 18 227 32
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
B checkFbRegistration() 0 49 6
D buildView() 0 43 10
B addAdditionalView() 0 36 6
A addMetaBitly() 0 10 1
A addGaEvent() 0 8 1
A addMetaTitle() 0 20 1
A customizeGameDesign() 0 15 3
B getShareData() 18 86 6
A successJson() 8 8 1
A errorJson() 8 8 1
A getViewHelper() 0 4 1
A getGameService() 0 8 2
A setGameService() 0 6 1
A getPrizeService() 0 8 2
A setPrizeService() 0 6 1
A getOptions() 0 8 2
A setOptions() 0 6 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

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

Common duplication problems, and corresponding solutions are:

Complex Class

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

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

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

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

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

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

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

Loading history...
81
    }
82
83
    public function getServiceLocator()
84
    {
85
        return $this->serviceLocator;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->serviceLocator; (PlaygroundGame\Controller\Frontend\ServiceManager) is incompatible with the return type of the parent method Zend\Mvc\Controller\Abst...ller::getServiceLocator of type Zend\ServiceManager\ServiceLocatorInterface.

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

Let’s take a look at an example:

class Author {
    private $name;

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

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

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

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

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

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

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

Loading history...
86
    }
87
88
    public function setEventManager(\Zend\EventManager\EventManagerInterface $events)
89
    {
90
        parent::setEventManager($events);
91
92
        $controller = $this;
93
94
        $events->attach('dispatch', function (\Zend\Mvc\MvcEvent $e) use ($controller) {
95
            $identifier = $e->getRouteMatch()->getParam('id');
96
            $controller->game = $controller->getGameService()->checkGame($identifier, false);
97
98
            $config = $this->getServiceLocator()->get('config');
99
            $customUrl = str_replace('frontend.', '', $e->getRouteMatch()->getMatchedRouteName());
100
            $customUrl = explode("/", $customUrl)[0];
101
102
            if (isset($config['custom_games']) && $config['custom_games'][$controller->game->getIdentifier()] &&
103
                    $controller->getRequest()->getUri()->getHost() === $customUrl
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Zend\Stdlib\RequestInterface as the method getUri() does only exist in the following implementations of said interface: Zend\Http\PhpEnvironment\Request, Zend\Http\Request.

Let’s take a look at an example:

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

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

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

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

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

Available Fixes

  1. Change the type-hint for the parameter:

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

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

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

Let’s take a look at an example:

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

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

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

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

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

Available Fixes

  1. Change the type-hint for the parameter:

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

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

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
190
        if ($this->game) {
191
            $uri = str_replace($controllerPath.'/'.$this->game->getIdentifier().'/', '', $uri);
192
        }
193
        $uri      = str_replace("/".$this->getEvent()->getRouteMatch()->getParam('locale')."/", "/", $uri);
194
        $template = 'playground-game/'.$controllerPath.'/custom'.$uri;
195
196
        if (false === $templatePathResolver->resolve($template)) {
197
            $viewRender = $this->getServiceLocator()->get('ViewRenderer');
198
199
            $this->getEvent()->getRouteMatch()->setParam('action', 'not-found');
200
            $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...
201
202
            $res = 'error/404';
203
204
            $viewModel = $this->buildView($this->game);
205
            $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...
206
207
            $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...
208
            $this->response->setContent($viewRender->render($this->layout()));
209
210
            return $this->response;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->response; (Zend\Stdlib\ResponseInterface) is incompatible with the return type of the parent method Zend\Mvc\Controller\Abst...troller::notFoundAction of type Zend\View\Model\ViewMode...View\Model\ConsoleModel.

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

Let’s take a look at an example:

class Author {
    private $name;

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

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

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

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

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

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

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

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

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

Let’s take a look at an example:

class Author {
    private $name;

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

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

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

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

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

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

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

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

Let’s take a look at an example:

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

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

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

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

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

Available Fixes

  1. Change the type-hint for the parameter:

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

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

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
601
            $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...
602
            $form->setData($data);
603
            if ($form->isValid()) {
604
                $result = $this->getGameService()->sendShareMail($data, $this->game, $this->user, $lastEntry);
605
                if ($result) {
606
                    $statusMail = true;
607
                }
608
            }
609
        }
610
611
        $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...
612
                'statusMail' => $statusMail,
613
                'form'       => $form,
614
            ));
615
616
        return $viewModel;
617
    }
618
619
    public function inviteToTeamAction()
620
    {
621
        $statusMail = null;
622
        $message    = '';
623
624
        $form = $this->getServiceLocator()->get('playgroundgame_sharemail_form');
625
        $form->setAttribute('method', 'post');
626
627
        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...
628
            $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...
629
            $form->setData($data);
630
            if ($form->isValid()) {
631
                $result = $this->getGameService()->inviteToTeam($data, $this->game, $this->user);
632
                if ($result['result']) {
633
                    $statusMail = true;
634
                } else {
635
                    $statusMail = false;
636
                    $message    = $result['message'];
637
                }
638
            }
639
        }
640
641
        $viewModel = $this->buildView($this->game);
642
        $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...
643
                'message'    => $message,
644
                'statusMail' => $statusMail,
645
                'form'       => $form,
646
            ));
647
648
        return $viewModel;
649
    }
650
651 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...
652
    {
653
        $viewModel = new JsonModel();
654
        $viewModel->setTerminal(true);
655
        $fbId = $this->params()->fromQuery('fbId');
656
        if (!$this->game) {
657
            return $this->errorJson();
658
        }
659
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
660
        if (!$entry) {
661
            return $this->errorJson();
662
        }
663
        if (!$fbId) {
664
            return $this->errorJson();
665
        }
666
667
        $this->getGameService()->postFbWall($fbId, $this->game, $this->user, $entry);
668
669
        return $this->successJson();
670
    }
671
672
    public function fbrequestAction()
673
    {
674
        $viewModel = new ViewModel();
675
        $viewModel->setTerminal(true);
676
        $fbId = $this->params()->fromQuery('fbId');
677
        $to   = $this->params()->fromQuery('to');
678
679
        if (!$this->game) {
680
            return $this->errorJson();
681
        }
682
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
683
        if (!$entry) {
684
            return $this->errorJson();
685
        }
686
        if (!$fbId) {
687
            return $this->errorJson();
688
        }
689
690
        $this->getGameService()->postFbRequest($fbId, $this->game, $this->user, $entry, $to);
691
692
        return $this->successJson();
693
    }
694
695
    public function tweetAction()
696
    {
697
        $tweetId = $this->params()->fromQuery('tweetId');
698
699
        if (!$this->game) {
700
            return $this->errorJson();
701
        }
702
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
703
        if (!$entry) {
704
            return $this->errorJson();
705
        }
706
        if (!$tweetId) {
707
            return $this->errorJson();
708
        }
709
710
        $this->getGameService()->postTwitter($tweetId, $this->game, $this->user, $entry);
711
712
        return $this->successJson();
713
    }
714
715 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...
716
    {
717
        $viewModel = new ViewModel();
718
        $viewModel->setTerminal(true);
719
        $googleId = $this->params()->fromQuery('googleId');
720
721
        if (!$this->game) {
722
            return $this->errorJson();
723
        }
724
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
725
        if (!$entry) {
726
            return $this->errorJson();
727
        }
728
        if (!$googleId) {
729
            return $this->errorJson();
730
        }
731
732
        $this->getGameService()->postGoogle($googleId, $this->game, $this->user, $entry);
733
734
        return $this->successJson();
735
    }
736
737
    public function optinAction()
738
    {
739
        $userService = $this->getServiceLocator()->get('zfcuser_user_service');
740
741
        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...
742
            $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...
743
            $data['optinPartner'] = ($this->params()->fromPost('optinPartner'))?1:0;
744
745
            $userService->updateNewsletter($data);
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(),
751
                array('id' => $this->game->getIdentifier())
752
            )
753
        );
754
    }
755
756
    public function loginAction()
757
    {
758
        $request = $this->getRequest();
759
        $form    = $this->getServiceLocator()->get('zfcuser_login_form');
760
761
        if ($request->isPost()) {
762
            $form->setData($request->getPost());
763
764
            if (!$form->isValid()) {
765
                $this->flashMessenger()->addMessage(
766
                    'Authentication failed. Please try again.'
767
                );
768
769
                $viewModel = $this->buildView($this->game);
770
                $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...
771
                        'form'          => $form,
772
                        'flashMessages' => $this->flashMessenger()->getMessages(),
773
                    ));
774
775
                return $viewModel;
776
            }
777
778
            // clear adapters
779
            $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...
780
            $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...
781
782
            $logged = $this->forward()->dispatch('playgrounduser_user', array('action' => 'ajaxauthenticate'));
783
784 View Code Duplication
            if (!$logged) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
785
                $this->flashMessenger()->addMessage(
786
                    'Authentication failed. Please try again.'
787
                );
788
789
                return $this->redirect()->toUrl(
790
                    $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

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

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

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

Loading history...
1040
                return $this->redirect()->toUrl(
1041
                    $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...
1042
                        $this->game->getClassType(),
1043
                        array('id' => $this->game->getIdentifier())
1044
                    )
1045
                );
1046
            } else {
1047
                $this->flashMessenger()->setNamespace('zfcuser-login-form')->addMessage(
1048
                    'Authentication failed. Please try again.'
1049
                );
1050
                return $this->redirect()->toUrl(
1051
                    $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
1052
                        $this->game->getClassType().'/login',
1053
                        array('id' => $this->game->getIdentifier())
1054
                    )
1055
                );
1056
            }
1057
        }
1058
1059
        $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...
1060
            $this->game->getClassType().'/login',
1061
            array('id' => $this->game->getIdentifier())
1062
        ).($socialnetwork?'/'.$socialnetwork:'').($redirect?'?redirect='.$redirect:'');
1063
1064
        return $this->redirect()->toUrl($redirect);
1065
    }
1066
1067 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...
1068
    {
1069
        $viewModel = $this->forward()->dispatch(
1070
            'playgrounduser_user',
1071
            array(
1072
                'controller' => 'playgrounduser_user',
1073
                'action'     => 'profile',
1074
                'id'         => $this->game->getIdentifier()
1075
            )
1076
        );
1077
1078
        if ($viewModel && $viewModel instanceof \Zend\View\Model\ViewModel) {
1079
            $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...
1080
            $viewModel->setVariables(array('game'      => $this->game));
1081
        }
1082
1083
        return $viewModel;
1084
    }
1085
1086
    public function userresetAction()
1087
    {
1088
        $viewModel = $this->forward()->dispatch(
1089
            'playgrounduser_forgot',
1090
            array(
1091
                'controller' => 'playgrounduser_forgot',
1092
                'action'     => 'reset',
1093
                'id'         => $this->game->getIdentifier(),
1094
                'userId'     => $this->params()->fromRoute('userId', null),
1095
                'token'      => $this->params()->fromRoute('token', null),
1096
            )
1097
        );
1098
1099
        if ($viewModel && $viewModel instanceof \Zend\View\Model\ViewModel) {
1100
            $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...
1101
            $viewModel->setVariables(array('game'      => $this->game));
1102
        }
1103
1104
        return $viewModel;
1105
    }
1106
1107 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...
1108
    {
1109
        $view = $this->forward()->dispatch(
1110
            'playgrounduser_forgot',
1111
            array(
1112
                'controller' => 'playgrounduser_forgot',
1113
                'action'     => 'ajaxforgot',
1114
                'id'         => $this->game->getIdentifier()
1115
            )
1116
        );
1117
1118
        if ($view && $view instanceof \Zend\View\Model\ViewModel) {
1119
            $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...
1120
            $view->setVariables(array('game'           => $this->game));
1121
        }
1122
1123
        return $view;
1124
    }
1125
1126 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...
1127
    {
1128
        $viewModel = $this->forward()->dispatch(
1129
            'playgroundcms',
1130
            array(
1131
                'controller' => 'playgroundcms',
1132
                'action'     => 'index',
1133
                'id'         => $this->game->getIdentifier(),
1134
                'pid'        => $this->getEvent()->getRouteMatch()->getParam('pid')
1135
            )
1136
        );
1137
1138
        if ($viewModel && $viewModel instanceof \Zend\View\Model\ViewModel) {
1139
            $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...
1140
            $viewModel->setVariables(array('game'      => $this->game));
1141
        }
1142
1143
        return $viewModel;
1144
    }
1145
1146 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...
1147
    {
1148
        $viewModel = $this->forward()->dispatch(
1149
            'playgroundcms',
1150
            array(
1151
                'controller' => 'playgroundcms',
1152
                'action'     => 'list',
1153
                'id'         => $this->game->getIdentifier(),
1154
                'category'   => $this->game->getIdentifier()
1155
            )
1156
        );
1157
1158
        if ($viewModel && $viewModel instanceof \Zend\View\Model\ViewModel) {
1159
            $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...
1160
            $viewModel->setVariables(array('game'      => $this->game));
1161
        }
1162
1163
        return $viewModel;
1164
    }
1165
1166
    /**
1167
     *
1168
     * @param \PlaygroundGame\Entity\Game $game
1169
     * @param \PlaygroundUser\Entity\User $user
1170
     */
1171
    public function checkFbRegistration($user, $game)
1172
    {
1173
        $redirect = false;
1174
        $session  = new Container('facebook');
1175
        if ($session->offsetExists('signed_request')) {
1176
            if (!$user) {
1177
                // Get Playground user from Facebook info
1178
                $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...
1179
                $view         = $this->forward()->dispatch(
1180
                    'playgrounduser_user',
1181
                    array(
1182
                        'controller' => 'playgrounduser_user',
1183
                        'action'     => 'registerFacebookUser',
1184
                        'provider'   => 'facebook',
1185
                    )
1186
                );
1187
1188
                $this->layout()->setTemplate($beforeLayout);
1189
                $user = $view->user;
1190
1191
                // If the user can not be created/retrieved from Facebook info, redirect to login/register form
1192
                if (!$user) {
1193
                    $redirectUrl = urlencode(
1194
                        $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
1195
                            $game->getClassType().'/play',
1196
                            array('id'              => $game->getIdentifier()),
1197
                            array('force_canonical' => true)
1198
                        )
1199
                    );
1200
                    $redirect = $this->redirect()->toUrl(
1201
                        $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...
1202
                            'zfcuser/register'
1203
                        ).'?redirect='.$redirectUrl
1204
                    );
1205
                }
1206
            }
1207
1208
            if ($game->getFbFan()) {
1209
                if ($this->getGameService()->checkIsFan($game) === false) {
1210
                    $redirect = $this->redirect()->toRoute(
1211
                        $game->getClassType().'/fangate',
1212
                        array('id' => $game->getIdentifier())
1213
                    );
1214
                }
1215
            }
1216
        }
1217
1218
        return $redirect;
1219
    }
1220
1221
    /**
1222
     * This method create the basic Game view
1223
     * @param \PlaygroundGame\Entity\Game $game
1224
     */
1225
    public function buildView($game)
1226
    {
1227
        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...
1228
            $viewModel = new JsonModel();
1229
            if ($game) {
1230
                $view = $this->addAdditionalView($game);
1231
                if ($view && $view instanceof \Zend\View\Model\ViewModel) {
1232
                    $viewModel->setVariables($view->getVariables());
1233
                }
1234
            }
1235
        } else {
1236
            $viewModel = new ViewModel();
1237
1238
            if ($game) {
1239
                $this->addMetaTitle($game);
1240
                $this->addMetaBitly();
1241
                $this->addGaEvent($game);
1242
1243
                $this->customizeGameDesign($game);
1244
1245
                $view = $this->addAdditionalView($game);
1246
                if ($view && $view instanceof \Zend\View\Model\ViewModel) {
1247
                    $viewModel->addChild($view, 'additional');
1248
                } elseif ($view && $view instanceof \Zend\Http\PhpEnvironment\Response) {
1249
                    return $view;
1250
                }
1251
1252
                $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...
1253
                    array(
1254
                        'action'        => $this->params('action'),
1255
                        'game'          => $game,
1256
                        'flashMessages' => $this->flashMessenger()->getMessages(),
1257
1258
                    )
1259
                );
1260
1261
                $viewModel->setVariables($this->getShareData($game));
1262
                $viewModel->setVariables(array('game' => $game, 'user' => $this->user));
1263
            }
1264
        }
1265
1266
        return $viewModel;
1267
    }
1268
1269
    /**
1270
     * @param \PlaygroundGame\Entity\Game $game
1271
     */
1272
    public function addAdditionalView($game)
1273
    {
1274
        $view = false;
1275
1276
        $actionName = $this->getEvent()->getRouteMatch()->getParam('action', 'not-found');
1277
        $stepsViews = json_decode($game->getStepsViews(), true);
1278
        if ($stepsViews && isset($stepsViews[$actionName])) {
1279
            $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...
1280
            $actionData   = $stepsViews[$actionName];
1281
            if (is_string($actionData)) {
1282
                $action     = $actionData;
1283
                $controller = $this->getEvent()->getRouteMatch()->getParam('controller', 'playgroundgame_game');
1284
                $view       = $this->forward()->dispatch(
1285
                    $controller,
1286
                    array(
1287
                        'action' => $action,
1288
                        'id'     => $game->getIdentifier()
1289
                    )
1290
                );
1291
            } elseif (is_array($actionData) && count($actionData) > 0) {
1292
                $action     = key($actionData);
1293
                $controller = $actionData[$action];
1294
                $view       = $this->forward()->dispatch(
1295
                    $controller,
1296
                    array(
1297
                        'action' => $action,
1298
                        'id'     => $game->getIdentifier()
1299
                    )
1300
                );
1301
            }
1302
            // suite au forward, le template de layout a changé, je dois le rétablir...
1303
            $this->layout()->setTemplate($beforeLayout);
1304
        }
1305
1306
        return $view;
1307
    }
1308
1309
    public function addMetaBitly()
1310
    {
1311
        $bitlyclient = $this->getOptions()->getBitlyUrl();
1312
        $bitlyuser   = $this->getOptions()->getBitlyUsername();
1313
        $bitlykey    = $this->getOptions()->getBitlyApiKey();
1314
1315
        $this->getViewHelper('HeadMeta')->setProperty('bt:client', $bitlyclient);
1316
        $this->getViewHelper('HeadMeta')->setProperty('bt:user', $bitlyuser);
1317
        $this->getViewHelper('HeadMeta')->setProperty('bt:key', $bitlykey);
1318
    }
1319
1320
    /**
1321
     * @param \PlaygroundGame\Entity\Game $game
1322
     */
1323
    public function addGaEvent($game)
1324
    {
1325
        // Google Analytics event
1326
        $ga    = $this->getServiceLocator()->get('google-analytics');
1327
        $event = new \PlaygroundCore\Analytics\Event($game->getClassType(), $this->params('action'));
1328
        $event->setLabel($game->getTitle());
1329
        $ga->addEvent($event);
1330
    }
1331
1332
    /**
1333
     * @param \PlaygroundGame\Entity\Game $game
1334
     */
1335
    public function addMetaTitle($game)
1336
    {
1337
        $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...
1338
        $this->getGameService()->getServiceManager()->get('ViewHelperManager')->get('HeadTitle')->set($title);
1339
        // Meta set in the layout
1340
        $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...
1341
            array(
1342
                'breadcrumbTitle' => $title,
1343
                'currentPage'     => array(
1344
                    'pageGames'      => 'games',
1345
                    'pageWinners'    => '',
1346
                ),
1347
                'headParams'       => array(
1348
                    'headTitle'       => $title,
1349
                    'headDescription' => $title,
1350
                ),
1351
                'bodyCss' => $game->getIdentifier()
1352
            )
1353
        );
1354
    }
1355
1356
    /**
1357
     * @param \PlaygroundGame\Entity\Game $game
1358
     */
1359
    public function customizeGameDesign($game)
1360
    {
1361
        // If this game has a specific layout...
1362
        if ($game->getLayout()) {
1363
            $layoutViewModel = $this->layout();
1364
            $layoutViewModel->setTemplate($game->getLayout());
1365
        }
1366
1367
        // If this game has a specific stylesheet...
1368
        if ($game->getStylesheet()) {
1369
            $this->getViewHelper('HeadLink')->appendStylesheet(
1370
                $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...
1371
            );
1372
        }
1373
    }
1374
1375
    /**
1376
     * @param \PlaygroundGame\Entity\Game $game
1377
     */
1378
    public function getShareData($game)
1379
    {
1380
        $fo      = $this->getServiceLocator()->get('facebook-opengraph');
1381
        $session = new Container('facebook');
1382
1383
        // I change the fbappid if i'm in fb
1384
        if ($session->offsetExists('signed_request')) {
1385
            $fo->setId($game->getFbAppId());
1386
        }
1387
1388
        // If I want to add a share block in my view
1389 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...
1390
            $fbShareMessage = $game->getFbShareMessage();
1391
        } else {
1392
            $fbShareMessage = str_replace(
1393
                '__placeholder__',
1394
                $game->getTitle(),
1395
                $this->getOptions()->getDefaultShareMessage()
1396
            );
1397
        }
1398
1399
        if ($game->getFbShareImage()) {
1400
            $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...
1401
                '',
1402
                array(),
1403
                array('force_canonical' => true),
1404
                false
1405
            ).$game->getFbShareImage();
1406
        } else {
1407
            $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...
1408
                '',
1409
                array(),
1410
                array('force_canonical' => true),
1411
                false
1412
            ).$game->getMainImage();
1413
        }
1414
1415
        $secretKey = strtoupper(substr(sha1(uniqid('pg_', true).'####'.time()), 0, 15));
1416
1417
        // Without bit.ly shortener
1418
        $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...
1419
            $game->getClassType(),
1420
            array('id'              => $game->getIdentifier()),
1421
            array('force_canonical' => true)
1422
        );
1423
        // With core shortener helper
1424
        $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...
1425
1426
        // FB Requests only work when it's a FB app
1427
        if ($game->getFbRequestMessage()) {
1428
            $fbRequestMessage = urlencode($game->getFbRequestMessage());
1429
        } else {
1430
            $fbRequestMessage = str_replace(
1431
                '__placeholder__',
1432
                $game->getTitle(),
1433
                $this->getOptions()->getDefaultShareMessage()
1434
            );
1435
        }
1436
1437 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...
1438
            $twShareMessage = $game->getTwShareMessage().$socialLinkUrl;
1439
        } else {
1440
            $twShareMessage = str_replace(
1441
                '__placeholder__',
1442
                $game->getTitle(),
1443
                $this->getOptions()->getDefaultShareMessage()
1444
            ).$socialLinkUrl;
1445
        }
1446
1447
        $ogTitle = new \PlaygroundCore\Opengraph\Tag('og:title', $fbShareMessage);
1448
        $ogImage = new \PlaygroundCore\Opengraph\Tag('og:image', $fbShareImage);
1449
1450
        $fo->addTag($ogTitle);
1451
        $fo->addTag($ogImage);
1452
1453
        $data = array(
1454
            'socialLinkUrl'    => $socialLinkUrl,
1455
            'secretKey'        => $secretKey,
1456
            'fbShareMessage'   => $fbShareMessage,
1457
            'fbShareImage'     => $fbShareImage,
1458
            'fbRequestMessage' => $fbRequestMessage,
1459
            'twShareMessage'   => $twShareMessage,
1460
        );
1461
1462
        return $data;
1463
    }
1464
1465
    /**
1466
     * return ajax response in json format
1467
     *
1468
     * @param array $data
1469
     * @return \Zend\View\Model\JsonModel
1470
     */
1471 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...
1472
    {
1473
        $model = new JsonModel(array(
1474
                'success' => true,
1475
                'data'    => $data,
1476
            ));
1477
        return $model->setTerminal(true);
1478
    }
1479
1480
    /**
1481
     * return ajax response in json format
1482
     *
1483
     * @param string $message
1484
     * @return \Zend\View\Model\JsonModel
1485
     */
1486 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...
1487
    {
1488
        $model = new JsonModel(array(
1489
                'success' => false,
1490
                'message' => $message,
1491
            ));
1492
        return $model->setTerminal(true);
1493
    }
1494
1495
    /**
1496
     * @param string $helperName
1497
     */
1498
    protected function getViewHelper($helperName)
1499
    {
1500
        return $this->getServiceLocator()->get('viewhelpermanager')->get($helperName);
1501
    }
1502
1503
    public function getGameService()
1504
    {
1505
        if (!$this->gameService) {
1506
            $this->gameService = $this->getServiceLocator()->get('playgroundgame_lottery_service');
1507
        }
1508
1509
        return $this->gameService;
1510
    }
1511
1512
    public function setGameService(GameService $gameService)
1513
    {
1514
        $this->gameService = $gameService;
1515
1516
        return $this;
1517
    }
1518
1519
    public function getPrizeService()
1520
    {
1521
        if (!$this->prizeService) {
1522
            $this->prizeService = $this->getServiceLocator()->get('playgroundgame_prize_service');
1523
        }
1524
1525
        return $this->prizeService;
1526
    }
1527
1528
    public function setPrizeService(PrizeService $prizeService)
1529
    {
1530
        $this->prizeService = $prizeService;
1531
1532
        return $this;
1533
    }
1534
1535
    public function getOptions()
1536
    {
1537
        if (!$this->options) {
1538
            $this->setOptions($this->getServiceLocator()->get('playgroundcore_module_options'));
1539
        }
1540
1541
        return $this->options;
1542
    }
1543
1544
    public function setOptions($options)
1545
    {
1546
        $this->options = $options;
1547
1548
        return $this;
1549
    }
1550
}
1551