Completed
Pull Request — master (#250)
by greg
08:51 queued 03:04
created

GameController::setUserService()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
c 2
b 1
f 0
dl 0
loc 5
rs 9.4286
cc 1
eloc 3
nc 1
nop 1
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 ZfcUser\Options\UserControllerOptionsInterface;
12
use Zend\Http\PhpEnvironment\Response;
13
use Zend\Stdlib\Parameters;
14
15
class GameController extends AbstractActionController
16
{
17
    /**
18
     * @var gameService
19
     */
20
    protected $gameService;
21
22
    protected $prizeService;
23
24
    protected $options;
25
26
    /**
27
     * Action called if matched action does not exist
28
     * For this view not to be catched by Zend\Mvc\View\RouteNotFoundStrategy
29
     * it has to be rendered in the controller. Hence the code below.
30
     *
31
     * This action is injected as a catchall action for each custom_games definition
32
     * This way, when a custom_game is created, the 404 is it's responsability and the
33
     * view can be defined in design/frontend/default/custom/$slug/playground_game/$gametype/404.phtml
34
     *
35
     *
36
     * @return \Zend\Stdlib\ResponseInterface
37
     */
38
    public function notFoundAction()
39
    {
40
        $sg             = $this->getGameService();
41
        $identifier     = $this->getEvent()->getRouteMatch()->getParam('id');
42
        $viewRender     = $this->getServiceLocator()->get('ViewRenderer');
43
44
        $this->getEvent()->getRouteMatch()->setParam('action', 'not-found');
45
        $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...
46
47
        $game = $sg->checkGame($identifier);
48
49
        $res = 'error/404';
50
51
        $viewModel = $this->buildView($game);
52
        $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...
53
54
        $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...
55
        $this->response->setContent($viewRender->render($this->layout()));
56
57
        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...
58
    }
59
60
    /**
61
     * This action acts as a hub : Depending on the first step of the game, it will forward the action to this step
62
     */
63
    public function homeAction()
64
    {
65
        $identifier = $this->getEvent()->getRouteMatch()->getParam('id');
66
67
        $sg = $this->getGameService();
68
69
        $game = $sg->checkGame($identifier, false);
70
        if (!$game) {
71
            return $this->notFoundAction();
72
        }
73
74
        // This fix exists only for safari in FB on Windows : we need to redirect the user to the page outside of iframe
75
        // for the cookie to be accepted. PlaygroundCore redirects to the FB Iframed page when
76
        // it discovers that the user arrives for the first time on the game in FB.
77
        // When core redirects, it adds a 'redir_fb_page_id' var in the querystring
78
        // Here, we test if this var exist, and then send the user back to the game in FB.
79
        // Now the cookie will be accepted by Safari...
80
        $pageId = $this->params()->fromQuery('redir_fb_page_id');
81
        if (!empty($pageId)) {
82
            $appId = 'app_'.$game->getFbAppId();
83
            $url = '//www.facebook.com/pages/game/'.$pageId.'?sk='.$appId;
84
85
            return $this->redirect()->toUrl($url);
86
        }
87
88
        // If an entry has already been done during this session, I reset the anonymous_identifier cookie
89
        // so that another person can play the same game (if game conditions are fullfilled)
90
        $session = new Container('anonymous_identifier');
91
        if ($session->offsetExists('anonymous_identifier')) {
92
            $session->offsetUnset('anonymous_identifier');
93
        }
94
        
95
        return $this->forward()->dispatch('playgroundgame_'.$game->getClassType(), array('controller' => 'playgroundgame_'.$game->getClassType(), 'action' => $game->firstStep(), 'id' => $identifier, 'channel' => $this->getEvent()->getRouteMatch()->getParam('channel')));
96
    }
97
98
    /**
99
     * Homepage of the game
100
     */
101
    public function indexAction()
102
    {
103
        $identifier = $this->getEvent()->getRouteMatch()->getParam('id');
104
        $user = $this->zfcUserAuthentication()->getIdentity();
0 ignored issues
show
Documentation Bug introduced by
The method zfcUserAuthentication does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
105
        $sg = $this->getGameService();
106
        $channel = $this->getEvent()->getRouteMatch()->getParam('channel');
107
        $isSubscribed = false;
108
109
         // Determine if the play button should be a CTA button (call to action)
110
        $isCtaActive = false;
111
112
        $game = $sg->checkGame($identifier, false);
113
        if (!$game) {
114
            return $this->notFoundAction();
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->notFoundAction(); (Zend\Stdlib\ResponseInterface) is incompatible with the return type of the parent method Zend\Mvc\Controller\Abst...Controller::indexAction 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...
115
        }
116
117
        // If on Facebook, check if you have to be a FB fan to play the game
118
119
        if ($channel == 'facebook') {
120
            if ($game->getFbFan()) {
121
                $isFan = $sg->checkIsFan($game);
122
                if (!$isFan) {
123
                    return $this->redirect()->toUrl($this->frontendUrl()->fromRoute('' . $game->getClassType().'/fangate', array('id' => $game->getIdentifier(), 'channel' => $this->getEvent()->getRouteMatch()->getParam('channel'))));
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...
Bug Best Practice introduced by
The return type of return $this->redirect()...getParam('channel')))); (Zend\Http\Response) is incompatible with the return type of the parent method Zend\Mvc\Controller\Abst...Controller::indexAction 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...
124
                }
125
            }
126
127
            $isCtaActive = true;
128
        }
129
130
131
        $entry = $sg->checkExistingEntry($game, $user);
132
        if ($entry) {
133
            $isSubscribed = true;
134
        }
135
136
        $viewModel = $this->buildView($game);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->buildView($game); of type Zend\Http\PhpEnvironment...nd\View\Model\ViewModel adds the type Zend\Http\PhpEnvironment\Response to the return on line 142 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...
137
        $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...
138
            'isSubscribed'     => $isSubscribed,
139
            'isCtaActive'      => $isCtaActive,
140
        ));
141
142
        return $viewModel;
