UserController   B
last analyzed

Complexity

Total Complexity 20

Size/Duplication

Total Lines 276
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 17

Test Coverage

Coverage 0%

Importance

Changes 1
Bugs 1 Features 0
Metric Value
wmc 20
c 1
b 1
f 0
lcom 1
cbo 17
dl 0
loc 276
ccs 0
cts 162
cp 0
rs 7.8571

7 Methods

Rating   Name   Duplication   Size   Complexity  
A init() 0 5 1
A index() 0 9 1
B profile() 0 77 4
B add() 0 37 5
B edit() 0 38 5
A userForm() 0 51 2
A delete() 0 17 2
1
<?php
2
/**
3
 * PHPCI - Continuous Integration for PHP.
4
 *
5
 * @copyright    Copyright 2014, Block 8 Limited.
6
 * @license      https://github.com/Block8/PHPCI/blob/master/LICENSE.md
7
 *
8
 * @link         https://www.phptesting.org/
9
 */
10
11
namespace PHPCI\Controller;
12
13
use b8;
14
use b8\Exception\HttpException\NotFoundException;
15
use b8\Form;
16
use PHPCI\Controller;
17
use PHPCI\Helper\Lang;
18
use PHPCI\Service\UserService;
19
20
/**
21
 * User Controller - Allows an administrator to view, add, edit and delete users.
22
 *
23
 * @author       Dan Cryer <[email protected]>
24
 */
