Completed
Pull Request — master (#264)
by greg
02:58
created

GameController::checkFbRegistration()   B

Complexity

Conditions 6
Paths 10

Size

Total Lines 49
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

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

Let’s take a look at an example:

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

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

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

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

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

Available Fixes

  1. Change the type-hint for the parameter:

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

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

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

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

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

Loading history...
484
            $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...
485
            $form->setData($data);
486
            if ($form->isValid()) {
487
                $result = $this->getGameService()->sendShareMail($data, $this->game, $this->user, $lastEntry);
488
                if ($result) {
489
                    $statusMail = true;
490
                }
491
            }
492
        }
493
    
494
        // buildView must be before sendMail because it adds the game template path to the templateStack
495
        $viewModel = $this->buildView($this->game);
496
    
497
        $this->getGameService()->sendMail($this->game, $this->user, $lastEntry);
498
    
499
        $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...
500
            'statusMail'       => $statusMail,
501
            'form'             => $form,
502
        ));
503
    
504
        return $viewModel;
505
    }
506
    
507 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...
508
    {
509
        $viewModel = new JsonModel();
510
        $viewModel->setTerminal(true);
511
        $fbId = $this->params()->fromQuery('fbId');
512
        if (!$this->game) {
513
            return $this->errorJson();
514
        }
515
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
516
        if (! $entry) {
517
            return $this->errorJson();
518
        }
519
        if (!$fbId) {
520
            return $this->errorJson();
521
        }
522
    
523
        $this->getGameService()->postFbWall($fbId, $this->game, $this->user, $entry);
524
    
525
        return $this->successJson();
526
    }
527
    
528
    public function fbrequestAction()
529
    {
530
        $viewModel = new ViewModel();
531
        $viewModel->setTerminal(true);
532
        $fbId = $this->params()->fromQuery('fbId');
533
        $to = $this->params()->fromQuery('to');
534
    
535
        if (!$this->game) {
536
            return $this->errorJson();
537
        }
538
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
539
        if (! $entry) {
540
            return $this->errorJson();
541
        }
542
        if (!$fbId) {
543
            return $this->errorJson();
544
        }
545
    
546
        $this->getGameService()->postFbRequest($fbId, $this->game, $this->user, $entry, $to);
547
    
548
        return $this->successJson();
549
    }
550
    
551
    public function tweetAction()
552
    {
553
        $tweetId = $this->params()->fromQuery('tweetId');
554
    
555
        if (!$this->game) {
556
            return $this->errorJson();
557
        }
558
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
559
        if (! $entry) {
560
            return $this->errorJson();
561
        }
562
        if (!$tweetId) {
563
            return $this->errorJson();
564
        }
565
    
566
        $this->getGameService()->postTwitter($tweetId, $this->game, $this->user, $entry);
567
    
568
        return $this->successJson();
569
    }
570
    
571 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...
572
    {
573
        $viewModel = new ViewModel();
574
        $viewModel->setTerminal(true);
575
        $googleId = $this->params()->fromQuery('googleId');
576
577
        if (!$this->game) {
578
            return $this->errorJson();
579
        }
580
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
581
        if (! $entry) {
582
            return $this->errorJson();
583
        }
584
        if (!$googleId) {
585
            return $this->errorJson();
586
        }
587
    
588
        $this->getGameService()->postGoogle($googleId, $this->game, $this->user, $entry);
589
    
590
        return $this->successJson();
591
    }
592
593
    public function optinAction()
594
    {
595
        $userService = $this->getServiceLocator()->get('zfcuser_user_service');
596
597
        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...
598
            $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...
599
            $data['optinPartner'] = ($this->params()->fromPost('optinPartner'))? 1:0;
600
601
            $userService->updateNewsletter($data);
602
        }
603
604
        return $this->redirect()->toUrl(
605
            $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...
606
                'frontend/' . $this->game->getClassType() . '/index',
607
                array('id' => $this->game->getIdentifier())
608
            )
609
        );
610
    }
611
    
612
    public function loginAction()
