0

I want to be able to call the CakeS3 plugin from the Cake Shell. However, as I understand it components cannot be loaded from the shell. I have read this post outlining strategies for overcoming it: using components in Cakephp 2+ Shell - however, I have had no success. The CakeS3 code here is similar to perfectly functioning cake S3 code in the rest of my app.

<?php
App::uses('Folder','Utility');
App::uses('File','Utility');
App::uses('CakeS3.CakeS3','Controller/Component'); 
class S3Shell extends AppShell {
public $uses = array('Upload', 'User', 'Comment');


public function main() {

    $this->CakeS3 = new CakeS3.CakeS3(
     array(
        's3Key' =>  'key',        
        's3Secret' => 'key',      
        'bucket' => 'bucket')

    ); 
    $this->out('Hello world.');
    $this->CakeS3->permission('private');
    $response = $this->CakeS3->putObject(WWW_ROOT . '/file.type' , 'file.type', $this->CakeS3->permission('private'));
                    if ($response ==  false){
                    echo "it failed";
                    } else {
                    echo "it worked"; 
                    }
}

This returns an error of "Fatal error: Class 'CakeS3' not found in /home/app/Console/Command/S3Shell.php. The main reason I am trying to get this to work is so I can automate some uploads with a cron. Of course, if there is a better way, I am all ears.

Community
  • 1
  • 1
MrSynAckSter
  • 1,681
  • 1
  • 18
  • 34

3 Answers3

1

Forgive me this "advertising"... ;) but my plugin is probably better written and has a better architecture than this CakeS3 plugin if it is using a component which should be a model or behaviour task. Also it was made for exactly the use case you have. Plus it supports a few more storage systems than only S3.

You could do that for example in your shell:

StorageManager::adapter('S3')->write($key, StorageManager::adapter('Local')->read($key));

A file should be handled as an entity on its own that is associated to whatever it needs to be associated to. Every uploaded file (if you use or extend the models that come with the plugin, if not you have to take care of that) is stored as a single database entry that contains the name of the config that was used and some meta data for that file. If you do the line of code above in your shell you will have to keep record in the table if you want to access it this way later. Just check the examples in the readme.md out. You don't have to use the database table as a reference to your files but I really recommend the system the plugin implements.

Also, you might not be aware that WWW_ROOT is public accessible, so in the case you store sensitive data there it can be accessed publicly.

And finally in a shell you should not use echo but $this->out() for proper shell output.

floriank
  • 25,546
  • 9
  • 42
  • 66
  • Do you have any suggestions for getting the current plugin working? I might add yours, but I already have a significant amount of code within the main part of my app that uses the plugin for the question. I'll give yours a try if need be, but I feel kind of weird having two plugins that do the same thing in one app. – MrSynAckSter Jul 12 '13 at 21:07
0

I think the App:uses should look like:

App::uses('CakeS3', 'CakeS3.Controller/Component');
tersmitten
  • 1,310
  • 1
  • 9
  • 23
0

I'm the author of CakeS3, and no I'm afraid there is no "supported" way to do this as when we built this plugin, we didn't need to run uploads from shell and just needed a simple interface to S3 from our controllers. We then open sourced the plugin as a simple S3 connector.

If you'd like to have a go at modifying it to support shell access, I'd welcome a PR.

I don't have a particular road map for the plugin, so I've tagged your issue on github as an enhancement and will certainly consider it in future development, but I can't guarantee that it would fit your time requirements so that's why I mention you doing a PR.

fullybaked
  • 4,117
  • 1
  • 24
  • 37