Completed
Push — develop ( 922776...348e57 )
by greg
02:40
created

GameController::setEventManager()   D

Complexity

Conditions 15
Paths 1

Size

Total Lines 81
Code Lines 48

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 1 Features 0
Metric Value
c 4
b 1
f 0
dl 0
loc 81
rs 4.9974
cc 15
eloc 48
nc 1
nop 1

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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

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

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

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

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

Let’s take a look at an example:

class Author {
    private $name;

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

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

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

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

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

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

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

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

Let’s take a look at an example:

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

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

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

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

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

Available Fixes

  1. Change the type-hint for the parameter:

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

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

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
117
                ) {
118
                $this->isSoloGame = true;
119
            }
120
121
            if ($controller->game) {
122
                // this is possible to create a specific game design in /design/frontend/default/custom.
123
                //It will precede all others templates.
124
                $templatePathResolver = $controller->getServiceLocator()->get('Zend\View\Resolver\TemplatePathStack');
125
                $l = $templatePathResolver->getPaths();
126
                $templatePathResolver->addPath($l[0].'custom/'.$controller->game->getIdentifier());
127
            }
128
129
                $controller->user = $controller->zfcUserAuthentication()->getIdentity();
0 ignored issues
show
Documentation Bug introduced by
The method zfcUserAuthentication does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

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

Let’s take a look at an example:

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

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

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

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

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

Available Fixes

  1. Change the type-hint for the parameter:

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

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

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
191
        if ($this->game) {
192
            $uri = str_replace($controllerPath.'/'.$this->game->getIdentifier().'/', '', $uri);
193
        }
194
        $uri      = str_replace("/".$this->getEvent()->getRouteMatch()->getParam('locale')."/", "/", $uri);
195
        $template = 'playground-game/'.$controllerPath.'/custom'.$uri;
196
197
        if (false === $templatePathResolver->resolve($template)) {
198
            $viewRender = $this->getServiceLocator()->get('ViewRenderer');
199
200
            $this->getEvent()->getRouteMatch()->setParam('action', 'not-found');
201
            $this->response->setStatusCode(404);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Zend\Stdlib\ResponseInterface as the method setStatusCode() does only exist in the following implementations of said interface: Zend\Http\PhpEnvironment\Response, Zend\Http\Response, Zend\Http\Response\Stream.

Let’s take a look at an example:

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

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

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

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

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

Available Fixes

  1. Change the type-hint for the parameter:

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

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

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
202
203
            $res = 'error/404';
204
205
            $viewModel = $this->buildView($this->game);
206
            $viewModel->setTemplate($res);
0 ignored issues
show
Bug introduced by
The method setTemplate does only exist in Zend\View\Model\ViewModel, but not in Zend\Http\PhpEnvironment\Response.

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

Let’s take a look at an example:

class A
{
    public function foo() { }
}

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

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

Available Fixes

  1. Add an additional type-check:

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

    function someFunction(B $x) { /** ... */ }
    
Loading history...
207
208
            $this->layout()->setVariable("content", $viewRender->render($viewModel));
0 ignored issues
show
Bug introduced by
The method setVariable does only exist in Zend\View\Model\ModelInterface, but not in Zend\Mvc\Controller\Plugin\Layout.

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

Let’s take a look at an example:

class A
{
    public function foo() { }
}

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

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

Available Fixes

  1. Add an additional type-check:

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

    function someFunction(B $x) { /** ... */ }
    
Loading history...
209
            $this->response->setContent($viewRender->render($this->layout()));
210
211
            return $this->response;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->response; (Zend\Stdlib\ResponseInterface) is incompatible with the return type of the parent method Zend\Mvc\Controller\Abst...troller::notFoundAction of type Zend\View\Model\ViewMode...View\Model\ConsoleModel.

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

Let’s take a look at an example:

class Author {
    private $name;

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

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

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

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

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

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

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

Loading history...
212
        }
213
214
        $viewModel = $this->buildView($this->game);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->buildView($this->game); of type Zend\Http\PhpEnvironment...nd\View\Model\ViewModel adds the type Zend\View\Model\ViewModel to the return on line 217 which is incompatible with the return type documented by PlaygroundGame\Controlle...troller::notFoundAction of type Zend\Stdlib\ResponseInterface.
Loading history...
215
        $viewModel->setTemplate($template);
216
217
        return $viewModel;
218
    }
219
220
    /**
221
     * This action acts as a hub : Depending on the first step of the game, it will forward the action to this step
222
     */
223
    public function homeAction()
224
    {
225
        // This fix exists only for safari in FB on Windows : we need to redirect the user to the page
226
        // outside of iframe for the cookie to be accepted. PlaygroundCore redirects to the FB Iframed page when
227
        // it discovers that the user arrives for the first time on the game in FB.
228
        // When core redirects, it adds a 'redir_fb_page_id' var in the querystring
229
        // Here, we test if this var exist, and then send the user back to the game in FB.
230
        // Now the cookie will be accepted by Safari...
231
        $pageId = $this->params()->fromQuery('redir_fb_page_id');
232
        if (!empty($pageId)) {
233
            $appId = 'app_'.$this->game->getFbAppId();
234
            $url   = '//www.facebook.com/pages/game/'.$pageId.'?sk='.$appId;
235
236
            return $this->redirect()->toUrl($url);
237
        }
238
239
        // If an entry has already been done during this session, I reset the anonymous_identifier cookie
240
        // so that another person can play the same game (if game conditions are fullfilled)
241
        $session = new Container('anonymous_identifier');
242
        if ($session->offsetExists('anonymous_identifier')) {
243
            $session->offsetUnset('anonymous_identifier');
244
        }
245
246
        return $this->forward()->dispatch(
247
            'playgroundgame_'.$this->game->getClassType(),
248
            array(
249
                'controller' => 'playgroundgame_'.$this->game->getClassType(),
250
                'action'     => $this->game->firstStep(),
251
                'id'         => $this->game->getIdentifier()
252
            )
253
        );
254
    }
255
256
    /**
257
     * Homepage of the game
258
     */
259
    public function indexAction()
260
    {
261
        $isSubscribed = false;
262
263
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
264
        if ($entry) {
265
            $isSubscribed = true;
266
        }
267
268
        $viewModel = $this->buildView($this->game);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->buildView($this->game); of type Zend\Http\PhpEnvironment...nd\View\Model\ViewModel adds the type Zend\Http\PhpEnvironment\Response to the return on line 273 which is incompatible with the return type of the parent method Zend\Mvc\Controller\Abst...Controller::indexAction of type Zend\View\Model\ViewModel.
Loading history...
269
        $viewModel->setVariables(array(
0 ignored issues
show
Bug introduced by
The method setVariables does only exist in Zend\View\Model\ViewModel, but not in Zend\Http\PhpEnvironment\Response.

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

Let’s take a look at an example:

class A
{
    public function foo() { }
}

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

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

Available Fixes

  1. Add an additional type-check:

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

    function someFunction(B $x) { /** ... */ }
    
Loading history...
270
            'isSubscribed' => $isSubscribed,
271
        ));
272
273
        return $viewModel;
274
    }
275
276
    /**
277
     * leaderboardAction
278
     *
279
     * @return ViewModel $viewModel
280
     */
281
    public function leaderboardAction()
