Zend Framework MVC driven ExtJS Thorsten Suckow-Homberg, K&K GmbH         Sourc{ - SenchaDev Conference                  M...
Who am I?●   Thorsten Suckow-Homberg●   Born 1976, Aachen, Germany●   Webdeveloper since 1999●   Senior Software Developer...
Who am I?… oh, and UI programming, of course:Author of:●   conjoon – http://www.conjoon.org●   Ext.ux.Livegrid – http://ww...
This talk will show you...●   … how you should plan your directory layout in    larger projects
This talk will show you...●   … how you should plan your directory layout in    larger projects●   … what is application c...
This talk will show you...●   … how you should plan your directory layout in    larger projects●   … what is application c...
This talk will show you...●   … how you should plan your directory layout in    larger projects●   … what is application c...
The BasicsDirectory Layout
The Basics – Directory Layout               ●   Top level should be a                   directory named after your        ...
The Basics – Directory Layout                   build-tools               ●   Real tools, like:                   ●   yuic...
The Basics – Directory Layout                   build-tools               ●   Real tools, like:                   ●   yuic...
The Basics – Directory Layout                   vendor               ●   All the third party libs                   youre ...
The Basics – Directory Layout                                   vendor                               ●   All the third par...
The Basics – Directory Layout                src
The Basics – Directory Layout                   src               ●   Everything youre actually                   coding
The Basics – Directory Layout                   src               ●   Everything youre actually                   coding: ...
The Basics – Directory Layout                corelib
The Basics – Directory Layout                corelib                ●   js – your client libraries                    (Ext...
The Basics – Directory Layout                corelib                ●   js – your client libraries                    (Ext...
The Basics – Directory Layout                datastore                ●   data storage                    definition/struc...
The Basics – Directory Layout                                 datastore                                  ●   data storage ...
The Basics – Directory Layout                www                ●   one step more towards                    a „callable“ ...
The Basics – Directory Layout                application
The Basics – Directory Layout                application                ●   ZF specific „frontend“                    code...
The Basics – Directory Layout                application                ●   ZF specific „frontend“                    code...
The Basics – Directory Layout                htdocs
The Basics – Directory Layout                htdocs                ●   Finally! The document                    root for y...
The Basics – Directory Layout                                htdocs                                 ●   Finally! The docum...
The Basics – Directory Layout                „This layout gets way too                complex!“                Dont go ber...
The Basics – Directory Layout                „Do I need to run a build                process every time a line           ...
The Basics – Directory Layout working copy (development): /var/www/your_project/vendor/ext-ux-util-messagebus /var/www/you...
The Basics – Directory Layout  working copy (development):  /var/www/your_project/vendor/ext-ux-util-messagebus  /var/www/...
The Basics – Directory Layout  working copy (development):  /var/www/your_project/vendor/ext-ux-util-messagebus  /var/www/...
The Basics – Directory Layout  working copy (development):  /var/www/your_project/vendor/ext-ux-util-messagebus  /var/www/...
The Basics – Directory Layout   working copy (development):   /var/www/your_project/vendor/ext-ux-util-messagebus   /var/w...
The Basics – Directory Layout   working copy (development):   /var/www/your_project/vendor/ext-ux-util-messagebus   /var/w...
The Basics – Directory Layout   working copy (development):   /var/www/your_project/vendor/ext-ux-util-messagebus   /var/w...
The Basics – Directory Layout    Cons●   will need some webserver configuration to get things    working●   build-files de...
The Basics – Directory Layout        Pros    ●   No symlinks –> not f***ing up the repository    ●   Code structured after...
Context based data  What is a „context“?
Context based data             Application Server
Context based data                    Application Server     send/receive    Desktop PC
Context based data                    Application Server     send/receive             send/receive    Desktop PC          ...
Context based data                       Application Server     send/receive                send/receive     Desktop PC   ...
Context based data                       Application Server     send/receive                send/receive     Desktop PC   ...
Context based data  Why do we need it?
Context based data●   Different devices need different views●   Content delivery optimizations●   One domain serves all (w...
Context based data   What do we need?
Context based dataclass Zend_Controller_Action_Helper_ContextSwitch                                       ContextSwitch.php
Context based dataclass Zend_Controller_Action_Helper_ContextSwitch                                                       ...
Context based data   How does it work?
Context based data - detection We can define a context based on (virtually) all data thats available during runtime!
Context based data - detection We can define a context based on (virtually) all data thats available during runtime! For e...
Context based data - detection We can define a context based on (virtually) all data thats available during runtime! For e...
Context based data - detection We can define a context based on (virtually) all data thats available during runtime! For e...
Context based data - detection We can define a context based on (virtually) all data thats available during runtime! For e...
Context based data - detection We can define a context based on (virtually) all data thats available during runtime! For e...
Context based data - detection We can define a context based on (virtually) all data thats available during runtime! For e...
Context based data - detection    We can define a context based on (virtually) all data    thats available during runtime!...
Context based data - detection    We can define a context based on (virtually) all data    thats available during runtime!...
Context based data - detection     We can define a context based on (virtually) all data     thats available during runtim...
Context based dataSo what can it do for me?
Context based data●   Detect devices/users (webbrowser, mobile, bots)
Context based data●   Detect devices/users (webbrowser, mobile, bots)●   One codebase for all devices: „Write once, run   ...
Context based data●   Detect devices/users (webbrowser, mobile, bots)●   One codebase for all devices: „Write once, run   ...
Context based data●   Detect devices/users (webbrowser, mobile, bots)●   One codebase for all devices: „Write once, run   ...
Context based data●   Detect devices/users (webbrowser, mobile, bots)●   One codebase for all devices:„Write once, run    ...
Context based data - example class User_ReceptionController extends Zend_Controller_Action() {     public function init() ...
Context based data - example class User_ReceptionController extends Zend_Controller_Action() {     public function init() ...
Context based data - example class User_ReceptionController extends Zend_Controller_Action() {     public function init() ...
Context based data - example class User_ReceptionController extends Zend_Controller_Action() {     public function init() ...
Context based data - example class User_ReceptionController extends Zend_Controller_Action() {     public function init() ...
Context based data - example class User_ReceptionController extends Zend_Controller_Action() {     public function init() ...
Context based data - example class User_ReceptionController extends Zend_Controller_Action() {     public function init() ...
Context based data - example class User_ReceptionController extends Zend_Controller_Action() {     public function init() ...
Context based data - example class User_ReceptionController extends Zend_Controller_Action() {     public function init() ...
Context based data - example class User_ReceptionController extends Zend_Controller_Action() {     ...     public function...
Context based data - example class User_ReceptionController extends Zend_Controller_Action() {     ...     public function...
Context based data - example class User_ReceptionController extends Zend_Controller_Action() {     ...     public function...
Context based data - example class User_ReceptionController extends Zend_Controller_Action() {     ...     public function...
Context based data - exampleNote●   This illustration explains    how a request gets    processed by Zend    Framework [6]...
Context based data - example                    RequestClient invokes request
Context based data - example                     Request        Router      Zend Framework routes toUser_ReceptionControll...
Context based data - example      Request   Router      pre         Any plugins defined?                         Dispatch ...
Context based data - example      Request   Router      pre                  Any plugins defined?                         ...
Context based data - example      Request   Router      pre         Dispatch the action –                         Dispatch...
Context based data - example      Request   Router      pre                         Dispatch                         Dispa...
Context based data - example      Request   Router      pre                         Dispatch                              ...
Context based data - example      Request   Router      pre                         Dispatch                              ...
Context based data - example      Request        Router          pre                                  Dispatch            ...
Context based data - example      Request        Router          pre                                  Dispatch            ...
Context based data - example      Request   Router      pre                         Dispatch                              ...
Context based data - example                                 Request            Router            pre                     ...
Context based data          AWESOME! This makes coding a real blast!
Skeptikal HippoIt makes sense when working with Ext 1.*   and 2.*, but what about Ext.direct.*?
Ext.direct.*What is Ext.direct.*?
Ext.direct.* „Ext Direct is a platform and language agnostictechnology to remote server-side methods to the               ...
Ext.direct.*●   That new kid in class no one wants to play with
Ext.direct.*●   That new kid in class no one wants to play with    ●   Bugs
Ext.direct.*●   That new kid in class no one wants to play with    ●   Bugs    ●   Clumsy
Ext.direct.*●   That new kid in class no one wants to play with    ●   Bugs    ●   Clumsy    ●   Implementation too complex
Ext.direct.*●   That new kid in class no one wants to play with    ●   Bugs    ●   Clumsy    ●   Implementation too comple...
Ext.direct.*●   That new kid in class no one wants to play with    ●   Bugs    ●   Clumsy    ●   Implementation too comple...
Ext.direct.* - advantages●   Lets you call remote procedures directly from    client code       class User_ReceptionContro...
Ext.direct.* - advantages●   Lets you call remote procedures directly from    client code       class User_ReceptionContro...
Ext.direct.* - advantages●   Lets you call remote procedures directly from    client code       class User_ReceptionContro...
Ext.direct.* - advantages●   Lets you call remote procedures directly from    client code       class User_ReceptionContro...
Ext.direct.* - advantages●   Lets you call remote procedures directly from    client code       class User_ReceptionContro...
Ext.direct.* - advantages●   Can stack remote procedure calls and send    them as one „batched request“      class Groupwa...
Ext.direct.* - advantages●   Can stack remote procedure calls and send    them as one „batched request“      class Groupwa...
Ext.direct.* - advantages●   Can stack remote procedure calls and send    them as one „batched request“      class Groupwa...
Ext.direct.* - advantages●   Can stack remote procedure calls and send    them as one „batched request“      class Groupwa...
Ext.direct.* - advantages●   Can stack remote procedure calls and send    them as one „batched request“      class Groupwa...
Ext.direct.* - advantages●   Can stack remote procedure calls and send    them as one „batched request“      class Groupwa...
Ext.direct.* - advantages●   Can stack remote procedure calls and send    them as one „batched request“      class Groupwa...
Ext.direct.*Batched request – what gives?
Ext.direct.*●   Can reduce serverload (1 request with n calls to    specific actions instead of n calls)
Ext.direct.*●   Can reduce serverload (1 request with n calls to    specific actions instead of n calls)●   Reduces possib...
Ext.direct.*●   Can reduce serverload (1 request with n calls to    specific actions instead of n calls)●   Reduces possib...
Ext.direct.* w/ Zend FrameworkUnfortunately, not supported out of the box :(
Ext.direct.* w/ Zend Framework       … so lets find a solution.       Lets sum up our goals:
Ext.direct.* w/ Zend Framework ●   Switch client code to Ext.direct.* without having to     change backend source code ●  ...
Ext.direct.* w/ Zend Framework ●   Switch client code to Ext.direct.* without having to     change backend source code ●  ...
Ext.direct.* w/ Zend Framework ●   Switch client code to Ext.direct.* without having to     change backend source code ●  ...
Ext.direct.* w/ Zend Framework ●   Switch client code to Ext.direct.* without having to     change backend source code ●  ...
Ext.direct.* w/ Zend Framework        What we need to do:
Ext.direct.* w/ Zend Framework   –   Show requests sent by Ext.direct.* their way through       Zend Framework to their mo...
Ext.direct.* w/ Zend Framework    Change Ext.direct.RemotingProvider             URLs on the fly
Ext.direct.* w/ Zend Framework    Remember?    The Ext.direct.RemotingProvider exposes access to    server side methods on...
Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({    id                : eu.sourcedevcon.provider,    enable...
Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({    id                : eu.sourcedevcon.provider,    enable...
Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({    id                : eu.sourcedevcon.provider,    enable...
Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({    id                : eu.sourcedevcon.provider,    enable...
Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({    id                : eu.sourcedevcon.provider,    enable...
Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({    id                : eu.sourcedevcon.provider,    enable...
Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({    id                : eu.sourcedevcon.provider,    enable...
Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({    id                : eu.sourcedevcon.provider,    enable...
Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({    id                : eu.sourcedevcon.provider,    enable...
Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({    id                : eu.sourcedevcon.provider,    enable...
Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({    id                : eu.sourcedevcon.provider,    enable...
Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({    id                : eu.sourcedevcon.provider,    enable...
Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({    id                : eu.sourcedevcon.provider,    enable...
Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({    id                : eu.sourcedevcon.provider,    enable...
Ext.direct.* w/ Zend Framework  Ext.direct.Manager.addProvider({     id                : eu.sourcedevcon.provider,     ena...
Ext.direct.* w/ Zend Framework  Ext.direct.Manager.addProvider({     id                : eu.sourcedevcon.provider,     ena...
Ext.direct.* w/ Zend Framework  Ext.direct.Manager.addProvider({     id                : eu.sourcedevcon.provider,     ena...
Ext.direct.* w/ Zend Framework  Ext.direct.Manager.addProvider({     id                : eu.sourcedevcon.provider,     ena...
Ext.direct.* w/ Zend Framework  Ext.direct.Manager.addProvider({     id                : eu.sourcedevcon.provider,     ena...
Ext.direct.* w/ Zend Framework  Ext.direct.Manager.addProvider({     id                : eu.sourcedevcon.provider,     ena...
Ext.direct.* w/ Zend Framework  Ext.direct.Manager.addProvider({     id                : eu.sourcedevcon.provider,     ena...
Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({    id                : eu.sourcedevcon.provider,    enable...
Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({    id                : eu.sourcedevcon.provider,    enable...
Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({    id                : eu.sourcedevcon.provider,    enable...
Ext.direct.* w/ Zend FrameworkURL = module   action = controller   method = action                                        ...
Ext.direct.* w/ Zend FrameworkURL = module                            action = controller                    method = acti...
Ext.direct.* w/ Zend FrameworkURL = module                            action = controller                    method = acti...
Ext.direct.* w/ Zend FrameworkURL = module                            action = controller                    method = acti...
Ext.direct.* w/ Zend FrameworkURL = module                            action = controller                    method = acti...
Ext.direct.* w/ Zend FrameworkURL = module                            action = controller                    method = acti...
Ext.direct.* w/ Zend FrameworkURL = module                            action = controller                    method = acti...
Ext.direct.* w/ Zend FrameworkURL = module                            action = controller                     method = act...
Ext.direct.* w/ Zend FrameworkURL = module                            action = controller                    method = acti...
Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({    id                : eu.sourcedevcon.provider,    enable...
Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({    id                : eu.sourcedevcon.provider,    enable...
Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({    id                : eu.sourcedevcon.provider,    enable...
Ext.direct.* w/ Zend Framework POST http://sourcedevcon/groupware/account/get.email.accounts/format/json extDirectData {"a...
Ext.direct.* w/ Zend Framework POST http://sourcedevcon/groupware/account/get.email.accounts/format/json extDirectData {"a...
Ext.direct.* w/ Zend Framework Will do! Let me send a batched request now!
Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({    id                : eu.sourcedevcon.provider,    enable...
Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({    id                : eu.sourcedevcon.provider,    enable...
Ext.direct.* w/ Zend Framework    ...?
Ext.direct.* w/ Zend Framework queueTransaction: function(transaction){         var me = this,             enableBuffer = ...
Ext.direct.* w/ Zend Framework queueTransaction: function(transaction){                        add transaction to callBuff...
Ext.direct.* w/ Zend Framework queueTransaction: function(transaction){                        add transaction to callBuff...
Ext.direct.* w/ Zend Framework queueTransaction: function(transaction){                        add transaction to callBuff...
Ext.direct.* w/ Zend Framework queueTransaction: function(transaction){                        add transaction to callBuff...
Ext.direct.* w/ Zend Frameworkeu.sourcedevcon.provider.account.getEmailAccounts();eu.sourcedevcon.provider.account.getFeed...
Ext.direct.* w/ Zend Frameworkeu.sourcedevcon.provider.account.getEmailAccounts();eu.sourcedevcon.provider.account.getFeed...
Zend Framework MVC driven ExtJS
Zend Framework MVC driven ExtJS
Zend Framework MVC driven ExtJS
Zend Framework MVC driven ExtJS
Zend Framework MVC driven ExtJS
Zend Framework MVC driven ExtJS
Zend Framework MVC driven ExtJS
Zend Framework MVC driven ExtJS
Zend Framework MVC driven ExtJS
Zend Framework MVC driven ExtJS
Zend Framework MVC driven ExtJS
Zend Framework MVC driven ExtJS
Zend Framework MVC driven ExtJS
Zend Framework MVC driven ExtJS
Zend Framework MVC driven ExtJS
Zend Framework MVC driven ExtJS
Zend Framework MVC driven ExtJS
Zend Framework MVC driven ExtJS
Zend Framework MVC driven ExtJS
Zend Framework MVC driven ExtJS
Upcoming SlideShare
Loading in...5
×

Zend Framework MVC driven ExtJS

16,091

Published on

This talk will give attendees details on how to set up their directory layout in larger PHP/ExtJS applications, along with hints to build processing and deployment. In the second part the talk will cover context based applications, how to detect context and how to utilize it with ExtJS. The third and last part will show how developers can use Ext.direct.* with an already existing Zend Framework backend, including merged requests and how to set up sandboxes for processing merged requests.

Published in: Education, Technology
0 Comments
11 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
16,091
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
570
Comments
0
Likes
11
Embeds 0
No embeds

No notes for slide

Zend Framework MVC driven ExtJS

  1. 1. Zend Framework MVC driven ExtJS Thorsten Suckow-Homberg, K&K GmbH Sourc{ - SenchaDev Conference May 5-7, 2011 Croatia, Split
  2. 2. Who am I?● Thorsten Suckow-Homberg● Born 1976, Aachen, Germany● Webdeveloper since 1999● Senior Software Developer for K&K GmbH, Aachen● Focus on planning, architecture and deployment of web based software
  3. 3. Who am I?… oh, and UI programming, of course:Author of:● conjoon – http://www.conjoon.org● Ext.ux.Livegrid – http://www.ext-livegrid.com● various other open source ExtJS extensions/ components● Numerous bug reports, rants and proposals over at the sencha forums :) (MindPatterns)
  4. 4. This talk will show you...● … how you should plan your directory layout in larger projects
  5. 5. This talk will show you...● … how you should plan your directory layout in larger projects● … what is application context - and how to use it to your advantage
  6. 6. This talk will show you...● … how you should plan your directory layout in larger projects● … what is application context - and how to use it to your advantage● … how to use Ext.Direct with existing ZF backend code
  7. 7. This talk will show you...● … how you should plan your directory layout in larger projects● … what is application context - and how to use it to your advantage● … how to use Ext.Direct with existing ZF backend code● In short: ...why Zend Framework could become the framework of your choice when combining Ext and PHP
  8. 8. The BasicsDirectory Layout
  9. 9. The Basics – Directory Layout ● Top level should be a directory named after your project (obviously) ● ...containing three child directories:
  10. 10. The Basics – Directory Layout build-tools ● Real tools, like: ● yuicompressor ● phing ● ant
  11. 11. The Basics – Directory Layout build-tools ● Real tools, like: ● yuicompressor ● phing ● ant ● (XML-)build scripts ● code sanity ● tests ● deployment ● etc... in short: Continuous Integration[1]!
  12. 12. The Basics – Directory Layout vendor ● All the third party libs youre using in your code ● ExtJS ● ZendFramework ● etc.
  13. 13. The Basics – Directory Layout vendor ● All the third party libs youre using in your code ● ExtJS ● ZendFramework ● etc. Note: ● files from separate repository vendor branch will be merged into this directory ● Best case: developers will not touch the vendor directory ● Read [2] for more infos on how to use vendor branches
  14. 14. The Basics – Directory Layout src
  15. 15. The Basics – Directory Layout src ● Everything youre actually coding
  16. 16. The Basics – Directory Layout src ● Everything youre actually coding: ● overrides ● extensions ● backend code ● code that might refer to vendor code ● … in short: all application-specific code your team writes
  17. 17. The Basics – Directory Layout corelib
  18. 18. The Basics – Directory Layout corelib ● js – your client libraries (ExtJS, own implementations)
  19. 19. The Basics – Directory Layout corelib ● js – your client libraries (ExtJS, own implementations) ● php – your backend code (including tests)
  20. 20. The Basics – Directory Layout datastore ● data storage definition/structure goes here
  21. 21. The Basics – Directory Layout datastore ● data storage definition/structure goes here Note: ● build scripts can refer to the structure file when deploying an application
  22. 22. The Basics – Directory Layout www ● one step more towards a „callable“ application
  23. 23. The Basics – Directory Layout application
  24. 24. The Basics – Directory Layout application ● ZF specific „frontend“ code (controllers, templates)
  25. 25. The Basics – Directory Layout application ● ZF specific „frontend“ code (controllers, templates) ● and: – Meta-Information files for your application – caching directories – etc.
  26. 26. The Basics – Directory Layout htdocs
  27. 27. The Basics – Directory Layout htdocs ● Finally! The document root for your application ● the only „public“ folder
  28. 28. The Basics – Directory Layout htdocs ● Finally! The document root for your application ● the only „public“ folder Note: ● Build-process focuses on this folder
  29. 29. The Basics – Directory Layout „This layout gets way too complex!“ Dont go berserk! Theres a solution to all of it!
  30. 30. The Basics – Directory Layout „Do I need to run a build process every time a line of code changed?“ „How do I get the resources from vendor into my src folder where – obviously - running code will resist?“
  31. 31. The Basics – Directory Layout working copy (development): /var/www/your_project/vendor/ext-ux-util-messagebus /var/www/your_project/src/www/htdocs/index.php
  32. 32. The Basics – Directory Layout working copy (development): /var/www/your_project/vendor/ext-ux-util-messagebus /var/www/your_project/src/www/htdocs/index.php<?php if ($isDeployment) { ?> <script type="text/javascript" src="/js/ext-ux-util-messagebus/src/messagebus.js"></script><?php } else { ?> <script type="text/javascript" src="/vendor/ext-ux-util-messagebus/src/messagebus.js"></script><?php } ?> index.phtml
  33. 33. The Basics – Directory Layout working copy (development): /var/www/your_project/vendor/ext-ux-util-messagebus /var/www/your_project/src/www/htdocs/index.php<?php if ($isDeployment) { ?> <script type="text/javascript" src="/js/ext-ux-util-messagebus/src/messagebus.js"></script><?php } else { ?> <script type="text/javascript" src="/vendor/ext-ux-util-messagebus/src/messagebus.js"></script><?php } ?> index.phtml# Alias for Ext.ux.util.MessageBusAlias /js/ext-ux-util-messagebus "/htdocs/your_project/vendor/ext-ux-util-messagebus/src"<Directory "/htdocs/your_project/vendor/ext-ux-util-messagebus/src">Order allow,denyAllow from all</Directory> apache.conf
  34. 34. The Basics – Directory Layout working copy (development): /var/www/your_project/vendor/ext-ux-util-messagebus /var/www/your_project/src/www/htdocs/index.php<?php if ($isDeployment) { ?> <script type="text/javascript" src="/js/ext-ux-util-messagebus/src/messagebus.js"></script><?php } else { ?> <script type="text/javascript" src="/vendor/ext-ux-util-messagebus/src/messagebus.js"></script><?php } ?> index.phtml# Alias for Ext.ux.util.MessageBusAlias /js/ext-ux-util-messagebus "/htdocs/your_project/vendor/ext-ux-util-messagebus/src"<Directory "/htdocs/your_project/vendor/ext-ux-util-messagebus/src">Order allow,denyAllow from all</Directory> apache.conf<script type="text/javascript" src="/js/ext-ux-util-messagebus/src/messagebus.js"></script> index.phtml
  35. 35. The Basics – Directory Layout working copy (development): /var/www/your_project/vendor/ext-ux-util-messagebus /var/www/your_project/src/www/htdocs/index.php # Alias for Ext.ux.util.MessageBusDevelopment: Alias /js/ext-ux-util-messagebus Virtual
  36. 36. The Basics – Directory Layout working copy (development): /var/www/your_project/vendor/ext-ux-util-messagebus /var/www/your_project/src/www/htdocs/index.php # Alias for Ext.ux.util.MessageBusDevelopment: Alias /js/ext-ux-util-messagebus Virtual Build: ... <target name="build_js"> <delete dir="./build/js/ext-ux-util-messagebus" /> <copy todir="./build/js/ext-ux-util-messagebus" includeemptydirs="true"> <fileset dir="./vendor/ext-ux-util-messagebus"> <exclude name="**/.svn" /> </fileset> </copy> </target> ... Build process
  37. 37. The Basics – Directory Layout working copy (development): /var/www/your_project/vendor/ext-ux-util-messagebus /var/www/your_project/src/www/htdocs/index.php # Alias for Ext.ux.util.MessageBusDevelopment: Alias /js/ext-ux-util-messagebus Virtual Build: ... <target name="build_js"> <delete dir="./build/js/ext-ux-util-messagebus" /> <copy todir="./build/js/ext-ux-util-messagebus" includeemptydirs="true"> <fileset dir="./vendor/ext-ux-util-messagebus"> <exclude name="**/.svn" /> </fileset> </copy> </target> ... Build process <script type="text/javascript" src="/js/ext-ux-util-messagebus/src/messagebus.js"></script> index.phtml
  38. 38. The Basics – Directory Layout Cons● will need some webserver configuration to get things working● build-files depend on initial layout, changes mean adjustment at several locations at once● needs documentation for your dev team● users need to know how to set up their dev environment when they check out „including sources“
  39. 39. The Basics – Directory Layout Pros ● No symlinks –> not f***ing up the repository ● Code structured after purpose ● No need to run builds after youve changed one line of code (except for tests, of course) ● Clean approach towards build- and development-code ● Makes build-definitions easy due to strictly defined layout Advice:● Use svn.ignore and template files! - it will help you and youre coworkers to set up things on different machines
  40. 40. Context based data What is a „context“?
  41. 41. Context based data Application Server
  42. 42. Context based data Application Server send/receive Desktop PC
  43. 43. Context based data Application Server send/receive send/receive Desktop PC Mobile
  44. 44. Context based data Application Server send/receive send/receive Desktop PC Mobile Context „default“
  45. 45. Context based data Application Server send/receive send/receive Desktop PC Mobile Context „default“ Context „mobile“
  46. 46. Context based data Why do we need it?
  47. 47. Context based data● Different devices need different views● Content delivery optimizations● One domain serves all (www.senchadevcon.eu vs. m.senchadevcon.eu)● Specific data format (send/receive) might not be available on devices used by our users
  48. 48. Context based data What do we need?
  49. 49. Context based dataclass Zend_Controller_Action_Helper_ContextSwitch ContextSwitch.php
  50. 50. Context based dataclass Zend_Controller_Action_Helper_ContextSwitch ContextSwitch.php ● Action helper that will detect context based requests ● Capable of sending specially formatted responses based on detected context and configuration ● Available as a default action helper provided by Zend Framework ● For more informations on how to use action helper, see [3]
  51. 51. Context based data How does it work?
  52. 52. Context based data - detection We can define a context based on (virtually) all data thats available during runtime!
  53. 53. Context based data - detection We can define a context based on (virtually) all data thats available during runtime! For example: http://myproject.com/user/reception/get.user/format/json url
  54. 54. Context based data - detection We can define a context based on (virtually) all data thats available during runtime! For example: http://myproject.com/user/reception/get.user/format/json url module
  55. 55. Context based data - detection We can define a context based on (virtually) all data thats available during runtime! For example: http://myproject.com/user/reception/get.user/format/json url controller
  56. 56. Context based data - detection We can define a context based on (virtually) all data thats available during runtime! For example: http://myproject.com/user/reception/get.user/format/json url action
  57. 57. Context based data - detection We can define a context based on (virtually) all data thats available during runtime! For example: http://myproject.com/user/reception/get.user/format/json url parameter/value pair
  58. 58. Context based data - detection We can define a context based on (virtually) all data thats available during runtime! For example: http://myproject.com/user/reception/get.user/format/json url $_GET[format] == json
  59. 59. Context based data - detection We can define a context based on (virtually) all data thats available during runtime! For example: http://myproject.com/user/reception/get.user/format/json url $_GET[format] == json● Application is now in „json“ context – i.e., return all responses json formatted, since the client told us so!
  60. 60. Context based data - detection We can define a context based on (virtually) all data thats available during runtime! For example: http://myproject.com/user/reception/get.user/format/json url $_GET[format] == json● Application is now in „json“ context – i.e., return all responses json formatted, since the client told us so!● In fact, this is a default option coming with the ContextSwitch action helper
  61. 61. Context based data - detection We can define a context based on (virtually) all data thats available during runtime! Another example: ... $userAgent = strtolower($_SERVER[HTTP_USER_AGENT]); // request coming from ipad? if (strpos($userAgent, ipad) !== false) { $this->currentContext = ipad; // request coming from android? } else if (strpos($userAgent), android) !== false) { $this->currentContext = android; } ... User Agent ● Context set by detection, not manually enforced by parameters
  62. 62. Context based dataSo what can it do for me?
  63. 63. Context based data● Detect devices/users (webbrowser, mobile, bots)
  64. 64. Context based data● Detect devices/users (webbrowser, mobile, bots)● One codebase for all devices: „Write once, run anywhere“
  65. 65. Context based data● Detect devices/users (webbrowser, mobile, bots)● One codebase for all devices: „Write once, run anywhere“
  66. 66. Context based data● Detect devices/users (webbrowser, mobile, bots)● One codebase for all devices: „Write once, run anywhere“
  67. 67. Context based data● Detect devices/users (webbrowser, mobile, bots)● One codebase for all devices:„Write once, run anywhere“ ● View variables will either be assigned to templates (plain html mixed with PHP for example) or transformed to json (xml etc.) – automatically – no need to implement special logic as long as your client can handle the response ● Requesting different formats is often just a thing of switching a parameter at client site ● Makes even delivering views from the backend very easy! ● Test a context by switching a parameter ● Only views? No, different business logic depending on the context, too!
  68. 68. Context based data - example class User_ReceptionController extends Zend_Controller_Action() { public function init() { // define the actions that should consider different contexts $this->_helper->contextSwitch() ->addActionContext(get.user, json) ->initContext(); } /** * This method will return user data to the client as requested. */ public function getUserAction() { ... $this->view->userName = Peter Griffin; $this->view->userEmail = peter@birdistheword.com; } } ReceptionController.php
  69. 69. Context based data - example class User_ReceptionController extends Zend_Controller_Action() { public function init() { // define the actions that should consider different contexts $this->_helper->contextSwitch() ->addActionContext(get.user, json) implement parents init() method ->initContext(); } to add action contexts... /** * This method will return user data to the client as requested. */ public function getUserAction() { ... $this->view->userName = Peter Griffin; $this->view->userEmail = peter@birdistheword.com; } } ReceptionController.php
  70. 70. Context based data - example class User_ReceptionController extends Zend_Controller_Action() { public function init() { // define the actions that should consider different contexts $this->_helper->contextSwitch() ->addActionContext(get.user, json) ->initContext(); } /** * This method will return user data to the client as requested. ...which happens here: */ public function getUserAction() { ... $this->view->userName = Peter Griffin; $this->view->userEmail = peter@birdistheword.com; } } ReceptionController.php
  71. 71. Context based data - example class User_ReceptionController extends Zend_Controller_Action() { public function init() { // define the actions that should consider different contexts $this->_helper->contextSwitch() ->addActionContext(get.user, json) ->initContext(); } /** * This method will return user data to the client as requested. getUserAction() will now... */ public function getUserAction() { ... $this->view->userName = Peter Griffin; $this->view->userEmail = peter@birdistheword.com; } } ReceptionController.php
  72. 72. Context based data - example class User_ReceptionController extends Zend_Controller_Action() { public function init() { // define the actions that should consider different contexts $this->_helper->contextSwitch() ->addActionContext(get.user, json) ->initContext(); } /** * This method will return user data response json-formatted if … return the to the client as requested. */ the get-Parameter „format“ was set to „json“ public function getUserAction() { ... $this->view->userName = Peter Griffin; $this->view->userEmail = peter@birdistheword.com; } } ReceptionController.php
  73. 73. Context based data - example class User_ReceptionController extends Zend_Controller_Action() { public function init() { // define the actions that should consider different contexts $this->_helper->contextSwitch() ->addActionContext(get.user, json) ->initContext(); } /** * This method will return user data to the client as requested. */ public function getUserAction() { ... $this->view->userName = Peter Griffin; $this->view->userEmail = peter@birdistheword.com; } We have just added an action context to this action } ReceptionController.php
  74. 74. Context based data - example class User_ReceptionController extends Zend_Controller_Action() { public function init() { // define the actions that should consider different contexts $this->_helper->contextSwitch() ->addActionContext(get.user, json) ->initContext(); } /** * This method will return user data to the client as requested. */ public function getUserAction() { ... $this->view->userName = Peter Griffin; $this->view->userEmail = peter@birdistheword.com; } We have just added an action context to this action } ReceptionController.php
  75. 75. Context based data - example class User_ReceptionController extends Zend_Controller_Action() { public function init() { // define the actions that should consider different contexts $this->_helper->contextSwitch() ->addActionContext(get.user, json) ->initContext(); } /** * This method will return user data to the client as requested. */ Call business logic... public function getUserAction() { ... $this->view->userName = Peter Griffin; $this->view->userEmail = peter@birdistheword.com; } } ReceptionController.php
  76. 76. Context based data - example class User_ReceptionController extends Zend_Controller_Action() { public function init() { // define the actions that should consider different contexts $this->_helper->contextSwitch() ->addActionContext(get.user, json) ->initContext(); } /** * This method will return user data to the client as requested. */ And finally: Assign values to the public function getUserAction() controllers view { ... $this->view->userName = Peter Griffin; $this->view->userEmail = peter@birdistheword.com; } } ReceptionController.php
  77. 77. Context based data - example class User_ReceptionController extends Zend_Controller_Action() { ... public function getUserAction() { ... $this->view->userName = Peter Griffin; $this->view->userEmail = peter@birdistheword.com; } } ReceptionController.php Ext.Ajax.request({ url : „/user/reception/get.user/format/json“, success : function(response) { console.log(response.responseText); } }); client.js
  78. 78. Context based data - example class User_ReceptionController extends Zend_Controller_Action() { ... public function getUserAction() { ... $this->view->userName = Peter Griffin; $this->view->userEmail = peter@birdistheword.com; } Module } ReceptionController.php Ext.Ajax.request({ url : „/user/reception/get.user/format/json“, success : function(response) { console.log(response.responseText); } }); client.js
  79. 79. Context based data - example class User_ReceptionController extends Zend_Controller_Action() { ... public function getUserAction() { ... $this->view->userName = Peter Griffin; $this->view->userEmail = peter@birdistheword.com; } Controller } ReceptionController.php Ext.Ajax.request({ url : „/user/reception/get.user/format/json“, success : function(response) { console.log(response.responseText); } }); client.js
  80. 80. Context based data - example class User_ReceptionController extends Zend_Controller_Action() { ... public function getUserAction() { ... $this->view->userName = Peter Griffin; $this->view->userEmail = peter@birdistheword.com; } Action } ReceptionController.php Ext.Ajax.request({ url : „/user/reception/get.user/format/json“, success : function(response) { console.log(response.responseText); } }); client.js
  81. 81. Context based data - exampleNote● This illustration explains how a request gets processed by Zend Framework [6]● Well use it to show how ContextSwitch changes the ResponseObject based on the applications context
  82. 82. Context based data - example RequestClient invokes request
  83. 83. Context based data - example Request Router Zend Framework routes toUser_ReceptionController::getUserAction()
  84. 84. Context based data - example Request Router pre Any plugins defined? Dispatch Signal a preDispatch to them!
  85. 85. Context based data - example Request Router pre Any plugins defined? Dispatch Signal a preDispatch to them! public function preDispatch() { } Zend_Controller_Action_Helper_Abstract
  86. 86. Context based data - example Request Router pre Dispatch the action – Dispatch getUserAction() gets processed! Dispatch
  87. 87. Context based data - example Request Router pre Dispatch Dispatch Action Controller public function getUserAction() { ... $this->view->userName = Peter Griffin; $this->view->userEmail = peter@birdistheword.com; } ReceptionController.php
  88. 88. Context based data - example Request Router pre Dispatch Action Dispatch Controller Any plugins defined? post Signal a postDispatch to them! Dispatch
  89. 89. Context based data - example Request Router pre Dispatch Action Dispatch Controller Any plugins defined? post Signal a postDispatch to them! Dispatch public function postDispatch() { $context = $this->getCurrentContext(); ... //$this->postJsonContext(); } ContextSwitch.php
  90. 90. Context based data - example Request Router pre Dispatch Action Dispatch Controller post Dispatch $response->setHeader(Content-Type, application/json); ContextSwitch.php actions left? Response Object
  91. 91. Context based data - example Request Router pre Dispatch Action Dispatch Controller post Dispatch $response->setHeader(Content-Type, application/json); ContextSwitch.php actions left? $response->setBody(Zend_Json::encode($view->getVars())); ContextSwitch.php Response Object
  92. 92. Context based data - example Request Router pre Dispatch Action Dispatch Controller post Dispatch actions left? send response Response Object
  93. 93. Context based data - example Request Router pre Dispatch Action Dispatch Controller post Dispatch actions left?{userName : „Peter Griffin“, userEmail : „peter@birdistheword.com“} console send response Response Object
  94. 94. Context based data AWESOME! This makes coding a real blast!
  95. 95. Skeptikal HippoIt makes sense when working with Ext 1.* and 2.*, but what about Ext.direct.*?
  96. 96. Ext.direct.*What is Ext.direct.*?
  97. 97. Ext.direct.* „Ext Direct is a platform and language agnostictechnology to remote server-side methods to the client-side.“[4]
  98. 98. Ext.direct.*● That new kid in class no one wants to play with
  99. 99. Ext.direct.*● That new kid in class no one wants to play with ● Bugs
  100. 100. Ext.direct.*● That new kid in class no one wants to play with ● Bugs ● Clumsy
  101. 101. Ext.direct.*● That new kid in class no one wants to play with ● Bugs ● Clumsy ● Implementation too complex
  102. 102. Ext.direct.*● That new kid in class no one wants to play with ● Bugs ● Clumsy ● Implementation too complex ● The bad thing: – Sencha started to focus remote functionality in their library on Ext.direct.* with 3.*
  103. 103. Ext.direct.*● That new kid in class no one wants to play with ● Bugs ● Clumsy ● Implementation too complex ● The bad thing: – Sencha started to focus remote functionality in their library on Ext.direct.* with 3.* ● The good thing: – Sencha eliminated almost all implementation issues
  104. 104. Ext.direct.* - advantages● Lets you call remote procedures directly from client code class User_ReceptionController extends Zend_Controller_Action { public function getUserAction() { ... } } ReceptionController.php
  105. 105. Ext.direct.* - advantages● Lets you call remote procedures directly from client code class User_ReceptionController extends Zend_Controller_Action { public function getUserAction() { ... } } ReceptionController.php user.reception.getUser(); client.js
  106. 106. Ext.direct.* - advantages● Lets you call remote procedures directly from client code class User_ReceptionController extends Zend_Controller_Action { public function getUserAction() { ... } } ReceptionController.php module user.reception.getUser(); client.js
  107. 107. Ext.direct.* - advantages● Lets you call remote procedures directly from client code class User_ReceptionController extends Zend_Controller_Action { public function getUserAction() { ... } } ReceptionController.php controller user.reception.getUser(); client.js
  108. 108. Ext.direct.* - advantages● Lets you call remote procedures directly from client code class User_ReceptionController extends Zend_Controller_Action { public function getUserAction() { ... } } ReceptionController.php action user.reception.getUser(); client.js
  109. 109. Ext.direct.* - advantages● Can stack remote procedure calls and send them as one „batched request“ class Groupware_AccountController extends Zend_Controller_Action { public function getEmailAccountsAction(){ ... } public function getFeedAccountsAction(){ ... } } GroupwareController.php
  110. 110. Ext.direct.* - advantages● Can stack remote procedure calls and send them as one „batched request“ class Groupware_AccountController extends Zend_Controller_Action { public function getEmailAccountsAction(){ ... } public function getFeedAccountsAction(){ ... } } GroupwareController.php groupware.account.getEmailAccounts(); client.js
  111. 111. Ext.direct.* - advantages● Can stack remote procedure calls and send them as one „batched request“ class Groupware_AccountController extends Zend_Controller_Action { public function getEmailAccountsAction(){ ... } public function getFeedAccountsAction(){ ... } } GroupwareController.php groupware.account.getEmailAccounts(); client.js
  112. 112. Ext.direct.* - advantages● Can stack remote procedure calls and send them as one „batched request“ class Groupware_AccountController extends Zend_Controller_Action { public function getEmailAccountsAction(){ ... } public function getFeedAccountsAction(){ ... } } GroupwareController.php groupware.account.getEmailAccounts(); groupware.account.getFeedAccounts(); client.js Firebug
  113. 113. Ext.direct.* - advantages● Can stack remote procedure calls and send them as one „batched request“ class Groupware_AccountController extends Zend_Controller_Action { public function getEmailAccountsAction(){ ... } public function getFeedAccountsAction(){ ... } } GroupwareController.php groupware.account.getEmailAccounts(); groupware.account.getFeedAccounts(); client.js POST http://sourcedevcon/groupware/account/get.email.accounts POST http://sourcedevcon/groupware/account/get.feed.accounts Firebug
  114. 114. Ext.direct.* - advantages● Can stack remote procedure calls and send them as one „batched request“ class Groupware_AccountController extends Zend_Controller_Action { public function getEmailAccountsAction(){ ... } public function getFeedAccountsAction(){ ... } } GroupwareController.php groupware.account.getEmailAccounts(); groupware.account.getFeedAccounts(); client.js POST http://sourcedevcon/groupware/account/get.email.accounts POST http://sourcedevcon/groupware/account/get.feed.accounts Firebug POST http://sourcedevcon/groupware Firebug
  115. 115. Ext.direct.* - advantages● Can stack remote procedure calls and send them as one „batched request“ class Groupware_AccountController extends Zend_Controller_Action { public function getEmailAccountsAction(){ ... } public function getFeedAccountsAction(){ ... } } GroupwareController.php groupware.account.getEmailAccounts(); groupware.account.getFeedAccounts(); client.js POST http://sourcedevcon/groupware/account/get.email.accounts POST http://sourcedevcon/groupware/account/get.feed.accounts Firebug POST http://sourcedevcon/groupware extDirectData [{"action":"account","method":"getEmailAccounts","data":null,"type":"rpc","tid":1}, {"action":"account","method":"getFeedAccounts","data":null,"type":"rpc","tid":2}] Firebug
  116. 116. Ext.direct.*Batched request – what gives?
  117. 117. Ext.direct.*● Can reduce serverload (1 request with n calls to specific actions instead of n calls)
  118. 118. Ext.direct.*● Can reduce serverload (1 request with n calls to specific actions instead of n calls)● Reduces possibility of losing connections (http allows for n concurrent connections to one domain at a time)
  119. 119. Ext.direct.*● Can reduce serverload (1 request with n calls to specific actions instead of n calls)● Reduces possibility of losing connections (http allows for n concurrent connections to one domain at a time) This alone are tremendously important reasons for you to go ahead and make friendship with that new kid in class!
  120. 120. Ext.direct.* w/ Zend FrameworkUnfortunately, not supported out of the box :(
  121. 121. Ext.direct.* w/ Zend Framework … so lets find a solution. Lets sum up our goals:
  122. 122. Ext.direct.* w/ Zend Framework ● Switch client code to Ext.direct.* without having to change backend source code ● Add another tier of complexity and automatically create backend methods/client code. Tests, changing naming conventions etc. have to be added by hand then. ● Keep our backend testable, reusable and make sure it runs with any other client library/ implementation
  123. 123. Ext.direct.* w/ Zend Framework ● Switch client code to Ext.direct.* without having to change backend source code ● Add another tier of complexity and automatically create backend methods/client code. Tests, changing naming conventions etc. have to be added by hand then. ● Keep our backend testable, reusable and make sure it runs with any other client library/ implementation
  124. 124. Ext.direct.* w/ Zend Framework ● Switch client code to Ext.direct.* without having to change backend source code ● Add another tier of complexity and automatically create backend methods/client code. Tests, changing naming conventions etc. have to be added by hand then. ● Keep our backend testable, reusable and make sure it runs with any other client library/ implementation
  125. 125. Ext.direct.* w/ Zend Framework ● Switch client code to Ext.direct.* without having to change backend source code ● Add another tier of complexity and automatically create backend methods/client code. Tests, changing naming conventions etc. have to be added by hand then. ● Keep our backend testable, reusable and make sure it runs with any other client library/ implementation
  126. 126. Ext.direct.* w/ Zend Framework What we need to do:
  127. 127. Ext.direct.* w/ Zend Framework – Show requests sent by Ext.direct.* their way through Zend Framework to their module/controller/action – Teach Zend Framework how to distinguish between old fashioned and merged requests – Show Zend Framework how to disassemble 1 request into n requests – Give Zend Framework a sandbox where it can work/play/you name it with a disamssembled request – Collect sandboxed requests and merge them back into one response
  128. 128. Ext.direct.* w/ Zend Framework Change Ext.direct.RemotingProvider URLs on the fly
  129. 129. Ext.direct.* w/ Zend Framework Remember? The Ext.direct.RemotingProvider exposes access to server side methods on the client. By mapping those remote methods to the client, there is almost no need anymore to spray URLs around the source like crazy. It establishes a connection between the client and the backend by providing a programmer friendly interface.
  130. 130. Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({ id : eu.sourcedevcon.provider, enableUrlEncode : extDirectData, url : ./groupware, format : json, type : zend, actions : { account : [{ name : getFeedAccounts }, { name : getEmailAccounts }] }, namespace : eu.sourcedevcon.provider }); client.js
  131. 131. Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({ id : eu.sourcedevcon.provider, enableUrlEncode : extDirectData, url : ./groupware, URL format : json, type : zend, actions : { account : [{ name : getFeedAccounts }, { name : getEmailAccounts }] }, namespace : eu.sourcedevcon.provider }); client.js
  132. 132. Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({ id : eu.sourcedevcon.provider, enableUrlEncode : extDirectData, url : ./groupware, URL format : json, type : zend, actions : { account : [{ „action“ name : getFeedAccounts }, { name : getEmailAccounts }] }, namespace : eu.sourcedevcon.provider }); client.js
  133. 133. Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({ id : eu.sourcedevcon.provider, enableUrlEncode : extDirectData, url : ./groupware, URL format : json, type : zend, actions : { account : [{ „action“ name : getFeedAccounts }, { name : getEmailAccounts method }] }, namespace : eu.sourcedevcon.provider }); client.js
  134. 134. Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({ id : eu.sourcedevcon.provider, enableUrlEncode : extDirectData, url : ./groupware, format : json, type : zend, actions : { account : [{ name : getFeedAccounts }, { name : getEmailAccounts }] }, namespace : eu.sourcedevcon.provider }); client.jseu.sourcedevcon.provider.account.getEmailAccounts(); client.js
  135. 135. Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({ id : eu.sourcedevcon.provider, enableUrlEncode : extDirectData, url : ./groupware, format : json, type : zend, actions : { account : [{ name : getFeedAccounts }, { name : getEmailAccounts }] }, namespace : eu.sourcedevcon.provider }); namespace client.jseu.sourcedevcon.provider.account.getEmailAccounts(); client.js
  136. 136. Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({ id : eu.sourcedevcon.provider, enableUrlEncode : extDirectData, url : ./groupware, format : json, type : zend, actions : { account : [{ name : getFeedAccounts }, { name : getEmailAccounts }] action }, namespace : eu.sourcedevcon.provider }); client.jseu.sourcedevcon.provider.account.getEmailAccounts(); client.js
  137. 137. Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({ id : eu.sourcedevcon.provider, enableUrlEncode : extDirectData, url : ./groupware, format : json, type : zend, actions : { account : [{ name : getFeedAccounts }, { name : getEmailAccounts }] }, namespace : eu.sourcedevcon.provider method }); client.jseu.sourcedevcon.provider.account.getEmailAccounts(); client.js
  138. 138. Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({ id : eu.sourcedevcon.provider, enableUrlEncode : extDirectData, url : ./groupware, format : json, type : zend, actions : { account : [{ name : getFeedAccounts }, { name : getEmailAccounts }] }, namespace : eu.sourcedevcon.provider }); client.jseu.sourcedevcon.provider.account.getEmailAccounts(); client.js POST http://sourcedevcon/groupware Firebug
  139. 139. Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({ id : eu.sourcedevcon.provider, enableUrlEncode : extDirectData, url : ./groupware, format : json, type : zend, actions : { account : [{ name : getFeedAccounts }, { name : getEmailAccounts }] }, namespace : eu.sourcedevcon.provider }); client.jseu.sourcedevcon.provider.account.getEmailAccounts(); client.js POST http://sourcedevcon/groupware extDirectData {"action":"account","method":"getEmailAccounts","data":null,"type":"rpc","tid":1} Firebug
  140. 140. Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({ id : eu.sourcedevcon.provider, enableUrlEncode : extDirectData, url : ./groupware, format : json, type : zend, actions : { account : [{ name : getFeedAccounts }, { name : getEmailAccounts }] }, namespace : eu.sourcedevcon.provider }); client.jseu.sourcedevcon.provider.account.getEmailAccounts(); client.js POST http://sourcedevcon/groupware extDirectData {"action":"account","method":"getEmailAccounts","data":null,"type":"rpc","tid":1} Firebug
  141. 141. Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({ id : eu.sourcedevcon.provider, enableUrlEncode : extDirectData, url : ./groupware, format : json, type : zend, actions : { account : [{ name : getFeedAccounts }, { name : getEmailAccounts }] }, namespace : eu.sourcedevcon.provider }); client.jseu.sourcedevcon.provider.account.getEmailAccounts(); client.js POST http://sourcedevcon/groupware extDirectData {"action":"account","method":"getEmailAccounts","data":null,"type":"rpc","tid":1} Firebug
  142. 142. Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({ id : eu.sourcedevcon.provider, enableUrlEncode : extDirectData, url : ./groupware, format : json, type : zend, actions : { account : [{ name : getFeedAccounts }, { name : getEmailAccounts }] }, namespace : eu.sourcedevcon.provider }); client.jseu.sourcedevcon.provider.account.getEmailAccounts(); client.js POST http://sourcedevcon/groupware extDirectData {"action":"account","method":"getEmailAccounts","data":null,"type":"rpc","tid":1} Firebug
  143. 143. Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({ id : eu.sourcedevcon.provider, enableUrlEncode : extDirectData, url : ./groupware, format : json, type : zend, actions : { account : [{ name : getFeedAccounts }, { name : getEmailAccounts }] }, namespace : eu.sourcedevcon.provider }); client.jseu.sourcedevcon.provider.account.getEmailAccounts(); client.js POST http://sourcedevcon/groupware extDirectData {"action":"account","method":"getEmailAccounts","data":null,"type":"rpc","tid":1} Firebug
  144. 144. Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({ id : eu.sourcedevcon.provider, enableUrlEncode : extDirectData, url : ./groupware, format : json, type : zend, actions : { account : [{ name : getFeedAccounts }, { name : getEmailAccounts }] }, namespace : eu.sourcedevcon.provider }); client.js eu.sourcedevcon.provider.account.getEmailAccounts(); client.js POST http://sourcedevcon/groupware extDirectData {"action":"account","method":"getEmailAccounts","data":null,"type":"rpc","tid":1} Firebugif (isset($_POST[extDirectData])) { ...} /groupware Firebug
  145. 145. Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({ id : eu.sourcedevcon.provider, enableUrlEncode : extDirectData, url : ./groupware, format : json, type : zend, actions : { account : [{ name : getFeedAccounts }, { name : getEmailAccounts }] }, namespace : eu.sourcedevcon.provider }); client.js eu.sourcedevcon.provider.account.getEmailAccounts(); client.js POST http://sourcedevcon/groupware extDirectData {"action":"account","method":"getEmailAccounts","data":null,"type":"rpc","tid":1} Firebugif (isset($_POST[extDirectData])) { ...} /groupware Firebug
  146. 146. Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({ id : eu.sourcedevcon.provider, enableUrlEncode : extDirectData, url : ./groupware, format : json, type : zend, actions : { account : [{ name : getFeedAccounts }, { name : getEmailAccounts }] }, namespace : eu.sourcedevcon.provider }); client.js eu.sourcedevcon.provider.account.getEmailAccounts(); client.js POST http://sourcedevcon/groupware extDirectData {"action":"account","method":"getEmailAccounts","data":null,"type":"rpc","tid":1} Firebugif (isset($_POST[extDirectData])) { http://sourcedevcon/groupware/account/get.email.accounts ...} /groupware Firebug
  147. 147. Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({ id : eu.sourcedevcon.provider, enableUrlEncode : extDirectData, url : ./groupware, format : json, type : zend, actions : { account : [{ name : getFeedAccounts }, { name : getEmailAccounts }] }, namespace : eu.sourcedevcon.provider }); client.js eu.sourcedevcon.provider.account.getEmailAccounts(); URL = module client.js POST http://sourcedevcon/groupware extDirectData {"action":"account","method":"getEmailAccounts","data":null,"type":"rpc","tid":1} Firebugif (isset($_POST[extDirectData])) { Http://sourcedevcon/groupware/account/get.email.accounts ...} /groupware Firebug
  148. 148. Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({ id : eu.sourcedevcon.provider, enableUrlEncode : extDirectData, url : ./groupware, format : json, type : zend, actions : { account : [{ name : getFeedAccounts }, { name : getEmailAccounts }] }, namespace : eu.sourcedevcon.provider }); client.js eu.sourcedevcon.provider.account.getEmailAccounts(); URL = module client.js action = controller POST http://sourcedevcon/groupware extDirectData {"action":"account","method":"getEmailAccounts","data":null,"type":"rpc","tid":1} Firebugif (isset($_POST[extDirectData])) { http://sourcedevcon/groupware/account/get.email.accounts ...} /groupware Firebug
  149. 149. Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({ id : eu.sourcedevcon.provider, enableUrlEncode : extDirectData, url : ./groupware, format : json, type : zend, actions : { account : [{ name : getFeedAccounts }, { name : getEmailAccounts }] }, namespace : eu.sourcedevcon.provider }); client.js eu.sourcedevcon.provider.account.getEmailAccounts(); URL = module client.js action = controller POST http://sourcedevcon/groupware extDirectData method = action {"action":"account","method":"getEmailAccounts","data":null,"type":"rpc","tid":1} Firebugif (isset($_POST[extDirectData])) { http://sourcedevcon/groupware/account/get.email.accounts ...} /groupware Firebug
  150. 150. Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({ id : eu.sourcedevcon.provider, enableUrlEncode : extDirectData, url : ./groupware, URL format : json, type : zend, actions : { account : [{ „action“ name : getFeedAccounts }, { name : getEmailAccounts method }] }, namespace : eu.sourcedevcon.provider }); client.js eu.sourcedevcon.provider.account.getEmailAccounts(); URL = module client.js action = controller POST http://sourcedevcon/groupware extDirectData method = action {"action":"account","method":"getEmailAccounts","data":null,"type":"rpc","tid":1} Firebugif (isset($_POST[extDirectData])) { http://sourcedevcon/groupware/account/get.email.accounts ...} /groupware Firebug
  151. 151. Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({ id : eu.sourcedevcon.provider, enableUrlEncode : extDirectData, url : ./groupware, format : json, type : zend, actions : { account : [{ name : getFeedAccounts }, { name : getEmailAccounts }] }, namespace : eu.sourcedevcon.provider }); client.js
  152. 152. Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({ id : eu.sourcedevcon.provider, enableUrlEncode : extDirectData, url : ./groupware, format : json, type : zend, actions : { account : [{ name : getFeedAccounts }, { name : getEmailAccounts }] }, namespace : eu.sourcedevcon.provider }); client.js
  153. 153. Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({ id : eu.sourcedevcon.provider, enableUrlEncode : extDirectData, url : ./groupware, format : json, type : zend, actions : { account : [{ name : getFeedAccounts }, { name : getEmailAccounts }] }, namespace : eu.sourcedevcon.provider }); client.js Ext.define(eu.sourcedevcon.direct.ZendProvider, { alias : direct.zendprovider, extend : Ext.direct.RemotingProvider }); ZendProvider.js
  154. 154. Ext.direct.* w/ Zend FrameworkURL = module action = controller method = action client.js
  155. 155. Ext.direct.* w/ Zend FrameworkURL = module action = controller method = actionExt.Ajax.on(beforerequest, function(conn, options) { var trans = options.transaction; if (trans && trans.provider && trans.provider.type == zend) { var controller = options.transaction.action; controller = controller.replace(/([a-z])([A-Z])/g, "$1.$2").toLowerCase(); var action = options.transaction.method; action = action.replace(/([a-z])([A-Z])/g, "$1.$2").toLowerCase(); var module = options.url; var url = module + (module.lastIndexOf(/) == module.length-1 ? : /) + controller + / + action; if (options.transaction.provider.format) { url += /format/ + options.transaction.provider.format; } options.url = url; options.disableCaching = true; }}); client.js
  156. 156. Ext.direct.* w/ Zend FrameworkURL = module action = controller method = actionExt.Ajax.on(beforerequest, function(conn, options) { var trans = options.transaction; if (trans && trans.provider && trans.provider.type == zend) { var controller = options.transaction.action; controller = controller.replace(/([a-z])([A-Z])/g, "$1.$2").toLowerCase(); var action = options.transaction.method; action = action.replace(/([a-z])([A-Z])/g, "$1.$2").toLowerCase(); var module = options.url; var url = module + (module.lastIndexOf(/) == module.length-1 ? : /) + controller + / + action; if (options.transaction.provider.format) { url += /format/ + options.transaction.provider.format; } options.url = url; options.disableCaching = true; }}); client.js
  157. 157. Ext.direct.* w/ Zend FrameworkURL = module action = controller method = actionExt.Ajax.on(beforerequest, function(conn, options) { var trans = options.transaction; if (trans && trans.provider && trans.provider.type == zend) { var controller = options.transaction.action; controller = controller.replace(/([a-z])([A-Z])/g, "$1.$2").toLowerCase(); var action = options.transaction.method; action = action.replace(/([a-z])([A-Z])/g, "$1.$2").toLowerCase(); var module = options.url; var url = module + (module.lastIndexOf(/) == module.length-1 ? : /) + controller + / + action; if (options.transaction.provider.format) { url += /format/ + options.transaction.provider.format; } options.url = url; options.disableCaching = true; }}); client.js
  158. 158. Ext.direct.* w/ Zend FrameworkURL = module action = controller method = actionExt.Ajax.on(beforerequest, function(conn, options) { var trans = options.transaction; if (trans && trans.provider && trans.provider.type == zend) { var controller = options.transaction.action; controller = controller.replace(/([a-z])([A-Z])/g, "$1.$2").toLowerCase(); var action = options.transaction.method; action = action.replace(/([a-z])([A-Z])/g, "$1.$2").toLowerCase(); var module = options.url; var url = module + (module.lastIndexOf(/) == module.length-1 ? : /) + controller + / + action; if (options.transaction.provider.format) { url += /format/ + options.transaction.provider.format; } options.url = url; options.disableCaching = true; }}); client.js
  159. 159. Ext.direct.* w/ Zend FrameworkURL = module action = controller method = actionExt.Ajax.on(beforerequest, function(conn, options) { var trans = options.transaction; if (trans && trans.provider && trans.provider.type == zend) { var controller = options.transaction.action; controller = controller.replace(/([a-z])([A-Z])/g, "$1.$2").toLowerCase(); var action = options.transaction.method; action = action.replace(/([a-z])([A-Z])/g, "$1.$2").toLowerCase(); var module = options.url; var url = module + (module.lastIndexOf(/) == module.length-1 ? : /) + controller + / + action; if (options.transaction.provider.format) { url += /format/ + options.transaction.provider.format; } options.url = url; options.disableCaching = true; }}); client.js
  160. 160. Ext.direct.* w/ Zend FrameworkURL = module action = controller method = actionExt.Ajax.on(beforerequest, function(conn, options) { var trans = options.transaction; if (trans && trans.provider && trans.provider.type == zend) { var controller = options.transaction.action; controller = controller.replace(/([a-z])([A-Z])/g, "$1.$2").toLowerCase(); var action = options.transaction.method; action = action.replace(/([a-z])([A-Z])/g, "$1.$2").toLowerCase(); var module = options.url; var url = module + (module.lastIndexOf(/) == module.length-1 ? : /) + controller + / + action; if (options.transaction.provider.format) { url += /format/ + options.transaction.provider.format; } options.url = url; options.disableCaching = true; }}); client.js
  161. 161. Ext.direct.* w/ Zend FrameworkURL = module action = controller method = actionExt.Ajax.on(beforerequest, function(conn, options) { var trans = options.transaction; if (trans && trans.provider && trans.provider.type == zend) { var controller = options.transaction.action; controller = controller.replace(/([a-z])([A-Z])/g, "$1.$2").toLowerCase(); var action = options.transaction.method; action = action.replace(/([a-z])([A-Z])/g, "$1.$2").toLowerCase(); var module = options.url; var url = module + (module.lastIndexOf(/) == module.length-1 ? : /) + controller + / + action; if (options.transaction.provider.format) { ContextSwitch url += /format/ + options.transaction.provider.format; } options.url = url; options.disableCaching = true; }}); client.js
  162. 162. Ext.direct.* w/ Zend FrameworkURL = module action = controller method = actionExt.Ajax.on(beforerequest, function(conn, options) { var trans = options.transaction; if (trans && trans.provider && trans.provider.type == zend) { var controller = options.transaction.action; controller = controller.replace(/([a-z])([A-Z])/g, "$1.$2").toLowerCase(); var action = options.transaction.method; action = action.replace(/([a-z])([A-Z])/g, "$1.$2").toLowerCase(); var module = options.url; var url = module + (module.lastIndexOf(/) == module.length-1 ? : /) + controller + / + action; if (options.transaction.provider.format) { url += /format/ + options.transaction.provider.format; } options.url = url; options.disableCaching = true; }}); client.js
  163. 163. Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({ id : eu.sourcedevcon.provider, enableUrlEncode : extDirectData, url : ./groupware, format : json, type : zend, actions : { account : [{ name : getFeedAccounts }, { name : getEmailAccounts }] }, namespace : eu.sourcedevcon.provider }); client.jseu.sourcedevcon.provider.account.getEmailAccounts(); client.js
  164. 164. Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({ id : eu.sourcedevcon.provider, enableUrlEncode : extDirectData, url : ./groupware, format : json, type : zend, actions : { account : [{ name : getFeedAccounts }, { name : getEmailAccounts }] }, namespace : eu.sourcedevcon.provider }); client.jseu.sourcedevcon.provider.account.getEmailAccounts(); client.js POST http://sourcedevcon/groupware
  165. 165. Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({ id : eu.sourcedevcon.provider, enableUrlEncode : extDirectData, url : ./groupware, format : json, type : zend, actions : { account : [{ name : getFeedAccounts }, { name : getEmailAccounts }] }, namespace : eu.sourcedevcon.provider }); client.jseu.sourcedevcon.provider.account.getEmailAccounts(); client.js POST http://sourcedevcon/groupware POST http://sourcedevcon/groupware/account/get.email.accounts/format/json extDirectData {"action":"account","method":"getEmailAccounts","data":null,"type":"rpc","tid":1} Firebug
  166. 166. Ext.direct.* w/ Zend Framework POST http://sourcedevcon/groupware/account/get.email.accounts/format/json extDirectData {"action":"account","method":"getEmailAccounts","data":null,"type":"rpc","tid":1} Firebug Note: ● Teach your actions the „extDirectData“-POST parameter
  167. 167. Ext.direct.* w/ Zend Framework POST http://sourcedevcon/groupware/account/get.email.accounts/format/json extDirectData {"action":"account","method":"getEmailAccounts","data":null,"type":"rpc","tid":1} Firebug Note: ● Teach your actions the „extDirectData“-POST parameter ● Your responses must return the „tid“ as received by the request
  168. 168. Ext.direct.* w/ Zend Framework Will do! Let me send a batched request now!
  169. 169. Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({ id : eu.sourcedevcon.provider, enableUrlEncode : extDirectData, url : ./groupware, format : json, type : zend, actions : { account : [{ name : getFeedAccounts }, { name : getEmailAccounts }] }, namespace : eu.sourcedevcon.provider }); client.jseu.sourcedevcon.provider.account.getEmailAccounts();eu.sourcedevcon.provider.account.getFeedAccounts(); client.js
  170. 170. Ext.direct.* w/ Zend Framework Ext.direct.Manager.addProvider({ id : eu.sourcedevcon.provider, enableUrlEncode : extDirectData, url : ./groupware, format : json, type : zend, actions : { account : [{ name : getFeedAccounts }, { name : getEmailAccounts }] }, namespace : eu.sourcedevcon.provider }); client.jseu.sourcedevcon.provider.account.getEmailAccounts();eu.sourcedevcon.provider.account.getFeedAccounts(); client.js POST http://sourcedevcon/groupware extDirectData [{"action":"account","method":"getEmailAccounts","data":null,"type":"rpc","tid":1}, {"action":"account","method":"getFeedAccounts","data":null,"type":"rpc","tid":2}] Firebug
  171. 171. Ext.direct.* w/ Zend Framework ...?
  172. 172. Ext.direct.* w/ Zend Framework queueTransaction: function(transaction){ var me = this, enableBuffer = me.enableBuffer; if (transaction.form) { me.sendFormRequest(transaction); return; } me.callBuffer.push(transaction); if (enableBuffer) { if (!me.callTask) { me.callTask = Ext.create(Ext.util.DelayedTask, me.combineAndSend, me); } me.callTask.delay(Ext.isNumber(enableBuffer) ? enableBuffer : 10); } else { me.combineAndSend(); } } RemotingProvider.js
  173. 173. Ext.direct.* w/ Zend Framework queueTransaction: function(transaction){ add transaction to callBuffer Array var me = this, enableBuffer = me.enableBuffer; if (transaction.form) { me.sendFormRequest(transaction); return; } me.callBuffer.push(transaction); if (enableBuffer) { if (!me.callTask) { me.callTask = Ext.create(Ext.util.DelayedTask, me.combineAndSend, me); } me.callTask.delay(Ext.isNumber(enableBuffer) ? enableBuffer : 10); } else { me.combineAndSend(); } } RemotingProvider.js
  174. 174. Ext.direct.* w/ Zend Framework queueTransaction: function(transaction){ add transaction to callBuffer Array var me = this, enableBuffer = me.enableBuffer; if batching is enabled, create a task if (transaction.form) { me.sendFormRequest(transaction); return; } me.callBuffer.push(transaction); if (enableBuffer) { if (!me.callTask) { me.callTask = Ext.create(Ext.util.DelayedTask, me.combineAndSend, me); } me.callTask.delay(Ext.isNumber(enableBuffer) ? enableBuffer : 10); } else { me.combineAndSend(); } } RemotingProvider.js
  175. 175. Ext.direct.* w/ Zend Framework queueTransaction: function(transaction){ add transaction to callBuffer Array var me = this, enableBuffer = me.enableBuffer; if batching is enabled, create a task wait for 10ms for another if (transaction.form) { transaction to be added me.sendFormRequest(transaction); return; } me.callBuffer.push(transaction); if (enableBuffer) { if (!me.callTask) { me.callTask = Ext.create(Ext.util.DelayedTask, me.combineAndSend, me); } me.callTask.delay(Ext.isNumber(enableBuffer) ? enableBuffer : 10); } else { me.combineAndSend(); } } RemotingProvider.js
  176. 176. Ext.direct.* w/ Zend Framework queueTransaction: function(transaction){ add transaction to callBuffer Array var me = this, enableBuffer = me.enableBuffer; if batching is enabled, create a task wait for 10ms for another if (transaction.form) { transaction to be added me.sendFormRequest(transaction); no more transactions coming in? Call return; combineAndSend } me.callBuffer.push(transaction); if (enableBuffer) { if (!me.callTask) { me.callTask = Ext.create(Ext.util.DelayedTask, me.combineAndSend, me); } me.callTask.delay(Ext.isNumber(enableBuffer) ? enableBuffer : 10); } else { me.combineAndSend(); } } RemotingProvider.js
  177. 177. Ext.direct.* w/ Zend Frameworkeu.sourcedevcon.provider.account.getEmailAccounts();eu.sourcedevcon.provider.account.getFeedAccounts(); client.jsExt.Ajax.on(beforerequest, function(conn, options) { var trans = options.transaction; if (trans && trans.provider && trans.provider.type == zend) { var controller = options.transaction.action; controller = controller.replace(/([a-z])([A-Z])/g, "$1.$2").toLowerCase(); var action = options.transaction.method; action = action.replace(/([a-z])([A-Z])/g, "$1.$2").toLowerCase(); var module = options.url; var url = module + (module.lastIndexOf(/) == module.length-1 ? : /) + controller + / + action; if (options.transaction.provider.format) { url += /format/ + options.transaction.provider.format; } options.url = url; options.disableCaching = true; }}); client.js
  178. 178. Ext.direct.* w/ Zend Frameworkeu.sourcedevcon.provider.account.getEmailAccounts();eu.sourcedevcon.provider.account.getFeedAccounts(); client.jsExt.Ajax.on(beforerequest, function(conn, options) { false var trans = options.transaction; if (trans && trans.provider && trans.provider.type == zend) { var controller = options.transaction.action; controller = controller.replace(/([a-z])([A-Z])/g, "$1.$2").toLowerCase(); var action = options.transaction.method; action = action.replace(/([a-z])([A-Z])/g, "$1.$2").toLowerCase(); var module = options.url; var url = module + (module.lastIndexOf(/) == module.length-1 ? : /) + controller + / + action; if (options.transaction.provider.format) { url += /format/ + options.transaction.provider.format; } options.url = url; options.disableCaching = true; }}); client.js
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×