143
    }
144
145
    /**
146
      * leaderboardAction
147
      *
148
      * @return ViewModel $viewModel
149
      */
150
    public function leaderboardAction()
151
    {
152
        $identifier = $this->getEvent()->getRouteMatch()->getParam('id');
153
        $sg = $this->getGameService();
154
155
        $game = $sg->checkGame($identifier);
156
        if (!$game || $game->isClosed()) {
157
            return $this->notFoundAction();
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->notFoundAction(); (Zend\Stdlib\ResponseInterface) is incompatible with the return type documented by PlaygroundGame\Controlle...ller::leaderboardAction 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...
158
        }
159
160
        $filter = $this->getEvent()->getRouteMatch()->getParam('filter');
161
        $p = $this->getEvent()->getRouteMatch()->getParam('p');
162
163
        $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...
164
        $subViewModel = $this->forward()->dispatch('playgroundreward', array('action' => 'leaderboard', 'filter' => $filter, 'p' => $p));
165
        
166
        // suite au forward, le template de layout a changé, je dois le rétablir...
167
        $this->layout()->setTemplate($beforeLayout);
168
169
        // give the ability to the game to have its customized look and feel.
170
        $templatePathResolver = $this->getServiceLocator()->get('Zend\View\Resolver\TemplatePathStack');
171
        $l = $templatePathResolver->getPaths();
172
173
        $templatePathResolver->addPath($l[0].'custom/'.$game->getIdentifier());
174
175
        return $subViewModel;
176
    }
177
178
    /**
179
     * This action has been designed to be called by other controllers
180
     * It gives the ability to display an information form and persist it in the game entry
181
     *
182
     * @return \Zend\View\Model\ViewModel
183
     */
184
    public function registerAction()
185
    {
186
        $identifier = $this->getEvent()->getRouteMatch()->getParam('id');
187
        $sg = $this->getGameService();
188
189
        $game = $sg->checkGame($identifier);
190
        if (!$game || $game->isClosed()) {
191
            return $this->notFoundAction();
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->notFoundAction(); (Zend\Stdlib\ResponseInterface) 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...
192
        }
193
194
        $user = $this->zfcUserAuthentication()->getIdentity();
0 ignored issues
show
Documentation Bug introduced by
The method zfcUserAuthentication does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
195
196
        $form = $sg->createFormFromJson($game->getPlayerForm()->getForm(), 'playerForm');
197
198
        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...
199
            // POST Request: Process form
200
            $data = array_merge_recursive(
201
                $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...
202
                $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...
203
            );
204
            
205
            $form->setData($data);
206
207
            if ($form->isValid()) {
208
                $steps = $game->getStepsArray();
209
                $viewSteps = $game->getStepsViewsArray();
210
                $key = array_search($this->params('action'), $viewSteps);
211
                if (!$key) {
212
                    $key = array_search($this->params('action'), $steps);
213
                }
214
                $keyplay = array_search('play', $steps);
215
216
                // If register step before play, I don't have no entry yet. I have to create one
217
                // If register after play step, I search for the last entry created by play step.
218
219
                if ($key && $key < $keyplay) {
220
                    $entry = $sg->play($game, $user);
221
                    if (!$entry) {
222
                        // the user has already taken part of this game and the participation limit has been reached
223
                        $this->flashMessenger()->addMessage('Vous avez déjà participé');
224
                    
225
                        return $this->redirect()->toUrl($this->frontendUrl()->fromRoute($game->getClassType().'/result', array('id' => $identifier, 'channel' => $this->getEvent()->getRouteMatch()->getParam('channel'))));
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...
Bug Best Practice introduced by
The return type of return $this->redirect()...getParam('channel')))); (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...
226
                    }
227
                } else {
228
                    // I'm looking for an entry without anonymousIdentifier (the active entry in fact).
229
                    $entry = $sg->findLastEntry($game, $user);
230
                    if ($sg->hasReachedPlayLimit($game, $user)) {
231
                        // the user has already taken part of this game and the participation limit has been reached
232
                        $this->flashMessenger()->addMessage('Vous avez déjà participé');
233
                    
234
                        return $this->redirect()->toUrl($this->frontendUrl()->fromRoute($game->getClassType().'/result', array('id' => $identifier, 'channel' => $this->getEvent()->getRouteMatch()->getParam('channel'))));
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...
Bug Best Practice introduced by
The return type of return $this->redirect()...getParam('channel')))); (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...
235
                    }
236
                }
237
                
238
                $sg->updateEntryPlayerForm($form->getData(), $game, $user, $entry);
239
240
                return $this->redirect()->toUrl($this->frontendUrl()->fromRoute($game->getClassType() .'/' . $game->nextStep($this->params('action')), array('id' => $game->getIdentifier(), 'channel' => $this->getEvent()->getRouteMatch()->getParam('channel')), array('force_canonical' => true)));
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...
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...
241
            }
242
        }
243
244
        $viewModel = $this->buildView($game);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->buildView($game); of type Zend\Http\PhpEnvironment...nd\View\Model\ViewModel adds the type Zend\Http\PhpEnvironment\Response to the return on line 251 which is incompatible with the return type documented by PlaygroundGame\Controlle...troller::registerAction of type Zend\View\Model\ViewModel.
Loading history...
245
        $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...
246
            'form' => $form,
247
            'title' => $game->getPlayerForm()->getTitle(),
248
            'description' => $game->getPlayerForm()->getDescription(),
249
        ));
250
251
        return $viewModel;
252
    }
253
254
    /**
255
     * This action takes care of the terms of the game
256
     */
257 View Code Duplication
    public function termsAction()
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...
258
    {
259
        $identifier = $this->getEvent()->getRouteMatch()->getParam('id');
260
        $sg = $this->getGameService();
261
262
        $game = $sg->checkGame($identifier, false);
263
        if (!$game) {
264
            return $this->notFoundAction();
265
        }
266
267
        $viewModel = $this->buildView($game);
268
269
        return $viewModel;
270
    }
