Completed
Push — develop ( 8cc9e7...453ab4 )
by greg
29:32
created

GameController::prizeAction()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 6
Bugs 2 Features 0
Metric Value
c 6
b 2
f 0
dl 0
loc 14
rs 9.4286
cc 2
eloc 8
nc 2
nop 0
1
<?php
2
3
namespace PlaygroundGame\Controller\Frontend;
4
5
use Zend\Mvc\Controller\AbstractActionController;
6
use Zend\View\Model\ViewModel;
7
use Zend\Session\Container;
8
use PlaygroundGame\Service\GameService;
9
use PlaygroundGame\Service\Prize as PrizeService;
10
use Zend\View\Model\JsonModel;
11
use Zend\Http\PhpEnvironment\Response;
12
use Zend\Stdlib\Parameters;
13
14
class GameController extends AbstractActionController
15
{
16
    /**
17
     * @var \PlaygroundGame\Service\GameService
18
     */
19
    protected $gameService;
20
21
    protected $prizeService;
22
23
    protected $options;
24
25
    protected $game;
26
27
    protected $user;
28
29
    protected $withGame = array(
30
        'home',
31
        'index',
32
        'terms',
33
        'conditions',
34
        'leaderboard',
35
        'register',
36
        'bounce',
37
        'prizes',
38
        'prize',
39
        'fangate',
40
        'share',
41
        'optin',
42
        'login',
43
        'play',
44
        'result',
45
        'preview',
46
        'list'
47
    );
48
49
    protected $withOnlineGame = array(
50
        'leaderboard',
51
        'register',
52
        'bounce',
53
        'play',
54
        'result'
55
    );
56
57
    protected $withAnyUser = array(
58
        'share',
59
        'result',
60
        'play'
61
    );
62
63
    public function setEventManager(\Zend\EventManager\EventManagerInterface $events)
64
    {
65
        parent::setEventManager($events);
66
67
        $controller = $this;
68
        $events->attach('dispatch', function (\Zend\Mvc\MvcEvent $e) use ($controller) {
69
70
            $identifier = $e->getRouteMatch()->getParam('id');
71
            $controller->game = $controller->getGameService()->checkGame($identifier, false);
72
            if (!$controller->game &&
73
                in_array($controller->params('action'), $controller->withGame)
74
            ) {
75
                return $controller->notFoundAction();
76
            }
77
78
            if ($controller->game &&
79
                $controller->game->isClosed() &&
80
                in_array($controller->params('action'), $controller->withOnlineGame)
81
            ) {
82
                return $controller->notFoundAction();
83
            }
84
85
            $controller->user = $controller->zfcUserAuthentication()->getIdentity();
0 ignored issues
show
Documentation Bug introduced by
The method zfcUserAuthentication does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
86
            if (
87
                $controller->game &&
88
                !$controller->user && 
89
                !$controller->game->getAnonymousAllowed() &&
90
                in_array($controller->params('action'), $controller->withAnyUser)
91
            ) {
92
                $redirect = urlencode(
93
                    $controller->url()->fromRoute(
94
                        'frontend/'.$this->game->getClassType() . '/' . $controller->params('action'),
95
                        array('id' => $controller->game->getIdentifier())
96
                    )
97
                );
98
                return $controller->redirect()->toUrl(
99
                    $controller->url()->fromRoute(
100
                        'frontend/zfcuser/register',
101
                        array()
102
                    ) . '?redirect='.$redirect
103
                );
104
            }
105
106
            return;
107
        }, 100); // execute before executing action logic
108
    }
109
110
    /**
111
     * Action called if matched action does not exist
112
     * For this view not to be catched by Zend\Mvc\View\RouteNotFoundStrategy
113
     * it has to be rendered in the controller. Hence the code below.
114
     *
115
     * This action is injected as a catchall action for each custom_games definition
116
     * This way, when a custom_game is created, the 404 is it's responsability and the
117
     * view can be defined in design/frontend/default/custom/$slug/playground_game/$gametype/404.phtml
118
     *
119
     *
120
     * @return \Zend\Stdlib\ResponseInterface
121
     */
122
    public function notFoundAction()
123
    {
124
        $viewRender     = $this->getServiceLocator()->get('ViewRenderer');
125
126
        $this->getEvent()->getRouteMatch()->setParam('action', 'not-found');
127
        $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...
128
129
        $res = 'error/404';
130
131
        $viewModel = $this->buildView($this->game);
132
        $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...
133
134
        $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...
135
        $this->response->setContent($viewRender->render($this->layout()));
136
137
        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...
138
    }
139
140
    /**
141
     * This action acts as a hub : Depending on the first step of the game, it will forward the action to this step
142
     */
143
    public function homeAction()
144
    {
145
        // This fix exists only for safari in FB on Windows : we need to redirect the user to the page
146
        // outside of iframe for the cookie to be accepted. PlaygroundCore redirects to the FB Iframed page when
147
        // it discovers that the user arrives for the first time on the game in FB.
148
        // When core redirects, it adds a 'redir_fb_page_id' var in the querystring
149
        // Here, we test if this var exist, and then send the user back to the game in FB.
150
        // Now the cookie will be accepted by Safari...
151
        $pageId = $this->params()->fromQuery('redir_fb_page_id');
152
        if (!empty($pageId)) {
153
            $appId = 'app_'.$this->game->getFbAppId();
154
            $url = '//www.facebook.com/pages/game/'.$pageId.'?sk='.$appId;
155
156
            return $this->redirect()->toUrl($url);
157
        }
158
159
        // If an entry has already been done during this session, I reset the anonymous_identifier cookie
160
        // so that another person can play the same game (if game conditions are fullfilled)
161
        $session = new Container('anonymous_identifier');
162
        if ($session->offsetExists('anonymous_identifier')) {
163
            $session->offsetUnset('anonymous_identifier');
164
        }
165
        
166
        return $this->forward()->dispatch(
167
            'playgroundgame_'.$this->game->getClassType(),
168
            array(
169
                'controller' => 'playgroundgame_'.$this->game->getClassType(),
170
                'action' => $this->game->firstStep(),
171
                'id' => $this->game->getIdentifier()
172
            )
173
        );
174
    }
175
176
    /**
177
     * Homepage of the game
178
     */
179
    public function indexAction()
180
    {
181
        $isSubscribed = false;
182
183
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
184
        if ($entry) {
185
            $isSubscribed = true;
186
        }
187
188
        $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 193 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...
189
        $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...
190
            'isSubscribed' => $isSubscribed
191
        ));
