Vous êtes sur la page 1sur 436

 

Kumbia Enterprise Framework 
Un Framework para el PHP Empresarial 
LouderTechnology 
www.loudertechnology.com 
Abril de 2009 
Versión del Producto: 1.0.17GA 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    2 

Tabla de Contenido 
1  Prefacio .................................................................................................................. 15 
1.1  Antes de Leer este Documento .................................................................................................................. 15 
1.2  Como esta organizado este Documento................................................................................................. 15 
1.3  Convenciones Tipográficas.......................................................................................................................... 16 
1.4  A Quien está Orientado este Texto........................................................................................................... 17 
1.5  Información sobre marcas y productos referenciados ................................................................... 17 
1.6  Referencias a sitios web de terceros....................................................................................................... 17 
1.7  Sus comentarios están bienvenidos ........................................................................................................ 18 
2  Introducción ........................................................................................................... 19 
2.1  Diferencias con la versión Comunitaria................................................................................................. 19 
2.2  Licencia ................................................................................................................................................................ 20 
3  Instalación .............................................................................................................. 21 
3.1  Introducción ...................................................................................................................................................... 21 
3.2  Configuración con Apache Web Server 2.x........................................................................................... 21 
3.3  Configuración con Microsoft IIS e ISAPI Rewrite .............................................................................. 23 
3.4  Configuración de PHP .................................................................................................................................... 24 
3.5  Configuración con Zend Application Server ........................................................................................ 25 
3.6  Crear una Instancia de Kumbia Enterprise .......................................................................................... 25 
3.7  Solución a problemas de instalación....................................................................................................... 25 
4  ¿Qué es Kumbia Enterprise Framework?................................................................. 28 
4.1  Sobre Aplicaciones Web ............................................................................................................................... 28 
4.2  Sobre PHP y la Web ........................................................................................................................................ 28 
4.3  Introducción ...................................................................................................................................................... 28 
4.4  Características del Framework.................................................................................................................. 29 
4.5  PHP en entornos críticos .............................................................................................................................. 30 
4.6  Preguntas frecuentes sobre Kumbia Enterprise................................................................................ 31 
5  Arquitectura ........................................................................................................... 34 
5.1  Introducción ...................................................................................................................................................... 34 
5.2  Capas en una Aplicación ............................................................................................................................... 34 
5.3  Usando Modelo‐Vista‐Controlador .......................................................................................................... 35 
5.4  Ventajas de usar MVC .................................................................................................................................... 36 
5.5  Arquitectura SOA............................................................................................................................................. 37 
5.6  Beneficios de una SOA ................................................................................................................................... 38 
5.7  SOA en Kumbia Enterprise .......................................................................................................................... 38 
5.8  Loose Coupling/Tight Coupling ................................................................................................................ 40 
6  Caso de Uso: Aplicación de Cajero Bancario ............................................................ 41 
6.1  Introducción ...................................................................................................................................................... 41 
6.2  Análisis de los Requerimientos ................................................................................................................. 41 
6.3  Esqueleto de la Aplicación........................................................................................................................... 45 
6.4  Configurar la conexión a la base de datos............................................................................................. 45 
6.5  Crear los modelos de Base de Datos........................................................................................................ 46 
6.6  Crear el Inicio de Sesión ............................................................................................................................... 49 
6.7  Autenticando al Cliente................................................................................................................................. 52 
6.8  Un Menú para la Aplicación ........................................................................................................................ 54 
6.9  Visualización del saldo del cliente............................................................................................................ 55 
6.10  Crear el TransactionActivity .................................................................................................................... 58 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    3 

7  Aplicaciones en Kumbia Enterprise ......................................................................... 62 


7.1  Introducción ...................................................................................................................................................... 62 
7.2  Instancias del framework ............................................................................................................................ 62 
7.3  Estructura de directorios de una Instancia.......................................................................................... 62 
7.4  Publicar contenido estático......................................................................................................................... 64 
7.5  Bootstrap............................................................................................................................................................. 65 
7.6  Crear la acción por defecto en una Aplicación.................................................................................... 66 
7.7  Crear un procedimiento de inicialización de la aplicación............................................................ 66 
7.8  Detectar un cambio en la ejecución de una instancia a otra......................................................... 67 
8  Componente Controller .......................................................................................... 68 
8.1  Introducción ...................................................................................................................................................... 68 
8.2  Como funciona el componente Controller?.......................................................................................... 68 
8.3  Crear un Controlador..................................................................................................................................... 70 
8.4  Servicios del Componente Router............................................................................................................ 71 
8.5  Servicios proporcionados por Dispatcher ............................................................................................ 73 
8.6  Excepciones Generadas en el Dispatcher.............................................................................................. 74 
8.7  Peticiones HTTP a Controladores............................................................................................................. 76 
8.7.1  Administrar archivos adjuntos en una petición .............................................................................. 77 
8.7.2  API de ControllerRequest........................................................................................................................... 78 
8.8  Respuestas HTTP de Controladores........................................................................................................ 81 
8.8.1  Establecer el tipo de salida de la Petición.......................................................................................... 82 
8.8.2  API de ControllerResponse........................................................................................................................ 83 
8.9  Controlar acciones no encontradas ......................................................................................................... 84 
8.10  Filtros en controladores............................................................................................................................. 85 
8.11  Enrutamiento en controladores ............................................................................................................. 86 
8.11.1  Ciclo de enrutamiento .............................................................................................................................. 86 
8.11.2  Enrutar usando Router::routeTo......................................................................................................... 87 
8.11.3  Enrutar usando Router::routeToURI() ............................................................................................. 88 
8.12  Inicialización de Controladores.............................................................................................................. 88 
8.13  Estado de persistencia de Controladores........................................................................................... 89 
8.13.1  Ventajas del Estado de Persistencia................................................................................................... 90 
8.13.2  Consideraciones del estado de Persistencia.................................................................................... 90 
8.13.3  Transacciones y Concurrencia del Estado de Persistencia ...................................................... 91 
8.13.4  Eventos del estado de Persistencia ..................................................................................................... 91 
8.14  La Clase ControllerBase ............................................................................................................................. 92 
8.15  La Clase Controller ....................................................................................................................................... 92 
8.15.1  API de Controller ........................................................................................................................................ 92 
8.16  Controladores usando ApplicationController .................................................................................. 96 
8.16.1  API de ApplicationController ................................................................................................................ 96 
8.16.2  Controladores usando MultiThreadController.............................................................................. 97 
8.17  Servicios Web usando WebServiceController.................................................................................. 98 
8.17.1  Qué es un Web Service?............................................................................................................................ 98 
8.17.2  Para que son necesarios los Web Services....................................................................................... 99 
8.17.3  Arquitectura Orientada a Servicios (SOA) ...................................................................................... 99 
8.17.4  Crear un Web Service .............................................................................................................................100 
8.17.5  WebServiceClient......................................................................................................................................102 
8.17.6  Obteniendo el WSDL de un Servicio Web.......................................................................................103 
8.17.7  Orquestación de servicios .....................................................................................................................104 
8.17.8  Características de Servicios Web en Kumbia Enterprise ........................................................106 
8.18  Controladores StandardForm ...............................................................................................................106 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    4 

8.18.1  Características de StandardForm.....................................................................................................106 
8.18.2  Limitantes de StandardForm..............................................................................................................107 
8.19  Plugins de Controladores ........................................................................................................................107 
8.19.1  Crear un Plugin de Controlador.........................................................................................................107 
9  Componente UDDI................................................................................................ 109 
9.1  Introducción ....................................................................................................................................................109 
9.2  Requerimientos..............................................................................................................................................109 
10  Componente BusinessProcess ............................................................................. 110 
10.1  Introducción..................................................................................................................................................110 
10.1.1  ¿Que es un proceso de negocio?..........................................................................................................110 
10.1.2  ¿Qué es BPEL? ............................................................................................................................................110 
10.2  Job Executor ..................................................................................................................................................110 
10.3  Crear un Proceso de Negocio.................................................................................................................110 
10.3.1  Tipos de nodos de un meta­proceso PDL........................................................................................112 
10.3.2  Crear los handlers del BusinessProcess ..........................................................................................113 
11  Componente Filter .............................................................................................. 114 
11.1  Introducción..................................................................................................................................................114 
11.2  Estructura del Componente ...................................................................................................................114 
11.3  Usar filtros en forma directa..................................................................................................................116 
11.4  Crear chains de Filtros..............................................................................................................................116 
11.5  Usar filtros en Controladores ................................................................................................................117 
11.6  Filtrar la entrada de usuario ..................................................................................................................118 
11.7  Crear un filtro de usuario ........................................................................................................................119 
11.7.1  Requerimientos de un filtro de usuario ..........................................................................................120 
12  ActionHelpers ..................................................................................................... 121 
12.1  Introducción..................................................................................................................................................121 
12.2  Mensajes usando Flash.............................................................................................................................121 
12.2.1  Generar mensajes contextuales..........................................................................................................121 
12.2.2  Cambiar el estilo por defecto de los mensajes .............................................................................121 
12.2.3  Cambiar el estilo en forma dinámica...............................................................................................122 
12.2.4  Enviar múltiples mensajes del mismo tipo en forma simúltanea........................................122 
12.2.5  Mostrar mensajes por su tipo..............................................................................................................123 
12.2.6  Cachear mensajes para mostrarlos en la próxima petición ..................................................123 
12.3  Condiciones SQL con FormCriteria .....................................................................................................124 
12.3.1  Criterios de Rangos..................................................................................................................................126 
12.3.2  Unir varias condiciones .........................................................................................................................127 
12.4  Información del Navegador con Browser ........................................................................................128 
12.4.1  API de Browser ..........................................................................................................................................128 
12.5  Autocompletar con Scriptaculous........................................................................................................130 
13  Componente Validator........................................................................................ 132 
13.1  Introducción..................................................................................................................................................132 
14  Seguridad con Kumbia Enterprise........................................................................ 133 
14.1  Introducción..................................................................................................................................................133 
14.2  Características de Seguridad..................................................................................................................133 
14.3  Mecanismos de Seguridad.......................................................................................................................134 
14.4  Seguridad a nivel de Capa de Aplicación ..........................................................................................134 
14.5  Seguridad a nivel de Capa de Transporte.........................................................................................135 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    5 

14.6  Implementar Seguridad Declarativa ..................................................................................................136 


14.7  Implementar Seguridad Programacional .........................................................................................138 
14.8  Definir Realms, Usuarios y Grupos para Autenticación .............................................................138 
14.8.1  Realms...........................................................................................................................................................138 
14.8.2  Usuarios........................................................................................................................................................139 
14.8.3  Grupos ...........................................................................................................................................................139 
15  Componente ACL (Lista de Control de Acceso) .................................................... 140 
15.1  Introducción..................................................................................................................................................140 
15.2  Estructura del Componente ...................................................................................................................140 
15.3  ¿Que es un Recurso? ..................................................................................................................................141 
15.4  ¿Que es un Rol? ............................................................................................................................................141 
15.5  ¿Que es un Acceso?.....................................................................................................................................141 
15.6  Tipos de Reglas ............................................................................................................................................141 
15.7  ACL en Acción...............................................................................................................................................141 
15.8  Herencia de Roles .......................................................................................................................................143 
15.9  Adaptadores de ACL ..................................................................................................................................143 
15.9.1  AclModel.......................................................................................................................................................144 
15.9.2  AclMemory...................................................................................................................................................144 
15.9.3  AclXML ..........................................................................................................................................................144 
15.10  API de un Adaptador...............................................................................................................................146 
15.11  API de AclResource ..................................................................................................................................147 
15.12  API de AclRole ...........................................................................................................................................147 
16  Componente Auth............................................................................................... 148 
16.1  Introducción..................................................................................................................................................148 
16.2  Adaptadores de Auth.................................................................................................................................148 
16.3  Administración de Identidad .................................................................................................................149 
16.4  Expiración de Sesión .................................................................................................................................149 
16.5  Control de Autenticación concurrente ..............................................................................................149 
16.6  Autenticación con Modelos.....................................................................................................................150 
16.7  Autenticación con KerberosV ................................................................................................................151 
16.8  Autenticación con Radius........................................................................................................................152 
16.9  Autenticación con Digest .........................................................................................................................153 
16.10  Autenticación con LDAP........................................................................................................................154 
17  Componente AuditLogger ................................................................................... 157 
17.1  Introducción..................................................................................................................................................157 
17.2  Crear un componente de control .........................................................................................................157 
18  Componente Security.......................................................................................... 158 
18.1  Introducción..................................................................................................................................................158 
18.2  Subcomponente SecurityFirewall........................................................................................................158 
18.2.1  Introducción ...............................................................................................................................................158 
18.2.2  Como se evaluan las reglas ..................................................................................................................159 
18.2.3  Tipos de Atributos de una Regla........................................................................................................159 
19  Persistencia, Transacciones y Concurrencia......................................................... 161 
19.1  Introducción..................................................................................................................................................161 
20  Componente Db.................................................................................................. 161 
20.1  Introducción..................................................................................................................................................161 
20.2  Capas de acceso ...........................................................................................................................................161 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    6 

20.3  Adaptadores del componente Db.........................................................................................................162 
20.4  Generación de SQL......................................................................................................................................164 
20.5  Conexiones a gestores relacionales por defecto............................................................................165 
20.5.1  Consideraciones para Oracle...............................................................................................................165 
20.5.2  Consideraciones para Microsoft SQL Server.................................................................................168 
20.5.3  Consideraciones para MySQL..............................................................................................................175 
20.5.4  Consideraciones para IBM Informix.................................................................................................178 
20.5.5  Consideraciones con SQLite .................................................................................................................181 
20.6  Pool de Conexiones ....................................................................................................................................182 
20.6.1  Conexiones de Bajo Nivel ......................................................................................................................182 
20.6.2  Trazar Conexiones ...................................................................................................................................183 
20.7  Generar Profiles de ejecución de SQL ................................................................................................184 
20.8  Manejar Excepciones de Db....................................................................................................................184 
20.8.1  Tipos de Excepciones lanzadas por el componente Db............................................................185 
20.8.2  Información extendida de excepciones generadas por Db.....................................................185 
20.9  Tipos de Resultado al Obtener de Registros ...................................................................................188 
20.10  Leer registros.............................................................................................................................................189 
20.11  Manipular Registros................................................................................................................................192 
20.12  Administrar Transacciones..................................................................................................................194 
20.13  Crear, Cerrar y obtener información de conexiones.................................................................196 
20.14  Información de Errores .........................................................................................................................197 
20.15  Obtener el valor de la columna identidad .....................................................................................197 
20.16  Obtener información de Tablas .........................................................................................................198 
20.17  Crear y Eliminar Tablas.........................................................................................................................198 
20.18  Fecha del gestor relacional ..................................................................................................................201 
20.19  Debug, Seguimiento y Traza ................................................................................................................201 
21  Componente Active Record ‐ ORM ...................................................................... 202 
21.1  Introducción..................................................................................................................................................202 
21.2  Cuando usar ActiveRecord......................................................................................................................203 
21.3  Entidades........................................................................................................................................................203 
21.3.1  Requerimientos de las Clases de Entidades...................................................................................203 
21.3.2  Atributos de las Entidades....................................................................................................................204 
21.4  Atributos y Campos persistentes .........................................................................................................204 
21.5  Llaves Primarias..........................................................................................................................................205 
21.6  Convenciones en llaves primarias .......................................................................................................206 
21.7  Fechas Auto‐Asignables ...........................................................................................................................206 
21.8  Multiplicidad en Relaciones de Entidades .......................................................................................206 
21.8.1  Convenciones en Relaciones.................................................................................................................207 
21.8.2  Relaciones Unidireccionales ................................................................................................................207 
21.8.3  Relaciones Bidireccionales ...................................................................................................................207 
21.8.4  Muchos a uno .............................................................................................................................................207 
21.8.5  Uno a Muchos.............................................................................................................................................209 
21.8.6  Uno a Uno ....................................................................................................................................................209 
21.8.7  Muchos a Muchos .....................................................................................................................................209 
21.9  API de ActiveRecord ..................................................................................................................................210 
21.9.1  Origen de Datos.........................................................................................................................................210 
21.9.2  Volcado de Meta­Datos..........................................................................................................................210 
21.9.3  Debug y Seguimiento ..............................................................................................................................210 
21.9.4  Transacciones ............................................................................................................................................211 
21.9.5  Consultar registros ..................................................................................................................................212 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    7 

21.9.6  Contar registros ........................................................................................................................................214 


21.9.7  Promediar registros ................................................................................................................................215 
21.9.8  Realizar sumatorias ................................................................................................................................215 
21.9.9  Obtener el valor máximo de un atributo........................................................................................215 
21.9.10  Obtener el valor mínimo de un atributo......................................................................................216 
21.9.11  Asignar valores a instancias .............................................................................................................216 
21.9.12  Validación .................................................................................................................................................216 
21.9.13  Información de atributos ...................................................................................................................217 
21.9.14  Creación y actualización de registros...........................................................................................218 
21.9.15  Eliminación de registros.....................................................................................................................219 
21.9.16  Operaciones en Batch ..........................................................................................................................219 
21.9.17  Lectura/escritura de Atributos .......................................................................................................219 
21.9.18  Validación .................................................................................................................................................219 
21.9.19  Multiplicidad de relaciones ...............................................................................................................220 
21.9.20  Herencia.....................................................................................................................................................221 
21.9.21  Excepciones ..............................................................................................................................................221 
21.10  Identifiers ....................................................................................................................................................221 
21.10.1  Establecer el Generador......................................................................................................................222 
21.10.2  Algoritmo Hi/Lo .....................................................................................................................................222 
21.10.3  Algoritmo UUID ......................................................................................................................................223 
21.10.4  Generador UniqId ..................................................................................................................................224 
21.10.5  Generador Native...................................................................................................................................224 
21.10.6  Columnas Identidad y Secuencias ..................................................................................................224 
21.11  Convenciones en Identificadores ......................................................................................................225 
21.12  Los Meta‐datos en ActiveRecordMetadata ...................................................................................226 
21.12.1  Tipos de Meta­Datos Almacenados................................................................................................226 
21.12.2  Meta­Datos en etapas de Desarrollo .............................................................................................227 
21.12.3  API de ActiveRecordMetaData.........................................................................................................227 
21.13  Cursores y Resulsets de Consultas ...................................................................................................229 
21.13.1  Utilizar el cursor como tipo Forward­Only ................................................................................229 
21.13.2  Utilizar el cursor como Scrollable ..................................................................................................229 
21.13.3  API de ActiveRecordResulset ............................................................................................................230 
21.14  Mensajes de ActiveRecord ...................................................................................................................231 
21.14.1  API de ActiveRecordMessage............................................................................................................232 
21.15  Transacciones en ActiveRecord.........................................................................................................232 
21.15.1  Administracion de Transacciones ..................................................................................................233 
21.15.2  Sincronización de Recursos con Transacciones .......................................................................236 
21.15.3  Consideraciones de Sincronización................................................................................................236 
21.15.4  API de TransactionDefinition...........................................................................................................239 
21.15.5  API de ActiveRecordTransaction ....................................................................................................239 
21.15.6  Timeouts en Transacciones...............................................................................................................240 
21.16  Validadores de Integridad de Datos.................................................................................................241 
21.16.1  Validadores para atributos No­Nulos...........................................................................................243 
21.16.2  Tratar el resultado de un proceso de Validación.....................................................................243 
21.16.3  Validadores de Usuario .......................................................................................................................245 
21.16.4  Eventos en la Validación.....................................................................................................................246 
21.16.5  Implementar un evento de validación..........................................................................................249 
21.16.6  Detener/Cancelar una operación...................................................................................................250 
21.16.7  Establecer un evento con un nombre no estándar..................................................................250 
21.16.8  Evento cuando el proceso de validación detiene la operación ..........................................251 
21.16.9  Deshabilitar eventos de validación................................................................................................252 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    8 

21.17  Llaves Foráneas Virtuales.....................................................................................................................252 
21.17.1  Crear una llave foránea virtual.......................................................................................................253 
21.17.2  Opciones de las llaves foráneas .......................................................................................................254 
21.18  Entidades Temporales ...........................................................................................................................255 
21.18.1  Crear un TemporaryActiveRecord .................................................................................................256 
21.18.2  Comportamiento de un TemporaryActiveRecord....................................................................256 
21.18.3  Transacciones con Entidades Temporales .................................................................................257 
21.18.4  Usar un TemporaryActiveRecord ...................................................................................................257 
21.19  ActiveRecordJoin......................................................................................................................................259 
21.19.1  Agrupamientos con ActiveRecordJoin ..........................................................................................262 
21.19.2  Parámetros de ActiveRecordJoin ....................................................................................................262 
21.20  ActiveRecordUnion .................................................................................................................................263 
21.21  SessionRecord ...........................................................................................................................................263 
21.22  PropertyAccessors y Mutators ...........................................................................................................264 
21.23  DynamicUpdate y DynamicInsert .....................................................................................................264 
21.24  Manejo de Excepciones..........................................................................................................................265 
21.24.1  Capturar excepciones dentro de modelos ...................................................................................266 
21.24.2  Información de Excepciones .............................................................................................................266 
21.25  Plugins de Modelos..................................................................................................................................266 
21.25.1  Crear un Plugin de ActiveRecord ....................................................................................................267 
21.26  Organización de Modelos......................................................................................................................267 
21.27  Auto‐inicialización de Modelos ..........................................................................................................268 
21.27.1  Activar inicialización dinámica.......................................................................................................269 
22  Componente EntityManager ............................................................................... 270 
22.1  Introducción..................................................................................................................................................270 
22.2  Obtener una nueva instancia de un Modelo....................................................................................270 
22.3  API del Componente EntityManager ..................................................................................................271 
22.3.1  Métodos para inicializar modelos y obtener instancias de ellos .........................................271 
22.3.2  Métodos para administrar relaciones de multiplicidad..........................................................272 
22.3.3  Métodos adminitrar para Entidades Temporales......................................................................273 
22.3.4  Origenes de datos .....................................................................................................................................274 
22.3.5  Administrar generadores de entidades ..........................................................................................274 
22.3.6  LLaves foráneas virtuales.....................................................................................................................274 
23  Componente TransactionManager ...................................................................... 276 
23.1  Introducción..................................................................................................................................................276 
23.2  Contexto de Scope Persistente..............................................................................................................276 
23.3  Event Listeners ............................................................................................................................................276 
23.4  Estados de las entidades..........................................................................................................................277 
23.5  Asignar el objeto al estado administrado.........................................................................................277 
23.6  API de TransactionManager...................................................................................................................278 
24  Presentación....................................................................................................... 279 
24.1  Introducción..................................................................................................................................................279 
25  Componente View .............................................................................................. 280 
25.1  Introducción..................................................................................................................................................280 
25.2  Jerarquía de vistas en la presentación...............................................................................................280 
25.2.1  Vista Principal ...........................................................................................................................................281 
25.2.2  Requerimientos de la Vista Principal ..............................................................................................282 
25.2.3  Requerimientos Vistas a nivel de Controlador ............................................................................282 
25.2.4  Requerimientos de Layouts de Controladores.............................................................................283 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    9 

25.2.5  Requerimientos de Vistas Parciales en Controladores.............................................................283 
25.2.6  Requerimientos de Vistas Parciales Generales............................................................................283 
25.2.7  Requerimientos de Plantillas ó Templates....................................................................................284 
25.3  Inserción automática y manual de vistas .........................................................................................284 
25.4  Implementar los tipos de vistas............................................................................................................285 
25.5  Transferir valores del controlador a la vista ..................................................................................288 
25.5.1  Transferir mediante atributos públicos .........................................................................................288 
25.5.2  Transferir mediante setParamToView ...........................................................................................289 
25.6  Controlar Niveles de Renderización...................................................................................................290 
25.7  Utilizar modelos en la presentación ...................................................................................................291 
25.8  Plugins de View............................................................................................................................................291 
25.8.1  Crear un Plugin de View ........................................................................................................................291 
25.9  API del Componente View.......................................................................................................................292 
25.9.1  Jerarquia de renderización ..................................................................................................................292 
25.9.2  Administrar presentación.....................................................................................................................292 
25.9.3  Visualizar vistas programacionalmente........................................................................................293 
25.10  Crear un componente de Presentación personalizado............................................................294 
25.11  Crear un componente de presentación de Excepciones no capturadas...........................295 
25.12  Integrar otros Engines de presentación.........................................................................................296 
25.12.1  Comportamiento de la integración................................................................................................296 
25.12.2  Componentes Soportados...................................................................................................................296 
26  Componente Tag................................................................................................. 299 
26.1  Introducción..................................................................................................................................................299 
26.2  Establecer el valor de helpers creados con Tag.............................................................................299 
26.3  Comportamiento de helpers ..................................................................................................................300 
26.4  API del Componente Tag .........................................................................................................................300 
26.4.1  Crear enlaces..............................................................................................................................................300 
26.4.2  Componentes de interfaz de usuario ...............................................................................................303 
26.4.3  Componentes de listas/combos..........................................................................................................304 
26.4.4  Tratamiento de etiquetas META .......................................................................................................310 
26.4.5  Tratamiento e Inclusión de archivos CSS.......................................................................................310 
26.4.6  Componentes para fechas.....................................................................................................................311 
26.4.7  Incluir recursos Javascript ...................................................................................................................312 
26.4.8  Interacción con la presentación ........................................................................................................313 
27  Helpers JavaScript............................................................................................... 315 
27.1  Introducción..................................................................................................................................................315 
27.2  Clase Format .................................................................................................................................................315 
27.2.1  Instanciando la clase ..............................................................................................................................315 
27.2.2  Funciones de Format ..............................................................................................................................317 
27.3  Clase Validator .............................................................................................................................................318 
27.3.1  Instanciando la clase ..............................................................................................................................318 
28  Componente PDFDocument................................................................................ 320 
28.1  Introducción..................................................................................................................................................320 
28.2  Crear un documento PDF ........................................................................................................................320 
28.3  Agregar una tabla al documento ..........................................................................................................320 
28.4  Tipos de Papel Soportados .....................................................................................................................322 
28.5  API de PdfDocument..................................................................................................................................322 
29  Componente Report ........................................................................................... 329 
29.1  Introducción..................................................................................................................................................329 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    10 

29.2  Alcance del componente..........................................................................................................................329 
29.3  Adaptadores de Report ............................................................................................................................329 
29.4  Paginación en reportes.............................................................................................................................331 
29.5  Ejemplo de un listado usando Report................................................................................................331 
29.6  Modo Vista Previa.......................................................................................................................................332 
29.7  API de Report................................................................................................................................................333 
30  Componente Feed............................................................................................... 334 
30.1  Introducción..................................................................................................................................................334 
30.2  Leer/Importar documentos RSS ..........................................................................................................334 
30.3  Crear documentos RSS .............................................................................................................................334 
30.4  API de Feed....................................................................................................................................................335 
30.4.1  API de FeedItem ........................................................................................................................................336 
31  Componente Core ............................................................................................... 338 
31.1  Introducción..................................................................................................................................................338 
31.2  Jerarquía de Clases .....................................................................................................................................338 
31.2.1  Clase Object.................................................................................................................................................338 
31.2.2  CoreConfig ...................................................................................................................................................338 
31.2.3  CoreLocale...................................................................................................................................................338 
31.2.4  CoreClassPath ............................................................................................................................................338 
31.2.5  CoreRemote.................................................................................................................................................338 
31.3  Servicios del Componente Core............................................................................................................338 
31.3.1  Obtener el Instance Name ....................................................................................................................338 
31.3.2  Zona Horaria de las Aplicaciones......................................................................................................339 
31.3.3  Cambiar el Charset de la aplicación.................................................................................................339 
31.3.4  Cambiar la localización por defecto ................................................................................................340 
31.3.5  Obtener la versión del Framework ...................................................................................................340 
31.4  Subcomponente CoreConfig...................................................................................................................341 
31.4.1  API del subcomponente CoreConfig .................................................................................................341 
31.5  Subcomponente CoreClassPath............................................................................................................342 
31.5.1  Reemplazar un componente del Framework...............................................................................342 
31.5.2  API de CoreClassPath..............................................................................................................................343 
31.6  Subcomponente CoreType......................................................................................................................343 
31.6.1  API de CoreType........................................................................................................................................343 
31.7  Crear Plugins de Aplicación....................................................................................................................344 
31.7.1  Crear un Plugin de Aplicación ............................................................................................................344 
32  Componente PluginManager .............................................................................. 346 
32.1  Introducción..................................................................................................................................................346 
32.2  Arquitectura de Plug‐Ins .........................................................................................................................346 
32.3  Autoinicialización de Plug‐Ins...............................................................................................................346 
32.4  API de PluginManager ..............................................................................................................................346 
33  Internacionalización y Localización...................................................................... 349 
33.1  Introducción..................................................................................................................................................349 
34  Componente Locale ............................................................................................ 350 
34.1  Introducción..................................................................................................................................................350 
34.2  Definir la localización en una sesión de Usuario...........................................................................350 
34.2.1  Obtener la localización adecuada.....................................................................................................350 
34.3  Establecer la localización por defecto................................................................................................351 
34.4  Obtener traducciones localizadas........................................................................................................351 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    11 

34.5  API del Componente Locale....................................................................................................................352 
34.6  Subcomponente LocaleMath..................................................................................................................356 
34.6.1  API de LocaleMath ...................................................................................................................................356 
35  Componente Traslate.......................................................................................... 358 
35.1  Introducción..................................................................................................................................................358 
35.2  Adaptadores soportados por Traslate...............................................................................................358 
35.3  Como funciona la traducción .................................................................................................................358 
35.4  Utilizar traducciones .................................................................................................................................359 
35.4.1  Consideraciones para el adaptador Array ....................................................................................360 
35.4.2  Consideraciones para el adaptador Csv .........................................................................................360 
35.4.3  Consideraciones para el adaptador Ini...........................................................................................360 
35.4.4  Consideraciones para el adaptador Database ............................................................................360 
36  Componente Date............................................................................................... 361 
36.1  Introducción..................................................................................................................................................361 
36.2  Porque debe usar este componente ...................................................................................................361 
36.3  Timestamps ilimitados .............................................................................................................................361 
36.4  Establecer el Timezone ............................................................................................................................362 
36.5  Obtener partes ó fragmentos de fechas ............................................................................................362 
36.6  Posición en el Tiempo ...............................................................................................................................363 
36.7  Información de Fechas .............................................................................................................................364 
36.8  Cambiar fragmentos de la fecha ...........................................................................................................365 
36.9  Operaciones con fechas............................................................................................................................366 
36.10  Localización de Fechas...........................................................................................................................367 
36.11  Establecer el formato de la fecha ......................................................................................................368 
36.12  Obtener la fecha y hora mundial .......................................................................................................370 
37  Componente Currency ........................................................................................ 371 
37.1  Introducción..................................................................................................................................................371 
37.2  Cantidades usando el formato adecuado..........................................................................................371 
37.3  Simbolo y nombre de la moneda utilizada.......................................................................................371 
37.4  Versiones escritas de cantidades .........................................................................................................372 
37.5  API del Componente Currency..............................................................................................................373 
38  Componente ApplicationMonitor ....................................................................... 375 
38.1  Introducción..................................................................................................................................................375 
38.2  Infraestructura de Eventos comunes .................................................................................................375 
38.3  Componentes de la Infraestructura de Eventos ............................................................................376 
38.3.1  CommonBaseEvent..................................................................................................................................376 
38.3.2  Emmiter........................................................................................................................................................376 
38.3.3  Event Service ..............................................................................................................................................376 
38.4  ¿Porque usar monitorización? ..............................................................................................................376 
38.4.1  Determinación de problemas..............................................................................................................376 
38.4.2  Sintonización del Rendimiento...........................................................................................................376 
38.4.3  Confiabildad de la Operación..............................................................................................................377 
38.5  ¿Qué se puede monitorear?....................................................................................................................377 
39  Componente CommonEvent ............................................................................... 378 
39.1  Introducción..................................................................................................................................................378 
40  Componentes de Propósito General.................................................................... 379 
40.1  Introducción..................................................................................................................................................379 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    12 

41  Componente Config ............................................................................................ 380 


41.1  Introducción..................................................................................................................................................380 
41.2  Adaptadores de Config .............................................................................................................................380 
41.2.1  Adaptador de configuración Ini.........................................................................................................380 
41.2.2  Adaptador de configuración XML .....................................................................................................381 
41.2.3  Adaptador de configuración Arrays de PHP ................................................................................381 
41.2.4  Adaptador de configuración Yaml....................................................................................................382 
41.2.5  Leer archivos de configuración ..........................................................................................................382 
41.2.6  Ejemplo: Leer un archivo de configuración ..................................................................................382 
42  Componente Extensions ..................................................................................... 383 
42.1  Introducción..................................................................................................................................................383 
42.2  Cargar una extensión dinámicamente ...............................................................................................383 
42.3  Cargar una extensión estáticamente ..................................................................................................383 
42.3.1  Cargar componentes de Zend Framework ....................................................................................384 
42.4  Cargar archivos individuales al iniciar la petición .......................................................................384 
42.5  Obtener información de extensiones cargadas..............................................................................384 
42.6  Inyección de componentes .....................................................................................................................385 
43  Componente Logger............................................................................................ 386 
43.1  Introducción..................................................................................................................................................386 
43.2  Adaptadores de Logger ............................................................................................................................386 
43.3  Tipos de Eventos en Logs ........................................................................................................................389 
43.4  Logger Facilities ..........................................................................................................................................390 
43.5  Transacciones con Logs ...........................................................................................................................391 
43.6  API de FileLogger........................................................................................................................................392 
43.7  Uso de MailLogger ......................................................................................................................................393 
43.8  Uso de DatabaseLogger............................................................................................................................394 
43.9  Uso de CompressedLogger .....................................................................................................................394 
43.10  Uso de SAMLogger ...................................................................................................................................396 
43.11  Uso de StreamLogger..............................................................................................................................396 
43.12  Uso de SocketLogger...............................................................................................................................398 
44  Componente Utils ............................................................................................... 399 
44.1  Introducción..................................................................................................................................................399 
44.2  API de Utils ....................................................................................................................................................399 
45  Rendimiento y Optimización ............................................................................... 401 
45.1  Introducción..................................................................................................................................................401 
45.2  Consideraciones de Rendimiento ........................................................................................................401 
45.2.1  Utilización de parámetros por nombre ..........................................................................................401 
45.2.2  Instalar un Cache de OpCode ..............................................................................................................401 
45.2.3  Sintonización del Servidor Web .........................................................................................................402 
45.2.4  Sintonización de PHP..............................................................................................................................403 
46  Componente Cache............................................................................................. 404 
46.1  Introducción..................................................................................................................................................404 
47  Componente Compiler ........................................................................................ 405 
47.1  Introducción..................................................................................................................................................405 
47.2  Teoria de optimización avanzada........................................................................................................406 
47.2.1  Optimización de ciclos............................................................................................................................406 
47.2.2  Optimización por evaluación de terminos estáticos.................................................................406 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    13 

47.3  Comportamiento de Compiler...............................................................................................................406 
47.3.1  Optimizaciones básicas de la compilación....................................................................................406 
47.3.2  Optimizaciones avanzadas de la compilación.............................................................................407 
47.4  Generar una Compilación........................................................................................................................408 
47.5  Limitaciones de Compiler........................................................................................................................408 
48  Componente GarbageCollector ........................................................................... 409 
48.1  Introducción..................................................................................................................................................409 
48.2  ¿Porque usar este componente?...........................................................................................................409 
48.3  Como funciona el GarbageCollector....................................................................................................409 
48.3.1  Fase de Compresión.................................................................................................................................409 
48.3.2  Fase de Eliminación.................................................................................................................................409 
48.4  Activar el GarbageCollector....................................................................................................................410 
48.4.1  Activación de manera programacional..........................................................................................410 
48.4.2  Activación de manera declarativa....................................................................................................410 
48.5  Parámetros del Collector.........................................................................................................................410 
48.6  API de GarbageCollector ..........................................................................................................................411 
49  Componente Session........................................................................................... 412 
49.1  Introducción..................................................................................................................................................412 
49.2  Adaptadores de Sesión .............................................................................................................................413 
49.2.1  Adaptador de Sesión Memcache ........................................................................................................414 
49.2.2  Adaptador de Sesión Database...........................................................................................................414 
49.2.3  Adaptador de sesión Files .....................................................................................................................414 
49.2.4  Adaptador de sesión Louder Cache ..................................................................................................415 
49.3  Comportamiento de Sesiones................................................................................................................415 
49.4  Consideraciones de Seguridad ..............................................................................................................415 
49.5  Variables de sesión.....................................................................................................................................416 
49.5.1  API del Componente Session................................................................................................................416 
49.6  SessionNamespace .....................................................................................................................................417 
49.6.1  API de SessionNameSpace ....................................................................................................................418 
50  Herramientas del Desarrollador .......................................................................... 420 
50.1  Introducción..................................................................................................................................................420 
51  Errores y Excepciones.......................................................................................... 420 
51.1  Introducción..................................................................................................................................................420 
51.2  Modo SUPER_STRICT ................................................................................................................................421 
51.3  Capturar excepciones de gravedad leve ...........................................................................................421 
52  Componente Debug ............................................................................................ 423 
52.1  Introducción..................................................................................................................................................423 
52.2  Seguimiento al estado de variables.....................................................................................................423 
52.3  Visualizar la traza del seguimiento de un valor.............................................................................424 
52.4  Detener un proceso mediante Aserciones .......................................................................................425 
52.5  Establecer una acción a ejecutar al finalizar el proceso de debug ........................................426 
53  Test de Unidad.................................................................................................... 427 
53.1  Introducción..................................................................................................................................................427 
53.2  Tests para Componentes .........................................................................................................................427 
54  Componente Script ............................................................................................. 428 
54.1  Introducción..................................................................................................................................................428 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    14 

55  Apendices ........................................................................................................... 429 


55.1  Estándares de Codificación.....................................................................................................................429 
55.1.1  Objetivos.......................................................................................................................................................429 
55.1.2  Formato de Archivos PHP.....................................................................................................................429 
55.1.3  Clases .............................................................................................................................................................429 
55.1.4  Interfaces .....................................................................................................................................................429 
55.1.5  Métodos.........................................................................................................................................................429 
55.1.6  Variables ......................................................................................................................................................430 
55.1.7  Constantes ...................................................................................................................................................430 
55.1.8  Boleanos y valores nulos .......................................................................................................................430 
55.1.9  Literales de Cadenas de Caracteres..................................................................................................430 
55.1.10  Substituciones de variables ...............................................................................................................430 
55.2  Licencia de este Documento...................................................................................................................430 
55.2.1  Creative Commons Attribution 3.0 ...................................................................................................430 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    15 

1 Prefacio
El presente documento es documento todo‐en‐uno de guía de referencia, API y tutorial para el 
desarrollo  de  aplicaciones  usando  Kumbia  Enterprise  Framework.  El  prefacio  contiene 
información sobre las convenciones utilizadas para desarrollar este texto. 

1.1 Antes de Leer este Documento

Antes  de  leer  este  texto  usted  debe  tener  un  buen  conocimiento  de  lenguaje  PHP, 
programación  orientada  a  objetos,  tecnologías  para  desarrollo  Web  como  HTML,  CSS, 
JavaScript y otras como XML, AJAX, SQL, así como conocimientos en bases de datos y sistemas 
operativos. 

1.2 Como esta organizado este Documento

Kumbia Enterprise es un framework robusto para el desarrollo de aplicaciones empresariales 
usando  tecnologia  abierta  para  ambientes  con  altos  requerimientos  de  estabilidad, 
rendimiento  y  escalabilidad.  Toda  su  robustez  esta  plasmada  en  este  extenso  documento  y 
espera ofrecer toda la información posible para el entendimiento y aprovechamiento de esta 
plataforma. 
 
El documento ofrece una referencia de cada componente, junto con ejemplos y la API de cada 
uno. Se busca que relacione la arquitectura de los componentes y como se integran unos con 
otros en forma de servicios.  
 
La  primera  parte  explica  para  que  y  donde  puede  utilizar  Kumbia  Enteprise  Framework 
características,  su  instalación  y  la  arquitectura  de  las  aplicaciones  como  introducción  al 
contexto de desarrollo e implementación.   
 
El capitulo de Tutorial realiza la creación de una aplicación completa paso a paso como caso 
de estudio, integrando los diferentes componentes y aplicando la mayor parte del Framework 
como base ilustrativa del mismo. 
 
La segunda parte detalla la capa de lógica de dominio explicando todo lo relacionado con la 
orquestación de controladores y servicios Web. 
 
La tercera parte explica cada componente y características de seguridad en el framework. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    16 

 
La cuarta parte habla de la lógica de datos y detalla términos de persistencia, concurrencia y 
transacciones. 
 
La  quinta  parte  explica  las  características  y  componentes  de  internacionalización  y 
localización  que  permiten  adaptar  aplicaciones  a  condiciones  especificas  geográficas, 
políticas, culturales ó regionales. 
 
La  sexta  parte  presenta  los  componentes  de  la  capa  de  presentación  y  las  herramientas  de 
interacción con el usuario final hacia la aplicación. 
 
La séptima parte explica componentes de monitorización y componentes de propósito general 
para el desarrollo de aplicaciones Web. 
 
La octava parte explica los componentes que ayudan a mejorar el rendimiento y optimización 
de aplicaciones. 
 
La novena parte detalla el componente de administración, contexto y persistencia de sesiones 
de usuario. 
 
La  décima  parte  son  las  herramientas  del  desarrollador  como  test  de  unidad,  debug  de 
procesos y datos, generación de código etc. 

1.3 Convenciones Tipográficas

La siguiente tabla describe las condiciones tipográficas usadas en este texto: 
 
Fuente  Significado  Ejemplo 
AaBbCdDeFf  Hace  referencia  a  extranjerismos  del  El  servidor  de  directorios 
lenguaje castellano que hacen referencia  LDAP 
a  componentes,  productos,  marcas, 
nombres de métodos ó módulos. 
AaBbCdDeFf Hace  referencia  a  código  fuente  ó  <?php
$filter = new Filter();
sentencias SQL. 
AaBbCdDeFf Hace  referencia  a  Pseudocódigo  para  valor := LLamarFuncion();
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    17 

representar  fragmentos  de  código  ó 


procedimientos en lenguaje humano. 
 
1.4 A Quien está Orientado este Texto

Este  documento  está  orientado  a  personas  que  deseen  aprender  en  forma  profunda  las 
capacidades  de  Kumbia  Enterprise  Framework  para  el  desarrollo  de  aplicaciones,  soporte  a 
software existente y/o extender el mismo. 

1.5 Información sobre marcas y productos referenciados

Las  siguientes  son  marcas  de  productos  referenciados  que  pertenecen  a  otras  compañias  y 
son mencionadas en este documento: 
 
Excel  ,  Windows,  SQL  Server  y  Word  son  marcas  registradas  de  Microsoft  Corporation  en 
estados unidos y otros países. 
Oracle  es una marca registrada de Oracle Corporation en estados unidos y otros países. 
Informix  es una marca registrada de IBM en estados unidos y otros países. 
DB2  es una marca registrada de IBM en estados unidos y otros países. 
Adobe  Acrobat    es  una  marca  registrada  de  Adobe  Corporation  en  estados  unidos  y  otros 
países. 
Windows  es  una  marca  registrada  de  Microsoft  Corporation  en  estados  unidos  y  otros 
países. 
Mac OS X es una marca registrada de Apple en estados unidos y otros países. 

1.6 Referencias a sitios web de terceros

Algunas  URLs  son  referenciadas  en  este  documento  y  proporcionan  información  asociada  a 
estas. 
 
Nota:  LouderTechnology  no  se  hace  responsable  por  la  disponibilidad  de  sitios  web  de  terceros 
mencionados  en  este  documento.  LouderTechnology  no  se  hace  responsable  por  el  contenido, 
publicidad,  productos  ó otros materiales que estén disponibles en estos  sitios.  LouderTechnology 
no se hace responsable por daños ó perdidas causadas bajo ó sin conexión con el contenido en esos 
sitios y recursos. 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    18 

1.7 Sus comentarios están bienvenidos

En LouderTechnology estamos interesados en el mejoramiento la documentación de nuestros 
y  sus  productos  y  proyectos,  por  esto  sus  comentarios  están  siempre  bienvenidos.  La 
referencia  de este documento es KEF‐1108. Escriba a support@loudertechnology.com 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    19 

Capítulo Introducción 
 

2 Introducción
Kumbia Enterprise es un framework PHP cuyo principal objetivo es la practicidad y facilidad 
de uso, sin dejar de darle importancia al rendimiento, robustez, profesionalismo y calidad de 
una  aplicación  orientada  a  la  Web.  Esta  implementado  usando  la  versión  5.2  de  PHP  y  está 
completamente orientado a Objetos. Los componentes están integrados y optimizados lo cual 
aumenta el rendimiento interno del framework y de las aplicaciones desarrolladas con él. 

El  framework  adicionalmente  permite  usar  componentes  independientes  y  librerías  de 


terceros e integrarlas a las aplicaciones desarrolladas. 

Kumbia Enterprise Framework es una versión modificada del Kumbia Framework Comunitario 
versión  0.5,  el  cuál  ha  sido  estabilizado  y  refactorizado  para  aumentar  su  robustez  y 
velocidad.  La  versión  comunitaria  es  punto  fundamental  de  innovación  y  desarrollo  para  la 
constante  integración  a  la  versión  creada  por  LouderTechnology.  El  objetivo  de  este 
framework  es  fortalecer  el  desarrollo  de  aplicaciones  de  negocios  orientadas  a  una 
presentación  Web  que  funcionen  tanto  en  Intranets  como  en  Internet.  La  creación  de  sitios 
Web usando Kumbia Enterprise es posible, aunque pueda encontrar otras herramientas  más 
indicadas y ligeras para esta tarea.  

El presente documento explica en forma detallada cada componente del framework. 

2.1 Diferencias con la versión Comunitaria

La  versión  modificada  que  desarrollamos  en  Louder  Technology  ha  pasado  por  un  riguroso 
proceso  de  estabilización  y  calidad  que  exigen  entornos  de  producción  para  aplicaciones  de 
alta disponibilidad. 

Beneficios clave al usar Kumbia Enterprise: 

• Reducción de costos operacionales cuando se implementan grandes sistemas 
• Capacidad de escalamiento mejorada (clusterización, cache distribuido) 
• La posibilidad de obtener soporte en diferentes niveles que mitigue el riesgo y ayude a 
eliminar el lock‐in de proveedores de herramientas de desarrollo de software. 
• Integrar  las  aplicaciones  con  código  PHP5  existente  incluyendo  otros  frameworks 
como Zend Framework.  
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    20 

• Facilidades  en  la  integración  requerida  para  implementar  arquitecturas  orientadas  a 


servicios (SOA). 
 
Otras mejoras esta versión:  

• Soporte para múltiples aplicaciones certificado  
• Estructura de archivos optimizada para múltiples aplicaciones  
• Soporte para Transacciones de Alto y Bajo nivel 
• Adaptadores de conexión a gestores relacionales certificados 
• Requerimientos de hardware reducidos en un 40%  
• Adaptadores de Manejadores de Sesión escalables  
• Políticas de Seguridad con adaptadores para gestores relacionales, LDAP, Kerberos5 y 
otros  

2.2 Licencia

Los  modelo  de  negocios  open‐source  está  diseñado  para  permirle  tanto  a  usted  como  a  sus 
socios  expandirse  desde  pequeñas  instalaciones  hasta  las  más  grandes  sin  generarle 
sobrecostos adicionales.  
 
Kumbia Enterprise Framework es un proyecto de software abierto con una licencia apta para 
negocios  aprovada  por  la  OSI  (http:///www.opensource.org)  llamada  New  BSD  y  que  se 
entrega con la distribución del framework. 
 
Soporte comercial para desarrollo, producción y entrenamiento están disponibles a través de 
LouderTechnology. 
 
 
 
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    21 

3 Instalación
3.1 Introducción

Kumbia  Enterprise  Framework  requiere  de  PHP  versión  5.2.0  ó  superior  para  un 
funcionamiento optimo. El framework requiere del Apache Web Server preferiblemente en su 
versión 2.0 ó 2.2 y del modulo mod_rewrite instalado para su correcto funcionamiento. 
 
Kumbia Enterprise Framework soporta adicionalmente Microsoft Internet Information Services 
(IIS) desde la versión 6.0 utilizando el modulo del servidor ISAPI_Rewrite. 
 
Al  descargar  el  paquete  de  Kumbia  Enterprise  Framework  este  debe  ser  descomprimido  y 
ubicado en la raíz de documentos del servidor Web  ó en un subdirectorio de este, este puede 
variar de acuerdo a la plataforma ó distribución utilizada. 

3.2 Configuración con Apache Web Server 2.x

Kumbia  Enterprise  Framework  implementa  soporte  para  Smart  URLs  lo  cual  las  hace  más 
familiares  y  humanas  para  los  usuarios  finales.  Para  esto  es  necesario  instalar  el  modulo  de 
Apache llamado mod_rewrite que realiza la reescritura de las URLs a una convención interna 
en  el  framework,  esto  es  vital  para  la  correcta  implementación  del  patrón  arquitectacional 
Model‐View‐Controller. 

Apache  proporciona  el  comando  a2enmod  en  la  mayoría  de  distribuciones  Linux,  mediante 
este comando se puede habilitar fácilmente el modulo, después solo es necesario reiniciar el 
servidor Web. 

Con el usuario administrador root utilizamos el comando así:  

# a2enmod rewrite
# /etc/init.d/apache2 restart
 
En algunos sistemas como RedHat/Fedora el comando para reiniciar el servidor es:  
 
# service httpd restart
 
Para  Microsoft  Windows  es  necesario  habilitar  el  modulo  directamente  en  el  archivo  de 
configuración de Apache. Para esto se quita el comentario dejando que el modulo de Apache 
Web Server sea cargado:  
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    22 

LoadModule rewrite_module modules/mod_rewrite.so


 
Las  reglas  de  reescritura  del  framework  deben  ser  leídas  por  Apache  y  ejecutadas  en  cada 
petición a la aplicación. Para esto es necesario habilitar la lectura de los archivos .htaccess ó 
agregar las reglas al archivo de configuración de Apache. 
 
La  ubicación  del  archivo  httpd.conf  ó  default‐server.conf  puede  variar  de  acuerdo  a  la 
distribución Linux ó el sistema operativo. 
 
Tabla:  Directorio  de  publicación  web  y  configuración  del  servidor  en  diversas 
plataformas 
Distribución   Ubicación   Directorio Raíz Web  

RedHat Enterprise 4/5   /etc/httpd/conf/httpd.conf   /var/www/html  

OpenSuSE  /etc/apache2/default‐
/srv/www/htdocs/  
10.1/10.2/10.3/11   server.conf  

/etc/apache2/sites‐
Ubuntu/Debian   /var/www  
available/default  

MacOS  X  (Leopard  10.5) 


/Applications/MAMP/conf/
usando  /Applications/MAMP/htdocs/  
apache/httpd.conf  
MAMP  

c:\Archivos  de 
Windows XP/2003  c:\Archivos  de 
Programa\xampp\apache\c
usando XAMPP   Programa\xampp\apache\htdocs\  
onf\httpd.conf  
 
Las  reglas  de  reescritura  de  mod_rewrite  pueden  ir  en  los  archivos  .htaccess  incluidos  en  el 
framework  ó  en  los  archivos  de  configuración  de  Apache  Web  Server.  Las  siguientes  reglas 
deben pertenecer al archivo .htaccess ó al directorio raíz donde esta el framework:  

<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^$ public/ [L]
RewriteRule (.*) public/$1 [L]
</IfModule>

 
Las segundas reglas de configuración deben ir en el archivo .htaccess ubicado en el directorio 
public/ así:  
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    23 

 
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
</IfModule>

Cuando  utilizamos  archivos  .htaccess  es  necesario  habilitar  las  opciones  AllowOverride  All  y 
Options All para el directorio raíz del Web Server en el archivo de configuración de Apache. 
Cuando  agregamos  la  configuración  directamente  a  los  archivos  de  Apache  Web  Server 
debemos usar la directiva Directory así:  
 
Tabla: Parámetros de configuración de Apache Web Server directamente en httpd.conf 
<Directory "/srv/www/htdocs/application">
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^$ public/ [L]
RewriteRule (.*) public/$1 [L]
/IfModule>
</Directory>
<Directory "/srv/www/htdocs/application/public">
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
</IfModule>
</Directory>

 
Si  no  requerimos  de  la  utilización  de  archivos  .htaccess  es  recomendable  desabilitarlos 
mediante  AllowOverride  None,  de  esta  forma  evitamos  que  el  servidor  Web  busque  este 
archivo  en  cada  directorio  en  cada  petición  Web  aumentando  considerablemente  el 
rendimiento de las aplicaciones. 
También  es  importante  revisar  que  el  archivo  index.php  sea  el  primero  en  la  directiva 
DirectoryIndex, así Apache Web Server le dará más prioridad antes de otras extensiones:  
DirectoryIndex index.php index.html

Después de realizar la configuración es necesario reiniciar el servidor Web. 

3.3 Configuración con Microsoft IIS e ISAPI Rewrite

Para  esto  debemos  agregar  al  archivo  httpd.ini  del  directorio  raíz  del  paquete  Kumbia  lo 
siguiente:  
 
Ejemplo: Parámetros de configuración para Microsoft IIS 
[ISAPI_Rewrite]
RewriteCond URL (?!/javascript/|/img/|/files/|/css/|/temp/).*
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    24 

RewriteRule (.*?\.php)(\?[^/]*)?/([^/]*)/(.*) $1(?2$2&:\?url=/$3/$4)


RewriteCond URL (?!/javascript/|/img/|/files/|/css/|/temp/).*
RewriteRule ^/(.*) /public/index.php?url=/$1 [L]
RewriteCond URL (?!/javascript/|/img/|/files/|/css/|/temp/).*
RewriteRule /(.*) /public/$1

Enlaces Relacionados  

• Configuración de Apache en RedHat Enterprise   


• PHP sobre Microsoft IIS  
• PHP sobre Apache 2.x sobre Windows  
• PHP sobre Apache 2.x sobre Unix/Linux  
• Instalando ISAPI Rewrite en Microsoft IIS  

3.4 Configuración de PHP

La siguiente configuración es opcional para Aplicaciones Web con Kumbia. A continuación se 
listan los parámetros de configuración del php.ini: 
 
Tabla: Parámetros de configuración de PHP opcionales 
Nombre   Descripción  

Permite usar las etiquetas especiales de php <?= y <. No se recomienda 
short_open_tag   si va a redistribuir sus aplicaciones en servidores de terceros. No es un 
estándar profesional de PHP el uso de estas etiquetas.  

Permite  que  al  generarse  un  error  se  muestren  las  rutas  y  archivos 
display_errors   donde se generan errores PHP, es útil en entornos development pero 
no en modo production.  

En  entornos  de  producción  64M  es  un  número  adecuado  para  este 
memory_limit  
parámetro por script. Debe ser ajustada de acuerdo a las circustancias. 

Kumbia Enterprise Framework esta desarrollado bajo nivel de reporte 
error_reporting   E_ALL  |  E_NOTICE  |  E_STRICT  lo  que  asegura  la  calidad  del  código  y 
cumplimiento de estándares básicos de desarrollo OOP en PHP5  

Permite  que  el  contenido  de  las  superglobales  se  convierta  en 
register_globals   variables locales. En general se debe dejar deshabilitado ya que no es 
seguro de muchas formas.  

Al estar en On podría ayudar a evitar ataques de inyección de SQL, al 
magic_quotes_gpc  
mismo tiempo hace que el rendimiento del servidor sea algo menor.  

session.use_only_coo Cuando  tiene  valor  1  ayuda  a  evitar  considerablemente  ataques  de 


LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    25 

kies   inyección de SQL y XSS.  
 

3.5 Configuración con Zend Application Server

Zend  Application  Server  es  un  servidor  para  aplicaciones  PHP  basado  en  Apache  Web  Server 
por lo tanto su configuración es similar.  
 
Puede seguir los pasos de configuración de Apache y reproducirlos en Zend Server. El módulo 
rewrite ya está activado por defecto lo que los pasos de configuración deben ser minimos. 

3.6 Crear una Instancia de Kumbia Enterprise

El  framework  se  distribuye  en  un  archivo  comprimido  multi‐plataforma  que  contiene  la 
estructura  de  archivos  del  framework  y  recursos  necesarios  para  el  desarrollo,  prueba  e 
implementación de aplicaciones en Kumbia Enterprise. 
 
El nombre del archivo tiene la siguiente estructura kumbia­ef­version­madurez­extension. 
 

3.7 Solución a problemas de instalación

Las siguientes situaciones se pueden presentar al realizar la instalación de una instancia del 
framework: 
 
Situación: No tiene Mod­ReWrite de Apache instalado 
El servidor web no tiene el modulo rewrite instalado, consulte la sección “Configuración con 
Apache Web Server 2.x” en el capítulo de instalación. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    26 

 
Situación:  En  la  pantalla  se  presenta  el  mensaje  “No  se  pudo  utilizar  reescritura  de 
URLs” 
 Se debe verificar lo siguiente: 
 
 Si  se  usa  Apache  Web  Server  el  archivo  '.htaccess'  debe  estar  presente  en  la  raíz  del 
directorio donde está la instancia del framework ó las reglas en este deben estar activas 
en la configuración del servidor web. 
 Apache Web Server soporta archivos de sobreescritura de configuración '.htaccess'.  
 La  opción  de  configuración  de  Apache  'AllowOverride  All'  no  está  presente  para  las 
opciones de configuración del DocumentRoot del servidor web. 
 
Situación:  Al  ingresar  a  la  aplicación  por  defecto  se  presenta  una  pantalla  blanca  sin 
ningún mensaje 
 
La  directiva  del  servidor  Web  de  archivos  por  defecto  le  está  dando  prioridad  al  archivo 
index.html y no al index.php. En el caso de Apache Web Server esto se soluciona mediante la  
opción de configuración DirectoryIndex. 
 
Situación:  Al  ingresar  a  la  aplicación  se  genera  la  excepción  “CoreException:  El 
directorio public/temp no tiene permisos de escritura” 
Esta excepción se genera cuando el directorio public/temp es un directorio de solo lectura ó 
no  tiene  permisos  de  escritura  para  el  usuario  con  el  que  se  ejecuta  el  proceso  del  servidor 
web. 
 
Situación: Al ingresar a la aplicación se genera la excepción “CoreException: Debe tener 
instalado PHP version 5.20 ó superior para utilizar este framework” 
La versión de PHP que tiene instalada es igual ó superior a la versión 5.0 pero es inferior a la 
5.2.0. La versión 5.2.0 en adelante corrige errores importantes de seguridad en en núcleo de 
PHP y tiene un mejor rendimiento. 
 
Situación: Al ingresar a la aplicación se genera la excepción “CoreException: Timezone 
inválido” 
Ha  definido  una  zona  horaria  en  el  archivo  config/config.ini  inválido  por  lo  que  muchas 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    27 

opciones del framework generarán información erronea. 
 
Situación: Al ingresar a la aplicación se genera la excepción “RouterException: No se ha 
indicado la aplicación por defecto en config/config.ini (defaultApp)” 
La  opción  defaultApp  en  el  archivo  de  configuración  de  la  instancia  no  existe  ó  define  una 
aplicación que no existe en la instancia del framework. 
 
Situación:  Al  ingresar  a  la  aplicación  se  genera  la  excepción:  “CoreConfigException: 
Debe indicar el nombre de la aplicación dende está el archivo 'config.ini'” 
La  opción  defaultApp  en  el  archivo  de  configuración  de  la  instancia  no  existe  ó  define  una 
aplicación que no existe en la instancia del framework. 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    28 

4 ¿Qué es Kumbia Enterprise Framework?


4.1 Sobre Aplicaciones Web

Cuando  la  web  se  empezó  a  tomar  más  en  serio,  no  solo  para  presentar  sitios  Web  con 
contenido  estático  ó  simplemente  informativo  y  se  dio  paso  a  la  prestación  de  servicios  con 
contenido  dinámico,  la  estructuración  y  profesionalización  de  las  aplicaciones  Web  se  hace 
evidente  como  una  forma  de  ofrecer  calidad  y  confiabilidad  a  clientes,  proveedores, 
inversionistas,  empleados  y  todo  el  entorno  de  las  empresas  y  organizaciones  en  forma 
novedosa y eficiente.  
 
La aceptación general del lenguaje PHP como herramienta especializada en el entorno Web y 
su  amplio  desenvolvimiento  así  como  sencillez  de  uso,  han  aportado  considerablemente  al 
crecimiento y capacidad de implementación de alta tecnología en la Web. 
 
Kumbia  Enterprise  es  un  paso  adelante  en  la  evolución  de  los  frameworks  y  de  PHP  como 
plataforma de desarrollo de carácter general.  

4.2 Sobre PHP y la Web

A  través  de  los  años  PHP  se  ha  convertido  en  un  estándar  de  facto  para  la  construcción  de 
software para Internet de alta escalabilidad y velocidad. Muchos de los sitios más populares y 
concurridos en la actualidad incluyendo Wikipedia, Yahoo! y Facebook.   

4.3 Introducción

Kumbia Enterprise Framework es un conjunto de tecnologías para la producción de software 
que  integra  una  novedosa  plataforma  de  middleware  proporcionando  servicios  de 
persistencia,  transacciones,  mensajes  y  clustering  a  aplicaciones  basadas  en  PHP  que  esten 
orientadas a la Web.  
 
Por años la madurez del desarrollo empresarial en PHP ha evolucionado incrementalmente y 
hoy  en  día  se  cuenta  con  productos  maduros  que  pueden  proporcionar  alternativas  que 
reduzcan  los  costos  de  tecnologías  de  información  y  puedan  ser  aplicados  a  entornos 
empresariales desde la mediana y pequeña empresa hasta grandes aplicaciones orientadas al 
cliente final. 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    29 

Nuestra  plataforma  pretende  unificar  la  plataforma  tecnológica  de  backend  y  frontend 
acelerando  los  procesos  de  desarrollo  e  implementación  de  software  usando  middleware 
multiplataforma escalable con tecnologia open‐source. Para lograr esto una de nuestras fichas 
claves es Kumbia Enterprise Framework. 
 
Kumbia  Enterprise  es  un  framework  especialmente  orientado  al  entorno  empresarial,  que 
implementa las mejoras prácticas de desarrollo de software y prácticas orientadas a las Web 
de  la  actualidad  e  intenta  fomentar  principalmente  la  generación  de  aplicaciones 
profesionales,  potentes,  seguras  y  mantenibles  en  el  tiempo  para  empresas  que  deseen 
adoptar software abierto y tecnología PHP.  
 
Gracias  al  apoyo  de  diferentes  empresas  patrocinadoras  y  de  LouderTechnology  ahora  es 
posible implementar aplicaciones con una base de código más sólida, estable y funcional junto 
con un servicio de soporte que asegure que su desarrollo y mejoramiento será continuo en el 
tiempo. 

4.4 Características del Framework

Sumadas a las de su hermano comunitario, Kumbia Enterprise Framework posee las siguientes 
características: 

• Arquitectura Modelo‐Vista‐Controlador (Múltiples Aplicaciones extendible con Plugins 
y Eventos) 
• Contenedor para aplicaciones y servicios web 
• Componente de Cacheo Flexible  
• Object‐Relational‐Mapping  (ORM)  potente  y  robusto  (Transacciones,  Validadores, 
Joins, Unions, Generadores, Multiplicidad de Relaciones, Herencia) 
• Business Process Management (BPEL) 
• Servicios Web (Integración y Orquestamiento) (Soap, SCA) 
• Componente  de  Administrador  de  Sesión  (Session  Handling)  Flexible  (Memcached, 
Database, LouderCache, Files) 
• Componente  de  Autenticación  (LDAP,  Model,  KerberosV,  Radius)  con  soporte  para 
Sesión Activa y Expiración de Sesión 
• Componente de Access List Control (ACL) Flexible (Model, Memory, Xml) 
• Componente de Auditoria de Sistemas  
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    30 

• Sistema de Logging Flexible (File, Compressed, Mail, Database,Stream,SCA) 
• Localización (Traducción, Fechas, Monedas) independiente de la plataforma  
• Monitoreo de Aplicaciones (CommonEventInfrastructure) 
• Componente para generación de reportes empresariales en múltiples formatos  (Pdf, 
Excel, Html) 
• Componente para implementación de servicios WebDAV  
• Componentes de conexión a motores de base de datos certificados (Oracle y MySQL)  
• Semi‐Compilador para el Framework y las aplicaciones 
• GarbageCollector de Sesión 
• Plantillas rápidas y flexibles  
• Filtros y Validación Integrada  
• Tests de Unidad 
• Debug, Traza y Profiling avanzado 
• Componente de Configuración Flexible (Ini, Xml, PHP) 
• Documentos PDF con PdfDocument 
• Integración con Louder Clustering Technology  
• Integración con Louder Cache  
• Integración con IBM WebSphere sMash 

4.5 PHP en entornos críticos


El lenguaje PHP no ha tenido una gran participación en entornos de aplicaciones críticas y en 
un  muchos  casos  ha  sido  relegado  a  la  creación  de  sitios  Web  y  portales.    Algunas 
características del lenguaje PHP como la tipificación débil y su carácter interpretado pueden y 
han hecho desconfiar a organizaciones en su implementación en software grande y complejo. 
 
Kumbia  Enterprise  Framework  ha  sido  diseñado  para  mantener  estrictos  controles  de 
validación  de  tipos  e  integridad  de  datos,  garantizando  en  gran  medida  que  los  procesos, 
entrada y salida de datos, cumplan a satisfacción con los requerimientos de negocio sin perder 
la potencia y capacidades para el desarrollo rápido que ofrece la tecnología PHP. 
 
Proyectos y productos como APC (Alternative PHP Cache), Zend Optimizer, eAccelator, Zend 
Guard  y  otros  más,  permiten  llevar  aplicaciones  en  PHP  a  un  carácter  semi‐interpretado  y 
hasta proteger la propiedad intelectual del código fuente del software. 
 
En  resumen  se  puede  decir  que  existe  actualmente  entornos  y  tecnología  que  permiten  el 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    31 

desarrollo e implementación satisfactoria de aplicaciones para entornos críticos basados en el 
lenguaje PHP. 

4.6 Preguntas frecuentes sobre Kumbia Enterprise

¿Para qué otro framework PHP? 
Como  se  ha  mencionado  anteriormente  PHP  ha  sido  un  lenguaje  usado  para  la  creación  de 
software y sitios web. Los frameworks actuales han avanzado mucho en este sentido y ofrecen 
todas  las  herramientas  necesarias  para  llevar  a  cabo  estos  proyectos.  La  inmediatez  en  el  
desarrollo es algo que todos los desarrolladores PHP hoy en día normalmente buscan.  
 
Por otro lado cuando el objetivo es desarrollar aplicaciones de misión critica, con procesos de 
negocio  complejos,  cientos  ó  miles  de  usuarios,  concurrencia  muy  alta,  necesidad  de 
integrarse a otros sistemas en otras plataformas de desarrollo y además se requiere que sean 
monitorizadas y que se adapten rápidamente a la evolución de los requerimientos del negocio, 
el panorama cambia.  
 
Para asegurar el éxito de proyectos complejos de software, aparte de la inversión de recursos 
de gerencia y administración, se requiere asegurar que esta inversión no se vaya a perder por 
seleccionar las herramientas equivocadas para llevar a cabo el proyecto.  
 
Es  difícil  determinar  cuando  un  proyecto  va  a  crecer  más  de  lo  que  se  espera  y  como  esto 
puede  a  obligar  a  cambiar  sobre  el  camino  un  diseño  erroneo  ó  en  el  peor  de  los  casos 
reescribir parte de los componentes de las aplicaciones para adaptarse a los cambios. 
 
Kumbia Enterprise nació precisamente cuando un software en PHP tuvo que prepararse para 
soportar  250.000  peticiones  diarias  (más  de  7  millones  al  mes),  15000  transacciones  y 
además ofrecer funcionalidad reusable a otras aplicaciones haciendo más mantenible toda la 
infraestructura de sistemas de una empresa.  La enseñanza: Es mejor pensar en grande ahora, 
tardar un poco más en desarrollar y no preocuparse en el futuro por el crecimiento, ni en las 
posibles  oportunidades  comerciales  ó  de  requerimientos  y  adaptabilidad  del  negocio  que  se 
puedan presentar en el ciclo de vida de un conjunto de sistemas. 
 
¿Por qué un framework para SOA? 
SOA es un concepto, no una tecnología. Un desarrollador puede implementar una arquitectura 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    32 

orientada  a  servicios  usando  otro  lenguaje  u  otro  framework,  no  necesariamente  debe  ser 
Kumbia Enterprise.  SOA tampoco es apto para cualquier proyecto, esto debe ser una decisión 
planeada y estrategica que beneficie y propenda por los objetivos de negocio de una empresa 
u organización.  
 
SOA  se  ha  convertido  en  un  estándar  de  la  industria  para  la  implementación  de 
infraestructuras  de  sistemas  que  requieran  una  alta  reusabilidad  y  flexibilidad  de  los 
componentes de las aplicaciones tanto internamente como externamente. Grandes compañias 
de  software  como  IBM,  JBoss  y  Oracle  invierten  grandes  cantidades  de  recursos  en  el 
desarrollo y mejoramiento de soluciones para empresas que busquen implementar este tipo 
de arquitecturas. 
 
Puede que tarde más tiempo en implementar una arquitectura eficiente y estable a partir de 
componentes poco acoplados de otros frameworks generandole contratiempos y en el peor de 
los casos perdidas en su inversión en IT. Kumbia Enterprise ha sido diseñado para facilitar la 
definición  y  construcción  de  SOA  utilizando  el  lenguaje  PHP  mediante  un  contenedor  de 
aplicaciones  y  servicios  web  diseñado  específicamente  para  este  tipo  de  arquitecturas  y 
también para aplicaciones orientadas a la web comunes. 
 
¿Kumbia  Enterprise  ofrece  más  o  menos  funcionalidad  que  el  Kumbia  PHP 
Comunitario? 
Kumbia  Enterprise  es  un  proyecto  con  objetivos  claros  diferentes  por  los  que  trabaja  el 
Kumbia  Comunitario  ó  otros  frameworks  como  Symfony  ó  CakePHP.  Este  framework  ha 
implementado muchos de los componentes que se requieren para construir aplicaciones Web 
pero además ofrece características empresariales únicas que facilitan el desarrollo de grandes 
y  medianas  aplicaciones  con  procesos  de  negocio  complejos  y  que  debido  a  su  naturaleza 
requieran de alguna funcionalidad especifica del framework. 
 
¿Por  qué  Kumbia  Enterprise  no  parece  ser  completamente  libre  y  manejado  por  la 
comunidad como lo es el Kumbia PHP Comunitario? 
Kumbia Enterprise tiene una licencia abierta llamada New BSD que ofrece libertades similares 
a  la  LGPL.    El  desarrollador  no  tiene  problema  en  crear,  distribuir  y  comercializar  software 
basado en el framework gracias a esta licencia.  
LouderTechnology busca liderar y asegurar el desarrollo activo y mejoramiento continuo del 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    33 

framework permitiendo que empresas y desarrolladores adopten el software tranquilamente 
y  se  puedan  enfocar  en  sus  propias  aplicaciones  ofreciendo  el  espacio  para  que  puedan 
retroalimentar aportar y colaborar  al proyecto retroactivamente. 
 
¿Trabajo  ó  he  trabajado  en  Zend  Framework,  como  puedo  integrarlo  con  Kumbia 
Enterprise? 
Los  componentes  del  Zend  Framework  pueden  ser  integrados  a  Kumbia  Enterprise 
cargandolos  como  extensiones  ya  sea  estáticamente  ó  dinámicamente.    Componentes  de 
usuario pueden registrar componentes de auto‐carga de zend ó hacer uso de los mismos. 
 
¿Conozco  ó  he  trabajado  desarrollando  en  Java,  que  puedo  esperar  de  Kumbia 
Enterprise? 
Este framework ha sido diseñado para ser familiar en muchos aspectos a los desarrolladores 
Java  y  también  a  los  desarrolladores  PHP.  Kumbia  Enterprise  tiene  estrictos  controles  de 
validación  en  busca  de  encontrar  más  problemas  y  de  tratar  de  identificar  potenciales 
posibles problemas que puedan tener los componentes desarrollados.  
 
Kumbia  Enterprise  además  permite  ejecutar  aplicaciones  bajo  IBM  WebSphere  sMash 
permitiendo integrar código nativo Java en aplicaciones PHP y viceversa aprovechando código 
y experiencia existente del desarrollador.  
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    34 

5 Arquitectura
5.1 Introducción

Kumbia Enterprise permite el desarrollo de aplicaciones en varias capas esto permite romper 
un  sistema  en  subsistemas  más  pequeños  reduciendo  la  complejidad  del  mismo  y 
proporcionando importantes beneficios.  
 
Cuando  se  trabaja  con  un  sistema  multi‐capa  se  entiende  que  existen  capas  de  alto  nivel  y 
otras  de  menor  nivel,  las  de  mayor  nivel  aprovechan  la  funcionalidad  implementada  en  las 
capas inferiores ocultando detalles que no requieren de un entendimiento inmediato aunque 
reduciendo la flexibilidad en una u otra medida. 
 
Los principales beneficios de implementar sistemas multi‐capa son: 
 
• Es posible trabajar sobre una capa superior sin necesidad de conocer como funcionan 
las capas inferiores. Cuando desarrolla con Kumbia Enterprise utiliza una capa de alto 
nivel que aumenta la productividad sin requerir el entendimiento en profundidad de  
comportamientos ó funcionalidad de bajo nivel.  
• Una capa puede ser sustituida por otra manteniendo una interface consistente que se 
adapte a necesidades especificas sin modificar la aplicación por completo. 

5.2 Capas en una Aplicación

Una aplicación Web desarrollada en Kumbia se separa en 3 capas principales llamadas: Lógica 
de Dominio, Persistencia y Presentación.  
 
La  lógica  de  dominio  ó  de  negocio  es  quien  dicta  las  reglas  sobre  como  debe  trabajar  la 
aplicación  en  si.  Constituye  todo  lo  que  tiene  que  ver  con  cálculos  de  entrada  de  datos, 
validaciones, procesos y como se presentaran los datos en la capa de presentación. 
 
La persistencia y/ó lógica del modelo de datos trata sobre como la lógica de dominio requiere 
de  los  datos  que  le  proporcionan  servicios  de  bases  de  datos,  sistemas  de  transacciones, 
mensajes, sistemas de archivos, etc. 
 
La  presentación  trata  de  todos  aquellos  elementos  que  permiten  la  interacción  entre  el 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    35 

usuario final y la aplicación. En una aplicación Web se refiere además a las tecnologías de lado 
del  cliente  como  CSS  ó  JavaScript,  los  navegadores,  los  lenguajes  de  marcas  y  de 
transformación. 
 
Cada capa mencionada anteriormente ofrece servicios y tiene responsabilidades diferentes en 
una  aplicación  empresarial,  la  clara  separación  de  estas  capas  es  fundamental  para  un 
desarrollo  satisfactorio.  Los  componentes  para  la  administración  y  uso  de  cada  capa  son 
proporcionados por el framework así como servicios de integración entre ellos también. 
 
5.3 Usando Modelo-Vista-Controlador

Las  aplicaciones  en  Kumbia  utilizan  el  patrón  arquitectacional  llamado  MVC.  Con  él  las 
aplicaciones Web se pueden separar en 3 capas bien definidas ayudando a la mantenibilidad 
de  la  misma  y  exigiendo  un  orden  y  claridad  que  con  el  tiempo  alarga  la  vida  útil  de  las 
mismas. 

• Modelos: Representan la información sobre la cual la aplicación opera, las entidades y 
su lógica de negocio. Contienen todas las validaciones, constraints y reglas que hacen 
que  la  lógica  del  negocio  se  cumpla  y  haya  integridad  en  los  datos.  Corresponde  a  la 
capa de persistencia. 
• Vistas: Visualizan el modelo usando interfaces Web e interactuando con los usuarios 
de éstas. Corresponde a la capa de Presentación. 
• Controladores: Atienden, responden y enrutan las acciones solicitadas por el usuario 
final  e  invocan  cambios  en  las  vistas  ó  en  los  modelos  según  sea  necesario. 
Corresponde a la capa de lógica de dominio. 

Los  controladores  están  separados  en  partes,  llamadas  front  controller  y  en  un  conjunto  de 
acciones. Cada acción puede interactuar de forma diferente de acuerdo al tipo de petición. Las 
vistas están separadas en layouts, templates, vistas de acción y partials. El modelo ofrece una 
capa de abstracción de la base de datos llamada ORM que además dan funcionalidad agregada 
a datos de sesión y validación de integridad relacional. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    36 

Este modelo ayuda a separar el trabajo de la lógica de negocios (modelos) y la presentación 
(Vistas) 
 
El controlador ayuda a ocultar los detalles de protocolo utilizados en la petición (HTTP, modo 
consola, etc.) para el modelo y la vista. Finalmente, el modelo abstrae la lógica de datos, que 
hace a los modelos independientes de las vistas. 
 
Kumbia  Enterprise  Framework  agrega  componentes  y  plugins  que  interactúan  con  la 
arquitectura de la aplicación. 
 
Enlaces Relacionados  
• Modelo Vista Controlador  

5.4 Ventajas de usar MVC

Al implementar el patrón arquitectacional MVC es posible separar claramente la forma en la 
que  se  presenta  la  información,  de  la  forma  en  la  que  se  almacena,  de  la  forma  en  la  que 
orquesta la lógica de la aplicación. De esta forma es menos complicado: 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    37 

 
• Detectar en que capa se esta generando un problema de la aplicación. Por ejemplo si 
un  proceso  no  se  esta  ejecutando  correctamente  es  muy  probable  que  el  problema 
este en el controlador. 
• Si se agrega un nuevo constraint (restricción) al modelo de datos este se aplica a todo 
el sistema inmediatamente. 
• Si  los  diseñadores  requieren  trabajar  en  la  presentación  esto  es  posible  sin  que  se 
afecte la lógica de negocio ó el modelo de datos. 
• Definitivamente  la  aplicación  se  hace  más  mantenible  y  reusable  creando  unidades 
que interactúan entre si y están separadas en forma lógica de manera clara. 

5.5 Arquitectura SOA

La arquitectura SOA proporciona estrategias al desarrollo e integración de infraestructuras de 
software que permiten utilizar la funcionalidad de un sistema como servicios interoperables. 
Las  arquitecturas  SOA  permiten  el  intercambio  transparente  de  datos  entre  diferentes 
aplicaciones.  Un  SOA  permite  que  haya  loose  coupling  de  servicios  entre  diferentes 
aplicaciones, sistemas operativos y lenguajes de desarrollo.  
 
Por  muchos  años  las  empresas  han  tratado  de  integrar  múltiples  aplicaciones  con  el  fin  de 
apoyar  los  procesos  de  negocio  en  cada  uno  de  sus  departamentos  y  de  ofrecer  de  forma 
automatizada información a sus proveedores y clientes. 
 
Durante  estos  procesos  es  normal  encontrarse  con  inconvenientes  como  incompatibilidad 
entre  lenguajes,  formatos,  plataformas,  etc.  Por  esto  la  industria  tecnológica  ha  creado  todo 
tipo de estrategías que conlleven al mejoramiento y exito de este tipo de integraciones.   
 
SOA  es  una  estrategía  que  no  es  aplicable  a  todo  tipo  de  organizaciones  pero  si  es  muy 
recomendable.  En  el  mundo  PHP  esta  arquitectura  ha  sido  poco  adoptada  debido  a  su  poco 
desarrollo, exploración y culturización. Actuamente PHP proporciona librerias y funcionalidad 
que permite ofrecer servicios web usando diferentes protocolos, pero SOA es mucho más que 
servicios web. 
 
Los siguientes conceptos son parte de lo que representa una arquitectura SOA: 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    38 

SOA  Governance:  Son  todas  las  actividades  relacionadas  a  tener  control  sobre  una  SOA.  En 
términos  cortos  se  puede  decir  que  son  las  reglas  con  las  que  se  implementa  y  adopta  esta 
arquitectura. 
 
Orquestación y Coreografía de Servicios: Aunque no es directamente dependiente de una 
SOA es fundamental cuando se implementan procesos de negocio complejos. 
 
Business  Process  Management:  Permite  el  mejoramiento  y  optimización  de  procesos  de 
negocio aprovechando la arquitectura en si misma.  
 
Y  aunque  existen  muchos  más,  Kumbia  Enterprise  ha  trabajo  en  proporcionar  herramientas 
que permitan la rápida adopción de un arquitectura orientada a servicios basada en PHP y su 
objetivo es ofrecer un ambiente cada vez más robusto que permita lograr este objetivo. 

5.6 Beneficios de una SOA

Las tres beneficios más importantes de adoptar una arquitectura SOA son: 
 
• Al  generar  cada  unidad  de  negocio  como  un  servicio  y  poder  usarlo  rápidamente  en 
una aplicación, se promueve la agilidad al cambio en forma más efectiva que mediante 
sistemas aislados . 
• Al  utilizar  servicios  se  crean  abstracciones  autosuficientes  capaces  de  mejorarsen 
afectando en forma positiva a sus dependencias en forma transparente. 
• Los  servicios  son  en  cierta  forma  auto‐documentados  lo  cual  es  muy  importante  al 
desarrollar sistemas flexibles y adaptables. 

5.7 SOA en Kumbia Enterprise

En este apartado trataremos de ilustrar como Kumbia Enterprise mediante su contenedor de 
servicios y aplicaciones permite la rápida adopción de SOA en una organización. 
 
Controladores  Inteligentes:  Como  se  vió  anteriormente,  Kumbia  Enterprise  utiliza  el 
concepto  de  controlador,  quienes  son  los  que  atienden  las  peticiones  realizadas  desde  el 
cliente  y  ejecutan  la  lógica  de  negocio  adecuada  para  producir  una  salida  en  una  vista.  El 
framework proporciona algo que hemos denominado “controladores inteligentes”.   
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    39 

Cuando  una  aplicación  en  Kumbia  Enterprise  recibe  una  petición  esta  es  analizada  para 
determinar el tipo de cliente y tipo de respuesta adecuada que espera este cliente.  
 
El siguiente diagrama muestra el funcionamiento del contenedor: 
 

 
Según  el  diagrama  una  aplicación  puede  recibir  peticiones  de  diferentes  clientes  solicitando 
respuestas adecuadas al tipo de cliente.  El diagrama separa a los clientes de las aplicaciones 
en tres: 
 
Usuarios Finales/Visitantes: Un usuario que utiliza la aplicación y que espera obtener una 
respuesta humana que pueda entender para continuar realizando otro proceso.  
 
Maquinas  Servicios  Web:  Maquinas  que  consumen  servicios  web  y  que  requieren  de 
mantener sesiones conversacionales. Por ejemplo SOAP ó REST. 
 
Maquinas  Proceso  de  Datos:  Clientes  web  que  solicitan  a  aplicaciones  datos  en  formatos 
adecuados que puedan ser procesados por el mismo cliente. Por ejemplo JSON ó XML. 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    40 

El contenedor de Kumbia Enterprise analiza el solicitud de respuesta  del cliente y transfiere 
la  solicitud  al  controlador/accion  adecuado  que  en  cada  uno  de  los  casos  tendrá  un 
tratamiento diferente. 
 
La capa Enterprise Service Layer es opcional y cuando se accede directamente a la aplicación 
esta no existe. La capa es el ESB (Enterprise Service Bus) el cual tiene un servicio registrado y 
puede modificar y monitorizar el acceso a los servicios. 
 
La capa Domain Layer es una super capa que abstrae la implementación de todos los procesos 
de  negocio.  La  capa  Application  Layer  son  las  aplicaciones/controladores/servicios  como  tal 
que componen el proceso de negocio requerido. 

5.8 Loose Coupling/Tight Coupling

Uno  de  los  objetivos  de  diseño  de  Kumbia  Enterprise  Framework  es  buscar  que  el 
arquitecto/desarrollador no tenga que integrar ningún componente para definir la estructura 
de  su  aplicación  por  esta  razón  varios  componentes  son  dependientes  los  unos  de  los  otros 
proporcionando un entorno ready­to­use donde sea posible desarrollar y ejecutar aplicaciones 
empresariales favoreciendo principios de reusabilidad y rendimiento de cualquier aplicación. 
 
Los  patrones  de  diseño  VirtualProxy  y  DependecyInjection  son  utilizados  para  permitirle  al 
desarrollador reemplazar/integrar componentes escritos por terceros a la aplicación. 
 
Muchos otros componentes están pensados en ser débilmente acoplados ó loose coupling de 
tal forma que puedan ser integrados a otras aplicaciones escritas en otros frameworks.  
 
Kumbia  Enterprise  Framework  ofrece  avanzada  funcionalidad  cuyo  nivel  de  madurez  es 
similar ó superior al de otros frameworks PHP actuales. 
 
 
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    41 

Capítulo Tutorial 
 

6 Caso de Uso: Aplicación de Cajero Bancario


6.1 Introducción

En  el  presente  capitulo  del  manual  de  referencia  se  tratará  de  ilustrar  con  un  ejemplo  de 
aplicación las principales características del Framework en un ejemplo práctico. 
 
La  idea  es  crear  una  aplicación  que  sirva  como  un  futuro  cajero  electrónico  virtual  para  un 
banco llamado Central Bank. Las reglas del negocio son las siguientes: 
 
• Los  clientes  del  banco  pueden  entrar  a  la  sucursal  virtual  usando  el  número  de  su 
identificación personal y la clave de alguna de sus tarjetas. 
• Una vez autenticados los clientes pueden consultar sus extractos, hacer transferencias 
a otras cuentas y revisar su saldo. 
 
El  desarrollo  e  implementación  de  aplicaciones  bancarias  exige  requerimientos  altísimos  de 
seguridad,  prestaciones,  alta  disponibilidad,    infraestructura  de  redes  y  probablemente  la 
implementación de muchas reglas financieras y bancarias para que el sistema sea funcional y 
usable. Sin embargo, para que nuestro ejemplo no sea eterno y no se salga de contexto, vamos 
a crear un sistema muy simplificado pero que sirva para entender los conceptos y entorno de 
trabajo con el Framework. 
 
Puede que sea necesario entender los conceptos de ORM (ActiveRecord) y el funcionamiento 
del componente Controller y View, para una mayor comprensión del presente Tutorial. 

6.2 Análisis de los Requerimientos

Haciendo un análisis más profundo del tema identificamos las siguientes entidades: 
 
• Clientes: Son el usuario final de la aplicación y se asume que habrá una entidad donde 
se mantendrá la información asociada a ellos. 
• Cuentas:  Manejan  el  saldo  actual  de  la  cuenta,  su  saldo  en  canje  y  su  relación  a 
clientes. 
• Movimiento:  Almacena  un  log  de  las  operaciones  realizadas  por  el  cliente  en  sus 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    42 

cuentas y será utilizado para generar los extractos del cliente. 
• Intereses: Son los intereses ganados por el cliente cada día que tiene su dinero en el 
banco. 
• Sucursales: Es la ubicación en la que se realiza la transacción bancaria. 
 
Para desarrollar el ejemplo se utiliza una base de datos usando el RBDM MySQL 5.0, esta base 
de datos es multiplataforma y se instala fácilmente en la mayor parte de sistemas operativos. 
El nombre de la base de datos será ‘bankdb’. Creamos la base de datos así: 
 
CREATE DATABASE nombre_bd CHARACTER SET utf8;
 
La estructura de las tablas será la siguiente: 
 
Tabla Customer: Administra la información de los clientes del banco 
 
CREATE TABLE `customer` (
`id` int(11) NOT NULL auto_increment,
`identification` varchar(20) NOT NULL,
`sucursal_id` int(11) NOT NULL,
`name` varchar(120) NOT NULL,
`email` varchar(52) default NULL,
`created_at` datetime default NULL,
`status` char(1) default NULL,
PRIMARY KEY (`id`),
KEY `sucursal_id` (`sucursal_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Descripción de los campos: 
Campo  Descripción 
id  Es la llave primaria de la tabla y es auto numérica. 
identification  Es el numero de identificación de la persona. 
sucursal_id  Es el código de la sucursal donde se creó la cuenta. 
name  Es el nombre de la persona 
email  Es el correo electrónico del cliente 
created_at  Es la fecha en la que se creó el cliente en la base de datos 
status  Es el estado del cliente en el banco. (A)ctivo ó (I)nactivo 
 
Tabla Account: Administra la información de las cuentas y sus saldos 
 
CREATE TABLE `account` (
`id` int(11) NOT NULL auto_increment,
`number` int(22) NOT NULL,
`password` varchar(40) NOT NULL,
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    43 

`sucursal_id` int(11) NOT NULL,


`customer_id` int(11) NOT NULL,
`balance` decimal(30,6) NOT NULL,
`swap_balance` decimal(30,6) NOT NULL,
`type` char(1) NOT NULL,
`created_at` datetime default NULL,
`status` char(1) default NULL,
PRIMARY KEY (`id`),
KEY `clientes_id` (`customer_id`),
KEY `sucursal_id` (`sucursal_id`),
CONSTRAINT `account_ibfk_1` FOREIGN KEY (`customer_id`) REFERENCES `customer`
(`id`),
CONSTRAINT `account_ibfk_2` FOREIGN KEY (`sucursal_id`) REFERENCES `sucursal`
(`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
Descripción de los campos: 
 
Campo  Descripción 
id  Es la llave primaria de la tabla y es auto numérica. 
number  Es el número de la cuenta 
password  Es el resumen SHA1 de la clave de la cuenta 
sucursal_id  Es la sucursal en donde se creó la cuenta. 
customer_id  Es el cliente al que pertenece la cuenta 
balance  Es el saldo que tiene la cuenta. 
swap_balance  Es el saldo que tiene en canje. 
type  Indica si la cuenta es de ahorros ó corriente. 
created_at  Es la fecha en la que se creó la cuenta en la base de datos 
status  Es el estado del cliente en el banco. (A)ctivo ó (I)nactivo 
 
Tabla Movement: Administra la información de los movimientos realizados en las cuentas 
 
CREATE TABLE `movement` (
`id` int(11) NOT NULL auto_increment,
`account_id` int(11) NOT NULL,
`ubication_id` int(11) NOT NULL,
`cash` decimal(30,6) NOT NULL,
`created_at` datetime default NULL,
PRIMARY KEY (`id`),
KEY `account_id` (`account_id`),
KEY `ubication_id` (`ubication_id`),
CONSTRAINT `movement_ibfk_2` FOREIGN KEY (`ubication_id`) REFERENCES
`ubication` (`id`),
CONSTRAINT `movement_ibfk_1` FOREIGN KEY (`account_id`) REFERENCES `account`
(`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
Descripción de los campos: 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    44 

Campo  Descripción 
id  Es la llave primaria de la tabla y es auto numérica. 
account_id  Es la cuenta en la que se realizó el movimiento 
ubication_id  Es la ubicación en la que se generó el movimiento 
cash  Es el monto por el que se realizó el movimiento 
created_at  Es la fecha en la que se creó la cuenta en la base de datos 
 
Tabla Sucursal: Administra la información de las sucursales del banco 
 
CREATE TABLE `sucursal` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(120) NOT NULL,
`ubication_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `id` (`id`),
KEY `ubication_id` (`ubication_id`),
CONSTRAINT `sucursal_ibfk_1` FOREIGN KEY (`ubication_id`) REFERENCES
`ubication` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
Descripción de los campos: 
 
Campo  Descripción 
id  Es la llave primaria de la tabla y es auto numérica. 
name  Nombre  de la sucursal 
ubication_id  Es la ubicación donde se encuentra la sucursal 
 
Tabla  Ubication:  Administra  la  información  de  las  ubicaciones  donde  se  pueden  realizar 
operaciones bancarias. 
 
CREATE TABLE `ubication` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(120) NOT NULL,
PRIMARY KEY (`id`),
KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
Descripción de los campos: 
Campo  Descripción 
id  Es la llave primaria de la tabla y es auto numérica. 
name  Nombre  de la Ubicación 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    45 

6.3 Esqueleto de la Aplicación

Una  vez  creado  el  modelo  de  datos  generamos  el  esqueleto  de  aplicación  donde  irá  ubicado 
los  archivos  fuente  de  la  arquitectura  MVC.  Para  esto  debemos  crear  un  directorio  llamado 
‘bank’  en  apps  y  los  subdirectorios  controllers,  config,  models  y  views.  Una  forma  rapida  de 
crear el esqueleto de la aplicación es utilizar el script create_application.php en modo consola: 
 
Al ubicarse dentro del directorio donde esta la instancia del Framework usamos el comando: 
 
php script/create_application.php –name bank
 
El nombre del directorio que tiene el Framework se llama ‘example’. La siguiente estructura 
de archivos se ha creado: 
 
example/
apps/
default/
bank/
controllers/
application.php
config/
boot.ini
config.ini
environment.ini
routes.ini
logs/
models/
base/
modelBase.php
views
layouts/
index.phtml

Una vez definida la estructura de directorios de la aplicación es posible empezar a desarrollar 
sobre ella. La aplicación se encuentra en entorno de desarrollo y todo lo relacionado con ello 
esta activado por defecto. 

6.4 Configurar la conexión a la base de datos

Para  empezar  a  probar  los  controladores  y  la  iteración  con  los  modelos  es  necesario 
configurar la conexión a la base de datos que se va a utilizar en el entorno de desarrollo. Para 
esto se edita el archivo de configuración environment.ini creado en el directorio config: 
 
[development]
database.host = localhost
database.username = root
database.password = 2fe0517
database.name = bankdb
database.type = mysql
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    46 

Estos  parámetros  serán  usados  en  toda  la  aplicación  para  conectarse  a  la  base  de  datos  de 
desarrollo. Kumbia Enterprise Framework permite definir una arquitectura de 3 capas en caso 
de que se necesite utilizar la base de datos en un servidor externo al de desarrollo. 

6.5 Crear los modelos de Base de Datos

Un  modelo  debe  ir  ubicado  en  el  directorio  models  de  la  aplicación.  Los  nombres  de  los 
archivos de modelos “deben” tener el nombre de la tabla a mapear (esto es una convención). 
En  cada  archivo  debe  existir  una  sola  clase  con  el  nombre  del  modelo  usando  notación 
camelizada. Las clases de modelos “deben” heredar de la clase ActiveRecord. 
 
Un  ejemplo  de  un  modelo  de  la  tabla  ubication  es  el  archivo  models/ubication.php  que 
implementa la clase Ubication así: 
 
<?php
class Ubication extends ActiveRecord {
}

Al definir un modelo con una implementación de atributos ‘vacía’ se indica a ActiveRecord que 
debe crear los atributos de la tabla en forma dinámica y por lo tanto la visibilidad de esta será 
pública. En general esto no es una buena practica de desarrollo ya que se deja al descubierto 
la  privacidad  de  los  valores  de  los  campos  sin  que  haya  ningún  control  en  su  acceso.    Para 
solucionar esto e implementar un modelo más seguro se hace así: 
 
<?php
class Ubication extends ActiveRecord {
protected $id;
protected $name;
public function getId(){
return $this->id;
}
public function setId($id){
$this->id = $id;
}
public function getName(){
return $this->name;
}
public function setName($name){
$this->name = $name;
}

}
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    47 

Los  getters  y  setters  proporcionan  puntos  unificados  para  obtener/establecer  los  valores 
internos del modelo. En general, cada tabla que se utilice en la aplicación debe ser mapeada 
por un modelo en la misma. El script create_all_models.php permite crear todos los modelos de 
la base de datos actual implementando cada clase como se vió en el ejemplo anterior. El uso 
del script es el siguiente: 
 
php scripts/create_all_models.php –-application bank
 
Adicional  a  los  getters/setters  generados,  el  script  agrega  los  PHPDocs  a  cada  método  y 
atributo con lo que se mejora la documentación del sistema y si se utilizan IDEs como Zend 
Studio ó Eclipse estos comentarios son leídos ayudando a autocompletar el código cuando sea 
posible. 
 
El modelo para la tabla customer generado es: 
 
<?php
class Customer extends ActiveRecord {
/**
* @var integer
*/
protected $id;
/**
* @var string
*/
protected $identification;
/**
* @var integer
*/
protected $sucursal_id;
/**
* @var string
*/
protected $name;
/**
* @var string
*/
protected $email;
/**
* @var Date
*/
protected $created_at;
/**
* @var string
*/
protected $status;

/**
* Metodo para establecer el valor del campo id
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    48 

* @param integer $id


*/
public function setId($id){
$this->id = $id;
}
/**
* Metodo para establecer el valor del campo identification
* @param string $identification
*/
public function setIdentification($identification){
$this->identification = $identification;
}
/**
* Metodo para establecer el valor del campo sucursal_id
* @param integer $sucursal_id
*/
public function setSucursalId($sucursal_id){
$this->sucursal_id = $sucursal_id;
}
/**
* Metodo para establecer el valor del campo name
* @param string $name
*/
public function setName($name){
$this->name = $name;
}
/**
* Metodo para establecer el valor del campo email
* @param string $email
*/
public function setEmail($email){
$this->email = $email;
}
/**
* Metodo para establecer el valor del campo created_at
* @param Date $created_at
*/
public function setCreatedAt($created_at){
$this->created_at = $created_at;
}
/**
* Metodo para establecer el valor del campo status
* @param string $status
*/
public function setStatus($status){
$this->status = $status;
}

/**
* Devuelve el valor del campo id
* @return integer
*/
public function getId(){
return $this->id;
}
/**
* Devuelve el valor del campo identification
* @return string
*/
public function getIdentification(){
return $this->identification;
}
/**
* Devuelve el valor del campo sucursal_id
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    49 

* @return integer
*/
public function getSucursalId(){
return $this->sucursal_id;
}
/**
* Devuelve el valor del campo name
* @return string
*/
public function getName(){
return $this->name;
}
/**
* Devuelve el valor del campo email
* @return string
*/
public function getEmail(){
return $this->email;
}
/**
* Devuelve el valor del campo created_at
* @return Date
*/
public function getCreatedAt(){
return new Date($this->created_at);
}
/**
* Devuelve el valor del campo status
* @return string
*/
public function getStatus(){
return $this->status;
}
}

6.6 Crear el Inicio de Sesión

El inicio de sesión para el usuario final de la sucursal virtual según los requerimientos de la 
aplicación, es una pantalla en donde el cliente deberá ingresar su documento personal junto 
con alguna de las claves de las cuentas asociadas a ese documento. 
 
Según la arquitectura MVC los controladores son el punto de entrada a cualquier acción que se 
realice  en  la  aplicación,  aunque  de  momento  el  primer  requerimiento  nos  hace  pensar  en 
presentación  antes  de  ‘lógica  del  negocio’  empezaremos  creando  un  controlador  que  no 
implemente ningún tipo de lógica por ahora: 
 
El controlador creado se llama login y el archivo donde se implementa la clase controladora es 
el archivo controllers/login_controller.php y de momento contiene lo siguiente: 
 
<?php
class LoginController extends ApplicationController {
public function indexAction(){
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    50 

}
}

La  implementación  ‘vacía’  de  la  acción  ‘index’  permite  que  la  presentación  (la  vista  se 
visualice) en cuanto se invoca el controlador. 
 
Ya  que  ‘login’  será  el  controlador  por  defecto  de  la  aplicación  se  implementa  el  método 
ControllerBase::init de la siguiente forma: 
 
<?php
class ControllerBase {
public function init(){
//Enrutar al controlador login
Router::routeTo("controller: login");
}
}

Según las convenciones en la arquitectura MVC del Framework la vista para la acción ‘index’ 
del controlador ‘login’ se crea en el archivo views/login/index.phtml. 
 
La interfaz presenta una campo de texto donde es posible ingresar el documento del cliente y 
otra para la clave numérica de 4 dígitos. 
 
<h1>Bienvenido a Central Bank</h1>
<?php echo Tag::form("login/validateCredentials") ?>
<table>
<tr>
<td align='right'><b>Documento Identificaci&oacute;n:</b></td>
<td><?php echo Tag::textField("identification", "size: 20",
"maxlength: 20") ?></td>
</tr>
<tr>
<td align='right'><b>Contrase&ntilde;a:</b></td>
<td><?php echo Tag::numericPasswordField("password", "size: 4",
"maxlength: 4") ?></td>
</tr>
<tr>
<td></td>
<td><?php echo Tag::submitButton("Entrar") ?></td>
</tr>
</table>
<?php echo Tag::endForm() ?>

Ambos campos son requeridos y por lo tanto se validan como requeridos en el controlador. La 
validación  también  se  puede  hacer  en  JavaScript,  sin  embargo  estamos  haciendo  un  sistema 
confiable y no podemos confiar en lo que ocurra en el cliente.   

<?php
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    51 

class LoginController extends ApplicationController {


public function indexAction(){
}
public function validateCredentialsAction(){
$rules = array(
"identification" => array(
"filter" => "alpha",
"message" => "Por favor indique su documento de
identificación"
),
"password" => array(
"filter" => "int",
"message" => "Por favor indique su contraseña"
),
);
if($this->validateRequired($rules)==true){
//Aquí viene la autenticación
} else {
$this->routeTo("action: index");
}
}
}
 
La  utilización  del  método  heredado  validateRequired  permite  validar  el  tipo  de  dato  y 
comprobar si el usuario ha ingresado algún valor en estos campos. Los valores de los campos 
son filtrados usando el componente Filter antes de validar si están presentes en la entrada de 
usuario. 
 
Si  la  validación  falla  el  flujo  de  ejecución  se  enruta  nuevamente  a  la  acción  index.  Ahora  se 
modifica la vista para mostrar al usuario los mensajes generados en la validación. 
 
<h1>Bienvenido a Central Bank</h1>
<?php
foreach(View::getValidationMessages() as $message){
Flash::error($message->getMessage());
}
?>
<?php echo Tag::form("login/validateCredentials") ?>
<table>
<tr>
<td align='right'><b>Documento Identificaci&oacute;n:</b></td>
<td><?php echo Tag::textField("identification", "size: 20",
"maxlength: 20") ?></td>
</tr>
<tr>
<td align='right'><b>Contrase&ntilde;a:</b></td>
<td><?php echo Tag::numericPasswordField("password", "size: 4",
"maxlength: 4") ?></td>
</tr>
<tr>
<td></td>
<td><?php echo Tag::submitButton("Entrar") ?></td>
</tr>
</table>
<?php echo Tag::endForm() ?>
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    52 

 
El método estático View::getValidationMessages() permite obtener los mensajes obtenidos en 
la  validación.  Cuando  el  proceso  de  validación  es  satisfactorio  se  puede  continuar  con  el 
proceso de autenticación.  

6.7 Autenticando al Cliente

El  requerimiento  del  banco  exige  que  la  implementación  de  la  autenticación  se  haga  de  la 
siguiente forma: 
 
• Validar que exista un cliente con el documento ingresado 
• Validar que la clave proporcionada corresponda al menos a una cuenta del cliente 
 
Los modelos Customer y Account contienen los datos requeridos para efectuar esta operación. 
La acción modificada validateCredentials queda así: 
 
public function validateCredentialsAction(){
$rules = array(
"identification" => array(
"filter" => "alpha",
"message" => "Porfavor indique su documento de
identificación"
),
"password" => array(
"filter" => "int",
"message" => "Porfavor indique su contraseña"
),
);
if($this->validateRequired($rules)){
$identification = $this->getPostParam("identification", "alpha");
$password = sha1($this->getPostParam("password", "int"));
$customer = $this->Customer-
>findFirst("identification='$identification' AND status=’A’");
if($customer!==false){
$successAuth = false;
$accounts = $this->Account->find("customer_id = '{$customer-
>getId()}' AND status=’A’");
foreach($accounts as $account){
if($password==$account->getPassword()){
$successAuth = true;
break;
}
}
if($successAuth==false){
$this->addValidationMessage("Documento/Password
Incorrectos");
$this->routeTo("action: index");
} else {
Session::set(“existsValidUser”, true);
$userData = SessionNamespace::add('UserData');
$userData->setCustomer($customer->getId());
$userData->setLogInTime(time());
$this->routeTo("controller: menu");
}
} else {
$this->addValidationMessage("Documento/Password
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    53 

Incorrectos");
$this->routeTo("action: index");
}
} else {
$this->routeTo("action: index");
}
}
 
En  el  anterior  procedimiento  se  ilustran  varios  aspectos  de  un  procedimiento  usando  el 
Framework: 
 
• Para  recuperar  los  valores  que  vienen  del  formulario  se  utiliza  el  método  getPost. 
Como  primer  parámetro  se  pasa  el  nombre  del  campo  usado  en  el  formulario. 
Adicionalmente se puede aplicar un filtro para asegurar que la entrada si es segura y 
corresponde al tipo de dato esperado. 
• Para acceder a cualquier modelo basta con invocarlo usando $this dentro de cualquier 
acción del Framework. El nombre de la variable corresponde al nombre de la clase que 
utiliza el modelo. 
• El método del modelo findFirst busca un registro ó como su traducción dice “buscar el 
Primero”.  La  condición  permite  obtener  el  registro  deseado.  Este  método  devuelve 
false cuando no encuentra registros con las condiciones indicadas. 
• El  método  find  realiza  una  búsqueda  de  varios  registros,  la  condición  permite  filtrar 
solo  los  registros  de  las  cuentas  asociadas  al  cliente.  Cuando  no  encuentra  registros 
devuelve  un  vector  vacío,  en  caso  contrario  el  resultado  de  find  es  un  Objeto  de  la 
clase  ActiveRecordResulset  que  implementa  el  patrón  Recordset,  es  decir  una 
representación en memoria del resultado devuelto por la base de datos. 
• La  variable  $successAuth  sirve  como  variable  bandera  para  identificar  si  se  ha 
encontrado una cuenta con la contraseña proporcionada. 
• Para obtener los valores de los campos del modelo es necesario usar los getters en el 
caso de customer se uso getId() para obtener el id del registro que se consultó. 
• Las claves en la tabla Account son resúmenes usando el algoritmo sha1. 
• Para  agregar  un  mensaje  de  validación  personalizado  se  puede  usar  el  método 
addValidationMessage el cual también es usado internamente por validateRequired. 
• Cuando falla algún requisito del proceso se muestra el mensaje y se enruta a la acción 
index lo que le permitirá al usuario final reingresar la información. 
• Cuando el documento de identificación y la clave son correctos se crea una variable de 
sesión mediante Session::set, esta es llamada existsValidUser y se le asigna valor “true”. 
Esta  variable  indica  a  lo  largo  de  la  aplicación  que  existe  un  usuario  valido 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    54 

autenticado. 

6.8 Un Menú para la Aplicación

Para organizar las opciones que utiliza el usuario final se crea un menú y se implementa de tal 
forma  que  siempre  sea  visible  por  el  usuario  final  durante  todo  el  tiempo  que  ejecute  la 
aplicación. Como se vió en el procedimiento de autenticación, cuando esta es satisfactoria el 
flujo  de  ejecución  es  redireccionado  al  controlador  “menu”.  La  implementación  de  este 
controlador  carece  de  lógica  de  negocio  alguna  y  muestra  la  vista  que  permite  al  cliente 
escoger la opción que desea: 
 
El  script  de  ayuda  del  Framework  llamado  create_controller  permite  la  creación  del 
controlador: 
 
php scripts/create_controller.php --application bank –-name menu
 
Como resultado se obtiene el codigo generado: 
 
<?php
class MenuController extends ApplicationController {
public function indexAction(){
}
}

La  jerarquía  de  vistas  implementada  en  el  componente  View  permite  que  la  presentación 
correspondiente  a  un  controlador  sea  compartida  por  otros,  por  esto  se  ha  creado  el  menú 
enlazando cada opción en el layout del controlador. 
 
El archivo views/layouts/menu.phtml queda así: 
 
<h1>Cajero Virtual</h1>
<b>Men&uacute; Principal:</b>
<ul>
<li><?php echo Tag::linkTo("banking/checkBalance", "Ver Saldo") ?></li>
<li><?php echo Tag::linkTo("banking/showTransactionActivity", "Ver
Extractos Bancarios") ?></li>
<li><?php echo Tag::linkTo("transfer", "Transferencias") ?></li>
<li><?php echo Tag::linkTo("logout", "Salir del Banco") ?></li>
</ul>

El  uso  del  helper  Tag::linkTo  permite  crear  un  enlace  al  controlador  requerido  y  utilizar  un 
label  para  indicar  el  texto  asociado  a  él.  La  ventaja  de  utilizar  este  tipo  de  helpers  es  que 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    55 

mantiene  actualizados  los  path  absolutos  a  la  aplicación  y  si  se  llegase  a  mover  a  otro  URI 
automáticamente estos mantendrían las rutas correctas.  

6.9 Visualización del saldo del cliente

La primera opción que presenta el menú al cliente le permite consultar el saldo de las cuentas 
bancarias que tenga en el banco. Para implementar la consulta se crea el controlador ‘banking’ 
que consulta el saldo de cada cuenta y lo presenta en una vista. 
 
El controlador ‘BankingController’ queda así: 
<?php
class BankingController extends ApplicationController {
public function indexAction(){
}
public function checkBalanceAction(){
$userData = SessionNamespace::get('UserData');
$customerId = $userData->getCustomer();
$accounts = $this->Account->find("customer_id='$customerId' AND
status = 'A'");
$this->setParamToView("accounts", $accounts);
}
}
 
Se  toman  los  datos  de  sesión  que  se  crearon  cuando  el  cliente  inició  sesión  desde  el 
SessionNamespace. El modelo ‘Account’ es inyectado para realizar la consulta, el resultado de 
esta se pasa a la vista usando el parámetro “accounts”.  
 
En la presentación la idea es presentar una tabla con los saldos en cada cuenta junto con una 
sumatoria del saldo total por cuenta y de todas las cuentas. La tabla a presentar contiene las 
siguientes columnas: Número de la Cuenta, Saldo, Saldo en Canje y Total (que suma el saldo 
más  el  saldo  en  canje).  Podemos  definir  el  total  como  una  columna  calculada,  obteniendola 
como  una  regla  del  negocio  implementando  el  método  getBalanceTotal()  en  el  modelo 
Account: 
 
<?php
class Account extends ActiveRecord {
/* getters y setters */
/**
* Devuelve el saldo total de la cuenta
*
* @return double
*/
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    56 

public function getBalanceTotal(){


return $this->balance+$this->swap_balance;
}
}
 
Al  definir  este  método  se  extiende  el  modelo  y  se  cumple  con  la  regla  del  negocio. 
getBalanceTotal() está disponible en cada instancia de Account en toda la aplicación.  
 
Se  crea  la  vista  de  esta  acción  en  el  archivo  apps/bank/views/banking/checkBalance.phtml. 
Notese que banking corresponde a el nombre del controlador y checkBalance al nombre de la 
acción: 
 
<?php
print "<table border='1'>
<thead>
<tr>
<th>N&uacute;mero</th>
<th>Saldo</th>
<th>Saldo en Canje</th>
<th>Total</th>
</tr>
</thead>
<tbody>";
foreach($accounts as $account){
print "<tr>
<td>".$account->getNumber()."</td>
<td align='right'>".number_format($account->getBalance(), 2)."</td>
<td align='right'>".number_format($account->getSwapBalance(),
2)."</td>
<td align='right'>".number_format($account->getBalanceTotal(),
2)."</td>
</tr>";
}
print "</tbody></table>";
?>

El  resultado  devuelto  por  el  método  find  de  Account  es  un  objeto  ActiveRecordResulset  que 
puede ser recorrido por foreach para construir la tabla de cuentas. Algun cliente puede tener 
varias  cuentas  ó  tener  ninguna,  en  este  ultimo  caso,  la  aplicación  le  informará  al  cliente.  Ya 
que  los  objetos  ActiveRecordResultset  implementan  la  interface  Countable  es  posible  saber 
cuantos registros devolvió la consulta usando la función count(): 
 
<?php
if(count($accounts)>0){
print "<table border='1' align='center'>
<thead>
<tr>
<th>Número</th>
<th>Saldo</th>
<th>Saldo en Canje</th>
<th>Total</th>
</tr>
</thead>
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    57 

<tbody>";
$total = 0;
$totalBalance = 0;
$totalSwapBalance = 0;
foreach($accounts as $account){
print "<tr>
<td>".$account->getNumber()."</td>
<td align='right'>".number_format($account->getBalance(),
2)."</td>
<td align='right'>".number_format($account->getSwapBalance(),
2)."</td>
<td align='right'>".number_format($account-
>getBalanceTotal(), 2)."</td>
</tr>";
$totalBalance+=$account->getBalance();
$totalSwapBalance+=$account->getSwapBalance();
$total+=$account->getBalanceTotal();
}
print "<tr>
<td align='right'>TOTALES</td>
<td align='right'>".number_format($totalBalance, 2)."</td>
<td align='right'>".number_format($totalSwapBalance, 2)."</td>
<td align='right'>".number_format($total, 2)."</td>
</tr>";
print "</tbody></table>";
} else {
Flash::notice("No tiene cuentas activas en nuestro banco");
}
 
En  este  momento  al  visualizar  los  saldos  se  puede  ver  que  el  menú  no  aparece  al  lado 
izquierdo, esto se debe a que el layout del menú que se definió anteriormente solo esta activo 
para el controlador del mismo nombre. Para definir el layout ‘menu’ como el del controlador 
‘banking’  se usa el método setTemplateAfter() en el inicializador del controlador. 
 
<?php
class BankingController extends ApplicationController {
protected function initialize(){
$this->setTemplateAfter("menu");
}
public function indexAction(){
}
public function checkBalanceAction(){
$userData = SessionNamespace::get('UserData');
$customerId = $userData->getCustomer();
$accounts = $this->Account->find("customer_id='$customerId' AND
status = 'A'");
$this->setParamToView("accounts", $accounts);
}
}
 
El  layout  menú  es  modificado  para  que  muestre  tanto  el  menu  de  la  aplicación  como  el 
contenido de las vistas que lo utilicen: 
 
<h1>Cajero Virtual</h1>
<table width="100%">
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    58 

<tr>
<td valign="top" width="25%">
<b>Men&uacute; Principal:</b>
<ul>
<li><?php echo Tag::linkTo("banking/checkBalance",
"Ver Saldo") ?></li>
<li><?php echo
Tag::linkTo("banking/showTransactionActivity", "Ver Extractos Bancarios")
?></li>
<li><?php echo Tag::linkTo("transfer",
"Transferencias") ?></li>
<li><?php echo Tag::linkTo("logout", "Salir del
Banco") ?></li>
</ul>
</td>
<td>
<?php View::getContent() ?>
</td>
</tr>
</table>
 
El  llamado  a  View::getContent()  indica  donde  se  debe  auto‐incluir  el  contenido  de  la  vista 
asociada  al  layout,  en  este  caso  es  checkBalance.phtml.  Según  la  configuración  actual, 
cualquier  petición  a  los  controladores  ‘menú’  y  ‘banking’  mostrarian  el  mismo  layout  del 
´menu  principal’,  con  esto  logramos  que  los  clientes  puedan  ir  de  una  opción  a  otra  sin 
problemas y la aplicación obtiene un menu que se puede mantener fácilmente ya que esta en 
un solo archivo, pero aplica a varios estados de la aplicación.  

6.10 Crear el TransactionActivity

La  segunda  acción  que  se  debe  implementar  en  el  controlador  banking  es 
‘showTransactionActivity’ cuyo objetivo es mostrar los extractos bancarios del cliente en cada 
una de sus cuentas. Para empezar, se debe permitir al cliente que seleccione las cuentas en las 
que  desea  ver  sus  extractos  y  luego  mostrarlos  paginando  los  resultados  y  dar  la  opción  de 
imprimirlos. 
 
La implementación de la acción showTransactionActivity consulta las cuentas del cliente y las 
visualiza en la presentación de ella. Ya que el procedimiento para obtener las cuentas activas 
del  cliente  se  habia  implementado  en  la  acción  checkBalance,  se  define  el  método  privado 
_getActiveAcounts()  para  hacer  reusable  el  procedimiento  mencionado  y  usarlo  en 
showTransactionActivity. El controlador queda entonces así: 
 
<?php
class BankingController extends ApplicationController {
protected function initialize(){
$this->setTemplateAfter("menu");
}
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    59 

public function indexAction(){


}
private function _getActiveAccounts(){
$userData = SessionNamespace::get('UserData');
$customerId = $userData->getCustomer();
return $this->Account->find("customer_id='$customerId' AND status =
'A'");
}
public function checkBalanceAction(){
$this->setParamToView("accounts", $this->_getActiveAccounts());
}
public function showTransactionActivityAction(){
$this->setParamToView("accounts", $this->_getActiveAccounts());
}
}
 
La  vista  en  el  archivo  apps/bank/views/banking/showTransactionActivity.phtml  contiene  un 
formulario donde el usuario selecciona las cuentas y un botón de ‘Ver extractos’: 
 
<?php
if(count($accounts)>0){
print "<p>Por favor seleccione las cuentas a consultar:</p>";
print Tag::form("banking/getSelectedActivity");
print "<table align='center' border='1'>
<thead>
<tr>
<th></th>
<th>N&uacute;mero Cuenta</th>
<th>Oficina</th>
</tr>
</thead>
<tbody>";
foreach($accounts as $account){
print "<tr>
<td>".Tag::checkboxField("cuenta[]", "value: {$account-
>getId()}", “checked: checked”)."</td>
<td align='center'>{$account->getNumber()}</td>
<td align='center'>{$account->getSucursalId()}</td>
</tr>";
}
print "</tbody></table><p align='center'>";
print Tag::submitButton("Consultar");
print "</p>";
print Tag::endForm();
} else {
Flash::notice("No tiene cuentas activas en nuestro banco");
}
?>
 
La descripción de la vista anterior es la siguiente: 
 
• Se controla que haya cuentas activas contando los registros devueltos y presentando 
un mensaje informativo en su defecto. 
• El helper Tag::form(string $action) permite la creación de una etiqueta de formulario 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    60 

cuya acción es /banking/getSelectedActivity. 
• Se recorren las cuentas activas y por cada una se genera una fila con un checkbox que 
por defecto esta seleccionado. 
• El helper Tag::submitButton(string $caption) permite crear el botón de ‘Consultar’, al 
hacer click en él se enviará la información a la acción mencionada. 
• El helper Tag::endForm() cierra el formulario. 
 
La columna de la sucursal visualiza el código de esta tal y como está en la tabla lo cual no es 
muy amigable para el usuario final. Las asociaciones pueden resolver esto y obtener el detalle 
de la sucursal por cada cuenta en forma natural. Se define una multiplicidad n a 1 en el modelo 
‘Account’ así: 
 
<?php
class Account extends ActiveRecord {
/* getters y setters */
/**
* Devuelve el saldo total de la cuenta
*
* @return double
*/
public function getBalanceTotal(){
return $this->balance+$this->swap_balance;
}
/**
* Inicializa el modelo
*
*/
public function initialize(){
$this->belongsTo("sucursal");
}
}
 
De  esta  forma  se  puede  reemplazar  la  línea  de  la  vista  showTransactionActivity.phtml  en 
donde se imprime el codigo de la sucursal por: 
 
<td align='center'>{$account->getSucursal()->getName()}</td>
 
Al enviar los datos del formulario a la acción banking/getSelectedActivity, se recibe las cuentas 
seleccionadas y consulta los movimientos asociados a estas: 
 
<?php
class BankingController extends ApplicationController {
protected function initialize(){
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    61 

$this->setTemplateAfter("menu");
}
public function indexAction(){
}
private function _getActiveAccounts(){
$userData = SessionNamespace::get('UserData');
$customerId = $userData->getCustomer();
return $this->Account->find("customer_id='$customerId' AND
status='A'");
}
public function checkBalanceAction(){
$this->setParamToView("accounts", $this->_getActiveAccounts());
}
public function showTransactionActivityAction(){
$this->setParamToView("accounts", $this->_getActiveAccounts());
}
public function getSelectedActivityAction(){
$selectedAccountsIds = $this->getPostParam("cuenta");
$customerAccounts = array();
if(is_array($selectedAccountsIds)){
$userData = SessionNamespace::get('UserData');
$customerId = $userData->getCustomer();
foreach($selectedAccountsIds as $accountId){
$accountId = $this->filter($accountId, "int");
$existsAccount = $this->Account->count("customer_id =
'$customerId' AND id='$accountId' AND status='A'");
if($existsAccount==true){
$customerAccounts[] = $accountId;
} else {
Flash::error("Cuentas invalidas en la
peticion");
return;
}
}
} else {
Flash::error("Datos invalidos en la peticion");
return;
}
$movements = $this->Movement->find("account_id IN (".join(", ",
$customerAccounts).")", "order: created_at DESC");
$this->setParamToView("movements", $movements);
}
}
 
La explicación del procedimiento es la siguiente: 
 
• Se obtienen las cuentas seleccionadas del formulario mediante $selectedAccountsIds = 
$this­>getPostParam("cuenta");  
• En la siguiente linea se valida que el valor obtenido sea un vector con las cuentas 
• Luego se valida que cada una de las cuentas que es enviada sea realmente del cliente 
activo en la sesión y que la cuenta esté activa. 
• Después de filtrar las cuentas se consulta el movimiento asociado a estas, se envia los 
resultados a la vista donde en una tabla paginada se presentan los registros. 

 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    62 

Creación de Aplicaciones 

7 Aplicaciones en Kumbia Enterprise


7.1 Introducción

Una aplicación web es una extensión dinámica de un sitio web ó un servidor de aplicaciones. 
Existes 2 tipos de aplicaciones web: 
   
• Orientadas a la Presentación: Son aplicaciones que generan páginas web dinámicas 
usando  diferentes  lenguajes  de  marcas  (HTML,  XML,  etc)  y  tecnologías  como  (CSS, 
JavaScript,  etc)  generando  contenidos  de  respuesta  de  acuerdo  a  las  peticiones 
recibidas.  
• Orientadas  a  Servicios:  Implementan  endpoints  para  servicios  web.  Aplicaciones 
orientadas a la presentación suelen ser clientes de las orientadas a servicios.  
 
Kumbia  Enterprise  Framework  (KEF)  proporciona  un  completo  y  robusto  entorno  para  el 
desarrollo,  testeo,  implementación  y  puesta  en  producción  de  ambos  tipos  de  aplicaciones 
web usando tecnología PHP. 

7.2 Instancias del framework

Una instancia del framework hace referencia a una distribución del framework que reside en 
un  servidor  web.  Las  instancias  pueden  contener  una  ó  más  aplicaciones  compartiendo  una 
misma versión del framework y un mismo directorio público. 
 
Las instancias pueden verse también como application containers manteniendo la memoria y 
recursos de las aplicaciones en forma separada pero proporcionando un entorno integrado de 
operación. 

7.3 Estructura de directorios de una Instancia

La estructura de archivos de una instancia de Kumbia Enterprise Framework tiene lo siguiente: 
 
Listado: Estructura de directorios predeterminada 
 
apps/
default/
controllers/
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    63 

application.php
config/
filters/
library/
models/
base/
plugins/
validators/
views/
config/
languages/
Library/
public/
javascript/
css/
files/
temp/
img/
index.php
scripts/
test/
index.php

La descripción de cada directorio es la siguiente: 
 
Tabla: Descripción de directorios del framework 

Directorio  Descripción 

El  directorio  apps  contiene  todas  las  aplicaciones  que  usen  la  misma 
apps 
versión del framework  

Es  la  aplicación  por  defecto,  el  Front‐Controller  para  esta  aplicación 
default  permite acceder directamente a los controladores sin indicar el nombre 
de la aplicación. 

controllers  Es el directorio en el que se deben ubicar todos controladores. 

Contiene  la  clase  ControllerBase  de  la  cual  heredan  todos  los 
application.php 
controladores y en donde también definimos el método init 

Contiene los archivos de configuración por aplicación y personalizada de 
config 
aplicación 

Contiene filtros personalizados por usuario. Es opcional la presencia de 
filters 
este directorio. 

Contiene  componentes  personalizados  por  aplicación.  Es  opcional  la 


library 
presencia de este directorio. 

Aquí  se  deben  ubicar  todos  los  modelos  de  la  aplicación,  Kumbia 
models  Enterprise Framework permite organizar lógicamente en directorios los 
grupos de modelos. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    64 

Permite  crear  la  presentación  de  aplicaciones  mediante  el  componente 


views 
View. 

Es  posible  crear  plugins  que  aumenten  la  funcionalidad  de  la 
plugins 
implementación MVC. 

Permiten crear validadores para ActiveRecord que se ayuden a validar la  
validators 
lógica de datos. 

config  Contiene la configuración general del framework 

languages  Contiene los mensajes localizados del framework. 

Library  Contiene al framework como tal y librerías de terceros 

Hace  el  papel  de  DocumentRoot  (raíz  de  documentos)  de  la  aplicación, 
todo  los  archivos  debajo  de  este  directorio  pueden  ser  accedidos 
public 
públicamente.  En  sus  subdirectorios  se  encuentra  todo  el  contenido 
estático como imágenes, javascript, css y archivos descargables. 

Contiene scripts que automatizan tareas en el framework y reducen la  
scripts 
codificación manual. 

test  Contienen test de unidad de los framework. 

 
La  estructura  de  directorios  esta  pensada  buscando  convención  sobre  configuración,  así  el 
desarrollo producido es más mantenible y se hace más eficiente el desarrollo cuando todo se 
encuentra en su lugar.  

7.4 Publicar contenido estático

El directorio public en la estructura de archivos está destinado a publicar contenido estático 
que  es  visible  públicamente.  Cualquier  archivo  ubicado  en  este  directorio  ó  en  un 
subdirectorio puede ser accedido por los clientes de la aplicación. 
 
Con el fin de establecer ubicaciones que hagan más mantenibles las aplicaciones se incluyen 
por defecto los siguientes subdirectorios: 
 
Tabla: Directorios de publicación de contenido estático  
Subdirectorio  Descripción 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    65 

img  Contiene  imágenes  predefinidas  del  framework  y  su  objetivo  es 


colocar aquí imagenes a ser usadas por la aplicación. 
css  Contiene  archivos  de  estilos  CSS.  El  archivo  style.css  contiene  las 
definiciones de estilos estándares para todas las aplicaciones. 
javascript  Está  destinado  a  almacenar  archivos  JavaScript.  El  framework  coloca 
en este directorio los frameworks y funciones básicas JavaScript. 
temp  Directorio para archivos temporales. 
files  Directorio para archivos a descargar. 
 
El desarrollador debe tener en cuenta que cuando un contenido en estos directorios no existe 
la petición es direccionada a la aplicación. Evitar las peticiones a archivos inexistentes es una 
buena práctica en miras a mejorar el rendimiento de las aplicaciones. 

7.5 Bootstrap

En cualquier estructura MVC el boostrap cumple el papel de tomar la URL reescrita e invocar 
tanto el Dispatcher como los enrutadores necesarios para ejecutar la petición. Para entender 
la  forma  en  la  que  el  Dispatcher  busca  el  controlador  en  las  aplicaciones  y  ejecuta  la  acción 
asociada es necesario comprender la forma en la que deben formar las URLs antes de generar 
una petición. 
 
Para una estructura de directorios que incluye 2 aplicaciones, la primera default y la segunda 
que se llama producción que ilustramos así: 
 
Ejemplo: Estructura de directorios para múltiples aplicaciones 
 
empresa/
apps/
default/
controllers/
clientes_controller.php
productos_controller.php
config/
models/
views/
produccion/
controllers/
compras_controller.php
config/
models/
views/

Una petición al controlador clientes sería así: 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    66 

Ejemplo: Acceder a las aplicaciones y controladores desde una URL 
http://www.ejemplo.com/empresa/clientes/
http://www.ejemplo.com/empresa/clientes/buscar
http://www.ejemplo.com/empresa/clientes/consultar/18
 
En donde, el dominio del servidor es www.ejemplo.com, la ruta al framework es empresa (en 
este directorio del DocumentRoot esta el framework), el nombre del controlador es clientes, la 
acción en la tercera URL sería consultar y el parámetro para esta acción es el número 18.  
 
Una  petición  para  la  aplicación  de  producción  se  coloca  el  nombre  de  esta  después  del 
directorio donde esta Kumbia Enterprise Framework, así: 
 
Ejemplo: Acceder a la aplicación de producción desde una URL 
http://www.ejemplo.com/empresa/produccion/compras/
http://www.ejemplo.com/empresa/produccion/verEstado/22
 
Cada  aplicación  dentro  de  apps  contiene  una  estructura  de  directorios  para  controladores, 
modelos y vistas única, la forma de acceder a cada aplicación es indicando su nombre antes 
del nombre del controlador.  

7.6 Crear la acción por defecto en una Aplicación

La clase ControllerBase ubicada en apps/default/controllers/application.php permite definir el 
método init que se ejecuta en caso que no se defina un controlador ó acción por defecto: 

Ejemplo: Acción por defecto en una aplicación 
<?php

class ControllerBase {
public function init(){
//Cargar algunas extensiones
Extensions::loadExtension("Kumbia.ApplicationMonitor");
Extensions::loadExtension("Kumbia.Acl");
//Enrutar al controlador login
Router::routeTo("controller: login");
}
}

7.7 Crear un procedimiento de inicialización de la aplicación

El  método  ControllerBase::init  es  ejecutado  si  no  se  especifica  un  controlador  en  la  URL,  en 
ciertas ocasiones puede que no sea útil si se requiere inicializar extensiones ó ejecutar algún 
proceso de inicialización. El método ControllerBase::onStartApplication resulta más apropiado, 
en  estos  casos.  Este  método  solo  ejecuta  un  procedimiento  en  cuanto  se  realiza  la  primera 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    67 

petición a la aplicación. El siguiente ejemplo ilustra mejor el funcionamiento de este método: 
 
Ejemplo: Definir un procedimiento de inicialización de la aplicación 
<?php
class ControllerBase {

public function onStartApplication(){


//Cargar algunas extensiones
Extensions::loadExtension("Kumbia.Feed");
Extensions::loadExtension("Kumbia.Acl");
}
public function init(){
//Enrutar al controlador login
Router::routeTo("controller: login");
}

 
También se debe evitar realizar cualquier tipo de salida al explorador ya que este método es 
ejecutado antes de inicializarse el contexto de sesión. 

7.8 Detectar un cambio en la ejecución de una instancia a otra

En la clase ControllerBase también es posible implementar el método onChangeInstanceEvent 
que es ejecutado cuando se detecta que en la misma sesión se ha ejecutado ya una aplicación 
en otra instancia de Kumbia Enterprise Framework. 
 
Ejemplo: Detectar el cambio de ejecución de una instancia a otra 
<?php
class ControllerBase {

public function onChangeInstanceEvent(){


//Se ha cambiado la instancia
}
}

 
Es  posible  que  este  evento  no  se  llame  correctamente  si  las  aplicaciones  e  instancias  tienen 
adaptadores de sesión diferentes. 
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    68 

Parte 1: La lógica de dominio 

8 Componente Controller
8.1 Introducción

El  componente  Controller  cumple  una  importante  tarea  dentro  de  la  arquitectura  MVC  de 
Kumbia.  El  framework  proporciona  la  integración  de  este  componente  con  el  componente 
View y ActiveRecord que realiza el papel de los modelos. 
 
La integración de estos componentes proporciona una estructura estable y eficiente para las 
aplicaciones  orientadas  a  la  Web.  Además  de  esto,  el  componente  ofrece  un  sistema  de 
persistencia transparente al desarrollador que acerca las aplicaciones Web a aplicaciones de 
escritorio,  eliminando  la  complejidad  de  administrar  el  estado  y  entorno  de  la  lógica  de 
negocios  en  una  sesión.  Por  medio  de  plug‐ins  es  posible  extender  la  funcionalidad  de  este 
componente. 

8.2 Como funciona el componente Controller?

Kumbia  Enterprise  Framework  ha  implementado  una  estructura  jerárquica  de  clases  que 
permiten crear diferentes tipos de servicios y desarrollar la lógica de aplicación en diferentes 
niveles de flexibilidad ó practicidad.  
 
El  componente  Controller  posee  la  siguiente  jerarquía  de  clases  e  implementación  de 
servicios: 
 
Tabla: Jerarquia de clases del componente Controller 
Clase  Ubicación  Descripción 

Es  la  clase  padre  de  todos  los 


controladores, el desarrollador puede 
agregar  métodos  que  serán 
apps/default/controllers/ 
ControllerBase   heredados  por  cualquier  controlador 
application.php  
de  la  aplicación.  Aquí  se  puede 
agregar  validación  de  seguridad  ó 
Auditoría de sistemas.  

Controller   Library/Kumbia/Controller/C Es  el  componente  Controller  en  si, 


LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    69 

ontroller/Controller.php   implementa  todos  los  métodos 


comunes  para  los  tipos  de 
controladores del framework.  

El  diseño  de  este  controlador  ayuda 


Library/Kumbia/Controller/A
al  programador  a  interactuar  con 
ApplicationController   pplication/ 
vistas  y  modelos  de  la  forma  más 
Application.php  
directa y flexible.  

Es  una  implementación  del 


componente  Controller  que  funciona 
como  Scallfolding  (generador  de 
Library/Kumbia/Controller/St código)  dinámico.  Busca  ayudar  al 
StandardForm   andardForm/  desarrollador  a  crear  capturas  de 
StandardForm.php   limitada  personalización  pero  que 
realizan  las  operaciones  de  creación, 
consulta,  modificación,  reporte  y 
eliminación de los datos de una tabla.  

Este  tipo  de  controlador  Permite 


crear  Servicios  web  basados  en  el 
Library/Kumbia/Controller/
estándar SOAP, generar descripciones 
WebServiceController   WebServiceController/ 
en  WSDL  y  orquestar  el  intercambio 
ApplicationController.php  
de  datos  entre  aplicaciones  usando 
este método.  

Es  una  sub‐implementación  de 


Library/Kumbia/Controller/A ApplicationController  que  está   
MultiThreadController  pplication/  diseñada  para  correr  procesos  de 
MultiThreadController.php   negocio  que  requieran  seguimiento 
estilo cross‐cutting. 
 
El  objetivo  de  cada  controlador  es  básicamente  separar  la  lógica  de  la  presentación,  el 
componente Controller implementa el patrón Front­Controller en el cual todas las peticiones a 
la  aplicación  son  atendidas  inicialmente  por  él  y  luego  son  enrutadas  a  controladores  de 
usuario y acciones que atienden cada una. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    70 

8.3 Crear un Controlador

Los  controladores  son  clases  que  heredan  de  las  implementaciones  de  Controladores  como 
ApplicationController  ó  WebServiceController  y  que  deben  ser  creados  bajo  ciertas 
convenciones en el directorio apps/default/controllers/ 
 
Al  crear  un  controlador  para  la  administración  de  la  información  de  clientes  se  crea  un 
archivo  llamado  customer_controller.php,  en  él  una  clase  CustomerController  heredando  de 
alguna de las implementaciones del componente Controller. 
 
La acción por defecto en el controlador debe tener visibilidad pública y llamarse indexAction 
así: 
 
Ejemplo:  Un controlador y su acción por defecto 
<?php
class CustomerController extends ApplicationController {
public function indexAction(){
$this->renderText("Hola Mundo");
}
public function getStatusAction($id){
$this->renderText("Ver el estado del cliente $id");
}
}

 
Para realizar una petición a la aplicación se hace mediante la siguiente URL: 
 
Ejemplo: Acceder al controlador mediante una URL 
http://www.example.com/company/customer/index
http://www.example.com/company/customer/
 
Ya que index es la acción por defecto no es necesario indicarla, ya que es implícita. El indicarla 
produciría  el  mismo  resultado.  Para  acceder  a  la  acción  getStatus  se  hace  de  la  siguiente 
forma: 
 
Ejemplo: Acceder a una acción personalizada desde una URL 
http://www.example.com/company/customer/getStatus/190
 
• El componente Controller esta integrado con el componente View que implementa el 
patrón Template View. Esta integración permite que en cuanto termina la ejecución de 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    71 

la  lógica  en  la  acción  automáticamente  se  renderiza  la  presentación  ó  vista 
correspondiente al controlador y acción solicitados. 
• El  funcionamiento  del  componente  Controller  se  apoya  tanto  en  Dispatcher  como  en 
Router  para  realizar  todo  el  trabajo  al  atender  una  petición  a  la  aplicación.  No  es 
necesario  entender  el  funcionamiento  de  estos  componentes  en  detalle  aunque  si  se 
desea  extender  la  funcionalidad  de  la  arquitectura  implementada  en  Kumbia 
Enterprise Framework puede resultar útil 
• Primero  la  clean  URL  es  fragmentada  usando  el  método  Router::rewrite  aquí  se 
determina  que  aplicación,  controlador  y  acción  se  requiere  ejecutar.  El  componente 
Router es quien realiza la orquestación de todo el flujo de ejecución. 
• El  componente  Dispatcher  recibe  los  parámetros  de  controlador  y  acción  y  busca  el 
indicado  en  el  directorio  de  controladores  para  su  procesamiento  y  delegación  a  la 
operación requerida. 
• Antes  de  ejecutar  la  petición  Dispatcher  busca  si  esta  definido  el  método  ó  atributo 
beforeFilter en la clase del controlador ó en su jerarquía y lo ejecuta.  
• Si el flujo de la ejecución no ha sido cambiado mediante el método Controller::routeTo 
entonces ejecuta la acción solicitada en el controlador. La acción tiene acceso a todo el 
entorno HTTP e información enviada por métodos POST, GET, PUT, etc. 
• Si  no  cambia  el  flujo  de  ejecución  Dispatcher  busca  si  esta  definido  el  método  ó 
atributo afterFilter en la clase controladora en su jerarquía de clases y lo ejecuta.  
• El proceso de enrutamiento es cíclico y termina solo cuando se deja ó no se invoca el 
método Controller::routeTo. 
• El Compontente View toma el control y recibe lo generado por Controller y visualiza la 
presentación para éste, en caso de que exista.  
 
El  patrón  Front­Controller  junto  con  Model­View­Controller  funciona  como  el  corazón  el 
framework  e  integra  los  componentes  Controller,  Router,  Dispatcher  y  Core  para  hacerlo 
funcionar. Cuando requerimos de entender ó modificar la ejecución del flujo de aplicación nos 
remitimos a los servicios que estos componentes proporcionan. 

8.4 Servicios del Componente Router

void Router::rewrite(string $url) 
Toma  la  clean  URL  y  fragmenta  cada  componente  localizando  la  aplicación,  controlador  y 
acción  solicitados,  este  método  es  llamado  automáticamente  en  el  bootstrap  del  framework 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    72 

ubicado en public/index.php. cedula  
 
void Router::ifRouted() 
Antes de la ejecución de cualquier acción busca en la tabla de enrutamiento estático generada 
a partir de config/routes.ini si se debe enrutar a otra controlador ó acción dinámicamente. 
 
boolean Router::getRouted() 
Este método devuelve el estado del router que indica si es necesario hacer una enrutación ó 
continuar con el flujo normal de la aplicación. 
 
string Router::getApplication() 
Devuelve el nombre de la aplicación que fue solicitada en la petición. 
 
string Router::getModule() 
Devuelve el nombre del módulo que fue solicitado en la petición. 
 
string Router::getController() 
Devuelve  el  nombre  del  controlador  que  fue  solicitado  en  la  petición.  Esta  información 
adicionalmente  se  puede  obtener  usando  el  método  en  el  controlador  llamado 
getControllerName(). 
 
string Router::getAction() 
Devuelve  el  nombre  de  la  acción  que  fue  solicitada  en  la  petición.  Esta  información 
adicionalmente  se  puede  obtener  usando  el  método  en  el  controlador  llamado 
getActionName(). 
 
string Router::getId() 
Devuelve el primer parámetro enviado por URL en la petición. 
 
array Router::getParameters() 
Devuelve en un array los parámetros enviados por URL en la petición, estos igualmente se les 
hace binding a la acción como parámetros del método ejecutado de la clase controladora. 
 
array Router::getAllParameters() 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    73 

Devuelve un array con todos los fragmentos de la URL solicitada en la petición. 
 
array Router::routeTo(mixed $params) 
Permite cambiar el flujo de ejecución de la aplicación transfiriéndoselo a otro controlador y/o 
acción. 
 
array Router::routeToURI(string $uri) 
Permite cambiar el flujo de ejecución de la aplicación transfiriéndoselo a otro controlador y/o 
acción mediante un Uniform Resource Identifier. 
 
string Router::getActiveApplication()   
Devuelve  el  nombre  de  la  aplicación  actual.  Cuando  es  la  aplicación  por  defecto  devuelve  la 
palabra default. 
 
void Router::setApplication(string $name) 
Permite establecer dinámicamente el nombre de la aplicación actual. 
 
void Router::setDefaultActionName(string $actionName) 
Permite establecer el nombre de la acción por defecto en todos los controladores. 
 
string Router::getDefaultActionName() 
Devuelve el nombre de la acción por defecto en todos los controladores.  
 
int Router::getRoutingType() 
Devuelve  el  tipo  de  enrutamiento  producido  de  acuerdo  al  origen  de  la  petición.  El  valor 
devuelto es la constante Router::ROUTING_NORMAL ó Router::ROUTING_OTHER. 

8.5 Servicios proporcionados por Dispatcher

void Dispatcher::setControllersDir(string $directory) 
Permite  establecer  el  directorio  de  controladores  usado  para  hacer  el  lookup  de  un 
controlador cuando se realiza una petición. 
 
Controller Dispatcher::getControllerInstance() 
Devuelve el objeto controlador instanciado que se está ejecutando. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    74 

 
int Dispatcher:.getDispatchStatus() 
Devuelve el estado actual del flujo de ejecución. Puede ser alguna de las constantes de la clase 
Dispatcher: 
 
• STATUS_UNINITIALIZED: Indica que no se ha iniciado el proceso de ejecución  
• STATUS_DISPATCHING:  Indica  que  se  esta  localizando  el  controlador  y  su  acción 
solicitada  
• STATUS_RUNNING_BEFORE_FILTERS:  Indica  que  se  están  localizando  los  métodos  y 
atributos beforeFilter y se están ejecutando.  
• STATUS_RUNNING_AFTER_FILTERS:  Indica  que  se  están  localizando  los  métodos  y 
atributos afterFilter y se están ejecutando.  
• STATUS_RENDER_PRESENTATION:  Indica  que  el  control  de  la  aplicación  fue 
transferido al componente View.  
• STATUS_RUNNING_BEFORE_STORE_PERSISTENCE:  Indica  que  se  va  a  realizar  el 
procedimiento de almacenamiento de los datos persistentes del controlador.  
• STATUS_RUNNING_AFTER_STORE_PERSISTENCE:  Indica  que  se  ha  realizado  el 
procedimiento de almacenamiento de los datos persistentes del controlador.  
• STATUS_RUNNING_CONTROLLER_ACTION: Indica que el control de ejecución lo tiene 
el controlador como tal y su acción solicitada.  

boolean Dispatcher::isRunningController() 
Indica si el control de ejecución esta a nivel del controlador y no del framework. 
 
boolean Dispatcher::isRunningUserLevel() 
Indica si la ejecución esta a nivel de la lógica del desarrollador y no del framework. 
 
mixed Dispatcher::getValueReturned() 
Devuelve el valor que retornó la última acción ejecutada en la petición. 

8.6 Excepciones Generadas en el Dispatcher

En  el  proceso  del  Dispatcher  pueden  ocurrir  excepciones  que  son  enviadas  directamente  al 
cliente  si  no  se  encuentra  definido  el  método  onException  ya  sea  en  el  controlador  ó  en 
ControllerBase.  Las  excepciones  ocurridas  en  Dispatcher  lanzan  una  excepción  de  clase 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    75 

DispatcherException en las siguientes circunstancias:  
 
Tabla: Códigos y descripción de excepciones generadas en Dispatcher 
Código  Descripción 
Dispatcher::NOT_FOUND_ACTION  Se  genera  cuando  no  existe  un  método 
con el nombre de la acción indicado en 
la  clase  controladora  y  además  no 
existe la acción notFoundAction. 
Dispatcher::NOT_FOUND_CONTROLLER  Se  genera  cuando  no  se  encuentra  el 
controlador  solicitado  pero  si  existe  el 
archivo correcto. 
Dispatcher::NOT_FOUND_FILE_CONTROLLER  Ocurre  cuando  no  existe  el  archivo  del 
controlador  y  por  ende  la  clase  del 
mismo al solicitar la petición a este. 
Dispatcher::NOT_FOUND_INIT_ACTION  Ocurre  cuando  se  esta  tratando  de 
ejecutar  el  método  init  en 
ControllerBase  pero  este  no  se  ha 
definido ó su visibilidad no es pública. 
Dispacher:: INVALID_METHOD_CALLBACK  Se  genera  cuando  se  trata  de  invocar 
externamente el constructor de la clase 
controladora  ó  un  método  protegido  ó 
privado. 
Dispatcher::INVALID_ACTION_VALUE_PARAMETER  Se genera cuando no se ha enviado por 
la  URL  ó  al  redireccionar  a  una 
determinada  acción  se  ha  omitido  el 
valor  para  un  parámetro  de  una  acción 
en el controlador solicitado. 
 
Como se ha mencionado anteriormente es posible definir un método que actúe como una capa 
previa  al  lanzamiento  de  la  excepción  al  usuario  llamada  onException.  Esta  recibe  el  objeto 
instanciado  de  la  excepción  generada,  este  método  recibe  además  cualquier  excepción 
independiente de si genera en Dispatcher ó dentro del mismo controlador: 
 
Ejemplo: Definir un método que administre las excepciones en controladores 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    76 

<?php
class CustomerController extends ApplicationController {
public function indexAction(){
}
public function onException($e){
if($e instanceof DispatcherException){
if($e->getCode()==Dispatcher::NOT_FOUND_ACTION){
Flash::notice(“Lo sentimos la página no existe”);
}
} else {
//Se relanza la excepción
throw $e;
}
}
}

 
Nota:  Una  excepción  que  se  presenta  frecuentemente  es  la 
INVALID_ACTION_VALUE_PARAMETER,  que  se  genera  cuando  se  omite  en  la  URL  un 
parámetro  del  método  de  la  acción  que  no  es  opcional  ó  que  tiene  un  valor  por  defecto. 
Kumbia Enterprise Framework es estricto en este sentido y generará una excepción cuando se 
omita  un  valor  aunque  PHP  en  sí  generaría  solo  una  advertencia.  La  forma  más  práctica  de 
evitar  esto  es  asignar  valores  predeterminados  a  cada  parámetro  del  método  haciendo  la 
lógica de aplicación más consistente evitando mensajes en la pantalla del cliente (explorador, 
consola, etc). Este tipo de excepciones también se generan al realizar el enrutamiento y omitir 
el valor de algún parámetro. 

8.7 Peticiones HTTP a Controladores

Cuando se realiza una petición a un controlador mediante protocolo HTTP es posible crear el 
objeto de petición ControllerRequest y además utilizar métodos que ayudan a interactuar con 
los datos enviados a estos como por ejemplo cuando se usan formularios HTML.  
 
La  instancia  de  ControllerRequest  se  puede  obtener  en  el  controlador  usando  el  método 
Controller::getRequestInstance(), el objeto obtenido encapsula toda la información enviada en 
la petición HTTP y la información de su entorno para ser utilizada dentro del controlador: 
 
Ejemplo: Obtener un instancia de la clase ControllerRequest 
<?php
class CustomerController extends ApplicationController {
public function indexAction(){
$request = $this->getRequestInstance();
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    77 

if($request->isPost()==true){
Flash::notice(“La petición se ha realizado por método http
POST”);
}
}
/**
* Devuelve el nombre del cliente usando JSON solo si la petición
* fue realizada con AJAX
*/
public function getCustomerClientAction(){
$this->setResponse(“json”);
$request = $this->getRequestInstance();
if($request->isAjax()==true){
$this->renderText($this->jsonEncode(array(“name” => “John
Smith”)));
}
}

 
Los valores de las variables superglobales $_GET, $_POST, $_COOKIE, $_REQUEST, $_SERVER Y 
$_ENV pueden ser accesados usando los métodos de ControllerRequest usando getParamGet, 
getParamPost, getParamCookie, getParamServer y getParamEnv. De igual forma puede utilizar 
los  métodos  del  controlador  getQueryParam,  getPostParam,  getRequestParam, 
getCookieParam,  getServerParam  y  getEnvParam  para  obtener  estos  valores  sin  obtener  la 
instancia  de la clase ControllerRequest aunque esto se haga implícitamente. 

8.7.1 Administrar archivos adjuntos en una petición 
Los  archivos  adjuntos  en  una  petición  pueden  ser  administrados  usando  los  métodos  de 
ControllerRequest llamados hasFiles, getParamFile y getUploadedFiles.  
 
Ejemplo: Tratamiento de archivos enviados en una petición 
<?php
class Movement extends ApplicationController {
public function loadMovementAction(){
if($this->getRequestInstance()->hasFiles()==true){
foreach($this->getRequestInstance()->getUploadedFiles() as
$file){
print "Nombre original del archivo: ".$file-
>getFileName();
print "Tamaño del archivo: ".$file->getFileSize();
print "MIME del archivo: ".$file->getFileType();
print "Nombre Temporal: ".$file->getTempName();
$file->moveFileTo('movement/'.$file->getFileName());
}
}
}
}
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    78 

8.7.2 API de ControllerRequest 
Adicional  a  los  métodos  mencionados  anteriormente  la  referencia  del  API  de 
ControllerRequest además tiene: 
 
void setParamRequest(string $index, mixed $value) 
Cambia  un  valor  enviado  en  una  petición  en  la  superglobal  $_REQUEST.  Este  método 
automáticamente actualiza $_POST y $_GET si es necesario. 
 
void setParamGet(string $index, mixed $value) 
Cambia un valor enviado en una petición en la superglobal $_GET. 
 
void setParamPost(string $index, mixed $value) 
Cambia un valor enviado en una petición en la superglobal $_POST. 
  
void setParamCookie(string $index, mixed $value) 
Cambia un valor enviado en una petición en la superglobal $_COOKIE. 
 
boolean isSetRequestParam($index) 
Indica si existe una llave para un valor en la superglobal $_REQUEST. 
 
boolean isSetQueryParam($index) 
Indica si existe una llave para un valor en la superglobal $_GET. 
 
boolean isSetPostParam($index) 
Indica si existe una llave para un valor en la superglobal $_POST. 
 
boolean isSetCookieParam($index) 
Indica si existe una llave para un valor en la superglobal $_COOKIE. 
 
boolean isSetServerParam($index) 
Indica si existe una llave para un valor en la superglobal $_SERVER. 
 
boolean isSetEnvParam($index) 
Indica si existe una llave para un valor en la superglobal $_ENV. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    79 

 
boolean isSetRequestParam($index) 
Elimina  un  valor  en  la  superglobal  $_REQUEST.  Implicitamente  elimina  el  valor  de  $_GET  y 
$_POST. 
 
boolean isSetQueryParam($index) 
Elimina un valor en la superglobal $_GET. 
 
boolean isSetPostParam($index) 
Elimina un valor en la superglobal $_POST. 
 
boolean isAjax() 
Indica si la petición ha sido realizada usando AJAX. Funciona cuando se utiliza el framework 
Javascript Prototype. 
 
boolean isFlashRequested() 
Indica si la petición ha sido realizada desde un objeto Macromedia Flash incrustado en un sitio 
Web. 
 
boolean isSoapRequested() 
Indica  si  la  petición  ha  sido  realizada  desde  un  cliente  SOAP.  Al  solicitarsen  este  tipo  de 
peticiones a la aplicación el administrador de presentación y enrutamiento se cambian para 
crear una comunicación machine­to­machine.  
 
boolean isSecure() 
Indica si la petición se realiza bajo una conexión encriptada usando HTTPS. 
 
string getRawBody() 
Devuelve el cuerpo de la petición HTTP directamente. 
 
string getHeader(string $name) 
Devuelve un encabezado HTTP a partir de su nombre. Funciona anteponiendo el sufijo HTTP_ 
ó sin él. 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    80 

string getScheme() 
Devuelve el scheme (protocolo) utilizado para realizar la petición HTTP. Devuelve http ó https 
generalmente. 
 
string getHttpHost() 
Devuelve el host y puerto en el que realizo la petición. Generalmente es la ip pública ó privada 
del servidor donde esta instalado el interprete PHP. 
 
string getMethod() 
Devuelve el método HTTP utilizado para hacer la petición POST, GET, PUT, etc. 
 
boolean isGet() 
Devuelve true si la petición HTTP fue realizada usando método GET. 
 
boolean isPost() 
Devuelve true si la petición HTTP fue realizada usando método POST. 
 
boolean isPut() 
Devuelve true si la petición HTTP fue realizada usando método PUT. Es útil cuando se crean 
aplicaciones REST. 
 
boolean isOptions() 
Devuelve  true  si  la  petición  HTTP  fue  realizada  usando  método  OPTIONS.  Es  útil  cuando  se 
crean aplicaciones REST. 
 
boolean isHead() 
Devuelve true si la petición HTTP fue realizada usando método HEAD. Es útil cuando se crean 
aplicaciones REST. 
 
boolean isDelete() 
Devuelve  true  si  la  petición  HTTP  fue  realizada  usando  método  DELETE.  Es  útil  cuando  se 
crean aplicaciones REST. 
 
boolean hasFiles() 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    81 

Indica si la petición incluye archivos subidos mediante método POST. 
 
array getUploadedFiles() 
Obtiene un vector con objetos ControllerUploadFile que encapsulan la información de archivos 
subidos en la petición. 
 
string getHTTPReferer() 
Obtiene el HTTP referer de la petición. 
 
array getAcceptableContent() 
Obtiene un vector con los mimes del tipo de contenido aceptado por el cliente HTTP junto con 
su calidad. Devuelve un array como: Array ( [0] => Array ( [accept] => text/html [quality] => 1 
) [1] => Array ( [accept] => application/xhtml+xml [quality] => 1 ) [2] => Array ( [accept] => 
application/xml [quality] => 0.9 ) [3] => Array ( [accept] => */* [quality] => 0.8 ) ) 
 
array getClientCharsets() 
Devuelve la lista de idiomas soportados por el cliente HTTP junto con su calidad. Devuelve un 
array  como:  Array  (  [0]  =>  Array  (  [accept]  =>  ISO‐8859‐1  [quality]  =>  1  )  [1]  =>  Array  ( 
[accept] => utf‐8 [quality] => 0.7 ) [2] => Array ( [accept] => * [quality] => 0.7 ) ) 
 
string getBestQualityCharset() 
Obtiene el charset de mejor calidad soportado por el cliente HTTP. 

8.8 Respuestas HTTP de Controladores

La respuesta que generan los controladores en una petición HTTP es encapsulada en el objeto 
ControllerResponse  el  cual  funciona  como  un  Gateway  entre  la  vista  y  el  controlador.  Este 
objeto esta implementado al igual que ControllerRequest con el patrón Singleton, es decir que 
por  cada  petición  a  la  aplicación  solo  existirá  una  intancia  en  todo  el  contexto  de  ejecución. 
Para  obtener  la  instancia  de  la  clase  ControllerResponse  se  usa  el  método  estático 
getInstance(). 
 
Ejemplo:  Uso del objeto ControllerResponse 
<?php
class DocumentsController extends ApplicationController {
public function indexAction(){
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    82 

$response = ControllerResponse::getInstance();
$response->setHeader(“Content-Type: application/pdf”);
$response->setResponse(ControllerResponse::RESPONSE_OTHER);
$response->setResponseAdapter(‘pdf’);
}
}

En el ejemplo anterior la acción index visualiza un archivo en formato PDF que es leído en la 
presentación,  el  método  setHeader  establece  un  encabezado  HTTP  apto  para  la  salida  y 
además indica a la aplicación que no debe utilizar el adaptador de presentación por defecto 
(HTML) sino debe usar ‘pdf’.  

8.8.1 Establecer el tipo de salida de la Petición 
El  controlador  proporciona  el  método  Controller::setResponse  que  permite  establecer  el  tipo 
de salida que se genera en la acción solicitada. Los tipos de salida que admite este método son 
los siguientes: 
 
Tabla: Tipos de respuesta que acepta el objeto ControllerResponse 
Valor  Descripción 
view  Indica que solo la vista correspondiente a la acción solicitada será la que se 
visualizará.  Usualmente  aplica  cuando  se  renderizan  vistas  parciales  ó 
fragmentos AJAX. 
ajax  Realiza lo mismo que ‘view’ pero documenta el código más claramente. 
json  Permite  producir  salidas  usando  notación  JSON  (JavaScript  Serializable 
Object Notation). 
xml  Produce una salida XML, agrega el encabezado Content‐type: text/xml y no 
muestra ningun layout asociado. 
rss  Produce  una  salida  XML  agrega  el  encabezado  encabezado  Content‐type: 
application/rss+xml  y no muestra ningun layout asociado. 
 
Los valores de los tipos de salida son internamente convertidos a un tipo de salida soportado 
por ControllerResponse: 
 
Tabla: Tipos de respuesta avanzados del objeto ControllerResponse 
Valor  Descripción 
RESPONSE_NORMAL  Es  la  respuesta  que  se  genera  normalmente.  No  es  necesario 
establecerla. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    83 

RESPONSE_OTHER  Indica que no se debe usar el adaptador de visualización por defecto 
porque se generará una salida en otro formato. 
 
En  el  siguiente  ejemplo  se  ilustra  como  generar  una  salida  usando  JSON,  la  acción 
countItemsAction  implementa  una  salida  primero  estableciendo  el  tipo  de  salida    y  después 
haciendo la salida de la misma, en getItemsAction se resumen los dos pasos anteriores en una 
sola línea: 
 
Ejemplo: Implementar una salida JSON desde un controlador 

<?php
class CartController extends ApplicationController {
public $items = array();
public function addToListAction($item){
$this->ítems[] = $item;
}
public function countItemsAction(){
$this->setResponse(‘json’);
$this->renderText($this->jsonEncode(count($this->ítems)));
}
public function getItemsAction(){
$this->outputJSONResponse($this->ítems);
}
}

Nota:  El  método  setResponse  tiene  una  funcionalidad  limitada  por  lo  cual  ha  sido  marcado 
como  obsoleto,  en  vez  de  este  se  debe  usar  View::setRenderLevel  en  conjunto  con 
Controller::setResponseType. 

8.8.2 API de ControllerResponse 
El API de la clase ControllerResponse es: 
 
public static ControllerResponse getInstance() 
Obtiene la instancia del objeto ControllerResponse. 
 
public void setHeader(string $header, boolean $replace=true) 
Permite establecer un encabezado HTTP en la petición actual. El parámetro $replace indica si 
el encabezado debe reemplazar uno del mismo tipo establecido anteriormente. 
 
public array getHeaders(boolean $process=true) 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    84 

Obtiene  un  array  con  los  encabezados  HTTP  que    van  a  ser  enviados  en  la  respuesta  de  la 
petición.  Si  el  parámetro  $process  es  true  devolvera  un  array  asociativo  cuyas  claves 
corresponden a los nombres de los encabezados. 
 
public boolean hasHeader(string $headerName) 
Indica si ya se ha definido un encabezado para ser enviado en la respuesta a la petición. 
 
public void setResponseType(int $type) 
Permite  establecer  el  tipo  de  respuesta  que  debe  generar  la  petición.  El  parámetro  $type 
recibe  los  valores  de  las  constantes  ControllerResponse::RESPONSE_NORMAL  y  
ControllerResponse:: RESPONSE_OTHER. 
 
public integer getResponseType() 
Obtiene el tipo de respuesta que va a generar el controlador. Devuelve el valor de cualquiera 
de las 3 constantes mencionadas anteriormente. 
 
public integer setResponseAdapter(string $adapter) 
Establece  el  nombre  del  adaptador  utilizado  para  procesar  la  salida  de  la  petición.  Los 
posibles valores para $adapter son json, pdf y xml. En la referencia del componente View se 
explica como utilizar otros adaptadores. 
 
public function getResponseAdapter() 
Devuelve el adaptador usado para generar la salida. 
 
public function setContentType($contentType) 
Establece el encabezado Content‐Type de la respuesta del controlador. 

8.9 Controlar acciones no encontradas

Cuando se realiza una petición a un controlador y la acción solicitada no esta implementada se 
genera  una  excepción  que  cuando  no  es  controlada  presenta  información  de  la  excepción  al 
usuario de la aplicación. La información de excepciones presenta información técnica que en 
manos equivocadas puede permitir facilitar el ataque a la aplicación. 
 
El desarrollador puede implementar la acción notFoundAction ya sea en el controlador ó en la 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    85 

jerarquía  de  clases  lo  cuál  permitirá  presentar  al  usuario  un  mensaje  personalizado  y 
probablemente almacenar un log de la situación ocurrida. 
 
Ejemplo:  Definir  una  acción  que  administre  las  peticiones  a  controladotes  y  acciones 
que no esten definidas 

<?php
class ReportsController extends ApplicationController {
public function notFoundAction($actionName=””){
$logger = new Logger(“File”, “notFoundReports.txt”);
$logger->log(“No se encontró la acción $actionName”);
}
}

8.10 Filtros en controladores

Cada  acción  ejecutada  en  cualquier  controlador  de  la  aplicación  ejecuta,  si  están  presentes 
filtros  antes  y  después  de  la  ejecución  del  método  solicitado.  Los  filtros  permiten  ejecutar 
tareas de autenticación, politicas de seguridad, validación y enrutamiento, además de acceder 
por completo al entorno HTTP y modificar la respuesta de la petición. 
 
Los dos tipos de filtros son: beforeFilter que es ejecutado antes de ejecutar la acción solicitada 
como tal y afterFilter que se ejecuta inmediatamente después. 
 
Los  filtros  son  métodos  que  se  implementan  directamente  como  métodos  en  la  clase 
controladora  ó  en  la  jerarquia  de  clases  del  mismo.  Usualmente  filtros  generales  para  todos 
controladores  se  implementan  en  la  clase  padre  ControllerBase,  de  esta  forma  interceptan 
todas las peticiones a la aplicación. 
 
Ejemplo: Definir filtros a nivel general en la aplicación 
<?php
class ControllerBase {
public function init(){
Router::routeTo("controller: login");
}
public function beforeFilter(){
$activeRole = Session::getData("activeRole");
if(Router::getController()=="admin"&&$activeRole!="Administradores"){
Router::routeTo("controller: login", “action: index”);
return false;
}
}
}
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    86 

 
Se  debe  devolver  false  desde  beforeFilter  cuando  se  realiza  un  enrutamiento  a  otro 
controlador diferente al activo. 
 
Cuando  se  implementan  múltiples  filtros  es  necesario  invocar  el  filtro  padre  en  el  momento 
indicado: 
 
Ejemplo: Definición de múltiples filtros  
<?php
class CustomerController extends ApplicationController {
public function beforeFilter(){
/**
* Algún código de filtro
*/
parent::beforeFilter();
}
}

8.11 Enrutamiento en controladores

El  componente  Router  ofrece  servicios  que  permiten  al  desarrollador  alterar  el  flujo  de 
ejecución como sea necesario, ya sea reescribiendo URLs, redireccionando mediante HTTP ó 
haciendo  enrutamientos  a  nivel  de  controlador.  El  proceso  de  enrutamiento  se  requiere  en 
una  aplicación  cuando  es  necesario  llevar  al  usuario  a  un  controlador  y  acción  sin  que  sea 
solicitado propiamente por el mismo. 

8.11.1 Ciclo de enrutamiento 
Por cada petición que se realiza a la aplicación se inicia un ciclo de enrutamiento que permite 
ejecutar  todas  las  acciones  requeridas  en  los  controladores  según  la  lógica  de  negocio.  Este 
ciclo ejecuta cada acción enrutada como si se tratara de una petición normal de usuario. 
 
El psudo‐código del ciclo de enrutamiento es el siguiente: 
 
Pseudocódigo:  Flujo y orden de ejecución de eventos en ciclo de enrutamiento  
Intentar
InvocarEventoDeControlador(“beforeDispatchLoop”)
HayEnrutamiento := Verdadero
Mientras HayEnrutamiento = Verdadero Hacer
HayEnrutamiento := InvocarEventoDeControlador(“beforeDispatch”)
HayEnrutamiento := InvocarEventoDeControlador(“beforeExecuteRoute”)
EjecutarFiltroBeforeFilter()
HayEnrutamiento := EjecutarAccionEnControlador()
EjecutarFiltroAfterFilter()
HayEnrutamiento := InvocarEventoDeControlador(“afterExecuteRoute”)
HayEnrutamiento := InvocarEventoDeControlador(“afterDispatch”)
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    87 

ContinuarMientras
InvocarEventoDeControlador(“afterDispatchLoop”)
CapturarExcepción
InvocarEventoDeControlador(“onExceptions”)
FinIntentar
 
Cuando  termina  el  ciclo  de  enrutamiento  se  transfiere  el  control  de  la  aplicación  a  la 
presentación (vista), en donde el compontente View realiza este trabajo. 

8.11.2 Enrutar usando Router::routeTo 
El  Componente  Router  ofrece  el  método  estático  routeTo  que  realiza  las  tareas  de 
enrutamiento  y  valida  si  existen  rutas  estáticas  predefinidas  con  la  prioridad  del  caso.  Es 
posible utilizar parámetros con nombre para indicar la ruta requerida donde se desea enrutar. 
El método routeTo de Controller es un proxy al método estático mencionado. 
 
En el siguiente ejemplo se ilustra la validación de un usuario y su enrutamiento de acuerdo a 
si la autenticación es exitosa ó falla: 
 
Ejemplo:  Validación de usuario y enrutamiento condicional 
<?php
class LoginController extends ApplicationController {
public function startSessionAction(){
$login = $this->getPostParam('login', 'alpha');
$pass = $this->getPostParam('pass', 'alpha');
if($this->Usuarios->findFirst("login = ’$login’ AND clave =
'$pass'")){
Flash::success('Bienvenido '.$this->Usuarios->getNombre());
$this->routeTo('controller: menu');
} else {
Flash::error('Permisos Insuficientes/Password Incorrecto');
$this->routeTo('action: startSession');
}
}
}
 
El  método  routeTo,  gracias  a  los  parámetros  por  nombre,  puede  recibir  la  ruta  de 
enrutamiento  en  cualquier  orden,  usando  las  claves:  controller,  action  e  id.  Si  es  necesario 
pasar más parámetros adicionales  puede usar llaves numéricas que coincidan con el orden en 
que la acción recibe los parámetros requeridos: 
 
Router::routeTo(“controller: invoice”, “action: setMovementDate”, “id:
2008/01/12”, “1: 2008/01/17”);
 
Cuando  se  solicita  un  enrutamiento  con  routeTo()  solo  es  efectivo  hasta  que  termina  la 
ejecución  de  todo  el  método  de  la  acción,  es  posible  utilizar  return  para  salir  del  método 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    88 

anticipadamente. 

8.11.3 Enrutar usando Router::routeToURI() 
También es posible hacer enrutamientos usando un Uniform Resource Indentifier como lo es 
una clean URL dentro de la misma lógica de aplicación. Para esto se recurre al método estático 
Router::routeToURI  que  realiza  el  papel  del  mod_rewrite  fragmentando  la  URL  y 
convirtiéndola  en  los  valores  internos  necesario  para  hacer  el  enrutamiento.  El  siguiente 
ejemplo ilustra la reescritura de una fecha pasada por la URL estilo Blogger: 
 
Ejemplo: Reescritura de URL mediante Router::routeToURI 
<?php
class BloggerController extends ApplicationController {

public function showPostAction ($year, $month, $date, $name){


$this->routeToURI(“/blogger/showPostByDate/$year-$month-
$date/$name”);
}
public function showPostByDateAction($date, $name) {
// alguna lógica aqui
}
}

8.12 Inicialización de Controladores

Debido a que el componente Controller proporciona un entorno de estado de persistencia, los 
objetos instanciados de las clases controladoras no son destruidos al terminar la sesión y son 
persistidos durante toda la sesión de usuario. Según lo anterior los constructores de las clases 
controladoras no son confiables para inicializar las condiciones de ejecución cada vez que se 
genera  una  petición  a  los  mismos.  Por  esta  razón  se  proporciona  la  posibilidad  de  definir  el 
método  protegido  ‘initialize’  con  el  fin  de  inicializar  el  objeto  desde  la  persistencia  en  cada 
petición al controlador. 
 
Ejemplo: Inicializar un controlador mediante initialize() 
<?php
class UsuariosController extends StandardForm {
public $scaffold = true;
public $template = "admin_menu";
public function beforeInsert(){
$clave = sprintf("%04s", mt_rand(0, 9999));
$this->Usuarios->clave = sha1($clave);
Flash::success('La clave del Usuario es "'.$clave.'", por favor no
la olvide');
}
public function beforeUpdate(){
$usuario = new Usuarios();
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    89 

$usuario->find($this->getRequestParam("fl_id", "int"));
$this->Usuarios->clave = $usuario->clave;
}
public function initialize(){
$this->ignore('clave');
$this->setTextUpper("nombre");
$this->setComboStatic('perfil', array(
array('Administradores', 'ADMINISTRADOR'),
array('Cajeros', 'CAJERO'),
array('Meseros', 'MESERO')
));
$this->setComboStatic("estado", array(
array("A", "ACTIVO"),
array("I", "INACTIVO")
));
}
}

 
Este método es invocado tanto en el constructor del controlador como en el evento __wakeup 
que ocurre al deserializar el objeto desde la persistencia de sesión. 

8.13 Estado de persistencia de Controladores

Como se menciono anteriormente Kumbia Enterprise Framework implementa persistencia del 
estado de los controladores buscando aproximar el desarrollo Web a un comportamiento de 
aplicación  de  escritorio.  Para  activar/desactivar  la  persistencia  es  necesario  invocar  el 
método setPersistance(bool $persitence), en el método inicializador el controlador. 
 
Gracias  a  la  implementación  del  patrón  base  Registry  en  el  componente  Dispatcher,  cada 
objeto  de  una  clase  controladora  instanciada  se  almacena  temporalmente  y  si  se  realizan 
enrutamientos  a  controladores  previamente  accedidos  estos  no  son  llevados  a  persistencia 
por lo que el estado de sesión del controlador se mantiene intacto como la primera vez que se 
invocó un método de la misma. 
 
Al  activar  la  persistencia  el  valor  del  atributo  name  se  mantiene  entre  peticiones  al 
controlador: 
 
Ejemplo: Implementar persistencia en el controlador 
<?php
class ProductsController extends ApplicationController {
public $name;
public function indexAction(){
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    90 

$this->name = “TV 22’”;


}
public function showProductAction(){
Flash::notice($this->name);
}

public function initialize(){


$this->setPersistance(true);
}
}

8.13.1 Ventajas del Estado de Persistencia 
El estado de persistencia ó contexto de conversación permite que: 
 
  Implementar atributos modulares en los controladores de tal forma que se haga un uso más 
intuitivo de los datos de sesión. 
  Implementar interfaces y componentes que “recuerden” el estado que se le dio la última vez 
que se accedió a ellos. 
  Crear conversaciones con el usuario de la aplicación de tal forma que contextualmente cada 
módulo  mantenga  un  flujo  de  trabajo  ó  proceso  como  parte  de  su  naturaleza  de  negocio 
misma. 

8.13.2 Consideraciones del estado de Persistencia 
El estado de persistencia esta pensando en dar la posibilidad de mantener los valores de los 
atributos  de  los  controladores  con  el  fin  de  establecer  un  contexto  de  conversación  entre  el 
cliente y la aplicación. 
 
Los  controladores  en  un  “estado”  persistente  almacenan  los  datos  en  el  administrador  de 
sesiones, si el volumen de datos almacenado es elevado el rendimiento de la aplicación podría 
disminuir. Instancias de entidades y otros objetos complejos que hagan parte de los datos de 
persistencia  son  excluidos  de  los  datos  almacenados  debido  a  la  cantidad  de  recursos  que 
consumen.  Puede  utilizar  el  componente  Cache  para  almacenar  este  tipo  de  objetos  usando 
diversos backends. 
 
En  el  capítulo    de  optimización  y  rendimiento  se  presenta  el  componente  GarbageCollector 
que permite de forma controlada comprimir y/o eliminar datos de estado de persistencia que 
sean utilizados por la aplicación. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    91 

8.13.3 Transacciones y Concurrencia del Estado de Persistencia 
Los controladores con estado de persistencia activo generan una transacción de los atributos 
de  al  iniciar  la  ejecución  de  cualquier  acción  en  el.  Mientras  se  ejecuta  la  petición  en  el 
controlador  la  transacción  permanece  en  un  nivel  de  isolación  en  el  cuál  no  realiza  ningún 
bloqueo sobre los datos de sesión. Se puede entender que se realizan transacciones atómicas 
con estos datos persistentes. Peticiones con un alto grado de concurrencia en la misma sesión 
de usuario y al mismo controlador podrían generar inconsistencias.  
 
Cuando  se  genera  una  excepción  no  controlada  la  transacción  realiza  un  rollback  haciendo 
que  los  atributos  del  controlador  permanezcan  intactos  a  su  estado  en  la  última  petición 
exitosa. 

8.13.4 Eventos del estado de Persistencia 
Un  controlador  con  el  contexto  de  persistencia  activado  puede  implementar  eventos  que 
permitan modificar la estado inicial al restaurar el objeto de su estado “dormido” y también 
cual será su estado final antes de ser almacenado “dormir”: 
 
Tabla: Tipos de respuesta que acepta el objeto ControllerResponse 
Evento  Descripción 
afterRestorePersistence  Se genera cuando despierta el controlador de su estado “dormido” 
en la persistencia. Esto solo ocurre cuando se realiza una petición al 
controlador. 
beforeStorePersistence  Se genera cuando el objeto controlador se esta preparando para ir a 
la persistencia. 
 
En el siguiente ejemplo se implementa el evento beforeStorePersitence para evitar que un dato 
de gran tamaño no relevante se lleve a la persistencia: 
 
Ejemplo: Implementar un evento del estado de persistencia 
<?php
class ProductsController extends ApplicationController {
public $name;
public $veryLongData;
public function indexAction(){
$this->name = “TV 22’”;
}

public function showProductAction(){


LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    92 

Flash::notice($this->name);
}

public function initialize(){


$this->setPersistance(true);
}
public function beforeStorePersitence(){
$this->veryLongData = “”;
}
}

8.14 La Clase ControllerBase

Esta clase es la padre de todos los controladores, el concepto de esta clase esta inspirado en el 
patrón  “ApplicationController”  (no  esta  relacionado  con  la  clase  del  mismo  nombre),  que  es 
una  extensión  al  MVC  permitiendo  que  parte  de  la  lógica  de  negocio  sea  compartida  por  un 
clase de la cual heredan las demás. Esta clase además sirve de punto de intersección y permite 
ajustar el flujo de ejecución de acuerdo al contexto en el que se invoque.  
 
El desarrollador puede implementar métodos que serán heredados por cualquier controlador 
de la aplicación. Es importante proteger la visibilidad de la lógica compartida en esta clase de 
tal forma que solo sea utilizada internamente por los controladores. 

8.15 La Clase Controller

La  clase  Controller  implementa  funcionalidad  compartida  a  todas  las  implementaciones  de 
controladores.  Esta clase actúa como el corazón de la capa de lógica de dominio.  

8.15.1 API de Controller 
Controller implementa principalmente métodos proxy a otros componentes facilitando su uso 
inmediato en un proceso de negocio. 
 
function void routeTo() 
Este método es implementado por conveniencia al desarrollador y realiza un proxy al método 
Route::routeTo. 
 
function void routeToURI()  
Este método es implementado por conveniencia al desarrollador y realiza un proxy al método 
Route::routeToURI. 
 
function mixed getPostParam(string $paramName)  
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    93 

Este método es implementado por conveniencia al desarrollador y realiza un proxy al método 
ControllerRequest::getParamPost. 
 
function mixed getQueryParam(string $paramName) 
Este método es implementado por conveniencia al desarrollador y realiza un proxy al método 
ControllerRequest::getParamQuery. 
  
function mixed getRequestParam(string $paramName)  
Este método es implementado por conveniencia al desarrollador y realiza un proxy al método 
ControllerRequest::getParamRequest. 
 
function mixed getServer(string $paramName) 
Este método es implementado por conveniencia al desarrollador y realiza un proxy al método 
ControllerRequest::getParamServer. 
  
function mixed getEnvironment(string $paramName)  
Este método es implementado por conveniencia al desarrollador y realiza un proxy al método 
ControllerRequest::getParamEnvironment. 
 
function mixed filter(string $paramValue) 
Este  método  es  implementado  por  conveniencia  al  desarrollador  y  permite  aplicar  un  filtro 
usando el componente Filter . 
  
function void setRequestParam(mixed $index, mixed $value)  
Este método es implementado por conveniencia al desarrollador y realiza un proxy al método 
ControllerRequest::setParamRequest. 
 
function void setPostParam(mixed $index, mixed $value) 
Este método es implementado por conveniencia al desarrollador y realiza un proxy al método 
ControllerRequest::setParamPost. 
  
function void setQueryParam(mixed $index, mixed $value)  
Este método es implementado por conveniencia al desarrollador y realiza un proxy al método 
ControllerRequest::setParamQuery. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    94 

 
function void setCookie(mixed $index, mixed $value) 
Este método es implementado por conveniencia al desarrollador y realiza un proxy al método 
ControllerRequest::setParamCookie. 
  
function void setPersistance(boolean $persistance)  
Establece el estado conversacional del controlador. Cuando $persistance es true el estado del 
controlador,  (los  valores  de  sus  atributos)  se  mantienen  entre  una  petición  y  otra  a  la 
aplicación. 
 
function boolean getPersistance() 
Devuelve un valor booleano que indica si el estado conversacional del controlador está activo 
ó no. 
  
function void redirect(string $uri)  
Permite realizar una redirección HTTP a una determinada  URI dentro de la aplicación actual. 
 
function void setResponse(string $type)  
Establece  el  tipo  de  respuesta  que  debe  generar  la  petición.  Consulte  la  referencia  de 
ControllerResponse para obtener más información sobre el uso de este método. 
 
function void exceptions(Exception $exception) 
Al  reescribir  este  método  es  possible  administrar  las  excepciones  producidas  en  el 
controlador.  
   
function string jsonEncode(mixed $data) 
Codifica una variable $data usando notación JSON para luego ser enviada al cliente. 
  
function void outputJSONResponse(mixed $data)  
Codifica una variable $data usando notación JSON y la envia directamente al cliente. 
 
function string getControllerName() 
Obtiene el nombre del controlador actualmente en ejecución. 
   
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    95 

function string getActionName() 
Obtiene el nombre de la acción actualmente en ejecución  
 
function void getId() 
Obtiene el valor del primer parámetro adicional pasado por la URL después del nombre de la 
acción. 
  
function void getViewHandler() 
Al reescribir este método es posible transferir el control de la presentación a un componente 
de usuario ó según sea requerido por la aplicación. 
 
function array getViewExceptionHandler()  
Al reescribir este método es posible transferir el control de la presentación a un componente 
de usuario ó según sea requerido por la aplicación cuando halla una excepción sin capturar. 
  
function void setTemplateBefore(string|array $template) 
Permite definir uno ó mas layouts que se deben incluir en la jerarquía de renderización de la 
presentación. Este/estos layout(s) son visualizados antes del layout del controlador. Consulte 
la referencia del componente View para obtener más información sobre el uso de este método. 
  
function void cleanTemplateBefore()  
Resetea la lista de layouts definidos a visualizar antes del layout del controlador. 
 
function void setTemplateAfter(string|array $template)  
Permite definir uno ó mas layouts que se deben incluir en la jerarquía de renderización de la 
presentación. Este/estos layout(s) son visualizados antes del layout del controlador. Consulte 
la referencia del componente View para obtener más información sobre el uso de este método. 
 
function void cleanTemplateAfter()  
Resetea la lista de layouts definidos a visualizar después del layout del controlador. 
 
function string|array getTemplateBefore() 
Obtiene  el  ó  los  layouts  a  renderizar  antes  del  layout  del  controlador  definidos  hasta  el 
momento.  
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    96 

  
function string|array getTemplateAfter()  
Obtiene  el  ó  los  layouts  a  renderizar  después  del  layout  del  controlador  definidos  hasta  el 
momento.  
 
function ControllerRequest getRequestInstance()  
Obtiene la instancia del objeto ControllerRequest para su uso en el controlador. 
 
function ControllerResponse getResponseInstance()  
Obtiene la instancia del objeto ControllerResponse para su uso en el controlador. 
 
function void setParamToView(string $index,  string $value)  
Transfiere un valor a la vista. El valor $value puede ser utilizado en la vista por medio de una 
variable local de la vista llamada $index. 
 
function WebServiceClient getService(string $serviceName)  
Obtiene  una  instancia  de  un  servicio  del  contenedor  de  servicios  para  ser  usada  en  el 
controlador. El servicio $serviceName puede también ser un nombre del Naming Directory ó 
un valor obtenido de usando un UDDI. Consulte el capítulo del contenedor de servicios para 
obtener más información de este método. 

8.16 Controladores usando ApplicationController

La implementación de controladores ApplicationController es la principal que debe ser usada 
cuando  se  requiere  dar  respuestas  a  peticiones  solicitadas  por  los  usuarios  finales  de  las 
aplicaciones. 
 

8.16.1 API de ApplicationController 
function void renderText(string $text)  
Envia un texto a la presentación 
 
function boolean validateRequired(string $rules, string $base='', string $getMode='')  
Valida  la  presencia  obligatoria  de  determinados  campos  recibidos  de  la  entrada  con  base  a 
unas  reglas  definidas  por  el  desarrollador.  Consulte  el  componente  Validator  y  Filter  para 
obtener más información. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    97 

 
function void cleanValidationMessages()  
Resetea los mensajes de validación producidos hasta el momento. 
 
function void addValidationMessage(string $message, string $fieldName='')  
Agrega un mensaje a la cola de validación. El Segundo parámetro opcional $fieldName permite 
establecer un campo de la interfaz de usuario al que está relacionado el mensaje. 
 
function array getValidationMessages()  
Obtiene los mensajes de validación generados hasta el momento en la cola de mensajes. 
 
function boolean isExportable() 
Este método puede ser reescrito y debe devolver un valor booleano indicando si los atributos 
publicos del controlador deben transferirse a la presentación como variables locales. 
 

8.16.2 Controladores usando MultiThreadController 
Este tipo de controlador es una sub‐implementación de ApplicationController cuyo objetivo es 
poder  implementar  procesamiento  asimetrico  para  grandes  procesos  en  controladores.  De 
esta  forma  es  posible  ejecutar  en  forma  simultanea  tareas  de  seguimiento  y  monitorización 
para procesos de negocio. 
 
Los procesos se ejecutan de forma asincrónica y en un orden que no puede ser denominado 
seguro  por  lo  tanto  son  aptos  para  procesos  de  debug  ó  monitorización  y  no  para 
implementar otros procesos de negocio buscando su ejecución simultánea. 
 
En el siguiente ejemplo se simula la implementación de un proceso de negocio que debido a la 
cantidad de datos que se deben procesar puede tardar un tiempo prolongado en procesarse, si 
el  proceso  fuese  más  grande  y  complejo  hacer  un  seguimiento  y  monitorización  detallado 
puede degradar progresivamente la lógica misma.   
 
El controlador contiene una acción llamada hugeProcess que contiene el proceso a ejecutar, la 
anotación  @synchronized  en  el  método  logProcessState  indica  que  este  método  debe  ser 
ejecutado simultáneamente con cualquier acción ejecutada en el controlador: 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    98 

class MyProcessController extends MultiThreadController {


private $_percent;
private $_customerName;
/**
* Realiza el log del proceso
*
* @synchronized
*/
public function logProcessState(){
if($this->_logger==null){
$this->_logger = new Logger('File', 'processLog.txt');
}
$this->_logger('El cliente actual es: '.$this->_customerName.
' '.$this->_percent);
}
public function hugeProcessAction(){
$totalQuantity = 0;
foreach($this->Movement->find() as $movement){
$customer = $movement->getCustomer();
$this->_customerName = $customer->getName();
$this->_percent = $movement->getQuantity()/
$customer->getCreditAmmount();
$product = $movement->getProduct();
if($product->getType()=='A'){
$totalQuantity+=$movement->getQuantity();
}
}
$this->setParamToView('totalQuantity', $totalQuantity);
}
}

 
Múltiples métodos del controlador pueden tener la anotación @synchronized de tal forma que 
sean ejecutados de manera simúltanea con cualquier acción del controlador. 

8.17 Servicios Web usando WebServiceController

8.17.1 Qué es un Web Service? 
Según  la  definición  de  la  arquitectura  de  Servicios  Web  del  W3C,  un  servicio  Web  es  un 
sistema  de  software  diseñado  para  soportar  interacción  interoperable  maquina  a  maquina 
sobre una red de computación. Cada servicio Web contiene una descripción que otra maquina 
puede  procesar  (usando  WSDL  probablemente).  Algunos  servicios  Web  pueden  interactuar 
directamente usando mensajes SOAP apoyándose en serialización XML y el protocolo HTTP en 
sí.  
 
Con  Servicios  Web  es  posible  dotar  a  las  aplicaciones  de  interoperatividad  estándar 
permitiendo  su  comunicación  de  forma  independiente  a  su  plataforma  tecnológica.    Kumbia 
Enterprise  Framework  permite  al  desarrollador  implementar  controladores  como  Servicios 
Web automatizando los procesos de publicación del servicio, administración y persistencia en 
forma transparente. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    99 

 
Un controlador WebServiceController funciona como un Service Provider el cual proporciona 
un  contrato  de  servicio  que  lo  conforman  las  acciones  del  mismo  y  que  son  expuestas 
públicamente  como  operaciones  del  mismo  de  tal  forma  que  clientes  externos  puedan 
utilizarlos de manera controlada. 
 
Los  Service  Customers  (clientes  de  servicios)  y  Services  Providers  ofrecen  funcionalidad 
concreta  para  el  envío  y  recepción  de  mensajes  en  una  comunicación  maquina  a  maquina. 
Esto  es  transparente  para  el  desarrollador  aunque  debe  ser  mencionado  de  manera 
informativa. 
 
Kumbia Enterprise Framework proporciona capas de Software que permiten implementar ya 
sea  Service  Customers  ó  Services  Providers  en  aplicaciones  desarrolladas  con  él.    De  esta 
forma  usted  puede  preocuparse  por  desarrollar  la  lógica  de  negocio  sin  preocuparse  por  la 
forma en que los servicios Web vayan a interactuar a más bajo nivel. 
 

8.17.2 Para que son necesarios los Web Services 
Las aplicaciones empresariales se pueden ver muy beneficiadas con el uso de Web Services. 
Crear  contratos  de  servicio  adecuados  permite  a  los  desarrolladores  extraer  en  forma 
abstracta servicios que permitan el intercambio de información  con aplicaciones de terceros, 
encapsulando detalles como la conexión a bases de datos, credenciales de seguridad, dominio 
y control de la información entregada bajo las condiciones pactadas.  
 
Sistemas  empresariales  ganan  nuevos  sub‐sistemas  de  comunicación  estandarizada  entre 
aplicaciones de tal forma que su composición sea reutilizable y componible. Mediante el uso 
de  Web  Services  se  eliminan  dependencias  del  pasado  como  el  traspaso  de  información 
mediante archivos planos, vistas en las bases de datos, conexiones por FTP ó directamente a 
los  RBDMs  que  carecían  de  un  control  adecuado  y  obligaban  a  implementaciones  rígidas  y 
complicadas además de exigir la integración de otros componentes en su aplicación. 
 

8.17.3 Arquitectura Orientada a Servicios (SOA) 
Las  organizaciones  empresariales  de  hoy  en  dia  requieren  interconectar  procesos  e 
información  entre  los  departamentos  de  las  mismas,  sus  provedores,  clientes  y  socios 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    100 

comerciales  extendiendo  sus  fronteras  y  aumentando  la  competitividad  y  capacidad  de 


crecimiento. 
 
La Arquitectura Orientada a Servicios proporciona elementos que permiten que un conjunto 
de  aplicaciones  distribuidas  se  convierta  en  conjunto  de  recursos  que  puedan  ser  utilizados 
tanto interna como externamente y como resultado se obtiene mayor agilidad y productividad 
en la organización.  
 
Kumbia Enterprise Framework ofrece herramientas para la construcción de una Arquitectura 
Orientada  a  Servicios,  sin  embargo,  debe  ser  el  arquitecto  ó  desarrollador  quien  debe 
determinar si es realmente necesario implementar esta estrategia de acuerdo a la complejidad 
y objetivos del negocio.  
 
Transformar  la  lógica  de  negocios  empresarial  a  una  arquitectura  orientada  a  servicios 
incluye  implementar  contratos  de  servicio,  reusabilidad,  abstracción,  loose  coupling 
(acoplamiento débil) y composibilidad. SOA es un modelo arquitectacional para plataformas 
de tecnología y cada empresa puede definir los objetivos asociados a computación orientada a 
servicios usando diferentes tecnologías.  
 
Usar Web Services es probablemente uno de las mejores opciones para aplicar los principios 
SOA y empezar a usar esta arquitectura. 
 

8.17.4 Crear un Web Service 
Como  se  mencionó  anteriormente  es  posible  crear  servidores  para  servicios  Web  usando  la 
implementación  de  Controller  llamada  WebServiceController.  Este  tipo  de  Controlador 
permite  crear  servicios  web  XML  y  encapsula  toda  la  comunicación  basada  en  el  estándar 
SOAP.  Las  comunicaciones  soportan  las  especificaciones  SOAP  1.1  y  1.2  así  como  el  uso  de 
descriptores WSDL. 
 
A  pesar  que  los  mensajes  SOAP  son  complejos;  todos  estos  detalles  son  transparentemente 
implementados  en  una  capa  funcional  apta  al  desarrollo  rápido  y  efectivo.  Del  lado  del 
servidor  el  desarrollador  puede  implementar  servicios  usando  lenguaje  PHP  nativo  y  la 
arquitectura y servicios del framework sin demasiados cambios. Del lado del cliente es posible 
utilizar  servicios  Web  invocando  el  nombre  de  los  métodos/acciones  implementados  en  el 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    101 

servicio servidor. 
 
Gracias  a  que  se  cumple  con  la  especificaciones  definidas  por  el  W3C  (Word  Wide  Web 
Consortium) es posible tener independencia del lenguaje PHP tanto del lado del cliente como 
del  servidor.  Lo  anterior  permite  acceder  a  servicios  Web  creados  en  otras  plataformas  y 
lenguajes y que están accedan a otros creados usando PHP. 
 
El ejemplo a continuación muestra la definición de un servicio Web simplificado que permite 
chequear  la  disponibilidad  de  fechas  para  realizar  una  reserva  en  un  sistema  ficticio.  En  el 
primer  método  startSession  se  recibe  como  parámetros  el  login  y  password  y  usando  el 
componente Auth se autentica contra un servidor ActiveDirectory usando el adaptador LDAP, 
si estas credenciales son validas entonces el resultado devuelto es devuelto y posteriormente 
permite validar que el usuario este autenticado. Notese que el segundo método getAvalability 
lanza  una  excepción  WebServiceControllerException  cuando  no  se  cumple  una  validación  la 
cual se notifica al cliente de igual manera.  
 
Los  valores  escalares  devueltos  por  cada  método  se  transfieren  transparentemente  entre  el 
servidor  y  el  cliente,  datos  más  complejos  exigen  distribuir  componente  compartidos  de  tal 
manera  que  no  haya  perdida  de  información  entre  el  Service  Provider  (servidor)  y  el 
Customer (cliente).  
  
Nótese que todos los métodos de la clase que vayan a ser accedidos remotamente deben tener 
el sufijo Action. 
 
Ejemplo: Servicio web con WebServiceController 
<?php
class ReservationController extends WebServiceController {
public function startSessionAction($login, $password){
$password = $this->filter($password, “alpha”);
$login = $this->filter($login, “alpha”);
$auth = new Auth(“ldap”, “server: ldap.server.local”,
“accountDomainName: server.local”,
“username: CN=$login,DC=server,DC=local”,
“password: $password”);
if($auth->autentícate()){
return true;
} else {
sleep(2);
return false;
}
}
public function getAvalabilityAction($initialDate, $finalDate){
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    102 

if(Auth::isValid()==false){
return false;
}
if(Date::compareDates($initialDate, $finalDate)==-1){
throw new WebServiceControllerException(“Fechas
incorrectas”);
} else {
$reserva = Reserva($initialDate, $finalDate);
return $reserva->checkAvalability();
}
}
public function getTicketNumberAction(){
if(Auth::isValid()==false){
return false;
}
return “AE1872”;
}
}
 
En  el  cliente  se  utiliza  la  clase  SoapClient  estándar  para  acceder  al  servicio  Web  Basado  en 
Soap: 
 
Ejemplo: Acceder a un servicio web usando SoapClient 
<?php
class VerifierController extends ApplicationController {
public function validateAction(){
$initialDate = $this->getPostParam(“initialDate”, “date”);
$finalDate = $this->getPostParam(“finalDate”, “date”);
$reservationService = new SoapClient(null, array(
'location' => 'http://web.server.local/w/reservation',
'uri' => 'http://app-services'
));
try {
if($reservationService->startSession(“webserviceUser”,
“2fe05187a”)==true) {
if($reservationService->getAvailability($initialDate,
$finalDate)==true) {
$ticketNumber = $reservationService-
>getTicketNumber();
return $this->routeTo(“action: successChecking”,
“id: $ticketNumber”);
}
}
}
catch(SoapFault $e) {
Flash::error(“Ha ocurrido un error”);
}
}
public function successCheckingAction($ticketNumber){
Flash::success(“Felicidades, esta disponible el ticket
$ticketNumber”);
}
}

8.17.5 WebServiceClient 
Kumbia Enterprise Framework también proporciona la clase WebServiceClient que extiende el 
cliente  SOAP  SoapClient  y  pretende  dar  más  facilidades  al  trabajar  con  servicios  Web  con 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    103 

servidores en este framework. El primer parámetro del constructor puede ser la ubicación del 
servicio (location) cuyo Uniform Resource Identificador (uri) es http://app­services: 
 
Ejemplo: Crear un servicio web con WebServiceClient 
$webService = new WebServiceClient('http://web.server.local/w/reservation');
 
Es posible definir los parámetros del cliente mediante un array de esta forma: 
 
Ejemplo: Definir parámetros extra en el servicio web con WebServiceClient 
$webService = new WebServiceClient(array(
‘wdsl’ => ‘http://www.example.com/external-services/reservation.wsdl’,
‘location’ => 'http://web.server.local/w/reservation',
‘uri’ => ‘http://www.example.com/external-services’,
‘encoding’ => ‘ISO-8859-1’
));
 
El constructor establece los siguientes parámetros por defecto para el cliente SoapClient: 
 
Tabla: Parámetros que recibe el contructor de WebServiceClient 
Parámetro  Valor 
wsdl  null 
uri  http://app-services 

encoding  UTF‐8 
compression  SOAP_COMPRESSION_ACCEPT  | 
SOAP_COMPRESSION_GZIP 
 
La extensión Soap de PHP es requerida para usar este cliente. 

8.17.6 Obteniendo el WSDL de un Servicio Web 
Kumbia  Enterprise  Framework  puede  hacer  AutoDiscover  de  servicios  Web  basados  en 
WebServiceController, en caso que no se defina un WSDL manualmente para el servicio. Para 
generar  un  descriptor  WSDL  correcto  es  necesario  agregar  PHPDocs  a  cada  acción  del 
controlador  y  así  poder  determinar  el  tipo  de  dato  devuelto  por  cada  operación  pública  del 
Service Provider, sino se puede determinar se genera un empty type. 
 
El mapeo de los valores escalares tanto los que se reciben como los que se envían en PHP a su 
correspondiente xsd ó soap‐enc, es el siguiente: 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    104 

String  :  <xsd:string>,  Integer  :  <xsd:integer>,  Float  y  Doubles  :  <xsd:float>,  Boolean: 


<xsd:bool>, Array : <soap‐enc:Array> y objetos <xsd:struct>. 
 
Los espacios de nombres XML usados son: 
 
xsd: "http://www.w3.org/2001/XMLSchema” 
soap‐enc: “http://schemas.xmlsoap.org/soap/encoding/"  
 
Es  posible  invocar  la  acción  getWSDLDescriptor  en  el  controlador  para  obtener  una 
descripción WSDL del servicio.  

8.17.7 Orquestación de servicios 
La lógica de negocio de los servicios web es implementada usando controladores que hacen 
parte  de  la  arquitectura  MVC,  tanto  la  capa  de  lógica  de  dominio  como  la  de  datos  tienen 
sentido para el desarrollador pero la presentación no existe ó no es claro su implementación 
ya  que en servicios web la comunicación  se  realiza  entre  maquinas  y  no  existe  intervención 
humana donde se requiera. 
 
Al recibir una petición desde un cliente Soap la instancia del framework es capaz de enrutar a 
la  acción  en  el  controlador  adecuada  examinando  el  mensaje  SOAP  enviado  a  la  aplicación. 
Luego  de  ejecutar  la  lógica  de  dominio  en  la  acción  el  valor  devuelto  por  esta  es  tratado  y 
convertido en un mensaje SOAP que se envia al cliente. 
 
La  manipulación  a  bajo  nivel  de  los  mensajes  SOAP  se  le  encarga  al  componente  Soap  que 
implementa los recursos necesarios para recibir y enviar comunicaciones de servicios Web y 
hacerlo transparente al usuario. 
 
En el siguiente ejemplo se ilustra como la comunicación de servicios Web es transparente al 
desarrollador y como el entorno MVC facilita la orquestación de servicios: 
 
En la maquina servidor1 se implementa el siguiente servicio web: 
 
Ejemplo: Servicio web aritmético 
<?php
class AritmethicController extends WebServiceController {
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    105 

public function addAction($a, $b){


return $a + $b;
}
}

En la maquina servidor2 se implementa un cliente del Servicio Web: 
 
Ejemplo: Acceso al servicio web aritmético 
<?php
class CalculatorController extends WebServiceController {
public function addAction($x, $y){
$service = new WebServiceClient(“http://server1/ins/aritmethic/”);
$result = $service->add($x, $y); //Realiza la suma en el servidor1
}
}
 
Al invocarse la acción calculador/add en servidor 2 se mapean automáticamente los valores 
de $x y $y a la acción add a $a y $b respectivamente en servidor1 al invocar este método en el 
objeto de servicio creado. 
 
El  mismo  ejemplo  se  puede  implementar  utilizando  un  Proxy  a  un  tercer  servidor  quien 
finalmente realiza la operación. 
 
El servicio web en el servidor2 queda así implementado: 
 
Ejemplo: Definir un Proxy a servicios web 
<?php
class AritmethicController extends WebServiceController {
public function addAction($a, $b){
$service = new
WebServiceClient(“http://server3/ins/aritmethicserver/”);
return $service->add($x, $y); //Devuelve la suma en el servidor3
}
}

El servicio Web AritmethicServer implementado en el servidor3: 
 
Ejemplo: Servicio web aritmético en el tercer servidor 
<?php
class AritmethicServerController extends WebServiceController {
public function addAction($c, $d){
return $c + $d;
}
}
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    106 

Aunque no es necesario implementar este ejemplo usando 3 maquinas, permite ilustrar como 
se  puede  abstraer  la  lógica  de  aplicación  en  forma  distribuida  de  tal  forma  que  múltiples 
aplicaciones  accedan  a  servicios  reutilizables  que  aumentan  la  escalabilidad  de  los  sistemas 
desarrollados. 

8.17.8 Características de Servicios Web en Kumbia Enterprise 
Al  igual  que  los  otras  implementaciones  de  controladores,  en  los  servicios  web  usando 
WebServiceController se usa de forma transparente toda la funcionalidad del framework que 
se usa en los controladores de aplicación, algunas de estas son: 
 
• Es posible acceder a los modelos como propiedades de la clase controladora 
• Se  puede  implementar  persistencia  del  estado  del  controlador  entre  sesiones  y 
peticiones 
• Se  puede  enrutar  el  flujo  de  ejecución  a  otros  servicios  Web  dentro  de  la  misma 
aplicación 
• Seguridad  declarativa  y  programacional  se  puede  implementar  en  este  tipo  de 
controladores 

8.18 Controladores StandardForm

La implementación de controladores StandardForm es una característica heredada de Kumbia 
PHP  Framework.  Por  motivos  de  compatibilidad  con  aplicaciones  existentes  en  la  versión 
Enterprise  su  funcionalidad  se  mantiene  intacta.  El  objetivo  de  esta  implementación  es  la 
generación dinámica de formularios que permitan administrar la información de tablas en la 
conexión pretederminada del entorno actual. 
 
El  desarrollador  debe  evaluar  si  las  limitantes  de  esta  implementación  no  afectarán  en  un 
futuro los objetivos de negocio de la aplicación. 
 
Nota:  Esta  implementación  esta  agendada  para  ser  marcada  como  obsoleta  en  versiones 
posteriores  del  framework.  LouderTechnology  está  activamente  desarrollado  Louder 
Application  Forms  el  cuál  genera  componentes  de  aplicación  robustos  que  aprovechan  de 
manera más adecuada y flexible las posibilidades del framework. 

8.18.1 Características de StandardForm 
• Generación  dinámica  de  un  CRUD  (Create,  Read,  Update,  Delete)  con  posibilidad  de 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    107 

utilizar parte de ellas ó todos. 
• De  acuerdo  a  la  información  de  los  meta‐datos  de  una  tabla  en  la  base  de  datos 
generando componentes de interfaz de usuario adecuados para cada campo. 
• Es posible realizar validación del lado del cliente y del servidor. 
• Es posible implementar eventos de acuerdo a las acciones ejecutadas por el usuario en 
el controlador. 
• La información de la tabla creada puede ser exportada a PDF, HTML, Microsoft Word y 
Excel. 

8.18.2 Limitantes de StandardForm 
• La  especificación  del  modelo  entidad‐relación  esta  limitada  a  tablas  y  campos 
definidos mediante las convenciones del framework 
• La funcionalidad de los formularios generados sobre todo la visual puede ser difícil de 
personalizar con respecto a los objetivos del desarrollador. 

8.19 Plugins de Controladores

En  ciertas  ocasiones  cuando  las  aplicaciones  corren  en  múltiples  entornos  con  diferentes 
características,  la  funcionalidad  y  alcance  de  la  misma  aplicación  no  es  suficiente  y  se  debe 
extender  automáticamente  durante  el  runtime.  La  arquitectura  de  plugins  de  Controladores 
permite observar, extender y manipular el comportamiento de las clases controladoras de la 
aplicación según las condiciones lo exijan. 
 
Los  plugins  permiten  interceptar  eventos  de  los  controladores  de  tal  forma  que  estos  sean 
observables  y  además  ejecutárse  uno  tras  otro  de  manera  centralizada  sin  requerir 
refactorización ó reintegración en la aplicación. 

8.19.1 Crear un Plugin de Controlador 
Los plugins de controlador son clases que implementan eventos que son invocados a medida 
que avanza la ejecución de una petición en cualquier controlador. Estas clases deben cumplir 
con los siguientes requerimientos: 
 
 Deben estar ubicados en el directorio de plugins usualmente apps/app­name/plugins 
 El nombre del archivo que implementa la clase debe ser el nombre del plugin 
 El nombre de la clase debe tener la extensión Plugin 
 Los plugins de controlador deben heredar de la clase ControllerPlugin ó ser subclase de ella 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    108 

 
Las  clases  pueden  implementar  métodos  públicos  que  referencian  los  eventos  ocurridos  en 
los controladores, la lista de ellos es la siguiente: 
 
Tabla: Eventos que se pueden implementar en plugins de Controlador 
Nombre Evento  Descripción 
beforeDispatchLoop  Ocurre  antes  de  iniciar  el  ciclo  de  enrutamiento,  en  este  punto 
no se ha cargado el controlador, aunque se encuentra disponible 
todo el entorno de la aplicación. 
beforeDispatch  Ocurre dentro del ciclo de enrutamiento y justo antes de invocar 
el  controlador  solicitado.  Este  evento  se  invoca  por  cada 
controlador usado en el flujo de ejecución. 
beforeExecuteRoute  Ocurre  antes  de  ejecutar  la  acción  solicitada  en  el  controlador, 
en  este  punto  se  puede  obtener  los  datos  de  la  petición, 
controlador, acción y parámetros. 
afterExecuteRoute  Ocurre  después  de  ejecutar  la  acción  solicitada  en  el 
controlador. 
afterDispatch  Ocurre  después  del  proceso  de  ejecución  de  la  acción  por 
controlador. 
afterDispatchLoop  Ocurre cuando termina el ciclo de enrutamiento. 
beforeNotFoundAction  Ocurre  cuando  la  acción  ó  controlador  ejecutado  solicitado  no 
esta  implementado.  Es  independiente  de  si  la  acción 
notFoundAction está implementada. 
beforeUncaugthException  Ocurre  antes  de  lanzarse  una  excepción  que  no  fue  capturada 
por la aplicación. 
onControllerException  Ocurre cuando se genera una excepción dentro del controlador. 
Se ejecuta antes de beforeUncaughException 
 
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    109 

9 Componente UDDI
9.1 Introducción

Este  componente  es  una  implementación  de  la  especificación  de  servicios  Web,  Universal 
Description,  Discovery  and  Integration  (UDDI).  El  prinicipal  objetivo  de  este  componente  es 
permitir a servicios e controladores desarrollados en Kumbia Enterprise servir como registros 
de servicios permitiendo que dominios de computación heterogeneos puedan consultarlos y 
conectar servicios a sistemas existentes. 

9.2 Requerimientos

Se requiere tener en cuenta lo siguiente para utilizar UDDI: 
 
 Persistencia:  El  componente  UDDI  requiere  de  un  gestor  relacional  para  almacenar 
los registros del directorio.  
 Autenticación:  El  componente  Auth  es  requerido  para  ofrecer  los  servicios  de 
autenticación a los controladores de publicación de registros. 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    110 

10 Componente BusinessProcess
10.1 Introducción

Este  componente  da  la  posibilidad  de  implementar  meta‐procesos  usando  BPEL,  de  esta 
forma  se  busca  la  optimización  y  mejoramiento  de  procesos  de  negocio  en  una  aplicación 
desarrollada usando Kumbia Enterprise. 
 
Actualmente  el  lenguaje  PDL  (basado  en  el  jPDL)  es  soportado  por  este  componente  con  el 
cual  se  puede  expresar  procesos  de  negocio  en  terminos  de  tareas,  estados  de  espera, 
comunicación sincronica, etc.  
 
El  componente  permite  su  integración  con  otros  componentes  permitiendo  levantar 
configuración, establecer persistencia, identificación, etc. 
 

10.1.1 ¿Que es un proceso de negocio? 
Un proceso de negocio es un conjunto de actividades estructuradas y relacionadas que tienen 
como objetivo prestart un servicio que satisfaga las necesidades de un cliente. Los procesos de 
negocio  son  críticos  para  las  organizaciones  y  su  correcta  estructuración  y  definición 
determina el éxito de una organización. 
 

10.1.2 ¿Qué es BPEL? 
BPEL  es  un  lenguaje  de  orquestación  de  servicios  web.  Los  lenguajes  de  orquestación 
implicitamente  indican  la  intervención  ó  la  facilidad  de  comunicación  entre  diferentes 
sistemas que puedan tener diferentes plataformas e infraestructura de sistemas. 

10.2 Job Executor

El  componente  BusinessProcess  ofrece  un  entorno  de  ejecución  para  PHP  que  permite 
ejecutar procesos PDL ya sea para orquestar servicios ó ejecutar procesos funcionales. 

10.3 Crear un Proceso de Negocio

Un proceso de negocio se especifica utilizando una estructura XML que representa los estados 
del  meta‐proceso.  Cada  uno  debe  contener  un  estado  inicial  y  uno  final  que  indique  donde 
empezar y donde se debe terminar. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    111 

 
En el siguiente ejemplo se ilustra un proceso BPM de un sistema de punto de venta (POS). El 
estado  inicial  del  proceso  se  marca  con  el  nodo  “start‐state”.  Es  sencillo  seguir  el  flujo  del 
meta‐proceso gracias a los nodos “transition” que transfieren el flujo de ejecución de un nodo 
a otro. 
 
Ejemplo: Definición de un proceso BPM en PDL 
<?xml version="1.0" encoding="UTF-8"?>
<process-definition name='Pedido'>
<start-state>
<transition to="irAlMenu"/>
</start-state>
<state name="irAlMenu">
<transition to="ingresarClave"/>
</state>
<state name="ingresarClave">
<decision handler="autenticar">
<transition condition="{#autorizado}==false" to="fin"/>
<transition condition="{#autorizado}==true"
to="tomarPedido"/>
</decision>
</state>
<state name='tomarPedido'>
<task-node name='Mesa y Comanda'>
<task name='Ir a Mesas' handler='irAMesas'/>
<task name='Escoger Mesa' handler='escogerMesa'/>
<decision name='Consultar Tipo de Comanda'
handler='consultarTipoComanda'>
<transition condition="{#tipoComanda}=='A'"
to="ingresarNumeroPersonas"/>
<transition condition="{#tipoComanda}=='M'"
to="ingresarComandaManual"/>
</decision>
</task-node>
</state>
<state name='ingresarComandaManual'>
<decision name='Comanda Existe' handler='comandaExiste'>
<transition condition="{#comandaExiste}==true" to="fin"/>
<transition condition="{#comandaExiste}==false"
to="estableceNumeroComanda"/>
</decision>
</state>
<state name='estableceNumeroComanda'>
<task name='Establece la comanda' handler='establecerComanda'/>
<transition to='ingresarNumeroPersonas'/>
</state>
<state name='ingresarNumeroPersonas'>
<decision name='Requiere Numero Personas'
handler='requiereNumeroPersonas'>
<transition condition="{#requierePersonas}==true"
to="ingresarPersonas"/>
<transition condition="{#requierePersonas}==false"
to="seleccionarMenu"/>
</decision>
</state>
<state name='ingresarPersonas'>
<task name='Establece las Personas en la Mesa'
handler='ingresarPersonas'/>
<transition to='seleccionarMenu'/>
</state>
<state name='seleccionarMenu'>
<task-node name='Seleccionar Menu'>
<task name='Seleccionar un Menu' handler='escogerMenu'/>
</task-node>
</state>
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    112 

<state name="fin">
</state>
</process-definition>
 

10.3.1 Tipos de nodos de un meta­proceso PDL 
Un meta‐proceso soporta los siguientes tipos de nodos: 
 
Tabla: Tipos de nodos de un meta­proceso PDL 

Tipo Nodo  Descripción 

Representa un estado del proceso. Los estados deben tener un 
nombre  que  permite  identificarlos  unívocamente  en  toda  la 
definición del proceso y así generar una transición a ellos. Este 
state 
tipo de nodos contienen nodos hijos que conrresponden a las 
actividades  realizadas  por  el  estado.  El  nombre  del  estado  se 
define con el atributo “name”. 

Este tipo de nodo permite realizar una transición a otro estado 
del proceso. Dependiendo del proceso la transición puede ser 
condicional,  en  estos  casos  se  implementarán  2  nodos  de 
transtion  transición  seguidos  con  el  atributo  “condition”  definido.  La 
primera  transición  cuya  evaluación  resulte  verdadera  sera 
quien  realice  la  transición.  El  nodo  a  recibir  el  flujo  de 
ejecución se especifica con el atributo “to”. 

Los  nodos  “decision”  permiten  efectuar  saltos  condicionales 


usando transiciones. El parámetro “handler” indica el nombre 
decision  de un método en el proceso PHP asociado al meta‐proceso que 
tiene como objetivo cargar las condiciones para la evaluación 
en las transiciones siguientes. 

Este  tipo  de  nodos  tienen  un  handler  que  referencia  un 
método  en  el  proceso  PHP  asociado  y  normalmente  es  usado 
task 
para  realizar  una  operación  de  negocio  parte  del  meta‐
proceso.  

Cuando  se  requiere  ejecutar  varios  nodos  “task”  se  usa  un 
task‐node 
“task‐node”  el  cual  permite  asociar  varias  operaciones  de 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    113 

negocio dentro de un estado del meta‐proceso. 

10.3.2 Crear los handlers del BusinessProcess 
Un proceso de negocio debe ser definido el cual realizará la carga de la definición PDL para su 
posterior ejecución: 
 
Ejemplo: Crear una clase de proceso de negocio BusinessProcess 
<?php
class PedidoProcess extends BusinessProcess {
/**
* Inicializar el proceso de negocio
*
*/
public function initialize(){
$processDefinition =
ProcessDefinition::parseXMLFile("apps/pos/test/pedido.xml");
$processInstance = new ProcessInstance($processDefinition, $this);
$processInstance->signal();
}
}
 
Enlaces externos: 
 http://en.wikipedia.org/wiki/Business_Process_Management#BPM_Technology 
 http://en.wikipedia.org/wiki/BPEL 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    114 

11 Componente Filter
11.1 Introducción

El componente Filter proporciona un conjunto de filtros de datos y una interfase consistente 
para su aplicación a datos y entrada de usuario en un proceso de negocio. 
 
Los  filtros  están  diseñados  para  transformar  datos,  quitar  partes  indeseadas,  eliminar 
espacios ó caracteres innecesarios y en resumen asegurarse que una variable contiene lo que 
se espera que contenga.  
 
El  aplicar  los  filtros  adecuados  a  la  entrada  de  usuario  constituye  el  primer  paso  para 
cerciorarse que los procesos de negocio se ejecutaran utilizando datos que en cierta forma no 
dañen ni alteren el flujo y estado normal de una aplicación. 

11.2 Estructura del Componente

El  componente  lo  constituye  la  clase  Filter  y  una  serie  de  filtros  base  de  uso  general  que 
incluye el framework para su aplicación al común de aplicaciones Web de negocios. 
 
Los filtros base son los siguientes: 
 
Tabla: Filtros base del componente Filter 
Nombre  Nombre Corto  Uso/Descripción 
Alnum  alnum  Filtra  caracteres  alfanuméricos  (letras  y 
números). 
Alpha  alpha  Filtra  letras  del  abecedario  occidental 
incluyendo caracteres latinos como vocales con 
tilde y eñes. 
AddSlaches  addslaches  Escapa las comillas simples y dobles para evitar 
inyección de SQL. 
BaseName  basename  Filtra  un  path  para  obtener  el  nombre  del 
archivo ó el último directorio. 
Date  date  Filtra  una  cadena  de  caracteres  devolviendo 
una fecha que coincida con la expresión regular 
'/(19|20)(\d{2})[‐\/](\d{1,2})[‐\/](\d{1,2})/' 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    115 

ó el formato YYYY‐MM‐DD. 
Digits  digits  Filtra  una  cadena  para  que  contenga  solo 
dígitos (números del 0 al 9) 
Double  double  Filtra  un  valor  devolviendo  un  valor  numérico 
de alta precisión. 
Email  email  Filtra una cadena de caracteres devolviendo un 
correo electrónico valido. 
Extraspaces  extraspaces  Filtra  una  cadena  de  caracteres  eliminando 
espacios y saltos de línea al principio y final de 
la cadena. 
Float  float  Filtra  un  valor  devolviendo  un  valor  numérico 
de alta precision 
HtmlEntities  htmlentities  Convierte  todos  los  caracteres  aplicables  de 
una cadena de caracteres a sus entidades HTML 
correspondientes. 
HtmlDecode  htmldecode  Convierte entidades HTML a su carácter UTF‐8 
correspondiente. 
Identifier  identifier  Filtra un valor dejando solo un identificador de 
variable valido. 
Int  int  Filtra el valor recibido en un entero de 32bit ó 
64 bit dependiendo de la plataforma. 
Ipv4  ipv4  Filtra  una  cadena  de  caracteres  devolviendo 
una dirección IP versión 4. 
Ipv6  ipv6  Filtra  una  cadena  de  caracteres  devolviendo 
una dirección IP versión 6. 
Lower  lower  Filtra  una  cadena  de  caracteres  devolviéndola 
en minúsculas. Este filtro respeta el charset de 
la aplicación. 
Locale  locale  Filtra  una  cadena  de  definición  de  localización 
UNICODE. 
Md5  md5  Convierte  una  cadena  de  caracteres  a  su 
resumen criptográfico md5 
Numeric  numeric  Convierte el valor recibido en valor numérico. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    116 

Onechar  onechar  Filtra la cadena para obtener un solo carácter. 


Stripspace  stripspace  Elimina  los  caracteres  espacios  en  toda  la 
cadena de caracteres recibida. 
Striptags  striptags  Elimina  las  etiquetas  HTML  que  contenga  la 
cadena de caracteres recibida. 
Stripslaches  stripslaches  Des‐escapa  una  cadena  de  carácteres 
convirtiendolos  a  sus  carácteres  de  comillas 
normales. 
Upper  upper  Filtra  una  cadena  de  caracteres  devolviéndola 
en mayúsculas. Este filtro respeta el charset de 
la aplicación. 
Utf8  utf8  Convierte  una  cadena  de  caracteres  en  ISO‐
8859‐1 a UTF‐8 

11.3 Usar filtros en forma directa

Para  aplicar  un  filtro  a  un  valor  en  forma  directa  es  necesario  instanciar  la  clase  Filter  e 
invocar  el  método  applyFilters  enviando  como  primer  parámetro  el  valor  a  filtrar  y  como 
parámetros siguientes los nombres cortos de los filtros a aplicar: 
 
Ejemplo: Crear filtros en forma directa 
<?php
$filter = new Filter();
print $filter->applyFilter("a1b2c3d4e5", "digits"); // Imprime 12345
$filter = new Filter();
print $filter->applyFilter("<h1>Hola</h1>", "striptags", “upper”); // Imprime
HOLA

 
Es  necesario  crear  una  instancia  de  filter  por  cada  combinación  de  filtros  que  se  requieran 
aplicar ya que cada objeto filter almacena en un buffer estos filtros: 
  
Ejemplo: Usar el buffer de los filtros 
<?php
$filter = new Filter();
print $filter->applyFilter("a1b2c3d4e5", "digits"); // Imprime 12345
print $filter->applyFilter("www.radiobox77.com"); // Imprime 77

11.4 Crear chains de Filtros

Es posible crear chains para la aplicación de filtros base y de usuario a un mismo valor de la 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    117 

siguiente manera: 
 
Ejemplo: Implementar Chains de Filtros 
<?php
Filter::load("striptags", "email", "lower", “special”);
$filter = new Filter();
$filter->addFilter(new StriptagsFilter());
$filter->addFilter(new EmailFilter());
$filter->addFilter(new LowerFilter());
$filter->addFilter(new LowerFilter());
$filter->addFilter(new SpecialFilter());
print $filter->applyFilter("<b>ANEWUSER1978@YAHOO.ES</b>")."<br>";
 
El  método  estático  Filter::load  carga  uno  ó  más  filtros  ya  sean  de  usuario  ó  base  luego  se 
agregan los filtros y se aplican como es estándar. Los filtros también pueden agregarse por su 
nombre corto, agregar varios a la vez y mezclarlos. El orden en que se agregan indica el orden 
de aplicación: 
 
Ejemplo: Aplicar múltiples filtros a un valor 
<?php
Filter::load("striptags", "email", "lower", “special”);
$filter = new Filter();
$filter->addFilter("striptags");
$filter->addFilter("email", new LowerFilter());
$filter->addFilter(new SpecialFilter());
print $filter->applyFilter("<b>ANEWUSER@YAHOO.ES</b>")."<br>";

11.5 Usar filtros en Controladores

Los controladores son probablemente un punto donde los filtros tengan mayor participación 
ya que es aquí donde se requiere asegurar que los procesos de negocio se ejecuten con datos 
consistentes y confiables. 
 
El método de Controller::filter actua como un Proxy al componente Filter permitiendo filtrar 
variables sin instanciar explícitamente alguna clase adicional: 
 
Ejemplo: Aplicar un filtro desde un controlador 
<?php
class InvoicesController extends ApplicationController {
public function listInvoicesAction(){
//Se obtiene un valor de la entrada y se filtra
$initialDate = $this->getPostParam("initialDate");
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    118 

$initialDate = $this->filter($initialDate, "date");


//Resto del proceso…
}
}
 
Adicional  a  lo  anterior  los  métodos  de  Controller  getPostParam,  getRequestParam  y 
getQueryParam reciben como parámetros extra al valor requerido nombres cortos de filtros 
los cuales se aplican en este orden y se retornan al proceso: 
 
Ejemplo: Aplicar un filtro a la entrada de usuario 
<?php
class InvoicesController extends ApplicationController {
public function listByNameInvoicesAction(){
//Se obtiene un valor de la entrada y se filtra directamente
$name = $this->getPostParam("name", “striptags”, “extraspaces”);
//Resto del proceso…
}
}

11.6 Filtrar la entrada de usuario

El  componente  filter  está  integrado  a  los  controladores  permitiendo  validar  la  entrada  de 
usuario cuando es recibida desde un formulario ó una URL. 
 
El siguiente ejemplo  define una serie de reglas para validar los valores recibidos desde una 
entrada de usuario generando los mensajes correspondientes: 
 
Ejemplo: Filtrar y validar la entrada de usuario desde un formulario 
<?php
class UsersController extends ApplicationController {
public function doRegisterAction(){
$fields = array(
'username' => array(
'message' => 'Por favor indique su nombre de usuario',
'filter' => 'extraspaces|striptags'
),
'password' => array(
'message' => 'Por favor indique su contrase&ntilde;a'
),
'confirmPassword' => array(
'message' => 'Por favor indique la confirmaci&oacute;n
de la contrase&ntilde;a'
),
'email' => array(
'message' => 'Por favor indique su correo
electrónico',
'filter' => 'email'
),
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    119 

'confirmEmail' => array(


'message' => 'Por favor indique la confirmación de su
correo electrónico',
'filter' => 'email'
),
'name' => array(
'message' => 'Por favor indique su nombre',
'filter' => 'extraspaces|striptags'
),
'lastName' => array(
'message' => 'Por favor indique sus apellidos',
'filter' => 'extraspaces|striptags'
),
'address' => array(
'message' => 'Por favor indique la dirección de su
residencia',
'filter' => 'extraspaces|striptags'
),
'phone' => array(
'message' => 'Por favor indique su teléfono'
),
'city' => array(
'message' => 'Por favor indique la ciudad'
),
'company' => array(
'message' => 'Por favor indique la empresa'
)
);
if($this->validateRequired($rules)==false){
foreach($this->getValidationMessages() as $message){
$message->showErrorMessage();
}
$this->routeTo(array('action' => 'startSignIn'));
}
}
}

La  propiedad  de  la  regla  ‘filter’  permite  definir  el  filtro  que  debe  ser  aplicado  a  cada  valor 
recibido antes de determinar si está presente, de esta forma se controla que el valor evaluado 
sea válido y se genere el mensaje correspondiente.  Si se requiere que se aplique más de un 
filtro, se puede indicar una lista separada por | (pipes). 
 
Consulte  el  componente  Validator  para  obtener  más  información  sobre  filtrar  la  entrada  de 
usuario. 

11.7 Crear un filtro de usuario

El  desarrollador  puede  crear  sus  propios  filtros  en  la  aplicación  e  integrarlo  al  componente 
filter para su posterior utilización. 
 
Tanto los filtros base como los de usuario deben implementar la interface FilterInterface que 
tiene la siguiente estructura: 
 
<?php
interface FilterInterface {
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    120 

public function execute($value);


}

11.7.1 Requerimientos de un filtro de usuario 
Al crear un filtro de usuario se debe tener en cuenta lo siguiente: 
 
• Se crea un archivo ubicado en el directorio filters/ de la aplicación ó donde la opción 
filtersDir del archivo de configuración config/config.ini indique. 
• El nombre del archivo es el nombre del filtro con la primera letra en mayúscula  
• El archivo debe contener una clase con el nombre del filtro y sufijo “Filter” 
• La clase debe implementar la interface FilterInterface 
 
En el siguiente ejemplo se crea un filtro de usuario que apartir de una URL filtra el dominio 
que corresponde a ella: 
 
Ejemplo: Filter de usuario que filtra dominios en una URL 
<?php
class DomainFilter implements FilterInterface {
public function execute($url){
$protocol = strpos($url, "//");
if($protocol!==false){
$url = substr($url, $protocol+2);
}
$fisrtSlash = strpos($url, "/");
if($fisrtSlash!==false){
$url = substr($url, 0, $fisrtSlash);
}
return $url;
}
}
 
En  cualquier  parte  de  la  aplicación  se  puede  utilizar  usando  su  nombre  corto  ó  cargandolo 
mediante Filter::load: 
 
Ejemplo: Aplicar un filtro de usuario 
<?php
$filter = new Filter();
$url = "http://www.google.com/?q=kumbia%20framework";
print $filter->applyFilter($url, "domain"); // www.google.com
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    121 

12 ActionHelpers
12.1 Introducción

Los  ActionHelpers  son  subcomponentes  auxiliares  que  complementan  y  auxilian  a  las 


implementaciones de controladores algunas veces estableciendo puentes a la presentación y 
otras veces a la capa de datos. 

12.2 Mensajes usando Flash

El ActionHelper Flash permite la generación de mensajes contextuales en cualquier parte de la 
aplicación.    Adicional  a  esto  es  posible  almacenar  mensajes  para  ser  mostrados  cuando  se 
requiera en otras peticiones. 

12.2.1 Generar mensajes contextuales  
Los  mensajes  contextuales  permiten  aparte  del  mensaje  por  medio  de  colores  e  iconos 
informar el carácter del mismo. 
 
Tabla: Tipos de mensajes contextuales con Flash 

Método  Tipo  Descripción 

Error  Informa que hay una situación de error. Por defecto se usa 
Flash::error 
fondo rosa, texto en rojo y un icono de adminiración. 

Información  Da  el  contexto  de  información.  Por  defecto  se  usa  fondo 
Flash::notice 
azul y letra azul oscuro. 

Éxito  Indica que la operación tuvo éxito ó se ejecutó un proceso 
Flash::success  satisfactoriamente.  Por  defecto  se  usa  fondo  verde 
llamativo y letra verde oscura. 

Advertencia  Genera  un  mensaje  con  el  contexto  de  advertencia.  Por 
Flash::warning  defecto se usa amarillo claro en el fondo, letra en negro y 
un icono de alerta. 

 
Todos los métodos reciben en su parámetro el mensaje a mostrar.  

12.2.2 Cambiar el estilo por defecto de los mensajes 
Si se desea cambiar el estilo de los mensajes de texto se puede modificar ó sobreescribir las 
clases CSS en el archivo public/css/style.css que siempre se inserta en todas las peticiones. Por 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    122 

defecto las clases tienen los siguientes estilos: 
 
Ejemplo: Estilos CSS predefinidos para mensajes del Flash 
.kumbiaDisplay {
font-size: 11px;
font-weight: bold;
margin: 0 auto;
padding: 2px 25px;
background-repeat: no-repeat;
background-position: 5px center;
text-align: left;
}
.errorMessage {
background-image: url("@path/img/error.gif");
background-color: #FFDDDD;
color: #B30000;
border: 1px solid #FFB7B7;
margin: 2px;
text-align: left;
}
.noticeMessage {
background-image: url("@path/img/user.gif");
background-color: #CCDEFF;
color: #004A6F;
margin: 2px;
border: 1px solid #004A6F;
text-align: left;
}
.sucessMessage {
background-image: url("@path/img/ok.gif");
background-color: #CCFF99;
color: #008000;
border: 1px solid #008000;
}
.warningMessage {
background-image: url("@path/img/warning.gif");
background-color: #FFFFC6;
color: #000000;
border: 1px solid #DDDD00;
}

12.2.3 Cambiar el estilo en forma dinámica 
Si  se  requiere  cambiar  la  presentación  de  un  mensaje  en  forma  programacional  se  puede 
enviar un listado de clases CSS como segundo parámetro.  
 
Ejemplo: Establecer una clase CSS personalizada para Flash  
Flash::notice("Esto es una información personalizada", array("mi_clase_css",
"otra_clase_css"));
 

12.2.4 Enviar múltiples mensajes del mismo tipo en forma simúltanea 
Cuando el primer parámetro recibido por un método de mensajes es un vector con mensajes 
la lista de estos es enviada una tras otra en el orden recibido. 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    123 

Ejemplo: Enviar varios mensajes simultáneos  mediante un array con Flash  
Flash::error(array(
"Este es el primer error",
"Este es el segundo error",
"Este es el tercer error",
));

12.2.5 Mostrar mensajes por su tipo 
El  método  de  Flash  llamado  message  permite  mostrar  un  mensaje  utilizando  una  constante 
como segundo parámetro que establece el tipo a mostrar: 
 
Flash::message("Esto es una advertencia", Flash::WARNING);
Flash::message("Esto es un error", Flash::ERROR, array("my_error_css"));
 
Tabla: Constantes de los tipos de mensajes 

Valor  Constante  Descripción 

0  Flash::ERROR  Mensajes de error 

1  Flash::NOTICE  Mensajes de información 

2  Flash::SUCCESS  Mensajes de éxito 

3  Flash::WARNING  Mensajes de advertencia 

12.2.6 Cachear mensajes para mostrarlos en la próxima petición 
Si  se  requiere  mostrar  mensajes  al  usuario  después  de  realizar  una  redirección  se  puede 
utilizar el método addMessage que funciona como el método message recibe el mensaje y un 
código indicando el tipo. Los mensajes que se agregan de esta forma no son visualizados sino 
hasta que se invoca el método getMessages().   
 
El siguiente ejemplo ilustra el funcionamiento de este tipo de mensajes: 
 
Ejemplo: Enviar mensajes Flash usando la cola de mensajes de próxima petición 
<?php
class LoginController extends ApplicationController {
public function indexAction(){
Flash::addMessage("Bienvenido usuario", Flash::SUCCESS);
$this->redirect("login/menu");
}
public function menuAction(){
foreach(Flash::getMessages() as $message){
Flash::message($message['message'], $message['type']);
}
}
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    124 

}
 
Los  mensajes  agregados  con  addMessage  se  almacenan  en  un  buffer  del  contexto  de  sesión. 
Cuando los mensajes se obtienen con getMessages el buffer interno se resetea. 

12.3 Condiciones SQL con FormCriteria

El  actionhelper  FormCriteria  permite  crear  condiciones  SQL  a  partir  de  los  parámetros 
recibidos  por  un  formulario  de  entrada  de  usuario.  De  acuerdo  a  los  parámetros  recibidos, 
solo los que tengan valores no nulos se incluyen en las condiciones generadas. 
 
En el siguiente ejemplo se muestra como crear la condición de búsqueda para diversos tipos 
de datos obtenidos desde un formulario. 
 
Los datos capturados son: 
 
 Código: Corresponde al código del producto y es de tipo numérico. 
 Nombre: El nombre del producto y es de tipo texto. 
 Categoría:  Campo  de  tipo  entero  de  la  entidad  Products  que  es  relación  a  la  tabla 
ProductCategories.  Se  usa  Tag::select  para  cargar  los  datos  de  esta  tabla  y  se  indica  el 
parámetro useDummy para agregar la opción ‘Seleccione…’. 
 Tipo:  Combo  creado  apartir  de  un  array  con  valores  estáticos  que  corresponde  al 
campo type de la entidad Products. 
 
El formulario en la vista views/products/index.phtml es el siguiente: 
 
<h1>Buscar Productos</h1>
<?php echo Tag::form('products/search'); ?>
<table>
<tr>
<td align="right">Código:</td>
<td><?php echo Tag::numericField('code') ?></td>
</tr>
<tr>
<td align="right">Nombre:</td>
<td><?php echo Tag::textField('name') ?></td>
</tr>
<tr>
<td align="right">Categoría:</td>
<td><?php echo Tag::select('product_category_id',
$ProductsCategories->find(), 'using: id,name', 'useDummy: yes') ?></td>
</tr>
<tr>
<td align="right">Tipo:</td>
<td><?php echo Tag::selectStatic('type', array(
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    125 

'A' => 'ALIMIMENTOS',


'B' => 'BEBIDAS',
'O' => 'OTRO'
), 'useDummy: yes') ?></td>
</tr>
<tr>
<td></td>
<td><?php echo Tag::submitButton('Enviar') ?></td>
</tr>
</table>
<?php echo Tag::endForm() ?>
 
En el controlador se define la búsqueda según se envie los parámetros a la acción search:  
 
Ejemplo: Crear un criterio de búsqueda SQL usando FormCriteria 
<?php
class ProductsController extends ApplicationController {
public function indexAction(){
}
public function searchAction(){
$criteria = new FormCriteria($_POST, array(
'code' => array(
'type' => 'integer',
'fieldName' => 'id'
),
'name' => array(
'type' => 'string'
),
'product_categories_id' => array(
'type' => 'integer',
'operator' => '=',
'nullValue' => '@'
),
'type' => array(
'type' => 'string',
'operator' => '=',
'nullValue' => '@'
)
));
$this->Products->find($criteria->getConditions());
}
}

 
El  constructor  recibe  2  parámetros,  el  primero  corresponde  al  origen  de  los  datos  de  los 
cuales se construira el criterio de búsqueda. El segundo es un descriptor con los campos que 
se reciben del formulario y la forma en que debe construirse la condición para cada uno. Las 
llaves  del  descriptor  son  los  nombres  de  las  variables  que  vienen  del  formulario  y  que  son 
parte del origen de datos.  En el ejemplo el origen de datos es la superglobal $_POST. 
 
La descripción de las opciones para cada campo es: 
 
Tabla: Opciones de los campos para crear el criterio de búsqueda con FormCriteria 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    126 

Opción  Descripción 
type  Es  el  tipo  de  dato  que  se  espera  recibir  del  formulario.  Puede  ser 
integer,  float,  double,  date  y  string.  Dependiendo  del  tipo  de  dato  es 
posible que se apliquen filtros.  
operador  Un  operador  compatible  con  el  gestor  relacional  utilizado.    Cuando  la 
opción  “type”  es  integer,  float,  double  y  date  se  utiliza  el  operador  ‘=’ 
cuando es string se usa el operador ‘LIKE’.  
missOnNull  Un valor booleano que determina si se debe omitir la condición  caso de 
que el valor recibido sea nulo ó el valor establecido para nulo mediante 
‘nullValue’. Por defecto su valor es true. 
nullValue  El  valor  que  debe  entenderse  como  valor  nulo  para  saber  si  se  debe 
omitir al generar la condición. 
fieldName  El nombre del atributo en la entidad. Si no se indica se usa el nombre de 
la llave en el descriptor. 
 
Si se envia el valor code=10 se produce la condición: 
 
id = 10

Si se envian los valores code=10 y nombre=”cheese cake” se produce la condición: 
 
id = 10 OR name LIKE ‘%cheese%cake%’

Si se envian los valores product_categories_id = 2 y type=’A’ (type es el nombre del campo) se 
produce la condición: 
 
product_categories_id = 2 OR type = ‘A’
 
Por  defecto  el  operador  para  unir  las  condiciones  es  OR,  con  lo  que  si  cualquiera  de  las 
opciones  se  cumple  entonces  se  obtiene  el  resultado.  Si  se  desea  lo  contrario  entonces  se 
puede enviar el operador como parámetro de getConditions así. 
 
$this->Products->find($criteria->getConditions(‘AND’));

12.3.1 Criterios de Rangos 
Con  FormCriteria  también  es  posible  crear  criterios  de  rangos  cuyos  valores  sean  obtenidos 
de un formulario de entrada de usuario.  
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    127 

Si lo que se requiere es que apartir de campos obtenidos del formulario se cree la condición 
entonces debe definir de la siguiente forma: 
 
Ejemplo: Crear un criterio basado en un rango de fechas con FormCriteria 
$criteria = new FormCriteria($_POST, array(
'fechaInicial:fechaFinal' => array(
'type' => 'date',
'fieldName' => 'fecha'
)
));
 
Si se envian los valores fechaInicial=”2008‐10‐20” y fechaFinal=”2008‐11‐22” se produciría la 
siguiente condición: 
 
fecha >= ‘2008-10-20’ AND fecha <= ‘2008-11-22’
 
Y si lo que se requiere es que el valor de la entrada de usuario se encuentre entre 2 campos de 
la tabla entonces se define así: 
 
//La tabla es de registro de vuelos
$criteria = new FormCriteria($_POST, array(
‘fecha' => array(
'type' => 'date',
'fieldName' => 'fechaLlegada:fechaSalida'
)
));

Si se envian el valor fecha=”2008‐10‐20”  se produciría la siguiente condición: 
 
fechaLlegada >= ‘2008-10-20’ AND fechaSalida <= ‘2008-10-20’

12.3.2 Unir varias condiciones 
Varias  criterios  pueden  ser  unidos  utilizando  operadores  diferentes  para  de  esta  forma 
construir condiciones más complejas: 
 
Ejemplo: Crear condiciones de búsqueda compuestas con FormCriteria::form 
$criteria1 = new FormCriteria($_POST, array(
'code' => array(
'type' => 'integer',
'fieldName' => 'id'
),
'product_categories_id' => array(
'type' => 'integer',
'operator' => '=',
'nullValue' => '@'
),
));
$criteria2 = new FormCriteria($_POST, array(
'code' => array(
'type' => 'integer',
'fieldName' => 'id'
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    128 

),
'name' => array(
'type' => 'string'
),
));
$conditions = FormCriteria::join(‘OR’, array(
$criteria1->getConditions(‘AND’),
$criteria2->getConditions(‘AND’)
));

 
El  método  estático  FormCriteria::join  puede  unir  2  ó  más  objetos  FormCriteria  con  un 
operador diferente. 

12.4 Información del Navegador con Browser

Este ActionHelper permite obtener información del explorador del cliente desde el cuál se está 
accediendo a la aplicación. 

12.4.1 API de Browser 
El API es la siguiente: 
 
public static boolean isFirefox() 
Devuelve true si el explorador utilizado es Mozilla Firefox. 
 
public static boolean isSafari() 
Devuelve true si el explorador utilizado es Apple Safari. 
 
public static boolean isCamino() 
Devuelve true si el explorador utilizado es Camino. 
 
public static boolean isInternetExplorer() 
Devuelve true si el explorador utilizado es Microsoft Internet Explorer. 
 
public static boolean isMobileSafari() 
Devuelve true si el explorador utilizado es Apple Mobile Safari, el que usa el SO del iPhone y 
iPod Touch. 
 
public static boolean isIEMobile() 
Devuelve  true  si  el  explorador  utilizado  es  Microsoft  Internet  Explorer  Mobile  usado  en  el 
sistema operativo Windows Mobile. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    129 

 
public static boolean isOperaMobile() 
Devuelve  true  si  el  explorador  utilizado  es  Opera  Mobile  si  el  explorador  utilizado  es  Opera 
para Windows Mobile. 
 
public static string getVersion() 
Devuelve la versión del explorador utilizado. 
 
public static string getUserAgent() 
Devuelve el User Agent del explorador cliente. 
 
public static boolean isGecko() 
Devuelve true si el motor de renderizado del explorador es Gecko. 
 
public static boolean isWebKit() 
Devuelve true si el motor de renderizado del explorador es WebKit. 
 
public static string getAcceptEncoding() 
Indica los tipo de codificación soportador por el explorador. 
 
public static string getAcceptLanguage() 
Obtiene el idioma utilizado por el explorador usando el estándar RFC. 
 
public static boolean acceptCompressedOutput() 
Indica si el explorador acepta salida comprimida ya sea usando gzip ó deflate. 
 
public static string getBrowserAbrev() 
Devuelve una abreviatura del User Agent del explorador. 
 
public static boolean isMobile() 
Indica si el explorador usado se encuentra en una plataforma móvil. 
 
public static boolean isMacOSX() 
Devuelve true si el sistema operativo del cliente es Apple Mac OS X. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    130 

 
public static boolean isWindows() 
Devuelve true si el sistema operativo del cliente es Microsoft Windows 
 
public static boolean isLinux() 
Devuelve true si el sistema operativo del cliente es Linux. 

12.5 Autocompletar con Scriptaculous

El  helper  Scriptaculous  permite  convertir  un  conjunto  de  datos  en  el  formato  compatible  al 
componente  visual  de  autocompletar  que  proporciona  el  framework  script.aculo.us.  En  el 
siguiente ejemplo se muestra el uso de este: 
 
En  la  vista  se  usa  el  helper  de  la  vista  Tag::textWithAutocomplete  para  crear  un  campo  con 
autocompletar: 
 
<?php echo Tag::textFieldWithAutocomplete('pais', 'action: paises/consultar') ?>

Según su definición cuando el usuario escriba algunos carácteres se obtendrán los datos del 
resultado de la acción consultar en el controlador paises. 
 
Si  los  datos  de  paises  se  obtienen  de  un  array  estático  entonces  el  controlador  paises  es  el 
siguiente: 
 
Ejemplo:  Obtener  los  datos  de  auto­completado  desde  una  array  usando 
Scriptaculous::autocomplete 
<?php
class PaisesController extends ApplicationController {
public function consultarAction(){
//Se indica que la respuesta es AJAX
$this->setResponse('ajax');
//Se obtiene lo que digitó el usuario en la caja de texto
$pais = $this->getPostParam('pais');
//Obtener los datos de un array estatico
$paises = array(
'C' => 'COLOMBIA',
'E' => 'ECUADOR',
'M' => 'MEXICO',
'A' => 'ARGENTINA',
'U' => 'URUGUAY',
'B' => 'BOLIVIA'
);
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    131 

//Se filtran los que coincida con la busqueda


$paisesBusqueda = Scriptaculous::filter($pais, $paises);
//Se genera el HTML a devolver al usuario
$htmlCode = Scriptaculous::autocomplete($paisesBusqueda);
$this->renderText($htmlCode);
}
}
 
Si los datos de paises se obtienen de una tabla entonces el controlador paises es el siguiente: 
 
Ejemplo:  Obtener  los  datos  de  auto­completado  desde  una  tabla  usando 
Scriptaculous::autocomplete 
<?php

class PaisesController extends ApplicationController {


public function consultarAction(){
//Se indica que la respuesta es AJAX
$this->setResponse('ajax');
//Campos del modelo utilizados para crear el resultado
$fields = array('cod_pais', 'nombre');
//Obtener los paises requeridos
$paises = Scriptaculous::querySource(‘paises’, $fields, $pais);
//Se genera el HTML a devolver al usuario
$htmlCode = Scriptaculous::autocomplete($paises, $fields);
$this->renderText($htmlCode);
}
}
 
 
 
 
 
 
 
 
 
 
 
 

 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    132 

13 Componente Validator
13.1 Introducción

Este componente está integrado a las implementaciones de controladores y permite realizar 
validaciones sobre la entrada de usuario. Al ser independiente de la capa de lógica de dominio 
y presentación puede ser usado en los puntos de la aplicación que se requiera sin afectar la 
arquitectura de la misma. 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    133 

Parte 2: Seguridad  
 

14 Seguridad con Kumbia Enterprise


14.1 Introducción

Las aplicaciones Web y Servicios Web creadas usando Kumbia Enterprise Framework pueden 
ser distribuidas e implementadas usando diferentes entornos dentro de una misma instancia. 
Cada  aplicación  puede  constituir  una  arquitectura  multicapa  independiente  con 
requerimientos de seguridad diferentes. 
 
La seguridad de una aplicación puede ser implementada de 2 formas: 
 
• Declarativa  Externa:  Se  definen  los  requerimientos  de  seguridad  de  una  aplicación 
utilizando recursos externos a la misma sin intervenir de manera intrusiva en la lógica 
de la aplicación. La descripción de esta incluye detalles sobre como los roles acceden a 
los recursos de la aplicación y sus políticas.  
• Programacional  Interna:  Esta  embebida  en  la  aplicación  y  esta  implementada  en 
forma  de  decisiones  de  seguridad,  es  suficiente  cuando  los  requerimientos  de 
seguridad son simples y no cambian con frecuencia. 

14.2 Características de Seguridad

Mecanismos adecuados de seguridad ofrecen la siguiente funcionalidad: 
 
• Previenen acceso inautorizado a información y procesos de negocio 
• Controlan  que  las  actividades  realizadas  por  un  usuario  no  interfieran  con  las 
realizadas por otros impactando la integridad del sistema. 
• Protegen  el  los  servicios  del  sistema  de  riesgos  que  puedan  decaer  la  calidad  del 
servicio proporcionada 
 
La  seguridad  de  aplicaciones  basadas  en  Kumbia  Enterprise  Framework  consiste  en  la 
implementación  de  componentes  que  ayuden  a  proteger  los  recursos  de  la  misma.  Los 
procesos  de  seguridad  requieren  de  la  implementación  adecuada  de  autenticación, 
identificación, control de acceso, integridad de datos y calidad del servicio: 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    134 

 Autenticación:  La  aplicación  ejecuta  procesos  que  permiten  confiar  que  quien  hace 
uso de la misma es quien realmente se espera. 
 Autorización:  Es  el  proceso  de  identificar  a  que  conjunto  de  recursos  puede 
utilizar/acceder  con  el  propósito  de  establecer  controles  adecuados  de  integridad  de 
datos y limitaciones. 
 Integridad  de  Datos:  Permiten  que  solo  usuarios  ó  roles  autorizados  alteren  la 
información  a  la  que  se  les  ha  permitido  el  acceso  y  que  no  intervengan  con  otros 
procesos de otros usuarios autenticados. 
 Confidencialidad ó Privacidad: Permite que la información solo esté disponible para 
el usuario adecuado y de la forma adecuada. 
 Calidad del Servicio (QoS): Permite que se ofrezca una mejor experiencia de usuario 
aprovechando diferentes tecnologías. 
 Auditoria:  Permite  almacenar  un  registro  consistente  que  permita  saber  las 
actividades que un usuario realizo y bajo que condiciones se realizaron. 

14.3 Mecanismos de Seguridad

Kumbia  Enterprise  Framework  ofrece  diferentes  componentes  para  una  adecuada 


implementación  de  seguridad  tanto  de  aplicaciones  Web  como  de  Servicios  Web 
empresariales: 
 
 Access  Control  List  (ACL):  Este  componente  permite  crear  listas  en  donde  se 
establece a que recursos puede acceder determinados roles. 
 Auth: Permite realizar el proceso de autenticación utilizando diferentes adaptadores 
como Digest, LDAP, Bases de Datos, Kerberos5 y Radius. 
 AuditLogger: Permite crear registros de auditoria de las actividades realizadas en las 
aplicaciones. 
 Session:  Mantiene  la  persistencia  de  sesión  independiente  entre  aplicaciones  y 
usuarios autenticados. 
 Security: Permite detectar ataques de negación de servicio ó bloquear el acceso a un 
cliente através de su dirección IP. 

14.4 Seguridad a nivel de Capa de Aplicación

Los controladores en las aplicaciones son apropiados para establecer controles de seguridad 
en  las  aplicaciones,  sin  embargo,  todos  los  requerimientos  de  seguridad  no  pueden  ser 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    135 

controlados  en  profundidad  desde  este  punto  y  generalmente  es  necesario  apoyarse  por 
firewalls u otras técnicas para aumentar la confiabilidad de un sistema. 
 
Como cada aplicación maneja sus propios entornos de ejecución y de memoria la información 
de  seguridad  reside  en  forma  independiente  facilitando  la  administración  de  cada  entorno. 
Cuando  se  utilizan  servicios  Web  con  múltiples  intermediarios  es  posible  que  haya  la 
necesidad  de  implementar  mecanismos  de  seguridad  compartidos  y  transferencia  de 
identidad entre aplicaciones. 
 
Las ventajas de la seguridad a nivel de aplicación incluyen: 
 
 La  seguridad  de  cada  aplicación  se  puede  adaptar/generar  de  acuerdo  a  las 
necesidades de cada una. 
 La seguridad es optimizada con opciones especificas de cada una. 
 
Las desventajas de este tipo de implementación son: 
 
 La  aplicación  es  dependiente  de  atributos  de  seguridad  que  no  pueden  ser 
establecidos ó transferidos desde otra. 
 Se  crea  un  único  punto  de  vulnerabilidad  que  de  ser  violado  expondría  muchos 
aspectos de las aplicaciones. 

14.5 Seguridad a nivel de Capa de Transporte

El uso de protocolos como HTTPS/SSL puede mejorar la seguridad desde otro punto de vista 
sin que pueda reemplazar la seguridad a nivel de aplicación. La seguridad a nivel de capa de 
transporte  trata  de  mecanismos  uno  a  uno  en  donde  por  medio  de  llaves  criptográficas  es 
posible implementar autenticación, integridad de mensajes y confidencialidad.  
 
Certificados  digitales  son  requeridos  para  implementar  este  tipo  de  seguridad.  Estos  están 
directamente asociados al servidor Web utilizado y suponen una capa de la cual el framework 
no puede tener control. 
 
Las ventajas de la seguridad en la capa de transporte son: 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    136 

 Fácil de implementar. 
 Esta basado en estándares 

14.6 Implementar Seguridad Declarativa

El componente de listas de control de Acceso de Kumbia Enterprise (ACL) esta integrado con 
el  Core  del  framework  interceptando  cada  petición  y  validando  que  su  ejecución  este 
permitida en el contexto actual. La seguridad declarativa está implementada usando listas de 
control de acceso definidas en la configuración de la aplicación mediante descriptores.  
 
Los  descriptores  permiten  definir  la  estructura  de  autorización  de  seguridad  que  incluye: 
roles, control de acceso y requerimientos de autenticación en forma externa a la aplicación. 
 
La opción securityAccessList en la sección application del archivo config.ini permite establecer 
el tipo de lista de acceso que controlará la seguridad de la aplicación: 
 
Ejemplo: Implementar seguridad declarativa desde config.ini 
[application]
mode = production
name = "Project Name"
dbdate = Y-m-d
debug = Off
securityAccessList = “xml:filePath=%app-base%/security/security.xml”
 
Los descriptores ACL tienen el formato de un Data Source Name indicando primero el nombre 
del adaptador a utilizar y luego las opciones del mismo usando punto y comas para separar las 
mismas. Los descriptores deben ir entre comillas dobles con el fin de que ciertos caracteres no 
causen conflictos al leer el archivo .ini. 
 
En  el  siguiente  ejemplo  de  un  descriptor  de  una  lista  de  acceso  basada  en  XML  se  muestra 
como definir los aspectos básicos de una lista. En el capítulo del componente Acl se detalla la 
implementación de cada parte del archivo XML. 
 
Ejemplo: Lista ACL en XML para control de acceso 
<?xml version="1.0" encoding="UTF-8" ?>
<security xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<!-- ROLES DE LA APLICACION -->
<roles-collection>
<role>
<name>Public</name>
<description>Rol para usuarios no autenticados</description>
</role>
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    137 

<role>
<name>EconomyCustomers</name>
<description>Usuarios con plan economico</description>
</role>
</roles-collection>
<!-- RECURSOS DE LA APLICACION -->
<resources-collection>
<resource>
<name>banking</name>
<description>Controlador para operaciones del
cajero</description>
</resource>
<resource>
<name>login</name>
<description>Controlador para operaciones de inicio de
sesión</description>
</resource>
</resources-collection>
<!-- CONSTRAINTS DE ACCESO -->
<access-constraint>
<role-name>Public</role-name>
<resource-name>*</resource-name>
<action-name>*</action-name>
<rule-type>deny</rule-type>
</access-constraint>
<access-constraint>
<role-name>Public</role-name>
<resource-name>login</resource-name>
<action-name>validateCredentials</action-name>
<rule-type>allow</rule-type>
</access-constraint>
<access-constraint>
<role-name>EconomyCustomers</role-name>
<resource-name>*</resource-name>
<action-name>*</action-name>
<rule-type>allow</rule-type>
</access-constraint>
<access-constraint>
<role-name>EconomyCustomers</role-name>
<resource-name>banking</resource-name>
<action-name>checkBalance</action-name>
<rule-type>deny</rule-type>
</access-constraint>
</security>
 
Los  recursos  de  una  aplicación  para  la  seguridad  declarativa  son  los  controladores  de  la 
misma  y  sus  nombres  coinciden  con  estos  en  las  opciones  resource­name  en  el  ejemplo.  La 
asociación  recurso‐controlador  ofrece  un  potente  sistema  de  control  para  cada  petición  a  la 
aplicación de forma transparente para el desarrollador. 
 
El rol con el cual se realizan las validaciones de seguridad es el definido mediante el método 
del  componente  Security  llamado  setActiveRole(string  $roleName),  cuando  el  rol  no  se  ha 
definido  aún  se  usa  la  convención  para  el  rol  Public  de  tal  forma  que  se  asuma  que  la 
aplicación es pública ó no se ha definido identificación de quien usa la aplicación. 
 
Los recursos que no se han mencionado en las listas de acceso tienen por defecto la política 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    138 

‘Allow’ con lo que se hacen públicos con solo acceder a ellos. 
 
Por cada petición a la aplicación el método Security::checkResourceAccess valida si el rol activo 
tiene acceso al recurso solicitado. Cuando se tiene acceso al recurso el proceso de negocio en 
la  acción  del  controlador  se  ejecuta  normalmente,  cuando  la  validación  falla,  la  aplicación 
trata de enrutar a la acción del controlador llamada unauthorizedAccessAction. 

14.7 Implementar Seguridad Programacional

La seguridad programacional esta embebida en la aplicación y esta implementada en forma de 
decisiones de seguridad. Es más útil cuando la seguridad declarativa resulta muy básica y no 
se adapta a las necesidades de negocio.  
 
En este punto los filtros de controladores y el punto de entrada a la aplicación ControllerBase 
resultan apropiados para definir las reglas de seguridad y aplicar el API de los componentes 
Acl y Auth para controlar los procesos requeridos. 

14.8 Definir Realms, Usuarios y Grupos para Autenticación

Los Realms son colecciones de usuarios los cuales pueden o no pertenecer a un determinado 
grupo  y  son  controlados  mediante  una  misma  política  de  autenticación.  Normalmente  una 
aplicación establece controles como un usuario y contraseña antes de proporcionar acceso a 
un  recurso  protegido,  los  datos  proporcionados  por  un  usuario  se  validan  en  forma  de 
credenciales  produciendo  un  resultado  de  éxito  del  proceso  de  autenticación.  Kumbia 
Enterprise Framework ofrece diferentes adaptadores de autenticación usando el componente 
Auth. 
 
En algunos casos los usuarios de las aplicaciones tienen asignados roles, esto indica que hacen 
parte de grupos con características se seguridad definidas en un dominio de aplicación. 

14.8.1  Realms 
Los realms son bases de datos de usuarios y grupos que contienen las credenciales necesarias 
para  controlar  una  política  de  autenticación.  Debido  a  la  flexibilidad  del  componente  de 
autenticación Auth es posible crear bases de datos de autenticación en varios formatos cada 
uno con características distintas.  
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    139 

14.8.2  Usuarios 
Los usuarios son identidades individuales que son reconocidos por la aplicación. Un usuario 
puede tener roles asociados que permiten conocer que recursos pueden acceder de acuerdo a 
una política de seguridad.  

14.8.3  Grupos 
Los  grupos  representan  una  serie  de  características  compartidas  por  uno  o  varios  usuarios. 
Un  grupo  es  un  conjunto  de  usuarios  que  comparten  los  mismos  accesos  y  controles  de 
seguridad en la aplicación.  
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    140 

15 Componente ACL (Lista de Control de Acceso)


15.1 Introducción

La Lista de Control de Acceso ó en inglés (Access Control List) es un componente de Kumbia 
Enterprise  Framework  es  un  concepto  de  seguridad  informática  usado  para  fomentar  la 
separación de privilegios. Es una forma de determinar los permisos de acceso apropiados a un 
determinado objeto, dependiendo de ciertos aspectos del proceso que hace el pedido.  

Al  igual  que  otros  componentes  del  framework  que  están  basados  en  componentes  se 
implementa el patrón Virtual Proxy, una instancia de Acl solo actúa como un Proxy al objeto 
real instanciado que corresponde al tipo de adaptador utilizado por el mismo. 

15.2 Estructura del Componente

Kumbia  Enterprise  Framework  ha  integrado  la  siguiente  estructura  jerárquica  de  clases  que 
permiten la implementación de este componente: 

Tabla: Jerarquia de clases del componente Acl 

Clase  Descripción 

Es  la  clase  constructora  de  las  listas  Acl.  Es  un  Proxy  a  la 
Acl.php 
funcionalidad implementada en cada adaptador. 

Interface.php  Es la interfase que deben utilizar todos los adaptadores Acl . 

Es  el  adaptador  que  permite  administrar  las  listas  de  acceso 
Adapters/Memory.php 
en memoria. 

El  Adaptador  permite  definir  listas  de  acceso  en  archivos  de 
Adapters/Xml.php 
descripción en XML. 

Es el adaptador permite la administración de la lista de acceso 
Adapters/Model.php 
a una base de datos como backend. 

Es  la  clase  que  permite  administrar  cada  recurso  como  una 
Resource/Resource.php 
entidad independiente de su backend. 

Es  la  clase  que  permite  administrar  los  roles  que  tendrán 
Role/Role.php 
acceso a la lista ACL independientemente de su backend. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    141 

15.3 ¿Que es un Recurso?

Un recurso es cualquier elemento de una aplicación del cual se pueda controlar su acceso. Por 
conveniencia  los  controladores  de  la  aplicación  son  vistos  como  recursos  con  el  objetivo  de 
generar un modelo de seguridad consistente. 

15.4 ¿Que es un Rol?

Un  rol  es  un  nombre  abstracto  para  el  permiso  de  usuarios  a  un  conjunto  particular  de 
recursos en una aplicación. Un rol puede ser comparado a la llave que abre un candado, este 
abre sin importar quien tiene la clave. Los roles están generalmente asociados a los mismos 
usuarios, a los grupos de estos ó a sus perfiles. 

15.5 ¿Que es un Acceso?

Los  accesos  son  las  operaciones  ó  acciones  que  se  pueden  realizar  en  los  recursos.  Niveles 
más profundos de seguridad controlan hasta este nivel lo que se pueda hacer por parte de los 
usuarios. 

15.6 Tipos de Reglas

El acceso a un determinado recurso tiene una regla de ‘permitir’ (allow) ó ‘denegar’ (deny), no 
están soportadas otros tipos de reglas de acceso. 

15.7 ACL en Acción

En  el  siguiente  ejemplo  se  ilustra  como  al  definir  un  filtro  beforeFilter  en  la  clase 
ControllerBase  en  apps/default/controllers/application.php  con  el  que  se  puede  implementar 
el control de acceso a los recursos de la aplicación en forma programacional: 
 
Ejemplo:  Utilizar  ACL  con  modelos  para  validar  el  acceso  a  los  recursos  de  una 
aplicación 
<?php
class ControllerBase {
public function beforeFilter(){
$role = Session::get('role');
if($role==""){
$role = 'Public';
}
$acl = new Acl('Model', 'className: AccessList');
$resourceName = $this->getControllerName();
$operationName = $this->getActionName();
if($acl->isAllowed($role, $resourceName, $operationName)==false){
if($this->getControllerName()!='appmenu'){
$this->routeTo("controller: appmenu");
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    142 

} else {
throw new ApplicationControllerException("No tiene
permiso
para usar esta aplicación");
}
$authLog = new Log(“File”, "auth_failed.txt");
$authLog->log("Autenticación fallo para el rol '$role' en el
recurso '". $this->getControllerName()."/".$this->getActionName()."'");
return false;
}
}
}

Gracias a que el método beforeFilter se encuentra en la jerarquía de todos los controladores 
este se ejecuta previamente a cualquier acción solicitada. Se obtiene de los datos de sesión, la 
variable  role  indica  el  nombre  del  rol  actualmente  logueado,  si  aun  no  hay  un  rol  activo  es 
asignado por defecto Public.  
 
Ahora es posible instanciar la clase Acl, y definir como adaptador un Modelo en donde se ha 
referencia a la clase AccessList quien mapea a la tabla llamada access_list, la cual administra 
los accesos a los recursos de la aplicación. La tabla contiene un Security Policy Domain de un 
POS (Point Of Sale): 
 
Ejemplo: Datos de lista ACL basada en Modelos 
SQL > select * from access_list order by role;
+----+-----------------+-----------------------+--------+-------+
| id | role | resource | action | allow |
+----+-----------------+-----------------------+--------+-------+
| 6 | Public | * | * | Y |
| 7 | Public | dinein | * | N |
| 15 | Public | users | * | N |
| 27 | Public | appmenu | * | Y |
| 29 | Public | admin | * | Y |
| 30 | Public | menus | * | N |
| 9 | Administradores | * | * | Y |
| 10 | Cajeros | * | * | Y |
| 11 | Cajeros | ambient_items | * | N |
| 12 | Cajeros | drop_invoice | * | N |
| 13 | Cajeros | menus | * | N |
| 14 | Cajeros | menus_items | * | N |
| 16 | Cajeros | users | * | N |
| 17 | Cajeros | modifiers | * | N |
| 18 | Cajeros | ambient_menus_items | * | N |
| 19 | Cajeros | discount | * | N |
| 26 | Cajeros | data | query | N |
+----+-----------------+-----------------------+--------+-------+
 
El parámetro className permite establecer un modelo que contiene la estructura descrita en 
la  tabla  anterior.  El  campo  resource  y  action  pueden  contener  asteriscos  (*)  que  son  usados 
como comodines para cualquier criterio que coincida. El campo allow puede tener los valores 
Y(es) o N(o) para indicar si le concede el acceso al recurso. 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    143 

La principal ventaja de la listas ACL es que validan los accesos en forma jerárquica ya sea a 
nivel de recursos ó mediante herencia de roles. En el ejemplo el acceso de jerarquía más alto 
es en el que hay comodines tanto para el recurso como para la acción, el método Acl::isAllowed 
busca jerárquicamente si existe un acceso ó no en la lista de acceso. 
 
Según el ejemplo las siguientes consultas a la lista de acceso darian como resultado: 
 
Ejemplo: Comportamiento de la lista ACL según datos de ejemplo 
$acl = new Acl('Model', 'className: AccessList');
//Esta permitido el rol ‘Public’ a acceder al recurso ‘menus’ en la operación
‘index’?
//No Permitido
$acl->isAllowed("Public", "menus", "index")
//Esta permitido el rol ‘Cajeros’ a acceder al recurso ‘dinein’ en cualquier
operación?
//Permitido
$acl->isAllowed("Cajeros", "dinein", "*")
//Esta permitido el rol ‘Cajeros a acceder al recurso ‘data’ en la operación
‘query’?
//No Permitido
$acl->isAllowed("Cajeros", "data", "query")
 
El primer parámetro de Acl::isAllowed es el nombre del rol, el segundo el nombre del recurso y 
el  tercero  el  nombre  de  la  acción.  Cuando  no  se  encuentra  una  regla  especifica  para  rol‐
recurso‐operación, se busca rol‐recurso‐cualquiera y por ultimo rol‐cualquiera‐cualquiera. 

15.8 Herencia de Roles

Una de las grandes ventajas del uso de listas de control de acceso es la construcción de arboles 
de  jerarquía  de  roles.  De  esta  forma  los  permisos  de  acceso  pueden  ser  heredados  ó 
compartidos entre varios roles sin que haya redundancia de información proporcionando a la 
aplicación capacidades de control de acceso potentes y flexibles. 

15.9 Adaptadores de ACL

Kumbia  Enterprise  Framework  permite  utilizar  varios  backends  para  almacenar  listas  Acl. 
Cada adaptador implementa la interface AclInterface: 
 
<?php
interface AclAdapter {
public function addRole(AclRole $roleObject, $accessInherits='');
public function addInherit($role, $roleToInherit);
public function isRole($role_name);
public function isResource($resource_name);
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    144 

public function addResource(AclResource $resource);


public function addResourceAccess($resource, $accessList);
public function dropResourceAccess($resource, $accessList);
public function allow($role, $resource, $access);
public function deny($role, $resource, $access);
public function isAllowed($role, $resource, $accessList);
}

 
A continuación se explican las consideraciones de uso de cada adaptador: 

15.9.1 AclModel 
La  lista  de  accesos  también  puede  ser  administrada  usando  modelos  disponibles  en  la 
aplicación.  Para esto es necesario crear una entidad con la siguiente estructura: 
 
Ejemplo: Estructura de una tabla apta para almacenar una lista ACL 
CREATE TABLE `access_list` (
`id` int(11) NOT NULL,
`role` varchar(24) NOT NULL,
`resource` varchar(32) NOT NULL,
`action` varchar(32) NOT NULL,
`allow` char(1) default NULL,
PRIMARY KEY (`id`),
)
 
Al  instanciar  el  objeto  Acl  se  debe  indicar  el  modelo  a  utilizar  mediante  el  parámetro 
className, luego el comportamiento y utilización es el normal: 
 
Ejemplo: Uso de listas ACL con Modelos 
$acl = new Acl('Model', 'className: AccessList');
$acl->isAllowed("Administrators", "customers", "create")
 

15.9.2 AclMemory 
El  adaptador  AclMemory  almacena  los  permisos  en  memoria.  La  lista  de  control  de  acceso 
puede  construirse  en  un  proceso  inicializador  y  almacenarse  en  un  backend  de  cache  para 
usarse en otras peticiones. Para aplicaciones con requerimientos de validación de control de 
acceso reducidos este adaptador puede ser una opción a tener en cuenta. 

15.9.3 AclXML 
Este  adaptador  permite  crear  listas  de  control  de  acceso  en  archivos  XML.  Estos  archivos 
mantienen los controles de forma estructurada haciendo sencilla su manipulación desde otros 
lenguajes y aplicaciones. 
 
El archivo debe contener la siguiente estructura: 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    145 

 
  Un nodo raíz ‘security’ que contendrá la lista en sí 
  Un solo nodo ‘roles‐collection’ que contiene nodos ‘role’ con información de roles 
  Los  nodos  ‘role’  deben  tener  los  sub‐nodos  ‘name’  y  ‘description’  con  el  nombre  y 
descripción  del rol respectivamente. 
  Un  solo  nodo  ‘resources‐collection’  que  contiene  nodos  ‘resource’  con  información  de  los 
recursos en la lista. 
  Los  nodos  ‘resource’  deben  tener  los  sub‐nodos  ‘name’  y  ‘description’  con  el  nombre  y 
descripción del recurso respectivamente. 
  Múltiples  nodos  ‘access‐constraint’  con  las  reglas  de  acceso.  El  orden  de  estas  indica  la 
prioridad de cada una. 
  Cada  nodo  ‘access‐constraint’  contiene  los  nodos  ‘role‐name’  que  es  nombre  del  rol, 
‘resource‐name’  que  es  el  nombre  del  recurso,  ‘action‐name’  que  es  nombre  del  acceso  y 
‘rule‐type’ que contiene ‘allow’ si tiene acceso al recurso y ‘deny’ de lo contrario. 
 
El siguiente es el ejemplo de una lista ACL en XML: 
 
Ejemplo: Lista ACL usando una definición en XML 
<?xml version="1.0" encoding="UTF-8" ?>
<security xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<!-- ROLES DE LA APLICACION -->
<roles-collection>
<role>
<name>Public</name>
<description>Rol para usuarios no autenticados</description>
</role>
<role>
<name>Customers</name>
<description>Usuarios clientes de la empresa</description>
</role>
<role>
<name>QueryOnly</name>
<description>Usuarios con permisos de solo
lectura</description>
</role>
</roles-collection>
<!-- RECURSOS DE LA APLICACION -->
<resources-collection>
<resource>
<name>banking</name>
<description>Controlador para operaciones del
cajero</description>
</resource>
<resource>
<name>login</name>
<description>Controlador para operaciones de inicio de
sesión</description>
</resource>
</resources-collection>
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    146 

<!-- CONSTRAINTS DE ACCESO -->


<access-constraint>
<role-name>Public</role-name>
<resource-name>*</resource-name>
<action-name>*</action-name>
<rule-type>deny</rule-type>
</access-constraint>
<access-constraint>
<role-name>Public</role-name>
<resource-name>login</resource-name>
<action-name>validateCredentials</action-name>
<rule-type>allow</rule-type>
</access-constraint>
<access-constraint>
</security>

15.10 API de un Adaptador

public boolean addRole(AclRole $roleObject, mixed $accessInherits) 
Agrega un rol a la lista de roles de la lista de Acceso. En este tipo de Adaptador el rol se crea en 
la entidad definida en el constructor de la lista en el parámetro: rolesClassName. 
 
public void addInherit($role, $roleToInherit) 
Agrega una herencia a la lista en la que el rol $role hereda todos los constraints de acceso que 
tiene el rol $roleToInherit. 
 
public boolean isRole(string $roleName) 
Permite saber si $roleName esta presente en la lista ACL 
 
public boolean isResource(string $resourceName) 
Permite saber si un recurso existe ó no en la lista de acceso actual. 
 
public boolean addResource(AclResource $resource) 
Agrega un recurso para ser administrador por la lista de control de acceso. 
 
public void addResourceAccess(string $resource, mixed $accessList) 
Agrega una operación/acción a un recurso de la lista ACL. El parámetro $accessList puede ser 
un string ó un vector. 
 
public void dropResourceAccess($resource, $accessList) 
Elimina una operación/acción de un recurso de la lista ACL. El parámetro $accessList puede 
ser un string ó un vector. 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    147 

public void allow(string $role, string $resource, mixed $access) 
Agrega una regla que da acceso a un determinado rol a un recurso. 
 
public void deny(string $role, string $resource, mixed $access) 
Agrega una regla denegando el acceso de un determinado rol a un recurso. 
 
public boolean isAllowed(string $role, string $resource, array $accessList) 
Realiza una consulta en la lista ACL  

15.11 API de AclResource

public void getName() 
Obtener el nombre del recurso 
 
public void getDescription() 
Obtener la descripción del recurso 

15.12 API de AclRole

public void getName() 
Obtener el nombre del Role 
 
public void getDescription() 
Obtener la descripción del Role, usualmente el nombre extendido del rol. 
 
 
 
 
 
 
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    148 

16 Componente Auth
16.1 Introducción

El  componente  Auth  esta  diseñado  para  permitir  la  autenticación  y  administración  de  la 
entidad  de  los  usuarios  en  una  aplicación  ya  sea  de  forma  independiente  ó  de  manera 
compartida.  
 
Este  componente  accede  a  sus  adaptadores  usando  el  patrón  Virtual  Proxy,  es  decir,  una 
instancia de Auth solo actúa como un Proxy al objeto real instanciado que corresponde al tipo 
de adaptador utilizado por el mismo. Esta implementación permite crear un punto de entrada 
único par la utilización de adaptadores del framework ó de usuario. 
 
La  instancia  interna  del  adaptador  se  puede  obtener  usando  el  método 
Auth::getAdapterInstance(). 

16.2 Adaptadores de Auth

El  componente  implementa  una  arquitectura  de  adaptadores  de  autenticación,  estos 
establecen interfaces consistentes a diferentes proveedores de identificación bajo una misma 
interfaz  de  aplicación.  Cada  adaptador  requiere  de  diferentes  parámetros  solicitados  por  el 
servicio de autenticación utilizado. 
 
Los adaptadores disponibles son: 
 
Tabla: Adaptadores de Auth disponibles 
Adaptador  Descripción 
Digest  Permite la  autenticación  usando  un  realm  basado  en un  archivo plano 
de texto. 
Radius  Implementa autenticación usando protocolo Radius Autentication RFC‐
2865. 
Kerberos V  Autentica usando servidores Kerberos 5 y además permite obtener las 
politicas asociadas al usuario identidad. 
Model  Usa  un  modelo  de  la  aplicación  en  donde  los  atributos  de  esta  actuan 
como credenciales en la autenticación. 
LDAP  Permite  utilizar  servidores  LDAP  como  ActiveDirectory  para 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    149 

autenticarse en una aplicación. 
 
Todos los adaptadores de Auth implementan la interface AuthInterface: 
 
interface AuthInterface {
public function __construct($auth, $extraArgs);
public function getIdentity();
public function authenticate();
}

16.3 Administración de Identidad

La  administración  de  identidad  es  uno  de  los  procesos  más  usuales  en  cualquier  aplicación 
Web, una vez se produce la autenticación e identificación del usuario es necesario conocer la 
identidad durante toda la sesión del mismo en la aplicación. 
 
Al  realizar  una  autenticación  satisfactoria  con  el  componente  Auth  automáticamente  se  crea 
un  registro  de  la  identidad  de  quien  inició  sesión  y  poder  cumplir  con  objetivos  de  la 
aplicación como personalización ó confidencialidad. 
 
El  método  estático  de  Auth  llamado  getActiveIdentity()  devuelve  la  identidad  creada  en  la 
autenticación  en  cualquier  parte  de  la  aplicación.  Para  destruir  la  identidad  activa  se  usa  el 
también método estático destroyIdentity(). 
 
Para  conocer  si  existe  una  identidad  valida  en  la  aplicación  se  usa  el  método  Auth::isValid() 
que devuelve un valor boleano correspondiente a esa información. 

16.4 Expiración de Sesión

El  componente  Auth  soporta  expiración  de  la  sesión  con  lo  que  es  posible  controlar  que  un 
usuario autenticado solamente pueda utilizar la aplicación durante un determinado rango de 
tiempo.  
 
En estos casos se debe establecer el tiempo en segundos que debe durar la sesión mediante el 
método del objeto Auth llamado setExpireTime después de la autenticación del usuario. 

16.5 Control de Autenticación concurrente

Las reglas del negocio en una aplicación podrían contemplar que un usuario este autenticado 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    150 

en una aplicación solamente desde una terminal de trabajo. En otros casos cuando se genere 
una autenticación del usuario desde otra maquina se requiera que se cierre ó se invaliden las 
sesiones abiertas en otras terminales. 

16.6 Autenticación con Modelos

El  adaptador  Model  permite  realizar  la  autenticación  mediante  un  realm  en  una  entidad  del 
gestor relacional por defecto en config/environment.ini. La principal ventaja de este adaptador 
es  que  aprovecha  las  capacidades  para  atender  múltiples  peticiones  concurrentes  de 
autenticaciónn que pueda tener el gestor relacional. 
 
El siguiente ejemplo ilustra como realizar una autenticación através usando este adaptador: 
 
Ejemplo: Uso del componente Auth con modelos 
<?php
class LoginController extends ApplicationController {
public function indexAction(){
}
public function authSessionAction(){
$login = $this->getPostParam("login");
$password = sha1($this->getPostParam("password"));
$auth = new Auth('model', "class: Usuarios", "login: $login",
"password: $password");
if($auth->authenticate()==false){
Flash::error("Usuario/clave incorrectos");
$this->routeTo("action: index");
} else {
$this->routeTo("controller: menu");
}
$this->setRequest("password", "");
}

 
Tabla: Parámetros que requiere el adaptador Auth con modelos 
Nombre  Descripción 
class  Nombre de la clase del modelo que servira como realm. 
 
Los campos que conforman la clave de identidad deben ser pasados como parámetros con su 
respectivo valor. 
 
La  identidad  se  construye  apartir  de  los  atributos  de  la  entidad  exceptuando  los  campos  de 
password ó contraseña. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    151 

16.7 Autenticación con KerberosV

Este adaptador permite autenticarse usando servidores administrativos Kerberos 5 así como 
obtener las politicas asociadas a los usuarios autenticados. 
 
Puede  obtener  más  información  sobre  servidores  Kerberos  en 
http://web.mit.edu/kerberos/www/krb5‐1.2/krb5‐1.2.8/doc/admin_toc.html. 
 
El siguiente ejemplo ilustra como realizar una autenticación através usando este adaptador: 
 
Ejemplo: Uso del componente Auth con un servidor KerberosV 
<?php
class LoginController extends ApplicationController {
public function startSessionAction(){
$login = $this->getPostParam("login");
$password = $this->getPostParam("password");
$auth = new Auth('kerberos5',
"realm: GONICUS.LOCAL",
"username: admin/admin",
"password: 12345");
if($auth->authenticate()==true){
$identity = $auth->getIdentity();
$policies = $auth->getPolicies();
Flash::success("Bienvenido {$identity['username']}");
foreach($policies as $policy){
Flash::notice($policy);
}
} else {
Flash::error("Fallo autenticacion. Credenciales invalidas");
}
}
}

 
Tabla: Parámetros que requiere el adaptador Auth con KerberosV 
Nombre  Descripción 
server  Es  el  nombre  de  dominio  ó  dirección  IP  del  servidor  Kerberos  V.  Este 
parámetro es obligatorio. 
realm  El  nombre  de  la  base  de  datos  con  la  politica  de  autenticación  en  el 
servidor K5. 
principal  Una combinación usuario/grupo con el que se hará la autenticación 
password  Contraseña del usuario usado en principal. 
 
La identidad devuelta está consta de los campos realm y username. 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    152 

Advertencia:  El  uso  de  este  adaptador  requiere  que  este  presente  la  extensión  de  PHP 
llamada php_kadm5. 

16.8 Autenticación con Radius

Este  adaptador  permite  la  autenticación  mediante  protocolo  Radius  (RFC2865  ‐ 


http://www.faqs.org/rfcs/rfc2865). Este adaptador requiere de la extensión php_radius que 
se encuentra disponible en plataformas Unix (FreeBSD, Linux) y Windows. 
 
El siguiente ejemplo ilustra como realizar una autenticación através usando este adaptador: 
 
Ejemplo: Uso del componente Auth con un servidor Radius 
<?php
class LoginController extends ApplicationController {
public function startSessionAction(){
$login = $this->getPostParam("login");
$password = $this->getPostParam("password");
$auth = new Auth('radius',
"server: 172.16.2.10",
"port: 1821",
"secret: a1b2c3d4",
"username: tierry",
"password: henry"
);
if($auth->authenticate()==true){
$identity = $auth->getIdentity();
Flash::success("Bienvenido {$identity['username']}");
} else {
Flash::error("Fallo autenticacion. Credenciales invalidas");
}
}
}
 
Tabla: Parámetros que requiere el adaptador Auth con Radius 
Nombre  Descripción 
server  Es  el  nombre  de  dominio  ó  dirección  IP  del  servidor  Radius  V.  Este 
parámetro es obligatorio. 
port  Puerto  UDP  donde  escucha  el  servicio  Radius.  Si  el  puerto  es  0  el 
adaptador  localiza  el  servicio  mediante  el  archivo  /etc/services  y  como 
última opción el puerto estándar 1812. 
secret  La clave compartida que se pasará al servidor Radius.  
timeout  Número de segundos que el adaptador espera por obtener respuesta del 
servidor. 
max_retries  Número de intentos que realiza para tratar de autenticarse. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    153 

username  Nombre de usuario a autenticar. 
password  Password el usuario a autenticar. 
 
La identidad se construye con el campo username. 

16.9 Autenticación con Digest

El  adaptador  de  autenticación  Digest  permite  utilizar  archivos  planos  de  texto  como  realms 
para la comprobación de identidad de los usuarios de una aplicación.  Un archivo Digest tiene 
la siguiente estructura: 
 
nombreusuario:nombrerealm:resumenpassword
otronombreusuario:nombrerealm:otroresumenpassword
 
Cada línea del archivo constituye una identidad. Los campos de la identidad están separados 
por  “:”  (dos  puntos).  El  primer  campo  es  el  nombre  del  usuario,  este  puede  tener  la  forma 
john.smith. El segundo campo es el realm al que pertenece el usuario, un archivo digest puede 
tener  varios  realms  en  él.  Por  último  el  tercer  campo  es  un  resúmen  criptográfico 
correspondiente  al  password  del  usuario.  El  algoritmo  estándar  de  una  sola  vía  utilizado  es 
MD5  pero  es  posible  utilizar  otro  mediante  la  opción  de  configuración  algorithm.  Para  un 
archivo digest como el siguiente: 
 
john.smith:Production:5ebe2294ecd0e0f08eab7690d2a6ee69
 
El siguiente proceso de autenticación es satisfactorio: 
 
Ejemplo: Autenticación usando el adaptador Digest 
<?php
class LoginController extends ApplicationController {
public function startSessionAction(){
$auth = new Auth('digest',
"filename: auth/passwd.txt",
"username: john.smith",
"password: secret",
"realm: Production"
);
if($auth->authenticate()==true){
$identity = $auth->getIdentity();
Flash::success("Bienvenido {$identity['username']}");
} else {
Flash::error("Falló autenticación. Credenciales invalidas");
}
}
}
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    154 

Ejemplo: Autenticación usando un archivo con otro charset diferente al de entrada 
<?php
class LoginController extends ApplicationController {
public function startSessionAction(){
$auth = new Auth('digest',
"filename: auth/passwd.txt",
"username: お読みください",
"password: secret",
"realm: フォルダに入れてください",
“charset: EUC-JP”
);
if($auth->authenticate()==true){
$identity = $auth->getIdentity();
Flash::success("Bienvenido {$identity['username']}");
} else {
Flash::error("Falló autenticación. Credenciales invalidas");
}
}

Tabla: Parámetros que requiere el adaptador Auth con Digest 
Nombre  Descripción 
filename  Ruta al archivo digest. El archivo debe ser de texto, si está disponible la 
extensión de PHP Multibyte Strings su codificación puede ser cualquiera 
que soporte ésta.  
username  Nombre del usuario a autenticar 
password  Password plano del usuario 
realm  Realm al que pertenece el usuario a autenticar 
algorithm  Callback  del  algoritmo  que  se  utilizará  para  comparar  el  password  del 
usuario con los del archivo digest. Por defecto es MD5.  
charset  Codificación  que  tiene  el  archivo  de  identidades  digest.  El  valor  por 
defecto es UTF‐8. 
 
La identidad se construye a partir de los campos username y realm del usuario encontrado. 

16.10 Autenticación con LDAP

El  protocolo  LDAP  “Lightweight  Directory  Access  Protocol”  es  utilizado  para  acceder  a 
servidores  de  directorios.  Estos  son  estructuras  que  almacenan  datos  en  una  jerarquia  de 
arbol. 
 
El adaptador de autenticación LDAP soporta autenticación con servidores de directorios como 
Microsoft Active Directory, OpenLDAP, Sun OpenDS ó Mac OS X Server LDAP Service.  
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    155 

 
La notación DN ó “Distinguished Name” representan rutas a objetos alojados en un servidor 
LDAP. Cada atributo esta indicado con su nombre estandar, un igual y su valor.  Los atributos 
están  separados  por  comas  y  el  orden  de  lectura  de  los  atributos  se  realiza  de  derecha  a 
izquierda.  
 
En  el  siguiente  ejemplo  se  ilustra  la  autenticación  a  un  servidor  LDAP  a  partir  de  los 
parámetros de un formulario: 
 
Ejemplo: Uso del componente Auth con un servidor LDAP 
<?php
class LoginController extends ApplicationController {
public function startSessionAction(){
$login = $this->getPostParam("login");
$password = $this->getPostParam("password");
$auth = new Auth('ldap', "server: server.local",
"accountDomainName: example.com",
"baseDN: dc=example,dc=com",
"username: uid=$login,dc=example,dc=com",
"password: $password",
"identityAttributes: cn,uid",
"port: 1389"
);
if($auth->authenticate()==true){
$identity = $auth->getIdentity();
Flash::success("Bienvenido {$identity['username']}");
} else {
Flash::error("Falló autenticación. Credenciales invalidas");
}
}
}
 
Los  siguientes  parámetros  deben  ser  indicados  para  realizar  una  autenticación  satisfactoria 
en un servidor LDAP: 
 
Tabla: Parámetros que recibe el adaptador Auth con LDAP 
Nombre  Descripción 
server  Es  el  nombre  de  dominio  ó  dirección  IP  del  servidor  LDAP.  Este 
parámetro es obligatorio. 
accountDomainName  Nombre del dominio al que pertenece la cuenta a autenticar. 
username  DN del usuario que se va a autenticar en el servidor. Este parámetro 
es obligatorio. 
password  Contraseña del usuario que se va a autenticar. Si el parámetro no es 
indicado se produce un intento de autenticación anónimo. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    156 

baseDN  DN base donde se hace la búsqueda de la identidad del usuario. Es el 
DN del servidor donde la cuenta se encuentra ubicada. 
port  Puerto del servidor donde escucha el LDAP Server. 
identityAttributes  Atributos  de  la  entrada  del  servidor  LDAP  que  serán  usados  para 
construir la identidad del usuario autenticado. 
accountCanonicalForm  Indica  la  forma  en  la  que  el  nombre  de  usuario  esta  canonizado, 
dependiendo  del  tipo  de  servidor  LDAP  el  adaptador  traduce  este 
nombre automáticamente al adecuado. Un valor de 2 indica la forma 
normal,  3  usa  la  forma  \\SERVIDOR\usuario  y  la  4 
usuario@servidor. 
 
La identidad se construye apartir de los campos del registro del nombre canonico del usuario 
en el servidor LDAP. 
 
Advertencia:  El  uso  de  este  adaptador  requiere  que  este  presente  la  extensión  de  PHP 
llamada php_ldap. 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    157 

17 Componente AuditLogger
17.1 Introducción

El  componente  AuditLogger  esta  diseñado  para    asistir  las  tareas  de  auditoria  de  sistemas 
creando logs que lleven el registro de las actividades realizadas en una aplicación de negocios 
por parte de cada uno de los roles que la utilizan.  

17.2 Crear un componente de control

Ejemplo: Crear un componente de usuario para la auditoría de sistemas 
<?php
class MyApplicationAudit extends AuditLogger {
public function __construct($note, $transaction=null){
parent::__construct("Audit");
$this->bindToField("USER_ID", "usuarios_id");
$this->bindToField("USERNAME", "nombre");
$this->bindToField("NOTE", "nota");
$this->bindToField("IP_ADDRESS", "ipaddress");
$this->setFieldData("controller", Router::getController());
$this->setFieldData("action", Router::getAction());
$this->setFieldData("USER_ID", Session::get("usuariosId"));
$this->setFieldData("USERNAME", Session::get("usuariosNombre"));
$this->setFieldData("NOTE", $note);
if($transaction!=null){
$this->setTransaction($transaction);
}
$this->commit();
}
}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    158 

18 Componente Security
18.1 Introducción

El objetivo de este componente es ofrecer funcionalidades varias de seguridad a aplicaciones 
web  empresariales.  Una  característica  importante  de  este  componente  es  un  Firewall  que 
permite definir reglas de acceso estilo firewall a una aplicación.  

18.2 Subcomponente SecurityFirewall

18.2.1 Introducción 
El objetivo del subcomponente SecurityFirewall es el de permitir al desarrollador analizar el 
entorno  desde  el  cual  se  accede  a  un  determinado  punto  de  la  aplicación  y  validar  si  se 
permite el acceso ó no. 
 
Las reglas se definen en un archivo XML en el orden de prioridad como deben ser evaluadas. 
Un ejemplo es el siguiente documento XML: 
 
Ejemplo: Definición XML de reglas para SecurityFirewall 
<?xml version="1.0" encoding="UTF-8"?>
<firewallRules>
<hostTraslation>
<hostname>localhost</hostname>
<address>::1</address>
</hostTraslation>
<rule>
<source>localhost</source>
<controller>products</controller>
<action>*</action>
<target>reject</target>
</rule>
<rule>
<source>192.168.10.120</source>
<controller>admin</controller>
<action>*</action>
<target>reject</target>
</rule>
<rule>
<source>localhost</source>
<controller>*</controller>
<action>*</action>
<target>accept</target>
</rule>
</firewallRules>

 
El  nodo  raiz  firewallRules  abre  el  documento.  Los  nodos  hostTraslation  contienen 
traducciones  predefinidas  para  nombres‐de‐maquina/direcciones‐ip,  así  es  posible  indicarle 
al  firewall  que  un  mismo  nombre  de  maquina  tiene  varias  direcciones  IP  asignadas.  En  el 
ejemplo la dirección ::1 del loopback de una maquina Mac OS X es agregada como localhost. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    159 

 
Los nodos rule permiten definir las reglas del firewall. Por obligación estos nodos deben tener 
un atributo target que indica que el tipo de acción a ejecutar cuando se cumple la regla. 
 

18.2.2 Como se evaluan las reglas 
Las reglas son evaluadas  en el orden en el que se definieron en el archivo XML. Si una regla 
cumple  con  las  condiciones  del  entorno  de  la  petición  entonces  las  demás  reglas  no  son 
evaluadas. 
 
Es  necesario  tener  en  cuenta  el  orden  en  el  que  se  definen  para  evitar  que  una  regla 
sobreescriba a otras y no se logre el objetivo esperado. 

18.2.3 Tipos de Atributos de una Regla 
Una regla del SecurityFirewall puede tener los siguientes tipos de atributos: 
 
Tabla: Tipos de atributos de una regla en SecurityFirewall 
Nombre  Descripción 
source  El origen de la petición. Puede ser un nombre de maquina en la red, 
un  nombre  de  dominio  ó  una  dirección  IP.  Cuando  se  establece  un 
nombre  de  maquina  se  utilizan  las  capacidades  de  resolución  de 
nombres que tenga la maquina actual para obtener las direcciones IP 
correspondientes.  La  dirección  IP  del  cliente  se  obtiene  incluso 
cuando el acceso se realiza mediante un proxy transparente. Las IPs 
no pueden ser obtenidas cuando se usa un proxy anónimo. 
mac  La NIC de la tarjeta de red puede ser obtenida cuando la aplicación 
es  ejecutada  en  sistemas  Linux/Unix  y  cuando  los  clientes  se 
encuentran en la mismo rango de red del servidor. 
controller  El  nombre  del  controlador  de  aplicación  ó  servicio  web  en  la 
aplicación  activa  que  se  está  tratando  de  acceder.    Se  puede  usar  * 
como comodín que coincida con cualquier controlador. 
action  El  nombre  de  la  acción  en  el  controlador  solicitado  que  se  está 
tratando  de  acceder.  Se  puede  usar  *  como  comodín  que  coincida 
con cualquier nombre de acción. 
isAjaxRequested  Indica si la petición se está tratando de hacer usando AJAX. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    160 

isSoapRequested  Indica si la petición se está tratando de hacer desde un cliente Soap. 
isSecure  Indica si la conexión se realiza usando una conexión segura. 
isFlashRequested  Indica si la conexión se realiza desde un plug‐in de Adobe Flash. 
hasHeader  Si  la  petición  contiene  un  determinado  encabezado.  Múltiples 
encabezados pueden definirse separandolos por pipes (|). 
method  Permite  indicar  el  tipo  de  método  HTTP  utilizado  para  solicitar  la 
petición. 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    161 

Parte 3: La lógica de datos 
 

19 Persistencia, Transacciones y Concurrencia


19.1 Introducción

El papel de la capa de persistencia en una aplicación es traer y llevar los datos requeridos para 
que  la  lógica  de  dominio  en  los  controladores  puede  realizar  su  trabajo  correctamente. 
Cuando  se  habla  de  persistencia  se  piensa  normalmente  en  bases  de  datos  relacionales  y  el 
tratamiento  de  estas  generalmente  conlleva  a  tratar  inconvenientes  de  bajo  nivel  como 
conexiones ó incompatibilidad de la sintaxis de lenguaje SQL.  
 
Kumbia  Enterprise  Framework  ofrece  una  variedad  de  componentes  para  acceder  a  gestores 
relacionales a bajo ó alto nivel. 
 

20 Componente Db
20.1 Introducción

Kumbia  Enterprise  Framework  implementa  una  doble  capa  de  abstracción  para  la 
manipulación  de  la  persistencia  de  la  aplicación  cuando  se  utilizan  bases  de  datos.  El 
componente Db administra todo lo relacionado con la interacción a bajo nivel con los gestores 
relacionales  de  base  de  datos,  esto  incluye  abstraer  detalles  de  conexión,  utilización  de 
lenguaje SQL, cursores, transacciones, etc.  
 
Esta independencia se logra mediante la implementación de adaptadores que crean puntos de 
compatibilidad  a  los  motores  de  bases  de  datos  de  tal  forma  que  sin  importar  el  gestor 
utilizado  se  garantice  que  las  operaciones  sobre  ellos  va  a  ser  consistente  logrando  el 
resultado esperado. 
 
Mientras que el Kumbia PHP Framework ofrece múltiples opciones para conectarse a bases de 
datos, Kumbia Enterprise Framework recomienda su uso en producción a los adaptadores de 
MySQL y Oracle, aunque algunos otros tienen una madurez aceptable. 

20.2 Capas de acceso

El  componente  Db  puede  utilizar  multiples  capas  de  abstracción  existentes  para  el  acceso  a 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    162 

gestores  relacionales,  de  esta  forma  se  aumentan  las  posibilidades  y  capacidades  de 
aprovechar la funcionalidad del motor desde una aplicación. 
 
Las capas de acceso soportadas son las siguientes: 
 
Tabla: Capas de acceso a gestores relacionales soportadas por Kumbia Enterprise 
Nombre  Descripción 
Native  Sin  capa  intermedia.  Utiliza  las  extensiones  PHP  escritas  en 
lenguaje  C  que  implementan  acceso  directo  a  los  motores  de 
base de datos. 
PDO  Utiliza la capa PHP Data Objects (PDO) escrita en lenguaje C que 
implementa  acceso  uniforme  a  los  principales  motores  de  base 
de datos de código abierto y cerrado.  
JDBC  Utiliza  la  capa  de  acceso  a  bases  de  datos  Java  Database 
Connectivity  (JDBC)  de  Java.  Con  lo  que  es  possible  utilizar 
drivers JDBC y la funcionalidad de estos. Solo disponible cuando 
se usa IBM WebSphere sMash. 
 

20.3 Adaptadores del componente Db

En  la  siguiente  tabla  se  detalla  los  adaptadores  de  la  distribución  de  Kumbia  Enterprise 
Framework junto con sus características y estado de madurez: 
 
Tabla: Adaptadores del componente Db y madurez actual 
Nombre  Capa de Acceso  Estado de Madurez 
MySQL  Nativo (MySQL)  Estable 
MySQLi  Nativo (MySQLi)  Estable 
Oracle  Nativo (oci8)  Estable 
PostgreSQL  Nativo  Beta 
Microsoft SQL Server  PDO  Beta 
IBM Informix  PDO  Beta 
SQLite  PDO  Beta 
Oracle  PDO  Beta 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    163 

Oracle  JDBC  Estable 


 
Cada  adaptador  nativo  hereda  de  la  clase DbBase  la  cual  implementa  métodos  utiles  validos 
para  cualquier  gestor  relacional  en  forma  de  capa  de  abstracción  intermedia.  La  interface 
DbBaseInterface  es  implementada  por  cada  adaptador  de  tal  forma  que  cada  uno  mantenga 
una estructura consistente que permita efectuar operaciones básicas  y avanzadas sin incurrir 
en detalles de bajo nivel ó dependientes de cada gestor relacional. 
 
La estructura de la interface DbBaseInterface es la siguiente: 

interface DbBaseInterface {
public function __construct($descriptor='');
public function connect($descriptor='');
public function query($sqlStatement);
public function fetchArray($resultQuery='', $opt='');
public function close();
public function numRows($resultQuery='');
public function fieldName($position, $resultQuery='');
public function dataSeek($position, $resultQuery='');
public function affectedRows($resultQuery='');
public function error($errorInfo='', $resultQuery='');
public function noError($resultQuery='');
public function inQuery($sqlStatement, $type=db::DB_BOTH);
public function inQueryAssoc($sql);
public function inQueryNum($sql);
public function fetchOne($sql);
public function fetchAll($sql);
public function insert($tableName, $values, $fields='',
$automaticQuotes=true);
public function update($tableName, $fields, $values, $whereCondition=null,
$automaticQuotes=true);
public function delete($tableName, $whereCondition='');
public function limit($sqlStatement, $number);
public function forUpdate($sqlQuery);
public function sharedLock($sqlQuery);
public function begin();
public function rollback();
public function commit();
public function listTables($schemaName='');
public function describeTable($tableName, $schemaName='');
public function getRequiredSequence($tableName='', $identityColumn='',
$sequenceName='');
public function lastInsertId($tableName='', $identityColumn='',
$sequenceName='');
public function createTable($tableName, $definition, $index=array(),
$tableOptions=array());
public function dropTable($tableName, $ifExists=false);
public function tableExists($tableName, $schema='');
public function getDateUsingFormat($date, $format='YYYY-MM-DD');
public function getHaveAutoCommit();
public function setIsolationLevel($isolationLevel);
public function getCurrentDate();
public function getLastResultQuery();
public function getConnectionId();
public function getDatabaseName();
public function getUsername();
public function getHostName();
}
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    164 

20.4 Generación de SQL

Cada  gestor  relacional  sigue  estándares  del  lenguaje  SQL,  principalmente  de  las 
especificaciones ANSI92 y ANSI99. Muchos motores de base de datos agregan extensiones al 
lenguaje ó no implementan adecuadamente los estándares establecidos por diversas razones. 
Cuando se escriben aplicaciones multi‐motor es posible encontrar ciertas incompatibilidades 
que  podrían  conllevar  a  reescrituras  de  código  que  reabren  el  ciclo  del  software  y  podrian 
generar sobrecostos. La capa de abstracción de Kumbia Enterprise Framework se encarga de 
los  detalles  y  genera  la  mayor  parte  de  las  sentencias  de  DML  que  soporta  un  gestor 
relacional. 
 
A nivel de aplicación el lenguaje PHP ofrece una extensa biblioteca de funciones que permiten 
conectarse  y  efectuar  operaciones  sobre  una  gran  variedad  de  gestores  relacionales.  Sin 
embargo, la forma en que estan implementadas estas funciones no es estándar  y consistente 
por  lo  que  el  cambio  de  un  gestor  a  otro  conlleva  a  reescribir  código  y  se  presentan  las 
situaciones mencionadas anteriormente. 
 
Ejemplo: Conexión tradicional a gestores relacionales usando PHP 
//Conexión a Oracle
$connId = oci_connect("scott", "tiger", "//192.168.0.40/XE");
//Conexión a Informix
$connId = ifx_connect("stores@ol_srv1", "informix", "pass");
//Conexión en PostgreSQL
$connId = pg_connect("host=192.62.10.1 port=5432 dbname=bankdb user=dma
password=2fe051871");

Clausulas  que  extendienden  el  lenguaje  SQL  como  LIMIT  en  SELECT,  estan  soportadas  por 
algunos  gestores  relacionales  y  en  otros  es  necesario  implementarlos  de  tal  forma  que  sea 
transparente y funcionen como se espera. 
 
Ejemplo:  Incompatibilidad  de  algunas  extensiones  del  lenguage  SQL  en  gestores 
relacionales 
//LIMIT en SQLServer ó Sybase
SELECT * FROM (SELECT TOP 10 * FROM (SELECT TOP 10 customers.categoryId FROM
customers) AS itable) AS otable
//LIMIT en MySQL
SELECT customers.categoryId FROM customers LIMIT 10

El  componente  DBR  implementa  en  cada  uno  de  los  adaptadores  métodos  que  generan  SQL 
optimizado  para  cada  gestor  relacional  soportado  aumentando  las  capacidades  de  cada 
aplicación desarrollada con el mismo. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    165 

20.5 Conexiones a gestores relacionales por defecto

Cada aplicación proporciona el archivo de configuración environment.ini en donde se pueden 
establecer los parámetros de conexión de acuerdo a los entornos de las fases de desarrollo de 
la aplicación. 
 
El archivo de configuración environment.ini predeterminado tiene la siguiente estructura: 
 
Ejemplo: Archivo de configuración enviroment.ini predeterminado 
[development]
database.type = mysql
database.host = localhost
database.username = root
database.password =
database.name = development_db
[production]
database.type = mysql
database.host = localhost
database.username = root
database.password =
database.name = production_db
[test]
database.type = mysql
database.host = localhost
database.username = root
database.password =
database.name = test_db
 
Los  parámetros  de  conexión  tienen  el  prefijo  databse  y  pueden  variar  de  acuerdo  al  gestor 
relacional utilizado. Para indicar el adaptador a usar se utiliza el parámetro database.type. A 
continuación se explican las consideraciones de conexión para los motores soportados: 

20.5.1 Consideraciones para Oracle 
Oracle  es  muy  conocido  por  sus  capacidades  de  escalamiento  y  características,  además  es 
lider en bases de datos y está disponible en varias plataformas. 
 
El  adaptador  de  conexión  a  Oracle  requiere  que  la  extensión  de  PHP  oci8  este  disponible, 
mediante  esta  es  posible  conectarse  a  Oracle  en  sus  versiones  8i,  9i,  10g  y  11g.  Adicional  a 
esto es necesario instalar el Oracle Instant Client apropiado a la plataforma requerida.  
 
Estas  librerias  pueden  ser  descargadas  en  la  siguiente  URL: 
http://www.oracle.com/technology/tech/oci/instantclient/instantclient.html. 
 
Las  variables  de  entorno  ORACLE_HOME,  ORACLE_SID,  LD_PRELOAD  Y  NLS_LANG  deben 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    166 

estar definidas para realizar la conexión a Oracle.  
 
Parámetros  de  configuración  de  la  extensión  OCI8  como  oci8.max_persistent, 
oci8.persistent_timeout y oci8.default_prefetch también deberían tenerse en cuenta. 
 
De acuerdo a la versión de la extensión OCI8 podría ó no haber compatibilidad con el gestor 
relacional  requerido.  En  la  siguiente  tabla  se  presenta  la  compatibilidad  de  acuerdo  a  la 
versión de OCI8: 
 
Tabla: Matriz de compatibilidad entre PHP, OCI8 y cliente Oracle 
Distribución  Versión PHP  Versión de OCI8  Versiones del 
cliente Oracle 
soportado 
PHP CVS  5.2.7+  1.2.5  8i, 9i, 10g, 11g 
PHP  Binario  para  5.27+  1.2.5  10g, 11g 
Windows 
PECL OCI8 CVS  Se  puede  construir  1.3.4  9iR2, 10g, 11g 
desde PHP 4.3.9  
Zend Core for Oracle 2.5  5.2.5  1.2.3  Incluye  el  Oracle 
Instant  Client  10  por 
lo  que  se  soportan: 
8i, 9i, 10g, 11g 
 
Este adaptador no soporta múltiples transacciones simultaneas, esto quiere decir que al tratar 
de crear una transacción cuando ya hay una activa se generará una excepción.  
 
Los parámetros de conexión al conectarse a Oracle son: 
 
[production]
database.type = oracle
database.host = 127.0.0.1
database.username = scott
database.password = tiger
database.instance = XE
database.port = 1521
database.territory = spain
database.sort = spanish_m
database.comp = linguistic
database.charset = AL32UTF8
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    167 

La descripción de los parámetros es la siguiente: 
 
Tabla: Parámetros de conexión a Oracle usando adaptador Nativo 
Parámetro  Descripción 
database.username  Los  usuarios  en  Oracle  son  propiedad  de  schemas  que  tienen 
el mismo nombre del usuario. Este parámetro permite indicar 
el nombre del usuario ó ambiguamente el schema. 
database.host  Nombre  de  la  maquina  ó  dirección  IP  donde  se  encuentra  el 
servidor Oracle. 
database.password  Contraseña del usuario con el que se realiza la conexión. 
database.instance  Nombre  de  la  instancia  de  Oracle  ó  del  servicio  del  TNS 
Listener.  Cuando  se  usa  Oracle  Database  Express  este  es  ‘XE’ 
por defecto. 
database.port  Puerto del servicio TNS Listener. Por defecto es 1521. 
database.sort  Este  parámetro  permite  establecer  como  se  hará  el 
ordenamiento  de  columnas  que  contengan  valores 
alfanuméricos como CHAR ó VARCHAR2. Su valor por defecto 
es spanish_m. En paises hispano‐hablantes las letras ch, ll y 
ñ  son  consideradas  parte  del  alfabeto  y  esta  variable  permite 
que el ordenamiento sea adecuado a la localización utilizada. 
database.comp  Es  la  forma  en  la  que  se  realizan  las  comparaciones  entre 
valores  constantes  y  columnas  de  las  tablas.  El  valor  por 
defecto  linguistic  permite  que  las  comparaciones  no  sean 
sensibles a mayúsculas/minúsculas. 
database.charset  Permite  establecer  el  charset  en  el  que  se 
almacenan/devolveran valores en las bases de datos. El valor 
Al32UTF8 es el nombre de Oracle para el charset UTF8. 
database.territory  Permite  establecer  el  territorio  en  el  que  se  encuentra  la 
aplicación.  Dependiendo  de  este  los  formatos  de  fechas  y  de 
valores  númericos  se  ajusta  a  la  localización  requerida.  Por 
defecto es ‘spain’. 
database.language  El  idioma  en  el  que  se  presentarán  los  mensajes  de  error  del 
motor y se formatearán los resultados numéricos y de fechas. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    168 

Por defecto es ‘spanish’. 
 

20.5.1.1 Conectar a Oracle mediante JDBC 
También  es  posible  realizar  conexiones  a  Oracle  usando  el  adaptador  JDBC  cuando  la 
aplicación ha sido implementada en un contenedor de aplicaciones IBM WebSphere sMash. 
 
El  archivo  JAR  ojdbc14.jar  debe  estar  ubicado  en  el  directorio  lib  de  la  aplicación  sMash 
siguiendo las convenciones de arquitectura de la maquina. Por ejemplo si se ejecuta en Linux 
sobre un procesador arquitectura x86 entonces la ubicación es: 
 
lib/x86/linux/ojdbc14.jar
 
Los parámetros en enviroment.ini deben ser: 
 
[production]
database.layer = jdbc
database.type = oracle
database.driver = "oracle.jdbc.driver.OracleDriver"
database.dsn = "thin:@192.168.151.12:1521:XE"
database.username = scott
database.password = tiger

20.5.2 Consideraciones para Microsoft SQL Server 
SQL Server  es el motor de base de datos relacional de Microsoft. La conexión a este motor es 
realizada via PHP Data Objects (PDO). Este adaptador solo soporta conexiones a SQL Server 
desde Windows usando conexiones ODBC mediante el driver php_pdo_odbc. Las versiones de 
SQL Server soportadas van desde la 7.x hasta la 2008. 
 

20.5.2.1 Creación de un DSN ODBC para SQL Server 
A  continuación  se  ilustra  el  proceso  de  creación  de  una  conexión  a  SQL  Server  mediante 
ODBC.  Utilizando  un  usuario  con  credenciales  administrativas  se  abre  el  Administrador  de 
Origenes de Datos ODBC desde Panel de Control ‐> Herramientas Administrativas. 
 
En esta pantalla se selecciona la pestaña ‘DSN de usuario’ y se da click en el botón ‘Agregar…’ 
para crear una nuevo origen de datos: 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    169 

 
 
A continuación se selecciona el tipo de driver utilizado, se busca ‘SQL Server’ y se da click en 
siguiente: 
 

 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    170 

Se  da  click  en  ‘Finalizar’  para  abrir  el  asistente  de  origenes  de  datos  para  SQLServer.  Se 
presenta la siguiente pantalla: 
 

 
 
El campo nombre hace referencia nombre al origen de datos ó Data Source Name (DSN) que 
será  utilizado  luego  para  realizar  la  conexión  en  la  aplicación.  El  campo  servidor  indica  el 
nombre  de  la  instancia  y  maquina  donde  está  instalado  SQL  Server.  Se  da  click  en  siguiente 
para continuar. 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    171 

 
 
El tipo de autenticación se debe tener en cuenta cuando se realice la conexión desde Kumbia 
Enterprise.  Si  se  selecciona  autenticaciónn  de  Windows  NT  no  será  necesario  indicar  el 
parámetro UID y PWD del usuario de conexión. En este caso el usuario con el que se ejecute el 
proceso  del  servidor  web  se  utilizará  para  autenticarse  en  SQL  Server.  Si  se  selecciona 
autenticación de SQL Server se deben indicar los parámetros mencionados anteriormente. 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    172 

 
 
En la siguiente pantalla se puede configurar la base de datos predeterminada. Las opciones 
‘Usar identificadores entrecomillados ANSI’ y ‘Usar nulos, rellenos y advertencias ANSI’ deben 
estar seleccionados. 
 
En esta pantalla se pueden activar otras opciones, al terminar se da click en ‘Finalizar’: 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    173 

 
 
La última pantalla permite probar la conexión, si todo esta bien no habrá problema al efectuar 
una conexión desde Kumbia Enterprise. 
 

 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    174 

Los parámetros requeridos de conexión al conectarse con el adaptador “mssql” son: 
 
[production]
database.layer = “pdo”
database.type = mssql
database.dsn = "DRIVER={SQL Server};SERVER=SQLEXPRESS;DATABASE=test"
 
Usando un DSN de Usuario: 
 
Ejemplo: Conexión a SQL Server estableciendo un DSN 
[production]
database.layer = “pdo”
database.type = mssql
database.dsn = "bankdb"
 
Estableciendo el usuario y contraseña: 
 
Ejemplo: Conexión a SQL Server estableciendo usuario y contraseña con DSN 
[production]
database.layer = “pdo”
database.type = mssql
database.dsn = "bankdb;UID=sa;PWD=mypass"
 
Estableciendo el usuario y contraseña sin DSN: 
 
Ejemplo: Conexión a SQL Server estableciendo usuario y contraseña sin DSN 
[production]
database.layer = “pdo”
database.type = mssql
database.dsn = "DRIVER={SQL
Server};SERVER=SQLEXPRESS;DATABASE=test;UID=sa;PWD=pass
 
Tabla: Parámetros de conexión a Microsoft SQL Server usando PDO 
Parámetro  Descripción 
database.pdo  Indica  que  se  debe  cargar  un  Adaptador  PDO.  Su  valor  debe 
ser On para que tenga efecto. 
database.dsn  Indica los parámetros del Data Source Name (DSN) del origen 
datos. SERVER es la maquina donde está instalada la instancia 
del framework. DATABASE es el nombre de la base de datos de 
trabajo.  UID  es  el  nombre  del  usuario  con  el  que  se  hará  la 
conexión.  PWD  es  el  password  del  usuario.  DRIVER  es  el 
nombre  del  driver  ODBC  para  SQL  Server,  normalmente  es 
‘SQL Server’. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    175 

20.5.3 Consideraciones para MySQL 
MySQL  es  uno  de  los  motores  Open  Source  más  populares  y  con  mayor  presencia  en 
aplicaciones  para  Internet.  Existen  2  adaptadores  que  permiten  la  conexión  a  MySQL,  el 
primero es “mysql“ que usa la extensión de PHP nativa del mismo nombre y que permite la 
conexión  usando  librerias  cliente  desde  la  versión  4.1.  La  segunda  es  “mysqli”  que  utiliza  la 
extensión del mismo nombre y que tiene una funcionalidad y rendimiento superior a la de la 
extensión  “mysql”.  Ambos  adaptadores  soportan  transacciones  en  sesiones  de  conexión 
diferentes. 
 
Kumbia Enterprise Framework puede trabajar con MySQL cuando está en modo SQL estricto y 
no estricto. En modo estricto se generarán excepciones DbInvalidFormatException cuando se 
trate de insertar un valor que no tenga un formato adecuado al tipo de dato requierido de la 
columna de este. 
 
Los parámetros requeridos de conexión al conectarse con el adaptador “mysql” son: 
 
Ejemplo: Parámetros de conexión requeridos usando el adaptador nativo de mysql 
[production]
database.type = mysqli
database.host = localhost
database.username = root
database.password = my_password
database.name = production_db
 
Los posibles parámetros de conexión al conectarse con el adaptador “mysql” son: 
 
Ejemplo: Posibles parámetros de conexión a mysql 
[production]
database.type = mysql
database.host = localhost
database.username = root
database.password = my_password
database.name = production_db
database.port = 3306
database.autocommit = Off
database.compression = Off
database.ssl = Off
database.interactive = Off
 
La descripción de los parámetros anteriores es la siguiente: 
 
Tabla: Parámetros de conexión a MySQL usando el adaptador “mysql” 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    176 

Parámetro  Descripción 
database.username  El  nombre  de  usuario  de  MySQL  con  el  que  se  efectuará  la 
conexión. 
database.password  El password del usuario de MySQL. 
database.host  Servidor  de  MySQL.  Se  puede  utilizar  el  string  de  conexión 
hostname:puerto  ó  :/path/al/socket  cuando  se  trata  de 
localhost. 
database.name  Nombre de la base de datos. 
database.port  Puerto  del  servidor  de  MySQL  al  especificarse  se  hace  la 
conexión por TCP/IP. 
database.autocommit  Cuando  el  valor  es  On.  Indica  si  la  sesión  de  MySQL  debe 
establecerse  en  modo  AUTOCOMMIT,  esto  significa  que  se 
debe  hacer  un  COMMIT  obligatoriamente  para  que  se  tenga 
efecto  los  cambios  realizados  sobre  la  base  de  datos.  Por 
defecto es Off. 
database.compression  Indica  si  el  cliente  MySQL  debe  comprimir  todo  el  tráfico  de 
red  entre  la  aplicación  y  el  servidor  de  base  de  datos.  Por 
defecto es Off 
database.ssl  Indica  si  se  debe  encriptar  el  tráfico  entre  la  aplicación  y  el 
servidor de base de datos mediante SSL. Por defecto es Off. 
database.interactive  Indica  si  se  debe  crear  una  sesión  interactiva  en  vez  de  una 
conexión temporal. Por defecto es Off. 
 
Los parámetros requeridos de conexión al conectarse con el adaptador “mysqli” son: 
 
Ejemplo: Parámetros de conexión requeridos para mysqli 
[production]
database.type = mysqli
database.host = localhost
database.username = root
database.password = my_password
database.name = production_db
 
Los posibles parámetros de conexión al conectarse con el adaptador “mysqli” son: 
 
Ejemplo: Configuración de la conexión usando mysqli 
[production]
database.type = mysqli
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    177 

database.host = localhost
database.socket = /tmp/mysql.sock
database.username = root
database.password = my_password
database.name = production_db
database.port = 3306
database.autocommit = Off
database.compression = Off
database.ssl = Off
database.interactive = Off
database.charset = utf8
database.key = “/home/user/key.pem”
database.cert = “/home/user/ca.crt”
database.ca = “/home/user/ca_file”
database.capath = “/home/user/capath”
database.cipher = “aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-
cbc,aes256-cbc”
 
Los parámetros adicionales que soporta el adaptador “mysqli” son: 
 
Tabla: Parámetros de conexión soportados usando mysqli 
Parámetro  Descripción 
database.socket  Aplica cuando el host el localhost y permite establecer el path 
al socket UNIX ó al named pipe en Windows. 
database.charset  Permite  establecer  el  charset  utilizado  por  el  cliente  MySQL 
para enviar la información al servidor. 
database.key  La  ruta  a  donde  se  encuentra  el  archivo  de  llave  compartida. 
Este parámetro solo aplica cuando la opción SSL está On. Por 
defecto su valor es NULL. 
database.cert  La  ruta  al  archivo  de  certificado.  Este  parámetro  solo  aplica 
cuando la opción SSL está On. Por defecto su valor es NULL. 
database.ca  La  ruta  al  archivo  certificate  authority.  Este  parámetro  solo 
aplica  cuando  la  opción  SSL  está  On.  Por  defecto  su  valor  es 
NULL. 
database.capath  La  ruta  al  archivo  que  contiene  certificados  SSL  validos  en 
formato PEM. Este parámetro solo aplica cuando la opción SSL 
está On. Por defecto su valor es NULL. Por defecto su valor es 
NULL. 
database.cipher  Una  lista  de  métodos  de  cifrado  para  usar  en  la  encriptación 
SSL. Este parámetro solo aplica cuando la opción SSL está On. 
Por defecto su valor es NULL. 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    178 

20.5.4 Consideraciones para IBM Informix 
Kumbia Enterprise utiliza PHP Data Objects (PDO) para acceder a bases de datos IBM Informix.  
Es  posible  realizar  conexiones  a  Informix  (IDS)    versión  7.x,  Universal  Server  (IUS)  9.x  y  a 
Informix Dynamic Server 2000, 10 y 11. Los siguientes requisitos son necesarios para realizar 
una conexión satisfactoria a este motor: 
 
• PHP debe estar compilado con la extensión pdo_informix, esta puede ser obtenida via 
PECL ó al compilar PHP desde el código fuente. 
• Cuando  se  compila  desde  el  código  fuente  la  opción  de  configuración  debe  incluir 
./configure --with-pdo-informix=/path/to/SDK[,shared] 
• La  extensión  PECL  puede  ser  instalada  usando  el  comando  pecl install
pdo_informix  en entornos Unix. Para una compilación satisfactoria de la extensión 
el cliente SDK de IBM para Informix debe estar instalado en la maquina ó el servidor 
Informix en si mismo. 
• La  variable  de  entorno  INFORMIXDIR  debe  apuntar  al  directorio  de  instalación  de 
informix ó del client SDK. 
• ESQL/C es necesario para trabajar con informix. El Informix Client SDK contiene este 
software. El client SDK para IBM Informix puede ser descargado desde el sitio web de 
soporte de IBM en  http://www-306.ibm.com/software/data/informix/tools/csdk/ . 
Si está utilizando Informix versión 10 ó 11 no es necesario instalar CSDK ya que este 
viene incluido en la distribución del servidor. 
• El servidor de Informix debe estar configurado para aceptar conexiones mediante tcp 
mediante el módulo onsoctcp. 
 
Una  vez  las  extensiones  php_pdo  y  php_pdo_informix  se  encuentren  disponibles  la  conexión 
puede realizarse de la siguiente forma: 
 
Ejemplo: Configuración de la conexión a IBM Informix 
[development]
database.layer = “pdo”
database.type = informix
database.dsn = "host=127.0.0.1;service=9800;database=bankdb;server=ids_server;
protocol=onsoctcp;EnableScrollableCursors=1"
database.username = informix
database.password = bypass
 
Parámetros de conexión con Informix: 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    179 

Tabla:Parámetros de conexión a IBM Informix con PDO 
Parámetro  Descripción 
database.pdo  Indica  que  se  debe  cargar  un  adaptador  PDO.  Su  valor  debe  ser 
On para que tenga efecto. 
database.dsn  Los parámetros de conexión del Data Source Name. El parámetro 
host  indica  el  nombre  del  maquina  ó  dirección  IP  donde  está 
instalado  el  Informix.  Service  es  el  puerto  donde  se  realizará  la 
conexión  TCP/IP.  Database  es  el  nombre  de  la  base  de  datos. 
Server  es  nombre  de  la  instancia  de  informix.  Protocol  debe  ser 
siempre  onsoctcp.  EnableScrollableCursors  debe  ser  igual  a  1 
para  permitir  el  uso  de  cursores  que  se  pueden  recorrer  en 
cualquier  orden,  esto  puede  mejorar  el  rendimiento  cuando  se 
usan paginadores por ejemplo. 
 
Otras  opciones  que  se  pueden  enviar  en  el  DSN  son: 
TraslationOption,  permite  utilizar  una  librería  de  traducción  de 
mensajes, con valor 0 permite solucionar un problema común en 
unixODBC. 
 
IsolationLevel:  Indica  el  nivel  de  isolación  de  la  conexión.  0  es 
Predeterminado, 1 es Read Uncommited, 2 es Read Commited, 3 
es Repeteable Read, 4 es Serializable y 5 es LastCommited. 
 
CursorBehavior: Cuando es 0 el cursor se cierra automáticamente 
al recorrer los registros, cuando es 1 se preserva. 
 
ClienteLocale:  Permite  establecer  la  localización  del  cliente.  Por 
defecto es en_US.CP1251 
 
DatabaseLocale:  Permite  establecer  la  localización  de  la  base 
datos por defecto es: en_US.819 
 
AutoCommitOptimization:  Indica  si  el  driver  debe  efectuar 
optimización para conexiones no‐transaccionales. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    180 

database.username  Nombre del usuario que realizará la conexión. 
database.password  Contraseña del usuario. 

20.5.4.1 Configuración del Servidor 
Es posible que deba cambiar el usuario con el que se ejecutan los procesos del servidor web al 
usuario  informix  ó  un  usuario  del  grupo  informix.  En  el  caso  de  Apache  Web  Server  puede 
modificar esto cambiando los parámetros User y Group así: 
 
User informix
Group informix
 
Si el servidor está instalado en Windows y se usa Microsoft IIS se debe entrar a la consola de 
administración  de  servicios.  Puede  ingresar  a  ella  mediante  el  comando  services.msc  en  el 
cuadro de dialogo ejecutar. Se da click derecho en el servicio “Informix IDS – Nombre” y luego 
en propiedades. En la pestaña inicio de sesión se coloca el usuario con permisos del motor y 
luego click en ‘Aceptar’. 
 
La siguiente es una configuración de las variables de entorno para un profile para el usuario 
“informix” en un servidor Unix ó Windows: 
 
Ejemplo:  Variables  de  entorno  recomendadas  para  realizar  una  conexión  a  IBM 
Informix 
export INFORMIXDIR=/opt/IBM/informix
export INFORMIXTMP=/opt/IBM/informix/tmp
export INFORMIXSERVER=ol_server
export INFORMIXSQLHOSTS=$INFORMIXDIR/etc/sqlhosts
export ONCONFIG=onconfig
export TERMCAP=/home/informix/etc/termcap
export
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/IBM/informix/lib:/opt/IBM/informix/etc/lib
:/opt/IBM/informix/lib/esql
export DBDATE=y4md
export DB_LOCALE=en_US.819
export SERVER_LOCALE=en_US.819
export CLIENT_LOCALE=en_US.819
export TERM=ansi
export PATH=$PATH:$HOME/bin:$INFORMIXDIR/bin
 
El archivo INFORMIXSQLHOSTS debe tener al menos un servicio tcp/ip disponible:  
 
ol_server onsoctcp localhost informixserver
 
El archivo /etc/services debe incluir la descripción TCP para el servicio creado: 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    181 

informixserver 9800/tcp # Informix Dynamic Server

20.5.4.2 Consideraciones con Transacciones 
El desarrollador debe activar el logging de la base de datos a Unbuffered Logging ó Buffered 
Logging  usando  la  herramienta  onmonitor  ó  mediante  el  comando  ontape  –B  dbname,  de  lo 
contrario el adaptador generará una excepción al tratar de realizar un commit ó un rollback a 
una transacción. 
 
Informix no genera un timeout cuando registros que se vayan a modificar ó leer esten siendo 
modificados  en  otra  transacción.  Kumbia  Enterprise  generará  una  excepción  como 
[Informix][Informix ODBC Driver][Informix]Could not do a physical‐order read to fetch next 
row.  sqlerrm(t)  (SQLFetchScroll[‐244]  at  /root/PDO_INFORMIX/informix_statement.c:889)] 
(‐244)  de tipo DbLockAdquisitionTimeout. 
 
Todos  los  niveles  de  isolación  son  soportados  en  runtime.  El  nivel  de  isolación  CURSOR 
SCALABILITY es validado con ISOLATION_SERIALIZABLE. 
 
Nota:  IBM  Informix  no  soporta  la  extensión  del  lenguaje  SQL  LIMIT  por  lo  que  el 
desarrollador debe asegurarse que los resultados devuelva el número de registros requeridos 
via condiciones en la clausula WHERE. 
 

20.5.5 Consideraciones con SQLite 
SQLite  es  un  motor  de  base  de  datos  escrito  en  C  que  es  embebible  en  aplicaciones  web  de 
baja concurrencia. La librería SQLite permite administrar bases de datos que se crean en un 
solo archivo y que se pueden distribuir junto con la aplicación. 
 
Como  se  mencionó  anteriormente  las  bases  de  datos  SQLite  no  están  recomendadas  para 
grandes aplicaciones con alto tráfico y acceso concurrente elevado.  
 
Kumbia Enterprise soporta SQLite versión 3 mediante la capa de abstracción PDO (PHP Data 
Objects) por lo que se requiere que las extensiones de PHP pdo y pdo_sqlite esten disponibles 
por la aplicación. Este adaptador no soporta múltiples transacciones simultáneas. 
 
Los parámetros de Conexión a SQLite son: 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    182 

Ejemplo: Definir una conexión a SQLite con PDO 
[development]
database.layer = “pdo”
database.dsn = "data/company.db"
database.type = sqlite
 
Tabla: Parámetros de conexión del adaptador de SQLite con PDO 
Parámetro  Descripción 
database.layer  Indica  que  se  debe  cargar  un  Adaptador  PDO.  Su  valor  debe 
ser “pdo” para que tenga efecto. 
database.dsn  Cuando  se  trata  de  SQLite  indica  la  ruta  al  archivo  base  de 
datos. La extensión .db es opcional pero es más representativa. 
El  PATH  del  archivo  puede  ser  un  path  absoluto  desde  el 
directorio donde está instalada la instancia ó un path relativo. 

20.6 Pool de Conexiones

El componente DbBase mediante la implementación de un Singleton controla que cada vez que 
se solicite la conexión a la base de datos se devuelva la misma conexión evitando la creación 
de  múltiples  conexiones  al  gestor  relacional  de  forma  innecesaria  aumentando  los  recursos 
requeridos por la aplicación. 
 
El método estático Database::rawConnect() devuelve la misma conexión activa sin importar el 
número  de  veces  que  sea  invocado,  si  aun  no  existe  una  conexión  entonces  la  crea.  Los 
parámetros  de  conexión  son  los  establecidos  por  entorno  activo  en  environment.ini.  Si  se 
requiere  una  nueva  conexión  al  gestor  se  puede  enviar  true  como  primer  parámetro  y  si  se 
requiere renovar la conexión es decir reemplazar la conexión del Singleton se envia true como 
segundo parámetro. 

20.6.1 Conexiones de Bajo Nivel 
Es  posible  establecer  conexiones  de  bajo  nivel  a  múltiples  motores  independientemente  del 
gestor  relacional  requerido.  El  subcomponente  DbLoader  permite  tanto  cargar  el  adaptador 
activo establecido en enviroment.ini como uno cualquiera usando el método estático factory. 
 
El  primer  parámetro  corresponde  al  nombre  del  adaptador  requerido  para  efectuar  la 
conexión, el segundo es un vector que contiene las opciones de conexión. Estas son las mismas 
utilizadas en una sección de un archivo de configuración enviroment.ini. 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    183 

Ejemplo: Establecer una conexión a un gestor relacional mediante DbLoader::factory 
<?php
$db = DbLoader::factory('MySQL', array(
"host" => "localhost",
"username" => "root",
"password" => "mypass",
"name" => "bankdb"
));
print_r($db->fetchAll(“SELECT * FROM accounts”));

 
Si se desea usar los adaptadores PDO hay que indicar la opción adicional “pdo” => true en el 
vector de configuración.  
 
Ejemplo: Establecer una conexión a un gestor relacional mediante un adaptador PDO 
<?php
$db = DbLoader::factory('MySQL', array(
"pdo" => true,
"host" => "localhost",
"username" => "root",
"password" => "mypass",
"name" => "bankdb"
));
$db->fetchAll("SELECT * FROM account");

Un  descriptor  string  también  puede  ser  usado  para  establecer  una  conexión.  Estos  tienen  el 
mismo formato que un DSN de PDO. 

Ejemplo: Establecer una conexión mediante un descriptor string 
$descriptor = “mysql:host=localhost;username=root;password=mypass;name=bankdb”;
$db = DbLoader::factoryFromDescriptor($descriptor);
 

20.6.2 Trazar Conexiones 
La  propiedad  de  las  conexiones  de  generar  trazas  permite  obtener  una  lista  de  todas  las 
operaciones SQL de bajo nivel ejecutadas en una sessión al gestor relacional. 
 
Para activar la traza en una conexión se debe llamar al método setTracing con parámetro true 
apartir del momento donde se desea empezar la traza: 
 
Ejemplo:  Activar  y  obtener  la  traza  de  seguimiento  en  un  procedimiento  con  gestores 
relacionales 
<?php
$db = DbBase::rawConnect();
$db->setTracing(true);
$results1 = $db->fetchAll(“SELECT * FROM customers”);
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    184 

$results2 = $db->fetchAll(“SELECT * FROM customers WHERE status = ‘Active’”);


foreach($db->getTracedSQL() as $sqlStatement){
echo $sqlStatement.”\n”;
}

20.7 Generar Profiles de ejecución de SQL

Los objetos del componente Db permiten generar Profiles de la ejecución de sentencias SQL 
que  se  envian  al  gestor  relacional.  La  información  generada  incluye  los  tiempos  en 
milisegundos que duró la ejecución de cada sentencia y así poder identificar cuellos de botella 
en la aplicación. 
 
Ejemplo: Activar el profiling desde objeto de conexión a un gestor relacional 
<?php
$db = DbBase::rawConnect();
$db->setProfiling(true);
 
Internamente  una  instancia  de  DbProfiler  es  instanciada  para  generar  los  profiles  de  las 
operaciones  SQL.  El  desarrollador  puede  definir  su  propio  profiler  estableciendo  una 
instancia  de  la  clase  que  implemente  la  interfaz  DbProfilerInterface  como  parámetro  de 
setProfiling(). 
 
Ejemplo: Definir una clase de profile personalizada 
<?php
$db = DbBase::rawConnect();
$db->setProfiling(new MyProfiler());
 
La interface DbProfilerInterface exige la implementación de: 
 
interface DbProfileInterface {
public function startProfile($sqlStatement);
public function stopProfile();
public function getNumberTotalStatements();
public function getTotalElapsedSeconds();
public function getProfiles();
public function reset();
public function getLastProfile();
}

20.8 Manejar Excepciones de Db

Crear  la  instancia  del  adaptador  ó  directamente  en  el  constructor  del  mismo  crea 
automáticamente una conexión a la base de datos. Si ocurren problemas al hacer la conexión ó 
alguno  de  los  parámetros  es  invalido  se  genera  una  excepción  en  la  misma  la  cual  debe  ser 
controlada por el desarrollador. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    185 

 
Las excepciones son controladas mediante un bloque try/catch que capture una excepción del 
tipo DbException: 
 
Ejemplo: Capturar una excepción DbException generada por el adaptador de conexión 
al gestor relacional 
<?php
try {
$db = DbLoader::factory('MySQL', array(
"pdo" => true,
"host" => "localhost",
"username" => "root",
"password" => "hea101",
"name" => "bankdb"
));
}
catch(DbException $e){
//No se pudo cargar el adaptador
}

20.8.1 Tipos de Excepciones lanzadas por el componente Db 
Excepción  Descripción 
DbException  Excepción generica lanzada por adaptador 
de conexión al gestor relacional utilizado. 
DbLockAdquisitionException  Excepción  lanzada  cuando  la  transacción 
actual en la conexión no puede efectuar un 
bloqueo  sobre  algún  recurso  por  ejemplo 
una tabla ó una serie de registros. 
DbSQLGrammarException  Excepción  lanzada  cuando  se  envia  una 
sentencia  SQL  mal  formada  ó  con  errores 
de sintaxis. 
DbContraintViolationException  Excepción  lanzada  cuando  la  operación  de 
modificación  ó  actualización  viola  un 
constraint de  llave foránea. 
DbInvalidFormatException  Excepción  lanzada  cuando  se  trata  de 
insertar ó actualizar un valor en una tabla 
con un formato erroneo. 
 

20.8.2 Información extendida de excepciones generadas por Db 
Las  excepciones  generadas  por  el  componente  Db  ofrecen  información  extendida  del  origen 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    186 

de  una  excepción.  Cuando  la  aplicación  se  encuentra  en  modo  debug  esta  información  se 
puede visualizar en pantalla. La referencia de la pantalla de excepciones es la siguiente: 
 
En la esquina superior derecha se presenta el tipo de excepción generada: 
 

 
 
Después de esta el mensaje que ha enviado el gestor relacional y la sentencia SQL que generó 
la excepción. En este caso tanto el tipo de excepción como el mensaje de error indica que la 
sentencia SQL esta mal formada ó tiene errores de sintaxis. 
 
El  id  de  conexión  es  un  código  interno  que  identifica  el  recurso  utilizado  para  conectarse  al 
motor  de  base  de  datos.  El  mensaje  de  la  excepción  informa  que  conexión  estaba  activa 
cuando se produjo la excepción. El id aparece al final como “Resource id #64”. 
 
El  codigo  de  error  enviado  por  el  motor  también  puede  resultar  de  ayuda  en  algunos  casos. 
Este se muestra al final del mensaje de error entre paréntesis. 
 

 
 
Como  la  aplicación  se  encuentra  en  modo  debug  se  visualiza  la  traza  de  ejecución  de  la 
excepción. Si Kumbia Enteprise detecta que la excepción se ha generado en un archivo de la 
aplicación  entonces  se  muestra  el  fragmento  de  código  resaltando  la  línea  exacta  donde  se 
generó la excepción: 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    187 

 
 
Debajo de la traza se encuentra el cuadro “Datos de la conexión activa” y presenta atributos 
del estado de la conexión en el momento de la excepción: 
 

 
 
En este caso la traza se encuentra desactivada, al activarla se obtendría todas las intrucciones 
SQL que se ejecutaron en la misma conexión previamente a que se produjera la excepción. La 
traza  se  puede  activar  declarativamente  en  el  modo  activo  en  config/environment.ini  ó 
programacionalmente  pasando  el  parámetro  “tracing”  =>  true  al  constructor  del  objeto 
conexión.  
 
El archivo config/environment.ini  entonces quedaría así: 
 
Ejemplo: Activar la traza en el archivo config/environment.ini 
[development]
database.host = 127.0.0.1
database.username = my_user
database.password = my_password
database.name = bankdb
database.type = mysql
database.tracing = true
 
Al ejecutar nuevamente el procedimiento se puede visualizar la traza de la conexión: 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    188 

 
 
El campo “Traza” dice “SI” y debajo de este el nuevo campo “Contenido de la Traza” muestra 
en orden cronológico las sentencias SQL generadas en la conexión activa. 
 
Más  debajo  se  visualiza  el  cuadro  datos  de  entrada,  en  él  se  detalla  la  información  que  fue 
enviada  al  procedimiento  desde  el  formulario  ó  enlace  anterior.  El  objetivo  del  cuadro  es 
identificar si los datos de entrada pueden ser los causantes del problema: 
 

 
 
Los valores de entrada se muestran en modo detallado ayudando así a conocer su contenido 
más fácilmente. 
 
Si  la  información  generada  no  es  suficiente  para  identificar  la  causa  de  la  excepción  puede 
utilizar  el  componente  Debug  el  cual  proporciona  ayudas  para  realizar  procedimientos 
tradicionales de rastreo de procesos. 

20.9 Tipos de Resultado al Obtener de Registros

Cada adaptador implementa los mismos tipos de vector al obtener registros, esto se refiere a 
la  forma  en  la  que  los  vectores  devueltos  estan  indexados.  Los  métodos  inQuery,  fetchOne  y 
fetchAll  permiten  establecer  en  su  segundo  parámetro  los  valores  de  las  constantes  que 
permiten cambiar la forma en la que estan dispuestos los resultados al obtenerlos. 
 
Tabla: Tipos de constantes para obtener los registros de un resultado 
Constante  Descripción 
Db::DB_NUM  Devuelve  cada  registro  como  un  vector  indexado  solamente 
numéricamente. 
Db::DB_ASSOC  Devuelve  cada  registro  como  un  vector  indexado  solamente 
asociativamente.  Las  claves  utilizadas  como  indices  corresponden  a 
los  nombres  de  las  columnas  de  la  sentencia  SELECT  ejecutada. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    189 

Cuando se realizan JOINs en múltiples tablas es posible que el nombre 
de los indices se repita por lo cual es necesario implementar alias para 
las columnas repetidas. 
 
Para  todos  los  gestores  relacionales  los  indices  se  encuentran  en 
minúsculas. 
Db::DB_BOTH  Devuelve  cada  registro  indexado  tanto  numéricamente  como 
asociativamente.  El  número  de  elementos  por  vector  resultado  es  el 
doble del número de columnas devuelto en la sentencia SELECT. 
 

20.10 Leer registros

Los siguientes métodos corresponden al API del componente Db que permiten leer registros 
de las entidades: 
 
public resource|false query(string $sqlQuery) 
Envia  una  sentencia  SQL  al  gestor  relacional.  La  sentencia  puede  devolver  registros  o  no 
devolverlos. 
 
Ejemplo: Enviar una sentencia SQL al gestor relacional mediante el método query() 
<?php
$db = DbLoader::factory('Oracle', array(
"host" => "192.168.2.140",
"username" => "scott",
"password" => "tiger",
"instance" => "XE"
));
$result = $db->query("SELECT id, name FROM customer WHERE category_id = 1");
while($row = $db->fetchArray($result)){
print $row['name']."\n";
}
 
public array find(string $tableName, string $whereClause, string $fields=””, string $orderBy=”1”) 
Realiza una consulta SELECT en una tabla en forma abstraida.  
 
Ejemplo: Realizar una búsqueda usando el método find() 
<?php
//Mostrar todos los clientes activos
$db = DbBase::rawConnect();
$resultset = $db->find(“customers”, “status = ‘Active’”);
foreach($resulset as $row){
print $row[‘name’].”\n”;
}
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    190 

public array inQuery(string $sqlQuery, int $fetchType=db::DB_BOTH) 
Devuelve los resultados de una consulta SQL en un array. El parámetro $fetchType se refiere a 
las constantes db::DB_ASSOC, db::DB_NUM y db::DB_BOTH que es el tipo de indexamiento del 
vector devuelto por registro. 
 
public array fetchAll(string $sqlQuery, int $fetchType=db::DB_BOTH) 
Obtiene  todos  los  resultados  de  una  consulta  SQL  en  un  array.  Es  un  alias  para  el  método 
inQuery. 
 
public array inQueryAssoc(string $sqlQuery) 
Obtiene  todos  los  resultados  de  una  consulta  SQL  en  un  array.  Cada  registro  es  un  array 
indexado asociativamente. 
 
Ejemplo:  Realizar  un  consulta  que  devuelve  los  registros  como  vectores  indexados 
asociativamente 
 
<?php
$db = db::rawConnect();
$customers = $db->inQueryAssoc(“SELECT id, name FROM customers ORDER BY id”);
foreach($customers as $customer) {
print $customer[‘name’].”\n”;
}
 
public array inQueryNum(string $sqlQuery) 
Obtiene  todos  los  resultados  de  una  consulta  SQL  en  un  array.  Cada  registro  es  un  array 
indexado numéricamente. 
 
Ejemplo:  Realizar  un  consulta  que  devuelve  los  registros  como  vectores  indexados 
numéricamente 
<?php
$db = db::rawConnect();
$customers = $db->inQueryNum(“SELECT id, name FROM customers ORDER BY id”);
foreach($customers as $customer) {
print $customer[1].”\n”; //Imprime el nombre
}
 
public array fetchOne(string $sqlQuery, int $fetchType=db::DB_BOTH) 
Devuelve un solo registro en un array de la consulta SELECT en $sqlQuery. El parámetro $type 
se  refiere  a  las  constantes  db::DB_ASSOC,  db::DB_NUM  y  db::DB_BOTH  que  es  el  tipo  de 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    191 

indexamiento del array devuelto por registro. 
 
Ejemplo: Obtener un resultado para consultas que devuelven un solo registro 
 
<?php
$db = DbBase::rawConnect();
$customer = $db->fetchOne(“SELECT * FROM customers WHERE id = 124”);

 
public array fetchArray(resource $resultQuery) 
Obtiene  un  registro  del  ultimo  recurso  de  consulta  generado  en  el  objeto  adaptador  ó  el 
indicado  mediante  el  recurso  $resultQuery.    El  resultado  devuelto  depende  del  fetchMode 
establecido con setFetchMode.  
 
public void numRows(resource $resultQuery=null) 
Devuelve  el  número  de  filas  obtenidas  en  la  ultima  consulta  SQL  ejecutada  en  el  objeto 
adaptador.  Es  posible  establecer  el  recurso  devuelto  por  el  método  query  para  obtener  esta 
información. 
 
Ejemplo: Obtener el número de registros que devuelve una consulta  
<?php
$db = Db::rawConnect();
$result = $db->query("SELECT id, name FROM customer WHERE status = 'Active'");
print "Hay ".$result->numRows($result)." clientes activos";
 
public boolean dataSeek(int $number, resource $resultQuery=null) 
Permite establecer la posición en el cursor interno ó el establecido por $resultQuery haciendo 
que el próximo registro que obtenga fetchArray sea el número $number. 
 
Ejemplo: Mover el puntero del resultado de una consulta 
<?php
$db = DbLoader::factory('MySQL', array(
"host" => "127.0.0.1",
"username" => "root",
"password" => "hea101",
"name" => "bankdb"
));
$db->query("SELECT id, name FROM customer WHERE category_id = 1");
if($db->numRows()>10){
//Empezar desde el 10 registro
$db->dataSeek(10);
while($row = $db->fetchArray()){
print $row['name']."\n";
}
}
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    192 

public resource getLastResultQuery() 
Obtiene el último recurso generado en una consulta SQL mediante el objeto. 
 
Ejemplo: Obtener el último resulset generado con Db::getLastResultQuery 
<?php
$db = Db::rawConnect();
$db->query("SELECT id, name FROM customer WHERE status = 'A'");
$result = $db->getLastResultQuery();
while($row = $db->fetchArray()){
print $row['name']."\n";
}

 
public string limit(string $sqlQuery, int $number) 
La  extensión  del  la  sentencia  SQL  SELECT  llamada  LIMIT  permite  especificar  al  gestor 
relacional que no debe devolver más del numero de registros limitados a $number. No todos 
los  gestores  relacionales  implementan  esta  extensión  y  otros  permiten  hacerlo  utilizando 
otros procedimientos. 
 
Este  método  permite  crear  una  sentencia  SQL  que  reproduzca  la  funcionalidad  LIMIT  en 
forma transparente. 
 
Ejemplo: Aplicar la extensión del lenguaje SQL LIMIT a una consulta 
<?php
$db = Db::rawConnect();
$sqlQuery = $db->limit("SELECT id, name FROM customer WHERE status = 'A'", 10);
$db->query($sqlQuery);
$result = $db->getLastResult();
while($row = $db->fetchArray()){
print $row['name']."\n";
}

20.11 Manipular Registros

Los siguientes métodos permiten la generación y ejecución de sentencias SQL que permiten la 
manipulación de registros: 
 
public  boolean  insert(string  $table,  array  $values,  array  $fields=array(),  boolean 
$automaticQuotes=false) 
Permite realizar una inserción sin usar SQL directamente. El SQL es generado está de acuerdo 
al  gestor  relacional  utilizado.  Notese  que  por  defecto  el  método  espera  que  los  valores  a 
insertar  esten  correctamente  escapados,  el  parámetro  $automaticQuotes  permite  que  se 
agregen  comillas  simples  y  se  escapen  los  valores  usando  la  función  addslaches()  en  forma 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    193 

automática. 
 
Las  columnas  que  son  omitidas  se  les  aplica  la  regla  del  gestor  relacional  DEFAULT  si  esta 
existe, en caso contrario se insertan valores nulos. 
 
Ejemplo: Realizar una inserción con $automaticQuotes y sin ellas 
<?php
$db = DbBase::rawConnect();
//Usando Quotes Manualmente
$values = array(“’0044’”, “’England’”);
$fields = array(“code”, “name);
if($db->insert(“countries”, $values, $fields)){
Flash::success(“Se insertó correctamente el registro”);
}
//Usando Quotes en forma automática
$values = array(“0044”, “England”);
$fields = array(“code”, “name);
if($db->insert(“countries”, $values, $fields, true)){
Flash::success(“Se insertó correctamente el registro”);
}

 
Cuando  se  agrega  el  parámetro  $automaticQuotes  y  se  requiere  insertar  expresiones  ó 
ejecución de funciones de la base de datos es necesario indicar estos usando instancias de la 
clase DbRawValue. 
 
Ejemplo: Insertar un valor expresión de la base de datos 
 
<?php
$db = DbBase::rawConnect();
$values = array(“John Smith”, new DbRawValue(“current_date()”));
$fields = array(‘name’, ‘created_at’);
if($db->insert(“employees”, $values, $fields, true)){
Flash::success(“Se insertó correctamente el registro”);
}
 
public  boolean  update(string  $table,  array  $fields,  array  $values,  string  $whereClause=null, 
boolean $automaticQuotes=false) 
Permite realizar una actualización sin usar SQL directamente. El SQL es generado de acuerdo 
al  gestor  relacional  utilizado.  Notese  que  por  defecto  el  método  espera  que  los  valores  a 
actualizar  esten  correctamente  escapados,  el  parámetro  $automaticQuotes  permite  que  se 
agregen comillas simples y se escapen los valores usando la función addslaches(). 
 
Ejemplo: Realizar una actualización de datos 
<?php
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    194 

$db = DbBase::rawConnect();
$fields = array(“code”, “name);
$values = array(“’0044’”, “’England’”);
if($db->update(“countries”, $fields, $values)){
Flash::success(“Se actualizó correctamente el registro”);
}
$fields = array(“code”, “name);
$values = array(“0044”, “England”);
if($db->update(“countries”, $fields, $values, true)){
Flash::success(“Se actualizó correctamente el registro”);
}
 
public void delete(string $table, string $whereCondition=””) 
Permite realizar una eliminación de registros sin usar SQL directamente. El SQL es generado 
de acuerdo al gestor relacional utilizado. 
 
Ejemplo: Realizar una eliminación de datos 
<?php
$db = DbBase::rawConnect();
//Eliminar todos los registros de la tabla customer
if($db->delete(“customer”)==true){
Flash::success(“Se eliminaron correctamente todos los registros”);
}
//Eliminar usando condiciones
if($db->delete(“customer”, “status = ‘Active’”)==true){
Flash::success(“Se eliminaron correctamente los registros”);
}
 
public integer affectedRows(Resource $resultQuery=null) 
Devuelve  el  numero  de  filas  afectadas  por  una  operación  de  inserción,  actualización  ó 
borrado.  El  parámetro  $resultQuery  permite  cambiar  el  recurso  devuelto  por  otra  ejecución 
del método query ó exec. 
 
Ejemplo:  Obtener  información  de  los  registros  afectados  en  una  operación  de 
manipulación de datos 
<?php
$db = Db::rawConnect();
$db->query("DELETE FROM customer WHERE status = 'I'");
print "Filas borradas = ".$db->affectedRows();

20.12 Administrar Transacciones

public boolean begin() 
Permite iniciar una transacción en la conexión utilizada.  
 
Ejemplo: Uso de transacciones a bajo nivel  
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    195 

 
<?php
$db = DbBase::rawConnect();
$db->begin();
$fields = array("name", "createdAt");
$values = array("John Smith", "2007-10-21");
if($db->insert("customer", $values, $fields, true)==false){
$values = array("Darren Davison", "2007-12-02");
if($db->insert("customer", $values, $fields, true)==false){
$db->commit();
} else {
$db->rollback();
}
} else {
$db->rollback();
}
 
public boolean rollback() 
Permite anular una transacción en la conexión utilizada. 
 
public boolean commit() 
Permite hacer commit a una transacción pendiente en la conexión actual. 
 
public string forUpdate(string $sqlQuery) 
Genera un SQL que efectúa un bloqueo no‐compartido del grupo de registros seleccionados. 
 
public string sharedLock(string $sqlQuery) 
Genera un SQL que efectúa un bloqueo compartido del grupo de registros seleccionados. 
 
public void setIsolationLevel(int $isolationLevel) 
Permite  establecer  el  nivel  de  isolación  de  la  conexión.  Los  niveles  de  isolación  deben  estar 
disponibles en el gestor relacional, consulte la documentación si tiene dudas de ello. El valor 
del parámetro $isolationLevel es alguna de las constantes: 
 
Tabla: Descripción de constantes de niveles de Isolación 
Valor  Nombre  Descripción 
1  ISOLATION_READ_UNCOMMITED  Los SELECTs se ejecutan en un 
modo de no‐bloqueo. 
2  ISOLATION_READ_COMMITED  Las  consultas  se  ejecutan  un 
un  modo  de  lecturas 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    196 

consistentes con no‐bloqueo. 
3  ISOLATION_REPEATABLE_READ  Gestores  transaccionales 
normalmente  trabajan  sobre 
este modo de isolación. 
4  ISOLATION_SERIALIZABLE  Algunos  gestores  relacionales 
como  Oracle  soportan 
nativamente  este  modo,  otros 
como  MySQL  convierten  todas 
las  instrucciones  SELECT  en 
SELECT  …  LOCK  IN  SHARE 
MODE bloqueando el grupo de 
registros  obtenidos  en  una 
consulta a modo‐solo lectura. 
 
public boolean isUnderTransaction() 
Permite conocer si la conexión se encuentra bajo una transacción activa. 
 
public void getHaveAutoCommit() 
Permite conocer si la conexión tiene auto‐commit ó nivel de isolación READ UNCOMMITED. 

20.13 Crear, Cerrar y obtener información de conexiones

public Db rawConnect(boolean $newConnection=false, boolean $renovate=false) 
Obtiene  un  objeto  conexión  a  la  base  de  datos  del  entorno  actual  con  los  parámetros 
establecidos en el archivo config/enviroment.ini. Este método implementa el patrón Singleton 
controlando que solo una instancia de la conexión se cree cada vez que se hace el llamado al 
mismo desde cualquier parte de la aplicación. 
 
Ejemplo: Obtener la conexión por defecto al gestor relacional 
<?php
//Crear o obtener la última conexión creada
$db = DbBase::rawConnect();
//Crear una nueva conexión sin cambiar la conexión del Singleton
$db = DbBase::rawConnect(true);
//Crear una nueva conexión renovando la conexión del Singleton
$db = DbBase::rawConnect(true, true);
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    197 

public ResourceConnection connect(stdClass $descriptor) 
Establece la conexión al gestor relacional. 
 
Ejemplo: Crear una conexión usando el método Db::connect 
<?php
$db = new Db();
$db->connect("192.168.2.140", "scott", "tiger", "bankdb");
$result = $db->query("SELECT * FROM customer");
while($row = $db->fetchArray($result)){
print $row['name']."\n";
}
 
public resource getConnectionId() 
Obtiene  el  recurso  interno  de  bajo  nivel  con  el  que  se  identifica  la  conexión  al  gestor 
relacional. 
 
public void close() 
Cierra la conexión actual con el gestor relacional. Si la conexión es persistente no se cerrará. 
 
public void setReadOnly(boolean $readOnly) 
Establece si la conexión será de solo lectura. En este estado se generará una excepción cuando 
se trate de realizar una inserción, modificación ó eliminación de datos. 
 
public void isReadOnly() 
Permite saber si la conexión es de solo lectura ó no. 

20.14 Información de Errores

public string error(string $errorString=’’, resource $resultQuery=null) 
Devuelve información del último error generado en el adaptador. 
 
public integer noError(resource $resultQuery=null) 
Devuelve el número del último error generado. 

20.15 Obtener el valor de la columna identidad

Algunos  gestores  relacionales  soportan  columnas  identidad,  es  decir,  que  manejan  un 
consecutivo auto‐numérico para diferenciar unívocamente cada registro en una tabla.  
 
public integer lastInsertId(string $table=’’, string $identityField=””) 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    198 

Obtiene el último valor insertado en una columna identidad. Algunos gestores relacionales no 
soportan este tipo de columnas y por ello es necesario obtener el valor buscando el máximo 
valor insertado en el campo llave primaria.  
 
public boolean tableExists(string $table, string $schema=””) 
Permite  consultar  si  una  relación  con  el  nombre  $table  existe  en  el  schema  de  la  conexión 
actual ó el indicado usando el parámetro $schema. 

20.16 Obtener información de Tablas

public array getFieldsFromTable(string $tableName) 
Este  método  obtiene  los  campos  de  una  tabla  en  un  vector.  El  vector  puede  ser  indexado 
numéricamente ó asociativamente: 
 
Ejemplo: Obtener los campos de una tabla con Db::getFieldsFromTable 
<?php
 
$db = DbBase::rawConnect();
$fields = $db->getFieldsFromTable(“customer”);
 
public string fieldName(int $number, Resource $resultQuery=null) 
Obtiene  el  nombre  de  un  campo  en  la  posición  establecida  por  $number  del  resultado 
$resultQuery. 
 
public array listTables(string $schemaName=’’) 
Devuelve  un  array  con  las  tablas  que  hay  en  la  schema  actual  ó  en  el  que  se  indique  en 
$schemaName.  En  algunos  gestores  relacionales  también  se  devuelven  las  vistas  a  las  que 
tenga acceso el usuario de la conexión activa. 
 
public array describeTable(string $tableName=’’, string $schemaName=’’) 
Devuelve un array con la descripción de los campos de una tabla junto con sus tipos de datos. 

20.17 Crear y Eliminar Tablas

public  boolean  createTable(string  $tableName,  array  $definition,  array  $index=array(),  array 


$tableOptions=array()) 
Permite crear tablas físicas ó temporales en la conexión activa. El parámetro $definition es un 
vector con la lista de campos de la tabla y sus atributos. El parámetro $index permite indicar 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    199 

indices  que  se  deban  crear  junto  con  la  tabla  y  por  último  $tableOptions  permite  indicar 
opciones  de  la  tabla  a  crear  tales  como  el  Engine  en  el  caso  de  MySQL,  el  charset  ó  el 
tablespace en el caso de Oracle. Devuelve un valor booleano indicando el éxito de la operación. 
 
Ejemplo: Crear una tabla usando un adaptador en especial 
<?php
$db = DbLoader::factory('MySQL', array(
'hostname' => 'localhost',
'username' => 'root',
'password' => '',
'name' => 'test'
));
$db->createTable(“example”, array(
"id" => array(
"type" => DbMySQL::TYPE_INTEGER,
"notNull" => true,
"primary" => true,
"auto" => true
),
"nombre" => array(
"type" => DbMySQL::TYPE_VARCHAR,
"notNull" => true,
"size" => 120
),
"texto" => array(
"type" => DbMySQL::TYPE_TEXT,
"notNull" => true
),
"cantidad" => array(
"type" => DbMySQL::TYPE_INTEGER,
"notNull" => true,
"size" => 11
),
"fecha" => array(
"type" => DbMySQL::TYPE_DATETIME,
"notNull" => true
),
"fecha_at" => array(
"type" => DbMySQL::TYPE_DATE
),
"fecha_in" => array(
"type" => DbMySQL::TYPE_DATE
),
"estado" => array(
"type" => DbMySQL::TYPE_CHAR ,
"notNull" => true,
"size" => 1
)
), array(
“ix1” => “nombre”,
“ix2” => array(“fecha”, “estado”)
));

 
También es posible crear la tabla usando la conexión predeterminada del entorno actual: 
 
Ejemplo: Crear una tabla usando la conexión predeterminada 
<?php
$db = Db::rawConnect();
$db->createTable(“example”, array(
"id" => array(
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    200 

"type" => Db::TYPE_INTEGER,


"notNull" => true,
"primary" => true,
"auto" => true
),
"nombre" => array(
"type" => Db::TYPE_VARCHAR,
"notNull" => true,
"size" => 120
)
));
 
Los  tipos  de  atributos  con  los  que  se  puede  describir  un  campo  en  la  definición  de  las 
columnas es la siguiente: 
 
Tabla: Tipos de atributos para describir una tabla con Db::createTable 
Atributo  Descripción 
type  El tipo de dato que se almacenará en la columna, se puede utilizar un 
string con el tipo de dato ó usar las constantes del adaptador lo que es 
más recomendable. 
notNull  Indica si la columna debe permitir nulos o no. 
primary  Indica si el campo hace parte de la llave primaria de la tabla. 
auto  Indica si el campo es identidad. Solo puede haber un campo 
autonumérico en la tabla. 
size  Tamaño del campo. 
scale  Permite establecer la escala del campo. 
precision  Permite establecer la precisión del campo. 
default  Permite establecer el valor por defecto de la columna cuando se 
inserta un valor nulo en ella. 
 
public boolean dropTable(string $tableName, $ifExists=false) 
Elimina una tabla del schema actual de la conexión. El parámetro $ifExists permite establecer 
si  se  debe  comprobar  que  la  tabla  exista  antes  de  ser  eliminada  lo  que  evita  una  excepción 
generada  por  el  gestor  relacional.  Devuelve  un  valor  booleano  indicando  el  éxito  de  la 
operación. 
 
Ejemplo: Eliminar una tabla con Db::dropTable 
<?php
$db = DbBase::rawConnect();
$db->dropTable(“customer”);
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    201 

20.18 Fecha del gestor relacional

public string getDateUsingFormat(string $date, string $format=”YYYY­MM­DD”) 
Devuelve la fecha del gestor relacional en un determinado formato. 
 
public string getCurrentDate() 
Obtiene la fecha actual desde el gestor relacional. 
 
public string addQuotes(string $value) 
Agrega comillas especiales soportadas por el gestor relacional a un valor $value. 

20.19 Debug, Seguimiento y Traza

protected void log(string $msg, int $type=Logger::DEBUG) 
Envia un valor al log interno del objeto conexión. La variable $type debe tener el valor de una 
de las constantes del componente Logger. 
 
protected void debug(string $sqlStatement) 
Realiza un debug de la instrucción SQL $sqlStatement enviandola a pantalla. Generalmente no 
es usado externamente y se invoca cuando la conexión se encuentra en modo debug. 
 
public void setDebug(boolean $debug) 
Permite imprimir en pantalla las operaciones internas de SQL generadas en el objeto. 
 
public void setTracing(boolean $tracing) 
Establece si el objeto está en modo traza ó no. 
 
public array getTracedSQL() 
Devuelve un vector con las operaciones SQL ejecutadas en la conexión mientras se encontraba 
en modo traza. 
 
public void setLogger(mixed $logger) 
Establece  el  nombre  del  archivo  con  el  que  se  hará  seguimiento  a  las  operaciones  SQL 
generadas en la conexión. Si se envia true como parámetro se creará un log con la convención 
dbYYYYMMDD.txt. Si se establece una instancia de un adaptador de logger este es tomado para 
hacer el seguimiento. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    202 

21 Componente Active Record - ORM


21.1 Introducción

Muchos  de  los  procesos  críticos  del  software  en  una  empresa  están  relacionados  con  el 
funcionamiento, desarrollo y mantenimiento de los datos que representan la información, un 
activo muy valioso de una organización. Los entornos empresariales actuales requieren de la 
integración  continua  de  requerimientos  dadas  las  condiciones  de  un  mundo  cambiante  y 
evolutivo. Las aplicaciones desarrolladas bajo un componente de acceso a la información poco 
escalable ó demasiado dependiente de componentes y proveedores tecnológicos, puede llevar 
a  que  una  organización  pierda  clientes  ó  dinero  debido  a  la  imposibilidad  de  adaptarse 
rápidamente a las necesidades requeridas sin perder estabilidad ó requiriendo mayor tiempo 
de desarrollo e implementación generando sobre costos. 
 
Un componente importante en Kumbia Enterprise Framework es el componente ActiveRecord. 
Este es el encargado de realizar el mapeo objeto‐relacional y de encargarse de los modelos en 
la  arquitectura  MVC  de  las  aplicaciones.  El  concepto  de  ORM  se  refiere  a  una  técnica  de 
mapear las relaciones de una base de datos a objetos nativos del lenguaje utilizado (PHP en 
este caso), de tal forma que se pueda interactuar con ellos en forma más natural. Los objetivos 
de este componente van más allá de mapear tablas y convertirlas en clases (incluyendo tipos 
de  datos,  constraints,  lógica  de  dominio,  etc.)  ó  de  convertir  registros  en  objetos.  La  idea  es 
reducir los detalles de la interacción con las bases de datos en gran medida mediante varias 
capas  de  abstracción,  incluyendo  reducir  el  uso  de  SQL  ó  lidiar  con  conexiones  y  sintaxis 
programacional de bajo nivel. 
 
Al implementar el acceso a las bases de datos usando un ORM se gana: 
 
• Independencia  de  la  base  de  datos  utilizada  en  gran  medida,  esto  aumenta  las 
características comerciales de un software ya que es posible cambiar de RBDM con un 
menor impacto sobre las áreas implicadas al uso e implementación del mismo. 
• Reducción del tamaño del código haciendo más simple el uso y entendimiento a nivel 
de desarrollo de sistemas que utilicen bases de datos. 
• La  capa  intermedia  de  acceso  a  loas  RBDMs  proporciona  un  método  potente    de 
interceptación de cualquier evento relacionado con las bases de datos, lo cual facilita 
la validación de la lógica de dominio, integridad de datos, definir niveles de seguridad, 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    203 

logging , auditoria de sistemas, etc. 
• El ORM permite administrar las asociaciones de las entidades del modelo incluso si el 
backend de almacenamiento es distinto.  
• ActiveRecord  proporciona  event  handling  en  la  capa  intermedia,  lo  cual  permite 
notificar cambios en el modelo de forma uniforme y consistente. 
 
La mayor parte de la implementación de ActiveRecord se basa en el patrón de diseño del tipo 
Data  Source  Architectural  del  mismo  nombre.  En  conjunto  con  el  almacenamiento  de  meta‐
datos y la administración de transacciones se realizan los procesos de interacción con bases 
de datos a más alto nivel. 

21.2 Cuando usar ActiveRecord

ActiveRecord  es  un  patrón  de  diseño  en  los  cual  los  datos  y  la  estructura  de  los  mismos  se 
encuentran asociados en una misma clase. Los datos generalmente son persistentes, es decir 
que están almacenados en algún gestor relacional, archivo ó medio físico. La lógica de acceso a 
los datos es fácilmente implementable usando ActiveRecord y además la convierte en parte de 
la lógica de dominio de la aplicación. 
 
ActiveRecord es una buena opción cuando la lógica de dominio no es muy compleja, es decir se 
implementa  un  modelo  isomorfico,  se  usan  derivaciones,  colecciones  ó  herencia  no‐sencilla. 
Modelos entidad‐relación con un diseño consistente ayudan a mejorar la implementación de 
patrón de diseño. 

21.3 Entidades

Las entidades son objetos persistentes ligeros que normalmente representan una tabla en una 
base  de  datos  relacional.  El  estado  persistente  de  una  entidad  este  representado  usando 
atributos persistentes asociados a los campos de las tablas. Cada entidad se implementa en un 
modelo que es una clase en un archivo en el directorio models/. 

21.3.1 Requerimientos de las Clases de Entidades   
Las clases deben tener los siguientes requerimientos: 
 
• Cada archivo debe tener el nombre de la tabla y la extensión .php 
• Debe haber una entidad por archivo 
• La clase debe ser subclase (heredar) de la clase ActiveRecord 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    204 

• La clase no debe tener constructores 
• La clases que representen entidades finales no debe ser abstracta 
 

21.3.2 Atributos de las Entidades 
Debido a que PHP es un lenguaje con tipificación dinámica los atributos de las clases entidad 
no representan el tipo de dato real del campo en la base de datos. Con objetivos funcionales 
los  getters  de  algunos  campos  crean  objetos  asociados  al  tipo  de  dato  real,  por  ejemplo,  los 
campos tipo fecha devuelven un objeto de la clase Date con el valor del campo. 
 
Es  posible  agregar  casting  al  valor  de  cada  objeto  usando  la  opción  del  script  que  crea 
modelos así: 
 
php scripts/create_model.php –-table-name customers –-enable-casting yes
 
Los tipos de datos a los que les aplica casting son los siguientes: 
 
Tabla: Relación de casting entre tipo de dato de la base de datos y tipo de dato de PHP 
Tipo Dato BD  Tipo Dato PHP/Kumbia 
Enterprise 
Varchar, Char, Text, Blob  String 
Integer, smallint, tinyint  Integer 
decimal, float, Money  double 
date  Date 
time  Time 
 
Adicional  a  lo  anterior  es  recomendable  inicializar  los  atributos  del  modelo  a  un  valor 
adecuado  a  su  tipo  de  dato,  de  esta  forma  se  evitan  inconvientes  con  la  ampliamente 
construcción del framework isset usada por el framework, ya que algunas veces considera que 
un campo no está definido pero en realidad tiene un valor nulo (null). 

21.4 Atributos y Campos persistentes

La  implementación  de  los  atributos  de  las  entidades  en  las  clases  se  puede  realizar 
estáticamente  ó  dinámicamente  dependiendo  de  los  requerimientos  de  la  aplicación.  En 
general una implementación estática propende por mejores practicas de desarrollo y software 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    205 

más seguro. 
 
En la forma estática se definen los campos de la tabla como atributos protegidos de la clase. 
Esto permite encapsular el estado interno de cada propiedad y evitar que sea cambiada por 
equivocación  ó  a  propósito  en  lógica  de  la  aplicación.  En  estos  casos  también  es  necesario 
implementar  métodos  get/set  para  poder  obtener/establecer  el  valor  de  los  atributos.  Los 
métodos  de  ActiveRecord  isAttribute($property),  writeAttribute($property,  $value)  y 
readAttribute($property)  permiten  dinámicamente  conocer  si  existe  un  atributo,  obtener  y 
devolver  su  valor  en  forma  pública.  Por  ejemplo  isName(),  getName()  y  setName()  es  una 
implementación estática para el atributo ‘name’ de una entidad Customer. 
 
La forma general en la que los getters/setters deben ser implementados es la siguiente: 
 
public function getProperty();
public function setProperty($valueOfProperty);
 
El método protegido setTrasient($attribute) permite establecer que campos de la entidad no 
deben  ser  persistidos.  Las  operaciones  de  inserción  y  actualización  omiten  los  atributos 
marcados como Trasient. 
 
Ejemplo: Establecer un campo trasient en el modelo 
protected function initialize(){
$this->setTransient(“user_code”);
}
 
Cuando los campos se mapean dinámicamente su visibilidad queda establecida como pública 
por defecto.  

21.5 Llaves Primarias

Generalmente  de  entidades  tienen  una  llave  primaria  que  permite  identificar  un  registro  en 
forma  única.  Kumbia  Enterprise  Framework  lee  los  meta‐datos  de  la  tabla  mapeada 
directamente  del  gestor  relacional  e  identifica  la  llave  primaria  con  sus  características: 
simples, compuestas y/o auto‐numéricas. 
 
El tipo de dato de llaves primarias debe ser un tipo de dato integral, en general se debe evitar 
el  uso  de  campos  con  tipo  de  dato  flotante,  decimal  ó  Money,  ya  que  pueden  variar 
ligeramente y no ofrecen seguridad en que un registro sea univoco. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    206 

 
Los accesores (métodos get) de los atributos que pertenezcan a una llave primaria compuesta 
ó simple deben ser todos públicos.  

21.6 Convenciones en llaves primarias

Kumbia Enterprise Framework soporta convención en llave primaria, para esto debe tener los 
siguientes requisitos: 
 
• El campo debe llamarse ‘id’ 
• El campo debe estar marcado como llave primaria en el gestor relacional 
• El campo debe ser entero preferiblemente unsigned (sin signo) 
• El  campo  debe  ser  una  columna  identidad  ósea  ser  autonumérico  (DB2,  MySQL, 
Sybase,  Microsoft  SQL  Server)  ó  estar  asociado  a  una  secuencia  (Oracle,  DB2, 
PostgreSQL, Interbase) 
 
El uso de esta convención reduce la complejidad de la aplicación y reduce la codificación ya 
que muchos aspectos el framework puede asumir esto.  

21.7 Fechas Auto-Asignables

ActiveRecord soporta fechas auto‐asignables mediante convención mediante lo cual se puede 
realizar versionamiento concurrente óptimista ó simplemente llevar un registro de fechas de 
creación  y modificación de registros. 
 
Las convenciones para fechas auto‐asignables son las siguientes: 
 
 Para  que  un  campo  tome  automáticamente  la  fecha  del  sistema  en  la  operación  de 
insertar este debe tener el sufijo “_at” y permitir valores nulos. 
 Para  que  un  campo  tome  automáticamente  la  fecha  del  sistema  en  la  operación  de 
actualizar este debe tener el sufijo “_in” y permitir valores nulos. 

21.8 Multiplicidad en Relaciones de Entidades

Existen cuatro tipos de multiplicidad en relaciones: una‐a‐una, una‐a‐muchos, muchos‐a‐una y 
muchos‐a‐muchos. La multiplicidad puede ser unidireccional ó bidireccional y cada una puede 
ser simple ó mediante combinación de tablas. El tipo de relaciones establece como se lleva a 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    207 

persistencia  una  instancia  de  una  entidad.  Normalmente  el  gestor  relacional  administra 
constraints de llave foránea correspondientes a estas relaciones, la definición de estos ayuda a 
que  la  integridad  de  datos  sea  confiable  y  las  relaciones  definidas  obtengan  los  resultados 
esperados. A través de la implementación de las relaciones es posible acceder a los registros 
relacionados a cada registro de forma uniforme ahorrando código. 

21.8.1 Convenciones en Relaciones 
Los  nombres  de  campos  de  las  entidades  con  ciertas  convenciones  permiten  que  se 
establezcan automáticamente los campos referencias y se automaticen tareas de codificación 
mediante una estructura nemotécnica: 
 
• Para especificar un campo que es llave foránea a otra relación se utiliza el nombre de 
campo “nombre_tabla_id” 
• La  tabla  referenciada  debe  tener  un  campo  identidad  que  sea  llave  primaria  con 
nombre “id”. 
• Si es posible, los campos relacionados deben tener el mismo tipo de dato. 
 

21.8.2 Relaciones Unidireccionales 
Las  relaciones  unidireccionales  son  aquellas  que  se  generan  de  una  relación  a  otra  pero  no 
viceversa.  Mediante  los  métodos  belongsTo,  hasMany  ó  hasOne  se  establece  que  uno  ó  mas 
campos hacen referencia a otros equivalentes en otra entidad.  

21.8.3 Relaciones Bidireccionales 
Las relaciones bidireccionales establecen asociaciones en las que cada una de ellas tiene una 
viceversa complementaria.  

21.8.4 Muchos a uno 
La  asociación  unidireccional  muchos‐a‐uno  es  la  más  común  de  todas.  Para  establecer  una 
relación de este tipo se utiliza el método protegido de ActiveRecord belongsTo: 
 
Ejemplo: Multiplicidad muchos a uno relacionada con un solo campo 
 
Para 2 Tablas: 
 
CREATE TABLE `country` (
`code` int(11) NOT NULL,
`name` varchar(20) default NULL,
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    208 

PRIMARY KEY (`code`)


);
CREATE TABLE `city` (
`code` int(11) NOT NULL,
`country_code` int(11) default NULL,
`name` varchar(80) default NULL,
PRIMARY KEY (`code`)
);
 
El modelo de ciudades con una relación muchos‐a‐uno se implementa así: 
 
<?php
class City extends ActiveRecord {
protected function initialize(){
$this->belongsTo(“country_code”, “country”, “code”);
}

}
 
El  primer  parámetro  de  belongsTo  indica  el  campo  de  la  entidad  que  hace  la  asociación,  el 
segundo indica el nombre de la entidad referenciada y el tercero el nombre del campo en la 
entidad referenciada. La asociación una vez definida se puede utilizar así: 
 
Ejemplo: Utilizar una asociación muchos a uno 
 
$city = EntityManager::getEntityInstance(“City”);
$city->findByName(“Bogotá”);
$country = $city->getCountry()
print $country->getNombre(); // => Colombia
 
Un getter con el nombre de la relación ‘Country’ permite obtener  el registro asociado al país 
en la ciudad consultada.  

Relacionada con varios campos: 
El siguiente ejemplo implementa una relación muchos a uno con 2 campos referencia, en este 
caso los nombres de los campos son iguales en ambas tablas si fuesen diferentes se podrían 
definir en el tercer parámetro de belongsTo. 
 
Ejemplo: Utilizar una relación compuesta muchos a uno 

CREATE TABLE `customer` (


`identification_type` char(3) NOT NULL default '',
`number` varchar(40) NOT NULL default '',
`nombre` varchar(120) default NULL,
`status` char(1) default NULL,
PRIMARY KEY (`identification_type`,`number`)
);
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    209 

CREATE TABLE `flights` (


`flight_number` varchar(12) NOT NULL default '',
`identification_type` char(3) default NULL,
`number` varchar(40) default NULL,
`flight_date` date default NULL,
`initial_hour` time default NULL,
`final_hour` time default NULL,
PRIMARY KEY (`flight_number`)
);
 
El modelo Flights se implementa así: 
 
Ejemplo:  Definir  una  relación  belongsTo  en  un  modelo  entidad­relación  sin 
convenciones 
 
<?php
class Flights extends ActiveRecord {
protected function initialize(){
$this->belongsTo(array(“identification_type”, “number”),
“customer”);
}
}
 
La relación puede ser utilizada así: 
 
$flight = $this->Flights->findByDate(“2008-11-01”);
$customer = $flight->getCustomer();
 
Un getter con el nombre de la relación permite obtener  el registro asociado al cliente en el 
vuelo consultado. 

21.8.5 Uno a Muchos 
La  asociación  unidireccional  uno‐a‐muchos  indica  que  para  cada  registro  de  una  entidad 
existen uno ó más registros asociado en la entidad referenciada. Para establecer una relación 
de este tipo se utiliza el método protegido de ActiveRecord hasMany. 

21.8.6 Uno a Uno 
La  asociación  unidireccional  uno‐a‐uno  es  la  más  inusual  de  todas.  Indica  que  para  cada 
registro  de  una  entidad  existe  solo  uno  asociado  en  la  entidad  referenciada.  Para  establecer 
una relación de este tipo se utiliza el método protegido de ActiveRecord hasOne. 

21.8.7 Muchos a Muchos 
FALTA 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    210 

21.9 API de ActiveRecord

A continuación se presenta una referencia de los principales métodos de la clase ActiveRecord. 

21.9.1 Origen de Datos 
public void setSource($source) 
Permite establecer la entidad del gestor de donde se mapearan los atributos del modelo. 
 
public string getSource() 
Devuelve el nombre de la entidad usada internamente para mapear los atributos del modelo. 
 
public void setSchema(string $schema) 
Establece el nombre del $schema en donde se encuentra la tabla donde se mapearan los datos. 
 
public void setConnection(Db $connection) 
Permite  establecer  un  objeto  Db  dinámicamente  sobrescribiendo  la  conexión  actual  del 
modelo. 
 
public DbBase getConnection() 
Obtiene  el  objeto  Db  utilizado  para  realizar  las  operaciones  a  bajo  nivel  con  el  gestor 
relacional. 

21.9.2 Volcado de Meta­Datos 
public boolean isDumped() 
Indica si ya se han obtenido los meta‐datos del gestor relacional en el objeto. 
 
public void dumpModel() 
Forza al modelo a obtener los meta‐datos del gestor relacional. 
 
protected boolean dump() 
Obtiene los meta‐datos del gestor relacional. Si ya se han obtenido no se vuelven a consultar 
 
public void resetMetaData() 
Elimina los meta‐datos obtenidos del gestor‐relacional cargandolos nuevamente. 

21.9.3 Debug y Seguimiento 
public void setDebug(boolean $debug) 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    211 

Establece  si  el  modelo  esta  en  modo  debug.  Todas  las  operaciones  internas  de  la  conexión 
activa se visualizan como Flash::notices en la salida al navegador. 
 
public void setLogger(mixed $logger) 
Establece el modelo en modo debug. Todas las operaciones internas de la conexión asociada al 
modelo son almacenadas en un archivo con nombre $logger. Si el primer parámetro es true se 
utiliza la convención dbYYYYMMDD.txt 
 
//Grabar todas las operaciones SQL internas a un archivo en
logs/customersDebug.txt
$this->Employees->setLogger(“customersDebug.txt”);
 
También  es  posible  pasar  una  instancia  de  logger  utilizando  cualquier  adaptador  disponible 
utilizando como parámetro el objeto creado: 
 
Ejemplo:  Loguear  las  operaciones  internas  de  un  modelo  a  un  logger  que  usa 
compresión 
$logger = new Logger(‘Compressed’, ‘log.employees.txt.gz’);
$logger->setPath(“/usr/local/log/”);
$this->Employees->setLogger($logger);
 
El desarrollador también puede pasar una instancia de un objeto que implemente un método 
log como parámetro e implementar operaciones personalizadas mediante él. 
 
Ejemplo:  Definir  un  Logger  personalizado  para  hacer  seguimiento  a  las  operaciones 
internas de un modelo 
 
$myLog = new MyUserLog();
$this->Employees->setLogger($myLog);
 
public string inspect() 
Obtiene una cadena de inspección con los valores internos de cada atributo de la entidad. 
 

21.9.4 Transacciones 
public void setTransaction(ActiveRecordTransaction $transaction) 
Establece la transacción utilizada para efectuar las operaciones en el modelo. La transacción 
debe  haberse  inicializado  antes  de  asignarla  al  objeto  ó  generará  una  excepción 
ActiveRecordException. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    212 

21.9.5 Consultar registros 
public ActiveRecordResulset findAllBySql(string $sqlQuery) 
Permite  realizar  una  consulta  en  el  modelo  usando  lenguaje  de  consulta  SQL.  Los  valores 
obtenidos son devueltos como instancias de la clase. 
 
public ActiveRecordResulset findBySql(string $sqlQuery) 
Permite realizar una consulta en el modelo que devuelve un solo registro usando lenguaje de 
consulta SQL. Los valores obtenidos son devueltos como instancias de la clase. 
 
Ejemplo: Realizar una consulta en un modelo usando SQL 
 
//Obtener los empleados con una condición en un subselect
$empoyees = $this->Employees->findBySql(“SELECT employees.* FROM employees WHERE
id NOT IN (SELECT employees_id FROM historical_data WHERE period = ‘2005-02’”);
 
public DbResource sql(string $sqlQuery) 
Permite  realizar  una  consulta  usando  lenguaje  SQL.  El  cursor  de  bajo  nivel  es  devuelto 
directamente. 
 
public ActiveRecord findFirst(mixed $params) 
Permite  realizar  una  búsqueda  de  registros  que  devuelve  un  solo  registro  ó  el  primero  que 
coincida  con  las  condiciones  indicadas.  Los  parámetros  de  consulta  se  establecen  usando 
parámetros por nombre. 
 
Ejemplo: Utilizar findFirst para obtener el primer registro de un modelo ó el primero 
que cumpla determinadas condiciones 
//Obtener el primer empleado que se almacenó en la entidad
$employee = $this->Employees->findFirst();
//Obtener el primer usuario cuyo login sea ‘j.smith’
$user = $this->Users->findFirst(“login = ‘j.smith’”);
//Obtener el ultimo producto cuyo precio sea menor a 100 y este activo
$user = $this->Products->findFirst(“price < 100 AND status = ‘Active’”, “order:
price DESC”);
 
public ActiveRecordResulset find(mixed $params) 
Permite  realizar  una  búsqueda  de  registros  que  devuelve  todos  los  que  coincidan  con  las 
condiciones indicadas. 
 
Ejemplo: Utilizar find para consultar los registros del modelo 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    213 

//Obtener todos los registros de una entidad


$employees = $this->Employees->find();
//Obtener todos los registros que cumplan con una condición
$employees = $this->Employees->find(“status = ‘Active’”);
//Obtener todos los registros que cumplan una condición y aplicándoles un
ordenamiento
$employees = $this->Employees->find(“status = ‘Active’”, “order: name desc”);
//Obtener todos los registros y aplicarles un ordenamiento
$employees = $this->Employees->find(“order: name”);
//Obtener los 20 primeros registros que cumplan con unas condiciones
$employees = $this->Employees->find(“agreement_date >= ‘2008-12-31’ AND
status=’Active’”, “limit: 20”);
 
public ActiveRecordResulset findForUpdate($params) 
Permite  realizar  una  búsqueda  de  registros  que  devuelve  todos  los  que  coincidan  con  las 
condiciones indicadas. Los registros encontrados son bloqueados en modo no compartido por 
lo  que  otras  sesiones  de  aplicación  que  traten  de  leer/escribir  estos  registros  resultaran  en 
una espera. 
 
Ejemplo: Bloquear un conjunto de registros en modo no compartido en una transacción 
<?php
class OrdersController extends ApplicationController {
public function increaseQuantityAction(){
try {
$transaction = new ActiveRecordTransaction(true);
$this->Products->setTransaction($transaction);
foreach($this->Products->findForUpdate(“quantity<100”) as
$product){
$product->setQuantity($product->getMinStock()*2);
if($product->save()==false){
$transaction->rollback();
}
}
}
catch(TransactionFailed $e) {
Flash::error($e->getMessage());
}
}
}
 
public ActiveRecordResulset findWithSharedLock($params) 
Permite  realizar  una  búsqueda  de  registros  que  devuelve  todos  los  que  coincidan  con  las 
condiciones indicadas. Los registros encontrados son bloqueados en modo no compartido por 
lo que otras sesiones de aplicación que traten de escribir en estos registros resultaran en una 
espera por parte del gestor relacional. 
 
public string convertParamsToSql(mixed $params) 
Crea una consulta de SQL mediante los parámetros por nombre indicados. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    214 

 
public array distinct(mixed $params) 
Realiza una sentencia DISTINCT sobre una columna del modelo devolviendo un listado de los 
valores diferentes encontrados. 
 
public boolean exists(string $wherePk) 
 
public ActiveRecordResultset findAllBy(string $field, mixed $value) 
 
public static array singleSelect(string $sql) 
Realiza una consulta SQL sobre el gestor relacional en la tabla ‘dual’ en el caso de Oracle ó solo 
hace la instrucción SELECT sobre ninguna entidad en otros motores. 

21.9.6 Contar registros 
public integer count(mixed $params) 
Devuelve un conteo de registros a partir de las condiciones indicadas.  Los parámetros pueden 
ser establecidos usando parámetros por nombre ó un array cuyos indices indiquen el tipo de 
parámtro  a  establecer.  El  parámetro  especial  group  modifica  el  resultado  obtenido 
agrupandolo mediante otros atributos de la entidad. 
 
Ejemplo: Realizar conteos sobre atributos del modelo 
 
//Cuantos productos hay?
$this->Products->count();
//Cuantos productos tienen categoria 1
$this->Products->count("categories_id = 1");
//Contar productos por categoria
foreach($this->Products->count("group: categories_id") as $result){
print $result->categories_id." ".$result->rowcount;
}
// Contar productos por categoria, mostrar aquellas categorias que tienen mas de
// 10 productos
$resultset =$this->Products->count("group: categories_id", “having:
rowcount>10”);
foreach($resultset as $result){
print $result->categories_id." ".$result->rowcount;
}
 
public mixed countBySql(string $sqlQuery) 
Realiza un conteo en el modelo mediante una sentencia SQL. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    215 

21.9.7 Promediar registros 
public double average($params) 
Devuelve  un  promedio  de  los  valores  de  una  columna  numérica  a  partir  de  las  condiciones 
indicadas. El parámetro especial group modifica el resultado obtenido agrupándolo mediante 
otros atributos de la entidad. 
 
Ejemplo: Realizar promedios sobre atributos del modelo 
 
//En promedio, cual es el precio de un producto
$this->Products->average(“price”);
//En promedio, cual es el precio de un producto activo
$this->Products->average(“price”, “conditions: status=’Active’”);

//Promedio de precios por categoria


$averages = $this->Products->average(“price”, “group: categories_id”);
foreach($averages as $result){
print $result->categories_id." ".$result->average.”\n”;
}

21.9.8 Realizar sumatorias 
public double sum($params) 
Este método permite realizar sumatorias de los atributos de la entidad. El parámetro especial 
group modifica el resultado obtenido agrupandolo mediante otros atributos de la entidad. 
 
Ejemplo: Realizar sumatorias sobre atributos del modelo 
 
//Cuanto suman los impuestos en las ordenes de compra?
$this->Orders->sum(“taxes”);
//Cuanto suman los impuestos del año 2007?
$this->Orders->sum(“taxes”, “conditions: year = ‘2007’”);
//Cuanto suman las cantidades en las ordenes de compra por cada cliente
$summatories = $this->Orders->sum(“quantity”, “group: customers_id”);
foreach($summatories as $result){
print $result->categories_id." ".$result->summatory.”\n”;
}
 
//Cuanto suman las cantidades en las ordenes de compra por cada cliente, cuya
//cantidad sea superior a 100 unidades
$summatories = $this->Orders->sum(“quantity”, “group: customers_id”, “having:
summatory>100”);
foreach($summatories as $result){
print $result->categories_id." ".$result->summatory.”\n”;
}
 

21.9.9 Obtener el valor máximo de un atributo 
public mixed maximum($params) 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    216 

Devuelve un valor máximo de una columna numérica a partir de las condiciones indicadas. El 
parámetro  especial  group  modifica  el  resultado  obtenido  agrupandolo  mediante  otros 
atributos de la entidad. 
 
Ejemplo: Obtener el valor máximo de un atributo de un modelo 
//Quien es el empleado más antiguo?
$this->Employees->maximum(“contract_date”, “conditions: status=’Active’”);

21.9.10 Obtener el valor mínimo de un atributo 
public mixed minimum($params) 
Devuelve un valor mínimo de una columna numérica a partir de las condiciones indicadas. El 
parámetro  especial  group  modifica  el  resultado  obtenido  agrupandolo  mediante  otros 
atributos de la entidad. 
 
Ejemplo: Obtener el valor mínimo de un atributo de un modelo 
//Quien es el empleado más nuevo?
$this->Employees->minimum(“contract_date”, “conditions: status=’Active’”);
 

21.9.11 Asignar valores a instancias  
public ActiveRecord dumpResult(array $result) 
Toma  un  vector  cuyos  indices  coinciden  con  los  nombres  de  los  atributos  del  modelo  y  los 
asigna  devolviendo  un  objeto  copia  de  este  con  los  valores  asignados.  Si  algún  indice  no 
corresponde a un atributo del modelo se genera una excepción. 
 
public void dumpResultSelf(array $result) 
Toma  un  vector  cuyos  indices  coinciden  con  los  nombres  de  los  atributos  del  modelo  y  los 
asigna al mismo objeto. Si algún indice no corresponde a un atributo del modelo se genera una 
excepción. 

21.9.12 Validación 
public array getMessages() 
Obtiene los mensajes de validación generados en un proceso de inserción ó actualización. 
 
public void appendMessage(ActiveRecordMessage $message) 
Agrega un mensaje al buffer de mensajes de validación del modelo. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    217 

21.9.13 Información de atributos 
public array getAttributes() 
Obtiene un vector con los nombres de los atributos de la entidad. 
 
public array getAttributesNames() 
Obtiene  un  vector  con  los  nombres  de  los  atributos  de  la  entidad.  Es  un  alias  de 
getAttributes(). 
 
public boolean hasField($string field) 
Permite consultar si una entidad tiene un determinado campo $field. 
 
public array getPrimaryKeyAttributes() 
Obtiene un vector con los nombres de los atributos de la entidad que son llave primaria. 
 
public array getNonPrimaryKeyAttributes() 
Obtiene un vector con los nombres de los atributos de la entidad que no son llave primaria. 
 
public array getNotNullAttributes() 
Obtiene  un  vector  con  los  nombres  de  los  atributos  de  la  entidad  que  no  aceptan  valores 
nulos. 
 
public array getDatesAtAttributes() 
Obtiene  un  vector  con  los  nombres  de  los  atributos  de  la  entidad  que  auto‐asignan  la  fecha 
actual cuando se realiza una operación de inserción. 
 
public array getDatesInAttributes() 
Obtiene  un  vector  con  los  nombres  de  los  atributos  de  la  entidad  que  auto‐asignan  la  fecha 
actual cuando se realiza una operación de modificación. 
 
public boolean isANumericType(string $field) 
Permite consultar si un atributo en la tabla tiene un tipo de dato númerico (int, integer, float, 
number, bigint, Money, etc). 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    218 

21.9.14 Creación y actualización de registros 
public boolean create(array $values=array()) 
Este método permite la creación de un registro apartir de los valores asignados previamente a 
los atributos del modelo  ó asignando  valores  a  estos  a  través  de  un  array  asociativo pasado 
como parámetro. Debe usarse este método cuando el desarrollador quiera asegurarse que se 
realice una actualización en vez de usar save(). 
 
public boolean update(array $values=array()) 
Este  método  permite  la  actualización  de  un  registro  apartir  de  los  valores  asignados 
previamente  a  los  atributos  del  modelo  ó  asignando  valores  a  estos  a  través  de  un  array 
asociativo pasado como parámetro. Debe usarse este método cuando el desarrollador quiera 
asegurarse que se realice una actualización en vez de usar save(). 
 
public boolean save() 
Este método permite crear/actualizar registros de acuerdo a si estos ya existen en la entidad 
asociada  a  un  modelo.  El  método  save  es  llamado  también  internamente  por  los  métodos 
create y update de ActiveRecord. Para que este método funcione como se espera es necesario 
que se haya definido una llave primaria correctamente en la entidad para poder determinar si 
un registro debe ser actualizado ó creado. 
 
El método save() ejecuta los validadores asociados, llaves primarias virtuales y eventos que se 
hayan definido en el modelo.  El generador de identificadores asociado también es ejecutado y 
al terminar el proceso el objeto se refresca con los valores finales que quedaron en la base de 
datos. 
 
Ejemplo: Crear un registro usando el método save() de ActiveRecord 
<?php
$product = new Products();
$product->setName('Potattos');
$product->setType('Food');
if($product->save()==false){
foreach($product->getMessages() as $message){
Flash::error($message->getMessage());
}
}
 
El ejecutarse save(), este devuelve un valor booleano indicando el éxito de la operación. En el 
ejemplo anterior se obtienen y muestran los mensajes de validación en pantalla cuando save() 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    219 

devuelve false. 

21.9.15 Eliminación de registros 
public boolean delete($params) 
Elimina el registro activo asociado al objeto ActiveRecord.  

21.9.16 Operaciones en Batch 
public boolean updateAll(array $values, string $conditions=””) 
Realiza  una  actualización  en  batch  de  todos  los  campos  de  una  entidad  asegurando  alto 
rendimiento. El parámetro $values permite indicar, mediante un array asociativo, los valores 
a  actualizar,  en  donde  los  indices  son  los  nombres  de  los  campos.  El  parámetro  $conditions 
permite definir las condiciones que se deben cumplir para que el registro sea actualizado. Si 
no se establece un valor para $conditions se actualizarán todos los registros de la entidad. 
 
public boolean deleteAll($conditions=””) 
Realiza una eliminación de registros en batch en una entidad asegurando alto rendimiento. El 
parámetro  $conditions  permite  definir  las  condiciones  que  se  deben  cumplir  para  que  el 
registro  sea  actualizado.  Si  no  se  establece  un  valor  para  $conditions  se  borrarán  todos  los 
registros de la entidad. 
 

21.9.17 Lectura/escritura de Atributos 
public mixed readAttribute(string $attribute) 
Obtiene  el  valor  de  un  atributo  del  modelo  apartir  de  su  nombre.  Este  método  lee  el  valor 
independiente de la visibilidad de la propiedad en la clase. 
 
public mixed writeAttribute(string $attribute, mixed $value) 
Asigna un valor a un atributo del modelo apartir de su nombre. Este método escribe el valor 
independiente de la visibilidad de la propiedad en la clase. 

21.9.18 Validación 
protected void validate(string $validatorClass, array $options) 
Agrega  un  validador  a  un  modelo.  Consulte  el  capítulo  de  validadores  de  integridad  para 
aprender más sobre este método. 
 
public boolean validationHasFailed() 
Este método puede ser usado dentro de un evento de validación para indicar si el proceso de 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    220 

completo  de  validación  ha  fallado.  Consulte  el  capítulo  de  validadores  de  integridad  para 
aprender más sobre este método. 

21.9.19 Multiplicidad de relaciones 
protected void hasOne(mixed $fields, string $referenceTable, mixed $referencedFields) 
Crea una relación 1 a 1 con otra entidad presente en el administrador de entidades. El primer 
parámetro especifica el atributo ó atributos en la entidad local y $referencedFields el atributo 
ó atributos en la tabla referenciada. El parámetro $referenceTable indica la tabla referenciada. 
 
Ejemplo: Establecer relaciones hasOne (1 a 1) de acuerdo al modelo entidad­relacion 
//Relación de un campo a otro por convención
$this->hasOne(“tabla_id”);

//Relación de un campo a otro


$this->hasOne(“campo“, “tabla_referenciada”, “campo_referenciado”);
//Relación de varios campos a varios campos
$this->hasOne(
array(“campo1“, “campo2),
“tabla_referenciada”,
array(“campo_referenciado1”, “campo_referenciado2”)
);
 
protected void belongsTo(mixed $fields, string $referenceTable, mixed $referencedFields, string 
$relationName=’’ ) 
Crea una relación 1 a 1 inversa con otra entidad presente en el administrador de entidades. El 
primer parámetro especifica el atributo ó atributos en la entidad local y $referencedFields el 
atributo  ó  atributos  en  la  tabla  referenciada.  El  parámetro  $referenceTable  indica  la  tabla 
referenciada. 
 
Ejemplo: Establecer relaciones belongsTo (muchos a 1) de acuerdo al modelo entidad­
relacion 
//Relación de un campo a otro por convención
$this->belongsTo(“tabla_id”);
//Relación de un campo a otro
$this->belongsTo(“campo“, “tabla_referenciada”, “campo_referenciado”);
//Relación de varios campos a varios campos
$this->belongsTo(
array(“campo1“, “campo2),
“tabla_referenciada”,
array(“campo_referenciado1”, “campo_referenciado2”)
);
 
protected void hasMany(mixed $fields, string $referenceTable, mixed $referencedFields) 
Crea una relación 1 a n  con otra entidad presente en el administrador de entidades. El primer 
parámetro especifica el atributo ó atributos en la entidad local y $referencedFields el atributo 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    221 

ó atributos en la tabla referenciada. El parámetro $referenceTable indica la tabla referenciada. 
 
Ejemplo:  Establecer  relaciones  hasMany  (1  a  muchos)  de  acuerdo  al  modelo  entidad­
relacion 
//Relación de un campo a otro por convención
$this->hasMany(“tabla_id”);
//Relación de un campo a otro
$this->hasMany(“campo“, “tabla_referenciada”, “campo_referenciado”);
//Relación de varios campos a varios campos
$this->hasMany(
array(“campo1“, “campo2),
“tabla_referenciada”,
array(“campo_referenciado1”, “campo_referenciado2”)
);
 
protected void hasAndBelongsToMany(mixed $fields, string $referenceTable, string $gateTable, 
mixed $referencedFields) 
Crea una relación n a m inversa con otra entidad presente en el administrador de entidades. El 
primer parámetro especifica el atributo ó atributos en la entidad local y $referencedFields el 
atributo  ó  atributos  en  la  tabla  referenciada.  El  parámetro  $referenceTable  indica  la  tabla 
referenciada y $gateTable la tabla puente para acceder a la tabla referenciada. 

21.9.20 Herencia 
public void parentOf(string $parent) 
Establece una relación de herencia que utiliza una estrategía de tabla por subclase mediante 
un discriminador. El parámetro $parent indica la entidad padre. 

21.9.21 Excepciones 
protected void exceptions($e) 
Al  reescribir  este  método  es  posible  tratar  las  excepciones  generadas  dentro  de  un  modelo 
antes que sean lanzadas a otras partes de la aplicación. 

21.10 Identifiers

Las  clases  mapeadas  con  ActiveRecord  que  pretendan  efectuar  operaciones  de  manipulación 
de  datos  deben  declarar  llaves  primarias.  Por  defecto  se  utilizan  estrategias  para  obtener  el 
valor de estas al hacer una inserción.  
 
Los tipos de identificadores soportados son: 
 
Tabla: Tipos de generadores soportados 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    222 

 
Tipo  Descripción 
Increment  Genera identificadores de tipo integer, que son únicos solo 
cuando  otros  procesos  no  generar  operaciones  de 
inserción  concurrentes.  Esta  opción  no  debería  ser  usada 
en clusteres. 
Identity  No  realiza  ninguna  operación  en  especial  ya  que 
aprovecha  una  columna  identidad  presente  en  la  entidad. 
Este  tipo  de  columnas  son  soportadas  por  MySQL,  IBM 
DB2, Microsoft SQL Server, IBM Informix y SQLite. 
Sequence  Obtiene el valor de un objeto del gestor relacional llamado 
secuencias.  Las  secuencias  son  soportadas  por  Oracle, 
PostgreSQL e IBM DB2. 
Hilo  Utiliza un algoritmo tipo hi/lo para eficientemente generar 
los valores únicos de tipo integer. 
UUID  Genera  identificadores  unicos  de  128bits  tipo  string 
basados en el algoritmo UUID (Universal Unique Identifier. 
Assigned   No  aplica  ninguna  estrategía  y  utiliza  el  valor  asignado 
directamente al objeto instancia del modelo. 
Uniqid  Permite obtener identificadores únicos de 128bits usando 
la función de PHP llamada uniqid. 
 

21.10.1 Establecer el Generador 
Para establecer este tipo de identificadores se debe usar el método protegido de ActiveRecord 
llamado  setIdGenerator.  El  primer  parámetro  indica  que  tipo  de  generador  se  usará    y  el 
segundo permite establecer las opciones del generador. 

21.10.2 Algoritmo Hi/Lo 
El generador Hi/Lo permite obtener el valor que deba se utilizado como llave primaria de un 
campo  en  otra  entidad  en  forma  eficiente.    En  una  transacción  al  obtener  el  valor  del 
identicador se efectúa (si se soporta) un bloqueo por fila en el registro para asegurarse que 
ningún otro proceso obtenga el mismo valor. 
 
Ejemplo: Establecer un generador eficiente Hi/Lo en un modelo 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    223 

<?php
class Invoices extends ActiveRecord {
public function initialize(){
$this->setIdGenerator("Hilo", “code”, array(
"table" => "invoces_data",
"column" => "consecutive",
"max_lo" => 100
));
}
}

La opción max_lo indica el valor mínimo que debe tomar el consecutivo. 
 
Tabla: Parámetros del generador Hi/Lo 
Tipo  Descripción 
table   Table donde se encuentra el consecutivo 
columna  Columna que lleva el consecutivo 
source  Es opcional. Permite establecer que la tabla se encuentra en otro schema. 
max_lo  Es  opcional.  Permite  controlar  el  mínimo  valor  que  debe  almacenar  la 
columna. 
number  Es opcional. Indica cuantos consecutivos se deben generar para aumentar la 
eficiencia. 
 
Uno de los objetivos del algoritmo Hi/Lo es aumentar la eficiencia mediante la reducción de la 
lectura/escritura  de  la  tabla  consecutivo.  Esto  solo  es  posible  cuando  la  operación  se 
encuentra en medio de una transacción administrada por el TransactionManager. 

21.10.3 Algoritmo UUID 
El algoritmo UUID genera identificadores únicos que pueden ser usados como llave primaria 
mediante  el  algoritmo  del  mismo  nombre.    El  sistemas  UNIX  utiliza  /dev/urandom  para 
generar el identificador. 
 
Un UUID tiene la siguiente forma:  
 
4cfce7c2-6089-102c-91cf-d8dbbe268425
 
Se establece un generador UUID de esta forma: 
 
Ejemplo: Establecer un generador de identificadores que use el algorimo UUID 
<?php
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    224 

class Media extends ActiveRecord {


public function initialize(){
$this->setIdGenerator("Uuid", “id”);
}
}

21.10.4 Generador UniqId 
El  generador  Uniqid  genera  identificadores  únicos  apartir  de  la  función  Uniqid  de  PHP.  El 
valor generado es un string de 32 caracteres (un número hexadecimal de 128 bits) que es muy 
difícil de repetir. 
 
Ejemplo: Establecer un generador de identificadores que use el algoritmo uniqid 
<?php

class Media extends ActiveRecord {


public function initialize(){
$this->setIdGenerator("Uniqid", “id”);
}
}

21.10.5 Generador Native 
El  generador  “Native”    debe  usarse  en  aquellos  casos  en  los  que  el  valor  de  la  columna 
identidad  son  asignados  por  un  trigger  en  la  tabla  y  que  toma  el  valor  de  una  secuencia.  En 
estos casos ActiveRecord no asignará ningún valor en la sentencia INSERT creada respetando 
el  consecutivo  de  la  secuencia  aunque  si  consultará  su  valor  para  actualizar  el  estado  del 
objeto. 
 
El generador “Native” debe establecerse de la siguiente forma: 
 
Ejemplo: Establecer un generador nativo en un modelo 
<?php
class Orders extends ActiveRecord {
public function sequenceName(){
return “ORDERS_SEQ”;
}
public function initialize(){
$this->setIdGenerator("Native", “id”);
}
}

21.10.6 Columnas Identidad y Secuencias 
Para bases de datos que soporten columnas identidad el generador asigna el valor adecuado 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    225 

para que se genere valor autonumérico en la columna adecuada. En estos casos el generador 
Identity se puede usar con motores como IBM DB2, MySQL y Microsoft SQL Server.  
 
Para  los  motores  que  soportan  secuencias  como  Oracle,  PostgreSQL  e  IBM  DB2  se  debe 
utilizar  el  generador  “Sequence”  ó  “Native”.  El  generador  “Sequence”  se  debe  establecer 
cuando no existan triggers que asignen el valor de la columna en la tabla ya que esto hará que 
se altere el consecutivo innecesariamente. 
 
Ejemplo:  Establecer  un  generador  de  secuencias  para  un  modelo  con  un  gestor 
relacional que lo soporte 
<?php
class Orders extends ActiveRecord {
public function initialize(){
$this->setIdGenerator("Sequence", “id”, array(
“name” => “ORDERS_ID”
));
}
}

El  nombre  de  la  secuencia  también  puede  ser  establecido  mediante  el  método  público 
sequenceName tanto para los modelos con generadores como los que tienen identificador por 
convención: 
 
Ejemplo: Definir el nombre la secuencia del generador de valores identidad 
<?php
class Orders extends ActiveRecord {
public function sequenceName(){
return “ORDERS_ID_SEQ”;
}

public function initialize(){


$this->setIdGenerator("Sequence", “id”);
}
}

21.11 Convenciones en Identificadores

ActiveRecord puede automáticamente establecer el tipo de generador a Identity si en los meta‐
datos  de  la  entidad  encuentra  que  existe  una  columna  identidad.  Igualmente  si  el  campo  se 
llama  explícitamente  ‘id’  igualmente  se  entenderá  la  convención  que  se  trata  de  un  campo 
identidad generado por el gestor relacional ó mediante el generador Increment.  
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    226 

Requisitos para utilizar la convención en identificadores: 
 
• El campo debe llamarse “id” 
• El campo debe tener un tipo de dato enterno (bigint, int, integer, number) 
• El campo debe ser la llave primaria de la tabla 
• El campo debe ser no nulo 

21.12 Los Meta-datos en ActiveRecordMetadata

Gran  parte  de  la  ciencia  en  la  implementación  de  ActiveRecord  esta  relacionada  con  la 
administración  de  los  metadatos  de  las  tablas  mapeadas.  El  almacenamiento  de  sus 
características es punto fundamental para la utilización de los métodos que consultan, borran, 
modifican,  almacenan,  etc.  El  subcomponente  ActiveRecordMetadata  implementa  el  patrón 
Metadata Mapping el cual permite crear un data map por schema sobre la información de las 
tablas y así reducir el consumo de memoria por objeto ActiveRecord y consolidar una base de 
datos in‐memory de las características de cada entidad utilizada en la aplicación. 
 
Normalmente  los  meta‐datos  son  escritos  manualmente  por  el  desarrollador  pero  Kumbia 
Enterprise  los  toma  directamente  del  gestor  relacional,  con  esto  se  gana  eficiencia  en  el 
desarrollo  generando  un  schema  auto‐actualizable  que  refleja  cualquier  cambio  en  la 
estructura del modelo de datos. 

21.12.1 Tipos de Meta­Datos Almacenados 
En  ActiveRecordMetaData  se  almacenan  varios  tipos  de  información  sobre  entidades  que 
pretenden  acelerar  las  operaciones  de  manipulación  y  consulta  de  datos  en  ActiveRecord. 
Estos tipos de datos son: 
 
Tabla: Meta­datos almacenados para una entidad en el ActiveRecordMeta­Data 
Tipo Meta­Dato  Descripción 
Campos de la tabla  Nombres de los campos de las tablas 
Llaves Primarias  Campos que hacen parte de la llave primaria de las 
tablas. 
Campos no llave primaria  Conjunto de campos que no pertenece a la llave 
primaria de las tablas. 
Campos No Nulos  Campos que no permiten valores nulos 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    227 

Tipos de Datos  Tipo de datos de cada campo en una tabla. 
Campos Fecha Auto‐ Campos que por convención asignan automáticamente 
Asignables  la fecha del sistema al actualizar ó modificar. 
 

21.12.2 Meta­Datos en etapas de Desarrollo 
Cuando  las  aplicaciones  se  encuentran  en  etapa  de  desarrollo  es  posible  que  el  los 
desarrolladores encuentren que los cambios en la estructuras de la base de datos no se ven 
reflejados en las aplicaciones. 
 
Esto sucede porque los meta‐datos de las tablas son cacheados temporalmente en sesión para 
evitar que la base de datos sea accedida continuamente disminuyendo el rendimiento. 
 
Para  hacer  que  los  meta‐datos  sean  cargados  nuevamente  es  necesario  cerrar  y  abrir  el 
navegador ó el cliente web y así se verán los cambios del modelo de datos reflejados. 
 

21.12.3 API de ActiveRecordMetaData 
public void static existsMetaData(string $table, string $schema) 
Permite saber si ya se ha definido los meta‐datos para una tabla y esquema en especial. 
 
public void static createMetaData(string $table, string $schema) 
Crea un registro para meta‐datos en el meta‐data store. 
 
public void static setAttributes(string $tableName, string $schemaName, array $attributes) 
Establece los nombres de los campos de una determinada tabla. 
 
public array static getAttributes(string $tableName, string $schemaName) 
Obtiene los nombres de los campos de una determinada tabla. 
 
public  array  static  setPrimaryKeys(string  $tableName,  string  $schemaName,  array 
$primaryKey) 
Establece los campos que son llave primaria a una determinada tabla. 
 
public array static getPrimaryKeys(string $tableName, string $schemaName=””) 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    228 

Obtiene los campos que son llava primaria en una determinada tabla 
 
public  void  static  setNonPrimaryKeys(string  $tableName,  string  $schemaName,  array 
$nonPrimaryKey) 
Establece los campos que no son llave primaria a una determinada tabla. 
 
public array static getNonPrimaryKeys($tableName, $schemaName) 
Obtiene los campos que no son llava primaria en una determinada tabla 
 
public void static setNotNull(string $tableName, string $schemaName, array $notNull) 
Establece los campos que no pueden tener valores nulos. 
 
public array static getNotNull($tableName, $schemaName) 
Obtiene los valores que no son nulos en una tabla. 
 
public void static setDataType(string $tableName, string $schemaName, array $dataType) 
Establece los tipos de datos de una tabla. 
 
public array static getDataTypes(string $tableName, string $schemaName) 
Obtiene los tipos de datos de una determinada tabla. 
 
public void static setDatesAt(string $tableName, string $schemaName, array $datesAt) 
Establece los atributos de la tabla a los cuales se les asigna fecha automática al insertar. 
 
public array static getDatesAt(string $tableName, string $schemaName) 
Obtiene los atributos de la tabla a los cuales se les asigna fecha automática al insertar. 
 
public void static setDatesIn(string $tableName, string $schemaName, array $datesIn) 
Establece los atributos de la tabla a los cuales se les asigna fecha automática al actualizar. 
 
public array static getDatesIn(string $tableName, string $schemaName) 
Obtiene los atributos de la tabla a los cuales se les asigna fecha automática al actualizar. 
 
public void static dumpMetaData(string $table, string $schema, array $metaData) 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    229 

Almacena los meta‐datos para una determinada tabla en el meta‐data store. 

21.13 Cursores y Resulsets de Consultas

Los resultados devueltos por los métodos de consulta de ActiveRecord son objetos instancias 
de la clase ActiveRecordResulset que encapsulan la manipulación y obtención de los registros 
individuales en el cursor enviado por el RBDM. 
 
La  clase  implementa  las  interfaces  Iterator,  ArrayAccess,  SeekableIterator  y  Countable  con  lo 
cuál  el  objeto  se  puede  recorrer  usando  una  sentencia  como  foreach,  acceder  a  indices 
individuales mediante el operador de acceso de vectores y contar el total de registros usando 
funciones como count ó sizeof. 
 
La implementación de este objeto logra una administración de memoria más eficiente ya que 
solo  el  registro  activo  en  el  cursor  consume  memoria  en  el  script  actual  y  se  va  liberando  a 
medida  que  se  recorren  los  registros.  Las  implementaciones  de  ORM  que  devuelven  los 
registros  en  un  array  consumen  mayor  memoria  y  si  la  consulta  devuelve  una  cantidad 
considerable  de  registros  es  probable  que  el  interprete  PHP  aborte  debido  al  consumo 
excesivo de memoria por parte de la aplicación. 

21.13.1 Utilizar el cursor como tipo Forward­Only 
Los  objetos  de  resultado  de  consulta  pueden  ser  recorridos  usando  sentencias  del  lenguaje 
como foreach y while utilizandolos como cursores tipo forward­only. Al terminar de recorrer 
los registros los cursores son auto‐resetados permitiendo volver a recorrerlos. 
 
Ejemplo: Recorrer un cursor tipo forward­only 
//Recorrerlo con Foreach
foreach($this->Products->find() as $product){
print $product->getId()."\n";
}
//Recorrerlo con While
$resultSet = $this->Products->find();
while($resultSet->valid()){
$product = $resultSet->current();
print $product->getId()."\n";
}

21.13.2 Utilizar el cursor como Scrollable 
Los  resultsets  también  pueden  ser  recorridos  en  modo  scrollable  de  esta  forma  se  puede 
acceder a un registro en particular usando un indice para establecer su posición. 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    230 

$resultSet = $this->Products->find();
//Obtener el primer registro
print $resultSet->getFirst()->id."\n";
//Obtener el segundo registro
print $resultSet->offsetGet(1)->id."\n";
//Obtener el último
print $resultSet->getLast()->id."\n";

21.13.3 API de ActiveRecordResulset 
public integer key() 
Obtiene el número del registro que está actualmente activo en el cursor. 
 
public boolean offsetExists(integer $index) 
Permite consultar si existe un registro en una determinada posición. 
 
public void rewind() 
Devuelve el cursor interno del resulset al primer registro. 
 
public boolean valid() 
Indica la posición actual del cursor interno es valida, es decir que aun quedan más registros 
para recorrer. 
 
public void next() 
Mueve el cursor interno al siguiente registro del Resultset. 
 
public void current() 
Devuelve el objeto ActiveRecord activo en el cursor. 
 
public void seek(int $position) 
Mueve  el  cursor  interno  del  resultset  a  la  posición  indicada  por  $position,  esta  debe  ser  un 
número entero mayor a 0. 
 
public integer count() 
Implementa el método que exige la interface Countable el cual permite saber cuantos registros 
ha devuelto el resultset. 
 
public ActiveRecord getFirst() 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    231 

Obtiene el primer registro del cursor. Implicitamente rebobina el puntero al primer registro. 
 
public ActiveRecord getLast() 
Obtiene  el  último  registro  del  cursor.  Implicitamente  mueve  el  puntero  interno  al  último 
registro. 
 
public ActiveRecord offsetGet($index) 
Obtiene el registro ubicado en la posición $index del cursor. Las posiciones empiezan en 0. 
 
public boolean offsetExists($index) 
Permite consultar si existe un registro una determinada posición del cursor. 
 
public  string getSQLQuery() 
Devuelve el SQL que produjo la consulta. 
 
public ActiveRecord getEntity() 
Devuelve la entidad que produjo la consulta. 

21.14 Mensajes de ActiveRecord

ActiveRecord  tiene  un  subsistema  de  mensajes  que  permite  flexibilizar  la  forma  en  que  se 
presentan  ó  almacena  la  salida  de  validación  que  se  genera  en  los  procesos  de  inserción  ó 
actualización. Cada mensaje consta de una instancia de la clase ActiveRecordMessage. El grupo 
de  mensajes  generado  puede  ser  recogido  usando  el  método  getMessages()  del  objeto 
ActiveRecord donde se produjo la operación. 
 
Cada mensaje ofrece información extendida como el nombre del campo que generó el mensaje 
y el tipo de mensaje. 
 
En  el  siguiente  ejemplo  se  ilustra  como  imprimir  los  mensajes  que  resultan  de  un  proceso 
fallido de inserción: 
 
Ejemplo: Obtener los mensajes de validación de un modelo 
<?php
$customer = new Customer();
$customer->setName("Steve Conrad");
$customer->setEmail("s.conrad@mail.com");
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    232 

if($customer->save()==false){
foreach($customer->getMessages() as $message){
Flash::error($message->getMessage());
}
}

21.14.1 API de ActiveRecordMessage 
El API de la clase ActiveRecordMessage es la siguiente: 
 
public void setType(string $type) 
Establece el tipo de mensaje. 
 
public string getType() 
Obtiene el tipo de mensaje. 
 
public void setMessage(string $message) 
Establece el mensaje interno del objeto. 
 
public string getMessage() 
Obtiene el mensaje generado. 
 
public void setField(string $field) 
Establece el nombre del campo de cuyo valor se generó el mensaje. 
 
public string getField() 
Obtiene el nombre del campo que generó el mensaje. 

21.15 Transacciones en ActiveRecord

Las aplicaciones empresariales generalmente administran datos cuyo valor es critico para las 
organizaciones  y  su  manejo  debe  ser  seguro,  estable  y  confiable.  La  integridad  de  datos  se 
pierde  cuando  las  operaciones  son  interrumpidas  y  no  se  completan  satisfactoriamente.  Las 
transacciones  en  el  software  tratan  precisamente  de  evitar  estas  situaciones  buscando  que 
haya integridad en los datos y que se puede recuperar la información si ocurre un estado de 
fallo. 
 
La implementación de Transacciones de Negocio para ActiveRecord esta basada en la idea del 
patrón  del  grupo  Object­Relational  Behavioral  llamado  Unit  of  Work,  aunque  este  sin 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    233 

administrar el log de objetos utilizados. Su funcionamiento básicamente permite separar los 
objetos ActiveRecord que pertenecen a una transacción de tal forma que todas las operaciones 
efectuadas por ellos mantengan un estado de concurrencia consistente y se pueda controlar si 
se altera la base de datos ó se hace rollback en caso que se requiera.  
 
La implementación de transacciones en ActiveRecord tiene 2 ventajas principales: 
 
• Se encapsulan detalles sobre la implementación de transacciones del gestor relacional 
utilizado. 
• Soporta administración de transacciones declarativas. 
• Esta  integrado  con  el  componente  TransactionManager  que  reduce  la  codificación  y 
administra globalmente las transacciones. 
 

21.15.1 Administracion de Transacciones 
La  administración  de  transacciones  puede  ser  utilizada  a  nivel  global  ó  nivel  local, 
independientemente de la forma en que se utilicen su objetivo es primordialmente controlar 
la  concurrencia  a  los  recursos  de  persistencia  de  la  aplicación.  La  gestión  de  transacciones 
depende explícitamente de los requisitos de la aplicación: 
 
• Globales: Las globales son administradas y gestionadas por la aplicación, el bloqueo 
de  recursos  es  dependiente  de  la  naturaleza  de  los  mismos.  Como  el  estado  de 
ejecución  de  una  aplicación  Web  duerme  entre  una  petición  y  otra  es  necesario 
cancelar y/o aceptar las transacciones pendientes cada vez que terminan los hilos de 
ejecución.  Las  transacciones  pueden  ser  compartidas  entre  la  ejecución  de  varias 
acciones  en  un  mismo  hilo.  Kumbia  Enterprise  Framework  permite  establecer 
transacciones  en  forma  automática  para  cualquier  petición  a  la  aplicación  y  cada 
objeto  instanciado,  sin  embargo  esta  implementación  puede  resultar  demasiado 
incondicional para las reglas de negocio de una aplicación. Su mayor ventaja es que las 
operaciones  que  se  realizan  a  nivel  global  pueden  ser  replicadas  a  varios  recursos 
transaccionales. 
 
• Locales:  Permiten  al  desarrollador  establecer  modelos  de  programación  más 
naturales  y  faciles  de  implementar  que  cumplen  detalladamente  con  la  lógica  de 
negocio  de  la  aplicación.  La  principal  desventaja  es  que  tiene  a  invadir  el  modelo  de 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    234 

programación de la aplicación. 
 
El  componente  TransactionManager  administra  la  creación,  cancelación,  destrucción  y 
aceptación de transacciones cuando se implementan en múltiples acciones en un determinado 
flujo  de  ejecución  ó  cuando  se  usan  transacciones  globales.  Este  componente  implementa  la 
interfase  TransactionManagerInterface,  así  el  desarrollador  puede  implementar  un 
componente propio de administración de transacciones implementando esta: 
 
interface TransactionManagerInterface {
public function getUserTransaction($definition=null);
public function commit();
public function rollback();
public function initializeManager();
public function rollbackPendent();
public static function notifyRollback();
public static function notifyCommit();
}
 
El  método  TransactionManager::getUserTransaction()  devuelve  la  última  transacción  ó  crea 
una si es necesario de acuerdo a la definición pasada como argumento. La definición es una 
instancia  de  la  clase  TransactionDefinition.  La  definición  de  la  transacción  establece 
parámetros como el nivel de isolación ó si la transacción es propagable: 
 
Ejemplo: Establecer los parámetros de la transacción con un TransactionDefinition 
<?php
class AccountsController extends ApplicationController {
public function createCustomerDataAction(){
try {
$definition = new TransactionDefinition();
$definition->
setIsolationLevel(TransactionDefinition::ISOLATION_SERIALIZABLE);
$definition->setPropagation(false);
$definition->setReadOnly(false);
$definition->setTimeout(0);
$transaction =
TransactionManager::getUserTransaction($definition);
$customer = new Customer();
$customer->setTransaction($transaction);
$customer->setName("John Smith");
$customer->setStatus("Active");
if($customer->save()){
$this->routeToAction("action: createAccountData");
} else {
$transaction->rollback();
}
}
catch(TransactionFailed $e){
Flash::error($e->getMessage());
}
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    235 

}
public function createCustomerDataAction($clientId){
$clientId = $this->filter($clientId, "int");
try {
$transaction =
TransactionManager::getUserTransaction($definition);
$this->Account->setTransaction($transaction);
$accounts = $this->Account-
>findWithSharedLock("client_id=’$clientId’");
foreach($accounts as $account){
if($account->getStatus()=='Inactive'){
$account->setBalance(0);
$account->setStatus('Active');
if($account->save()==false){
foreach($account->getMessages() as
$message){
Flash::error($message-
>getMessage());
}
$transaction->rollback();
}
}
}
if($transaction->commit()==true){
Flash::success("Se creó correctamente el cliente");
}
}
catch(TransactionFailed $e){
Flash::error($e->getMessage());
}
}
}
 
El ejemplo muestra como se aplica la transacción creada mediante la definición y se reutiliza 
entre las diferentes acciones que conforman la operación de negocio. Una descripción de los 
parámetros que se pueden definir en TransactionDefinition es la siguiente: 
 
• Isolación:  Permite  establecer  el  grado  de  isolación  con  el  que  trabajaran  las 
transacciones. Este se refiere al estándar SQL92  y depende de si esta soportado por el 
gestor relacional. 
• Propagation:  La  propagación  de  transacciones  permite  que  cuando  una  transacción 
sea cancelada se cancelen otras creadas en la misma petición a la aplicación.  
• Read­Only:  Permite  establecer  una  transacción  de  solo  lectura,  cualquier  intento  de 
modificación (inserción, actualización, borrado) de registros termina en la generación 
de una excepción. 
• Timeout: Permite establecer un tiempo en segundos después del cual la transacción 
será  cancelada  automáticamente  si  no  se  ha  realizado  un  commit.  Esto  permite 
controlar ciertos procesos de negocio donde el acceso a los recursos es por demanda. 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    236 

El  método  estático  TransactionManager::getUserTransaction()  devuelve  una  instancia  de  la 


clase  ActiveRecordTransaction  quien  administra  el  acceso  al  Data  Source  de  la  transacción. 
Múltiples  entidades  comparten  un  mismo  DataSource  aunque  esto  sea  transparentemente 
administrado. 

21.15.2 Sincronización de Recursos con Transacciones 
El  desarrollador  debe  tener  cuidado  al  utilizar  transacciones,  ya  que  multiples 
administradores  transaccionales  que  trabajen  sobre  un  mismo  gestor  relacional  podria 
realizar bloqueos sobre recursos necesarios en una misma operación de negocio que termina 
en un deadlock y una excepción. 
 
El  uso  de  TransactionManager  permite  evitar  esto  en  cierta  medida  ya  que  este  controla  la 
creación,  reutilización,  propagación,  cancelación  y  aceptación  de  los  procesos  relacionados 
con transacciones así como otras operaciones. 

21.15.2.1 Sincronización de Alto Nivel 
El  método  de  ActiveRecord::setTransaction()  proporciona  un  método  para  el  objeto  que 
representa un registro comparta una transacción de forma transparente. La sincronización de 
alto nivel permite que varios objetos ActiveRecord compartan un mismo DataSource bajo una 
transacción y todas sus operaciones de bajo nivel son administradas por los componentes del 
framework  lo  cual  aumenta  la  seguridad  y  confiabilidad  que  la  operación  no  se  salga  de 
control y se ejecuten las tareas de finalización de transacciones requeridas. 

21.15.2.2 Sincronización a Bajo Nivel 
La  conexión  al  gestor  relacional  puede  ser  obtenida  de  un  objeto  ActiveRecord  mediante  el 
método  getConnection().  El  objeto  devuelto  es  una  instancia  de  la  clase  Db  que  es  quien 
ejecuta  las  tareas  de  bajo  nivel  directamente  en  el  gestor  relacional.  Los  métodos  begin(), 
rollback() y commit() estan presentes y permiten iniciar y terminar transacciones a bajo nivel. 
 
Ejemplo: Utilizar transacciones a bajo nivel 
$invoice = new Invoice();
$db = $invoice->getConnection();
$db->begin();
$invoice->find(124);
$invoice->setStatus(“Cancelled”);
$invoice->save();
$db->commit();

21.15.3 Consideraciones de Sincronización 
La importancia de la sincronización yace en la necesidad de una correcta implementación del 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    237 

proceso de negocio en donde la disponibilidad de los recursos sea consistente entre los que 
son transaccionales y los que no. 
 
Es  fundamental  entender  que  los  objetos  que  poseen  una  misma  transacción  administran 
ciertos  recursos  y  se  debe  controlar  que  no  vayan  a  ser  utilizados  ó  requeridos  en  otra 
transacción dentro del mismo proceso, si no se controlan estas situaciones es posible que se 
presenten inconsistencias en los procesos de negocio. 
 
En el siguiente proceso se puede comprender la situación presentada: 
 
Ejemplo: Sincronización de recursos en controladores 
<?php
try {
$transaction = new ActiveRecordTransaction(true);
foreach($Accounts->find("status = 'P'") as $accountItem){
$accountItem->setTransaction($transaction);
$accountItem->setStatus("A");
if($accountItem->save()==false){
foreach($accountItem->getMessages() as $message){
Flash::error($message->getMessage());
}
$transaction->rollback();
}
}
foreach($Accounts->find("status = 'A' AND customer_id = '$customerId'") as
$accountItem){
$accountItem->setTransaction($transaction);
$accountItem->setBalance($accountItem->getBalance()-
$manageDiscount);
if($accountItem->save()==false){
foreach($accountItem->getMessages() as $message){
Flash::error($message->getMessage());
}
$transaction->rollback();
}
}
$transaction->commit();
}
catch(TransactionFailed $e){
Flash::error($e->getMessage());
}
 
En  el  primer  foreach  se  consultan  las  cuentas  cuyo  estado  sea  igual  a  ‘P’  y  se  les  cambia  el 
estado  a  ‘A’,  en  el  segundo  foreach  se  consultan  las  cuentas  cuyo  estado  sea  igual  a  ‘A’  y 
pertenezcan a un cliente determinado para luego aplicar un descuento sobre estas cuentas. 
 
El  proceso  espera  que  las  cuentas  recién  actualizadas  en  el  primer  foreach  se  les  haga 
igualmente  el  descuento  del  segundo,  sin  embargo  esto  no  será  así  ya  que  los  resultados 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    238 

devueltos  por  la  transacción  base  pertenecen  a  un  espejo  diferente  al  espejo  de  los  objetos 
administrados por la transacción $transaction. 
 
En resumen, los objetos que se espera que también se les aplique el descuento en el segundo 
foreach quedaran sin este, ya que en el gestor relacional aún no se ha reflejado la actualización 
de estados del primer foreach. 
 
La solución a este inconveniente es seguir las siguientes consideraciones: 
 
• Los  procesos  de  negocio  que  accedan  a  un  mismo  recurso,  en  este  caso  la  entidad 
Account deben asociar todas las instancias a una misma transacción 
• Si  existe  integridad  referencial  en  el  modelo  de  datos  igualmente  es  necesario  que 
todas  las  entidades  relacionadas  y  sus  procesos  estén  administradas  por  una  misma 
transacción. 
 
Si  no  es  necesario  que  se  reflejen  los  cambios  en  el  modelo  de  datos  dentro  de  un  mismo 
proceso de negocio entonces puede hacer caso omiso a estas consideraciones y utilizar tantos 
administradores de transacciones como requiera. 
 
El ejemplo presentado anteriormente sin el inconveniente mencionado se implementaría así: 
 
Ejemplo: Sincronización de recursos en controladores 
<?php
try {
$transaction = new ActiveRecordTransaction(true);
$Accounts->setTransaction($transaction);
foreach($Accounts->find("status = 'P'") as $accountItem){
$accountItem->setStatus("A");
if($accountItem->save()==false){
foreach($accountItem->getMessages() as $message){
Flash::error($message->getMessage());
}
$transaction->rollback();
}
}
foreach($Accounts->find("status = 'A' AND customer_id = '$customerId'") as
$accountItem){
$accountItem->setBalance($accountItem->getBalance()-
$manageDiscount);
if($accountItem->save()==false){
foreach($accountItem->getMessages() as $message){
Flash::error($message->getMessage());
}
$transaction->rollback();
}
}
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    239 

$transaction->commit();
}
catch(TransactionFailed $e){
Flash::error($e->getMessage());
}
 
Cada instancia devuelta por find esta automáticamente asociada a la transacción $transaction 
y se controla que todas las operaciones efectuadas sobre la entidad Accounts se refleje en todo 
el proceso de negocio. 

21.15.4 API de TransactionDefinition 
public void setIsolationLevel(int $isolationLevel) 
Establece  el  nivel  de  Isolación  que  tendrá  la  conexión  asociada  a  la  transacción.  El  valor  del 
parámetro  $isolationLevel  es  una  constante  de  TransactionDefinition  que  puede  ser 
ISOLATION_DEFAULT,  ISOLATION_READ_COMMITED,  ISOLATION_READ_UNCOMMITED, 
ISOLATION_REPETEABLE_READ  y  ISOLATION_SERIALIZABLE.  La  disponibilidad  de  estas 
depende exclusivamente de si esta soportada por el gestor relacional. 
 
public void setPropagation(boolean $propagation) 
Establece un valor booleano que indica si las transacciones creadas al cancelarse cualquiera se 
propagará el estado a las demás del administrador de transacciones. 
 
public void setTimeout(int $timeout) 
Establece el tiempo máximo que pueda durar una transacción antes que sea cancelada.  
 
public void setReadOnly(boolean $readOnly) 
Establece el carácter de solo lectura de la conexión  

21.15.5 API de ActiveRecordTransaction 
public __construct(boolean $autoBegin=false, TransactionDefinition $definition=null) 
Constructor de la definición de la transacción. 
 
public boolean commit() 
Realiza la operación de ‘commit’ sobre la transacción administrada. 
 
public boolean rollback() 
Realiza  la  operación  de  ‘rollback’  sobre  la  transacción  administrada.  Si  la  transacción  es 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    240 

propagable cancelará otras transacciones creadas bajo el mismo TransactionManager. 
 
public boolean begin() 
Permite iniciar la transacción en la conexión activa al gestor relacional. 
 
public DbBase getConnection() 
Obtiene le objeto del adaptador al gestor relacional que administrada la transacción. 
 
public void setIsNewTransaction(boolean $isNew) 
Establece si la transacción ha creado una nueva conexión al gestor relacional ó esta reusando 
una existente. 
 
protected void setPropagation(boolean $propagation) 
Establece  si  la  transacción  esta  en  modo  de  propagación.  La  propagación  solo  funciona  si  la 
transacción fue creada con el TransactionManager. 
 
public bool getPropagation() 
Devuelve  el  estado  de  propagación  de  la  transacción.  La  propagación  solo  funciona  si  la 
transacción fue creada con el TransactionManager. 

21.15.6 Timeouts en Transacciones 
Kumbia Enterprise ofrece un entorno administrado para la implementación de transacciones 
de tal forma que es posible conocer cuando ocurre alguna novedad con una transacción. Los 
timeouts son un ejemplo de esto, cuando un procedimiento no puede obtener un bloqueo para 
efectuar la operación una excepción de tipo DbLockAdquisitionException es generada. 
 
Ejemplo: Capturar una excepción al no poder obtener un bloqueo en una transacción 
<?php
class OrdersController extends ApplicationController {
public function increaseQuantityAction(){
try {
$transaction = new ActiveRecordTransaction(true);
$this->Products->setTransaction($transaction);
foreach($this->Products->findForUpdate(“quantity<100”) as
$product){
$product->setQuantity($product->getMinStock()*2);
if($product->save()==false){
$transaction->rollback();
}
}
}
catch(DbLockAdquisitionException $e){
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    241 

Flash::error(“No se pudo obtener el bloqueo requerido”);


}
catch(TransactionFailed $e){
Flash::error($e->getMessage());
}
}
}

21.16 Validadores de Integridad de Datos

ActiveRecord  permite  que  los  modelos  ejecuten  tareas  de  validación  definidas  por  el 
desarrollador que garanticen que los datos que se almacenen en la persistencia sean íntegros 
y se evite todo lo que esto conlleva. 
 
Los  eventos  del  modelo:  beforeValidation,  beforeValidationOnCreate, 
beforeValidationOnUpdate y validation permiten definir reglas de validación en forma general 
ó de acuerdo a la operación que se vaya a realizar sobre el modelo: 
 
Ejemplo: Definir validadores de integridad de datos en un modelo 
<?php
class Customers extends ActiveRecord {
protected $id;
protected $name;
protected $e_mail;
protected $status;
protected function setId($id){
$this->id = $id;
}
protected function setName($name){
$this->name = $name;
}
protected function setEMail($e_mail){
$this->e_mail = $e_mail;
}
protected function setStatus($status){
$this->status = $status;
}
protected function validation(){
$this->validate("Length", array("field" => "name", "minimum" => 10,
"maximum" => 50));
$this->validate("Email", "e_mail");
$this->validate("InclusionIn", array("field" => "status", “domain”
=> array(“A”, “I”), “required” => false);
if($this->validationHasFailed()==true){
return false;
}
}
}
 
El método protegido de los modelos ActiveRecord::validate() recibe en su primer parámetro el 
validador  con  el  que  se  efectuará  la  validación  y  como  segundo  parámetro  una  lista  de 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    242 

opciones  para  el  mismo.  Algunos  validadores  pueden  recibir  simplemente  el  nombre  del 
campo a validar como segundo parámetro.  El desarrollador puede determinar si la validación 
debe  cancelar  la  acción  que  se  está  ejecutando  sobre  el  modelo  mediante  el  método 
ActiveRecord::validationHasFailed()  el  cuál  indica  si  se  han  generado  mensajes  de  validación 
en  las  clases  validadoras.  El  devolver  false  desde  cualquiera  de  los  eventos  de  validación 
conlleva a la cancelación de la acción actual y a que el método save, create ó update también 
devuelvan false.   
 
El Listado de validadores por defecto que contiene la versión estándar de Kumbia Enterprise 
Framework son los siguientes: 
 
Tabla: Validadores por defecto que hacen parte de ActiveRecord 
Validador  Descripción 
PresenceOf  Es  un  validador  implicito  para  los  modelos  cuyas 
entidades  tengan  atributos  NOT  NULL  y  sean  requeridos 
al insertar ó actualizar. 
DateIn  Valida que el valor de un atributo de la entidad tenga un 
formato de fecha valido. 
Length  Valida que el numero de caracteres  de un el valor de un 
atributo de la entidad tipo String tenga un limite inferior, 
superior ó ambos. 
InclusionIn   Valida  que  el  valor  de  un  atributo  de  la  entidad  se 
encuentre en un listado estático definido en un vector. El 
vector se define usando la opción ‘domain’. 
ExclusionIn  Valida  que  el  valor  de  un  atributo  de  la  entidad  no  se 
encuentre en un listado estático definido en un vector. El 
vector se define usando la opción ‘domain’ 
Numericality  Valida  que  el  valor  de  un  atributo  de  la  entidad  sea 
numérico. 
Format  Valida que el valor de un atributo de la entidad tenga un 
formato  establecido  en  una  expresión  regular,  esta  se 
define usando la opción ‘format’. 
Email  Valida que el valor de un atributo de la entidad tenga un 
formato de e‐mail correcto. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    243 

Uniqueness  Permite  validar  que  el  valor  de  un  atributo  no  exista  en 
otro registro de la entidad. La opción “field” puede recibir 
un  Array  cuando  se  debe  validar  combinaciones  de 
campos.  
 

21.16.1 Validadores para atributos No­Nulos 
Cuando se define un validador, este valida cualquier valor que se vaya a insertar ó actualizar 
sobre la persistencia. Algunas veces el atributo puede permitir nulos, el valor nulo igual será 
validado  por  el  Validador  y  si  no  cumple  con  las  condiciones  establecidas  generará  un 
mensaje y dependiendo de las condiciones podría detener la ejecución de la operación actual.  
 
Una  forma  de  establecer  una  regla  de  excepción  para  estos  casos  es  agregar  la  opción 
‘required’ con valor false al método validate:  
 
Ejemplo: Establecer reglas de validación de integridad de datos en modelos 
protected function validation(){
$this->validate("Numericality", array(“field" => “precio_venta",
“required” => false));
if($this->validationHasFailed()==true){
return false;
}
}

 
Ejemplo: Validar que una combinación de campos no se repita  
protected function validation(){
$this->validate("Uniqueness", array(
“field" => array(“invoice_number", “invoice_preffix”)
);
if($this->validationHasFailed()==true){
return false;
}
}

21.16.2 Tratar el resultado de un proceso de Validación 
Cuando  se  ejecuta  el  método  inteligente  save()  se  ejecutan  los  procesos  de  validación  y  los 
validators  asociados  al  modelo,  normalmente,  el  método  save  devuelve  un  valor  booleano 
indicando  el  éxito  de  la  operación,  cuando  el  valor  devuelto  es  false  es  posible  obtener  los 
mensajes que se han generado y tratarlos adecuadamente para ser presentados al usuario. 
 
Ejemplo:  Obtener  los  mensajes  de  validación  cuando  falla  una  operación  de 
manipulación de datos 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    244 

 
<?php
$customer = new Customer();
$customer->setName("Carl Johnson");
$customer->setEmail("c.johnson@mail.com");
$customer->setContractDate(“2009-02-01”);
if($customer->save()==false){
foreach($customer->getMessages() as $message){
Flash::error($message->getMessage());
}
}
 
Aplicando la API de ActiveRecordMessage es posible personalizar los mensajes de validación y 
la forma en que se tratan. En el siguiente ejemplo se muestra como presentar los mensajes de 
validación de correo electrónico como advertencias y el resto como errores: 
 
Ejemplo: Personalizar la presentación de los mensajes de validación mediante el API de 
ActiveRecordMessage 
<?php
$customer = new Customer();
$customer->setName("Carl Johnson");
$customer->setEmail("c.johnson@mail.com");
$customer->setContractDate(“2009-02-01”);
if($customer->save()==false){
foreach($customer->getMessages() as $message){
if($message->getType()==’Email’){
Flash::warning($message->getMessage());
} else {
Flash::error($message->getMessage());
}
}
}

El campo que genera el mensaje también permite personalizar los mensajes generados: 
 
Ejemplo:  Obtener  información  de  los  mensajes  de  validación  en  un  proceso  de 
manipulación de datos 
<?php
$customer = new Customer();
$customer->setName("Carl Johnson");
$customer->setEmail("c.johnson@mail.com");
$customer->setContractDate($contractDate);
if($customer->save()==false){
foreach($customer->getMessages() as $message){
if($message->getField()==’contractDate’){
Flash::warning(“La fecha de contrato no ha sido
establecida”);
} else {
Flash::error($message->getMessage());
}
}
}
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    245 

21.16.3 Validadores de Usuario 
El desarrollador puede definir validadores de aplicación que extiendan ó se adecuen mejor a 
las  reglas  de  negocio  de  la  aplicación.  Todos  los  validadores  deben  cumplir  con  unos 
requisitos para su integración con ActiveRecord y su correcta ejecución: 
 
• El  Validador  debe  estar  ubicado  en  el  directorio  validators  en  el  directorio  de  la 
aplicación. Si este directorio no existe se debe crear. 
• Los  archivos  donde  se  implementan  las  clases  validadoras  deben  tener  la  siguiente 
convención: NombreValidator.php 
• Los validadores pueden heredar la clase ActiveRecordValidator la cual implementa una 
estructura  consistente  para  el  desarrollo  de  un  validador  eliminando  detalles  poco 
usables. 
• Las clases validadoras deben llamarse usando la convención: NombreValidator 
• Las clases validadoras deben implementar la interface ActiveRecordValidatorInterface. 
 
La interface ActiveRecordValidatorInterface tiene la siguiente estructura: 
 
interface ActiveRecordValidatorInterface {
public function __construct($record, $field, $value, $options = array());
public function checkOptions();
public function getMessages();
public function validate();
}
 
Tanto  el  constructor  como  el  método  getMessages()  se  encuentran  ya  definidos  en  la  clase 
ActiveRecordValidator.  Un  validador  solo  implementa  validate  y  opcionalmente  sobrescribe 
checkOptions. El primero realiza la validación en si y devuelve un valor booleano indicando si 
el proceso fue satisfactorio ó no. El método checkOptions permite chequear si los parámetros 
enviados en las opciones del validador son correctos. 
 
En  el  siguiente  ejemplo  se  implementa  un  validador  que  proporciona  a  la  aplicación  un 
servicio  de  validación  de  números  de  identificación  de  acuerdo  a  las  convenciones  de  algún 
país.  Los  números  de  identificación  deben  ser  de  20  dígitos,  los  3  primeros  deben  ser  las 
letras ABC si es una empresa ó XYZ si es una persona natural. 
 
El archivo validators/IdentificationValidator.php queda así: 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    246 

 
Ejemplo: Crear un validador para integridad de datos en modelos 
<?php
class IdentificationValidator extends ActiveRecordValidator
implements ActiveRecordValidatorInterface {
public function checkOptions(){
if($this->isSetOption('type')==false){
throw new ActiveRecordException("Debe indicar el tipo de
numero de identificaci&oacute;n para IdentificationValidator");
}
if(!in_array($this->getOption('type'), array('any', 'company',
'people'))){
throw new ActiveRecordException("El tipo de numero de
identificaci&oacute;n no es valido, para IdentificationValidator");
}
}
public function validate(){
$number = $this->getValue();
$type = $this->getOption('type');
$valid = true;
if($type=='any'||$type=='company'){
if(substr($number, 0, 3)=='ABZ'){
$valid = false;
}
}
if($type=='any'||$type=='people'){
if(substr($number, 0, 3)!='XYZ'){
$valid = false;
}
}
if(strlen($number)!=20){
$valid = false;
}
if(!$valid){
$this->appendMessage("El valor del campo '{$this-
>getFieldName()}' debe ser una identificaci&oacute;n valida");
return false;
} else {
return true;
}
}
}
 
Para aplicar el validador se invoca el método validate en la implementación de algún evento 
del modelo de tipo ‘validation’: 
 
Ejemplo: Implementar un evento de validación de acuerdo a la operación ejecutada 
protected function beforeValidationOnCreate(){
$this->validate("Identification", array(“field" => “number_iden", “type”
=> “any”));
if($this->validationHasFailed()==true){
return false;
}
}

21.16.4 Eventos en la Validación 
Los  modelos  permiten  la  implementación  de  eventos  que  se  lanza  cuando  se  efectúa  una 
operación de inserción ó actualización y que tienen como objetivo definir lógica de validación 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    247 

e integridad de datos en la aplicación. 
 
A continuación se nombran y explican los eventos soportados así como su orden de ejecución:  
 
Tabla: Tipos de eventos de validación y su orden de ejecución 
Puede 
cancelar 
Operación  Nombre  operación:  Explicación 
Inserción  y  beforeValidation  SI  Se  ejecuta  antes  de 
Actualización  que  se  validen  los 
campos  no  nulos  y  se 
ejecuten  los 
validadores  de 
integridad de datos. 
Inserción  beforeValidationOnCreate  SI  Se  ejecuta  antes  de 
que  se  validen  los 
campos  no  nulos  y  se 
ejecuten  los 
validadores  de 
integridad  de  datos, 
solo  cuando  se  realiza 
una inserción sobre  el 
modelo. 
Actualización  beforeValidationOnUpdate  SI  Se  ejecuta  antes  de 
que  se  validen  los 
campos  no  nulos  y  se 
ejecuten  los 
validadores  de 
integridad  de  datos, 
solo  cuando  se  realiza 
una  actulización  del  
modelo 
Actualización  ó  onValidationFails  SI (ya se ha  Se  ejecuta  después 
Inserción  detenido)  que  un  validador  de 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    248 

integridad falla.   
Inserción  afterValidationOnCreate  SI  Se  ejecuta  después  de 
que  se  validen  los 
campos  no  nulos  y  se 
ejecuten  los 
validadores  de 
integridad  de  datos, 
solo  cuando  se  realiza 
una inserción sobre  el 
modelo. 
Actualización  afterValidationOnUpdate  SI  Se  ejecuta  después  de 
que  se  validen  los 
campos  no  nulos  y  se 
ejecuten  los 
validadores  de 
integridad  de  datos, 
solo  cuando  se  realiza 
una  actulización  del  
modelo 
Inserción  y  afterValidation  SI  Se  ejecuta  después  de 
Actualización  que  se  validen  los 
campos  no  nulos  y  se 
ejecuten  los 
validadores  de 
integridad de datos. 
Inserción  y  beforeSave  SI  Se  ejecuta  antes  de 
Actualización  realizar  la  operación 
requerida  sobre  el 
gestor relacional. 
Actualización  beforeUpdate  SI  Se  ejecuta  antes  de 
realizar  la 
actualización  en  el 
gestor relacional. 
Inserción  beforeCreate  SI  Se  ejecuta  antes  de 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    249 

realizar  la  inserción 


en el gestor relacional. 
Actualización  afterUpdate  NO  Se  ejecuta  después  de 
realizar  la 
actualización  en  el 
gestor relacional. 
Inserción  afterCreate  NO  Se  ejecuta  después  de 
realizar  la  inserción 
en el gestor relacional. 
Inserción  y  afterSave  NO  Se  ejecuta  después  de 
Actualización  realizar  la  operación 
requerida  sobre  el 
gestor relacional. 
Eliminación  beforeDelete  SI  Se  ejecuta  antes  de 
eliminar  el  registro 
del gestor relacional. 
Eliminación  afterDelete  NO  Se  ejecuta  después  de 
eliminar  el  registro 
del gestor relacional. 
 

21.16.5 Implementar un evento de validación 
Cuando  se  ejecuta  una  operación  de  inserción,  actualización  ó  eliminación  sobre  el  modelo 
ActiveRecord verifica si se han definido métodos con los nombres de los eventos y en caso de 
encontrarlos los ejecuta en el orden mencionado en la tabla anterior. 
 
Los eventos de validación deben ser métodos protegidos recomendablemente para evitar que 
la lógica de datos que contienen se exponga públicamente. 
 
En  el  siguiente  ejemplo  se  implementa  un  evento  que  valida  que  la  cantidad  a  actualizar  ó 
insertar sobre el modelo sea mayor a 0 según los requerimientos del negocio: 
 
Ejemplo: Implementar un evento de validación para modelos 
<?php
class Products extends ActiveRecord {
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    250 

protected function beforeSave(){


if($this->quantity<0){
Flash::error("La cantidad no puede ser negativa");
return false;
}
}
}

21.16.6 Detener/Cancelar una operación 
Si dadas las condiciones al ejecutar un evento de validación se requiere detener ó cancelar la 
operación que se esta ejecutando se puede realizar si el evento lo permite y así evitar que se 
almacenen datos incorrectos favoreciendo la integridad del dominio de datos. 
 
En la tabla de eventos de validación es posible verificar si el evento permite la cancelación de 
la  operación.  Un  método  que  requiera  detener  la  operación  debe  devolver  el  valor  boleano 
false, en este caso los métodos save, create y update también devolveran false indicando que 
no se pudo efectuar la operación. 

21.16.7 Establecer un evento con un nombre no estándar 
Los  eventos  de  validación  también  pueden  ser  definidos  usando  atributos  protegidos  en  la 
clase  del  modelo.  De  esta  forma  se  pueden  definir  uno  ó  más  eventos  en  forma  dinámica 
flexibilizando la implementación de estos: 
 
Ejemplo: Cambiar el nombre estándar de un evento en un modelo 
<?php
class Products extends ActiveRecord {
protected $beforeSave = “myCustomEvent”
protected function myCustomEvent(){
if($this->quantity<0){
Flash::error("La cantidad no puede ser negativa");
return false;
}
}
}
 
Si se requiere ejecutar varios métodos para un mismo evento se puede indicar un vector con 
la  lista  de  métodos  en  el  orden  de  ejecución  requerido.  Si  alguno  falla  los  demás  no  serán 
ejecutados. 
 
Ejemplo: Definir múltiples callbacks para un mismo evento de un modelo 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    251 

<?php
class Products extends ActiveRecord {
protected $beforeSave = array(“myFirstEvent”, “mySecondEvent”);
protected function myFirstEvent(){
if($this->quantity<0){
Flash::error("La cantidad no puede ser negativa");
return false;
}
}
protected function mySecondEvent(){
if($this->quantity>100){
Flash::error("La cantidad no puede ser mayor a 100");
return false;
}
}

}
 
Los eventos pueden ser establecidos dinámicamente desde otros eventos ó en el inicializador 
del  modelo.  De  esta  forma  se  pueden  crear  potentes  modelos  de  validación  de  la  lógica  de 
datos en una aplicación: 
 
Ejemplo: Definir eventos del modelo dinámicamente mediante atributos 
<?php
class Products extends ActiveRecord {
protected $beforeSave;
protected function beforeValidation(){
if($this->category==”Food”){
$this->beforeSave = “checkFoodQuantity”;
} else {
$this->beforeSave = “checkOtherQuantity”;
}
}
protected function checkFoodQuantity(){
if($this->quantity>100){
Flash::error("La cantidad de alimentos no puede ser mayor a
100");
return false;
}
}
protected function checkOtherQuantity(){
if($this->quantity>50){
Flash::error("La cantidad no puede ser mayor a 50");
return false;
}
}
}

21.16.8 Evento cuando el proceso de validación detiene la operación 
Las operaciones ejecutadas en el método save pueden fallar si al menos un validador falla en 
este caso develve el valor booleano false indicando este estado. Es posible definir un evento 
llamado  ‘onValidationFails’  que  es  ejecutado  cuando  el  proceso  de  validación  devuelve  un 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    252 

resultado  no  satisfactorio.  En  este  evento  se  puede  definir  elementos  de  logging  ó 
informativos  de  usuario  para  indicar  el  porqué  no  se  ha  podido  realizar  la  operación 
requerida. 
 
Ejemplo:  Definir  un  evento  a  la  espera  de  un  fallo  en  el  proceso  de  validación  de  un 
modelo 
<?php
class Products extends ActiveRecord {
protected function onValidationFails(){
if($this->operationWasCreate()==true){
Flash::error(“La inserción falló”);
}
if($this->operationWasUpdate()==true){
Flash::error(“La actualización falló”);
}
foreach($this->getMessages() as $message()){
Flash::error($message->getMessage());
}
}

21.16.9 Deshabilitar eventos de validación 
Los  eventos  de  validación  pueden  ser  deshabilitados  para  aumentar  el  rendimiento  en 
aplicaciones  que  no  requieren  de  ellos  ó  cuando  se  ejecutan  procesos  de  manipulación  de 
datos que no requieran de esta característica. 
 
El  método  ActiveRecord::disableEvents(bool  $disable)  permite  cambiar  este  comportamiento. 
Un  valor  booleano  true  los  deshabilita  y  un  valor  false  los  habilita  nuevamente.  Esta 
funcionalidad actúa en forma general para cualquier modelo de la aplicación. 

21.17 Llaves Foráneas Virtuales

ActiveRecord permite definir llaves primarias virtuales que validen la integridad relacional en 
las operaciones de manipulación de datos asegurando que los campos llave contengan valores 
que existan en las entidades referenciadas. 
 
Ventajas sobre el control convencional a nivel de base datos: 
 
• Es posible validar integridad relacional sobre columnas con tipos de datos diferentes 
• Se disminuye la carga del motor de base de datos 
• Es  posible  controlar  la  integridad  sobre  tablas  en  diferentes  motores  ó  diferentes 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    253 

servidores 
• Se puede generar mensajes de usuario personalizados de acuerdo al intento fallido de 
efectuar una operación por violación de llave foránea. 
• Se puede validar la integridad  en  motores  que  no  soporten  llaves  foraneas  (MyISAM 
en MySQL). 
• Se  pueden  definir  llaves  foráneas  que  validen  la  integridad  en  objetos  de  la  base  de 
datos como vistas y sinonimos. 
• No se requieren indices en las tablas referenciadas (aunque es recomendado que los 
tengan). 
 
Desventajas de las llaves foráneas virtuales: 
 
• El  rendimiento  no  es  tan  óptimo  como  el  de  las  administradas  directamente  por  el 
motor de base de datos. 
• La  integridad  solo  es  validada  cuando  las  operaciones  se  realizan  mediante  eventos 
realizados a través de los modelos. 

21.17.1 Crear una llave foránea virtual 
El  método  protegido  de  ActiveRecord  llamado  addForeignKey  permite  la  definición  de  llaves 
foráneas virtuales en el inicializador de la clase modelo. 
 
Mediante convenciones se coloca solamente el nombre del campo y de esta forma la tabla y 
campo referenciado se intuye normalmente: 
 
Ejemplo: Definir una llave foránea virtual por convención 
<?php
class Products extends ActiveRecord {
protected function initialize(){
$this->addForeignKey(“categories_id”);
}
}
 
Sino se utiliza un modelo entidad‐relación que use convenciones la forma de indicar las llaves 
foráneas se realiza de esta manera: 
 
Ejemplo: Establecer llaves foráneas de acuerdo al modelo entidad relación 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    254 

<?php
class Employees extends ActiveRecord {
protected function initialize(){
//Un campo a un campo
$this->addForeignKey(“code_cat”, “categories”, “code”);
//Varios campos a varios campos
$this->addForeignKey(
array(“country_born“, “city_born”),
“cities”,
array(“country_code”, “city_code”)
);
}
}

21.17.2 Opciones de las llaves foráneas 
El  cuarto  parámetro  de  addForeignKey  permite  establecer  opciones  adicionales  como  el 
mensaje a generar cuando se viole la integridad y las acciones a realizar cuando se actualiza ó 
borra un registro y falla el proceso de validación. 
 
Ejemplo: Establecer acciones de una llave foránea virtual en un modelo 
<?php
class Employees extends ActiveRecord {
protected function initialize(){
$this->addForeignKey(“office_id”, “office”, “id”, array(
“message” => “La oficina %s no existe”,
“on_delete” => ActiveRecord::ACTION_CASCADE,
“on_update” => ActiveRecord::ACTION_RESTRICT
));
}
}
 
Tabla: Opciones de addForeignKey 
Opción  Descripción 
message  Mensaje  del  validador  cuando  se  viola  la  llave  foránea  y  la 
acción efectuada debe restringir la operación. 
on_delete  Establece una acción a ejecutar cuando una llave foránea es 
violada  al  hacer  una  eliminación  de  datos  en  la  entidad.  El 
valor  es  alguna  de  las  constantes 
ActiveRecord::ACTION_CASCADE  ó 
ActiveRecord::ACTION_RESTRICT. 
on_update  Establece una acción a ejecutar cuando una llave foránea es 
violada al hacer una actualización de datos en la entidad. El 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    255 

valor  es  alguna  de  las  constantes 


ActiveRecord::ACTION_CASCADE  ó 
ActiveRecord::ACTION_RESTRICT. 
 
Tabla: Acciones dependiendo de la operación 
Opción  Descripción 
ActiveRecord::ACTION_CASCADE  Cuando  se  realiza  una  eliminación  de  datos  indica  que 
todas  los  datos  en  llaves  dependientes  deben  ser 
eliminados  antes  de  efectuar  la  operación.  Esto  permite 
que no queden registros huérfanos. En una actualización 
se actualiza el nuevo valor en las relaciones dependientes. 
ActiveRecord::ACTION_RESTRICT  Indica que se debe cancelar la operación actual debido a 
la  violación  de  la  llave  foránea.  El  objeto 
ActiveRecordMessage  es  cargado  con  el  mensaje 
establecido en la opción ‘message’. 
 

21.18 Entidades Temporales

Administrar datos en una entidad  proporciona recursos importantes para las aplicaciones de 
negocios. En ciertas ocasiones se requiere utilizar entidades para almacenar datos temporales 
que permitan la ejecución de procesos de negocio sin que  estas afecten el dominio de datos 
en forma notable. 
 
El  componente  ActiveRecord  proporciona  el  subcomponente  TemporaryActiveRecord  el  cual 
permite  crear  modelos  que  administran  sus  datos  sobre  entidades  temporales  en  el  gestor 
relacional.  
 
Este tipo de entidades pueden ser consideradas de alto rendimiento ya que no requieren de 
escritura de disco además este tipo de modelos están optimizados para un procesamiento más 
efectivo en memoria. 
 
En  estos  casos  la  persistencia  es  temporal  ya  que  todos  los  datos  que  administra  el  modelo 
existen  en  memoria  mientras  la  conexión  al  gestor  relacional  esta  activa.  Como  estas 
conexiones se realizan en modo no‐persistente  los datos en las entidades creadas solo existen 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    256 

durante  el  tiempo  que  emplee  la  petición  en  ejecutarse  por  completo  creándose  y 
destruyéndose cada vez que se utilicen. 

21.18.1 Crear un TemporaryActiveRecord 
Lo siguiente se debe hacer para crear un modelo temporal: 
 
• Se  crea  un  modelo  que  extienda  al  subcomponente  TemporaryActiveRecord  en  el 
directorio de modelos. 
• Se  debe  implementar  un  método  protegido  que  se  debe  llamar  _tableDefinition  es 
requerido para obtener la definición de la entidad, esta constituye un array asociativo 
con las llaves attributes e indexes. 
• La  llave  attributes  es  obligatoria  y  contiene  un  vector  asociativo  cuyas  llaves 
corresponden a los nombres de los campos y cuyo valor es una descripción del campo 
tal y como es aceptada por el método de los adaptadores del componente Db llamado 
createTable. 
• Cuando se definan los atributos del modelo como protegidos se deben definir con los 
mismos nombres utilizados en la definición del método _tableDefinition. 
• Si  no  se  definen  los  atributos  protegidos  ActiveRecord  los  definirá  como  públicos 
aunque esto no es recomendable. 
• Las  entidades  temporales  también  soportan  relaciones  unidireccionales  y 
bidireccionales definiéndose como es usual en los modelos persistentes. 

21.18.2 Comportamiento de un TemporaryActiveRecord 
El  siguiente  comportamiento  debe  tenerse  en  cuenta  cuando  se  trabaja  con  entidades 
temporales: 
 
• Al  instanciarse  por  primera  vez  la  clase  del  modelo  temporal  cuando  el  Facility  es 
USER_LEVEL  se  crea  una  tabla  temporal  en  la  conexión  por  defecto  al  gestor 
relacional. 
• La  tabla  temporal  creada  tiene  el  nombre  de  la  clase  utilizada  las  limitaciones  del 
gestor relacional en cuanto a los nombres de tablas y que otras entidades no existan 
con este nombre deben ser tenidas en cuenta. 
• Las  sentencias  de  creación  de  la  tabla  temporal  no  corresponden  a  manipulación  de 
datos  por  lo  tanto  las  transacciones  globales  y  locales  no  tienen  en  cuenta  esta 
operación. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    257 

• Como la tabla es creada en cada petición en donde se haga uso del modelo los meta‐
datos  de  la  tabla  no  son  almacenados  así  que  no  es  posible  obtener  información  de 
esta usando ActiveRecordMetaData. 
• La  tabla  es  destruida  en  cuanto  se  cierra  la  conexión  con  el  gestor  relacional,  si  es 
requerido destruirla desde la aplicación se puede usar el método del administrador de 
entidades  EntityManager::destroyTemporaryEntity(string  $name)  donde  $name  es  el 
nombre del modelo, este método destruye la tabla temporal en cada conexión al gestor 
relacional donde fue creada. Si una nueva instancia del la clase modelo es invocada ó 
utilizada la tabla temporal se creará nuevamente. 

21.18.3 Transacciones con Entidades Temporales 
Las  operaciones  de  manipulación  de  datos  sobre  las  entidades  temporales  soportan 
transacciones  en  forma  transparente,  aunque  se  debe  tener  en  cuenta  que  no  todos  los 
gestores relacionales soportan transacciones en tablas temporales. 
 
Al  crear  una  transacción  ya  sea  directamente  con  ActiveRecordTransaction  ó  usando 
TransactionManager  se  crea  una  nueva  conexión  temporal  al  gestor  relacional  y  es  posible 
que la tabla temporal esté creada sobre la conexión no‐transaccional por defecto.  
 
Cuando  esto  se  detecta,  ActiveRecord  crea  nuevamente  la  tabla  en  la  conexión  transaccional 
pero es seguro que los datos que ya se hayan almacenado usando los modelos asociados a la 
conexión no transaccional no esten disponibles en la nueva.  

21.18.4 Usar un TemporaryActiveRecord 
En el siguiente ejemplo se ilustra como implementar una entidad temporal y como utilizarlo 
en un proceso de negocio. 
 
El modelo temporal models/product_stadistics.php queda así: 
 
Ejemplo: Crear una entidad temporal 

<?php
class ProductStadistics extends TemporaryActiveRecord {
protected $id;
protected $product_id;
protected $cantidad;
public function getId(){
return $this->id;
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    258 

}
public function getProductId(){
return $this->product_id;
}
public function getCantidad(){
return $this->cantidad;
}
public function setId($id){
$this->id = $id;
}
public function setProductId($product_id){
$this->product_id = $product_id;
}
public function setCantidad($cantidad){
$this->cantidad = $cantidad;
}
protected function _tableDefinition(){
return array(
"attributes" => array(
"id" => array(
"type" => db::TYPE_INTEGER,
"notNull" => true,
"primary" => true,
"auto" => true
),
"product_id" => array(
"type" => db::TYPE_INTEGER,
"notNull" => true
),
"cantidad" => array(
"type" => db::TYPE_VARCHAR,
"notNull" => true,
"size" => 10
)
),
"indexes" => array("product_id")
);
}
protected function initialize(){
$this->belongsTo("product");
}
}

El  modelo  anterior  permite  ingresar  una  serie  de  datos  y  aprovechar  las  capacidades  de 
ordenamiento y agrupamiento para obtener las estadísticas de la venta de unos productos. 
 
Es  necesario  que  las  entidades  relacionadas  al  proceso  de  negocio  esten  asociadas  a  la 
transacción  donde  se  manipulan  los  datos  de  la  entidad  temporal  cuando  se  instancian 
directamente de la clase modelo ó se inyectan en el controlador usando $this. 
 
Ejemplo: Utilizar entidades temporales con transacciones 
try {
$transaction = TransactionManager::getUserTransaction();
$this->Movement->setTransaction($transaction);
$this->Cart->setTransaction($transaction);
$conditions = "sellDate = '".Date::getCurrentDate()."'";
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    259 

foreach($this->Movement->find($conditions) as $movement){
$productStadistic = new ProductStatistics();
$productStadistic->setTransaction($transaction);
$productStadistic->setProductId($movement->getProductId());
$productStadistic->setCantidad($movement->getQuantity());
if($productStadistic->save()==false){
foreach($productStadistic->getMessages() as $message){
Flash::error($message->getMessage());
}
$transaction->rollback();
}
}
$transaction->commit();
$productStadistic = $this->ProductStadistics->findFirst();
print "La cantidad total de productos es: ";
print $productStadistic->sum("cantidad")."<br>";
print "La cantidad minima es: ";
print $productStadistic->minimum("cantidad")."<br>";
print "La cantidad máxima es: ";
print $productStadistic->maximum("cantidad")."<br>";
print "El promedio de cantidad es: ";
print $productStadistic->average("cantidad")."<br>";
}
catch(TransactionFailed $e){
Flash::error($e->getMessage());
}

21.19 ActiveRecordJoin

El  subcomponente  ActiveRecordJoin  permite  aprovechar  las  relaciones  establecidas  en  el 
modelo de datos para generar consultas simples ó con agrupamientos en más de 2 entidades 
relacionadas  ó  no  relacionadas,  proponiendo  una  forma  adicional  de  utilizar  el  Object­
Relational­Mapping (ORM). 
 
El constructor de la clase acepta un vector con las opciones de la consulta. De acuerdo al tipo 
(consulta simple, agrupación de conteo, sumatoria, máximo, mínimo) que se requiera utilizar 
estos varian. 
 
En  el  ejemplo  existen  4  entidades  Products  ProductCategories,  Customers,  Invoices  e 
InvoicesLines: 
 
CREATE TABLE `products_categories` (
`id` int(18) NOT NULL,
`name` varchar(70) default NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `products` (
`id` int(18) NOT NULL,
`name` varchar(100) default NULL,
`products_categories_id` int(11) NOT NULL,
`quantity` int(11) NOT NULL,
`price` decimal(16,2) NOT NULL,
PRIMARY KEY (`id`)
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    260 

);
CREATE TABLE `customers` (
`id` int(18) NOT NULL,
`name` varchar(20) default NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `invoices` (
`id` int(18) NOT NULL,
`customers_id` int(18) NOT NULL,
`sell_date` date NOT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `invoices_lines` (
`id` int(18) NOT NULL,
`invoices_id` int(18) NOT NULL,
`products_id` int(18) NOT NULL,
`quantity` int(11) NOT NULL,
`price` decimal(16,2) NOT NULL,
`taxes` decimal(16,2) NOT NULL,
PRIMARY KEY (`id`)
);

Los modelos de estas entidades son los siguientes, (a propósito se omiten los getters/setters): 
 
Ejemplo: Definición de modelos y sus relaciones para uso con ActiveRecordJoin 
<?php
// Modelo de Categorias de Productos
class ProductsCategories extends ActiveRecord {
public function initialize(){
// Relación 1-n con productos
$this->hasMany("products");
}
}
// Modelo de Productos
class Products extends ActiveRecord {
public function initialize(){
// Relacion 1-1 inversa con categorias de productos
$this->belongsTo("products_categories");
// Relacion 1-n con lineas de facturas
$this->hasMany("invoices_lines");
}
}
// Modelo de Clientes
class Customers extends ActiveRecord {
public function initialize(){
// Relacion 1-n con facturas
$this->hasMany("invoices");
}
}
// Modelo de Facturas
class Invoices extends ActiveRecord {
public function initialize(){
// Relacion 1-1 inversa con clientes
$this->belongsTo("customers");
}
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    261 

}
// Modelo de Detalle de Facturas
class InvoicesLines extends ActiveRecord {
public function initialize(){
// Relacion 1-1 inversa con clientes
$this->belongsTo("invoices");
// Relacion 1-1 inversa con productos
$this->belongsTo("products");
}
}
 
Una  vez  se  definan  las  relaciones  entre  las  entidades  del  dominio  de  datos  es  posible 
utilizarlas tanto para obtener registros simples ó colecciones mediante ActiveRecorJoin: 
 
Ejemplo: Hacer un Join de tres entidades 

//Listar los productos vendidos, su cantidad y la fecha en que se vendieron


$query = new ActiveRecordJoin(array(
"entities" => array("Invoices", "Products", "InvoicesLines"),
"fields" => array(
"{#Products}.name",
"{#Invoices}.sell_date",
"{#InvoicesLines}.quantity"
)
));

Los  resultados  de  la  consulta  pueden  ser  obtenidos  mediante  el  método  getResultSet()  del 
objeto ActiveRecordJoin. El valor de cada columna de la consulta puede ser obtenido usando 
un getter virtual creado implícitamente en cada objeto resultado ó mediante el nombre de la 
columna como una propiedad pública. 
 
Ejemplo: Obtener los registros generados en un Join con ActiveRecordJoin 

//Mediante getters
foreach($query->getResultSet() as $result){
print $result->getName()." ".
$result->getSellDate()." ".
$result->getQuantity()."\n";
}
//Mediante atributos públicos
foreach($query->getResultSet() as $result){
print $result->name." ".$result->sell_date." ".$result->quantity."\n";
}

La  consulta  interna  SQL  SELECT  puede  ser  examinada  mediante  el  método  getSQLQuery() 
ActiveRecordJoin. La consulta anterior genera la siguiente sentencia: 
 
Ejemplo: SQL generado por ActiveRecordJoin 
SELECT products.name, invoices.sell_date, invoices_lines.quantity FROM invoices,
products, invoices_lines WHERE products.id = invoices_lines.products_id AND
invoices.id = invoices_lines.invoices_id ORDER BY 1
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    262 

Notése como las relaciones adecuadas hacen parte de la sentencia SELECT en forma dinámica. 

21.19.1 Agrupamientos con ActiveRecordJoin 
ActiveRecordJoin  permite  crear  consultas  avanzadas  utilizando  agrupamientos.  Los 
agrupamientos  soportados  son:  sumatorias,  conteos,  mínimos,  máximos  y  promedios.  Un 
agrupamiento se establece de la siguiente forma: 
 
Ejemplo: Agrupamientos de datos con ActiveRecordJoin 
//Cuantos productos se han vendido por cada producto
$query = new ActiveRecordJoin(array(
"entities" => array("Invoices", "Products", "InvoicesLines"),
"groupFields" => array("{#Products}.name"),
"sumatory" => array("{#InvoicesLines}.quantity")
));
// Cuantos productos se han vendido por cada producto, cuya cantidad vendida sea
// mayor a 150
$query = new ActiveRecordJoin(array(
"entities" => array("Invoices", "Products", "InvoicesLines"),
"groupFields" => array("{#Products}.name"),
"sumatory" => array("{#InvoicesLines}.quantity"),
"having" => "quantity>10"
));
//En promedio cuál ha sido el precio del producto durante el mes de octubre
$query = new ActiveRecordJoin(array(
"entities" => array("Invoices", "Products", "InvoicesLines"),
"groupFields" => array("{#Products}.name"),
"sumatory" => array("{#InvoicesLines}.price"),
"conditions" => "MONTH({#Invoices}.sell_date) = 10"
));

21.19.2 Parámetros de ActiveRecordJoin 
Los parámetros soportados por ActiveRecordJoin son: 
 
Tabla: Parámetros soportados por ActiveRecordJoin 
Opción  Descripción 
entities  Un vector que indica los modelos utilizados para realizar el 
join. No se debe utilizar el mismo nombre las tablas sino el 
nombre  de  las  clases  usadas  como  modelos  para  acceder  a 
ellas. 
conditions  Un  string  con  condiciones  adicionales  del  join.  No  se  debe 
utilizar los nombres de las tablas en las condiciones sino la 
convención {#NombreClase}. (opcional) 
sumatory  Un  vector  con  los  campos  en  los  cuales  se  debe  aplicar  un 
agrupamiento de sumatoria. (opcional) 
average  Un  vector  con  los  campos  en  los  cuales  se  debe  aplicar  un 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    263 

agrupamiento de promedio. (opcional) 
count  Un  vector  con  los  campos  en  los  cuales  se  debe  aplicar  un 
agrupamiento de conteo. (opcional) 
maximum  Un  vector  con  los  campos  en  los  cuales  se  debe  aplicar  un 
agrupamiento de valor máximo. (opcional) 
minimum  Un  vector  con  los  campos  en  los  cuales  se  debe  aplicar  un 
agrupamiento de valor mínimo. (opcional) 
having  Un string con condiciones para el agrupamiento. (opcional). 
noRelations  Con  el  valor  true  indica  que  no  se  deben  construir 
dinámicamente  las  relaciones  entre  las  entidades  del  join. 
Por defecto su valor es false. (opcional). 
 

21.20 ActiveRecordUnion

El  objetivo  del  subcomponente  ActiveRecordUnion  es  unir  dos  ó  más  objetos 
ActiveRecordResultset ó ActiveRecordRow sin volcar a memoria los resultados producidos por 
ellos consiguiendo una gestión de los recursos de la aplicación más eficiente. 

21.21 SessionRecord

El subcomponente SessionRecord permite administrar entidades de persistencia de sesión de 
forma  natural  como  si  fuesen  entidades  pero  destinadas  a  mantener  registros  de  manera 
independiente  por  id  de  sesión.  El  estado  de  los  objetos  instanciados  es  trasient  ya  que  al 
terminarse la sesión los datos se vuelven inusables. 
 
Por defecto las entidades tipo SessionRecord localizan el campo sid que deben tener un tamaño  
suficiente  para  almacenar  un  valor  de  identificador  de  sesión.  El  valor  de  la  variable  de 
configuración  de  PHP  session.hash_function  establece  el  tipo  de  algoritmo  utilizado  para 
generar  el  identificador  de  sesión,  si  su  valor  es  0  indica  que  se  usa  md5  de  128  bits  (35 
caracteres) y cuando es 1 indica que es sha1 de 160 bits (40  caracteres).  
 
La  siguiente  tabla  contiene  la  estructura  necesaria  para  utilizar  una  entidad  con 
SessionRecord. 
 
CREATE TABLE `cart` (
`id` int(11) NOT NULL auto_increment,
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    264 

`sid` char(35) default NULL,


`product_id` int(11) NOT NULL,
`quantity` int(11) default NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=UTF8;

 
La  definición  de  la  clase  de  un  modelo  de  este  tipo  es  la  normal  pero  en  vez  de  heredar  de 
ActiveRecord  debe  heredar  de  la  clase  SessionRecord.  Las  operaciones  sobre  el  modelo  se 
ejecutan normalmente con la diferencia que los registros grabados y devueltos siempre harán 
referencia a aquellos donde el session_id actual sea el del campo sid de la tabla. 

21.22 PropertyAccessors y Mutators

ActiveRecord accede al valor de los atributos de la tabla al realizar una operación mediante los 
métodos  readAttribute  y  writeAttribute  heredados  en  cualquier  modelo.  El  desarrollador 
puede  sobreescribir  estos  atributos  en  la  definición  del  módelo  y  controlar  la  forma  en  que 
obtienen/establecen internamente los valores de los atributos de la entidad. 
 
Ejemplo: Sobreescribir un PropertyAccessor en un modelo 

<?php
class Products extends ActiveRecord {
protected function readAttribute($attributeName){
if($attributeName==”very_private_field”){
return null;
} else {
return $this->$attributeName;
}
}
}

21.23 DynamicUpdate y DynamicInsert

Un modelo tiene la propiedad de ahorrar trabajo al gestor relacional mediante estas opciones. 
En el primero al realizar una operación de actualización solo los campos que han cambiado en 
la  base  de  datos  son  actualizados,  en  la  segunda  solo  los  campos  que  contienen  valores  no 
nulos se insertan en la operación. 
 
Por  defecto  ambas  propiedades  estan  desactivadas  para  cambiar  su  valor  se  deben  usar  los 
métodos  protegidos  setDynamicUpdate  y  setDynamicInsert  respectivamente.  Al  activarlas  en 
contra  prestación  por  ejemplo  al  actualizar  cada  registro  debe  leerse  antes  de  realizar  la 
operación y compararar cada valor de los atributos con el del objeto actual. 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    265 

Ejemplo: Establecer la creación de sentencias de inserción y actualización solo para los 
atributos del modelo que han cambiando 
 
<?php
class Categories extends ActiveRecord {
protected function initialize(){
$this->setDynamicUpdate(true);
$this->setDynamicInsert(true);
}
}

21.24 Manejo de Excepciones

Las siguientes excepciones son generadas y asociadas a operaciones con ActiveRecord:  
 
Tabla: Excepciones generadas cuando se trabaja con ActiveRecord 
Excepción  Componente  Descripción 
DbException  Db  Excepción  generica  lanzada  por 
adaptador  de  conexión  al  gestor 
relacional utilizado. 
DbLockAdquisitionException  Db  Excepción  lanzada  cuando  la 
transacción  actual  en  la  conexión 
no  puede  efectuar  un  bloqueo 
sobre  algún  recurso  por  ejemplo 
una tabla ó una serie de registros. 
DbSQLGrammarException  Db  Excepción  lanzada  cuando  se 
envia  una  sentencia  SQL  mal 
formada ó con errores de sintaxis. 
DbInvalidFormatException  Db  Excepción  lanzada  cuando  se 
trata  de  asignar  un  valor  con  un 
formato  invalido  al  tipo  de  dato 
de la columna en una una entidad. 
DbContraintViolationException  Db  Excepción  lanzada  cuando  la 
operación  de  modificación  ó 
actualización  viola  un  constraint 
de  llave foránea. 
ActiveRecordException  ActiveRecord  Excepción  generica  de 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    266 

ActiveRecord. 

21.24.1 Capturar excepciones dentro de modelos 
Si  se  requiere  tratar  las  excepciones  generadas  dentro  de  un  modelo  en  específico  se  puede 
sobreescribir  el  método  protegido  exceptions  el  cuál  recibe  las  excepciones  generadas  y  por 
defecto las re‐lanza al controlador ó la vista donde se invocó el modelo. 
 
En el siguiente ejemplo se ilustra como efectuar un procedimiento que trate las excepciones 
por violación de llaves foráneas para un modelo en particular: 
 
Ejemplo: Tratar excepciones por violación de llave foránea 
 
<?php
class Inventory extends ActiveRecord {
protected function exceptions($e){
if($e instanceof DbConstraintViolationException){
//Algún procedimiento
} else {
throw $e;
}
}
}

21.24.2 Información de Excepciones 
Las excepciones generadas por el adaptador al motor de base de datos usualmente permiten 
obtener mayor información sobre el entorno de la excepción agregando datos como el código 
y descripción de bajo nivel generadas por el RTP.  
 
En  el  capítulo  del  componente  Db  se  explica  como  obtener  mayor  información  sobre 
excepciones generadas en la base de datos. 

21.25 Plugins de Modelos

Los Plugins de modelos ó capa de datos permiten extender la funcionalidad del componente 
ActiveRecord  y  sus  subcomponentes.  La  arquitectura  de  plugins  de  ActiveRecord  permite 
observar, extender y manipular el comportamiento de los modelos de la aplicación según las 
condiciones lo exijan. 
 
Los  plugins  permiten  interceptar  eventos  de  los  modelos  de  tal  forma  que  estos  sean 
observables  y  además  ejecutárse  uno  tras  otro  de  manera  centralizada  sin  requerir 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    267 

refactorización ó reintegración en la aplicación. 

21.25.1 Crear un Plugin de ActiveRecord 
Los plugins de ActiveRecord son clases que implementan eventos que son invocados a medida 
que avanza la ejecución del proceso de acceso a la capa de datos en cualquier petición. Estas 
clases deben cumplir con los siguientes requerimientos: 
 
 Deben estar ubicados en el directorio de plugins usualmente apps/app­name/plugins 
 El nombre del archivo que implementa la clase debe ser el nombre del plugin 
 El nombre de la clase debe tener la extensión Plugin 
 Los plugins de controlador deben heredar de la clase ModelPlugin ó ser subclase de ella 
 
Las  clases  pueden  implementar  métodos  públicos  que  referencian  los  eventos  ocurridos  en 
los controladores, la lista de ellos es la siguiente: 
 
Tabla: Eventos que se pueden implementar en plugins de ActiveRecord 
Nombre Evento  Descripción 
afterInitialize  Ocurre  después  de  inicializar  un  modelo.  Normalmente  los 
modelos son inicializados solo una vez en cada petición. 
onException  Ocurre cuando se genera una excepción dentro de un modelo. 
 

21.26 Organización de Modelos

Los archivos de modelos deben estar ubicados en el directorio models/ ó donde la variable de 
configuración modelsDir lo indique. Cuando los modelos se cargan en modo auto‐inicializador 
es posible organizarlos en subdirectorios de tal forma que representen un grupo ó categoría 
lógica al cual pertenezcan. 
 
Un ejemplo de una organización lógica es el siguiente: 
 
Ejemplo: Organización lógica de modelos 
models/
base/
modelBase.php
security/
roles.php
users.php
access_list.php
inventory/
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    268 

references.php
kardex.php
orders.php
movement.php

21.27 Auto-inicialización de Modelos

Los  modelos  pueden  inicializarse  de  2  formas,  automáticamente  ó  dinámicamente.  Por 


defecto los modelos son auto‐inicializados esto significa que en cada petición todas las clases 
del directorio de modelos son leídas y se construyen las relaciones y restricciones definidas 
en ellos.  
 
El usar una forma ó la otra depende del tipo de aplicación que se tenga. Es recomendable usar 
auto‐inicialización cuando: 
 
• El servidor donde está instalada la maquina tiene buenas prestaciones (discos duros 
rápidos, procesadores de última generación, etc).  
• Con relación a las prestaciones del servidor el número de modelos y su complejidad en 
cuanto a relaciones y restricciones es moderado ó bajo. 
• La aplicación requiere frecuentemente del acceso a la mayor parte de los modelos en 
la mayor parte de los procesos de negocio. 
 
Desventajas de la auto‐inicialización: 
 
• Dependiendo de las condiciones, el acceso a disco puede elevarse considerablemente 
en cada petición 
• Si  los  modelos  tienen  muchas  relaciones  y  restricciones  se  podría  aumentar  el 
consumo de memoria innecesariamente 
 
Se recomienda utilizar inicialización dinámica cuando: 
 
• El servidor tiene bajas prestaciones ó una concurrencia elevada 
• La aplicación requiere de modelos en forma selectiva sin que haya un patrón definido 
de acceso a ellos 
• El número de modelos de la aplicación es alto y hay muchas relaciones y restricciones 
entre ellas. 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    269 

 Desventajas de la inicialización dinámica: 
 
• Procesos que requieran varios modelos simultaneamente puede elevar los recursos de 
procesamiento solicitados por la aplicación 
• Solo los modelos inicializados son llevados a las vistas asociadas a la petición 
 

21.27.1 Activar inicialización dinámica 
Para  activar  la  inicialización  dinámica  se  debe  agregar  la  sección  entities  con  la  variable  de 
configuración autoInitialize = Off al archivo de configuración config/config.ini de la aplicación. 
Un archivo de configuración config.ini queda así: 
 
Ejemplo: Definir autonicialización de modelos en la configuración 

[application]
mode = development
name = "Project Name"
interactive = On
dbdate = YYYY-MM-DD
debug = On
[entities]
autoInitialize = Off

 
 
 
 
 
 
 
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    270 

22 Componente EntityManager
22.1 Introducción

El componente EntityManager es usado internamente por el framework y principalmente por 
ActiveRecord  y  Controller  para  administrar  las  entidades,  sus  relaciones  de  asociación, 
relaciones  de  integridad  y  generadores  de  tal  forma  que  el  acceso  a  ellas  sea  consistente  y 
uniforme. 
 
La  clase  EntityManager  es  una  clase  abstracta  en  la  que  sus  métodos  solo  pueden  ser 
invocados estáticamente, de esta forma se asegura que los datos de entidades y sus relaciones 
existan solo una vez por proceso de negocio. 

22.2 Obtener una nueva instancia de un Modelo

Cada vez que se llama el constructor de una clase de ActiveRecord se ejecutan procedimientos 
internos  como  la  inicialización  del  modelo,  tals  como  la  localización  del  data  source,  la 
definición de las relaciones con otros modelos y en algunos casos se trata de volcar los meta‐
datos de la tabla si estos no se encuentran disponibles para la aplicación. 
 
El  componente  EntityManager  proporciona  el  método  getEntityInstance(string 
$instanceName) que permite obtener una instancia de la entidad ya inicializada mejorando el 
rendimiento de un proceso de negocio. 
 
En el siguiente ejemplo se muestra como se reemplaza el instanciamiento mediante new por el 
método de obtener instancias ya inicializadas en blanco: 
 
Ejemplo: Obtener instancias de modelos en forma eficiente 
<?php
try {
$transaction = TransactionManager::getUserTransaction();
$this->Movement->setTransaction($transaction);
$this->Cart->setTransaction($transaction);
$conditions = "sellDate = '".Date::getCurrentDate()."'";
foreach($this->Movement->find($conditions) as $movement){
$productSt = EntityManager::getEntityInstance(“ProductStatistics”);
$productSt->setTransaction($transaction);
$productSt->setProductId($movement->getProductId());
$productSt->setCantidad($movement->getQuantity());
if($productSt->save()==false){
foreach($productSt->getMessages() as $message){
Flash::error($message->getMessage());
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    271 

}
$transaction->rollback();
}
}
$transaction->commit();
}
catch(TransactionFailed $e){
Flash::error($e->getMessage());
}

 
Nota:  Podría  obtener  un  error  como  “Fatal  error:  Cannot  redeclare  class  Products  in 
/path/to/application/instance/apps/default/models/products.php  on  line  230”  si  no 
establece el parámetro de getEntityInstance usando el nombre de la clase modelo tal y como 
fué definida en el archivo del modelo. 

22.3 API del Componente EntityManager

El  desarrollador  no  debería  interactuar  directamente  con  este  componente  ya  que 
ActiveRecord y sus subcomponentes son los encargados de utilizar este API para administrar 
las  relaciones  y  la  información  de  las  entidades.  La  siguiente  API  es  presentada  buscando 
ayudar a extender el core del framework ó reemplazar este componente. 
 

22.3.1 Métodos para inicializar modelos y obtener instancias de ellos 
static function array getEntities()  
Obtiene un vector con todas las entidades inicializadas en la petición actual. 
 
static function void setAutoInitialize(boolean $autoInitialize) 
Establece si los modelos son auto‐inializados ó no. 
  
static function boolean getAutoInitialize()  
Indica si los modelos están siendo auto‐inicializados ó no. 
 
static function void setModelsDirectory(string $modelsDir)  
Establece el directorio desde donde deben ser cargados los modelos. 
 
static function mixed getEntityInstance(string $entityName, boolean $newInstance=true)  
Obtiene una instancia de una clase de un modelo. Si se pasa false en el segundo parámetro se 
obtiene una instancia existente. 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    272 

static function void initModelBase(string $modelsDir)  
Carga la clase ActiveRecord ubicada en el directorio de modelos de la aplicación. 
 
static function void initModels(string $modelsDir)  
Inicializa el directorio de modelos cargandolos e inicializandolos. 
 
static function boolean isEntity(string $entityName)  
Permite consultar si existe un determinado modelo en la petición actual. 
 
static function boolean isModel(string $modelName)  
Es un alias del método isEntity. 
 
static function string getEntityName(string $model)  
Obtiene el nombre de una entidad de acuerdo a su origen de datos (tabla). 
 
static function void addEntityByClass(string $entityClass)  
Inicializa un dinámicamente modelo por el nombre de su clase. 
 

22.3.2 Métodos para administrar relaciones de multiplicidad 
static function boolean existsBelongsTo(string $entityName, string $relationRequested)  
Permite  consultar  si  una  entidad  está  relacionada  con  otra  mediante  una  relación  tipo 
belongsTo (muchos a 1) al menos unidireccionalmente. 
 
static function boolean existsHasMany(string $entityName, string $relationRequested)  
Permite  consultar  si  una  entidad  está  relacionada  con  otra  mediante  una  relación  tipo 
hasMany (1 a muchos) al menos unidireccionalmente. 
 
static function boolean existsHasOne(string $entityName, string $relationRequested)  
Permite consultar si una entidad está relacionada con otra mediante una relación tipo hasOne 
(1 a 1) al menos unidireccionalmente. 
 
static  function  boolean  getBelongsToRecords(string  $entityName,  string  $relationRequested, 
ActiveRecord $record)  
Obtiene  un  resultado  de  los  registros  relacionados  mediante  una  relación  de  multiplicidad 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    273 

belongsTo.    El  parámetro  $record  es  la  instancia  de  un  modelo  utilizada  para  efectuar  la 
operación. 
 
static  function  boolean  getHasOneRecords(string  $entityName,  string  $relationRequested, 
ActiveRecord $record)  
Obtiene  un  resultado  de  los  registros  relacionados  mediante  una  relación  de  multiplicidad 
hasOne.    El  parámetro  $record  es  la  instancia  de  un  modelo  utilizada  para  efectuar  la 
operación. 
 
static  function  boolean  getHasManyRecords(string  $entityName,  string  $relationRequested, 
ActiveRecord $record)  
Obtiene  un  resultado  de  los  registros  relacionados  mediante  una  relación  de  multiplicidad 
hasMany.    El  parámetro  $record  es  la  instancia  de  un  modelo  utilizada  para  efectuar  la 
operación. 
 
static  function  void  addBelongsTo(string  $entityName,  string  $fields='',  string 
$referenceTable='', string $referencedFields='', string $relationName='')  
Agrega una relación belongsTo al administrador de entidades en forma programacional. 
 
static function void addHasMany(string $entityName, mixed $fields='', string $referenceTable='', 
mixed $referencedFields='')  
Agrega una relación belongsTo al administrador de entidades en forma programacional. 
 
static  function  void  addHasOne(string  $entityName,  mixed  $fields='',  string  $referenceTable='', 
mixed $referencedFields='')  
Agrega una relación hasOne al administrador de entidades en forma programacional. 
 
static function void addTrasientAttribute(string $entityName, string $attribute) 
Agrega un atributo de una entidad que no debe ser persistido. 
  
static function array getRelationsOf(string $entityName)  
Obtiene un array con las relaciones que han sido definidas para una determinada entidad. 

22.3.3 Métodos adminitrar para Entidades Temporales 
static function boolean existsTemporaryEntity(string $entityName)  
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    274 

Permite consultar si una entidad temporal ya ha sido definida. 
 
static function void addTemporaryEntity(string $entityName)  
Agrega una entidad temporal al administrador de entidades. 
 
static function void destroyTemporaryEntity(string $entityName)  
Destruye una entidad temporal del administrador de entidades. 
 
static function boolean isCreatedTemporaryEntity(DbBase $connection, string $entityName)  
Consulta si una entidad temporal ya ha sido creada en una determinada conexión. 
 

22.3.4 Origenes de datos 
static function string getSourceName(string $entityName)  
Obtiene el origen de datos (tabla) de una determinada entidad 
 

22.3.5 Administrar generadores de entidades 
static  function  void  setEntityGenerator(string  $entityName,  string  $adapter,  string  $column, 
array $options)  
Establece el generador de una determinada entidad. 
 
static function boolean hasGenerator(string $entityName)  
Indica si una entidad tiene definido algun generador. 
 
static function ActiveRecordGenerator getEntityGenerator(string $entityName)  
Obtiene el generador de una determinada entidad. 
 
static function array getAllCreatedGenerators()  
Obtiene todos los generadores definidos en la petición actual. 
 

22.3.6 LLaves foráneas virtuales 
static  function  void  addForeignKey(string  $entityName,  array  $fields='',  string 
$referenceTable='', array $referencedFields='', array $options=array())  
Establece una llave foránea virtual en una entidad. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    275 

 
static function array getForeignKeys(string $entityName)  
Obtiene las llaves foráneas virtuales definidas para una entidad. 
 
static function boolean hasForeignKeys(string $entityName)  
Permite consultar una entidad tiene llaves foráneas virtuales definidas. 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    276 

23 Componente TransactionManager
23.1 Introducción

El objetivo de este componente es administrar las transacciones globales requeridas por los 
procesos de negocio de una aplicación. Su API es utilizada para acceder a un gestor relacional 
en una unidad de trabajo en particular. Toda la arquitectura de este componente proporciona 
a las aplicaciones desarrolladas en Kumbia Enterprise un contenedor para administración de 
transacciones en PHP como los usados en Java EE. 
 
Es  responsable  de  abrir  y  cerrar  transaciones  manteniendo  unidades  de  trabajo  en  forma 
controlada. Las transacciones pueden ser creadas programacionalmente ó declarativamente.  

23.2 Contexto de Scope Persistente

El  TransactionManager  es  el  puente  para  que  objetos  del  ORM  puedan  interactuar  con  su 
contexto persistente adecuado.  Cada objeto que es ligado a una transacción administrada por 
el contenedor es notificado de otras transacciones activas en el mismo contexto. Los objetos 
mantienen su estado y este es replicado cuando se abre ó cierra la transacción informando el 
estado de la misma. 

23.3 Event Listeners

El  componente  TransactionManager  hace  uso  del  CommonEventInfraestructure  de  Kumbia 


Enterprise  para  notificar  eventos  a  los  objetos  dependientes  de  una  transacción  y  también 
entre ellos mismos. 
 
Los eventos soportados son: 
 
Tabla: Event Listeners de TransactionManager 
Evento  Descripción 
delete  Ocurre  cuando  un  objeto  es  destruido  cuando  se  replica  el  estado  del 
mismo en la persistencia. 
create  Ocurre cuando un objeto es creado. 
update  Ocurre cuando un objeto es actualizado. 
preInsert  Ocurre antes de realizar una inserción de un registro. 
preDelete  Ocurre antes de realizar una eliminación de un registro. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    277 

preLoad  Ocurre al crear un objeto instanciado como resultado de una consulta. 
postInsert  Ocurre después de realizar una inserción. 
postDelete  Ocurre después de realizar una eliminación. 
postUpdate  Ocurre después de realizar una actualización. 

23.4 Estados de las entidades

Las  entidades  pueden  tener  los  siguientes  estados  cuando  intervienen  en  procesos 
transaccionales: 
 
 Estado New: Cuando una entidad es creada mediante el operador new por defecto se 
encuentra ligada a una conexión no transaccional y no representa ningun registro de la base 
de datos. 
 Estado Managed: Cuando una entidad está asociada a una transacción creada por el 
TransactionManager se dice que se encuentra en estado administrado. 
 Estado Detached: Cuando la entidad perteneció a una transacción administrada pero 
la transacción ya fue cerrada ó su contexto fue cambiado a la conexión no transaccional. 
 Estado Removed: Cuando la entidad fue eliminada de la persistencia y por lo tanto no 
puede estar asociada a un contexto transaccional. 

23.5 Asignar el objeto al estado administrado

Los  métodos  de  ActiveRecord  llamados  setTransaction()  y  detachTransaction()  permiten 


cambiar programacionalmente el estado transaccional de un objeto. 
 
Ejemplo: Cambiar un objeto ActiveRecord a un estado administrado 
<?php
$transaction = TransactionManager::getUserTransaction();
$customer = new Customer();
$customer->setTransaction($transaction);
$customer->setName(“John”);
$customer->setSurname(“Smith”);
$customer->save();
$transaction->commit();
$customer->detachTransaction();
 
Cuando  la  transacción  es  cerrada  ya  sea  por  un  rollback  ó  commit  los  objetos  no  son 
automáticamente cambiados al estado detached. Las transacciones cerradas ya no son usables 
pero la unidad de trabajo mantiene su dependencia a la transacción. El desligamiento de los 
objetos  de  la  transacción  puede  realizarse  manualmente  ó  llamar  el  método 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    278 

detachDependencies() de ActiveRecordTransaction. 

23.6 API de TransactionManager

static  function  ActiveRecordTransaction  getUserTransaction(TransactionDefinition 


$definition='')  
Crea  ó  obtiene  una  transacción  ActiveRecordTransaction.  Si  se  define  una  definición  de 
transacción se crea una nueva.  
 
static function void initializeManager() 
Inicializa el administrador de transacciones. El desarrollador no debe invocar este método ya 
que es automáticamente llamado por el contenedor de aplicaciones al iniciar la petición. 
  
static function void rollbackPendent()  
Realiza  un  rollback  sobre  todas  las  transacciones  administradas  por  el  TransactionManager. 
Cuando  ocurre  una  excepción  no  capturada  el  framework  llama  este  método  para  cancelar 
cualquier operación pendiente y así cuidar la integridad de los datos.  
 
static function void commit()  
Realiza un commit sobre todas las transacciones administradas por el TransactionManager. 
 
static function void rollback() 
Realiza un rollback sobre todas las transacciones administradas por el TransactionManager. 
 
static function void notifyRollback(ActiveRecordTransaction $transaction)  
Permite  notificar  a  otras  transacciones  administradas  por  el  TransactionManager  que  una 
transacción realizo un rollback buscando que las demás también lo hagan. 
 
static function void notifyCommit(ActiveRecordTransaction $transaction)  
Permite  notificar  a  otras  transacciones  administradas  por  el  TransactionManager  que  una 
transacción realizo un commit buscando que las demás también lo hagan. 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    279 

Parte 4: La capa de presentación 
 

24 Presentación
24.1 Introducción

La  capa  de  presentación  es  la  tercera  de  la  arquitectura  de  una  aplicación  Web  y  permite 
definir  interfaces  y  métodos  para  interactuar  con  el  usuario  final  así  como  presentarle 
información al mismo. 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    280 

25 Componente View
25.1 Introducción

El  componente  View  se  encarga  de  administrar  la  forma  estándar  en  la  que  se  genera  la 
presentación al usuario final en su explorador.  
 
La presentación estándar en una aplicación en Kumbia Enterprise se basa en varios patrones 
de  diseño  que  permiten  reducir  la  codificación  y  hacer  más  mantenible  esta  parte  del 
desarrollo. 
 
El  primer  patrón  utilizado  es  Template  View  el  cuál  habla  de  utilizar  tags  personalizados  ó 
marcas embebidas en el contenido dinámico proporcionando flexibilidad y poder para crear 
interfaces web. 
 
El segundo patrón es el Two State View el cual permite definir múltiples interfaces de acuerdo 
al  dispositivo  ó  cliente  desde  el  cuál  se  este  se  accediendo  a  la  aplicación.  Este  tipo  de 
implementación  favorece  principalmente  aplicaciones  que  accedan  desde  un  browser  ó  un 
dispositivo móvil como un telefono celular, en donde es necesario personalizar detalles para 
cada tipo de interfaz. 
 
La arquitectura MVC presenta el concepto de vista la cuál actúa como puente entre el usuario 
final y la lógica de dominio en los controladores. 

25.2 Jerarquía de vistas en la presentación

Una jerarquía de archivos con vistas imbebibles soportadas por el componente View permite 
reducir  la  codificación  creando  puntos  de  presentación  comunes  para  la  aplicación, 
controladores ó mediante la implementación de plantillas. 
 
Cada parte de la presentación se crea en un archivo ubicado en una estructura convenida de 
directorios en el directorio de la aplicación llamado views/.  
 
El  componente  View  permite  definir  la  presentación  en  varios  niveles,  cada  uno  contiene  al 
siguiente: 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    281 

Tabla: Niveles de presentación en el componente View 
Archivo ó Ubicación  Descripción 
index.phtml  Contiene  la  vista  principal  y  encabezado 
XHTML de todas las vistas. 
directorio‐con‐nombre‐del‐controlador  Permite  establecer  archivos  con  vistas  para 
cada acción del controlador. 
directorio‐con‐nombre‐del‐ Permite crear una presentación para la acción 
controlador/archivo‐con‐nombre‐de‐la‐ activa en el controlador. 
acción.phtml 
layouts/archivo‐con‐nombre‐del‐ Permite  establecer  una  vista  común  para 
controlador.phtml  todas las acciones del controlador. 
layouts/nombre‐template.phtml  Permite  establecer  una  plantilla  común  para 
varios controladores. 
directorio‐con‐nombre‐del‐ Permite  establecer  vistas  parciales  que  se 
controlador/_nombre‐vista‐parcial.phtml  pueden  incluir  en  varias  vistas  de  acciones 
del controlador activo. 
partials/_nombre‐vista‐parcial.phtml  Permite  establecer  vistas  parciales  que  se 
pueden  incluir  en  cualquier  vista  ó  template 
de la aplicación. 
  
El  componente  View  no  requiere  que  exista  cada  componente  de  presentación  que  se 
mencionó anteriormente, el único requerido es la vista principal. 

25.2.1 Vista Principal 
En  el  directorio  views/  se  puede  encontrar  el  archivo  index.phtml  que  implementa  el 
encabezado XHTML estándar para cualquier vista de la aplicación: 
 
Ejemplo: Vista principal views/index.phtml por defecto 
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv='Content-type' content='text/html; charset=UTF-8' />
<title>Application Title</title>
<?php Tag::stylesheetLink('style', true) ?>
<?php echo Core::stylesheetLinkTags() ?>
<?php echo Core::javascriptBase() ?>
</head>
<body>
<?php echo View::getContent(); ?>
</body>
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    282 

</html>
 
Por  defecto  se  utiliza  un  encabezado  XHTML  1.0  Strict  el  cuál  propende  por  aplicaciones 
basadas en estándares y que funcionan mejor en los navegadores más avanzados del mercado. 
 
Los  helpers  Core::stylesheetLinkTags()  y  Core::javascriptBase()  incluyen  archivos  JavaScript 
como frameworks y utilidades además de los CSS incrustados en otras vistas activas. 
 
El XHTML generado por la vista anterior es: 
 
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv='Content-type' content='text/html; charset=UTF-8' />
<title>Application Title</title>
<link rel='stylesheet' type='text/css' href='/app-
path/css.php?c=style&p=/app-path' />
<script type='text/javascript' src='/app-
path/javascript/scriptaculous/protoculous.js'></script>
<script type='text/javascript' src='/hfos/javascript/core/base.js'></script>
<script type='text/javascript' src='/app-
path/javascript/core/validations.js'></script>
<script type='text/javascript' src='/app-path/javascript/core/main.php?app=
&module=&path=%2Finstance-name%2F&controller=login&action=index&id='></script>
</head>
<body>
</body>
</html>
 
Notese el llamado a View::getContent(), este imprime todo el contenido generado en el layout 
ó vistas activas en la aplicación en el lugar que se indique. 

25.2.2 Requerimientos de la Vista Principal 
Es recomendable no eliminar los llamados a los helpers estándar en la vista principal ya que 
esto  puede  impactar  el  comportamiento  del  framework.  En  general  los  requerimientos  del 
contenido de la vista principal son los siguientes: 
 
• Su nombre debe ser index.phtml y mantenerse en la raíz de views/ 
• Incluir los archivos JavaScript que se utilicen en cada petición a la aplicación 
• Incluir los archivos CSS que se utilicen en cada petición a la aplicación 
• Incluir codigo XHTML que sea común a cada controlador y acción de la aplicación 

25.2.3 Requerimientos Vistas a nivel de Controlador 
Generalmente cada acción solicitada presenta ó solicita información diferente al usuario de tal 
forma que el flujo de la aplicación sea consistente tanto para el desarrollador como para los 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    283 

usuarios. Los requerimientos de las vistas a nivel de controlador son: 
 
• Es  necesario  que  exista  un  directorio  con  el  nombre  del  controlador  donde  se 
encuentre la acción 
• El nombre del directorio debe ir en minúsculas y sin el sufijo “Controller”. 
• El archivo de la vista debe tener la extensión .phtml y el nombre debe ser el nombre de 
la acción sin el sufijo “Action”. 
 

25.2.4 Requerimientos de Layouts de Controladores 
Los layouts de controladores son vistas que contienen fragmentos comunes de presentación 
que  son  validos  para  cualquier  acción  del  controlador.  Los  requerimientos  de  los  layouts  de 
controladores son: 
• Un archivo con el nombre del controlador en el directorio views/layouts debe existir. 
• El nombre del archivo debe ir en minúsculas y sin el sufijo “Controller”. 
• El archivo debe tener extensión .phtml. 
 

25.2.5 Requerimientos de Vistas Parciales en Controladores 
En ocasiones fragmentos de presentación como menús, encabezados, pie de paginas, etc son 
comunes  a  varias  acciones  de  un  controlador  pero  no  a  todas,  en  estos  casos  se  puede 
implementar vistas parciales. Los requerimientos de las vistas parciales en controladores son: 
 
• Es  necesario  que  exista  un  directorio  con  el  nombre  del  controlador  donde  se 
encuentre la vista parcial. 
• El nombre del directorio debe ir en minúsculas y sin el sufijo “Controller”. 
• El  archivo  de  la  vista  parcial  debe  tener  la  extensión  .phtml  y  el  prefijo  “_” 
(underscore). 
 

25.2.6 Requerimientos de Vistas Parciales Generales 
Al igual que las vistas parciales de controladores las generales realizan la misma tarea con la 
diferencia que estan disponibles para cualquier layout, template ó vista de la aplicación. 
 
Los requerimientos de las vistas parciales generales son: 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    284 

• La vista parcial debe estar ubicada en el directorio views/partials. 
• El  archivo  de  la  vista  parcial  debe  tener  la  extensión  .phtml  y  el  prefijo  “_” 
(underscore). 
 

25.2.7 Requerimientos de Plantillas ó Templates 
Las plantillas permiten establecer múltiples fragmentos de presentación y aplicarsen antes ó 
después del layout del controlador. Los requerimientos de las plantallas son: 
• Deben entas ubicados en el directorio views/layouts/. 
• La extensión del archivo debe ser “.phtml” 

25.3 Inserción automática y manual de vistas

El  componente  View  utiliza  convenciones  para  insertar  automáticamente  la  presentación 
correspondiente a un controlador ó una acción, otros componentes de presentación requiere 
que se establezca programacionalmente su relación con la presentación diseñada. 
 
Si se realiza una petición a la aplicación mediante la URL: 
 
http://172.16.5.2/company/categories/create 
 
En  donde  company  es  el  nombre  de  la  instancia  del  framework,  categories  es  el  nombre  del 
controlador y create la acción requerida. 
 
Gracias  a  la  presentación  por  convención  el  componente  View  tratará    de  crear  la 
presentación a partir de los archivos: 
 
• default/views/categories/create.phtml 
• default/views/layouts/categories.phtml 
• default/views/index.phtml 
 
Si  alguno  de  los  archivos  mencionados  no  existe  se  trata  de  ubicar  el  siguiente  y  así 
sucesivamente. 
 
En este segundo caso la URL solicitada es: 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    285 

http://172.16.5.2/company/press/categories/ 
 
En  donde  company  es  el  nombre  de  la  instancia  del  framework,  press  es  el  nombre  de  la 
aplicación  y  categories  es  el  nombre  del  controlador.  El  nombre  de  la  acción  no  se  ha 
establecido por lo que se asume que es index. 
 
Los archivos de presentación son los siguientes: 
 
• press/views/categories/index.phtml 
• press/views/layouts/categories.phtml 
• default/views/index.phtml 

25.4 Implementar los tipos de vistas

En el siguiente ejemplo se ilustra los tipos de vistas y su integración en la presentación de una 
aplicación. El controlador customers se inicializa con 3 templates: 
 
Ejemplo: Aplicar multiples templates a un mismo controlador 
<?php
class CustomersController extends ApplicationController {
public function initialize(){
$this->setTemplateBefore("template1");
$this->setTemplateAfter(array("template2", "template3"));
}
public function createAction(){
}

public function updateAction(){


}
}
 
Los  métodos  del  controlador  setTemplate  y  setTemplateAfter  permiten  insertar  plantillas 
antes  y  después  del  layout  del  controlador.  Los  templates  como  se  mencionó  deben  estar 
ubicados en views/layouts.   
 
El archivo de plantilla views/layouts/template1.phtml tiene: 
 
<div style='background:yellow;padding:10px'>
<h2>Template 1</h2>
<?php View::getContent(); ?>
</div>
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    286 

El  llamado  a  View::getContent()  indica  donde  se  debe  incrustar  el  contenido  de  otras  vistas 
contenidas por el fragmento de presentación. 
 
El archivo de plantilla views/layouts/template2.phtml tiene: 
 
<div style='background:#faca22;padding:10px'>
<h2>Template 2</h2>
<?php View::getContent(); ?>
</div>
 
El archivo de plantilla views/layouts/template3.phtml tiene: 
<div style='background:#ccccf2;padding:10px'>
<h2>Template 3</h2>
<?php View::getContent(); ?>
</div>

 
El archivo de layout del controlador views/layout/customers.phtml tiene: 
 

<?php View::renderPartial('header') ?>


<div style='background:orange;padding:10px'>
<h2>Layout de Customers</h2>
<?php View::getContent(); ?>
</div>
<?php View::renderPartial('footer') ?>

 
El  método  View::renderPartial  inserta  una  vista  parcial  que  esta  ubicada  en  el  mismo 
directorio de controlador views/customers/. Notése que el prefijo “_” de las vistas parciales es 
omitido a propósito al establecer el nombre de esta. 
 
La vista parcial views/customers/_header.phtml tiene: 
<h4>Este es el encabezado</h4>
 
La vista parcial views/customers/_footer.phtml tiene: 
<h4>Este es el pie de página</h4>
 
La vista de la acción create en el archivo views/customers/_create.phtml  tiene: 
<div style='background:#eac2ff;padding:10px'>
<h3>Acción Create</h3>
<?php View::getContent(); ?>
</div>

La vista de la acción update en el archivo views/customers/_update.phtml  tiene: 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    287 

<div style='background:#cceaff;padding:10px'>
<h3>Acción Update</h3>
<?php View::getContent(); ?>
</div>

El resultado obtenido en el explorador al invocar la acción create es: 
 

 
 
El resultado obtenido al invocar la acción update en customers es: 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    288 

 
 
Como  se  mostró  todos  los  tipos  de  fragmentos  de  presentación  proporcionan  una  poderosa 
forma de compartir el código y construir interfaces flexibles siguiendo un principio básico de 
mantenibilidad de una aplicación. 

25.5 Transferir valores del controlador a la vista

Existen 2 formas de transferir datos del controlador a la presentación: 

25.5.1 Transferir mediante atributos públicos 
Si al procesar una acción en un controlador se requiere presentar información al cliente final 
esta debe ser transferida a las vistas asociadas para su posterior tratamiento. Por defecto los 
atributos  públicos  de  los  controladores  son  transferidos  automáticamente  a  la  presentación 
en forma de variables locales. 
 
El siguiente controlador tiene 2 atributos públicos que se visualizan al invocar la acción info: 
 
Ejemplo: Utilizar atributos públicos para transferir valores a la presentación 
<?php
class PressController extends ApplicationController {
public $code;
public $name;
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    289 

public function indexAction(){


}
public function infoAction(){
$this->code = 100;
$this->name = “Este es un nombre”;
}
}
 
Todas las vistas asociadas a la petición tienen acceso a las variables locales $code y $name que 
pueden ser usadas a conveniencia: 
 
El archivo views/layouts/press.phtml tiene: 
<h1>El código es <?php echo $code ?></h1>
 
El archivo views/press/info.phtml tiene: 
<p>El contenido de “name” es <?php echo $name ?></p>
 
Lo que en conjunto produce en el explorador: 
 

 
 

25.5.2 Transferir mediante setParamToView 
La segunda forma de transferir valores desde las acciones del controlador es mediante el uso 
del método setParamToView. Este método es especialmente útil cuando se requiera transferir 
grandes cantidades de datos a las vistas ó datos poco relevantes que no ameriten la definición 
de un atributo público en el controlador. 
 
También si se usan controladores con el estado persistente activo es posible que también se 
quiera restringir la definición de atributos públicos a los estrictamente necesarios. 
 
Ejemplo: Transferir datos a la presentación mediante setParamToView 
<?php
class PressController extends ApplicationController {
public function indexAction(){
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    290 

}
public function showAllAction(){
$this->setParamToView(“editions”, $this->Editions-
>find(“status=’A’”));
}
}
 
En la vista se crea una variable local llamada $editions con el valor asignado en la acción. 

25.6 Controlar Niveles de Renderización

En determinadas situaciones es posible que se requiera controlar el nivel de profundidad de la 
visualización.  El  componente  View  permite  establecer  el  nivel  de  renderización  mediante  el 
método setRenderLevel(int $level). 
 
Esté  método  puede  ser  invocado  desde  el  controlador  ó  desde  una  capa  de  visualización 
superior para evitar que otras sean presentadas. 
 
Tabla: Niveles de renderización en View 
Valor  Constante  Descripción 
0  LEVEL_NO_RENDER  Indica  que  se  debe  evitar  generar 
cualquier tipo de presentación. 
1  LEVEL_ACTION_VIEW  Genera  la  presentación  hasta  la  vista 
asociada a la acción. 
2  LEVEL_BEFORE_TEMPLATE  Genera  la  presentación  hasta  las 
plantillas  antes  de  el  layout  del 
controlador. 
3  LEVEL_LAYOUT  Genera  la  presentación  hasta  el  layout 
del controlador. 
4  LEVEL_AFTER_TEMPLATE  Genera  la  presentación  hasta  las 
plantillas  después  de  el  layout  del 
controlador. 
5  LEVEL_MAIN_VIEW  Genera  la  presentación  hasta  la  vista 
principal. Archivo views/index.phtml 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    291 

25.7 Utilizar modelos en la presentación

Los  modelos  de  la  aplicación  siempre  están  disponibles  en  la  presentación.  Si  la  opción  de 
autoinicialización de modelos está activa se creará una referencia de todos los modelos de la 
aplicación  como  variables  globales  con  el  nombre  del  modelo,  si  no  está  activa  solo  los 
modelos utilizados en la petición actual serán llevados a la presentación. 
 
Dependiendo  del  caso  se  puede  usar  en  forma  natural  dentro  de  cualquier  tipo  de  vista  los 
modelos de esta forma: 
 
Ejemplo: Utilizar modelos en la presentación cuando son auto­inicializados 
//Listar las ordenes de compra
foreach($Orders->find() as $order){
print $order->getRecordedDate();
}
 
Si  los  modelos  no  son  auto‐inicializados  se  puede  obtener  una  instancia  de  ellos  usando  el 
método de EntityManager llamado getEntityInstance: 
 
Ejemplo: Usar modelos en la presentación cuando no son auto­inicializados 
$orders = EntityManager::getEntityInstance(‘Orders’);
foreach($Orders->find() as $order){
print $order->getRecordedDate();
}

25.8 Plugins de View

Los  Plugins  de  presentación  permiten  extender  la  funcionalidad  del  componente  View.  La 
arquitectura de plugins de View permite observar, extender y manipular el comportamiento 
de las vistas de la aplicación según las condiciones lo exijan. 
 
Los plugins permiten interceptar eventos en las vistas de tal forma que estos sean observables 
y  además  ejecutárse  uno  tras  otro  de  manera  centralizada  sin  requerir  refactorización  ó 
reintegración en la aplicación. 

25.8.1 Crear un Plugin de View 
Los  plugins  de  View  son  clases  que  implementan  eventos  que  son  invocados  a  medida  que 
avanza  la  ejecución  del  proceso  de  presentación  en  cualquier  petición.  Estas  clases  deben 
cumplir con los siguientes requerimientos: 
 
 Deben estar ubicados en el directorio de plugins usualmente apps/app­name/plugins 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    292 

 El nombre del archivo que implementa la clase debe ser el nombre del plugin 
 El nombre de la clase debe tener la extensión Plugin 
 Los plugins de controlador deben heredar de la clase ViewPlugin ó ser subclase de ella 
 
Las  clases  pueden  implementar  métodos  públicos  que  referencian  los  eventos  ocurridos  en 
los controladores, la lista de ellos es la siguiente: 
 
Tabla: Eventos que se pueden implementar en plugins de View 
Nombre Evento  Descripción 
beforeRender  Ocurre  antes  de  empezar  el  proceso  de  visualización  de  las 
vistas  asociadas  a  la  petición.  El  evento  recibe  la  instancia  de 
ControllerResponse actual 
afterRender  Ocurre  después  de  terminar  el  proceso  de  visualización  de  las 
vistas asociadas a la presentación. 
 

25.9 API del Componente View

25.9.1 Jerarquia de renderización 
static function string getContent(boolean $returnContent=false) 
El llamado a este método le indica al componente View donde debe insertar el siguiente nivel 
de la jerarquía de renderización. Si se pasa true en $returnContent devuelve el contenido del 
buffer de salida hasta el momento. 
 
static function void setRenderLevel(int $level)  
Establece hasta que nivel de renderización se debe generar la presentación. Consulte la tabla 
de niveles de presentación para obtener más información sobre el uso de este método. 

25.9.2 Administrar presentación 
static function void handleViewRender(Controller $controller)  
Este método actua como el administrador de presentación predeterminado recibiendo como 
parámetro  el  último  controlador  enrutado.  No  debería  ser  invocado  directamente  por  el 
desarrollador ya que es llamado por el contenedor de aplicaciones.  
 
static function void handleViewExceptions(Exception $e, Controller $controller)  
Este  método  actua  como  el  administrador  de  presentación  predeterminado  cuando  no  se 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    293 

captura  una  excepción  recibiendo  como  parámetro  el  último  controlador  enrutado.  No 
debería ser invocado directamente por el desarrollador ya que es llamado por el contenedor 
de aplicaciones cuando esta situación ocurre.  
 

25.9.3 Visualizar vistas programacionalmente 
static function void renderPartial(string $_partialView,  string $_partialValue='')  
Permite  visualizar  una  vista  parcial  dentro  de  otra  vista.  El  segundo  parámetro  permite 
transferir un valor desde la vista donde se invoca este método al interior de la vista parcial.  
La vista parcial es ubicada en el directorio de vistas del controlador actual. 
 
El método se utiliza de la siguiente forma: 
<?php View::renderPartial(“nombreVista”, “Un Valor”) ?>
 
En el archivo _nombreVista.phtml el valor transferido puede ser usado así: 
<?php echo $nombreVista; ?>
 
Si se requiere visualizar una vista parcial en otro controlador diferente al actual debe usarse: 
<?php echo View::renderPartial(“nombreVista”, “controller: nombreControlador”);
?>
 
static function void renderView(string $_view) 
Permite visualizar una vista de acción dentro de otra vista. La vista de acción es ubicada en el 
directorio de vistas del controlador actual. 
 
El método se utiliza de la siguiente forma: 
<?php View::renderView(“nombreVista”) ?>
 
Si se requiere visualizar una vista parcial en otro controlador diferente al actual debe usarse: 
<?php echo View::renderView(“nombreVista”, “controller: nombreControlador”); ?>
 
static function array getValidationMessages()  
Obtiene desde una vista los mensajes de validación producidos por el componente Validation 
ó otro componente de usuario. 
 
static function void setContent(string $content)  
Establece programacionalmente el contenido del buffer de salida actual de la presentación. 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    294 

static function void setViewParam(string $index, string $value)  
Establece una variable de la vista que será creada en un ambito local como $index con el valor 
$value.  
 
static function array getViewParams()  
Obtiene un array con las variables pasadas a la vista usando View::setViewParam. 
 
static function void setProxyProvider(string $proxy, array $options)  
Establece  un  proxy‐provider  que  administre  las  peticiones  de  presentación  usando 
componentes de terceros. 
 
static function void proxyHandler()  
Método predeterminado para la administración de presentación cuando se usan componentes 
de terceros 
 
static function boolean existsActionView(string $name, string $controllerName='')  
Permite  consultar  si  una  vista  de  acción  existe  en  el  controlador  actual  ó  en  el  definido  en 
$controllerName. 

25.10 Crear un componente de Presentación personalizado

El  desarrollador  puede  crear  componentes  de  aplicación  que  reemplacen  al  componente  de 
presentación  View  por  defecto  en  Kumbia  Enterprise.  Como  los  demás  componentes  de 
usuario estos deben estar ubicados en el directorio library de la aplicación ó donde la variable 
de configuración libraryDir indique. 
 
Los  controladores  deben  establecer  el  administrador  de  presentación  requerido 
sobrescribiendo el método getViewHandler de esta forma: 
 
Ejemplo: Cambiar el componente que administra la generación de la presentación 
<?php
class CustomersController extends ApplicationController {
public function getViewHandler(){
return array("MyView", "handleViewRender");
}
}
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    295 

De  esta  forma  cuando  se  requiera  mostrar  la  presentación  para  el  controlador  se  pasará  el 
control  a  el  componente  MyView  invocando  el  método  estático  handleViewRender.  Este 
método  recibe  el  objeto  del  controlador  instanciado  (ó  el  último  que  se  utilizó  después  de 
realizar enrutamientos) en la petición: 
 
Ejemplo: Definir un componente de usuario que administer la presentación 
<?php
class MyView {
static public function handleViewRender($controller){
//Realizar la presentación
}
}

Se debe tener en cuenta toda la funcionalidad mencionada en el componente View no estará 
disponible  si  se  reescribe  el  componente  de  presentación.  Los  servicios  de  los  componentes 
Core (CoreConfig, CoreLocale, etc), Router y Dispatcher pueden resultar útiles en este punto. 

25.11 Crear un componente de presentación de Excepciones no capturadas

Al igual que la presentación normal, la de excepciones también puede ser reescrita siguiendo 
un  procedimiento  parecido  al  del  anterior.  En  este  caso  el  método  getViewExceptionHandler 
debe ser reescrito en el controlador. 
 
EJemplo:  Definir  un  componente  de  usuario  que  adminisre  la  presentación  de 
excepciones no capturadas 
<?php
class CustomersController extends ApplicationController {
public function getViewExceptionHandler(){
return array("MyView", "handleViewExceptionRender");
}
}

El  método  recibe  la  excepción  y  el  último  controlador  activo  antes  de  que  se  generará.  El 
componente MyView sería: 
 
Ejemplo:  Definir  un  componente  de  usuario  que  administre  la  presentación  de 
excepciones no capturadas 
<?php
class MyView {
static public function handleViewRender($controller){
//Realizar la presentación normal
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    296 

}
static public function handleViewExceptions($e, $controller){
//Excepciones
}
}
 
Consulte la referencia de CoreException y Exception para obtener más información sobre las 
excepciones generadas que no han sido capturadas. 

25.12 Integrar otros Engines de presentación

Si el desarrollador requiere, es posible integrar componentes de generación de presentación 
de terceros (otros frameworks ó proyectos). Con esto se aprovecha la funcionalidad de estos 
componentes sin perder el comportamiento y potencia del componente de Kumbia Enterprise 
View.  

25.12.1 Comportamiento de la integración 
La integración con los componentes de terceros tiene el siguiente comportamiento: 
 
 Las  variables  públicas  del  controlador,  datos  pasados  mediante  setViewParam  y  modelos 
utilizados  en  la  petición  (ó  todos  si  la  autoinicialización  de  entidades  está  activa)  son 
creados  en  el  formato  adecuado  del  componente  utilizado.  Por  ejemplo  en  Zend_View  se 
debe usar $this para acceder a estos valores. 
 Los nombres de la extensiones de archivos de vistas pueden configurarse como se requiera 
y no se debe usar “.phtml” como es normal. 
 La jerarquia de inclusión “vista principal/templates/layouts/vista/partials” se mantiene sin 
cambio  alguno  con  la  única  diferencia  que  el  resultado  de  cada  vista  es  producido  por  el 
componente seleccionado. 
 Todo  el  framework  aplicable  puede  utilizarse  en  las  vistas  creadas  con  otros  engines  sin 
restricciones. 
 Los plugins de View funcionan normalmente 

25.12.2 Componentes Soportados 
Actualmente  hay  soporte  para  los  componentes  de  presentación  Zend_View  de  Zend 
Framework y Smarty. 

25.12.2.1 Proxy a Zend_View 
El  componente  de  Zend  Framework  llamado  Zend_View  ofrece  la  posibilidad  de  integrar 
helpers,  filtros  y  scripts  a  las  vistas  generadas  con  este.  Para  indicar  que  se  usará  este 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    297 

componente se debe cambiar el administrador de presentación en el controlador así: 
 
Ejemplo: Establecer un proxy al componente de presentación Zend_View 
<?php
class MyController extends ApplicationController {
public function getViewHandler(){
View::setProxyProvider('Zend', array(
'zendPath' => 'Library',
'class' => 'Zend_View',
'extension' => 'phtml',
'encoding' => 'UTF-8',
'strictVars' => false
));
return array('View', 'proxyHandler');
}
}
 
El  método  View::setProxyProvider  establece  que  se  usará  el  Proxy  a  componentes  terceros 
‘Zend’. El segundo parámetro permite indicar otras opciones opcionales de la integración. 
 
Tabla: Parámetros del ProxyProvider a Zend_View 
Opción  Descripción 
zendPath  La ruta a donde está ubicado el Zend Framework. Si hace parte 
del include_path de PHP entonces no es necesario establecerla. 
class  La  clase  utilizada  para  administrar  las  vistas.  Por  defecto  es 
Zend_View  pero  puede  establecerse  cualquier  otra  que 
implemente la interfaz Zend_View_Interface. 
extension  La extensión que tendrán las vistas. Por defecto es .phtml. 
encoding  Esta opción aplica al constructor de Zend_View. 
strictVars  Esta opción aplica al contructor de Zend_View. 
 
Consulte la documentación de este framework en http://framework.zend.com/ . 

25.12.2.2 Proxy a Smarty 
Este ProxyProvider permite tratar vistas usando el Smarty Engine.  La forma en que se debe 
indicar que se usará este adaptador es la siguiente: 
 
Ejemplo: Generar un proxy de presentación a Smarty 
<?php
class MyController extends ApplicationController {
public function getViewHandler(){
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    298 

View::setProxyProvider('Smarty', array(
'smartyPath' => 'Library',
‘extension’ => ‘tpl’
));
return array('View', 'proxyHandler');
}
}
 
Opciones que recibe el ProxyProvider: 
 
Tabla: Parámetros del ProxyProvider a Smarty 
Opción  Descripción 
smartyPath  La  ruta  a  donde  está  ubicado  Smarty.  Si  hace  parte  del 
include_path de PHP entonces no es necesario establecerla. 
extension  La extensión que tendrán las vistas. Por defecto es .tpl 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    299 

26 Componente Tag
26.1 Introducción

Este componente actua como una biblioteca de etiquetas que permite generar tags XHTML en 
la presentación de una aplicación mediante métodos estáticos PHP predefinidos flexibles que 
integran tecnología del lado del cliente como CSS y Javascript. 
 
La  ventaja  de  utilizar  estos  helpers  en  lugar  de  XHTML  puro,  es  que  acelera  el  desarrollo  y 
hace consistente el código XHTML y otros aspectos como las URLs y el convencionalismo del 
framework. 
 
Cada  método  estático  recibe  sus  opciones  mediante  parámetros  por  nombre  que  se  pueden 
enviar  en  cualquier  orden  al  mismo.  En  los  tag  que  generan  etiquetas  es  posible  enviar 
parámetros XHTML ó CSS con su respectivo valor asignandose a la etiqueta generada. 

26.2 Establecer el valor de helpers creados con Tag

Una de las ventajas más importantes de crear componentes de interfaz de usuario con Tag es 
lo sencillo que se puede asignar el valor de estos de forma uniforme y controlada. 
 
Cada  componente  localiza  el  valor  que  debe  presentar  mediante  las  siguientes  reglas.  Si 
alguna regla se cumple las demás no son validadas: 
 
  Verifica si existe algún valor para él asignado con Tag::displayTo y lo toma como valor 
  Verifica si hay algún indice en $_POST que coincida con el atributo “id” de él y toma como 
valor 
  Verfica si existe un atributo público en el último controlador ejecutado que coincida con el 
atributo “id” de él y lo toma como valor. 
 
Si  a  algún  helper  se  le  asigna  directamente  con  el  parámetro  “value”  ninguna  de  las  reglas 
anteriores se tiene en cuenta. 
 
El  siguiente  ejemplo  ilustra  la  asignación  de  un  valor  a  componente  de  interfaz  de  usuario 
creado mediante Tag:  
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    300 

Ejemplo:  Mostrar  un  valor  en  un  componente  visual  desde  el  controlador  mediante 
Tag::displayTo 
<?php
class PeopleController extends ApplicationController {
public function indexAction(){
Tag::displayTo('genero', 'F');
}
}

 
En la vista el como estático se visualizará con el valor “F” seleccionado: 
 
<?php

$generos = array(
'M' => 'Masculino',
'F' => 'Femenino'
);
echo Tag::selectStatic("genero", $generos); ?>
El  desarrollador  debe  validar  que  no  se  asignen  valores  con  displayTo  cuando  se  deba 
visualizar los valores capturados por el usuario en la petición POST. 

26.3 Comportamiento de helpers

Todos  los  helpers  en  el  componente  Tag  devuelven  código  HTML  generado  por  cada  uno  lo 
que  permite  utilizar  este  para  utilizarlo  como  parámetro  de  otros  helpers  ó  usarlo  como  se 
requiera. 
 
<?php echo Tag::linkTo(“controlador/accion”, Tag::image(“foto.jpg”)) ?>
 
Los helpers pueden recibir parámetros por nombre ó un array asociativo cuyos indices seán 
los nombres de los parámetros.  
 
<?php echo Tag::form(“controlador/accion”, “method: post”) ?>
 
<?php echo Tag::form(array(“controlador/accion”, “method” => “post”)) ?>

26.4 API del Componente Tag

A continuación se presenta el API del componente: 

26.4.1 Crear enlaces 
public static function linkTo(mixed $params) 
Permite crear un enlace a una punto de la aplicación utilizando las convenciones de Kumbia 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    301 

Enterprise; este método genera un tag A de XHTML con la posibilidad de implementar tanto 
una confirmación antes de ejecutarse como de aplicar cualquier atributo que se desee a este 
tag.  El  label  de  la  etiqueta  puede  ser  un  texto  ó  cualquier  otro  tag  como  por  ejemplo  una 
imagen. 
 
Las opciones extendidas del componente son: 
 
Tabla: Parámetros que recibe linkTo 
Nombre  Descripción 
confirm  Permite establecer que se presente un cuadro de dialogo de presentación 
al usuario que confirme la petición de la URL en el tag A. 
text  Es el texto que aparecerá en el enlace. 
 
Ejemplo: Uso de linkTo 
<?php echo Tag::linkTo(“controlador/saludo”, ”Saludar”) ?>
 
<?php echo Tag::linkTo(“controlador/saludo”,”SALUDAR”, ”class: css_saludo”,
”border: 0”, “confirm: Desea ir a Saludo?”) ?>

Genera el siguiente código XHTML: 
 
<a onclick='if(!confirm("Desea ir a saludo?”)) return false;' border="0"
class="css_saludo" href="/instancia/controlador/saludo">SALUDAR</a>
 
public static function linkToAction(mixed $params) 
Genera  un  enlace  a  una  acción  asociada  al  controlador  actual.  Al  igual  que  linkTo  es  posible 
aplicar atributos HTML pasandolos como otros parámetros. 
 
Ejemplo: Uso de linkToAction 
<?php echo Tag::linkTo(“cancelInvoice”, ”Cancelar”) ?>
 
<?php echo Tag::linkTo(“cancelInvoice”, ”Cancelar”, ”class: css_saludo”,
”border: 0”, “confirm: Desea cancelar la factura?”); ?>
 
Opciones extendidas de linkToAction: 
 
Tabla: Opciones extendidas de linkToAction 
Nombre  Descripción 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    302 

confirm  Permite establecer que se presente un cuadro de dialogo de presentación 
al usuario que confirme la petición de la URL en el tag A. 
text  Es el texto que aparecerá en el enlace. 
 
public static function linkToRemote(mixed $params) 
Carga el contenido de una acción en un contenedor HTML dentro de la presentación actual. La 
vista se obtiene mediante AJAX por lo que la página no es recargada. 
 
En el siguiente ejemplo se cargará el contenido de una acción en el div con id ‘the_menu’: 
 
Ejemplo: Uso del helper linkToRemote 
<div id='the_menu'></div>
<?php echo Tag::linkToRemote('main/getMenu', 'Texto del Enlace', 'the_menu') ?>
 
Como la presentación es parcial se debe modificar la salida del controlador para solo mostrar 
la vista asociada y saltar los templates ó layouts. 
 
<?php
class MainController extends ApplicationController {
public function indexAction(){
}
public function getMenuAction(){
$this->setResponse('ajax');
}
}
 
También es posible implementar eventos AJAX a medida que se procesa la petición mejorando 
la experiencia de usuario: 
 
<div id='the_menu'></div>
<?php echo Tag::linkToRemote("main/getMenu", "Texto del Enlace", "the_menu",
"onLoading: $('info').update('Cargando...')") ?>

Opciones de linkToRemote: 

Tabla: Parámetros que recibe linkToRemote 
Nombre  Descripción 
confirm  Permite establecer que se presente un cuadro de dialogo  que confirme la 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    303 

petición de la URL. 
text  Es  el  texto  que  aparecerá  en  el  enlace.  Si  no  se  establece  el  segundo 
parámetro del enlace es tomado. 
update  Es el contenedor HTML donde se presentará el contenido de la vista. 
onLoading  Código JavaScript a ejecutar antes de realizar la petición HTTP interna. 
onSuccess  Código JavaScript a ejecutar cuando la petición se completa con éxito. El 
objeto  con  la  el  resultado  petición  puede  obtenerse  usando  la  variable 
‘transport’. 
onComplete  Código JavaScript a ejecutar cuando la petición se completa. El objeto con 
la el resultado petición puede obtenerse usando la variable ‘transport’. 
onFailure  Código  JavaScript  a  ejecutar  cuando  la  petición  falla  ó  se  genera  una 
excepción. El objeto con la el resultado petición puede obtenerse usando 
la variable ‘transport’. En este mismo evento se carga el contenido de la 
presentación en el contenedor. 
asynchronous  Permite  establecer  si  la  petición  es  asincronica  ó  sincrónica.  Se  debe 
establecer un valor booleano true ó false. Por defecto es false. 
 
Adicional  a  lo  anterior  linkToRemote  acepta  como  parámetro  cualquier  nombre  de  atributo 
aplicable a la etiqueta A. 

26.4.2 Componentes de interfaz de usuario 
public static function textField(mixed $params) 
Crea una caja de texto con los parámetros establecidos.  
 
<?php echo Tag::textField("nombre") ?>
 
El código HTML generado es: 
 
<input type='text' id='nombre' value='' name='nombre' />
 
El  helper  textField  acepta  como  parámetro  cualquier  nombre  de  atributo  aplicable  a  la 
etiqueta input type=”text”. 
 
public static function textArea(mixed $params) 
Permite crear una area de texto (textarea) con los parámetros establecidos. 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    304 

Ejemplo: Uso del helper Tag::textArea 
<?php echo Tag::textArea("nombre", "cols: 120", "rows: 5") ?>

 
Lo cúal genera el siguiente código HTML: 
 
<textarea id="nombre" name="nombre" cols="120" rows="5"></textarea>

El  helper  textArea  acepta  como  parámetro  cualquier  nombre  de  atributo  aplicable  a  la 
etiqueta textarea. 
 
public static function numericField(mixed $params) 
Crea  una  caja  de  texto  con  los  parámetros  establecidos  validando  que  su  entrada  sea  solo 
valores numéricos.  
 
Ejemplo: Uso del helper Tag::numericField 
<?php echo Tag::numericField("accountNumber") ?>

 
El  helper  numericField  acepta  como  parámetro  cualquier  nombre  de  atributo  aplicable  a  la 
etiqueta input type=”text”. 
 
public static function numericPasswordField(mixed $params) 
Crea  una  caja  de  texto  para  contraseñas  con  los  parámetros  establecidos  validando  que  su 
entrada sea solo valores numéricos. Este componente debe ser usado en casos especiales de 
confianza  ya  que  su  naturaleza  ayudaría  a  un  tercero  malintencionado  a  conocer  que  el 
password solicitado es un algún valor numérico. 
 
Ejemplo: Uso del helper numericPasswordField 
<?php echo Tag::numericPasswordField("password") ?>
 
El  helper  numericPasswordField  acepta  como  parámetro  cualquier  nombre  de  atributo 
aplicable a la etiqueta input type=”password”.  

26.4.3 Componentes de listas/combos 
public static function selectStatic(mixed $params) 
Crea un combo con valores estáticos establecidos en un vector.  
 
Ejemplo: Uso del helper Tag::selectStatic 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    305 

<?php
$estados = array(
'A' => 'ACTIVO',
'I' => 'INACTIVO'
);
echo Tag::selectStatic("estados", $estados, 'useDummy: yes');
?>

Lo cuál genera el siguiente HTML: 

<select id='estados' name='estados'>


<option value='@'>Seleccione...</option>
<option value='A'>ACTIVO</option>
<option value='I'>INACTIVO</option>
</select>
 
Opciones de selectStatic: 
 
Tabla: Parámetros recibidos por selectStatic 
Nombre  Descripción 
useDummy  Indica  que  se  debe  colocar  una  opción  adicional  ‘Seleccione…’  al 
prinicipio de la lista. El valor de este es una ‘@’. 
dummyValue  Permite cambiar el valor de la opción Dummy de ‘@’ al valor indicado. 
dummyText  Permite  cambiar  el  texto  de  la  opción  Dummy  de  ‘Seleccione…’  al  texto 
indicado. 
 
Adicional  a  lo  anterior  selectStatic  acepta  como  parámetro  cualquier  nombre  de  atributo 
aplicable a la etiqueta SELECT. 
 
public static function select(mixed $params) 
Permite generar una lista desplegable mediante un array, un ActiveRecordResultset (resultado 
de ActiveRecord) ó un ActiveRecordRow (resultado de ActiveRecordJoin): 
 
Ejemplo: Uso del helper Tag::select 
<?php echo Tag::select('userId', $Users->find('order: name'), 'using: id,name',
'useDummy: yes') ?>
 
El primer parámetro de este helper es el id/name que tomará la lista. El segundo son los datos 
de  la  lista.  Cuando  se  usa  un  ActiveRecordResultset  ó  ActiveRecordRow  se  debe  establecer  el 
parámetro  using,  el  cuál  es  una  pareja  de  atributos  que  será  utilizada  como  valor/texto  de 
cada opción de la etiqueta SELECT generada. 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    306 

Opciones de select: 
 
Tabla: Parámetros recibidos por Tag::select 
Nombre  Descripción 
useDummy  Indica  que  se  debe  colocar  una  opción  adicional  ‘Seleccione…’  al 
prinicipio de la lista. El valor de este es una ‘@’. 
dummyValue  Permite  cambiar  el  valor  de  la  opción  Dummy  de  ‘@’  al  valor 
indicado. 
dummyText  Permite  cambiar  el  texto  de  la  opción  Dummy  de  ‘Seleccione…’  al 
texto indicado. 
 
Adicional a lo anterior select acepta como parámetro cualquier nombre de atributo aplicable a 
la etiqueta SELECT. 
 
public static function localeSelect() 
Es identico al helper select pero en este se aplica una función de localización a cada texto de 
las opción mediante un objeto de traducción. 
 
El siguiente ejemplo muestra los idiomas disponibles basado en un objeto de traducción: 
 
Ejemplo: Uso del helper Tag::localeSelect 
<?php echo Tag::localeSelect('languageId', $Languages->find('order: name'),
$traslate, 'using: id,name', 'useDummy: yes') ?>

public static function selectMixed() 
Este  método  permite  crear  listas  combinando  arrays  de  valores  estáticos  y  resultados 
dinámicos. 
 
Ejemplo: Uso del helper Tag::selectMixed 
<?php
$dynamicData = $Categories->find();
$staticData = array(
‘N’ => ‘NINGUNO DE LOS ANTERIORES’
);
echo Tag::selectMixed('categoriesId', $dynamicData, $staticData, 'using:
id,name', 'useDummy: yes') ?>

Las opciones adicionales de selectStatic y select también aplican a selectMixed. 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    307 

public static function submitImage($caption, $src) 
Permite  crear  un  botón  de  envío  de  formulario  con  una  imagen  en  vez  de  un  texto.  Recibe 
como parámetros “caption” que contendrá el texto que aparece en caso de que la imágen no 
pueda ser cargada. “src” especifica la ruta de la imagen. 
 
Ejemplo: Uso del helper Tag::submitImage 
<?php echo Tag::submitImage('Enviar', Core::getInstancePath.'img/submit.png') ?>
 
Adicionalmente este helper acepta como parámetro cualquier atributo o propiedad que pueda 
ser aplicable a la etiqueta input type='image'. 
 
public static function button() 
Permite crear un botón típico de HTML sin ninguna acción por defecto.  
 
Ejemplo: Uso del helper Tag::button 
<?php echo Tag::button('Actualizar','id: update','onclick: actualiza()') ?>
 
Recibe además los cualquier evento que pueda definirse para el botón con su correspondiente 
acción en javascript. 
 
public static function image($img) 
Incluye una imagen en una vista teniendo en cuenta el direccionamiento de los directorios del 
framework. El parámetro “img” define el nombre de la imagen que debe estar incluida dentro 
de la carpeta 'img'.  
 
Ejemplo: Uso del helper Tag::image 
<?php echo Tag::image('imagen.png', 'alt: Imagen') ?>
 
Opciones de image: 
 
Tabla: Parámetros recibidos por Tag::image 

Nombre  Descripción 

alt  Especifica un texto alternativo para la imagen. 

 
public static function formRemote($params) 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    308 

Permite  generar  un  formulario  remoto,  que  será  enviado  con  una  petición  de  Ajax.  El 
parámetro  “params”  permite  ingresar  una  serie  de  opciones  para  el  helper.El  primer 
parámetro ingresado es el que define el valor de la propiedad action para la etiqueta 'form'. 
 
Ejemplo: Uso del helper Tag::formRemote 
<?php echo Tag::formRemote('usuarios/buscar','update: findResults','required:
name') ?>
 
Opciones de formRemote: 
 
Tabla: Parámetros que recibe formRemote 

Nombre  Descripción 

action  Valor que tendrá la propiedad 'action' del formulario. 

complete  Callback que contendrá el codigo javascript que se ejecutará una vez se 
active el evento complete del formulario. 

befote  Callback  que  contendrá  el  codigo  javascript  que  se  ejecutará  antes  de 
que el formulario sea enviado. 

success  Callback que contendrá el codigo javascript que se ejecutará una vez se 
active el evento success del formulario. 

required  Colección de campos que son requeridos para el formulario, ocurre una 
validación de dichos campos antes de hacer el envío. 

update  Id de la etiqueta que será actualizada una vez se complete el envío. 

 
public static function submitRemote($caption) 
Crea  un  botón  de  envío  para  el  formulario  remoto  actual.  El  parámetro  “caption”  define  el 
texto que se muestra en el botón. 
 
Ejemplo: Uso del helper Tag::submitRemote 
<?php echo Tag::submitRemote('Buscar', 'update: findResults') ?>
 
Opciones de submitRemote: 
 
Tabla:  Parámetros que recibe Tag::submitRemote 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    309 

Nombre  Descripción 

caption  Valor que tendrá la propiedad 'value' del botón. 

complete  Callback que contendrá el codigo javascript que se ejecutará una vez se 
active el evento complete del formulario. 

before  Callback  que  contendrá  el  codigo  javascript  que  se  ejecutará  antes  de 
que el formulario sea enviado. 

success  Callback que contendrá el codigo javascript que se ejecutará una vez se 
active el evento success del formulario. 

update  Id de la etiqueta que será actualizada una vez se complete el envío. 

 
public static function form($action) 
Crea  una  etiqueta  de  apertura  de  un  formulario.  El  parámetro  “action”  es  el  valor  de  la 
propiedad 'action' del formulario. 
 
Ejemplo: Uso del helper Tag::form 
<?php echo Tag::form('usuarios/buscar','id: formSearch') ?>
 
Opciones de submitRemote: 
Tabla: Parámetros que recibe el helper Tag::form 

Nombre  Descripción 

action  Valor que tendrá la propiedad 'action' del formulario. 

method  Método que será usado para el envío del formulario. 

confirm  Si es declarado define el mensaje de confirmación para el envío del formulario. 

onsubmit  Callback  que  contendrá  el  codigo  javascript  que  se  ejecutará  una  vez  se  active  el 
evento submit del formulario. 

 
public static function endForm() 
Etiqueta que finaliza el formulario, corresponde al codigo de cierre de dicha etiqueta. 
 
Ejemplo: Uso del helper Tag::endForm() 
<?php echo Tag::endForm() ?>
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    310 

Genera el siguiente codigo XHTML: 
 
</form>
 
public static function submitButton($caption) 
Permite crear un botón de envío para el formulario actual. Ingresa como parámetro el valor 
del  texto  que  será  mostrado  en  el  botón.  Además  recibe  cualquier  atributo  que  pueda  ser 
aplicable a una etiqueta input type='submit'. 
 
Ejemplo: Uso del helper Tag::submitButton 
<?php echo Tag::submitButton('Buscar', 'id: submitSearch') ?>
 

26.4.4 Tratamiento de etiquetas META 
public static function setMeta(string $name, string $content) 
Carga  en  memoria  una  etiqueta  Meta  para  las  cabeceras  del  documento  HTML.  Recibe  el 
nombre de la etiqueta y un contenido para la misma. 
 
Ejemplo: Uso del helper Tag::setMeta 
<?php echo Tag::setMeta('description','Busqueda de usuarios.') ?>
 
public static function getMetas() 
Imprime  las  etiquetas  Meta  que  han  sido  cargadas  previamente.  No  recibe  parámetros  e 
imprime automáticamente el resultado en el documento HTML. 
 
Ejemplo: Uso del helper Tag::getMetas() 
<?php Tag::getMetas() ?>

26.4.5 Tratamiento e Inclusión de archivos CSS 
public static function stylesheetLink(string $src='', $useVariables=false) 
Adiciona una etiqueta de link que incluye un archivo CSS teniendo en cuenta las rutas que se 
definen  en  Kumbia  Enterprise.  El  primer  parámetro  constituye  la  ruta  de  ubicación  del 
archivo  CSS,  el  segundo  determina  si  se  usará  un  traductor  de  las  variables  globales  que  se 
pueden especificar en los archivos CSS. 
 
Ejemplo: Uso del helper Tag::styleSheetLink 
<?php echo Tag::stylesheetLink('calendar', true) ?>
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    311 

Las  variables  CSS  pueden  usarse  para  reemplazar  rutas  absolutas  que  ayuden  asegurar  que 
imagenes u otros recursos seran establecidos correctamente. 
 
Las posibles variables que se pueden utilizar son: 
 
Tabla: Variables CSS que soporta el Tag::styleSheetLink 

Variable  Descripción 

@path  Ruta absoluta del servidor web hacia la instancia del framework. 

@img_path  Ruta  absoluta  del  servidor  web  hacia  el  directorio  img  de  la  instancia  del 
framework. 

@css_path  Ruta  absoluta  del  servidor  web  hacia  el  directorio  css  de  la  instancia  del 
framework. 

 
En una clase CSS las variables se utilizan así: 
 
Ejemplo: Uso de variables CSS con Tag::stylesheetLink 
.header {
background-image: url(“@path/img/site/bg-header.gif”);
}
 
Para aumentar el rendimiento del reemplazo de variables en archivos CSS estos se cachean en 
el directorio temp/ y se refrescan cuando se detecta cambios en ellos. 
 
public static function removeStylesheets() 
Remueve los tags de css agregados. 
 

26.4.6 Componentes para fechas 
public static function dateField(mixed $params) 
Permite  validar  que  los  dato  capturado  sea  una  fecha.  Este  helper  crea  3  listas  una  para  los 
meses,  días  y  otra  para  los  años.  Los  nombres  de  los  meses  se  muestran  en  el  idioma  de  la 
localización  activa.  El  valor  capturado  se  almacena  en  un  input  oculto  con  el  nombre  del 
dateField. 
 
Ejemplo: Uso de helper Tag::dateField 
<?php echo Tag::dateField("fechaInicial") ?>
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    312 

Por defecto dateField muestra la fecha 1 de enero del año en curso, sin embargo esta fecha no 
es válida.  
 
Opciones de dateField: 

Tabla: Parámetros que acepta Tag::dateField 
Nombre  Descripción 
startYear  Indica el año menor que tendrá la lista año. 
finalYear  Indica el año mayor que tendrá la lista año. 
useDummy  Indica si se debe forzar al usuario a seleccionar un valor valido. 
 
Adicional  a  lo  anterior  dateField  acepta  como  parámetro  cualquier  nombre  de  atributo 
aplicable a la etiqueta table. 
 
public static function localeDateField(mixed $params, Traslate $traslate) 
Es identico a dateField pero los nombres de los meses son tomados de la lista de localización 
actual permitiendo mostrarlos varios idiomas. 
 
Ejemplo: Uso del helper Tag::localeDateField 
<?php echo Tag::localeDateField("fechaInicial", $traslate) ?>
 
El helper localeDateField acepta como parámetro cualquier nombre de atributo aplicable a la 
etiqueta table. 

26.4.7 Incluir recursos Javascript 
public static function javascriptInclude(string $src='',  boolean $cache=true) 
Permite insertar una etiqueta <script> con la referencia a un archivo javascript de la instancia 
actual. La extensión .js debe ser omitida ya que el helper la agrega automáticamente.  
 
Ejemplo: Uso del helper Tag::javascriptInclude 
<?php echo Tag::javascriptInclude(“lightbox”) ?>

Genera el código HTML: 

<script type='text/javascript' src='/instance/javascript/lightbox.js'></script>

Cuando  se  pasa  false  en  el  segundo  parámetro  se  agrega  a  la  URL  del  HTML  generado  el 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    313 

parámetro GET nocache=valor donde valor es un entero aleatorio entre 0 y 999999. De esta 
forma se obliga al navegador a recargar el recurso javascript en cada petición. 
 
Ejemplo: Uso del helper Tag::javascriptInclude con cache 
<?php echo Tag::javascriptInclude(“lightbox”, false) ?>
 
Genera el código HTML: 
 
<script type='text/javascript'
src='/instance/javascript/lightbox.js?nocache=18261'></script>
 
Si se omite el nombre del JavaScript se trata de insertar un archivo con el mismo nombre del 
controlador actual. 

public static function javascriptMinifiedInclude(string $src='') 
Permite  insertar  un  javascript  minimizado  con  JsMin.  El  parámetro  $src  es  la  ubicación  del 
archivo en el servidor una versión pública es generada la cuál es regenerada cada vez que se 
modifica el archivo original. Los archivos javascript minimizados consumen menor ancho de 
banda y pueden aumentar la velocidad de carga de la aplicación en clientes con velocidades de 
conexión reducidas. 
 
Ejemplo: Uso del helper Tag::javascriptMinifiedInclude 
<?php echo Tag::javascriptMinifiedInclude(“lightbox”) ?>

Genera el código HTML: 
 
<script type='text/javascript'
src='/instance/javascript/lightbox.min.js'></script>

El directorio public/javascript debe tener permisos de escritura para usar este helper. 

26.4.8 Interacción con la presentación 
static function void displayTo(string $id, string $value) 
Establece  el  valor  para  un  componente  visual  del  formulario  que  se  va  a  presentar  en  la 
petición actual.  El valor definido mediante este helper tiene mayor prioridad cuando se trata 
de obtener el valor de los componentes visuales. 
 
Ejemplo: Uso del helper Tag::displayTo 
<?php Tag::displayTo(“nombre”, “Juanita Mendoza”);
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    314 

En la vista la caja “nombre” se muestra con el valor establecido: 
 
<?php echo Tag::textField(“nombre”) ?>

lo que produce: 

<input type=”text” id=”nombre” name=”nombre” value=”Juanita Mendoza” />


 
static function mixed getValueFromAction(string $name)  
Permite obtener el valor que será presentado en un componente visual como lo es una caja de 
texto ó una lista (combo). Todos los helpers realizan un llamado interno usando este método 
para obtener el valor a presentar dependiendo la naturaleza de cada uno. 
 
Los valores son obtenidos en este orden: 
 
  Se verifica si existe algún valor para él asignado con Tag::displayTo y lo toma como valor 
  Se verifica si hay algún indice en $_POST que coincida con el atributo “id” de él y toma como 
valor 
  Verfica si existe un atributo público en el último controlador ejecutado que coincida con  
 
Ejemplo: Uso del helper Tag::getValueFromAction 
<?php
$nameValue = Tag::getValueFromAction(‘nameValue’);
 
 
 
 
 
 
 
 
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    315 

27 Helpers JavaScript
27.1 Introducción

En este capítulo se describen clases y funciones en JavaScript que proporciona el framework 
al  desarrollador  para  agilizar  el  proceso  de  creación  de  capturas  y  presentación  de  datos  e 
información al usuario final. 

27.2 Clase Format

Esta  clase  permite  darle  formato  a  los  diferentes  tipos  de  datos  que  pueden  ser  incluidos 
dentro  de  una  captura  de  datos  o  una  vista  tal.  Está  enteramente  codificada  en  javascript 
usando el framework Prototype. Tiene licencia de uso y modifcación totalmente abierta y hace 
parte del proyecto de Herramientas JavaScript de uso común en Aplicaciones Web.

27.2.1 Instanciando la clase
Para  iniciar  el  uso  de  esta  herramienta  es  necesario  crear  un  objeto  que  definirá  las 
propiedades  que  se  usarán  para  darle  formato  a  los  datos.  Esto  se  logra  de  la  siguiente 
manera: 

Ejemplo: Uso del helper JavaScript Format 

<script type="text/javascript">
var format = new Format({
type: 'numeric',
properties: { decimals: 2, letNegative: false, blankToZero: false } }, {
type: 'percent',
properties: { decimals: 3, complete: 2 } }, {
type: 'money',
properties: { decimals: 2, simbMon: 'US$', leftZeros: 1 }
});
</script>

Puede  notar  que  no  todas  estas  propiedades  deben  ser  definidas,  todas  poseen  valores  por 
defecto que serán usados en principio para el formato. Estas propiedades son determinadas 
por el tipo, con lo cual se usa la notación type: 'nombre_tipo', properties: {propiedades}. 
 
Los tipos de datos soportados por el Format son: numeric, que define las propiedades para los 
valores que serán numéricos, tanto enteros como punto flotante; percent, para los valores que 
tienen un formato de porcentaje; money en el cual se establecen los atributos para los datos 
tipo moneda. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    316 

Opciones del constructor de Format: 

Tabla: Parámetros que recibe el helper javascript Format 
Nombre  Valor por  Aplicable a  Descripción 
Defecto 
decimals  0  todas  Establece  el  número  de 
decimales. 
puntoDec  ','  todas  Carácter para el punto decimal. 
sepMiles  '.'  todas  Carácter  para  el  separador  de 
Miles. 
simbPer  '%'  percent  Símbolo de porcentaje. 
simbMon  '$'  money  Símbolo de moneda. 
letNegative  true  todas  Establece si permite negativos o 
no. 
blankToZero  true  todas  Define  si  un  valor  vacío  es 
puesto como cero. 
leftZeros  0  todas  Número  de  ceros  que  serán 
añadidos a la izquierda del dato. 
complete  0  todas  Tamaño  obligatorio  que  deben 
tener  los  datos  en  su  parte 
entera. 
completeCaracter  '0'  todas  Carácter  que  se  usará  para 
completar los datos. 
onCompleteTruncate  true  todas  Define  si  se  truncará  un  dato  si 
este  supera  el  tamaño  definido 
en  complete.  No  aplica  si 
complete es cero. 
 
Uso del Format: 
 
<div><input id="temp" type="text" /></div>
 
Númerico:   
<input type='boton' onclick='formatoNumerico()' />
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    317 

<input type='boton' onclick='deFormatoNumerico()' />


<script type="text/javascript">
function formatoNumerico(){
$('temp').value = format.numeric($F('temp'));
}
function deFormatoNumerico(){
$('temp').value = format.deFormat($F('temp'),'numeric');
}
</script>
 
Nótese que una vez que ha sido creado el objeto format lo único que debe hacerse es usarlo 
para  dar  formato  a  los  datos  que  se  tengan,  asimismo  es  posible  deshacer  dicho  formato 
haciendo uso de la función deFormat. También es importante observar que todos los llamados 
son  dinámicos  y  debe  usarse  un  objeto  definido  para  ello  es  decir,  antes  de  usar  cualquier 
función es necesario crear un objeto como se indica en el apartado Instanciando la clase, y una 
vez hecho esto todas las funciones se deben invocar con variable.función(parámetros). 

27.2.2 Funciones de Format 
numeric(number) 
Formatea  un  número  que  es  ingresado  como  parámetro  usando  las  propiedades  definidas 
para  los  tipo  numeric  al  instanciar  la  clase  o  que  hayan  sido  establecidas  con  el  método 
changeProperties. Retorna una cadena de caracteres que posee el formato adecuado. 
 
money(number) 
Formatea  un  número  que  es  ingresado  como  parámetro  usando  las  propiedades  definidas 
para  los  tipo  money  al  instanciar  la  clase  o  que  hayan  sido  establecidas  con  el  método 
changeProperties.  Retorna  una  cadena  de  caracteres  que  posee  el  formato  adecuado, 
agregando el símbolo de pesos requerido. 
 
percent(number) 
Formatea  un  número  que  es  ingresado  como  parámetro  usando  las  propiedades  definidas 
para  los  tipo  percent  al  instanciar  la  clase  o  que  hayan  sido  establecidas  con  el  método 
changeProperties.  Retorna  una  cadena  de  caracteres  que  posee  el  formato  adecuado, 
agregando el símbolo porcentual definido. 
 
changeProperties() 
Cambia  las  propiedades  del  tipo  especificado.  Las  propiedades  que  no  sean  incluidas 
conservan su valor anterior. 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    318 

format.changeProperties({type: 'numeric', properties: { letNegative: false } });


 
deFormat(str,type) 
Deformatea una cadena de caracteres. Recibe como parámetros “str” que representa la cadena 
de texto a procesar; “type” que debe ser el tipo de formato al que fue sometida dicha cadena. 

27.3 Clase Validator

Esta clase permite realizar validaciones a los diferentes datos que pueden ser incluidos dentro 
de una captura de datos o una vista tal. Está enteramente codificada en javascript usando el 
framework Prototype. Tiene licencia de uso y modifcación totalmente abierta y hace parte del 
proyecto de Herramientas JavaScript de uso común en aplicaciones Web. 

27.3.1 Instanciando la clase 
Antes de hacer uso de esta clase debe instanciarse un objeto que contendrá las propiedades 
para las validaciones que se requieran. El constructor del objeto acepta tipos predefinidos y 
otros personalizados que se definen dinámicamente. 
 
Tipos de dato predefinidos en Validator: 
 
Tabla: Tipos de datos que recibe el helper Javascript Validator 
Nombre  Descripción 
text  Tipo que representa valores textuales. 
number  Se asocia a los números enteros. 
decimal  Se asocia a los números decimales. 
date  Tipo definido para las fechas. 
select  Este tipo de dato es usado en los combos de selección. 
email  Tipo  que  se  usa  para  los  campos  que  deben  contener  un 
email. 
format_number  Se  usa  para  definir  los  formatos  numéricos  estableciendo 
una  asociación  con  algún  objeto  del  tipo  format  que  será 
aplicado sobre ese campo. 
format_decimal  Relaciona una variable de la clase Format con un campo que 
contendrá valores decimales. 
format_money  Relaciona una variable de la clase Format con un campo que 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    319 

contendrá valores de moneda. 
format_percent  Relaciona una variable de la clase Format con un campo que 
contendrá valores porcentaje. 
 
<script type="text/javascript">
var val = new Validator();
</script>

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    320 

28 Componente PDFDocument
28.1 Introducción

El objetivo del componente PDFDocument es la generación de documentos PDF. Está basado 
en  la  estable    librería  FPDF  pero  adaptado  y  mejorado  para  ser  integrado  como  parte  del 
framework y hacerlo parte de su “garantía”.  
 
Las mejoras con respecto a FPDF son: 
 
 Soporte para múltiples charsets ISO8859‐1, UTF‐8, etc. 
 Facilidades para definir colores y estilos 
 Sintaxis y API más regular acorde al estándar del framework 

28.2 Crear un documento PDF

Un documento PDF se crea instanciando la clase PdfDocument. En el siguiente ejemplo se crea 
agrega una página con un texto y se envia al navegador. 
 
Ejemplo: Crear un documento PDF con PDFDocument 
<?php
class ReportsController extends ApplicationController {
public function showAction(){
$pdf = new PdfDocument();
$pdf->addPage();
$black = PdfColor::fromName(PdfColor::COLOR_BLACK);
$pdf->setTextColor($black);
$pdf->setFont('helvetica', '', 18);
$pdf->writeCell(40, 10, "Hello PDF");
$pdf->outputToBrowser();
}
}

28.3 Agregar una tabla al documento

PdfDocument proporciona soporte para celdas y multi‐celdas las cuales son útiles cuando se 
crean documentos que van a visualizar tablas de datos. En el siguiente ejemplo se genera un 
documento PDF con los datos obtenidos de un modelo: 
 
Ejemplo: Crear una tabla con datos en un documento PDF 
<?php

class ReportsController extends ApplicationController {


LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    321 

public function showAction(){


$pdf = new PdfDocument();
$pdf->addPage();
$black = PdfColor::fromName(PdfColor::COLOR_BLACK);
$pdf->setTextColor($black);
//Agregar el titulo
$pdf->setFont('helvetica', '', 18);
$pdf->writeCell(40, 7, "Reporte de Productos");
$pdf->lineFeed();
//La fecha del reporte
$pdf->setFont('helvetica', '', 12);
$pdf->writeCell(40, 7, "Fecha: ".Date::getCurrentDate());
$pdf->lineFeed();
foreach($this->Products->find('order: id') as $product){
$pdf->writeCell(20, 7, $product->getId());
$pdf->writeCell(70, 7, $product->getName());
$pdf->lineFeed();
}
$pdf->outputToBrowser();
}
}

 
Una  versión  más  estilizada  del  reporte/listado  se  puede  obtener  agregando  bordes, 
encabezados y colores de fondo al documento: 
 
Ejemplo: Crear un documento PDF con una tabla de datos más estilizada 
<?php

class ReportsController extends ApplicationController {


public function showAction(){
$pdf = new PdfDocument();
$pdf->addPage();
//Los datos de entrada son UTF-8
$pdf->setEncoding(PdfDocument::ENC_UTF8);
$black = PdfColor::fromName(PdfColor::COLOR_BLACK);
$pdf->setTextColor($black);
//Agregar el titulo
$pdf->setFont('helvetica', '', 18);
$pdf->writeCell(40, 7, "Reporte de Productos");
$pdf->lineFeed();
//La fecha del reporte
$pdf->setFont('helvetica', '', 12);
$pdf->writeCell(40, 7, "Fecha: ".Date::getCurrentDate());
$pdf->lineFeed();
//Encabezados con fondo gris
$lightGray = PdfColor::fromGrayScale(0.75);
$pdf->setFillColor($lightGray);
$pdf->writeCell(20, 7, 'Código', 1, 0, PdfDocument::ALIGN_JUSTIFY,
1);
$pdf->writeCell(90, 7, 'Nombre', 1, 0, PdfDocument::ALIGN_JUSTIFY,
1);
$pdf->lineFeed();
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    322 

//Volver al fondo blanco


$white = PdfColor::fromName(PdfColor::COLOR_WHITE);
$pdf->setFillColor($white);

foreach($this->Products->find('order: id') as $product){


$pdf->writeCell(20, 7, $product->getId(), 1, 0,
PdfDocument::ALIGN_JUSTIFY, 1);
$pdf->writeCell(70, 7, $product->getName(), 1, 0,
PdfDocument::ALIGN_JUSTIFY, 1););
$pdf->lineFeed();
}
//Se envia el listado al navegador
$pdf->outputToBrowser();
}
}

28.4 Tipos de Papel Soportados

PdfDocument soporta los siguientes tipos de papel: 
 
Tabla: Tipos de papel soportados por PdfDocument 
Constante Tipo Papel  Descripción 
PAPER_A3  Tipo de papel A3 
PAPER_A4  Tipo de papel A4 
PAPER_A5  Tipo de papel A5 
PAPER_LEGAL  Tipo de papel oficio 
PAPER_LETTER  Tipo de papel carta 
 

28.5 API de PdfDocument

function  void  __construct($orientation=self::ORI_PORTRAIT,  $unit=self::UNIT_MM, 


$format=self::PAPER_A4) 
Es el constructor de PdfDocument. Por defecto se establece orientación vertical, medidas en 
milimetros y papel tipo A4. 
 
public function setEncoding($encoding) 
Establece  la  codificación  del  texto  de  entrada  a  métodos  como  writeCell,  writeText  y 
writeMultiCell.  
 
Las codificaciones soportadas son: 
Tabla: Tipos de codificaciones soportadas por PdfDocument 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    323 

Constante Codificación  Descripción 
ENC_ISO88591  Codificación ISO‐8859‐1 ó latin occidental. 
ENC_UTF8  Codificación Unicode UTF‐8 
ENC_ISO8022JP  Codificación Japonesa ISO‐8022‐JP 
 
function void setDebug(boolean $debug) 
Establece si el documento se genera en modo debug ó no. Por defecto es false. Si se envia el 
documento al navegador en modo debug se visualiza el formato interno del documento PDF. 
 
function void setMargins(integer $left, integer $top, integer $right=­1)  
Permite  establecer  las  margenes    del  documento  PDF.  El  primer  parámetro  es  la  margen 
izquierda, el segundo la superior y el tercero la derecha. Si no se indica el tercer parámetro la 
margen derecha queda igual a la izquierda. 
 
function void setLeftMargin(integer $margin) 
Establece la margen izquierda del documento PDF.  
 
function void setTopMargin(integer $margin)  
Establece la margen superior del documento PDF. 
 
function void setRightMargin(integer $margin)  
Establece la margen derecha del documento PDF. 
 
function void setAutoPageBreak(boolean $auto, integer $margin=0) 
Establece si se debe agregar una página automáticamente cuando se exceda el limite inferior 
al ir agregando registros. El parámetro $margin permite establecer la margen inferior donde 
se excede el limite de cada página. El comportamiento por defecto es que se haga el salto de 
página automáticamente. 
  
function void setDisplayMode(int $zoom, string $layout=1) 
Permite  establecer  el  tipo  de  visualización  del  documento  que  el  software  de  visualización 
debe tomar por defecto. Los posibles valores son constantes de la clase PdfDocument: 
 
Tabla: Tipos de zoom en documentos PDF 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    324 

Constante Zoom  Descripción 
LAYOUT_DEFAULT   Es  el  tipo  de  zoom  por  defecto  que  tenga  el  software  de 
visualización utilizado par ver el documento PDF. 
LAYOUT_CONTINUOUS  Indica que no se debe ver el páginado sino que una página 
se visualiza una tras otra como si estuvieran unidas. 
LAYOUT_SINGLE   Indica que se debe visualizar una página completa a la vez 
LAYOUT_TWO  Indica que se debe visualizar dos páginas completas a la vez. 
 
function void setCompression(boolean $compress)  
Indica  si  el  documento  PDF  debe  ser  comprimido  para  reducir  su  tamaño  final.  Para  usar  la 
opción de compresión es necesario que la extensión de php llamada zlib esté habilitada. 
 
function void setTitle(string $title)  
Establece el titulo del documento PDF. 
 
function void setSubject(string $subject)  
Establece el asunto del documento PDF. 
 
function void setAuthor(string $author)  
Establece el autor del documento PDF. 
 
function void setKeywords(string $keywords)  
Establece las palabras clave del documento PDF. 
 
function void setCreator(string $creator)  
Establece el creador del documento PDF. 
 
function void aliasNbPages(string $alias='{nb}')  
Establece  la  cadena  utilizada  para  reemplazar  el  número  de  página  total  de  un  documento 
PDF en encabezados y pie de página. 
 
function void open()  
Abre  el  documento  PDF.  Es  necesario  hacer  el  llamado  a  este  método  para  inicializar  el 
documento. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    325 

 
function void close()  
Cierra el documento PDF. 
 
function void addPage(int $orientation=PdfDocument::OR_PORTRAIT)  
Agrega  una  página  al  documento  PDF.  La  orientación  por  defecto  es  vertical.  Las  posibles 
orientaciones son: 
 
Tabla: Tipos de orientación de página soportadas por PdfDocument 
Constante Orientación  Descripción 
OR_PORTRAIT  Orientación vertical. 
OR_LANDSCAPE  Orientación horizontal. 
 
Es posible utilizar diferentes orientaciones en un mismo documento PDF. 
 
function integer getPageNumber()  
Obtiene el número de página actual. 
 
function void setDrawColor(integer $red, integer $green=­1, integer $blue=­1)  
function void setDrawColor(PdfColor $color) 
Establece  el  color  con  el  que  se  dibujarán  las  lineas  y  bordes  del  documento.  Este  método 
recibe 3 parámetros que corresponden a los niveles RGB del color deseado. Cada nivel es un 
entero  entre  0  y  255.  Adicionalmente  puede  recibir  un  objeto  PdfColor  con  el  color  a 
establecer.  Si  no  se  indican  valores  para  $green  y  $blue  se  utiliza  el  valor  definido  en  $red 
para estos. 
 
function void checkTTF(string $file) 
Consulta si un archivo de fuente TrueType permite ser embebido en documentos PDF. 
  
function void setFillColor(integer $red,  integer $green=­1,  integer $blue=­1)  
function void setFillColor(PdfColor $color) 
Establece  el  color  con  el  que  se  hará  el  relleno  de  cuadros  y  celdas  del  documento.  Este 
método recibe 3 parámetros que corresponden a los niveles RGB del color deseado. Cada nivel 
es  un  entero  entre  0  y  255.  Adicionalmente  puede  recibir  un  objeto  PdfColor  con  el  color  a 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    326 

establecer.  Si  no  se  indican  valores  para  $green  y  $blue  se  utiliza  el  valor  definido  en  $red 
para estos. 
 
function void setTextColor(integer $red, integer $green=­1, integer $blue=­1) 
function void setFillColor(PdfColor $color) 
Establece  el  color  de  los  textos  del  documento.  Este  método  recibe  3  parámetros  que 
corresponden  a  los  niveles  RGB  del  color  deseado.  Cada  nivel  es  un  entero  entre  0  y  255. 
Adicionalmente  puede  recibir  un  objeto  PdfColor  con  el  color  a  establecer.  Si  no  se  indican 
valores para $green y $blue se utiliza el valor definido en $red para estos. 
  
function double getStringWidth(string $s)  
Permite  obtener  el  tamaño  de  una  cadena  de  carácteres  de  acuerdo  a  la  fuente  activa  en  el 
documento. 
 
function void setLineWidth(integer $width)  
Establece el ancho de línea de la página activa del documento. 
 
function void drawLine(integer $x1, integer $y1, integer $x2, integer $y2)  
Permite dibujar una línea recta en la página activa del documento. 
 
function void drawRect(integer $x,  integer $y,  integer $w,  integer $h,  string $style='')  
Permite dibujar un cuadrado ó rectángulo en la página activa del documento. 
 
function void addFont(string $family, string $style='', string $file='')  
Agrega una fuente que no haga parte de las fuentes core. Las fuentes core son: Helvetica, arial, 
times, symbol y zapfdingbats. 
 
function void setFont(string $family, string $style='', integer $size=0)  
Establece la fuente activa en el  documento.  Si  es  una  fuente  core  puede  ser:  Helvetica, arial, 
times, symbol y zapfdingbats. Si es una fuente agregada con addFont se debe utilizar el mismo 
nombre para $family utilizado en ella. 
 
function void setFontSize(integer $size)  
Establece el tamaño de la fuente activa en puntos (pt). 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    327 

 
function void link(integer $x, integer $y, integer $width, integer $height, string $link)  
Agrega un enlace al documento PDF en las posiciones indicadas. 
 
function void writeText(integer $x, integer $y, string $txt)  
Agrega un texto  al documento PDF en las posiciones indicadas. 
 
function boolean acceptPageBreak()  
Indica  si  el  documento  tiene  el  salto  automático  de  página  al  superar  la  margen  inferior  de 
una página. 
 
function void writeCell(integer $w, integer $h=0, string $txt='', integer $border=0, integer $ln=0, 
string $align='', integer $fill=0, string $link='')  
Dibuja una celda en el documento PDF con los parámetros definidos. El parámetro $w indica 
el ancho de la celda, $h es el alto,  $txt es el texto, $border puede ser 1 ó 0 e indica si la celda 
debe  tener  un  borde  visible,  $ln  puede  ser  1  ó  0  e  indica  si  el  contenido  de  la  celda  es  un 
enlace, $fill puede ser 1 ó 0 e indica si la celda debe ser coloreada, $link es el enlace y aplica 
solo cuando $ln es 1. 
 
function  void  writeMultiCell(integer  $w,  integer  $h,  string  $txt,  integer  $border=0,  string 
$align=PdfDocument::ALIGN_JUSTIFY, integer $fill=0)  
 
function void write(integer $h,  string $txt,  string $link='')  
Agrega un texto al documento PDF en las coordenadas actuales. 
 
function  void  addImage(string  $file,  integer  $x,  integer  $y,  integer  $w=0,  integer  $h=0,  string 
$type='', string $link='')  
 
function void lineFeed(string $h='')  
Realiza un salto de línea en el documento aumentando la coordenada “y” y reiniciando “x” al 
valor del margen izquierdo. El tamaño opcional del salto de línea puede indicarse con $h. 
 
function integer getX()  
Devuelve  el  valor  de  la  coordenada  en  “x”  (horizontal)  donde  se  producirá  la  siguiente 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    328 

renderización de texto ó figuras del documento. 
 
function void setX(integer $x)  
Establece la coordenada en ”x” (horizontal) donde se producirá la siguiente renderización de 
texto ó figuras del documento. 
 
function float getY()  
Devuelve  el  valor  de  la  coordenada  en  “y”  (vertical)  donde  se  producirá  la  siguiente 
renderización de texto ó figuras del documento. 
 
function void setY(integer $y)  
Establece  la  coordenada  en  “y”  (vertical)  donde  se  producirá  la  siguiente  renderización  de 
texto ó figuras del documento. 
 
function void setXY(integer $x, integer $y)  
Establece  simultaneamente  las  coordenadas  en  “y”  (vertical)  y  “x”  (horizontal)  donde  se 
producirá la siguiente renderización de texto ó figuras del documento. 
 
function string outputDocument(string $name='', string $dest='')  
 
function string outputToBrowser() 
Envia  el  reporte  directamente  al  navegador.  El  desarrollador  debe  cerciorarse  que  otros 
contenidos no sean enviados junto con la salida ya que esto generará una excepción. 
 
function int getAvailableWidth()  
 
function void setFontPath(string $path)  
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    329 

29 Componente Report
29.1 Introducción

El  objetivo  del  componente  Report  es  crear  una  capa  de  abstracción  consitente  que  permita 
mediante  una  misma  API  crear  listados  ó  reportes  a  varios  formatos  aprovechando  las 
caracteristicas de cada uno sin requerir esfuerzo adicional. 
 
El  alcance  de  la  funcionalidad  de  este  componente  es  limitado  ya  que  cada  muchas  de  las 
características  de  un  tipo  de  formato  no  son  fácilmente  reproducibles  en  otros  y  viceversa. 
Reportes y listados de complejidad media con respecto a su presentación son la “audiencia” 
esperada de este componente. 

29.2 Alcance del componente

Las siguientes caracteristicas de presentación están soportadas en los reportes generados: 
 
• Paginación automática a tipo de papel “carta” (letter), A4 y oficio (“legal”). 
• Tablas con encabezados  
• Formato de colores, fuentes, sombreado, subrayado e italica a los textos 
• Bordes con ó sin colores en las tablas  
• Alineación de Texto Izquierda, Centro y Derecha 
 
Las siguientes caracteristicas funcionales estan soportadas en los reportes generados: 
 
• Encabezados y pie de página 
• Numeración de páginas 
• Encabezado de tablas con columnas por página 
• Sumatoría de campos por página y al final del reporte 
• Conteo de registros 

29.3 Adaptadores de Report

Los adaptadores de Report implementan una misma interfaz a un tipo de formato especifico 
de  tal  forma  que  la  presentación  de  un  listado  a  otro  en  otro  formato  no  varie 
considerablemente. 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    330 

Los  adaptadores  se  apoyan  el  librerias  externas  estables  para  generar  documentos  con  las 
caracteristicas requeridas por el desarrollador. 
 
Los siguientes adaptadores de tipos de formato se encuentran disponibles en el componente 
Report: 
 
Tabla: Adaptadores del componente Report 
Nombre  Ventajas  Desventajas  Librería 
Externa 
Html  ‐  Es  portable  a  cualquier  ‐  La  paginación  de  los  Ninguna 
navegador  resultados  no  es  muy 
‐  No  requiere  de  plugins  confiable 
adicionales  para  su  visualización  ‐  Los  datos  generados  no 
inmediata  son editables 
‐ Es rápido en la mayoría de casos  ‐  Dependiendo  del 
navegador  utilizado  la 
exportación  a  otras 
aplicaciones  puede  ser 
compleja 
Pdf  ‐  Los  reportes  generados  no  son  ‐  Dependiendo  de  la  PDFDocument 
modicables *  información  generada  los  de  Kumbia 
‐  La  presentación  es  la  misma  en  documentos  PDF  pueden  Enterprise 
cualquier plataforma  ser grandes ó muy grandes  basado  en 
‐  La  paginación  de  los  resultados  ‐  Requiere  de  aplicaciones  FPDF  
es óptima  ó plug‐ins extra 
‐  La  información  suele  ser 
complicada  de  exportar  a 
otras  aplicaciones  para  su 
analisis 
Excel  ‐  La  información  es  editable  y  da  ‐  El  formato  es  privativo  y  Excel  de 
libertad  al  usuario  de  ajustar  los  requiere de Microsoft Excel  Kumbia 
informes después de generados  para su visualización ó otra  Enterprise 
‐  Es  posible  analisar  datos  y  hoja  de  calculo  que  pueda  basado  en 
generar gráficas estadísticas  abrir  este  tipo  de  archivos  PEAR 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    331 

como OpenOffice  Spreadsheet 
‐  No  es  seguro  que  la  Excel_Writer 
información  no  sea 
alterada por terceros 
CSV  La información se puede exportar  No  permiten  formato  a  Ninguna 
a otras aplicaciones de terceros ó  textos  y  no  son  fáciles  de 
a una suite ofimatica  leer por un humano 
 

29.4 Paginación en reportes

FALTA 

29.5 Ejemplo de un listado usando Report

 
Ejemplo: Crear un listado usando Report 
<?php
class ListingController extends ApplicationController {
public function listReservationTypesAction(){
$this->getResponseInstance-
>setResponseType(ControllerResponse::RESPONSE_NO_LAYOUT);
ReportComponent::load(array("Text", "Style"));
// Para PDF
$report = new Report('Pdf');
// Para HTML
$report = new Report('Html');
$numeroPagina = new ReportText("%pageNumber%", array(
"fontSize" => 9,
"textAlign" => "right"
));
$titulo = new ReportText("REPORTE DE TIPOS DE RESERVA", array(
"fontSize" => 16,
"fontWeight" => "bold",
"textAlign" => "center"
));
$titulo2 = new ReportText("Fecha: ".date("Y-m-d H:i a"), array(
"fontSize" => 11,
"fontWeight" => "bold",
"textAlign" => "center"
));
$report->setHeader(array($numeroPagina, $titulo, $titulo2));
$report->setDocumentTitle("Reporte de Tipos de Reserva");
$report->setColumnHeaders(array("CODIGO", "DETALLE"));
$report->setCellHeaderStyle(new ReportStyle(array(
"textAlign" => "center",
"backgroundColor" => "#eaeaea"
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    332 

)));
$report->setColumnStyle(0, new ReportStyle(array("textAlign" =>
"center")));
$report->setColumnStyle(1, new ReportStyle(array("textAlign" =>
"center")));
foreach($this->ReservationType->find() as $tipoReserva){
$report->addRow(array($tipoReserva->getId(), $tipoReserva-
>getDetail()));
}
$report->outputToBrowser();
}
}

29.6 Modo Vista Previa

Cuando un reporte es generado a formato HTML es posible generar una salida de vista previa 
permitiendole al usuario navegar por el reporte en forma más efectiva. Esta presentación no 
es  apta  para  impresión  ya  que  contiene  colores  y  no  representa  lo  que  realmente  irá  a  la 
impresora. 
 
Para activar este modo de visualización se invoca el método setDisplayMode con el parámetro 
Report::DISPLAY_PRINT_PREVIEW en el objeto Report de esta forma: 
 
Ejemplo: Establecer modo de vista previa para reportes HTML 
<?php
// Para HTML
$report = new Report('Html');
$report->setDisplayMode(Report::DISPLAY_PRINT_PREVIEW);

Esta  opción  no  tiene  efecto  en  los  reportes  en  los  demás  formatos.  Un  ejemplo  de  la 
visualización de este modo es el siguiente: 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    333 

29.7 API de Report

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    334 

30 Componente Feed
30.1 Introducción

El objetivo del componente Feed es la lectura y generación de sindicación usando el formato 
RSS.    Los  documentos  RSS  generados  siguen  la  especificación  RSS  2.0  según  el  documento 
http://cyber.law.harvard.edu/rss/rss.html  de  la  universidad  de  Harvard  y 
http://www.rssboard.org/rss-specification .  

30.2 Leer/Importar documentos RSS

El  siguiente  ejemplo  muestra  como  leer  un  rss  desde  un  recurso  remoto,  la  ruta  también 
puede ser una archivo local: 
 
Ejemplo: Leer/Importar documentos RSS 
<?php
$feed = new Feed();
$feed->readRss('http://www.nytimes.com/services/xml/rss/nyt/World.xml');
foreach($feed->getItems() as $item){
print $feed->getTitle();
print $feed->getLink();
}

 
Una vez cargados los documentos pueden ser manipulados ó modificados de acuerdo a lo que 
se requiera. 

30.3 Crear documentos RSS

Este  componente  también  permite  la  creación  desde  cero  y  presentarlos  como  una  salida 
estándar de la petición. 
 
Ejemplo: Crear un documento de sindicación RSS 
<?php
class BlogController extends ApplicationController {
public function rssAction(){
$this->setResponse('rss');
$feed = new Feed();
$feed->setTitle('Corporate Blog');
$feed->setDescription('This is our corporate blog');
$feed->setLink('http://www.examplecompany.com/blog');
$feed->setLanguage('en-us');
foreach($this->Posts->find('order: created_at DESC') as $post){
$item = new FeedItem();
$item->setTitle($post->getTitle());
$item->setLink($post->getPermaLink());
$item->setDescription($post->getBody());
$feed->addItem($item);
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    335 

}
return $feed->getXMLFeed();
}
}

30.4 API de Feed

function void setTitle(string $title)  
Cambia/establece el título del recurso RSS. 
 
function void setDescription(string $description)  
Cambia/establece la descripción del recurso RSS. 
 
function void setLink(string $link) 
Cambia/establece el enlace al sitio ó aplicación que generó el recurso RSS. 
  
function void setLanguage(string $language)  
Cambia/establece  el  idioma  original  en  que  se  encuentra  el  contenido  del  recurso  RSS.  El 
idioma  debe  ser  estblecido  usando  el  formato  que  aparece  en  este  enlace: 
http://www.w3.org/TR/REC-html40/struct/dirlang.html#langcodes 
 
function void setTtl(string $ttl) 
Indica cada cuanto tiempo el cliente RSS debe reactualizar el recurso. 
  
function void setGenerator(string $generator) 
Permite cambiar/establecer el software utilizado para generar el contenido. 
  
function void setDocs(string $docs) 
Permite  establecer  un  enlace  en  donde  haya  documentación  sobre  el  formato  utilizado  para 
crear el recurso RSS. 
  
function void addItem(FeedItem $item)  
Agrega un objeto FeedItem a la lista de items del recurso RSS. 
 
function string getXMLFeed()  
Genera una versión XML apta para publicar el recurso RSS. 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    336 

function boolean readRss(string $url)  
Lee ó importa un recurso RSS desde una ubicación local ó remota.  
 
function boolean readRssString(string $rssString)  
Importa un recurso RSS apartir de un string con la descripción XML de el. Devuelve false en 
caso de que hayan errores en el formato ó sintaxís. 
 
function array getItems()  
Obtiene un array de objetos FeedItem con cada item del recurso. 
 

30.4.1 API de FeedItem 
El objetivo de la clase FeedItem es encapsular la información referente a cada item del recurso 
RSS de tal forma que pueda se manipulada de una forma orientada a objetos. 
 
function void setTitle(string $title) 
Establece el titulo del item. 
  
function string getTitle()  
Devuelve el titulo del item. 
 
function void setLink(string $link)  
Establece el enlace del item. 
 
function string getLink()  
Devuelve el enlace del item. 
 
function void setAuthor(string $author)  
Establece el autor del item. 
 
function string getAuthor() 
Devuelve el autor del item. 
  
function void setDescription(string $description)  
Establece la descripción del item. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    337 

 
function string getDescription()  
Devuelve la descripción del item. 
 
function void setGuid(string $guid)  
Establece el identificador único del item. 
 
function string getGuid()  
Devuelve el identicador único del item. 
 
function void setPubDate(string $pubDate)  
Establece la fecha de públicación del item. Esta debe indicarse usando formato RFC‐2822. 
 
function string getPubDate()  
Devuelve  la  fecha  de  públicación  del  item.  La  fecha  se  devuelve  en  formato  RFC‐2822.  El 
componente Date permite manipular las fechas desde este formato. 
 
function array getElementsAsArray()  
Obtiene  un  array  asociativo  con  la  información  del  item.  Los  indices  corresponden  a  los 
atributos del item. 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    338 

Núcleo e integración de componentes del framework 
 

31 Componente Core
31.1 Introducción

El componente Core actúa como integrador y orquestador de todas las operaciones ejecutadas 
en el Framework, además proporciona información sobre el entorno de ejecución a múltiples 
componentes. 

31.2 Jerarquía de Clases


31.2.1  Clase Object 
La  mayor  parte  de  las  clases  en  Kumbia  Enterprise  Framework  poseen  una  clase  superior 
llamada Object. Esta clase implementa el patrón Layer Supertype el cual permite implementar 
métodos que no puedan ser duplicados a lo largo de toda la implementación de componentes 
en el Framework. La clase Object se encuentra en Library/Kumbia/Object.php. 

31.2.2 CoreConfig 
Se  encarga  de  leer  los  archivos  de  configuración  de  las  aplicaciones  e  integrar  las  opciones 
definidas en ellos a los componentes del framework. 

31.2.3 CoreLocale 
Su objetivo es servir de puente entre los componentes de la aplicación y los componentes de 
localización e internacionalización. Cuando se genera una excepción este componente obtiene 
los mensajes localizados apropiados al desarrollador. 

31.2.4 CoreClassPath 
Mantiene un directorio de rutas a las clases del framework de tal forma que se pueda realizar 
la inyección de dependencia en la aplicación cuando sean requeridos. 

31.2.5 CoreRemote 
Ofrece información extendida sobre un entorno de ejecución remoto que permita determinar 
problemas localmente. 

31.3 Servicios del Componente Core


31.3.1 Obtener el Instance Name 
El nombre de la instancia se refiere al nombre lógico del grupo de aplicaciones instaladas en 
una misma distribución del framework. Adicional a lo anterior también se refiere al directorio 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    339 

donde se encuentra instalado el framework, este es importante es muchos aspectos.  

31.3.2  Zona Horaria de las Aplicaciones 
Kumbia Enterprise Framework permite establecer un parámetro de zona horaria general para 
todas  las  aplicaciones  dentro  de  una  misma  instancia.  Este  parámetro  se  encuentra  en  la 
sección core del archivo config/config.ini. 
 
Ejemplo: Establecer la zona horaria en el archivo config.ini 
[core]
defaultApp = default
timezone = "America/Bogota"
locale = "es_CO"
charset = “UTF-8”
 
En  el  manual  de  PHP  puede  encontrar  identificadores  validos  para  la  mayor  parte  de  zonas 
horarias de la tierra. 
 
En  tiempo  de  ejecución  puede  cambiar  la  zona  horaria  usando  el  método  estático 
Core::setTimeZone(string $timezone), si establece una zona invalida se generará una excepción 
CoreException. 

31.3.3 Cambiar el Charset de la aplicación 
Por defecto una aplicación en Kumbia Enterprise produce salidas usando codificación Unicode 
UTF‐8.  Para  que  toda  la  aplicación  utilice  un  mismo  charset  se  requiere  que  multiples 
aspectos estén sincronizados en este sentido. 
 
Servidor  Web:  La  salida  del  servidor  web  en  el  caso  de  Apache  Web  Server  es  establecida 
dinámicamente en el archivo public/.htaccess con la opción: 
 
AddDefaultCharset UTF-8
 
La vista principal: La vista principal de la aplicación proporciona el meta Content‐Type que 
debe ser establecida de la siguiente forma para definir el charset: 
 
<meta http-equiv='Content-type' content='text/html; charset=UTF-8' />
 
Archivos  XML:  La  primera  línea  del  encabezado  de  un  archivo  XML  también  debe  ser 
cambiada para reflejar el cambio del charset. 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    340 

<?xml version="1.0" encoding="UTF-8" ?>


 
Bases de datos: Los motores de base de datos como MySQL ó Oracle permiten establecer la 
codificación  en  que  se  almacenan  y  devuelven  los  datos  en  las  tablas.  Consulte  la 
documentación del motor utilizado para aprender como modificar la codificación por defecto. 
 
JavaScript:  Los  archivos  javascript  deben  estar  guardados  con  la  codificación  correcta  sin 
embargo  la  etiqueta  SCRIPT  puede  ser  establecida  de  la  siguiente  forma  para  ayudar  al 
navegador a determinar el charset correcto: 
 
<script src="/instante/javascript/menu.js" type="text/javascript" charset="utf-
8"></script>
 
CSS:  En  los  recursos  CSS  es  posible  usar  establecer  la  codificación  del  archivo  también  para 
ayudar al navegador a un major reconocimiento de la misma así: 
 
@charset "utf-8";
 

31.3.4 Cambiar la localización por defecto 
Es  posible  cambiar  la  localización  por  defecto  usando  el  método  Locale::setDefault  esto 
afectará todas las operaciones realizadas con los componentes de internacionalización como 
lo son Date, Traslate y Currency. 
 
Ejemplo: Cambiar la localización por defecto programacionalmente 
<?php Locale::setDefault(“es_ES”) ?>
 

31.3.5  Obtener la versión del Framework 
La  constante  Core::FRAMEWORK_VERSION  permite  obtener  la  versión  del  framework 
utilizado. Puede utilizar este valor para separar la compatibilidad de sus aplicaciones cuando 
actualice el framework y se presenten inconvenientes. 
 
Ejemplo:  Comparar  la  compatibilidad  de  una  aplicación  usando 
Core::FRAMEWORK_VERSION 
<?php
if(version_compare(Core::FRAMEWORK_VERSION, "1.0", ">=")){
//La versión del framework es mayor ó igual a la 1.0
}
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    341 

31.4 Subcomponente CoreConfig


El subcomponente CoreConfig permite leer la configuración de las aplicaciones y convertirlas 
en valores nativos de PHP para su uso en procesos de la aplicación.  
 
CoreConfig  puede  leer  en  forma  sencilla  archivos  de  configuración  de  la  instancia,  de  la 
aplicación actualmente en ejecución y de otras aplicaciones. 

31.4.1 API del subcomponente CoreConfig 
static public void function setAdapter($adapterName) 
Permite establecer el tipo de adaptador del componente Config debe ser usado para leer los 
archivos  de  configuración  de  la  aplicación.  Este  cambio  debe  ser  hecho  en  el  boostrap  de  la 
instancia y afectará a todas las aplicaciones en ella. 
 
static public Config  function read(string $path, string $adapter) 
Lee  un  archivo  de  configuración  mediante  su  path.  El  path  absoluto  por  defecto  es  el 
directorio  raíz  de  la  instancia  del  framework.  El  parámetro  $adapter  indica  el  tipo  de 
adaptador del componente Config debe ser usado para leer el archivo. 
 
static public Config function readAppConfig($applicationName=””) 
Lee el archivo “config” (normalmente config.ini) de la aplicación activa devolviendo un objeto 
Config.  Las  secciones  del  archivo  .ini  son  procesadas  y  devueltas  como  propiedades  objetos 
del objeto. Si no se establece el parámetro $applicationName entonces se lee de la aplicación 
actual. 
 
static public Config function readBootConfig() 
Lee  el  archivo  boot.ini  (normalmente  boot.ini)  de  la  aplicación  activa  devolviendo  un  objeto 
Config.  Las  secciones  del  archivo  .ini  son  procesadas  y  devueltas  como  propiedades  objetos 
del objeto. 
 
static public Config function readEnviroment() 
Lee el archivo environment de la aplicación activa. Los valores del entorno actual pueden ser 
accedidos directamente en el objeto Config devuelto, los demás entornos se acceden mediante 
una propiedad del objeto. 
 
public static Config function getConfigurationFrom(string $applicationName, string $file) 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    342 

Devuelve  la  configuración  en  un  archivo  ubicado  en  una  aplicación  especifica.  Este  archivo 
debe estar ubicado en el directorio config/ de la aplicación. 
 
public static function readFromActiveApplication(string $file, string $adapter=’’) 
Lee  un  archivo  ubicado  el  directorio  config/  de  la  aplicación  que  está  actualmente  en 
ejecución. El parámetro $adapter indica el tipo de adaptador del componente Config debe ser 
usado para leer el archivo 

31.5 Subcomponente CoreClassPath

Gran  parte  de  los  componentes  y  subcomponentes  en  Kumbia  Enterprise  son  cargados 
mediante  inyección  de  dependencia  usando  autoload.  Gracias  a  esto  se  reduce 
considerablemente  la  lectura  de  disco  obteniendo  lo  que  se  requiere  en  forma  dinámica  a 
medida que es solicitado por la aplicación. 
 
El  ClassPath  es  un  directorio  interno  que  almacena  las  ubicaciones  de  las  clases  y 
componentes para su posterior inyección cuando son requeridos. Por motivos de rendimiento 
no todos los componentes son inyectados sobre todo los que funcionan como integradores y 
los que atienden la petición.  
 
En subcomponente CoreClassPath ofrece una interfaz de aplicación para la administración del 
directorio  de  clases  permitiendo  agregar,  cambiar  ó  eliminar  entradas  facilitando  la 
modificación del comportamiento del framework. 

31.5.1 Reemplazar un componente del Framework 
Es  posible  reemplazar  un  componente  del  framework  cambiando  la  ruta  del  directorio  de 
clases a la del nuevo componente. La única restricción es utilizar el mismo nombre de la nueva 
clase en el componente utilizado. 
 
En  el  siguiente  ejemplo  se  muestra  como  reemplazar  el  componente  de  localización  de 
Kumbia  Enterprise  por  uno  de  la  aplicación.  Notese  que  la  extensión  .php  del  archivo  es 
omitida a propósito: 
 
Ejemplo: Reemplazar la ruta de una clase a otra definida por el usuario 
<?php
CoreClassPath::replacePath('Locale', 'apps/my-app/library/Locale/Locale');
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    343 

 
El  path  asignado  no  es  comprobado  por  el  framework  por  lo  que  debe  cerciorarse  que  este 
exista y que el archivo contenga la clase solicitada. 

31.5.2 API de CoreClassPath 
static public function lookupClass(string $className) 
Permite consultar si una clase existe en el directorio de clases. 
 
static public function getClassPath(string $className) 
 Permite consultar la ruta existente en el framework para una determinada clase. 
 
static public function addToPath(string $className, string $path) 
Agrega una nueva ruta al directorio de clases. Si esta ya existe no se reemplaza. 
 
static public function replacePath(string $className, string $path) 
Reemplaza una entrada en el directorio de clases. 
 

31.6 Subcomponente CoreType


El  subcomponente  CoreType  permite  realizar  aserciones  sobre  los  parámetros  recibidos  en 
diferentes componentes del framework asegurando que se recibe el tipo de dato adecuado. El 
trabajo de este subcomponente es fundamental para asegurar en gran medida procesos más 
confiables  y  seguros.  Cuando  las  aserciones  fallan  se  lanza  una  excepción  tipo 
CoreTypeException. 

31.6.1 API de CoreType 
static function void assertNumeric(int $var)  
Realiza una aserción sobre un valor numérico 
 
static function void assertBool(bool $var)  
Realiza una aserción sobre un valor booleano 
 
static function void assertString(string $str)  
Realiza una aserción sobre un valor de cadena de caracteres. 
 
static function void assertArray(array $var)  
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    344 

Realiza una aserción sobre un valor array. 
 
static function void assertResource(resource $var)  
Realiza una aserción sobre una variable de recurso. 
 
static function void assertObject(object $var)  
Realiza una aserción sobre un objeto. 

31.7 Crear Plugins de Aplicación

La  arquitectura  de  plugins  de  Aplicaciones  permite  observar,  extender  y  manipular  el 
comportamiento de la aplicación según como las condiciones lo exijan. 
 
Los  plugins  permiten  interceptar  eventos  de  la  aplicación  de  tal  forma  que  estos  sean 
observables  y  además  ejecutárse  uno  tras  otro  de  manera  centralizada  sin  requerir 
refactorización ó reintegración en la aplicación. 

31.7.1 Crear un Plugin de Aplicación 
Los plugins son clases que implementan eventos generales que son invocados a medida que el 
flujo de vida  de una aplicación  avanza  en  una  sesión  de  usuario.  Estas  clases  deben  cumplir 
con los siguientes requerimientos: 
 
  Deben  estar  ubicados  en  el  directorio  de  plugins  usualmente  apps/app­name/plugins  ó 
donde la variable pluginsDir indique. 
  El nombre del archivo que implementa la clase debe ser el nombre del plugin 
  El nombre de la clase debe tener la extensión Plugin 
  Los  plugins  de  controlador  deben  heredar  de  la  clase  ApplicationPlugin  ó  ser  subclase  de 
ella 
 
Las  clases  pueden  implementar  métodos  públicos  que  referencian  los  eventos  ocurridos  en 
los controladores, la lista de ellos es la siguiente: 
 
Tabla: Eventos que se pueden implementar en plugins de Aplicación 
Nombre Evento  Descripción 
beforeStartApplication  Ocurre en la primera petición a la aplicación antes de invocarse 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    345 

el método de ControllerBase onStartApplication 
afterStartApplication  Ocurre  en  la  primera  petición  a  la  aplicación  después  de 
invocarse el método de ControllerBase onStartApplication 
beforeChangeInstance  Ocurre cuando en una misma sesión de usuario se cambia a otra 
instancia del framework en el mismo servidor de aplicaciones. 
afterChangeInstance  Ocurre  después  de  ejecutarse  el  método  de  ControllerBase 
llamado onChangeInstance. 
beforeStartRequest  Ocurre  antes  de  iniciar  empezar  a  atender  una  petición 
realizada a la aplicación. 
beforeFinishRequest  Ocurre  cuando  se  termina  de  atender  la  petición  realizada  a  la 
aplicación. 
beforeUncaughtException  Ocurre  antes  de  lanzarse  una  excepción  que  no  fue  capturada 
por la aplicación. 
onControllerException  Ocurre cuando se genera una excepción dentro del controlador. 
Se ejecuta antes de beforeUncaughException 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    346 

32 Componente PluginManager
32.1 Introducción

Este  componente  permite  administrar  los  plugins  cargados  en  una  aplicación  facilitando    el 
agregar ó quitar dinámicamente plug‐ins. 

32.2 Arquitectura de Plug-Ins

Kumbia Enterprise Framework proporciona una arquitectura de Plug‐Ins flexible que permite 
notificar y registrar eventos desde los diferentes componentes del framework.  

32.3 Autoinicialización de Plug-Ins

Por  defecto  los  plug‐ins  encontrados  en  el  directorio  de  plugins  son  cargados 
automáticamente por el administrador de plug‐ins.  Cuando hay muchos plug‐ins ó estos no 
son usados frecuentemente entre peticiones pueden causar un deterioro en el rendimiento de 
la aplicación. 
 
En  el  archivo  config/config.ini  es  possible  configurar  que  los  plug‐ins  no  sean  cargados 
automáticamente sino que tengan que ser cargados programacionalmente asi: 
 
Ejemplo: Hacer que los plug­ins no sean cargados automáticamente 
[plugins]
autoInitialize = Off
 
En este caso es necesario registrar los plugins que se vayan a utilizar en tiempo de ejecución. 

32.4 API de PluginManager

static function boolean initializePlugins() 
Inicializa  los  plugins  cargados  separandolos  de  acuerdo  a  su  naturaleza:  De  controlador, 
modelos, vistas y aplicación. No debería ser invocado por el desarrollador ya que es llamado 
automáticamente por el contenedor de aplicaciones. 
 
static function array loadApplicationPlugins()  
Carga  los  plugins  almacenados  en  el  directorio  plugins  ó  el  indicado  en  la  variable  de 
configuración pluginsDir. 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    347 

static function array getPlugins() 
Obtiene un array con todas las instancias de los plugins registrados en la petición actual. 
  
static function array getControllerPlugins()  
Obtiene  un  array  con  todas  las  instancias  de  los  plugins  de  controlador  registrados  en  la 
petición actual. 
 
static function array getModelPlugins()  
Obtiene un array con todas las instancias de los plugins de modelos registrados en la petición 
actual. 
 
static function array getViewPlugins()  
Obtiene  un  array  con  todas  las  instancias  de  los  plugins  de  presentación  registrados  en  la 
petición actual. 
 
static function void notifyFromApplication(string $event) 
Permite notificar a los plug‐ins de aplicación sobre un evento determinado $event. 
  
static function void notifyFromController(string $event, Controller $controller)  
Permite notificar a los plug‐ins de controlador sobre un evento determinado $event. 
 
static function void notifyFromView(string $event, ControllerResponse $controllerResponse)  
Permite notificar a los plug‐ins de presentación sobre un evento determinado $event. 
 
static function void notifyFrom(string $component, string $event, string $reference)  
Permite notificar a los plug‐ins de componentes sobre un evento determinado $event. 
 
static function void registerControllerPlugin(ControllerPlugin $plugin)  
Permite registrar un objeto como plugin de controlador. Solo los eventos producidos despues 
de realizar el registro del plugin de controlador. 
 
static function void registerApplicationPlugin(ApplicationPlugin $plugin)  
Permite registrar un objeto como plugin de controlador. Solo los eventos producidos despues 
de realizar el registro del plugin de aplicación. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    348 

 
static function void registerViewPlugin(ViewPlugin $plugin) 
Permite  registrar  un  objeto  como  plugin  de  presentación.  Solo  los  eventos  producidos 
despues de realizar el registro del plugin de presentación. 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    349 

Parte 5: Internacionalización y Localización 
 

33 Internacionalización y Localización
33.1 Introducción

Las  actuales  infraestructuras  de  computación  ofrecen  localización  de  tal  forma  que  un 
determinado usuario pueda efectuar operaciones de negocio adecuadamente. Los objetivos de 
la localización van mucho más allá de que la presentación este traducida a múltiples idiomas, 
además  de  esto  se  requiere  adaptar  fechas,    formatos  de  moneda,  hora,  respuestas,  saludos, 
etc. 
 
Los  componentes  Locale,  Traslate,  Date  y  Currency  ofrecen  la  funcionalidad  necesaria  para 
implementar aplicaciones de negocio localizadas. 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    350 

34 Componente Locale
34.1 Introducción

El  componente  Locale  permite  obtener  y  establecer  información  de  localización  en 
aplicaciones  sobre  datos  especificos  geográficos,  políticos,  culturales  ó  regionales. 
Actualmente es posible obtener información de 381 localizaciones.   

34.2 Definir la localización en una sesión de Usuario

Kumbia  Enterprise  permite  establecer  la  localización  por  sesión,  esta  es  definida  usando  un 
identificador  de  localización  que  sigue  el  formato  idioma_REGION.  Por  ejemplo  es_CO 
representa la localización para idioma español y país Colombia. Un listado de las cadenas de 
localización  puede  ser  encontrado  en: 
http://unicode.org/cldr/data/diff/supplemental/languages_and_territories.html. 
 
El  componente  Locale  utiliza  localización  independiente  de  la  plataforma  y  que  es  segura 
cuando se usa en entorno multi­thread como lo son los servidores web modernos. El uso de la 
función  setlocale  podría  producir  resultados  inesperados  si  se  usan  aplicaciones  con 
diferentes localizaciones en un mismo proceso del servidor de aplicaciones. 
 
La localización general se establece usando el método estático Locale::setLocale(string $locale) 
pasando como parámetro un identificador: 
 
Ejemplo: Crear un objeto Locale usando una cadena  de localización 
$locale = new Locale(‘es_CO’);
 
En  caso  de  pasarse  un  identicador  no  valido,  este  es  recortado  hasta  que  sea  valido.  Por 
ejemplo: 
 
Ejemplo: Obtener una localización válida al pasar una cadena incorrecta 
$locale = new Locale(‘es_XX’); //Es recortado a localización ‘es’
 
Una instancia de la clase Locale es devuelta al definir la localización. 

34.2.1 Obtener la localización adecuada 
La  localización  puede  ser  obtenida  de  3  formas,  del  navegador  del  cliente,  del  archivo  de 
configuración de la aplicación activa ó del entorno de ejecución de la aplicación. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    351 

34.2.1.1 Leer la localización del navegador 
La localización es leida de la variable de la petición HTTP_ACCEPT_LANGUAGE. La que tenga 
mayor calidad es la que se devuelve: 

Ejemplo: Leer la cultura del usuario final según el navegador 
$browserLocale = Locale::getBrowser();
 
Todas  las  localizaciones  soportadas  por  el  cliente  HTTP  pueden  ser  obtenidas  usando 
Locale::getBrowserAll(). Cada localización incluye un vector con idioma, region y calidad.  

34.2.1.2 Leer la localización del entorno de ejecución 
La localización es leida del valor establecido por la función setlocale en el mismo proceso de 
ejecución actual. 
 
Ejemplo: Obtener la localización según el entorno de ejecución de la aplicación 
$environLocale = Locale::getEnvironment();
 
Todas  las  localizaciones  del  entorno  de  ejecución  pueden  ser  obtenidas  usando 
Locale::getEnviromentAll(). Cada localización incluye un vector con idioma, region y calidad.  

34.2.1.3 Leer la localización de la configuración de la aplicación 
La variable de configuración ‘locale’ puede ser establecida tanto en el archivo config.ini de la 
aplicación como el de la instancia: 
 
Ejemplo: Obtener la localización según la configuración de la aplicación 
$applicationLocale = Locale::getApplication();

34.3 Establecer la localización por defecto

Cuando la localización no es establecida bajo ninguno de los parámetros anteriores se usa el 
valor por defecto. El método de locale setDefault permite establecer esto. 
 
Ejemplo: Cambiar la localización por defecto en forma programacional 
// Localización por defecto para Español/Venezuela
Locale::setDefault(‘es_VE’);

34.4 Obtener traducciones localizadas

El  objeto  locale  implementa  traducciones  localizadas  para  diversos  criterios  de  acuerdo  al 
idioma y país. En el siguiente ejemplo se muestra como obtener la traducción para ‘SI’ y ‘NO’ 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    352 

en Francés y Japónes: 
 
Ejemplo: Obtener traducciones localizadas para diferentes culturas 
<?php
//Mostrar las traducciones de ‘SI’ y ‘NO’ en Francés
$locale = new Locale('fr_FR');
print $locale->getYesString()."\n"; // Imprime “oui”
print $locale->getNoString(); // Imprime “non”
 
//Mostrar las traducciones de ‘SI’ y ‘NO’ en Japonés
$locale = new Locale('ja_JP');

print $locale->getYesString()."\n"; // Imprime “はい


print $locale->getNoString(); // Imprime “いいえ

34.5 API del Componente Locale

function void __construct($locale)  
Constructor  del  objeto  locale.  El  parámetro  $locale  puede  ser  un  string  de  identificación  de 
localización ó otro objeto Locale del cuál se tomará sus propiedades de localización. 
 
Ejemplo: Crear objetos de Localización 
$locale = new Locale(‘en_US’);
$copyLocale = new Locale($locale);
 
function boolean hasCountry()  
Permite  consultar  si  una  localización  tiene  un  territorio  ó  país  válido.  Algunas  funciones 
generarán excepciones si se trata consultar datos del territorio y este no se ha definido. 
 
Ejemplo: Uso de Locale::hasCountry 
$locale = new Locale(‘en_US’);
$locale->hasCountry(); // true
$locale = new Locale(‘es’);
$locale->hasCountry(); // false
 
function void setCountry(string $country) 
Permite cambiar/establecer el territorio ó país de la localización.  Al utilizarse este método el 
conjunto  idioma/territorio  es  validado  nuevamente  para  comprobar  que  es  una  localización 
válida. 
 
Ejemplo: Uso de Locale::setCountry 
$locale = new Locale(‘es’);
$locale->hasCountry(); // false
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    353 

$locale->setCountry(‘AR’);
$locale->getLocaleString(); // es_AR
$locale->hasCountry(); // true
 
function string getLanguage() 
Obtiene el idioma definido en la localización. 
 
Ejemplo: Uso de Locale::getLanguage 
$locale = new Locale(‘en_US’);
$locale->getLanguage(); // en
  
function string getCountry()  
Obtiene el país/territorio en la localización. 
 
Ejemplo: Uso de Locale::getCountry 
$locale = new Locale(‘en_US’);
$locale->getLanguage(); // US
 
function string|array getYesString($all=false)  
Obtiene  la  traducción  para  ‘Si’  según  la  localización  activa.  Por  defecto  devuelve  la  primera 
traducción  para  ‘Si’,  en  caso  de  que  se  pase  true  como  segundo  parámetro  entonces  se 
devuelve un array con todas las posibles traducciones. 
 
Ejemplo: Uso de Locale::getYesString 
$locale = new Locale(‘es_ES’);
$locale->getYesString(); // Array ( [0] => sí [1] => si [2] => s )
 
function string getNoString($all=false) 
Obtiene la traducción para ‘No’ según la localización activa. Por defecto devuelve la primera 
traducción  para  ‘No’,  en  caso  de  que  se  pase  true  como  segundo  parámetro  entonces  se 
devuelve un array con todas las posibles traducciones. 
 
Ejemplo: Uso de Locale::getNoString 

//No en alemán
$locale = new Locale(‘de_DE’);
$locale->getNoString(); // Array ( [0] => nein [1] => n )

function array getMonthList()  
Obtiene un array con los nombres completos de los meses según la localización del objeto. Los 
indices de los meses empiezan en 0. 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    354 

Ejemplo: Uso de Locale::getMonthList 

//Lista de meses en francés


$locale = new Locale(‘fr_FR’);
$locale->getMonthList(); // Array ( [0] => janvier [1] => février [2] => mars
[3] => avril [4] => mai [5] => juin [6] => juillet [7] => août [8] => septembre
[9] => octobre [10] => novembre [11] => décembre )
 
function array getAbrevMonthList() 
Obtiene  un  array  con  los  nombres  abreviados  de  los  meses  según  la  localización  del  objeto. 
Los indices de los meses empiezan en 0.  
  
function array getDaysNamesList() 
Obtiene un array con los nombres completos de los días de la semana según la localización del 
objeto. Los indices de los meses empiezan en 0.  
 
function array getAbrevDaysNamesList()  
Obtiene un array con los nombres abreviados de los días de la semana según la localización 
del objeto. Los indices de los meses empiezan en 0.  
 
function string getDateFormat(string $type='full') 
Obtiene  el  formato  de  fecha  a  aplicar  según  el  tipo  en  la  localización  actual.  Los  posibles 
valores para $type son: full (completo), long (largo), medium (mediano) y short (corto).   
 
Ejemplo: Uso de Locale::getDateFormat 

//Formatos de fecha ISO válidos para Español de México


$locale = new Locale(‘es_MX’);
$locale->getDateFormat(); // EEEE d 'de' MMMM 'de' yyyy
$locale->getDateFormat(‘long’); // d 'de' MMMM 'de' yyyy
$locale->getDateFormat(‘medium’); // dd/MM/yyyy
$locale->getDateFormat(‘short’); // dd/MM/yy
 
function string getLanguageString() 
Obtiene la traducción para la palabra “idioma” de acuerdo a la localización actual. 
  
function string getCurrencyFormat() 
Devuelve el formato ISO monetario utilizado según la localización. 
  
function array getCurrency(string $codeISO=null, string $displayType='') 
  
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    355 

function boolean isDefaultLocale() 
Permite consultar si el objeto Locale actual corresponde a la localización actual. 
  
static function void setDefault(string $locale)  
Establece la localización por defecto de la aplicación programacionalmente. Este valor no es 
almacenado en sesión y debe indicarse en cada petición en que aplique. 
 
static function array getLocale(string $localeValue)  
Crea  array  de  información  de  localización  y  comprueba  que  este  sea  válido  a  partir  de  su 
identificador de localización. 
 
static function array getEnvironmentAll()  
Devuelve todas las posibles identificadores de localización según el entorno de ejecución de la 
aplicación. 
 
static function Locale getEnviroment() 
Devuelve un objeto Locale apartir de la localización obtenida según el entorno de ejecución de 
la aplicación.  
 
static function array getBrowserAll()  
Obtiene un array con todos los posibles identificadores de localización y su calidad según el 
explorador del cliente. 
 
Ejemplo:  Obtener  las  localizaciones  admitidas  por  el  navegador  con 
Locale::getBrowserAll 
Locale::getBrowserAll() ; //Array ( [0] => Array ( [locale] => es_es [country]
=> ES [language] => es [quality] => 1 ) )
 
static function Locale getBrowser()  
Obtiene  un  objeto  de  localización  según  el  identificador  de  localización  de  mayor  calidad 
enviado por el explorador. 
 
static function Locale getApplication()  
Obtiene la localización que esta configurada en el archivo config (config.ini normalmente) de 
la aplicación. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    356 

 
static function void setApplication(Locale $locale)  
Establece programacionalmente la localización por defecto de la aplicación. 
 
function string getLocaleString()  
Obtiene el identificador de localización con el que se creo el objeto Locale. 
 
function string __toString()  
Método mágico que al convertir el objeto a string devuelve el identificador de localización con 
el que se creó el objeto Locale. 
 
Nota: Es posible que el componente Locale haga conflicto con la extensión Intl del repositorio 
PECL así que es reconmendable desactivarla. El componente Locale reemplaza y extendiende  
funcionalidad de esta extensión por lo que no requerirá de ella. 

34.6 Subcomponente LocaleMath

Este  subcomponente  permite  realizar  operaciones  matemáticas  de  alta  precisión  que  son 
usadas para trabajar con fechas con timestamp por fuera del rango del admitido por el tipo de 
máquina donde se ejecuta la aplicación y que también pueden ser usados por el desarrollador 
en sus aplicaciones. 
 
LocaleMath  requiere  que  la  extensión  php_bcmath  este  habilitada  de  lo  contrario  las 
operaciones realizadas se ejecutaran usando las capacidades matemáticas normales de PHP. 
Para  todos  los  métodos  de  LocaleMath  las  sumas  deberían  establecerse  usando  cadenas  de 
caracteres para evitar que el interprete php las convierta en enteros. 
 

34.6.1 API de LocaleMath 
static function string add(double $value1, double $value2, int $scale=0)  
Realiza  una  operación  aritmética  de  suma  de  alta  precisión.  El  resultado  final  puede  ser 
redondeado usando el parámetro $scale. 
 
static function string mul(string $value1, string $value2, int $scale=0) 
Realiza  una  operación  de  multiplicación    con  alta  precisión.  El  resultado  final  puede  ser 
redondeado usando el parámetro $scale. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    357 

 
  
static function string sub(string $value1, string $value2, int $scale=0) 
Realiza  una  operación  aritmética  de  resta  con  alta  precisión.  El  resultado  final  puede  ser 
redondeado usando el parámetro $scale. 
  
static function string div(string $value1, string $value2, int $scale=0)  
Realiza  una  operación  aritmética  de  división  de  alta  precisión.  El  resultado  final  puede  ser 
redondeado usando el parámetro $scale. 
 
static function string mod(string $value1, string $value2) 
Realiza  una  operación  aritmética  de  suma  de  alta  precisión.  El  resultado  final  puede  ser 
redondeado usando el parámetro $scale. 
  
static function int cmp(string $value1, string $value2, int $scale=0) 
Realiza  una  operación  aritmética  de  comparación  de  alta  precisión.  El  resultado  final  puede 
ser  redondeado  usando  el  parámetro  $scale.  Si  el  valor  devuelto  es  0  indica  que  los  valores 
enviados son iguales, ‐1 cuando el $value1 es menor a $value2 y 1 en caso contrario. 
  
static function string round(string $value, int $precision=0) 
Redondea un valor usando alta precisión. Se recomienda altamente el uso de este método en 
vez  de  la  función  de  php  round.    El  número  de  decimales  del  resultado  redondeado  se 
establece con $precision. 
 
static function void disableBcMath()  
Deshabilita  el  uso  de  la  extensión  bc_math  para  realizar  las  operaciones  aritméticas  de  alta 
precisión. 
 
static function void enableBcMath()  
Habilita  el  uso  de  la  extensión  bc_math  para  realizar  las  operaciones  aritméticas  de  alta 
precisión.  El  valor  no  queda  activado  durante  el  transcurso  de  la  sesión  sino  solamente 
durante la ejecución de la petición donde se haga el llamado. 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    358 

35 Componente Traslate
35.1 Introducción

El  componente  Traslate  permite  la  creación  de  aplicaciones  multi‐idioma  usando  diferentes 
adaptadores para obtener las listas de traducción. La clase implementa el patrón Proxy para 
acceder a la funcionalidad de los adaptadores de manera uniforme. 

35.2 Adaptadores soportados por Traslate

Los siguientes adaptadores son soportados por este componente:  
 
Tabla: Tipos de adaptadores soportados por Traslate 
Tipo Formato  Descripción 
Array  Utiliza  arrays  nativos  de  PHP  para  almacenar  las  listas  de  traducción.  Las 
llaves son utilizadas para acceder al valor traducido. 
CSV  Utiliza  archivos  separados  por  comas.  El  primer  campo  representa  la  llave 
de traducción y el segundo la traducción en sí. 
INI  Utiliza archivos .ini. La traducción se establece normalmente como variables 
y su valor es la traducción. 
Database  Utiliza una tabla para almacenar el diccionario de traducción. 

35.3 Como funciona la traducción

Independientemente del adaptador utilizado, el proceso de traducción sigue estos principios: 
 
  Los recursos de traducción deben estar disponibles y mantener una estructura consistente 
de tal forma que sea posible cargar uno el otro dependiendo de la localización activa.  
 Los  diccionarios  de  traducción  deben  tener  una  clave  y  un  valor,  en  donde  la  clave  es  un 
código  interno  ó  convención  que  usa  el  desarrollador  para  acceder  a  los  valores  de 
traducción.  Las  claves  deben  ser  las  mismas  para  cada  diccionario  de  traducción  de  esta 
forma es posible obtener los valores consistentemente. 
  El  tipo  de  idioma  a  utilizar  debe  ser  cargado  por  el  desarrollador.  El  componente  Locale 
permite  obtener  mediante  varios  métodos  el  lenguaje  más  adecuado  dependiendo  de  los 
requerimientos de negocio de la aplicación. 
 Una  vez  completados  los  pasos  anteriores  se  instancia  la  clase  Traslate  indicando  en  el 
primer parámetro del constructor el tipo de adaptador a usar, seguido de este las opciones 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    359 

del mismo. 
 El  recurso  cargado  en  el  objeto  Traslate  contiene  las  traducciones  para  la  sesión  activa.  El 
uso del método $traslate‐>_(string $key) permite acceder a los valores de traducción siendo 
$key la llave de indexación del diccionario. 
 El  desarrollador  debe  controlar  que  el  objeto  traslate  este  creado  y  disponible  para  cada 
vista multi‐idioma en la aplicación. 

35.4 Utilizar traducciones

El componente Traslate carga los datos de traducción del adaptador indicado y luego permite 
obtener  las  traducciones.  En  el  siguiente  ejemplo  se  muestra  como  crear  el  objeto  de 
traducción en cada petición a un controlador: 
 
Ejemplo: Cargar la lista de traducción según la cultura obtenida del navegador 
<?php
class NewsController extends ApplicationController {
private function _loadTraslation(){
$locale = Locale::getBrowser();
$language = $locale->getLanguage();
$path = "apps/myapp/languages/$language/LC_MESSAGES/messages.php";
require $path;
$traslate = new Traslate(‘Array’, $messages);
$this->setParamToView("traslate", $traslate);
}
public function beforeFilter(){
$this->_loadTraslation();
}
}
 
En cada petición al controlador la variable $traslate es transferida a la presentación para su 
uso: 
 
Ejemplo: Obtener las traducciones mediante las llaves definidas 
<?php echo $traslate->_(“home”) ?>
<?php echo $traslate->_(“exit”) ?>
 
Si el archivo “es/LC_MESSAGES/messages.php” tiene el siguiente diccionario: 
 
<?php $messages = array(“home” => “Inicio”, “exit” => “Salir”) ?>
 
y el archivo “en/LC_MESSAGES/messages.php” tiene el siguiente diccionario: 
 
<?php $messages = array(“home” => “Home”) ?>
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    360 

 
Entonces  se  produce  la  salida  respectiva  para  los  idiomas  español  e  inglés:  “Inicio  Salir”    y 
“Home exit”. 

35.4.1 Consideraciones para el adaptador Array 
Como se explicó este adaptador utiliza arrays nativos de PHP para almacenar los diccionarios 
de traducción. Se recomienda el uso de este adaptador ya que ofrece el mejor rendimiento en 
la mayoría de los casos.  

35.4.2 Consideraciones para el adaptador Csv 
El adaptador CSV permite cargar las listas de traducción desde archivos CSV (seperados por 
comas) FALTA. 

35.4.3 Consideraciones para el adaptador Ini 
El adaptador INI permite cargar las listas de traducción desde archivos INI FALTA. 

35.4.4 Consideraciones para el adaptador Database 
El adaptador Database permite cargar las listas de traducción desde una tabla en la base de 
datos. FALTA 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    361 

36 Componente Date
36.1 Introducción

El componente Date esta diseñado para extender el lenguaje PHP agregando un tipo de dato 
para  el  manejo  de  fechas  de  forma  orientada  a  objetos  que  permita  las  operaciones  entre 
estas, obtener fragmentos e información de las propiedades del tiempo teniendo en cuenta la 
configuración de localización requerida por la aplicación.  

36.2 Porque debe usar este componente

Con Date se pueden efectuar operaciones usando fechas y fragmentos de fechas en cualquier 
rango  de  tiempo  independientemente  de  la  plataforma  utilizada.  El  uso  de  las  funciones    de 
PHP  gmmktime(),  mktime(),  date(),  strftime()  y  otras  tienen  restricciones  de  plataforma  y 
conflictos cuando las fechas están fuera de rango Fri, 13 Dec 1901 20:45:54 GMT a Tue, 19 Jan 
2038 03:14:07 GMT. 
 
Las restricciones se deben a que gran parte de las operaciones entre fechas y horas se realizan 
usando  marcas  de  tiempo  que  consisten  en  el  número  de  segundos  transcurridos  antes  ó 
después del 1 de Enero de 1970, cuando este número es muy grande el tipo de dato float de 
PHP resulta insuficiente para almacenarlo.  
 
La  referencia  del  manual  de  PHP  dice  “The  size  of  a  float  is  platform‐dependent,  although  a 
maximum of ~1.8e308 with a precision of roughly 14 decimal digits is a common value (that's 
64 bit IEEE format).”. 
 
Cuando  los  números  de  marcas  de  tiempo  a  almacenar  son  muy  grandes  es  posible  utilizar 
extensiones de PHP que soportan precisión arbitraria como lo son bcmath ó gmp. 
 
El componente también soporta los ajustes horarios de acuerdo al timezone de la aplicación y 
establece las correcciones necesarias para el calendario gregoriano. Igualmente si se trabaja 
en un entorno localizado Date obtiene los nombres de días y meses de acuerdo al establecido. 

36.3 Timestamps ilimitados

El componente Date realiza gran parte de sus operaciones basado en las marcas internas de 
tiempo Unix que se generan apartir de la fecha del objeto y condiciones de zona horaria entre 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    362 

otros. Cuando las aplicaciones requieren soportar operaciones con fechas fuera del rango de 
Fri,  13  Dec  1901  20:45:54  GMT  a  Tue,  19  Jan  2038  03:14:07  GMT  es  necesario  que  el 
componente Date realice sus operaciones utilizando matemática de alta precisión mediante el 
empleo de la extensión de PHP bcmath. 
 
La  extensión  bcmath  proporciona  una  calculadora  binaria  que  sopora  números  de  precisión 
arbitraria representandolos como cadenas de caracteres. Cuando la extensión esta disponible 
se  puede  activar  la  integración  con  el  componente  Date  ejecutando  el  método  del 
subcomponente de operaciones matemáticas localizadas LocaleMath llamado enableBcMath. 
 
De esta forma se puede usar fechas en cualquier rango y efectuar operaciones sobre ellas con 
tranquilidad. 

36.4 Establecer el Timezone

Para un correcto funcionamiento de este componente es necesario establecer la zona horaria 
donde  está  ubicada  la  aplicación  y  de  donde  tomará  la  información  para  realizar  los  ajustes 
adecuados a las fechas y horas. 
 
Kumbia  Enterprise  Framework  permite  configurar  el  timezone  en  el  archivo  config/config.ini 
en  la  sección  [kumbia]  usando  un  CLDR  Timezone  Identifier  que  es  aceptado  por  la  función 
date_default_timezone_set() de PHP. Para mayor consistencia de las aplicaciones desarrolladas 
en el framework se debe usar el método estático Kumbia::setTimeZone(string $cldrIdentifier). 
Cuando se establece un timezone invalido se genera una excepción. 
 
Ejemplo: Cambiar el timezone activo de forma programacional 
// Para establecer el timezone para Bogotá Colombia:
Core::setTimezone(“America/Bogota”);
// Para establecer el timezone para Londres Inglaterra:
Core::setTimezone(“Europe/London”);
 
Para  una  lista  completa  de  las  zonas  horarias  soportadas  visite: 
http://unicode.org/cldr/data/diff/supplemental/territory_containment_un_m_49.html.  

36.5 Obtener partes ó fragmentos de fechas

Es posible crear un objeto de fecha instanciando directamente la clase Date, el parámetro que 
recibe el constructor es una fecha en formato YYYY‐MM‐DD. Si no se establece este se utiliza la 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    363 

fecha  actual.  Si  el  constructor  recibe  una  fecha  invalida  se  genera  una  excepción 
DateException. 
 
Ejemplo: Obtener fragmentos de fechas 
//Crear Fecha
$fecha = new Date("1986-02-17");
//Obtener el Número del Mes
$fecha->getMonth(); // Devuelve 2
//Obtener el Año
$fecha->getYear(); // Devuelve 1986
//Obtener el Año en formato corto
$fecha->getShortYear(); // Devuelve 86
//Obtener el Número del Día
$fecha->getDay(); // Devuelve 17
//Obtener el timestamp (marca de tiempo UNIX)
$fecha->getTimestamp(); // Devuelve 509000400
//Obtener el nombre del mes abreviado según la localización actual
$fecha->getAbrevMonthName(); // Devuelve Feb
/Obtener el nombre del mes según la localización actual
$fecha->getMonthName(); // Devuelve Febrero
//Obtener el nombre del día según la localización actual
$fecha->getDayOfWeek(); //Devuelve Lunes
//Obtener el nombre del día según la localización actual en forma abreviada
$fecha->getAbrevDayOfWeek(); //Devuelve Lun
//Obtener el número del dia de la semana (Domingo=0 hasta Sábado=7)
$fecha->getDayNumberOfWeek(); // Devuelve 1
//Obtener la fecha interna en el formato YYYY-MM-DD
$fecha->getDate(); // Devuelve 1986-02-17
(string) $fecha; // Devuelve 1986-02-17
//Obtener la fecha de acuerdo a un formato establecido
$fecha->getUsingFormat(“yy.dd.mm”); // Devuelve 86.17.02
//Obtener la fecha de acuerdo al formato de fecha en config.ini
$fecha->getUsingDefaultFormat();

//Obtener el periodo de la fecha (YYYYMM)


$fecha->getPeriod(); // Devuelve 198602
//Obtener la fecha en formato ISO-8601
$fecha->getISO8601Date(); // Devuelve 1986-02-17T00:00:00-05:00
//Obtener la fecha en formato RFC-2822
$fecha->getRFC2822Date(); // Devuelve Mon, 17 Feb 1986 00:00:00 -0500

36.6 Posición en el Tiempo

Un objeto Date también puede proporcionar información sobre su posición en el tiempo, las 
funciones que reciben otras fechas aceptan strings en el formato YYYY‐MM‐DD ó otros objetos 
de fechas: 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    364 

Ejemplos: Uso de métodos de posición del tiempo con Date 
//Indica si la fecha corresponde a la actual
$fecha->isToday();
//Indica si la fecha corresponde a la fecha de mañana
$fecha->isTomorrow();
//Indica si la fecha corresponde a la fecha de ayer
$fecha->isYesterday();
//Indica si la fecha se encuentra en el mes actual
$fecha->isThisMonth();
//Indica si la fecha se encuentra en el año actual
$fecha->isThisYear();
//Indica si el año de la fecha es bisiesto
$fecha->isLeapYear();
//Si la fecha está entre un rango
$fecha = new Date(“1990-06-04”);
$fecha->isBetween(“1980-01-01”, “2000-12-31“) // Devuelve true

//Si la fecha NO está entre un rango


$fecha = new Date(“1990-06-04”);
$fecha->isNotBetween(“1980-01-01”, “2000-12-31“) // Devuelve false
//Indica si está en el pasado
$fecha->isPast();
//Indica si está en el futuro
$fecha->isFuture();
//Indica si una fecha es menor que la otra
Date::isEarlier(“2001-02-30”, “2003-04-21”) // Devuelve true
//Indica si una fecha es mayor que la otra
Date::isLater(“2001-02-30”, “2003-04-21”) // Devuelve false
//Indica si una fecha es igual a la otra
Date::isEquals(“2001-02-30”, “2003-04-21”) // Devuelve false
 
// Compara dos fechas, si la primera es menor a la segunda devuelve -1, si son
// iguales devuelve 0 y si la primera es mayor a la segunda devuelve 1
Date::compareDates(“2009-01-20”, “2009-02-14”); // Devuelve -1
Date::compareDates(“2009-01-20”, “2009-01-20”); // Devuelve 0
Date::compareDates(“2009-03-05”, “2009-02-14”); // Devuelve 1

36.7 Información de Fechas

El  componente  Date  ofrece  métodos  para  obtener  la  fecha  y  hora  actual,  así  como  fechas 
iniciales y finales de años y meses: 
 
Ejemplo: Métodos para obtener información de fechas 
// Obtiene el rango de fechas de la semana de Lunes a Domingo donde está
// ubicada la fecha
$fecha = new Date("2009-02-11");
print_r($fecha->getWeekRange()); //Array ([0] => 2009-02-09 [1] => 2009-02-15)
 
//Obtener la fecha actual en formato YYYY-MM-DD
Date::getCurrentDate();
//Obtener la hora actual en formato HH:MM:SS
Date::getCurrentTime();
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    365 

//Obtener la fecha y hora actual en formato “YYYY-MM-DD HH:MM:SS”


Date::now();
//Obtener el primer dia del año actual
Date::getFirstDayOfYear();
//Obtener el primer dia del año 1999
Date::getFirstDayOfYear(1999); //Devuelve 1999-12-31
//Obtener el último dia habil del año 2006
print Date::getLastNonWeekendDayOfYear(2006); //2006-12-29
 
//Obtener el primer dia del año 1980
Date::getFirstDayOfYear(1980); //Devuelve 1980-01-01
  
//Obtener el primer dia del mes de febrero del año 1980
Date::getFirstDayOfMonth(2, 1980); //Devuelve 1980-02-01
//Obtener el último dia del mes de febrero del año actual
Date::getLastDayOfMonth(2);
//Obtener el último dia del mes de febrero del año 2000
Date::getLastDayOfMonth(2, 2000); //Devuelve 2000-02-29
//Obtener el último dia habil del mes de julio del año 1983
print Date::getLastNonWeekendDayOfMonth(7, 1997); //1983-07-29

36.8 Cambiar fragmentos de la fecha

Cada  objeto  de  fecha  almacena  cada  parte  de  la  fecha  y  permite  cambiar  cada  parte 
manteniendo la consistencia de la misma:  
 
Ejemplo: Métodos para manipular fragmentos de fechas 
$fecha = new Date(“2008-11-30”);
//Cambiar el mes a Marzo
$fecha->setMonth(3);
print $fecha; //Devuelve 2008-03-30
//Cambiar el mes a Febrero (se ajusta el día automáticamente)
$fecha->setMonth(2);
print $fecha; // Devuelve 2008-02-29
//Cambiar el año de un año bisiesto a uno no bisiesto
$fecha->setYear(“2009”);
print $fecha; // Devuelve 2009-02-28
//Cambiar el dia de la fecha
$fecha->setDay(30);
print $fecha; // Devuelve 2009-02-28
$fecha->setDay(12);
print $fecha; // Devuelve 2009-02-12
//Cuando el mes es mayor a 12 ajusta al año ó años siguientes
$fecha = new Date("2008-01-01");
$fecha->setMonth(13);
print $fecha; //2009-01-01
$fecha = new Date("2009-01-30");
$fecha->setMonth(14);
print $fecha; //2009-02-28
$fecha = new Date("2008-01-30");
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    366 

$fecha->setMonth(-2);
print $fecha; //2007-11-30
$fecha = new Date("2008-02-29");
$fecha->setMonth(-14);
print $fecha; //2007-11-30

36.9 Operaciones con fechas

Las  operaciones  con  fechas  se  dividen  en  las  que  modifican  la  fecha  interna  del  objeto  y  las 
que devuelven nuevos valores: 

Ejemplo: Realizar operaciones con fechas 
//Agregar meses a la fecha
$fecha = new Date("2008-08-10");
$fecha->addMonths(2);
print $fecha; //2008-10-10
//Quitar meses a la fecha
$fecha = new Date("2008-01-10");
$fecha->diffMonths(3);
print $fecha; //2008-10-10
//Agregar dias
$fecha = new Date("2008-02-29");
$fecha->addDays(5);
print $fecha; //2008-03-05
//Quitar dias
$fecha = new Date("2008-01-02");
$fecha->diffDays(5);
print $fecha; //2007-12-28
//Agregar años
$fecha = new Date("2008-01-02");
$fecha->addYears(3);
print $fecha; //2011-01-02
//Quitar años
$fecha = new Date("2008-01-02");
$fecha->diffYears(3);
print $fecha; //2005-01-02
// Restar una fecha y devolver dias de diferencia, la fecha interna no se
// modifica
$fecha = new Date("2008-01-02");
print $fecha->diffDate(“2008-01-10”); //Devuelve -8
$fecha = new Date("2008-01-30");
print $fecha->diffDate(“2008-01-25”); //Devuelve 5

 
El  método  addInterval  y  diffInterval  realiza  sumas  y  restas  de  intervalos  respectivamente  a 
otras  fechas,  la  función  siempre  suma  ó  resta  por  lo  cual  pasar  números  negativos  como 
segundo parámetro genera el mismo resultado.  
 
Las  operaciones  tienen  en  cuenta  años  bisiestos,  correcciones  gregorianas,  zonas  horarias  y 
rangos de fecha de cualquier longitud. 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    367 

Tabla: Tipos de intervalos soportados por Date::addInterval 
Constante  Descripción 
INTERVAL_DAY  Establece un intervalo de días del calendario gregoriano 
INTERVAL_WEEK  Establece un intervalo de semanas 
INTERVAL_MONTH  Establece un intervalo de meses del calendario gregoriano 
INTERVAL_YEAR  Establece un intervalo de años del calendario gregoriano 

Ejemplo: Uso de addInterval para sumar intervalos a fechas 
//Devuelve un objeto de fecha apartir de sumarle un intervalo a otra fecha
Date::addInterval(“1980-05-11”, 10, Date::INTERVAL_DAY); //1980-05-21
Date::addInterval(“1981-02-27”, 7, Date::INTERVAL_DAY); //1980-03-06
Date::addInterval(“1980-05-11”, 2, Date::INTERVAL_MONTH); //1980-07-11
Date::addInterval(“1980-05-11”, 5, Date::INTERVAL_YEAR); //1985-05-21
//Devuelve un objeto de fecha apartir de sumarle un intervalo a otra fecha
Date::diffInterval(“1980-05-11”, 10, Date::INTERVAL_DAY); //1980-05-01

36.10 Localización de Fechas

Por  defecto  los  nombres  de  meses,  dias,  eras  y  formatos  de  fechas  son  devueltos  usando  la 
localización  de  la  aplicación  en  config.ini.  Es  posible  modificar  la  localización  de  un  objeto 
fecha usando el método setLocale() que acepta un objeto Locale: 
 
Ejemplo: Cambiar la localización de los objetos de fecha 
<?php
$date = new Date('1986-02-02');
//Fecha en Inglés
$date->setLocale(new Locale('en_US'));
print $date->getLocaleDate();
//Fecha en Francés
$date->setLocale(new Locale('fr_FR'));
print $date->getLocaleDate();
//Fecha en Español
$date->setLocale(new Locale('es_AR'));
print $date->getLocaleDate();
//Fecha en Chino
$date->setLocale(new Locale('zh_CN'));
print $date->getLocaleDate();
 
Lo anterior genera la siguiente salida: 
 
Sunday, February 2, 1986
Dimanche 2 Février 1986
Domingo 2 de Febrero de 1986
1986年2月2日星期日

El método getLocaleDate obtiene una fecha apta por la cultura establecida usando diferentes 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    368 

tipos  de  formatos.  El  método  acepta  un  parámetro  indicando  el  tipo  de  formato  de  fecha  a 
obtener: 
 
Tabla: Tipos de formatos localizados que soporta Date 
Tipo Formato  Descripción 
full  Obtiene  una  fecha  apta  para  la  localización  en  formato  completo  ó 
extendido. Es el formato predeterminado del método getLocaleDate(). 
long  Formato largo pero mas corto que ‘full’. 
medium  Formato de fecha medio, útil en reportes ó listados. 
short  Formato de fecha corto. 
 
El siguiente ejemplo ilustra las fechas obtenidas de acuerdo a cada tipo de formato localizado. 
Las variaciones incluso de paises de la misma lengua son tenidas en cuenta: 
 
Ejemplo: Obtener fechas en formatos localizados de acuerdo a la cultura 
<?php
$date = new Date('1985-11-01');
//Tipos de formatos en español de Mexico
$date->setLocale(new Locale('es_MX'));
print $date->getLocaleDate('full');
print $date->getLocaleDate('long');
print $date->getLocaleDate('medium');
print $date->getLocaleDate('short');
//Tipos de formatos en español de Colombia
$date->setLocale(new Locale('es_CO'));
print $date->getLocaleDate('full');
print $date->getLocaleDate('long');
print $date->getLocaleDate('medium');
print $date->getLocaleDate('short');
 
Generando la siguiente salida: 
 
Viernes 1 de Noviembre de 1985
1 de Noviembre de 1985
01/11/1985
01/11/85
Viernes 1 de Noviembre de 1985
1 de Noviembre de 1985
1/11/1985
1/11/85

36.11 Establecer el formato de la fecha

Los formatos de fecha devueltos por getLocaleDate representan el estándar internacional de 
acuerdo a la Unicode para cada localización (idioma y territorio).  Además de estos es posible 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    369 

obtener  una  fecha  en  un  formato  personalizado  usando  el  método  getUsingFormat().  Los 
formatos  son  aplicados  por  el  componente  y  se  evita  el  uso  de  funciones  PHP  como  date  ó 
strftime  de  esta  forma  puede  que  algunos  formatos  disponibles  en  ellas  no  se  encuentren 
presentes. 
 
Los modificadores de tipos de formato aceptados por este son los siguientes: 
 
Tabla:  Tipos  de  modificadores  de  formatos  de  fecha  aceptados  por 
Date::getUsingFormat 
Tipo  Descripción 
Modificador 
GGGG  Nombre  de  la  era  de  la  fecha.  Antes  de  cristo  ó  después  de  cristo  según  la 
localización. 
GGG  Nombre abreviado de la era. a.c. y d.c. 
GG 

yy  Año abreviado. El año 1997 sería 97. 
yyyy  Año completo. 

dd  Dia del mes usando un cero al inicio cuando el dia es menor a 10. 
d  Dia del mes. 
EEEE  Nombre del día de la semana. 
EEE  Nombre del día de la semana abreviado. 
MMMM  Nombre del mes. 
MMM  Nombre del mes abreviado. 
MM  Numero del mes usando un cero al inicio cuando es menor a 10. 
M  Número del mes. 
r  Fecha en formato RFC‐2822 
c  Fecha ISO 8601 
z  Día del año. 
o  Número del año ISO‐8601. 
L  Muestra un 1 cuando es año biciesto y cero de lo contrario. 
W  Número de la semana en el año. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    370 

N  Representación númerica de la fecha  
t  Timestamp Unix 
e  Identicador de Zona Horaria 
 
Un ejemplo de uso de los modificadores de formato es: 
 
Ejemplo:    Obtener  la  fecha  con  un  formato  personalizado  y  una  localización 
establecidad 
$d = new Date('1999-10-18');
$d->setLocale(new Locale('en_US'));
print $d->getUsingFormat('yyyy.MM.dd, DD EEEE r MMMM L c t');

36.12 Obtener la fecha y hora mundial

Cuando  se  desarrollan  aplicaciones  que  serán  implementadas  en  diferentes  paises  y/o 
continentes  y  el  servidor  de  aplicaciones  reside  en  un  punto  central  el  componente  Date 
proporciona datos de fecha y hora que permiten lograr esto apartir de la zona horaria. 
 
La información de zona horaria depende de la plataforma en la que está instalada la aplicación 
y de la versión de PHP, puede instalar una versión actualizada de la extensión php_timezone 
disponible en PECL para obtener los últimos datos de zona horaria. 

Ejemplo:  Obtener  la  fecha  actual  simultaneamente  de  acuerdo  a  diferentes  zonas 
horarias 
print Date::getNowFromTimezone("Arctic/Longyearbyen"); // 2009-02-12 03:20:52
print Date::now(); // 2009-02-11 21:20:52
print Date::getNowFromTimezone("America/Caracas"); // 2009-02-11 21:50:52
print Date::getNowFromTimezone("Europe/Amsterdam"); // 2009-02-12 03:20:52
print Date::getNowFromTimezone("Europe/Berlin"); // 2009-02-12 03:20:52
print Date::getNowFromTimezone("Europe/Stockholm"); // 2009-02-12 03:20:52
print Date::getNowFromTimezone("Africa/Cairo"); // 2009-02-12 04:20:52
print Date::getNowFromTimezone("Asia/Jerusalem"); // 2009-02-12 04:20:52
print Date::getNowFromTimezone("Asia/Tokyo"); // 2009-02-12 11:20:52
print Date::getNowFromTimezone("Australia/Sydney"); // 2009-02-12 13:20:52
print Date::getNowFromTimezone("Antarctica/South_Pole"); // 2009-02-12 15:20:52
 
 
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    371 

37 Componente Currency
37.1 Introducción

El objetivo de este componente es proporcionar facilidades al desarrollador para trabajar con 
cantidades numéricas relacionadas con dinero y monedas, su representación de acuerdo a la 
localización activa y la generación de montos en letras en diferentes idiomas. El componente 
soporta datos monetarios para más de 90 localizaciones.  

37.2 Cantidades usando el formato adecuado

El  componente  Currency  permite  aplicar  el  formato  correcto  a  cantidades  de  acuerdo  a  la 
localización activa ó la que se establezca. De esta forma es posible utilizar los separadores de 
decimales  y  miles  adecuados  para  cada  territorio,  el  nombre  de  la  moneda  y  el  simbolo  de 
dinero adecuados. 
 
Currency puede ser usado mediante métodos estáticos ó creando instancias de esta cuando se 
requiere utilizar múltiples localizaciones en un mismo proceso. 
 
El separador de comas y agrupamiento puede cambiar de una localización a otra: 
 
Ejemplo: Imprimir cantidades monetarias usando diferentes localizaciones 
<?php
$currency = new Currency(new Locale('en_US'));
print $currency->getMoney(10000); //10,000.00
$currency->setLocale(new Locale('es_CO'));
print $currency->getMoney(10000); //10.000,00

37.3 Simbolo y nombre de la moneda utilizada

El  componente  Currency  puede  combinar  la  conversión  al  formato  numérico  correcto  y  el 
nombre de la moneda incluso cuando es diferente a la localización actual. El método getMoney 
también  acepta  un  formato  con  tipos  de  identificadores  para  indicar  datos  adicionales  de  la 
salida monetaria: 
 
Ejemplo: Imprimir una cantidad monetaria usando un formato personalizado 
<?php
$currency = new Currency(new Locale('en_US'));
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    372 

print $currency->getMoney(10000, '%symbol%%name% %quantity% (%displayName%)');


$currency->setLocale(new Locale('es_CO'));
print $currency->getMoney(10000, '%symbol%%name% %quantity% (%displayName%)');
 
Generando la salida: 
 
$USD 10,000.00 (US Dollar)
$COP 10.000,00 (Peso de Colombia)
 
Los tipos de identificadores soportados son: 
 
Tabla: Tipos de modificadores de formato soportados por Currency 
Tipo  Descripción 
Modificador 
%symbol%  Simbolo predeterminado de la moneda utilizada. 
%name%  Codigo ISO 3166 de la moneda 
%displayName%  Nombre de la moneda en la localización activa. 
%quantity  Ubicación de la cantidad a formatear. 
 
Si se require se puede pasar un tercer parámetro a getMoney indicando la moneda en la que 
está la cantidad pero sin cambiar la localización: 
 
Ejemplo: Indicar el tipo de moneda usado según la localización en Currency 

$currency->setLocale(new Locale('es_CO'));
print $currency->getMoney(100, '%symbol%%name% %quantity% (%displayName%)',
‘USD’);
 
El ejemplo anterior imprime: 
 
USD 100.00 (dólar estadounidense)

37.4 Versiones escritas de cantidades

Una  de  las  capacidades  importantes  de  Currency  es  la  posibilidad  de  generar  versiones  en 
texto  de  cantidades  monetarias.  El  componente  se  apoya  en  LocaleMath  para  generar 
versiones escritas de cantidades superiores a billones: 
 
//CUATROMIL QUINIENTOS BOLíVARES FUERTES VENEZOLANOS
$currency = new Currency(new Locale('es_VE'));
print $currency->getMoneyAsText(4500);
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    373 

//UN MILLON DOSCIENTOS CINCUENTAMIL PESOS COLOMBIANOS


$currency = new Currency(new Locale('es_CO'));
print $currency->getMoneyAsText(1250000);
//UN MILLON DE PESOS COLOMBIANOS
$currency = new Currency(new Locale('es_CO'));
print $currency->getMoneyAsText(1000000);
//CIEN PESOS COLOMBIANOS CON CINCUENTA CENTAVOS
$currency = new Currency(new Locale('es_CO'));
print $currency->getMoneyAsText(100.50);
//UN PESO ARGENTINO
$currency = new Currency(new Locale('es_AR'));
print $currency->getMoneyAsText(1);
//DOSCIENTOS CINCUENTA PESOS URUGUAYOS
$currency = new Currency(new Locale('es_UY'));
print $currency->getMoneyAsText(250);
 
//OMITIR LA MONEDA
$currency = new Currency(new Locale('es_UY'));
print $currency->getMoneyAsText(250, false);
 
El método getMoneyAsText recibe una cantidad y segundo parámetro opcional que indica si se 
debe agregar la moneda. Este método realiza una correcta pluralización del texto de acuerdo a 
la cantidad y agrega las cantidades en centavos si aplica.  

37.5 API del Componente Currency

function void __construct(Locale $locale) 
Constructor de Currency. Opcionalmente puede establecerse la localización que debe tener en 
cuenta el objeto.  
  
function void setLocale(Locale $locale) 
Permite establecer cambiar la localización del objeto Currency. 
  
function string getMoney(double $quantity, string $format='', string $codeISO='')  
Obtiene una cantidad monetaria formateada de acuerdo a la localización del objeto ó la de la 
aplicación.  El parámetro $format permite indicar el formato del string resultante.  
 
function string getMoneySymbol(string $codeISO='') 
Obtiene el simbolo de moneda para la localización actual ó la indicada mediante el código ISO 
del país con $codeISO. 
  
function string getMoneyDisplayName(string $codeISO='', string $type='')  
Obtiene el nombre de la moneda para la localización actual ó la indicada mediante el código 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    374 

ISO del país con $codeISO. 
 
function string getMoneyISOCode(string $codeISO='')  
Obtiene el código ISO de una moneda de acuerdo al código ISO del país. 
 
function array getCurrency(string $codeISO='', string $displayType='') 
Obtiene un array con el simbolo y nombre de la moneda en localización actual del objeto. 
 
static function string moneyToWords(numeric $valor, string $moneda, string $centavos)  
Convierte  un  valor  en  monedas  a  su  representación  en  palabras.  Actualmente  solo  genera 
textos en español. 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    375 

Parte 6: Monitorización de Aplicaciones 
 

38 Componente ApplicationMonitor
38.1 Introducción

Kumbia Enterprise Framework ofrece características para el monitoreo de aplicaciones y sus 
componentes de tal forma que pueda mejorar las tareas de administración como sintonización 
ó  determinación  de  problemas.  El  componente  ApplicationMonitor  está  integrado  con  el 
Louder  KEF  Instance  Administration  Console  permitiendo  que  personal  no‐especialista  en 
áreas  de  desarrollo  pueda  monitorizar  las  aplicaciones  de  una  determinada  instancia  del 
framework. 
 
Al  observar  el  flujo  de  ejecución  de  una  aplicación  es  posible  controlar  que  un  proceso  de 
negocio genere los resultados esperados. 
 
Gracias  a  los  capacidades  del  framework  de  ejecución  horizontal,  ApplicationMonitor  puede 
recorrer cada componente en ejecución y tomar los datos necesarios para hacer seguimiento a 
una petición. 

38.2 Infraestructura de Eventos comunes

La  infraestructura  de  eventos  comunes  es  una  tecnología  embebible  que  proporciona 
servicios básicos de administración de servicios a aplicaciones que requieren monitorización. 
Esta  infraestructura  ofrece  un  punto  de  consolidación  y  persistencia  para  eventos  desde 
múltiples  fuentes  así  como  su  distribución  a  los  consumidores  de  eventos.  Cada  evento  es 
definido usando una estructura XML que define la descripción del mismo. 
 
Esta  arquitectura  de  eventos  permite  que  diversos  productos  que  no  están  fuertemente 
acoplados los unos con los otros puedan integrar eventos de administración proporcionando 
una vista final a los recursos empresariales existentes. 
 
Esta  infraestructura  de  eventos  proporciona  facilidades  para  la  generación,  propagación, 
persistencia  y  consumo  de  eventos  sin  definir  los  eventos  en  si  mismos.  El  desarrollador 
puede definir tipos de eventos, grupos, filtros y relaciones entre ellos.  
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    376 

38.3 Componentes de la Infraestructura de Eventos

La infraestructura de común de eventos consta de los siguientes componentes: 

38.3.1 CommonBaseEvent 
Permite la creación de eventos y acceso a sus datos. Los recursos de eventos utilizan la API de 
CommonBaseEvent  para  crear  nuevos  eventos  en  base  al  modelo  de  aplicación.  Los 
consumidores  de  eventos  utilizan  su  API  para  leer  la  información  en  ellos.  Aplicaciones  de 
terceros  pueden  convertir  los  objetos  en  representaciones  en  XML  para  intercambiar  los 
datos. 

38.3.2 Emmiter 
El emisor permite el envio de eventos por un canal de comunicación HTTP. Después de que un 
evento  se  alimenta  de  datos  es  transferido  al  emisor.  Este  puede  opcionalmente  completar 
datos del evento y hacerlos parte de la petición. Los eventos son enviados mediante SOAP ó 
SCA. 

38.3.3 Event Service 
El  servicio  de  eventos  recibe  los  mensajes  enviados  por  el  Emmiter,  los  almacena  en  un 
almacen  de  datos  persistente  y  luego  los  distribuye  asincrónicamente  a  otros  consumidores 
de eventos.  

38.4 ¿Porque usar monitorización?

Los servicios de monitoreo de Kumbia Enterprise Framework permiten evaluar rendimiento, 
encontrar  problemas  y  evaluar  el  procesamiento  normal  de  un  conjunto  de  aplicaciones  en 
una instancia. Hay tres razones principales por las que se debe monitorizar: 

38.4.1 Determinación de problemas 
Es  posible  diagnosticar  errores  particulares  usando  las  capacidades  de  logging  y  traza  que 
ofrece  el  framework.  Por  ejemplo  si  un  determinada  aplicación  no  está  produciendo  los 
resultados  esperados  es  posible  activar  un  log  que  realice  segumiento  a  los  procesos  de  la 
misma y así detectar las razones del fallo. 

38.4.2 Sintonización del Rendimiento  
El  componente  ApplicationMonitor  también  puede  obtener  estadísticas  de  rendimiento  de 
determinados procesos y así poder encontrar cuellos de botella generando las sintonizaciones 
correspondientes que mejoren el rendimiento. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    377 

38.4.3 Confiabildad de la Operación 
La monitorización continua de las aplicaciones ayuda a estabilizar en forma más eficiente una 
aplicación  generando  respuestas  continuas  a  problemas  tanto  funcionales  como  de 
rendimiento.  

38.5 ¿Qué se puede monitorear?

El  monitoreo  se  realiza  con  base  a  eventos  procesados  por  el  framework.  Estos  eventos  se 
lanzan en determinados puntos de la ejecución en una petición. 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    378 

39 Componente CommonEvent
39.1 Introducción

El objetivo de este componente es crear eventos propagables como mensajes de una red y que 
puedan ser procesados por múltiples endpoints en diferentes plataformas. 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    379 

Parte 8: Administración e Información de Aplicaciones 

40 Componentes de Propósito General


40.1 Introducción

A  continuación  se  presenta  la  referencia  de  los  componentes  del  framework  que  aplican  a 
cualquier proyecto de software. 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    380 

41 Componente Config
41.1 Introducción

Este  componente  permite  al  desarrollador  leer  archivos  de  configuración  en  diferentes 
formatos en objetos php aptos para usar en procesos de las aplicaciones.  

41.2 Adaptadores de Config

El componente hace uso de adaptadores que encapsulan los detalles de cada formato. 
 
Tabla: Adaptadores del componente Config 
Tipo Formato  Descripción 
Ini  Utiliza archivos PHP para almacenar la configuración. Internamente se usa 
la función de php parse_ini_file.  
Xml  Utiliza archivos de configuración en XML. 
Array  Utiliza arrays multidimencionales nativos de PHP para almacenar la 
configuración. En términos de rendimiento es el mejor. 
Yaml  Utiliza el formato YAML (Yet another markup language) para la definición 
de archivos de configuración. El rendimiento puede ser menor debido a que 
se utiliza PHP para parsear el archivo de configuración. 
 
La flexibilidad de este componente permite que el desarrollador utilice el formato que le sea 
más  familiar  tanto  para  los  archivos  de  configuración  de  su  aplicación  como  los  del 
framework. 
 
El componente Config cachea el resultado de procesar un archivo, así, si es procesado en una 
misma petición más de una vez este es no es re‐procesado mejorando el rendimiento. 
 
En  los  siguientes  ejemplos  se  muestra  como  el  mismo  archivo  de  configuración  es 
representando en diferentes formatos: 

41.2.1 Adaptador de configuración Ini 
Config  soporta  archivos  INI  estos  son  ampliamente  usados  por  todo  tipo  de  software  que 
además son el formato predeterminado del framework. El adaptador procesa las secciones del 
archivo  y  variables  compuestas.  Gracias  a  que  se  usan  funciones  nativas  del  lenguaje  su 
procesado es más rápido. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    381 

 
Ejemplo: Archivo de configuración en INI 
[example]
variable = “valor”
[development]
database.host = “localhost”
database.user = “jasmin”
database.password = “secret”

41.2.2 Adaptador de configuración XML 
El adaptador de configuración XML permite procesar archivos que usen el lenguaje de marcas 
XML.  Los  archivos  XML  son  ampliamente  reusables  por  otras  tecnologías  y  lenguajes.  El 
procesado  de  los  archivos  se  hace  usando  funciones  nativas  del  lenguaje  PHP  por  lo  que  es 
muy rápida. 
 
Ejemplo: Archivo de configuración en XML 
<?xml version="1.0" encoding="UTF-8"?>
<config>
<example>
<variable>value</variable>
</example>
<development>
<database>
<host>localhost</host>
<username>jasmin</username>
<password>secret</password>
</database>
</development>
</configdata>
 

41.2.3 Adaptador de configuración Arrays de PHP 
El  adaptador  de  configuración  PHP  permite  definir  la  configuración  en  arrays 
multidimensionales nativos del lenguaje con lo cual se obtiene la mayor velocidad al leerlos y 
procesarlos. 
 
Ejemplo: Archivo de configuración en PHP 
<?php
$config = array(
'example' => array(
'variable' => 'value'
),
'development' => array(
'database' => array(
'host' => 'localhost',
'username' => 'jasmin',
'password' => 'secret'
)
)
);
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    382 

41.2.4 Adaptador de configuración Yaml 
Los  archivos  de  configuración  Yaml  son  ampliamente  usados  por  otros  frameworks  como 
Symfony ó Ruby On Rails. Son conocidos por su simplicidad y facilidad de entendimiento. Su 
procesamiento se realiza a nivel de PHP por lo que su procesamiento puede ser más lento. 
 
Ejemplo: Archivo de configuración en YAML 
# Archivo para adaptador Yaml
example:
variable: value
development:
database:
host: localhost
username: jasmin
password: secret
 

41.2.5 Leer archivos de configuración 
Para  los  ejemplos  de  archivos  de  configuración  el  siguiente  ejemplo  sin  importar  el  que  se 
escogiese produciría el mismo objeto Config como resultado: 

41.2.6 Ejemplo: Leer un archivo de configuración 

//Leer la configuración
$config = Config::read('myconfig/config.ini', 'ini');
//Comprobar los valores leídos
assertEquals($config->example->variable, 'value');
assertEquals($config->development->database->host, 'localhost');
assertEquals($config->development->database->username, 'jasmin');
assertEquals($config->development->database->password, 'secret');
 
 
 
 
 
 
 
 
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    383 

42 Componente Extensions
42.1 Introducción

El  componente  Extensions  se  encarga  de  administrar  las  extensiones  cargadas  en  una 
aplicación ya sea de forma dinámica ó estática. 
 
Una  extensión  es  un  componente  del  framework  que  no  se  carga  por  defecto  y  tampoco  es 
inyectado al requerirse en un proceso de negocio. 

42.2 Cargar una extensión dinámicamente

La carga dinámica de extensiones permite cargar componentes del framework ó de usuario en 
el momento en el que se necesiten y por consiguiente reducir ligeramente la carga de lectura 
de disco. 
 
Ejemplo: Cargar una extension dinámicamente usando el componente Extensions 
<?php
class PressController extends ApplicationController {
public function indexAction(){
//Cargar extensión de Localización
Extensions::loadExtension("Kumbia.Locale");
}
}

42.3 Cargar una extensión estáticamente

Los  extensiones  que  se  usen  ampliamente  en  la  aplicación  pueden  cargarse  mediante  el 
archivo de configuración de las aplicaciones llamado config/boot.ini. La estructura del archivo 
es la siguiente: 
 
Ejemplo: Cargar una extension estáticamente usando boot.ini 
; Cargar extensiones
[modules]
extensions = Kumbia.Acl,User.MyComponent,Mail.Phpmailer
 
La sección modules tiene la opción de configuración extensions en la cual se puede definir las 
extensiones  a  cargar  separandolas  por  comas.  Las  extensiones  que  están  en  el  namespace 
Kumbia  hacen  parte  de  la  biblioteca  de  componentes  de  framework,  las  que  empiezan  por 
User son componentes que el desarrollador a creado y están ubicadas en el directorio library 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    384 

de  la  aplicación,  por  último,  la  extensión  se  localiza  en  el  directorio  principal  Library  de  la 
instancia como es el caso de PhpMailer. 

42.3.1 Cargar componentes de Zend Framework 
Componentes  especificos  de  Zend  Framework  pueden  ser  cargados  estáticamente  ó 
dinámicamente  usando  la  convención  “Zend.Componente”.  Por  defecto  el  framework  es 
buscado  en  la  ruta  de  la  instancia  Library/Zend,  esta  ruta  puede  ser  modificada  usando  el 
método Extensiones::setZendDirectory. 
 
Para cargar una extensión dinámicamente se usa: 
 
Ejemplo: Cargar componentes de Zend Framework 
Load::extension(“Zend.Dojo”)
 
Para cargarlas en config/boot.ini se usa: 
Ejemplo: Cargar componentes de Zend Framework estáticamente 
[modules]
extensions = Zend.Amf

42.4 Cargar archivos individuales al iniciar la petición

Este componente también permite cargar archivos individuales al inicio de cada petición que 
preferiblemente sean usados con frecuencia buscando mejorar el rendimiento. 
 
Estos archivos se definen declarativamente separandolos por comas en el archivo boot.ini así: 
 
Ejemplo: Cargar archivos PHP individuales en boot.ini 
[classes]
files = apps/default/classes/MiClase.php,
Library/Kumbia/ActiveRecord/SessionRecord/SessionRecord.php,Library/Kumbia/Local
e/LocaleMath/LocaleMath.php
 

42.5 Obtener información de extensiones cargadas

Los  siguientes  métodos  de  clase  Extensions  proporcionan  información  sobre  las  extensiones 
cargadas: 
 
public boolean static isLoaded(string $extensionName) 
Devuelve true si la extensión ya ha sido cargada en la petición actual, false de lo contrario. 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    385 

public array static getLoadedExtensions() 
Devuelve un arreglo con los nombres de las extensiones cargadas en la petición actual. 

42.6 Inyección de componentes

Kumbia Enterprise Framework utiliza inyección de dependencia para cargar los componentes 
justo cuando son requeridos. Si un componente es usado frecuentemente por la aplicación es 
probable  que  cargarlo  estáticamente  mejore  el  rendimiento  en  los  demás  casos  es 
recomendable permitir que sean inyectados durante la ejecución. 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    386 

43 Componente Logger
43.1 Introducción

El  componente  Logger  es  un  componente  cuyo  propósito  es  el  crear  logs  usando  diferentes 
backends  mediante  adaptadores,    opciones  de  generación  como  formatos  y  filtros  e 
implementación de transacciones. 
 
Este componente accede a sus adaptadores usando el patrón Virtual Proxy, es decir, el objeto 
logger  solo  actúa  como  un  Proxy  al  objeto  real  instanciado  que  corresponde  al  tipo  de 
adaptador utilizado por el mismo. La clase Logger delega todas las tareas al adaptador que por 
defecto es el subcomponente FileLogger, el cual realiza el almacenamiento en archivos planos 
del servidor. 

43.2 Adaptadores de Logger

Todos los adaptadores implementan la interface LoggerInterface que define los métodos que 
cada adaptador debe implementar.  La interface tiene la siguiente estructura: 
 
interface LoggerInterface {
public function begin();
public function rollback();
public function commit();
public function close();
public function log($message, $type);
}
 
Los adaptadores disponibles son los siguientes: 
 
Tabla: Adaptadores disponibles en el componente Logger 
Adaptador  Descripción 
FileLogger  Permite escribir logs a archivos de texto plano en el servidor local. 
MailLogger  Permite  enviar  un  log  a  un  correo  electrónico  automáticamente  en 
cuanto es creado. 
SAMLogger  Permite  enviar  logs  como  mensajes  de  un  servidor  de  mensajería 
Simple Asynchronous Messaging (SAM). 
DatabaseLogger  Permite grabar los logs en una tabla en la base de datos. 
CompressedLogger  Permite  escribir  logs  a  archivos  de  texto  plano  comprimidos  usando 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    387 

ZLib en el servidor local. 
StreamLogger  Permite  escribir  logs  a  envolturas  y  protocolos  de  PHP  que  soporten 
escritura. 
SocketLogger  Permite  escribir  logs  a  puertos  TCP/UDP  que  tengan  servidores  que 
acepten cadenas de texto. 
 
El  desarrollador  puede  implementar  sus  propios  logs  implementando  la  interface 
LoggerInterface. 
 
Un ejemplo del uso del componente Logger es el siguiente: 
 
Ejemplo: Creación de logs usando el componente Logger 
<?php
class TestController extends ApplicationController {
public function testAction(){
$logger = new Logger();
$logger->log("Esto es una prueba");
}
}

Se ha creado una instancia de la clase Logger y se ha logueado el texto “Esto es una prueba”. El 
primer  parámetro  que  recibe  el  constructor  de  Logger  es  el  nombre  del  adaptador  y  el 
segundo  el  nombre  del  archivo,  en  este  caso  se  ha  asumido  que  el  adaptador  es  ‘File’  y  el 
nombre del  log la convención logYYYYMMDD.txt.  
 
Los  logs  se  almacenan  por  defecto  en  el  directorio  ‘logs’  de  la  aplicación,  sin  embargo  esto 
puede  modificarse  usando  el  método  setPath().  Los  mensajes  de  los  logs  se  crean  en  modo 
“append”  es  decir,  que  agregar  nuevos  logs  sobre  un  archivo  ya  existe  inserta  al  final  del 
archivo.  
 
El contenido resultante del archivo es el siguiente: 
 
[Sun, 31 Aug 08 20:12:31 -0400][DEBUG] Esto es una prueba
 
Por defecto el formato del log es [%date%][%type%] %message%. En el siguiente ejemplo se 
cambia el formato de fecha y hora y de la línea del log en general, además se cambia el nombre 
del log: 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    388 

 
<?php
class TestController extends ApplicationController {
public function testAction(){
$logger = new Logger("File", "my_app.log");
$logger->setFormat("> %type% > %controller%/%action% on
%application% at %date% with message: %message%");
$logger->log("Esto es una prueba");
$logger->log("Esto es otra prueba");
}
}

El formato del log ha sido modificado usando el método setFormat, el cual recibe una cadena 
con modificadores que son reemplazados por su valor correspondiente en el momento en que 
se genera el log: 
 
> DEBUG > test/test on default at Sun, 31 Aug 08 20:00:00 -0400 with message:
Esto es una prueba
> DEBUG > test/test on default at Sun, 31 Aug 08 20:00:00 -0400 with message:
Esto es otra prueba

Los modificadores que acepta él método setFormat son: 
 
Tabla: Modificadores  que recibe el método setFormat 
Modificador  Descripción 
%type%  Indica  el  tipo  de  evento  logueado.  Consulte  la  tabla  de  tipos  de  eventos 
para más información. 
%message%  Es el mensaje logueado como tal. 
%date%  Es la fecha en que ocurre el evento. Por defecto utiliza el formato que esta 
asignado al modificador de la función date(‘r’) que corresponde al formato 
RFC 2822. 

%controller%  El controlador actual en el que se llama el log. 
%action%  La acción actual en la que se llama el log. 
%priority%  La prioridad con respecto al contexto y el tipo de evento. 
%facility%  Indica el contexto en el se produce el log. 
%url%  La URL completa pasada al enrutador antes de llamar al log. 
%application%  La aplicación actual en la que se genera el log. 

El formato de fecha se puede modificar usando el método setFormatDate: 
 
Ejemplo: Cambiar el formato de fecha de un log usando setFormatDate 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    389 

<?php
class TestController extends ApplicationController {

public function testAction(){


$logger = new Logger("File", "my_app.log");
$logger->setFormat("> %type% > %controller%/%action% on
%application% at %date% with message: %message%");
$logger->setDateFormat("Y.m.d H:i");
$logger->log("Esto es una prueba");
}
}
?>

El log generado es el siguiente: 
 

> DEBUG > test/test on default at 2008.10.21 00:14 with message: Esto es una
prueba

43.3 Tipos de Eventos en Logs

El componente Logger proporciona una serie de tipos de eventos que permiten clasificar cada 
uno  de  acuerdo  a  una  gravedad  ó  prioridad  en  algunos  contextos.  Para  definir  el  tipo  de 
evento en una línea del log se pasa como segundo parámetro al método log una constante del 
componente logger así: 
 
$logger->log("La memoria usada por la aplicación es ".memory_get_usage(),
Logger::INFO);
 
Los  valores  de  las  constantes  coinciden  con  las  severidades  usadas  por  syslog  y 
estandarizadas en el RFC 3164 : The BSD syslog Protocol (http://tools.ietf.org/html/rfc3164) . 
 
Adicionales  a  los  estándar,  Logger  agrega  los  eventos  CUSTOM  y  SPECIAL  con  menor 
severidad  que  los  demás  pero  que  se  utilizan  en  contextos  menos  críticos.  Los  tipos  de 
eventos soportados son: 
 
Tabla: Eventos y su descripción 
Tipo de Evento  Severidad  Descripción 
EMERGENCY  0  Emergencia: El sistema esta inutilizable. 
ALERT  1  Alerta: Mensajes de alerta. 
CRITICAL  2  Critico: Propende a la que se tomen acciones de 
inmediato 
ERROR  3  Errores: Errores ó excepciones de la aplicación 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    390 

WARNING  4  Advertencias: Condiciones de Advertencia 
NOTICE  5  Mensajes que ocurren en condición normal. 
INFO  6  Mensajes de información. 
DEBUG  7  Mensajes de debug. 
CUSTOM  8  Mensajes  sin  clasificar  generandos  por  el 
usuario final. 
SPECIAL  9  Condiciones  especiales  fuera  de  un  contexto  de 
criticidad.  Como  por  ejemplo  llevar  un  registro 
de los usuarios que ingresan a la aplicación. 
 
Métodos del mismo nombre son proporcionados en la clase Logger y realizan la misma tarea 
que log: 
 
Ejemplo: Usar métodos alias para indicar la severidad de un mensaje 
$logger->log("Esto es una Advertencia!”, Logger::WARNING);
$logger->warning("Esto es una Advertencia!”);

El tipo de evento por defecto es Logger::DEBUG. 

43.4 Logger Facilities

Kumbia Enterprise Framework mantiene separados los espacios de memoria y ejecución desde 
el  Sistema  Operativo  hasta  el  Nivel  de  Usuario  esta  información  permite  evaluar  en  que 
contexto se producen los mensajes de log.  
 
Los Facility son los siguientes: 
 
Tabla: Nombres y descripción de Facilities 
Código  Nombre  Descripción 
0  SO  Generada  en  el  contexto  de  sistema  operativo. 
Usualmente  se  relaciona  con  problemas  con 
permisos ó alertas del SO. 
1  HARDWARE  Relacionado con actividades  
2  NETWORK  Es  el  contexto  de  comunicaciones  e 
infraestructura de red. 
3  FRAMEWORK_CORE  Contexto del núcleo del Framework. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    391 

4  FRAMEWORK_COMPONENTS  Contexto  de  Componentes  del  Framework 


(bundled) 
5  SECURITY  Contexto de Seguridad 
5  AUDIT  Contexto de Auditoria 
6  USER_LEVEL  Problemas  ocurridos  a  nivel  de  usuario  y 
aplicaciones. 
 
Para  obtener  el  código  numérico  del  Facility  Actual  se  utiliza  el  método  estático 
Facility::getFacility().  Por  medio  del  facility  es  posible  determinar  el  contexto  en  el  que  se 
originó un log. El tipo de evento visto como severidad y el facility como el contexto en el que 
se generó, permiten calcular la “Prioridad”. Ésta es el resultado de multiplicar los códigos de 
ambos, la severidad y el facility. 

43.5 Transacciones con Logs

Cada adaptador realiza una implementación propia de transacciones según su naturaleza. Las 
transacciones permiten al desarrollador decidir si los mensajes de log acumulados durante un 
proceso  de  negocio  es  necesario  almacenarlos  en  los  backend  ó  anular  la  operación.  Los 
métodos  begin,  commit  y  rollback  familiares  en  un  ambiente  de  base  de  datos  pueden  ser 
usados en el archivo de log para administrar el estado de la transacción. 
 
En  el  siguiente  se  ejemplo  se  ilustra  mediante  una  transacción  de  negocio  como  el  log  es 
creado pero solo se guarda si se cumplen ciertas condiciones del procedimiento: 
 
Ejemplo: Crear una transacción en un log 
<?php
class PricesController extends WebServiceController {
public function enterpriseProcedureAction(){
$logger = new Logger("File", "procedure.log");
$logger->begin();
$customer = new Customer();
$movements = $customer->getMovement();
if(count($movement)==0){
$logger->log("No hay movimiento para el cliente '{$customer-
>getId()}'");
}
$firstDay = Date::getFirstDayOfYear();
$lastDay = Date::getLastDayOfYear();
$totalPrice = 0;
foreach($movements as $movement){
if(Date::between($movement->getDate(), $firstDay,
$lastDay)==true){
$logger->log("El movimiento {$movement->getId()} es de
este año");
if($movement->getStatus()!="F"){
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    392 

$movement->setStatus("F");
$movement->save();
$totalPrice+=$movement->getPrice();
}
} else {
if($movement->getStatus()!="H"){
$movement->moveToHistorical();
}
}
}
if($totalPrice>=$cutomer->getMaxPrice()){
$logger->log("El cliente '{$customer->getId()}' ha
sobrepasado su crédito");
$logger->commit();
}
$logger->rollback();
}
}
?>

43.6 API de FileLogger

public void setPath(string $path) 
Permite establecer el Path donde se almacenaran los logs. 
 
public void setFormat(string $format) 
Establece el formato en el que se producirá cada línea del log. 
 
public void setDateFormat(string $format) 
Establece  el  formato  de  fecha  con  los  modificadores  de  las  función  date()  para  producir  las 
fechas en las lineas del log. 
 
public $path getPath() 
Obtiene el path actual donde se están almacenando los logs. 
 
public void log(mixed $msg, $type=Logger::DEBUG) 
Agrega una líne al log de tipo $type. 
 
public void begin() 
Inicia una transacción en el log. 
 
public void rollback() 
Cancela una transacción en el log. 
 
public void commit() 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    393 

Acepta una transacción en el log almacenando las lineas pendientes. 
 
public void close() 
Cierra el log. 

43.7 Uso de MailLogger

El  componente  Logger  soporta  un  adaptador  especial  que  permite  que  este  al  cerrarse  se 
envie automáticamente a un correo electrónico. La extensión hace uso de la librería de envío 
de correo electrónico Swift que se distribuye con el framework.  
 
El  adaptador  está  diseñado  para  realizar  el  envío  de  e‐mails  usando  el  protocolo  SMTP  sin 
depender de la función mail() de PHP ó de la herramienta sendmail. 
 
Todas los registros del log que son agregados se almacenan en memoria hasta que se cierra el 
log, se invoca el método commit ó se destruye el objeto. Debido a lo anterior es recomendable 
no almacenar logs muy grandes ya que pueden consumir demasiada memoria y generar una 
salida fatal por parte de la aplicación. 
 
Los registros solo se pueden agregar cuando se activa una transacción en el log, por defecto 
una es iniciada automáticamente. También se puede usar el método begin() para iniciarla. 
 
Es necesario que el servidor pueda establecer conexiones salientes a puertos seguros (465) e 
inseguros  (25)  y  que  el  servidor  SMTP  esté  disponible  al  tratar  de  realizar  el  envio  del  log 
pues de lo contrario se generará una excepción. 
 
La extensión de PHP php_openssl debe estar cargada para hacer uso de este adaptador. 
 
El siguiente es un ejemplo del uso de MailLogger enviando un mensaje desde una cuenta de 
Gmail: 
 
Ejemplo: Crear un MailLogger que envia los mensajes a un correo de Gmail 
$log = new Logger("Mail", "support@example.com", array(
"server" => "smtp.gmail.com",
"secureConnection" => true,
"username" => "company.support@gmail.com",
"password" => "98j2ue12",
"subject" => "Problema en la aplicación"
));
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    394 

$log->log("Un Message de Error", Logger::ERROR);


$log->log("Un Message Critico", Logger::CRITICAL);
$log->close();
 
Al cerrar el log se envia un mail con los 2 mensajes acumulados internamente en el log. Para 
realizar  conexiones  seguras  por  TLS  se  debe  establecer  el  parámetro  “secureConnection”  a 
true. 
 
Cuando no se establece el asunto del mensaje MailLogger utiliza el siguiente formato: 
 
MailLog: nombreAplicacion – Fecha usando formato RFC2822 
 
Si se desea enviar el log a varios e‐mails se puede pasar un array como segundo parámetro al 
instanciar el log: 
 
Ejemplo: Enviando los mensajes del MailLogger a varios correos electronicos 
$log = new Logger("Mail", array(
"Soporte al Cliente" => "customer.support@example.com",
"Soporte Tecnico" => "technical.support@example.com",
"anothermail@example.com"
), array(
"server" => "smtp.gmail.com",
"secureConnection" => true,
"username" => "company.support@gmail.com",
"password" => "98j2ue12",
"subject" => "Problema en la aplicación"
));
$log->log("Un Message de Error", Logger::ERROR);
$log->log("Un Message Critico", Logger::CRITICAL);
$log->close();

43.8 Uso de DatabaseLogger

FALTA 

43.9 Uso de CompressedLogger

El adaptador CompressedLogger permite escribir logs a archivos de texto plano comprimidos 
usando zlib en el servidor local.  La extensión de PHP zlib debe estar cargada para hacer uso 
de este adaptador. 
 
La  ventaja  de  el  uso  de  este  tipo  de  logs  es  que  ahorran  sustancialmente  espacio  de  disco 
aunque requieren de mayores requerimientos de procesamiento. 
 
Ejemplo: Crear un log comprimido con Logger 
$logger = new Logger("Compressed", "my_app.log.gz");
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    395 

$logger->log(“Esta cadena será comprimida en el log”);


$logger->close();
 
Al  igual que FileLogger los registro se agregan en modo append es decir que nuevos mensajes 
se agregan al final del archivo. 
 
public void setPath(string $path) 
Permite establecer el Path donde se almacenaran los logs. 
 
public void setFormat(string $format) 
Establece el formato en el que se producirá cada línea del log. 
 
public void setDateFormat(string $format) 
Establece  el  formato  de  fecha  con  los  modificadores  de  las  función  date()  para  producir  las 
fechas en las lineas del log. 
 
public $path getPath() 
Obtiene el path actual donde se están almacenando los logs. 
 
public void log(mixed $msg, $type=Logger::DEBUG) 
Agrega una líne al log de tipo $type. 
 
public void begin() 
Inicia una transacción en el log. 
 
public void rollback() 
Cancela una transacción en el log. 
 
public void commit() 
Acepta una transacción en el log almacenando las lineas pendientes. 
 
public void close() 
Cierra el log. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    396 

43.10 Uso de SAMLogger

El adaptador SAMLogger permite enviar logs a un servicio de mensajes que soporten Simple 
Asynchronous  Messaging  como  el  IBM  WebSphere  MQSeries.  Este  adaptador  requiere  de  a 
extensión  SAM  que  permite  el  envio  de  mensajes  de  logs  a  aplicaciones  basadas  en  el  
WebSphere  Application  Server  que  usen  el  protocolo  de  mensajes  WebSphere  Platform 
Messaging (WPM). La extensión puede ser descargada de PECL.  
 
Ejemplo: Enviar mensajes de log a WebSphere Messaging Server 
//Conectarse a un servidor SAM con WebSphere Messaging Server
$logger = new Logger("SAM", null, array(
‘host => ‘192.168.10.100’,
‘port’ => 1506’,
‘broker’ => ‘webspherebroker’
));
$logger->log(“Esto es una alerta”, Logger::ALERT);
//Conectarse a un servidor SAM de una aplicación en WebSphere Application Server
$logger = new Logger("SAM", null, array(
‘endpoints => ‘192.168.10.100:7278:MyMessagingBoostrap’,
‘bus’ => Bus1’,
‘targetchain’ => ‘InboundMessaging’
));
$logger->log(“Esto es una alerta”, Logger::ALERT);

43.11 Uso de StreamLogger

Este  adaptador  es  el  más  flexible  y  potente  de  los  adaptadores  de  Logger  ya  que  permite 
escribir logs a diferentes recursos cuya escritura por stream este soportada por PHP. 
 
En los siguientes ejemplos se ilustra el uso de este adaptador: 
 
Ejemplo: Enviar mensajes de Log usando el adaptador StreamLogger 
//Este log será enviado a un archivo
$logger = new Logger("Stream", “file://mylog.txt");
$logger->log(“Un log de ejemplo”);
$logger->close();
//Este log será enviado a un archivo comprimido con gzip
$logger = new Logger("Stream", “compress.zlib://mylog.txt.gz");
//Este log será enviado a un archivo comprimido con bzip2
$logger = new Logger("Stream", “compress.bzip2://mylog.txt.gz");
//Este log será enviado a un archivo comprimido con bzip2
$logger = new Logger("Stream", “compress.bzip2://mylog.txt.bz2");
 
//Este log será enviado a un archivo mediante SSH
$logger = new Logger("Stream",
‘ssh2.sftp://user:password@example.com:22/path/to/file.txt");
//Este log será enviado a un archivo mediante FTP
$logger = new Logger("Stream",
”ftp://user:password@example.com/path/to/file.txt");
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    397 

//Este log será enviado a un archivo mediante FTP seguro


$logger = new Logger("Stream",
"ftps://user:password@example.com/path/to/file.txt");
 
//Este log será enviado a la salida estándar
$logger = new Logger("Stream", “php://stdout");
 
//Este log será enviado a la salida de errores
$logger = new Logger("Stream", “php://stderr");
//Este log será enviado a memoria
$logger = new Logger("Stream", “php://memory");
 
//Este log será enviado a memoria, en caso que los datos tengan un tamaño
superior a 2MB serán escritos a disco
$logger = new Logger("Stream", “php://temp");
//Cambiar limite a 10MB – 1073741824 bytes
$logger = new Logger("Stream", “php://temp/maxmemory:1073741824");

 
En las opciones del Stream puede establecerse el modo de escritura que tendrá en Log de esta 
forma: 
 

$logger = new Logger("Stream", “file://my_log.txt", array(


“mode” => “a”
));

 
Los posibles modos de escritura son: 
 
Tabla: Modos de escritura de logs usando StreamLogger 
Modo  Descripción 
a  Agrega logs al final del archivo existente. Si no existe lo crea. 
ab  Agrega  logs  al  final  del  archivo  existe.  La  escritura  es  binaria.  Este  es  el 
modo  predeterminado  para  StreamLogger,  FileLogger  y 
CompressedLogger. 
w  Escribe logs en el archivo. Lo trunca si existe y lo crea si no existe. 
wb  Escribe  logs  en  el  archivo.  Lo  trunca  si  existe  y  lo  crea  si  no  existe.  La 
escritura es binaria. 
x  Escribe logs en el archivo. Si ya existe genera una excepción. 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    398 

43.12 Uso de SocketLogger

Permite  escribir  logs  a  puertos  TCP/UDP  que  tengan  servidores  ó  servicios  que  acepten 
cadenas de texto. Los servidores de sockets pueden replicar logs a otros servidores mediante 
carácteristicas de bajo nivel. 
 
Ejemplo: Enviar mensajes de logs usando sockets TCP/UDP 
//Escribir a un servidor TCP en el puerto 1589
$logger = new Logger("Socket", “tcp://192.168.0.10:1589");
//Escribir a un servidor TCP en el puerto 1589 usando una conexión segura
$logger = new Logger("Socket", “ssl://192.168.0.10:1589");
//Escribir a un servidor UDP en el puerto 111
$logger = new Logger("Socket", “udp://192.168.0.10:111");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    399 

44 Componente Utils
44.1 Introducción

Utils  es  un  componente  que  principalmente  es  utilizado  por  el  framework  para  centralizar 
funciones  auxiliares  de  propósito  general,  su  funcionalidad  también  está  disponible  al 
desarrollador. 

44.2 API de Utils

static function array arrayMergeOverwrite(array $a1, array $a2)  
Este  método  permite  combinar  2  arrays  asociativos  multidimencionales  devolviendo  el 
resultado. 
 
static function void arrayInsert(array $form, mixed $index, mixed $value, mixed $key=null)  
Este método permite insertar un valor en una determinada posición de un array moviendo los 
elementos a su posición siguiente. 
 
static function array scandirRecursive(string $package_dir, array $files=array())  
Devuelve  un  vector  con  todos  los  archivos  que  haya  una  ruta.  Este  método  recorre 
recursivamente los directorios encontrados. 
 
static function array getParams(array $params, int $numberArgs)  
Convierte  los  parámetros  por  nombre  recibidos  en  una  función  y  los  convierte  a  un  array 
asociativo.  El  primer  parámetro  normalmente  es  un  array  devuelto  por  la  función 
func_get_args() y el segundo el valor devuelto por func_num_args(). 
 
static function array getParam(string $param)  
Devuelve un array asociativo con el resultado de un parámetro por nombre. La llave del item 
es el nombre del parámetro y su valor respectivo. 
 
static function string camelize(string $str)  
Devuelve una cadena de carácteres en notación camelizada. 
 
static function string uncamelize(string $str) 
 Devuelve una cadena de carácteres en noticación under score (guion bajo). 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    400 

static function string lcfirst(string $s)  
Convierte la primera letra de una palabra a minúsculas. 
 
static function string getKumbiaUrl(string $url)  
Obtiene  una  ruta  valida  según  el  entorno  de  ejecución  de  la  aplicación.  Esta  URL  devuelta 
permitirá acceder a la aplicación usando un recurso externo. 
 
static function array getQuotedArray(array $toQuoteArray, string $quoteChar=''')  
Agrega  comillas  a  cada  elemento  de  un  array.  El  carácter  de  comillas  se  establece  con 
$quoteChar. 
 
static function string ucwords(string $words)  
Convierte la primera letra de cada palabra de $words a mayúscula respetando el charset en el 
que se encuentra el valor de entrada. 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    401 

Parte 8: Rendimiento y Optimización 
 

45 Rendimiento y Optimización
45.1 Introducción

En  este  capítulo  se  referencian  los  componentes  y  prácticas  que  ayudan  a  mejorar  el 
rendimiento de aplicación desarrollada en Kumbia Enterprise. 

45.2 Consideraciones de Rendimiento

En  los  siguientes  apartados  se  recomiendan  prácticas  que  mejoran  el  rendimiento  de  una 
aplicación.  

45.2.1 Utilización de parámetros por nombre 
Muchos  de  los  componentes  de  framework  como  ActiveRecord,  Router  y  Tag  soportan 
parámetros por nombre. Estos permiten indicar los valores de los parámetros requeridos en 
cualquier orden solventando una limitación del lenguaje PHP.   
 
Cuando se trata de mejorar el rendimiento de una aplicación es recomendable reemplazar los 
llamados  a  métodos  que  utilicen  parámetros  por  nombre  por  arrays  cuyos  indices 
representen los nombres de estos.  De esta forma se elimina el overhead que requiere evaluar 
mediante expresiones regulares los parámetros por nombre y así optimiza la ejecución de la 
aplicación. 

45.2.2 Instalar un Cache de OpCode 
Una de las mejores prácticas para mejorar el rendimiento de aplicaciones en Kumbia Enteprise 
en  fase  de  producción  es  instalar  un  cacheador  de  código  intermedio.  Debido  a  que  en  esta 
fase  archivos  que  contienen  código  PHP  usualmente  no  se  modifican,  un  software 
especializado puede cachear el  codigo intermedio (codigo PHP que se ha revisado su sintaxis 
y se ha eliminado fragmentos innecesarios para la ejecución como comentarios y otras partes) 
de  esta  forma  cada  vez  que  se  carga  un  archivo  PHP  en  el  compilador  parte  del  trabajo  de 
interpretación ya está hecho. 
 
Normalmente los caches de código intermedio leen datos de los archivos PHP como el inodo y 
el  dispositivo  donde  esta  almacenado  para  crear  un  identificador  único  para  el  mismo  y  así 
evitar que un mismo archivo sea leido varias veces en una misma petición. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    402 

 
La  eliminación  de  la  etapa  de  parseo  del  código  intermedio  PHP  no  es  la  única  mejora  que 
realiza un cacheador. Otras mejoras incluyen un consumo reducido de recursos de disco duro 
y optimizaciones al código intermedio. Las aplicaciones que normalmente realicen peticiones 
cortas  con  una  inclusión  moderada  de  otros  archivos  en  la  misma  pueden  obtener  mejoras 
hasta del 200% y 300%. Para procesos largos la optimización puede ser del 30% al 40%. En 
cualquier caso la mejora siempre es considerable. 
 
La  mayor  ventaja  de  los  cacheadores  de  código  intermedio  es  que  no  requiren  que  la 
aplicación sea desarrollada bajo ningún tipo de estandar ó con algún requerimiento especial. 
La única limitación es que PHP debe estar instalado como un módulo del servidor ó usando 
FastCGI,  esto  se  debe  a  que  los  datos  del  código  intermedio  se  almacenan  en  memoria 
compartida y ésta no está disponible para modulos cgi. 
 

45.2.2.1  Cacheadores de Código Intemerdio Disponibles 
Existen  implementaciones  de  cacheadores  tanto  abiertas  como  cerradas.  En  las  de  código 
abierto  se  encuentra  la  extensión  PECL  Alternative  PHP  Cache  (APC) 
http://pecl.php.net/package/APC  y  Turck  MMCache  http://turck-
mmcache.sourceforge.net/index_old.html.  En  las  opciones  de  código  cerrado  está  Zend 
Optimizer  http://www.zend.com/store/products/zend-platform/  y  phpAccelerator 
http://freshmeat.net/projects/phpa/. 
 
Las  velocidades  de  todas  las  implementaciones  son  en  promedio  muy  parecidas.  La  opción 
APC no implementa optimizaciones de código intemerdio por lo que en algunas situaciones en 
rendimiento puede ser menor. 

45.2.3 Sintonización del Servidor Web 
Algunas optimizaciones referentes a aplicaciones desarrolladas en Kumbia Enterprise pueden 
ser  realizadas  a  nivel  del  Web  Server.  A  continuación  se  presentan  las  que  aplican  para 
Apache Web Server ó otros basados en él, como Oracle HTTP Server y Zend Application Server. 

45.2.3.1 Eliminar encabezados innecesarios 
El encabezado HTTP que contiene el tipo de servidor usado es enviado en cada respuesta que 
genera el servidor Web. En la mayor parte de los casos este encabezado no tiene uso aplicable 
y por lo tanto hace algo más grande la respuesta del servidor sin necesidad alguna. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    403 

 
Server: Apache/2.0.59 (Unix) PHP/5.2.9 DAV/2 Server at localhost Port 80
 
Este  encabezado  puede  eliminarse  cambiando  en  la  configurción  de  Apache  la  opción 
ServerSignature  a  Off.  De  esta  forma  se  puede  ahorrar  más  de  1GB  de  ancho  de  banda  para 
una aplicación en producción durante un mes. 

45.2.4 Sintonización de PHP 
FALTA 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    404 

46 Componente Cache
46.1 Introducción

Las aplicaciones de alta disponibilidad requieren dependiendo de las condiciones del negocio 
sistemas  de  cache  que  ofrezcan  la  posibilidad  de  implementar  transacciones,  control  de 
concurrencia  y  clusterización.  LouderTechnology  proporciona  LouderCache  un  proyecto 
independiente pero totalmente integrable al framework el cual ha sido desarrollado pensando 
en estas características empresariales.  
 
Cuando se requiere mejorar el rendimiento y optimizar una aplicación mediante tareas más 
sencillas como cachear fragmentos de vistas, datos y registros Kumbia Enterprise framework 
proporciona el componente Cache.  
 
FALTA 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    405 

47 Componente Compiler
47.1 Introducción

Kumbia  Enterprise  Framework  utiliza  inyección  de  dependencias  para  instanciar  cualquier 
componete  a  medida  que  se  va  requiriendo.  Esto  resulta  ideal  ya  que  evita  que  decenas  de 
archivos sean cargados en una petición sin que sean requeridos encontrado la media perfecta 
de requerimientos de dependencias para cada proceso de negocio. 
 
Algunos  componentes  como  Router,  Dispatcher,  Core,  etc.,  no  requieren  de  inyección  ya  que 
debido  a  la  arquitectura  del  framework  son  requeridos  siempre  en  cada  petición  y  de  está 
forma  se  mejora  el  rendimiento  de  una  aplicación.  Otros  componentes  son  requeridos 
usualmente  pero  dependiendo  de  los  objetivos  de  la  aplicación  se  puede  decir  que  son 
utilizados ‘frecuentemente’.   
 
El  desarrollador  puede  contar  cuantos  archivos  son  leidos  en  una  determinada  petición  de 
esta forma: 
 
<?php echo print_r(get_required_files()); ?>
 
Si el número de archivos es muy elevado, la aplicación podría estar consumiendo recursos de 
lectura de disco altos haciendo que el rendimiento de una aplicación se disminuya. 
 
El  componente  Compiler  resuelve  estas  situación  generando  un  solo  archivo  con  todos  los 
componentes y archivos del framework en una versión ‘optimizada’ que son utilizados en una 
petición  regular  y  dejándole  el  resto  del  trabajo  al  inyector  de  dependencias.  El  uso  de  este 
componente puede aumentar el rendimiento del framework de 4 a 5 veces. Si se cuenta ó no 
se  cuenta  con  un  optimizador  y  cacheador  de  código  intermedio  este  componente  siempre 
puede ser de gran ayuda para el mejoramiento del rendimiento de una aplicación. 
 
Por ser una solución basada 100% en PHP puede tener un papel vital cuando no se cuenta con 
control del hardware donde se implementa la aplicación. 
 
Nota: Compiler solo debe ser usado cuando la aplicación haya cumplido en gran medida con 
las fases de desarrollo y testeo ya que algunos componentes de la aplicación son incluidos en 
la compilación con lo cuál no se podría realizar cambios a estos. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    406 

47.2 Teoria de optimización avanzada

En este apartado se trata de explicar las teorias que en LouderTechnology se han investigado 
para tratar de búscar una ejecución más optima de aplicaciones en PHP. Las investigaciones se 
basan en benchmarks a diferentes tipos de procesos. 

47.2.1 Optimización de ciclos 
47.2.1.1 Optimización por reemplazo de funciones 
Si para un conjunto X’ de instrucciones repetitivas se evalua n veces una misma función f(x) ­> 
y’,  en  donde  x  es  un  valor  estático  para  este  contexto  entonces  podría  decirse  que  hay  una 
degradación del rendimiento ya que el valor y’ es evaluado al menos n veces. 
 
La función entonces puede ser traducida a f(x) ­> z’ reemplazando z’ ‐> y’ en el conjunto X’. 

47.2.2 Optimización por evaluación de terminos estáticos 
Definición 1: Si para una evaluación de la expresión de compilación f : X ‐> Y, los valores de x 
resultan  de  operaciones  polimorficas    deducibles  entonces  se  puede  decir  que  f  :  z’  ‐>  Y 
producirá el mismo resultado en ejecución. 
 
Definición 2: Si para una evaluación de la expresión de compilación f : X ‐> Y, los valores de x 
resultan de reemplazar constantes deducibles entonces se puede decir que f : z’ ‐> Y producirá 
el mismo resultado en ejecución. 

47.3 Comportamiento de Compiler

El componente genera un único archivo con todos los componentes y clases utilizados en una 
petición  regular  a  una  aplicación.  Otros  componentes  pueden  ser  agregados  a  este  archivo 
para hacer más efectivo el objetivo esperado. 

47.3.1 Optimizaciones básicas de la compilación 
El  archivo  generado  es  producido  realizando  las  siguientes  optmizaciones  que  pueden 
mejorar en medida menor ó media el rendimiento de una petición: 
 
• Todos los comentarios de linea sencilla y multi‐linea son eliminados 
• Espacios, tabulaciones y saltos de línea son eliminados. 
• Archivos que sean incluidos en otros archivos ya incluidos son omitidos 
• Las constantes __FILE__ y __LINE__ mantienen su valor original 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    407 

47.3.2 Optimizaciones avanzadas de la compilación 
Con  base  al  funcionamiento  interno  del  compilador  de  PHP  es  posible  determinar  que 
prácticas  de  programación  son  más  reconmendables  para  obtener  mejoras  en  velocidad  y 
rendimiento. Compiler ofrece una fase de compilación denominada avanzada en la que realiza 
las siguientes optimizaciones: 
 
• Todos los strings de doble comilla que no contengan sustituciones de variables ó 
caracteres de barra invertida son convertidos a strings de comilla sencilla, excepto los 
que son multi‐línea, de esta forma se evita que el analizador léxico del interprete PHP 
búsque innecesariamente expresiones regulares que no van a ser encontradas. 
• Las sentencias ‘for’ son optimizadas cuando realizan conteos sucesivos en su 
evaluación. El código es modificado haciendo que el conteo se ejecute una sola vez: 
 
Ejemplo: Optimización por eliminación de calculos redundantes 
<?php
$unArrayGrande = range(1, 10000);
for($i=0;$i<=count($unArrayGrande)-1;$i++){
print $unArrayGrande[$i];
}
 
Es modificado a: 
 
<?php
$unArrayGrande = range(1, 10000);
$_sp=count($unArrayGrande)-1;
for($i=0;$i<=$_sp;$i++){
print $unArrayGrande[$i];
}
 
• Cuando alguna de las variables de la evaluación es modificada entonces la sentencia 
‘for’ se mantiene intacta: 
 
<?php
$unaPalabra = "esto es un texto";
for($i=0;$i<=strlen($unaPalabra)-1;$i++){
if($i%2==0){
$unaPalabra.="x";
}
if($i>10){
break;
}
}
 
• Las  asignaciones  que  no  se  hagan  con  el  operador  de  incremento  ó  decremento  son 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    408 

convertidas  a  esta  forma,  por  lo  tanto  $x  =  $x  +1  se  lleva  a  $x++  y  $x  =  $x  +  $y  se 
convierte en $x+=$y; 
 
El desarrollador puede tener en cuenta las optimizaciones anteriores e implementarlas como 
buenas prácticas de desarrollo. 

47.4 Generar una Compilación

Como  se  mencionó  anteriormente  el  objetivo  de  la  compilación  es  reunir  todos  aquellos 
componentes y recursos que constituyen una media de lectura de disco optimizandolos y así 
mejorar el rendimiento de la aplicación. 
 
En  el  proceso  seleccionado  por  el  desarrollador  se  invoca  el  método  compileFramework  del 
componente Compiler: 
 
<?php Compiler::compileFramework() ?>

47.5 Limitaciones de Compiler

El componente Compiler tiene las siguientes limitaciones: 
FALTA 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    409 

48 Componente GarbageCollector
48.1 Introducción

El  componente  GarbageCollector  permite  de  manera  controlada  comprimir  ó  eliminar  datos 
del  estado  de  persistencia  y  meta‐datos  de  entidades  almacenados  en  el  administrador  de 
sesión. 

48.2 ¿Porque usar este componente?

Los  controladores  que  implementan  el  estado  de  persistencia  proporcionan  un  potente 
método  para  mantener  contextos  de  sesión  que  mejoran  la  experiencia  de  usuario  en  un 
determinando componente de la aplicación. El uso excesivo de múltiples contextos (múltiples 
controladores  con  estado  de  persitencia)  podría  sobrecargar  la  aplicación  ya  que  todos  los 
datos de persistencia son parcialmente cargados en cada petición.  
 
Este componente puede detectar que contextos han expirado y liberar la memoria persistente 
utilizada aumentando el rendimiento de la aplicación. 

48.3 Como funciona el GarbageCollector

El  componente  proporciona  el  método  GarbageCollector::startCollect()  que  con  base  a  una 
probabilidad  predefinida  invoca  una  rutina  en  busca  de  datos  del  estado  de  persistencia  ó 
meta‐datos de entidades que se consideren en des‐uso ó expirados. La rutina del colector se 
ejecuta en 2 fases:  

48.3.1 Fase de Compresión 
Primero se localizan datos que no se hayan usado en un tiempo predefinido y se comprimen 
los  datos  usando  zlib  en  nivel  de  compresión  5  (normal).  En  este  caso  no  se  actúa 
propiamente  como  recolector  de  datos  en  desuso  pero  da  la  oportunidad  de  re‐utilizar  los 
datos ahorrando espacio al mismo tiempo. 

48.3.2 Fase de Eliminación  
Cuando  los  datos  han  superado  un  tiempo  de  desuso  pronunciado  se  procede  a  su 
eliminación. En el caso de los controladores persistentes básicamente se produce el efecto de 
reinicio de sus atributos y en el de los meta‐datos de entidades se obliga a un nuevo volcado 
por parte de ActiveRecordMetaData. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    410 

48.4 Activar el GarbageCollector

Por  defecto  el  garbage  collector  se  encuentra  desactivado  para  cualquier  aplicación,  su 
activación puede ser programacional ó declarativa. 

48.4.1 Activación de manera programacional 
La  rutina  de  recolección  puede  ser  invocada  programacionalmente  al  finalizar  una  petición. 
Un plugin de aplicación resulta ideal para invocar el garbage collector. Se recomienda que la 
recolección se haga siempre al finalizar las peticiones ya que en este punto se asegura que los 
datos a liberar realmente esten en desuso ó expirados. 
 
Ejemplo: Establecer las opciones del collector programacionalmente 
<?php
class MyCollectorPlugin extends ApplicationPlugin {
public function beforeFinishRequest(){
//Expirar objetos que tengan más de una hora en desuso
GarbageCollector::setCollectTime(3600);
GarbageCollector::startCollect();
}
}

48.4.2 Activación de manera declarativa 
En el archivo config/config.ini es posible activar de forma declarativa el recolector mediante la 
siguiente configuración: 
 
Ejemplo: Activar el collector desde el archivo de configuración config.ini 
[application]
mode = development
name = "APPLICATION NAME"
debug = On
[collector]
probability = 100
compressionTime = 900
compressionLevel = 5
collectTime = 1800
 
La  definición  de  la  sección  collector  activa  el  componente  GarbageCollector  y  su  rutina  de 
liberación de recursos es ejecutada al final de cada petición a la aplicación. 

48.5 Parámetros del Collector

Los siguientes parámetros determinan el comportamiento del componente: 
 
Tabla: Parámetros del componente GarbageCollector 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    411 

Parámetro  Descripción 
probability  Es  un  número  entero  positivo  que  determina  la  probabilidad  que  la 
rutina  de  recolección  se  ejecute.  El  collector  se  ejecuta  cuando  un 
número aleatorio generado entre 1 y probability da exactamente en su 
mitad  entera.  Un  número  alto  reduce  la  probabilidad  y  uno  bajo  la 
aumenta. 
compressionTime  Es  el  tiempo  que  un  objeto  debe  superar  para  que  el  colector  lo 
comprima  para  ahorrar  espacio.  Por  defecto  es  900  segundos  (15 
minutos). 
compressionLevel  Es  el  nivel  de  compressión  que  se  utilizara  en  la  primera  fase  del 
colector. Es un entero entre 0 para cero compresión y 9 para máxima. 
Un  número  elevado  aumenta  los  recursos  utilizados  para  efectuar  la 
operación pero reduce más espacio. La compresión se realiza usando el 
formato Zlib (ZLIB Compressed Data Format Specification version 3.3).
Se requiere que la extensión de PHP zlib este disponible. Por defecto es 
5. 
collectTime  Es el tiempo que debe pasar un objeto en desuso para marcarse como 
expirado  y  realizar  su  posterior  eliminación.  Por  defecto  es  1800 
segundos (30 minutos). 
 

48.6 API de GarbageCollector

FALTA 
 
 
 
 
 
 
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    412 

Parte 9: Contexto y Administración de Sesiones 
 

49 Componente Session
49.1 Introducción

El  componente  Session  ofrece  principalmente  un  método  orientado  a  objetos  para  la 
administración  de  persistencia  de  una  aplicación  Web.  Con  una  arquitectura  basada  en 
adaptadores es posible de manera flexible definir diferentes backend de almacenamiento de 
sesión a cada aplicación.    
 
Es altamente recomendable utilizar el componente Session para almacenar datos de sesión en 
vez  de  utilizar  la  superglobal  $_SESSION.  Los  métodos  estáticos  Session::set  y  Session::get 
administran  la  memoria  de  las  aplicaciones  de  tal  forma  que  los  datos  de  sesión  sean 
completamente independientes a otras aplicaciones que corran en el mismo servidor y sobre 
el mismo cliente.  
 
Esta  independencia  elimina  posibles  problemas  de  seguridad  asociados  a  la  utilización  de 
aplicaciones con una estructura de autenticación y validación de credenciales idéntica.  
 
En  el  siguiente  ejemplo  se  visualiza  como  Session  separa  la  persistencia  en  cada  aplicación. 
Tenemos 2 instancias del Framework en el document root del servidor web, la primera para la 
intranet y la segunda para la intranet. Cada instancia tiene una serie de aplicaciones asociadas 
a cada una junto con un backend de sesión diferente. 
 
Ejemplo: Estructura de aplicaciones con diferentes backend de Sesión  
intranet/
apps/
default/ | memcached
produccion/ | files
compras/ | Database:MySQL
extranet/
apps/
default/ | files
reservas/ | Database:Sqlite
informacion/ | memcached
produccion/ | files
 
En  la  aplicación  existe  una  variable  de  sesión  llamada  “auth”,  esta  variable  controla  que  el 
usuario  final  esté  autenticado  en  una  aplicación.  Normalmente  utilizaríamos  esta  variable 
usando  la  superglobal  $_SESSION[‘auth’].  Sin  embargo  el  valor  de  esta  variable  estaría 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    413 

asociado  a  nuestro  ‘session  id’  y  si  accedemos  a  otra  aplicación  también  estaríamos 
autenticados. Si las reglas del negocio lo permiten esto estaría correcto, pero en la mayoría de 
casos cada aplicación administra diferentes modelos de seguridad y validación.  
 
El componente Session hace que la misma variable “auth” sea diferente en cada aplicación de 
forma independiente y en forma transparente para el desarrollador. 
 
En  el  ejemplo  también  se  visualiza  que  la  aplicación  ‘produccion’  existe  tanto  en  ‘intranet’ 
como  en  ‘extranet’  sin  embargo  su  finalidad  es  diferente.  El  componente  Session  separa  la 
persistencia  de  sesión  tomando  en  cuenta  que  se  encuentra  en  diferentes  instancias  del 
Framework así el nombre de la aplicación sea el mismo. 

49.2 Adaptadores de Sesión

Cada  aplicación  puede  utilizar  un  backend  diferente  desacuerdo  a  las  necesidades  de  la 
aplicación.  El  componente  Session  implementa  el  patrón  Gateway  actuando  como  puerta  de 
enlace  al  adaptador  requerido  cuando  se  efectúan  operaciones  sobre  el  estado  de  la  sesión. 
Una descripción de los backend disponibles es: 
 
Tabla: Adaptadores del componente Session 
Adaptador  Descripción 
Memcache  Ofrece  mayor  velocidad  y  rendimiento  que  los  demás  backend.  El 
almacenamiento se realiza en memoria RAM por lo que se evita la intensiva 
lectura/escritura de disco de los demás backend. Su escalabilidad es mayor 
igualmente. 
Database  Permite  realizar  el  usando  una  tabla  en  una  base  de  datos.  En  el  caso  de 
MySQL junto con NDB Cluster puede aumentar la escalabilidad, aunque esto 
debe  ser  evaluado  de  acuerdo  a  las  reglas  del  negocio.  Este  tipo  de 
implementación de sesiones aplica el patrón Database Session State. 
Files  Es el medio de almacenamiento por defecto de PHP que utiliza el sistema de 
archivos  para  guardar  los  datos  de  sesión.  Optimizaciones  al  sistema  de 
archivo podrían mejorar el rendimiento. 
LouderCache  Utiliza  el  Louder  Cache  como  backend  para  almacenar  los  datos  de  sesión. 
De  esta  forma  se  puede  conseguir  un  sistema  escalable  y  de  alta 
disponibilidad para almacenar el estado de sesión de una aplicación. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    414 

 
Los adaptadores de sesión implementan la interface SessionInterface: 
 
interface SessionInterface {
public function getSaveHandler();
public function initialize();
}

49.2.1 Adaptador de Sesión Memcache 
Para  activar  el  adaptador  Memcache  se  debe  agregar  a  la  sección  application  del  archivo 
config.ini de la aplicación lo siguiente: 
 
Ejemplo: Establecer el adaptador de sesión a Memcached 
sessionAdapter = memcache
sessionSavePath = "tcp://127.0.0.1:11211?persistent=1&weight=2&timeout=2"
 

49.2.2 Adaptador de Sesión Database 
Para usar el adaptador de sesiones usando una tabla de la bases de datos se debe agregar a la 
sección application del archivo config.ini de la aplicación lo siguiente: 
 
Ejemplo: Establecer el adaptador de sesión a Database 
sessionAdapter = database
sessionSavePath = "mysql:host=127.0.0.1;username=root;password=mypass;name=mydb"
 
En la base de datos seleccionada se debe crear la siguiente tabla: 
 
CREATE TABLE `session_data` (
`id` int(18) NOT NULL auto_increment,
`session_id` varchar(35) NOT NULL,
`data` text,
`timelife` int(15) default NULL,
PRIMARY KEY (`id`),
KEY `session_id` (`session_id`)
);
 
Un  collector  de  datos  de  sesión  no  utilizados  es  implementado  en  este  adaptador  para  los 
datos  de  sesión  que  hayan  expirado.    Sesiones  que  tengan  más  de  24  horas  de  expiración 
serán eliminadas de la tabla session_data. 

49.2.3 Adaptador de sesión Files 
Es  el  adaptador  por  defecto  y  no  es  necesario  realizar  configuraciones  adicionales  para 
establecerlo. La ruta de almacenamiento de archivos puede modificarse buscando aprovechar 
optimizaciones del sistema de archivos. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    415 

 
Ejemplo: Establecer el adaptador de sesión a files 
sessionAdapter = files
sessionSavePath = "/path/to/session/data"
 
Sistemas  de  archivos  como  ReiserFS  en  Linux  pueden  mejorar  el  rendimiento  ya  que  estos 
administran mejor archivos pequeños. 

49.2.4 Adaptador de sesión Louder Cache 
Para usar este adaptador LouderCache debe estar instalado como una librería en la instancia 
del framework.  

49.3 Comportamiento de Sesiones

Las  sesiones  Kumbia  Enterprise  Framework  son  inicializadas  en  un  managed  environment 
(entorno administrado) con lo que el punto de inicialización y finalización de sesiones no debe 
ser  un  problema  para  el  desarrollador.  Los  datos  en  el  entorno  de  persistencia  son 
serializados/deserializados exactamente cuando es necesario, un mal manejo de esto podría 
generar  perdida  de  datos  si  se  realizase  manualmente,  especialmente  cuando  se  almacenan 
objetos  ó  se  trabaja  con  Web  services.  El  Framework  implementa  el  patrón  Server  Session 
State para conceptualmente administrar el estado de persistencia de la aplicación. 
 
Las  sesiones  se  inicializan  justo  después  de  cargar  la  clase  controladora,  cualquier 
procedimiento previo a esto en donde se interactúe con sesiones puede producir resultados 
confusos.  Los  plugins  de  controlador  que  implementen  el  método 
Plugin::beforeDispatchLoop() son un ejemplo de esto. 

49.4 Consideraciones de Seguridad

Las sesiones son un blanco de ataques informáticos entre ellos estan los Hijacking ó Fixation. 
Una  aplicación  Web  mal  diseñada  puede  ser  blanco  de  ello,  independiente  del  Framework 
utilizado  para  su  desarrollo.  Una  de  las  mejores  formas  de  evitar  esto  es  usar  sessiones 
basadas  en  cookies  usando  la  directiva  de  configuración  de  php    session.use_cookies  =  1  y 
además session.use_only_cookies = 1.  
 
Una  buena  practica  adicional  a  lo  anterior  es  ocasionalmente  validar  el  tipo  de  dato  de  los 
valores  que  provengan  de  sesiones  usando  el  componente  Filter  en  casos  en  los  que  los 
valores de sesión vayan a ser utilizados para insertar datos en la base de datos: 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    416 

 
Ejemplo:  Filtrar los datos de session para evitar hijacking 
<?php
class CustomerController extends ApplicationController {
public function beforeFilter(){
$valor = Session::get(“valor”, “int”);
$nombre = Session::get(“nombre”, “alpha”);
}
}

49.5 Variables de sesión

El componente Session permite la administración de variables de sesión que corresponden a 
valores simples que se referencia mediante un índice ó nombre clave. 
 
 Las variables de sesión se almacenan en espacios de memoria independientes por aplicación 
con lo que se evita situaciones confusas al utilizar índices comunes en diferentes aplicaciones 
que se usen en una mismo contexto de sesión con un usuario. 

49.5.1 API del Componente Session 
public static void initSessionData() 
Inicializa los datos de sesión es decir los deserializa y crea un vector interno listo para usar. 
Usualmente este método no es invocada por el desarrollador y es implícitamente llamado al 
usar getData ó setData. 
 
public static void storeSessionData() 
Este método es llamado como un register_shutdown_function y serializa los datos de sesión. 
 
public static void setData(string $index, mixed $value) 
Permite establecer un valor de sesión $value mediante la llave $index. 
 
public static mixed getData(string $index) 
Permite obtener un valor de sesión de un valor establecido con la llave $index. 
 
public static void set(string $index, mixed $value) 
Establece el valor de una variable de sesión usando la clave $index y el valor $value. 
 
public static mixed get(string $index) 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    417 

Obtener el valor de una variable de sesión usando la clave $index. 
 
public static void unsetData(string $index) 
Eliminar un variable de sesión usando la clave $index 
 
public static mixed issetData(string $index) 
Permite conocer si una variable de sesión ya existe. Este método devuelve un valor booleano 
true cuando ya existe y false en el caso contrario. 
 
public static void isLocked() 
Permite saber si la sesión esta bloqueada para escritura. 
 
public static boolean isStarted() 
Permite saber si ya se ha inicializado el adaptador de sesión y todo el contexto de sesión como 
tal. 
 
public static void startSession() 
Inicia el contexto de sesión incluyendo el adaptador de administración de sesiones. 

49.6 SessionNamespace

La clase SessionNamespace es un subcomponente de Session el cual permite la utilización de 
datos  de  sesión  de  manera  orientada  a  objetos  y  manteniendo  la  independización  de  la 
memoria persistente de las aplicaciones desarrolladas. 
 
Al  crear  un  Namespace  se  asigna  un  nombre  único  que  permite  identificar  el  espacio  de 
nombres en toda la aplicación. Los identificadores de los Namespaces deben ser Strings, estos 
no tienen conflicto con los nombres utilizados en los métodos Session::set y Session::get. 
 
Los  objetos  de  sesión  creados  en  los  SessionNamespace  son  objetos  administrables  que  son 
automáticamente  serializados/deserializados  al  guardarse  en  el  backend  de  sesión.  Además, 
estos objetos tienen la propiedad de poderse bloquear/desbloquear para evitar que su valor 
sea modificado por error ó por componentes de terceros. 
 
En  el  siguiente  ejemplo  se  muestra  un  SessionNamespace  para  almacenar  la  información 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    418 

relevante  a  los  datos  del  usuario  al  inicio  de  una  sesión.  Como  se  ilustra,  no  es  necesario 
ejecutar  ningún  procedimiento  para  almacenar  los  cambios  del  Namespace,  el  nombre 
UserData es usado posteriormente para recuperar la información del mismo. 
 
Ejemplo: Utilización de SessionNamespace 
<?php
class LoginController extends ApplicationController {
public function processLoginAction(){
$userData = SessionNamespace::add('UserData', 'name', 'John
Smith');
$userData->setRole("Administrator");
$userData->setLogin("j.smith");
}
public function anotherAction(){
$userData = SessionNamespace::get('UserData');
if($userData->getRole()=="Administrator"){
Flash::notice("Bienvenido, su login es ".$userData-
>getLogin());
}
SessionNamespace::lock('UserData');
}
public function theLastAction(){
$userData = SessionNamespace::get('UserData');
try {
$userData->setRole("Public");
}
catch(SessionException $e){
Flash::error("Error: La sesi&oacute;n esta bloqueada");
}
}
}

 
Para obtener/establecer los valores del namespace se debe utilizar getters/setters implícitos 
en  el  objeto  devuelto  por  SessionNamespace::add  ó  SessionNamespace::get.  Estos  utilizan 
notación camelizada y la utilización del mismo ayuda a que el comportamiento de este sea el 
esperado.  Los  objetos  creados  son  instancias  de  NamespaceContainer  quien  además 
proporciona los métodos setValue y getValue que permiten obtener/establecer los valores del 
namespace dinámicamente mediante claves.  

49.6.1 API de SessionNameSpace 
public  static  NamespaceContainer  add(string  $namespace,  string  $property=null,  mixed 
$value=null) 
Crea  un  nuevo  SessionNamespace  ó  devuelve  uno  existe.  Es  posible  establecer  un  primer 
valor usando el parámetro $property y $value. 
 
public static void lock(string $namespace) 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    419 

Bloquea el SessionNamespace para evitar cambios en sus datos internos. 
 
public static void unlock(string $namespace) 
Desbloquea el SessionNamespace permitiendo cambios en sus datos internos. 
 
public static NamespaceContainer get(string $namespace) 
Obtiene un SessionNamespace existente. 
 
public static boolean exists(string $namespace) 
Indica si un SessionNamespace ya existe ó no. 
 
public static void reset(string $namespace) 
Elimina los datos del SessionNamespace. 
 
public static void drop(string $namespace) 
Elimina el SessionNamespace. 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    420 

Parte 10: Herramientas del Desarrollador 
 

50 Herramientas del Desarrollador


50.1 Introducción

En  este  capítulo  se  explican  comportamientos  de  las  aplicaciones  desarrolladas  en  Kumbia 
Enterrprise  que  sirvan  de  guía  al  desarrollador.  Además  se  presentan  componentes  que 
ofrecen  facilidades  para  el  testeo  ó  el  rapid  development  como  la  generación  de  código 
acelerando procesos de desarrollo en una aplicación de negocios. 
 

51 Errores y Excepciones
51.1 Introducción

Kumbia  Enteprise  es  un  framework  diseñado  para  sostener  e  implementar  aplicaciones 
críticas cuyos procesos esten excesivamente testeados y cuando se lleven a producción tengan 
una  madurez  considerablemente  buena.  Para  lograr  esto  se  ha  diseñado  el  framework  para 
adoptar  en  cierto  nivel  comportamientos    como  los  de  los  lenguajes  compilados  ó  semi‐
compilados.  
 
Las  aplicaciones  en  PHP  normalmente  realizan  acciones  que  dependiendo  de  la  situación 
conllevan a que procesos aborten ó no se ejecuten correctamente debido a malas prácticas de 
desarrollo.  Estas  prácticas  van  desde  crear  dinámicamente  atributos  en  objetos,  obtener 
valores  de  indices  que  no  se  han  definido  en  arrays,  pasar  argumentos  del  tipo  incorrecto  a 
métodos y funciones y hasta no implementar el modo E_STRICT. 
 
Cuando  usted  desarrolla  en  Kumbia  Enterprise  el  framework  le  ayuda  a  detectar  cualquier 
mala práctica de desarrollo ó situaciones de baja criticidadad que muchas veces se pasan por 
alto obligando a que se tome un correctivo apropiado. 
 
El carácter interpretado de PHP dificulta que se encuentren errores ó inconvenientes de tipos 
en  una  primera  fase  de  compilación  ya  que  esta  es  inexistente.  Por  esto  es  necesario  hacer 
testeos a todos los procesos en múltiples escenarios para detectar problemas y corregirlos. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    421 

51.2 Modo SUPER_STRICT

Todas las situaciones de error, advertencia e información que se generan desde PHP y como 
parte  del  proceso  de  validación  riguroso  implementado  en  una  aplicación  se  reportan  al 
desarrollador en forma de excepciones.   
 
Algunas situaciones que generan excepciones: 
 
• Llamados a métodos y funciones enviando tipos de datos incorrectos. Funciones que 
reciban arrays ó instancias predefinidas de objetos. 
• Llamados a métodos y funciones con un número incorrecto de parámetros 
• Leer una propiedad de un objeto que no haya definido previamente 
• Escribir una propiedad de un objeto que no se haya definido previamente 
• Leer una variable que no se haya definido 
• Leer un valor de un indice de un array que no se haya definido 
• Leer con include un archivo que no exista 
• Invocar un método en forma estática sin que este definido como tal 
• Realizar una división por cero 
• Realizar una operación cuyos operandos no esten soporados por los operadores  
• Deserializar un objeto incompleto 
• Asignar una referencia a un objeto instanciado con new 
• Indexar un vector usando una constante no definida 
• Tratar de convertir un objeto (sin __toString()) definido en un valor escalar (entero, 
flotante) 
• Tratar de convertir un objeto stdClass en una cadena 
 
Variables de configuración que generan excepciones (pueden ser desactivadas): 
 
• Tener register_globals activado 
• Tener session.use_only_cookies = 0 

51.3 Capturar excepciones de gravedad leve

Algunos desarrolladores pueden considerar que determinados componentes son susceptibles 
a  excepciones  leves  y  por  lo  tanto  estas  deban  controlarse  adecuadamente.  Las  excepciones 
por  notificaciones,  advertencias  y  otras  son  generadas  con  un  código  que  permite 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    422 

identificarlas: 
 
Ejemplo: Capturar una excepción de gravedad leve 
<?php
try {
//Imprimir una variable que no existe
print $value;
}
catch(CoreException $e){
//Si es una excepción leve la re-lanza
if($e->getMessage()!=-8){
throw $e;
}
}
 
Los códigos de las excepciones leves son las siguientes: 
 
Tabla: Códigos para identificar excepciones leves 
Código  Tipo  Descripción 
‐8  Notificaciones  Indica  que  se  ha  encontrado  situaciones  que  podrían 
indicar un posible error ó inconsistencia. 
‐2  Advertencias  Indica  situaciones  que  indica  que  no  se  ha  podido 
completar  una  operación  esperada  pero  que  permiten 
que se continue con la ejecución de la aplicación. 
‐16  Advertencias de PHP  Son situaciones de advertencia generadas por PHP como 
por ejemplo el no poder cargar una extensión. 
‐2048  Modo Strict  Genera  excepciones  que  previenen  que  el  código  no  se 
vuelva  obsoleto  a  través  del  tiempo  y  sea  fácilmente 
portable a nuevas versiones de PHP. 
 
Existen otros tipos de excepciones, sus códigos coinciden  con los valores de las constantes 
E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE, E_DEPRECATED y otras. 
 
 
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    423 

52 Componente Debug
52.1 Introducción

El componente Debug ofrece al desarrollador la posibilidad de realizar seguimiento y obtener 
información extendida en procesos de negocio de forma tradicional mediante la inserción de 
banderas en el código para conocer el valor y estado en un determinado punto del mismo. Es 
una  buena  práctica  realizar  previamente  test  de  unidad  a  los  procesos  de  negocio  para 
automatizar los procesos de testeo mejorando la estabilidad de estos. 

52.2 Seguimiento al estado de variables

El  componente  Debug  proporciona  el  método  add(mixed  $value,  $showTrace=false)  que 
permite  agregar  una  variable  a  la  lista  de  seguimiento.  Los  valores  de  seguimiento  solo  se 
agregan si el procedimiento trazado ejecuta la línea donde se encuentra el llamado.  
 
En el siguiente ejemplo se envia al seguimiento 2 valores en determinados puntos del proceso. 
El  primero  visualiza  el  contenido  de  la  variable  $customerId  y  el  segundo  el  contenido  del 
vector $customerAccounts; 
 
Ejemplo: Realizar un Debug a un proceso de negocio 
<?php
class BankingController extends ApplicationController {
public function getSelectedActivityAction(){
$selectedAccountsIds = $this->getPostParam("cuenta");
$customerAccounts = array();
if(is_array($selectedAccountsIds)){
$userData = SessionNamespace::get('UserData');
$customerId = $userData->getCustomer();
//Que hay en la variable $customerId?
Debug::add($customerId);
foreach($selectedAccountsIds as $accountId){
$accountId = $this->filter($accountId, "int");
$existsAccount = $this->Account->count("customer_id =
'$customerId' AND id='$accountId' AND status='A'");
if($existsAccount==true){
$customerAccounts[] = $accountId;
} else {
Flash::error("Cuentas invalidas en la
peticion");
return;
}
}
} else {
Flash::error("Datos invalidos en la peticion");
return;
}
//Que hay en customerAccounts?
Debug::add($customerAccounts);
$movements = $this->Movement->find("account_id IN (".join(", ",
$customerAccounts).")", "order: created_at DESC");
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    424 

$this->setParamToView("movements", $movements);
new DebugException(“Visualizar el Debug”);
}
}
 
Siempre se requiere que se lance una excepción sin capturar. El componente Debug visualiza 
el  seguimiento  sin  importar  el  tipo  de  excepción  generada.  En  el  ejemplo  no  se  produce 
ninguna excepción por lo que a propósito se lanza un DebugException. 
 
En la pantalla de excepciones ahora se muestra el cuadro llamado “Datos de Debug” como el 
siguiente: 
 

 
 
La primera columna es el orden en el que se agregaron al seguimiento los valores, la segunda 
es  el  valor  que  se  pasó  al  método  add(),  luego  la  clase  y  el  método  en  donde  se  agregó  el 
debug, la linea, el archivo y por último el tiempo transcurrido entre un seguimiento y otro. 

52.3 Visualizar la traza del seguimiento de un valor

Para ciertos casos puede que sea importante verificar que métodos se ejecutaron para que un 
dato se haya agregado al seguimiento. El segundo parámetro de add permite que se muestre la 
traza asociada al valor de seguimiento. 
 

 
 
Los  valores  resaltados  en  rosado  indican  que  tienen  una  traza  asociada  que  aparece  a 
continuación  en  gris.  En  la  traza  es  posible  visualizar  que  parámetros  recibió  cada  método 
ejecutado y en que archivo se encuentra. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    425 

52.4 Detener un proceso mediante Aserciones

En  un  proceso  de  seguimiento  también  puede  ser  útil  detener  el  proceso  cuando  se  cumpla 
una  determinada  condición.  Tomando  la  idea  de  los  test  de  unidad  es  posible  insertar 
aserciones  en  el  proceso.  Las  aserciones  evaluan  condiciones  y  en  caso  de  cumplirse  lanzan 
una  excepción  de  tipo  DebugException  deteniendo  el  proceso  y  mostrando  el  segumiento 
hasta  ese  punto.  Todas  las  aserciones  que  no  se  cumplieron  también  se  muestran  en  el 
seguimiento. Las aserciones disponibles son: 
 
Tabla: Aserciones soportadas en Debug 
Método  Descripción 
assertEquals(mixed $val1, mixed $val2, $showTrace=false)  Aserción si el valor $val1 
es igual a $val2. 
assertNotEquals(mixed $val1, mixed $val2, $showTrace=false)  Aserción si el valor $val1 
no es igual a $val2. 
assertNull(mixed $val1, $showTrace=false)  Aserción  si  $val1  es 
nulo. 
assertArray(mixed $val1, $showTrace=false)  Aserción  si  $val1  es  un 
array. 
assetTrue(mixed $val1, $showTrace=false)  Aserción  si  $val1  es 
verdadero. 
assertFalse(mixed $val1, $showTrace=false)  Aserción  si  $val1  es 
falso. 
 
El uso de las aserciones es el siguiente: 
 
Ejemplo: Uso de aserciones en Debug 
<?php
$v = 100;
Debug::assertEquals(“1”, $v); //No se lanza la excepción
Debug::assertNotEquals(“1”, $v); //Se lanza la excepción
Debug::assertTrue(100==$v); //Se lanza la excepción
$employees = $this->Employees->find(“status=’A’”);
Debug::assertEquals(count($employees), 10); //Se lanza si hay 10 trabajadores

Tomando el ejemplo anterior, el cuadro de debug se visualiza el tipo de aserción y los valores 
del mismo: 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    426 

52.5 Establecer una acción a ejecutar al finalizar el proceso de debug

El  componente  Debug  puede  aprovechar  las  capacidades  para  programar  eventos  del 
framework para efectuar operaciones al terminar la procesar una determinada petición. Las 
acciones que se pueden programar son generar una excepción que visualice el contenido del 
seguimiento ó almacenarlos en un archivo de log: 
 
Para detener la ejecución al finalizar la petición se debe hacer el llamado a: 
 
Ejemplo: Establecer el lanzamiento de una excepción cuando finalice la petición 
Debug::setActionOnFinish(Debug::ACTION_HALT);
 
Utilizar un logger para almacenar el seguimiento: 
 
Ejemplo: Almacenar el seguimiento usando un Logger 
$logger = new Logger(“File”, “debug.txt”);
Debug::setActionOnFinish(Debug::ACTION_LOG, $logger);
 
 
 
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    427 

53 Test de Unidad
53.1 Introducción

El  testeo  unitario  permite  a  desarrolladores  e  ingenieros  de  pruebas  comprobar  que  cada 
unidad  de  código  fuente  en  el  software  funciona  como  se  espera.  Se  puede  decir  que  una 
unidad es la parte más pequeña de una aplicación que se puede probar.  
 
Los test de unidad ayudan a organizaciones a generar mejores aplicaciones más rápido, lo que 
les genera ventajas competitivas importantes.  
 
Kumbia Enterprise Framework posee su propio componente para el desarrollo y ejecución de 
pruebas unitarias tanto para aplicaciones, como para probarse a sí mismo. Los ingenieros de 
LouderTechnology han desarrollado más de 1500 test unitarios para probar en profundidad, 
cada funcionalidad del framework y mejorar el componente en si mismo. 

53.2 Tests para Componentes

Componentes de usuario pueden ser probados usando test de unidad. Estos deben residir en 
un ambiente externo para comprobar que la misma naturaleza de su uso es la esperada. 
FALTA 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    428 

54 Componente Script
54.1 Introducción

Este  componente  permite  la  creación  de  scripts  tipo  shell  que  ayuden  al  desarrollador  a 
optimizar tareas. FALTA 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    429 

55 Apendices
55.1 Estándares de Codificación

En este apendice se explica los estándares que fueron seguidos para codificar el framework y 
que deben ser seguidos por colaboradores y empleados de LouderTechnology. 

55.1.1 Objetivos 
Auto‐documentar el framework de tal manera que las características de auto‐completado de 
código que tienen los IDEs de desarrollo 

55.1.2 Formato de Archivos PHP 
 La etiqueta de cierre “?>” no está permitida para los archivos que contienen solo código 
PHP. 
 La indentación de los archivos debe hacerse con 4 espacios sin caracteres tabuladores. 
 La codificación de los archivos debe ser UTF‐8 
 En archivos no‐comprimidos, cada línea debe tener máximo 80 caracteres. 
 En  archivos  comprimidos  cada  línea  debe  tener  máximo  2048  caracteres  ó  700 
construcciones del lenguaje 
 La terminación de línea debe realizarse con el carácter LF, ASCII 10 correspondiente a 
archivos Unix. 

55.1.3 Clases 
 Las  clases  correspondientes  al  framework  deben  estar  ubicadas  en  el  directorio 
“Kumbia/”. 
 Los  nombres  de  las  clases  deben  estar  camelizados  y  contener  solo  caracteres 
alfanuméricos. 
 Solo es permitido una clase por archivo 
 El nombre del archivo corresponde al nombre de la clase en él más la extensión “.php”. 

55.1.4 Interfaces 
 Las  interfaces  deben  estar  definidas  en  un  archivo  llamado  Interface.php  en  el 
directorio del paquete ó subpaquete donde aplique su uso. 
 Las interfaces deben tener el sufijo Interface. 

55.1.5 Métodos 
 Los  nombres  de  los  métodos  deben  tener  nomenclatura  camelizada,  es  decir  no  se 
permiten underscores “_” y siempre deben empezar  por un carácter en minúsculas. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    430 

55.1.6 Variables 
 Las  variables  deben  tener  solo  caracteres  alfanuméricos.  Cuando  son  propiedades 
privadas ó protegidas de clases deben empezar por un underscore “_”.  
 La  visibilidad  de  las  propiedades  de  las  clases  debe  ser  principalmente  privada  ó 
protegida.  
 Los nombres de las variables deben ser lo más humanizadas posible de tal forma que 
se  entienda  el  objetivo  de  la  variable.  Variables  que  almacenan  valores  auxiliares  en  ciclos 
pueden tener nombres como $j ó $i. 

55.1.7 Constantes 
 Solo  está  permitido  definir  constantes  de  clase.  Estas  deben  estar  en  mayúsculas  y 
cada palabra debe estar separada por underscore “_”. 

55.1.8 Boleanos y valores nulos 
 Los valores true, false y null siempre deben ir en minúsculas. 

55.1.9 Literales de Cadenas de Caracteres 
 Las cadenas de caracteres siempre deben ir encerradas usando comillas simples (‘) a 
menos que contengan substituciones ó otras comillas sencillas. 
 $cadena = ‘Esto es una cadena’; 

55.1.10 Substituciones de variables 
Se recomienda evitar las substituciones de variables por expresiones de concatenación. 
FALTA 

55.2 Licencia de este Documento

55.2.1 Creative Commons Attribution 3.0 
THE  WORK  (AS  DEFINED  BELOW)  IS  PROVIDED  UNDER  THE  TERMS  OF  THIS  CREATIVE 
COMMONS  PUBLIC  LICENSE  ("CCPL"  OR  "LICENSE").  THE  WORK  IS  PROTECTED  BY 
COPYRIGHT  AND/OR  OTHER  APPLICABLE  LAW.  ANY  USE  OF  THE  WORK  OTHER  THAN  AS 
AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. 
BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO 
BE  BOUND  BY  THE  TERMS  OF  THIS  LICENSE.  TO  THE  EXTENT  THIS  LICENSE  MAY  BE 
CONSIDERED  TO  BE  A  CONTRACT,  THE  LICENSOR  GRANTS  YOU  THE  RIGHTS  CONTAINED 
HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS. 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    431 

 
1. Definitions 
"Adaptation" means a work based upon the Work, or upon the Work and other pre‐existing 
works,  such  as  a  translation,  adaptation,  derivative  work,  arrangement  of  music  or  other 
alterations  of  a  literary  or  artistic  work,  or  phonogram  or  performance  and  includes 
cinematographic  adaptations  or  any  other  form  in  which  the  Work  may  be  recast, 
transformed, or adapted including in any form recognizably derived from the original, except 
that a work that constitutes a Collection will not be considered an Adaptation for the purpose 
of this License. For the avoidance of doubt, where the Work is a musical work, performance or 
phonogram,  the  synchronization  of  the  Work  in  timed‐relation  with  a  moving  image 
("synching") will be considered an Adaptation for the purpose of this License. 
 
"Collection"  means  a  collection  of  literary  or  artistic  works,  such  as  encyclopedias  and 
anthologies,  or  performances,  phonograms  or  broadcasts,  or  other  works  or  subject  matter 
other  than  works  listed  in  Section  1(f)  below,  which,  by  reason  of  the  selection  and 
arrangement of their contents, constitute intellectual creations, in which the Work is included 
in  its  entirety  in  unmodified  form  along  with  one  or  more  other  contributions,  each 
constituting  separate  and  independent  works  in  themselves,  which  together  are  assembled 
into  a  collective  whole.  A  work  that  constitutes  a  Collection  will  not  be  considered  an 
Adaptation (as defined above) for the purposes of this License. 
 
"Distribute"  means  to  make  available  to  the  public  the  original  and  copies  of  the  Work  or 
Adaptation, as appropriate, through sale or other transfer of ownership. 
 
"Licensor"  means  the  individual,  individuals,  entity  or  entities  that  offer(s)  the  Work  under 
the terms of this License. 
 
"Work"  means  the  literary  and/or  artistic  work  offered  under  the  terms  of  this  License 
including  without  limitation  any  production  in  the  literary,  scientific  and  artistic  domain, 
whatever  may  be  the  mode  or  form  of  its  expression  including  digital  form,  such  as  a  book, 
pamphlet and other writing; a lecture, address, sermon or other work of the same nature; a 
dramatic or dramatico‐musical work; a choreographic work or entertainment in dumb show; 
a  musical  composition  with  or  without  words;  a  cinematographic  work  to  which  are 
assimilated works expressed by a process analogous to cinematography; a work of drawing, 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    432 

painting, architecture, sculpture, engraving or lithography; a photographic work to which are 
assimilated works expressed by a process analogous to photography; a work of applied art; an 
illustration, map, plan, sketch or three‐dimensional work relative to geography, topography, 
architecture or science; a performance; a broadcast; a phonogram; a compilation of data to the 
extent  it  is  protected  as  a  copyrightable  work;  or  a  work  performed  by  a  variety  or  circus 
performer to the extent it is not otherwise considered a literary or artistic work. 
 
"You"  means  an  individual  or  entity  exercising  rights  under  this  License  who  has  not 
previously violated the terms  of  this  License  with  respect  to  the  Work,  or  who  has  received 
express permission from the Licensor to exercise rights under this License despite a previous 
violation. 
 
"Publicly  Perform"  means  to  perform  public  recitations  of  the  Work  and  to  communicate  to 
the  public  those  public  recitations,  by  any  means  or  process,  including  by  wire  or  wireless 
means  or  public  digital  performances;  to  make  available  to  the  public  Works  in  such  a  way 
that members of the public may access these Works from a place and at a place individually 
chosen  by  them;  to  perform  the  Work  to  the  public  by  any  means  or  process  and  the 
communication  to  the  public  of  the  performances  of  the  Work,  including  by  public  digital 
performance; to broadcast and rebroadcast the Work by any means including signs, sounds or 
images. 
 
"Reproduce" means to make copies of the Work by any means including without limitation by 
sound  or  visual  recordings  and  the  right  of  fixation  and  reproducing  fixations  of  the  Work, 
including storage of a protected performance or phonogram in digital form or other electronic 
medium. 
 
2.  Fair  Dealing  Rights.  Nothing  in  this  License  is  intended  to  reduce,  limit,  or  restrict  any 
uses free from copyright or rights arising from limitations or exceptions that are provided for 
in connection with the copyright protection under copyright law or other applicable laws. 
 
3. License Grant. Subject to the terms and conditions of this License, Licensor hereby grants 
You  a  worldwide,  royalty‐free,  non‐exclusive,  perpetual  (for  the  duration  of  the  applicable 
copyright) license to exercise the rights in the Work as stated below: 
to  Reproduce  the  Work,  to  incorporate  the  Work  into  one  or  more  Collections,  and  to 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    433 

Reproduce the Work as incorporated in the Collections; 
to  create  and  Reproduce  Adaptations  provided  that  any  such  Adaptation,  including  any 
translation  in  any  medium,  takes  reasonable  steps  to  clearly  label,  demarcate  or  otherwise 
identify  that  changes  were  made  to  the  original  Work.  For  example,  a  translation  could  be 
marked "The original work was translated from English to Spanish," or a modification could 
indicate "The original work has been modified."; 
to Distribute and Publicly Perform the Work including as incorporated in Collections; and, 
to Distribute and Publicly Perform Adaptations. 
 
For the avoidance of doubt:  
Non‐waivable Compulsory License Schemes. In those jurisdictions in which the right to collect 
royalties  through  any  statutory  or  compulsory  licensing  scheme  cannot  be  waived,  the 
Licensor  reserves  the  exclusive  right  to  collect  such  royalties  for  any  exercise  by  You  of  the 
rights granted under this License; 
Waivable  Compulsory  License  Schemes.  In  those  jurisdictions  in  which  the  right  to  collect 
royalties through any statutory or compulsory licensing scheme can be waived, the Licensor 
waives  the  exclusive  right  to  collect  such  royalties  for  any  exercise  by  You  of  the  rights 
granted under this License; and, 
Voluntary  License  Schemes.  The  Licensor  waives  the  right  to  collect  royalties,  whether 
individually  or,  in  the  event  that  the  Licensor  is  a  member  of  a  collecting  society  that 
administers  voluntary  licensing  schemes,  via  that  society,  from  any  exercise  by  You  of  the 
rights granted under this License. 
 
The above rights may be exercised in all media and formats whether now known or hereafter 
devised.  The  above  rights  include  the  right  to  make  such  modifications  as  are  technically 
necessary to exercise the rights in other media and formats. Subject to Section 8(f), all rights 
not expressly granted by Licensor are hereby reserved. 
4.  Restrictions.  The  license  granted  in  Section  3  above  is  expressly  made  subject  to  and 
limited by the following restrictions: 
You  may  Distribute  or  Publicly  Perform  the  Work  only  under  the  terms  of  this  License.  You 
must include a copy of, or the Uniform Resource Identifier (URI) for, this License with every 
copy of the Work You Distribute or Publicly Perform. You may not offer or impose any terms 
on the Work that restrict the terms of this License or the ability of the recipient of the Work to 
exercise  the  rights  granted  to  that  recipient  under  the  terms  of  the  License.  You  may  not 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    434 

sublicense  the  Work.  You  must  keep  intact  all  notices  that  refer  to  this  License  and  to  the 
disclaimer  of  warranties  with  every  copy  of  the  Work  You  Distribute  or  Publicly  Perform. 
When  You  Distribute  or  Publicly  Perform  the  Work,  You  may  not  impose  any  effective 
technological measures on the Work that restrict the ability of a recipient of the Work from 
You  to  exercise  the  rights  granted  to  that  recipient  under  the  terms  of  the  License.  This 
Section 4(a) applies to the Work as incorporated in a Collection, but this does not require the 
Collection  apart  from  the  Work  itself  to  be  made  subject  to  the  terms  of  this  License.  If  You 
create a Collection, upon notice from any Licensor You must, to the extent practicable, remove 
from  the  Collection  any  credit  as  required  by  Section  4(b),  as  requested.  If  You  create  an 
Adaptation, upon notice from any Licensor You must, to the extent practicable, remove from 
the Adaptation any credit as required by Section 4(b), as requested. 
If You Distribute, or Publicly Perform the Work or any Adaptations or Collections, You must, 
unless a request has been made pursuant to Section 4(a), keep intact all copyright notices for 
the Work and provide, reasonable to the medium or means You are utilizing: (i) the name of 
the  Original  Author  (or  pseudonym,  if  applicable)  if  supplied,  and/or  if  the  Original  Author 
and/or Licensor designate another party or parties (e.g., a sponsor institute, publishing entity, 
journal) for attribution ("Attribution Parties") in Licensor's copyright notice, terms of service 
or by other reasonable means, the name of such party or parties; (ii) the title of the Work if 
supplied; (iii) to the extent reasonably practicable, the URI, if any, that Licensor specifies to be 
associated with the Work, unless such URI does not refer to the copyright notice or licensing 
information for the Work; and (iv) , consistent with Section 3(b), in the case of an Adaptation, 
a  credit  identifying  the  use  of  the  Work  in  the  Adaptation  (e.g.,  "French  translation  of  the 
Work  by  Original  Author,"  or  "Screenplay  based  on  original  Work  by  Original  Author").  The 
credit  required  by  this  Section  4  (b)  may  be  implemented  in  any  reasonable  manner; 
provided,  however,  that  in  the  case  of  a  Adaptation  or  Collection,  at  a  minimum  such  credit 
will  appear,  if  a  credit  for  all  contributing  authors  of  the  Adaptation  or  Collection  appears, 
then as part of these credits and in a manner at least as prominent as the credits for the other 
contributing authors. For the avoidance of doubt, You may only use the credit required by this 
Section  for  the  purpose  of  attribution  in  the  manner  set  out  above  and,  by  exercising  Your 
rights under this License, You may not implicitly or explicitly assert or imply any connection 
with,  sponsorship  or  endorsement  by  the  Original  Author,  Licensor  and/or  Attribution 
Parties,  as  appropriate,  of  You  or  Your  use  of  the  Work,  without  the  separate,  express  prior 
written permission of the Original Author, Licensor and/or Attribution Parties. 
Except as otherwise agreed in writing by the Licensor or as may be otherwise permitted by 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    435 

applicable law, if You Reproduce, Distribute or Publicly Perform the Work either by itself or as 
part  of  any  Adaptations  or  Collections,  You  must  not  distort,  mutilate,  modify  or  take  other 
derogatory action in relation to the Work which would be prejudicial to the Original Author's 
honor  or  reputation.  Licensor  agrees  that  in  those  jurisdictions  (e.g.  Japan),  in  which  any 
exercise  of  the  right  granted  in  Section  3(b)  of  this  License  (the  right  to  make  Adaptations) 
would  be  deemed  to  be  a  distortion,  mutilation,  modification  or  other  derogatory  action 
prejudicial  to  the  Original  Author's  honor  and  reputation,  the  Licensor  will  waive  or  not 
assert, as appropriate, this Section, to the fullest extent permitted by the applicable national 
law, to enable You to reasonably exercise Your right under Section 3(b) of this License (right 
to make Adaptations) but not otherwise. 
5. Representations, Warranties and Disclaimer 
UNLESS  OTHERWISE  MUTUALLY  AGREED  TO  BY  THE  PARTIES  IN  WRITING,  LICENSOR 
OFFERS  THE  WORK  AS‐IS  AND  MAKES  NO  REPRESENTATIONS  OR  WARRANTIES  OF  ANY 
KIND  CONCERNING  THE  WORK,  EXPRESS,  IMPLIED,  STATUTORY  OR  OTHERWISE, 
INCLUDING,  WITHOUT  LIMITATION,  WARRANTIES  OF  TITLE,  MERCHANTIBILITY,  FITNESS 
FOR  A  PARTICULAR  PURPOSE,  NONINFRINGEMENT,  OR  THE  ABSENCE  OF  LATENT  OR 
OTHER  DEFECTS,  ACCURACY,  OR  THE  PRESENCE  OF  ABSENCE  OF  ERRORS,  WHETHER  OR 
NOT  DISCOVERABLE.  SOME  JURISDICTIONS  DO  NOT  ALLOW  THE  EXCLUSION  OF  IMPLIED 
WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU. 
6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO 
EVENT  WILL  LICENSOR  BE  LIABLE  TO  YOU  ON  ANY  LEGAL  THEORY  FOR  ANY  SPECIAL, 
INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS 
LICENSE  OR  THE  USE  OF  THE  WORK,  EVEN  IF  LICENSOR  HAS  BEEN  ADVISED  OF  THE 
POSSIBILITY OF SUCH DAMAGES. 
7. Termination. 
This License and the rights granted hereunder will terminate automatically upon any breach 
by You of the terms of this License. Individuals or entities who have received Adaptations or 
Collections  from  You  under  this  License,  however,  will  not  have  their  licenses  terminated 
provided such individuals or entities remain in full compliance with those licenses. Sections 1, 
2, 5, 6, 7, and 8 will survive any termination of this License. 
Subject  to  the  above  terms  and  conditions,  the  license  granted  here  is  perpetual  (for  the 
duration  of  the  applicable  copyright  in  the  Work).  Notwithstanding  the  above,  Licensor 
reserves the right to release the Work under different license terms or to stop distributing the 
Work at any time; provided, however that any such election will not serve to withdraw this 
LouderTechnology/Kumbia Enterprise Framework – Manual de Referencia                                                                    436 

License (or any other license that has been, or is required to be, granted under the terms of 
this License), and this License will continue in full force and effect unless terminated as stated 
above. 
8. Miscellaneous 
Each time You Distribute or Publicly Perform the Work or a Collection, the Licensor offers to 
the recipient a license to the Work on the same terms and conditions as the license granted to 
You under this License. 
Each time You Distribute or Publicly Perform an Adaptation, Licensor offers to the recipient a 
license to the original Work on the same terms and conditions as the license granted to You 
under this License. 
If  any  provision  of  this  License  is  invalid  or  unenforceable  under  applicable  law,  it  shall  not 
affect the validity or enforceability of the remainder of the terms of this License, and without 
further  action  by  the  parties  to  this  agreement,  such  provision  shall  be  reformed  to  the 
minimum extent necessary to make such provision valid and enforceable. 
No  term  or  provision  of  this  License  shall  be  deemed  waived  and  no  breach  consented  to 
unless such waiver or consent shall be in writing and signed by the party to be charged with 
such waiver or consent 
This License constitutes the entire agreement between the parties with respect to the Work 
licensed  here.  There  are  no  understandings,  agreements  or  representations  with  respect  to 
the  Work  not  specified  here.  Licensor  shall  not  be  bound  by  any  additional  provisions  that 
may appear in any communication from You. This License may not be modified without the 
mutual written agreement of the Licensor and You. 
The  rights  granted  under,  and  the  subject  matter  referenced,  in  this  License  were  drafted 
utilizing  the  terminology  of  the  Berne  Convention  for  the  Protection  of  Literary  and  Artistic 
Works  (as  amended  on  September  28,  1979),  the  Rome  Convention  of  1961,  the  WIPO 
Copyright  Treaty  of  1996,  the  WIPO  Performances  and  Phonograms  Treaty  of  1996  and  the 
Universal Copyright Convention (as revised on July 24, 1971). These rights and subject matter 
take effect in the relevant  jurisdiction  in  which  the  License  terms  are  sought  to  be  enforced 
according to the corresponding provisions of the implementation of those treaty provisions in 
the applicable national law. If the standard suite of rights granted under applicable copyright 
law  includes  additional  rights  not  granted  under  this  License,  such  additional  rights  are 
deemed to be included in the License; this License is not intended to restrict the license of any 
rights under applicable law. 
 

Vous aimerez peut-être aussi