271
272
    /**
273
     * This action takes care of the conditions of the game
274
     */
275 View Code Duplication
    public function conditionsAction()
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...
276
    {
277
        $identifier = $this->getEvent()->getRouteMatch()->getParam('id');
278
        $sg = $this->getGameService();
279
280
        $game = $sg->checkGame($identifier, false);
281
        if (!$game) {
282
            return $this->notFoundAction();
283
        }
284
285
        $viewModel = $this->buildView($game);
286
287
        return $viewModel;
288
    }
289
290
    /**
291
     * This action takes care of bounce page of the game
292
     */
293
    public function bounceAction()
294
    {
295
        $identifier = $this->getEvent()->getRouteMatch()->getParam('id');
296
        $user = $this->zfcUserAuthentication()->getIdentity();
0 ignored issues
show
Documentation Bug introduced by
The method zfcUserAuthentication does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
297
        $sg = $this->getGameService();
298
299
        $game = $sg->checkGame($identifier);
300
        if (!$game || $game->isClosed()) {
301
            return $this->notFoundAction();
302
        }
303
304
        $availableGames = $sg->getAvailableGames($user);
305
306
        $rssUrl = '';
307
        $config = $sg->getServiceManager()->get('config');
308
        if (isset($config['rss']['url'])) {
309
            $rssUrl = $config['rss']['url'];
310
        }
311
312
        $viewModel = $this->buildView($game);
313
        $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...
314
            'rssUrl'         => $rssUrl,
315
            'user'           => $user,
316
            'availableGames' => $availableGames,
317
        ));
318
319
        return $viewModel;
320
    }
321
322
    /**
323
     *
324
     * @param \PlaygroundGame\Entity\Game $game
325
     * @param \PlaygroundUser\Entity\User $user
326
     * @param string $channel
327
     */
328
    public function checkFbRegistration($user, $game, $channel)
329
    {
330
        $redirect = false;
331
        $session = new Container('facebook');
332
        $sg = $this->getGameService();
333
        if ($channel == 'facebook' && $session->offsetExists('signed_request')) {
334
            if (!$user) {
335
                // Get Playground user from Facebook info
336
                $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...
337
                $view = $this->forward()->dispatch(
338
                    'playgrounduser_user',
339
                    array(
340
                        'controller' => 'playgrounduser_user',
341
                        'action' => 'registerFacebookUser',
342
                        'provider' => $channel
343
                    )
344
                );
345
346
                $this->layout()->setTemplate($beforeLayout);
347
                $user = $view->user;
348
349
                // If the user can not be created/retrieved from Facebook info, redirect to login/register form
350 View Code Duplication
                if (!$user) {
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...
351
                    $redirectUrl = urlencode(
352
                        $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...
353
                            $game->getClassType() .'/play',
354
                            array(
355
                                'id' => $game->getIdentifier(),
356
                                'channel' => $channel
357
                            ),
358
                            array('force_canonical' => true)
359
                        )
360
                    );
361
                    $redirect =  $this->redirect()->toUrl(
362
                        $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...
363
                            'zfcuser/register',
364
                            array('channel' => $channel)
365
                        ) . '?redirect='.$redirectUrl
366
                    );
367
                }
368
            }
369
370
            if ($game->getFbFan()) {
371
                if ($sg->checkIsFan($game) === false) {
372
                    $redirect =  $this->redirect()->toRoute(
373
                        $game->getClassType().'/fangate',
374
                        array('id' => $game->getIdentifier())
375
                    );
376
                }
377
            }
378
        }
379
380
        return $redirect;
381
    }
382
383
    /**
384
     * This method create the basic Game view
385
     * @param \PlaygroundGame\Entity\Game $game
386
     */
387
    public function buildView($game)
388
    {
389
        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...
390
            $viewModel = new JsonModel();
391
        } else {
392
            $viewModel = new ViewModel();
393
394
            if ($game) {
395
                $this->addMetaTitle($game);
396
                $this->addMetaBitly();
397
                $this->addGaEvent($game);
398
399
                $this->customizeGameDesign($game);
400
                
401
                // this is possible to create a specific game design in /design/frontend/default/custom. It will precede all others templates.
402
                $templatePathResolver = $this->getServiceLocator()->get('Zend\View\Resolver\TemplatePathStack');
403
                $l = $templatePathResolver->getPaths();
404
                $templatePathResolver->addPath($l[0].'custom/'.$game->getIdentifier());
405
                
406
                $view = $this->addAdditionalView($game);
407
                if ($view && $view instanceof \Zend\View\Model\ViewModel) {
408
                    $viewModel->addChild($view, 'additional');
409
                } elseif ($view && $view instanceof \Zend\Http\PhpEnvironment\Response) {
410
                    return $view;
411
                }
412
413
                $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...
414
                    array(
415
                        'action' => $this->params('action'),
416
                        'game' => $game,
417
                        'flashMessages'    => $this->flashMessenger()->getMessages(),
418
                        'channel' => $this->getEvent()->getRouteMatch()->getParam('channel')
419
                    )
420
                );
421
            }
422
        }
423
        
424
        if ($game) {
425
            $viewModel->setVariables($this->getShareData($game));
426
            $viewModel->setVariables(array('game' => $game));
427
        }
428
429
        return $viewModel;
430
    }
431
432
    /**
433
     * @param \PlaygroundGame\Entity\Game $game
434
     */
435
    public function addAdditionalView($game)
