SaveOperation   B
last analyzed

Complexity

Total Complexity 37

Size/Duplication

Total Lines 273
Duplicated Lines 27.11 %

Coupling/Cohesion

Components 1
Dependencies 8

Importance

Changes 4
Bugs 1 Features 1
Metric Value
wmc 37
c 4
b 1
f 1
lcom 1
cbo 8
dl 74
loc 273
rs 8.6

11 Methods

Rating   Name   Duplication   Size   Complexity  
A get_model() 0 4 1
C lazy_get_properties() 28 69 9
A lazy_get_form() 0 14 2
A control_permission() 0 11 3
A control_ownership() 0 15 3
A action() 0 6 1
A validate() 0 10 1
B validate_password() 0 25 4
B validate_username() 23 23 4
B validate_email() 23 23 4
B process() 0 23 5

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
/*
4
 * This file is part of the Icybee package.
5
 *
6
 * (c) Olivier Laviale <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Icybee\Modules\Users\Operation;
13
14
use Brickrouge\Form;
15
use ICanBoogie\ErrorCollection;
16
use ICanBoogie\HTTP\Request;
17
18
use Icybee\Modules\Users\Module;
19
use Icybee\Modules\Users\User;
20
use Icybee\Modules\Users\UserModel;
21
22
/**
23
 * Create or update a user profile.
24
 *
25
 * @property-read UserModel $model
26
 * @property User $record User
27
 */
