GameController::editGame()   F
last analyzed

Complexity

Conditions 46
Paths > 20000

Size

Total Lines 425

Duplication

Lines 6
Ratio 1.41 %

Importance

Changes 0
Metric Value
dl 6
loc 425
rs 0
c 0
b 0
f 0
cc 46
nc 64168
nop 2

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace PlaygroundGame\Controller\Admin;
4
5
use PlaygroundGame\Service\Game as AdminGameService;
6
use Zend\Mvc\Controller\AbstractActionController;
7
use Zend\View\Model\ViewModel;
8
use PlaygroundGame\Options\ModuleOptions;
9
use Zend\Paginator\Paginator;
10
use DoctrineORMModule\Paginator\Adapter\DoctrinePaginator as DoctrineAdapter;
11
use PlaygroundCore\ORM\Pagination\LargeTablePaginator;
12
use Doctrine\ORM\Tools\Pagination\Paginator as ORMPaginator;
13
use Zend\Stdlib\ErrorHandler;
14
use Zend\ServiceManager\ServiceLocatorInterface;
15
use Zend\Session\Container;
16
17
class GameController extends AbstractActionController
18
{
19
    protected $options;
20
21
    /**
22
     * @var \PlaygroundGame\Service\Game
23
     */
24
    protected $adminGameService;
25
26
    protected $game;
27
28
    /**
29
     *
30
     * @var ServiceManager
31
     */
32
    protected $serviceLocator;
33
34
    public function __construct(ServiceLocatorInterface $locator)
35
    {
36
        $this->serviceLocator = $locator;
0 ignored issues
show
Documentation Bug introduced by
It seems like $locator of type object<Zend\ServiceManag...erviceLocatorInterface> is incompatible with the declared type object<PlaygroundGame\Co...r\Admin\ServiceManager> of property $serviceLocator.

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...
37
    }
38
39
    public function getServiceLocator()
40
    {
41
        return $this->serviceLocator;
42
    }
43
44
    public function checkGame()
45
    {
46
        $gameId = $this->getEvent()->getRouteMatch()->getParam('gameId');
47
        if (!$gameId) {
48
            return $this->redirect()->toUrl($this->adminUrl()->fromRoute('playgroundgame/list'));
0 ignored issues
show
Documentation Bug introduced by
The method adminUrl does not exist on object<PlaygroundGame\Co...r\Admin\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...
49
        }
50
        
51
        $game = $this->getAdminGameService()->getGameMapper()->findById($gameId);
52
        if (!$game) {
53
            return $this->redirect()->toUrl($this->adminUrl()->fromRoute('playgroundgame/list'));
0 ignored issues
show
Documentation Bug introduced by
The method adminUrl does not exist on object<PlaygroundGame\Co...r\Admin\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...
54
        }
55
        $this->game = $game;
56
    }
57
58
    public function createForm($form)
59
    {
60
        // I use the wonderful Form Generator to create the Player form
61
        $this->forward()->dispatch(
62
            'playgroundcore_admin_formgen',
63
            array(
64
                'controller' => 'playgroundcore_admin_formgen',
65
                'action' => 'create'
66
            )
67
        );
68
69
        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, Zend\Psr7Bridge\Zend\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...
70
            $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, Zend\Psr7Bridge\Zend\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...
71
            $form = $this->getAdminGameService()->createForm($data, $this->game, $form);
72
            if ($form) {
73
                $this->flashMessenger()->setNamespace('playgroundgame')->addMessage('The form was created');
0 ignored issues
show
Documentation Bug introduced by
The method flashMessenger does not exist on object<PlaygroundGame\Co...r\Admin\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...
74
            }
75
        }
76
        $formTemplate='';
77
        if ($form) {
78
            $formTemplate = $form->getFormTemplate();
79
        }
80
81
        return array(
82
            'form' => $form,
83
            'formTemplate' => $formTemplate,
84
            'gameId' => $this->game->getId(),
85
            'game' => $this->game,
86
        );
87
    }
88
89
    /**
90
     * @param string $templatePath
91
     * @param string $formId
92
     */
93
    public function editGame($templatePath, $formId)
