I need to change page title from default "Error" when handling errors like 404. So I need to put my the title in the variable $title_for_layout for my Layout. I tried to create custom error handling function by changing configuration in app/Config/core.php and setting the page title as in controllers
Configure::write('Error.handler', function($code, $description, $file = null, $line = null, $context = null) {
$this->set('title_for_layout', 'Vyskytla sa chyba');
});
As I expected, I got a PHP error (line 59 is the second line in the code sample)
Fatal error: Using $this when not in object context in /var/www/web/app/Config/core.php on line 59
So how I can set the title for my default.ctp layout?
Thanks.
In CakePHP 2.0, you can try the following code to achieve the same you needed.
Try this:
/app/Config/core.php
Exception render need to set as an AppExceptionRender. Example:
Configure::write('Exception', array(
'handler' => 'ErrorHandler::handleException',
'renderer' => 'AppExceptionRenderer',
'log' => true
));
/app/Controller/ErrorsController.php
class ErrorsController extends AppController {
public $name = 'Errors';
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow('error404');
}
public function error404() {
//$this->layout = 'default';
$this->set('title_for_layout', 'Vyskytla sa chyba');
}
}
/app/Lib/Error/AppExceptionRenderer.php
App::uses('ExceptionRenderer', 'Error');
class AppExceptionRenderer extends ExceptionRenderer {
public function notFound($error) {
$this->controller->redirect(array('controller' => 'errors', 'action' => 'error404'));
}
}
/app/View/Errors/error404.ctp
<div class="inner404">
<h2>404 Error - Page Not Found</h2>
</div>
Insert it where you need: throw new NotFoundException();
Ref: CakePHP 2.0 - How to make custom error pages?
For < CakePHP 2.x:
If you create a custome error page view in app/views/errors then in a
php section on that error view page you can use:
$this->setLayout("Title for the error page here");
Then when you see the error page, it will have your title. Again, that
is if you set a custom error page.
Here is another way to do the same you needed.
// Create an error.php file in your /app folder with the following code:
<?php
class AppError extends ErrorHandler {
function error404($params) {
$this->controller->layout = "error";
$this->set('title_for_layout', 'Vyskytla sa chyba');
parent::error404($params);
}
}
?>
Related
This question already has answers here:
CakePHP 2.0 - How to make custom error pages?
(7 answers)
Closed 6 years ago.
I using cakephp, when have error, cakephp show error for users example : undefine index, notice in view page...I want when have error cakephp just show one message customize by me in view. Someone know ? Thank very much.
You can make custom error pages,
/app/Config/core.php
Exception render need to set as an AppExceptionRender. Example:
Configure::write('Exception', array(
'handler' => 'ErrorHandler::handleException',
'renderer' => 'AppExceptionRenderer',
'log' => true ));
/app/Controller/ErrorsController.php
class ErrorsController extends AppController {
public $name = 'Errors';
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow('error404');
}
public function error404() {
//$this->layout = 'default';
} }
/app/Lib/Error/AppExceptionRenderer.php
App::uses('ExceptionRenderer', 'Error');
class AppExceptionRenderer extends ExceptionRenderer {
public function notFound($error) {
$this->controller->redirect(array('controller' => 'errors', 'action' => 'error404'));
} }
/app/View/Errors/error404.ctp
`enter code here`
404 Error - Page Not Found`enter code here`
Insert it where you need: throw new NotFoundException();
after that make sure debug mode is 0,
Its work with production mode only
Configure::write('debug', 0);
I am using cakephp 2.0.4 (Doing Changes in existing project)
My controller function is..
class PagesController extends AppController {
public function getlocations($string = ''){
$this->autoRender = false;
$aResult = array(0=>'Florida', 1=>'London');
echo json_encode($aResult);
}
}
And also I have try $this->autoLayout = $this->autoRender = false;
When I am calling this action directly in browser mysite/app/pages/getlocations it will give following error
View file "/home/mysite/public_html/testing/app/View/Pages/g.ctp" is missing.
Create a /View/Ajax/json.ctp view:
<?php
if(!empty($data)) echo json_encode($data);
Then in the action:
$this->set('data', array(0=>'Florida', 1=>'London'));
$this->layout = false;
$this->render('/Ajax/json');
You could also make it work following the Cake way.
First you have to add the following code to your routes file:
Router::parseExtensions('json');
Next, in the controller add the 'RequestHandler' to your components array and serialize your result in your getlocations function:
public $components = array('RequestHandler');
public function getlocations($string = ''){
$this->set('aResult', array(0=>'Florida', 1=>'London'));
$this->set('_serialize', 'aResult');
}
Finally, you can see the results in your browser mysite/app/pages/getlocations.json
Doing this way CakePHP will add the application/json headers automatically.
More info: http://book.cakephp.org/2.0/en/views/json-and-xml-views.html
So I started to play around with cakePHP after i did the blog tutorial (yes im new), and i would like to do something complicated. Like, theres a comment form, which is simple it contains Name and the Comment. And I would like to send the data to another application in the same host, which is save this comment in the DB. Currently the Comments/add.ctp saves it.
Thanks for any advice!
So theres the CommentsControll.php
<?php
class CommentsController extends AppController{
public $components = 'Session'
public function add(){
if($this->request->is('POST')){
$this->Comment->create();
if($this->Comment->save($this->request->data)){
$this->Session->setFlash('Your comment is saved!')
}
}
}
}
?>
And theres the Comments/add.ctp file
<?php
echo $this->Form->create('Comment');
echo $this->Form->input('name', array(
'label' => 'Your Name'
));
echo $this->Form->input('commenttext',array(
'label' => 'Your Comment'
));
echo $this->Form->end('Submit');
?>
Solution HttpSocket
CakePHP includes an HttpSocket class which can be used easily for making requests. It is a great way to communicate with external webservices, or remote apis.
// in your controller
App::uses('HttpSocket', 'Network/Http'); // This should be at the top of your Controller
class CommentsController extends AppController{
public $components = 'Session'
public function add(){
if($this->request->is('POST')){
$this->Comment->create();
$HttpSocket = new HttpSocket();
$response = $HttpSocket->post('http://example.com/add', $this->request->data));
// Get the status code for the response.
$code = $results->code;
if($code == 200) {
$this->Session->setFlash('Your comment is saved!');
} else {
$this->Session->setFlash('Opps! Somthing is wrong!');
}
}
}
}
Also see here CakePHP HttpSocket
I have a CakePHP project where I modified "app/config/routes.php" so that the root points to the "Users" controller's "dashboard" action. In other words, these two URLs go to the same place:
http://example.com/
http://example.com/users/dashboard
I have the "Auth" component set up in my "App" controller like so:
class AppController extends Controller {
var $components = array('Auth', 'Session');
function beforeFilter() {
$this->Auth->authorize = 'controller';
$this->Auth->loginRedirect = array('controller' => 'users', 'action' => 'dashboard');
if ($this->Auth->user()) {
$this->set('logged_in', true);
}
else {
$this->set('logged_in', false);
}
}
}
I want it so that if a non-authenticated user goes straight to http://example.com/users/dashboard , they are taken to the login page with the "Auth" component's "authError" message showing, but if they go to http://example.com/ , they are taken to the login page without the "Auth" component's "authError" message showing. Is this possible?
I resolved this by putting the following code in my "Users" controller's "login" action:
if ($this->Session->read('Auth.redirect') == $this->webroot && $this->Session->read('Message.auth.message') == $this->Auth->authError) {
$this->Session->delete('Message.auth');
}
been looking for somthing like that for a long time! Thank you.
I had to make a little change then $this->webroot is not "/":
if (str_replace("//","/",$this->webroot.$this->Session->read('Auth.redirect')) == $this->webroot && $this->Session->read('Message.auth.message') == $this->Auth->authError) {
$this->Session->delete('Message.auth');
}
Well, I don't understand why sometimes you show the error and why sometimes not.. but you can afford this creating an isAuthorized method and modifying all the logic of the default AuthComponent behavior.
Open your Auth component and check for method "startup()". There, at it's last line, you will se this:
$this->Session->setFlash($this->authError, $this->flashElement, array(), 'auth');
$controller->redirect($controller->referer(), null, true);
This is the part responsible for displaying the error.
Before it, you will se...
if ($this->isAuthorized($type)) {
return true;
}
So you can change your isAuthorized method to change this message when you want.
Is a lot of work for (I think..) nothing.
PS. There may be a simpler way to be ignoring me
If you really wants to prevent authError message on homepage and simple redirect to login page then you have to put false as parameter of authError
class AppController extends Controller {
public function initialize() {
parent::initialize();
$this->loadComponent('RequestHandler');
$this->loadComponent('Flash');
$this->loadComponent('Auth', [
'authError' => false
]);
}
}
I wanna have a different layout for the page not found 404 page. How can i set a different layout for that page?
Savant from the IRC helped me out and he suggest in using beforeRender(){} in the app_controller
// Before Render
function beforeRender() {
if($this->name == 'CakeError') {
//$this->layout = 'error';
}
}
CakeError is a catchAll for errors :D
In CakePHP 2.2.2 I changed the ExceptionRenderer in core.php with my own, like this:
app/Config/core.php:
Configure::write('Exception', array(
'handler' => 'ErrorHandler::handleException',
'renderer' => 'MyExceptionRenderer', // this is ExceptionRenderer by default
'log' => true
));
app/Lib/Error/MyExceptionRenderer.php:
App::uses('ExceptionRenderer', 'Error');
class MyExceptionRenderer extends ExceptionRenderer {
protected function _outputMessage($template) {
$this->controller->layout = 'error';
parent::_outputMessage($template);
}
}
Just you need to make layout changes in your error400.ctp file under /app/View/Errors/error400.ctp
Open that file and set layout by
<?php $this->layout=''; //set your layout here ?>
better to create an error.php file in your app folder
class AppError extends ErrorHandler {
function error404($params) {
$this->controller->layout = 'error';
parent::error404($params);
}
}
so you can avoid the if-testing at EVERY page render that savants' solution introduces
My solution for CakePHP 2.3
Change the ExceptionRenderer in core.php to use your own renderer.
app/Config/core.php:
Configure::write('Exception', array(
'handler' => 'ErrorHandler::handleException',
'renderer' => 'MyExceptionRenderer',
'log' => true
));
app/Lib/Error/MyExceptionRenderer.php:
App::uses('ExceptionRenderer', 'Error');
class MyExceptionRenderer extends ExceptionRenderer
{
/**
* Overrided, to always use a bare controller.
*
* #param Exception $exception The exception to get a controller for.
* #return Controller
*/
protected function _getController($exception) {
if (!$request = Router::getRequest(true)) {
$request = new CakeRequest();
}
$response = new CakeResponse(array('charset' => Configure::read('App.encoding')));
$controller = new Controller($request, $response);
$controller->viewPath = 'Errors';
$controller->layout = 'error';
return $controller;
}
}
The advantage to this approach is that it ensures any exceptions thrown from AppController don't cause an endless loop when rendering the exception. Forces a basic rendering of the exception message every time.
This simplest way I know of is to create this function in your AppController:
function appError($method, $messages)
{
}
You can then do whatever you want with the error, display it however you like, or not display it at all, send an email etc.. (I'm not sure if this method if still valid.)
There is also an option of creating app_error.php in your app root, with class AppError extends ErrorHandler in it, which enables you to override all kinds of errors. But I haven't done this yet, so I can't tell you more about it.
See cake/libs/error.php and cake/libs/object.php and of course The Book for more info.
Edit: Forgot to mention, once you caught the error, there's nothing preventing you to - for example - store the error in session, redirect to your "error handling controller", and then display it in your controller however you want.