ifusion
ifusion

Reputation: 2233

Using a form in a custom controller?

I have created a Register_Controller and have setup a route for it as per below. The RegisterForm renders fine but when you click 'Register' it goes to the following URL: http://website.com/Register_Controller/RegisterForm and displays 'Page not found' and thus is not hitting the doRegister method.

What am I doing wrong?

Routes.yml

---
Name: mysiteroutes
After: framework/routes#coreroutes
---
Director:
  rules:
    'register': 'Register_Controller'

Register_Controller.php

<?php


class Register_Controller extends Page_Controller {
    private static $allowed_actions = array(
        'RegisterForm'
    );

    public function index() {
        return $this->renderWith(array('RegisterPage', 'Page'));
    }

    public function RegisterForm(){
        return new RegisterForm($this, 'RegisterForm');
    }
}

RegisterForm.php

<?php

class RegisterForm extends Form {
    public function __construct($controller, $name) {
        $fields = new FieldList(
            TextField::create('FirstName'),
            TextField::create('Surname'),
            TextField::create('Email'),
            PasswordField::create('Password'),
            PasswordField::create('ConfirmPassword'),
            TextField::create('Username')

        );

        $actions = new FieldList(
            new FormAction('doRegister', 'Register')
        );

        $validator = new RequiredFields(
            'Email', 'Password', 'ConfirmPassword', 'Username'
        );

        parent::__construct($controller, $name, $fields, $actions, $validator);

        $this->disableSecurityToken();

        if (Session::get('RegisterFormData')) {
            $this->loadDataFrom(Session::get('RegisterFormData'));
        }
    }

    public function doRegister($data, $form) {

        $checkIfEmailExsists = Member::get()->filter('Email', $data['Email'])->first();
        $registerFormData = Session::set('RegisterFormData', $data);

        if ($checkIfEmailExsists) {
            $form->addErrorMessage('Email', 'This email already exists', 'bad');
            return $this->controller->redirectBack();
        }

        $member = new Member();
        $form->saveInto($member);
        $password = $data['Password'];
        $member->changePassword($password);
        $member->write();
        $member->addToGroupByCode('administrators', 'Administrators');
        $member->logIn();
        Session::clear('RegisterFormData');
        return $this->controller->redirect($this->controller->Link('thanks'));
    }
}

RegisterPage.ss

<h2>Register Here</h2>

$RegisterForm

Upvotes: 0

Views: 454

Answers (1)

Greg Smirnov
Greg Smirnov

Reputation: 1592

Your form is trying to get a base link from the controller, but since it cannot find one on custom route controller, it uses controller name. You need to add Link() method.

class Register_Controller extends Page_Controller {
    public function Link($action = null) {
        return Controller::join_links(Director::baseURL(), '/register/', $action);
    }
}

Upvotes: 1

Related Questions