tags:

views:

701

answers:

3

In my controller, I check a condition to see if the user is allowed to do something. If the check fails, I want to send a 403 back to the browser. How do I do that in Cakephp?

+3  A: 

Perhaps something in this section of the cakephp manual can help you.

redirect(string $url, integer $status, boolean $exit)

The flow control method you’ll use most often is redirect(). This method takes its first parameter in the form of a CakePHP-relative URL. When a user has successfully placed an order, you might wish to redirect them to a receipt screen. The second parameter of redirect() allows you to define an HTTP status code to accompany the redirect. You may want to use 301 (moved permanently) or 303 (see other), depending on the nature of the redirect.

The method will issue an exit() after the redirect unless you set the third parameter to false.

Adriano Varoli Piazza
But I don't want to send a 3xx status code back. Even if this works, it seems wrong.
allyourcode
You can send any status code back, the 303 are just an example.
Adriano Varoli Piazza
I'd like to know the reason for downmodding...
Adriano Varoli Piazza
apologies, i downmodded because i thought your answer was incorrect. i have since read your comment (on my answer) and also understand SO a bit better (ie. downvotes reduce rep and should be saved for worse things). if you edit your answer, i will be able to remove my down vote. (Vote too old to be changed, unless this answer is edited)
deizel
edited lightly, thank you
Adriano Varoli Piazza
+6  A: 

By looking at the relevant API code from the previous comment, it seems you can call Controller::header($status) to output a header without redirection. In your case, the proper usage is most likely:

$this->header('HTTP/1.1 403 Forbidden');
deizel
Also, the code above only outputs the header, so you may want to end execution with `return false`, `die`, `exit`, or something similar.
deizel
This answers the question more precisely than my answer. Still, I think it's useful to be able to redirect the user to a custom page in this case, it's nicer than a blank 'the server responded this' page.
Adriano Varoli Piazza
Looking at the body of that method, it seems to be a wrapper around a built in function called header.
allyourcode
since all of cakephp is actually more php, indeed most stuff could be boiled to 'a wrapper around a built-in function'. The idea is that your development is eased by the wrapping, and that the performance overhead is negligible.
Adriano Varoli Piazza
What I mean is, header() is the standard way to send an http header in PHP, but you did ask 'How do I do this using CakePHP', which, I assume, implies 'I'm going to use what Cake offers'.
Adriano Varoli Piazza
Since $this->header in a controller is exactly like the PHP std `header` function, I prefer to use the latter. When a method does NOT provide a higher level of abstraction, it's a distraction and should be avoided. On the other hand, other parts of CakePHP do provide higher levels of abstraction. I'll continue to use such parts to make my code more understandable, and my life easier..
allyourcode
+5  A: 

Upon revisiting this question, and reading Adriano's comment on my previous answer (regarding redirecting the user to a friendly page), I have come up with a new solution.

Within a controller you can call $this->cakeError('error404') to generate a friendly 404 page. This can can be customised (as with other errors) by creating file at 'app/views/errors/error404.ctp'.

After having a closer look at the code for cakeError, my recommendation is to try extending Cake's ErrorHandler by creating a file at 'app/error.php' or (possibly more preferable) 'app/app_error.php'.

The code for your error403 (mimicking the error404 code) could read as follows:

class AppError extends ErrorHandler {
    function error403($params) {
        extract($params, EXTR_OVERWRITE);
        $this->error(array(
            'code' => '403',
            'name' => 'Forbidden',
            'message' => sprintf(__("Access was forbidden to the requested address %s on this server.", true), $url, $message)));
            $this->_stop();
     }
}

You should also be able to provide a custom view for this error by creating 'app/views/errors/error403.ctp'. Here is a modified version of the error404 view:

<h2><?php echo $name; ?></h2>
<p class="error">
    <strong>Error: </strong>
    <?php echo sprintf(__("Access was forbidden to the requested address %s on this server.", true), "<strong>'{$message}'</strong>")?>
</p>
deizel
Good answer! This is one thing I didn't know you could do with Cake.
Adriano Varoli Piazza