Completed
Push — develop ( d4b566...117c35 )
by greg
04:46
created

GameController::fangateAction()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 5
Bugs 1 Features 0
Metric Value
c 5
b 1
f 0
dl 0
loc 6
rs 9.4286
cc 1
eloc 3
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 $withAnyUser = array(
58
        'share',
59
        'result',
60
        'play'
61
    );
62
63
    public function setEventManager(\Zend\EventManager\EventManagerInterface $events)
64
    {
65
        parent::setEventManager($events);
66
67
        $controller = $this;
68
        $events->attach('dispatch', function (\Zend\Mvc\MvcEvent $e) use ($controller) {
69
70
            $identifier = $e->getRouteMatch()->getParam('id');
71
            $controller->game = $controller->getGameService()->checkGame($identifier, false);
72
            if (!$controller->game &&
73
                in_array($controller->params('action'), $controller->withGame)
74
            ) {
75
                return $controller->notFoundAction();
76
            }
77
78
            if ($controller->game &&
79
                $controller->game->isClosed() &&
80
                in_array($controller->params('action'), $controller->withOnlineGame)
81
            ) {
82
                return $controller->notFoundAction();
83
            }
84
85
            $controller->user = $controller->zfcUserAuthentication()->getIdentity();
0 ignored issues
show
Documentation Bug introduced by
The method zfcUserAuthentication does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
86
            if ($controller->game &&
87
                !$controller->user &&
88
                !$controller->game->getAnonymousAllowed() &&
89
                in_array($controller->params('action'), $controller->withAnyUser)
90
            ) {
91
                $redirect = urlencode(
92
                    $controller->url()->fromRoute(
93
                        'frontend/'.$controller->game->getClassType() . '/' . $controller->params('action'),
94
                        array('id' => $controller->game->getIdentifier()),
95
                        array('force_canonical' => true)
96
                    )
97
                );
98
99
                $urlRegister = ($controller->game->getAnonymousAllowed())?
100
                    $controller->url()->fromRoute(
101
                        'frontend/'.$controller->game->getClassType().'/register',
102
                        array()
103
                    ) . '?redirect='.$redirect :
104
                    $controller->url()->fromRoute(
105
                        'frontend/zfcuser/register',
106
                        array(),
107
                        array('force_canonical' => true)
108
                    ) . '?redirect='.$redirect;
109
110
                $config = $controller->getGameService()->getServiceManager()->get('config');
111
                $customUrl = str_replace('frontend.', '', $e->getRouteMatch()->getParam('area'));
112
                // custom game
113
                if(
114
                    $config['custom_games'][$controller->game->getIdentifier()] && 
115
                    $controller->getRequest()->getUri()->getHost() === $customUrl
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Zend\Stdlib\RequestInterface as the method getUri() does only exist in the following implementations of said interface: Zend\Http\PhpEnvironment\Request, Zend\Http\Request.

Let’s take a look at an example:

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

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

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

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

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

Available Fixes

  1. Change the type-hint for the parameter:

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

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

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
116
                ){
117
                    return $controller->redirect()->toUrl($urlRegister);
118
                } else {
119
                    return $controller->redirect()->toUrl($urlRegister);
120
                }
121
            }
122
123
            return;
124
        }, 100); // execute before executing action logic
125
    }
126
127
    /**
128
     * Action called if matched action does not exist
129
     * For this view not to be catched by Zend\Mvc\View\RouteNotFoundStrategy
130
     * it has to be rendered in the controller. Hence the code below.
131
     *
132
     * This action is injected as a catchall action for each custom_games definition
133
     * This way, when a custom_game is created, the 404 is it's responsability and the
134
     * view can be defined in design/frontend/default/custom/$slug/playground_game/$gametype/404.phtml
135
     *
136
     *
137
     * @return \Zend\Stdlib\ResponseInterface
138
     */
139
    public function notFoundAction()