192
193
        return $viewModel;
194
    }
195
196
    /**
197
      * leaderboardAction
198
      *
199
      * @return ViewModel $viewModel
200
      */
201
    public function leaderboardAction()
202
    {
203
        $filter = $this->getEvent()->getRouteMatch()->getParam('filter');
204
        $p = $this->getEvent()->getRouteMatch()->getParam('p');
205
206
        $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...
207
        $subViewModel = $this->forward()->dispatch(
208
            'playgroundreward',
209
            array('action' => 'leaderboard', 'filter' => $filter, 'p' => $p)
210
        );
211
        
212
        // suite au forward, le template de layout a changé, je dois le rétablir...
213
        $this->layout()->setTemplate($beforeLayout);
214
215
        // give the ability to the game to have its customized look and feel.
216
        $templatePathResolver = $this->getServiceLocator()->get('Zend\View\Resolver\TemplatePathStack');
217
        $l = $templatePathResolver->getPaths();
218
219
        $templatePathResolver->addPath($l[0].'custom/'.$this->game->getIdentifier());
220
221
        return $subViewModel;
222
    }
223
224
    /**
225
     * This action has been designed to be called by other controllers
226
     * It gives the ability to display an information form and persist it in the game entry
227
     *
228
     * @return \Zend\View\Model\ViewModel
229
     */
230
    public function registerAction()
231
    {
232
        $form = $this->getGameService()->createFormFromJson($this->game->getPlayerForm()->getForm(), 'playerForm');
233
234
        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...
235
            // POST Request: Process form
236
            $data = array_merge_recursive(
237
                $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...
238
                $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...
239
            );
240
            
241
            $form->setData($data);
242
243
            if ($form->isValid()) {
244
                // steps of the game
245
                $steps = $this->game->getStepsArray();
246
                // sub steps of the game
247
                $viewSteps = $this->game->getStepsViewsArray();
248
249
                // register position
250
                $key = array_search($this->params('action'), $viewSteps);
251
                if (!$key) {
252
                    // register is not a substep of the game so it's a step
253
                    $key = array_search($this->params('action'), $steps);
254
                    $keyStep = true;
255
                } else {
256
                    // register was a substep, i search the index of its parent
257
                    $key = array_search($key, $steps);
258
                    $keyStep = false;
259
                }
260
261
                // play position
262
                $keyplay = array_search('play', $viewSteps);
263
264
                if (!$keyplay) {
265
                    // play is not a substep, so it's a step
266
                    $keyplay = array_search('play', $steps);
267
                    $keyplayStep = true;
268
                } else {
269
                    // play is a substep so I search the index of its parent
270
                    $keyplay = array_search($keyplay, $steps);
271
                    $keyplayStep = false;
272
                }
273
274
                // If register step before play, I don't have no entry yet. I have to create one
275
                // If register after play step, I search for the last entry created by play step.
276
277
                if ($key < $keyplay || ($keyStep && !$keyplayStep && $key <= $keyplay)) {
278
                    $entry = $this->getGameService()->play($this->game, $this->user);
279
                    if (!$entry) {
280
                        // the user has already taken part of this game and the participation limit has been reached
281
                        $this->flashMessenger()->addMessage('Vous avez déjà participé');
282
                    
283
                        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...
284
                            $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...
285
                                $this->game->getClassType().'/result',
286
                                array(
287
                                    'id' => $this->game->getIdentifier(),
288
                                    
289
                                )
290
                            )
291
                        );
292
                    }
293
                } else {
294
                    // I'm looking for an entry without anonymousIdentifier (the active entry in fact).
295
                    $entry = $this->getGameService()->findLastEntry($this->game, $this->user);
296
                    if ($this->getGameService()->hasReachedPlayLimit($this->game, $this->user)) {
297
                        // the user has already taken part of this game and the participation limit has been reached
298
                        $this->flashMessenger()->addMessage('Vous avez déjà participé');
299
                    
300
                        return $this->redirect()->toUrl(
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->redirect()...me->getIdentifier()))); (Zend\Http\Response) is incompatible with the return type documented by PlaygroundGame\Controlle...troller::registerAction of type Zend\View\Model\ViewModel.

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