282
    {
283
        $filter = $this->getEvent()->getRouteMatch()->getParam('filter');
284
        $p      = $this->getEvent()->getRouteMatch()->getParam('p');
285
286
        $beforeLayout = $this->layout()->getTemplate();
0 ignored issues
show
Bug introduced by
The method getTemplate does only exist in Zend\View\Model\ModelInterface, but not in Zend\Mvc\Controller\Plugin\Layout.

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

Let’s take a look at an example:

class A
{
    public function foo() { }
}

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

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

Available Fixes

  1. Add an additional type-check:

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

    function someFunction(B $x) { /** ... */ }
    
Loading history...
287
        $subViewModel = $this->forward()->dispatch(
288
            'playgroundreward',
289
            array('action' => 'leaderboard', 'filter' => $filter, 'p' => $p)
290
        );
291
292
        // suite au forward, le template de layout a changé, je dois le rétablir...
293
        $this->layout()->setTemplate($beforeLayout);
294
        $this->layout()->setVariables(
0 ignored issues
show
Bug introduced by
The method setVariables does only exist in Zend\View\Model\ModelInterface, but not in Zend\Mvc\Controller\Plugin\Layout.

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

Let’s take a look at an example:

class A
{
    public function foo() { }
}

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

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

Available Fixes

  1. Add an additional type-check:

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

    function someFunction(B $x) { /** ... */ }
    
Loading history...
295
            array(
296
                'action' => $this->params('action'),
297
                'game'   => $this->game,
298
            )
299
        );
300
301
        $subViewModel->setVariables($this->getShareData($this->game));
302
        $subViewModel->setVariables(array('game' => $this->game, 'user' => $this->user));
303
304
        return $subViewModel;
305
    }
306
307
    /**
308
     * This action has been designed to be called by other controllers
309
     * It gives the ability to display an information form and persist it in the game entry
310
     *
311
     * @return \Zend\View\Model\ViewModel
312
     */
313
    public function registerAction()
314
    {
315
        $formDef = $this->game->getPlayerForm();
316
        if ($formDef !== null) {
317
            $form = $this->getGameService()->createFormFromJson($formDef->getForm(), 'playerForm');
318
        } else {
319
            return $this->notFoundAction();
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->notFoundAction(); (Zend\Stdlib\ResponseInterface) is incompatible with the return type documented by PlaygroundGame\Controlle...troller::registerAction of type Zend\View\Model\ViewModel.

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

Let’s take a look at an example:

class Author {
    private $name;

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

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

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

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

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

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

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

Loading history...
320
        }
321
322
        if ($this->getRequest()->isPost()) {
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Zend\Stdlib\RequestInterface as the method isPost() does only exist in the following implementations of said interface: Zend\Http\PhpEnvironment\Request, Zend\Http\Request.

Let’s take a look at an example:

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

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

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

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

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

Available Fixes

  1. Change the type-hint for the parameter:

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

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

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

Let’s take a look at an example:

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

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

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

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

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

Available Fixes

  1. Change the type-hint for the parameter:

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

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

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

Let’s take a look at an example:

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

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

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

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

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

Available Fixes

  1. Change the type-hint for the parameter:

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

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

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
327
            );
328
329
            $form->setData($data);
330
331
            if ($form->isValid()) {
332
                // steps of the game
333
                $steps = $this->game->getStepsArray();
334
                // sub steps of the game
335
                $viewSteps = $this->game->getStepsViewsArray();
336
337
                // register position
338
                $key = array_search($this->params('action'), $viewSteps);
339
                if (!$key) {
340
                    // register is not a substep of the game so it's a step
341
                    $key     = array_search($this->params('action'), $steps);
342
                    $keyStep = true;
343
                } else {
344
                    // register was a substep, i search the index of its parent
345
                    $key     = array_search($key, $steps);
346
                    $keyStep = false;
347
                }
348
349
                // play position
350
                $keyplay = array_search('play', $viewSteps);
351
352
                if (!$keyplay) {
353
                    // play is not a substep, so it's a step
354
                    $keyplay     = array_search('play', $steps);
355
                    $keyplayStep = true;
356
                } else {
357
                    // play is a substep so I search the index of its parent
358
                    $keyplay     = array_search($keyplay, $steps);
359
                    $keyplayStep = false;
360
                }
361
362
                // If register step before play, I don't have no entry yet. I have to create one
363
                // If register after play step, I search for the last entry created by play step.
364
365
                if ($key < $keyplay || ($keyStep && !$keyplayStep && $key <= $keyplay)) {
366
                    $entry = $this->getGameService()->play($this->game, $this->user);
367
                    if (!$entry) {
368
                        // the user has already taken part of this game and the participation limit has been reached
369
                        $this->flashMessenger()->addMessage('Vous avez déjà participé');
370
371
                        return $this->redirect()->toUrl(
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->redirect()...me->getIdentifier()))); (Zend\Http\Response) is incompatible with the return type documented by PlaygroundGame\Controlle...troller::registerAction of type Zend\View\Model\ViewModel.

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

Let’s take a look at an example:

class Author {
    private $name;

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

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

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

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

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

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

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

Loading history...
372
                            $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
373
                                $this->game->getClassType().'/result',
374
                                array(
375
                                    'id' => $this->game->getIdentifier(),
376
                                )
377
                            )
378
                        );
379
                    }
380
                } else {
381
                    // I'm looking for an entry without anonymousIdentifier (the active entry in fact).
382
                    $entry = $this->getGameService()->findLastEntry($this->game, $this->user);
383
                    if ($this->getGameService()->hasReachedPlayLimit($this->game, $this->user)) {
384
                        // the user has already taken part of this game and the participation limit has been reached
385
                        $this->flashMessenger()->addMessage('Vous avez déjà participé');
386
387
                        return $this->redirect()->toUrl(
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->redirect()...me->getIdentifier()))); (Zend\Http\Response) is incompatible with the return type documented by PlaygroundGame\Controlle...troller::registerAction of type Zend\View\Model\ViewModel.

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

Let’s take a look at an example:

class Author {
    private $name;

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

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

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

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

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

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

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

Loading history...
388
                            $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
389
                                $this->game->getClassType().'/result',
390
                                array(
391
                                    'id' => $this->game->getIdentifier(),
392
                                )
393
                            )
394
                        );
395
                    }
396
                }
397
398
                $this->getGameService()->updateEntryPlayerForm($form->getData(), $this->game, $this->user, $entry);
399
400
                if (!empty($this->game->nextStep($this->params('action')))) {
401
                    return $this->redirect()->toUrl(
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->redirect()..._canonical' => true))); (Zend\Http\Response) is incompatible with the return type documented by PlaygroundGame\Controlle...troller::registerAction of type Zend\View\Model\ViewModel.

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

Let’s take a look at an example:

class Author {
    private $name;

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

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

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

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

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

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

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

Loading history...
402
                        $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
403
                            $this->game->getClassType().'/'.$this->game->nextStep($this->params('action')),
404
                            array('id'              => $this->game->getIdentifier()),
405
                            array('force_canonical' => true)
406
                        )
407
                    );
408
                }
409
            }
410
        }
411
412
        $viewModel = $this->buildView($this->game);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->buildView($this->game); of type Zend\Http\PhpEnvironment...nd\View\Model\ViewModel adds the type Zend\Http\PhpEnvironment\Response to the return on line 417 which is incompatible with the return type documented by PlaygroundGame\Controlle...troller::registerAction of type Zend\View\Model\ViewModel.
Loading history...
413
        $viewModel->setVariables(array(
0 ignored issues
show
Bug introduced by
The method setVariables does only exist in Zend\View\Model\ViewModel, but not in Zend\Http\PhpEnvironment\Response.

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

Let’s take a look at an example:

class A
{
    public function foo() { }
}

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

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

Available Fixes

  1. Add an additional type-check:

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

    function someFunction(B $x) { /** ... */ }
    
Loading history...
414
                'form' => $form,
415
            ));
416
417
        return $viewModel;
418
    }
419
420
    /**
421
     * This action takes care of the terms of the game
422
     */
423
    public function termsAction()
424
    {
425
        $viewModel = $this->buildView($this->game);
426
427
        return $viewModel;
428
    }
429
430
    /**
431
     * This action takes care of the conditions of the game
432
     */
433
    public function conditionsAction()
434
    {
435
        $viewModel = $this->buildView($this->game);
436
437
        return $viewModel;
438
    }
439
440
    /**
441
     * This action takes care of bounce page of the game
442
     */
443
    public function bounceAction()