613
    {
614
        $request = $this->getRequest();
615
        $form = $this->getServiceLocator()->get('zfcuser_login_form');
616
    
617
        if ($request->isPost()) {
618
            $form->setData($request->getPost());
619
            
620
            if (!$form->isValid()) {
621
                $this->flashMessenger()->setNamespace('zfcuser-login-form')->addMessage(
622
                    'Authentication failed. Please try again.'
623
                );
624
                
625
626
                return $this->redirect()->toUrl(
627
                    $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...
628
                        $this->game->getClassType() . '/login',
629
                        array('id' => $this->game->getIdentifier())
630
                    )
631
                );
632
            }
633
            
634
            // clear adapters
635
            $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...
636
            $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...
637
638
            $logged = $this->forward()->dispatch('playgrounduser_user', array('action' => 'ajaxauthenticate'));
639
640 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...
641
                $this->flashMessenger()->setNamespace('zfcuser-login-form')->addMessage(
642
                    'Authentication failed. Please try again.'
643
                );
644
                
645
                return $this->redirect()->toUrl(
646
                    $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...
647
                        $this->game->getClassType() . '/login',
648
                        array('id' => $this->game->getIdentifier())
649
                    )
650
                );
651
            } else {
652
                return $this->redirect()->toUrl(
653
                    $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...
654
                        $this->game->getClassType() . '/' . $this->game->nextStep('index'),
655
                        array('id' => $this->game->getIdentifier())
656
                    )
657
                );
658
            }
659
        }
660
        
661
        $form->setAttribute(
662
            'action',
663
            $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...
664
                $this->game->getClassType().'/login',
665
                array('id' => $this->game->getIdentifier())
666
            )
667
        );
668
        $viewModel = $this->buildView($this->game);
669
        $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...
670
            'form' => $form,
671
        ));
672
        return $viewModel;
673
    }
674
675
    public function userregisterAction()
676
    {
677
        $userOptions = $this->getServiceLocator()->get('zfcuser_module_options');
678
679
        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...
680
            return $this->redirect()->toUrl(
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().'/'.$this->game->nextStep('index'),
683
                    array('id' => $this->game->getIdentifier())
684
                )
685
            );
686
        }
687
        $request = $this->getRequest();
688
        $service = $this->getServiceLocator()->get('zfcuser_user_service');
689
        $form = $this->getServiceLocator()->get('playgroundgame_register_form');
690
        $socialnetwork = $this->params()->fromRoute('socialnetwork', false);
691
        $form->setAttribute(
692
            'action',
693
            $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...
694
                $this->game->getClassType().'/user-register',
695
                array('id' => $this->game->getIdentifier())
696
            )
697
        );
698
        $params = array();
699
        $socialCredentials = array();
700
701
        if ($userOptions->getUseRedirectParameterIfPresent() && $request->getQuery()->get('redirect')) {
702
            $redirect = $request->getQuery()->get('redirect');
703
        } else {
704
            $redirect = false;
705
        }
706
707
        if ($socialnetwork) {
708
            $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...
709
710
            if (!empty($infoMe)) {
711
                $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...
712
                    $infoMe->identifier,
713
                    $socialnetwork
714
                );
715
716
                if ($user || $service->getOptions()->getCreateUserAutoSocial() === true) {
717
                    //on le dirige vers l'action d'authentification
718
                    if (! $redirect && $userOptions->getLoginRedirectRoute() != '') {
719
                        $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...
720
                            $this->game->getClassType().'/login',
721
                            array('id' => $this->game->getIdentifier())
722
                        );
723
                    }
724
                    $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...
725
                        $this->game->getClassType().'/login',
726
                        array('id' => $this->game->getIdentifier())
727
                    ) .'/' . $socialnetwork . ($redirect ? '?redirect=' . $redirect : '');
728
729
                    return $this->redirect()->toUrl($redir);
730
                }
731
732
                // Je retire la saisie du login/mdp
733
                $form->setAttribute(
734
                    'action',
735
                    $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...
736
                        $this->game->getClassType().'/user-register',
737
                        array(
738
                            'id' => $this->game->getIdentifier(),
739
                            'socialnetwork' => $socialnetwork,
740
                            
741
                        )
742
                    )
743
                );
744
                $form->remove('password');
745
                $form->remove('passwordVerify');
746
747
                $birthMonth = $infoMe->birthMonth;
748
                if (strlen($birthMonth) <= 1) {
749
                    $birthMonth = '0'.$birthMonth;
750
                }
751
                $birthDay = $infoMe->birthDay;
