1. #1
    Sencha User willf1976's Avatar
    Join Date
    May 2009
    Location
    carpinteria, ca
    Posts
    84
    Vote Rating
    0
    willf1976 is on a distinguished road

      0  

    Default Zend Framework Ext.Direct implementation

    Zend Framework Ext.Direct implementation


    Hi All


    I have been going through the classes we have developed over the last few years and sharing back with the community some of them that I think will be useful to others.


    Our application is very heavily ext direct based. We liked the php ext direct implantation created by TommyMaintz (http://www.sencha.com/forum/showthre...ation&p=331128) so we re purposed it to work with our Zend Framework implementation. Please see this thread for more documentation.


    Our controller class automatically generates an Ext.ss.APIDesc object based on the exposed controller actions with in each class that is then used by Ext.Direct.addProvider to expose these direct methods to javascript.


    This means that any views associated with a controller that extends Zend_Controller_Action_Direct will have it's actions that have been tagged as @remotable exposed automatically as direct methods for ext to access via javascript space.


    All methods exposed in this way can also be access via post methods which our code automatically translates into direct methods.


    To use this post functionality just call the post method of your controller submitting a value of: "postAction". The postAction should be name of the method on the controller you wish to invoke as if it were being called through ext direct. This will allow you to expose your direct methods as api calls for other web services to interface with.


    We also use optional functionality to pass log in credentials with these post requests but you will need to extend our class to make this work with your own implementation.


    This project has a few proprietary pieces of code in it which are isolated into methods that 3rd parties may extend for their own purposes. Some our proprietary code was left in place commented out to give the reader an idea of how they may want to extend these methods.


    To make your own implementation of this code be sure you extend and override, or replace the following methods for our own purposes:


    Zend_Controller_Action_Helper_Abstract_Direct_Router::handleMethodException
    Zend_Controller_Action_Helper_Abstract_Direct_Router::handleOtherException
    Zend_Controller_Action_Helper_Abstract_Direct_Router::isAllowed
    Zend_Controller_Action_Direct::login


    You also will need to define a constant that our code uses to find where modules directory is: MODULES_SOURCE. this is referenced in the following places: Zend_Controller_Action_Direct::init, Zend_Controller_Action_Helper_Abstract_Direct_Api::getClassPath


    Attached file contains the following classes:


    Zend_Controller_Action_Helper_Abstract_Direct_Api -- the helper by our controller class
    Zend_Controller_Action_Helper_Abstract_Direct_BogusAction -- used by the direct implementation
    Zend_Controller_Action_Helper_Abstract_Direct_Cache -- used by the direct implementation
    Zend_Controller_Action_Helper_Abstract_Direct_Router -- used by the direct implementation
    Zend_Controller_Action_Direct -- the controller class that your controllers should extend to allow their remotable actions to be automatically exposed


    Make sure to bootstrap in the helper -- in your bootstrap file:


    Code:
    protected function _initZendDirectApi()
        {
    
    
            $zendDirectApi = new Zend_Controller_Action_Helper_Abstract_Direct_Api();
            Zend_Controller_Action_HelperBroker::addHelper($zendDirectApi);
    }

    Here is the layout code that is referenced in our code -- place in your layouts folder:


    direct.phtml:
    Code:
    <?php
    /**
     * @author Will Ferrer, Ethan Brooks
     * @copyright (c) 2012, Intellectual Property Private Equity Group
     *  @licensee 2012 developed under license for Switchsoft LLC  http://www.switchsoft.com a "Direct response telephony company" as part  of it's "VOIP Call distribution, ROI analysis platform, call recording,  and IVR for inbound and outbound sales" and Run the Business Systems LLC  a "Technology development investment group" as part of it's "PHP,  Javascript rapid application development framework and MySQL analysis  tools"
     * @license licensed under the terms of
     * the Open Source LGPL 3.0 license.  Commercial use is permitted to the extent
     * that the code/component(s) do NOT become part of another Open
    Source or Commercially
     * licensed development library or toolkit without explicit permission.
     * <p>License details: <a href="http://www.gnu.org/licenses/lgpl.html"
     * target="_blank">http://www.gnu.org/licenses/lgpl.html</a></p>
    * We are pretty nice just ask. We want to meet our licensees
    */
    echo $this->response;
    ?>

    Be sure that your view or layout files include the ext direct api actions generated by our controller class (apiJS is populated by our controller class but you need to put in your views / layouts yourself)


    Code:
    <?php
    echo "<script>".$this->apiJS."</script>";
    ?>



    Finally, we also use the class in thread below to show and hide a loading mask for direct calls and display exceptions to the user (if configured to allow it):


    http://www.sencha.com/forum/showthread.php?253464


    I have tried to modify our live code to be consumable and ready for extension but I may have missed or bumped something in the process, please let me know if you find any problems with the attached code.


    Best regards


    Will Ferrer (Run the Business)
    Attached Files
    Last edited by willf1976; 18 Jan 2013 at 11:31 AM. Reason: Made title more descriptive

  2. #2
    Sencha - Senior Forum Manager mitchellsimoens's Avatar
    Join Date
    Mar 2007
    Location
    Gainesville, FL
    Posts
    37,065
    Vote Rating
    851
    mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute

      0  

    Default


    Thanks for the contribution!
    Mitchell Simoens @SenchaMitch
    Sencha Inc, Senior Forum Manager
    ________________
    Check out my GitHub, lots of nice things for Ext JS 4 and Sencha Touch 2
    https://github.com/mitchellsimoens

    Think my support is good? Get more personalized support via a support subscription. https://www.sencha.com/store/

    Need more help with your app? Hire Sencha Services services@sencha.com

    Want to learn Sencha Touch 2? Check out Sencha Touch in Action that is in print!

    When posting code, please use BBCode's CODE tags.

  3. #3
    Sencha User willf1976's Avatar
    Join Date
    May 2009
    Location
    carpinteria, ca
    Posts
    84
    Vote Rating
    0
    willf1976 is on a distinguished road

      0  

    Default


    Thank you very Mitchell. I hope some folks find these components handy.

    I hope you have a great day.

    Best regards

    Will Ferrer

  4. #4
    Sencha User demon222's Avatar
    Join Date
    Jan 2008
    Location
    Poland, Warsaw
    Posts
    133
    Vote Rating
    4
    demon222 is on a distinguished road

      0  

    Default


    Hi,
    Can you give examples of the use of controllers?

    and since then have been some updates to the code?

    Regards
    Radek

  5. #5
    Sencha User willf1976's Avatar
    Join Date
    May 2009
    Location
    carpinteria, ca
    Posts
    84
    Vote Rating
    0
    willf1976 is on a distinguished road

      0  

    Default


    Hi Radek

    Here is an example controller using our direct implementation -- this is a trimmed version of the index controller we use for our log in page. I am including it only for illustration, I doubt any of it's methods would be useful any one else's code.:

    Code:
    <?php
    /**
     * RTB
     *
     * LICENSE
     *
     * All rights restricted
     *
     * @category   Rtb
     * @package    Rtb_Default
     * @author     Will Ferrer
    
     * @copyright  Copyright (c) 2010 Intellectual Property Private Equity Group
     * @license    All rights restricted
     * @version    1.0-beta
     */
    
    class Default_IndexController extends Zend_Controller_Action_Direct implements Zend_Auth_Adapter_Interface{
        /**
         * displays login page or redirects to portal if user is logged in.
         * @return void
         */
        public function indexAction() {
          $auth = Zend_Auth::getInstance();
            if ($auth->hasIdentity()) {
                $this->_helper->redirector('reader', 'event');
            }
    
        }
    
        /**
         * logs the user in using Zend_Auth
         * @return array
         * @remotable
         * @formHandler
         */
        public function loginDirectAction() {
            $req = $this->getRequest();
            $username = $req->getParam('username');
            $password = $req->getParam('password');
            $roleid = $req->getParam('roleid');
            $groupid = $req->getParam('groupid');
    
            $timezone = $req->getParam('timezone');
            $locale = $req->getParam('locale');
    
            $result = Rtb_Auth::fullLogin($username, $password, $roleid, $groupid, $timezone, $locale);
            if ($result && $result->isValid()){
                return array('success'=>true);
            } else {
                $messages = $result->getMessages();
                return array('success'=>false, 'message'=>$messages[0]);
            }
        }
    
        /**
         * logs out the currently logged in user via direct
         * @remotable
         * @formHandler
         */
        public function logoutDirectAction()
        {
            Zend_Auth::getInstance()->clearIdentity();
            return array('success'=>true);
    
            $this->_helper->redirector('file'/*, 'example'*/);
        }
    
    
    
        /**
         * function used by zends innerworkings because this class extends Zend_Auth_Adapter_Interface.
         * @return Zend_Auth_Result
         */
        public function authenticate()
        {
            $req = $this->getRequest();
            $username = $req->getParam('username');
            $password = $req->getParam('password');
            $roleid = $req->getParam('roleid');
            $groupid = $req->getParam('groupid');
            $roleid = $req->getParam('roleid');
            $groupid = $req->getParam('groupid');
    
            $timezone = $req->getParam('timezone');
            $locale = $req->getParam('locale');
    
    
            $result = Default_Models_Auth::login($username, $password, $roleid, $groupid, $timezone, $locale);
            return $result;
        }
    }
    
    ?>


    We also found and fixed an issue where the special kinds of exceptions that our code supports for passing messages to the front end user weren't displaying properly in the front end because the TID that the exceptions were a response to were being lost.

    The fix is included in the attached file and below is a diff to illustrate the change.

    Code:
    ... | ...
    271 | 271 try {
    272 | 272 $response['result'] = call_user_func_array(array($instance, $serverMethod), $params);
    273 | 273 } catch(Exception $e) {
    274 | - $response = $this->handleMethodException($e);
    | 274 + $response = $this->handleMethodException($e, $cdata);
    275 | 275 }
    276 | 276 } catch(Exception $e) {
    277 | - $response = $this->handleOtherException($e);
    | 277 + $response = $this->handleOtherException($e, $cdata);
    278 | 278 }
    279 | 279
    280 | 280 return $response;
    ... | ...
    283 | 283 /**
    284 | 284 * handles exceptions from direct method call, we catch specific types of exceptions here that can be shown to end users. 3rd parties will need to extend this method for their own purposes
    285 | 285 * @param Exception $e
    | 286 + * @param object $cdata
    286 | 287 * @return mixed
    287 | 288 */
    288 | - protected function handleMethodException($e) {
    | 289 + protected function handleMethodException($e, $cdata) {
    289 | 290 try {
    290 | 291 throw $e;
    291 | 292 } catch(Default_Exception_UserReadableError $e) {
    292 | 293 $response = array(
    293 | - 'success' => false,
    294 | - 'type' => 'rpc',
    295 | - 'tid' => $cdata->tid,
    296 | - 'result'=> array(
    297 | - 'message' => $e->getMessage(),
    298 | - 'exceptionType' => 'Default_Exception_UserReadableError'
    299 | - )
    | 294 + 'success' => false,
    | 295 + 'type' => 'rpc',
    | 296 + 'tid' => $cdata->tid,
    | 297 + 'result'=> array(
    | 298 + 'message' => $e->getMessage(),
    | 299 + 'exceptionType' => 'Default_Exception_UserReadableError'
    | 300 + )
    300 | 301 );
    301 | 302 if (ini_get('display_errors')) {
    302 | 303 $response['result']['where'] = $e->getTraceAsString();
    ... | ...
    307 | 308 Zend_Registry::get('errorLogger')->ERR($e);
    308 | 309 } catch(Default_Exception_UserReadable $e) {
    309 | 310 $response = array(
    310 | - 'success' => false,
    311 | - 'type' => 'rpc',
    312 | - 'tid' => $cdata->tid,
    313 | - 'result'=> array(
    314 | - 'message' => $e->getMessage(),
    315 | - 'exceptionType' => 'Default_Exception_UserReadable'
    316 | - )
    | 311 + 'success' => false,
    | 312 + 'type' => 'rpc',
    | 313 + 'tid' => $cdata->tid,
    | 314 + 'result'=> array(
    | 315 + 'message' => $e->getMessage(),
    | 316 + 'exceptionType' => 'Default_Exception_UserReadable'
    | 317 + )
    317 | 318 );
    318 | 319 if (ini_get('display_errors')) {
    319 | 320 $response['result']['where'] = $e->getTraceAsString();
    320 | 321 }
    321 | 322 } catch(Default_Exception_UserConfirmation $e) {
    322 | 323 $response = array(
    323 | - 'success' => false,
    324 | - 'type' => 'rpc',
    325 | - 'tid' => $cdata->tid,
    326 | - 'result'=> array(
    327 | - 'message' => $e->getMessage(),
    328 | - 'exceptionType' => 'Default_Exception_UserConfirmation'
    329 | - )
    | 324 + 'success' => false,
    | 325 + 'type' => 'rpc',
    | 326 + 'tid' => $cdata->tid,
    | 327 + 'result'=> array(
    | 328 + 'message' => $e->getMessage(),
    | 329 + 'exceptionType' => 'Default_Exception_UserConfirmation'
    | 330 + )
    330 | 331 );
    331 | 332 }
    332 | 333 return $response;

    I hope that helps.

    All the best.

    Will Ferrer

    Quote Originally Posted by demon222 View Post
    Hi,
    Quote Originally Posted by demon222 View Post
    Can you give examples of the use of controllers?

    and since then have been some updates to the code?

    Regards
    Radek
    On Wed, Nov 6, 2013 at 5:19 AM, Sencha Forum <no-reply@sencha.com> wrote:
    > Dear willf1976,
    >
    > demon222 has just replied to a thread you have subscribed to entitled - Zend Framework Ext.Direct implementation - in the Ext.Direct forum of Sencha Forum.
    >
    > This thread is located at:
    > http://www.sencha.com/forum/showthre...n&goto=newpost
    >
    > Here is the message that has just been posted:
    > ***************
    > Hi,
    > Can you give examples of the use of controllers?
    >
    > and since then have been some updates to the code?
    >
    > Regards
    > Radek
    > ***************
    >
    >
    > There may also be other replies, but you will not receive any more notifications until you visit the forum again.
    >
    > All the best,
    > Sencha Forum
    >
    > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    > Unsubscription information:
    >
    > To unsubscribe from this thread, please visit this page:
    > http://www.sencha.com/forum/subscrip...9b737dc4ecab01
    >
    > To unsubscribe from ALL threads, please visit this page:
    > http://www.sencha.com/forum/subscrip...n&folderid=all
    Attached Files

  6. #6
    Sencha User demon222's Avatar
    Join Date
    Jan 2008
    Location
    Poland, Warsaw
    Posts
    133
    Vote Rating
    4
    demon222 is on a distinguished road

      0  

    Default


    Thank you.

    I understand that it is a zip file with the latest changes. I need a simple controller with examples of actions.

    I see that you are creating RTB systems. Are you creating the systems of Recommendation?

    Regards
    Radek

Thread Participants: 2

Tags for this Thread