444
    {
445
        $availableGames = $this->getGameService()->getAvailableGames($this->user);
446
447
        $rssUrl = '';
448
        $config = $this->getGameService()->getServiceManager()->get('config');
449
        if (isset($config['rss']['url'])) {
450
            $rssUrl = $config['rss']['url'];
451
        }
452
453
        $viewModel = $this->buildView($this->game);
454
        $viewModel->setVariables(array(
0 ignored issues
show
Bug introduced by
The method setVariables does only exist in Zend\View\Model\ViewModel, but not in Zend\Http\PhpEnvironment\Response.

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

Let’s take a look at an example:

class A
{
    public function foo() { }
}

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

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

Available Fixes

  1. Add an additional type-check:

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

    function someFunction(B $x) { /** ... */ }
    
Loading history...
455
                'rssUrl'         => $rssUrl,
456
                'user'           => $this->user,
457
                'availableGames' => $availableGames,
458
            ));
459
460
        return $viewModel;
461
    }
462
463
    /**
464
     * This action displays the Prizes page associated to the game
465
     */
466
    public function prizesAction()
467
    {
468
        if (count($this->game->getPrizes()) == 0) {
469
            return $this->notFoundAction();
470
        }
471
472
        $viewModel = $this->buildView($this->game);
473
474
        return $viewModel;
475
    }
476
477
    /**
478
     * This action displays a specific Prize page among those associated to the game
479
     */
480
    public function prizeAction()
481
    {
482
        $prizeIdentifier = $this->getEvent()->getRouteMatch()->getParam('prize');
483
        $prize           = $this->getPrizeService()->getPrizeMapper()->findByIdentifier($prizeIdentifier);
484
485
        if (!$prize) {
486
            return $this->notFoundAction();
487
        }
488
489
        $viewModel = $this->buildView($this->game);
490
        $viewModel->setVariables(array('prize' => $prize));
0 ignored issues
show
Bug introduced by
The method setVariables does only exist in Zend\View\Model\ViewModel, but not in Zend\Http\PhpEnvironment\Response.

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

Let’s take a look at an example:

class A
{
    public function foo() { }
}

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

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

Available Fixes

  1. Add an additional type-check:

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

    function someFunction(B $x) { /** ... */ }
    
Loading history...
491
492
        return $viewModel;
493
    }
494
495
    public function gameslistAction()
496
    {
497
        $layoutViewModel = $this->layout();
498
499
        $slider = new ViewModel();
500
        $slider->setTemplate('playground-game/common/top_promo');
501
502
        $sliderItems = $this->getGameService()->getActiveSliderGames();
503
504
        $slider->setVariables(array('sliderItems' => $sliderItems));
505
506
        $layoutViewModel->addChild($slider, 'slider');
0 ignored issues
show
Bug introduced by
The method addChild does only exist in Zend\View\Model\ModelInterface, but not in Zend\Mvc\Controller\Plugin\Layout.

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

Let’s take a look at an example:

class A
{
    public function foo() { }
}

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

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

Available Fixes

  1. Add an additional type-check:

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

    function someFunction(B $x) { /** ... */ }
    
Loading history...
507
508
        $games = $this->getGameService()->getActiveGames(false, '', 'endDate');
509
        if (is_array($games)) {
510
            $paginator = new \Zend\Paginator\Paginator(new \Zend\Paginator\Adapter\ArrayAdapter($games));
511
        } else {
512
            $paginator = $games;
513
        }
514
515
        $paginator->setItemCountPerPage(7);
516
        $paginator->setCurrentPageNumber($this->getEvent()->getRouteMatch()->getParam('p'));
517
518
        $bitlyclient = $this->getOptions()->getBitlyUrl();
519
        $bitlyuser   = $this->getOptions()->getBitlyUsername();
520
        $bitlykey    = $this->getOptions()->getBitlyApiKey();
521
522
        $this->getViewHelper('HeadMeta')->setProperty('bt:client', $bitlyclient);
523
        $this->getViewHelper('HeadMeta')->setProperty('bt:user', $bitlyuser);
524
        $this->getViewHelper('HeadMeta')->setProperty('bt:key', $bitlykey);
525
526
        $this->layout()->setVariables(
0 ignored issues
show
Bug introduced by
The method setVariables does only exist in Zend\View\Model\ModelInterface, but not in Zend\Mvc\Controller\Plugin\Layout.

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

Let’s take a look at an example:

class A
{
    public function foo() { }
}

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

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

Available Fixes

  1. Add an additional type-check:

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

    function someFunction(B $x) { /** ... */ }
    
Loading history...
527
            array(
528
                'sliderItems'  => $sliderItems,
529
                'currentPage'  => array(
530
                    'pageGames'   => 'games',
531
                    'pageWinners' => '',
532
                ),
533
            )
534
        );
535
536
        return new ViewModel(
537
            array(
538
                'games' => $paginator,
539
            )
540
        );
541
    }
542
543
    public function fangateAction()
544
    {
545
        $viewModel = $this->buildView($this->game);
546
547
        return $viewModel;
548
    }
549
550
    public function shareAction()
551
    {
552
        $statusMail = null;
553
        $lastEntry  = null;
554
555
        // steps of the game
556
        $steps = $this->game->getStepsArray();
557
        // sub steps of the game
558
        $viewSteps = $this->game->getStepsViewsArray();
559
560
        // share position
561
        $key = array_search($this->params('action'), $viewSteps);
562
        if (!$key) {
563
            // share is not a substep of the game so it's a step
564
            $key = array_search($this->params('action'), $steps);
565
        } else {
566
            // share was a substep, I search the index of its parent
567
            $key = array_search($key, $steps);
568
        }
569
570
        // play position
571
        $keyplay = array_search('play', $viewSteps);
572
573
        if (!$keyplay) {
574
            // play is not a substep, so it's a step
575
            $keyplay = array_search('play', $steps);
576
        } else {
577
            // play is a substep so I search the index of its parent
578
            $keyplay = array_search($keyplay, $steps);
579
        }
580
581
        if ($key && $keyplay && $keyplay <= $key) {
582
            // Has the user finished the game ?
583
            $lastEntry = $this->getGameService()->findLastInactiveEntry($this->game, $this->user);
584
585
            if ($lastEntry === null) {
586
                return $this->redirect()->toUrl(
587
                    $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
588
                        $this->game->getClassType(),
589
                        array('id' => $this->game->getIdentifier())
590
                    )
591
                );
592
            }
593
        }
594
595
        $form = $this->getServiceLocator()->get('playgroundgame_sharemail_form');
596
        $form->setAttribute('method', 'post');
597
598
        // buildView must be before sendMail because it adds the game template path to the templateStack
599
        $viewModel = $this->buildView($this->game);
600
601 View Code Duplication
        if ($this->getRequest()->isPost()) {
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Zend\Stdlib\RequestInterface as the method isPost() does only exist in the following implementations of said interface: Zend\Http\PhpEnvironment\Request, Zend\Http\Request.

Let’s take a look at an example:

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

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

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

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

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

Available Fixes

  1. Change the type-hint for the parameter:

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

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

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

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

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

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

Let’s take a look at an example:

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

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

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

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

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

Available Fixes

  1. Change the type-hint for the parameter:

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

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

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
603
            $form->setData($data);
604
            if ($form->isValid()) {
605
                $result = $this->getGameService()->sendShareMail($data, $this->game, $this->user, $lastEntry);
606
                if ($result) {
607
                    $statusMail = true;
608
                }
609
            }
610
        }
611
612
        $viewModel->setVariables(array(
0 ignored issues
show
Bug introduced by
The method setVariables does only exist in Zend\View\Model\ViewModel, but not in Zend\Http\PhpEnvironment\Response.

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

Let’s take a look at an example:

class A
{
    public function foo() { }
}

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

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

Available Fixes

  1. Add an additional type-check:

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

    function someFunction(B $x) { /** ... */ }
    
Loading history...
613
                'statusMail' => $statusMail,
614
                'form'       => $form,
615
            ));
