Login   Register  
PHP Classes
elePHPant
Icontem

File: ExtDirectApp.php

Recommend this page to a friend!
Stumble It! Stumble It! Bookmark in del.icio.us Bookmark in del.icio.us
  Classes of Joćo Bruni  >  Ext Direct App  >  ExtDirectApp.php  >  Download  
File: ExtDirectApp.php
Role: Class source
Content type: text/plain
Description: Required file, containing all necessary classes for ExtDirectApp
Class: Ext Direct App
Call PHP classes from Javascript using ExtJS
Author: By
Last change:
Date: 4 years ago
Size: 8,344 bytes
 

Contents

Class file image Download
<?php

/**
 * Process Ext.Direct HTTP requests
 * 
 * @author jbruni
 *
 */
class ExtDirectRequest
{
    
/**
     * @var array   Actions to be executed in this request
     */
    
public $actions = array();
    
    
/**
     * @var string   Name of the API class (ExtDirectActions descendant) 
     */
    
public $actions_class;
    
    
/**
     * @param string $actions_class   Name of the API class (ExtDirectActions descendant)
     */
    
public function __construct$actions_class )
    {
        
$this->actions_class $actions_class;
        
        if ( isset( 
$_POST['extAction'] ) )
            
$this->getFormAction();
        else
            
$this->getRequestActions();
    }
    
    
/**
     * Instantiate actions to be executed in this request using "extAction" (form)
     */
    
protected function getFormAction()
    {
        
$extParameters $_POST;
        foreach( array( 
'extAction''extMethod''extTID''extUpload' ) as $variable )
        {
            if ( !isset( 
$extParameters[$variable] ) )
                $
$variable '';
            else
            {
                $
$variable $extParameters[$variable];
                unset( 
$extParameters[$variable] );
            }
        }
        
$this->actions[] = new $this->actions_class$extAction$extMethod$extParameters$extTID$extUpload );
    }
    
    
/**
     * Instantiate actions to be executed in this request (without "extAction")
     */
    
protected function getRequestActions()
    {
        
$input file_get_contents'php://input' );
        
        
$request json_decode$input );
        
        if ( !
is_array$request ) )
            
$request = array( $request );
        
        foreach( 
$request as $rpc )
        {
            foreach( array( 
'type''action''method''data''tid' ) as $variable )
                $
$variable = ( isset( $rpc->$variable ) ? $rpc->$variable '' );
            if ( 
$type == 'rpc' )
                
$this->actions[] = new $this->actions_class$action$method$data$tidfalse );
        }
    }
}

/**
 * Store HTTP response contents for output
 * 
 * @author jbruni
 *
 */
class ExtDirectResponse
{
    
/**
     * @var array   HTTP headers to be sent in the response
     */
    
public $headers = array();
    
    
/**
     * @var content   HTTP body to be sent in the response
     */
    
public $content '';
}

/**
 * Ext.Direct API controller
 * 
 * @author jbruni
 *
 */
class ExtDirectController
{
    
/**
     * @var string   Name of the API class (ExtDirectActions descendant)
     */
    
public $actions_class;
    
    
/**
     * @var ExtDirectRequest   Object to process HTTP request
     */
    
public $request;
    
    
/**
     * @var ExtDirectResponse   Object to store HTTP response
     */
    
public $response;
    
    
/**
     * @var string   Filename of Javascript template file
     */
    
public $template_file 'app.js';
    
    
/**
     * @var array   Contents of the template elements
     */
    
public $template_elements = array();
    
    
/**
     * @param string $actions_class   Name of the API class (ExtDirectActions descendant)
     * @param boolean $autorun   If true, automatically run the controller
     */
    
public function __construct$actions_class$autorun true )
    {
        
$this->actions_class $actions_class
        
$this->request   = new ExtDirectRequest$this->actions_class );
        
$this->response  = new ExtDirectResponse();
        
        if ( 
$autorun )
        {
            
$this->run();
            
$this->output();
            exit();
        }
    }
    
    
/**
     * @return string   Parsed Javascript template, including the API declaration of the class (Ext.Direct.Provider object actions configuration)
     */
    
public function getJavascript()
    {
        
$template file_get_contents$this->template_file );
        
$this->template_elements['[%actions%]'] = $this->getActionsAPI$this->actions_class );
        return 
strtr$template$this->template_elements );
    }
    
    
/**
     * @param string $class   Name of the API class (ExtDirectActions descendant)
     * @return string   API declaration of the class (Ext.Direct.Provider object "actions" configuration)
     */
    
