Users_Account_Controller   A
last analyzed

Complexity

Total Complexity 27

Size/Duplication

Total Lines 387
Duplicated Lines 1.81 %

Coupling/Cohesion

Components 2
Dependencies 15

Importance

Changes 0
Metric Value
wmc 27
lcom 2
cbo 15
dl 7
loc 387
rs 10
c 0
b 0
f 0

16 Methods

Rating   Name   Duplication   Size   Complexity  
A getMember() 0 4 1
A setMember() 0 5 1
A RequireVerification() 0 8 3
A init() 0 16 3
A Link() 0 7 1
A AbsoluteLink() 0 4 1
A RelativeLink() 0 6 1
A getMenu() 7 7 2
A Menu() 0 4 1
A index() 0 41 1
A edit() 0 27 2
A changepassword() 0 39 3
A EditAccountForm() 0 8 1
A ChangePasswordForm() 0 23 1
A getAccountMenu() 0 43 4
A providePermissions() 0 17 1

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
 * Controller that is used to allow users to manage their accounts via
5
 * the front end of the site.
6
 * 
7
 * @package Users
8
 * @author  i-lateral <[email protected]>
9
 */
10
class Users_Account_Controller extends Controller implements PermissionProvider
11
{
12
13
    /**
14
     * URL That you can access this from
15
     *
16
     * @config
17
     */
18
    private static $url_segment = "users/account";
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
19
20
    /**
21
     * Allowed sub-URL's on this controller
22
     * 
23
     * @var    array
24
     * @config
25
     */
26
    private static $allowed_actions = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
27
        "edit",
28
        "changepassword",
29
        "EditAccountForm",
30
        "ChangePasswordForm",
31
    );
32
33
    /**
34
     * User account associated with this controller
35
     *
36
     * @var Member
37
     */
38
    protected $member;
39
40
    /**
41
     * Getter for member
42
     *
43
     * @return Member
44
     */
45
    public function getMember()
46
    {
47
        return $this->member;
48
    }
49
50
    /**
51
     * Setter for member
52
     *
53
     * @param Member $member A member to associate
54
     * 
55
     * @return self
56
     */
57
    public function setMember(Member $member)
58
    {
59
        $this->member = $member;
60
        return $this;
61
    }
62
63
    /**
64
     * Determine if current user requires verification (based on their
65
     * account and Users verification setting).
66
     *
67
     * @return boolean
68
     */
69
    public function RequireVerification()
70
    {
71
        if (!$this->member->isVerified() && Users::config()->require_verification) {
0 ignored issues
show
Coding Style introduced by
The if-else statement can be simplified to return !$this->member->i...->require_verification;.
Loading history...
72
            return true;
73
        } else {
74
            return false;
75
        }
76
    }
77
78
    /**
79
     * Perorm setup when this controller is initialised
80
     *
81
     * @return void
82
     */
83
    public function init()
84
    {
85
        parent::init();
86
87
        // Check we are logged in as a user who can access front end management
88
        if (!Permission::check("USERS_MANAGE_ACCOUNT")) {
89
            Security::permissionFailure();
90
        }
91
92
        // Set our member object
93
        $member = Member::currentUser();
94
95
        if ($member instanceof Member) {
96
            $this->member = $member;
97
        }
98
    }
99
100
    /**
101
     * Get the link to this controller
102
     * 
103
     * @param string $action The URL endpoint for this controller
0 ignored issues
show
Documentation introduced by
Should the type for parameter $action not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
104
     * 
105
     * @return string
106
     */
107
    public function Link($action = null)
108
    {
109
        return Controller::join_links(
110
            $this->config()->url_segment,
111
            $action
112
        );
113
    }
114
115
    /**
116
     * Get an absolute link to this controller
117
     *
118
     * @param string $action The URL endpoint for this controller
0 ignored issues
show
Documentation introduced by
Should the type for parameter $action not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
119
     * 
120
     * @return string
0 ignored issues
show
Documentation introduced by
Should the return type not be false|string?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
121
     */