436
    {
437
        $view = false;
438
439
        $actionName = $this->getEvent()->getRouteMatch()->getParam('action', 'not-found');
440
        $stepsViews = json_decode($game->getStepsViews(), true);
441
        if ($stepsViews && isset($stepsViews[$actionName])) {
442
            $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...
443
            $actionData = $stepsViews[$actionName];
444
            if (is_string($actionData)) {
445
                $action = $actionData;
446
                $controller = $this->getEvent()->getRouteMatch()->getParam('controller', 'playgroundgame_game');
447
                $view = $this->forward()->dispatch($controller, array('action' => $action, 'id' => $game->getIdentifier()));
448
            } elseif (is_array($actionData) && count($actionData)>0) {
449
                $action = key($actionData);
450
                $controller = $actionData[$action];
451
                $view = $this->forward()->dispatch($controller, array('action' => $action, 'id' => $game->getIdentifier()));
452
            }
453
            // suite au forward, le template de layout a changé, je dois le rétablir...
454
            $this->layout()->setTemplate($beforeLayout);
455
        }
456
457
        return $view;
458
    }
459
460
    public function addMetaBitly()
461
    {
462
        $bitlyclient = $this->getOptions()->getBitlyUrl();
463
        $bitlyuser = $this->getOptions()->getBitlyUsername();
464
        $bitlykey = $this->getOptions()->getBitlyApiKey();
465
466
        $this->getViewHelper('HeadMeta')->setProperty('bt:client', $bitlyclient);
467
        $this->getViewHelper('HeadMeta')->setProperty('bt:user', $bitlyuser);
468
        $this->getViewHelper('HeadMeta')->setProperty('bt:key', $bitlykey);
469
    }
470
471
    /**
472
     * @param \PlaygroundGame\Entity\Game $game
473
     */
474
    public function addGaEvent($game)
475
    {
476
        // Google Analytics event
477
        $ga = $this->getServiceLocator()->get('google-analytics');
478
        $event = new \PlaygroundCore\Analytics\Event($game->getClassType(), $this->params('action'));
479
        $event->setLabel($game->getTitle());
480
        $ga->addEvent($event);
481
    }
482
483
    /**
484
     * @param \PlaygroundGame\Entity\Game $game
485
     */
486
    public function addMetaTitle($game)
487
    {
488
        $sg = $this->getGameService();
489
        $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...
490
        $sg->getServiceManager()->get('ViewHelperManager')->get('HeadTitle')->set($title);
491
        // Meta set in the layout
492
        $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...
493
            array(
494
                'breadcrumbTitle' => $title,
495
                'currentPage' => array(
496
                    'pageGames' => 'games',
497
                    'pageWinners' => ''
498
                ),
499
                'headParams' => array(
500
                    'headTitle' => $title,
501
                    'headDescription' => $title,
502
                ),
503
                'bodyCss' => $game->getIdentifier()
504
            )
505
        );
506
    }
507
508
    /**
509
     * @param \PlaygroundGame\Entity\Game $game
510
     */
511
    public function customizeGameDesign($game)
512
    {
513
        // If this game has a specific layout...
514
        if ($game->getLayout()) {
515
            $layoutViewModel = $this->layout();
516
            $layoutViewModel->setTemplate($game->getLayout());
517
        }
518
519
        // If this game has a specific stylesheet...
520
        if ($game->getStylesheet()) {
521
            $this->getViewHelper('HeadLink')->appendStylesheet($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...
522
        }
523
    }
524
525
    /**
526
     * @param \PlaygroundGame\Entity\Game $game
527
     */
528
    public function getShareData($game)
529
    {
530
        $fo = $this->getServiceLocator()->get('facebook-opengraph');
531
        // I change the fbappid if i'm in fb
532
        if ($this->getEvent()->getRouteMatch()->getParam('channel') === 'facebook') {
533
            $fo->setId($game->getFbAppId());
534
        }
535
536
        // If I want to add a share block in my view
537 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...
538
            $fbShareMessage = $game->getFbShareMessage();
539
        } else {
540
            $fbShareMessage = str_replace('__placeholder__', $game->getTitle(), $this->getOptions()->getDefaultShareMessage());
541
        }
542
543
        if ($game->getFbShareImage()) {
544
            $fbShareImage = $this->frontendUrl()->fromRoute('', array('channel' => ''), array('force_canonical' => true), false) . $game->getFbShareImage();
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...
545
        } else {
546
            $fbShareImage = $this->frontendUrl()->fromRoute('', array('channel' => ''), array('force_canonical' => true), false) . $game->getMainImage();
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...
547
        }
548
549
        $secretKey = strtoupper(substr(sha1(uniqid('pg_', true).'####'.time()), 0, 15));
550
551
        // Without bit.ly shortener
552
        $socialLinkUrl = $this->frontendUrl()->fromRoute($game->getClassType(), array('id' => $game->getIdentifier(), 'channel' => $this->getEvent()->getRouteMatch()->getParam('channel')), array('force_canonical' => true));
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...
553
        // With core shortener helper
554
        $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...
555
556
        // FB Requests only work when it's a FB app
557
        if ($game->getFbRequestMessage()) {
558
            $fbRequestMessage = urlencode($game->getFbRequestMessage());
559
        } else {
560
            $fbRequestMessage = str_replace('__placeholder__', $game->getTitle(), $this->getOptions()->getDefaultShareMessage());
561
        }
562
563 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...
564
            $twShareMessage = $game->getTwShareMessage() . $socialLinkUrl;
565
        } else {
566
            $twShareMessage = str_replace('__placeholder__', $game->getTitle(), $this->getOptions()->getDefaultShareMessage()) . $socialLinkUrl;
567
        }
568
569
        $ogTitle = new \PlaygroundCore\Opengraph\Tag('og:title', $fbShareMessage);
570
        $ogImage = new \PlaygroundCore\Opengraph\Tag('og:image', $fbShareImage);
571
        
572
        $fo->addTag($ogTitle);
573
        $fo->addTag($ogImage);
574
        
575
        $data = array(
576
            'socialLinkUrl'       => $socialLinkUrl,
577
            'secretKey'           => $secretKey,
578
            'fbShareMessage'      => $fbShareMessage,
579
            'fbShareImage'        => $fbShareImage,
580
            'fbRequestMessage'    => $fbRequestMessage,
581
            'twShareMessage'      => $twShareMessage,
582
        );
583
584
        return $data;
585
    }
586
587
    /**
588
     * This action displays the Prizes page associated to the game
589
     */