140
    {
141
        $viewRender     = $this->getServiceLocator()->get('ViewRenderer');
142
143
        $this->getEvent()->getRouteMatch()->setParam('action', 'not-found');
144
        $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...
145
146
        $res = 'error/404';
147
148
        $viewModel = $this->buildView($this->game);
149
        $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...
150
151
        $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...
152
        $this->response->setContent($viewRender->render($this->layout()));
153
154
        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...
155
    }
156
157
    /**
158
     * This action acts as a hub : Depending on the first step of the game, it will forward the action to this step
159
     */
160
    public function homeAction()
161
    {
162
        // This fix exists only for safari in FB on Windows : we need to redirect the user to the page
163
        // outside of iframe for the cookie to be accepted. PlaygroundCore redirects to the FB Iframed page when
164
        // it discovers that the user arrives for the first time on the game in FB.
165
        // When core redirects, it adds a 'redir_fb_page_id' var in the querystring
166
        // Here, we test if this var exist, and then send the user back to the game in FB.
167
        // Now the cookie will be accepted by Safari...
168
        $pageId = $this->params()->fromQuery('redir_fb_page_id');
169
        if (!empty($pageId)) {
170
            $appId = 'app_'.$this->game->getFbAppId();
171
            $url = '//www.facebook.com/pages/game/'.$pageId.'?sk='.$appId;
172
173
            return $this->redirect()->toUrl($url);
174
        }
175
176
        // If an entry has already been done during this session, I reset the anonymous_identifier cookie
177
        // so that another person can play the same game (if game conditions are fullfilled)
178
        $session = new Container('anonymous_identifier');
179
        if ($session->offsetExists('anonymous_identifier')) {
180
            $session->offsetUnset('anonymous_identifier');
181
        }
182
        
183
        return $this->forward()->dispatch(
184
            'playgroundgame_'.$this->game->getClassType(),
185
            array(
186
                'controller' => 'playgroundgame_'.$this->game->getClassType(),
187
                'action' => $this->game->firstStep(),
188
                'id' => $this->game->getIdentifier()
189
            )
190
        );
191
    }
192
193
    /**
194
     * Homepage of the game
195
     */
196
    public function indexAction()
197
    {
198
        $isSubscribed = false;
199
200
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
201
        if ($entry) {
202
            $isSubscribed = true;
203
        }
204
205
        $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 210 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...
206
        $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...
207
            'isSubscribed' => $isSubscribed
208
        ));
209
210
        return $viewModel;
211
    }
212
213
    /**
214
      * leaderboardAction
215
      *
216
      * @return ViewModel $viewModel
217
      */
218
    public function leaderboardAction()
219
    {
220
        $filter = $this->getEvent()->getRouteMatch()->getParam('filter');
221
        $p = $this->getEvent()->getRouteMatch()->getParam('p');
222
223
        $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...
224
        $subViewModel = $this->forward()->dispatch(
225
            'playgroundreward',
226
            array('action' => 'leaderboard', 'filter' => $filter, 'p' => $p)
227
        );
228
        
229
        // suite au forward, le template de layout a changé, je dois le rétablir...
230
        $this->layout()->setTemplate($beforeLayout);
231
232
        // give the ability to the game to have its customized look and feel.
233
        $templatePathResolver = $this->getServiceLocator()->get('Zend\View\Resolver\TemplatePathStack');
234
        $l = $templatePathResolver->getPaths();
235
236
        $templatePathResolver->addPath($l[0].'custom/'.$this->game->getIdentifier());
237
238
        return $subViewModel;
239
    }
240
241
    /**
242
     * This action has been designed to be called by other controllers
243
     * It gives the ability to display an information form and persist it in the game entry
244
     *
245
     * @return \Zend\View\Model\ViewModel
246
     */
247
    public function registerAction()