Let’s take a look at an example:

class Author {
    private $name;

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

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

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

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

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

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

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

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

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
302
                                $this->game->getClassType().'/result',
303
                                array(
304
                                    'id' => $this->game->getIdentifier(),
305
                                    
306
                                )
307
                            )
308
                        );
309
                    }
310
                }
311
312
                $this->getGameService()->updateEntryPlayerForm($form->getData(), $this->game, $this->user, $entry);
313
314
                if (!empty($this->game->nextStep($this->params('action')))) {
315
                    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...
316
                        $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...
317
                            $this->game->getClassType() .'/' . $this->game->nextStep($this->params('action')),
318
                            array('id' => $this->game->getIdentifier()),
319
                            array('force_canonical' => true)
320
                        )
321
                    );
322
                }
323
            }
324
        }
325
326
        $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 331 which is incompatible with the return type documented by PlaygroundGame\Controlle...troller::registerAction of type Zend\View\Model\ViewModel.
Loading history...
327
        $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...
328
            'form' => $form
329
        ));
330
331
        return $viewModel;
332
    }
333
334
    /**
335
     * This action takes care of the terms of the game
336
     */
337
    public function termsAction()
338
    {
339
        $viewModel = $this->buildView($this->game);
340
341
        return $viewModel;
342
    }
343
344
    /**
345
     * This action takes care of the conditions of the game
346
     */
347
    public function conditionsAction()
348
    {
349
        $viewModel = $this->buildView($this->game);
350
351
        return $viewModel;
352
    }
353
354
    /**
355
     * This action takes care of bounce page of the game
356
     */
357
    public function bounceAction()
358
    {
359
        $availableGames = $this->getGameService()->getAvailableGames($this->user);
360
361
        $rssUrl = '';
362
        $config = $this->getGameService()->getServiceManager()->get('config');
363
        if (isset($config['rss']['url'])) {
364
            $rssUrl = $config['rss']['url'];
365
        }
366
367
        $viewModel = $this->buildView($this->game);
368
        $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...
369
            'rssUrl'         => $rssUrl,
370
            'user'           => $this->user,
371
            'availableGames' => $availableGames,
372
        ));
373
374
        return $viewModel;
375
    }
376
377
378
    /**
379
     * This action displays the Prizes page associated to the game
380
     */
381
    public function prizesAction()
382
    {
383
        if (count($this->game->getPrizes()) == 0) {
384
            return $this->notFoundAction();
385
        }
386
387
        $viewModel = $this->buildView($this->game);
388
389
        return $viewModel;
390
    }
391
392
    /**
393
     * This action displays a specific Prize page among those associated to the game
394
     */
395
    public function prizeAction()
396
    {
397
        $prizeIdentifier = $this->getEvent()->getRouteMatch()->getParam('prize');
398
        $prize = $this->getPrizeService()->getPrizeMapper()->findByIdentifier($prizeIdentifier);
399
        
400
        if (!$prize) {
401
            return $this->notFoundAction();
402
        }
403
404
        $viewModel = $this->buildView($this->game);
405
        $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...
406
407
        return $viewModel;
408
    }
409
410
    public function gameslistAction()