122
    public function AbsoluteLink($action = null)
123
    {
124
        return Director::absoluteURL($this->Link($action));
125
    }
126
127
    /**
128
     * Get a relative (to the root url of the site) link to this
129
     * controller
130
     *
131
     * @param string $action The URL endpoint for this controller 
0 ignored issues
show
Documentation introduced by
Should the type for parameter $action not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
132
     * 
133
     * @return string
134
     */
135
    public function RelativeLink($action = null)
136
    {
137
        return Controller::join_links(
138
            $this->Link($action)
139
        );
140
    }
141
142
    /**
143
     * If content controller exists, return it's menu function
144
     *
145
     * @param int $level Menu level to return.
146
     * 
147
     * @return ArrayList
148
     */
149 View Code Duplication
    public function getMenu($level = 1)
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...
150
    {
151
        if (class_exists(ContentController::class)) {
152
            $controller = Injector::inst()->get(ContentController::class);
153
            return $controller->getMenu($level);
154
        }
155
    }
156
157
    /**
158
     * Shortcut for getMenu
159
     * 
160
     * @param int $level Menu level to return.
161
     * 
162
     * @return ArrayList
163
     */
164
    public function Menu($level)
0 ignored issues
show
Unused Code introduced by
The parameter $level is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
165
    {
166
        return $this->getMenu();
167
    }
168
169
    /**
170
     * Display the currently outstanding orders for the current user
171
     * 
172
     * @return HTMLText
173
     */
174
    public function index()
175
    {
176
        // Setup default profile summary sections
177
        $sections = ArrayList::create();
178
179
        $sections->push(
180
            ArrayData::create(
181
                array(
182
                "Title" => "",
183
                "Content" => $this->renderWith(
184
                    "UsersProfileSummary",
185
                    array("CurrentUser" => Member::currentUser())
186
                )
187
                )
188
            )
189
        );
190
191
        // Allow users to add extra content sections to the
192
        // summary
193
        $this->extend("updateIndexSections", $sections);
194
195
        $this->customise(
196
            array(
197
            "Title" => _t('Users.ProfileSummary', 'Profile Summary'),
198
            "MetaTitle" => _t('Users.ProfileSummary', 'Profile Summary'),
199
            "Content" => $this->renderWith(
200
                "UsersAccountSections",
201
                array("Sections" => $sections)
202
            )
203
            )
204
        );
205
206
        $this->extend("onBeforeIndex");
207
208
        return $this->renderWith(
209
            array(
210
            "UserAccount",
211
            "Page"
212
            )
213
        );
214
    }
215
216
    public function edit()
217
    {
218
        $member = Member::currentUser();
219
        $form = $this->EditAccountForm();
220
221
        if ($member instanceof Member) {
222
            $form->loadDataFrom($member);
223
        }
224
225
        $this->customise(
226
            array(
227
            "Title" => _t("Users.EditAccountDetails", "Edit account details"),
228
            "MetaTitle" => _t("Users.EditAccountDetails", "Edit account details"),
229
            "Form"  => $form
230
            )
231
        );
232
233
        $this->extend("onBeforeEdit");
234
235
        return $this->renderWith(
236
            array(
237
            "UserAccount_edit",
238
            "UserAccount",
239
            "Page"
240
            )
241
        );
242
    }
243
244
    public function changepassword()
245
    {
246
        // Set the back URL for this form
247
        $back_url = Controller::join_links(
248
            $this->Link("changepassword"),
249
            "?s=1"
250
        );
251
        
252
        Session::set("BackURL", $back_url);
253
        
254
        $form = $this->ChangePasswordForm();
255
        
256
        // Is password changed, set a session message.
257
        $password_set = $this->request->getVar("s");
258
        if($password_set && $password_set == 1) {
259
            $form->sessionMessage(
260
                _t("Users.PasswordChangedSuccessfully", "Password Changed Successfully"),
261
                "good"
262
            );
263
        }
264
265
        $this->customise(
266
            array(
267
            "Title" => _t("Security.ChangeYourPassword", "Change your password"),
268
            "MetaTitle" => _t("Security.ChangeYourPassword", "Change your password"),
269
            "Form"  => $form
270
            )
271
        );
272
273
        $this->extend("onBeforeChangePassword");
274
275
        return $this->renderWith(
276
            array(
277
            "UserAccount_changepassword",
278
            "UserAccount",
279
            "Page"
280
            )
281
        );
282
    }
