1

so far what I have managed to do is upload the file in app/files directory and download them using the deprecated media views. I am unable to use

    $file = $this->Attachment->getFile($id);

and i want to display the images/files to the user, say like a profile image of the user. How can i get this done without comprising on the security of the user images.

I get the error

    Call to a member function getFile() on a non-object

I don't want to use any plugins for the same.

Thanks in advance.

Chaitanya
  • 13
  • 4

2 Answers2

1

You've got three options;

  1. Create a mod_rewrite rule that allows access to the directory outside your web root to be viewed via an URL. This way the image will not have to be output via a PHP script
  2. Create a symlink inside your webroot that points to the directory outside your web root. This way the images will also be output directly by apache, not via a PHP script. You can follow the instructions for 'plugin assets' here: http://book.cakephp.org/2.0/en/plugins.html#plugin-assets
  3. Read the file with PHP and output (a resized version of) the image with PHP, e.g via the imagejpeg() function. For this to work you should output the image without using a 'layout' and set the right response headers. More information on the 'response' object can be found here: http://book.cakephp.org/2.0/en/controllers/request-response.html#sending-files

I don't have time at the moment to write examples, but can provide some pointers if needed

update

Although the MediaView is deprecated in CakePHP 2.3, you can still 'learn' from it on how to handle file-downloads yourself. Most of the 'magic' in the MediaView is concentrated around the Response-object, which is available in just about every object inside Cake (also inside your Controller). It's probably easy to convert de MediaView into a Component that you can attach to your Controller for outputting/sending files.

The source of the MediaView can be found here: http://api.cakephp.org/2.2/source-class-MediaView.html#23-242

And, additional information on sending files via the response-object can be found in the link I mentioned earlier (http://book.cakephp.org/2.0/en/controllers/request-response.html#sending-files)

important

Although not directly related to your question, some warnings;

User-provided uploads are dangerous always be sure that you check filetypes and sanitize filenames and paths (if you allow users to specify a path). Always assume that a user is able to send something like '../../../../' as a pathname an guard yourself against that situation

Be sure to disable PHP parsing for the directories/URLs that contain files uploaded by users. I've seen situations where users were able to upload dangerous_file.php.jpg and were able to rename the file afterwards (remove .jpg).

More information on disabling PHP in paths can be found here: Disable PHP in directory (including all sub-directories) with .htaccess

And, regarding that last point: Be sure to disable 'overriding' those settings within the user-directories (e.g. consider a situation where the user is able to upload a .htaccess file?

Community
  • 1
  • 1
thaJeztah
  • 27,738
  • 9
  • 73
  • 92
  • Thank you so much for the reply, any direct way or specific way of acheiving this in cakephp? and will your point 1. and 2. also allow non logged in users to access that folder? – Chaitanya Mar 01 '13 at 08:23
  • Yes, the downside of 1. and 2. is that non logged-in users will be able to reach those urls (if they know them). You should therefore consider *how* important security is for your case. A semi-secure option is to make use of GUIDs for the filenames, this will make it very hard to 'guess' a filename, although a brute-force attempt will always be possible. Regarding point (3), if you don't need resizing, there's no need to use the imagejpeg() method, but you need to pass-thru the raw content of the file (after sending the right content-type) – thaJeztah Mar 01 '13 at 08:47
  • Thanks a ton, could you also help me with the error I am getting Call to a member function getFile() on a non-object, I am using cakephp 2.3, what am i missing? and i am still relatively new to cakephp, what would be the best resource or how should i go about development, any suggestions will be appreciated. – Chaitanya Mar 01 '13 at 11:10
  • I think your code refers to this example; http://book.cakephp.org/2.0/en/controllers/request-response.html#sending-files. My guess is that the `$this->Attachment->getFile($id);` part of that example is meant to illustrate 'get the data from the model'. 'Attachment' is the name of the `Model` in that example. I must agree that it is confusing, it would have been better to use 'Mymodel' for that or add a comment to indicate what 'Attachment' is, maybe @ADmad can pick this up :) – thaJeztah Mar 01 '13 at 12:58
0

Media view are deprecated now in cakephp 2.3

please have look on this link :

http://book.cakephp.org/2.0/en/views/media-view.html

public function download() {
    $this->viewClass = 'Media';
    // Download app/outside_webroot_dir/example.zip
    $params = array(
        'id'        => 'example.zip',
        'name'      => 'example',
        'download'  => true,
        'extension' => 'zip',
        'path'      => APP . 'outside_webroot_dir' . DS
    );
    $this->set($params);
}
Krishna
  • 1,540
  • 2
  • 11
  • 25
  • Hey thanks for your reply, this will help me to downlad the file. But i want to display the picture of the user on the website itself. How would i go about doing that? – Chaitanya Mar 01 '13 at 07:37
  • @Krishna, why are you posting the same answer in different posts? Why don't you just link to your other answer under comments, if you think it is relevant? – Arun Mar 01 '13 at 08:29