94
    {
95
        // We try to get FB pages from the logged in user
96
        $session = new Container('facebook');
97
        $config = $this->getServiceLocator()->get('config');
98
        $appsArray = [];
99
        $platformFbAppId = '';
100
        
101
        if (isset($config['facebook'])) {
102
            $platformFbAppId     = $config['facebook']['fb_appid'];
103
            $platformFbAppSecret = $config['facebook']['fb_secret'];
104
        }
105
        $fb = new \Facebook\Facebook([
106
            'app_id' => $platformFbAppId,
107
            'app_secret' => $platformFbAppSecret,
0 ignored issues
show
Bug introduced by
The variable $platformFbAppSecret does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
108
            'default_graph_version' => 'v3.1',
109
        ]);
110
111
        $helper = $fb->getRedirectLoginHelper();
112
        $fb_args_param = array('req_perms' => 'manage_pages,publish_pages');
113
        $fb_login_url = $helper->getLoginUrl($this->adminUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method adminUrl does not exist on object<PlaygroundGame\Co...r\Admin\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...
114
            'playgroundgame/list',
115
            array(),
116
            array('force_canonical' => true)
117
        ), $fb_args_param);
118
        $accessToken = $helper->getAccessToken();
119
120
        if (isset($accessToken) || $session->offsetExists('fb_token')) {
121
            if (isset($accessToken)) {
122
                $session->offsetSet('fb_token', $accessToken);
123
            }
124
125
            // checking if user access token is not valid then ask user to login again
126
            $debugToken = $fb->get('/debug_token?input_token='. $session->offsetGet('fb_token'), $platformFbAppId . '|' . $platformFbAppSecret)
127
            ->getGraphNode()
128
            ->asArray();
129
            if (isset($debugToken['error']['code'])) {
130
                $session->offsetUnset('fb_token');
131
            } else {
132
                // setting default user access token for future requests
133
                $fb->setDefaultAccessToken($session->offsetGet('fb_token'));
134
                $pages = $fb->get('/me/accounts')
135
                    ->getGraphEdge()
136
                    ->asArray();
137
138
                foreach ($pages as $key) {
139
                    $app_label = '';
140
                    if (isset($key['name'])) {
141
                        $app_label .= $key['name'];
142
                    }
143
                    if (isset($key['id'])) {
144
                        $app_label .= ' ('.$key['id'].')';
145
                    }
146
                    $appsArray[$key['id']] = $app_label;
147
                }
148
                $fb_login_url = '';
149
150
                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, Zend\Psr7Bridge\Zend\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...
151
                    $data = array_replace_recursive(
152
                        $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, Zend\Psr7Bridge\Zend\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...
153
                        $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, Zend\Psr7Bridge\Zend\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...
154
                    );
155
                    // Removing a previously page tab set on this game
156
                    if ($this->game &&
157
                        !empty($this->game->getFbPageId()) &&
158
                        !empty($this->game->getFbAppId()) &&
159
                        (
160
                            (
161
                                $this->game->getFbPageId() !== $data['fbPageId'] ||
162
                                $this->game->getFbAppId() !== $data['fbAppId']
163
                            ) ||
164
                            $data['broadcastFacebook'] == 0
165
                        )
166
                    ) {
167
                        $oldPage = $fb->get('/' . $this->game->getFbPageId() . '?fields=access_token,name,id')
168
                            ->getGraphNode()
169
                            ->asArray();
170
                        $removeTab = $fb->delete(
0 ignored issues
show
Unused Code introduced by
$removeTab 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...
171
                            '/' . $this->game->getFbPageId() . '/tabs',
172
                            [
173
                                    'tab' => 'app_'.$this->game->getFbAppId(),
174
                                ],
175
                            $oldPage['access_token']
176
                        )
177
                            ->getGraphNode()
178
                            ->asArray();
179
                    }
180
181
                    // Removing a previously post set on this game
182
                    if ($this->game &&
183
                        !empty($this->game->getFbPostId()) &&
184
                        $data['broadcastPostFacebook'] == 0
185
                    ) {
186
                        $oldPage = $fb->get('/' . $this->game->getFbPageId() . '?fields=access_token,name,id')
187
                            ->getGraphNode()
188
                            ->asArray();
189
                        $removePost = $fb->delete(
0 ignored issues
show
Unused Code introduced by
$removePost 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...
190
                            '/' . $this->game->getFbPostId(),
191
                            [],
192
                            $oldPage['access_token']
193
                        )
194
                            ->getGraphNode()
195
                            ->asArray();
196
                    }
197
                }
198
            }
199
        }
200
201
        $viewModel = new ViewModel();
202
        $viewModel->setTemplate($templatePath);
203
204
        $gameForm = new ViewModel();
205
        $gameForm->setTemplate('playground-game/game/game-form');
206
207
        $form   = $this->getServiceLocator()->get($formId);
208
        $form->setAttribute(
209
            'action',
210
            $this->adminUrl()->fromRoute(
0 ignored issues
show
Documentation Bug introduced by
The method adminUrl does not exist on object<PlaygroundGame\Co...r\Admin\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...
211
                'playgroundgame/edit-' . $this->game->getClassType(),
212
                array('gameId' => $this->game->getId())
213
            )
214
        );
