Yii 1.1: s3assetmanager

A asset manager that stores content in the Amazon AWS S3.
18 followers

This extension serves as a replacement for the class CAssetManager. It publishes content on the Amazon AWS S3, allowing you to enable and use a CloudFront CDN for your assets.

Requirements

  • A cache component set.
  • An account on Amazon AWS S3

Usage

To install just unzip into the protected folder . Warning! I used as a basis the extension ES3, so if you have it installed you may have name conflicts.

Basic configuration:

'components' = array(
        ......
 
        'cache'=>array(
            'class'=>'system.caching.CMemCache',
            'servers'=>array(
                array('host'=>'localhost', 'port'=>11211),
            ),
        ),
        's3' => array(
            'class' => 'ext.s3.ES3',
            'aKey'=>'ADD YOUR AKEY HERE', 
            'sKey'=>'ADD YOUR SKEY HERE',
        ),
        'assetManager' => array(
            'class' => 'S3AssetManager',
            'host' => 'Your-bucket.s3.amazonaws.com', // changing this you can point to your CloudFront hostname
            'bucket' => 'Your-bucket',
            'path' => 'assets', //or any other folder you want
        ),
 
        ......
    )

Done! Your assets will be stored on Amazon!

Resources

Total 11 comments

#14634 report it
dmapes123 at 2013/08/30 09:24pm
database based components

GillesK, I would be very interested to see the class for using the db to store this info. I have the same concerns, I need to support autoscaling app in the cloud.

#11858 report it
MetaYii at 2013/02/07 07:26pm
mongodb instead of memcached

Hi, I've just modified your component to use MongoDB instead of memcached. Since memcached is volatile, if the locks are lost, content is uploaded again. MongoDB is persistent and very fast, so locks are safe there. If interested, I can send you the code (just send me a private message in the forum)

#10938 report it
GillesK at 2012/12/05 07:47am
Specific cache component

Andre,

I´ve created a cache component inspired on CDbCache but what it does is (for each request):

  • init : read the asset information from a database table and put it in memory

  • respond to Asset manager publish method with the corresponding information in memory

  • on Yii::app()->onEndRequest : update database table if needed

This component suites my needs for Amazon AWS deployment with autoscaling and no need to use ElastiCache

If you are interested I can send you the class I came with

#10851 report it
GillesK at 2012/11/27 01:05pm
memcached

Hello Andre,

I´m asking that because I´m planning to deploy on the cloud some day and it would be another component to manage ... Maybe in database or it will be slow also ?

#10843 report it
Andre Metzen at 2012/11/27 06:44am
memcached

GillesK,

Because you do not know if your asset is already published in S3 or not (and check that every request would be extremely slow), the solution I found was to store in the cache the items which were published.

Maybe there is a better way, but I could not think of anything.

#10840 report it
GillesK at 2012/11/27 06:07am
Memcache

Hello, Why do we need the memcached server ?

#10615 report it
Nathan at 2012/11/08 04:37am
Can't find S3

I get a include(S3.php): failed to open stream: No such file or directory

The S3.php file is inside extensions>S3

Am I missing something?

#10614 report it
Nathan at 2012/11/08 04:24am
cache

Could someone explain what the 'cache' section of the config is about? More precilse

array('host'=>'localhost', 'port'=>11211),

What are those hostname and port?

#7520 report it
DarkNSF at 2012/03/27 07:43pm
Almost!

For some reason Chrome requires the contentType to be 'text/css' to load properly, the asset manager uploads everything as 'text/plain'. Also, I kept having filename issue on uploading deep asset directories.

Here are my changes:

S3AssetManager.publish()

if (is_file($src))

$contentType = CFileHelper::getMimeTypeByExtension($dstFile); 
if ($this->getS3()->putObjectFile($src, $this->bucket, $dstFile, S3::ACL_PUBLIC_READ, array(), $contentType))

AND

else if (is_dir($src))

$dstFile = $this->getBasePath().'/'.$dir.'/'.str_replace($src.DIRECTORY_SEPARATOR, '', $file);
$dstFile = str_replace('\\', '/', $dstFile); // windows xampp fix?
$contentType = CFileHelper::getMimeTypeByExtension($dstFile);
if (!$this->getS3()->putObjectFile($file, $this->bucket, $dstFile, S3::ACL_PUBLIC_READ, array(), $contentType))
#6492 report it
Andre Metzen at 2012/01/13 01:49pm
Thanks haykelbj!

Thank you Haykelbj!

Already correct and upload the extension.

I did not use the extension 'ES3' because it does not provide public access to all methods of S3 class (or at least I did not see how to access it).

#6491 report it
Haykel at 2012/01/13 01:28pm
Missing 'if'-statement

Wow! I was about to implement this extension. Thanks!

I have just looked at the code on github and I noticed that the function S3AssetManager::getS3() is missing an if-statement:

private function getS3()
{
    throw new CException('You need to configure the S3 component or set the variable s3Component properly');
    return Yii::app()->{$this->s3Component};
}

missing line before 'throw':

if (!Yii::app()->{$this->s3Component})

One question: Is there a special reason why you did not use the 'es3' extension?

Thanks.

Leave a comment

Please to leave your comment.

Create extension