752
                if (strlen($birthDay) <= 1) {
753
                    $birthDay = '0'.$birthDay;
754
                }
755
756
                $gender = $infoMe->gender;
757
                if ($gender == 'female') {
758
                    $title = 'Me';
759
                } else {
760
                    $title = 'M';
761
                }
762
763
                $params = array(
764
                    //'birth_year'  => $infoMe->birthYear,
765
                    'title'      => $title,
766
                    'dob'      => $birthDay.'/'.$birthMonth.'/'.$infoMe->birthYear,
767
                    'firstname'   => $infoMe->firstName,
768
                    'lastname'    => $infoMe->lastName,
769
                    'email'       => $infoMe->email,
770
                    'postalCode' => $infoMe->zip,
771
                );
772
                $socialCredentials = array(
773
                    'socialNetwork' => strtolower($socialnetwork),
774
                    'socialId'      => $infoMe->identifier,
775
                );
776
            }
777
        }
778
779
        $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...
780
            $this->game->getClassType().'/user-register',
781
            array('id' => $this->game->getIdentifier())
782
        ) .($socialnetwork ? '/' . $socialnetwork : ''). ($redirect ? '?redirect=' . $redirect : '');
783
        $prg = $this->prg($redirectUrl, true);
784
785
        if ($prg instanceof Response) {
786
            return $prg;
787
        } elseif ($prg === false) {
788
            $form->setData($params);
789
            $viewModel = $this->buildView($this->game);
790
            $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...
791
                'registerForm' => $form,
792
                'enableRegistration' => $userOptions->getEnableRegistration(),
793
                'redirect' => $redirect,
794
            ));
795
            return $viewModel;
796
        }
797
798
        $post = $prg;
799
        $post = array_merge(
800
            $post,
801
            $socialCredentials
802
        );
803
804
        $user = $service->register($post, 'playgroundgame_register_form');
805
806
        if (! $user) {
807
            $viewModel = $this->buildView($this->game);
808
            $viewModel->setVariables(array(
809
                'registerForm' => $form,
810
                'enableRegistration' => $userOptions->getEnableRegistration(),
811
                'redirect' => $redirect,
812
            ));
813
            
814
            return $viewModel;
815
        }
816
817
        if ($service->getOptions()->getEmailVerification()) {
818
            $vm = new ViewModel(array('userEmail' => $user->getEmail()));
819
            $vm->setTemplate('playground-user/register/registermail');
820
821
            return $vm;
822
        } elseif ($service->getOptions()->getLoginAfterRegistration()) {
823
            $identityFields = $service->getOptions()->getAuthIdentityFields();
824
            if (in_array('email', $identityFields)) {
825
                $post['identity'] = $user->getEmail();
826
            } elseif (in_array('username', $identityFields)) {
827
                $post['identity'] = $user->getUsername();
828
            }
829
            $post['credential'] = isset($post['password'])?$post['password']:'';
830
            $request->setPost(new Parameters($post));
831
832
            // clear adapters
833
            $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...
834
            $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...
835
836
            $logged = $this->forward()->dispatch('playgrounduser_user', array('action' => 'ajaxauthenticate'));
837
838 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...
839
                return $this->redirect()->toUrl(
840
                    $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...
841
                        $this->game->getClassType() . '/' . $this->game->nextStep('index'),
842
                        array('id' => $this->game->getIdentifier())
843
                    )
844
                );
845
            } else {
846
                $this->flashMessenger()->setNamespace('zfcuser-login-form')->addMessage(
847
                    'Authentication failed. Please try again.'
848
                );
849
                return $this->redirect()->toUrl(
850
                    $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...
851
                        $this->game->getClassType() . '/login',
852
                        array('id' => $this->game->getIdentifier())
853
                    )
854
                );
855
            }
856
        }
857
858
        $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...
859
            $this->game->getClassType().'/login',
860
            array(
861
                'id' => $this->game->getIdentifier(),
862
                
863
            )
864
        ) . ($socialnetwork ? '/' . $socialnetwork : ''). ($redirect ? '?redirect=' . $redirect : '');
865
866
        return $this->redirect()->toUrl($redirect);
867
    }
868
869
    /**
870
     *
871
     * @param \PlaygroundGame\Entity\Game $game
872
     * @param \PlaygroundUser\Entity\User $user
873
     */
