tags:

views:

469

answers:

2

I have a Cake PHP plugin that I have written. The plugin has its own controller so that it can serve up some dynamic code on the plugin's index page (/keyedit/ or /keyedit/index).

When images are requested from /keyedit/img/ they are served up properly. But if the image doesn't exist Cake thinks the /img/ is a method in the keyedit_controller.php and throws a missing method error. This wouldn't be so bad, but it also deletes the session cookie, breaking everything else.

How can I tell Cake to just return a 404 when files are missing from /img/ instead of falling through into the controller code?

I suppose I could add a img() method that just returns a 404, but that seems like a kludge.(ETA: Tried that, still deletes the session cookie)

+2  A: 

You probably have debug > 0 in app/config/core.php. When debug is 0, missing method is the same as 404.

You can also create app/app_error.php to change behavior of errors.

niteria
You are correct about having debug > 1. Set it to 0 and it works. Adding .htaccess didn't help, the controller is still catching it. I guess I'll have to try to find some good docs on app_error.php
Brian C. Lane
Tried adding a custom app_error.php handler (that just dies when hit). That removes the response page, but the cookie is still deleted. Its buried someplace higher up in the call stack apparently.
Brian C. Lane
You can try this app_error.php: http://bin.cakephp.org/view/1035390701 but it makes debugging harder. I don't know why your cookie is deleted, try changing your security level.
niteria
Thanks, I'll give that a try to see if it is cleaner than my solution above. I suspect that it won't be, because the cakeError call seems to delete the cookie before it gets to the app_error.php class.
Brian C. Lane
+1  A: 

Cake uses an .htaccess file to rewrite the original pretty URLs into something Cake can use, like this:

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]

Those lines make sure that the URL will only be passed to Cake (by rewriting it) if it's not an actual file you're requesting. However, if the file is missing, those rules obviously don't apply, so it'll happily pass it to Cake as well.

What you can do is add a condition to exclude any directories you know don't need Cake. E.g.

RewriteCond %{REQUEST_URI} !^/(keyedit/img|other_folder)/

Alternatively, you can exclude files based on their file extensions, like so:

RewriteCond %{REQUEST_URI} !\.(js|ico|gif|jpg|png|css)$

Or you can edit the regular expression in the RewriteRule itself to exclude specific directories or file extensions...

mercator
The problem with this is that the img directory is buried inside Cake's directory tree, so skipping the rewrite doesn't work for images that do exist. I could put the full path on there, but there should be a right way to do this...
Brian C. Lane
Ah, the image URLs need to be rewritten by Cake as well? Using app_error must be the way to go then, and the session cookie being cleared is (was?) a bug: https://trac.cakephp.org/ticket/3507
mercator