616
617
        return $viewModel;
618
    }
619
620
    public function inviteToTeamAction()
621
    {
622
        $statusMail = null;
623
        $message    = '';
624
625
        $form = $this->getServiceLocator()->get('playgroundgame_sharemail_form');
626
        $form->setAttribute('method', 'post');
627
628
        if ($this->getRequest()->isPost()) {
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Zend\Stdlib\RequestInterface as the method isPost() does only exist in the following implementations of said interface: Zend\Http\PhpEnvironment\Request, Zend\Http\Request.

Let’s take a look at an example:

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

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

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

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

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

Available Fixes

  1. Change the type-hint for the parameter:

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

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

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

Let’s take a look at an example:

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

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

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

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

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

Available Fixes

  1. Change the type-hint for the parameter:

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

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

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
630
            $form->setData($data);
631
            if ($form->isValid()) {
632
                $result = $this->getGameService()->inviteToTeam($data, $this->game, $this->user);
633
                if ($result['result']) {
634
                    $statusMail = true;
635
                } else {
636
                    $statusMail = false;
637
                    $message    = $result['message'];
638
                }
639
            }
640
        }
641
642
        $viewModel = $this->buildView($this->game);
643
        $viewModel->setVariables(array(
0 ignored issues
show
Bug introduced by
The method setVariables does only exist in Zend\View\Model\ViewModel, but not in Zend\Http\PhpEnvironment\Response.

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

Let’s take a look at an example:

class A
{
    public function foo() { }
}

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

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

Available Fixes

  1. Add an additional type-check:

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

    function someFunction(B $x) { /** ... */ }
    
Loading history...
644
                'message'    => $message,
645
                'statusMail' => $statusMail,
646
                'form'       => $form,
647
            ));
648
649
        return $viewModel;
650
    }
651
652 View Code Duplication
    public function fbshareAction()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
653
    {
654
        $viewModel = new JsonModel();
655
        $viewModel->setTerminal(true);
656
        $fbId = $this->params()->fromQuery('fbId');
657
        if (!$this->game) {
658
            return $this->errorJson();
659
        }
660
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
661
        if (!$entry) {
662
            return $this->errorJson();
663
        }
664
        if (!$fbId) {
665
            return $this->errorJson();
666
        }
667
668
        $this->getGameService()->postFbWall($fbId, $this->game, $this->user, $entry);
669
670
        return $this->successJson();
671
    }
672
673
    public function fbrequestAction()
674
    {
675
        $viewModel = new ViewModel();
676
        $viewModel->setTerminal(true);
677
        $fbId = $this->params()->fromQuery('fbId');
678
        $to   = $this->params()->fromQuery('to');
679
680
        if (!$this->game) {
681
            return $this->errorJson();
682
        }
683
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
684
        if (!$entry) {
685
            return $this->errorJson();
686
        }
687
        if (!$fbId) {
688
            return $this->errorJson();
689
        }
690
691
        $this->getGameService()->postFbRequest($fbId, $this->game, $this->user, $entry, $to);
692
693
        return $this->successJson();
694
    }
695
696
    public function tweetAction()
697
    {
698
        $tweetId = $this->params()->fromQuery('tweetId');
699
700
        if (!$this->game) {
701
            return $this->errorJson();
702
        }
703
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
704
        if (!$entry) {
705
            return $this->errorJson();
706
        }
707
        if (!$tweetId) {
708
            return $this->errorJson();
709
        }
710
711
        $this->getGameService()->postTwitter($tweetId, $this->game, $this->user, $entry);
712
713
        return $this->successJson();
714
    }
715
716 View Code Duplication
    public function googleAction()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
717
    {
718
        $viewModel = new ViewModel();
719
        $viewModel->setTerminal(true);
720
        $googleId = $this->params()->fromQuery('googleId');
721
722
        if (!$this->game) {
723
            return $this->errorJson();
724
        }
725
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
726
        if (!$entry) {
727
            return $this->errorJson();
728
        }
729
        if (!$googleId) {
730
            return $this->errorJson();
731
        }
732
733
        $this->getGameService()->postGoogle($googleId, $this->game, $this->user, $entry);
734
735
        return $this->successJson();
736
    }
737
738
    public function optinAction()
739
    {
740
        $userService = $this->getServiceLocator()->get('zfcuser_user_service');
741
742
        if ($this->getRequest()->isPost()) {
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Zend\Stdlib\RequestInterface as the method isPost() does only exist in the following implementations of said interface: Zend\Http\PhpEnvironment\Request, Zend\Http\Request.

Let’s take a look at an example:

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

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

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

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

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

Available Fixes

  1. Change the type-hint for the parameter:

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

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

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
743
            $data['optin']        = ($this->params()->fromPost('optin'))?1:0;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$data was never initialized. Although not strictly required by PHP, it is generally a good practice to add $data = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
744
            $data['optinPartner'] = ($this->params()->fromPost('optinPartner'))?1:0;
745
746
            $userService->updateNewsletter($data);
747
        }
748
749
        return $this->redirect()->toUrl(
750
            $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
751
                $this->game->getClassType(),
752
                array('id' => $this->game->getIdentifier())
753
            )
754
        );
755
    }
756
757
    public function loginAction()
758
    {
759
        $request = $this->getRequest();
760
        $form    = $this->getServiceLocator()->get('zfcuser_login_form');
761
762
        if ($request->isPost()) {
763
            $form->setData($request->getPost());
764
765
            if (!$form->isValid()) {
766
                $this->flashMessenger()->addMessage(
767
                    'Authentication failed. Please try again.'
768
                );
769
770
                $viewModel = $this->buildView($this->game);
771
                $viewModel->setVariables(array(
0 ignored issues
show
Bug introduced by
The method setVariables does only exist in Zend\View\Model\ViewModel, but not in Zend\Http\PhpEnvironment\Response.

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

Let’s take a look at an example:

class A
{
    public function foo() { }
}

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

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

Available Fixes

  1. Add an additional type-check:

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

    function someFunction(B $x) { /** ... */ }
    
Loading history...
772
                        'form'          => $form,
773
                        'flashMessages' => $this->flashMessenger()->getMessages(),
774
                    ));
775
776
                return $viewModel;
777
            }
778
779
            // clear adapters
780
            $this->zfcUserAuthentication()->getAuthAdapter()->resetAdapters();
0 ignored issues
show
Documentation Bug introduced by
The method zfcUserAuthentication does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
781
            $this->zfcUserAuthentication()->getAuthService()->clearIdentity();
0 ignored issues
show
Documentation Bug introduced by
The method zfcUserAuthentication does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
782
783
            $logged = $this->forward()->dispatch('playgrounduser_user', array('action' => 'ajaxauthenticate'));
784
785 View Code Duplication
            if (!$logged) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

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

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
792
                        $this->game->getClassType().'/login',
793
                        array('id' => $this->game->getIdentifier())
794
                    )
795
                );
796
            } else {
797
                return $this->redirect()->toUrl(
798
                    $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
799
                        $this->game->getClassType().'/'.$this->game->nextStep('index'),
800
                        array('id' => $this->game->getIdentifier())
801
                    )
802
                );
803
            }
804
        }
805
806
        $form->setAttribute(
807
            'action',
808
            $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
809
                $this->game->getClassType().'/login',
810
                array('id' => $this->game->getIdentifier())
811
            )
812
        );
813
        $viewModel = $this->buildView($this->game);
814
        $viewModel->setVariables(array(
815
                'form'          => $form,
816
                'flashMessages' => $this->flashMessenger()->getMessages(),
817
            ));
818
        return $viewModel;
819
    }