25
class UserController extends Controller
26
{
27
    /**
28
     * @var \PHPCI\Store\UserStore
29
     */
30
    protected $userStore;
31
32
    /**
33
     * @var \PHPCI\Service\UserService
34
     */
35
    protected $userService;
36
37
    /**
38
     * Initialise the controller, set up stores and services.
39
     */
40
    public function init()
41
    {
42
        $this->userStore = b8\Store\Factory::getStore('User');
43
        $this->userService = new UserService($this->userStore);
0 ignored issues
show
Compatibility introduced by
$this->userStore of type object<b8\Store> is not a sub-type of object<PHPCI\Store\UserStore>. It seems like you assume a child class of the class b8\Store to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
44
    }
45
46
    /**
47
     * View user list.
48
     */
49
    public function index()
50
    {
51
        $users = $this->userStore->getWhere(array(), 1000, 0, array(), array('email' => 'ASC'));
52
        $this->view->users = $users;
53
54
        $this->layout->title = Lang::get('manage_users');
55
56
        return $this->view->render();
57
    }
58
59
    /**
60
     * Allows the user to edit their profile.
61
     *
62
     * @return string
63
     */
64
    public function profile()
0 ignored issues
show
Coding Style introduced by
profile uses the super-global variable $_SESSION which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

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

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
profile uses the super-global variable $_COOKIE which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

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

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
65
    {
66
        $user = $_SESSION['phpci_user'];
67
68
        if ($this->request->getMethod() == 'POST') {
69
            $name = $this->getParam('name', null);
70
            $email = $this->getParam('email', null);
71
            $password = $this->getParam('password', null);
72
73
            $currentLang = Lang::getLanguage();
74
            $chosenLang = $this->getParam('language', $currentLang);
75
76
            if ($chosenLang !== $currentLang) {
77
                setcookie('phpcilang', $chosenLang, time() + (10 * 365 * 24 * 60 * 60), '/');
78
                Lang::setLanguage($chosenLang);
79
            }
80
81
            $_SESSION['phpci_user'] = $this->userService->updateUser($user, $name, $email, $password);
82
            $user = $_SESSION['phpci_user'];
83
84
            $this->view->updated = 1;
85
        }
86
87
        $this->layout->title = $user->getName();
88
        $this->layout->subtitle = Lang::get('edit_profile');
89
90
        $values = $user->getDataArray();
91
92
        if (array_key_exists('phpcilang', $_COOKIE)) {
93
            $values['language'] = $_COOKIE['phpcilang'];
94
        }
95
96
        $form = new Form();
97
        $form->setAction(PHPCI_URL.'user/profile');
98
        $form->setMethod('POST');
99
100
        $name = new Form\Element\Text('name');
101
        $name->setClass('form-control');
102
        $name->setContainerClass('form-group');
103
        $name->setLabel(Lang::get('name'));
104
        $name->setRequired(true);
105
        $form->addField($name);
106
107
        $email = new Form\Element\Email('email');
108
        $email->setClass('form-control');
109
        $email->setContainerClass('form-group');
110
        $email->setLabel(Lang::get('email_address'));
111
        $email->setRequired(true);
112
        $form->addField($email);
113
114
        $password = new Form\Element\Password('password');
115
        $password->setClass('form-control');
116
        $password->setContainerClass('form-group');
117
        $password->setLabel(Lang::get('password_change'));
118
        $password->setRequired(false);
119
        $form->addField($password);
120
121
        $lang = new Form\Element\Select('language');
122
        $lang->setClass('form-control');
123
        $lang->setContainerClass('form-group');
124
        $lang->setLabel(Lang::get('language'));
125
        $lang->setRequired(true);
126
        $lang->setOptions(Lang::getLanguageOptions());
127
        $lang->setValue(Lang::getLanguage());
128
        $form->addField($lang);
129
130
        $submit = new Form\Element\Submit();
131
        $submit->setClass('btn btn-success');
132
        $submit->setValue(Lang::get('save'));
133
        $form->addField($submit);
134
135
        $form->setValues($values);
136
137
        $this->view->form = $form;
138
139
        return $this->view->render();
140
    }
141
142
    /**
143
     * Add a user - handles both form and processing.
144
     */
145
    public function add()
146
    {
147
        $this->requireAdmin();
148
149
        $this->layout->title = Lang::get('add_user');
150
151
        $method = $this->request->getMethod();
152
153
        if ($method == 'POST') {
154
            $values = $this->getParams();
155
        } else {
156
            $values = array();
157
        }
158
159
        $form = $this->userForm($values);
160
161
        if ($method != 'POST' || ($method == 'POST' && !$form->validate())) {
162
            $view = new b8\View('UserForm');
163
            $view->type = 'add';
164
            $view->user = null;
165
            $view->form = $form;
166
167
            return $view->render();
168
        }
169
170
        $name = $this->getParam('name', null);
171
        $email = $this->getParam('email', null);
172
        $password = $this->getParam('password', null);
173
        $isAdmin = (int) $this->getParam('is_admin', 0);
174
175
        $this->userService->createUser($name, $email, $password, $isAdmin);
0 ignored issues
show
Documentation introduced by
$isAdmin is of type integer, but the function expects a boolean.

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...
176
177
        $response = new b8\Http\Response\RedirectResponse();
178
        $response->setHeader('Location', PHPCI_URL.'user');
179
180
        return $response;
181
    }
182
183
    /**
184
     * Edit a user - handles both form and processing.
185
     */
186
    public function edit($userId)
187
    {
188
        $this->requireAdmin();
189
190
        $method = $this->request->getMethod();
191
        $user = $this->userStore->getById($userId);
192
193
        if (empty($user)) {
194
            throw new NotFoundException(Lang::get('user_n_not_found', $userId));
195
        }
196
197
        $this->layout->title = $user->getName();
198
        $this->layout->subtitle = Lang::get('edit_user');
199
200
        $values = array_merge($user->getDataArray(), $this->getParams());
201
        $form = $this->userForm($values, 'edit/'.$userId);
202
203
        if ($method != 'POST' || ($method == 'POST' && !$form->validate())) {
204
            $view = new b8\View('UserForm');
205
            $view->type = 'edit';
206
            $view->user = $user;
207
            $view->form = $form;
208
209
            return $view->render();
210
        }
211
212
        $name = $this->getParam('name', null);
213
        $email = $this->getParam('email', null);
214
        $password = $this->getParam('password', null);
215
        $isAdmin = (int) $this->getParam('is_admin', 0);
216
217
        $this->userService->updateUser($user, $name, $email, $password, $isAdmin);
218
219
        $response = new b8\Http\Response\RedirectResponse();
220
        $response->setHeader('Location', PHPCI_URL.'user');
221
222
        return $response;
223
    }
224
225
    /**
226
     * Create user add / edit form.
227
     */
228
    protected function userForm($values, $type = 'add')
229
    {
230
        $form = new Form();
231
        $form->setMethod('POST');
232
        $form->setAction(PHPCI_URL.'user/'.$type);
233
        $form->addField(new Form\Element\Csrf('csrf'));
234
235
        $field = new Form\Element\Email('email');
236
        $field->setRequired(true);
237
        $field->setLabel(Lang::get('email_address'));
238
        $field->setClass('form-control');
239
        $field->setContainerClass('form-group');
240
        $form->addField($field);
241
242
        $field = new Form\Element\Text('name');
243
        $field->setRequired(true);
244
        $field->setLabel(Lang::get('name'));
245
        $field->setClass('form-control');
246
        $field->setContainerClass('form-group');
247
        $form->addField($field);
248
249
        $field = new Form\Element\Password('password');
250
251
        if ($type == 'add') {
252
            $field->setRequired(true);
253
            $field->setLabel(Lang::get('password'));
254
        } else {
255
            $field->setRequired(false);
256
            $field->setLabel(Lang::get('password_change'));
257
        }
258
259
        $field->setClass('form-control');
260
        $field->setContainerClass('form-group');
261
        $form->addField($field);
262
263
        $field = new Form\Element\Checkbox('is_admin');
264
        $field->setRequired(false);
265
        $field->setCheckedValue(1);
266
        $field->setLabel(Lang::get('is_user_admin'));
267
        $field->setContainerClass('form-group');
268
        $form->addField($field);
269
270
        $field = new Form\Element\Submit();
271
        $field->setValue(Lang::get('save_user'));
272
        $field->setClass('btn-success');
273
        $form->addField($field);
274
275
        $form->setValues($values);
276
277
        return $form;
278
    }
279
280
    /**
281
     * Delete a user.
282
     */
283
    public function delete($userId)
284
    {
285
        $this->requireAdmin();
286
287
        $user = $this->userStore->getById($userId);
288
289
        if (empty($user)) {
290
            throw new NotFoundException(Lang::get('user_n_not_found', $userId));
291
        }
292
293
        $this->userService->deleteUser($user);
294
295
        $response = new b8\Http\Response\RedirectResponse();
296
        $response->setHeader('Location', PHPCI_URL.'user');
297
298
        return $response;
299
    }
300
}
301