248
    {
249
        $form = $this->getGameService()->createFormFromJson($this->game->getPlayerForm()->getForm(), 'playerForm');
250
251
        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...
252
            // POST Request: Process form
253
            $data = array_merge_recursive(
254
                $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...
255
                $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...
256
            );
257
            
258
            $form->setData($data);
259
260
            if ($form->isValid()) {
261
                // steps of the game
262
                $steps = $this->game->getStepsArray();
263
                // sub steps of the game
264
                $viewSteps = $this->game->getStepsViewsArray();
265
266
                // register position
267
                $key = array_search($this->params('action'), $viewSteps);
268
                if (!$key) {
269
                    // register is not a substep of the game so it's a step
270
                    $key = array_search($this->params('action'), $steps);
271
                    $keyStep = true;
272
                } else {
273
                    // register was a substep, i search the index of its parent
274
                    $key = array_search($key, $steps);
275
                    $keyStep = false;
276
                }
277
278
                // play position
279
                $keyplay = array_search('play', $viewSteps);
280
281
                if (!$keyplay) {
282
                    // play is not a substep, so it's a step
283
                    $keyplay = array_search('play', $steps);
284
                    $keyplayStep = true;
285
                } else {
286
                    // play is a substep so I search the index of its parent
287
                    $keyplay = array_search($keyplay, $steps);
288
                    $keyplayStep = false;
289
                }
290
291
                // If register step before play, I don't have no entry yet. I have to create one
292
                // If register after play step, I search for the last entry created by play step.
293
294
                if ($key < $keyplay || ($keyStep && !$keyplayStep && $key <= $keyplay)) {
295
                    $entry = $this->getGameService()->play($this->game, $this->user);
296
                    if (!$entry) {
297
                        // the user has already taken part of this game and the participation limit has been reached
298
                        $this->flashMessenger()->addMessage('Vous avez déjà participé');
299
                    
300
                        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...
301
                            $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...
302
                                $this->game->getClassType().'/result',
303
                                array(
304
                                    'id' => $this->game->getIdentifier(),
305
                                    
306
                                )
307
                            )
308
                        );
309
                    }
310
                } else {
311
                    // I'm looking for an entry without anonymousIdentifier (the active entry in fact).
312
                    $entry = $this->getGameService()->findLastEntry($this->game, $this->user);
313
                    if ($this->getGameService()->hasReachedPlayLimit($this->game, $this->user)) {
314
                        // the user has already taken part of this game and the participation limit has been reached
315
                        $this->flashMessenger()->addMessage('Vous avez déjà participé');
316
                    
317
                        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...
318
                            $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...
319
                                $this->game->getClassType().'/result',
320
                                array(
321
                                    'id' => $this->game->getIdentifier(),
322
                                    
323
                                )
324
                            )
325
                        );
326
                    }
327
                }
328
329
                $this->getGameService()->updateEntryPlayerForm($form->getData(), $this->game, $this->user, $entry);
330
331
                if (!empty($this->game->nextStep($this->params('action')))) {
332
                    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...
333
                        $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...
334
                            $this->game->getClassType() .'/' . $this->game->nextStep($this->params('action')),
335
                            array('id' => $this->game->getIdentifier()),
336
                            array('force_canonical' => true)
337
                        )
338
                    );
339
                }
340
            }
341
        }
342
343
        $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 348 which is incompatible with the return type documented by PlaygroundGame\Controlle...troller::registerAction of type Zend\View\Model\ViewModel.
Loading history...
344
        $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...
345
            'form' => $form
346
        ));
347
348
        return $viewModel;
349
    }
350
351
    /**
352
     * This action takes care of the terms of the game
353
     */
354
    public function termsAction()
355
    {
356
        $viewModel = $this->buildView($this->game);
357
358
        return $viewModel;
359
    }
360
361
    /**
362
     * This action takes care of the conditions of the game
363
     */
364
    public function conditionsAction()
365
    {
366
        $viewModel = $this->buildView($this->game);
367
368
        return $viewModel;
369
    }