820
821 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...
822
    {
823
        $viewModel = $this->forward()->dispatch(
824
            'playgrounduser_user',
825
            array(
826
                'controller' => 'playgrounduser_user',
827
                'action'     => 'logout',
828
                'id'         => $this->game->getIdentifier()
829
            )
830
        );
831
832
        if ($viewModel && $viewModel instanceof \Zend\View\Model\ViewModel) {
833
            $this->layout()->setVariables(array('game' => $this->game));
0 ignored issues
show
Bug introduced by
The method setVariables does only exist in Zend\View\Model\ModelInterface, but not in Zend\Mvc\Controller\Plugin\Layout.

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

Let’s take a look at an example:

class A
{
    public function foo() { }
}

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

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

Available Fixes

  1. Add an additional type-check:

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

    function someFunction(B $x) { /** ... */ }
    
Loading history...
834
            $viewModel->setVariables(array('game'      => $this->game));
835
        }
836
837
        return $viewModel;
838
    }
839
840
    public function userregisterAction()
841
    {
842
        $userOptions = $this->getServiceLocator()->get('zfcuser_module_options');
843
844
        if ($this->zfcUserAuthentication()->hasIdentity()) {
0 ignored issues
show
Documentation Bug introduced by
The method zfcUserAuthentication does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
845
            return $this->redirect()->toUrl(
846
                $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
847
                    $this->game->getClassType().'/'.$this->game->nextStep('index'),
848
                    array('id' => $this->game->getIdentifier())
849
                )
850
            );
851
        }
852
        $request       = $this->getRequest();
853
        $service       = $this->getServiceLocator()->get('zfcuser_user_service');
854
        $form          = $this->getServiceLocator()->get('playgroundgame_register_form');
855
        $socialnetwork = $this->params()->fromRoute('socialnetwork', false);
856
        $form->setAttribute(
857
            'action',
858
            $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
859
                $this->game->getClassType().'/user-register',
860
                array('id' => $this->game->getIdentifier())
861
            )
862
        );
863
        $params            = array();
864
        $socialCredentials = array();
865
866
        if ($userOptions->getUseRedirectParameterIfPresent() && $request->getQuery()->get('redirect')) {
867
            $redirect = $request->getQuery()->get('redirect');
868
        } else {
869
            $redirect = false;
870
        }
871
872
        if ($socialnetwork) {
873
            $infoMe = $this->getProviderService()->getInfoMe($socialnetwork);
0 ignored issues
show
Documentation Bug introduced by
The method getProviderService does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
874
875
            if (!empty($infoMe)) {
876
                $user = $this->getProviderService()->getUserProviderMapper()->findUserByProviderId(
0 ignored issues
show
Documentation Bug introduced by
The method getProviderService does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
877
                    $infoMe->identifier,
878
                    $socialnetwork
879
                );
880
881
                if ($user || $service->getOptions()->getCreateUserAutoSocial() === true) {
882
                    //on le dirige vers l'action d'authentification
883
                    if (!$redirect && $userOptions->getLoginRedirectRoute() != '') {
884
                        $redirect = $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
885
                            $this->game->getClassType().'/login',
886
                            array('id' => $this->game->getIdentifier())
887
                        );
888
                    }
889
                    $redir = $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
890
                        $this->game->getClassType().'/login',
891
                        array('id' => $this->game->getIdentifier())
892
                    ).'/'.$socialnetwork.($redirect?'?redirect='.$redirect:'');
893
894
                    return $this->redirect()->toUrl($redir);
895
                }
896
897
                // Je retire la saisie du login/mdp
898
                $form->setAttribute(
899
                    'action',
900
                    $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
901
                        $this->game->getClassType().'/user-register',
902
                        array(
903
                            'id'            => $this->game->getIdentifier(),
904
                            'socialnetwork' => $socialnetwork,
905
906
                        )
907
                    )
908
                );
909
                $form->remove('password');
910
                $form->remove('passwordVerify');
911
912
                $birthMonth = $infoMe->birthMonth;
913
                if (strlen($birthMonth) <= 1) {
914
                    $birthMonth = '0'.$birthMonth;
915
                }
916
                $birthDay = $infoMe->birthDay;
917
                if (strlen($birthDay) <= 1) {
918
                    $birthDay = '0'.$birthDay;
919
                }
920
921
                $gender = $infoMe->gender;
922
                if ($gender == 'female') {
923
                    $title = 'Me';
924
                } else {
925
                    $title = 'M';
926
                }
927
928
                $params = array(
929
                    //'birth_year'  => $infoMe->birthYear,
930
                    'title'      => $title,
931
                    'dob'        => $birthDay.'/'.$birthMonth.'/'.$infoMe->birthYear,
932
                    'firstname'  => $infoMe->firstName,
933
                    'lastname'   => $infoMe->lastName,
934
                    'email'      => $infoMe->email,
935
                    'postalCode' => $infoMe->zip,
936
                );
937
                $socialCredentials = array(
938
                    'socialNetwork' => strtolower($socialnetwork),
939
                    'socialId'      => $infoMe->identifier,
940
                );
941
            }
942
        }
943
944
        $redirectUrl = $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
945
            $this->game->getClassType().'/user-register',
946
            array('id' => $this->game->getIdentifier())
947
        ).($socialnetwork?'/'.$socialnetwork:'').($redirect?'?redirect='.$redirect:'');
948
        $prg = $this->prg($redirectUrl, true);
949
950
        if ($prg instanceof Response) {
951
            return $prg;
952
        } elseif ($prg === false) {
953
            $form->setData($params);
954
            $viewModel = $this->buildView($this->game);
955
            $viewModel->setVariables(array(
0 ignored issues
show
Bug introduced by
The method setVariables does only exist in Zend\View\Model\ViewModel, but not in Zend\Http\PhpEnvironment\Response.

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

Let’s take a look at an example:

class A
{
    public function foo() { }
}

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

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

Available Fixes

  1. Add an additional type-check:

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

    function someFunction(B $x) { /** ... */ }
    
Loading history...
956
                'registerForm'       => $form,
957
                'enableRegistration' => $userOptions->getEnableRegistration(),
958
                'redirect'           => $redirect,
959
            ));
960
            return $viewModel;
961
        }
962
963
        $post = $prg;
964
        $post = array_merge(
965
            $post,
966
            $socialCredentials
967
        );
968
969
        if ($this->game->getOnInvitation()) {
970
            $credential = trim(
971
                $post[$this->getGameService()->getOptions()->getOnInvitationField()]
972
            );
973
            if (!$credential) {
974
                $credential = $this->params()->fromQuery(
975
                    $this->getGameService()->getOptions()->getOnInvitationField()
976
                );
977
            }
978
            $found = $this->getGameService()->getInvitationMapper()->findOneBy(array('requestKey' => $credential));
979
980
            if (!$found || !empty($found->getUser())) {
981
                $this->flashMessenger()->addMessage(
982
                    'Authentication failed. Please try again.'
983
                );
984
                $form->setData($post);
985
                $viewModel = $this->buildView($this->game);
986
                $viewModel->setVariables(array(
987
                        'registerForm'       => $form,
988
                        'enableRegistration' => $userOptions->getEnableRegistration(),
989
                        'redirect'           => $redirect,
990
                        'flashMessages'      => $this->flashMessenger()->getMessages(),
991
                        'flashErrors'        => $this->flashMessenger()->getErrorMessages(),
992
                    ));
993
994
                return $viewModel;
995
            }
996
        }
997
998
        $user = $service->register($post, 'playgroundgame_register_form');
999
1000
        if (!$user) {
1001
            $viewModel = $this->buildView($this->game);
1002
            $viewModel->setVariables(array(
1003
                    'registerForm'       => $form,
1004
                    'enableRegistration' => $userOptions->getEnableRegistration(),
1005
                    'redirect'           => $redirect,
1006
                    'flashMessages'      => $this->flashMessenger()->getMessages(),
1007
                    'flashErrors'        => $this->flashMessenger()->getErrorMessages(),
1008
                ));
1009
1010
            return $viewModel;
1011
        }
