*
The user interface will generally be created with either PHP pages,
* which will not themselves contain any business logic. These pages represent
* the "view" component of an MVC architecture.
* Forms and hyperlinks in the user interface that require business logic
* to be executed will be submitted to a request URI that is mapped to the
* ActionController. The ActionController receives and processes all requests
* that change the state of a user's interaction with the application. This
* component represents the "controller" component of an MVC architecture.
* The ActionController will select and invoke an Action class to perform
* the requested business logic.
* The Action classes will manipulate the state of the application's
* interaction with the user, typically by creating or modifying classes that
* are stored as session attributes. Such classes represent the "model"
* component of an MVC architecture.
* Instead of producing the next page of the user interface directly,
* Action classes will forward control to an appropriate PHP page to produce
* the next page of the user interface.
*
* The standard version of ActionController implements the following logic for
* each incoming HTTP request. You can override some or all of this
* functionality by subclassing this class and implementing your own version of
* the processing.
*
* - Identify, from the incoming request URI, the substring that will be used
* to select an Action procedure.
* - Use this substring to map to the class name of the corresponding Action
* class (a subclass of the Action class).
* - If this is the first request for a particular Action class, instantiate
* an instance of that class and cache it for future use.
* - Optionally populate the properties of an ActionForm class associated
* with this ActionMapping and cache it for future use.
* - Call the perform() method of this Action class. Passing in the mapping
* and the request that were passed to the ActionController by the bootstrap.
*
*
*
* The standard version of ActionController is configured based on the
* following initialization parameters, which you will specify in the options
* for your application. Subclasses that specialize this ActionController are
* free to define additional initialization parameters.
*
* - options - This sets the ActionController options.
*
*
* @author Arnold Cano
* @version $Id: ActionController.php,v 1.28 2010-02-23 15:51:59 gaspar Exp $
* @package Phrame
* @link http://phrame.sourceforge.net/docs/guide/guide.php Documentation.
* @link http://phrame.sourceforge.net/docs/guide/controller.php Documentation.
*/
class ActionController extends Object
{
/**
* @access protected
* @var array Array: [ _CACHE => bool, _ERROR_HANDLER => int, _ERROR_HANDLER => string ]
*/
protected $_options;
/**
* @access protected
* @var HashMap
*/
protected $_actionMappings;
/**
* @access protected
* @var HashMap
*/
protected $_actions;
/**
* @access protected
* @var string (comunicación)
*/
protected $_communication;
/**
* Create a ActionController specifying the options.
*
* @access public
* @param array $options Array: [ _CACHE => bool, _ERROR_HANDLER => int, _ERROR_HANDLER => string ]
*/
public function __construct( $options )
{
if (!is_array($options)) {
trigger_error('Invalid options file');
return;
}
$this->_options = $options;
//initialize cache
$this->_actionMappings = new HashMap();
$this->_actions = new HashMap();
} //Fin de constructor
/**
* Process the request.
*
* @access public
* @param string[] $mappings Array: [ _ACTION_MAPPINGS => [name => [_TYPE => string, _INPUT => string, _ACTION_FORWARDS => [[ _PATH => string, _REDIRECT => bool], ...]], ...] ]
* @param array $request
*/
public function process( $mappings, $request )
{
if (!is_array($mappings)) {
trigger_error('Invalid mappings file');
return;
}
if (!is_array($request)) {
trigger_error('Invalid request');
return;
}
//error_reporting($this->_options[_ERROR_REPORTING]);
$actionMapping = $this->_processMapping($mappings, $request);
//Creamos el ActionForm (un Hasmap sobre el request)
$actionForm = new HashMap($request);
$actionForward = $this->_processAction($actionMapping, $actionForm);
$path = $actionForward->getPath();
if(strpos($path, 'phrame.php')!==false)//Si estamos pasando por phrame
{
//La segunda vuelta de los saltos modales (ida y vuelta) se hace desde el Jquery ya que se lanzan desde el showDialog
if (isset($actionForward->_saco['IGEPaccionDestinoSalto']) OR isset($actionForward->_saco['IGEPSaltoDestinoVuelta'])) //Estamos en un salto, procesamos el destino
{
$path = isset($actionForward->_saco['IGEPaccionDestinoSalto'])?$actionForward->_saco['IGEPaccionDestinoSalto']:$actionForward->_saco['IGEPSaltoDestinoVuelta'];
$actionForward->setPath($path);
}
//En otros casos, no llegamos a Jquery. Es el caso de un mappings que apunte a phrame
else {
header('Location: '.$path);
die;
}
}
if (is_object($actionForward)) {
$this->_processForward($actionForward);
}
} //Fin de process
/**
* Identify and return an appropriate ActionMapping.
*
* @access protected
* @param string[] $mappings Array: [ _ACTION_MAPPINGS => [name => [_TYPE => string, _INPUT => string, _ACTION_FORWARDS => [[ _PATH => string, _REDIRECT => bool], ...]], ...] ]
* @param array $request
* @return ActionMapping
*/
protected function _processMapping( $mappings, $request )
{
$name = $request[_ACTION];
$mapping = $mappings[_ACTION_MAPPINGS][$name];
$actionMapping = $this->_actionMappings->get($name);
if (!is_object($actionMapping)) {
$actionMapping = new ActionMapping($name, $mapping);
if ($this->_options[_CACHE]) {
$this->_actionMappings->put($name, $actionMapping);
}
}
return $actionMapping;
} //Fin de _processMapping
/**
* Ask the specified Action instance to handle this request.
*
* @access protected
* @param ActionMapping $actionMapping
* @param HashMap $actionForm ActionForm.
* @return ActionForward
*/
protected function _processAction( $actionMapping, $actionForm )
{
$name = $actionMapping->getName();
$type = $actionMapping->getType();
$action = $this->_actions->get($name);
if (!is_object($action)) {
//Si la clase no existe marcamos el error.
if (!class_exists($type)) {
$name = htmlentities($name, ENT_COMPAT | ENT_HTML401, 'UTF-8');
$type = htmlentities($type, ENT_COMPAT | ENT_HTML401, 'UTF-8');
if($type=='' AND $name=='') {
IgepDebug::setDebug(ERROR,'Se ha producido un error al intentar ejecutar una clase vacía y una acción vacía.');
}
elseif($type=='') {
IgepDebug::setDebug(ERROR,'Se ha intentado ejecutar la acción \''.$name.'\' y no está programada para la clase actual. Compruebe el fichero de la clase y el mappings.php de su aplicación.');
}
else {
IgepDebug::setDebug(ERROR,'Se ha producido un error intentado ejecutar la acción \''.$name.'\' de la clase \''.$type.'\'. Compruebe el nombre de la clase y su accesibilidad (fichero include.php).');
}
die('ACCESO NO PERMITIDO: Se ha intentado ejecutar una acción \''.$name.'\' no programada.');
return;
}
//Guardamos la referencia del modulo si es la primera pantalla del modulo a la que accedemos.
if(isset($_REQUEST['modActv'])){
IgepSession::guardaVariable('global','modActv',$_REQUEST['modActv']);
//Borramos el contenido de los paneles anteriores
IgepSession::_borrarPanelesVisitados();
//Borramos el contenido del salto
IgepSession::borraSalto();
$this->_communication = 'request';
}
else {
$this->_communication = 'json';
}
//Si el panel ya existe lo recuperamos de la Session
if(IgepSession::existePanel($type)&&(strpos($type,'gvHidraForm')===false)) {
$action = IgepSession::damePanel($type);
if(method_exists($action,'regenerarInstancia')) {
$action->regenerarInstancia('');
}
else{
IgepSession::borraPanel($type);
IgepDebug::setDebug(PANIC,'Error al recuperar la instancia de '.$type.'. Puede deberse a un error en el constructor. Se crea una nueva instancia.');
$action = new $type();
}
}
else {
/*
if($type!='gvHidraDebugger') {
IgepDebug::setDebug(DEBUG_IGEP,'Creamos una instancia de la clase '.$type);
}
*/
$action = new $type();
}
if ($this->_options[_CACHE]) {
$this->_actions->put($name, $action);
}
}
if(is_callable($this->_options[_ERROR_HANDLER]))
set_error_handler($this->_options[_ERROR_HANDLER]);
if(!$action->obj_errorNegocio->hayError()) {
$actionForward = $action->perform($actionMapping, $actionForm);
$miPath = $actionForward->getPath();
$claseM = $actionForward->get('IGEPclaseManejadora');
if(empty($claseM)) {
$actionForward->put('IGEPclaseManejadora',$type);
}
if($action->isModal()) {
$this->_communication='json';
if(!$action->getCloseModalWindow()) {
if($type=='IgepAccionesGenericas') { //Para los saltos dentro de una ventana modal
$idpath = isset($actionForward->_saco['IGEPaccionDestinoSalto'])?'IGEPaccionDestinoSalto':'IGEPSaltoDestinoVuelta';
$path = isset($actionForward->_saco['IGEPaccionDestinoSalto'])?$actionForward->_saco['IGEPaccionDestinoSalto']:$actionForward->_saco['IGEPSaltoDestinoVuelta'];
$idModal = $actionForward->get('IGEPmodalID');
$claseManejadora = $actionForward->get('IGEPclaseManejadora');
}
$actionForward = new ActionForward('gvHidraJDialog');
if($type=='IgepAccionesGenericas') {
$actionForward->_saco[$idpath] = $path;
$actionForward->_saco['IGEPmodalID'] = $idModal;
$actionForward->_saco['IGEPclaseManejadora'] = $claseManejadora;
}
else {
$actionForward->put('IGEPclaseManejadora',$type);
}
}
else {
//Cuando cerramos la ventana modal tenemos que ver que tiene URL de vuelta
//Recuperamos el id de la ventana
$idModal = $actionForward->get('IGEPmodalID');
$actionForward = new ActionForward('gvHidraCloseJDialog');
$returnPath = $actionForward->get('IGEPSaltoDestinoVuelta');
$actionForward->_saco['IGEPmodalID']=$idModal;
if(empty($returnPath)) {
$salto = IgepSession::dameSalto();
if(is_object($salto)) {
// REVIEW: VERO Clase manejadora para identificar la Ventana Modal
$actionForward->put('IGEPclaseManejadora',$salto->getClaseDestino());
$pathAux = $salto->getDestinoVuelta();
$actionForward->put('IGEPSaltoDestinoVuelta',$pathAux);
}
}
$action->setCloseModalWindow(false);
}
$actionForward->setPath($miPath);
}
//Si es un gvHidraNoAction, cargamos la clase manejadora
if($actionForward->getName()=='gvHidraReload') {
//Cargamos la ruta actual desde el views.
$posicionIndice = strpos($_SERVER['HTTP_REFERER'],"index.php?view=");
if($posicionIndice!==false AND $posicionIndice>0)
$actionForward->setPath(substr($_SERVER['HTTP_REFERER'],$posicionIndice));
}
}
else {
$action->obj_errorNegocio->limpiarError();
unset($action);
$actionForward = new ActionForward('IgepInicioAplicacion');
$actionForward->_path = 'index.php?view=igep/views/aplicacion.php';
//Borramos cualquier referencia a la clase en la SESSION
IgepSession::borraPanel($type);
}
if(is_callable($this->_options[_ERROR_HANDLER]))
restore_error_handler();
return $actionForward;
} // Fin de _processAction
/**
* Forward to the specified destination.
*
* @access protected
* @param ActionForward $actionForward
*/
protected function _processForward( $actionForward )
{
$salto ='';
$actionForwardName = $actionForward->getName();
$claseManejadora = $actionForward->get('IGEPclaseManejadora');
switch($actionForwardName) {
case 'gvHidraNoAction':
$path='';
$salto = "Location: index.php?view=igep/views/igep_regenerarVentana.php&IGEPpath=$path&IGEPclaseManejadora=$claseManejadora";
break;
case 'IgepOperacionOculto':
$path = $actionForward->getPath();
$salto = "Location: $path";
break;
case 'IgepSaltoVentana': //Salto no modal
$path = $actionForward->get('IGEPaccionDestinoSalto');
$salto = "Location: $path";
$actionForwardName = 'gvHidraLoad';
//header($salto);die;
break;
case 'IgepSaltoVentanaModal': //Salto modal
$path = $actionForward->get('IGEPaccionDestinoSalto');
$salto = "Location: $path";
break;
case 'IgepVentanaSeleccion':
$path = $actionForward->getPath();
$salto = "Location: $path";
break;
default:
$path = $actionForward->getPath();
//REVIEW: Toni PHRAME
/* La variable clase Manejadora no está definida, por tanto se podrá eliminar.
*/
//$claseManejadora ='';
//$salto ="Location: index.php?view=igep/views/igep_regenerarVentana.php&IGEPpath=$path&IGEPclaseManejadora=$claseManejadora";
$salto = "Location: $path";
}
if ($claseManejadora != 'gvHidraDebugger')
{
IgepDebug::setDebug(PANIC, "actionForwardName: ".print_r($actionForwardName,true)." claseManejadora: ".print_r($claseManejadora,true)."
");
}
if($this->_communication=='json') {
switch($actionForwardName)
{
case 'gvHidraNoAction':
$objeto = IgepSession::damePanel($claseManejadora);
$jsLoadScript = '';
//Recuperamos mensaje
if(IgepSession::existeMensaje($claseManejadora)) {
$mensaje = IgepSession::dameMensaje($claseManejadora);
$jsLoadScript .= gvHidraUTF8::toUTF8(IgepSmarty::getJsMensaje($mensaje));
IgepSession::borraMensaje($claseManejadora);
};
//Recuperamos scripts
if(isset($objeto->obj_IgSmarty) and is_object($objeto->obj_IgSmarty)) {
$jsLoadScript .= $objeto->obj_IgSmarty->getScriptLoad(false);
}
$params = array
(
'path' => '',
'context' => array(
'targetType' => 'self',
'action' => 'NoAction',
'script' => "$jsLoadScript"
)
);
$response = json_encode($params, JSON_FORCE_OBJECT);
print($response);die;
break;
case 'IgepVentanaSeleccion':
$width = $actionForward->get('IGEPmodalWidth');
$height = $actionForward->get('IGEPmodalHeight');
$idWS = "WS_".$claseManejadora;
$idWS = "WS";
$params = array
(
'path'=>rawUrlEncode($path),
'context' => array(
'targetType' => 'JDialog',
'action' => 'gvHidraOpenJDialog',
'width' => $width,
'height' => $height,
'idVentana' => $idWS
)
);
$response = json_encode($params, JSON_FORCE_OBJECT);
print($response);die;
break;
case 'gvHidraJDialog':
case 'IgepSaltoVentanaModal':
$objeto = IgepSession::damePanel($claseManejadora);
$jsLoadScript = '';
//Recuperamos mensaje
if(IgepSession::existeMensaje($claseManejadora)) {
$mensaje = IgepSession::dameMensaje($claseManejadora);
$jsLoadScript .= gvHidraUTF8::toUTF8(IgepSmarty::getJsMensaje($mensaje));
IgepSession::borraMensaje($claseManejadora);
};
//Recuperamos scripts
if(isset($objeto->obj_IgSmarty) and is_object($objeto->obj_IgSmarty)) {
$jsLoadScript .= $objeto->obj_IgSmarty->getScriptLoad(false);
}
$width = $actionForward->get('IGEPmodalWidth');
$height = $actionForward->get('IGEPmodalHeight');
$returnPath = $actionForward->get('IGEPaccionDestinoVueltaSalto');
// No vale pq siempre viene IgepAccionesGenericas
$idModal = $actionForward->get('IGEPmodalID');
if (empty($idModal) || $idModal == 'WM')
{
$idModal = 'WM_'.$claseManejadora;
}
$params = array
(
'path'=>rawUrlEncode($path),
'context' => array(
'targetType' => 'JDialog',
'action' => 'gvHidraOpenJDialog',
'width' => $width,
'height' => $height,
'idVentana' => $idModal,
'returnPath' => $returnPath,
'script' => "$jsLoadScript"
)
);
$response = json_encode($params, JSON_FORCE_OBJECT);
print($response);die;
break;
case 'gvHidraCloseJDialog':
$objeto = IgepSession::damePanel($claseManejadora);
$jsLoadScript = '';
//Recuperamos mensaje
if(IgepSession::existeMensaje($claseManejadora)) {
$mensaje = IgepSession::dameMensaje($claseManejadora);
$jsLoadScript .= gvHidraUTF8::toUTF8(IgepSmarty::getJsMensaje($mensaje));
IgepSession::borraMensaje($claseManejadora);
};
//Recuperamos scripts
if(isset($objeto->obj_IgSmarty) and is_object($objeto->obj_IgSmarty)) {
$jsLoadScript .= $objeto->obj_IgSmarty->getScriptLoad(false);
}
$returnPath = $actionForward->get('IGEPSaltoDestinoVuelta');
$idModal = $actionForward->get('IGEPmodalID');
if (empty($idModal) || $idModal == 'WM')
{
$idModal = 'WM_'.$claseManejadora;
}
$panelRetorno = $actionForward->get('IGEPpanelRetorno');
//$idModal = 'Modal';
$params = array
(
'path'=>rawUrlEncode($path),
'context' => array(
'targetType' => 'JDialog',
'action' => 'gvHidraCloseJDialog',
'returnPath' => $returnPath,
'idVentana' => $idModal,
'panelRetorno' => $panelRetorno,
'script' => "$jsLoadScript"
)
);
$response = json_encode($params, JSON_FORCE_OBJECT);
print($response);die;
break;
case 'gvHidraCloseApp':
case 'IgepSaltoVentana':
$params = array
(
'path'=>rawUrlEncode($path),
'context' => array(
'targetType'=>'self'
)
);
$response = json_encode($params, JSON_FORCE_OBJECT);
print($response);die;
break;
case 'gvHidraOpenApp':
case 'gvHidraPrincipal':
case 'gvHidraHeader':
header($salto);
break;
case 'gvHidraLoad':
$params = array
(
'path'=>rawUrlEncode($path),
'context' => array(
'targetType' => 'self',
'action' => 'salto'
)
);
$response = json_encode($params, JSON_FORCE_OBJECT);
print($response);die;
break;
default:
$params = array
(
'path'=>rawUrlEncode($path),
'context' => array(
'targetType'=>'self'
)
);
$response = json_encode($params, JSON_FORCE_OBJECT);
print($response);die;
break;
}
}
else {
//Cuando entramos desde la entrada de menu
header($salto);
}
} // Fin de _processForward
} //End ActionController