874
    public function checkFbRegistration($user, $game)
875
    {
876
        $redirect = false;
877
        $session = new Container('facebook');
878
        if ($session->offsetExists('signed_request')) {
879
            if (!$user) {
880
                // Get Playground user from Facebook info
881
                $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...
882
                $view = $this->forward()->dispatch(
883
                    'playgrounduser_user',
884
                    array(
885
                        'controller' => 'playgrounduser_user',
886
                        'action' => 'registerFacebookUser',
887
                        'provider' => 'facebook'
888
                    )
889
                );
890
891
                $this->layout()->setTemplate($beforeLayout);
892
                $user = $view->user;
893
894
                // If the user can not be created/retrieved from Facebook info, redirect to login/register form
895
                if (!$user) {
896
                    $redirectUrl = urlencode(
897
                        $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...
898
                            $game->getClassType() .'/play',
899
                            array('id' => $game->getIdentifier()),
900
                            array('force_canonical' => true)
901
                        )
902
                    );
903
                    $redirect =  $this->redirect()->toUrl(
904
                        $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...
905
                            'zfcuser/register'
906
                        ) . '?redirect='.$redirectUrl
907
                    );
908
                }
909
            }
910
911
            if ($game->getFbFan()) {
912
                if ($this->getGameService()->checkIsFan($game) === false) {
913
                    $redirect =  $this->redirect()->toRoute(
914
                        $game->getClassType().'/fangate',
915
                        array('id' => $game->getIdentifier())
916
                    );
917
                }
918
            }
919
        }
920
921
        return $redirect;
922
    }
923
924
    /**
925
     * This method create the basic Game view
926
     * @param \PlaygroundGame\Entity\Game $game
927
     */
928
    public function buildView($game)
929
    {
930
        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...
931
            $viewModel = new JsonModel();
932
            if ($game) {
933
                $view = $this->addAdditionalView($game);
934
                if ($view && $view instanceof \Zend\View\Model\ViewModel) {
935
                    $viewModel->setVariables($view->getVariables());
936
                }
937
            }
938
        } else {
939
            $viewModel = new ViewModel();
940
941
            if ($game) {
942
                $this->addMetaTitle($game);
943
                $this->addMetaBitly();
944
                $this->addGaEvent($game);
945
946
                $this->customizeGameDesign($game);
947
                
948
                // this is possible to create a specific game design in /design/frontend/default/custom.
949
                //It will precede all others templates.
950
                $templatePathResolver = $this->getServiceLocator()->get('Zend\View\Resolver\TemplatePathStack');
951
                $l = $templatePathResolver->getPaths();
952
                $templatePathResolver->addPath($l[0].'custom/'.$game->getIdentifier());
953
                
954
                $view = $this->addAdditionalView($game);
955
                if ($view && $view instanceof \Zend\View\Model\ViewModel) {
956
                    $viewModel->addChild($view, 'additional');
957
                } elseif ($view && $view instanceof \Zend\Http\PhpEnvironment\Response) {
958
                    return $view;
959
                }
960
961
                $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...
962
                    array(
963
                        'action' => $this->params('action'),
964
                        'game' => $game,
965
                        'flashMessages'    => $this->flashMessenger()->getMessages(),
966
                        
967
                    )
968
                );
969
            }
970
        }
971
        
972
        if ($game) {
973
            $viewModel->setVariables($this->getShareData($game));
974
            $viewModel->setVariables(array('game' => $game));
975
        }
976
977
        return $viewModel;
978
    }
979
980
    /**
981
     * @param \PlaygroundGame\Entity\Game $game
982
     */
983
    public function addAdditionalView($game)
984
    {
985
        $view = false;
986
987
        $actionName = $this->getEvent()->getRouteMatch()->getParam('action', 'not-found');
988
        $stepsViews = json_decode($game->getStepsViews(), true);
989
        if ($stepsViews && isset($stepsViews[$actionName])) {
990
            $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...
991
            $actionData = $stepsViews[$actionName];
992
            if (is_string($actionData)) {
993
                $action = $actionData;
994
                $controller = $this->getEvent()->getRouteMatch()->getParam('controller', 'playgroundgame_game');
995
                $view = $this->forward()->dispatch(
996
                    $controller,
997
                    array(
998
                        'action' => $action,
999
                        'id' => $game->getIdentifier()
1000
                    )
1001
                );
1002
            } elseif (is_array($actionData) && count($actionData)>0) {
1003
                $action = key($actionData);
1004
                $controller = $actionData[$action];
1005
                $view = $this->forward()->dispatch(
1006
                    $controller,
1007
                    array(
1008
                        'action' => $action,
1009
                        'id' => $game->getIdentifier()
1010
                    )
1011
                );
1012
            }
1013
            // suite au forward, le template de layout a changé, je dois le rétablir...
1014
            $this->layout()->setTemplate($beforeLayout);
1015
        }
1016
1017
        return $view;
1018
    }
