Amazon S3 Upload behavior for CakePHP 1.2.x

Nowadays developers are preferring Amazon S3 for file storage and there are various libraries available in PHP to facilitate the file transfer to S3. This behavior uses Amazon S3 class by Donovan Schonknecht. Before using this behavior make sure you place the S3.php file in your vendors directory.

This behavior is very similar to normal upload behavior except that the uploaded file is not kept on the server but transferred to the specified S3 bucket.

Note: This behavior requires PHP > 5.2 and cURL. Actually this is the requirement of the S3 class which this behavior uses.

Usage:

Get the behavior from Github (Direct link).

Place the s3_upload.php file in app/models/behaviors/ directory and edit the file to put your AWS access key and secret key

PHP:
  1. // File: s3_upload.php
  2. var $__accessKey = 'set your aws access key here';
  3.  
  4. var $__secretKey = 'set your aws secret key here';

Alternately you can pass the credentials in settings when you attach the behavior to the model or use the behavior's setS3Credentials method.

PHP:
  1. // In Controller before calling MyModel::save()
  2. $this->MyModel->setS3Credentials('access key', 'secret key');

Then to attach the behavior to your model

PHP:
  1. // In your model attach the S3Upload behavior
  2. var $actsAs = array(
  3.     'S3Upload' => array(
  4.         'fieldname' => array(
  5.             's3_bucket' => 'my-bucket',
  6.             // Acces and secret key are required if you have not put it in behavior itself
  7.             // or if you need different access credentials for different fields
  8.             's3_access_key' => 'your access key',
  9.             's3_secret_key' => 'your secret key',
  10.             // Other options as explained below
  11.         ),
  12.     ),
  13. );

Above, only one option i.e. s3_bucket is compulsory. The other two options i.e. s3_access_key and s3_secret_key are required only if you have not set the global S3 credentials in S3UploadBehavior class. There are many other optional settings as explained below...

  • formfield (string) : If the name of your form field which uploads the file is different from db fieldname
  • s3_path (string): If you want your file to be placed in a (virtual) sub directory in S3 bucket
  • s3_acl (string): S3 permissions - private, public-read, public-read-write or authenticated-read. Defaults to public-read
  • s3_request_headers (array): Headers to be sent along with the file
  • s3_meta_headers (array): Metadata to be sent
  • allowed_ext (array): File extensions to be allowed.
  • append_salt (bool): True to append a random salt to the filename to make it unique. Defaults to false.
  • required (bool): True to make the file upload compulsory. Defaults to false.
  • unique (bool): True to create unique filenames. Defaults to true.

The uploaded file will be transferred to S3 in all save operations. If updating then the old file will be deleted from S3 and new file will be uploaded.

The behavior class is simple and self explanatory. Explore the code to learn more.

Download behavior

About Abbas Ali

Abbas Ali is a Mechanical Engineer by education. He turned to programming and took it as a profession just after finishing his studies. He is fascinated equally by both machines and computers. He leads the team of dynamic programmers at SANIsoft and works as a Technology Manager. He is also an active developer on the Coppermine Picture Gallery team.