215
        $form->setAttribute('method', 'post');
216
217
        $pageIds = $form->get('fbPageId')->getOption('value_options');
218
        foreach ($appsArray as $k => $v) {
219
            $pageIds[$k] = $v;
220
        }
221
        $form->get('fbPageId')->setAttribute('options', $pageIds);
222
223
        //if($form->get('fbAppId')->getValue() == '') {
224
            $form->get('fbAppId')->setValue($platformFbAppId);
225
        //}
226
227
        // if ($this->game->getFbAppId()) {
228
        //     $data['fbAppId'] = $form->get('fbAppId')->getOption('value_options');
229
        //     $appIds[$this->game->getFbAppId()] = $this->game->getFbAppId();
230
        //     $form->get('fbAppId')->setAttribute('options', $appIds);
231
        // }
232
233
        $gameOptions = $this->getAdminGameService()->getOptions();
234
        $gameStylesheet = $gameOptions->getMediaPath() . '/' . 'stylesheet_'. $this->game->getId(). '.css';
235 View Code Duplication
        if (is_file($gameStylesheet)) {
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...
236
            $values = $form->get('stylesheet')->getValueOptions();
237
            $values[$gameStylesheet] = 'Style personnalisé de ce jeu';
238
239
            $form->get('stylesheet')->setAttribute('options', $values);
240
        }
241
242
        $form->bind($this->game);
243
244
        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, Zend\Psr7Bridge\Zend\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...
245
            $data = array_replace_recursive(
246
                $this->getRequest()->getPost()->toArray(),
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Zend\Stdlib\RequestInterface as the method getPost() does only exist in the following implementations of said interface: Zend\Http\PhpEnvironment\Request, Zend\Http\Request, Zend\Psr7Bridge\Zend\Request.

Let’s take a look at an example:

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

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

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

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

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

Available Fixes

  1. Change the type-hint for the parameter:

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

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

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
247
                $this->getRequest()->getFiles()->toArray()
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Zend\Stdlib\RequestInterface as the method getFiles() does only exist in the following implementations of said interface: Zend\Http\PhpEnvironment\Request, Zend\Http\Request, Zend\Psr7Bridge\Zend\Request.

Let’s take a look at an example:

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

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

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

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

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

Available Fixes

  1. Change the type-hint for the parameter:

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

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

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
248
            );
249
            if (empty($data['prizes'])) {
250
                $data['prizes'] = array();
251
            }
252
            if (isset($data['drawDate']) && $data['drawDate']) {
253
                $data['drawDate'] = \DateTime::createFromFormat('d/m/Y', $data['drawDate']);
254
            }
255
256
            $game = $this->getAdminGameService()->createOrUpdate($data, $this->game, $formId);
