Question

I have the following form:

<form method="post" action="<?php echo $this->action('delete');?>">
<?php
    $token = Loader::helper('validation/token');
    $token->output('delete_event');
    echo $form->hidden('id', $row['bID']);
    echo $form->submit(null, t('Delete'), array('class' => 'delete', 'onclick' => 'return false'));
?>
</form>

and the controller method:

public function action_delete() {
    if($this->authenticate() && $this->isAdmin()){
        $id = (int) $_POST['id'];

        $val = Loader::helper('validation/form');
        $val->addRequiredToken('delete_event');

        if($val->test() == 0){
            //delete from DB
        }
    }
}

But for some reason the token does not get validated. Any insights?

Was it helpful?

Solution

The API docs are incorrect.

You should test with if ($val->test()) {} as in Jake's example. Comparing it to 0 is essentially saying == false (false and 0 are both falsey), and if you look at the code, it returns true or false based on success or failure:

return count($this->fieldsInvalid) == 0;

https://github.com/concrete5/concrete5/blob/master/web/concrete/core/helpers/validation/form.php#L217

Though, now that I've also read mkly's post, he's right too. You don't need to check the token in a block action. However, it's important to remember the correct $val->test() usage in general.

James

OTHER TIPS

I think this is because you are validating a token with a Block controller method. This should already be protected with a token which may be causing a conflict.

If you really do want to go ahead and check it you may be able to do this

$token = Loader::helper('validation/token');
$form->hidden('delete_event_token', $token->generate('delete_event'));

and then in the controller.php

if (Loader::helper('validation/token')->validate('delete_event', $this->post('delete_event_token'))) {
  // do db stuff
}

That said, in a Block action the CSRF token is already handled for you so you don't need to be checking that anyway.

Why are you testing for 0 (zero) ?

Remember that zero and false are not the same. Try changing to

public function action_delete() {
    if($this->authenticate() && $this->isAdmin()){
        $id = (int) $_POST['id'];

        $val = Loader::helper('validation/form');
        $val->addRequiredToken('delete_event');

        if($val->test()){
            //this authenticated
        }
        else{
            //this did not authenticate
        }
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top