Completed
Pull Request — master (#200)
by Fèvre
08:25 queued 06:00
created

AppController::beforeRender()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 9
rs 9.6666
cc 1
eloc 5
nc 1
nop 1
1
<?php
2
namespace App\Controller;
3
4
use App\Event\Badges;
5
use App\Event\Logs;
6
use App\I18n\Language;
7
use Cake\Controller\Controller;
8
use Cake\Core\Configure;
9
use Cake\Event\Event;
10
use Cake\I18n\Time;
11
12
class AppController extends Controller
13
{
14
15
    /**
16
     * Initialization hook method.
17
     *
18
     * @return void
19
     */
20
    public function initialize()
21
    {
22
        parent::initialize();
23
24
        //Components.
25
        $this->loadComponent('Flash');
26
        $this->loadComponent('Cookie');
27
        $this->loadComponent('Acl.Acl');
28
        $this->loadComponent('SessionsActivity');
29
        $this->loadComponent('Auth', [
30
            'className' => 'AclAuth',
31
            'allowedActionsForBanned' => [
32
                'Pages' => [
33
                    'home'
34
                ]
35
            ],
36
            'authenticate' => [
37
                'Form',
38
                'Xety/Cake3CookieAuth.Cookie'
39
            ],
40
            'flash' => [
41
                'element' => 'error',
42
                'key' => 'flash',
43
                'params' => [
44
                    'class' => 'error'
45
                ]
46
            ],
47
            'authorize' => [
48
                'Acl.Actions' => [
49
                    'actionPath' => 'app/'
50
                ]
51
            ],
52
            'loginAction' => [
53
                'controller' => 'users',
54
                'action' => 'login',
55
                'prefix' => false
56
            ],
57
            'unauthorizedRedirect' => [
58
                'controller' => 'pages',
59
                'action' => 'home',
60
                'prefix' => false
61
            ],
62
            'loginRedirect' => [
63
                'controller' => 'pages',
64
                'action' => 'home'
65
            ],
66
            'logoutRedirect' => [
67
                'controller' => 'pages',
68
                'action' => 'home'
69
            ]
70
        ]);
71
72
        if (env('HTTPS')) {
73
            $this->loadComponent('Csrf', [
74
                'secure' => true
75
            ]);
76
        } else {
77
            $this->loadComponent('Csrf');
78
        }
79
    }
80
81
    /**
82
     * beforeFilter handle.
83
     *
84
     * @param Event $event The beforeFilter event that was fired.
85
     *
86
     * @return void
87
     */
88
    public function beforeFilter(Event $event)
89
    {
90
        $this->loadModel('Settings');
91
        $this->Settings->setSettings();
0 ignored issues
show
Documentation introduced by
The property Settings does not exist on object<App\Controller\AppController>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
92
93
        $this->Auth->config('authError', __('You need to be logged in or you are not authorized to access that location !'));
94
95
        //Define the language.
96
        $language = new Language($this);
97
        $language->setLanguage();
98
99
        //Set trustProxy or get the original visitor IP.
100
        $this->request->trustProxy = true;
101
102
        //Automatically Login.
103
        if (!$this->Auth->user() && $this->Cookie->read('CookieAuth')) {
104
            $this->loadModel('Users');
105
106
            $userLogin = $this->Auth->identify();
107
            if ($userLogin && $userLogin['is_deleted'] == false) {
108
                $this->loadComponent('TwoFactorAuth');
109
110
                //Verify if the user use 2FA and if yes, if he's authorized.
111
                if ($userLogin['two_factor_auth_enabled'] == true && $this->TwoFactorAuth->isAuthorized($userLogin['id']) === false) {
0 ignored issues
show
Documentation introduced by
The property TwoFactorAuth does not exist on object<App\Controller\AppController>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
112
                    $this->Cookie->delete('CookieAuth');
113
                } else {
114
                    $this->Auth->setUser($userLogin);
0 ignored issues
show
Bug introduced by
It seems like $userLogin defined by $this->Auth->identify() on line 106 can also be of type boolean; however, Cake\Controller\Component\AuthComponent::setUser() does only seem to accept array|object<ArrayAccess>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
115
116
                    $user = $this->Users->newEntity($userLogin, ['accessibleFields' => ['id' => true]]);
0 ignored issues
show
Documentation introduced by
The property Users does not exist on object<App\Controller\AppController>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
117
                    $user->isNew(false);
118
119
                    $user->last_login = new Time();
120
                    $user->last_login_ip = $this->request->clientIp();
121
122
                    $this->Users->save($user);
0 ignored issues
show
Documentation introduced by
The property Users does not exist on object<App\Controller\AppController>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
123
124
                    //Badges Event.
125
                    $this->eventManager()->attach(new Badges($this));
0 ignored issues
show
Documentation introduced by
new \App\Event\Badges($this) is of type object<App\Event\Badges>, but the function expects a callable.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Deprecated Code introduced by
The method Cake\Event\EventManager::attach() has been deprecated with message: 3.0.0 Use on() instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
126
                    $badge = new Event('Model.Users.register', $this, [
127
                        'user' => $user
128
                    ]);
129
                    $this->eventManager()->dispatch($badge);
130
131
                    //Logs Event.
132
                    $this->eventManager()->attach(new Logs());
0 ignored issues
show
Documentation introduced by
new \App\Event\Logs() is of type object<App\Event\Logs>, but the function expects a callable.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Deprecated Code introduced by
The method Cake\Event\EventManager::attach() has been deprecated with message: 3.0.0 Use on() instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
133
                    $event = new Event('Log.User', $this, [
134
                        'user_id' => $user->id,
135
                        'username' => $user->username,
136
                        'user_ip' => $this->request->clientIp(),
137
                        'user_agent' => $this->request->header('User-Agent'),
138
                        'action' => 'user.connection.auto'
139
                    ]);
140
                    $this->eventManager()->dispatch($event);
141
                }
142
            } else {
143
                $this->Cookie->delete('CookieAuth');
144
            }
145
        }
146
147
        //Layouts
148
        if (isset($this->request->params['prefix'])) {
149
            $prefix = explode('/', $this->request->params['prefix'])[0];
150
151
            switch ($prefix) {
152
                case 'admin':
153
                    $this->viewBuilder()->layout('admin');
154
                    break;
155
            }
156
        }
157
158
        $allowCookies = $this->Cookie->check('allowCookies');
159
        $this->set(compact('allowCookies'));
160
161
        //Site Maintenance
162
        if (Configure::read('Site.maintenance') === true) {
163
            $controller = $this->request->params['controller'];
164
            $action = $this->request->params['action'];
165
166
            if ($this->Auth->user()) {
167
                $this->loadModel('Users');
168
                $user = $this->Users
0 ignored issues
show
Documentation introduced by
The property Users does not exist on object<App\Controller\AppController>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
169
                    ->find()
170
                    ->contain([
171
                        'Groups' => function ($q) {
172
                            return $q->select(['id', 'is_staff']);
173
                        }
174
                    ])
175
                    ->where([
176
                        'Users.id' => $this->Auth->user('id')
177
                    ])
178
                    ->first();
179
180
                if (!is_null($user) && $user->group->is_staff == true) {
181
                    //To prevent multiple flash messages.
182
                    $this->Flash->config(['clear' => true]);
183
                    $this->Flash->error(__("Hello {0}, The website is under maintenance, only you and the staff groups have the access !", h($user->full_name)));
184 View Code Duplication
                } else {
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...
185
                    if (!($controller == 'Pages' && $action == 'maintenance') &&
186
                        !($controller == 'Users' && $action == 'login') &&
187
                        !($controller == 'Users' && $action == 'logout')) {
188
                        $this->redirect(['controller' => 'pages', 'action' => 'maintenance', 'prefix' => false]);
189
                    }
190
                }
191 View Code Duplication
            } else {
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...
192
                if (!($controller == 'Pages' && $action == 'maintenance') &&
193
                    !($controller == 'Users' && $action == 'login') &&
194
                    !($controller == 'Users' && $action == 'logout')) {
195
                    $this->redirect(['controller' => 'pages', 'action' => 'maintenance', 'prefix' => false]);
196
                }
197
            }
198
        }
199
200
        //JavaScript Notifications.
201
        if ($this->request->session()->read('Notification') && !empty($this->request->session()->read('Notification'))) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->request->session()->read('Notification') of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
202
            $notification = $this->request->session()->read('Notification');
203
            $this->request->session()->delete('Notification');
204
205
            $this->set(compact('notification'));
206
        }
207
    }
208
209
    /**
210
     * BeforeRender hook method.
211
     *
212
     * @param Event $event The beforeRender event that was fired.
213
     *
214
     * @return void
215
     */
216
    public function beforeRender(Event $event)
217
    {
218
        parent::beforeRender($event);
219
220
        $builder = $this->viewBuilder();
221
        $builder->helpers([
222
            'Acl' => $this->Auth->config('authorize')['Acl.Actions']
223
        ]);
224
    }
225
}
226