257
258
            if ($game) {
259
                if ($session->offsetExists('fb_token')) {
260
                    if (!empty($data['fbPageId']) && !empty($data['fbAppId'])) {
261
                        $page = $fb->get('/' . $data['fbPageId'] . '?fields=access_token,name,id')
262
                        ->getGraphNode()
263
                        ->asArray();
264
265
                        // let's create a post on FB
266
                        if ($data['broadcastPostFacebook'] && $game->getWelcomeBlock() != '' && $game->getMainImage() != '') {
267
                            $imgPath = $this->url()->fromRoute('frontend', [], ['force_canonical' => true], false).$game->getMainImage();
268
                            // emoticons : $emoji = html_entity_decode('&#128520;');
269
270
                            $message = str_replace('<p>', "", $game->getWelcomeBlock());
271
                            $message = str_replace('</p>', "\n", $message);
272
                            $message = strip_tags($message);
273
274
                            // Create the post
275
                            try {
276
                                // Associate the fbAppId to the page so that we can receive the webhooks
277
                                $linkAppToPage = $fb->post(
0 ignored issues
show
Unused Code introduced by
$linkAppToPage 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...
278
                                    '/' . $page['id'] . '/subscribed_apps',
279
                                    array(),
280
                                    $page['access_token']
281
                                );
282
283
                                /**
284
                                 *  post text and save the post_id to be able to get the likes and comments on the post
285
                                 */
286
                                // $post = $fb->post(
287
                                //     '/' . $page['id'] . '/feed',
288
                                //     array(
289
                                //         'message'           => 'message',
290
                                //     ),
291
                                //     $page['access_token']
292
                                // );
293
    
294
                                /**
295
                                 * Post a photo
296
                                 */
297
                                // $post = $fb->post(
298
                                //     '/' . $page['id'] . '/photos',
299
                                //     array(
300
                                //         'url'           => 'https://images.unsplash.com/photo-1538239010247-383da61e35db?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=22e9de10cd7e4d8e32d698099dc6d23c&auto=format&fit=crop&w=3289&q=80',
301
                                //         'published'     => true,
302
                                //     ),
303
                                //     $page['access_token']
304
                                // );
305
    
306
                                /**
307
                                 * Upload an unpublished photo and include it in a post
308
                                 */
309
                                $img = $fb->post(
310
                                    '/' . $page['id'] . '/photos',
311
                                    array(
312
                                        'url'           => $imgPath,
313
                                        'published'     => false,
314
                                    ),
315
                                    $page['access_token']
316
                                );
317
                                $img = $img->getGraphNode()->asArray();
318
                                
319
                                if ($game->getFbPostId() != '') {
320
                                    $post = $fb->post(
321
                                        '/' . $game->getFbPostId(),
322
                                        array(
323
                                            'message'           => $message,
324
                                            'attached_media[0]' => '{"media_fbid":"'.$img['id'].'"}',
325
                                        ),
326
                                        $page['access_token']
327
                                    );
328
                                } else {
329
                                    $post = $fb->post(
330
                                        '/' . $page['id'] . '/feed',
331
                                        array(
332
                                            'message'           => $message,
333
                                            'attached_media[0]' => '{"media_fbid":"'.$img['id'].'"}',
334
                                        ),
335
                                        $page['access_token']
336
                                    );
337
                                }
338
    
339
                                /**
340
                                 * Upload an unpublished photo and include it in a scheduled post
341
                                 */
342
                                // $img = $fb->post(
343
                                //     '/' . $page['id'] . '/photos',
344
                                //     array(
345
                                //         'url'           => 'https://images.unsplash.com/photo-1538239010247-383da61e35db?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=22e9de10cd7e4d8e32d698099dc6d23c&auto=format&fit=crop&w=3289&q=80',
346
                                //         'published'     => false,
347
                                //         'temporary'     => true
348
                                //     ),
349
                                //     $page['access_token']
350
                                // );
351
                                // $img = $img->getGraphNode()->asArray();
352
                                //
353
                                // $post = $fb->post(
354
                                //     '/' . $page['id'] . '/feed',
355
                                //     array(
356
                                //         'message'           => 'message avec image',
357
                                //         'attached_media[0]' => '{"media_fbid":"'.$img['id'].'"}',
358
                                //         'published'     => false,
359
                                //         'scheduled_publish_time' => '1512068400',
360
                                //         'unpublished_content_type' => 'SCHEDULED',
361
                                //     ),
362
                                //     $page['access_token']
363
                                // );
364
    
365
                                /**
366
                                 * publish multiple photos then associate these photos to a post
367
                                 */
368
                                // $endpoint = "/".$page['id']."/photos";
369
                                // $multiple_photos = [
370
                                //     'https://images.unsplash.com/photo-1538239010247-383da61e35db?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=22e9de10cd7e4d8e32d698099dc6d23c&auto=format&fit=crop&w=3289&q=80',
371
                                //     'https://images.unsplash.com/photo-1538218952949-2f5dda4a9156?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=b79a9c7314dd5ca8eac2f187902ceca2&auto=format&fit=crop&w=2704&q=80',
372
                                //     'https://images.unsplash.com/photo-1538157245064-badfdabb7142?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=dfa50d5dd51b85f25ca03f2b2667752a&auto=format&fit=crop&w=2700&q=80',
373
                                // ];
374
                                // $photos = [];
375
                                // $data_post = ['attached_media' => [], 'message' => 'message', 'published' => true];
376
                                // foreach ($multiple_photos as $file_url):
377
                                //     array_push($photos, $fb->request('POST',$endpoint,['url' =>$file_url,'published' => false,'temporary' => true], $page['access_token']));
378
                                // endforeach;
379
                                // $uploaded_photos = $fb->sendBatchRequest($photos, $page['access_token']);
380
                                // $uploaded_photos = $uploaded_photos->getGraphNode()->asArray();
381
                                
382
                                // foreach ($uploaded_photos as $photo):
383
                                //     $photo = json_decode($photo['body']);
384
                                //     array_push($data_post['attached_media'], '{"media_fbid":"'.$photo->id.'"}');
385
                                // endforeach;
386
                                // $post = $fb->sendRequest('POST', "/".$page['id']."/feed", $data_post, $page['access_token']);
387
    
388
                                /**
389
                                 * publish a carrousel to a post
390
                                 */
391
                                // $data_post = [
392
                                //     'child_attachments' => [],
393
                                //     'message' => 'message',
394
                                //     'link' => 'https://www.playground.gg',
395
                                //     'multi_share_end_card' => false,
396
                                //     'published' => true,
397
                                // ];
398
                                
399
                                // $multiple_photos = [
400
                                //     'https://images.unsplash.com/photo-1538239010247-383da61e35db?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=22e9de10cd7e4d8e32d698099dc6d23c&auto=format&fit=crop&w=3289&q=80',
401
                                //     'https://images.unsplash.com/photo-1538218952949-2f5dda4a9156?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=b79a9c7314dd5ca8eac2f187902ceca2&auto=format&fit=crop&w=2704&q=80',
402
                                //     'https://images.unsplash.com/photo-1538157245064-badfdabb7142?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=dfa50d5dd51b85f25ca03f2b2667752a&auto=format&fit=crop&w=2700&q=80',
403
                                // ];
404
                                // foreach ($multiple_photos as $k => $photo):
405
                                //     array_push($data_post['child_attachments'], '{"link":"'.$photo.'", "name": "message_'.$k.'"}');
406
                                // endforeach;
407
                                // $post = $fb->sendRequest('POST', "/".$page['id']."/feed", $data_post, $page['access_token']);
408
    
409
                                /** Texte avec lien vers une page
410
                                 *
411
                                 */
412
                                // $post = $fb->post(
413
                                //     '/' . $page['id'] . '/feed',
414
                                //     array(
415
                                //         'message'           => 'message',
416
                                //         'link'              => 'https://images.unsplash.com/photo-1538239010247-383da61e35db?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=22e9de10cd7e4d8e32d698099dc6d23c&auto=format&fit=crop&w=3289&q=80',
417
                                //         //'picture'           => 'https://images.unsplash.com/photo-1538239010247-383da61e35db?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=22e9de10cd7e4d8e32d698099dc6d23c&auto=format&fit=crop&w=3289&q=80',
418
                                //         'call_to_action'    => '{"type":"BOOK_TRAVEL","value":{"link":"https://images.unsplash.com/photo-1538239010247-383da61e35db?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=22e9de10cd7e4d8e32d698099dc6d23c&auto=format&fit=crop&w=3289&q=80"}}',
419
                                //     ),
420
                                //     $page['access_token']
421
                                // );
422
                            } catch (\Exception $e) {
423
                                if ($e->getMessage() == 'Missing or invalid image file') {
424
                                    if ($game->getFbPostId() != '') {
425
                                        $post = $fb->post(
426
                                            '/' . $game->getFbPostId(),
427
                                            array(
428
                                                'message' => $message,
429
                                            ),
430
                                            $page['access_token']
431
                                        );
432
                                    } else {
433
                                        $post = $fb->post(
434
                                            '/' . $page['id'] . '/feed',
435
                                            array(
436
                                                'message' => $message,
437
                                            ),
438
                                            $page['access_token']
439
                                        );
440
                                    }
441
                                } else {
442
                                    throw $e;
443
                                }
444
                            }
445
                            $post = $post->getGraphNode()->asArray();
446
                            if (isset($post['id'])) {
447
                                $game->setFbPostId($post['id']);
448
                                $game = $this->getAdminGameService()->getGameMapper()->update($game);
449
                            }
450
                        }
451
452
                        // Let's record the FB page tab if it is configured
453
                        // adding page tab to selected page using page access token
454
                        if ($data['broadcastFacebook']) {
455
                            try {
456
                                $addTab = $fb->post(
0 ignored issues
show
Unused Code introduced by
$addTab 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...
457
                                    '/' . $page['id'] . '/tabs',
458
                                    [
459
                                        'app_id' => $data['fbAppId'],
460
                                        'custom_name' => (!empty($data['fbPageTabTitle'])) ? $data['fbPageTabTitle'] : $data['title'],
461
                                        'custom_image_url' => ($game->getFbPageTabImage() !== '') ?
462
                                            $this->getAdminGameService()->getServiceManager()->get('ViewRenderer')->url(
463
                                                'frontend',
464
                                                array(),
465
                                                array('force_canonical' => true)
466
                                            ).$game->getFbPageTabImage() :
467
                                            null,
468
                                        'position' => (!empty($data['fbPageTabPosition'])) ? $data['fbPageTabPosition'] : 99
469
                                    ],
470
                                    $page['access_token']
471
                                )
472
                                    ->getGraphNode()
473
                                    ->asArray();
474
                            } catch (\Exception $e) {
475
                                // (#324) Missing or invalid image file
476
                                if ($e->getCode() == '324') {
477
                                    try {
478
                                        $addTab = $fb->post(
0 ignored issues
show
Unused Code introduced by
$addTab 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...
479
                                            '/' . $page['id'] . '/tabs',
480
                                            [
481
                                                'app_id' => $data['fbAppId'],
482
                                                'custom_name' => (!empty($data['fbPageTabTitle'])) ? $data['fbPageTabTitle'] : $data['title'],
483
                                                'position' => (!empty($data['fbPageTabPosition'])) ? $data['fbPageTabPosition'] : 99
484
                                            ],
485
                                            $page['access_token']
486
                                        )
487
                                            ->getGraphNode()
488
                                            ->asArray();
489
                                    } catch (\Exception $e) {
490
                                        throw $e;
491
                                    }
492
                                }
493
                            }
494
                        }
495
                    }
496
                }
497
                return $this->redirect()->toUrl($this->adminUrl()->fromRoute('playgroundgame/list'));
0 ignored issues
show
Documentation Bug introduced by
The method adminUrl does not exist on object<PlaygroundGame\Co...r\Admin\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...
498
            }