17 Responses to Amazon S3 Upload behavior for CakePHP 1.2.x

  1. Josey September 23, 2010 at 6:06 am #

    I look forward to using this behavior. I have attached it to my model but when I attempt to process the form with the file the behavior returns the following:

    Warning (512): S3::putObject(): [NoSuchBucket] The specified bucket does not exist [APP/vendors/S3.php, line 358]

    Array
    (
    [] => s3_upload_error
    )

    Any help would thrill me.

    Regards,
    Josey

  2. Abbas Ali September 23, 2010 at 1:48 pm #

    @Josey: The error suggests that you have not specified the correct bucket name in s3_bucket option of $actsAs in your model. Make sure the bucket name you have specified exists.

    • Josey September 23, 2010 at 7:49 pm #

      The bucket does exist, here is my call to the behavior:

      var $actsAs = array(
      'S3Upload' => array(
      'location' => array(
      's3_bucket' => 'development',
      'allowed_ext' => array('rtf')
      )
      )
      );

      I created the development bucket before I attempted to use this behavior

      • Abbas Ali September 24, 2010 at 3:35 pm #

        @Josey: Try to browse the bucket using some other tool and see if it works.

        • Josey October 9, 2010 at 10:52 pm #

          @abbas: When I browse to my account using S3 Browser for Mac OSX I can view the contents without any problem but when I try to use this behavior I'm told the bucket doesn't exist.

        • Abbas Ali October 11, 2010 at 8:26 am #

          Let me know the URL of any of the public files in your bucket.

        • Josey October 11, 2010 at 11:26 pm #

          here's a small image: https://s3.amazonaws.com/Mort_Development/OTV/cover.jpg

        • Josey October 11, 2010 at 11:27 pm #

          it should be know that i have renamed the bucket to Mort_Development and have changed the actAs accordingly.

  3. Abbas Ali October 12, 2010 at 8:40 am #

    @Josey: Don't know what's wrong with S3 but if "Mort_Development" is the bucket name then https://Mort_Development.s3.amazonaws.com/OTV/cover.jpg should work. But it gives 'No such bucket' error.

  4. Jono February 14, 2011 at 9:23 pm #

    Hello

    This behaviour looks great and I really want to use it. I'm getting it uploading ok and its saving but its throwing the following error:

    Fatal error: Existing data passed is not an array
    Called set_existing in /Users/jono/Dev/Netmums/bake/website/application/models/user.php on line 351
    Called afterSave in /Users/jono/Dev/Cake/1.3.x.x/cake/libs/model/model.php on line 1364
    Called save in /Users/jono/Dev/Netmums/bake/website/application/plugins/cms/controllers/users_controller.php on line 77
    Called edit in on line
    Called call_user_func_array in /Users/jono/Dev/Cake/1.3.x.x/cake/dispatcher.php on line 204
    Called _invoke in /Users/jono/Dev/Cake/1.3.x.x/cake/dispatcher.php on line 171
    Called dispatch in /Users/jono/Dev/Netmums/bake/website/application/webroot/index.php on line 83
    in [path]/includes/class_dm.php on line 265

    This is a CakePHP 1.3 app.

  5. Warren March 16, 2011 at 6:36 pm #

    Thanks for the code.

    I couldn't get it to work out the box as is on CakePHP 1.3 . I had to make quite a few modifications, would you like me to send you the code? Or should I fork it on github?

    • Abbas Ali March 16, 2011 at 8:07 pm #

      Warren, you can do either. Looking forward to it!!

  6. Adaptoid August 17, 2011 at 7:51 pm #

    Does this behavior work for CakePHP 1.3, I am really interested in using it.

Trackbacks/Pingbacks

  1. Tweets that mention Amazon S3 Upload behavior for CakePHP 1.2.x at SANIsoft – PHP for E Biz -- Topsy.com - March 29, 2010

    [...] This post was mentioned on Twitter by Tarique Sani, Aditya Mooley. Aditya Mooley said: RT @tariquesani: SANIsoft: blog : Amazon S3 Upload behavior for CakePHP 1.2.x http://bit.ly/dsGnoz [...]

  2. Iphoto Alternatives :Streets Of Dublin Project - March 31, 2010

    [...] Amazon S3 Upload behavior for CakePHP 1.2.x at SANIsoft – PHP for E Biz [...]

  3. Amazon S3 Upload behavior for CakePHP 1.2.x at SANIsoft – PHP for … | Source code bank - April 10, 2010

    [...] reading here: Amazon S3 Upload behavior for CakePHP 1.2.x at SANIsoft – PHP for … If you enjoyed this article please consider sharing [...]

  4. CakePHP: Fat Models and Skinny Controllers at SANIsoft – PHP for E Biz - May 31, 2010

    [...] certain actions repeatedly in your controller then you should go ahead and create a component. The Amazon S3 Upload Behavior is a good example of a generalized behavior which can be used efficiently to store files using [...]

Leave a Reply