590
    public function prizesAction()
591
    {
592
        $identifier = $this->getEvent()->getRouteMatch()->getParam('id');
593
        $sg = $this->getGameService();
594
595
        $game = $sg->checkGame($identifier);
596
        if (!$game) {
597
            return $this->notFoundAction();
598
        }
599
600
        if (count($game->getPrizes()) == 0) {
601
            return $this->notFoundAction();
602
        }
603
604
        $viewModel = $this->buildView($game);
605
606
        return $viewModel;
607
    }
608
609
    /**
610
     * This action displays a specific Prize page among those associated to the game
611
     */
612
    public function prizeAction()
613
    {
614
        $identifier = $this->getEvent()->getRouteMatch()->getParam('id');
615
        $prizeIdentifier = $this->getEvent()->getRouteMatch()->getParam('prize');
616
        $sg = $this->getGameService();
617
        $sp = $this->getPrizeService();
618
619
        $game = $sg->checkGame($identifier);
620
        if (!$game) {
621
            return $this->notFoundAction();
622
        }
623
624
        $prize = $sp->getPrizeMapper()->findByIdentifier($prizeIdentifier);
625
        
626
        if (!$prize) {
627
            return $this->notFoundAction();
628
        }
629
630
631
        $viewModel = $this->buildView($game);
632
        $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...
633
634
        return $viewModel;
635
    }
636
637
    public function gameslistAction()
638
    {
639
        $layoutViewModel = $this->layout();
640
641
        $slider = new ViewModel();
642
        $slider->setTemplate('playground-game/common/top_promo');
643
644
        $sliderItems = $this->getGameService()->getActiveSliderGames();
645
646
        $slider->setVariables(array('sliderItems' => $sliderItems));
647
648
        $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...
649
650
        $games = $this->getGameService()->getActiveGames(false, '', 'endDate');
651
        if (is_array($games)) {
652
            $paginator = new \Zend\Paginator\Paginator(new \Zend\Paginator\Adapter\ArrayAdapter($games));
653
        } else {
654
            $paginator = $games;
655
        }
656
657
        $paginator->setItemCountPerPage(7);
658
        $paginator->setCurrentPageNumber($this->getEvent()->getRouteMatch()->getParam('p'));
659
660
        $bitlyclient = $this->getOptions()->getBitlyUrl();
661
        $bitlyuser = $this->getOptions()->getBitlyUsername();
662
        $bitlykey = $this->getOptions()->getBitlyApiKey();
663
664
        $this->getViewHelper('HeadMeta')->setProperty('bt:client', $bitlyclient);
665
        $this->getViewHelper('HeadMeta')->setProperty('bt:user', $bitlyuser);
666
        $this->getViewHelper('HeadMeta')->setProperty('bt:key', $bitlykey);
667
668
        $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...
669
            array(
670
            'sliderItems'   => $sliderItems,
671
            /*'adserving'       => array(
672
                'cat1' => 'playground',
673
                'cat2' => 'game',
674
                'cat3' => ''
675
            ),*/
676
            'currentPage' => array(
677
                'pageGames' => 'games',
678
                'pageWinners' => ''
679
            ),
680
            )
681
        );
682
683
        return new ViewModel(
684
            array(
685
                'games'       => $paginator
686
            )
687
        );
688
    }
689
690 View Code Duplication
    public function fangateAction()
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...
691
    {
692
        $identifier = $this->getEvent()->getRouteMatch()->getParam('id');
693
        $sg = $this->getGameService();
694
        $game = $sg->checkGame($identifier, false);
695
        if (!$game) {
696
            return $this->notFoundAction();
697
        }
698
699
        $viewModel = $this->buildView($game);
700
701
        return $viewModel;
702
    }
703
    
704
    public function shareAction()
705
    {
706
        $identifier = $this->getEvent()->getRouteMatch()->getParam('id');
707
        $user = $this->zfcUserAuthentication()->getIdentity();
0 ignored issues
show
Documentation Bug introduced by
The method zfcUserAuthentication does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
708
    
709
        $statusMail = null;
710
    
711
        if (!$identifier) {
712
            return $this->notFoundAction();
713
        }
714
    
715
        $gameMapper = $this->getGameService()->getGameMapper();
716
        $game = $gameMapper->findByIdentifier($identifier);
717
    
718
        if (!$game || $game->isClosed()) {
719
            return $this->notFoundAction();
720
        }
721
    
722
        // Has the user finished the game ?
723
        $lastEntry = $this->getGameService()->findLastInactiveEntry($game, $user);
724
    
725 View Code Duplication
        if ($lastEntry === null) {
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...
726
            return $this->redirect()->toUrl($this->frontendUrl()->fromRoute('postvote', array('id' => $identifier, 'channel' => $this->getEvent()->getRouteMatch()->getParam('channel'))));
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...
727
        }
728
    
729 View Code Duplication
        if (!$user && !$game->getAnonymousAllowed()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
730
            $redirect = urlencode($this->frontendUrl()->fromRoute('postvote/result', array('id' => $game->getIdentifier(), 'channel' => $channel)));
0 ignored issues
show
Bug introduced by
The variable $channel does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
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...
731
            return $this->redirect()->toUrl($this->frontendUrl()->fromRoute('zfcuser/register', array('channel' => $channel)) . '?redirect='.$redirect);
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...
732
        }
733
    
734
        $form = $this->getServiceLocator()->get('playgroundgame_sharemail_form');
735
        $form->setAttribute('method', 'post');
736
    
737 View Code Duplication
        if ($this->getRequest()->isPost()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

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

Let’s take a look at an example:

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

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

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

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

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

Available Fixes

  1. Change the type-hint for the parameter:

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

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

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
738
            $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...
739
            $form->setData($data);
740
            if ($form->isValid()) {
741
                $result = $this->getGameService()->sendShareMail($data, $game, $user, $lastEntry);
742
                if ($result) {
743
                    $statusMail = true;
744
                }
745
            }
746
        }
747
    
748
        // buildView must be before sendMail because it adds the game template path to the templateStack
749
        $viewModel = $this->buildView($game);
750
    
751
        $this->getGameService()->sendMail($game, $user, $lastEntry);
752
    
753
        $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...
754
            'statusMail'       => $statusMail,
755
            'form'             => $form,
756
        ));
