Completed
Pull Request — master (#266)
by greg
02:53
created

GameController::shareAction()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 42
Code Lines 23

Duplication

Lines 6
Ratio 14.29 %

Importance

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

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

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

class ParentClass {
    private $data = array();

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

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

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

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
851
                        $this->game->getClassType() . '/' . $this->game->nextStep('index'),
852
                        array('id' => $this->game->getIdentifier())
853
                    )
854
                );
855
            } else {
856
                $this->flashMessenger()->setNamespace('zfcuser-login-form')->addMessage(
857
                    'Authentication failed. Please try again.'
858
                );
859
                return $this->redirect()->toUrl(
860
                    $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...
861
                        $this->game->getClassType() . '/login',
862
                        array('id' => $this->game->getIdentifier())
863
                    )
864
                );
865
            }
866
        }
867
868
        $redirect = $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
869
            $this->game->getClassType().'/login',
870
            array(
871
                'id' => $this->game->getIdentifier(),
872
                
873
            )
874
        ) . ($socialnetwork ? '/' . $socialnetwork : ''). ($redirect ? '?redirect=' . $redirect : '');
875
876
        return $this->redirect()->toUrl($redirect);
877
    }
878
879
    /**
880
     *
881
     * @param \PlaygroundGame\Entity\Game $game
882
     * @param \PlaygroundUser\Entity\User $user
883
     */
884
    public function checkFbRegistration($user, $game)
885
    {
886
        $redirect = false;
887
        $session = new Container('facebook');
888
        if ($session->offsetExists('signed_request')) {
889
            if (!$user) {
890
                // Get Playground user from Facebook info
891
                $beforeLayout = $this->layout()->getTemplate();
0 ignored issues
show
Bug introduced by
The method getTemplate does only exist in Zend\View\Model\ModelInterface, but not in Zend\Mvc\Controller\Plugin\Layout.

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

Let’s take a look at an example:

class A
{
    public function foo() { }
}

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

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

Available Fixes

  1. Add an additional type-check:

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

    function someFunction(B $x) { /** ... */ }
    
Loading history...
892
                $view = $this->forward()->dispatch(
893
                    'playgrounduser_user',
894
                    array(
895
                        'controller' => 'playgrounduser_user',
896
                        'action' => 'registerFacebookUser',
897
                        'provider' => 'facebook'
898
                    )
899
                );
900
901
                $this->layout()->setTemplate($beforeLayout);
902
                $user = $view->user;
903
904
                // If the user can not be created/retrieved from Facebook info, redirect to login/register form
905
                if (!$user) {
906
                    $redirectUrl = urlencode(
907
                        $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

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

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
915
                            'zfcuser/register'
916
                        ) . '?redirect='.$redirectUrl
917
                    );
918
                }
919
            }
920
921
            if ($game->getFbFan()) {
922
                if ($this->getGameService()->checkIsFan($game) === false) {
923
                    $redirect =  $this->redirect()->toRoute(
924
                        $game->getClassType().'/fangate',
925
                        array('id' => $game->getIdentifier())
926
                    );
927
                }
928
            }
929
        }
930
931
        return $redirect;
932
    }
933
934
    /**
935
     * This method create the basic Game view
936
     * @param \PlaygroundGame\Entity\Game $game
937
     */
938
    public function buildView($game)
939
    {
940
        if ($this->getRequest()->isXmlHttpRequest()) {
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Zend\Stdlib\RequestInterface as the method isXmlHttpRequest() does only exist in the following implementations of said interface: Zend\Http\PhpEnvironment\Request, Zend\Http\Request.

Let’s take a look at an example:

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

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

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

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

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

Available Fixes

  1. Change the type-hint for the parameter:

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

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

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
941
            $viewModel = new JsonModel();
942
            if ($game) {
943
                $view = $this->addAdditionalView($game);
944
                if ($view && $view instanceof \Zend\View\Model\ViewModel) {
945
                    $viewModel->setVariables($view->getVariables());
946
                }
947
            }
948
        } else {
949
            $viewModel = new ViewModel();
950
951
            if ($game) {
952
                $this->addMetaTitle($game);
953
                $this->addMetaBitly();
954
                $this->addGaEvent($game);
955
956
                $this->customizeGameDesign($game);
957
                
958
                // this is possible to create a specific game design in /design/frontend/default/custom.
959
                //It will precede all others templates.
960
                $templatePathResolver = $this->getServiceLocator()->get('Zend\View\Resolver\TemplatePathStack');
961
                $l = $templatePathResolver->getPaths();
962
                $templatePathResolver->addPath($l[0].'custom/'.$game->getIdentifier());
963
                
964
                $view = $this->addAdditionalView($game);
965
                if ($view && $view instanceof \Zend\View\Model\ViewModel) {
966
                    $viewModel->addChild($view, 'additional');
967
                } elseif ($view && $view instanceof \Zend\Http\PhpEnvironment\Response) {
968
                    return $view;
969
                }
970
971
                $this->layout()->setVariables(
0 ignored issues
show
Bug introduced by
The method setVariables does only exist in Zend\View\Model\ModelInterface, but not in Zend\Mvc\Controller\Plugin\Layout.

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

Let’s take a look at an example:

class A
{
    public function foo() { }
}

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

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

Available Fixes

  1. Add an additional type-check:

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

    function someFunction(B $x) { /** ... */ }
    
Loading history...
972
                    array(
973
                        'action' => $this->params('action'),
974
                        'game' => $game,
975
                        'flashMessages'    => $this->flashMessenger()->getMessages(),
976
                        
977
                    )
978
                );
979
            }
980
        }
981
        
982
        if ($game) {
983
            $viewModel->setVariables($this->getShareData($game));
984
            $viewModel->setVariables(array('game' => $game));
985
        }
986
987
        return $viewModel;
988
    }
