Custom 404 page in CakePHP 3.X - cakephp

I want to create one custom 404 page for all errors coming to the website for production environment. For example if I receive missing controller or view error then it will redirect to
http://example.com/404.html, Also in some cases I will deliberately redirect it http://example.com/404.html
Earlier in CakePHP 2.x it was done by adding following action in AppContoller.php
public function appError($error) {
$this->redirect('/page-not-found.html',301,false);
}
But It is not working in CakePHP 3.x, I want to replicate same behavior in CakePHP 3.x

Do not redirect
The correct action to take if a page should render a 404 is to render a 404.
Redirecting to another page is confusing for users, especially since many browsers cache 301 responses making the original url inaccessible. This also affects e.g. search engines as the static file 404.html will have a 200 response code (unless you modify your webserver config) so it'll say 404 but simply not be.
The blog tutorial, which all devs should do before starting a project, guides you in the right direction:
public function view($id)
{
$article = $this->Articles->get($id);
$this->set(compact('article'));
}
The table method get returns a single entity object or throws an exception:
If the get operation does not find any results a Cake\Datasource\Exception\RecordNotFoundException will be raised. You can either catch this exception yourself, or allow CakePHP to convert it into a 404 error.
The controller code in this example doesn't need to have any "what if it doesn't exist" handling because by default if the record doesn't exist the result is a 404.
Changing the 404 template
If you want to change the way the 404 or 500 pages look change the template files
For all 4xx and 5xx errors the template files error400.ctp and error500.ctp are used respectively.
The error template is in your application, note that in production mode the output is very minimal.

If the get operation does not find any results a Cake\Datasource\Exception\RecordNotFoundException will be raised. You can either catch this exception yourself, or allow CakePHP to convert it into a 404 error.

The simplest way can be just implemented in two steps,
Step 1:
turn the debug mode off in config/app.php
Step 2:
Replace the content of src/Template/Layout/error.ctp with your custom layout.

Related

How to handle unknown URL request in CakePHP?

I am using CakePHP 3.3
I want to redirect all unknown URLs to login page, i.e. when someone types wrong URL they should be redirected to the login page and not show the usual error messages like below. Can anyone please guide me how to achieve this.
Missing Controller
Cake\Routing\Exception\MissingControllerException
Error: Unknown_urlController could not be found.
Error: Create the class Unknown_urlController below in file: src/Controller/Unknown_urlController.php
<?php
namespace App\Controller;
use App\Controller\AppController;
class Unknown_urlController extends AppController
{
}
It is probably a bad idea to redirect your users instead of showing a 404 page. It might be best to show a custom 404 page with helpful information like a link to the login page.
Similar Answer
Changing the 404 template
If you want to change the way the 404 or 500 pages look change the template files
For all 4xx and 5xx errors the template files error400.ctp and error500.ctp are used respectively.
The error template is in your application, note that in production mode the output is very minimal.

CakePHP: Can only load index.php, all pages 404 after Cake Bake

I'm trying to bake my first CakePHP application and am unable to get any page to particularly load for me right now. I've updated my config settings for salt,database, etc. and the index.php page tells me that I have configured everything.
So far I've used cake bake all on just one database table so far to make sure it loads properly. I created the Model, Controller, and View for the standard add/index/view/edit pages. When I try to access URL/organizations/index.php I'm hitting a 404 error however.
Is there any troubleshooting someone might have advice for how to solve this one? It is confusing to me that the index.php loads (so it redirects properly when loading the webroot) but trying to view any View pages yields no results. Is there any debug commands I can do to view what the valid pages would be? Or any additional information I can provide?
If you try URL/index.php/organisations or something similar to this and it works, then there is an issue with URL re-writing on the server which you'll need to correct.
I believe if you have things set up correctly you would want to visit /organizations in order to access the index() method of the organizations controller.
In general the ".php" is left off of the URL, as your index.php file initiates all the bootstrapping and routing. This also requires a correct .htaccess setup. Hard to say exactly what the problem is without seeing the app or an error message.
Try in url
URL/organizations/index.php
To
URL/organizations/index
or
URL/organizations/index.ctp
Cakephp using .ctp extension, that means cakephp Template. Please see this link. And also you can see your app\view\Organizations folder. Here all file is with .ctp extension. Isn't it ?

