Completed
Push — develop ( 1e6b48...487118 )
by greg
05:11
created

GameController::leaderboardAction()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 22
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 8
Bugs 2 Features 0
Metric Value
c 8
b 2
f 0
dl 0
loc 22
rs 9.2
cc 1
eloc 12
nc 1
nop 0
1
<?php
2
3
namespace PlaygroundGame\Controller\Frontend;
4
5
use Zend\Mvc\Controller\AbstractActionController;
6
use Zend\View\Model\ViewModel;
7
use Zend\Session\Container;
8
use PlaygroundGame\Service\GameService;
9
use PlaygroundGame\Service\Prize as PrizeService;
10
use Zend\View\Model\JsonModel;
11
use Zend\Http\PhpEnvironment\Response;
12
use Zend\Stdlib\Parameters;
13
14
class GameController extends AbstractActionController
15
{
16
    /**
17
     * @var \PlaygroundGame\Service\GameService
18
     */
19
    protected $gameService;
20
21
    protected $prizeService;
22
23
    protected $options;
24
25
    protected $game;
26
27
    protected $user;
28
29
    protected $withGame = array(
30
        'home',
31
        'index',
32
        'terms',
33
        'conditions',
34
        'leaderboard',
35
        'register',
36
        'bounce',
37
        'prizes',
38
        'prize',
39
        'fangate',
40
        'share',
41
        'optin',
42
        'login',
43
        'play',
44
        'result',
45
        'preview',
46
        'list'
47
    );
48
49
    protected $withOnlineGame = array(
50
        'leaderboard',
51
        'register',
52
        'bounce',
53
        'play',
54
        'result'
55
    );
56
57
    protected $withUser = array();
58
59
    public function setEventManager(\Zend\EventManager\EventManagerInterface $events)
60
    {
61
        parent::setEventManager($events);
62
63
        $controller = $this;
64
        $events->attach('dispatch', function ($e) use ($controller) {
65
            $identifier = $e->getRouteMatch()->getParam('id');
66
            $controller->game = $this->getGameService()->checkGame($identifier, false);
67
            if (!$controller->game &&
68
                in_array($controller->params('action'), $controller->withGame)
69
            ) {
70
                return $controller->notFoundAction();
71
            }
72
73
            if ($controller->game &&
74
                $controller->game->isClosed() &&
75
                in_array($controller->params('action'), $controller->withOnlineGame)
76
            ) {
77
                return $controller->notFoundAction();
78
            }
79
80
            return;
81
        }, 100); // execute before executing action logic
82
    }
83
84
    /**
85
     * Action called if matched action does not exist
86
     * For this view not to be catched by Zend\Mvc\View\RouteNotFoundStrategy
87
     * it has to be rendered in the controller. Hence the code below.
88
     *
89
     * This action is injected as a catchall action for each custom_games definition
90
     * This way, when a custom_game is created, the 404 is it's responsability and the
91
     * view can be defined in design/frontend/default/custom/$slug/playground_game/$gametype/404.phtml
92
     *
93
     *
94
     * @return \Zend\Stdlib\ResponseInterface
95
     */
96
    public function notFoundAction()
97
    {
98
        $viewRender     = $this->getServiceLocator()->get('ViewRenderer');
99
100
        $this->getEvent()->getRouteMatch()->setParam('action', 'not-found');
101
        $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...
102
103
        $res = 'error/404';
104
105
        $viewModel = $this->buildView($this->game);
106
        $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...
107
108
        $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...
109
        $this->response->setContent($viewRender->render($this->layout()));
110
111
        return $this->response;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->response; (Zend\Stdlib\ResponseInterface) is incompatible with the return type of the parent method Zend\Mvc\Controller\Abst...troller::notFoundAction of type array.

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

Let’s take a look at an example:

class Author {
    private $name;

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

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

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

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

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

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

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

Loading history...
112
    }
113
114
    /**
115
     * This action acts as a hub : Depending on the first step of the game, it will forward the action to this step
116
     */
117
    public function homeAction()
118
    {
119
        // This fix exists only for safari in FB on Windows : we need to redirect the user to the page
120
        // outside of iframe for the cookie to be accepted. PlaygroundCore redirects to the FB Iframed page when
121
        // it discovers that the user arrives for the first time on the game in FB.
122
        // When core redirects, it adds a 'redir_fb_page_id' var in the querystring
123
        // Here, we test if this var exist, and then send the user back to the game in FB.
124
        // Now the cookie will be accepted by Safari...
125
        $pageId = $this->params()->fromQuery('redir_fb_page_id');
126
        if (!empty($pageId)) {
127
            $appId = 'app_'.$this->game->getFbAppId();
128
            $url = '//www.facebook.com/pages/game/'.$pageId.'?sk='.$appId;
129
130
            return $this->redirect()->toUrl($url);
131
        }
132
133
        // If an entry has already been done during this session, I reset the anonymous_identifier cookie
134
        // so that another person can play the same game (if game conditions are fullfilled)
135
        $session = new Container('anonymous_identifier');
136
        if ($session->offsetExists('anonymous_identifier')) {
137
            $session->offsetUnset('anonymous_identifier');
138
        }
139
        
140
        return $this->forward()->dispatch(
141
            'playgroundgame_'.$this->game->getClassType(),
142
            array(
143
                'controller' => 'playgroundgame_'.$this->game->getClassType(),
144
                'action' => $this->game->firstStep(),
145
                'id' => $this->game->getIdentifier()
146
            )
147
        );
148
    }
149
150
    /**
151
     * Homepage of the game
152
     */
153
    public function indexAction()
154
    {
155
        $user = $this->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...
156
        $isSubscribed = false;
157
158
        $entry = $this->getGameService()->checkExistingEntry($this->game, $user);
159
        if ($entry) {
160
            $isSubscribed = true;
161
        }
162
163
        $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 168 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...
164
        $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...
165
            'isSubscribed' => $isSubscribed
166
        ));
167
168
        return $viewModel;
169
    }