499
        }
500
501
        $gameForm->setVariables(
502
            array(
503
                'platform_fb_app_id' => $platformFbAppId,
504
                'fb_login_url' => $fb_login_url,
505
                'form' => $form,
506
                'game' => $this->game
507
            )
508
        );
509
        $viewModel->addChild($gameForm, 'game_form');
510
511
        return $viewModel->setVariables(
512
            array(
513
                'form' => $form,
514
                'title' => 'Edit this game',
515
            )
516
        );
517
    }
518
519
    public function listAction()
520
    {
521
        // We try to get FB pages from the logged in user
522
        $session = new Container('facebook');
523
        $config = $this->getServiceLocator()->get('config');
524
        
525
        if (isset($config['facebook'])) {
526
            $platformFbAppId     = $config['facebook']['fb_appid'];
527
            $platformFbAppSecret = $config['facebook']['fb_secret'];
528
            $fb = new \Facebook\Facebook([
529
                'app_id' => $platformFbAppId,
530
                'app_secret' => $platformFbAppSecret,
531
                'default_graph_version' => 'v3.1',
532
            ]);
533
534
            $helper = $fb->getRedirectLoginHelper();
535
            $accessToken = $helper->getAccessToken();
536
        }
537
538
        if (isset($accessToken) || $session->offsetExists('fb_token')) {
539
            if (isset($accessToken)) {
540
                $session->offsetSet('fb_token', $accessToken);
541
            }
542
543
            // checking if user access token is not valid then ask user to login again
544
            $debugToken = $fb->get('/debug_token?input_token='. $session->offsetGet('fb_token'), $platformFbAppId . '|' . $platformFbAppSecret)
0 ignored issues
show
Bug introduced by
The variable $fb does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
Bug introduced by
The variable $platformFbAppId does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
Bug introduced by
The variable $platformFbAppSecret does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
545
            ->getGraphNode()
546
            ->asArray();
547
            if (isset($debugToken['error']['code'])) {
548
                $session->offsetUnset('fb_token');
549
            } else {
550
                // setting default user access token for future requests
551
                $fb->setDefaultAccessToken($session->offsetGet('fb_token'));
552
            }
553
        }
554
        $filter    = $this->getEvent()->getRouteMatch()->getParam('filter');
555
        $type    = $this->getEvent()->getRouteMatch()->getParam('type');
556
557
        $service    = $this->getAdminGameService();
558
        $adapter = new DoctrineAdapter(new ORMPaginator($service->getQueryGamesOrderBy($type, $filter)));
559
        $paginator = new Paginator($adapter);
560
        $paginator->setItemCountPerPage(25);
561
        $paginator->setCurrentPageNumber($this->getEvent()->getRouteMatch()->getParam('p'));
562
563
        foreach ($paginator as $game) {
564
            $game->entry = $service->getEntryMapper()->countByGame($game);
565
        }
566
567
        return array(
568
            'games'    => $paginator,
569
            'type'        => $type,
570
            'filter'    => $filter,
571
        );
572
    }