Best way to set up 404 pages in a angular SPA?

I have an application running on angular and I already have an http intercept setup. My issue is that my api returns some 404 errors that I would want to redirect to a 404 page and some that I wouldn't. For example when navigating to a new page, if the content of that page returns a 404 I want to direct to a 404 page instead of loading an empty template. However on a page where a user is checking out (paying for a purchased item) I check to see if they have a credit card token stored on file. If they do we can offer them the choice to use it. If they don't have one on file the api returns a 404 and we ask them to enter one.
My issue is that because of these two cases, it's not as simple at calling $state.go('404') anytime a 404 is thrown. I'm weighing a few options. One, have the api return a special message if it should redirect to a 404. This seems less than ideal, not really the responsibility of the api and we have multiple clients on a shared api. I could try to detect the current state/page in the http intercept and create a list of states that should redirect. I could $rootScope.$broadcast('no-template-data') or something similar from each controller that needs this and redirect from an global app.run function.
Has anyone else faced this challenge with single page applications?

Redirect (?) issue in CakePHP 1.3: "Failed to load source"

From the /posts/edit-view I'm submitting a form to the action addCategory in my Post controller.
The action does all the work it has to do, and subsequently calls $this->redirect($this->referer());.
At first sight my app works fine, but I encountered some hickups when moving to a production server. Monitoring the calls in Firebug I see that the action acually returns a 302 Found but the 'Response' is Failed to load source for: http://localhost/xps/posts/addCategory.
This happens on both dev en production servers, only on the production server it makes the redirect flow fail. On both servers the controller actions are executed well: category is added.
Removing all the code in the action results in the same failure. Removing the redirect removes the failure, but that's not getting me anywhere.
A second (though maybe irrelevant) irregularity is that the submit method of the form is identified as PUT in Firebug although I explicitly set it to POST in Cake.
I recently switched from CakePHP 1.3.4 to 1.3.6, but reversing does not change the behavior
I use the RequestHandler, Session and Auth components and call parent::beforeFilter() in beforeFilter().
I also found the following thread http://cakephp.1045679.n5.nabble.com/puzzle-over-activity-td1260972.html It suggests to remove $this->Auth->authorize = 'controller'; but I don't have that stated anywhere anyway.
Does anyone have an idea where to look next?
Just a guess, but if you are using Security component, it might cause problems. Also, sometimes when using the ajax and sessions it can cause problems. Maybe if the page requires sessions, you could try it without sessions and see if it works.
Ok, I found it.
The Failed to load source is still there but is not the cause of failure.
In one of my Behaviors I had a space after ?> which messed up the headers, which made me look into the wrong detail.

Cakephp is not redirecting properly when pages are cached

I am having some issues with a site that was working correctly until i implemented full page caching in CakePHP.
I have followed the guidance in the Manual and have my $session->flash in a no-cache block as so:
<cake:nocache>
<?
if($session->check('Message.flash')){
$session->flash();
}
?>
</cake:nocache>
However, whenever a controller sets a flash message and redirects to a cached page the page loads down to the tag and then gives the error:
Notice (8): Trying to get property of non-object
[CORE/cake/libs/view/helpers/session.php, line 145]
Fatal error: Call to undefined method stdClass::renderLayout() in
/home/decipherd/domains/example.com/public_html/beta/cake/libs/view/helpers/session.php
on line 14
If i then go to a page created by another controller the correct (delayed) message is displayed and the page loads correctly.
I have now submitted this to the CakePHP trac as ticket 282
Sounds like it might be an issue with the core, have you tried submitting a bug report?
Are you sure that there is something in the flash message? Try:
debug($session->read());
OR to output it to the debug.log
$this->log($session->read(), LOG_DEBUG); // this might not work in the view?
Looking at the error message, it seems as is SessionHelper is not available for some reason.
I am not sure why exactly, this helper is usually loaded automatically when using AuthComponent or SessionComponent in your application.
Just a guess, but it might be worth putting $helpers = array('Session', ...); in your problem controller or AppController for good measure.
You can inspect everything available to your view with debug($this);
Ultimately, I would take Matt's advice and upgrade to the latest stable version anyway.

Resources