170
171
    /**
172
      * leaderboardAction
173
      *
174
      * @return ViewModel $viewModel
175
      */
176
    public function leaderboardAction()
177
    {
178
        $filter = $this->getEvent()->getRouteMatch()->getParam('filter');
179
        $p = $this->getEvent()->getRouteMatch()->getParam('p');
180
181
        $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...
182
        $subViewModel = $this->forward()->dispatch(
183
            'playgroundreward',
184
            array('action' => 'leaderboard', 'filter' => $filter, 'p' => $p)
185
        );
186
        
187
        // suite au forward, le template de layout a changé, je dois le rétablir...
188
        $this->layout()->setTemplate($beforeLayout);
189
190
        // give the ability to the game to have its customized look and feel.
191
        $templatePathResolver = $this->getServiceLocator()->get('Zend\View\Resolver\TemplatePathStack');
192
        $l = $templatePathResolver->getPaths();
193
194
        $templatePathResolver->addPath($l[0].'custom/'.$this->game->getIdentifier());
195
196
        return $subViewModel;
197
    }
198
199
    /**
200
     * This action has been designed to be called by other controllers
201
     * It gives the ability to display an information form and persist it in the game entry
202
     *
203
     * @return \Zend\View\Model\ViewModel
204
     */
205
    public function registerAction()
206
    {
207
        $user = $this->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...
208
        $form = $this->getGameService()->createFormFromJson($this->game->getPlayerForm()->getForm(), 'playerForm');
209
210
        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...
211
            // POST Request: Process form
212
            $data = array_merge_recursive(
213
                $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...
214
                $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...
215
            );
216
            
217
            $form->setData($data);
218
219
            if ($form->isValid()) {
220
                // steps of the game
221
                $steps = $this->game->getStepsArray();
222
                // sub steps of the game
223
                $viewSteps = $this->game->getStepsViewsArray();
224
225
                // register position
226
                $key = array_search($this->params('action'), $viewSteps);
227
                if (!$key) {
228
                    // register is not a substep of the game so it's a step
229
                    $key = array_search($this->params('action'), $steps);
230
                    $keyStep = true;
231
                } else {
232
                    // register was a substep, i search the index of its parent
233
                    $key = array_search($key, $steps);
234
                    $keyStep = false;
235
                }
236
237
                // play position
238
                $keyplay = array_search('play', $viewSteps);
239
240
                if (!$keyplay) {
241
                    // play is not a substep, so it's a step
242
                    $keyplay = array_search('play', $steps);
243
                    $keyplayStep = true;
244
                } else {
245
                    // play is a substep so I search the index of its parent
246
                    $keyplay = array_search($keyplay, $steps);
247
                    $keyplayStep = false;
248
                }
249
250
                // If register step before play, I don't have no entry yet. I have to create one
251
                // If register after play step, I search for the last entry created by play step.
252
253
                if ($key < $keyplay || ($keyStep && !$keyplayStep && $key <= $keyplay)) {
254
                    $entry = $this->getGameService()->play($this->game, $user);
255
                    if (!$entry) {
256
                        // the user has already taken part of this game and the participation limit has been reached
257
                        $this->flashMessenger()->addMessage('Vous avez déjà participé');
258
                    
259
                        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...
260
                            $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...
261
                                $this->game->getClassType().'/result',
262
                                array(
263
                                    'id' => $this->game->getIdentifier(),
264
                                    
265
                                )
266
                            )
267
                        );
268
                    }
269
                } else {
270
                    // I'm looking for an entry without anonymousIdentifier (the active entry in fact).
271
                    $entry = $this->getGameService()->findLastEntry($this->game, $user);
272
                    if ($this->getGameService()->hasReachedPlayLimit($this->game, $user)) {
273
                        // the user has already taken part of this game and the participation limit has been reached
274
                        $this->flashMessenger()->addMessage('Vous avez déjà participé');
275
                    
276
                        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...
277
                            $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...
278
                                $this->game->getClassType().'/result',
279
                                array(
280
                                    'id' => $this->game->getIdentifier(),
281
                                    
282
                                )
283
                            )
284
                        );
285
                    }
286
                }
287
288
                $this->getGameService()->updateEntryPlayerForm($form->getData(), $this->game, $user, $entry);
289
290
                if (!empty($this->game->nextStep($this->params('action')))) {
291
                    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...
292
                        $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...
293
                            $this->game->getClassType() .'/' . $this->game->nextStep($this->params('action')),
294
                            array('id' => $this->game->getIdentifier()),
295
                            array('force_canonical' => true)
296
                        )
297
                    );
298
                }
299
            }
300
        }