28
class SaveOperation extends \ICanBoogie\Module\Operation\SaveOperation
29
{
30
	protected function get_model()
31
	{
32
		return $this->module->model;
33
	}
34
35
	protected function lazy_get_properties()
36
	{
37
		$properties = parent::lazy_get_properties();
38
		$request = $this->request;
39
40
		unset($properties[User::PASSWORD_HASH]);
41
42
		if ($request[User::PASSWORD])
43
		{
44
			$properties[User::PASSWORD] = $request[User::PASSWORD];
45
		}
46
47
		if ($this->app->user->has_permission(Module::PERMISSION_ADMINISTER, $this->module))
48
		{
49
			#
50
			# roles - because roles are not in the properties we need to prepare them for the
51
			# model using the params.
52
			#
53
54
			$roles = [];
55
56 View Code Duplication
			if ($request[User::ROLES])
57
			{
58
				foreach ($request[User::ROLES] as $rid => $value)
59
				{
60
					$value = filter_var($value, FILTER_VALIDATE_BOOLEAN);
61
62
					if (!$value)
63
					{
64
						continue;
65
					}
66
67
					$roles[] = (int) $rid;
68
				}
69
			}
70
71
			$properties[User::ROLES] = $roles;
72
73
			#
74
			# restricted sites - because restricted sites are not in the properties we need to
75
			# prepare them for the model using the params.
76
			#
77
78
			$sites = [];
79
80 View Code Duplication
			if ($request[User::RESTRICTED_SITES])
81
			{
82
				foreach ($request[User::RESTRICTED_SITES] as $site_id => $value)
83
				{
84
					$value = filter_var($value, FILTER_VALIDATE_BOOLEAN);
85
86
					if (!$value)
87
					{
88
						continue;
89
					}
90
91
					$sites[] = (int) $site_id;
92
				}
93
			}
94
95
			$properties[User::RESTRICTED_SITES] = $sites;
96
		}
97
		else
98
		{
99
			unset($properties[User::IS_ACTIVATED]);
100
		}
101
102
		return $properties;
103
	}
104
105
	/**
106
	 * Returns the form from the `edit` block if the getter wasn't able to retrieve the form. This
107
	 * is currently used to create records using XHR.
108
	 */
109
	protected function lazy_get_form()
110
	{
111
		$form = parent::lazy_get_form();
112
113
		if ($form)
114
		{
115
			return $form;
116
		}
117
118
		$block = $this->module->getBlock('edit', $this->key);
119
		$block->render(); // FIXME-20160327: because form is populated on render
120
121
		return $block->element;
122
	}
123
124
	/**
125
	 * Permission is granted if the user is modifying its own profile, and has permission to.
126
	 *
127
	 * @inheritdoc
128
	 */
129
	protected function control_permission($permission = Module::PERMISSION_CREATE)
130
	{
131
		$user = $this->app->user;
132
133
		if ($user->uid == $this->key && $user->has_permission('modify own profile'))
134
		{
135
			return true;
136
		}
137
138
		return parent::control_permission($permission);
139
	}
140
141
	protected function control_ownership()
142
	{
143
		$user = $this->app->user;
144
145
		if ($user->uid == $this->key && $user->has_permission('modify own profile'))
146
		{
147
			// TODO-20110105: it this ok to set the user as a record here ?
148
149
			$this->record = $user;
150
151
			return true;
152
		}
153
154
		return parent::control_ownership();
155
	}
156
157
	/**
158
	 * The 'User' role (rid 2) is mandatory for every user.
159
	 *
160
	 * @inheritdoc
161
	 */
162
	protected function action(Request $request)
163
	{
164
		$request->params[User::ROLES][2] = 'on';
165
166
		return parent::action($request);
167
	}
168
169
	/**
170
	 * Validates the `password`, `username`, and `email` properties.
171
	 *
172
	 * @inheritdoc
173
	 */
174
	protected function validate(ErrorCollection $errors)
175
	{
176
		$request = $this->request;
177
178
		$this->validate_password($request, $errors);
179
		$this->validate_username($request, $errors);
180
		$this->validate_email($request, $errors);
181
182
		return parent::validate($errors);
183
	}
184
185
	/**
186
	 * Checks that the password matches password-verify.
187
	 *
188
	 * @param Request $request
189
	 * @param ErrorCollection $errors
190
	 */
191
	protected function validate_password(Request $request, ErrorCollection $errors)
192
	{
193
		$password = $request[User::PASSWORD];
194
195
		if (!$password)
196
		{
197
			return;
198
		}
199
200
		$password_verify = $request[User::PASSWORD_VERIFY];
201
202
		if (!$password_verify)
203
		{
204
			$errors->add(User::PASSWORD_VERIFY, "Password verify is empty.");
205
206
			return;
207
		}
208
209
		if ($password === $password_verify)
210
		{
211
			return;
212
		}
213
214
		$errors->add(User::PASSWORD_VERIFY, "Password and password verify don't match.");
215
	}
216
217
	/**
218
	 * Checks that the username is unique.
219
	 *
220
	 * @param Request $request
221
	 * @param ErrorCollection $errors
222
	 */
223 View Code Duplication
	protected function validate_username(Request $request, ErrorCollection $errors)
224
	{
225
		$username = $request[User::USERNAME];
226
227
		if (!$username)
228
		{
229
			return;
230
		}
231
232
		$uid = $this->key ?: 0;
233
		$used = $this->model->where('username = ? AND uid != ?', $username, $uid)->exists;
234
235
		if (!$used)
236
		{
237
			return;
238
		}
239
240
		$errors->add(User::USERNAME, "The user name %username is already used.", [
241
242
			'%username' => $username
243
244
		]);
245
	}
246
247
	/**
248
	 * Checks that the email is email.
249
	 *
250
	 * @param Request $request
251
	 * @param ErrorCollection $errors
252
	 */
253 View Code Duplication
	protected function validate_email(Request $request, ErrorCollection $errors)
254
	{
255
		$email = $request[User::EMAIL];
256
257
		if (!$email)
258
		{
259
			return;
260
		}
261
262
		$uid = $this->key ?: 0;
263
		$used = $this->model->where('email = ? AND uid != ?', $email, $uid)->exists;
264
265
		if (!$used)
266
		{
267
			return;
268
		}
269
270
		$errors->add(User::EMAIL, "The email address %email is already used.", [
271
272
			'%email' => $email
273
274
		]);
275
	}
276
277
	protected function process()
278
	{
279
		$previous_uid = $this->app->user_id;
280
281
		$rc = parent::process();
282
283
		if (!$previous_uid)
284
		{
285
			$this->response->message = $this->format("Your profile has been created.");
286
		}
287
		else if ($previous_uid == $rc['key'])
288
		{
289
			$this->response->message = $this->format($rc['mode'] == 'update' ? "Your profile has been updated." : "Your profile has been created.");
290
		}
291
		else
292
		{
293
			$record = $this->record;
294
295
			$this->response->message = $this->format($rc['mode'] == 'update' ? "%name's profile has been updated." : "%name's profile has been created.", [ 'name' => $record->name ]);
296
		}
297
298
		return $rc;
299
	}
300
}
301