573
574
    /**
575
     * Return the list of entries for the game
576
     *
577
     * @return void
578
     */
579
    public function entryAction()
580
    {
581
        $this->checkGame();
582
583
        $grid = $this->getAdminGameService()->getGrid($this->game);
584
        $grid->render();
585
        
586
        return $grid->getResponse();
587
    }
588
589 View Code Duplication
    public function invitationAction()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
590
    {
591
        $this->checkGame();
592
593
        $adapter = new DoctrineAdapter(
594
            new LargeTablePaginator(
595
                $this->getAdminGameService()->getInvitationMapper()->queryByGame($this->game)
596
            )
597
        );
598
        $paginator = new Paginator($adapter);
599
        $paginator->setItemCountPerPage(25);
600
        $paginator->setCurrentPageNumber($this->getEvent()->getRouteMatch()->getParam('p'));
601
602
        return new ViewModel(
603
            array(
604
                'invitations' => $paginator,
605
                'gameId'      => $this->game->getId(),
606
                'game'        => $this->game,
607
            )
608
        );
609
    }
610
611
    public function removeInvitationAction()
612
    {
613
        $this->checkGame();
614
615
        $service = $this->getAdminGameService();
616
        $invitationId = $this->getEvent()->getRouteMatch()->getParam('invitationId');
617
        if ($invitationId) {
618
            $invitation   = $service->getInvitationMapper()->findById($invitationId);
619
            $service->getInvitationMapper()->remove($invitation);
620
        }
621
622
        return $this->redirect()->toUrl($this->adminUrl()->fromRoute($this->game->getClassType() .'/invitation', array('gameId'=>$this->game->getId())));
0 ignored issues
show
Documentation Bug introduced by
The method adminUrl does not exist on object<PlaygroundGame\Co...r\Admin\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...
623
    }