1012
1013
        if ($this->game->getOnInvitation()) {
1014
            // user has been created, associate the code with the userId
1015
            $found->setUser($user);
0 ignored issues
show
Bug introduced by
The variable $found does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1016
            $this->getGameService()->getInvitationMapper()->update($found);
1017
        }
1018
1019
        if ($service->getOptions()->getEmailVerification()) {
1020
            $vm = new ViewModel(array('userEmail' => $user->getEmail()));
1021
            $vm->setTemplate('playground-user/register/registermail');
1022
1023
            return $vm;
1024
        } elseif ($service->getOptions()->getLoginAfterRegistration()) {
1025
            $identityFields = $service->getOptions()->getAuthIdentityFields();
1026
            if (in_array('email', $identityFields)) {
1027
                $post['identity'] = $user->getEmail();
1028
            } elseif (in_array('username', $identityFields)) {
1029
                $post['identity'] = $user->getUsername();
1030
            }
1031
            $post['credential'] = isset($post['password'])?$post['password']:'';
1032
            $request->setPost(new Parameters($post));
1033
1034
            // clear adapters
1035
            $this->zfcUserAuthentication()->getAuthAdapter()->resetAdapters();
0 ignored issues
show
Documentation Bug introduced by
The method zfcUserAuthentication does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
1036
            $this->zfcUserAuthentication()->getAuthService()->clearIdentity();
0 ignored issues
show
Documentation Bug introduced by
The method zfcUserAuthentication does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
1037
1038
            $logged = $this->forward()->dispatch('playgrounduser_user', array('action' => 'ajaxauthenticate'));
1039
1040 View Code Duplication
            if ($logged) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
1041
                return $this->redirect()->toUrl(
1042
                    $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
1043
                        $this->game->getClassType().'/'.$this->game->nextStep('index'),
1044
                        array('id' => $this->game->getIdentifier())
1045
                    )
1046
                );
1047
            } else {
1048
                $this->flashMessenger()->setNamespace('zfcuser-login-form')->addMessage(
1049
                    'Authentication failed. Please try again.'
1050
                );
1051
                return $this->redirect()->toUrl(
1052
                    $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
1053
                        $this->game->getClassType().'/login',
1054
                        array('id' => $this->game->getIdentifier())
1055
                    )
1056
                );
1057
            }
1058
        }
1059
1060
        $redirect = $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
1061
            $this->game->getClassType().'/login',
1062
            array('id' => $this->game->getIdentifier())
1063
        ).($socialnetwork?'/'.$socialnetwork:'').($redirect?'?redirect='.$redirect:'');
1064
1065
        return $this->redirect()->toUrl($redirect);
1066
    }
1067
1068 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...
1069
    {
1070
        $viewModel = $this->forward()->dispatch(
1071
            'playgrounduser_user',
1072
            array(
1073
                'controller' => 'playgrounduser_user',
1074
                'action'     => 'profile',
1075
                'id'         => $this->game->getIdentifier()
1076
            )
1077
        );
1078
1079
        if ($viewModel && $viewModel instanceof \Zend\View\Model\ViewModel) {
1080
            $this->layout()->setVariables(array('game' => $this->game));
0 ignored issues
show
Bug introduced by
The method setVariables does only exist in Zend\View\Model\ModelInterface, but not in Zend\Mvc\Controller\Plugin\Layout.

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

Let’s take a look at an example:

class A
{
    public function foo() { }
}

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

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

Available Fixes

  1. Add an additional type-check:

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

    function someFunction(B $x) { /** ... */ }
    
Loading history...
1081
            $viewModel->setVariables(array('game'      => $this->game));
1082
        }
1083
1084
        return $viewModel;
1085
    }
1086
1087
    public function userresetAction()
1088
    {
1089
        $viewModel = $this->forward()->dispatch(
1090
            'playgrounduser_forgot',
1091
            array(
1092
                'controller' => 'playgrounduser_forgot',
1093
                'action'     => 'reset',
1094
                'id'         => $this->game->getIdentifier(),
1095
                'userId'     => $this->params()->fromRoute('userId', null),
1096
                'token'      => $this->params()->fromRoute('token', null),
1097
            )
1098
        );
1099
1100
        if ($viewModel && $viewModel instanceof \Zend\View\Model\ViewModel) {
1101
            $this->layout()->setVariables(array('game' => $this->game));
0 ignored issues
show
Bug introduced by
The method setVariables does only exist in Zend\View\Model\ModelInterface, but not in Zend\Mvc\Controller\Plugin\Layout.

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

Let’s take a look at an example:

class A
{
    public function foo() { }
}

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

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

Available Fixes

  1. Add an additional type-check:

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

    function someFunction(B $x) { /** ... */ }
    
Loading history...
1102
            $viewModel->setVariables(array('game'      => $this->game));
1103
        }
1104
1105
        return $viewModel;
1106
    }
1107
1108 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...
1109
    {
1110
        $view = $this->forward()->dispatch(
1111
            'playgrounduser_forgot',
1112
            array(
1113
                'controller' => 'playgrounduser_forgot',
1114
                'action'     => 'ajaxforgot',
1115
                'id'         => $this->game->getIdentifier()
1116
            )
1117
        );
1118
1119
        if ($view && $view instanceof \Zend\View\Model\ViewModel) {
1120
            $this->layout()->setVariables(array('game' => $this->game));
0 ignored issues
show
Bug introduced by
The method setVariables does only exist in Zend\View\Model\ModelInterface, but not in Zend\Mvc\Controller\Plugin\Layout.

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

Let’s take a look at an example:

class A
{
    public function foo() { }
}

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

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

Available Fixes

  1. Add an additional type-check:

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

    function someFunction(B $x) { /** ... */ }
    
Loading history...
1121
            $view->setVariables(array('game'           => $this->game));
1122
        }
1123
1124
        return $view;
1125
    }
1126
1127 View Code Duplication
    public function cmsPageAction()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
1128
    {
1129
        $viewModel = $this->forward()->dispatch(
1130
            'playgroundcms',
1131
            array(
1132
                'controller' => 'playgroundcms',
1133
                'action'     => 'index',
1134
                'id'         => $this->game->getIdentifier(),
1135
                'pid'        => $this->getEvent()->getRouteMatch()->getParam('pid')
1136
            )
1137
        );
1138
1139
        if ($viewModel && $viewModel instanceof \Zend\View\Model\ViewModel) {
1140
            $this->layout()->setVariables(array('game' => $this->game));
0 ignored issues
show
Bug introduced by
The method setVariables does only exist in Zend\View\Model\ModelInterface, but not in Zend\Mvc\Controller\Plugin\Layout.

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

Let’s take a look at an example:

class A
{
    public function foo() { }
}

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

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

Available Fixes

  1. Add an additional type-check:

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

    function someFunction(B $x) { /** ... */ }
    
Loading history...
1141
            $viewModel->setVariables(array('game'      => $this->game));
1142
        }
1143
1144
        return $viewModel;
1145
    }
1146
1147 View Code Duplication
    public function cmsListAction()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
1148
    {
1149
        $viewModel = $this->forward()->dispatch(
1150
            'playgroundcms',
1151
            array(
1152
                'controller' => 'playgroundcms',
1153
                'action'     => 'list',
1154
                'id'         => $this->game->getIdentifier(),
1155
                'category'   => $this->game->getIdentifier()
1156
            )
1157
        );
1158
1159
        if ($viewModel && $viewModel instanceof \Zend\View\Model\ViewModel) {
1160
            $this->layout()->setVariables(array('game' => $this->game));
0 ignored issues
show
Bug introduced by
The method setVariables does only exist in Zend\View\Model\ModelInterface, but not in Zend\Mvc\Controller\Plugin\Layout.

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

Let’s take a look at an example:

class A
{
    public function foo() { }
}

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

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

Available Fixes

  1. Add an additional type-check:

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

    function someFunction(B $x) { /** ... */ }
    
Loading history...
1161
            $viewModel->setVariables(array('game'      => $this->game));
1162
        }
1163
1164
        return $viewModel;
1165
    }
