Completed
Push — 1 ( fdc87b...27ddc3 )
by Morven
01:40
created

code/control/Users_Register_Controller.php (3 issues)

Check that @param annotations have the correct type.

Documentation Informational

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
/**
4
 * Base controller class for users to register. Provides extension hooks to
5
 * allow third party overwriting of both index and register form actions
6
 *
7
 * This controller is also used to allow registered accounts to "verify"
8
 * their details via email.
9
 *
10
 * This is done by adding verified users to the groups stipulated by the
11
 * $verification_groups config variable
12
 *
13
 */
14
class Users_Register_Controller extends Controller
15
{
16
17
    /**
18
     * URL That you can access this from
19
     *
20
     * @config
21
     */
22
    private static $url_segment = "users/register";
23
24
    /**
25
     * Current actions available to this controller
26
     *
27
     * @var array
28
     */
29
    private static $allowed_actions = array(
30
        "index",
31
        "sendverification",
32
        "verify",
33
        "RegisterForm"
34
    );
35
36
    /**
37
     * Internal function designed to allow us to send a verification
38
     * email from multiple locations
39
     *
40
     * @param $member Member object to send email to
41
     * @return boolean
42
     */
43
    protected function send_verification_email(Member $member)
44
    {
45
        if ($member->exists()) {
46
            return $member->sendVerificationEmail();            
47
        }
48
49
        return false;
50
    }
51
52
    /**
53
     * Get the link to this controller
54
     * 
55
     * @param string $action
0 ignored issues
show
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...
56
     * @return string
57
     */
58
    public function Link($action = null)
59
    {
60
        return Controller::join_links(
61
            $this->config()->url_segment,
62
            $action
63
        );
64
    }
65
66
    /**
67
     * Get an absolute link to this controller
68
     *
69
     * @param string $action
0 ignored issues
show
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...
70
     * @return false|string
71
     */
72
    public function AbsoluteLink($action = null)
73
    {
74
        return Director::absoluteURL($this->Link($action));
75
    }
76
77
    /**
78
     * Get a relative (to the root url of the site) link to this
79
     * controller
80
     *
81
     * @param string $action
0 ignored issues
show
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...
82
     * @return string
83
     */
84
    public function RelativeLink($action = null)
85
    {
86
        return Controller::join_links(
87
            $this->Link($action)
88
        );
89
    }
90
91
    /**
92
     * If content controller exists, return it's menu function
93
     * @param int $level Menu level to return.
94
     * @return ArrayList
95
     */
96 View Code Duplication
    public function getMenu($level = 1)
97
    {
98
        if (class_exists(ContentController::class)) {
99
            $controller = Injector::inst()->get(ContentController::class);
100
            return $controller->getMenu($level);
101
        }
102
    }
103
104
    public function Menu($level)
105
    {
106
        return $this->getMenu();
107
    }
108
109
    /**
110
     * Default action this controller will deal with
111
     *
112
     * @param SS_HTTPRequest $request
113
     * @return HTMLText
114
     */
115
    public function index(SS_HTTPRequest $request)
116
    {
117
        $this->customise(array(
118
            'Title'     => _t('Users.Register', 'Register'),
119
            'MetaTitle' => _t('Users.Register', 'Register'),
120
            'Form'      => $this->RegisterForm(),
121
        ));
122
123
        $this->extend("updateIndexAction");
124
125
        return $this->renderWith(array(
126
            "Users_Register",
127
            "Users",
128
            "Page"
129
        ));
130
    }
131
132
133
    /**
134
     * Send a verification email to the user provided (if verification
135
     * emails are enabled and account is not already verified)
136
     *
137
     * @param SS_HTTPRequest $request
138
     * @return HTMLText
139
     */
140
    public function sendverification(SS_HTTPRequest $request)
141
    {
142
        // If we don't allow verification emails, return an error
143
        if (!Users::config()->send_verification_email) {
144
            return $this->httpError(400);
145
        }
146
147
        $sent = false;
148
149
        if (Member::currentUserID()) {
150
            $member = Member::currentUser();
151
        } else {
152
            $member = Member::get()->byID($this->getRequest()->param("ID"));
153
        }
154
155
        if ($member && !$member->isVerified()) {
156
            $sent = $this->send_verification_email($member);
157
        }
158
159
        $this->customise(array(
160
            "Title" => _t('Users.AccountVerification','Account Verification'),
161
            "MetaTitle" => _t('Users.AccountVerification','Account Verification'),
162
            "Content" => $this->renderWith(
163
                "UsersSendVerificationContent",
164
                array("Sent" => $sent)
165
            ),
166
            "Sent" => $sent
167
        ));
168
169
        $this->extend("updateSendVerificationAction");
170
171
        return $this->renderWith(array(
172
            "Users_Register_sendverification",
173
            "Users",
174
            "Page"
175
        ));
176
    }
177
178
179
    /**
180
     * Verify the provided user (ID) using the verification code (Other
181
     * ID) provided
182
     *
183
     * @param SS_HTTPRequest $request
184
     * @return HTMLText
185
     */
186
    public function verify(SS_HTTPRequest $request)
187
    {   
188
        $member = Member::get()->byID($this->getRequest()->param("ID"));
189
        $code = $this->getRequest()->param("OtherID");
190
        $verify = false;
191
192
        // Check verification group exists, if not, make it
193
        // Add a verified users group (only used if we turn on
194
        // verification)
195
        $verify_groups = Group::get()
196
            ->filter("Code", Users::config()->verification_groups);
197
198
        $this->extend("onBeforeVerify", $member);
199
200
        if (($member && $code) && $code == $member->VerificationCode) {
201
            foreach ($verify_groups as $group) {
202
                $group->Members()->add($member);
203
                $verify = true;
204
            }
205
        }
206
207
        $this->customise(array(
208
            "Title" => _t('Users.AccountVerification','Account Verification'),
209
            "MetaTitle" => _t('Users.AccountVerification','Account Verification'),
210
            "Content" => $this->renderWith(
211
                "UsersVerifyContent",
212
                array("Verify" => $verify)
213
            ),
214
            "Verify" => $verify
215
        ));
216
217
        $this->extend("onAfterVerify", $member);
218
219
        return $this->renderWith(array(
220
            "Users_Register_verify",
221
            "Users",
222
            "Page"
223
        ));
224
    }
225
226
    /**
227
     * Registration form
228
     *
229
     * @return Form
230
     */
231
    public function RegisterForm()
232
    {
233
234
        // If back URL set, push to session
235
        if (isset($_REQUEST['BackURL'])) {
236
            Session::set('BackURL', $_REQUEST['BackURL']);
237
        }
238
239
        $config = Users::config();
240
241
        // Setup form fields
242
        $fields = FieldList::create(
243
            TextField::create("FirstName"),
244
            TextField::create("Surname"),
245
            EmailField::create("Email"),
246
            $password_field = ConfirmedPasswordField::create("Password")
247
        );
248
249
        $password_field->minLength = $config->get("password_min_length");
250
        $password_field->maxLength = $config->get("password_max_length");
251
        $password_field->requireStrongPassword = $config->get("password_require_strong");
252
253
        // Setup form actions
254
        $actions = new FieldList(
255
            FormAction::create("doRegister", "Register")
256
                ->addExtraClass("btn")
257
                ->addExtraClass("btn-green")
258
        );
259
260
        // Setup required fields
261
        $required = new RequiredFields(array(
262
            "FirstName",
263
            "Surname",
264
            "Email",
265
            "Password"
266
        ));
267
268
        $form = Form::create(
269
            $this,
270
            "RegisterForm",
271
            $fields,
272
            $actions,
273
            $required
274
        )->addExtraClass("forms")
275
        ->addExtraClass("forms-columnar");
276
277
        $this->extend("updateRegisterForm", $form);
278
279
        $session_data = Session::get("Form.{$form->FormName()}.data");
280
281
        if ($session_data && is_array($session_data)) {
282
            $form->loadDataFrom($session_data);
283
            Session::clear("Form.{$form->FormName()}.data");
284
        }
285
286
        return $form;
287
    }
288
289
    /**
290
     * Register a new member. This action is deigned to be intercepted at 2
291
     * points:
292
     *
293
     *  - Modify the initial member filter (so that you can perfom bespoke
294
     *    member filtering
295
     *
296
     *  - Modify the member user before saving (so we can add extra permissions
297
     *    etc)
298
     *
299
     * @param array $data User submitted data
300
     * @param Form $form Registration form
301
     */
302
    public function doRegister($data, $form)
303
    {
304
        $filter = array();
305
306
        if (isset($data['Email'])) {
307
            $filter['Email'] = $data['Email'];
308
        }
309
310
        $this->extend("updateMemberFilter", $filter);
311
312
        // Check if a user already exists
313
        if ($member = Member::get()->filter($filter)->first()) {
314
            if ($member) {
315
                $form->addErrorMessage(
316
                    "Blurb",
317
                    "Sorry, an account already exists with those details.",
318
                    "bad"
319
                );
320
321
                // Load errors into session and post back
322
                unset($data["Password"]);
323
                Session::set("Form.{$form->FormName()}.data", $data);
324
325
                return $this->redirectBack();
326
            }
327
        }
328
329
        $member = Member::create();
330
        $member->Register($data);
331
332
        $this->extend("updateNewMember", $member, $data);
333
334
        $session_url = Session::get("BackURL");
335
        $request_url = $this->getRequest()->requestVar("BackURL");
336
337
        // If a back URL is used in session.
338
        if (!empty($session_url)) {
339
            $redirect_url = $session_url;
340
        } elseif (!empty($request_url)) {
341
            $redirect_url = $request_url;
342
        } else {
343
            $controller = Injector::inst()->get("Users_Account_Controller");
344
            $redirect_url = $controller->Link();
345
        }
346
347
        return $this->redirect($redirect_url);
348
    }
349
}
350