757
    
758
        return $viewModel;
759
    }
760
    
761 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...
762
    {
763
        $viewModel = new JsonModel();
764
        $viewModel->setTerminal(true);
765
        $identifier = $this->getEvent()->getRouteMatch()->getParam('id');
766
        $fbId = $this->params()->fromQuery('fbId');
767
        $user = $this->zfcUserAuthentication()->getIdentity();
0 ignored issues
show
Documentation Bug introduced by
The method zfcUserAuthentication does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
768
        $sg = $this->getGameService();
769
    
770
        $game = $sg->checkGame($identifier);
771
        if (!$game) {
772
            return $this->errorJson();
773
        }
774
        $entry = $sg->checkExistingEntry($game, $user);
775
        if (! $entry) {
776
            return $this->errorJson();
777
        }
778
        if (!$fbId) {
779
            return $this->errorJson();
780
        }
781
    
782
        $sg->postFbWall($fbId, $game, $user, $entry);
783
    
784
        return $this->successJson();
785
    }
786
    
787
    public function fbrequestAction()
788
    {
789
        $viewModel = new ViewModel();
790
        $viewModel->setTerminal(true);
791
        $identifier = $this->getEvent()->getRouteMatch()->getParam('id');
792
        $fbId = $this->params()->fromQuery('fbId');
793
        $to = $this->params()->fromQuery('to');
794
        $user = $this->zfcUserAuthentication()->getIdentity();
0 ignored issues
show
Documentation Bug introduced by
The method zfcUserAuthentication does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
795
        $sg = $this->getGameService();
796
    
797
        $game = $sg->checkGame($identifier);
798
        if (!$game) {
799
            return $this->errorJson();
800
        }
801
        $entry = $sg->checkExistingEntry($game, $user);
802
        if (! $entry) {
803
            return $this->errorJson();
804
        }
805
        if (!$fbId) {
806
            return $this->errorJson();
807
        }
808
    
809
        $sg->postFbRequest($fbId, $game, $user, $entry, $to);
810
    
811
        return $this->successJson();
812
    }
813
    
814
    public function tweetAction()
815
    {
816
        $identifier = $this->getEvent()->getRouteMatch()->getParam('id');
817
        $tweetId = $this->params()->fromQuery('tweetId');
818
        $user = $this->zfcUserAuthentication()->getIdentity();
0 ignored issues
show
Documentation Bug introduced by
The method zfcUserAuthentication does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
819
        $sg = $this->getGameService();
820
    
821
        $game = $sg->checkGame($identifier);
822
        if (!$game) {
823
            return $this->errorJson();
824
        }
825
        $entry = $sg->checkExistingEntry($game, $user);
826
        if (! $entry) {
827
            return $this->errorJson();
828
        }
829
        if (!$tweetId) {
830
            return $this->errorJson();
831
        }
832
    
833
        $sg->postTwitter($tweetId, $game, $user, $entry);
834
    
835
        return $this->successJson();
836
    }
837
    
838 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...
839
    {
840
        $viewModel = new ViewModel();
841
        $viewModel->setTerminal(true);
842
        $identifier = $this->getEvent()->getRouteMatch()->getParam('id');
843
        $googleId = $this->params()->fromQuery('googleId');
844
        $user = $this->zfcUserAuthentication()->getIdentity();
0 ignored issues
show
Documentation Bug introduced by
The method zfcUserAuthentication does not exist on object<PlaygroundGame\Co...rontend\GameController>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
845
        $sg = $this->getGameService();
846
    
847
        $game = $sg->checkGame($identifier);
848
        if (!$game) {
849
            return $this->errorJson();
850
        }
851
        $entry = $sg->checkExistingEntry($game, $user);
852
        if (! $entry) {
853
            return $this->errorJson();
854
        }
855
        if (!$googleId) {
856
            return $this->errorJson();
857
        }
858
    
859
        $sg->postGoogle($googleId, $game, $user, $entry);
860
    
861
        return $this->successJson();
862
    }
863
864
    public function optinAction()
865
    {
866
        $request = $this->getRequest();
867
        $identifier = $this->getEvent()->getRouteMatch()->getParam('id');
868
        $userService = $this->getServiceLocator()->get('zfcuser_user_service');
869
    
870
        $sg = $this->getGameService();
871
    
872
        $game = $sg->checkGame($identifier, false);
873
        if (!$game) {
874
            return $this->notFoundAction();
875
        }
876
877
        if ($request->isPost()) {
878
            $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...
879
            $data['optinPartner'] = ($this->params()->fromPost('optinPartner'))? 1:0;
880
881
            $userService->updateNewsletter($data);
882
        }
883
884
        return $this->redirect()->toUrl($this->url()->fromRoute('frontend/' . $game->getClassType() . '/index', array('id' => $game->getIdentifier(), 'channel' => $this->getEvent()->getRouteMatch()->getParam('channel'))));
885
    }
886
    
887
    public function loginAction()
