Question

I have a custom Page called ForgotPasswordPage.php and a ForgotPasswordPage.ss template. I also have a custom Form class in ForgotPasswordForm.php and it's corresponding custom Form template, ForgotPasswordForm.ss, in the templates/Includes directory. The form action is supposed to call doForgotPassword, but this function is never called, otherwise, I'd be sent to google.com. This seems ever-so-basic, but I've had two developers looking at it and all we get is the following error:

There seems to have been a technical problem. Please click the back button, refresh your browser, and try again.

What am I doing wrong here?

ForgotPasswordForm.php

<?php

class ForgotPasswordForm extends Form { 
    function __construct($controller, $name, $arguments=array()) { 
        $fields = new FieldList( 
            EmailField::create("Email") 
        ); 
        $actions = new FieldList(FormAction::create("doForgotPassword")->setTitle("RETRIEVE PASSWORD")); 
        $validator = new RequiredFields('Email'); 
        parent::__construct($controller, $name, $fields, $actions, $validator); 
    }

    public function doForgotPassword($data, Form $form) { 
        //As a test, if we ever get here, the controller should send me to the Google website
        Controller::curr()->redirect('http://www.google.com'); 
    }

    public function forTemplate() { 
        return $this->renderWith(array( 
            $this->class, 
            'Form' 
        )); 
    }

}

ForgotPasswordForm.ss

<form $FormAttributes> 
    <label for="{$FormName}_Email">Enter Your Email Address</label> 
    $Fields.dataFieldByName(Email) 
    <% if $Actions %> 
        <% loop $Actions %> 
            $Field 
        <% end_loop %> 
    <% end_if %> 
</form>

ForgotPasswordPage.php

class ForgotPasswordPage extends Page { 
. 
. 
. 
}

class ForgotPasswordPage_Controller extends Page_Controller {

    public static $allowed_actions = array ( 
        'MyForgotPasswordForm' 
    );

    public function init() { 
        parent::init(); 
    }

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

}

ForgotPasswordPage.ss

. 
. 
. 
$MyForgotPasswordForm 
. 
. 
.
Was it helpful?

Solution

To protect forms against xsrf attacks, silverstripe forms are usually built with an extra hidden field populated with a security token, which is checked upon submission. By rewriting the template file for the form, this token is not included anymore. You could include it by adding $Fields.dataFieldByName(SecurityID) after $Fields.dataFieldByName(Email) in ForgotPasswordForm.ss. Alternatively, you could loop through the fields, which is a more robust solution (this is the approach in Form.ss)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top