301
302
        $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 307 which is incompatible with the return type documented by PlaygroundGame\Controlle...troller::registerAction of type Zend\View\Model\ViewModel.
Loading history...
303
        $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...
304
            'form' => $form
305
        ));
306
307
        return $viewModel;
308
    }
309
310
    /**
311
     * This action takes care of the terms of the game
312
     */
313
    public function termsAction()
314
    {
315
        $viewModel = $this->buildView($this->game);
316
317
        return $viewModel;
318
    }
319
320
    /**
321
     * This action takes care of the conditions of the game
322
     */
323
    public function conditionsAction()
324
    {
325
        $viewModel = $this->buildView($this->game);
326
327
        return $viewModel;
328
    }
329
330
    /**
331
     * This action takes care of bounce page of the game
332
     */
333
    public function bounceAction()
334
    {
335
        $user = $this->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...
336
337
        $availableGames = $this->getGameService()->getAvailableGames($user);
338
339
        $rssUrl = '';
340
        $config = $this->getGameService()->getServiceManager()->get('config');
341
        if (isset($config['rss']['url'])) {
342
            $rssUrl = $config['rss']['url'];
343
        }
344
345
        $viewModel = $this->buildView($this->game);
346
        $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...
347
            'rssUrl'         => $rssUrl,
348
            'user'           => $user,
349
            'availableGames' => $availableGames,
350
        ));
351
352
        return $viewModel;
353
    }
354
355
356
    /**
357
     * This action displays the Prizes page associated to the game
358
     */
359
    public function prizesAction()
360
    {
361
        if (count($this->game->getPrizes()) == 0) {
362
            return $this->notFoundAction();
363
        }
364
365
        $viewModel = $this->buildView($this->game);
366
367
        return $viewModel;
368
    }
369
370
    /**
371
     * This action displays a specific Prize page among those associated to the game
372
     */
373
    public function prizeAction()
374
    {
375
        $prizeIdentifier = $this->getEvent()->getRouteMatch()->getParam('prize');
376
        $prize = $this->getPrizeService()->getPrizeMapper()->findByIdentifier($prizeIdentifier);
377
        
378
        if (!$prize) {
379
            return $this->notFoundAction();
380
        }
381
382
        $viewModel = $this->buildView($this->game);
383
        $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...
384
385
        return $viewModel;
386
    }
387
388
    public function gameslistAction()
389
    {
390
        $layoutViewModel = $this->layout();
391
392
        $slider = new ViewModel();
393
        $slider->setTemplate('playground-game/common/top_promo');
394
395
        $sliderItems = $this->getGameService()->getActiveSliderGames();
396
397
        $slider->setVariables(array('sliderItems' => $sliderItems));
398
399
        $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...
400
401
        $games = $this->getGameService()->getActiveGames(false, '', 'endDate');
402
        if (is_array($games)) {
403
            $paginator = new \Zend\Paginator\Paginator(new \Zend\Paginator\Adapter\ArrayAdapter($games));
404
        } else {
405
            $paginator = $games;
406
        }
407
408
        $paginator->setItemCountPerPage(7);
409
        $paginator->setCurrentPageNumber($this->getEvent()->getRouteMatch()->getParam('p'));
410
411
        $bitlyclient = $this->getOptions()->getBitlyUrl();
412
        $bitlyuser = $this->getOptions()->getBitlyUsername();
413
        $bitlykey = $this->getOptions()->getBitlyApiKey();
414
415
        $this->getViewHelper('HeadMeta')->setProperty('bt:client', $bitlyclient);
416
        $this->getViewHelper('HeadMeta')->setProperty('bt:user', $bitlyuser);
417
        $this->getViewHelper('HeadMeta')->setProperty('bt:key', $bitlykey);
418
419
        $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...
420
            array(
421
            'sliderItems'   => $sliderItems,
422
            'currentPage' => array(
423
                'pageGames' => 'games',
424
                'pageWinners' => ''
425
            ),
426
            )
427
        );
428
429
        return new ViewModel(
430
            array(
431
                'games'       => $paginator
432
            )
433
        );
434
    }
435
436
    public function fangateAction()
437
    {
438
        $viewModel = $this->buildView($this->game);
439
440
        return $viewModel;
441
    }
442
    
443
    public function shareAction()
444
    {
445
        $user = $this->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...
446
        $statusMail = null;
447
    
448
        // Has the user finished the game ?
449
        $lastEntry = $this->getGameService()->findLastInactiveEntry($this->game, $user);
450
    
451
        if ($lastEntry === null) {
452
            return $this->redirect()->toUrl(
453
                $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...
454
                    'postvote',
455
                    array('id' => $this->game->getIdentifier())
456
                )
457
            );
458
        }
459
    
460 View Code Duplication
        if (!$user && !$this->game->getAnonymousAllowed()) {
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...
461
            $redirect = urlencode(
462
                $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...
463
                    'postvote/result',
464
                    array(
465
                        'id' => $this->game->getIdentifier(),
466
                        
467
                    )
468
                )
469
            );
470
            return $this->redirect()->toUrl(
471
                $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...
472
                    'zfcuser/register',
473
                    array()
474
                ) . '?redirect='.$redirect
475
            );
476
        }
477
    
478
        $form = $this->getServiceLocator()->get('playgroundgame_sharemail_form');
479
        $form->setAttribute('method', 'post');
480
    