370
371
    /**
372
     * This action takes care of bounce page of the game
373
     */
374
    public function bounceAction()
375
    {
376
        $availableGames = $this->getGameService()->getAvailableGames($this->user);
377
378
        $rssUrl = '';
379
        $config = $this->getGameService()->getServiceManager()->get('config');
380
        if (isset($config['rss']['url'])) {
381
            $rssUrl = $config['rss']['url'];
382
        }
383
384
        $viewModel = $this->buildView($this->game);
385
        $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...
386
            'rssUrl'         => $rssUrl,
387
            'user'           => $this->user,
388
            'availableGames' => $availableGames,
389
        ));
390
391
        return $viewModel;
392
    }
393
394
395
    /**
396
     * This action displays the Prizes page associated to the game
397
     */
398
    public function prizesAction()
399
    {
400
        if (count($this->game->getPrizes()) == 0) {
401
            return $this->notFoundAction();
402
        }
403
404
        $viewModel = $this->buildView($this->game);
405
406
        return $viewModel;
407
    }
408
409
    /**
410
     * This action displays a specific Prize page among those associated to the game
411
     */
412
    public function prizeAction()
413
    {
414
        $prizeIdentifier = $this->getEvent()->getRouteMatch()->getParam('prize');
415
        $prize = $this->getPrizeService()->getPrizeMapper()->findByIdentifier($prizeIdentifier);
416
        
417
        if (!$prize) {
418
            return $this->notFoundAction();
419
        }
420
421
        $viewModel = $this->buildView($this->game);
422
        $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...
423
424
        return $viewModel;
425
    }
426
427
    public function gameslistAction()
428
    {
429
        $layoutViewModel = $this->layout();
430
431
        $slider = new ViewModel();
432
        $slider->setTemplate('playground-game/common/top_promo');
433
434
        $sliderItems = $this->getGameService()->getActiveSliderGames();
435
436
        $slider->setVariables(array('sliderItems' => $sliderItems));
437
438
        $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...
439
440
        $games = $this->getGameService()->getActiveGames(false, '', 'endDate');
441
        if (is_array($games)) {
442
            $paginator = new \Zend\Paginator\Paginator(new \Zend\Paginator\Adapter\ArrayAdapter($games));
443
        } else {
444
            $paginator = $games;
445
        }
446
447
        $paginator->setItemCountPerPage(7);
448
        $paginator->setCurrentPageNumber($this->getEvent()->getRouteMatch()->getParam('p'));
449
450
        $bitlyclient = $this->getOptions()->getBitlyUrl();
451
        $bitlyuser = $this->getOptions()->getBitlyUsername();
452
        $bitlykey = $this->getOptions()->getBitlyApiKey();
453
454
        $this->getViewHelper('HeadMeta')->setProperty('bt:client', $bitlyclient);
455
        $this->getViewHelper('HeadMeta')->setProperty('bt:user', $bitlyuser);
456
        $this->getViewHelper('HeadMeta')->setProperty('bt:key', $bitlykey);
457
458
        $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...
459
            array(
460
            'sliderItems'   => $sliderItems,
461
            'currentPage' => array(
462
                'pageGames' => 'games',
463
                'pageWinners' => ''
464
            ),
465
            )
466
        );
467
468
        return new ViewModel(
469
            array(
470
                'games'       => $paginator
471
            )
472
        );
473
    }
474
475
    public function fangateAction()
476
    {
477
        $viewModel = $this->buildView($this->game);
478
479
        return $viewModel;
480
    }
481
    
482
    public function shareAction()
483
    {
484
        $statusMail = null;
485
    
486
        // Has the user finished the game ?
487
        $lastEntry = $this->getGameService()->findLastInactiveEntry($this->game, $this->user);
488
    
489
        if ($lastEntry === null) {
490
            return $this->redirect()->toUrl(
491
                $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...
492
                    'postvote',
493
                    array('id' => $this->game->getIdentifier())
494
                )
495
            );
496
        }
