Source

YiiFileManagerRemote /

Filename Size Date modified Message
templates
14 B
751 B
1.4 KB
6.7 KB
6.9 KB
4.4 KB
832 B

YII FILE MANAGER REMOTE

This class help us in receiving incoming data sent to a given URL driving it to a given instance into a class, it serves as an incoming entry point for remote messages.

As an example:

[a remote computer]
    [send a "message" via CURL POST to a given "URL"+"uid=123456"]

[the yii application]
    receive the "message" and send to a predefined class instance 
    previously associated to the UID provided in the URL.
  1. The URL is created by a know user by using an API, this URL is attached to a CLASSNAME and IDENTITY (ie: model->primarykey). Next the user can enable or disable the URL at any moment without deleting it, inclusive it is possible to specify some valid IP addresses to be allowed to connect from.

  2. The UID specified in the URL is crc32 hashed, so it is short. An example URL could be:

    http://myapp.com/incomingmessage/da73a857   (if you are using rewrite rules)
    or
    http://myapp.com/index.php?r=/somecontroller/incoming&uid=da73a857
    
  3. When a remote user perform a POST into this URL and (a) when this URL is enabled in the server side and (b) the remote IP address match the IP rules provided by the serverside creator then the message reach the instance associated to this UID.

  4. Every post sent to this URL is saved as a local file into the server, ofcourse you are always enabled to control it via method overrides of the action class.

  5. To handle the sent files you must use the YiiFileManager extension, this is because it provides a framework to do so. Anyway via overrides you can avoid it.

After all, your given classname and identity will receive a message in a safe way.

Dependencies

  1. (required) Install and get working "Yiifilemanager extension".

  2. (required) Install the provided SQL script. (see package, mysql)

  3. (optional) To manage file online install "Yiifilemanagerfilepicker extension".

Usage

  1. clone it from bitbucket into your 'protected/extensions' directory.

  2. Register this extension in your imports:

    'import'=>array(
        'application.models.*',
        'application.components.*',
        'application.extensions.yiifilemanager.*',          // required
        'application.extensions.yiifilemanagerfilepicker.*',//if youre using it
        'application.extensions.yiifilemanagerremote.*',    // required
    ),
    
  3. Copy the provided template from

    '../extensions/yiifilemanagerremote/templates/MyIncomingDataAction.php' 
    to
    'protected/components/MyIncomingDataAction.php'
    
  4. Edit the 'application/components/MyIncomingDataAction.php' class to feet your needs, pay attention to:

    class MyIncomingDataAction 
        extends YiiFileManagerAbstractAction 
            implements IYiiFileManagerAction {
        public function getDb(){
            return Yii::app()->db;
        }
        public function getFilemanager(){
            return Yii::app()->fileman; 
        }
    }
    
    // getFileManager returns Yii::app()->fileman because
    // you have this configuration for yiifilemanager component:
    'components'=>array(
        'fileman' => array(
            'class'=>'application.extensions.yiifilemanager.YiiDiskFileManager',
            'storage_path' => "/var/tmp/fileman",
    ),
    
  5. Register the action into any controller:

    class SiteController extends Controller
    {
        public function actions()
        {
            return array(
                'incoming'=>array(
                    'class'=>'application.components.MyIncomingDataAction',
                ),
            );
        }
    }
    
  6. You are required to create a URL for a given CLASSNAME and IDENTITY (this will be the Listener in your app, per instance), you can do so by using the provided API:

    // suppose you want to receive data for a given object instance, so all
    // incoming data received using from this remote interface will be 
    // stored in the model's file space. (see yiifilemanager extension)
    // 
    $model = SomeClassName::model()->findByPk('123');
    //
    $api = new YiiFileManagerRemoteApi();
    $CRC32_UID = $api->newListener("SomeClassName","123");
    $URL = CHtml::normalizeUrl(array('/site/incoming','uid'=>$CRC32_UID));
    // it will say:
    //  http://mysite.com/index.php?r=site/incoming&uid=ac92cf3ca
    echo "Dear user, send a POST['content']='hello world' to this URL: ".$URL;
    // please note we are not using the $model instance here, it is
    // in this document only as a reference in help to clarify the idea.
    // in place of it we are using the model primarykey and the model class
    
  7. When some one uses this URL to send messages to you then it will be received in the "SomeClassName" only if:

    7.1 the URL is enabled. (check the enabled attribute in the db table) 7.2 the source ipaddress is allowed to send messages. 7.3 the "SomeClassName" implements "IYiiFileManagerListener"

  8. Data reception is:

    class SomeClassName
        implements IYiiFileManagerListener {
    
        public function yiiFileManagerRemote_onDataArrival(
                $identity, $file_id){
    
            //  you can use the $identity to findout the right              
            //  instance:
            $model = SomeClassName::model()->findByPk($instance);
    
            $message = Yii::app()->fileman->read_file($identity, $file_id);
            echo "My message (or file content) is: ".$message;
        }
    }
    

Transaction

When a message or file is sent via POST from a client connection it will be usefull if this client is enabled to create a transactionID to identity the request, in this way the client will know if the data was successfully received by the remote endpoint.

As an example:

client create tid=123
    send data using tid=123
        remote endpoint process and returns result using onSuccess or onError
    read result from endpoint:
        "OK123" (because endpoint call: onSuccess('123'))
    or
        "ER123"

in this way when we are sending data then we are always informed about the transaction result, beacuse many transaction can be made at once.

Handling the transaction ID

a) From the client point of view:

    you send a POST having two fields: "content"=>"bla" and "transid"=>"t1"
    ..send your post using CURL or something else...
    result = (the server response with: OKT1 or ERT1)
    if($result == "OKT1") then done, else? ok..fix and send message again..

b) From the server side point of view

    Your action receive a request, having a $_POST['content'] and $_POST['transid']
    so, let the default implementation do the dirty work, and wait for onSuccess and onError:

    in your own extended class (protected/components/MyIncomingDataAction.php):

        public function onSuccess($transid,$data=null){
            // data is an array containing more info, see the base class action for details.
            echo "OK".$transid;
        }
        public function onError($error, $info="", $transid=""){
            echo "ER".$transid;
            //something goes wrong, must inform error and info ?
        }

Why the default base class YiiFileManagerRemoteAbstractAction does not perform the default "echo" calls ?

--Re: Because you must decide how to implement the protocol, via raw echo, via json via xml ?--