624
    
625
    public function downloadAction()
626
    {
627
        $this->checkGame();
628
        $header = $this->getAdminGameService()->getEntriesHeader($this->game);
629
        $qb = $this->getAdminGameService()->getEntriesQuery($this->game);
630
        $query = $qb->getQuery();
631
632
        $content = "\xEF\xBB\xBF"; // UTF-8 BOM
633
        $content .= $this->getAdminGameService()->getCSV(
634
            $this->getAdminGameService()->getGameEntries(
635
                $header,
636
                $query->getResult(),
637
                $this->game
638
            )
639
        );
640
641
        $response = $this->getResponse();
642
        $headers = $response->getHeaders();
643
        $headers->addHeaderLine('Content-Encoding: UTF-8');
644
        $headers->addHeaderLine('Content-Type', 'text/csv; charset=UTF-8');
645
        $headers->addHeaderLine('Content-Disposition', "attachment; filename=\"entry.csv\"");
646
        $headers->addHeaderLine('Accept-Ranges', 'bytes');
647
        $headers->addHeaderLine('Content-Length', strlen($content));
648
649
        $response->setContent($content);
650
651
        return $response;
652
    }
653
654
    // Only used for Quiz and Lottery
655
    public function drawAction()
656
    {
657
        $this->checkGame();
658
659
        $winningEntries = $this->getAdminGameService()->draw($this->game);
660
661
        $content = "\xEF\xBB\xBF"; // UTF-8 BOM
662
        $content .= "ID;Pseudo;Nom;Prenom;E-mail;Etat\n";
663
664
        foreach ($winningEntries as $e) {
665
            $etat = 'gagnant';
666
667
            $content   .= $e->getUser()->getId()
668
            . ";" . $e->getUser()->getUsername()
669
            . ";" . $e->getUser()->getLastname()
670
            . ";" . $e->getUser()->getFirstname()
671
            . ";" . $e->getUser()->getEmail()
672
            . ";" . $etat
673
            ."\n";
674
        }
675
676
        $response = $this->getResponse();
677
        $headers = $response->getHeaders();
678
        $headers->addHeaderLine('Content-Encoding: UTF-8');
679
        $headers->addHeaderLine('Content-Type', 'text/csv; charset=UTF-8');
680
        $headers->addHeaderLine('Content-Disposition', "attachment; filename=\"gagnants.csv\"");
681
        $headers->addHeaderLine('Accept-Ranges', 'bytes');
682
        $headers->addHeaderLine('Content-Length', strlen($content));
683
684
        $response->setContent($content);
685
686
        return $response;
687
    }
688
    
689
    /**
690
     * This method serialize a game an export it as a txt file
691
     * @return \Zend\Stdlib\ResponseInterface
692
     */
693
    public function exportAction()
694
    {
695
        $this->checkGame();
696
        $content = serialize($this->game);
697
698
        $response = $this->getResponse();
699
        $headers = $response->getHeaders();
700
        $headers->addHeaderLine('Content-Encoding: UTF-8');
701
        $headers->addHeaderLine('Content-Type', 'text/plain; charset=UTF-8');
702
        $headers->addHeaderLine(
703
            'Content-Disposition',
704
            "attachment; filename=\"". $this->game->getIdentifier() .".txt\""
705
        );
706
        $headers->addHeaderLine('Accept-Ranges', 'bytes');
707
        $headers->addHeaderLine('Content-Length', strlen($content));
708
    
709
        $response->setContent($content);
710
    
711
        return $response;
712
    }