481 View Code Duplication
        if ($this->getRequest()->isPost()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
Bug introduced by
It seems like you code against a concrete implementation and not the interface Zend\Stdlib\RequestInterface as the method isPost() does only exist in the following implementations of said interface: Zend\Http\PhpEnvironment\Request, Zend\Http\Request.

Let’s take a look at an example:

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

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

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

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

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

Available Fixes

  1. Change the type-hint for the parameter:

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

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

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
482
            $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...
483
            $form->setData($data);
484
            if ($form->isValid()) {
485
                $result = $this->getGameService()->sendShareMail($data, $this->game, $user, $lastEntry);
486
                if ($result) {
487
                    $statusMail = true;
488
                }
489
            }
490
        }
491
    
492
        // buildView must be before sendMail because it adds the game template path to the templateStack
493
        $viewModel = $this->buildView($this->game);
494
    
495
        $this->getGameService()->sendMail($this->game, $user, $lastEntry);
496
    
497
        $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...
498
            'statusMail'       => $statusMail,
499
            'form'             => $form,
500
        ));
501
    
502
        return $viewModel;
503
    }
504
    
505 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...
506
    {
507
        $viewModel = new JsonModel();
508
        $viewModel->setTerminal(true);
509
        $fbId = $this->params()->fromQuery('fbId');
510
        $user = $this->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...
511
        if (!$this->game) {
512
            return $this->errorJson();
513
        }
514
        $entry = $this->getGameService()->checkExistingEntry($this->game, $user);
515
        if (! $entry) {
516
            return $this->errorJson();
517
        }
518
        if (!$fbId) {
519
            return $this->errorJson();
520
        }
521
    
522
        $this->getGameService()->postFbWall($fbId, $this->game, $user, $entry);
523
    
524
        return $this->successJson();
525
    }
526
    
527
    public function fbrequestAction()
528
    {
529
        $viewModel = new ViewModel();
530
        $viewModel->setTerminal(true);
531
        $fbId = $this->params()->fromQuery('fbId');
532
        $to = $this->params()->fromQuery('to');
533
        $user = $this->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...
534
    
535
        if (!$this->game) {
536
            return $this->errorJson();
537
        }
538
        $entry = $this->getGameService()->checkExistingEntry($this->game, $user);
539
        if (! $entry) {
540
            return $this->errorJson();
541
        }
542
        if (!$fbId) {
543
            return $this->errorJson();
544
        }
545
    
546
        $this->getGameService()->postFbRequest($fbId, $this->game, $user, $entry, $to);
547
    
548
        return $this->successJson();
549
    }
550
    
551
    public function tweetAction()
552
    {
553
        $tweetId = $this->params()->fromQuery('tweetId');
554
        $user = $this->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...
555
    
556
        if (!$this->game) {
557
            return $this->errorJson();
558
        }
559
        $entry = $this->getGameService()->checkExistingEntry($this->game, $user);
560
        if (! $entry) {
561
            return $this->errorJson();
562
        }
563
        if (!$tweetId) {
564
            return $this->errorJson();
565
        }
566
    
567
        $this->getGameService()->postTwitter($tweetId, $this->game, $user, $entry);
568
    
569
        return $this->successJson();
570
    }
571
    
572 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...
573
    {
574
        $viewModel = new ViewModel();
575
        $viewModel->setTerminal(true);
576
        $googleId = $this->params()->fromQuery('googleId');
577
        $user = $this->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...
578
579
        if (!$this->game) {
580
            return $this->errorJson();
581
        }
582
        $entry = $this->getGameService()->checkExistingEntry($this->game, $user);
583
        if (! $entry) {
584
            return $this->errorJson();
585
        }
586
        if (!$googleId) {
587
            return $this->errorJson();
588
        }
589
    
590
        $this->getGameService()->postGoogle($googleId, $this->game, $user, $entry);
591
    
592
        return $this->successJson();
593
    }
594
595
    public function optinAction()
596
    {
597
        $userService = $this->getServiceLocator()->get('zfcuser_user_service');
598
599
        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...
600
            $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...
601
            $data['optinPartner'] = ($this->params()->fromPost('optinPartner'))? 1:0;
602
603
            $userService->updateNewsletter($data);
604
        }
605
606
        return $this->redirect()->toUrl(
607
            $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...
608
                'frontend/' . $this->game->getClassType() . '/index',
609
                array('id' => $this->game->getIdentifier())
610
            )
611
        );
612
    }
613
    
614
    public function loginAction()
615
    {
616
        $request = $this->getRequest();
617
        $form    = $this->getServiceLocator()->get('zfcuser_login_form');
618
    
619
        if ($request->isPost()) {
620
            $form->setData($request->getPost());
621
            
622
            if (!$form->isValid()) {
623
                $this->flashMessenger()->setNamespace('zfcuser-login-form')->addMessage(
624
                    'Authentication failed. Please try again.'
625
                );
626
                
627
628
                return $this->redirect()->toUrl(
629
                    $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...
630
                        $this->game->getClassType() . '/login',
631
                        array('id' => $this->game->getIdentifier())
632
                    )
633
                );
634
            }
635
            
636
            // clear adapters
637
            $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...
638
            $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...
639
640
            $logged = $this->forward()->dispatch('playgrounduser_user', array('action' => 'ajaxauthenticate'));
641
642 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...
643
                return $this->redirect()->toUrl(
644
                    $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...
645
                        $this->game->getClassType() . '/' . $this->game->nextStep('index'),
646
                        array(
647
                            'id' => $this->game->getIdentifier(),
648
                            
649
                        )
650
                    )
651
                );