497
    
498
        $form = $this->getServiceLocator()->get('playgroundgame_sharemail_form');
499
        $form->setAttribute('method', 'post');
500
    
501 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...
502
            $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...
503
            $form->setData($data);
504
            if ($form->isValid()) {
505
                $result = $this->getGameService()->sendShareMail($data, $this->game, $this->user, $lastEntry);
506
                if ($result) {
507
                    $statusMail = true;
508
                }
509
            }
510
        }
511
    
512
        // buildView must be before sendMail because it adds the game template path to the templateStack
513
        $viewModel = $this->buildView($this->game);
514
    
515
        $this->getGameService()->sendMail($this->game, $this->user, $lastEntry);
516
    
517
        $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...
518
            'statusMail'       => $statusMail,
519
            'form'             => $form,
520
        ));
521
    
522
        return $viewModel;
523
    }
524
    
525 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...
526
    {
527
        $viewModel = new JsonModel();
528
        $viewModel->setTerminal(true);
529
        $fbId = $this->params()->fromQuery('fbId');
530
        if (!$this->game) {
531
            return $this->errorJson();
532
        }
533
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
534
        if (! $entry) {
535
            return $this->errorJson();
536
        }
537
        if (!$fbId) {
538
            return $this->errorJson();
539
        }
540
    
541
        $this->getGameService()->postFbWall($fbId, $this->game, $this->user, $entry);
542
    
543
        return $this->successJson();
544
    }
545
    
546
    public function fbrequestAction()
547
    {
548
        $viewModel = new ViewModel();
549
        $viewModel->setTerminal(true);
550
        $fbId = $this->params()->fromQuery('fbId');
551
        $to = $this->params()->fromQuery('to');
552
    
553
        if (!$this->game) {
554
            return $this->errorJson();
555
        }
556
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
557
        if (! $entry) {
558
            return $this->errorJson();
559
        }
560
        if (!$fbId) {
561
            return $this->errorJson();
562
        }
563
    
564
        $this->getGameService()->postFbRequest($fbId, $this->game, $this->user, $entry, $to);
565
    
566
        return $this->successJson();
567
    }
568
    
569
    public function tweetAction()
570
    {
571
        $tweetId = $this->params()->fromQuery('tweetId');
572
    
573
        if (!$this->game) {
574
            return $this->errorJson();
575
        }
576
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
577
        if (! $entry) {
578
            return $this->errorJson();
579
        }
580
        if (!$tweetId) {
581
            return $this->errorJson();
582
        }
583
    
584
        $this->getGameService()->postTwitter($tweetId, $this->game, $this->user, $entry);
585
    
586
        return $this->successJson();
587
    }
588
    
589 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...
590
    {
591
        $viewModel = new ViewModel();
592
        $viewModel->setTerminal(true);
593
        $googleId = $this->params()->fromQuery('googleId');
594
595
        if (!$this->game) {
596
            return $this->errorJson();
597
        }
598
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
599
        if (! $entry) {
600
            return $this->errorJson();
601
        }
602
        if (!$googleId) {
603
            return $this->errorJson();
604
        }
605
    
606
        $this->getGameService()->postGoogle($googleId, $this->game, $this->user, $entry);
607
    
608
        return $this->successJson();
609
    }
610
611
    public function optinAction()
612
    {
613
        $userService = $this->getServiceLocator()->get('zfcuser_user_service');
614
615
        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...
616
            $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...
617
            $data['optinPartner'] = ($this->params()->fromPost('optinPartner'))? 1:0;
618
619
            $userService->updateNewsletter($data);
620
        }
621
622
        return $this->redirect()->toUrl(
623
            $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...
624
                'frontend/' . $this->game->getClassType() . '/index',
625
                array('id' => $this->game->getIdentifier())
626
            )
627
        );
628
    }
629
    
630
    public function loginAction()