989
990
    /**
991
     * @param \PlaygroundGame\Entity\Game $game
992
     */
993
    public function addAdditionalView($game)
994
    {
995
        $view = false;
996
997
        $actionName = $this->getEvent()->getRouteMatch()->getParam('action', 'not-found');
998
        $stepsViews = json_decode($game->getStepsViews(), true);
999
        if ($stepsViews && isset($stepsViews[$actionName])) {
1000
            $beforeLayout = $this->layout()->getTemplate();
0 ignored issues
show
Bug introduced by
The method getTemplate does only exist in Zend\View\Model\ModelInterface, but not in Zend\Mvc\Controller\Plugin\Layout.

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

Let’s take a look at an example:

class A
{
    public function foo() { }
}

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

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

Available Fixes

  1. Add an additional type-check:

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

    function someFunction(B $x) { /** ... */ }
    
Loading history...
1001
            $actionData = $stepsViews[$actionName];
1002
            if (is_string($actionData)) {
1003
                $action = $actionData;
1004
                $controller = $this->getEvent()->getRouteMatch()->getParam('controller', 'playgroundgame_game');
1005
                $view = $this->forward()->dispatch(
1006
                    $controller,
1007
                    array(
1008
                        'action' => $action,
1009
                        'id' => $game->getIdentifier()
1010
                    )
1011
                );
1012
            } elseif (is_array($actionData) && count($actionData)>0) {
1013
                $action = key($actionData);
1014
                $controller = $actionData[$action];
1015
                $view = $this->forward()->dispatch(
1016
                    $controller,
1017
                    array(
1018
                        'action' => $action,
1019
                        'id' => $game->getIdentifier()
1020
                    )
1021
                );
1022
            }
1023
            // suite au forward, le template de layout a changé, je dois le rétablir...
1024
            $this->layout()->setTemplate($beforeLayout);
1025
        }
1026
1027
        return $view;
1028
    }
1029
1030
    public function addMetaBitly()
1031
    {
1032
        $bitlyclient = $this->getOptions()->getBitlyUrl();
1033
        $bitlyuser = $this->getOptions()->getBitlyUsername();
1034
        $bitlykey = $this->getOptions()->getBitlyApiKey();
1035
1036
        $this->getViewHelper('HeadMeta')->setProperty('bt:client', $bitlyclient);
1037
        $this->getViewHelper('HeadMeta')->setProperty('bt:user', $bitlyuser);
1038
        $this->getViewHelper('HeadMeta')->setProperty('bt:key', $bitlykey);
1039
    }
1040
1041
    /**
1042
     * @param \PlaygroundGame\Entity\Game $game
1043
     */
1044
    public function addGaEvent($game)
1045
    {
1046
        // Google Analytics event
1047
        $ga = $this->getServiceLocator()->get('google-analytics');
1048
        $event = new \PlaygroundCore\Analytics\Event($game->getClassType(), $this->params('action'));
1049
        $event->setLabel($game->getTitle());
1050
        $ga->addEvent($event);
1051
    }
1052
1053
    /**
1054
     * @param \PlaygroundGame\Entity\Game $game
1055
     */
1056
    public function addMetaTitle($game)
1057
    {
1058
        $title = $this->translate($game->getTitle());
0 ignored issues
show
Documentation Bug introduced by
The method translate does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

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

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

Let’s take a look at an example:

class A
{
    public function foo() { }
}

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

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

Available Fixes

  1. Add an additional type-check:

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

    function someFunction(B $x) { /** ... */ }
    
Loading history...
1062
            array(
1063
                'breadcrumbTitle' => $title,
1064
                'currentPage' => array(
1065
                    'pageGames' => 'games',
1066
                    'pageWinners' => ''
1067
                ),
1068
                'headParams' => array(
1069
                    'headTitle' => $title,
1070
                    'headDescription' => $title,
1071
                ),
1072
                'bodyCss' => $game->getIdentifier()
1073
            )
1074
        );
1075
    }
1076
1077
    /**
1078
     * @param \PlaygroundGame\Entity\Game $game
1079
     */
1080
    public function customizeGameDesign($game)