652
            } else {
653
                $this->flashMessenger()->setNamespace('zfcuser-login-form')->addMessage(
654
                    'Authentication failed. Please try again.'
655
                );
656
                return $this->redirect()->toUrl(
657
                    $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...
658
                        $this->game->getClassType() . '/login',
659
                        array('id' => $this->game->getIdentifier())
660
                    )
661
                );
662
            }
663
        }
664
        
665
        $form->setAttribute(
666
            'action',
667
            $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...
668
                $this->game->getClassType().'/login',
669
                array('id' => $this->game->getIdentifier())
670
            )
671
        );
672
        $viewModel = $this->buildView($this->game);
673
        $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...
674
            'form' => $form,
675
        ));
676
        return $viewModel;
677
    }
678
679
    public function userregisterAction()
680
    {
681
        $userOptions = $this->getServiceLocator()->get('zfcuser_module_options');
682
683
        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...
684
            return $this->redirect()->toUrl(
685
                $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...
686
                    $this->game->getClassType().'/'.$this->game->nextStep('index'),
687
                    array('id' => $this->game->getIdentifier())
688
                )
689
            );
690
        }
691
        $request = $this->getRequest();
692
        $service = $this->getServiceLocator()->get('zfcuser_user_service');
693
        $form = $this->getServiceLocator()->get('playgroundgame_register_form');
694
        $socialnetwork = $this->params()->fromRoute('socialnetwork', false);
695
        $form->setAttribute(
696
            'action',
697
            $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...
698
                $this->game->getClassType().'/user-register',
699
                array('id' => $this->game->getIdentifier())
700
            )
701
        );
702
        $params = array();
703
        $socialCredentials = array();
704
705
        if ($userOptions->getUseRedirectParameterIfPresent() && $request->getQuery()->get('redirect')) {
706
            $redirect = $request->getQuery()->get('redirect');
707
        } else {
708
            $redirect = false;
709
        }
710
711
        if ($socialnetwork) {
712
            $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...
713
714
            if (!empty($infoMe)) {
715
                $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...
716
                    $infoMe->identifier,
717
                    $socialnetwork
718
                );
719
720
                if ($user || $service->getOptions()->getCreateUserAutoSocial() === true) {
721
                    //on le dirige vers l'action d'authentification
722
                    if (! $redirect && $userOptions->getLoginRedirectRoute() != '') {
723
                        $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...
724
                            $this->game->getClassType().'/login',
725
                            array('id' => $this->game->getIdentifier())
726
                        );
727
                    }
728
                    $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...
729
                        $this->game->getClassType().'/login',
730
                        array('id' => $this->game->getIdentifier())
731
                    ) .'/' . $socialnetwork . ($redirect ? '?redirect=' . $redirect : '');
732
733
                    return $this->redirect()->toUrl($redir);
734
                }
735
736
                // Je retire la saisie du login/mdp
737
                $form->setAttribute(
738
                    'action',
739
                    $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...
740
                        $this->game->getClassType().'/user-register',
741
                        array(
742
                            'id' => $this->game->getIdentifier(),
743
                            'socialnetwork' => $socialnetwork,
744
                            
745
                        )
746
                    )
747
                );
748
                $form->remove('password');
749
                $form->remove('passwordVerify');
750
751
                $birthMonth = $infoMe->birthMonth;
752
                if (strlen($birthMonth) <= 1) {
753
                    $birthMonth = '0'.$birthMonth;
754
                }
755
                $birthDay = $infoMe->birthDay;
756
                if (strlen($birthDay) <= 1) {
757
                    $birthDay = '0'.$birthDay;
758
                }
759
760
                $gender = $infoMe->gender;
761
                if ($gender == 'female') {
762
                    $title = 'Me';
763
                } else {
764
                    $title = 'M';
765
                }
766
767
                $params = array(
768
                    //'birth_year'  => $infoMe->birthYear,
769
                    'title'      => $title,
770
                    'dob'      => $birthDay.'/'.$birthMonth.'/'.$infoMe->birthYear,
771
                    'firstname'   => $infoMe->firstName,
772
                    'lastname'    => $infoMe->lastName,
773
                    'email'       => $infoMe->email,
774
                    'postalCode' => $infoMe->zip,
775
                );
776
                $socialCredentials = array(
777
                    'socialNetwork' => strtolower($socialnetwork),
778
                    'socialId'      => $infoMe->identifier,
779
                );
780
            }
781
        }
782
783
        $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...
784
            $this->game->getClassType().'/user-register',
785
            array('id' => $this->game->getIdentifier())
786
        ) .($socialnetwork ? '/' . $socialnetwork : ''). ($redirect ? '?redirect=' . $redirect : '');
787
        $prg = $this->prg($redirectUrl, true);
788
789
        if ($prg instanceof Response) {
790
            return $prg;
791
        } elseif ($prg === false) {
792
            $form->setData($params);
793
            $viewModel = $this->buildView($this->game);
794
            $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...
795
                'registerForm' => $form,
796
                'enableRegistration' => $userOptions->getEnableRegistration(),
797
                'redirect' => $redirect,
798
            ));