631
    {
632
        $request = $this->getRequest();
633
        $form = $this->getServiceLocator()->get('zfcuser_login_form');
634
    
635
        if ($request->isPost()) {
636
            $form->setData($request->getPost());
637
            
638
            if (!$form->isValid()) {
639
                $this->flashMessenger()->setNamespace('zfcuser-login-form')->addMessage(
640
                    'Authentication failed. Please try again.'
641
                );
642
                
643
644
                return $this->redirect()->toUrl(
645
                    $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...
646
                        $this->game->getClassType() . '/login',
647
                        array('id' => $this->game->getIdentifier())
648
                    )
649
                );
650
            }
651
            
652
            // clear adapters
653
            $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...
654
            $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...
655
656
            $logged = $this->forward()->dispatch('playgrounduser_user', array('action' => 'ajaxauthenticate'));
657
658 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...
659
                $this->flashMessenger()->setNamespace('zfcuser-login-form')->addMessage(
660
                    'Authentication failed. Please try again.'
661
                );
662
                
663
                return $this->redirect()->toUrl(
664
                    $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...
665
                        $this->game->getClassType() . '/login',
666
                        array('id' => $this->game->getIdentifier())
667
                    )
668
                );
669
            } else {
670
                return $this->redirect()->toUrl(
671
                    $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...
672
                        $this->game->getClassType() . '/' . $this->game->nextStep('index'),
673
                        array('id' => $this->game->getIdentifier())
674
                    )
675
                );
676
            }
677
        }
678
        
679
        $form->setAttribute(
680
            'action',
681
            $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...
682
                $this->game->getClassType().'/login',
683
                array('id' => $this->game->getIdentifier())
684
            )
685
        );
686
        $viewModel = $this->buildView($this->game);
687
        $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...
688
            'form' => $form,
689
        ));
690
        return $viewModel;
691
    }
692
693
    public function userregisterAction()
694
    {
695
        $userOptions = $this->getServiceLocator()->get('zfcuser_module_options');
696
697
        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...
698
            return $this->redirect()->toUrl(
699
                $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...
700
                    $this->game->getClassType().'/'.$this->game->nextStep('index'),
701
                    array('id' => $this->game->getIdentifier())
702
                )
703
            );
704
        }
705
        $request = $this->getRequest();
706
        $service = $this->getServiceLocator()->get('zfcuser_user_service');
707
        $form = $this->getServiceLocator()->get('playgroundgame_register_form');
708
        $socialnetwork = $this->params()->fromRoute('socialnetwork', false);
709
        $form->setAttribute(
710
            'action',
711
            $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...
712
                $this->game->getClassType().'/user-register',
713
                array('id' => $this->game->getIdentifier())
714
            )
715
        );
716
        $params = array();
717
        $socialCredentials = array();
718
719
        if ($userOptions->getUseRedirectParameterIfPresent() && $request->getQuery()->get('redirect')) {
720
            $redirect = $request->getQuery()->get('redirect');
721
        } else {
722
            $redirect = false;
723
        }
724
725
        if ($socialnetwork) {
726
            $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...
727
728
            if (!empty($infoMe)) {
729
                $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...
730
                    $infoMe->identifier,
731
                    $socialnetwork
732
                );
733
734
                if ($user || $service->getOptions()->getCreateUserAutoSocial() === true) {
735
                    //on le dirige vers l'action d'authentification
736
                    if (! $redirect && $userOptions->getLoginRedirectRoute() != '') {
737
                        $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...
738
                            $this->game->getClassType().'/login',
739
                            array('id' => $this->game->getIdentifier())
740
                        );
741
                    }
742
                    $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...
743
                        $this->game->getClassType().'/login',
744
                        array('id' => $this->game->getIdentifier())
745
                    ) .'/' . $socialnetwork . ($redirect ? '?redirect=' . $redirect : '');
746
747
                    return $this->redirect()->toUrl($redir);
748
                }