1019
1020
    public function addMetaBitly()
1021
    {
1022
        $bitlyclient = $this->getOptions()->getBitlyUrl();
1023
        $bitlyuser = $this->getOptions()->getBitlyUsername();
1024
        $bitlykey = $this->getOptions()->getBitlyApiKey();
1025
1026
        $this->getViewHelper('HeadMeta')->setProperty('bt:client', $bitlyclient);
1027
        $this->getViewHelper('HeadMeta')->setProperty('bt:user', $bitlyuser);
1028
        $this->getViewHelper('HeadMeta')->setProperty('bt:key', $bitlykey);
1029
    }
1030
1031
    /**
1032
     * @param \PlaygroundGame\Entity\Game $game
1033
     */
1034
    public function addGaEvent($game)
1035
    {
1036
        // Google Analytics event
1037
        $ga = $this->getServiceLocator()->get('google-analytics');
1038
        $event = new \PlaygroundCore\Analytics\Event($game->getClassType(), $this->params('action'));
1039
        $event->setLabel($game->getTitle());
1040
        $ga->addEvent($event);
1041
    }
1042
1043
    /**
1044
     * @param \PlaygroundGame\Entity\Game $game
1045
     */
1046
    public function addMetaTitle($game)
1047
    {
1048
        $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...
1049
        $this->getGameService()->getServiceManager()->get('ViewHelperManager')->get('HeadTitle')->set($title);
1050
        // Meta set in the layout
1051
        $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...
1052
            array(
1053
                'breadcrumbTitle' => $title,
1054
                'currentPage' => array(
1055
                    'pageGames' => 'games',
1056
                    'pageWinners' => ''
1057
                ),
1058
                'headParams' => array(
1059
                    'headTitle' => $title,
1060
                    'headDescription' => $title,
1061
                ),
1062
                'bodyCss' => $game->getIdentifier()
1063
            )
1064
        );
1065
    }
1066
1067
    /**
1068
     * @param \PlaygroundGame\Entity\Game $game
1069
     */
1070
    public function customizeGameDesign($game)
1071
    {
1072
        // If this game has a specific layout...
1073
        if ($game->getLayout()) {
1074
            $layoutViewModel = $this->layout();
1075
            $layoutViewModel->setTemplate($game->getLayout());
1076
        }
1077
1078
        // If this game has a specific stylesheet...
1079
        if ($game->getStylesheet()) {
1080
            $this->getViewHelper('HeadLink')->appendStylesheet(
1081
                $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...
1082
            );
1083
        }
1084
    }
1085
1086
    /**
1087
     * @param \PlaygroundGame\Entity\Game $game
1088
     */
1089
    public function getShareData($game)
1090
    {
1091
        $fo = $this->getServiceLocator()->get('facebook-opengraph');
1092
        $session = new Container('facebook');
1093
1094
        // I change the fbappid if i'm in fb
1095
        if ($session->offsetExists('signed_request')) {
1096
            $fo->setId($game->getFbAppId());
1097
        }
1098
1099
        // If I want to add a share block in my view
1100 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...
1101
            $fbShareMessage = $game->getFbShareMessage();
1102
        } else {
1103
            $fbShareMessage = str_replace(
1104
                '__placeholder__',
1105
                $game->getTitle(),
1106
                $this->getOptions()->getDefaultShareMessage()
1107
            );
1108
        }
1109
1110
        if ($game->getFbShareImage()) {
1111
            $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...
1112
                '',
1113
                array(),
1114
                array('force_canonical' => true),
1115
                false
1116
            ) . $game->getFbShareImage();
1117
        } else {
1118
            $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...
1119
                '',
1120
                array(),
1121
                array('force_canonical' => true),
1122
                false
1123
            ) . $game->getMainImage();