283
284
    /**
285
     * Factory for generating a profile form. The form can be expanded using an
286
     * extension class and calling the updateEditProfileForm method.
287
     *
288
     * @return Form
289
     */
290
    public function EditAccountForm()
291
    {
292
        $form = Users_EditAccountForm::create($this, "EditAccountForm");
293
294
        $this->extend("updateEditAccountForm", $form);
295
296
        return $form;
297
    }
298
299
    /**
300
     * Factory for generating a change password form. The form can be expanded
301
     * using an extension class and calling the updateChangePasswordForm method.
302
     *
303
     * @return Form
304
     */
305
    public function ChangePasswordForm()
306
    {
307
        $form = ChangePasswordForm::create($this, "ChangePasswordForm");
308
309
        $form
310
            ->Actions()
311
            ->find("name", "action_doChangePassword")
312
            ->addExtraClass("btn")
313
            ->addExtraClass("btn-green");
314
315
        $cancel_btn = LiteralField::create(
316
            "CancelLink",
317
            '<a href="' . $this->Link() . '" class="btn btn-red">'. _t("Users.CANCEL", "Cancel") .'</a>'
318
        );
319
320
        $form
321
            ->Actions()
322
            ->insertBefore($cancel_btn, "action_doChangePassword");
0 ignored issues
show
Documentation introduced by
'action_doChangePassword' is of type string, but the function expects a object<FormField>.

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...
323
324
        $this->extend("updateChangePasswordForm", $form);
325
326
        return $form;
327
    }
328
329
    /**
330
     * Return a list of nav items for managing a users profile. You can add new
331
     * items to this menu using the "updateAccountMenu" extension
332
     *
333
     * @return ArrayList
334
     */
335
    public function getAccountMenu()
336
    {
337
        $menu = ArrayList::create();
338
        
339
        $curr_action = $this->request->param("Action");
340
341
        $menu->add(
342
            ArrayData::create(
343
                array(
344
                "ID"    => 0,
345
                "Title" => _t('Users.PROFILESUMMARY', "Profile Summary"),
346
                "Link"  => $this->Link(),
347
                "LinkingMode" => (!$curr_action) ? "current" : "link"
348
                )
349
            )
350
        );
351
352
        $menu->add(
353
            ArrayData::create(
354
                array(
355
                "ID"    => 10,
356
                "Title" => _t('Users.EDITDETAILS', "Edit account details"),
357
                "Link"  => $this->Link("edit"),
358
                "LinkingMode" => ($curr_action == "edit") ? "current" : "link"
359
                )
360
            )
361
        );
362
363
        $menu->add(
364
            ArrayData::create(
365
                array(
366
                "ID"    => 30,
367
                "Title" => _t('Users.CHANGEPASSWORD', "Change password"),
368
                "Link"  => $this->Link("changepassword"),
369
                "LinkingMode" => ($curr_action == "changepassword") ? "current" : "link"
370
                )
371
            )
372
        );
373
374
        $this->extend("updateAccountMenu", $menu);
375
376
        return $menu->sort("ID", "ASC");
377
    }
378
379
    public function providePermissions()
380
    {
381
        return array(
382
            "USERS_MANAGE_ACCOUNT" => array(
383
                'name' => 'Manage user account',
384
                'help' => 'Allow user to manage their account details',
385
                'category' => 'Frontend Users',
386
                'sort' => 100
387
            ),
388
            "USERS_VERIFIED" => array(
389
                'name' => 'Verified user',
390
                'help' => 'Users have verified their account',
391
                'category' => 'Frontend Users',
392
                'sort' => 100
393
            ),
394
        );
395
    }
396
}
397