749
750
                // Je retire la saisie du login/mdp
751
                $form->setAttribute(
752
                    'action',
753
                    $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...
754
                        $this->game->getClassType().'/user-register',
755
                        array(
756
                            'id' => $this->game->getIdentifier(),
757
                            'socialnetwork' => $socialnetwork,
758
                            
759
                        )
760
                    )
761
                );
762
                $form->remove('password');
763
                $form->remove('passwordVerify');
764
765
                $birthMonth = $infoMe->birthMonth;
766
                if (strlen($birthMonth) <= 1) {
767
                    $birthMonth = '0'.$birthMonth;
768
                }
769
                $birthDay = $infoMe->birthDay;
770
                if (strlen($birthDay) <= 1) {
771
                    $birthDay = '0'.$birthDay;
772
                }
773
774
                $gender = $infoMe->gender;
775
                if ($gender == 'female') {
776
                    $title = 'Me';
777
                } else {
778
                    $title = 'M';
779
                }
780
781
                $params = array(
782
                    //'birth_year'  => $infoMe->birthYear,
783
                    'title'      => $title,
784
                    'dob'      => $birthDay.'/'.$birthMonth.'/'.$infoMe->birthYear,
785
                    'firstname'   => $infoMe->firstName,
786
                    'lastname'    => $infoMe->lastName,
787
                    'email'       => $infoMe->email,
788
                    'postalCode' => $infoMe->zip,
789
                );
790
                $socialCredentials = array(
791
                    'socialNetwork' => strtolower($socialnetwork),
792
                    'socialId'      => $infoMe->identifier,
793
                );
794
            }
795
        }
796
797
        $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...
798
            $this->game->getClassType().'/user-register',
799
            array('id' => $this->game->getIdentifier())
800
        ) .($socialnetwork ? '/' . $socialnetwork : ''). ($redirect ? '?redirect=' . $redirect : '');
801
        $prg = $this->prg($redirectUrl, true);
802
803
        if ($prg instanceof Response) {
804
            return $prg;
805
        } elseif ($prg === false) {
806
            $form->setData($params);
807
            $viewModel = $this->buildView($this->game);
808
            $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...
809
                'registerForm' => $form,
810
                'enableRegistration' => $userOptions->getEnableRegistration(),
811
                'redirect' => $redirect,
812
            ));
813
            return $viewModel;
814
        }
815
816
        $post = $prg;
817
        $post = array_merge(
818
            $post,
819
            $socialCredentials
820
        );
821
822
        $user = $service->register($post, 'playgroundgame_register_form');
823
824
        if (! $user) {
825
            $viewModel = $this->buildView($this->game);
826
            $viewModel->setVariables(array(
827
                'registerForm' => $form,
828
                'enableRegistration' => $userOptions->getEnableRegistration(),
829
                'redirect' => $redirect,
830
            ));
831
            
832
            return $viewModel;
833
        }
834
835
        if ($service->getOptions()->getEmailVerification()) {
836
            $vm = new ViewModel(array('userEmail' => $user->getEmail()));
837
            $vm->setTemplate('playground-user/register/registermail');
838
839
            return $vm;
840
        } elseif ($service->getOptions()->getLoginAfterRegistration()) {
841
            $identityFields = $service->getOptions()->getAuthIdentityFields();
842
            if (in_array('email', $identityFields)) {
843
                $post['identity'] = $user->getEmail();
844
            } elseif (in_array('username', $identityFields)) {
845
                $post['identity'] = $user->getUsername();
846
            }
847
            $post['credential'] = isset($post['password'])?$post['password']:'';
848
            $request->setPost(new Parameters($post));
849
850
            // clear adapters
851
            $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...
852
            $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...
853
854
            $logged = $this->forward()->dispatch('playgrounduser_user', array('action' => 'ajaxauthenticate'));
855
856 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...
857
                return $this->redirect()->toUrl(
858
                    $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

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