October: How to catch 404 response in OctoberCMS and make some logic before displaying 404 page?

Created on 22 Aug 2018  路  5Comments  路  Source: octobercms/october

Is it possible to catch 404 response in OctoberCMS and make some logic before displaying 404 page?

For example, a user is trying to access some image on my site with url = http://site.com/storage/app/media/image_name_500_350.jpg . If this image does not exist (if this link returns 404 error page), I want to catch this response, create image with width = 500 px and height = 350 px and show this image to the user.

In other words, I want to catch 404 response and add some logic (create new image with needed name and dimensions) and return this image to the user.

How can I do this? Thank you in advance for your reply.

October build

October build: 437

Question

Most helpful comment

You could listen to the "cms.page.display" event, this event has the controller which has the status code. You could put this (dirty) code for debugging purposes in your boot function of your plugin.php:

\Event::listen('cms.page.display', function (\Cms\Classes\Controller $controller, string $url, \Cms\Classes\Page $result) {
    if ($controller->getStatusCode() === 404) {
        $fileContent = file_get_contents('https://via.placeholder.com/350x150');
        return \Response::stream(function() use($fileContent) {
            echo $fileContent;
        }, 200, ['Content-Type' => 'image/png']);
    }
});

There might also be other events you can use for this problem (https://docs.google.com/spreadsheets/d/17vv4zn_ezp9iFBgYhYuYsmUG4MXW9uuIw7aOIrVcHiM/edit#gid=0).

All 5 comments

You could listen to the "cms.page.display" event, this event has the controller which has the status code. You could put this (dirty) code for debugging purposes in your boot function of your plugin.php:

\Event::listen('cms.page.display', function (\Cms\Classes\Controller $controller, string $url, \Cms\Classes\Page $result) {
    if ($controller->getStatusCode() === 404) {
        $fileContent = file_get_contents('https://via.placeholder.com/350x150');
        return \Response::stream(function() use($fileContent) {
            echo $fileContent;
        }, 200, ['Content-Type' => 'image/png']);
    }
});

There might also be other events you can use for this problem (https://docs.google.com/spreadsheets/d/17vv4zn_ezp9iFBgYhYuYsmUG4MXW9uuIw7aOIrVcHiM/edit#gid=0).

@nathan-van-der-werf thanks for your answer, but cms.page.display Event is not called when we access an image from MediaManager by url like so: http://site.com/storage/app/media/image_name.jpg
I have just checked. Maybe you know another solution?

@iboved For me it works, tried it with your URL (on my own local domain) (https://xxxxx.localhost/storage/app/media/image_name.jpg), the event cms.page.display gets fired since the file (page) doesn't exist.

What is the result you are getting? The 404 page ?

@nathan-van-der-werf I have found why cms.page.display Event is not called in my application. The cms.page.display Event is called only if you have a CMS page with url = "/404". If no, this Event is not called.
I have tried to use cms.page.beforeDisplay Event, but it seems that it is very early. I always have 200 status code in this Event.

@nathan-van-der-werf I think "/404" CMS page is not a problem. I will create this page to make it possible to catch cms.page.display Event. Thank you for your help. You gave me a very good starting point in this issue.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

d3monfiend picture d3monfiend  路  3Comments

Flynsarmy picture Flynsarmy  路  3Comments

mittultechnobrave picture mittultechnobrave  路  3Comments

ChVuagniaux picture ChVuagniaux  路  3Comments

axomat picture axomat  路  3Comments