1124
        }
1125
1126
        $secretKey = strtoupper(substr(sha1(uniqid('pg_', true).'####'.time()), 0, 15));
1127
1128
        // Without bit.ly shortener
1129
        $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...
1130
            $game->getClassType(),
1131
            array('id' => $game->getIdentifier()),
1132
            array('force_canonical' => true)
1133
        );
1134
        // With core shortener helper
1135
        $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...
1136
1137
        // FB Requests only work when it's a FB app
1138
        if ($game->getFbRequestMessage()) {
1139
            $fbRequestMessage = urlencode($game->getFbRequestMessage());
1140
        } else {
1141
            $fbRequestMessage = str_replace(
1142
                '__placeholder__',
1143
                $game->getTitle(),
1144
                $this->getOptions()->getDefaultShareMessage()
1145
            );
1146
        }
1147
1148 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...
1149
            $twShareMessage = $game->getTwShareMessage() . $socialLinkUrl;
1150
        } else {
1151
            $twShareMessage = str_replace(
1152
                '__placeholder__',
1153
                $game->getTitle(),
1154
                $this->getOptions()->getDefaultShareMessage()
1155
            ) . $socialLinkUrl;
1156
        }
1157
1158
        $ogTitle = new \PlaygroundCore\Opengraph\Tag('og:title', $fbShareMessage);
1159
        $ogImage = new \PlaygroundCore\Opengraph\Tag('og:image', $fbShareImage);
1160
        
1161
        $fo->addTag($ogTitle);
1162
        $fo->addTag($ogImage);
1163
        
1164
        $data = array(
1165
            'socialLinkUrl'       => $socialLinkUrl,
1166
            'secretKey'           => $secretKey,
1167
            'fbShareMessage'      => $fbShareMessage,
1168
            'fbShareImage'        => $fbShareImage,
1169
            'fbRequestMessage'    => $fbRequestMessage,
1170
            'twShareMessage'      => $twShareMessage,
1171
        );
1172
1173
        return $data;
1174
    }
1175
    
1176
    /**
1177
     * return ajax response in json format
1178
     *
1179
     * @param array $data
1180
     * @return \Zend\View\Model\JsonModel
1181
     */
1182 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...
1183
    {
1184
        $model = new JsonModel(array(
1185
            'success' => true,
1186
            'data' => $data
1187
        ));
1188
        return $model->setTerminal(true);
1189
    }
1190
    
1191
    /**
1192
     * return ajax response in json format
1193
     *
1194
     * @param string $message
1195
     * @return \Zend\View\Model\JsonModel
1196
     */
1197 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...
1198
    {
1199
        $model = new JsonModel(array(
1200
            'success' => false,
1201
            'message' => $message
1202
        ));
1203
        return $model->setTerminal(true);
1204
    }
1205
1206
    /**
1207
     * @param string $helperName
1208
     */
1209
    protected function getViewHelper($helperName)
1210
    {
1211
        return $this->getServiceLocator()->get('viewhelpermanager')->get($helperName);
1212
    }
1213
1214
    public function getGameService()
1215
    {
1216
        if (!$this->gameService) {
1217
            $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...
1218
        }
1219
1220
        return $this->gameService;
1221
    }
1222
1223
    public function setGameService(GameService $gameService)
1224
    {
1225
        $this->gameService = $gameService;
1226
1227
        return $this;
1228
    }
1229
1230
    public function getPrizeService()
1231
    {
1232
        if (!$this->prizeService) {
1233
            $this->prizeService = $this->getServiceLocator()->get('playgroundgame_prize_service');
1234
        }
1235
1236
        return $this->prizeService;
1237
    }
1238
1239
    public function setPrizeService(PrizeService $prizeService)
1240
    {
1241
        $this->prizeService = $prizeService;
1242
1243
        return $this;
1244
    }
1245
1246
    public function getOptions()
1247
    {
1248
        if (!$this->options) {
1249
            $this->setOptions($this->getServiceLocator()->get('playgroundcore_module_options'));
1250
        }
1251
1252
        return $this->options;
1253
    }
1254
1255
    public function setOptions($options)
1256
    {
1257
        $this->options = $options;
1258
1259
        return $this;
1260
    }
1261
}
1262