888
    {
889
        $request = $this->getRequest();
890
        $form    = $this->getServiceLocator()->get('zfcuser_login_form');
891
        
892
        $identifier = $this->getEvent()->getRouteMatch()->getParam('id');
893
        
894
        $sg = $this->getGameService();
895
        
896
        $game = $sg->checkGame($identifier, false);
897
        if (!$game) {
898
            return $this->notFoundAction();
899
        }
900
    
901
        if ($request->isPost()) {
902
            $form->setData($request->getPost());
903
            
904
            if (!$form->isValid()) {
905
                $this->flashMessenger()->setNamespace('zfcuser-login-form')->addMessage('Authentication failed. Please try again.');
906
            
907
                return $this->redirect()->toUrl($this->url()->fromRoute('frontend/' . $game->getClassType() . '/login', array('id' => $game->getIdentifier(), 'channel' => $this->getEvent()->getRouteMatch()->getParam('channel'))).($redirect ? '?redirect='.$redirect : ''));
0 ignored issues
show
Bug introduced by
The variable $redirect does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
908
            }
909
            
910
            // clear adapters
911
            $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...
912
            $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...
913
914
            $logged = $this->forward()->dispatch('playgrounduser_user', array('action' => 'ajaxauthenticate'));
915
916 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...
917
                return $this->redirect()->toUrl($this->url()->fromRoute('frontend/' . $game->getClassType() . '/' . $game->nextStep('index'), array('id' => $game->getIdentifier(), 'channel' => $this->getEvent()->getRouteMatch()->getParam('channel'))));
918
            } else {
919
                $this->flashMessenger()->setNamespace('zfcuser-login-form')->addMessage('Authentication failed. Please try again.');
920
                return $this->redirect()->toUrl($this->url()->fromRoute('frontend/' . $game->getClassType() . '/login', array('id' => $game->getIdentifier(), 'channel' => $this->getEvent()->getRouteMatch()->getParam('channel'))));
921
            }
922
        }
923
        
924
        $form->setAttribute('action', $this->url()->fromRoute('frontend/'.$game->getClassType().'/login', array('id' => $game->getIdentifier(), 'channel' => $this->getEvent()->getRouteMatch()->getParam('channel'))));
925
        $viewModel = $this->buildView($game);
926
        $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...
927
            'form'             => $form,
928
        ));
929
        return $viewModel;
930
    }
931
932
    public function userregisterAction()
933
    {
934
        $identifier = $this->getEvent()->getRouteMatch()->getParam('id');
935
        $sg = $this->getGameService();
936
        $game = $sg->checkGame($identifier, false);
937
        $userOptions = $this->getServiceLocator()->get('zfcuser_module_options');
938
939
        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...
940
            return $this->redirect()->toUrl($this->url()->fromRoute('frontend/'.$game->getClassType().'/'.$game->nextStep('index'), array('id' => $game->getIdentifier(), 'channel' => $this->getEvent()->getRouteMatch()->getParam('channel'))));
941
        }
942
        $request = $this->getRequest();
943
        $service = $this->getServiceLocator()->get('zfcuser_user_service');
944
        $form = $this->getServiceLocator()->get('playgroundgame_register_form');
945
        $socialnetwork = $this->params()->fromRoute('socialnetwork', false);
946
        $form->setAttribute('action', $this->url()->fromRoute('frontend/'.$game->getClassType().'/user-register', array('id' => $game->getIdentifier(), 'channel' => $this->getEvent()->getRouteMatch()->getParam('channel'))));
947
        $params = array();
948
        $socialCredentials = array();
949
950
        if ($userOptions->getUseRedirectParameterIfPresent() && $request->getQuery()->get('redirect')) {
951
            $redirect = $request->getQuery()->get('redirect');
952
        } else {
953
            $redirect = false;
954
        }
955
956
        if ($socialnetwork) {
957
            $infoMe = null;
0 ignored issues
show
Unused Code introduced by
$infoMe is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
958
            $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...
959
960
            if (!empty($infoMe)) {
961
                $user = $this->getProviderService()->getUserProviderMapper()->findUserByProviderId($infoMe->identifier, $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...
962
963
                if ($user || $service->getOptions()->getCreateUserAutoSocial() === true) {
964
                    //on le dirige vers l'action d'authentification
965
                    if (! $redirect && $userOptions->getLoginRedirectRoute() != '') {
966
                        $redirect = $this->url()->fromRoute('frontend/'.$game->getClassType().'/login', array('id' => $game->getIdentifier(), 'channel' => $this->getEvent()->getRouteMatch()->getParam('channel')));
967
                    }
968
                    $redir = $this->url()
969
                        ->fromRoute('frontend/'.$game->getClassType().'/login', array('id' => $game->getIdentifier(), 'channel' => $this->getEvent()->getRouteMatch()->getParam('channel'))) .'/' . $socialnetwork . ($redirect ? '?redirect=' . $redirect : '');
970
971
                    return $this->redirect()->toUrl($redir);
972
                }
973
974
                // Je retire la saisie du login/mdp
975
                $form->setAttribute('action', $this->url()->fromRoute('frontend/'.$game->getClassType().'/user-register', array('id' => $game->getIdentifier(), 'socialnetwork' => $socialnetwork, 'channel' => $this->getEvent()->getRouteMatch()->getParam('channel'))));
976
                $form->remove('password');
977
                $form->remove('passwordVerify');
978
979
                $birthMonth = $infoMe->birthMonth;
980
                if (strlen($birthMonth) <= 1) {
981
                    $birthMonth = '0'.$birthMonth;
982
                }
983
                $birthDay = $infoMe->birthDay;
984
                if (strlen($birthDay) <= 1) {
985
                    $birthDay = '0'.$birthDay;
986
                }
987
                $title = '';
0 ignored issues
show
Unused Code introduced by
$title is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
988
                $gender = $infoMe->gender;
989
                if ($gender == 'female') {
990
                    $title = 'Me';
991
                } else {
992
                    $title = 'M';
993
                }
994
995
                $params = array(
996
                    //'birth_year'  => $infoMe->birthYear,
997
                    'title'      => $title,
998
                    'dob'      => $birthDay.'/'.$birthMonth.'/'.$infoMe->birthYear,
999
                    'firstname'   => $infoMe->firstName,
1000
                    'lastname'    => $infoMe->lastName,
1001
                    'email'       => $infoMe->email,
1002
                    'postalCode' => $infoMe->zip,
1003
                );
1004
                $socialCredentials = array(
1005
                    'socialNetwork' => strtolower($socialnetwork),
1006
                    'socialId'      => $infoMe->identifier,
1007
                );
1008
            }
1009
        }
1010
1011
        $redirectUrl = $this->url()->fromRoute('frontend/'.$game->getClassType().'/user-register', array('id' => $game->getIdentifier(), 'channel' => $this->getEvent()->getRouteMatch()->getParam('channel'))) .($socialnetwork ? '/' . $socialnetwork : ''). ($redirect ? '?redirect=' . $redirect : '');
1012
        $prg = $this->prg($redirectUrl, true);
1013
1014
        if ($prg instanceof Response) {
1015
            return $prg;
1016
        } elseif ($prg === false) {
1017
            $form->setData($params);
1018
            $viewModel = $this->buildView($game);
1019
            $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...
1020
                'registerForm' => $form,
1021
                'enableRegistration' => $userOptions->getEnableRegistration(),
1022
                'redirect' => $redirect,
1023
            ));