1081
    {
1082
        // If this game has a specific layout...
1083
        if ($game->getLayout()) {
1084
            $layoutViewModel = $this->layout();
1085
            $layoutViewModel->setTemplate($game->getLayout());
1086
        }
1087
1088
        // If this game has a specific stylesheet...
1089
        if ($game->getStylesheet()) {
1090
            $this->getViewHelper('HeadLink')->appendStylesheet(
1091
                $this->getRequest()->getBaseUrl(). '/' . $game->getStylesheet()
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Zend\Stdlib\RequestInterface as the method getBaseUrl() does only exist in the following implementations of said interface: Zend\Http\PhpEnvironment\Request.

Let’s take a look at an example:

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

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

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

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

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

Available Fixes

  1. Change the type-hint for the parameter:

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

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

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
1092
            );
1093
        }
1094
    }
1095
1096
    /**
1097
     * @param \PlaygroundGame\Entity\Game $game
1098
     */
1099
    public function getShareData($game)
1100
    {
1101
        $fo = $this->getServiceLocator()->get('facebook-opengraph');
1102
        $session = new Container('facebook');
1103
1104
        // I change the fbappid if i'm in fb
1105
        if ($session->offsetExists('signed_request')) {
1106
            $fo->setId($game->getFbAppId());
1107
        }
1108
1109
        // If I want to add a share block in my view
1110 View Code Duplication
        if ($game->getFbShareMessage()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
1111
            $fbShareMessage = $game->getFbShareMessage();
1112
        } else {
1113
            $fbShareMessage = str_replace(
1114
                '__placeholder__',
1115
                $game->getTitle(),
1116
                $this->getOptions()->getDefaultShareMessage()
1117
            );
1118
        }
1119
1120
        if ($game->getFbShareImage()) {
1121
            $fbShareImage = $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

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

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
1129
                '',
1130
                array(),
1131
                array('force_canonical' => true),
1132
                false
1133
            ) . $game->getMainImage();
1134
        }
1135
1136
        $secretKey = strtoupper(substr(sha1(uniqid('pg_', true).'####'.time()), 0, 15));
1137
1138
        // Without bit.ly shortener
1139
        $socialLinkUrl = $this->frontendUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method frontendUrl does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

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

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
1146
1147
        // FB Requests only work when it's a FB app
1148
        if ($game->getFbRequestMessage()) {
1149
            $fbRequestMessage = urlencode($game->getFbRequestMessage());
1150
        } else {
1151
            $fbRequestMessage = str_replace(
1152
                '__placeholder__',
1153
                $game->getTitle(),
1154
                $this->getOptions()->getDefaultShareMessage()
1155
            );
1156
        }
1157
1158 View Code Duplication
        if ($game->getTwShareMessage()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
1159
            $twShareMessage = $game->getTwShareMessage() . $socialLinkUrl;
1160
        } else {
1161
            $twShareMessage = str_replace(
1162
                '__placeholder__',
1163
                $game->getTitle(),
1164
                $this->getOptions()->getDefaultShareMessage()
1165
            ) . $socialLinkUrl;
1166
        }
1167
1168
        $ogTitle = new \PlaygroundCore\Opengraph\Tag('og:title', $fbShareMessage);
1169
        $ogImage = new \PlaygroundCore\Opengraph\Tag('og:image', $fbShareImage);
1170
        
1171
        $fo->addTag($ogTitle);
1172
        $fo->addTag($ogImage);
1173
        
1174
        $data = array(
1175
            'socialLinkUrl'       => $socialLinkUrl,
1176
            'secretKey'           => $secretKey,
1177
            'fbShareMessage'      => $fbShareMessage,
1178
            'fbShareImage'        => $fbShareImage,
1179
            'fbRequestMessage'    => $fbRequestMessage,
1180
            'twShareMessage'      => $twShareMessage,
1181
        );
1182
1183
        return $data;
1184
    }
1185
    
1186
    /**
1187
     * return ajax response in json format
1188
     *
1189
     * @param array $data
1190
     * @return \Zend\View\Model\JsonModel
1191
     */
1192 View Code Duplication
    protected function successJson($data = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
1193
    {
1194
        $model = new JsonModel(array(
1195
            'success' => true,
1196
            'data' => $data
1197
        ));
1198
        return $model->setTerminal(true);
1199
    }
1200
    
1201
    /**
1202
     * return ajax response in json format
1203
     *
1204
     * @param string $message
1205
     * @return \Zend\View\Model\JsonModel
1206
     */
1207 View Code Duplication
    protected function errorJson($message = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
1208
    {
1209
        $model = new JsonModel(array(
1210
            'success' => false,
1211
            'message' => $message
1212
        ));
1213
        return $model->setTerminal(true);
1214
    }
1215
1216
    /**
1217
     * @param string $helperName
1218
     */
1219
    protected function getViewHelper($helperName)
1220
    {
1221
        return $this->getServiceLocator()->get('viewhelpermanager')->get($helperName);
1222
    }
1223
1224
    public function getGameService()
1225
    {
1226
        if (!$this->gameService) {
1227
            $this->gameService = $this->getServiceLocator()->get('playgroundgame_lottery_service');
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->getServiceLocator...dgame_lottery_service') can also be of type array. However, the property $gameService is declared as type object<PlaygroundGame\Service\GameService>. Maybe add an additional type check?

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

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

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

class Id
{
    public $id;

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

}

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

$account_id = false;

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

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