predator
28 May 2010, 1:55 PM
Here I will outline the integration process between ext and zf, I would really want to know if you think that some of my approaches are wrong or they can be done in a better way.
Also I know that I will talk mainly about php here, so if this is supposed to go in a different category really sorry.
Now the first obvious problem is that ZF is MVC framework, but with extjs the View part is not really needed and needs to be taken away somehow. There are two ways to do that:
first one is to disable the view in each controller by placing this code in the init() method
public function init()
{
$this->getHelper('layout')->disableLayout();
}
The second option is to create a plugin with predispatch method that will take care of it globaly
I found it very useful to merge it together with my user authorization stuff
In my access check plugin i have the following preDispatch
public function preDispatch(Zend_Controller_Request_Abstract $request)
{
if($this->_auth->hasIdentity()) {
//User is logged in
// All server calls are ajax/json, so we dont need the zend view
if($request->controller == 'auth') {
// dont disable it for auth controller
} else {
// Disable Layout
$layout = Zend_Layout::getMvcInstance();
$layout->disableLayout();
// Stops ZF from looking for scritps/*.phtml
$fc = Zend_Controller_Front::getInstance();
$fc->setParam('noViewRenderer', true);
}
// This user has no identity and needs to see the login page
} else {..........
Note that this plugin needs to be registered in the bootstrap.php, create a method that starts with _init*.() and register the plugin
protected function _initAuthorization()
{
/**
* This will check only if user is logged in
* Specific permissions MUST be checked within
* the appropriate controller, action or method
*/
$auth = Zend_Auth::getInstance();
$fc = Zend_Controller_Front::getInstance();
$fc->registerPlugin(new Plugin_AccessCheck($auth));
}Now you can load your js files within the layout file and not being bothered about any views from zf. Note that you can still benefit from everything else that ZF has to offer. But in a way you are turning it into json server that will handle requests and serve results.
Now here is my other problem... once the user is logged in and so on... the js files are served and the interface is loaded... but lets say the session on the server side expires.. the UI stills stays loaded and the only way for the user to see the login screen again is to refresh the page or revisit it... I needed some time to figure out a solution for that. Here is my approach
in my AccessCheck plugin, the same I use for disabling the layout I have the following code to be sent in a case of expired session
header('HTTP/1.1 401 Unauthorized'); // ExtJS is listening for this code in the header.
and in my layout file the following extjs code is handling 401 header
Ext.Ajax.on('requestexception', function(conn, response, options) {
switch (response.status) {
case 401:
Ext.getCmp('mainViewport').destroy();
Ext.Msg.show({
title:'<div align="center">Session Expired!</div>'
,msg:"<center>Your session has expired or you have logged out from another place.<br>Click OK to login again.</center>"
,height:200
,width:440
,closable:false
,buttons:Ext.Msg.OK
,fn: function(btn){
if(btn == 'ok') {
window.location = GV.baseUrl()+'/auth/login';
}
}
});
}
});
I really wonder if somebody else is working with ZF as backend how is he handling those two problems.
Thanks for reading
Also I know that I will talk mainly about php here, so if this is supposed to go in a different category really sorry.
Now the first obvious problem is that ZF is MVC framework, but with extjs the View part is not really needed and needs to be taken away somehow. There are two ways to do that:
first one is to disable the view in each controller by placing this code in the init() method
public function init()
{
$this->getHelper('layout')->disableLayout();
}
The second option is to create a plugin with predispatch method that will take care of it globaly
I found it very useful to merge it together with my user authorization stuff
In my access check plugin i have the following preDispatch
public function preDispatch(Zend_Controller_Request_Abstract $request)
{
if($this->_auth->hasIdentity()) {
//User is logged in
// All server calls are ajax/json, so we dont need the zend view
if($request->controller == 'auth') {
// dont disable it for auth controller
} else {
// Disable Layout
$layout = Zend_Layout::getMvcInstance();
$layout->disableLayout();
// Stops ZF from looking for scritps/*.phtml
$fc = Zend_Controller_Front::getInstance();
$fc->setParam('noViewRenderer', true);
}
// This user has no identity and needs to see the login page
} else {..........
Note that this plugin needs to be registered in the bootstrap.php, create a method that starts with _init*.() and register the plugin
protected function _initAuthorization()
{
/**
* This will check only if user is logged in
* Specific permissions MUST be checked within
* the appropriate controller, action or method
*/
$auth = Zend_Auth::getInstance();
$fc = Zend_Controller_Front::getInstance();
$fc->registerPlugin(new Plugin_AccessCheck($auth));
}Now you can load your js files within the layout file and not being bothered about any views from zf. Note that you can still benefit from everything else that ZF has to offer. But in a way you are turning it into json server that will handle requests and serve results.
Now here is my other problem... once the user is logged in and so on... the js files are served and the interface is loaded... but lets say the session on the server side expires.. the UI stills stays loaded and the only way for the user to see the login screen again is to refresh the page or revisit it... I needed some time to figure out a solution for that. Here is my approach
in my AccessCheck plugin, the same I use for disabling the layout I have the following code to be sent in a case of expired session
header('HTTP/1.1 401 Unauthorized'); // ExtJS is listening for this code in the header.
and in my layout file the following extjs code is handling 401 header
Ext.Ajax.on('requestexception', function(conn, response, options) {
switch (response.status) {
case 401:
Ext.getCmp('mainViewport').destroy();
Ext.Msg.show({
title:'<div align="center">Session Expired!</div>'
,msg:"<center>Your session has expired or you have logged out from another place.<br>Click OK to login again.</center>"
,height:200
,width:440
,closable:false
,buttons:Ext.Msg.OK
,fn: function(btn){
if(btn == 'ok') {
window.location = GV.baseUrl()+'/auth/login';
}
}
});
}
});
I really wonder if somebody else is working with ZF as backend how is he handling those two problems.
Thanks for reading