799
            return $viewModel;
800
        }
801
802
        $post = $prg;
803
        $post = array_merge(
804
            $post,
805
            $socialCredentials
806
        );
807
808
        $user = $service->register($post, 'playgroundgame_register_form');
809
810
        if (! $user) {
811
            $viewModel = $this->buildView($this->game);
812
            $viewModel->setVariables(array(
813
                'registerForm' => $form,
814
                'enableRegistration' => $userOptions->getEnableRegistration(),
815
                'redirect' => $redirect,
816
            ));
817
            
818
            return $viewModel;
819
        }
820
821
        if ($service->getOptions()->getEmailVerification()) {
822
            $vm = new ViewModel(array('userEmail' => $user->getEmail()));
823
            $vm->setTemplate('playground-user/register/registermail');
824
825
            return $vm;
826
        } elseif ($service->getOptions()->getLoginAfterRegistration()) {
827
            $identityFields = $service->getOptions()->getAuthIdentityFields();
828
            if (in_array('email', $identityFields)) {
829
                $post['identity'] = $user->getEmail();
830
            } elseif (in_array('username', $identityFields)) {
831
                $post['identity'] = $user->getUsername();
832
            }
833
            $post['credential'] = isset($post['password'])?$post['password']:'';
834
            $request->setPost(new Parameters($post));
835
836
            // clear adapters
837
            $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...
838
            $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...
839
840
            $logged = $this->forward()->dispatch('playgrounduser_user', array('action' => 'ajaxauthenticate'));
841
842 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...
843
                return $this->redirect()->toUrl(
844
                    $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...
845
                        $this->game->getClassType() . '/' . $this->game->nextStep('index'),
846
                        array(
847
                            'id' => $this->game->getIdentifier(),
848
                            
849
                        )
850
                    )
851
                );
852
            } else {
853
                $this->flashMessenger()->setNamespace('zfcuser-login-form')->addMessage(
854
                    'Authentication failed. Please try again.'
855
                );
856
                return $this->redirect()->toUrl(
857
                    $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
858
                        $this->game->getClassType() . '/login',
859
                        array(
860
                            'id' => $this->game->getIdentifier(),
861
                            
862
                        )
863
                    )
864
                );
865
            }
866
        }
867
868
        $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...
869
            $this->game->getClassType().'/login',
870
            array(
871
                'id' => $this->game->getIdentifier(),
872
                
873
            )
874
        ) . ($socialnetwork ? '/' . $socialnetwork : ''). ($redirect ? '?redirect=' . $redirect : '');
875
876
        return $this->redirect()->toUrl($redirect);
877
    }
878
879
    /**
880
     *
881
     * @param \PlaygroundGame\Entity\Game $game
882
     * @param \PlaygroundUser\Entity\User $user
883
     */
884
    public function checkFbRegistration($user, $game)
885
    {
886
        $redirect = false;
887
        $session = new Container('facebook');
888
        if ($session->offsetExists('signed_request')) {
889
            if (!$user) {
890
                // Get Playground user from Facebook info
891
                $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...
892
                $view = $this->forward()->dispatch(
893
                    'playgrounduser_user',
894
                    array(
895
                        'controller' => 'playgrounduser_user',
896
                        'action' => 'registerFacebookUser',
897
                        'provider' => 'facebook'
898
                    )
899
                );
900
901
                $this->layout()->setTemplate($beforeLayout);
902
                $user = $view->user;
903
904
                // If the user can not be created/retrieved from Facebook info, redirect to login/register form
905
                if (!$user) {
906
                    $redirectUrl = urlencode(
907
                        $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...
908
                            $game->getClassType() .'/play',
909
                            array('id' => $game->getIdentifier()),
910
                            array('force_canonical' => true)
911
                        )
912
                    );
913
                    $redirect =  $this->redirect()->toUrl(
914
                        $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...
915
                            'zfcuser/register'
916
                        ) . '?redirect='.$redirectUrl
917
                    );
918
                }
919
            }
920
921
            if ($game->getFbFan()) {
922
                if ($this->getGameService()->checkIsFan($game) === false) {
923
                    $redirect =  $this->redirect()->toRoute(
924
                        $game->getClassType().'/fangate',
925
                        array('id' => $game->getIdentifier())
926
                    );
927
                }
928
            }
929
        }
930
931
        return $redirect;
932
    }
933
934
    /**
935
     * This method create the basic Game view
936
     * @param \PlaygroundGame\Entity\Game $game
937
     */
938
    public function buildView($game)
939
    {
940
        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...
941
            $viewModel = new JsonModel();
942
            if ($game) {
943
                $view = $this->addAdditionalView($game);
944
                if ($view && $view instanceof \Zend\View\Model\ViewModel) {
945
                    $viewModel->setVariables($view->getVariables());
946
                }
947
            }
948
        } else {
949
            $viewModel = new ViewModel();
950
951
            if ($game) {
952
                $this->addMetaTitle($game);
953
                $this->addMetaBitly();
954
                $this->addGaEvent($game);
955
956
                $this->customizeGameDesign($game);
957
                
958
                // this is possible to create a specific game design in /design/frontend/default/custom.
959
                //It will precede all others templates.
960
                $templatePathResolver = $this->getServiceLocator()->get('Zend\View\Resolver\TemplatePathStack');
961
                $l = $templatePathResolver->getPaths();
962
                $templatePathResolver->addPath($l[0].'custom/'.$game->getIdentifier());
963
                
964
                $view = $this->addAdditionalView($game);
965
                if ($view && $view instanceof \Zend\View\Model\ViewModel) {
966
                    $viewModel->addChild($view, 'additional');
967
                } elseif ($view && $view instanceof \Zend\Http\PhpEnvironment\Response) {
968
                    return $view;
969
                }
970
971
                $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...
972
                    array(
973
                        'action' => $this->params('action'),
974
                        'game' => $game,
975
                        'flashMessages'    => $this->flashMessenger()->getMessages(),
976
                        
977
                    )
978
                );
979
            }