1024
            return $viewModel;
1025
        }
1026
1027
        $post = $prg;
1028
        $post = array_merge(
1029
            $post,
1030
            $socialCredentials
1031
        );
1032
1033
        $user = $service->register($post, 'playgroundgame_register_form');
1034
1035
        if (! $user) {
1036
            $viewModel = $this->buildView($game);
1037
            $viewModel->setVariables(array(
1038
                'registerForm' => $form,
1039
                'enableRegistration' => $userOptions->getEnableRegistration(),
1040
                'redirect' => $redirect,
1041
            ));
1042
            
1043
            return $viewModel;
1044
        }
1045
1046
        if ($service->getOptions()->getEmailVerification()) {
1047
            $vm = new ViewModel(array('userEmail' => $user->getEmail()));
1048
            $vm->setTemplate('playground-user/register/registermail');
1049
1050
            return $vm;
1051
        } elseif ($service->getOptions()->getLoginAfterRegistration()) {
1052
            $identityFields = $service->getOptions()->getAuthIdentityFields();
1053
            if (in_array('email', $identityFields)) {
1054
                $post['identity'] = $user->getEmail();
1055
            } elseif (in_array('username', $identityFields)) {
1056
                $post['identity'] = $user->getUsername();
1057
            }
1058
            $post['credential'] = isset($post['password'])?$post['password']:'';
1059
            $request->setPost(new Parameters($post));
1060
1061
            // clear adapters
1062
            $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...
1063
            $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...
1064
1065
            $logged = $this->forward()->dispatch('playgrounduser_user', array('action' => 'ajaxauthenticate'));
1066
1067 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...
1068
                return $this->redirect()->toUrl($this->url()->fromRoute('frontend/' . $game->getClassType() . '/' . $game->nextStep('index'), array('id' => $game->getIdentifier(), 'channel' => $this->getEvent()->getRouteMatch()->getParam('channel'))));
1069
            } else {
1070
                $this->flashMessenger()->setNamespace('zfcuser-login-form')->addMessage('Authentication failed. Please try again.');
1071
                return $this->redirect()->toUrl($this->url()->fromRoute('frontend/' . $game->getClassType() . '/login', array('id' => $game->getIdentifier(), 'channel' => $this->getEvent()->getRouteMatch()->getParam('channel'))));
1072
            }
1073
        }
1074
1075
        $redirect = $this->url()->fromRoute('frontend/'.$game->getClassType().'/login', array('id' => $game->getIdentifier(), 'channel' => $this->getEvent()->getRouteMatch()->getParam('channel'))) . ($socialnetwork ? '/' . $socialnetwork : ''). ($redirect ? '?redirect=' . $redirect : '');
1076
1077
        return $this->redirect()->toUrl($redirect);
1078
    }
1079
    
1080
    /**
1081
     * return ajax response in json format
1082
     *
1083
     * @param array $data
1084
     * @return \Zend\View\Model\JsonModel
1085
     */
1086 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...
1087
    {
1088
        $model = new JsonModel(array(
1089
            'success' => true,
1090
            'data' => $data
1091
        ));
1092
        return $model->setTerminal(true);
1093
    }
1094
    
1095
    /**
1096
     * return ajax response in json format
1097
     *
1098
     * @param string $message
1099
     * @return \Zend\View\Model\JsonModel
1100
     */
1101 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...
1102
    {
1103
        $model = new JsonModel(array(
1104
            'success' => false,
1105
            'message' => $message
1106
        ));
1107
        return $model->setTerminal(true);
1108
    }
1109
1110
    /**
1111
     * @param string $helperName
1112
     */
1113
    protected function getViewHelper($helperName)
1114
    {
1115
        return $this->getServiceLocator()->get('viewhelpermanager')->get($helperName);
1116
    }
1117
1118
    public function getGameService()
1119
    {
1120
        if (!$this->gameService) {
1121
            $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\Co...r\Frontend\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...
1122
        }
1123
1124
        return $this->gameService;
1125
    }
1126
1127
    public function setGameService(GameService $gameService)
1128
    {
1129
        $this->gameService = $gameService;
0 ignored issues
show
Documentation Bug introduced by
It seems like $gameService of type object<PlaygroundGame\Service\GameService> is incompatible with the declared type object<PlaygroundGame\Co...r\Frontend\gameService> of property $gameService.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
1130
1131
        return $this;
1132
    }
1133
1134
    public function getPrizeService()
1135
    {
1136
        if (!$this->prizeService) {
1137
            $this->prizeService = $this->getServiceLocator()->get('playgroundgame_prize_service');
1138
        }
1139
1140
        return $this->prizeService;
1141
    }
1142
1143
    public function setPrizeService(PrizeService $prizeService)
1144
    {
1145
        $this->prizeService = $prizeService;
1146
1147
        return $this;
1148
    }
1149
1150
    public function getOptions()
1151
    {
1152
        if (!$this->options) {
1153
            $this->setOptions($this->getServiceLocator()->get('playgroundcore_module_options'));
1154
        }
1155
1156
        return $this->options;
1157
    }
1158
1159
    public function setOptions($options)
1160
    {
1161
        $this->options = $options;
1162
1163
        return $this;
1164
    }
1165
}
1166