1166
1167
    /**
1168
     *
1169
     * @param \PlaygroundGame\Entity\Game $game
1170
     * @param \PlaygroundUser\Entity\User $user
1171
     */
1172
    public function checkFbRegistration($user, $game)
1173
    {
1174
        $redirect = false;
1175
        $session  = new Container('facebook');
1176
        if ($session->offsetExists('signed_request')) {
1177
            if (!$user) {
1178
                // Get Playground user from Facebook info
1179
                $beforeLayout = $this->layout()->getTemplate();
0 ignored issues
show
Bug introduced by
The method getTemplate does only exist in Zend\View\Model\ModelInterface, but not in Zend\Mvc\Controller\Plugin\Layout.

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

Let’s take a look at an example:

class A
{
    public function foo() { }
}

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

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

Available Fixes

  1. Add an additional type-check:

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

    function someFunction(B $x) { /** ... */ }
    
Loading history...
1180
                $view         = $this->forward()->dispatch(
1181
                    'playgrounduser_user',
1182
                    array(
1183
                        'controller' => 'playgrounduser_user',
1184
                        'action'     => 'registerFacebookUser',
1185
                        'provider'   => 'facebook',
1186
                    )
1187
                );
1188
1189
                $this->layout()->setTemplate($beforeLayout);
1190
                $user = $view->user;
1191
1192
                // If the user can not be created/retrieved from Facebook info, redirect to login/register form
1193
                if (!$user) {
1194
                    $redirectUrl = urlencode(
1195
                        $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
1196
                            $game->getClassType().'/play',
1197
                            array('id'              => $game->getIdentifier()),
1198
                            array('force_canonical' => true)
1199
                        )
1200
                    );
1201
                    $redirect = $this->redirect()->toUrl(
1202
                        $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
1203
                            'zfcuser/register'
1204
                        ).'?redirect='.$redirectUrl
1205
                    );
1206
                }
1207
            }
1208
1209
            if ($game->getFbFan()) {
1210
                if ($this->getGameService()->checkIsFan($game) === false) {
1211
                    $redirect = $this->redirect()->toRoute(
1212
                        $game->getClassType().'/fangate',
1213
                        array('id' => $game->getIdentifier())
1214
                    );
1215
                }
1216
            }
1217
        }
1218
1219
        return $redirect;
1220
    }
1221
1222
    /**
1223
     * This method create the basic Game view
1224
     * @param \PlaygroundGame\Entity\Game $game
1225
     */
1226
    public function buildView($game)
1227
    {
1228
        if ($this->getRequest()->isXmlHttpRequest()) {
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Zend\Stdlib\RequestInterface as the method isXmlHttpRequest() does only exist in the following implementations of said interface: Zend\Http\PhpEnvironment\Request, Zend\Http\Request.

Let’s take a look at an example:

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

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

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

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

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

Available Fixes

  1. Change the type-hint for the parameter:

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

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

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
1229
            $viewModel = new JsonModel();
1230
            if ($game) {
1231
                $view = $this->addAdditionalView($game);
1232
                if ($view && $view instanceof \Zend\View\Model\ViewModel) {
1233
                    $viewModel->setVariables($view->getVariables());
1234
                }
1235
            }
1236
        } else {
1237
            $viewModel = new ViewModel();
1238
1239
            if ($game) {
1240
                $this->addMetaTitle($game);
1241
                $this->addMetaBitly();
1242
                $this->addGaEvent($game);
1243
1244
                $this->customizeGameDesign($game);
1245
1246
                $view = $this->addAdditionalView($game);
1247
                if ($view && $view instanceof \Zend\View\Model\ViewModel) {
1248
                    $viewModel->addChild($view, 'additional');
1249
                } elseif ($view && $view instanceof \Zend\Http\PhpEnvironment\Response) {
1250
                    return $view;
1251
                }
1252
1253
                $this->layout()->setVariables(
0 ignored issues
show
Bug introduced by
The method setVariables does only exist in Zend\View\Model\ModelInterface, but not in Zend\Mvc\Controller\Plugin\Layout.

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

Let’s take a look at an example:

class A
{
    public function foo() { }
}

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

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

Available Fixes

  1. Add an additional type-check:

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

    function someFunction(B $x) { /** ... */ }
    
Loading history...
1254
                    array(
1255
                        'action'        => $this->params('action'),
1256
                        'game'          => $game,
1257
                        'flashMessages' => $this->flashMessenger()->getMessages(),
1258
1259
                    )
1260
                );
1261
1262
                $viewModel->setVariables($this->getShareData($game));
1263
                $viewModel->setVariables(array('game' => $game, 'user' => $this->user));
1264
            }
1265
        }
1266
1267
        return $viewModel;
1268
    }
1269
1270
    /**
1271
     * @param \PlaygroundGame\Entity\Game $game
1272
     */
1273
    public function addAdditionalView($game)
1274
    {
1275
        $view = false;
1276
1277
        $actionName = $this->getEvent()->getRouteMatch()->getParam('action', 'not-found');
1278
        $stepsViews = json_decode($game->getStepsViews(), true);
1279
        if ($stepsViews && isset($stepsViews[$actionName])) {
1280
            $beforeLayout = $this->layout()->getTemplate();
0 ignored issues
show
Bug introduced by
The method getTemplate does only exist in Zend\View\Model\ModelInterface, but not in Zend\Mvc\Controller\Plugin\Layout.

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

Let’s take a look at an example:

class A
{
    public function foo() { }
}

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

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

Available Fixes

  1. Add an additional type-check:

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

    function someFunction(B $x) { /** ... */ }
    
Loading history...
1281
            $actionData   = $stepsViews[$actionName];
1282
            if (is_string($actionData)) {
1283
                $action     = $actionData;
1284
                $controller = $this->getEvent()->getRouteMatch()->getParam('controller', 'playgroundgame_game');
1285
                $view       = $this->forward()->dispatch(
1286
                    $controller,
1287
                    array(
1288
                        'action' => $action,
1289
                        'id'     => $game->getIdentifier()
1290
                    )
1291
                );
1292
            } elseif (is_array($actionData) && count($actionData) > 0) {
1293
                $action     = key($actionData);
1294
                $controller = $actionData[$action];
1295
                $view       = $this->forward()->dispatch(
1296
                    $controller,
1297
                    array(
1298
                        'action' => $action,
1299
                        'id'     => $game->getIdentifier()
1300
                    )
1301
                );
1302
            }
1303
            // suite au forward, le template de layout a changé, je dois le rétablir...
1304
            $this->layout()->setTemplate($beforeLayout);
1305
        }
1306
1307
        return $view;
1308
    }
1309
1310
    public function addMetaBitly()
1311
    {
1312
        $bitlyclient = $this->getOptions()->getBitlyUrl();
1313
        $bitlyuser   = $this->getOptions()->getBitlyUsername();
1314
        $bitlykey    = $this->getOptions()->getBitlyApiKey();
1315
1316
        $this->getViewHelper('HeadMeta')->setProperty('bt:client', $bitlyclient);
1317
        $this->getViewHelper('HeadMeta')->setProperty('bt:user', $bitlyuser);
1318
        $this->getViewHelper('HeadMeta')->setProperty('bt:key', $bitlykey);
1319
    }
1320
1321
    /**
1322
     * @param \PlaygroundGame\Entity\Game $game
1323
     */
1324
    public function addGaEvent($game)
1325
    {
1326
        // Google Analytics event
1327
        $ga    = $this->getServiceLocator()->get('google-analytics');
1328
        $event = new \PlaygroundCore\Analytics\Event($game->getClassType(), $this->params('action'));
1329
        $event->setLabel($game->getTitle());
1330
        $ga->addEvent($event);
1331
    }
1332
1333
    /**
1334
     * @param \PlaygroundGame\Entity\Game $game
1335
     */
1336
    public function addMetaTitle($game)