713
    
714
    /**
715
     * This method take an uploaded txt file containing a serialized game
716
     * and persist it in the database
717
     * @return unknown
718
     */
719
    public function importAction()
720
    {
721
        $form = $this->getServiceLocator()->get('playgroundgame_import_form');
722
        $form->setAttribute('action', $this->adminUrl()->fromRoute('playgroundgame/import'));
0 ignored issues
show
Documentation Bug introduced by
The method adminUrl does not exist on object<PlaygroundGame\Co...r\Admin\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...
723
        $form->setAttribute('method', 'post');
724
        
725
        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, Zend\Psr7Bridge\Zend\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...
726
            $data = array_replace_recursive(
727
                $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, Zend\Psr7Bridge\Zend\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...
728
                $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, Zend\Psr7Bridge\Zend\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...
729
            );
730
            
731
            if (! empty($data['import_file']['tmp_name'])) {
732
                ErrorHandler::start();
733
                $game = unserialize(file_get_contents($data['import_file']['tmp_name']));
734
                $game->setId(null);
735
                if ($data['slug']) {
736
                    $game->setIdentifier($data['slug']);
737
                }
738
                $duplicate = $this->getAdminGameService()->getGameMapper()->findByIdentifier($game->getIdentifier());
739
                if (!$duplicate) {
740
                    $this->getAdminGameService()->getGameMapper()->insert($game);
741
                }
742
743
                ErrorHandler::stop(true);
744
            }
745
            
746
            return $this->redirect()->toUrl($this->adminUrl()->fromRoute('playgroundgame/list'));
0 ignored issues
show
Documentation Bug introduced by
The method adminUrl does not exist on object<PlaygroundGame\Co...r\Admin\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...
747
        }
748
        
749
        return array(
750
            'form' => $form,
751
        );
752
    }
753
754
    public function removeAction()
755
    {
756
        $this->checkGame();
757
758
        try {
759
            $this->getAdminGameService()->getGameMapper()->remove($this->game);
760
            $this->flashMessenger()->setNamespace('playgroundgame')->addMessage('The game has been edited');
0 ignored issues
show
Documentation Bug introduced by
The method flashMessenger does not exist on object<PlaygroundGame\Co...r\Admin\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...
761
        } catch (\Doctrine\DBAL\DBALException $e) {
762
            $this->flashMessenger()->setNamespace('playgroundgame')->addMessage(
0 ignored issues
show
Documentation Bug introduced by
The method flashMessenger does not exist on object<PlaygroundGame\Co...r\Admin\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...
763
                'Il y a déjà eu des participants à ce jeu. Vous ne pouvez plus le supprimer'
764
            );
765
        }
766
767
        return $this->redirect()->toUrl($this->adminUrl()->fromRoute('playgroundgame/list'));
0 ignored issues
show
Documentation Bug introduced by
The method adminUrl does not exist on object<PlaygroundGame\Co...r\Admin\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
    }
769
770
    public function setActiveAction()
771
    {
772
        $this->checkGame();
773
774
        $this->game->setActive(!$this->game->getActive());
775
        $this->getAdminGameService()->getGameMapper()->update($this->game);
776
777
        return $this->redirect()->toUrl($this->adminUrl()->fromRoute('playgroundgame/list'));
0 ignored issues
show
Documentation Bug introduced by
The method adminUrl does not exist on object<PlaygroundGame\Co...r\Admin\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...
778
    }
779
780
    public function formAction()
781
    {
782
        $this->checkGame();
783
        
784
        $form = $this->game->getPlayerForm();
785
786
        return $this->createForm($form);
787
    }
788
789
    public function setOptions(ModuleOptions $options)
790
    {
791
        $this->options = $options;
792
793
        return $this;
794
    }
795
796
    public function getOptions()
797
    {
798
        if (!$this->options instanceof ModuleOptions) {
799
            $this->setOptions($this->getServiceLocator()->get('playgroundgame_module_options'));
800
        }
801
802
        return $this->options;
803
    }
804
805
    public function getAdminGameService()
806
    {
807
        if (!$this->adminGameService) {
808
            $this->adminGameService = $this->getServiceLocator()->get('playgroundgame_game_service');
809
        }
810
811
        return $this->adminGameService;
812
    }
813
814
    public function setAdminGameService(AdminGameService $adminGameService)
815
    {
816
        $this->adminGameService = $adminGameService;
817
818
        return $this;
819
    }
820
}
821