980
        }
981
        
982
        if ($game) {
983
            $viewModel->setVariables($this->getShareData($game));
984
            $viewModel->setVariables(array('game' => $game));
985
        }
986
987
        return $viewModel;
988
    }
989
990
    /**
991
     * @param \PlaygroundGame\Entity\Game $game
992
     */
993
    public function addAdditionalView($game)
994
    {
995
        $view = false;
996
997
        $actionName = $this->getEvent()->getRouteMatch()->getParam('action', 'not-found');
998
        $stepsViews = json_decode($game->getStepsViews(), true);
999
        if ($stepsViews && isset($stepsViews[$actionName])) {
1000
            $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...
1001
            $actionData = $stepsViews[$actionName];
1002
            if (is_string($actionData)) {
1003
                $action = $actionData;
1004
                $controller = $this->getEvent()->getRouteMatch()->getParam('controller', 'playgroundgame_game');
1005
                $view = $this->forward()->dispatch(
1006
                    $controller,
1007
                    array(
1008
                        'action' => $action,
1009
                        'id' => $game->getIdentifier()
1010
                    )
1011
                );
1012
            } elseif (is_array($actionData) && count($actionData)>0) {
1013
                $action = key($actionData);
1014
                $controller = $actionData[$action];
1015
                $view = $this->forward()->dispatch(
1016
                    $controller,
1017
                    array(
1018
                        'action' => $action,
1019
                        'id' => $game->getIdentifier()
1020
                    )
1021
                );
1022
            }
1023
            // suite au forward, le template de layout a changé, je dois le rétablir...
1024
            $this->layout()->setTemplate($beforeLayout);
1025
        }
1026
1027
        return $view;
1028
    }
1029
1030
    public function addMetaBitly()
1031
    {
1032
        $bitlyclient = $this->getOptions()->getBitlyUrl();
1033
        $bitlyuser = $this->getOptions()->getBitlyUsername();
1034
        $bitlykey = $this->getOptions()->getBitlyApiKey();
1035
1036
        $this->getViewHelper('HeadMeta')->setProperty('bt:client', $bitlyclient);
1037
        $this->getViewHelper('HeadMeta')->setProperty('bt:user', $bitlyuser);
1038
        $this->getViewHelper('HeadMeta')->setProperty('bt:key', $bitlykey);
1039
    }
1040
1041
    /**
1042
     * @param \PlaygroundGame\Entity\Game $game
1043
     */
1044
    public function addGaEvent($game)
1045
    {
1046
        // Google Analytics event
1047
        $ga = $this->getServiceLocator()->get('google-analytics');
1048
        $event = new \PlaygroundCore\Analytics\Event($game->getClassType(), $this->params('action'));
1049
        $event->setLabel($game->getTitle());
1050
        $ga->addEvent($event);
1051
    }
1052
1053
    /**
1054
     * @param \PlaygroundGame\Entity\Game $game
1055
     */
1056
    public function addMetaTitle($game)
1057
    {
1058
        $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...
1059
        $this->getGameService()->getServiceManager()->get('ViewHelperManager')->get('HeadTitle')->set($title);
1060
        // Meta set in the layout
1061
        $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...
1062
            array(
1063
                'breadcrumbTitle' => $title,
1064
                'currentPage' => array(
1065
                    'pageGames' => 'games',
1066
                    'pageWinners' => ''
1067
                ),
1068
                'headParams' => array(
1069
                    'headTitle' => $title,
1070
                    'headDescription' => $title,
1071
                ),
1072
                'bodyCss' => $game->getIdentifier()
1073
            )
1074
        );
1075
    }
1076
1077
    /**
1078
     * @param \PlaygroundGame\Entity\Game $game
1079
     */
1080
    public function customizeGameDesign($game)
1081
    {
1082
        // If this game has a specific layout...
1083
        if ($game->getLayout()) {
1084
            $layoutViewModel = $this->layout();
1085
            $layoutViewModel->setTemplate($game->getLayout());
1086
        }
1087
1088
        // If this game has a specific stylesheet...
1089
        if ($game->getStylesheet()) {
1090
            $this->getViewHelper('HeadLink')->appendStylesheet(
1091
                $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...
1092
            );
1093
        }
1094
    }
1095
1096
    /**
1097
     * @param \PlaygroundGame\Entity\Game $game
1098
     */
1099
    public function getShareData($game)
