August 2, 2010 | In: component, componente_web, php, zend framework
Este plugin viene bastante bien para tener todos los datos de texto en un XML. Por norma general se suele guardar en una base de datos; pero muchas veces el sitio no tiene un CMS o es muy pequeño para tener la información en una base de datos.
Con este plugin cargamos un XML, pasandole unos parámetros de configuración para que automáticamente nos seleccione un nodo especifico del XML. Esta configuración utiliza comodines de Zend_Route (Module, Controller, Action, ParamX….) para el nombre del archivo y el nodo por defecto:
. * * * @category Cuatroxl * @package Cuatroxl_Zf_Action_Helper * @autor Jimmy Collazos* @license http://www.gnu.org/licenses/gpl.html GPLv3 * @version 0.01 */ /** * @see Zend_Controller_Plugin_Abstract */ require_once 'Zend/Controller/Plugin/Abstract.php'; /** * @category Cuatroxl * @package Cuatroxl_Controller * @subpackage Cuatroxl_Controller_Plugin * @license http://www.gnu.org/licenses/gpl.html GPLv3 */ class Cuatroxl_Controller_Plugin_DataPage extends Zend_Controller_Plugin_Abstract { /* * Variable de configuración * * @var Array */ protected $_config = array('autoload' => false ,'filePath' => 'public/:module/:controller/:action.xml' ,'xpath' => '' ,'basePath' => APPLICATION_PATH // esta opción es solo para cuando NO usamos Zend_Application ,'_keyPlugin' => ''); /* * Ruta del archivo XML a cargar * * @var string */ protected $_filePath = null; /* * Xpath query para poder obteenr el nodo por defecto del XML * * @var string */ protected $_xpath = null; /* * En esta variable se almacena el XML final con el que podemos trabajar * desde el controlador * * @var SimpleXMLElement */ protected $_data; /* * Nombre asignado en el archivo de configuración de al aplicación * * @var string */ private $_keyPlugin; /** * Constructor * * @param Array * @return void */ public function __construct( array $options = array() ) { $this->_setConfig($options); } /* * routeShutdown() es como el constructor ya que se usa para setear el XML * en caso de estar activado el "autoload" y también setea la configuración del INI * * @param Zend_Controller_Request_Abstract * @return void */ public function routeShutdown( Zend_Controller_Request_Abstract $request) { //@TODO cambiar esto por una funcion que setee todas las opciones $bootstrap = Zend_Controller_Front::getInstance() ->getParam('bootstrap'); if(! empty($bootstrap) ){ $bootstrapOptions = $bootstrap->getOptions(); $this->_keyPlugin = $this->_getKeyPlugin($bootstrapOptions['resources']['frontController']['plugins']); if($this->_keyPlugin){ if(! empty($bootstrapOptions[$this->_keyPlugin]['config'])){ $this->_setConfig($bootstrapOptions[$this->_keyPlugin]['config']); } } //@TODO añadir una excepción $this->_parseFilePath(); $this->_parseXPath(); if( $this->_config['autoload'] ){ $this->_loadXmlFile(); $this->_setXPath(); } } } /* * Setea los daots en la variable _data * * @param SimpleXMLElement * @return void */ public function setData ( SimpleXMLElement $data ) { $this->_data = $data; if(!empty ($this->_keyPlugin) ){ Zend_Controller_Front::getInstance() ->setParam($this->_keyPlugin, $this->_data); } } /* * Devueble el XML obtenido * * @return Cuatroxl_Controller_Plugin_DataPage $_data * */ public function getData () { return $this->_data; } /* * Configura todas las opiones de la clase * * @var array * @return Cuatroxl_Controller_Plugin_DataPage Provides a fluent interface * */ protected function _setConfig( array $config) { foreach ($config as $k => $v){ if(!empty ($v)){ $this->_config[$k] = $v; } } return $this; } /* * Carga el archivo XML * * @var string * @return Cuatroxl_Controller_Plugin_DataPage Provides a fluent interface * */ protected function _loadXmlFile( string $fileName = NULL ) { if( $fileName === NULL ){ $fileName = $this->_filePath; } if( file_exists( $fileName ) ){ $data = simplexml_load_file( $fileName ); $this->setData( $data ); } return $this; } /* * Ejecuta una query sobre el XML con xpath y devuelve TRUE o FALSE según el exito de la consulta * * @var string * @return Boolean * */ protected function _setXPath( string $path = NULL ) { if( $path === NULL){ $path = $this->_xpath; } if( empty($this->_xpath) ){ return false; } $data = $this->_data->xpath($this->_xpath); if( empty ($data[0]) ){ return false; }else{ $this->setData( array_shift( $data ) ); return true; } } /* * remplaza los comodines en la ruta al XML y devuelve TRUE o FALSE * según el exito de la consulta * * @return Boolean * */ private function _parseFilePath() { //@TODO indagar para hacer este proceso con con Zend_Controller_Router_Route if(! preg_match_all("/:[^\/\.]+/s", $this->_config['filePath'], $matches) ){ return false; } $request = $this->getRequest(); $values = array(); $matches = $matches[0]; foreach($matches as $v){ $values[] = $request->getParam(substr($v, 1)); } $matches[] = '/'; $values[] = DIRECTORY_SEPARATOR; $this->_filePath = str_replace($matches, $values, $this->_config['basePath'].$this->_config['filePath']); return true; } /* * remplaza los comodines en la ruta al nodop por defecto del XML * y devuelve TRUE o FALSE según el exito de la consulta * * @return Boolean * */ private function _parseXPath() { //@TODO indagar para hacer este proceso con con Zend_Controller_Router_Route if( empty ($this->_config['xpath']) ){ return false; } if(! preg_match_all("/:[\d\w_]+/s", $this->_config['xpath'], $matches) ){ $this->_xpath = $this->_config['xpath']; return true; } $request = $this->getRequest(); $values = array(); $matches = $matches[0]; foreach($matches as $v){ $values[] = $request->getParam(substr($v, 1)); } $this->_xpath = str_replace($matches, $values, $this->_config['xpath']); return true; } /* * Devuelve el nombre que se designó en el archivo de configuración * * @return string o false */ private function _getKeyPlugin(array $config) { foreach ($config as $k => $v){ if($v === 'Cuatroxl_Controller_Plugin_DataPage'){ return $k; } } return false; } }
Configuracion:
;definimos la clase, en este caso lo asociamos a "dataPage" resources.frontController.plugins.dataPage = "Cuatroxl_Controller_Plugin_DataPage" ;le decimos que la carga es automática dataPage.config.autoload = 1 ;la ruta del XML utilizando como comodín el parámetro LANG, nombre del controlador y acción dataPage.config.filePath = ":lang/:controller/:action.xml" ;el nodo, del XML, por defecto que tiene que cargar; también usando la variable PAGE dataPage.config.xpath = "pages/page[@id=':page']" ;el directorio raíz de donde están los XML dataPage.config.basePath = APPLICATION_PATH "/../public/data/"
Controller:
public function indexAction()
{
// El parámetro "dataPage" es el mismo nombre con que vinculamos en el archivo de configuración
var_dump($this->getFrontController()->getParam('dataPage'));
}
pdt: tengo que subirlo a Google Code; por lo que pronto colgaré la dirección con un manual más sencillo