411
    {
412
        $layoutViewModel = $this->layout();
413
414
        $slider = new ViewModel();
415
        $slider->setTemplate('playground-game/common/top_promo');
416
417
        $sliderItems = $this->getGameService()->getActiveSliderGames();
418
419
        $slider->setVariables(array('sliderItems' => $sliderItems));
420
421
        $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...
422
423
        $games = $this->getGameService()->getActiveGames(false, '', 'endDate');
424
        if (is_array($games)) {
425
            $paginator = new \Zend\Paginator\Paginator(new \Zend\Paginator\Adapter\ArrayAdapter($games));
426
        } else {
427
            $paginator = $games;
428
        }
429
430
        $paginator->setItemCountPerPage(7);
431
        $paginator->setCurrentPageNumber($this->getEvent()->getRouteMatch()->getParam('p'));
432
433
        $bitlyclient = $this->getOptions()->getBitlyUrl();
434
        $bitlyuser = $this->getOptions()->getBitlyUsername();
435
        $bitlykey = $this->getOptions()->getBitlyApiKey();
436
437
        $this->getViewHelper('HeadMeta')->setProperty('bt:client', $bitlyclient);
438
        $this->getViewHelper('HeadMeta')->setProperty('bt:user', $bitlyuser);
439
        $this->getViewHelper('HeadMeta')->setProperty('bt:key', $bitlykey);
440
441
        $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...
442
            array(
443
            'sliderItems'   => $sliderItems,
444
            'currentPage' => array(
445
                'pageGames' => 'games',
446
                'pageWinners' => ''
447
            ),
448
            )
449
        );
450
451
        return new ViewModel(
452
            array(
453
                'games'       => $paginator
454
            )
455
        );
456
    }
457
458
    public function fangateAction()
459
    {
460
        $viewModel = $this->buildView($this->game);
461
462
        return $viewModel;
463
    }
464
    
465
    public function shareAction()
466
    {
467
        $statusMail = null;
468
    
469
        // Has the user finished the game ?
470
        $lastEntry = $this->getGameService()->findLastInactiveEntry($this->game, $this->user);
471
    
472
        if ($lastEntry === null) {
473
            return $this->redirect()->toUrl(
474
                $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...
475
                    'postvote',
476
                    array('id' => $this->game->getIdentifier())
477
                )
478
            );
479
        }
480
    
481
        $form = $this->getServiceLocator()->get('playgroundgame_sharemail_form');
482
        $form->setAttribute('method', 'post');
483
    
484
        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...
485
            $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...
486
            $form->setData($data);
487
            if ($form->isValid()) {
488
                $result = $this->getGameService()->sendShareMail($data, $this->game, $this->user, $lastEntry);
489
                if ($result) {
490
                    $statusMail = true;
491
                }
492
            }
493
        }
494
    
495
        // buildView must be before sendMail because it adds the game template path to the templateStack
496
        $viewModel = $this->buildView($this->game);
497
    
498
        $this->getGameService()->sendMail($this->game, $this->user, $lastEntry);
499
    
500
        $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...
501
            'statusMail'       => $statusMail,
502
            'form'             => $form,
503
        ));
504
    
505
        return $viewModel;
506
    }
507
    
508 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...
509
    {
510
        $viewModel = new JsonModel();
511
        $viewModel->setTerminal(true);
512
        $fbId = $this->params()->fromQuery('fbId');
513
        if (!$this->game) {
514
            return $this->errorJson();
515
        }
516
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
517
        if (! $entry) {
518
            return $this->errorJson();
519
        }
520
        if (!$fbId) {
521
            return $this->errorJson();
522
        }
523
    
524
        $this->getGameService()->postFbWall($fbId, $this->game, $this->user, $entry);
525
    
526
        return $this->successJson();
527
    }
528
    
529
    public function fbrequestAction()
530
    {
531
        $viewModel = new ViewModel();
532
        $viewModel->setTerminal(true);
533
        $fbId = $this->params()->fromQuery('fbId');
534
        $to = $this->params()->fromQuery('to');
535
    
536
        if (!$this->game) {
537
            return $this->errorJson();
538
        }
539
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
540
        if (! $entry) {
541
            return $this->errorJson();
542
        }
543
        if (!$fbId) {
544
            return $this->errorJson();
545
        }
546
    
547
        $this->getGameService()->postFbRequest($fbId, $this->game, $this->user, $entry, $to);
548
    
549
        return $this->successJson();
550
    }
551
    
552
    public function tweetAction()
553
    {
554
        $tweetId = $this->params()->fromQuery('tweetId');
555
    
556
        if (!$this->game) {
557
            return $this->errorJson();
558
        }
559
        $entry = $this->getGameService()->checkExistingEntry($this->game, $this->user);
560
        if (! $entry) {
561
            return $this->errorJson();
562
        }
563
        if (!$tweetId) {
564
            return $this->errorJson();
565
        }
566
    
567
        $this->getGameService()->postTwitter($tweetId, $this->game, $this->user, $entry);
568
    
569
        return $this->successJson();
570
    }
571
    
572 View Code Duplication
    public function googleAction()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

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