1337
    {
1338
        $title = $this->translate($game->getTitle());
0 ignored issues
show
Documentation Bug introduced by
The method translate does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
1339
        $this->getGameService()->getServiceManager()->get('ViewHelperManager')->get('HeadTitle')->set($title);
1340
        // Meta set in the layout
1341
        $this->layout()->setVariables(
0 ignored issues
show
Bug introduced by
The method setVariables does only exist in Zend\View\Model\ModelInterface, but not in Zend\Mvc\Controller\Plugin\Layout.

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

Let’s take a look at an example:

class A
{
    public function foo() { }
}

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

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

Available Fixes

  1. Add an additional type-check:

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

    function someFunction(B $x) { /** ... */ }
    
Loading history...
1342
            array(
1343
                'breadcrumbTitle' => $title,
1344
                'currentPage'     => array(
1345
                    'pageGames'      => 'games',
1346
                    'pageWinners'    => '',
1347
                ),
1348
                'headParams'       => array(
1349
                    'headTitle'       => $title,
1350
                    'headDescription' => $title,
1351
                ),
1352
                'bodyCss' => $game->getIdentifier()
1353
            )
1354
        );
1355
    }
1356
1357
    /**
1358
     * @param \PlaygroundGame\Entity\Game $game
1359
     */
1360
    public function customizeGameDesign($game)
1361
    {
1362
        // If this game has a specific layout...
1363
        if ($game->getLayout()) {
1364
            $layoutViewModel = $this->layout();
1365
            $layoutViewModel->setTemplate($game->getLayout());
1366
        }
1367
1368
        // If this game has a specific stylesheet...
1369
        if ($game->getStylesheet()) {
1370
            $this->getViewHelper('HeadLink')->appendStylesheet(
1371
                $this->getRequest()->getBaseUrl().'/'.$game->getStylesheet()
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Zend\Stdlib\RequestInterface as the method getBaseUrl() does only exist in the following implementations of said interface: Zend\Http\PhpEnvironment\Request.

Let’s take a look at an example:

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

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

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

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

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

Available Fixes

  1. Change the type-hint for the parameter:

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

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

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
1372
            );
1373
        }
1374
    }
1375
1376
    /**
1377
     * @param \PlaygroundGame\Entity\Game $game
1378
     */
1379
    public function getShareData($game)
1380
    {
1381
        $fo      = $this->getServiceLocator()->get('facebook-opengraph');
1382
        $session = new Container('facebook');
1383
1384
        // I change the fbappid if i'm in fb
1385
        if ($session->offsetExists('signed_request')) {
1386
            $fo->setId($game->getFbAppId());
1387
        }
1388
1389
        // If I want to add a share block in my view
1390 View Code Duplication
        if ($game->getFbShareMessage()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
1391
            $fbShareMessage = $game->getFbShareMessage();
1392
        } else {
1393
            $fbShareMessage = str_replace(
1394
                '__placeholder__',
1395
                $game->getTitle(),
1396
                $this->getOptions()->getDefaultShareMessage()
1397
            );
1398
        }
1399
1400
        if ($game->getFbShareImage()) {
1401
            $fbShareImage = $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
1402
                '',
1403
                array(),
1404
                array('force_canonical' => true),
1405
                false
1406
            ).$game->getFbShareImage();
1407
        } else {
1408
            $fbShareImage = $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
1409
                '',
1410
                array(),
1411
                array('force_canonical' => true),
1412
                false
1413
            ).$game->getMainImage();
1414
        }
1415
1416
        $secretKey = strtoupper(substr(sha1(uniqid('pg_', true).'####'.time()), 0, 15));
1417
1418
        // Without bit.ly shortener
1419
        $socialLinkUrl = $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
1420
            $game->getClassType(),
1421
            array('id'              => $game->getIdentifier()),
1422
            array('force_canonical' => true)
1423
        );
1424
        // With core shortener helper
1425
        $socialLinkUrl = $this->shortenUrl()->shortenUrl($socialLinkUrl);
0 ignored issues
show
Documentation Bug introduced by
The method shortenUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
1426
1427
        // FB Requests only work when it's a FB app
1428
        if ($game->getFbRequestMessage()) {
1429
            $fbRequestMessage = urlencode($game->getFbRequestMessage());
1430
        } else {
1431
            $fbRequestMessage = str_replace(
1432
                '__placeholder__',
1433
                $game->getTitle(),
1434
                $this->getOptions()->getDefaultShareMessage()
1435
            );
1436
        }
1437
1438 View Code Duplication
        if ($game->getTwShareMessage()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
1439
            $twShareMessage = $game->getTwShareMessage().$socialLinkUrl;
1440
        } else {
1441
            $twShareMessage = str_replace(
1442
                '__placeholder__',
1443
                $game->getTitle(),
1444
                $this->getOptions()->getDefaultShareMessage()
1445
            ).$socialLinkUrl;
1446
        }
1447
1448
        $ogTitle = new \PlaygroundCore\Opengraph\Tag('og:title', $fbShareMessage);
1449
        $ogImage = new \PlaygroundCore\Opengraph\Tag('og:image', $fbShareImage);
1450
1451
        $fo->addTag($ogTitle);
1452
        $fo->addTag($ogImage);
1453
1454
        $data = array(
1455
            'socialLinkUrl'    => $socialLinkUrl,
1456
            'secretKey'        => $secretKey,
1457
            'fbShareMessage'   => $fbShareMessage,
1458
            'fbShareImage'     => $fbShareImage,
1459
            'fbRequestMessage' => $fbRequestMessage,
1460
            'twShareMessage'   => $twShareMessage,
1461
        );
1462
1463
        return $data;
1464
    }
1465
1466
    /**
1467
     * return ajax response in json format
1468
     *
1469
     * @param array $data
1470
     * @return \Zend\View\Model\JsonModel
1471
     */
1472 View Code Duplication
    protected function successJson($data = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
1473
    {
1474
        $model = new JsonModel(array(
1475
                'success' => true,
1476
                'data'    => $data,
1477
            ));
1478
        return $model->setTerminal(true);
1479
    }
1480
1481
    /**
1482
     * return ajax response in json format
1483
     *
1484
     * @param string $message
1485
     * @return \Zend\View\Model\JsonModel
1486
     */
1487 View Code Duplication
    protected function errorJson($message = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
1488
    {
1489
        $model = new JsonModel(array(
1490
                'success' => false,
1491
                'message' => $message,
1492
            ));
1493
        return $model->setTerminal(true);
1494
    }
1495
1496
    /**
1497
     * @param string $helperName
1498
     */
1499
    protected function getViewHelper($helperName)
1500
    {
1501
        return $this->getServiceLocator()->get('viewhelpermanager')->get($helperName);
1502
    }
1503
1504
    public function getGameService()
1505
    {
1506
        if (!$this->gameService) {
1507
            $this->gameService = $this->getServiceLocator()->get('playgroundgame_lottery_service');
1508
        }
1509
1510
        return $this->gameService;
1511
    }
1512
1513
    public function setGameService(GameService $gameService)
1514
    {
1515
        $this->gameService = $gameService;
1516
1517
        return $this;
1518
    }
1519
1520
    public function getPrizeService()
1521
    {
1522
        if (!$this->prizeService) {
1523
            $this->prizeService = $this->getServiceLocator()->get('playgroundgame_prize_service');
1524
        }
1525
1526
        return $this->prizeService;
1527
    }
1528
1529
    public function setPrizeService(PrizeService $prizeService)
1530
    {
1531
        $this->prizeService = $prizeService;
1532
1533
        return $this;
1534
    }
1535
1536
    public function getOptions()
1537
    {
1538
        if (!$this->options) {
1539
            $this->setOptions($this->getServiceLocator()->get('playgroundcore_module_options'));
1540
        }
1541
1542
        return $this->options;
1543
    }
1544
1545
    public function setOptions($options)
1546
    {
1547
        $this->options = $options;
1548
1549
        return $this;
1550
    }
1551
}
1552