protected function getActionsAPI$actions_class )
    {
        
$methods = array();
        
$reflection = new ReflectionClass$actions_class );
        foreach( 
$reflection->getMethods() as $method )
            if ( 
$method->isPublic() && ( $method->getDeclaringClass()->name == $actions_class ) )
                
$methods[] = array( 'name' => $method->getName(), 'len' => $method->getNumberOfRequiredParameters() );
        return 
json_encode$methods );
    }
    
    
/**
     * Process the request, execute the actions, and generate the response
     */
    
public function run()
    {
        if ( empty( 
$this->request->actions ) )
            
$this->response->content $this->getJavascript();
        
        else
        {
            
$response = array();
            foreach( 
$this->request->actions as $action )
                
$response[] = $action->run();
            
            if ( 
count$response ) > )
                
$this->response->content utf8_encodejson_encode$response ) );
            else
                
$this->response->content utf8_encodejson_encode$response[0] ) );
        }
        
        
$this->response->headers[] = 'Content-Type: text/javascript';
    }
    
    
/**
     * Output response contents
     */
    
public function output()
    {
        foreach( 
$this->response->headers as $header )
            
header$header );
        
        echo 
$this->response->content;
    }
}

/**
 * Base class for Ext.Direct APIs
 * 
 * @author jbruni
 *
 */
abstract class ExtDirectActions
{
    
/**
     * @var string   Class name
     */
    
    
public $action;
    
    
/**
     * @var string   Method name
     */
    
public $method;
    
    
/**
     * @var mixed   Method parameters
     */
    
public $parameters;
    
    
/**
     * @var integer   Unique identifier for the transaction
     */
    
public $transaction_id;
    
    
/**
     * @var boolean   True if there is a file upload; false otherwise
     */
    
public $upload false;
    
    
/**
     * @var boolean   Set this to true to allow exception detailed information in the output
     */
    
public $debug  false;
    
    
/**
     * @param string $action   Class name
     * @param string $method   Method name
     * @param mixed $parameters   Method parameters
     * @param integer $transaction_id   Unique identifier for the transaction
     * @param boolean $upload   True if there is a file upload; false otherwise
     * @param boolean $debug   Set this to true to allow exception detailed information in the output
     */
    
final public function __construct$action$method$parameters$transaction_id$upload false$debug null )
    {
        foreach( array( 
'action''method''parameters''transaction_id''upload''debug' ) as $parameter )
            
$this->$parameter = $$parameter;
    }
    
    
/**
     * @return array   Result of the action execution
     */
    
public function run()
    {
        
$response = array(
            
'type'    => 'rpc',
            
'tid'     => $this->transaction_id,
            
'action'  => get_class$this ),
            
'method'  => $this->method
        
);
        
        try
        {
            
$result $this->callAction();
            
$response['result'] = $result;
        }
        
        catch ( 
Exception $e )
        {
            
$response['result'] = 'Failure';
            if ( 
$this->debug )
                
$response = array(
                    
'type'    => 'exception',
                    
'tid'     => $this->transaction_id,
                    
'message' => $e->getMessage(),
                    
'where'   => $e->getTraceAsString()
                );
        }
        
        
array_walk_recursive$response, array( $this'utf8_encode' ) );
        
        return 
$response;
    }
    
    
/**
     * @param mixed $value   If it is a string, it will be UTF8 encoded
     * @param mixed $key   Not used (passed by "array_walk_recursive" function)
     * @return mixed   UTF8 encoded string, or unchanged value if not a string
     */
    
protected function &utf8_encode( &$value$key )
    {
        if ( 
is_string$value ) )
            
$value utf8_encode$value );
        return 
$value;
    }
    
    
/**
     * @return mixed   Result of the action
     */
    
protected function callAction()
    {
        
$class get_class$this );
        
        if ( 
$this->action != $class )
            throw new 
Exception'Only calls to ' $class ' are allowed; tried to call ' $this->actionE_USER_ERROR );
        
        if ( !
method_exists$class$this->method ) )
            throw new 
Exception'Call to undefined or not allowed ' $class ' method ' $this->methodE_USER_ERROR );
        
        
$method = new ReflectionMethod$class$this->method );
        
$params $method->getNumberOfRequiredParameters();
        if ( 
count$this->parameters ) < $params )
            throw new 
Exception'Call to ' $class ' method ' $this->method ' needs at least ' $params ' parameters'E_USER_ERROR );
        
        return 
call_user_func_array( array( $this$this->method ), $this->parameters );
    }
}

?>