1100
    {
1101
        $fo = $this->getServiceLocator()->get('facebook-opengraph');
1102
        $session = new Container('facebook');
1103
1104
        // I change the fbappid if i'm in fb
1105
        if ($session->offsetExists('signed_request')) {
1106
            $fo->setId($game->getFbAppId());
1107
        }
1108
1109
        // If I want to add a share block in my view
1110 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...
1111
            $fbShareMessage = $game->getFbShareMessage();
1112
        } else {
1113
            $fbShareMessage = str_replace(
1114
                '__placeholder__',
1115
                $game->getTitle(),
1116
                $this->getOptions()->getDefaultShareMessage()
1117
            );
1118
        }
1119
1120
        if ($game->getFbShareImage()) {
1121
            $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...
1122
                '',
1123
                array(),
1124
                array('force_canonical' => true),
1125
                false
1126
            ) . $game->getFbShareImage();
1127
        } else {
1128
            $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...
1129
                '',
1130
                array(),
1131
                array('force_canonical' => true),
1132
                false
1133
            ) . $game->getMainImage();
1134
        }
1135
1136
        $secretKey = strtoupper(substr(sha1(uniqid('pg_', true).'####'.time()), 0, 15));
1137
1138
        // Without bit.ly shortener
1139
        $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...
1140
            $game->getClassType(),
1141
            array('id' => $game->getIdentifier()),
1142
            array('force_canonical' => true)
1143
        );
1144
        // With core shortener helper
1145
        $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...
1146
1147
        // FB Requests only work when it's a FB app
1148
        if ($game->getFbRequestMessage()) {
1149
            $fbRequestMessage = urlencode($game->getFbRequestMessage());
1150
        } else {
1151
            $fbRequestMessage = str_replace(
1152
                '__placeholder__',
1153
                $game->getTitle(),
1154
                $this->getOptions()->getDefaultShareMessage()
1155
            );
1156
        }
1157
1158 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...
1159
            $twShareMessage = $game->getTwShareMessage() . $socialLinkUrl;
1160
        } else {
1161
            $twShareMessage = str_replace(
1162
                '__placeholder__',
1163
                $game->getTitle(),
1164
                $this->getOptions()->getDefaultShareMessage()
1165
            ) . $socialLinkUrl;
1166
        }
1167
1168
        $ogTitle = new \PlaygroundCore\Opengraph\Tag('og:title', $fbShareMessage);
1169
        $ogImage = new \PlaygroundCore\Opengraph\Tag('og:image', $fbShareImage);
1170
        
1171
        $fo->addTag($ogTitle);
1172
        $fo->addTag($ogImage);
1173
        
1174
        $data = array(
1175
            'socialLinkUrl'       => $socialLinkUrl,
1176
            'secretKey'           => $secretKey,
1177
            'fbShareMessage'      => $fbShareMessage,
1178
            'fbShareImage'        => $fbShareImage,
1179
            'fbRequestMessage'    => $fbRequestMessage,
1180
            'twShareMessage'      => $twShareMessage,
1181
        );
1182
1183
        return $data;
1184
    }
1185
    
1186
    /**
1187
     * return ajax response in json format
1188
     *
1189
     * @param array $data
1190
     * @return \Zend\View\Model\JsonModel
1191
     */
1192 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...
1193
    {
1194
        $model = new JsonModel(array(
1195
            'success' => true,
1196
            'data' => $data
1197
        ));
1198
        return $model->setTerminal(true);
1199
    }
1200
    
1201
    /**
1202
     * return ajax response in json format
1203
     *
1204
     * @param string $message
1205
     * @return \Zend\View\Model\JsonModel
1206
     */
1207 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...
1208
    {
1209
        $model = new JsonModel(array(
1210
            'success' => false,
1211
            'message' => $message
1212
        ));
1213
        return $model->setTerminal(true);
1214
    }
1215
1216
    /**
1217
     * @param string $helperName
1218
     */
1219
    protected function getViewHelper($helperName)
1220
    {
1221
        return $this->getServiceLocator()->get('viewhelpermanager')->get($helperName);
1222
    }
1223
1224
    public function getGameService()
1225
    {
1226
        if (!$this->gameService) {
1227
            $this->gameService = $this->getServiceLocator()->get('playgroundgame_lottery_service');
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->getServiceLocator...dgame_lottery_service') can also be of type array. However, the property $gameService is declared as type object<PlaygroundGame\Service\GameService>. Maybe add an additional type check?

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

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

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

class Id
{
    public $id;

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

}

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

$account_id = false;

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

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
1228
        }
1229
1230
        return $this->gameService;
1231
    }
1232
1233
    public function setGameService(GameService $gameService)
1234
    {
1235
        $this->gameService = $gameService;
1236
1237
        return $this;
1238
    }
1239
1240
    public function getPrizeService()
1241
    {
1242
        if (!$this->prizeService) {
1243
            $this->prizeService = $this->getServiceLocator()->get('playgroundgame_prize_service');
1244
        }
1245
1246
        return $this->prizeService;
1247
    }
1248
1249
    public function setPrizeService(PrizeService $prizeService)
1250
    {
1251
        $this->prizeService = $prizeService;
1252
1253
        return $this;
1254
    }
1255
1256
    public function getOptions()
1257
    {
1258
        if (!$this->options) {
1259
            $this->setOptions($this->getServiceLocator()->get('playgroundcore_module_options'));
1260
        }
1261
1262
        return $this->options;
1263
    }
1264
1265
    public function setOptions($options)
1266
    {
1267
        $this->options = $options;
1268
1269
        return $this;
1270
    }
1271
}
1272