You are on page 1of 436

KumbiaEnterpriseFramework

UnFrameworkparaelPHPEmpresarial
LouderTechnology
www.loudertechnology.com

Abrilde2009
VersindelProducto:1.0.17GA

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

TabladeContenido
1 Prefacio .................................................................................................................. 15 1.1 AntesdeLeeresteDocumento .................................................................................................................. 15 1.2 ComoestaorganizadoesteDocumento................................................................................................. 15 1.3 ConvencionesTipogrficas.......................................................................................................................... 16 1.4 AQuienestOrientadoesteTexto........................................................................................................... 17 1.5 Informacinsobremarcasyproductosreferenciados ................................................................... 17 1.6 Referenciasasitioswebdeterceros....................................................................................................... 17 1.7 Suscomentariosestnbienvenidos ........................................................................................................ 18 2 Introduccin ........................................................................................................... 19 2.1 DiferenciasconlaversinComunitaria................................................................................................. 19 2.2 Licencia ................................................................................................................................................................ 20 3 Instalacin .............................................................................................................. 21 3.1 Introduccin ...................................................................................................................................................... 21 3.2 ConfiguracinconApacheWebServer2.x........................................................................................... 21 3.3 ConfiguracinconMicrosoftIISeISAPIRewrite .............................................................................. 23 3.4 ConfiguracindePHP .................................................................................................................................... 24 3.5 ConfiguracinconZendApplicationServer ........................................................................................ 25 3.6 CrearunaInstanciadeKumbiaEnterprise .......................................................................................... 25 3.7 Solucinaproblemasdeinstalacin....................................................................................................... 25 4 QuesKumbiaEnterpriseFramework?................................................................. 28 4.1 SobreAplicacionesWeb ............................................................................................................................... 28 4.2 SobrePHPylaWeb ........................................................................................................................................ 28 4.3 Introduccin ...................................................................................................................................................... 28 4.4 CaractersticasdelFramework.................................................................................................................. 29 4.5 PHPenentornoscrticos .............................................................................................................................. 30 4.6 PreguntasfrecuentessobreKumbiaEnterprise................................................................................ 31 5 Arquitectura ........................................................................................................... 34 5.1 Introduccin ...................................................................................................................................................... 34 5.2 CapasenunaAplicacin ............................................................................................................................... 34 5.3 UsandoModeloVistaControlador .......................................................................................................... 35 5.4 VentajasdeusarMVC .................................................................................................................................... 36 5.5 ArquitecturaSOA............................................................................................................................................. 37 5.6 BeneficiosdeunaSOA ................................................................................................................................... 38 5.7 SOAenKumbiaEnterprise .......................................................................................................................... 38 5.8 LooseCoupling/TightCoupling ................................................................................................................ 40 6 CasodeUso:AplicacindeCajeroBancario ............................................................ 41 6.1 Introduccin ...................................................................................................................................................... 41 6.2 AnlisisdelosRequerimientos ................................................................................................................. 41 6.3 EsqueletodelaAplicacin........................................................................................................................... 45 6.4 Configurarlaconexinalabasededatos............................................................................................. 45 6.5 CrearlosmodelosdeBasedeDatos........................................................................................................ 46 6.6 CrearelIniciodeSesin ............................................................................................................................... 49 6.7 AutenticandoalCliente................................................................................................................................. 52 6.8 UnMenparalaAplicacin ........................................................................................................................ 54 6.9 Visualizacindelsaldodelcliente............................................................................................................ 55 6.10 CrearelTransactionActivity .................................................................................................................... 58

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

7 AplicacionesenKumbiaEnterprise ......................................................................... 62 7.1 Introduccin ...................................................................................................................................................... 62 7.2 Instanciasdelframework ............................................................................................................................ 62 7.3 EstructuradedirectoriosdeunaInstancia.......................................................................................... 62 7.4 Publicarcontenidoesttico......................................................................................................................... 64 7.5 Bootstrap............................................................................................................................................................. 65 7.6 CrearlaaccinpordefectoenunaAplicacin.................................................................................... 66 7.7 Crearunprocedimientodeinicializacindelaaplicacin............................................................ 66 7.8 Detectaruncambioenlaejecucindeunainstanciaaotra......................................................... 67 8 ComponenteController .......................................................................................... 68 8.1 Introduccin ...................................................................................................................................................... 68 8.2 ComofuncionaelcomponenteController?.......................................................................................... 68 8.3 CrearunControlador..................................................................................................................................... 70 8.4 ServiciosdelComponenteRouter............................................................................................................ 71 8.5 ServiciosproporcionadosporDispatcher ............................................................................................ 73 8.6 ExcepcionesGeneradasenelDispatcher.............................................................................................. 74 8.7 PeticionesHTTPaControladores............................................................................................................. 76 8.7.1 Administrararchivosadjuntosenunapeticin .............................................................................. 77 8.7.2 APIdeControllerRequest........................................................................................................................... 78 8.8 RespuestasHTTPdeControladores........................................................................................................ 81 8.8.1 EstablecereltipodesalidadelaPeticin.......................................................................................... 82 8.8.2 APIdeControllerResponse........................................................................................................................ 83 8.9 Controlaraccionesnoencontradas ......................................................................................................... 84 8.10 Filtrosencontroladores............................................................................................................................. 85 8.11 Enrutamientoencontroladores ............................................................................................................. 86 8.11.1 Ciclodeenrutamiento .............................................................................................................................. 86 8.11.2 EnrutarusandoRouter::routeTo......................................................................................................... 87 8.11.3 EnrutarusandoRouter::routeToURI() ............................................................................................. 88 8.12 InicializacindeControladores.............................................................................................................. 88 8.13 EstadodepersistenciadeControladores........................................................................................... 89 8.13.1 VentajasdelEstadodePersistencia................................................................................................... 90 8.13.2 ConsideracionesdelestadodePersistencia.................................................................................... 90 8.13.3 TransaccionesyConcurrenciadelEstadodePersistencia ...................................................... 91 8.13.4 EventosdelestadodePersistencia ..................................................................................................... 91 8.14 LaClaseControllerBase ............................................................................................................................. 92 8.15 LaClaseController ....................................................................................................................................... 92 8.15.1 APIdeController ........................................................................................................................................ 92 8.16 ControladoresusandoApplicationController .................................................................................. 96 8.16.1 APIdeApplicationController ................................................................................................................ 96 8.16.2 ControladoresusandoMultiThreadController.............................................................................. 97 8.17 ServiciosWebusandoWebServiceController.................................................................................. 98 8.17.1 QuesunWebService?............................................................................................................................ 98 8.17.2 ParaquesonnecesarioslosWebServices....................................................................................... 99 8.17.3 ArquitecturaOrientadaaServicios(SOA) ...................................................................................... 99 8.17.4 CrearunWebService .............................................................................................................................100 8.17.5 WebServiceClient......................................................................................................................................102 8.17.6 ObteniendoelWSDLdeunServicioWeb.......................................................................................103 8.17.7 Orquestacindeservicios .....................................................................................................................104 8.17.8 CaractersticasdeServiciosWebenKumbiaEnterprise ........................................................106 8.18 ControladoresStandardForm ...............................................................................................................106

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

8.18.1 CaractersticasdeStandardForm.....................................................................................................106 8.18.2 LimitantesdeStandardForm..............................................................................................................107 8.19 PluginsdeControladores ........................................................................................................................107 8.19.1 CrearunPlugindeControlador.........................................................................................................107

9 ComponenteUDDI................................................................................................ 109 9.1 Introduccin ....................................................................................................................................................109 9.2 Requerimientos..............................................................................................................................................109 10 ComponenteBusinessProcess ............................................................................. 110 10.1 Introduccin..................................................................................................................................................110 10.1.1 Queesunprocesodenegocio?..........................................................................................................110 10.1.2 QuesBPEL? ............................................................................................................................................110 10.2 JobExecutor ..................................................................................................................................................110 10.3 CrearunProcesodeNegocio.................................................................................................................110 10.3.1 TiposdenodosdeunmetaprocesoPDL........................................................................................112 10.3.2 CrearloshandlersdelBusinessProcess ..........................................................................................113 11 ComponenteFilter .............................................................................................. 114 11.1 Introduccin..................................................................................................................................................114 11.2 EstructuradelComponente ...................................................................................................................114 11.3 Usarfiltrosenformadirecta..................................................................................................................116 11.4 CrearchainsdeFiltros..............................................................................................................................116 11.5 UsarfiltrosenControladores ................................................................................................................117 11.6 Filtrarlaentradadeusuario ..................................................................................................................118 11.7 Crearunfiltrodeusuario ........................................................................................................................119 11.7.1 Requerimientosdeunfiltrodeusuario ..........................................................................................120 12 ActionHelpers ..................................................................................................... 121 12.1 Introduccin..................................................................................................................................................121 12.2 MensajesusandoFlash.............................................................................................................................121 12.2.1 Generarmensajescontextuales..........................................................................................................121 12.2.2 Cambiarelestilopordefectodelosmensajes .............................................................................121 12.2.3 Cambiarelestiloenformadinmica...............................................................................................122 12.2.4 Enviarmltiplesmensajesdelmismotipoenformasimltanea........................................122 12.2.5 Mostrarmensajesporsutipo..............................................................................................................123 12.2.6 Cachearmensajesparamostrarlosenlaprximapeticin ..................................................123 12.3 CondicionesSQLconFormCriteria .....................................................................................................124 12.3.1 CriteriosdeRangos..................................................................................................................................126 12.3.2 Unirvariascondiciones .........................................................................................................................127 12.4 InformacindelNavegadorconBrowser ........................................................................................128 12.4.1 APIdeBrowser ..........................................................................................................................................128 12.5 AutocompletarconScriptaculous........................................................................................................130 13 ComponenteValidator........................................................................................ 132 13.1 Introduccin..................................................................................................................................................132 14 SeguridadconKumbiaEnterprise........................................................................ 133 14.1 Introduccin..................................................................................................................................................133 14.2 CaractersticasdeSeguridad..................................................................................................................133 14.3 MecanismosdeSeguridad.......................................................................................................................134 14.4 SeguridadaniveldeCapadeAplicacin ..........................................................................................134 14.5 SeguridadaniveldeCapadeTransporte.........................................................................................135

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

14.6 ImplementarSeguridadDeclarativa ..................................................................................................136 14.7 ImplementarSeguridadProgramacional .........................................................................................138 14.8 DefinirRealms,UsuariosyGruposparaAutenticacin .............................................................138 14.8.1 Realms...........................................................................................................................................................138 14.8.2 Usuarios........................................................................................................................................................139 14.8.3 Grupos ...........................................................................................................................................................139

15 ComponenteACL(ListadeControldeAcceso) .................................................... 140 15.1 Introduccin..................................................................................................................................................140 15.2 EstructuradelComponente ...................................................................................................................140 15.3 QueesunRecurso? ..................................................................................................................................141 15.4 QueesunRol? ............................................................................................................................................141 15.5 QueesunAcceso?.....................................................................................................................................141 15.6 TiposdeReglas ............................................................................................................................................141 15.7 ACLenAccin...............................................................................................................................................141 15.8 HerenciadeRoles .......................................................................................................................................143 15.9 AdaptadoresdeACL ..................................................................................................................................143 15.9.1 AclModel.......................................................................................................................................................144 15.9.2 AclMemory...................................................................................................................................................144 15.9.3 AclXML ..........................................................................................................................................................144 15.10 APIdeunAdaptador...............................................................................................................................146 15.11 APIdeAclResource ..................................................................................................................................147 15.12 APIdeAclRole ...........................................................................................................................................147 16 ComponenteAuth............................................................................................... 148 16.1 Introduccin..................................................................................................................................................148 16.2 AdaptadoresdeAuth.................................................................................................................................148 16.3 AdministracindeIdentidad .................................................................................................................149 16.4 ExpiracindeSesin .................................................................................................................................149 16.5 ControldeAutenticacinconcurrente ..............................................................................................149 16.6 AutenticacinconModelos.....................................................................................................................150 16.7 AutenticacinconKerberosV ................................................................................................................151 16.8 AutenticacinconRadius........................................................................................................................152 16.9 AutenticacinconDigest .........................................................................................................................153 16.10 AutenticacinconLDAP........................................................................................................................154 17 ComponenteAuditLogger ................................................................................... 157 17.1 Introduccin..................................................................................................................................................157 17.2 Crearuncomponentedecontrol .........................................................................................................157 18 ComponenteSecurity.......................................................................................... 158 18.1 Introduccin..................................................................................................................................................158 18.2 SubcomponenteSecurityFirewall........................................................................................................158 18.2.1 Introduccin ...............................................................................................................................................158 18.2.2 Comoseevaluanlasreglas ..................................................................................................................159 18.2.3 TiposdeAtributosdeunaRegla........................................................................................................159 19 Persistencia,TransaccionesyConcurrencia......................................................... 161 19.1 Introduccin..................................................................................................................................................161 20 ComponenteDb.................................................................................................. 161 20.1 Introduccin..................................................................................................................................................161 20.2 Capasdeacceso ...........................................................................................................................................161

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

20.3 AdaptadoresdelcomponenteDb.........................................................................................................162 20.4 GeneracindeSQL......................................................................................................................................164 20.5 Conexionesagestoresrelacionalespordefecto............................................................................165 20.5.1 ConsideracionesparaOracle...............................................................................................................165 20.5.2 ConsideracionesparaMicrosoftSQLServer.................................................................................168 20.5.3 ConsideracionesparaMySQL..............................................................................................................175 20.5.4 ConsideracionesparaIBMInformix.................................................................................................178 20.5.5 ConsideracionesconSQLite .................................................................................................................181 20.6 PooldeConexiones ....................................................................................................................................182 20.6.1 ConexionesdeBajoNivel ......................................................................................................................182 20.6.2 TrazarConexiones ...................................................................................................................................183 20.7 GenerarProfilesdeejecucindeSQL ................................................................................................184 20.8 ManejarExcepcionesdeDb....................................................................................................................184 20.8.1 TiposdeExcepcioneslanzadasporelcomponenteDb............................................................185 20.8.2 InformacinextendidadeexcepcionesgeneradasporDb.....................................................185 20.9 TiposdeResultadoalObtenerdeRegistros ...................................................................................188 20.10 Leerregistros.............................................................................................................................................189 20.11 ManipularRegistros................................................................................................................................192 20.12 AdministrarTransacciones..................................................................................................................194 20.13 Crear,Cerraryobtenerinformacindeconexiones.................................................................196 20.14 InformacindeErrores .........................................................................................................................197 20.15 Obtenerelvalordelacolumnaidentidad .....................................................................................197 20.16 ObtenerinformacindeTablas .........................................................................................................198 20.17 CrearyEliminarTablas.........................................................................................................................198 20.18 Fechadelgestorrelacional ..................................................................................................................201 20.19 Debug,SeguimientoyTraza ................................................................................................................201

21 ComponenteActiveRecordORM ...................................................................... 202 21.1 Introduccin..................................................................................................................................................202 21.2 CuandousarActiveRecord......................................................................................................................203 21.3 Entidades........................................................................................................................................................203 21.3.1 RequerimientosdelasClasesdeEntidades...................................................................................203 21.3.2 AtributosdelasEntidades....................................................................................................................204 21.4 AtributosyCampospersistentes .........................................................................................................204 21.5 LlavesPrimarias..........................................................................................................................................205 21.6 Convencionesenllavesprimarias .......................................................................................................206 21.7 FechasAutoAsignables ...........................................................................................................................206 21.8 MultiplicidadenRelacionesdeEntidades .......................................................................................206 21.8.1 ConvencionesenRelaciones.................................................................................................................207 21.8.2 RelacionesUnidireccionales ................................................................................................................207 21.8.3 RelacionesBidireccionales ...................................................................................................................207 21.8.4 Muchosauno .............................................................................................................................................207 21.8.5 UnoaMuchos.............................................................................................................................................209 21.8.6 UnoaUno ....................................................................................................................................................209 21.8.7 MuchosaMuchos .....................................................................................................................................209 21.9 APIdeActiveRecord ..................................................................................................................................210 21.9.1 OrigendeDatos.........................................................................................................................................210 21.9.2 VolcadodeMetaDatos..........................................................................................................................210 21.9.3 DebugySeguimiento ..............................................................................................................................210 21.9.4 Transacciones ............................................................................................................................................211 21.9.5 Consultarregistros ..................................................................................................................................212

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

21.9.6 Contarregistros ........................................................................................................................................214 21.9.7 Promediarregistros ................................................................................................................................215 21.9.8 Realizarsumatorias ................................................................................................................................215 21.9.9 Obtenerelvalormximodeunatributo........................................................................................215 21.9.10 Obtenerelvalormnimodeunatributo......................................................................................216 21.9.11 Asignarvaloresainstancias .............................................................................................................216 21.9.12 Validacin .................................................................................................................................................216 21.9.13 Informacindeatributos ...................................................................................................................217 21.9.14 Creacinyactualizacinderegistros...........................................................................................218 21.9.15 Eliminacinderegistros.....................................................................................................................219 21.9.16 OperacionesenBatch ..........................................................................................................................219 21.9.17 Lectura/escrituradeAtributos .......................................................................................................219 21.9.18 Validacin .................................................................................................................................................219 21.9.19 Multiplicidadderelaciones ...............................................................................................................220 21.9.20 Herencia.....................................................................................................................................................221 21.9.21 Excepciones ..............................................................................................................................................221 21.10 Identifiers ....................................................................................................................................................221 21.10.1 EstablecerelGenerador......................................................................................................................222 21.10.2 AlgoritmoHi/Lo .....................................................................................................................................222 21.10.3 AlgoritmoUUID ......................................................................................................................................223 21.10.4 GeneradorUniqId ..................................................................................................................................224 21.10.5 GeneradorNative...................................................................................................................................224 21.10.6 ColumnasIdentidadySecuencias ..................................................................................................224 21.11 ConvencionesenIdentificadores ......................................................................................................225 21.12 LosMetadatosenActiveRecordMetadata ...................................................................................226 21.12.1 TiposdeMetaDatosAlmacenados................................................................................................226 21.12.2 MetaDatosenetapasdeDesarrollo .............................................................................................227 21.12.3 APIdeActiveRecordMetaData.........................................................................................................227 21.13 CursoresyResulsetsdeConsultas ...................................................................................................229 21.13.1 UtilizarelcursorcomotipoForwardOnly ................................................................................229 21.13.2 UtilizarelcursorcomoScrollable ..................................................................................................229 21.13.3 APIdeActiveRecordResulset ............................................................................................................230 21.14 MensajesdeActiveRecord ...................................................................................................................231 21.14.1 APIdeActiveRecordMessage............................................................................................................232 21.15 TransaccionesenActiveRecord.........................................................................................................232 21.15.1 AdministraciondeTransacciones ..................................................................................................233 21.15.2 SincronizacindeRecursosconTransacciones .......................................................................236 21.15.3 ConsideracionesdeSincronizacin................................................................................................236 21.15.4 APIdeTransactionDefinition...........................................................................................................239 21.15.5 APIdeActiveRecordTransaction ....................................................................................................239 21.15.6 TimeoutsenTransacciones...............................................................................................................240 21.16 ValidadoresdeIntegridaddeDatos.................................................................................................241 21.16.1 ValidadoresparaatributosNoNulos...........................................................................................243 21.16.2 TratarelresultadodeunprocesodeValidacin.....................................................................243 21.16.3 ValidadoresdeUsuario .......................................................................................................................245 21.16.4 EventosenlaValidacin.....................................................................................................................246 21.16.5 Implementaruneventodevalidacin..........................................................................................249 21.16.6 Detener/Cancelarunaoperacin...................................................................................................250 21.16.7 Estableceruneventoconunnombrenoestndar..................................................................250 21.16.8 Eventocuandoelprocesodevalidacindetienelaoperacin ..........................................251 21.16.9 Deshabilitareventosdevalidacin................................................................................................252

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

21.17 LlavesForneasVirtuales.....................................................................................................................252 21.17.1 Crearunallaveforneavirtual.......................................................................................................253 21.17.2 Opcionesdelasllavesforneas .......................................................................................................254 21.18 EntidadesTemporales ...........................................................................................................................255 21.18.1 CrearunTemporaryActiveRecord .................................................................................................256 21.18.2 ComportamientodeunTemporaryActiveRecord....................................................................256 21.18.3 TransaccionesconEntidadesTemporales .................................................................................257 21.18.4 UsarunTemporaryActiveRecord ...................................................................................................257 21.19 ActiveRecordJoin......................................................................................................................................259 21.19.1 AgrupamientosconActiveRecordJoin ..........................................................................................262 21.19.2 ParmetrosdeActiveRecordJoin ....................................................................................................262 21.20 ActiveRecordUnion .................................................................................................................................263 21.21 SessionRecord ...........................................................................................................................................263 21.22 PropertyAccessorsyMutators ...........................................................................................................264 21.23 DynamicUpdateyDynamicInsert .....................................................................................................264 21.24 ManejodeExcepciones..........................................................................................................................265 21.24.1 Capturarexcepcionesdentrodemodelos ...................................................................................266 21.24.2 InformacindeExcepciones .............................................................................................................266 21.25 PluginsdeModelos..................................................................................................................................266 21.25.1 CrearunPlugindeActiveRecord ....................................................................................................267 21.26 OrganizacindeModelos......................................................................................................................267 21.27 AutoinicializacindeModelos ..........................................................................................................268 21.27.1 Activarinicializacindinmica.......................................................................................................269

22 ComponenteEntityManager ............................................................................... 270 22.1 Introduccin..................................................................................................................................................270 22.2 ObtenerunanuevainstanciadeunModelo....................................................................................270 22.3 APIdelComponenteEntityManager ..................................................................................................271 22.3.1 Mtodosparainicializarmodelosyobtenerinstanciasdeellos .........................................271 22.3.2 Mtodosparaadministrarrelacionesdemultiplicidad..........................................................272 22.3.3 MtodosadminitrarparaEntidadesTemporales......................................................................273 22.3.4 Origenesdedatos .....................................................................................................................................274 22.3.5 Administrargeneradoresdeentidades ..........................................................................................274 22.3.6 LLavesforneasvirtuales.....................................................................................................................274 23 ComponenteTransactionManager ...................................................................... 276 23.1 Introduccin..................................................................................................................................................276 23.2 ContextodeScopePersistente..............................................................................................................276 23.3 EventListeners ............................................................................................................................................276 23.4 Estadosdelasentidades..........................................................................................................................277 23.5 Asignarelobjetoalestadoadministrado.........................................................................................277 23.6 APIdeTransactionManager...................................................................................................................278 24 Presentacin....................................................................................................... 279 24.1 Introduccin..................................................................................................................................................279 25 ComponenteView .............................................................................................. 280 25.1 Introduccin..................................................................................................................................................280 25.2 Jerarquadevistasenlapresentacin...............................................................................................280 25.2.1 VistaPrincipal ...........................................................................................................................................281 25.2.2 RequerimientosdelaVistaPrincipal ..............................................................................................282 25.2.3 RequerimientosVistasaniveldeControlador ............................................................................282 25.2.4 RequerimientosdeLayoutsdeControladores.............................................................................283

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

25.2.5 RequerimientosdeVistasParcialesenControladores.............................................................283 25.2.6 RequerimientosdeVistasParcialesGenerales............................................................................283 25.2.7 RequerimientosdePlantillasTemplates....................................................................................284 25.3 Insercinautomticaymanualdevistas .........................................................................................284 25.4 Implementarlostiposdevistas............................................................................................................285 25.5 Transferirvaloresdelcontroladoralavista ..................................................................................288 25.5.1 Transferirmedianteatributospblicos .........................................................................................288 25.5.2 TransferirmediantesetParamToView ...........................................................................................289 25.6 ControlarNivelesdeRenderizacin...................................................................................................290 25.7 Utilizarmodelosenlapresentacin ...................................................................................................291 25.8 PluginsdeView............................................................................................................................................291 25.8.1 CrearunPlugindeView ........................................................................................................................291 25.9 APIdelComponenteView.......................................................................................................................292 25.9.1 Jerarquiaderenderizacin ..................................................................................................................292 25.9.2 Administrarpresentacin.....................................................................................................................292 25.9.3 Visualizarvistasprogramacionalmente........................................................................................293 25.10 CrearuncomponentedePresentacinpersonalizado............................................................294 25.11 CrearuncomponentedepresentacindeExcepcionesnocapturadas...........................295 25.12 IntegrarotrosEnginesdepresentacin.........................................................................................296 25.12.1 Comportamientodelaintegracin................................................................................................296 25.12.2 ComponentesSoportados...................................................................................................................296

26 ComponenteTag................................................................................................. 299 26.1 Introduccin..................................................................................................................................................299 26.2 EstablecerelvalordehelperscreadosconTag.............................................................................299 26.3 Comportamientodehelpers ..................................................................................................................300 26.4 APIdelComponenteTag .........................................................................................................................300 26.4.1 Crearenlaces..............................................................................................................................................300 26.4.2 Componentesdeinterfazdeusuario ...............................................................................................303 26.4.3 Componentesdelistas/combos..........................................................................................................304 26.4.4 TratamientodeetiquetasMETA .......................................................................................................310 26.4.5 TratamientoeInclusindearchivosCSS.......................................................................................310 26.4.6 Componentesparafechas.....................................................................................................................311 26.4.7 IncluirrecursosJavascript ...................................................................................................................312 26.4.8 Interaccinconlapresentacin ........................................................................................................313 27 HelpersJavaScript............................................................................................... 315 27.1 Introduccin..................................................................................................................................................315 27.2 ClaseFormat .................................................................................................................................................315 27.2.1 Instanciandolaclase ..............................................................................................................................315 27.2.2 FuncionesdeFormat ..............................................................................................................................317 27.3 ClaseValidator .............................................................................................................................................318 27.3.1 Instanciandolaclase ..............................................................................................................................318 28 ComponentePDFDocument................................................................................ 320 28.1 Introduccin..................................................................................................................................................320 28.2 CrearundocumentoPDF ........................................................................................................................320 28.3 Agregarunatablaaldocumento ..........................................................................................................320 28.4 TiposdePapelSoportados .....................................................................................................................322 28.5 APIdePdfDocument..................................................................................................................................322 29 ComponenteReport ........................................................................................... 329 29.1 Introduccin..................................................................................................................................................329

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

10

29.2 29.3 29.4 29.5 29.6 29.7

Alcancedelcomponente..........................................................................................................................329 AdaptadoresdeReport ............................................................................................................................329 Paginacinenreportes.............................................................................................................................331 EjemplodeunlistadousandoReport................................................................................................331 ModoVistaPrevia.......................................................................................................................................332 APIdeReport................................................................................................................................................333

30 ComponenteFeed............................................................................................... 334 30.1 Introduccin..................................................................................................................................................334 30.2 Leer/ImportardocumentosRSS ..........................................................................................................334 30.3 CreardocumentosRSS .............................................................................................................................334 30.4 APIdeFeed....................................................................................................................................................335 30.4.1 APIdeFeedItem ........................................................................................................................................336 31 ComponenteCore ............................................................................................... 338 31.1 Introduccin..................................................................................................................................................338 31.2 JerarquadeClases .....................................................................................................................................338 31.2.1 ClaseObject.................................................................................................................................................338 31.2.2 CoreConfig ...................................................................................................................................................338 31.2.3 CoreLocale...................................................................................................................................................338 31.2.4 CoreClassPath ............................................................................................................................................338 31.2.5 CoreRemote.................................................................................................................................................338 31.3 ServiciosdelComponenteCore............................................................................................................338 31.3.1 ObtenerelInstanceName ....................................................................................................................338 31.3.2 ZonaHorariadelasAplicaciones......................................................................................................339 31.3.3 CambiarelCharsetdelaaplicacin.................................................................................................339 31.3.4 Cambiarlalocalizacinpordefecto ................................................................................................340 31.3.5 ObtenerlaversindelFramework ...................................................................................................340 31.4 SubcomponenteCoreConfig...................................................................................................................341 31.4.1 APIdelsubcomponenteCoreConfig .................................................................................................341 31.5 SubcomponenteCoreClassPath............................................................................................................342 31.5.1 ReemplazaruncomponentedelFramework...............................................................................342 31.5.2 APIdeCoreClassPath..............................................................................................................................343 31.6 SubcomponenteCoreType......................................................................................................................343 31.6.1 APIdeCoreType........................................................................................................................................343 31.7 CrearPluginsdeAplicacin....................................................................................................................344 31.7.1 CrearunPlugindeAplicacin ............................................................................................................344 32 ComponentePluginManager .............................................................................. 346 32.1 Introduccin..................................................................................................................................................346 32.2 ArquitecturadePlugIns .........................................................................................................................346 32.3 AutoinicializacindePlugIns...............................................................................................................346 32.4 APIdePluginManager ..............................................................................................................................346 33 InternacionalizacinyLocalizacin...................................................................... 349 33.1 Introduccin..................................................................................................................................................349 34 ComponenteLocale ............................................................................................ 350 34.1 Introduccin..................................................................................................................................................350 34.2 DefinirlalocalizacinenunasesindeUsuario...........................................................................350 34.2.1 Obtenerlalocalizacinadecuada.....................................................................................................350 34.3 Establecerlalocalizacinpordefecto................................................................................................351 34.4 Obtenertraduccioneslocalizadas........................................................................................................351

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

11

34.5 APIdelComponenteLocale....................................................................................................................352 34.6 SubcomponenteLocaleMath..................................................................................................................356 34.6.1 APIdeLocaleMath ...................................................................................................................................356

35 ComponenteTraslate.......................................................................................... 358 35.1 Introduccin..................................................................................................................................................358 35.2 AdaptadoressoportadosporTraslate...............................................................................................358 35.3 Comofuncionalatraduccin .................................................................................................................358 35.4 Utilizartraducciones .................................................................................................................................359 35.4.1 ConsideracionesparaeladaptadorArray ....................................................................................360 35.4.2 ConsideracionesparaeladaptadorCsv .........................................................................................360 35.4.3 ConsideracionesparaeladaptadorIni...........................................................................................360 35.4.4 ConsideracionesparaeladaptadorDatabase ............................................................................360 36 ComponenteDate............................................................................................... 361 36.1 Introduccin..................................................................................................................................................361 36.2 Porquedebeusarestecomponente ...................................................................................................361 36.3 Timestampsilimitados .............................................................................................................................361 36.4 EstablecerelTimezone ............................................................................................................................362 36.5 Obtenerpartesfragmentosdefechas ............................................................................................362 36.6 PosicinenelTiempo ...............................................................................................................................363 36.7 InformacindeFechas .............................................................................................................................364 36.8 Cambiarfragmentosdelafecha ...........................................................................................................365 36.9 Operacionesconfechas............................................................................................................................366 36.10 LocalizacindeFechas...........................................................................................................................367 36.11 Establecerelformatodelafecha ......................................................................................................368 36.12 Obtenerlafechayhoramundial .......................................................................................................370 37 ComponenteCurrency ........................................................................................ 371 37.1 Introduccin..................................................................................................................................................371 37.2 Cantidadesusandoelformatoadecuado..........................................................................................371 37.3 Simboloynombredelamonedautilizada.......................................................................................371 37.4 Versionesescritasdecantidades .........................................................................................................372 37.5 APIdelComponenteCurrency..............................................................................................................373 38 ComponenteApplicationMonitor ....................................................................... 375 38.1 Introduccin..................................................................................................................................................375 38.2 InfraestructuradeEventoscomunes .................................................................................................375 38.3 ComponentesdelaInfraestructuradeEventos ............................................................................376 38.3.1 CommonBaseEvent..................................................................................................................................376 38.3.2 Emmiter........................................................................................................................................................376 38.3.3 EventService ..............................................................................................................................................376 38.4 Porqueusarmonitorizacin? ..............................................................................................................376 38.4.1 Determinacindeproblemas..............................................................................................................376 38.4.2 SintonizacindelRendimiento...........................................................................................................376 38.4.3 ConfiabildaddelaOperacin..............................................................................................................377 38.5 Qusepuedemonitorear?....................................................................................................................377 39 ComponenteCommonEvent ............................................................................... 378 39.1 Introduccin..................................................................................................................................................378 40 ComponentesdePropsitoGeneral.................................................................... 379 40.1 Introduccin..................................................................................................................................................379

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

12

41 ComponenteConfig ............................................................................................ 380 41.1 Introduccin..................................................................................................................................................380 41.2 AdaptadoresdeConfig .............................................................................................................................380 41.2.1 AdaptadordeconfiguracinIni.........................................................................................................380 41.2.2 AdaptadordeconfiguracinXML .....................................................................................................381 41.2.3 AdaptadordeconfiguracinArraysdePHP ................................................................................381 41.2.4 AdaptadordeconfiguracinYaml....................................................................................................382 41.2.5 Leerarchivosdeconfiguracin ..........................................................................................................382 41.2.6 Ejemplo:Leerunarchivodeconfiguracin ..................................................................................382 42 ComponenteExtensions ..................................................................................... 383 42.1 Introduccin..................................................................................................................................................383 42.2 Cargarunaextensindinmicamente ...............................................................................................383 42.3 Cargarunaextensinestticamente ..................................................................................................383 42.3.1 CargarcomponentesdeZendFramework ....................................................................................384 42.4 Cargararchivosindividualesaliniciarlapeticin .......................................................................384 42.5 Obtenerinformacindeextensionescargadas..............................................................................384 42.6 Inyeccindecomponentes .....................................................................................................................385 43 ComponenteLogger............................................................................................ 386 43.1 Introduccin..................................................................................................................................................386 43.2 AdaptadoresdeLogger ............................................................................................................................386 43.3 TiposdeEventosenLogs ........................................................................................................................389 43.4 LoggerFacilities ..........................................................................................................................................390 43.5 TransaccionesconLogs ...........................................................................................................................391 43.6 APIdeFileLogger........................................................................................................................................392 43.7 UsodeMailLogger ......................................................................................................................................393 43.8 UsodeDatabaseLogger............................................................................................................................394 43.9 UsodeCompressedLogger .....................................................................................................................394 43.10 UsodeSAMLogger ...................................................................................................................................396 43.11 UsodeStreamLogger..............................................................................................................................396 43.12 UsodeSocketLogger...............................................................................................................................398 44 ComponenteUtils ............................................................................................... 399 44.1 Introduccin..................................................................................................................................................399 44.2 APIdeUtils ....................................................................................................................................................399 45 RendimientoyOptimizacin ............................................................................... 401 45.1 Introduccin..................................................................................................................................................401 45.2 ConsideracionesdeRendimiento ........................................................................................................401 45.2.1 Utilizacindeparmetrospornombre ..........................................................................................401 45.2.2 InstalarunCachedeOpCode ..............................................................................................................401 45.2.3 SintonizacindelServidorWeb .........................................................................................................402 45.2.4 SintonizacindePHP..............................................................................................................................403 46 ComponenteCache............................................................................................. 404 46.1 Introduccin..................................................................................................................................................404 47 ComponenteCompiler ........................................................................................ 405 47.1 Introduccin..................................................................................................................................................405 47.2 Teoriadeoptimizacinavanzada........................................................................................................406 47.2.1 Optimizacindeciclos............................................................................................................................406 47.2.2 Optimizacinporevaluacindeterminosestticos.................................................................406

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

13

47.3 ComportamientodeCompiler...............................................................................................................406 47.3.1 Optimizacionesbsicasdelacompilacin....................................................................................406 47.3.2 Optimizacionesavanzadasdelacompilacin.............................................................................407 47.4 GenerarunaCompilacin........................................................................................................................408 47.5 LimitacionesdeCompiler........................................................................................................................408

48 ComponenteGarbageCollector ........................................................................... 409 48.1 Introduccin..................................................................................................................................................409 48.2 Porqueusarestecomponente?...........................................................................................................409 48.3 ComofuncionaelGarbageCollector....................................................................................................409 48.3.1 FasedeCompresin.................................................................................................................................409 48.3.2 FasedeEliminacin.................................................................................................................................409 48.4 ActivarelGarbageCollector....................................................................................................................410 48.4.1 Activacindemaneraprogramacional..........................................................................................410 48.4.2 Activacindemaneradeclarativa....................................................................................................410 48.5 ParmetrosdelCollector.........................................................................................................................410 48.6 APIdeGarbageCollector ..........................................................................................................................411 49 ComponenteSession........................................................................................... 412 49.1 Introduccin..................................................................................................................................................412 49.2 AdaptadoresdeSesin .............................................................................................................................413 49.2.1 AdaptadordeSesinMemcache ........................................................................................................414 49.2.2 AdaptadordeSesinDatabase...........................................................................................................414 49.2.3 AdaptadordesesinFiles .....................................................................................................................414 49.2.4 AdaptadordesesinLouderCache ..................................................................................................415 49.3 ComportamientodeSesiones................................................................................................................415 49.4 ConsideracionesdeSeguridad ..............................................................................................................415 49.5 Variablesdesesin.....................................................................................................................................416 49.5.1 APIdelComponenteSession................................................................................................................416 49.6 SessionNamespace .....................................................................................................................................417 49.6.1 APIdeSessionNameSpace ....................................................................................................................418 50 HerramientasdelDesarrollador .......................................................................... 420 50.1 Introduccin..................................................................................................................................................420 51 ErroresyExcepciones.......................................................................................... 420 51.1 Introduccin..................................................................................................................................................420 51.2 ModoSUPER_STRICT ................................................................................................................................421 51.3 Capturarexcepcionesdegravedadleve ...........................................................................................421 52 ComponenteDebug ............................................................................................ 423 52.1 Introduccin..................................................................................................................................................423 52.2 Seguimientoalestadodevariables.....................................................................................................423 52.3 Visualizarlatrazadelseguimientodeunvalor.............................................................................424 52.4 DetenerunprocesomedianteAserciones .......................................................................................425 52.5 Establecerunaaccinaejecutaralfinalizarelprocesodedebug ........................................426 53 TestdeUnidad.................................................................................................... 427 53.1 Introduccin..................................................................................................................................................427 53.2 TestsparaComponentes .........................................................................................................................427 54 ComponenteScript ............................................................................................. 428 54.1 Introduccin..................................................................................................................................................428

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

14

55 Apendices ........................................................................................................... 429 55.1 EstndaresdeCodificacin.....................................................................................................................429 55.1.1 Objetivos.......................................................................................................................................................429 55.1.2 FormatodeArchivosPHP.....................................................................................................................429 55.1.3 Clases .............................................................................................................................................................429 55.1.4 Interfaces .....................................................................................................................................................429 55.1.5 Mtodos.........................................................................................................................................................429 55.1.6 Variables ......................................................................................................................................................430 55.1.7 Constantes ...................................................................................................................................................430 55.1.8 Boleanosyvaloresnulos .......................................................................................................................430 55.1.9 LiteralesdeCadenasdeCaracteres..................................................................................................430 55.1.10 Substitucionesdevariables ...............................................................................................................430 55.2 LicenciadeesteDocumento...................................................................................................................430 55.2.1 CreativeCommonsAttribution3.0 ...................................................................................................430

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

15

1 Prefacio
Elpresentedocumentoesdocumentotodoenunodeguadereferencia,APIytutorialparael desarrollo de aplicaciones usando Kumbia Enterprise Framework. El prefacio contiene informacinsobrelasconvencionesutilizadasparadesarrollarestetexto.

1.1 Antes de Leer este Documento


Antes de leer este texto usted debe tener un buen conocimiento de lenguaje PHP, programacin orientada a objetos, tecnologas para desarrollo Web como HTML, CSS, JavaScriptyotrascomoXML,AJAX,SQL,ascomoconocimientosenbasesdedatosysistemas operativos.

1.2 Como esta organizado este Documento


KumbiaEnterpriseesunframeworkrobustoparaeldesarrollodeaplicacionesempresariales usando tecnologia abierta para ambientes con altos requerimientos de estabilidad, rendimiento y escalabilidad. Toda su robustez esta plasmada en este extenso documento y esperaofrecertodalainformacinposibleparaelentendimientoyaprovechamientodeesta plataforma. Eldocumentoofreceunareferenciadecadacomponente,juntoconejemplosylaAPIdecada uno.Sebuscaquerelacionelaarquitecturadeloscomponentesycomoseintegranunoscon otrosenformadeservicios. La primera parte explica para que y donde puede utilizar Kumbia Enteprise Framework caractersticas, su instalacin y la arquitectura de las aplicaciones como introduccin al contextodedesarrolloeimplementacin. ElcapitulodeTutorialrealizalacreacindeunaaplicacincompletapasoapasocomocaso deestudio,integrandolosdiferentescomponentesyaplicandolamayorpartedelFramework comobaseilustrativadelmismo. Lasegundapartedetallalacapadelgicadedominioexplicandotodolorelacionadoconla orquestacindecontroladoresyserviciosWeb. Laterceraparteexplicacadacomponenteycaractersticasdeseguridadenelframework.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

16

Lacuartapartehabladelalgicadedatosydetallatrminosdepersistencia,concurrenciay transacciones. La quinta parte explica las caractersticas y componentes de internacionalizacin y localizacin que permiten adaptar aplicaciones a condiciones especificas geogrficas, polticas,culturalesregionales. La sexta parte presenta los componentes de la capa de presentacin y las herramientas de interaccinconelusuariofinalhacialaaplicacin. Lasptimaparteexplicacomponentesdemonitorizacinycomponentesdepropsitogeneral paraeldesarrollodeaplicacionesWeb. Laoctavaparteexplicaloscomponentesqueayudanamejorarelrendimientoyoptimizacin deaplicaciones. Lanovenapartedetallaelcomponentedeadministracin,contextoypersistenciadesesiones deusuario. La dcima parte son las herramientas del desarrollador como test de unidad, debug de procesosydatos,generacindecdigoetc.

1.3 Convenciones Tipogrficas


Lasiguientetabladescribelascondicionestipogrficasusadasenestetexto: Fuente AaBbCdDeFf Significado lenguajecastellanoquehacenreferencia LDAP a componentes, productos, marcas, nombresdemtodosmdulos.
AaBbCdDeFf

Ejemplo

Hace referencia a extranjerismos del El servidor de directorios

Hace referencia a cdigo fuente <?php sentenciasSQL.


$filter = new Filter();

AaBbCdDeFf

Hace referencia a Pseudocdigo para valor := LLamarFuncion();

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

17

representar fragmentos de cdigo procedimientosenlenguajehumano.

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 softwareexistentey/oextenderelmismo.

1.5 Informacin sobre marcas y productos referenciados


Las siguientes son marcas de productos referenciados que pertenecen a otras compaias y sonmencionadasenestedocumento: Excel , Windows, SQL Server y Word son marcas registradas de Microsoft Corporation en estadosunidosyotrospases. OracleesunamarcaregistradadeOracleCorporationenestadosunidosyotrospases. InformixesunamarcaregistradadeIBMenestadosunidosyotrospases. DB2esunamarcaregistradadeIBMenestadosunidosyotrospases. Adobe Acrobat es una marca registrada de Adobe Corporation en estados unidos y otros pases. Windows es una marca registrada de Microsoft Corporation en estados unidos y otros pases. MacOSXesunamarcaregistradadeAppleenestadosunidosyotrospases.

1.6 Referencias a sitios web de terceros


Algunas URLs son referenciadas en este documento y proporcionan informacin 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 otrosmaterialesqueestndisponiblesenestos sitios.LouderTechnology nosehaceresponsablepordaosperdidascausadasbajosinconexinconelcontenidoenesos sitiosyrecursos.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

18

1.7 Sus comentarios estn bienvenidos


EnLouderTechnologyestamosinteresadosenelmejoramientoladocumentacindenuestros y sus productos y proyectos, por esto sus comentarios estn siempre bienvenidos. La referenciadeestedocumentoesKEF1108.Escribaasupport@loudertechnology.com

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

19

CaptuloIntroduccin

2 Introduccin
KumbiaEnterpriseesunframeworkPHPcuyoprincipalobjetivoeslapracticidadyfacilidad deuso,sindejardedarleimportanciaalrendimiento,robustez,profesionalismoycalidadde una aplicacin orientada a la Web. Esta implementado usando la versin 5.2 de PHP y est completamenteorientadoaObjetos.Loscomponentesestnintegradosyoptimizadoslocual aumentaelrendimientointernodelframeworkydelasaplicacionesdesarrolladasconl. El framework adicionalmente permite usar componentes independientes y libreras de terceroseintegrarlasalasaplicacionesdesarrolladas. KumbiaEnterpriseFrameworkesunaversinmodificadadelKumbiaFrameworkComunitario versin 0.5, el cul ha sido estabilizado y refactorizado para aumentar su robustez y velocidad. La versin comunitaria es punto fundamental de innovacin y desarrollo para la constante integracin a la versin creada por LouderTechnology. El objetivo de este framework es fortalecer el desarrollo de aplicaciones de negocios orientadas a una presentacin Web que funcionen tanto en Intranets como en Internet. La creacin de sitios WebusandoKumbiaEnterpriseesposible,aunquepuedaencontrarotrasherramientas ms indicadasyligerasparaestatarea. Elpresentedocumentoexplicaenformadetalladacadacomponentedelframework.

2.1 Diferencias con la versin Comunitaria


La versin modificada que desarrollamos en Louder Technology ha pasado por un riguroso proceso de estabilizacin y calidad que exigen entornos de produccin para aplicaciones de altadisponibilidad. BeneficiosclavealusarKumbiaEnterprise:

Reduccindecostosoperacionalescuandoseimplementangrandessistemas Capacidaddeescalamientomejorada(clusterizacin,cachedistribuido) Laposibilidaddeobtenersoporteendiferentesnivelesquemitigueelriesgoyayudea eliminarellockindeproveedoresdeherramientasdedesarrollodesoftware. Integrar las aplicaciones con cdigo PHP5 existente incluyendo otros frameworks comoZendFramework.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

20

Facilidades en la integracin requerida para implementar arquitecturas orientadas a servicios(SOA).

Otrasmejorasestaversin:

Soporteparamltiplesaplicacionescertificado Estructuradearchivosoptimizadaparamltiplesaplicaciones SoporteparaTransaccionesdeAltoyBajonivel Adaptadoresdeconexinagestoresrelacionalescertificados Requerimientosdehardwarereducidosenun40% AdaptadoresdeManejadoresdeSesinescalables PolticasdeSeguridadconadaptadoresparagestoresrelacionales,LDAP,Kerberos5y otros

2.2 Licencia
Los modelo de negocios opensource est diseado para permirle tanto a usted como a sus socios expandirse desde pequeas instalaciones hasta las ms grandes sin generarle sobrecostosadicionales. KumbiaEnterpriseFrameworkesunproyectodesoftwareabiertoconunalicenciaaptapara negocios aprovada por la OSI (http:///www.opensource.org) llamada New BSD y que se entregaconladistribucindelframework. Soportecomercialparadesarrollo,produccinyentrenamientoestndisponiblesatravsde LouderTechnology.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

21

3 Instalacin
3.1 Introduccin
Kumbia Enterprise Framework requiere de PHP versin 5.2.0 superior para un funcionamientooptimo.ElframeworkrequieredelApacheWebServerpreferiblementeensu versin2.02.2ydelmodulomod_rewriteinstaladoparasucorrectofuncionamiento. KumbiaEnterpriseFrameworksoportaadicionalmenteMicrosoftInternetInformationServices (IIS)desdelaversin6.0utilizandoelmodulodelservidorISAPI_Rewrite. Al descargar el paquete de Kumbia Enterprise Framework este debe ser descomprimido y ubicadoenlarazdedocumentosdelservidorWebenunsubdirectoriodeeste,estepuede variardeacuerdoalaplataformadistribucinutilizada.

3.2 Configuracin con Apache Web Server 2.x


Kumbia Enterprise Framework implementa soporte para Smart URLs lo cual las hace ms familiares y humanas para los usuarios finales. Para esto es necesario instalar el modulo de Apachellamadomod_rewritequerealizalareescrituradelasURLsaunaconvencininterna en el framework, esto es vital para la correcta implementacin del patrn arquitectacional ModelViewController. Apache proporciona el comando a2enmod en la mayora de distribuciones Linux, mediante estecomandosepuedehabilitarfcilmenteelmodulo,despussoloesnecesarioreiniciarel servidorWeb. Conelusuarioadministradorrootutilizamoselcomandoas:
# a2enmod rewrite # /etc/init.d/apache2 restart

EnalgunossistemascomoRedHat/Fedoraelcomandoparareiniciarelservidores:
# service httpd restart

Para Microsoft Windows es necesario habilitar el modulo directamente en el archivo de configuracindeApache.ParaestosequitaelcomentariodejandoqueelmodulodeApache WebServerseacargado:

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

22

LoadModule rewrite_module modules/mod_rewrite.so

Las reglas de reescritura del framework deben ser ledas por Apache y ejecutadas en cada peticinalaaplicacin.Paraestoesnecesariohabilitarlalecturadelosarchivos.htaccess agregarlasreglasalarchivodeconfiguracindeApache. La ubicacin del archivo httpd.conf defaultserver.conf puede variar de acuerdo a la distribucinLinuxelsistemaoperativo. Tabla: Directorio de publicacin web y configuracin del servidor en diversas plataformas Distribucin Ubicacin DirectorioRazWeb

RedHatEnterprise4/5 /etc/httpd/conf/httpd.conf /var/www/html OpenSuSE 10.1/10.2/10.3/11 Ubuntu/Debian MacOS X (Leopard 10.5) usando MAMP WindowsXP/2003 usandoXAMPP Las reglas de reescritura de mod_rewrite pueden ir en los archivos .htaccess incluidos en el framework en los archivos de configuracin de Apache Web Server. Las siguientes reglas debenperteneceralarchivo.htaccessaldirectoriorazdondeestaelframework:
<IfModule mod_rewrite.c> RewriteEngine on RewriteRule ^$ public/ [L] RewriteRule (.*) public/$1 [L] </IfModule>

/etc/apache2/default server.conf /etc/apache2/sites available/default /Applications/MAMP/conf/ apache/httpd.conf c:\Archivos onf\httpd.conf de

/srv/www/htdocs/

/var/www

/Applications/MAMP/htdocs/

Programa\xampp\apache\c

c:\Archivos Programa\xampp\apache\htdocs\

de

Lassegundasreglasdeconfiguracindebenirenelarchivo.htaccessubicadoeneldirectorio public/as:

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

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 OptionsAllparaeldirectoriorazdelWebServerenelarchivodeconfiguracindeApache. Cuando agregamos la configuracin directamente a los archivos de Apache Web Server debemosusarladirectivaDirectoryas: Tabla:ParmetrosdeconfiguracindeApacheWebServerdirectamenteenhttpd.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 utilizacin 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 peticin Web aumentando considerablemente el rendimientodelasaplicaciones. Tambin es importante revisar que el archivo index.php sea el primero en la directiva DirectoryIndex,asApacheWebServerledarmsprioridadantesdeotrasextensiones:
DirectoryIndex index.php index.html

DespusderealizarlaconfiguracinesnecesarioreiniciarelservidorWeb.

3.3 Configuracin con Microsoft IIS e ISAPI Rewrite


Para esto debemos agregar al archivo httpd.ini del directorio raz del paquete Kumbia lo siguiente: Ejemplo:ParmetrosdeconfiguracinparaMicrosoftIIS
[ISAPI_Rewrite] RewriteCond URL (?!/javascript/|/img/|/files/|/css/|/temp/).*

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

24

RewriteRule RewriteCond RewriteRule RewriteCond RewriteRule

(.*?\.php)(\?[^/]*)?/([^/]*)/(.*) $1(?2$2&:\?url=/$3/$4) URL (?!/javascript/|/img/|/files/|/css/|/temp/).* ^/(.*) /public/index.php?url=/$1 [L] URL (?!/javascript/|/img/|/files/|/css/|/temp/).* /(.*) /public/$1

EnlacesRelacionados
Configuracin 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 Configuracin de PHP


LasiguienteconfiguracinesopcionalparaAplicacionesWebconKumbia.Acontinuacinse listanlosparmetrosdeconfiguracindelphp.ini: Tabla:ParmetrosdeconfiguracindePHPopcionales Nombre Descripcin Permiteusarlasetiquetasespecialesdephp<?=y<.Noserecomienda short_open_tag sivaaredistribuirsusaplicacionesenservidoresdeterceros.Noesun estndarprofesionaldePHPelusodeestasetiquetas. Permite que al generarse un error se muestren las rutas y archivos display_errors dondesegeneranerroresPHP,estilenentornosdevelopmentpero noenmodoproduction. memory_limit En entornos de produccin 64M es un nmero adecuado para este parmetroporscript.Debeserajustadadeacuerdoalascircustancias. KumbiaEnterpriseFrameworkestadesarrolladobajoniveldereporte error_reporting E_ALL | E_NOTICE | E_STRICT lo que asegura la calidad del cdigo y cumplimientodeestndaresbsicosdedesarrolloOOPenPHP5 Permite que el contenido de las superglobales se convierta en register_globals variableslocales.Engeneralsedebedejardeshabilitadoyaquenoes segurodemuchasformas. magic_quotes_gpc AlestarenOnpodraayudaraevitarataquesdeinyeccindeSQL,al mismotiempohacequeelrendimientodelservidorseaalgomenor.

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

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

25

kies

inyeccindeSQLyXSS.

3.5 Configuracin con Zend Application Server


Zend Application Server es un servidor para aplicaciones PHP basado en Apache Web Server porlotantosuconfiguracinessimilar. PuedeseguirlospasosdeconfiguracindeApacheyreproducirlosenZendServer.Elmdulo rewriteyaestactivadopordefectoloquelospasosdeconfiguracindebenserminimos.

3.6 Crear una Instancia de Kumbia Enterprise


El framework se distribuye en un archivo comprimido multiplataforma que contiene la estructura de archivos del framework y recursos necesarios para el desarrollo, prueba e implementacindeaplicacionesenKumbiaEnterprise. Elnombredelarchivotienelasiguienteestructurakumbiaefversionmadurezextension.

3.7 Solucin a problemas de instalacin


Lassiguientessituacionessepuedenpresentaralrealizarlainstalacindeunainstanciadel framework: Situacin:NotieneModReWritedeApacheinstalado Elservidorwebnotieneelmodulorewriteinstalado,consultelaseccinConfiguracincon ApacheWebServer2.xenelcaptulodeinstalacin.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

26

Situacin: En la pantalla se presenta el mensaje No se pudo utilizar reescritura de URLs Sedebeverificarlosiguiente: Si se usa Apache Web Server el archivo '.htaccess' debe estar presente en la raz del directoriodondeestlainstanciadelframeworklasreglasenestedebenestaractivas enlaconfiguracindelservidorweb. Situacin: Al ingresar a la aplicacin por defecto se presenta una pantalla blanca sin ningnmensaje La directiva del servidor Web de archivos por defecto le est dando prioridad al archivo index.htmlynoalindex.php.EnelcasodeApacheWebServerestosesolucionamediantela opcindeconfiguracinDirectoryIndex. Situacin: Al ingresar a la aplicacin se genera la excepcin CoreException: El directoriopublic/tempnotienepermisosdeescritura Estaexcepcinsegeneracuandoeldirectoriopublic/tempesundirectoriodesololectura no tiene permisos de escritura para el usuario con el que se ejecuta el proceso del servidor web. Situacin:AlingresaralaaplicacinsegeneralaexcepcinCoreException:Debetener instaladoPHPversion5.20superiorparautilizaresteframework LaversindePHPquetieneinstaladaesigualsuperioralaversin5.0peroesinferiorala 5.2.0.Laversin5.2.0enadelantecorrigeerroresimportantesdeseguridadenenncleode PHPytieneunmejorrendimiento. Situacin:AlingresaralaaplicacinsegeneralaexcepcinCoreException:Timezone invlido Ha definido una zona horaria en el archivo config/config.ini invlido por lo que muchas ApacheWebServersoportaarchivosdesobreescrituradeconfiguracin'.htaccess'. La opcin de configuracin de Apache 'AllowOverride All' no est presente para las

opcionesdeconfiguracindelDocumentRootdelservidorweb.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

27

opcionesdelframeworkgenerarninformacinerronea. Situacin:AlingresaralaaplicacinsegeneralaexcepcinRouterException:Noseha indicadolaaplicacinpordefectoenconfig/config.ini(defaultApp) La opcin defaultApp en el archivo de configuracin de la instancia no existe define una aplicacinquenoexisteenlainstanciadelframework. Situacin: Al ingresar a la aplicacin se genera la excepcin: CoreConfigException: Debeindicarelnombredelaaplicacindendeestelarchivo'config.ini' La opcin defaultApp en el archivo de configuracin de la instancia no existe define una aplicacinquenoexisteenlainstanciadelframework.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

28

4 Qu es Kumbia Enterprise Framework?


4.1 Sobre Aplicaciones Web
Cuando la web se empez a tomar ms en serio, no solo para presentar sitios Web con contenido esttico simplemente informativo y se dio paso a la prestacin de servicios con contenido dinmico, la estructuracin y profesionalizacin 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 novedosayeficiente. LaaceptacingeneraldellenguajePHPcomoherramientaespecializadaenelentornoWeby su amplio desenvolvimiento as como sencillez de uso, han aportado considerablemente al crecimientoycapacidaddeimplementacindealtatecnologaenlaWeb. Kumbia Enterprise es un paso adelante en la evolucin de los frameworks y de PHP como plataformadedesarrollodecarctergeneral.

4.2 Sobre PHP y la Web


A travs de los aos PHP se ha convertido en un estndar de facto para la construccin de softwareparaInternetdealtaescalabilidadyvelocidad.Muchosdelossitiosmspopularesy concurridosenlaactualidadincluyendoWikipedia,Yahoo!yFacebook.

4.3 Introduccin
KumbiaEnterpriseFrameworkesunconjuntodetecnologasparalaproduccindesoftware que integra una novedosa plataforma de middleware proporcionando servicios de persistencia, transacciones, mensajes y clustering a aplicaciones basadas en PHP que esten orientadasalaWeb. PoraoslamadurezdeldesarrolloempresarialenPHPhaevolucionadoincrementalmentey hoy en da se cuenta con productos maduros que pueden proporcionar alternativas que reduzcan los costos de tecnologas de informacin y puedan ser aplicados a entornos empresarialesdesdelamedianaypequeaempresahastagrandesaplicacionesorientadasal clientefinal.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

29

Nuestra plataforma pretende unificar la plataforma tecnolgica de backend y frontend acelerando los procesos de desarrollo e implementacin de software usando middleware multiplataformaescalablecontecnologiaopensource.Paralograrestounadenuestrasfichas clavesesKumbiaEnterpriseFramework. Kumbia Enterprise es un framework especialmente orientado al entorno empresarial, que implementalasmejorasprcticasdedesarrollodesoftwareyprcticasorientadasalasWeb de la actualidad e intenta fomentar principalmente la generacin de aplicaciones profesionales, potentes, seguras y mantenibles en el tiempo para empresas que deseen adoptarsoftwareabiertoytecnologaPHP. Gracias al apoyo de diferentes empresas patrocinadoras y de LouderTechnology ahora es posibleimplementaraplicacionesconunabasedecdigomsslida,estableyfuncionaljunto conunserviciodesoportequeasegurequesudesarrolloymejoramientosercontinuoenel tiempo.

4.4 Caractersticas del Framework


Sumadasalasdesuhermanocomunitario,KumbiaEnterpriseFrameworkposeelassiguientes caractersticas:

ArquitecturaModeloVistaControlador(MltiplesAplicacionesextendibleconPlugins yEventos) Contenedorparaaplicacionesyserviciosweb ComponentedeCacheoFlexible ObjectRelationalMapping (ORM) potente y robusto (Transacciones, Validadores, Joins,Unions,Generadores,MultiplicidaddeRelaciones,Herencia) BusinessProcessManagement(BPEL) ServiciosWeb(IntegracinyOrquestamiento)(Soap,SCA) Componente de Administrador de Sesin (Session Handling) Flexible (Memcached, Database,LouderCache,Files) Componente de Autenticacin (LDAP, Model, KerberosV, Radius) con soporte para SesinActivayExpiracindeSesin ComponentedeAccessListControl(ACL)Flexible(Model,Memory,Xml) ComponentedeAuditoriadeSistemas

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

30

SistemadeLoggingFlexible(File,Compressed,Mail,Database,Stream,SCA) Localizacin(Traduccin,Fechas,Monedas)independientedelaplataforma MonitoreodeAplicaciones(CommonEventInfrastructure) Componenteparageneracindereportesempresarialesenmltiplesformatos(Pdf, Excel,Html) ComponenteparaimplementacindeserviciosWebDAV Componentesdeconexinamotoresdebasededatoscertificados(OracleyMySQL) SemiCompiladorparaelFrameworkylasaplicaciones GarbageCollectordeSesin Plantillasrpidasyflexibles FiltrosyValidacinIntegrada TestsdeUnidad Debug,TrazayProfilingavanzado ComponentedeConfiguracinFlexible(Ini,Xml,PHP) DocumentosPDFconPdfDocument IntegracinconLouderClusteringTechnology IntegracinconLouderCache IntegracinconIBMWebSpheresMash

4.5 PHP en entornos crticos


EllenguajePHPnohatenidounagranparticipacinenentornosdeaplicacionescrticasyen un muchos casos ha sido relegado a la creacin de sitios Web y portales. Algunas caractersticasdellenguajePHPcomolatipificacindbilysucarcterinterpretadopuedeny hanhechodesconfiaraorganizacionesensuimplementacinensoftwaregrandeycomplejo. Kumbia Enterprise Framework ha sido diseado para mantener estrictos controles de validacin de tipos e integridad de datos, garantizando en gran medida que los procesos, entradaysalidadedatos,cumplanasatisfaccinconlosrequerimientosdenegociosinperder lapotenciaycapacidadesparaeldesarrollorpidoqueofrecelatecnologaPHP. ProyectosyproductoscomoAPC(AlternativePHPCache),ZendOptimizer,eAccelator,Zend Guard y otros ms, permiten llevar aplicaciones en PHP a un carcter semiinterpretado y hastaprotegerlapropiedadintelectualdelcdigofuentedelsoftware. En resumen se puede decir que existe actualmente entornos y tecnologa que permiten el

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

31

desarrolloeimplementacinsatisfactoriadeaplicacionesparaentornoscrticosbasadosenel lenguajePHP.

4.6 Preguntas frecuentes sobre Kumbia Enterprise


ParaquotroframeworkPHP? Como se ha mencionado anteriormente PHP ha sido un lenguaje usado para la creacin de softwareysitiosweb.Losframeworksactualeshanavanzadomuchoenestesentidoyofrecen todas las herramientas necesarias para llevar a cabo estos proyectos. La inmediatez en el desarrolloesalgoquetodoslosdesarrolladoresPHPhoyendanormalmentebuscan. Porotroladocuandoelobjetivoesdesarrollaraplicacionesdemisincritica,conprocesosde negocio complejos, cientos miles de usuarios, concurrencia muy alta, necesidad de integrarseaotrossistemasenotrasplataformasdedesarrolloyademsserequierequesean monitorizadasyqueseadaptenrpidamentealaevolucindelosrequerimientosdelnegocio, elpanoramacambia. Paraasegurarelxitodeproyectoscomplejosdesoftware,apartedelainversinderecursos degerenciayadministracin,serequiereasegurarqueestainversinnosevayaaperderpor seleccionarlasherramientasequivocadasparallevaracaboelproyecto. Es difcil determinar cuando un proyecto va a crecer ms de lo que se espera y como esto puede a obligar a cambiar sobre el camino un diseo erroneo en el peor de los casos reescribirpartedeloscomponentesdelasaplicacionesparaadaptarsealoscambios. KumbiaEnterprisenaciprecisamentecuandounsoftwareenPHPtuvoqueprepararsepara soportar 250.000 peticiones diarias (ms de 7 millones al mes), 15000 transacciones y ademsofrecerfuncionalidadreusableaotrasaplicacioneshaciendomsmantenibletodala infraestructuradesistemasdeunaempresa.Laenseanza:Esmejorpensarengrandeahora, tardarunpocomsendesarrollarynopreocuparseenelfuturoporelcrecimiento,nienlas posibles oportunidades comerciales de requerimientos y adaptabilidad del negocio que se puedanpresentarenelciclodevidadeunconjuntodesistemas. PorquunframeworkparaSOA? SOAesunconcepto,nounatecnologa.Undesarrolladorpuedeimplementarunaarquitectura

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

32

orientada a servicios usando otro lenguaje u otro framework, no necesariamente debe ser KumbiaEnterprise.SOAtampocoesaptoparacualquierproyecto,estodebeserunadecisin planeadayestrategicaquebeneficieypropendaporlosobjetivosdenegociodeunaempresa uorganizacin. SOA se ha convertido en un estndar de la industria para la implementacin de infraestructuras de sistemas que requieran una alta reusabilidad y flexibilidad de los componentesdelasaplicacionestantointernamentecomoexternamente.Grandescompaias de software como IBM, JBoss y Oracle invierten grandes cantidades de recursos en el desarrolloymejoramientodesolucionesparaempresasquebusquenimplementarestetipo dearquitecturas. Puedequetardemstiempoenimplementarunaarquitecturaeficienteyestableapartirde componentespocoacopladosdeotrosframeworksgenerandolecontratiemposyenelpeorde loscasosperdidasensuinversinenIT.KumbiaEnterprisehasidodiseadoparafacilitarla definicin y construccin de SOA utilizando el lenguaje PHP mediante un contenedor de aplicaciones y servicios web diseado especficamente para este tipo de arquitecturas y tambinparaaplicacionesorientadasalawebcomunes. Kumbia Enterprise ofrece ms 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 implementadomuchosdeloscomponentesqueserequierenparaconstruiraplicacionesWeb peroademsofrececaractersticasempresarialesnicasquefacilitaneldesarrollodegrandes y medianas aplicaciones con procesos de negocio complejos y que debido a su naturaleza requierandealgunafuncionalidadespecificadelframework. Por qu Kumbia Enterprise no parece ser completamente libre y manejado por la comunidadcomoloeselKumbiaPHPComunitario? KumbiaEnterprisetieneunalicenciaabiertallamadaNewBSDqueofrecelibertadessimilares a la LGPL. El desarrollador no tiene problema en crear, distribuir y comercializar software basadoenelframeworkgraciasaestalicencia. LouderTechnologybuscalideraryasegurareldesarrolloactivoymejoramientocontinuodel

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

33

frameworkpermitiendoqueempresasydesarrolladoresadoptenelsoftwaretranquilamente y se puedan enfocar en sus propias aplicaciones ofreciendo el espacio para que puedan retroalimentaraportarycolaboraralproyectoretroactivamente. 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 estticamente dinmicamente. Componentes de usuariopuedenregistrarcomponentesdeautocargadezendhacerusodelosmismos. Conozco he trabajado desarrollando en Java, que puedo esperar de Kumbia Enterprise? Esteframeworkhasidodiseadoparaserfamiliarenmuchosaspectosalosdesarrolladores Java y tambin a los desarrolladores PHP. Kumbia Enterprise tiene estrictos controles de validacin en busca de encontrar ms problemas y de tratar de identificar potenciales posiblesproblemasquepuedantenerloscomponentesdesarrollados. Kumbia Enterprise adems permite ejecutar aplicaciones bajo IBM WebSphere sMash permitiendointegrarcdigonativoJavaenaplicacionesPHPyviceversaaprovechandocdigo yexperienciaexistentedeldesarrollador.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

34

5 Arquitectura
5.1 Introduccin
KumbiaEnterprisepermiteeldesarrollodeaplicacionesenvariascapasestopermiteromper un sistema en subsistemas ms pequeos reduciendo la complejidad del mismo y proporcionandoimportantesbeneficios. Cuando se trabaja con un sistema multicapa se entiende que existen capas de alto nivel y otras de menor nivel, las de mayor nivel aprovechan la funcionalidad implementada en las capasinferioresocultandodetallesquenorequierendeunentendimientoinmediatoaunque reduciendolaflexibilidadenunauotramedida. Losprincipalesbeneficiosdeimplementarsistemasmulticapason:

Esposibletrabajarsobreunacapasuperiorsinnecesidaddeconocercomofuncionan lascapasinferiores.CuandodesarrollaconKumbiaEnterpriseutilizaunacapadealto nivelqueaumentalaproductividadsinrequerirelentendimientoenprofundidadde comportamientosfuncionalidaddebajonivel. Unacapapuedesersustituidaporotramanteniendounainterfaceconsistentequese adapteanecesidadesespecificassinmodificarlaaplicacinporcompleto.

5.2 Capas en una Aplicacin


UnaaplicacinWebdesarrolladaenKumbiaseseparaen3capasprincipalesllamadas:Lgica deDominio,PersistenciayPresentacin. La lgica de dominio de negocio es quien dicta las reglas sobre como debe trabajar la aplicacin en si. Constituye todo lo que tiene que ver con clculos de entrada de datos, validaciones,procesosycomosepresentaranlosdatosenlacapadepresentacin. Lapersistenciay/lgicadelmodelodedatostratasobrecomolalgicadedominiorequiere de los datos que le proporcionan servicios de bases de datos, sistemas de transacciones, mensajes,sistemasdearchivos,etc. La presentacin trata de todos aquellos elementos que permiten la interaccin entre el

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

35

usuariofinalylaaplicacin.EnunaaplicacinWebserefiereademsalastecnologasdelado del cliente como CSS JavaScript, los navegadores, los lenguajes de marcas y de transformacin. Cadacapamencionadaanteriormenteofreceserviciosytieneresponsabilidadesdiferentesen una aplicacin empresarial, la clara separacin de estas capas es fundamental para un desarrollo satisfactorio. Los componentes para la administracin y uso de cada capa son proporcionadosporelframeworkascomoserviciosdeintegracinentreellostambin.

5.3 Usando Modelo-Vista-Controlador


Las aplicaciones en Kumbia utilizan el patrn arquitectacional llamado MVC. Con l las aplicacionesWebsepuedensepararen3capasbiendefinidasayudandoalamantenibilidad de la misma y exigiendo un orden y claridad que con el tiempo alarga la vida til de las mismas.

Modelos:Representanlainformacinsobrelacuallaaplicacinopera,lasentidadesy sulgicadenegocio.Contienentodaslasvalidaciones,constraintsyreglasquehacen que la lgica del negocio se cumpla y haya integridad en los datos. Corresponde a la capadepersistencia. Vistas:VisualizanelmodelousandointerfacesWebeinteractuandoconlosusuarios destas.CorrespondealacapadePresentacin. Controladores:Atienden,respondenyenrutanlasaccionessolicitadasporelusuario final e invocan cambios en las vistas en los modelos segn sea necesario. Correspondealacapadelgicadedominio.

Los controladores estn separados en partes, llamadas front controller y en un conjunto de acciones.Cadaaccinpuedeinteractuardeformadiferentedeacuerdoaltipodepeticin.Las vistasestnseparadasenlayouts,templates,vistasdeaccinypartials.Elmodeloofreceuna capadeabstraccindelabasededatosllamadaORMqueademsdanfuncionalidadagregada adatosdesesinyvalidacindeintegridadrelacional.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

36

Estemodeloayudaaseparareltrabajodelalgicadenegocios(modelos)ylapresentacin (Vistas) Elcontroladorayudaaocultarlosdetallesdeprotocoloutilizadosenlapeticin(HTTP,modo consola,etc.)paraelmodeloylavista.Finalmente,elmodeloabstraelalgicadedatos,que hacealosmodelosindependientesdelasvistas. Kumbia Enterprise Framework agrega componentes y plugins que interactan con la arquitecturadelaaplicacin. EnlacesRelacionados
Modelo Vista Controlador

5.4 Ventajas de usar MVC


AlimplementarelpatrnarquitectacionalMVCesposiblesepararclaramentelaformaenla que se presenta la informacin, de la forma en la que se almacena, de la forma en la que orquestalalgicadelaaplicacin.Deestaformaesmenoscomplicado:

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

37

Detectarenquecapaseestagenerandounproblemadelaaplicacin.Porejemplosi un proceso no se esta ejecutando correctamente es muy probable que el problema esteenelcontrolador. Siseagregaunnuevoconstraint(restriccin)almodelodedatosesteseaplicaatodo elsistemainmediatamente. Si los diseadores requieren trabajar en la presentacin esto es posible sin que se afectelalgicadenegocioelmodelodedatos. Definitivamente la aplicacin se hace ms mantenible y reusable creando unidades queinteractanentresiyestnseparadasenformalgicademaneraclara.

5.5 Arquitectura SOA


LaarquitecturaSOAproporcionaestrategiasaldesarrolloeintegracindeinfraestructurasde softwarequepermitenutilizarlafuncionalidaddeunsistemacomoserviciosinteroperables. Las arquitecturas SOA permiten el intercambio transparente de datos entre diferentes aplicaciones. Un SOA permite que haya loose coupling de servicios entre diferentes aplicaciones,sistemasoperativosylenguajesdedesarrollo. Por muchos aos las empresas han tratado de integrar mltiples aplicaciones con el fin de apoyar los procesos de negocio en cada uno de sus departamentos y de ofrecer de forma automatizadainformacinasusproveedoresyclientes. Durante estos procesos es normal encontrarse con inconvenientes como incompatibilidad entre lenguajes, formatos, plataformas, etc. Por esto la industria tecnolgica ha creado todo tipodeestrategasqueconllevenalmejoramientoyexitodeestetipodeintegraciones. SOA es una estratega 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,exploracinyculturizacin.ActuamentePHPproporcionalibreriasyfuncionalidad quepermiteofrecerservicioswebusandodiferentesprotocolos,peroSOAesmuchomsque serviciosweb. LossiguientesconceptossonpartedeloquerepresentaunaarquitecturaSOA:

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

38

SOA Governance: Son todas las actividades relacionadas a tener control sobre una SOA. En trminos cortos se puede decir que son las reglas con las que se implementa y adopta esta arquitectura. OrquestacinyCoreografadeServicios:Aunquenoesdirectamentedependientedeuna SOAesfundamentalcuandoseimplementanprocesosdenegociocomplejos. Business Process Management: Permite el mejoramiento y optimizacin de procesos de negocioaprovechandolaarquitecturaensimisma. Y aunque existen muchos ms, Kumbia Enterprise ha trabajo en proporcionar herramientas quepermitanlarpidaadopcindeunarquitecturaorientadaaserviciosbasadaenPHPysu objetivoesofrecerunambientecadavezmsrobustoquepermitalograresteobjetivo.

5.6 Beneficios de una SOA


LastresbeneficiosmsimportantesdeadoptarunaarquitecturaSOAson: Al generar cada unidad de negocio como un servicio y poder usarlo rpidamente en unaaplicacin,sepromuevelaagilidadalcambioenformamsefectivaquemediante sistemasaislados. Al utilizar servicios se crean abstracciones autosuficientes capaces de mejorarsen afectandoenformapositivaasusdependenciasenformatransparente. Los servicios son en cierta forma autodocumentados lo cual es muy importante al desarrollarsistemasflexiblesyadaptables.

5.7 SOA en Kumbia Enterprise


EnesteapartadotrataremosdeilustrarcomoKumbiaEnterprisemediantesucontenedorde serviciosyaplicacionespermitelarpidaadopcindeSOAenunaorganizacin. 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 lgica de negocio adecuada para producir una salida en una vista. El frameworkproporcionaalgoquehemosdenominadocontroladoresinteligentes.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

39

Cuando una aplicacin en Kumbia Enterprise recibe una peticin esta es analizada para determinareltipodeclienteytipoderespuestaadecuadaqueesperaestecliente. Elsiguientediagramamuestraelfuncionamientodelcontenedor:

Segn el diagrama una aplicacin puede recibir peticiones de diferentes clientes solicitando respuestasadecuadasaltipodecliente.Eldiagramaseparaalosclientesdelasaplicaciones entres: UsuariosFinales/Visitantes:Unusuarioqueutilizalaaplicacinyqueesperaobteneruna respuestahumanaquepuedaentenderparacontinuarrealizandootroproceso. Maquinas Servicios Web: Maquinas que consumen servicios web y que requieren de mantenersesionesconversacionales.PorejemploSOAPREST. Maquinas Proceso de Datos: Clientes web que solicitan a aplicaciones datos en formatos adecuadosquepuedanserprocesadosporelmismocliente.PorejemploJSONXML.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

40

ElcontenedordeKumbiaEnterpriseanalizaelsolicitudderespuestadelclienteytransfiere la solicitud al controlador/accion adecuado que en cada uno de los casos tendr un tratamientodiferente. LacapaEnterpriseServiceLayeresopcionalycuandoseaccededirectamentealaaplicacin estanoexiste.LacapaeselESB(EnterpriseServiceBus)elcualtieneunservicioregistradoy puedemodificarymonitorizarelaccesoalosservicios. LacapaDomainLayeresunasupercapaqueabstraelaimplementacindetodoslosprocesos de negocio. La capa Application Layer son las aplicaciones/controladores/servicios como tal quecomponenelprocesodenegociorequerido.

5.8 Loose Coupling/Tight Coupling


Uno de los objetivos de diseo de Kumbia Enterprise Framework es buscar que el arquitecto/desarrolladornotengaqueintegrarningncomponenteparadefinirlaestructura de su aplicacin por esta razn varios componentes son dependientes los unos de los otros proporcionandounentornoreadytousedondeseaposibledesarrollaryejecutaraplicaciones empresarialesfavoreciendoprincipiosdereusabilidadyrendimientodecualquieraplicacin. Los patrones de diseo VirtualProxy y DependecyInjection son utilizados para permitirle al desarrolladorreemplazar/integrarcomponentesescritosportercerosalaaplicacin. Muchosotroscomponentesestnpensadosenserdbilmenteacopladosloosecouplingde talformaquepuedanserintegradosaotrasaplicacionesescritasenotrosframeworks. Kumbia Enterprise Framework ofrece avanzada funcionalidad cuyo nivel de madurez es similarsuperioraldeotrosframeworksPHPactuales.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

41

CaptuloTutorial

6 Caso de Uso: Aplicacin de Cajero Bancario


6.1 Introduccin
En el presente capitulo del manual de referencia se tratar de ilustrar con un ejemplo de aplicacinlasprincipalescaractersticasdelFrameworkenunejemploprctico. La idea es crear una aplicacin que sirva como un futuro cajero electrnico virtual para un bancollamadoCentralBank.Lasreglasdelnegociosonlassiguientes: Los clientes del banco pueden entrar a la sucursal virtual usando el nmero de su identificacinpersonalylaclavedealgunadesustarjetas. El desarrollo e implementacin de aplicaciones bancarias exige requerimientos altsimos de seguridad, prestaciones, alta disponibilidad, infraestructura de redes y probablemente la implementacindemuchasreglasfinancierasybancariasparaqueelsistemaseafuncionaly usable.Sinembargo,paraquenuestroejemplonoseaeternoynosesalgadecontexto,vamos acrearunsistemamuysimplificadoperoquesirvaparaentenderlosconceptosyentornode trabajoconelFramework. PuedequeseanecesarioentenderlosconceptosdeORM(ActiveRecord)yelfuncionamiento delcomponenteControlleryView,paraunamayorcomprensindelpresenteTutorial. Unavezautenticadoslosclientespuedenconsultarsusextractos,hacertransferencias aotrascuentasyrevisarsusaldo.

6.2 Anlisis de los Requerimientos


Haciendounanlisismsprofundodeltemaidentificamoslassiguientesentidades: Clientes:Sonelusuariofinaldelaaplicacinyseasumequehabrunaentidaddonde semantendrlainformacinasociadaaellos. Cuentas: Manejan el saldo actual de la cuenta, su saldo en canje y su relacin a clientes. Movimiento: Almacena un log de las operaciones realizadas por el cliente en sus

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

42

cuentasyserutilizadoparagenerarlosextractosdelcliente. Intereses:Sonlosinteresesganadosporelclientecadadaquetienesudineroenel banco. ParadesarrollarelejemploseutilizaunabasededatosusandoelRBDMMySQL5.0,estabase dedatosesmultiplataformayseinstalafcilmenteenlamayorpartedesistemasoperativos. Elnombredelabasededatosserbankdb.Creamoslabasededatosas:


CREATE DATABASE nombre_bd CHARACTER SET utf8;

Sucursales:Eslaubicacinenlaqueserealizalatransaccinbancaria.

Laestructuradelastablasserlasiguiente: TablaCustomer:Administralainformacindelosclientesdelbanco
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;

Descripcindeloscampos: Campo id identification sucursal_id name email created_at status TablaAccount:Administralainformacindelascuentasysussaldos


CREATE TABLE `account` ( `id` int(11) NOT NULL auto_increment, `number` int(22) NOT NULL, `password` varchar(40) NOT NULL,

Descripcin Eslallaveprimariadelatablayesautonumrica. Eselnumerodeidentificacindelapersona. Eselcdigodelasucursaldondesecrelacuenta. Eselnombredelapersona Eselcorreoelectrnicodelcliente Eslafechaenlaquesecreelclienteenlabasededatos Eselestadodelclienteenelbanco.(A)ctivo(I)nactivo

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

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;

Descripcindeloscampos: Campo id number password sucursal_id customer_id balance swap_balance type created_at status TablaMovement:Administralainformacindelosmovimientosrealizadosenlascuentas
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;

Descripcin Eslallaveprimariadelatablayesautonumrica. Eselnmerodelacuenta EselresumenSHA1delaclavedelacuenta Eslasucursalendondesecrelacuenta. Eselclientealquepertenecelacuenta Eselsaldoquetienelacuenta. Eselsaldoquetieneencanje. Indicasilacuentaesdeahorroscorriente. Eslafechaenlaquesecrelacuentaenlabasededatos Eselestadodelclienteenelbanco.(A)ctivo(I)nactivo

Descripcindeloscampos:

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

44

Campo id account_id ubication_id cash created_at

Descripcin Eslallaveprimariadelatablayesautonumrica. Eslacuentaenlaqueserealizelmovimiento Eslaubicacinenlaquesegenerelmovimiento Eselmontoporelqueserealizelmovimiento Eslafechaenlaquesecrelacuentaenlabasededatos

TablaSucursal:Administralainformacindelassucursalesdelbanco
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;

Descripcindeloscampos: Campo id name ubication_id Tabla Ubication: Administra la informacin de las ubicaciones donde se pueden realizar operacionesbancarias.
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;

Descripcin Eslallaveprimariadelatablayesautonumrica. Nombredelasucursal Eslaubicacindondeseencuentralasucursal

Descripcindeloscampos: Campo id name NombredelaUbicacin Descripcin Eslallaveprimariadelatablayesautonumrica.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

45

6.3 Esqueleto de la Aplicacin


Una vez creado el modelo de datos generamos el esqueleto de aplicacin 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 crearelesqueletodelaaplicacinesutilizarelscriptcreate_application.phpenmodoconsola: AlubicarsedentrodeldirectoriodondeestalainstanciadelFrameworkusamoselcomando:
php script/create_application.php name bank

ElnombredeldirectorioquetieneelFrameworksellamaexample.Lasiguienteestructura dearchivossehacreado:
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

Unavezdefinidalaestructuradedirectoriosdelaaplicacinesposibleempezaradesarrollar sobreella.Laaplicacinseencuentraenentornodedesarrolloytodolorelacionadoconello estaactivadopordefecto.

6.4 Configurar la conexin a la base de datos


Para empezar a probar los controladores y la iteracin con los modelos es necesario configurarlaconexinalabasededatosquesevaautilizarenelentornodedesarrollo.Para estoseeditaelarchivodeconfiguracinenvironment.inicreadoeneldirectorioconfig:
[development] database.host = localhost database.username = root database.password = 2fe0517 database.name = bankdb database.type = mysql

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

46

Estos parmetros sern usados en toda la aplicacin para conectarse a la base de datos de desarrollo.KumbiaEnterpriseFrameworkpermitedefinirunaarquitecturade3capasencaso dequesenecesiteutilizarlabasededatosenunservidorexternoaldedesarrollo.

6.5 Crear los modelos de Base de Datos


Un modelo debe ir ubicado en el directorio models de la aplicacin. Los nombres de los archivosdemodelosdebentenerelnombredelatablaamapear(estoesunaconvencin). En cada archivo debe existir una sola clase con el nombre del modelo usando notacin camelizada.LasclasesdemodelosdebenheredardelaclaseActiveRecord. Un ejemplo de un modelo de la tabla ubication es el archivo models/ubication.php que implementalaclaseUbicationas:
<?php class Ubication extends ActiveRecord { }

AldefinirunmodeloconunaimplementacindeatributosvacaseindicaaActiveRecordque debecrearlosatributosdelatablaenformadinmicayporlotantolavisibilidaddeestaser pblica.Engeneralestonoesunabuenapracticadedesarrolloyaquesedejaaldescubierto la privacidad de los valores de los campos sin que haya ningn control en su acceso. Para solucionarestoeimplementarunmodelomssegurosehaceas:
<?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/KumbiaEnterpriseFrameworkManualdeReferencia

47

Los getters y setters proporcionan puntos unificados para obtener/establecer los valores internosdelmodelo.Engeneral,cadatablaqueseutiliceenlaaplicacindebesermapeada porunmodeloenlamisma.Elscriptcreate_all_models.phppermitecreartodoslosmodelosde labasededatosactualimplementandocadaclasecomosevienelejemploanterior.Eluso delscripteselsiguiente:
php scripts/create_all_models.php -application bank

Adicional a los getters/setters generados, el script agrega los PHPDocs a cada mtodo y atributoconloquesemejoraladocumentacindelsistemaysiseutilizanIDEscomoZend StudioEclipseestoscomentariossonledosayudandoaautocompletarelcdigocuandosea posible. Elmodeloparalatablacustomergeneradoes:
<?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/KumbiaEnterpriseFrameworkManualdeReferencia

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/KumbiaEnterpriseFrameworkManualdeReferencia

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 Sesin


Eliniciodesesinparaelusuariofinaldelasucursalvirtualsegnlosrequerimientosdela aplicacin,esunapantallaendondeelclientedeberingresarsudocumentopersonaljunto conalgunadelasclavesdelascuentasasociadasaesedocumento. SegnlaarquitecturaMVCloscontroladoressonelpuntodeentradaacualquieraccinquese realice en la aplicacin, aunque de momento el primer requerimiento nos hace pensar en presentacin antes de lgica del negocio empezaremos creando un controlador que no implementeningntipodelgicaporahora: Elcontroladorcreadosellamaloginyelarchivodondeseimplementalaclasecontroladoraes elarchivocontrollers/login_controller.phpydemomentocontienelosiguiente:
<?php class LoginController extends ApplicationController { public function indexAction(){

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

50

} }

La implementacin vaca de la accin index permite que la presentacin (la vista se visualice)encuantoseinvocaelcontrolador. Ya que login ser el controlador por defecto de la aplicacin se implementa el mtodo ControllerBase::initdelasiguienteforma:
<?php class ControllerBase { public function init(){ //Enrutar al controlador login Router::routeTo("controller: login"); } }

SegnlasconvencionesenlaarquitecturaMVCdelFrameworklavistaparalaaccinindex delcontroladorloginsecreaenelarchivoviews/login/index.phtml. Lainterfazpresentaunacampodetextodondeesposibleingresareldocumentodelclientey otraparalaclavenumricade4dgitos.


<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() ?>

Amboscampossonrequeridosyporlotantosevalidancomorequeridosenelcontrolador.La validacin tambin se puede hacer en JavaScript, sin embargo estamos haciendo un sistema confiableynopodemosconfiarenloqueocurraenelcliente.
<?php

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

51

class LoginController extends ApplicationController { public function indexAction(){ } public function validateCredentialsAction(){ $rules = array( "identification" => array( "filter" => "alpha", "message" => "Por favor indique su documento de identificacin" ), "password" => array( "filter" => "int", "message" => "Por favor indique su contrasea" ), ); if($this->validateRequired($rules)==true){ //Aqu viene la autenticacin } else { $this->routeTo("action: index"); } } }

La utilizacin del mtodo heredado validateRequired permite validar el tipo de dato y comprobarsielusuariohaingresadoalgnvalorenestoscampos.Losvaloresdeloscampos sonfiltradosusandoelcomponenteFilterantesdevalidarsiestnpresentesenlaentradade usuario. Si la validacin falla el flujo de ejecucin se enruta nuevamente a la accin index. Ahora se modificalavistaparamostraralusuariolosmensajesgeneradosenlavalidacin.
<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/KumbiaEnterpriseFrameworkManualdeReferencia

52

ElmtodoestticoView::getValidationMessages()permiteobtenerlosmensajesobtenidosen la validacin. Cuando el proceso de validacin es satisfactorio se puede continuar con el procesodeautenticacin.

6.7 Autenticando al Cliente


El requerimiento del banco exige que la implementacin de la autenticacin se haga de la siguienteforma: LosmodelosCustomeryAccountcontienenlosdatosrequeridosparaefectuarestaoperacin. LaaccinmodificadavalidateCredentialsquedaas:
public function validateCredentialsAction(){ $rules = array( "identification" => array( "filter" => "alpha", "message" => "Porfavor indique su documento de identificacin" ), "password" => array( "filter" => "int", "message" => "Porfavor indique su contrasea" ), ); 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

Validarqueexistaunclienteconeldocumentoingresado Validarquelaclaveproporcionadacorrespondaalmenosaunacuentadelcliente

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

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 mtodo getPost. Como primer parmetro se pasa el nombre del campo usado en el formulario. Adicionalmentesepuedeaplicarunfiltroparaasegurarquelaentradasiesseguray correspondealtipodedatoesperado. Paraaccederacualquiermodelobastaconinvocarlousando$thisdentrodecualquier accindelFramework.Elnombredelavariablecorrespondealnombredelaclaseque utilizaelmodelo. ElmtododelmodelofindFirstbuscaunregistrocomosutraduccindicebuscarel Primero. La condicin permite obtener el registro deseado. Este mtodo devuelve falsecuandonoencuentraregistrosconlascondicionesindicadas. El mtodo find realiza una bsqueda de varios registros, la condicin permite filtrar solo los registros de las cuentas asociadas al cliente. Cuando no encuentra registros devuelve un vector vaco, en caso contrario el resultado de find es un Objeto de la clase ActiveRecordResulset que implementa el patrn Recordset, es decir una representacinenmemoriadelresultadodevueltoporlabasededatos. La variable $successAuth sirve como variable bandera para identificar si se ha encontradounacuentaconlacontraseaproporcionada. Paraobtenerlosvaloresdeloscamposdelmodeloesnecesariousarlosgettersenel casodecustomerseusogetId()paraobtenereliddelregistroqueseconsult. LasclavesenlatablaAccountsonresmenesusandoelalgoritmosha1. Para agregar un mensaje de validacin personalizado se puede usar el mtodo addValidationMessageelcualtambinesusadointernamenteporvalidateRequired. Cuandofallaalgnrequisitodelprocesosemuestraelmensajeyseenrutaalaaccin indexloquelepermitiralusuariofinalreingresarlainformacin. Cuandoeldocumentodeidentificacinylaclavesoncorrectossecreaunavariablede sesinmedianteSession::set,estaesllamadaexistsValidUseryseleasignavalortrue. Esta variable indica a lo largo de la aplicacin que existe un usuario valido

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

54

autenticado.

6.8 Un Men para la Aplicacin


Paraorganizarlasopcionesqueutilizaelusuariofinalsecreaunmenyseimplementadetal forma que siempre sea visible por el usuario final durante todo el tiempo que ejecute la aplicacin.Comosevienelprocedimientodeautenticacin,cuandoestaessatisfactoriael flujo de ejecucin es redireccionado al controlador menu. La implementacin de este controlador carece de lgica de negocio alguna y muestra la vista que permite al cliente escogerlaopcinquedesea: El script de ayuda del Framework llamado create_controller permite la creacin del controlador:
php scripts/create_controller.php --application bank -name menu

Comoresultadoseobtieneelcodigogenerado:
<?php class MenuController extends ApplicationController { public function indexAction(){ } }

La jerarqua de vistas implementada en el componente View permite que la presentacin correspondiente a un controlador sea compartida por otros, por esto se ha creado el men enlazandocadaopcinenellayoutdelcontrolador. Elarchivoviews/layouts/menu.phtmlquedaas:
<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/KumbiaEnterpriseFrameworkManualdeReferencia

55

mantiene actualizados los path absolutos a la aplicacin y si se llegase a mover a otro URI automticamenteestosmantendranlasrutascorrectas.

6.9 Visualizacin del saldo del cliente


Laprimeraopcinquepresentaelmenalclientelepermiteconsultarelsaldodelascuentas bancariasquetengaenelbanco.Paraimplementarlaconsultasecreaelcontroladorbanking queconsultaelsaldodecadacuentaylopresentaenunavista. ElcontroladorBankingControllerquedaas:
<?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 sesin que se crearon cuando el cliente inici sesin desde el SessionNamespace.ElmodeloAccountesinyectadopararealizarlaconsulta,elresultadode estasepasaalavistausandoelparmetroaccounts. Enlapresentacinlaideaespresentarunatablaconlossaldosencadacuentajuntoconuna sumatoriadelsaldototalporcuentaydetodaslascuentas.Latablaapresentarcontienelas siguientescolumnas:NmerodelaCuenta,Saldo,SaldoenCanjeyTotal(quesumaelsaldo ms el saldo en canje). Podemos definir el total como una columna calculada, obteniendola como una regla del negocio implementando el mtodo getBalanceTotal() en el modelo Account:
<?php class Account extends ActiveRecord { /* getters y setters */ /** * Devuelve el saldo total de la cuenta * * @return double */

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

56

public function getBalanceTotal(){ return $this->balance+$this->swap_balance; } }

Al definir este mtodo se extiende el modelo y se cumple con la regla del negocio. getBalanceTotal()estdisponibleencadainstanciadeAccountentodalaaplicacin. Se crea la vista de esta accin en el archivo apps/bank/views/banking/checkBalance.phtml. NotesequebankingcorrespondeaelnombredelcontroladorycheckBalancealnombredela accin:
<?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 mtodo find de Account es un objeto ActiveRecordResulset que puedeserrecorridoporforeachparaconstruirlatabladecuentas.Algunclientepuedetener varias cuentas tener ninguna, en este ultimo caso, la aplicacin le informar al cliente. Ya que los objetos ActiveRecordResultset implementan la interface Countable es posible saber cuantosregistrosdevolvilaconsultausandolafuncincount():
<?php if(count($accounts)>0){ print "<table border='1' align='center'> <thead> <tr> <th>Nmero</th> <th>Saldo</th> <th>Saldo en Canje</th> <th>Total</th> </tr> </thead>

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

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,estosedebeaqueellayoutdelmenquesedefinianteriormentesoloestaactivo paraelcontroladordelmismonombre.Paradefinirellayoutmenucomoeldelcontrolador bankingseusaelmtodosetTemplateAfter()enelinicializadordelcontrolador.
<?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 aplicacin como el contenidodelasvistasqueloutilicen:
<h1>Cajero Virtual</h1> <table width="100%">

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

58

<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>

<tr>

El llamado a View::getContent() indica donde se debe autoincluir el contenido de la vista asociada al layout, en este caso es checkBalance.phtml. Segn la configuracin actual, cualquier peticin a los controladores men y banking mostrarian el mismo layout del menu principal, con esto logramos que los clientes puedan ir de una opcin a otra sin problemasylaaplicacinobtieneunmenuquesepuedemantenerfcilmenteyaqueestaen unsoloarchivo,peroaplicaavariosestadosdelaaplicacin.

6.10 Crear el TransactionActivity


La segunda accin que se debe implementar en el controlador banking es showTransactionActivitycuyoobjetivoesmostrarlosextractosbancariosdelclienteencada unadesuscuentas.Paraempezar,sedebepermitiralclientequeseleccionelascuentasenlas que desea ver sus extractos y luego mostrarlos paginando los resultados y dar la opcin de imprimirlos. LaimplementacindelaaccinshowTransactionActivityconsultalascuentasdelclienteylas visualizaenlapresentacindeella.Yaqueelprocedimientoparaobtenerlascuentasactivas del cliente se habia implementado en la accin checkBalance, se define el mtodo privado _getActiveAcounts() para hacer reusable el procedimiento mencionado y usarlo en showTransactionActivity.Elcontroladorquedaentoncesas:
<?php class BankingController extends ApplicationController { protected function initialize(){ $this->setTemplateAfter("menu"); }

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

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 formulariodondeelusuarioseleccionalascuentasyunbotndeVerextractos:


<?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"); } ?>

Ladescripcindelavistaanterioreslasiguiente: Secontrolaquehayacuentasactivascontandolosregistrosdevueltosypresentando unmensajeinformativoensudefecto. ElhelperTag::form(string$action)permitelacreacindeunaetiquetadeformulario

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

60

cuyaaccines/banking/getSelectedActivity. Serecorrenlascuentasactivasyporcadaunasegeneraunafilaconuncheckboxque pordefectoestaseleccionado. ElhelperTag::submitButton(string$caption)permitecrearelbotndeConsultar,al hacerclickenlseenviarlainformacinalaaccinmencionada. Lacolumnadelasucursalvisualizaelcdigodeestatalycomoestenlatablalocualnoes muyamigableparaelusuariofinal.Lasasociacionespuedenresolverestoyobtenereldetalle delasucursalporcadacuentaenformanatural.Sedefineunamultiplicidadna1enelmodelo Accountas:


<?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"); } }

ElhelperTag::endForm()cierraelformulario.

De esta forma se puede reemplazar la lnea de la vista showTransactionActivity.phtml en dondeseimprimeelcodigodelasucursalpor:


<td align='center'>{$account->getSucursal()->getName()}</td>

Alenviarlosdatosdelformularioalaaccinbanking/getSelectedActivity,serecibelascuentas seleccionadasyconsultalosmovimientosasociadosaestas:
<?php class BankingController extends ApplicationController { protected function initialize(){

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

61

} 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); } }

$this->setTemplateAfter("menu");

Laexplicacindelprocedimientoeslasiguiente: Seobtienenlascuentasseleccionadasdelformulariomediante$selectedAccountsIds= $this>getPostParam("cuenta"); Enlasiguientelineasevalidaqueelvalorobtenidoseaunvectorconlascuentas Luegosevalidaquecadaunadelascuentasqueesenviadasearealmentedelcliente activoenlasesinyquelacuentaestactiva. Despusdefiltrarlascuentasseconsultaelmovimientoasociadoaestas,seenvialos resultadosalavistadondeenunatablapaginadasepresentanlosregistros.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

62

CreacindeAplicaciones

7 Aplicaciones en Kumbia Enterprise


7.1 Introduccin
Unaaplicacinwebesunaextensindinmicadeunsitiowebunservidordeaplicaciones. Existes2tiposdeaplicacionesweb: OrientadasalaPresentacin:Sonaplicacionesquegeneranpginaswebdinmicas usando diferentes lenguajes de marcas (HTML, XML, etc) y tecnologas como (CSS, JavaScript, etc) generando contenidos de respuesta de acuerdo a las peticiones recibidas. Kumbia Enterprise Framework (KEF) proporciona un completo y robusto entorno para el desarrollo, testeo, implementacin y puesta en produccin de ambos tipos de aplicaciones webusandotecnologaPHP. Orientadas a Servicios: Implementan endpoints para servicios web. Aplicaciones orientadasalapresentacinsuelenserclientesdelasorientadasaservicios.

7.2 Instancias del framework


Unainstanciadelframeworkhacereferenciaaunadistribucindelframeworkqueresideen un servidor web. Las instancias pueden contener una ms aplicaciones compartiendo una mismaversindelframeworkyunmismodirectoriopblico. Lasinstanciaspuedenversetambincomoapplicationcontainersmanteniendolamemoriay recursosdelasaplicacionesenformaseparadaperoproporcionandounentornointegradode operacin.

7.3 Estructura de directorios de una Instancia


LaestructuradearchivosdeunainstanciadeKumbiaEnterpriseFrameworktienelosiguiente: Listado:Estructuradedirectoriospredeterminada
apps/ default/ controllers/

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

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

Ladescripcindecadadirectorioeslasiguiente: Tabla:Descripcindedirectoriosdelframework Directorio apps Descripcin El directorio apps contiene todas las aplicaciones que usen la misma versindelframework Es la aplicacin por defecto, el FrontController para esta aplicacin default permiteaccederdirectamentealoscontroladoressinindicarelnombre delaaplicacin. controllers application.php Eseldirectorioenelquesedebenubicartodoscontroladores. Contiene la clase ControllerBase de la cual heredan todos los controladoresyendondetambindefinimoselmtodoinit Contienelosarchivosdeconfiguracinporaplicacinypersonalizadade aplicacin Contienefiltrospersonalizadosporusuario.Esopcionallapresenciade estedirectorio. Contiene componentes personalizados por aplicacin. Es opcional la presenciadeestedirectorio. Aqu se deben ubicar todos los modelos de la aplicacin, Kumbia models EnterpriseFrameworkpermiteorganizarlgicamenteendirectorioslos gruposdemodelos.

config

filters

library

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

64

views

Permite crear la presentacin de aplicaciones mediante el componente View. Es posible crear plugins que aumenten la funcionalidad de la implementacinMVC. PermitencrearvalidadoresparaActiveRecordqueseayudenavalidarla lgicadedatos. Contienelaconfiguracingeneraldelframework Contienelosmensajeslocalizadosdelframework. Contienealframeworkcomotalylibrerasdeterceros Hace el papel de DocumentRoot (raz de documentos) de la aplicacin,

plugins

validators config languages Library

public

todo los archivos debajo de este directorio pueden ser accedidos pblicamente. En sus subdirectorios se encuentra todo el contenido estticocomoimgenes,javascript,cssyarchivosdescargables.

scripts test

Contienescriptsqueautomatizantareasenelframeworkyreducenla codificacinmanual. Contienentestdeunidaddelosframework.

La estructura de directorios esta pensada buscando convencin sobre configuracin, as el desarrolloproducidoesmsmantenibleysehacemseficienteeldesarrollocuandotodose encuentraensulugar.

7.4 Publicar contenido esttico


Eldirectoriopublicenlaestructuradearchivosestdestinadoapublicarcontenidoesttico que es visible pblicamente. Cualquier archivo ubicado en este directorio en un subdirectoriopuedeseraccedidoporlosclientesdelaaplicacin. Conelfindeestablecerubicacionesquehaganmsmantenibleslasaplicacionesseincluyen pordefectolossiguientessubdirectorios: Tabla:Directoriosdepublicacindecontenidoesttico Subdirectorio Descripcin

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

65

img css javascript temp files

Contiene imgenes predefinidas del framework y su objetivo es colocaraquimagenesaserusadasporlaaplicacin. Contiene archivos de estilos CSS. El archivo style.css contiene las definicionesdeestilosestndaresparatodaslasaplicaciones. Est destinado a almacenar archivos JavaScript. El framework coloca enestedirectoriolosframeworksyfuncionesbsicasJavaScript. Directorioparaarchivostemporales. Directorioparaarchivosadescargar.

Eldesarrolladordebetenerencuentaquecuandouncontenidoenestosdirectoriosnoexiste lapeticinesdireccionadaalaaplicacin.Evitarlaspeticionesaarchivosinexistentesesuna buenaprcticaenmirasamejorarelrendimientodelasaplicaciones.

7.5 Bootstrap
EncualquierestructuraMVCelboostrapcumpleelpapeldetomarlaURLreescritaeinvocar tantoelDispatchercomolosenrutadoresnecesariosparaejecutarlapeticin.Paraentender la forma en la que el Dispatcher busca el controlador en las aplicaciones y ejecuta la accin asociadaesnecesariocomprenderlaformaenlaquedebenformarlasURLsantesdegenerar unapeticin. Paraunaestructuradedirectoriosqueincluye2aplicaciones,laprimeradefaultylasegunda quesellamaproduccinqueilustramosas: Ejemplo:Estructuradedirectoriosparamltiplesaplicaciones
empresa/ apps/ default/ controllers/ clientes_controller.php productos_controller.php config/ models/ views/ produccion/ controllers/ compras_controller.php config/ models/ views/

Unapeticinalcontroladorclientesseraas:

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

66

Ejemplo:AccederalasaplicacionesycontroladoresdesdeunaURL
http://www.ejemplo.com/empresa/clientes/ http://www.ejemplo.com/empresa/clientes/buscar http://www.ejemplo.com/empresa/clientes/consultar/18

Endonde,eldominiodelservidoreswww.ejemplo.com,larutaalframeworkesempresa(en estedirectoriodelDocumentRootestaelframework),elnombredelcontroladoresclientes,la accinenlaterceraURLseraconsultaryelparmetroparaestaaccineselnmero18. Una peticin para la aplicacin de produccin se coloca el nombre de esta despus del directoriodondeestaKumbiaEnterpriseFramework,as: Ejemplo:AccederalaaplicacindeproduccindesdeunaURL
http://www.ejemplo.com/empresa/produccion/compras/ http://www.ejemplo.com/empresa/produccion/verEstado/22

Cada aplicacin dentro de apps contiene una estructura de directorios para controladores, modelosyvistasnica,laformadeaccederacadaaplicacinesindicandosunombreantes delnombredelcontrolador.

7.6 Crear la accin por defecto en una Aplicacin


LaclaseControllerBaseubicadaenapps/default/controllers/application.phppermitedefinirel mtodoinitqueseejecutaencasoquenosedefinauncontroladoraccinpordefecto: Ejemplo:Accinpordefectoenunaaplicacin
<?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 inicializacin de la aplicacin


El mtodo ControllerBase::init es ejecutado si no se especifica un controlador en la URL, en ciertasocasionespuedequenoseatilsiserequiereinicializarextensionesejecutaralgn procesodeinicializacin.ElmtodoControllerBase::onStartApplicationresultamsapropiado, en estos casos. Este mtodo solo ejecuta un procedimiento en cuanto se realiza la primera

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

67

peticinalaaplicacin.Elsiguienteejemploilustramejorelfuncionamientodeestemtodo: Ejemplo:Definirunprocedimientodeinicializacindelaaplicacin
<?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"); } }

Tambinsedebeevitarrealizarcualquiertipodesalidaalexploradoryaqueestemtodoes ejecutadoantesdeinicializarseelcontextodesesin.

7.8 Detectar un cambio en la ejecucin de una instancia a otra


EnlaclaseControllerBasetambinesposibleimplementarelmtodoonChangeInstanceEvent queesejecutadocuandosedetectaqueenlamismasesinsehaejecutadoyaunaaplicacin enotrainstanciadeKumbiaEnterpriseFramework. Ejemplo:Detectarelcambiodeejecucindeunainstanciaaotra
<?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 adaptadoresdesesindiferentes.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

68

Parte1:Lalgicadedominio

8 Componente Controller
8.1 Introduccin
El componente Controller cumple una importante tarea dentro de la arquitectura MVC de Kumbia. El framework proporciona la integracin de este componente con el componente ViewyActiveRecordquerealizaelpapeldelosmodelos. Laintegracindeestoscomponentesproporcionaunaestructuraestableyeficienteparalas aplicaciones orientadas a la Web. Adems de esto, el componente ofrece un sistema de persistenciatransparentealdesarrolladorqueacercalasaplicacionesWebaaplicacionesde escritorio, eliminando la complejidad de administrar el estado y entorno de la lgica de negocios en una sesin. Por medio de plugins es posible extender la funcionalidad de este componente.

8.2 Como funciona el componente Controller?


Kumbia Enterprise Framework ha implementado una estructura jerrquica de clases que permitencreardiferentestiposdeserviciosydesarrollarlalgicadeaplicacinendiferentes nivelesdeflexibilidadpracticidad. El componente Controller posee la siguiente jerarqua de clases e implementacin de servicios: Tabla:JerarquiadeclasesdelcomponenteController Clase Ubicacin Descripcin Es la clase padre de todos los controladores,eldesarrolladorpuede ControllerBase apps/default/controllers/ application.php agregar mtodos que sern heredados por cualquier controlador de la aplicacin. Aqu se puede agregar validacin de seguridad Auditoradesistemas. Controller Library/Kumbia/Controller/C Es el componente Controller en si,

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

69

ontroller/Controller.php

implementa comunes

todos

los

mtodos tipos de

para

los

controladoresdelframework. Library/Kumbia/Controller/A ApplicationController pplication/ Application.php El diseo de este controlador ayuda al programador a interactuar con vistas y modelos de la forma ms directayflexible. Es una implementacin del

componente Controller que funciona como Scallfolding (generador de Library/Kumbia/Controller/St cdigo) dinmico. Busca ayudar al StandardForm andardForm/ StandardForm.php desarrollador a crear capturas de limitada personalizacin pero que realizan las operaciones de creacin, consulta, modificacin, reporte y eliminacindelosdatosdeunatabla. Este tipo de controlador Permite Library/Kumbia/Controller/ WebServiceController WebServiceController/ ApplicationController.php crear Servicios web basados en el estndarSOAP,generardescripciones en WSDL y orquestar el intercambio de datos entre aplicaciones usando estemtodo. Es MultiThreadController pplication/ MultiThreadController.php una subimplementacin que de est

Library/Kumbia/Controller/A ApplicationController

diseada para correr procesos de negocio que requieran seguimiento estilocrosscutting.

El objetivo de cada controlador es bsicamente separar la lgica de la presentacin, el componenteControllerimplementaelpatrnFrontControllerenelcualtodaslaspeticionesa la aplicacin son atendidas inicialmente por l y luego son enrutadas a controladores de usuarioyaccionesqueatiendencadauna.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

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 convencioneseneldirectorioapps/default/controllers/ Al crear un controlador para la administracin de la informacin de clientes se crea un archivo llamado customer_controller.php, en l una clase CustomerController heredando de algunadelasimplementacionesdelcomponenteController. LaaccinpordefectoenelcontroladordebetenervisibilidadpblicayllamarseindexAction as: Ejemplo:Uncontroladorysuaccinpordefecto
<?php class CustomerController extends ApplicationController { public function indexAction(){ $this->renderText("Hola Mundo"); } public function getStatusAction($id){ $this->renderText("Ver el estado del cliente $id"); } }

PararealizarunapeticinalaaplicacinsehacemediantelasiguienteURL: Ejemplo:AccederalcontroladormedianteunaURL
http://www.example.com/company/customer/index http://www.example.com/company/customer/

Yaqueindexeslaaccinpordefectonoesnecesarioindicarla,yaqueesimplcita.Elindicarla producira el mismo resultado. Para acceder a la accin getStatus se hace de la siguiente forma: Ejemplo:AccederaunaaccinpersonalizadadesdeunaURL
http://www.example.com/company/customer/getStatus/190

ElcomponenteControllerestaintegradoconelcomponenteViewqueimplementael patrnTemplateView.Estaintegracinpermitequeencuantoterminalaejecucinde

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

71

la lgica en la accin automticamente se renderiza la presentacin vista correspondientealcontroladoryaccinsolicitados. El funcionamiento del componente Controller se apoya tanto en Dispatcher como en Router para realizar todo el trabajo al atender una peticin a la aplicacin. No es necesario entender el funcionamiento de estos componentes en detalle aunque si se desea extender la funcionalidad de la arquitectura implementada en Kumbia EnterpriseFrameworkpuederesultartil Primero la clean URL es fragmentada usando el mtodo Router::rewrite aqu se determina que aplicacin, controlador y accin se requiere ejecutar. El componente Routeresquienrealizalaorquestacindetodoelflujodeejecucin. El componente Dispatcher recibe los parmetros de controlador y accin y busca el indicado en el directorio de controladores para su procesamiento y delegacin a la operacinrequerida. Antes de ejecutar la peticin Dispatcher busca si esta definido el mtodo atributo beforeFilterenlaclasedelcontroladorensujerarquayloejecuta. SielflujodelaejecucinnohasidocambiadomedianteelmtodoController::routeTo entoncesejecutalaaccinsolicitadaenelcontrolador.Laaccintieneaccesoatodoel entornoHTTPeinformacinenviadapormtodosPOST,GET,PUT,etc. Si no cambia el flujo de ejecucin Dispatcher busca si esta definido el mtodo atributoafterFilterenlaclasecontroladoraensujerarquadeclasesyloejecuta. Elprocesodeenrutamientoescclicoyterminasolocuandosedejanoseinvocael mtodoController::routeTo. El patrn FrontController junto con ModelViewController funciona como el corazn el framework e integra los componentes Controller, Router, Dispatcher y Core para hacerlo funcionar.Cuandorequerimosdeentendermodificarlaejecucindelflujodeaplicacinnos remitimosalosserviciosqueestoscomponentesproporcionan. ElCompontenteViewtomaelcontrolyrecibelogeneradoporControlleryvisualizala presentacinparaste,encasodequeexista.

8.4 Servicios del Componente Router


voidRouter::rewrite(string$url) Toma la clean URL y fragmenta cada componente localizando la aplicacin, controlador y accin solicitados, este mtodo es llamado automticamente en el bootstrap del framework

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

72

ubicadoenpublic/index.php.cedula voidRouter::ifRouted() Antesdelaejecucindecualquieraccinbuscaenlatabladeenrutamientoestticogenerada apartirdeconfig/routes.inisisedebeenrutaraotracontroladoraccindinmicamente. booleanRouter::getRouted() Estemtododevuelveelestadodelrouterqueindicasiesnecesariohacerunaenrutacin continuarconelflujonormaldelaaplicacin. stringRouter::getApplication() Devuelveelnombredelaaplicacinquefuesolicitadaenlapeticin. stringRouter::getModule() Devuelveelnombredelmduloquefuesolicitadoenlapeticin. stringRouter::getController() Devuelve el nombre del controlador que fue solicitado en la peticin. Esta informacin adicionalmente se puede obtener usando el mtodo en el controlador llamado getControllerName(). stringRouter::getAction() Devuelve el nombre de la accin que fue solicitada en la peticin. Esta informacin adicionalmente se puede obtener usando el mtodo en el controlador llamado getActionName(). stringRouter::getId() DevuelveelprimerparmetroenviadoporURLenlapeticin. arrayRouter::getParameters() DevuelveenunarraylosparmetrosenviadosporURLenlapeticin,estosigualmenteseles hacebindingalaaccincomoparmetrosdelmtodoejecutadodelaclasecontroladora. arrayRouter::getAllParameters()

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

73

DevuelveunarraycontodoslosfragmentosdelaURLsolicitadaenlapeticin. arrayRouter::routeTo(mixed$params) Permitecambiarelflujodeejecucindelaaplicacintransfirindoseloaotrocontroladory/o accin. arrayRouter::routeToURI(string$uri) Permitecambiarelflujodeejecucindelaaplicacintransfirindoseloaotrocontroladory/o accinmedianteunUniformResourceIdentifier. stringRouter::getActiveApplication() Devuelve el nombre de la aplicacin actual. Cuando es la aplicacin por defecto devuelve la palabradefault. voidRouter::setApplication(string$name) Permiteestablecerdinmicamenteelnombredelaaplicacinactual. voidRouter::setDefaultActionName(string$actionName) Permiteestablecerelnombredelaaccinpordefectoentodosloscontroladores. stringRouter::getDefaultActionName() Devuelveelnombredelaaccinpordefectoentodosloscontroladores. intRouter::getRoutingType() Devuelve el tipo de enrutamiento producido de acuerdo al origen de la peticin. El valor devueltoeslaconstanteRouter::ROUTING_NORMALRouter::ROUTING_OTHER.

8.5 Servicios proporcionados por Dispatcher


voidDispatcher::setControllersDir(string$directory) Permite establecer el directorio de controladores usado para hacer el lookup de un controladorcuandoserealizaunapeticin. ControllerDispatcher::getControllerInstance() Devuelveelobjetocontroladorinstanciadoqueseestejecutando.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

74

intDispatcher:.getDispatchStatus() Devuelveelestadoactualdelflujodeejecucin.Puedeseralgunadelasconstantesdelaclase Dispatcher:


STATUS_UNINITIALIZED:Indicaquenosehainiciadoelprocesodeejecucin STATUS_DISPATCHING: Indica que se esta localizando el controlador y su accin solicitada STATUS_RUNNING_BEFORE_FILTERS: Indica que se estn localizando los mtodos y atributosbeforeFilteryseestnejecutando. STATUS_RUNNING_AFTER_FILTERS: Indica que se estn localizando los mtodos y atributosafterFilteryseestnejecutando. STATUS_RENDER_PRESENTATION: Indica que el control de la aplicacin fue transferidoalcomponenteView. STATUS_RUNNING_BEFORE_STORE_PERSISTENCE: Indica que se va a realizar el procedimientodealmacenamientodelosdatospersistentesdelcontrolador. STATUS_RUNNING_AFTER_STORE_PERSISTENCE: Indica que se ha realizado el procedimientodealmacenamientodelosdatospersistentesdelcontrolador. STATUS_RUNNING_CONTROLLER_ACTION:Indicaqueelcontroldeejecucinlotiene elcontroladorcomotalysuaccinsolicitada.

booleanDispatcher::isRunningController() Indicasielcontroldeejecucinestaaniveldelcontroladorynodelframework. booleanDispatcher::isRunningUserLevel() Indicasilaejecucinestaaniveldelalgicadeldesarrolladorynodelframework. mixedDispatcher::getValueReturned() Devuelveelvalorqueretornlaltimaaccinejecutadaenlapeticin.

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 mtodo onException ya sea en el controlador en ControllerBase. Las excepciones ocurridas en Dispatcher lanzan una excepcin de clase

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

75

DispatcherExceptionenlassiguientescircunstancias: Tabla:CdigosydescripcindeexcepcionesgeneradasenDispatcher Cdigo Dispatcher::NOT_FOUND_ACTION Descripcin Se genera cuando no existe un mtodo conelnombredelaaccinindicadoen la clase controladora y adems no existelaaccinnotFoundAction. Dispatcher::NOT_FOUND_CONTROLLER Se genera cuando no se encuentra el controlador solicitado pero si existe el archivocorrecto. Dispatcher::NOT_FOUND_FILE_CONTROLLER Ocurre cuando no existe el archivo del controlador y por ende la clase del mismoalsolicitarlapeticinaeste. Dispatcher::NOT_FOUND_INIT_ACTION Ocurre cuando se esta tratando de ejecutar el mtodo init en ControllerBase pero este no se ha definidosuvisibilidadnoespblica. Dispacher::INVALID_METHOD_CALLBACK Se genera cuando se trata de invocar externamenteelconstructordelaclase controladora un mtodo protegido privado. Dispatcher::INVALID_ACTION_VALUE_PARAMETER Segeneracuandonosehaenviadopor la URL al redireccionar a una determinada accin se ha omitido el valor para un parmetro de una accin enelcontroladorsolicitado. Comosehamencionadoanteriormenteesposibledefinirunmtodoqueactecomounacapa previa al lanzamiento de la excepcin al usuario llamada onException. Esta recibe el objeto instanciado de la excepcin generada, este mtodo recibe adems cualquier excepcin independientedesigeneraenDispatcherdentrodelmismocontrolador: Ejemplo:Definirunmtodoqueadministrelasexcepcionesencontroladores

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

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 pgina no existe); } } else { //Se relanza la excepcin throw $e; } } }

Nota: Una excepcin que se presenta frecuentemente es la INVALID_ACTION_VALUE_PARAMETER, que se genera cuando se omite en la URL un parmetro del mtodo de la accin que no es opcional que tiene un valor por defecto. KumbiaEnterpriseFrameworkesestrictoenestesentidoygenerarunaexcepcincuandose omita un valor aunque PHP en s generara solo una advertencia. La forma ms prctica de evitar esto es asignar valores predeterminados a cada parmetro del mtodo haciendo la lgicadeaplicacinmsconsistenteevitandomensajesenlapantalladelcliente(explorador, consola,etc).Estetipodeexcepcionestambinsegeneranalrealizarelenrutamientoyomitir elvalordealgnparmetro.

8.7 Peticiones HTTP a Controladores


CuandoserealizaunapeticinauncontroladormedianteprotocoloHTTPesposiblecrearel objetodepeticinControllerRequestyademsutilizarmtodosqueayudanainteractuarcon losdatosenviadosaestoscomoporejemplocuandoseusanformulariosHTML. La instancia de ControllerRequest se puede obtener en el controlador usando el mtodo Controller::getRequestInstance(),elobjetoobtenidoencapsulatodalainformacinenviadaen lapeticinHTTPylainformacindesuentornoparaserutilizadadentrodelcontrolador: Ejemplo:ObteneruninstanciadelaclaseControllerRequest
<?php class CustomerController extends ApplicationController { public function indexAction(){ $request = $this->getRequestInstance();

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

77

POST); } } /** * Devuelve el nombre del cliente usando JSON solo si la peticin * 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))); } } }

if($request->isPost()==true){ Flash::notice(La peticin se ha realizado por mtodo http

Losvaloresdelasvariablessuperglobales$_GET,$_POST,$_COOKIE,$_REQUEST,$_SERVERY $_ENVpuedenseraccesadosusandolosmtodosdeControllerRequestusandogetParamGet, getParamPost,getParamCookie,getParamServerygetParamEnv.Deigualformapuedeutilizar los mtodos del controlador getQueryParam, getPostParam, getRequestParam, getCookieParam, getServerParam y getEnvParam para obtener estos valores sin obtener la instanciadelaclaseControllerRequestaunqueestosehagaimplcitamente. 8.7.1 Administrararchivosadjuntosenunapeticin

Los archivos adjuntos en una peticin pueden ser administrados usando los mtodos de ControllerRequestllamadoshasFiles,getParamFileygetUploadedFiles. Ejemplo:Tratamientodearchivosenviadosenunapeticin
<?php class Movement extends ApplicationController { public function loadMovementAction(){ if($this->getRequestInstance()->hasFiles()==true){ foreach($this->getRequestInstance()->getUploadedFiles() as $file){ >getFileName(); print "Tamao del archivo: ".$file->getFileSize(); print "MIME del archivo: ".$file->getFileType(); print "Nombre Temporal: ".$file->getTempName(); $file->moveFileTo('movement/'.$file->getFileName()); } } } } print "Nombre original del archivo: ".$file-

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

78

8.7.2

APIdeControllerRequest

Adicional a los mtodos mencionados anteriormente la referencia del API de ControllerRequestademstiene: voidsetParamRequest(string$index,mixed$value) Cambia un valor enviado en una peticin en la superglobal $_REQUEST. Este mtodo automticamenteactualiza$_POSTy$_GETsiesnecesario. voidsetParamGet(string$index,mixed$value) Cambiaunvalorenviadoenunapeticinenlasuperglobal$_GET. voidsetParamPost(string$index,mixed$value) Cambiaunvalorenviadoenunapeticinenlasuperglobal$_POST. voidsetParamCookie(string$index,mixed$value) Cambiaunvalorenviadoenunapeticinenlasuperglobal$_COOKIE. booleanisSetRequestParam($index) Indicasiexisteunallaveparaunvalorenlasuperglobal$_REQUEST. booleanisSetQueryParam($index) Indicasiexisteunallaveparaunvalorenlasuperglobal$_GET. booleanisSetPostParam($index) Indicasiexisteunallaveparaunvalorenlasuperglobal$_POST. booleanisSetCookieParam($index) Indicasiexisteunallaveparaunvalorenlasuperglobal$_COOKIE. booleanisSetServerParam($index) Indicasiexisteunallaveparaunvalorenlasuperglobal$_SERVER. booleanisSetEnvParam($index) Indicasiexisteunallaveparaunvalorenlasuperglobal$_ENV.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

79

booleanisSetRequestParam($index) Elimina un valor en la superglobal $_REQUEST. Implicitamente elimina el valor de $_GET y $_POST. booleanisSetQueryParam($index) Eliminaunvalorenlasuperglobal$_GET. booleanisSetPostParam($index) Eliminaunvalorenlasuperglobal$_POST. booleanisAjax() IndicasilapeticinhasidorealizadausandoAJAX.Funcionacuandoseutilizaelframework JavascriptPrototype. booleanisFlashRequested() IndicasilapeticinhasidorealizadadesdeunobjetoMacromediaFlashincrustadoenunsitio Web. booleanisSoapRequested() Indica si la peticin ha sido realizada desde un cliente SOAP. Al solicitarsen este tipo de peticionesalaaplicacineladministradordepresentacinyenrutamientosecambianpara crearunacomunicacinmachinetomachine. booleanisSecure() IndicasilapeticinserealizabajounaconexinencriptadausandoHTTPS. stringgetRawBody() DevuelveelcuerpodelapeticinHTTPdirectamente. stringgetHeader(string$name) DevuelveunencabezadoHTTPapartirdesunombre.FuncionaanteponiendoelsufijoHTTP_ sinl.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

80

stringgetScheme() Devuelveelscheme(protocolo)utilizadopararealizarlapeticinHTTP.Devuelvehttphttps generalmente. stringgetHttpHost() Devuelveelhostypuertoenelquerealizolapeticin.Generalmenteeslaippblicaprivada delservidordondeestainstaladoelinterpretePHP. stringgetMethod() DevuelveelmtodoHTTPutilizadoparahacerlapeticinPOST,GET,PUT,etc. booleanisGet() DevuelvetruesilapeticinHTTPfuerealizadausandomtodoGET. booleanisPost() DevuelvetruesilapeticinHTTPfuerealizadausandomtodoPOST. booleanisPut() DevuelvetruesilapeticinHTTPfuerealizadausandomtodoPUT.Estilcuandosecrean aplicacionesREST. booleanisOptions() Devuelve true si la peticin HTTP fue realizada usando mtodo OPTIONS. Es til cuando se creanaplicacionesREST. booleanisHead() DevuelvetruesilapeticinHTTPfuerealizadausandomtodoHEAD.Estilcuandosecrean aplicacionesREST. booleanisDelete() Devuelve true si la peticin HTTP fue realizada usando mtodo DELETE. Es til cuando se creanaplicacionesREST. booleanhasFiles()

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

81

IndicasilapeticinincluyearchivossubidosmediantemtodoPOST. arraygetUploadedFiles() ObtieneunvectorconobjetosControllerUploadFilequeencapsulanlainformacindearchivos subidosenlapeticin. stringgetHTTPReferer() ObtieneelHTTPrefererdelapeticin. arraygetAcceptableContent() ObtieneunvectorconlosmimesdeltipodecontenidoaceptadoporelclienteHTTPjuntocon sucalidad.Devuelveunarraycomo: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)) arraygetClientCharsets() DevuelvelalistadeidiomassoportadosporelclienteHTTPjuntoconsucalidad.Devuelveun array como: Array ( [0] => Array ( [accept] => ISO88591 [quality] => 1 ) [1] => Array ( [accept]=>utf8[quality]=>0.7)[2]=>Array([accept]=>*[quality]=>0.7)) stringgetBestQualityCharset() ObtieneelcharsetdemejorcalidadsoportadoporelclienteHTTP.

8.8 Respuestas HTTP de Controladores


LarespuestaquegeneranloscontroladoresenunapeticinHTTPesencapsuladaenelobjeto ControllerResponse el cual funciona como un Gateway entre la vista y el controlador. Este objetoestaimplementadoaligualqueControllerRequestconelpatrnSingleton,esdecirque por cada peticin a la aplicacin solo existir una intancia en todo el contexto de ejecucin. Para obtener la instancia de la clase ControllerResponse se usa el mtodo esttico getInstance(). Ejemplo:UsodelobjetoControllerResponse
<?php class DocumentsController extends ApplicationController { public function indexAction(){

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

82

} }

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

EnelejemploanteriorlaaccinindexvisualizaunarchivoenformatoPDFqueesledoenla presentacin, el mtodo setHeader establece un encabezado HTTP apto para la salida y ademsindicaalaaplicacinquenodebeutilizareladaptadordepresentacinpordefecto (HTML)sinodebeusarpdf. 8.8.1 EstablecereltipodesalidadelaPeticin

El controlador proporciona el mtodo Controller::setResponse que permite establecer el tipo desalidaquesegeneraenlaaccinsolicitada.Lostiposdesalidaqueadmiteestemtodoson lossiguientes: Tabla:TiposderespuestaqueaceptaelobjetoControllerResponse Valor view Descripcin Indicaquesololavistacorrespondientealaaccinsolicitadaserlaquese visualizar. Usualmente aplica cuando se renderizan vistas parciales fragmentosAJAX. ajax json xml rss Losvaloresdelostiposdesalidasoninternamenteconvertidosauntipodesalidasoportado porControllerResponse: Tabla:TiposderespuestaavanzadosdelobjetoControllerResponse Valor RESPONSE_NORMAL establecerla. Descripcin Es la respuesta que se genera normalmente. No es necesario Realizalomismoqueviewperodocumentaelcdigomsclaramente. Permite producir salidas usando notacin JSON (JavaScript Serializable ObjectNotation). ProduceunasalidaXML,agregaelencabezadoContenttype:text/xmlyno muestraningunlayoutasociado. Produce una salida XML agrega el encabezado encabezado Contenttype: application/rss+xmlynomuestraningunlayoutasociado.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

83

RESPONSE_OTHER

Indicaquenosedebeusareladaptadordevisualizacinpordefecto porquesegenerarunasalidaenotroformato.

En el siguiente ejemplo se ilustra como generar una salida usando JSON, la accin countItemsAction implementa una salida primero estableciendo el tipo de salida y despus haciendolasalidadelamisma,engetItemsActionseresumenlosdospasosanterioresenuna solalnea: Ejemplo:ImplementarunasalidaJSONdesdeuncontrolador
<?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 mtodo 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 APIdeControllerResponse

ElAPIdelaclaseControllerResponsees: publicstaticControllerResponsegetInstance() ObtienelainstanciadelobjetoControllerResponse. publicvoidsetHeader(string$header,boolean$replace=true) PermiteestablecerunencabezadoHTTPenlapeticinactual.Elparmetro$replaceindicasi elencabezadodebereemplazarunodelmismotipoestablecidoanteriormente. publicarraygetHeaders(boolean$process=true)

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

84

Obtiene un array con los encabezados HTTP que van a ser enviados en la respuesta de la peticin. Si el parmetro $process es true devolvera un array asociativo cuyas claves correspondenalosnombresdelosencabezados. publicbooleanhasHeader(string$headerName) Indicasiyasehadefinidounencabezadoparaserenviadoenlarespuestaalapeticin. publicvoidsetResponseType(int$type) Permite establecer el tipo de respuesta que debe generar la peticin. El parmetro $type recibe publicintegergetResponseType() Obtieneeltipoderespuestaquevaagenerarelcontrolador.Devuelveelvalordecualquiera delas3constantesmencionadasanteriormente. publicintegersetResponseAdapter(string$adapter) Establece el nombre del adaptador utilizado para procesar la salida de la peticin. Los posiblesvalorespara$adaptersonjson,pdfyxml.EnlareferenciadelcomponenteViewse explicacomoutilizarotrosadaptadores. publicfunctiongetResponseAdapter() Devuelveeladaptadorusadoparagenerarlasalida. publicfunctionsetContentType($contentType) EstableceelencabezadoContentTypedelarespuestadelcontrolador. los valores de las constantes ControllerResponse::RESPONSE_NORMAL y ControllerResponse::RESPONSE_OTHER.

8.9 Controlar acciones no encontradas


Cuandoserealizaunapeticinauncontroladorylaaccinsolicitadanoestaimplementadase genera una excepcin que cuando no es controlada presenta informacin de la excepcin al usuariodelaaplicacin.Lainformacindeexcepcionespresentainformacintcnicaqueen manosequivocadaspuedepermitirfacilitarelataquealaaplicacin. EldesarrolladorpuedeimplementarlaaccinnotFoundActionyaseaenelcontroladorenla

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

85

jerarqua de clases lo cul permitir presentar al usuario un mensaje personalizado y probablementealmacenarunlogdelasituacinocurrida. Ejemplo: Definir una accin que administre las peticiones a controladotes y acciones quenoestendefinidas
<?php class ReportsController extends ApplicationController { public function notFoundAction($actionName=){ $logger = new Logger(File, notFoundReports.txt); $logger->log(No se encontr la accin $actionName); } }

8.10 Filtros en controladores


Cada accin ejecutada en cualquier controlador de la aplicacin ejecuta, si estn presentes filtros antes y despus de la ejecucin del mtodo solicitado. Los filtros permiten ejecutar tareasdeautenticacin,politicasdeseguridad,validacinyenrutamiento,ademsdeacceder porcompletoalentornoHTTPymodificarlarespuestadelapeticin. Losdostiposdefiltrosson:beforeFilterqueesejecutadoantesdeejecutarlaaccinsolicitada comotalyafterFilterqueseejecutainmediatamentedespus. Los filtros son mtodos que se implementan directamente como mtodos 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 todaslaspeticionesalaaplicacin. Ejemplo:Definirfiltrosanivelgeneralenlaaplicacin
<?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/KumbiaEnterpriseFrameworkManualdeReferencia

86

Se debe devolver false desde beforeFilter cuando se realiza un enrutamiento a otro controladordiferentealactivo. Cuando se implementan mltiples filtros es necesario invocar el filtro padre en el momento indicado: Ejemplo:Definicindemltiplesfiltros
<?php class CustomerController extends ApplicationController { public function beforeFilter(){ /** * Algn cdigo de filtro */ parent::beforeFilter(); } }

8.11 Enrutamiento en controladores


El componente Router ofrece servicios que permiten al desarrollador alterar el flujo de ejecucincomoseanecesario,yaseareescribiendoURLs,redireccionandomedianteHTTP haciendo enrutamientos a nivel de controlador. El proceso de enrutamiento se requiere en una aplicacin cuando es necesario llevar al usuario a un controlador y accin sin que sea solicitadopropiamenteporelmismo. 8.11.1 Ciclodeenrutamiento Porcadapeticinqueserealizaalaaplicacinseiniciaunciclodeenrutamientoquepermite ejecutar todas las acciones requeridas en los controladores segn la lgica de negocio. Este cicloejecutacadaaccinenrutadacomosisetrataradeunapeticinnormaldeusuario. Elpsudocdigodelciclodeenrutamientoeselsiguiente: Pseudocdigo:Flujoyordendeejecucindeeventosenciclodeenrutamiento
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/KumbiaEnterpriseFrameworkManualdeReferencia

87

ContinuarMientras InvocarEventoDeControlador(afterDispatchLoop) CapturarExcepcin InvocarEventoDeControlador(onExceptions) FinIntentar

Cuando termina el ciclo de enrutamiento se transfiere el control de la aplicacin a la presentacin(vista),endondeelcompontenteViewrealizaestetrabajo. 8.11.2 EnrutarusandoRouter::routeTo El Componente Router ofrece el mtodo esttico routeTo que realiza las tareas de enrutamiento y valida si existen rutas estticas predefinidas con la prioridad del caso. Es posibleutilizarparmetrosconnombreparaindicarlarutarequeridadondesedeseaenrutar. ElmtodorouteTodeControlleresunproxyalmtodoestticomencionado. Enelsiguienteejemploseilustralavalidacindeunusuarioysuenrutamientodeacuerdoa silaautenticacinesexitosafalla: Ejemplo:Validacindeusuarioyenrutamientocondicional
<?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 mtodo routeTo, gracias a los parmetros por nombre, puede recibir la ruta de enrutamiento en cualquier orden, usando las claves: controller, action e id. Si es necesario pasarmsparmetrosadicionalespuedeusarllavesnumricasquecoincidanconelordenen quelaaccinrecibelosparmetrosrequeridos:
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 ejecucin de todo el mtodo de la accin, es posible utilizar return para salir del mtodo

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

88

anticipadamente. 8.11.3 EnrutarusandoRouter::routeToURI() TambinesposiblehacerenrutamientosusandounUniformResourceIndentifiercomoloes unacleanURLdentrodelamismalgicadeaplicacin.Paraestoserecurrealmtodoesttico Router::routeToURI que realiza el papel del mod_rewrite fragmentando la URL y convirtindola en los valores internos necesario para hacer el enrutamiento. El siguiente ejemploilustralareescrituradeunafechapasadaporlaURLestiloBlogger: Ejemplo:ReescrituradeURLmedianteRouter::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 lgica aqui } }

8.12 Inicializacin de Controladores


DebidoaqueelcomponenteControllerproporcionaunentornodeestadodepersistencia,los objetosinstanciadosdelasclasescontroladorasnosondestruidosalterminarlasesinyson persistidosdurantetodalasesindeusuario.Segnloanteriorlosconstructoresdelasclases controladorasnosonconfiablesparainicializarlascondicionesdeejecucincadavezquese genera una peticin a los mismos. Por esta razn se proporciona la posibilidad de definir el mtodo protegido initialize con el fin de inicializar el objeto desde la persistencia en cada peticinalcontrolador. Ejemplo:Inicializaruncontroladormedianteinitialize()
<?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/KumbiaEnterpriseFrameworkManualdeReferencia

89

} 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") )); } }

$usuario->find($this->getRequestParam("fl_id", "int")); $this->Usuarios->clave = $usuario->clave;

Estemtodoesinvocadotantoenelconstructordelcontroladorcomoenelevento__wakeup queocurrealdeserializarelobjetodesdelapersistenciadesesin.

8.13 Estado de persistencia de Controladores


ComosemencionoanteriormenteKumbiaEnterpriseFrameworkimplementapersistenciadel estadodeloscontroladoresbuscandoaproximareldesarrolloWebauncomportamientode aplicacin de escritorio. Para activar/desactivar la persistencia es necesario invocar el mtodosetPersistance(bool$persitence),enelmtodoinicializadorelcontrolador. Gracias a la implementacin del patrn 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 porloqueelestadodesesindelcontroladorsemantieneintactocomolaprimeravezquese invocunmtododelamisma. Al activar la persistencia el valor del atributo name se mantiene entre peticiones al controlador: Ejemplo:Implementarpersistenciaenelcontrolador
<?php class ProductsController extends ApplicationController { public $name; public function indexAction(){

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

90

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

$this->name = TV 22;

8.13.1 VentajasdelEstadodePersistencia Elestadodepersistenciacontextodeconversacinpermiteque: Implementaratributosmodularesenloscontroladoresdetalformaquesehagaunusoms intuitivodelosdatosdesesin. Implementarinterfacesycomponentesquerecuerdenelestadoqueselediolaltimavez queseaccediaellos. Crearconversacionesconelusuariodelaaplicacindetalformaquecontextualmentecada mdulo mantenga un flujo de trabajo proceso como parte de su naturaleza de negocio misma. 8.13.2 ConsideracionesdelestadodePersistencia Elestadodepersistenciaestapensandoendarlaposibilidaddemantenerlosvaloresdelos atributos de los controladores con el fin de establecer un contexto de conversacin entre el clienteylaaplicacin. Los controladores en un estado persistente almacenan los datos en el administrador de sesiones,sielvolumendedatosalmacenadoeselevadoelrendimientodelaaplicacinpodra disminuir.Instanciasdeentidadesyotrosobjetoscomplejosquehaganpartedelosdatosde 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 diversosbackends. En el captulo de optimizacin y rendimiento se presenta el componente GarbageCollector quepermitedeformacontroladacomprimiry/oeliminardatosdeestadodepersistenciaque seanutilizadosporlaaplicacin.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

91

8.13.3 TransaccionesyConcurrenciadelEstadodePersistencia Loscontroladoresconestadodepersistenciaactivogeneranunatransaccindelosatributos de al iniciar la ejecucin de cualquier accin en el. Mientras se ejecuta la peticin en el controlador la transaccin permanece en un nivel de isolacin en el cul no realiza ningn bloqueosobrelosdatosdesesin.Sepuedeentenderqueserealizantransaccionesatmicas conestosdatospersistentes.Peticionesconunaltogradodeconcurrenciaenlamismasesin deusuarioyalmismocontroladorpodrangenerarinconsistencias. Cuando se genera una excepcin no controlada la transaccin realiza un rollback haciendo que los atributos del controlador permanezcan intactos a su estado en la ltima peticin exitosa. 8.13.4 EventosdelestadodePersistencia Un controlador con el contexto de persistencia activado puede implementar eventos que permitanmodificarlaestadoinicialalrestaurarelobjetodesuestadodormidoytambin cualsersuestadofinalantesdeseralmacenadodormir: Tabla:TiposderespuestaqueaceptaelobjetoControllerResponse Evento Descripcin enlapersistencia.Estosoloocurrecuandoserealizaunapeticinal controlador. beforeStorePersistence Segeneracuandoelobjetocontroladorseestapreparandoparaira lapersistencia. EnelsiguienteejemploseimplementaeleventobeforeStorePersitenceparaevitarqueundato degrantamaonorelevantesellevealapersistencia: Ejemplo:Implementaruneventodelestadodepersistencia
<?php class ProductsController extends ApplicationController { public $name; public $veryLongData; public function indexAction(){ $this->name = TV 22; } public function showProductAction(){

afterRestorePersistence Segeneracuandodespiertaelcontroladordesuestadodormido

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

92

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

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

8.14 La Clase ControllerBase


Estaclaseeslapadredetodosloscontroladores,elconceptodeestaclaseestainspiradoenel patrn ApplicationController (no esta relacionado con la clase del mismo nombre), que es una extensin al MVC permitiendo que parte de la lgica de negocio sea compartida por un clasedelacualheredanlasdems.Estaclaseademssirvedepuntodeinterseccinypermite ajustarelflujodeejecucindeacuerdoalcontextoenelqueseinvoque. Eldesarrolladorpuedeimplementarmtodosquesernheredadosporcualquiercontrolador delaaplicacin.Esimportanteprotegerlavisibilidaddelalgicacompartidaenestaclasede talformaquesoloseautilizadainternamenteporloscontroladores.

8.15 La Clase Controller


La clase Controller implementa funcionalidad compartida a todas las implementaciones de controladores.Estaclaseactacomoelcorazndelacapadelgicadedominio. 8.15.1 APIdeController Controllerimplementaprincipalmentemtodosproxyaotroscomponentesfacilitandosuuso inmediatoenunprocesodenegocio. functionvoidrouteTo() Estemtodoesimplementadoporconvenienciaaldesarrolladoryrealizaunproxyalmtodo Route::routeTo. functionvoidrouteToURI() Estemtodoesimplementadoporconvenienciaaldesarrolladoryrealizaunproxyalmtodo Route::routeToURI. functionmixedgetPostParam(string$paramName)

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

93

Estemtodoesimplementadoporconvenienciaaldesarrolladoryrealizaunproxyalmtodo ControllerRequest::getParamPost. functionmixedgetQueryParam(string$paramName) Estemtodoesimplementadoporconvenienciaaldesarrolladoryrealizaunproxyalmtodo ControllerRequest::getParamQuery. functionmixedgetRequestParam(string$paramName) Estemtodoesimplementadoporconvenienciaaldesarrolladoryrealizaunproxyalmtodo ControllerRequest::getParamRequest. functionmixedgetServer(string$paramName) Estemtodoesimplementadoporconvenienciaaldesarrolladoryrealizaunproxyalmtodo ControllerRequest::getParamServer. functionmixedgetEnvironment(string$paramName) Estemtodoesimplementadoporconvenienciaaldesarrolladoryrealizaunproxyalmtodo ControllerRequest::getParamEnvironment. functionmixedfilter(string$paramValue) Este mtodo es implementado por conveniencia al desarrollador y permite aplicar un filtro usandoelcomponenteFilter. functionvoidsetRequestParam(mixed$index,mixed$value) Estemtodoesimplementadoporconvenienciaaldesarrolladoryrealizaunproxyalmtodo ControllerRequest::setParamRequest. functionvoidsetPostParam(mixed$index,mixed$value) Estemtodoesimplementadoporconvenienciaaldesarrolladoryrealizaunproxyalmtodo ControllerRequest::setParamPost. functionvoidsetQueryParam(mixed$index,mixed$value) Estemtodoesimplementadoporconvenienciaaldesarrolladoryrealizaunproxyalmtodo ControllerRequest::setParamQuery.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

94

functionvoidsetCookie(mixed$index,mixed$value) Estemtodoesimplementadoporconvenienciaaldesarrolladoryrealizaunproxyalmtodo ControllerRequest::setParamCookie. functionvoidsetPersistance(boolean$persistance) Estableceelestadoconversacionaldelcontrolador.Cuando$persistanceestrueelestadodel controlador, (los valores de sus atributos) se mantienen entre una peticin y otra a la aplicacin. functionbooleangetPersistance() Devuelveunvalorbooleanoqueindicasielestadoconversacionaldelcontroladorestactivo no. functionvoidredirect(string$uri) PermiterealizarunaredireccinHTTPaunadeterminadaURIdentrodelaaplicacinactual. functionvoidsetResponse(string$type) Establece el tipo de respuesta que debe generar la peticin. Consulte la referencia de ControllerResponseparaobtenermsinformacinsobreelusodeestemtodo. functionvoidexceptions(Exception$exception) Al reescribir este mtodo es possible administrar las excepciones producidas en el controlador. functionstringjsonEncode(mixed$data) Codificaunavariable$datausandonotacinJSONparaluegoserenviadaalcliente. functionvoidoutputJSONResponse(mixed$data) Codificaunavariable$datausandonotacinJSONylaenviadirectamentealcliente. functionstringgetControllerName() Obtieneelnombredelcontroladoractualmenteenejecucin.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

95

functionstringgetActionName() Obtieneelnombredelaaccinactualmenteenejecucin functionvoidgetId() ObtieneelvalordelprimerparmetroadicionalpasadoporlaURLdespusdelnombredela accin. functionvoidgetViewHandler() Alreescribirestemtodoesposibletransferirelcontroldelapresentacinauncomponente deusuariosegnsearequeridoporlaaplicacin. functionarraygetViewExceptionHandler() Alreescribirestemtodoesposibletransferirelcontroldelapresentacinauncomponente deusuariosegnsearequeridoporlaaplicacincuandohallaunaexcepcinsincapturar. functionvoidsetTemplateBefore(string|array$template) Permitedefinirunomaslayoutsquesedebenincluirenlajerarquaderenderizacindela presentacin.Este/estoslayout(s)sonvisualizadosantesdellayoutdelcontrolador.Consulte lareferenciadelcomponenteViewparaobtenermsinformacinsobreelusodeestemtodo. functionvoidcleanTemplateBefore() Resetealalistadelayoutsdefinidosavisualizarantesdellayoutdelcontrolador. functionvoidsetTemplateAfter(string|array$template) Permitedefinirunomaslayoutsquesedebenincluirenlajerarquaderenderizacindela presentacin.Este/estoslayout(s)sonvisualizadosantesdellayoutdelcontrolador.Consulte lareferenciadelcomponenteViewparaobtenermsinformacinsobreelusodeestemtodo. functionvoidcleanTemplateAfter() Resetealalistadelayoutsdefinidosavisualizardespusdellayoutdelcontrolador. functionstring|arraygetTemplateBefore() Obtiene el los layouts a renderizar antes del layout del controlador definidos hasta el momento.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

96

functionstring|arraygetTemplateAfter() Obtiene el los layouts a renderizar despus del layout del controlador definidos hasta el momento. functionControllerRequestgetRequestInstance() ObtienelainstanciadelobjetoControllerRequestparasuusoenelcontrolador. functionControllerResponsegetResponseInstance() ObtienelainstanciadelobjetoControllerResponseparasuusoenelcontrolador. functionvoidsetParamToView(string$index,string$value) Transfiereunvaloralavista.Elvalor$valuepuedeserutilizadoenlavistapormediodeuna variablelocaldelavistallamada$index. functionWebServiceClientgetService(string$serviceName) Obtiene una instancia de un servicio del contenedor de servicios para ser usada en el controlador.Elservicio$serviceNamepuedetambinserunnombredelNamingDirectory unvalorobtenidodeusandounUDDI.Consulteelcaptulodelcontenedordeserviciospara obtenermsinformacindeestemtodo.

8.16 Controladores usando ApplicationController


LaimplementacindecontroladoresApplicationControllereslaprincipalquedebeserusada cuando se requiere dar respuestas a peticiones solicitadas por los usuarios finales de las aplicaciones. 8.16.1 APIdeApplicationController functionvoidrenderText(string$text) Enviauntextoalapresentacin functionbooleanvalidateRequired(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 obtenermsinformacin.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

97

functionvoidcleanValidationMessages() Resetealosmensajesdevalidacinproducidoshastaelmomento. functionvoidaddValidationMessage(string$message,string$fieldName='') Agregaunmensajealacoladevalidacin.ElSegundoparmetroopcional$fieldNamepermite estableceruncampodelainterfazdeusuarioalqueestrelacionadoelmensaje. functionarraygetValidationMessages() Obtienelosmensajesdevalidacingeneradoshastaelmomentoenlacolademensajes. functionbooleanisExportable() Estemtodopuedeserreescritoydebedevolverunvalorbooleanoindicandosilosatributos publicosdelcontroladordebentransferirsealapresentacincomovariableslocales. 8.16.2 ControladoresusandoMultiThreadController EstetipodecontroladoresunasubimplementacindeApplicationControllercuyoobjetivoes poder implementar procesamiento asimetrico para grandes procesos en controladores. De esta forma es posible ejecutar en forma simultanea tareas de seguimiento y monitorizacin paraprocesosdenegocio. Losprocesosseejecutandeformaasincrnicayenunordenquenopuedeserdenominado seguro por lo tanto son aptos para procesos de debug monitorizacin y no para implementarotrosprocesosdenegociobuscandosuejecucinsimultnea. Enelsiguienteejemplosesimulalaimplementacindeunprocesodenegocioquedebidoala cantidaddedatosquesedebenprocesarpuedetardaruntiempoprolongadoenprocesarse,si el proceso fuese ms grande y complejo hacer un seguimiento y monitorizacin detallado puededegradarprogresivamentelalgicamisma. ElcontroladorcontieneunaaccinllamadahugeProcessquecontieneelprocesoaejecutar,la anotacin @synchronized en el mtodo logProcessState indica que este mtodo debe ser ejecutadosimultneamenteconcualquieraccinejecutadaenelcontrolador:

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

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); } }

Mltiplesmtodosdelcontroladorpuedentenerlaanotacin@synchronizeddetalformaque seanejecutadosdemanerasimltaneaconcualquieraccindelcontrolador.

8.17 Servicios Web usando WebServiceController


8.17.1 QuesunWebService? Segn la definicin de la arquitectura de Servicios Web del W3C, un servicio Web es un sistema de software diseado para soportar interaccin interoperable maquina a maquina sobreunareddecomputacin.CadaservicioWebcontieneunadescripcinqueotramaquina puede procesar (usando WSDL probablemente). Algunos servicios Web pueden interactuar directamenteusandomensajesSOAPapoyndoseenserializacinXMLyelprotocoloHTTPen s. Con Servicios Web es posible dotar a las aplicaciones de interoperatividad estndar permitiendo su comunicacin de forma independiente a su plataforma tecnolgica. Kumbia Enterprise Framework permite al desarrollador implementar controladores como Servicios Webautomatizandolosprocesosdepublicacindelservicio,administracinypersistenciaen formatransparente.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

99

UncontroladorWebServiceControllerfuncionacomounServiceProviderelcualproporciona un contrato de servicio que lo conforman las acciones del mismo y que son expuestas pblicamente como operaciones del mismo de tal forma que clientes externos puedan utilizarlosdemaneracontrolada. Los Service Customers (clientes de servicios) y Services Providers ofrecen funcionalidad concreta para el envo y recepcin de mensajes en una comunicacin maquina a maquina. Esto es transparente para el desarrollador aunque debe ser mencionado de manera informativa. KumbiaEnterpriseFrameworkproporcionacapasdeSoftwarequepermitenimplementarya sea Service Customers Services Providers en aplicaciones desarrolladas con l. De esta forma usted puede preocuparse por desarrollar la lgica de negocio sin preocuparse por la formaenquelosserviciosWebvayanainteractuaramsbajonivel. 8.17.2 ParaquesonnecesarioslosWebServices LasaplicacionesempresarialessepuedenvermuybeneficiadasconelusodeWebServices. Crear contratos de servicio adecuados permite a los desarrolladores extraer en forma abstractaserviciosquepermitanelintercambiodeinformacinconaplicacionesdeterceros, encapsulandodetallescomolaconexinabasesdedatos,credencialesdeseguridad,dominio ycontroldelainformacinentregadabajolascondicionespactadas. Sistemas empresariales ganan nuevos subsistemas de comunicacin estandarizada entre aplicacionesdetalformaquesucomposicinseareutilizableycomponible.Medianteeluso de Web Services se eliminan dependencias del pasado como el traspaso de informacin mediantearchivosplanos,vistasenlasbasesdedatos,conexionesporFTPdirectamentea los RBDMs que carecan de un control adecuado y obligaban a implementaciones rgidas y complicadasademsdeexigirlaintegracindeotroscomponentesensuaplicacin. 8.17.3 ArquitecturaOrientadaaServicios(SOA) Las organizaciones empresariales de hoy en dia requieren interconectar procesos e informacin entre los departamentos de las mismas, sus provedores, clientes y socios

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

100

comerciales extendiendo sus fronteras y aumentando la competitividad y capacidad de crecimiento. LaArquitecturaOrientadaaServiciosproporcionaelementosquepermitenqueunconjunto de aplicaciones distribuidas se convierta en conjunto de recursos que puedan ser utilizados tantointernacomoexternamenteycomoresultadoseobtienemayoragilidadyproductividad enlaorganizacin. KumbiaEnterpriseFrameworkofreceherramientasparalaconstruccindeunaArquitectura Orientada a Servicios, sin embargo, debe ser el arquitecto desarrollador quien debe determinarsiesrealmentenecesarioimplementarestaestrategiadeacuerdoalacomplejidad yobjetivosdelnegocio. Transformar la lgica de negocios empresarial a una arquitectura orientada a servicios incluye implementar contratos de servicio, reusabilidad, abstraccin, loose coupling (acoplamientodbil)ycomposibilidad.SOAesunmodeloarquitectacionalparaplataformas detecnologaycadaempresapuededefinirlosobjetivosasociadosacomputacinorientadaa serviciosusandodiferentestecnologas. UsarWebServicesesprobablementeunodelasmejoresopcionesparaaplicarlosprincipios SOAyempezarausarestaarquitectura. 8.17.4 CrearunWebService Como se mencion anteriormente es posible crear servidores para servicios Web usando la implementacin de Controller llamada WebServiceController. Este tipo de Controlador permite crear servicios web XML y encapsula toda la comunicacin basada en el estndar SOAP. Las comunicaciones soportan las especificaciones SOAP 1.1 y 1.2 as como el uso de descriptoresWSDL. A pesar que los mensajes SOAP son complejos; todos estos detalles son transparentemente implementados en una capa funcional apta al desarrollo rpido y efectivo. Del lado del servidor el desarrollador puede implementar servicios usando lenguaje PHP nativo y la arquitecturayserviciosdelframeworksindemasiadoscambios.Delladodelclienteesposible utilizar servicios Web invocando el nombre de los mtodos/acciones implementados en el

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

101

servicioservidor. Gracias a que se cumple con la especificaciones definidas por el W3C (Word Wide Web Consortium)esposibletenerindependenciadellenguajePHPtantodelladodelclientecomo del servidor. Lo anterior permite acceder a servicios Web creados en otras plataformas y lenguajesyqueestnaccedanaotroscreadosusandoPHP. ElejemploacontinuacinmuestraladefinicindeunservicioWebsimplificadoquepermite chequear la disponibilidad de fechas para realizar una reserva en un sistema ficticio. En el primer mtodo startSession se recibe como parmetros el login y password y usando el componenteAuthseautenticacontraunservidorActiveDirectoryusandoeladaptadorLDAP, siestascredencialessonvalidasentonceselresultadodevueltoesdevueltoyposteriormente permitevalidarqueelusuarioesteautenticado.NotesequeelsegundomtodogetAvalability lanza una excepcin WebServiceControllerException cuando no se cumple una validacin la cualsenotificaalclientedeigualmanera. Los valores escalares devueltos por cada mtodo se transfieren transparentemente entre el servidor y el cliente, datos ms complejos exigen distribuir componente compartidos de tal manera que no haya perdida de informacin entre el Service Provider (servidor) y el Customer(cliente). Ntesequetodoslosmtodosdelaclasequevayanaseraccedidosremotamentedebentener elsufijoAction. Ejemplo:ServiciowebconWebServiceController
<?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->autentcate()){ return true; } else { sleep(2); return false; } } public function getAvalabilityAction($initialDate, $finalDate){

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

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 estndar para acceder al servicio Web Basado en Soap: Ejemplo:AccederaunserviciowebusandoSoapClient
<?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 KumbiaEnterpriseFrameworktambinproporcionalaclaseWebServiceClientqueextiendeel cliente SOAP SoapClient y pretende dar ms facilidades al trabajar con servicios Web con

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

103

servidoresenesteframework.Elprimerparmetrodelconstructorpuedeserlaubicacindel servicio(location)cuyoUniformResourceIdentificador(uri)eshttp://appservices: Ejemplo:CrearunserviciowebconWebServiceClient


$webService = new WebServiceClient('http://web.server.local/w/reservation');

Esposibledefinirlosparmetrosdelclientemedianteunarraydeestaforma: Ejemplo:DefinirparmetrosextraenelserviciowebconWebServiceClient
$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 ));

ElconstructorestablecelossiguientesparmetrospordefectoparaelclienteSoapClient: Tabla:ParmetrosquerecibeelcontructordeWebServiceClient Parmetro wsdl uri encoding compression LaextensinSoapdePHPesrequeridaparausarestecliente. 8.17.6 ObteniendoelWSDLdeunServicioWeb Kumbia Enterprise Framework puede hacer AutoDiscover de servicios Web basados en WebServiceController,encasoquenosedefinaunWSDLmanualmenteparaelservicio.Para generar un descriptor WSDL correcto es necesario agregar PHPDocs a cada accin del controlador y as poder determinar el tipo de dato devuelto por cada operacin pblica del ServiceProvider,sinosepuededeterminarsegeneraunemptytype. ElmapeodelosvaloresescalarestantolosqueserecibencomolosqueseenvanenPHPasu correspondientexsdsoapenc,eselsiguiente: null
http://app-services

Valor

UTF8 SOAP_COMPRESSION_ACCEPT SOAP_COMPRESSION_GZIP |

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

104

String : <xsd:string>, Integer : <xsd:integer>, Float y Doubles : <xsd:float>, Boolean: <xsd:bool>,Array:<soapenc:Array>yobjetos<xsd:struct>. LosespaciosdenombresXMLusadosson: xsd:"http://www.w3.org/2001/XMLSchema soapenc:http://schemas.xmlsoap.org/soap/encoding/" Es posible invocar la accin getWSDLDescriptor en el controlador para obtener una descripcinWSDLdelservicio. 8.17.7 Orquestacindeservicios Lalgicadenegociodelosservicioswebesimplementadausandocontroladoresquehacen parte de la arquitectura MVC, tanto la capa de lgica de dominio como la de datos tienen sentidoparaeldesarrolladorperolapresentacinnoexistenoesclarosuimplementacin ya queenserviciosweblacomunicacin se realiza entre maquinas y no existe intervencin humanadondeserequiera. AlrecibirunapeticindesdeunclienteSoaplainstanciadelframeworkescapazdeenrutara la accin en el controlador adecuada examinando el mensaje SOAP enviado a la aplicacin. Luego de ejecutar la lgica de dominio en la accin el valor devuelto por esta es tratado y convertidoenunmensajeSOAPqueseenviaalcliente. La manipulacin a bajo nivel de los mensajes SOAP se le encarga al componente Soap que implementalosrecursosnecesariospararecibiryenviarcomunicacionesdeserviciosWeby hacerlotransparentealusuario. EnelsiguienteejemploseilustracomolacomunicacindeserviciosWebestransparenteal desarrolladorycomoelentornoMVCfacilitalaorquestacindeservicios: Enlamaquinaservidor1seimplementaelsiguienteservicioweb: Ejemplo:Serviciowebaritmtico
<?php class AritmethicController extends WebServiceController {

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

105

public function addAction($a, $b){ return $a + $b; }

Enlamaquinaservidor2seimplementaunclientedelServicioWeb: Ejemplo:Accesoalserviciowebaritmtico
<?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 } }

Alinvocarselaaccincalculador/addenservidor2semapeanautomticamentelosvalores de$xy$yalaaccinadda$ay$brespectivamenteenservidor1alinvocarestemtodoenel objetodeserviciocreado. El mismo ejemplo se puede implementar utilizando un Proxy a un tercer servidor quien finalmenterealizalaoperacin. Elserviciowebenelservidor2quedaasimplementado: Ejemplo:DefinirunProxyaserviciosweb
<?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 } }

ElservicioWebAritmethicServerimplementadoenelservidor3: Ejemplo:Serviciowebaritmticoeneltercerservidor
<?php class AritmethicServerController extends WebServiceController { public function addAction($c, $d){ return $c + $d; } }

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

106

Aunquenoesnecesarioimplementaresteejemplousando3maquinas,permiteilustrarcomo se puede abstraer la lgica de aplicacin en forma distribuida de tal forma que mltiples aplicaciones accedan a servicios reutilizables que aumentan la escalabilidad de los sistemas desarrollados. 8.17.8 CaractersticasdeServiciosWebenKumbiaEnterprise Al igual que los otras implementaciones de controladores, en los servicios web usando WebServiceControllerseusadeformatransparentetodalafuncionalidaddelframeworkque seusaenloscontroladoresdeaplicacin,algunasdeestasson: Esposibleaccederalosmodeloscomopropiedadesdelaclasecontroladora Se puede implementar persistencia del estado del controlador entre sesiones y peticiones Se puede enrutar el flujo de ejecucin a otros servicios Web dentro de la misma aplicacin Seguridad declarativa y programacional se puede implementar en este tipo de controladores

8.18 Controladores StandardForm


LaimplementacindecontroladoresStandardFormesunacaractersticaheredadadeKumbia PHP Framework. Por motivos de compatibilidad con aplicaciones existentes en la versin Enterprise su funcionalidad se mantiene intacta. El objetivo de esta implementacin es la generacindinmicadeformulariosquepermitanadministrarlainformacindetablasenla conexinpretederminadadelentornoactual. El desarrollador debe evaluar si las limitantes de esta implementacin no afectarn en un futurolosobjetivosdenegociodelaaplicacin. Nota: Esta implementacin esta agendada para ser marcada como obsoleta en versiones posteriores del framework. LouderTechnology est activamente desarrollado Louder Application Forms el cul genera componentes de aplicacin robustos que aprovechan de maneramsadecuadayflexiblelasposibilidadesdelframework. 8.18.1 CaractersticasdeStandardForm Generacin dinmica de un CRUD (Create, Read, Update, Delete) con posibilidad de

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

107

utilizarpartedeellastodos. De acuerdo a la informacin de los metadatos de una tabla en la base de datos generandocomponentesdeinterfazdeusuarioadecuadosparacadacampo. Esposiblerealizarvalidacindelladodelclienteydelservidor. Esposibleimplementareventosdeacuerdoalasaccionesejecutadasporelusuarioen elcontrolador. LainformacindelatablacreadapuedeserexportadaaPDF,HTML,MicrosoftWordy Excel. 8.18.2 LimitantesdeStandardForm La especificacin del modelo entidadrelacin esta limitada a tablas y campos definidosmediantelasconvencionesdelframework Lafuncionalidaddelosformulariosgeneradossobretodolavisualpuedeserdifcilde personalizarconrespectoalosobjetivosdeldesarrollador.

8.19 Plugins de Controladores


En ciertas ocasiones cuando las aplicaciones corren en mltiples entornos con diferentes caractersticas, la funcionalidad y alcance de la misma aplicacin no es suficiente y se debe extender automticamente durante el runtime. La arquitectura de plugins de Controladores permiteobservar,extenderymanipularelcomportamientodelasclasescontroladorasdela aplicacinsegnlascondicionesloexijan. Los plugins permiten interceptar eventos de los controladores de tal forma que estos sean observables y adems ejecutrse uno tras otro de manera centralizada sin requerir refactorizacinreintegracinenlaaplicacin. 8.19.1 CrearunPlugindeControlador Lospluginsdecontroladorsonclasesqueimplementaneventosquesoninvocadosamedida queavanzalaejecucindeunapeticinencualquiercontrolador.Estasclasesdebencumplir conlossiguientesrequerimientos: Debenestarubicadoseneldirectoriodepluginsusualmenteapps/appname/plugins Elnombredelarchivoqueimplementalaclasedebeserelnombredelplugin ElnombredelaclasedebetenerlaextensinPlugin LospluginsdecontroladordebenheredardelaclaseControllerPluginsersubclasedeella

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

108

Las clases pueden implementar mtodos pblicos que referencian los eventos ocurridos en loscontroladores,lalistadeelloseslasiguiente: Tabla:EventosquesepuedenimplementarenpluginsdeControlador NombreEvento beforeDispatchLoop Descripcin Ocurre antes de iniciar el ciclo de enrutamiento, en este punto nosehacargadoelcontrolador,aunqueseencuentradisponible todoelentornodelaaplicacin. beforeDispatch Ocurredentrodelciclodeenrutamientoyjustoantesdeinvocar el controlador solicitado. Este evento se invoca por cada controladorusadoenelflujodeejecucin. beforeExecuteRoute Ocurre antes de ejecutar la accin solicitada en el controlador, en este punto se puede obtener los datos de la peticin, controlador,accinyparmetros. afterExecuteRoute afterDispatch afterDispatchLoop beforeNotFoundAction Ocurre despus de ejecutar la accin solicitada en el controlador. Ocurre despus del proceso de ejecucin de la accin por controlador. Ocurrecuandoterminaelciclodeenrutamiento. Ocurre cuando la accin controlador ejecutado solicitado no esta implementado. Es independiente de si la accin notFoundActionestimplementada. beforeUncaugthException onControllerException Ocurre antes de lanzarse una excepcin que no fue capturada porlaaplicacin. Ocurrecuandosegeneraunaexcepcindentrodelcontrolador. SeejecutaantesdebeforeUncaughException

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

109

9 Componente UDDI
9.1 Introduccin
Este componente es una implementacin de la especificacin de servicios Web, Universal Description, Discovery and Integration (UDDI). El prinicipal objetivo de este componente es permitiraserviciosecontroladoresdesarrolladosenKumbiaEnterpriseservircomoregistros deserviciospermitiendoquedominiosdecomputacinheterogeneospuedanconsultarlosy conectarserviciosasistemasexistentes.

9.2 Requerimientos
SerequieretenerencuentalosiguienteparautilizarUDDI: Persistencia: El componente UDDI requiere de un gestor relacional para almacenar Autenticacin: El componente Auth es requerido para ofrecer los servicios de losregistrosdeldirectorio. autenticacinaloscontroladoresdepublicacinderegistros.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

110

10 Componente BusinessProcess
10.1 Introduccin
Este componente da la posibilidad de implementar metaprocesos usando BPEL, de esta forma se busca la optimizacin y mejoramiento de procesos de negocio en una aplicacin desarrolladausandoKumbiaEnterprise. 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, comunicacinsincronica,etc. El componente permite su integracin con otros componentes permitiendo levantar configuracin,establecerpersistencia,identificacin,etc. 10.1.1 Queesunprocesodenegocio? Unprocesodenegocioesunconjuntodeactividadesestructuradasyrelacionadasquetienen comoobjetivoprestartunservicioquesatisfagalasnecesidadesdeuncliente.Losprocesosde negocio son crticos para las organizaciones y su correcta estructuracin y definicin determinaelxitodeunaorganizacin. 10.1.2 QuesBPEL? BPEL es un lenguaje de orquestacin de servicios web. Los lenguajes de orquestacin implicitamente indican la intervencin la facilidad de comunicacin entre diferentes sistemasquepuedantenerdiferentesplataformaseinfraestructuradesistemas.

10.2 Job Executor


El componente BusinessProcess ofrece un entorno de ejecucin para PHP que permite ejecutarprocesosPDLyaseaparaorquestarserviciosejecutarprocesosfuncionales.

10.3 Crear un Proceso de Negocio


UnprocesodenegocioseespecificautilizandounaestructuraXMLquerepresentalosestados del metaproceso. Cada uno debe contener un estado inicial y uno final que indique donde empezarydondesedebeterminar.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

111

EnelsiguienteejemploseilustraunprocesoBPMdeunsistemadepuntodeventa(POS).El estado inicial del proceso se marca con el nodo startstate. Es sencillo seguir el flujo del metaprocesograciasalosnodostransitionquetransfierenelflujodeejecucindeunnodo aotro. Ejemplo:DefinicindeunprocesoBPMenPDL
<?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/KumbiaEnterpriseFrameworkManualdeReferencia

112

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

10.3.1 TiposdenodosdeunmetaprocesoPDL Unmetaprocesosoportalossiguientestiposdenodos: Tabla:TiposdenodosdeunmetaprocesoPDL TipoNodo Descripcin Representaunestadodelproceso.Losestadosdebentenerun nombre que permite identificarlos unvocamente en toda la state definicindelprocesoyasgenerarunatransicinaellos.Este tipodenodoscontienennodoshijosqueconrrespondenalas actividades realizadas por el estado. El nombre del estado se defineconelatributoname. Estetipodenodopermiterealizarunatransicinaotroestado delproceso.Dependiendodelprocesolatransicinpuedeser condicional, en estos casos se implementarn 2 nodos de transtion transicin seguidos con el atributo condition definido. La primera transicin cuya evaluacin resulte verdadera sera quien realice la transicin. El nodo a recibir el flujo de ejecucinseespecificaconelatributoto. Los nodos decision permiten efectuar saltos condicionales usandotransiciones.Elparmetrohandlerindicaelnombre decision deunmtodoenelprocesoPHPasociadoalmetaprocesoque tienecomoobjetivocargarlascondicionesparalaevaluacin enlastransicionessiguientes. Este tipo de nodos tienen un handler que referencia un task mtodo en el proceso PHP asociado y normalmente es usado para realizar una operacin de negocio parte del meta proceso. tasknode Cuando se requiere ejecutar varios nodos task se usa un tasknode el cual permite asociar varias operaciones de

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

113

negociodentrodeunestadodelmetaproceso. 10.3.2 CrearloshandlersdelBusinessProcess UnprocesodenegociodebeserdefinidoelcualrealizarlacargadeladefinicinPDLparasu posteriorejecucin: Ejemplo:CrearunaclasedeprocesodenegocioBusinessProcess


<?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(); } }

Enlacesexternos: http://en.wikipedia.org/wiki/Business_Process_Management#BPM_Technology http://en.wikipedia.org/wiki/BPEL

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

114

11 Componente Filter
11.1 Introduccin
ElcomponenteFilterproporcionaunconjuntodefiltrosdedatosyunainterfaseconsistente parasuaplicacinadatosyentradadeusuarioenunprocesodenegocio. Los filtros estn diseados para transformar datos, quitar partes indeseadas, eliminar espacioscaracteresinnecesariosyenresumenasegurarsequeunavariablecontieneloque seesperaquecontenga. El aplicar los filtros adecuados a la entrada de usuario constituye el primer paso para cerciorarsequelosprocesosdenegocioseejecutaranutilizandodatosqueenciertaformano daennialterenelflujoyestadonormaldeunaaplicacin.

11.2 Estructura del Componente


El componente lo constituye la clase Filter y una serie de filtros base de uso general que incluyeelframeworkparasuaplicacinalcomndeaplicacionesWebdenegocios. Losfiltrosbasesonlossiguientes: Tabla:FiltrosbasedelcomponenteFilter Nombre Alnum Alpha NombreCorto alnum alpha nmeros). Filtra letras del abecedario occidental incluyendocaractereslatinoscomovocalescon tildeyees. AddSlaches BaseName Date addslaches basename date Escapalascomillassimplesydoblesparaevitar inyeccindeSQL. Filtra un path para obtener el nombre del archivoelltimodirectorio. Filtra una cadena de caracteres devolviendo unafechaquecoincidaconlaexpresinregular '/(19|20)(\d{2})[\/](\d{1,2})[\/](\d{1,2})/' Uso/Descripcin Filtra caracteres alfanumricos (letras y

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

115

elformatoYYYYMMDD. Digits Double Email Extraspaces digits double email extraspaces Filtra una cadena para que contenga solo dgitos(nmerosdel0al9) Filtra un valor devolviendo un valor numrico dealtaprecisin. Filtraunacadenadecaracteresdevolviendoun correoelectrnicovalido. Filtra una cadena de caracteres eliminando espaciosysaltosdelneaalprincipioyfinalde lacadena. Float HtmlEntities float htmlentities Filtra un valor devolviendo un valor numrico dealtaprecision Convierte todos los caracteres aplicables de unacadenadecaracteresasusentidadesHTML correspondientes. HtmlDecode Identifier Int Ipv4 Ipv6 Lower htmldecode identifier int ipv4 ipv6 lower ConvierteentidadesHTMLasucarcterUTF8 correspondiente. Filtraunvalordejandosolounidentificadorde variablevalido. Filtraelvalorrecibidoenunenterode32bit 64bitdependiendodelaplataforma. Filtra una cadena de caracteres devolviendo unadireccinIPversin4. Filtra una cadena de caracteres devolviendo unadireccinIPversin6. Filtra una cadena de caracteres devolvindola enminsculas.Estefiltrorespetaelcharsetde laaplicacin. Locale Md5 Numeric locale md5 numeric Filtra una cadena de definicin de localizacin UNICODE. Convierte una cadena de caracteres a su resumencriptogrficomd5 Convierteelvalorrecibidoenvalornumrico.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

116

Onechar Stripspace Striptags Stripslaches

onechar stripspace striptags stripslaches

Filtralacadenaparaobtenerunsolocarcter. Elimina los caracteres espacios en toda la cadenadecaracteresrecibida. Elimina las etiquetas HTML que contenga la cadenadecaracteresrecibida. Desescapa normales. una cadena de carcteres convirtiendolos a sus carcteres de comillas

Upper

upper

Filtra una cadena de caracteres devolvindola enmaysculas.Estefiltrorespetaelcharsetde laaplicacin.

Utf8

utf8

Convierte una cadena de caracteres en ISO 88591aUTF8

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 mtodo applyFilters enviando como primer parmetro el valor a filtrar y como parmetrossiguienteslosnombrescortosdelosfiltrosaaplicar: Ejemplo:Crearfiltrosenformadirecta
<?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 combinacin de filtros que se requieran aplicaryaquecadaobjetofilteralmacenaenunbufferestosfiltros: Ejemplo:Usarelbufferdelosfiltros
<?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


Esposiblecrearchainsparalaaplicacindefiltrosbaseydeusuarioaunmismovalordela

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

117

siguientemanera: Ejemplo:ImplementarChainsdeFiltros
<?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 mtodo esttico Filter::load carga uno ms filtros ya sean de usuario base luego se agreganlosfiltrosyseaplicancomoesestndar.Losfiltrostambinpuedenagregarseporsu nombrecorto,agregarvariosalavezymezclarlos.Elordenenqueseagreganindicaelorden deaplicacin: Ejemplo:Aplicarmltiplesfiltrosaunvalor
<?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


Loscontroladoressonprobablementeunpuntodondelosfiltrostenganmayorparticipacin yaqueesaqudondeserequiereasegurarquelosprocesosdenegocioseejecutencondatos consistentesyconfiables. ElmtododeController::filteractuacomounProxyalcomponenteFilterpermitiendofiltrar variablessininstanciarexplcitamentealgunaclaseadicional: Ejemplo:Aplicarunfiltrodesdeuncontrolador
<?php class InvoicesController extends ApplicationController { public function listInvoicesAction(){ //Se obtiene un valor de la entrada y se filtra $initialDate = $this->getPostParam("initialDate");

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

118

$initialDate = $this->filter($initialDate, "date"); } } //Resto del proceso

Adicional a lo anterior los mtodos de Controller getPostParam, getRequestParam y getQueryParamrecibencomoparmetrosextraalvalorrequeridonombrescortosdefiltros loscualesseaplicanenesteordenyseretornanalproceso: Ejemplo:Aplicarunfiltroalaentradadeusuario
<?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 usuariocuandoesrecibidadesdeunformulariounaURL. Elsiguienteejemplodefineunaseriedereglasparavalidarlosvaloresrecibidosdesdeuna entradadeusuariogenerandolosmensajescorrespondientes: Ejemplo:Filtraryvalidarlaentradadeusuariodesdeunformulario
<?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 electrnico', 'filter' => 'email' ),

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

119

'confirmEmail' => array( 'message' => 'Por favor indique la confirmacin de su correo electrnico', '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 direccin de su residencia', 'filter' => 'extraspaces|striptags' ), 'phone' => array( 'message' => 'Por favor indique su telfono' ), '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 recibidoantesdedeterminarsiestpresente,deestaformasecontrolaqueelvalorevaluado seavlidoysegenereelmensajecorrespondiente.Siserequierequeseapliquemsdeun filtro,sepuedeindicarunalistaseparadapor|(pipes). Consulte el componente Validator para obtener ms informacin sobre filtrar la entrada de usuario.

11.7 Crear un filtro de usuario


El desarrollador puede crear sus propios filtros en la aplicacin e integrarlo al componente filterparasuposteriorutilizacin. TantolosfiltrosbasecomolosdeusuariodebenimplementarlainterfaceFilterInterfaceque tienelasiguienteestructura:
<?php interface FilterInterface {

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

120

public function execute($value); }

11.7.1 Requerimientosdeunfiltrodeusuario Alcrearunfiltrodeusuariosedebetenerencuentalosiguiente: Secreaunarchivoubicadoeneldirectoriofilters/delaaplicacindondelaopcin filtersDirdelarchivodeconfiguracinconfig/config.iniindique. EnelsiguienteejemplosecreaunfiltrodeusuarioqueapartirdeunaURLfiltraeldominio quecorrespondeaella: Ejemplo:FilterdeusuarioquefiltradominiosenunaURL


<?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; } }

Elnombredelarchivoeselnombredelfiltroconlaprimeraletraenmayscula ElarchivodebecontenerunaclaseconelnombredelfiltroysufijoFilter LaclasedebeimplementarlainterfaceFilterInterface

En cualquier parte de la aplicacin se puede utilizar usando su nombre corto cargandolo medianteFilter::load: Ejemplo:Aplicarunfiltrodeusuario
<?php $filter = new Filter(); $url = "http://www.google.com/?q=kumbia%20framework"; print $filter->applyFilter($url, "domain"); // www.google.com

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

121

12 ActionHelpers
12.1 Introduccin
Los ActionHelpers son subcomponentes auxiliares que complementan y auxilian a las implementacionesdecontroladoresalgunasvecesestableciendopuentesalapresentaciny otrasvecesalacapadedatos.

12.2 Mensajes usando Flash


ElActionHelperFlashpermitelageneracindemensajescontextualesencualquierpartedela aplicacin. Adicional a esto es posible almacenar mensajes para ser mostrados cuando se requieraenotraspeticiones. 12.2.1 Generarmensajescontextuales Los mensajes contextuales permiten aparte del mensaje por medio de colores e iconos informarelcarcterdelmismo. Tabla:TiposdemensajescontextualesconFlash Mtodo Flash::error Tipo Error Descripcin Informaquehayunasituacindeerror.Pordefectoseusa fondorosa,textoenrojoyuniconodeadminiracin. Informacin Da el contexto de informacin. Por defecto se usa fondo azulyletraazuloscuro. xito Flash::success Indicaquelaoperacintuvoxitoseejecutunproceso satisfactoriamente. Por defecto se usa fondo verde llamativoyletraverdeoscura. Advertencia Flash::warning Genera un mensaje con el contexto de advertencia. Por defectoseusaamarilloclaroenelfondo,letraennegroy uniconodealerta. Todoslosmtodosrecibenensuparmetroelmensajeamostrar. 12.2.2 Cambiarelestilopordefectodelosmensajes Sisedeseacambiarelestilodelosmensajesdetextosepuedemodificarsobreescribirlas clasesCSSenelarchivopublic/css/style.cssquesiempreseinsertaentodaslaspeticiones.Por

Flash::notice

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

122

defectolasclasestienenlossiguientesestilos: Ejemplo:EstilosCSSpredefinidosparamensajesdelFlash
.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 Cambiarelestiloenformadinmica Si se requiere cambiar la presentacin de un mensaje en forma programacional se puede enviarunlistadodeclasesCSScomosegundoparmetro. Ejemplo:EstablecerunaclaseCSSpersonalizadaparaFlash
Flash::notice("Esto es una informacin personalizada", array("mi_clase_css", "otra_clase_css"));

12.2.4 Enviarmltiplesmensajesdelmismotipoenformasimltanea Cuandoelprimerparmetrorecibidoporunmtododemensajesesunvectorconmensajes lalistadeestosesenviadaunatrasotraenelordenrecibido.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

123

Ejemplo:EnviarvariosmensajessimultneosmedianteunarrayconFlash
Flash::error(array( "Este es el primer error", "Este es el segundo error", "Este es el tercer error", ));

12.2.5 Mostrarmensajesporsutipo El mtodo de Flash llamado message permite mostrar un mensaje utilizando una constante comosegundoparmetroqueestableceeltipoamostrar:
Flash::message("Esto es una advertencia", Flash::WARNING); Flash::message("Esto es un error", Flash::ERROR, array("my_error_css"));

Tabla:Constantesdelostiposdemensajes Valor 0 1 2 3 12.2.6 Cachearmensajesparamostrarlosenlaprximapeticin Si se requiere mostrar mensajes al usuario despus de realizar una redireccin se puede utilizarelmtodoaddMessagequefuncionacomoelmtodomessagerecibeelmensajeyun cdigoindicandoeltipo.Losmensajesqueseagregandeestaformanosonvisualizadossino hastaqueseinvocaelmtodogetMessages(). Elsiguienteejemploilustraelfuncionamientodeestetipodemensajes: Ejemplo:EnviarmensajesFlashusandolacolademensajesdeprximapeticin
<?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']); } }

Constante Flash::ERROR Flash::NOTICE Flash::SUCCESS Flash::WARNING Mensajesdeerror

Descripcin

Mensajesdeinformacin Mensajesdexito Mensajesdeadvertencia

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

124

Los mensajes agregados con addMessage se almacenan en un buffer del contexto de sesin. CuandolosmensajesseobtienencongetMessageselbufferinternoseresetea.

12.3 Condiciones SQL con FormCriteria


El actionhelper FormCriteria permite crear condiciones SQL a partir de los parmetros recibidos por un formulario de entrada de usuario. De acuerdo a los parmetros recibidos, sololosquetenganvaloresnonulosseincluyenenlascondicionesgeneradas. Enelsiguienteejemplosemuestracomocrearlacondicindebsquedaparadiversostipos dedatosobtenidosdesdeunformulario. Losdatoscapturadosson: Cdigo:Correspondealcdigodelproductoyesdetiponumrico. Nombre:Elnombredelproductoyesdetipotexto. Categora: Campo de tipo entero de la entidad Products que es relacin a la tabla

ProductCategories. Se usa Tag::select para cargar los datos de esta tabla y se indica el parmetrouseDummyparaagregarlaopcinSeleccione. Elformularioenlavistaviews/products/index.phtmleselsiguiente:
<h1>Buscar Productos</h1> <?php echo Tag::form('products/search'); ?> <table> <tr> <td align="right">Cdigo:</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">Categora:</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(

Tipo: Combo creado apartir de un array con valores estticos que corresponde al

campotypedelaentidadProducts.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

125

</tr> <tr> </tr> </table> <?php echo Tag::endForm() ?> <td></td> <td><?php echo Tag::submitButton('Enviar') ?></td>

'A' => 'B' => 'O' => ), 'useDummy:

'ALIMIMENTOS', 'BEBIDAS', 'OTRO' yes') ?></td>

Enelcontroladorsedefinelabsquedasegnseenvielosparmetrosalaaccinsearch: Ejemplo:CrearuncriteriodebsquedaSQLusandoFormCriteria
<?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 parmetros, el primero corresponde al origen de los datos de los cualesseconstruiraelcriteriodebsqueda.Elsegundoesundescriptorconloscamposque serecibendelformularioylaformaenquedebeconstruirselacondicinparacadauno.Las llaves del descriptor son los nombres de las variables que vienen del formulario y que son partedelorigendedatos.Enelejemploelorigendedatoseslasuperglobal$_POST. Ladescripcindelasopcionesparacadacampoes: Tabla:OpcionesdeloscamposparacrearelcriteriodebsquedaconFormCriteria

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

126

Opcin type

Descripcin 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 posiblequeseapliquenfiltros.

operador

Un operador compatible con el gestor relacional utilizado. Cuando la opcin type es integer, float, double y date se utiliza el operador = cuandoesstringseusaeloperadorLIKE.

missOnNull

Unvalorbooleanoquedeterminasisedebeomitirlacondicincasode queelvalorrecibidoseanuloelvalorestablecidoparanulomediante nullValue.Pordefectosuvalorestrue.

nullValue fieldName

El valor que debe entenderse como valor nulo para saber si se debe omitiralgenerarlacondicin. Elnombredelatributoenlaentidad.Sinoseindicaseusaelnombrede lallaveeneldescriptor.

Siseenviaelvalorcode=10seproducelacondicin:
id = 10

Siseenvianlosvalorescode=10ynombre=cheesecakeseproducelacondicin:
id = 10 OR name LIKE %cheese%cake%

Siseenvianlosvaloresproduct_categories_id=2ytype=A(typeeselnombredelcampo)se producelacondicin:
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 puedeenviareloperadorcomoparmetrodegetConditionsas.
$this->Products->find($criteria->getConditions(AND));

12.3.1 CriteriosdeRangos Con FormCriteria tambin es posible crear criterios de rangos cuyos valores sean obtenidos deunformulariodeentradadeusuario.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

127

Siloqueserequiereesqueapartirdecamposobtenidosdelformulariosecreelacondicin entoncesdebedefinirdelasiguienteforma: Ejemplo:CrearuncriteriobasadoenunrangodefechasconFormCriteria


$criteria = new FormCriteria($_POST, array( 'fechaInicial:fechaFinal' => array( 'type' => 'date', 'fieldName' => 'fecha' ) ));

SiseenvianlosvaloresfechaInicial=20081020yfechaFinal=20081122seproducirala siguientecondicin:
fecha >= 2008-10-20 AND fecha <= 2008-11-22

Ysiloqueserequiereesqueelvalordelaentradadeusuarioseencuentreentre2camposde latablaentoncessedefineas:
//La tabla es de registro de vuelos $criteria = new FormCriteria($_POST, array( fecha' => array( 'type' => 'date', 'fieldName' => 'fechaLlegada:fechaSalida' ) ));

Siseenvianelvalorfecha=20081020seproduciralasiguientecondicin:
fechaLlegada >= 2008-10-20 AND fechaSalida <= 2008-10-20

12.3.2 Unirvariascondiciones Varias criterios pueden ser unidos utilizando operadores diferentes para de esta forma construircondicionesmscomplejas: Ejemplo:CrearcondicionesdebsquedacompuestasconFormCriteria::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/KumbiaEnterpriseFrameworkManualdeReferencia

128

)); $conditions = FormCriteria::join(OR, array( $criteria1->getConditions(AND), $criteria2->getConditions(AND) ));

), 'name' => array( 'type' => 'string' ),

El mtodo esttico FormCriteria::join puede unir 2 ms objetos FormCriteria con un operadordiferente.

12.4 Informacin del Navegador con Browser


EsteActionHelperpermiteobtenerinformacindelexploradordelclientedesdeelculseest accediendoalaaplicacin. 12.4.1 APIdeBrowser ElAPIeslasiguiente: publicstaticbooleanisFirefox() DevuelvetruesielexploradorutilizadoesMozillaFirefox. publicstaticbooleanisSafari() DevuelvetruesielexploradorutilizadoesAppleSafari. publicstaticbooleanisCamino() DevuelvetruesielexploradorutilizadoesCamino. publicstaticbooleanisInternetExplorer() DevuelvetruesielexploradorutilizadoesMicrosoftInternetExplorer. publicstaticbooleanisMobileSafari() DevuelvetruesielexploradorutilizadoesAppleMobileSafari,elqueusaelSOdeliPhoney iPodTouch. publicstaticbooleanisIEMobile() Devuelve true si el explorador utilizado es Microsoft Internet Explorer Mobile usado en el sistemaoperativoWindowsMobile.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

129

publicstaticbooleanisOperaMobile() Devuelve true si el explorador utilizado es Opera Mobile si el explorador utilizado es Opera paraWindowsMobile. publicstaticstringgetVersion() Devuelvelaversindelexploradorutilizado. publicstaticstringgetUserAgent() DevuelveelUserAgentdelexploradorcliente. publicstaticbooleanisGecko() DevuelvetruesielmotorderenderizadodelexploradoresGecko. publicstaticbooleanisWebKit() DevuelvetruesielmotorderenderizadodelexploradoresWebKit. publicstaticstringgetAcceptEncoding() Indicalostipodecodificacinsoportadorporelexplorador. publicstaticstringgetAcceptLanguage() ObtieneelidiomautilizadoporelexploradorusandoelestndarRFC. publicstaticbooleanacceptCompressedOutput() Indicasielexploradoraceptasalidacomprimidayaseausandogzipdeflate. publicstaticstringgetBrowserAbrev() DevuelveunaabreviaturadelUserAgentdelexplorador. publicstaticbooleanisMobile() Indicasielexploradorusadoseencuentraenunaplataformamvil. publicstaticbooleanisMacOSX() DevuelvetruesielsistemaoperativodelclienteesAppleMacOSX.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

130

publicstaticbooleanisWindows() DevuelvetruesielsistemaoperativodelclienteesMicrosoftWindows publicstaticbooleanisLinux() DevuelvetruesielsistemaoperativodelclienteesLinux.

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 siguienteejemplosemuestraelusodeeste: 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') ?>

Segnsudefinicincuandoelusuarioescribaalgunoscarcteresseobtendrnlosdatosdel resultadodelaaccinconsultarenelcontroladorpaises. Si los datos de paises se obtienen de un array esttico entonces el controlador paises es el siguiente: Ejemplo: Obtener los datos de autocompletado 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/KumbiaEnterpriseFrameworkManualdeReferencia

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); } }

Silosdatosdepaisesseobtienendeunatablaentonceselcontroladorpaiseseselsiguiente: Ejemplo: Obtener los datos de autocompletado 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/KumbiaEnterpriseFrameworkManualdeReferencia

132

13 Componente Validator
13.1 Introduccin
Estecomponenteestintegradoalasimplementacionesdecontroladoresypermiterealizar validacionessobrelaentradadeusuario.Alserindependientedelacapadelgicadedominio ypresentacinpuedeserusadoenlospuntosdelaaplicacinqueserequierasinafectarla arquitecturadelamisma.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

133

Parte2:Seguridad

14 Seguridad con Kumbia Enterprise


14.1 Introduccin
LasaplicacionesWebyServiciosWebcreadasusandoKumbiaEnterpriseFrameworkpueden serdistribuidaseimplementadasusandodiferentesentornosdentrodeunamismainstancia. Cada aplicacin puede constituir una arquitectura multicapa independiente con requerimientosdeseguridaddiferentes. Laseguridaddeunaaplicacinpuedeserimplementadade2formas: Declarativa Externa: Se definen los requerimientos de seguridad de una aplicacin utilizandorecursosexternosalamismasinintervenirdemaneraintrusivaenlalgica delaaplicacin.Ladescripcindeestaincluyedetallessobrecomolosrolesaccedena losrecursosdelaaplicacinysuspolticas. Programacional Interna: Esta embebida en la aplicacin y esta implementada en forma de decisiones de seguridad, es suficiente cuando los requerimientos de seguridadsonsimplesynocambianconfrecuencia.

14.2 Caractersticas de Seguridad


Mecanismosadecuadosdeseguridadofrecenlasiguientefuncionalidad: Previenenaccesoinautorizadoainformacinyprocesosdenegocio Controlan que las actividades realizadas por un usuario no interfieran con las realizadasporotrosimpactandolaintegridaddelsistema. La seguridad de aplicaciones basadas en Kumbia Enterprise Framework consiste en la implementacin de componentes que ayuden a proteger los recursos de la misma. Los procesos de seguridad requieren de la implementacin adecuada de autenticacin, identificacin,controldeacceso,integridaddedatosycalidaddelservicio: Protegen el los servicios del sistema de riesgos que puedan decaer la calidad del servicioproporcionada

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

134

Autenticacin: La aplicacin ejecuta procesos que permiten confiar que quien hace Autorizacin: Es el proceso de identificar a que conjunto de recursos puede

usodelamismaesquienrealmenteseespera. utilizar/acceder con el propsito de establecer controles adecuados de integridad de datosylimitaciones. Integridad de Datos: Permiten que solo usuarios roles autorizados alteren la informacin a la que se les ha permitido el acceso y que no intervengan con otros procesosdeotrosusuariosautenticados. ConfidencialidadPrivacidad:Permitequelainformacinsoloestdisponiblepara CalidaddelServicio(QoS):Permitequeseofrezcaunamejorexperienciadeusuario Auditoria: Permite almacenar un registro consistente que permita saber las elusuarioadecuadoydelaformaadecuada. aprovechandodiferentestecnologas. actividadesqueunusuariorealizoybajoquecondicionesserealizaron.

14.3 Mecanismos de Seguridad


Kumbia Enterprise Framework ofrece diferentes componentes para una adecuada implementacin de seguridad tanto de aplicaciones Web como de Servicios Web empresariales: Access Control List (ACL): Este componente permite crear listas en donde se Auth:Permiterealizarelprocesodeautenticacinutilizandodiferentesadaptadores AuditLogger:Permitecrearregistrosdeauditoriadelasactividadesrealizadasenlas Session: Mantiene la persistencia de sesin independiente entre aplicaciones y Security:Permitedetectarataquesdenegacindeserviciobloquearelaccesoaun estableceaquerecursospuedeaccederdeterminadosroles. comoDigest,LDAP,BasesdeDatos,Kerberos5yRadius. aplicaciones. usuariosautenticados. clienteatravsdesudireccinIP.

14.4 Seguridad a nivel de Capa de Aplicacin


Loscontroladoresenlasaplicacionessonapropiadosparaestablecercontrolesdeseguridad en las aplicaciones, sin embargo, todos los requerimientos de seguridad no pueden ser

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

135

controlados en profundidad desde este punto y generalmente es necesario apoyarse por firewallsuotrastcnicasparaaumentarlaconfiabilidaddeunsistema. Comocadaaplicacinmanejasuspropiosentornosdeejecucinydememorialainformacin de seguridad reside en forma independiente facilitando la administracin de cada entorno. Cuando se utilizan servicios Web con mltiples intermediarios es posible que haya la necesidad de implementar mecanismos de seguridad compartidos y transferencia de identidadentreaplicaciones. Lasventajasdelaseguridadaniveldeaplicacinincluyen: Lasdesventajasdeestetipodeimplementacinson: La aplicacin es dependiente de atributos de seguridad que no pueden ser Se crea un nico punto de vulnerabilidad que de ser violado expondra muchos establecidostransferidosdesdeotra. aspectosdelasaplicaciones. La seguridad de cada aplicacin se puede adaptar/generar de acuerdo a las Laseguridadesoptimizadaconopcionesespecificasdecadauna. necesidadesdecadauna.

14.5 Seguridad a nivel de Capa de Transporte


ElusodeprotocoloscomoHTTPS/SSLpuedemejorarlaseguridaddesdeotropuntodevista sinquepuedareemplazarlaseguridadaniveldeaplicacin.Laseguridadaniveldecapade transporte trata de mecanismos uno a uno en donde por medio de llaves criptogrficas es posibleimplementarautenticacin,integridaddemensajesyconfidencialidad. Certificados digitales son requeridos para implementar este tipo de seguridad. Estos estn directamenteasociadosalservidorWebutilizadoysuponenunacapadelacualelframework nopuedetenercontrol. Lasventajasdelaseguridadenlacapadetransporteson:

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

136

Fcildeimplementar. Estabasadoenestndares

14.6 Implementar Seguridad Declarativa


ElcomponentedelistasdecontroldeAccesodeKumbiaEnterprise(ACL)estaintegradocon el Core del framework interceptando cada peticin y validando que su ejecucin este permitidaenelcontextoactual.Laseguridaddeclarativaestimplementadausandolistasde controldeaccesodefinidasenlaconfiguracindelaaplicacinmediantedescriptores. Los descriptores permiten definir la estructura de autorizacin de seguridad que incluye: roles,controldeaccesoyrequerimientosdeautenticacinenformaexternaalaaplicacin. LaopcinsecurityAccessListenlaseccinapplicationdelarchivoconfig.inipermiteestablecer eltipodelistadeaccesoquecontrolarlaseguridaddelaaplicacin: Ejemplo:Implementarseguridaddeclarativadesdeconfig.ini
[application] mode = production name = "Project Name" dbdate = Y-m-d debug = Off securityAccessList = xml:filePath=%app-base%/security/security.xml

LosdescriptoresACLtienenelformatodeunDataSourceNameindicandoprimeroelnombre deladaptadorautilizaryluegolasopcionesdelmismousandopuntoycomasparasepararlas mismas.Losdescriptoresdebenirentrecomillasdoblesconelfindequeciertoscaracteresno causenconflictosalleerelarchivo.ini. En el siguiente ejemplo de un descriptor de una lista de acceso basada en XML se muestra comodefinirlosaspectosbsicosdeunalista.EnelcaptulodelcomponenteAclsedetallala implementacindecadapartedelarchivoXML. Ejemplo:ListaACLenXMLparacontroldeacceso
<?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/KumbiaEnterpriseFrameworkManualdeReferencia

137

<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 sesin</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>

<role>

Los recursos de una aplicacin para la seguridad declarativa son los controladores de la misma y sus nombres coinciden con estos en las opciones resourcename en el ejemplo. La asociacin recursocontrolador ofrece un potente sistema de control para cada peticin a la aplicacindeformatransparenteparaeldesarrollador. Elrolconelcualserealizanlasvalidacionesdeseguridadeseldefinidomedianteelmtodo del componente Security llamado setActiveRole(string $roleName), cuando el rol no se ha definido an se usa la convencin para el rol Public de tal forma que se asuma que la aplicacinespblicanosehadefinidoidentificacindequienusalaaplicacin. Losrecursosquenosehanmencionadoenlaslistasdeaccesotienenpordefectolapoltica

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

138

Allowconloquesehacenpblicosconsoloaccederaellos. PorcadapeticinalaaplicacinelmtodoSecurity::checkResourceAccessvalidasielrolactivo tieneaccesoalrecursosolicitado.Cuandosetieneaccesoalrecursoelprocesodenegocioen la accin del controlador se ejecuta normalmente, cuando la validacin falla, la aplicacin tratadeenrutaralaaccindelcontroladorllamadaunauthorizedAccessAction.

14.7 Implementar Seguridad Programacional


Laseguridadprogramacionalestaembebidaenlaaplicacinyestaimplementadaenformade decisionesdeseguridad.Esmstilcuandolaseguridaddeclarativaresultamuybsicayno seadaptaalasnecesidadesdenegocio. EnestepuntolosfiltrosdecontroladoresyelpuntodeentradaalaaplicacinControllerBase resultanapropiadosparadefinirlasreglasdeseguridadyaplicarelAPIdeloscomponentes AclyAuthparacontrolarlosprocesosrequeridos.

14.8 Definir Realms, Usuarios y Grupos para Autenticacin


LosRealmssoncoleccionesdeusuariosloscualespuedenonoperteneceraundeterminado grupo y son controlados mediante una misma poltica de autenticacin. Normalmente una aplicacinestablececontrolescomounusuarioycontraseaantesdeproporcionaraccesoa un recurso protegido, los datos proporcionados por un usuario se validan en forma de credenciales produciendo un resultado de xito del proceso de autenticacin. Kumbia EnterpriseFrameworkofrecediferentesadaptadoresdeautenticacinusandoelcomponente Auth. Enalgunoscasoslosusuariosdelasaplicacionestienenasignadosroles,estoindicaquehacen partedegruposconcaractersticasseseguridaddefinidasenundominiodeaplicacin. 14.8.1 Realms Losrealmssonbasesdedatosdeusuariosygruposquecontienenlascredencialesnecesarias para controlar una poltica de autenticacin. Debido a la flexibilidad del componente de autenticacinAuthesposiblecrearbasesdedatosdeautenticacinenvariosformatoscada unoconcaractersticasdistintas.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

139

14.8.2 Usuarios Losusuariossonidentidadesindividualesquesonreconocidosporlaaplicacin.Unusuario puedetenerrolesasociadosquepermitenconocerquerecursospuedenaccederdeacuerdoa unapolticadeseguridad. 14.8.3 Grupos Los grupos representan una serie de caractersticas compartidas por uno o varios usuarios. Un grupo es un conjunto de usuarios que comparten los mismos accesos y controles de seguridadenlaaplicacin.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

140

15 Componente ACL (Lista de Control de Acceso)


15.1 Introduccin
LaListadeControldeAccesoeningls(AccessControlList)esuncomponentedeKumbia Enterprise Framework es un concepto de seguridad informtica usado para fomentar la separacindeprivilegios.Esunaformadedeterminarlospermisosdeaccesoapropiadosaun determinadoobjeto,dependiendodeciertosaspectosdelprocesoquehaceelpedido. Al igual que otros componentes del framework que estn basados en componentes se implementaelpatrnVirtualProxy,unainstanciadeAclsoloactacomounProxyalobjeto realinstanciadoquecorrespondealtipodeadaptadorutilizadoporelmismo.

15.2 Estructura del Componente


Kumbia Enterprise Framework ha integrado la siguiente estructura jerrquica de clases que permitenlaimplementacindeestecomponente: Tabla:JerarquiadeclasesdelcomponenteAcl Clase Acl.php Interface.php Adapters/Memory.php Descripcin Es la clase constructora de las listas Acl. Es un Proxy a la funcionalidadimplementadaencadaadaptador. EslainterfasequedebenutilizartodoslosadaptadoresAcl. Es el adaptador que permite administrar las listas de acceso enmemoria. El Adaptador permite definir listas de acceso en archivos de descripcinenXML. Eseladaptadorpermitelaadministracindelalistadeacceso aunabasededatoscomobackend. Es la clase que permite administrar cada recurso como una entidadindependientedesubackend. Es la clase que permite administrar los roles que tendrn accesoalalistaACLindependientementedesubackend.

Adapters/Xml.php

Adapters/Model.php

Resource/Resource.php

Role/Role.php

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

141

15.3 Que es un Recurso?


Unrecursoescualquierelementodeunaaplicacindelcualsepuedacontrolarsuacceso.Por conveniencia los controladores de la aplicacin son vistos como recursos con el objetivo de generarunmodelodeseguridadconsistente.

15.4 Que es un Rol?


Un rol es un nombre abstracto para el permiso de usuarios a un conjunto particular de recursosenunaaplicacin.Unrolpuedesercomparadoalallavequeabreuncandado,este abresinimportarquientienelaclave.Losrolesestngeneralmenteasociadosalosmismos usuarios,alosgruposdeestosasusperfiles.

15.5 Que es un Acceso?


Los accesos son las operaciones acciones que se pueden realizar en los recursos. Niveles msprofundosdeseguridadcontrolanhastaestenivelloquesepuedahacerporpartedelos usuarios.

15.6 Tipos de Reglas


Elaccesoaundeterminadorecursotieneunaregladepermitir(allow)denegar(deny),no estnsoportadasotrostiposdereglasdeacceso.

15.7 ACL en Accin


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 elcontroldeaccesoalosrecursosdelaaplicacinenformaprogramacional: Ejemplo: Utilizar ACL con modelos para validar el acceso a los recursos de una aplicacin
<?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/KumbiaEnterpriseFrameworkManualdeReferencia

142

permiso para usar esta aplicacin"); } $authLog = new Log(File, "auth_failed.txt"); $authLog->log("Autenticacin fallo para el rol '$role' en el recurso '". $this->getControllerName()."/".$this->getActionName()."'"); return false; } } }

} else { throw new ApplicationControllerException("No tiene

GraciasaqueelmtodobeforeFilterseencuentraenlajerarquadetodosloscontroladores esteseejecutapreviamenteacualquieraccinsolicitada.Seobtienedelosdatosdesesin,la variable role indica el nombre del rol actualmente logueado, si aun no hay un rol activo es asignadopordefectoPublic. AhoraesposibleinstanciarlaclaseAcl,ydefinircomoadaptadorunModeloendondeseha referenciaalaclaseAccessListquienmapeaalatablallamadaaccess_list,lacualadministra losaccesosalosrecursosdelaaplicacin.LatablacontieneunSecurityPolicyDomaindeun POS(PointOfSale): Ejemplo:DatosdelistaACLbasadaenModelos
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 | +----+-----------------+-----------------------+--------+-------+

ElparmetroclassNamepermiteestablecerunmodeloquecontienelaestructuradescritaen la tabla anterior. El campo resource y action pueden contener asteriscos (*) que son usados comocomodinesparacualquiercriterioquecoincida.Elcampoallowpuedetenerlosvalores Y(es)oN(o)paraindicarsileconcedeelaccesoalrecurso.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

143

LaprincipalventajadelalistasACLesquevalidanlosaccesosenformajerrquicayaseaa nivelderecursosmedianteherenciaderoles.Enelejemploelaccesodejerarquamsalto esenelquehaycomodinestantoparaelrecursocomoparalaaccin,elmtodoAcl::isAllowed buscajerrquicamentesiexisteunaccesonoenlalistadeacceso. Segnelejemplolassiguientesconsultasalalistadeaccesodariancomoresultado: Ejemplo:ComportamientodelalistaACLsegndatosdeejemplo


$acl = new Acl('Model', 'className: AccessList'); //Esta permitido el rol Public a acceder al recurso menus en la operacin index? //No Permitido $acl->isAllowed("Public", "menus", "index") //Esta permitido el rol Cajeros a acceder al recurso dinein en cualquier operacin? //Permitido $acl->isAllowed("Cajeros", "dinein", "*") //Esta permitido el rol Cajeros a acceder al recurso data en la operacin query? //No Permitido $acl->isAllowed("Cajeros", "data", "query")

ElprimerparmetrodeAcl::isAllowedeselnombredelrol,elsegundoelnombredelrecursoy el tercero el nombre de la accin. Cuando no se encuentra una regla especifica para rol recursooperacin,sebuscarolrecursocualquierayporultimorolcualquieracualquiera.

15.8 Herencia de Roles


Unadelasgrandesventajasdelusodelistasdecontroldeaccesoeslaconstruccindearboles de jerarqua de roles. De esta forma los permisos de acceso pueden ser heredados compartidosentrevariosrolessinquehayaredundanciadeinformacinproporcionandoala aplicacincapacidadesdecontroldeaccesopotentesyflexibles.

15.9 Adaptadores de ACL


Kumbia Enterprise Framework permite utilizar varios backends para almacenar listas Acl. CadaadaptadorimplementalainterfaceAclInterface:
<?php interface AclAdapter { public public public public function function function function addRole(AclRole $roleObject, $accessInherits=''); addInherit($role, $roleToInherit); isRole($role_name); isResource($resource_name);

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

144

public public public public public public }

function function function function function function

addResource(AclResource $resource); addResourceAccess($resource, $accessList); dropResourceAccess($resource, $accessList); allow($role, $resource, $access); deny($role, $resource, $access); isAllowed($role, $resource, $accessList);

Acontinuacinseexplicanlasconsideracionesdeusodecadaadaptador: 15.9.1 AclModel La lista de accesos tambin puede ser administrada usando modelos disponibles en la aplicacin.Paraestoesnecesariocrearunaentidadconlasiguienteestructura: Ejemplo:EstructuradeunatablaaptaparaalmacenarunalistaACL
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 parmetro className,luegoelcomportamientoyutilizacineselnormal: Ejemplo:UsodelistasACLconModelos
$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 usarseenotraspeticiones.Paraaplicacionesconrequerimientosdevalidacindecontrolde accesoreducidosesteadaptadorpuedeserunaopcinatenerencuenta. 15.9.3 AclXML Este adaptador permite crear listas de control de acceso en archivos XML. Estos archivos mantienenloscontrolesdeformaestructuradahaciendosencillasumanipulacindesdeotros lenguajesyaplicaciones. Elarchivodebecontenerlasiguienteestructura:

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

145

Unnodorazsecurityquecontendrlalistaens Unsolonodorolescollectionquecontienenodosroleconinformacinderoles Los nodos role deben tener los subnodos name y description con el nombre y descripcindelrolrespectivamente. Un solo nodo resourcescollection que contiene nodos resource con informacin de los recursosenlalista. Los nodos resource deben tener los subnodos name y description con el nombre y descripcindelrecursorespectivamente. Mltiples nodos accessconstraint con las reglas de acceso. El orden de estas indica la prioridaddecadauna. Cada nodo accessconstraint contiene los nodos rolename que es nombre del rol, resourcename que es el nombre del recurso, actionname que es nombre del acceso y ruletypequecontieneallowsitieneaccesoalrecursoydenydelocontrario. ElsiguienteeselejemplodeunalistaACLenXML: Ejemplo:ListaACLusandounadefinicinenXML
<?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 sesin</description> </resource> </resources-collection>

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

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


publicbooleanaddRole(AclRole$roleObject,mixed$accessInherits) AgregaunrolalalistaderolesdelalistadeAcceso.EnestetipodeAdaptadorelrolsecreaen laentidaddefinidaenelconstructordelalistaenelparmetro:rolesClassName. publicvoidaddInherit($role,$roleToInherit) Agregaunaherenciaalalistaenlaqueelrol$roleheredatodoslosconstraintsdeaccesoque tieneelrol$roleToInherit. publicbooleanisRole(string$roleName) Permitesabersi$roleNameestapresenteenlalistaACL publicbooleanisResource(string$resourceName) Permitesabersiunrecursoexistenoenlalistadeaccesoactual. publicbooleanaddResource(AclResource$resource) Agregaunrecursoparaseradministradorporlalistadecontroldeacceso. publicvoidaddResourceAccess(string$resource,mixed$accessList) Agregaunaoperacin/accinaunrecursodelalistaACL.Elparmetro$accessListpuedeser unstringunvector. publicvoiddropResourceAccess($resource,$accessList) Eliminaunaoperacin/accindeunrecursodelalistaACL.Elparmetro$accessListpuede serunstringunvector.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

147

publicvoidallow(string$role,string$resource,mixed$access) Agregaunareglaquedaaccesoaundeterminadorolaunrecurso. publicvoiddeny(string$role,string$resource,mixed$access) Agregaunaregladenegandoelaccesodeundeterminadorolaunrecurso. publicbooleanisAllowed(string$role,string$resource,array$accessList) RealizaunaconsultaenlalistaACL

15.11 API de AclResource


publicvoidgetName() Obtenerelnombredelrecurso publicvoidgetDescription() Obtenerladescripcindelrecurso

15.12 API de AclRole


publicvoidgetName() ObtenerelnombredelRole publicvoidgetDescription() ObtenerladescripcindelRole,usualmenteelnombreextendidodelrol.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

148

16 Componente Auth
16.1 Introduccin
El componente Auth esta diseado para permitir la autenticacin y administracin de la entidad de los usuarios en una aplicacin ya sea de forma independiente de manera compartida. Este componente accede a sus adaptadores usando el patrn Virtual Proxy, es decir, una instanciadeAuthsoloactacomounProxyalobjetorealinstanciadoquecorrespondealtipo deadaptadorutilizadoporelmismo.Estaimplementacinpermitecrearunpuntodeentrada nicoparlautilizacindeadaptadoresdelframeworkdeusuario. La instancia interna del adaptador se puede obtener usando el mtodo Auth::getAdapterInstance().

16.2 Adaptadores de Auth


El componente implementa una arquitectura de adaptadores de autenticacin, estos estableceninterfacesconsistentesadiferentesproveedoresdeidentificacinbajounamisma interfaz de aplicacin. Cada adaptador requiere de diferentes parmetros solicitados por el serviciodeautenticacinutilizado. Losadaptadoresdisponiblesson: Tabla:AdaptadoresdeAuthdisponibles Adaptador Digest Radius KerberosV Model LDAP detexto. ImplementaautenticacinusandoprotocoloRadiusAutenticationRFC 2865. AutenticausandoservidoresKerberos5yademspermiteobtenerlas politicasasociadasalusuarioidentidad. Usa un modelo de la aplicacin en donde los atributos de esta actuan comocredencialesenlaautenticacin. Permite utilizar servidores LDAP como ActiveDirectory para Descripcin Permitela autenticacin usando un realm basado enun archivoplano

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

149

autenticarseenunaaplicacin. TodoslosadaptadoresdeAuthimplementanlainterfaceAuthInterface:
interface AuthInterface { public function __construct($auth, $extraArgs); public function getIdentity(); public function authenticate(); }

16.3 Administracin de Identidad


La administracin de identidad es uno de los procesos ms usuales en cualquier aplicacin Web,unavezseproducelaautenticacineidentificacindelusuarioesnecesarioconocerla identidaddurantetodalasesindelmismoenlaaplicacin. Al realizar una autenticacin satisfactoria con el componente Auth automticamente se crea un registro de la identidad de quien inici sesin y poder cumplir con objetivos de la aplicacincomopersonalizacinconfidencialidad. El mtodo esttico de Auth llamado getActiveIdentity() devuelve la identidad creada en la autenticacin en cualquier parte de la aplicacin. Para destruir la identidad activa se usa el tambinmtodoestticodestroyIdentity(). Para conocer si existe una identidad valida en la aplicacin se usa el mtodo Auth::isValid() quedevuelveunvalorboleanocorrespondienteaesainformacin.

16.4 Expiracin de Sesin


El componente Auth soporta expiracin de la sesin con lo que es posible controlar que un usuarioautenticadosolamentepuedautilizarlaaplicacinduranteundeterminadorangode tiempo. Enestoscasossedebeestablecereltiempoensegundosquedebedurarlasesinmedianteel mtododelobjetoAuthllamadosetExpireTimedespusdelaautenticacindelusuario.

16.5 Control de Autenticacin concurrente


Lasreglasdelnegocioenunaaplicacinpodrancontemplarqueunusuarioesteautenticado

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

150

enunaaplicacinsolamentedesdeunaterminaldetrabajo.Enotroscasoscuandosegenere unaautenticacindelusuariodesdeotramaquinaserequieraquesecierreseinvalidenlas sesionesabiertasenotrasterminales.

16.6 Autenticacin con Modelos


El adaptador Model permite realizar la autenticacin mediante un realm en una entidad del gestorrelacionalpordefectoenconfig/environment.ini.Laprincipalventajadeesteadaptador es que aprovecha las capacidades para atender mltiples peticiones concurrentes de autenticacinnquepuedatenerelgestorrelacional. Elsiguienteejemploilustracomorealizarunaautenticacinatravsusandoesteadaptador: Ejemplo:UsodelcomponenteAuthconmodelos
<?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:ParmetrosquerequiereeladaptadorAuthconmodelos Nombre class Loscamposqueconformanlaclavedeidentidaddebenserpasadoscomoparmetrosconsu respectivovalor. La identidad se construye apartir de los atributos de la entidad exceptuando los campos de passwordcontrasea. Descripcin Nombredelaclasedelmodeloqueserviracomorealm.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

151

16.7 Autenticacin con KerberosV


EsteadaptadorpermiteautenticarseusandoservidoresadministrativosKerberos5ascomo obtenerlaspoliticasasociadasalosusuariosautenticados. Puede Elsiguienteejemploilustracomorealizarunaautenticacinatravsusandoesteadaptador: Ejemplo:UsodelcomponenteAuthconunservidorKerberosV
<?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"); } } }

obtener

ms

informacin

sobre

servidores

Kerberos

en

http://web.mit.edu/kerberos/www/krb51.2/krb51.2.8/doc/admin_toc.html.

Tabla:ParmetrosquerequiereeladaptadorAuthconKerberosV Nombre server realm principal password Laidentidaddevueltaestconstadeloscamposrealmyusername. parmetroesobligatorio. El nombre de la base de datos con la politica de autenticacin en el servidorK5. Unacombinacinusuario/grupoconelqueseharlaautenticacin Contraseadelusuariousadoenprincipal. Descripcin Es el nombre de dominio direccin IP del servidor Kerberos V. Este

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

152

Advertencia: El uso de este adaptador requiere que este presente la extensin de PHP llamadaphp_kadm5.

16.8 Autenticacin con Radius


Este adaptador permite la autenticacin mediante protocolo Radius (RFC2865
http://www.faqs.org/rfcs/rfc2865).Esteadaptadorrequieredelaextensinphp_radiusque

seencuentradisponibleenplataformasUnix(FreeBSD,Linux)yWindows. Elsiguienteejemploilustracomorealizarunaautenticacinatravsusandoesteadaptador: Ejemplo:UsodelcomponenteAuthconunservidorRadius


<?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:ParmetrosquerequiereeladaptadorAuthconRadius Nombre server port parmetroesobligatorio. Puerto UDP donde escucha el servicio Radius. Si el puerto es 0 el adaptador localiza el servicio mediante el archivo /etc/services y como ltimaopcinelpuertoestndar1812. secret timeout max_retries LaclavecompartidaquesepasaralservidorRadius. Nmerodesegundosqueeladaptadoresperaporobtenerrespuestadel servidor. Nmerodeintentosquerealizaparatratardeautenticarse. Descripcin Es el nombre de dominio direccin IP del servidor Radius V. Este

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

153

username password

Nombredeusuarioaautenticar. Passwordelusuarioaautenticar.

Laidentidadseconstruyeconelcampousername.

16.9 Autenticacin con Digest


El adaptador de autenticacin Digest permite utilizar archivos planos de texto como realms paralacomprobacindeidentidaddelosusuariosdeunaaplicacin.UnarchivoDigesttiene lasiguienteestructura:
nombreusuario:nombrerealm:resumenpassword otronombreusuario:nombrerealm:otroresumenpassword

Cadalneadelarchivoconstituyeunaidentidad.Loscamposdelaidentidadestnseparados por : (dos puntos). El primer campo es el nombre del usuario, este puede tener la forma john.smith.Elsegundocampoeselrealmalqueperteneceelusuario,unarchivodigestpuede tener varios realms en l. Por ltimo el tercer campo es un resmen criptogrfico correspondiente al password del usuario. El algoritmo estndar de una sola va utilizado es MD5 pero es posible utilizar otro mediante la opcin de configuracin algorithm. Para un archivodigestcomoelsiguiente:
john.smith:Production:5ebe2294ecd0e0f08eab7690d2a6ee69

Elsiguienteprocesodeautenticacinessatisfactorio: Ejemplo:AutenticacinusandoeladaptadorDigest
<?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 autenticacin. Credenciales invalidas"); } } }

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

154

Ejemplo:Autenticacinusandounarchivoconotrocharsetdiferentealdeentrada
<?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 autenticacin. Credenciales invalidas"); } } }

Tabla:ParmetrosquerequiereeladaptadorAuthconDigest Nombre filename Descripcin Rutaalarchivodigest.Elarchivodebeserdetexto,siestdisponiblela extensindePHPMultibyteStringssucodificacinpuedesercualquiera quesoportesta. username password realm algorithm charset Laidentidadseconstruyeapartirdeloscamposusernameyrealmdelusuarioencontrado. Nombredelusuarioaautenticar Passwordplanodelusuario Realmalqueperteneceelusuarioaautenticar Callback del algoritmo que se utilizar para comparar el password del usuarioconlosdelarchivodigest.PordefectoesMD5. Codificacin que tiene el archivo de identidades digest. El valor por defectoesUTF8.

16.10 Autenticacin 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. EladaptadordeautenticacinLDAPsoportaautenticacinconservidoresdedirectorioscomo MicrosoftActiveDirectory,OpenLDAP,SunOpenDSMacOSXServerLDAPService.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

155

LanotacinDNDistinguishedNamerepresentanrutasaobjetosalojadosenunservidor LDAP.Cadaatributoestaindicadoconsunombreestandar,unigualysuvalor.Losatributos estn separados por comas y el orden de lectura de los atributos se realiza de derecha a izquierda. En el siguiente ejemplo se ilustra la autenticacin a un servidor LDAP a partir de los parmetrosdeunformulario: Ejemplo:UsodelcomponenteAuthconunservidorLDAP
<?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 autenticacin. Credenciales invalidas"); } } }

Los siguientes parmetros deben ser indicados para realizar una autenticacin satisfactoria enunservidorLDAP: Tabla:ParmetrosquerecibeeladaptadorAuthconLDAP Nombre server accountDomainName username password parmetroesobligatorio. Nombredeldominioalquepertenecelacuentaaautenticar. DNdelusuarioquesevaaautenticarenelservidor.Esteparmetro esobligatorio. Contraseadelusuarioquesevaaautenticar.Sielparmetronoes indicadoseproduceunintentodeautenticacinannimo. Descripcin Es el nombre de dominio direccin IP del servidor LDAP. Este

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

156

baseDN port identityAttributes

DNbasedondesehacelabsquedadelaidentidaddelusuario.Esel DNdelservidordondelacuentaseencuentraubicada. PuertodelservidordondeescuchaelLDAPServer. Atributos de la entrada del servidor LDAP que sern usados para construirlaidentidaddelusuarioautenticado.

accountCanonicalForm Indica la forma en la que el nombre de usuario esta canonizado, dependiendo del tipo de servidor LDAP el adaptador traduce este nombreautomticamentealadecuado.Unvalorde2indicalaforma normal, 3 usa la forma \\SERVIDOR\usuario y la 4 usuario@servidor. Laidentidadseconstruyeapartirdeloscamposdelregistrodelnombrecanonicodelusuario enelservidorLDAP. Advertencia: El uso de este adaptador requiere que este presente la extensin de PHP llamadaphp_ldap.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

157

17 Componente AuditLogger
17.1 Introduccin
El componente AuditLogger esta diseado para asistir las tareas de auditoria de sistemas creandologsquellevenelregistrodelasactividadesrealizadasenunaaplicacindenegocios porpartedecadaunodelosrolesquelautilizan.

17.2 Crear un componente de control


Ejemplo:Crearuncomponentedeusuarioparalaauditoradesistemas
<?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/KumbiaEnterpriseFrameworkManualdeReferencia

158

18 Componente Security
18.1 Introduccin
Elobjetivodeestecomponenteesofrecerfuncionalidadesvariasdeseguridadaaplicaciones web empresariales. Una caracterstica importante de este componente es un Firewall que permitedefinirreglasdeaccesoestilofirewallaunaaplicacin.

18.2 Subcomponente SecurityFirewall


18.2.1 Introduccin ElobjetivodelsubcomponenteSecurityFirewalleseldepermitiraldesarrolladoranalizarel entorno desde el cual se accede a un determinado punto de la aplicacin y validar si se permiteelaccesono. LasreglassedefinenenunarchivoXMLenelordendeprioridadcomodebenserevaluadas. UnejemploeselsiguientedocumentoXML: Ejemplo:DefinicinXMLdereglasparaSecurityFirewall
<?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 nombresdemaquina/direccionesip, as es posible indicarle al firewall que un mismo nombre de maquina tiene varias direcciones IP asignadas. En el ejemploladireccin::1delloopbackdeunamaquinaMacOSXesagregadacomolocalhost.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

159

Losnodosrulepermitendefinirlasreglasdelfirewall.Porobligacinestosnodosdebentener unatributotargetqueindicaqueeltipodeaccinaejecutarcuandosecumplelaregla. 18.2.2 Comoseevaluanlasreglas LasreglassonevaluadasenelordenenelquesedefinieronenelarchivoXML.Siunaregla cumple con las condiciones del entorno de la peticin entonces las dems reglas no son evaluadas. Es necesario tener en cuenta el orden en el que se definen para evitar que una regla sobreescribaaotrasynoselogreelobjetivoesperado. 18.2.3 TiposdeAtributosdeunaRegla UnaregladelSecurityFirewallpuedetenerlossiguientestiposdeatributos: Tabla:TiposdeatributosdeunareglaenSecurityFirewall Nombre source Descripcin Elorigendelapeticin.Puedeserunnombredemaquinaenlared, un nombre de dominio una direccin IP. Cuando se establece un nombre de maquina se utilizan las capacidades de resolucin de nombresquetengalamaquinaactualparaobtenerlasdireccionesIP correspondientes. La direccin IP del cliente se obtiene incluso cuandoelaccesoserealizamedianteunproxytransparente.LasIPs nopuedenserobtenidascuandoseusaunproxyannimo. mac LaNICdelatarjetaderedpuedeserobtenidacuandolaaplicacin es ejecutada en sistemas Linux/Unix y cuando los clientes se encuentranenlamismorangodereddelservidor. controller El nombre del controlador de aplicacin servicio web en la aplicacin activa que se est tratando de acceder. Se puede usar * comocomodnquecoincidaconcualquiercontrolador. action El nombre de la accin en el controlador solicitado que se est tratando de acceder. Se puede usar * como comodn que coincida concualquiernombredeaccin. isAjaxRequested IndicasilapeticinseesttratandodehacerusandoAJAX.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

160

isSoapRequested isSecure isFlashRequested hasHeader method

IndicasilapeticinseesttratandodehacerdesdeunclienteSoap. Indicasilaconexinserealizausandounaconexinsegura. IndicasilaconexinserealizadesdeunplugindeAdobeFlash. Si la peticin contiene un determinado encabezado. Mltiples encabezadospuedendefinirseseparandolosporpipes(|). Permite indicar el tipo de mtodo HTTP utilizado para solicitar la peticin.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

161

Parte3:Lalgicadedatos

19 Persistencia, Transacciones y Concurrencia


19.1 Introduccin
Elpapeldelacapadepersistenciaenunaaplicacinestraeryllevarlosdatosrequeridospara que la lgica 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 conexionesincompatibilidaddelasintaxisdelenguajeSQL. Kumbia Enterprise Framework ofrece una variedad de componentes para acceder a gestores relacionalesabajoaltonivel.

20 Componente Db
20.1 Introduccin
Kumbia Enterprise Framework implementa una doble capa de abstraccin para la manipulacin de la persistencia de la aplicacin cuando se utilizan bases de datos. El componenteDbadministratodolorelacionadoconlainteraccinabajonivelconlosgestores relacionales de base de datos, esto incluye abstraer detalles de conexin, utilizacin de lenguajeSQL,cursores,transacciones,etc. Estaindependenciaselogramediantelaimplementacindeadaptadoresquecreanpuntosde 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 resultadoesperado. MientrasqueelKumbiaPHPFrameworkofrecemltiplesopcionesparaconectarseabasesde datos,KumbiaEnterpriseFrameworkrecomiendasuusoenproduccinalosadaptadoresde MySQLyOracle,aunquealgunosotrostienenunamadurezaceptable.

20.2 Capas de acceso


El componente Db puede utilizar multiples capas de abstraccin existentes para el acceso a

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

162

gestores relacionales, de esta forma se aumentan las posibilidades y capacidades de aprovecharlafuncionalidaddelmotordesdeunaaplicacin. Lascapasdeaccesosoportadassonlassiguientes: Tabla:CapasdeaccesoagestoresrelacionalessoportadasporKumbiaEnterprise Nombre Native Descripcin Sin capa intermedia. Utiliza las extensiones PHP escritas en lenguaje C que implementan acceso directo a los motores de basededatos. PDO UtilizalacapaPHPDataObjects(PDO)escritaenlenguajeCque implementa acceso uniforme a los principales motores de base dedatosdecdigoabiertoycerrado. JDBC Utiliza la capa de acceso a bases de datos Java Database Connectivity (JDBC) de Java. Con lo que es possible utilizar driversJDBCylafuncionalidaddeestos.Solodisponiblecuando seusaIBMWebSpheresMash.

20.3 Adaptadores del componente Db


En la siguiente tabla se detalla los adaptadores de la distribucin de Kumbia Enterprise Frameworkjuntoconsuscaractersticasyestadodemadurez: Tabla:AdaptadoresdelcomponenteDbymadurezactual Nombre MySQL MySQLi Oracle PostgreSQL MicrosoftSQLServer IBMInformix SQLite Oracle CapadeAcceso Nativo(MySQL) Nativo(MySQLi) Nativo(oci8) Nativo PDO PDO PDO PDO EstadodeMadurez Estable Estable Estable Beta Beta Beta Beta Beta

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

163

Oracle

JDBC

Estable

Cada adaptador nativo hereda de la claseDbBase la cual implementa mtodos utiles validos para cualquier gestor relacional en forma de capa de abstraccin intermedia. La interface DbBaseInterface es implementada por cada adaptador de tal forma que cada uno mantenga unaestructuraconsistentequepermitaefectuaroperacionesbsicasyavanzadassinincurrir endetallesdebajoniveldependientesdecadagestorrelacional. LaestructuradelainterfaceDbBaseInterfaceeslasiguiente:
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/KumbiaEnterpriseFrameworkManualdeReferencia

164

20.4 Generacin de SQL


Cada gestor relacional sigue estndares del lenguaje SQL, principalmente de las especificacionesANSI92yANSI99.Muchosmotoresdebasededatosagreganextensionesal lenguajenoimplementanadecuadamentelosestndaresestablecidospordiversasrazones. Cuandoseescribenaplicacionesmultimotoresposibleencontrarciertasincompatibilidades que podran conllevar a reescrituras de cdigo que reabren el ciclo del software y podrian generarsobrecostos.LacapadeabstraccindeKumbiaEnterpriseFrameworkseencargade los detalles y genera la mayor parte de las sentencias de DML que soporta un gestor relacional. AniveldeaplicacinellenguajePHPofreceunaextensabibliotecadefuncionesquepermiten conectarse y efectuar operaciones sobre una gran variedad de gestores relacionales. Sin embargo,laformaenqueestanimplementadasestasfuncionesnoesestndaryconsistente por lo que el cambio de un gestor a otro conlleva a reescribir cdigo y se presentan las situacionesmencionadasanteriormente. Ejemplo:ConexintradicionalagestoresrelacionalesusandoPHP
//Conexin a Oracle $connId = oci_connect("scott", "tiger", "//192.168.0.40/XE"); //Conexin a Informix $connId = ifx_connect("stores@ol_srv1", "informix", "pass"); //Conexin 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 transparenteyfuncionencomoseespera. 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 mtodos que generan SQL optimizado para cada gestor relacional soportado aumentando las capacidades de cada aplicacindesarrolladaconelmismo.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

165

20.5 Conexiones a gestores relacionales por defecto


Cadaaplicacinproporcionaelarchivodeconfiguracinenvironment.iniendondesepueden establecerlosparmetrosdeconexindeacuerdoalosentornosdelasfasesdedesarrollode laaplicacin. Elarchivodeconfiguracinenvironment.inipredeterminadotienelasiguienteestructura: Ejemplo:Archivodeconfiguracinenviroment.inipredeterminado
[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 parmetros de conexin tienen el prefijo databse y pueden variar de acuerdo al gestor relacionalutilizado.Paraindicareladaptadorausarseutilizaelparmetrodatabase.type.A continuacinseexplicanlasconsideracionesdeconexinparalosmotoressoportados: 20.5.1 ConsideracionesparaOracle Oracle es muy conocido por sus capacidades de escalamiento y caractersticas, adems es liderenbasesdedatosyestdisponibleenvariasplataformas. El adaptador de conexin a Oracle requiere que la extensin de PHP oci8 este disponible, mediante esta es posible conectarse a Oracle en sus versiones 8i, 9i, 10g y 11g. Adicional a estoesnecesarioinstalarelOracleInstantClientapropiadoalaplataformarequerida. Estas Las variables de entorno ORACLE_HOME, ORACLE_SID, LD_PRELOAD Y NLS_LANG deben librerias pueden ser descargadas en la siguiente URL:
http://www.oracle.com/technology/tech/oci/instantclient/instantclient.html.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

166

estardefinidaspararealizarlaconexinaOracle. Parmetros de configuracin de la extensin OCI8 como oci8.max_persistent, oci8.persistent_timeoutyoci8.default_prefetchtambindeberantenerseencuenta. DeacuerdoalaversindelaextensinOCI8podranohabercompatibilidadconelgestor relacional requerido. En la siguiente tabla se presenta la compatibilidad de acuerdo a la versindeOCI8: Tabla:MatrizdecompatibilidadentrePHP,OCI8yclienteOracle Distribucin VersinPHP VersindeOCI8 Versionesdel clienteOracle soportado PHPCVS PHP Binario Windows PECLOCI8CVS ZendCoreforOracle2.5 Se puede construir 1.3.4 desdePHP4.3.9 5.2.5 1.2.3 Incluye el Oracle Instant Client 10 por lo que se soportan: 8i,9i,10g,11g Esteadaptadornosoportamltiplestransaccionessimultaneas,estoquieredecirquealtratar decrearunatransaccincuandoyahayunaactivasegenerarunaexcepcin. LosparmetrosdeconexinalconectarseaOracleson:
[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

5.2.7+ para 5.27+

1.2.5 1.2.5

8i,9i,10g,11g 10g,11g 9iR2,10g,11g

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

167

Ladescripcindelosparmetroseslasiguiente: Tabla:ParmetrosdeconexinaOracleusandoadaptadorNativo Parmetro database.username Descripcin Los usuarios en Oracle son propiedad de schemas que tienen elmismonombredelusuario.Esteparmetropermiteindicar elnombredelusuarioambiguamenteelschema. database.host database.password database.instance Nombre de la maquina direccin IP donde se encuentra el servidorOracle. Contraseadelusuarioconelqueserealizalaconexin. Nombre de la instancia de Oracle del servicio del TNS Listener. Cuando se usa Oracle Database Express este es XE pordefecto. database.port database.sort PuertodelservicioTNSListener.Pordefectoes1521. Este parmetro permite establecer como se har el ordenamiento de columnas que contengan valores alfanumricoscomoCHARVARCHAR2.Suvalorpordefecto esspanish_m.Enpaiseshispanohablanteslasletrasch,lly son consideradas parte del alfabeto y esta variable permite queelordenamientoseaadecuadoalalocalizacinutilizada. 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 sensiblesamaysculas/minsculas. database.charset Permite establecer el charset en el que se almacenan/devolveranvaloresenlasbasesdedatos.Elvalor Al32UTF8eselnombredeOracleparaelcharsetUTF8. database.territory Permite establecer el territorio en el que se encuentra la aplicacin. Dependiendo de este los formatos de fechas y de valores nmericos se ajusta a la localizacin requerida. Por defectoesspain. database.language El idioma en el que se presentarn los mensajes de error del motoryseformatearnlosresultadosnumricosydefechas.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

168

Pordefectoesspanish. 20.5.1.1 ConectaraOraclemedianteJDBC Tambin es posible realizar conexiones a Oracle usando el adaptador JDBC cuando la aplicacinhasidoimplementadaenuncontenedordeaplicacionesIBMWebSpheresMash. El archivo JAR ojdbc14.jar debe estar ubicado en el directorio lib de la aplicacin sMash siguiendolasconvencionesdearquitecturadelamaquina.PorejemplosiseejecutaenLinux sobreunprocesadorarquitecturax86entonceslaubicacines:
lib/x86/linux/ojdbc14.jar

Losparmetrosenenviroment.inidebenser:
[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 ConsideracionesparaMicrosoftSQLServer SQLServereselmotordebasededatosrelacionaldeMicrosoft.Laconexinaestemotores realizadaviaPHPDataObjects(PDO).EsteadaptadorsolosoportaconexionesaSQLServer desdeWindowsusandoconexionesODBCmedianteeldriverphp_pdo_odbc.Lasversionesde SQLServersoportadasvandesdela7.xhastala2008. 20.5.2.1 CreacindeunDSNODBCparaSQLServer A continuacin se ilustra el proceso de creacin de una conexin a SQL Server mediante ODBC. Utilizando un usuario con credenciales administrativas se abre el Administrador de OrigenesdeDatosODBCdesdePaneldeControl>HerramientasAdministrativas. EnestapantallaseseleccionalapestaaDSNdeusuarioysedaclickenelbotnAgregar paracrearunanuevoorigendedatos:

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

169

Acontinuacinseseleccionaeltipodedriverutilizado,sebuscaSQLServerysedaclicken siguiente:

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

170

Se da click en Finalizar para abrir el asistente de origenes de datos para SQLServer. Se presentalasiguientepantalla:

ElcamponombrehacereferencianombrealorigendedatosDataSourceName(DSN)que ser utilizado luego para realizar la conexin en la aplicacin. El campo servidor indica el nombre de la instancia y maquina donde est instalado SQL Server. Se da click en siguiente paracontinuar.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

171

EltipodeautenticacinsedebetenerencuentacuandoserealicelaconexindesdeKumbia Enterprise. Si se selecciona autenticacinn de Windows NT no ser necesario indicar el parmetroUIDyPWDdelusuariodeconexin.Enestecasoelusuarioconelqueseejecuteel proceso del servidor web se utilizar para autenticarse en SQL Server. Si se selecciona autenticacindeSQLServersedebenindicarlosparmetrosmencionadosanteriormente.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

172

Enlasiguientepantallasepuedeconfigurarlabasededatospredeterminada.Lasopciones UsaridentificadoresentrecomilladosANSIyUsarnulos,rellenosyadvertenciasANSIdeben estarseleccionados. Enestapantallasepuedenactivarotrasopciones,alterminarsedaclickenFinalizar:

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

173

Laltimapantallapermiteprobarlaconexin,sitodoestabiennohabrproblemaalefectuar unaconexindesdeKumbiaEnterprise.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

174

Losparmetrosrequeridosdeconexinalconectarseconeladaptadormssqlson:
[production] database.layer = pdo database.type = mssql database.dsn = "DRIVER={SQL Server};SERVER=SQLEXPRESS;DATABASE=test"

UsandounDSNdeUsuario: Ejemplo:ConexinaSQLServerestableciendounDSN
[production] database.layer = pdo database.type = mssql database.dsn = "bankdb"

Estableciendoelusuarioycontrasea: Ejemplo:ConexinaSQLServerestableciendousuarioycontraseaconDSN
[production] database.layer = pdo database.type = mssql database.dsn = "bankdb;UID=sa;PWD=mypass"

EstableciendoelusuarioycontraseasinDSN: Ejemplo:ConexinaSQLServerestableciendousuarioycontraseasinDSN
[production] database.layer = pdo database.type = mssql database.dsn = "DRIVER={SQL Server};SERVER=SQLEXPRESS;DATABASE=test;UID=sa;PWD=pass

Tabla:ParmetrosdeconexinaMicrosoftSQLServerusandoPDO Parmetro database.pdo database.dsn Descripcin Indica que se debe cargar un Adaptador PDO. Su valor debe serOnparaquetengaefecto. IndicalosparmetrosdelDataSourceName(DSN)delorigen datos.SERVEReslamaquinadondeestinstaladalainstancia delframework.DATABASEeselnombredelabasededatosde trabajo. UID es el nombre del usuario con el que se har la conexin. PWD es el password del usuario. DRIVER es el nombre del driver ODBC para SQL Server, normalmente es SQLServer.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

175

20.5.3 ConsideracionesparaMySQL MySQL es uno de los motores Open Source ms populares y con mayor presencia en aplicaciones para Internet. Existen 2 adaptadores que permiten la conexin a MySQL, el primeroesmysqlqueusalaextensindePHPnativadelmismonombreyquepermitela conexin usando librerias cliente desde la versin 4.1. La segunda es mysqli que utiliza la extensindelmismonombreyquetieneunafuncionalidadyrendimientosuperioraladela extensin mysql. Ambos adaptadores soportan transacciones en sesiones de conexin diferentes. KumbiaEnterpriseFrameworkpuedetrabajarconMySQLcuandoestenmodoSQLestrictoy noestricto.EnmodoestrictosegenerarnexcepcionesDbInvalidFormatExceptioncuandose tratedeinsertarunvalorquenotengaunformatoadecuadoaltipodedatorequieridodela columnadeeste. Losparmetrosrequeridosdeconexinalconectarseconeladaptadormysqlson: Ejemplo:Parmetrosdeconexinrequeridosusandoeladaptadornativodemysql
[production] database.type = mysqli database.host = localhost database.username = root database.password = my_password database.name = production_db

Losposiblesparmetrosdeconexinalconectarseconeladaptadormysqlson: Ejemplo:Posiblesparmetrosdeconexinamysql
[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

Ladescripcindelosparmetrosanterioreseslasiguiente: Tabla:ParmetrosdeconexinaMySQLusandoeladaptadormysql

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

176

Parmetro database.username database.password database.host conexin.

Descripcin El nombre de usuario de MySQL con el que se efectuar la ElpassworddelusuariodeMySQL. Servidor de MySQL. Se puede utilizar el string de conexin hostname:puerto :/path/al/socket cuando se trata de localhost.

database.name database.port database.autocommit

Nombredelabasededatos. Puerto del servidor de MySQL al especificarse se hace la conexinporTCP/IP. Cuando el valor es On. Indica si la sesin 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 defectoesOff.

database.compression

Indica si el cliente MySQL debe comprimir todo el trfico de red entre la aplicacin y el servidor de base de datos. Por defectoesOff

database.ssl database.interactive

Indica si se debe encriptar el trfico entre la aplicacin y el servidordebasededatosmedianteSSL.PordefectoesOff. Indica si se debe crear una sesin interactiva en vez de una conexintemporal.PordefectoesOff.

Losparmetrosrequeridosdeconexinalconectarseconeladaptadormysqlison: Ejemplo:Parmetrosdeconexinrequeridosparamysqli
[production] database.type = mysqli database.host = localhost database.username = root database.password = my_password database.name = production_db

Losposiblesparmetrosdeconexinalconectarseconeladaptadormysqlison: Ejemplo:Configuracindelaconexinusandomysqli
[production] database.type = mysqli

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

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,aes192cbc,aes256-cbc

Losparmetrosadicionalesquesoportaeladaptadormysqlison: Tabla:Parmetrosdeconexinsoportadosusandomysqli Parmetro database.socket database.charset database.key Descripcin Aplicacuandoelhostellocalhostypermiteestablecerelpath alsocketUNIXalnamedpipeenWindows. Permite establecer el charset utilizado por el cliente MySQL paraenviarlainformacinalservidor. La ruta a donde se encuentra el archivo de llave compartida. EsteparmetrosoloaplicacuandolaopcinSSLestOn.Por defectosuvaloresNULL. database.cert database.ca La ruta al archivo de certificado. Este parmetro solo aplica cuandolaopcinSSLestOn.PordefectosuvaloresNULL. La ruta al archivo certificate authority. Este parmetro solo aplica cuando la opcin SSL est On. Por defecto su valor es NULL. database.capath La ruta al archivo que contiene certificados SSL validos en formatoPEM.EsteparmetrosoloaplicacuandolaopcinSSL estOn.PordefectosuvaloresNULL.Pordefectosuvalores NULL. database.cipher Una lista de mtodos de cifrado para usar en la encriptacin SSL.EsteparmetrosoloaplicacuandolaopcinSSLestOn. PordefectosuvaloresNULL.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

178

20.5.4 ConsideracionesparaIBMInformix KumbiaEnterpriseutilizaPHPDataObjects(PDO)paraaccederabasesdedatosIBMInformix. Es posible realizar conexiones a Informix (IDS) versin 7.x, Universal Server (IUS) 9.x y a InformixDynamicServer2000,10y11.Lossiguientesrequisitossonnecesariospararealizar unaconexinsatisfactoriaaestemotor: PHPdebeestarcompiladoconlaextensinpdo_informix,estapuedeserobtenidavia PECLalcompilarPHPdesdeelcdigofuente.

Cuando se compila desde el cdigo fuente la opcin de configuracin debe incluir


./configure --with-pdo-informix=/path/to/SDK[,shared]

La extensin PECL puede ser instalada usando el comando pecl

install

pdo_informixenentornosUnix.Paraunacompilacinsatisfactoriadelaextensin

elclienteSDKdeIBMparaInformixdebeestarinstaladoenlamaquinaelservidor Informixensimismo. La variable de entorno INFORMIXDIR debe apuntar al directorio de instalacin de informixdelclientSDK. ESQL/Cesnecesarioparatrabajarconinformix.ElInformixClientSDKcontieneeste software.ElclientSDKparaIBMInformixpuedeserdescargadodesdeelsitiowebde soportedeIBMen http://www-306.ibm.com/software/data/informix/tools/csdk/. SiestutilizandoInformixversin1011noesnecesarioinstalarCSDKyaqueeste vieneincluidoenladistribucindelservidor. Una vez las extensiones php_pdo y php_pdo_informix se encuentren disponibles la conexin puederealizarsedelasiguienteforma: Ejemplo:ConfiguracindelaconexinaIBMInformix
[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

ElservidordeInformixdebeestarconfiguradoparaaceptarconexionesmediantetcp medianteelmduloonsoctcp.

ParmetrosdeconexinconInformix:

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

179

Tabla:ParmetrosdeconexinaIBMInformixconPDO Parmetro database.pdo database.dsn Onparaquetengaefecto. LosparmetrosdeconexindelDataSourceName.Elparmetro host indica el nombre del maquina direccin IP donde est instalado el Informix. Service es el puerto donde se realizar la conexin 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 usanpaginadoresporejemplo. Otras opciones que se pueden enviar en el DSN son: TraslationOption, permite utilizar una librera de traduccin de mensajes,convalor0permitesolucionarunproblemacomnen unixODBC. IsolationLevel: Indica el nivel de isolacin de la conexin. 0 es Predeterminado,1esReadUncommited,2esReadCommited,3 esRepeteableRead,4esSerializabley5esLastCommited. CursorBehavior:Cuandoes0elcursorsecierraautomticamente alrecorrerlosregistros,cuandoes1sepreserva. ClienteLocale: Permite establecer la localizacin del cliente. Por defectoesen_US.CP1251 DatabaseLocale: Permite establecer la localizacin de la base datospordefectoes:en_US.819 AutoCommitOptimization: Indica si el driver debe efectuar optimizacinparaconexionesnotransaccionales. Descripcin Indica que se debe cargar un adaptador PDO. Su valor debe ser

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

180

database.username database.password

Nombredelusuarioquerealizarlaconexin. Contraseadelusuario.

20.5.4.1 ConfiguracindelServidor Esposiblequedebacambiarelusuarioconelqueseejecutanlosprocesosdelservidorwebal usuario informix un usuario del grupo informix. En el caso de Apache Web Server puede modificarestocambiandolosparmetrosUseryGroupas:
User informix Group informix

SielservidorestinstaladoenWindowsyseusaMicrosoftIISsedebeentraralaconsolade administracin de servicios. Puede ingresar a ella mediante el comando services.msc en el cuadrodedialogoejecutar.SedaclickderechoenelservicioInformixIDSNombreyluego enpropiedades.Enlapestaainiciodesesinsecolocaelusuarioconpermisosdelmotory luegoclickenAceptar. Lasiguienteesunaconfiguracindelasvariablesdeentornoparaunprofileparaelusuario informixenunservidorUnixWindows: Ejemplo: Variables de entorno recomendadas para realizar una conexin 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

ElarchivoINFORMIXSQLHOSTSdebeteneralmenosunserviciotcp/ipdisponible:
ol_server onsoctcp localhost informixserver

Elarchivo/etc/servicesdebeincluirladescripcinTCPparaelserviciocreado:

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

181

informixserver

9800/tcp # Informix Dynamic Server

20.5.4.2 ConsideracionesconTransacciones EldesarrolladordebeactivarelloggingdelabasededatosaUnbufferedLoggingBuffered Logging usando la herramienta onmonitor mediante el comando ontape B dbname, de lo contrarioeladaptadorgenerarunaexcepcinaltratarderealizaruncommitunrollbacka unatransaccin. Informixnogenerauntimeoutcuandoregistrosquesevayanamodificarleerestensiendo modificados en otra transaccin. Kumbia Enterprise generar una excepcin como [Informix][InformixODBCDriver][Informix]Couldnotdoaphysicalorderreadtofetchnext row. sqlerrm(t) (SQLFetchScroll[244] at /root/PDO_INFORMIX/informix_statement.c:889)] (244)detipoDbLockAdquisitionTimeout. Todos los niveles de isolacin son soportados en runtime. El nivel de isolacin CURSOR SCALABILITYesvalidadoconISOLATION_SERIALIZABLE. Nota: IBM Informix no soporta la extensin del lenguaje SQL LIMIT por lo que el desarrolladordebeasegurarsequelosresultadosdevuelvaelnmeroderegistrosrequeridos viacondicionesenlaclausulaWHERE. 20.5.5 ConsideracionesconSQLite SQLite es un motor de base de datos escrito en C que es embebible en aplicaciones web de bajaconcurrencia.LalibreraSQLitepermiteadministrarbasesdedatosquesecreanenun soloarchivoyquesepuedendistribuirjuntoconlaaplicacin. Como se mencion anteriormente las bases de datos SQLite no estn recomendadas para grandesaplicacionesconaltotrficoyaccesoconcurrenteelevado. KumbiaEnterprisesoportaSQLiteversin3mediantelacapadeabstraccinPDO(PHPData Objects)porloqueserequierequelasextensionesdePHPpdoypdo_sqliteestendisponibles porlaaplicacin.Esteadaptadornosoportamltiplestransaccionessimultneas. LosparmetrosdeConexinaSQLiteson:

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

182

Ejemplo:DefinirunaconexinaSQLiteconPDO
[development] database.layer = pdo database.dsn = "data/company.db" database.type = sqlite

Tabla:ParmetrosdeconexindeladaptadordeSQLiteconPDO Parmetro database.layer database.dsn Descripcin Indica que se debe cargar un Adaptador PDO. Su valor debe serpdoparaquetengaefecto. Cuando se trata de SQLite indica la ruta al archivo base de datos.Laextensin.dbesopcionalperoesmsrepresentativa. El PATH del archivo puede ser un path absoluto desde el directoriodondeestinstaladalainstanciaunpathrelativo.

20.6 Pool de Conexiones


ElcomponenteDbBasemediantelaimplementacindeunSingletoncontrolaquecadavezque sesolicitelaconexinalabasededatossedevuelvalamismaconexinevitandolacreacin de mltiples conexiones al gestor relacional de forma innecesaria aumentando los recursos requeridosporlaaplicacin. ElmtodoestticoDatabase::rawConnect()devuelvelamismaconexinactivasinimportarel nmero de veces que sea invocado, si aun no existe una conexin entonces la crea. Los parmetros de conexin son los establecidos por entorno activo en environment.ini. Si se requiere una nueva conexin al gestor se puede enviar true como primer parmetro y si se requiererenovarlaconexinesdecirreemplazarlaconexindelSingletonseenviatruecomo segundoparmetro. 20.6.1 ConexionesdeBajoNivel Es posible establecer conexiones de bajo nivel a mltiples motores independientemente del gestor relacional requerido. El subcomponente DbLoader permite tanto cargar el adaptador activoestablecidoenenviroment.inicomounocualquierausandoelmtodoestticofactory. El primer parmetro corresponde al nombre del adaptador requerido para efectuar la conexin,elsegundoesunvectorquecontienelasopcionesdeconexin.Estassonlasmismas utilizadasenunaseccindeunarchivodeconfiguracinenviroment.ini.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

183

Ejemplo:EstablecerunaconexinaungestorrelacionalmedianteDbLoader::factory
<?php $db = DbLoader::factory('MySQL', array( "host" => "localhost", "username" => "root", "password" => "mypass", "name" => "bankdb" )); print_r($db->fetchAll(SELECT * FROM accounts));

SisedeseausarlosadaptadoresPDOhayqueindicarlaopcinadicionalpdo=>trueenel vectordeconfiguracin. Ejemplo:EstablecerunaconexinaungestorrelacionalmedianteunadaptadorPDO


<?php $db = DbLoader::factory('MySQL', array( "pdo" => true, "host" => "localhost", "username" => "root", "password" => "mypass", "name" => "bankdb" )); $db->fetchAll("SELECT * FROM account");

Un descriptor string tambin puede ser usado para establecer una conexin. Estos tienen el mismoformatoqueunDSNdePDO. Ejemplo:Establecerunaconexinmedianteundescriptorstring
$descriptor = mysql:host=localhost;username=root;password=mypass;name=bankdb; $db = DbLoader::factoryFromDescriptor($descriptor);

20.6.2 TrazarConexiones La propiedad de las conexiones de generar trazas permite obtener una lista de todas las operacionesSQLdebajonivelejecutadasenunasessinalgestorrelacional. ParaactivarlatrazaenunaconexinsedebellamaralmtodosetTracingconparmetrotrue apartirdelmomentodondesedeseaempezarlatraza: 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/KumbiaEnterpriseFrameworkManualdeReferencia

184

$results2 = $db->fetchAll(SELECT * FROM customers WHERE status = Active); foreach($db->getTracedSQL() as $sqlStatement){ echo $sqlStatement.\n; }

20.7 Generar Profiles de ejecucin de SQL


LosobjetosdelcomponenteDbpermitengenerarProfilesdelaejecucindesentenciasSQL que se envian al gestor relacional. La informacin generada incluye los tiempos en milisegundosquedurlaejecucindecadasentenciayaspoderidentificarcuellosdebotella enlaaplicacin. Ejemplo:Activarelprofilingdesdeobjetodeconexinaungestorrelacional
<?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 parmetro de setProfiling(). Ejemplo:Definirunaclasedeprofilepersonalizada
<?php $db = DbBase::rawConnect(); $db->setProfiling(new MyProfiler());

LainterfaceDbProfilerInterfaceexigelaimplementacinde:
interface DbProfileInterface { public public public public public public public } function function function function function function function startProfile($sqlStatement); stopProfile(); getNumberTotalStatements(); getTotalElapsedSeconds(); getProfiles(); reset(); getLastProfile();

20.8 Manejar Excepciones de Db


Crear la instancia del adaptador directamente en el constructor del mismo crea automticamenteunaconexinalabasededatos.Siocurrenproblemasalhacerlaconexin alguno de los parmetros es invalido se genera una excepcin en la misma la cual debe ser controladaporeldesarrollador.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

185

Lasexcepcionessoncontroladasmedianteunbloquetry/catchquecaptureunaexcepcindel tipoDbException: Ejemplo:CapturarunaexcepcinDbExceptiongeneradaporeladaptadordeconexin algestorrelacional


<?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 TiposdeExcepcioneslanzadasporelcomponenteDb Excepcin DbException DbLockAdquisitionException Descripcin Excepcingenericalanzadaporadaptador deconexinalgestorrelacionalutilizado. Excepcin lanzada cuando la transaccin actualenlaconexinnopuedeefectuarun bloqueo sobre algn recurso por ejemplo unatablaunaseriederegistros. DbSQLGrammarException Excepcin lanzada cuando se envia una sentencia SQL mal formada con errores desintaxis. DbContraintViolationException Excepcin lanzada cuando la operacin de modificacin actualizacin viola un constraintdellavefornea. DbInvalidFormatException Excepcin lanzada cuando se trata de insertaractualizarunvalorenunatabla conunformatoerroneo. 20.8.2 InformacinextendidadeexcepcionesgeneradasporDb Las excepciones generadas por el componente Db ofrecen informacin extendida del origen

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

186

de una excepcin. Cuando la aplicacin se encuentra en modo debug esta informacin se puedevisualizarenpantalla.Lareferenciadelapantalladeexcepcioneseslasiguiente: Enlaesquinasuperiorderechasepresentaeltipodeexcepcingenerada:

DespusdeestaelmensajequehaenviadoelgestorrelacionalylasentenciaSQLquegener laexcepcin.Enestecasotantoeltipodeexcepcincomoelmensajedeerrorindicaquela sentenciaSQLestamalformadatieneerroresdesintaxis. El id de conexin es un cdigo interno que identifica el recurso utilizado para conectarse al motor de base de datos. El mensaje de la excepcin informa que conexin estaba activa cuandoseprodujolaexcepcin.ElidaparecealfinalcomoResourceid#64. El codigo de error enviado por el motor tambin puede resultar de ayuda en algunos casos. Estesemuestraalfinaldelmensajedeerrorentreparntesis.

Como la aplicacin se encuentra en modo debug se visualiza la traza de ejecucin de la excepcin.SiKumbiaEnteprisedetectaquelaexcepcinsehageneradoenunarchivodela aplicacin entonces se muestra el fragmento de cdigo resaltando la lnea exacta donde se generlaexcepcin:

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

187

DebajodelatrazaseencuentraelcuadroDatosdelaconexinactivaypresentaatributos delestadodelaconexinenelmomentodelaexcepcin:

Enestecasolatrazaseencuentradesactivada,alactivarlaseobtendratodaslasintrucciones SQLqueseejecutaronenlamismaconexinpreviamenteaqueseprodujeralaexcepcin.La traza se puede activar declarativamente en el modo activo en config/environment.ini programacionalmente pasando el parmetro tracing => true al constructor del objeto conexin. Elarchivoconfig/environment.inientoncesquedaraas: Ejemplo:Activarlatrazaenelarchivoconfig/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

Alejecutarnuevamenteelprocedimientosepuedevisualizarlatrazadelaconexin:

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

188

ElcampoTrazadiceSIydebajodeesteelnuevocampoContenidodelaTrazamuestra enordencronolgicolassentenciasSQLgeneradasenlaconexinactiva. Ms debajo se visualiza el cuadro datos de entrada, en l se detalla la informacin que fue enviada al procedimiento desde el formulario enlace anterior. El objetivo del cuadro es identificarsilosdatosdeentradapuedenserloscausantesdelproblema: Losvaloresdeentradasemuestranenmododetalladoayudandoasaconocersucontenido msfcilmente. Si la informacin generada no es suficiente para identificar la causa de la excepcin puede utilizar el componente Debug el cual proporciona ayudas para realizar procedimientos tradicionalesderastreodeprocesos.

20.9 Tipos de Resultado al Obtener de Registros


Cadaadaptadorimplementalosmismostiposdevectoralobtenerregistros,estoserefierea la forma en la que los vectores devueltos estan indexados. Los mtodos inQuery, fetchOne y fetchAll permiten establecer en su segundo parmetro los valores de las constantes que permitencambiarlaformaenlaqueestandispuestoslosresultadosalobtenerlos. Tabla:Tiposdeconstantesparaobtenerlosregistrosdeunresultado Constante Db::DB_NUM Db::DB_ASSOC numricamente. 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. Descripcin Devuelve cada registro como un vector indexado solamente

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

189

CuandoserealizanJOINsenmltiplestablasesposiblequeelnombre delosindicesserepitaporlocualesnecesarioimplementaraliaspara lascolumnasrepetidas. Para todos los gestores relacionales los indices se encuentran en minsculas. Db::DB_BOTH Devuelve cada registro indexado tanto numricamente como asociativamente. El nmero de elementos por vector resultado es el dobledelnmerodecolumnasdevueltoenlasentenciaSELECT.

20.10 Leer registros


LossiguientesmtodoscorrespondenalAPIdelcomponenteDbquepermitenleerregistros delasentidades: publicresource|falsequery(string$sqlQuery) Envia una sentencia SQL al gestor relacional. La sentencia puede devolver registros o no devolverlos. Ejemplo:EnviarunasentenciaSQLalgestorrelacionalmedianteelmtodoquery()
<?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"; }

publicarrayfind(string$tableName,string$whereClause,string$fields=,string$orderBy=1) RealizaunaconsultaSELECTenunatablaenformaabstraida. Ejemplo:Realizarunabsquedausandoelmtodofind()


<?php //Mostrar todos los clientes activos $db = DbBase::rawConnect(); $resultset = $db->find(customers, status = Active); foreach($resulset as $row){ print $row[name].\n; }

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

190

publicarrayinQuery(string$sqlQuery,int$fetchType=db::DB_BOTH) DevuelvelosresultadosdeunaconsultaSQLenunarray.Elparmetro$fetchTypeserefierea lasconstantesdb::DB_ASSOC,db::DB_NUMydb::DB_BOTHqueeseltipodeindexamientodel vectordevueltoporregistro. publicarrayfetchAll(string$sqlQuery,int$fetchType=db::DB_BOTH) Obtiene todos los resultados de una consulta SQL en un array. Es un alias para el mtodo inQuery. publicarrayinQueryAssoc(string$sqlQuery) Obtiene todos los resultados de una consulta SQL en un array. Cada registro es un array indexadoasociativamente. 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; }

publicarrayinQueryNum(string$sqlQuery) Obtiene todos los resultados de una consulta SQL en un array. Cada registro es un array indexadonumricamente. Ejemplo: Realizar un consulta que devuelve los registros como vectores indexados numricamente
<?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 }

publicarrayfetchOne(string$sqlQuery,int$fetchType=db::DB_BOTH) DevuelveunsoloregistroenunarraydelaconsultaSELECTen$sqlQuery.Elparmetro$type se refiere a las constantes db::DB_ASSOC, db::DB_NUM y db::DB_BOTH que es el tipo de

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

191

indexamientodelarraydevueltoporregistro. Ejemplo:Obtenerunresultadoparaconsultasquedevuelvenunsoloregistro
<?php $db = DbBase::rawConnect(); $customer = $db->fetchOne(SELECT * FROM customers WHERE id = 124);

publicarrayfetchArray(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 establecidoconsetFetchMode. publicvoidnumRows(resource$resultQuery=null) Devuelve el nmero de filas obtenidas en la ultima consulta SQL ejecutada en el objeto adaptador. Es posible establecer el recurso devuelto por el mtodo query para obtener esta informacin. Ejemplo:Obtenerelnmeroderegistrosquedevuelveunaconsulta
<?php $db = Db::rawConnect(); $result = $db->query("SELECT id, name FROM customer WHERE status = 'Active'"); print "Hay ".$result->numRows($result)." clientes activos";

publicbooleandataSeek(int$number,resource$resultQuery=null) Permiteestablecerlaposicinenelcursorinternoelestablecidopor$resultQueryhaciendo queelprximoregistroqueobtengafetchArrayseaelnmero$number. Ejemplo:Moverelpunterodelresultadodeunaconsulta


<?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/KumbiaEnterpriseFrameworkManualdeReferencia

192

publicresourcegetLastResultQuery() ObtieneelltimorecursogeneradoenunaconsultaSQLmedianteelobjeto. Ejemplo:ObtenerelltimoresulsetgeneradoconDb::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"; }

publicstringlimit(string$sqlQuery,int$number) La extensin del la sentencia SQL SELECT llamada LIMIT permite especificar al gestor relacionalquenodebedevolvermsdelnumeroderegistroslimitadosa$number.Notodos los gestores relacionales implementan esta extensin y otros permiten hacerlo utilizando otrosprocedimientos. Este mtodo permite crear una sentencia SQL que reproduzca la funcionalidad LIMIT en formatransparente. Ejemplo:AplicarlaextensindellenguajeSQLLIMITaunaconsulta
<?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


LossiguientesmtodospermitenlageneracinyejecucindesentenciasSQLquepermitenla manipulacinderegistros: public boolean insert(string $table, array $values, array $fields=array(), boolean $automaticQuotes=false) PermiterealizarunainsercinsinusarSQLdirectamente.ElSQLesgeneradoestdeacuerdo al gestor relacional utilizado. Notese que por defecto el mtodo espera que los valores a insertar esten correctamente escapados, el parmetro $automaticQuotes permite que se agregen comillas simples y se escapen los valores usando la funcin addslaches() en forma

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

193

automtica. Las columnas que son omitidas se les aplica la regla del gestor relacional DEFAULT si esta existe,encasocontrarioseinsertanvaloresnulos. Ejemplo:Realizarunainsercincon$automaticQuotesysinellas
<?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 automtica $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 parmetro $automaticQuotes y se requiere insertar expresiones ejecucindefuncionesdelabasededatosesnecesarioindicarestosusandoinstanciasdela claseDbRawValue. Ejemplo:Insertarunvalorexpresindelabasededatos
<?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) PermiterealizarunaactualizacinsinusarSQLdirectamente.ElSQLesgeneradodeacuerdo al gestor relacional utilizado. Notese que por defecto el mtodo espera que los valores a actualizar esten correctamente escapados, el parmetro $automaticQuotes permite que se agregencomillassimplesyseescapenlosvaloresusandolafuncinaddslaches(). Ejemplo:Realizarunaactualizacindedatos
<?php

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

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); }

publicvoiddelete(string$table,string$whereCondition=) PermiterealizarunaeliminacinderegistrossinusarSQLdirectamente.ElSQLesgenerado deacuerdoalgestorrelacionalutilizado. Ejemplo:Realizarunaeliminacindedatos


<?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); }

publicintegeraffectedRows(Resource$resultQuery=null) Devuelve el numero de filas afectadas por una operacin de insercin, actualizacin borrado. El parmetro $resultQuery permite cambiar el recurso devuelto por otra ejecucin delmtodoqueryexec. Ejemplo: Obtener informacin de los registros afectados en una operacin de manipulacindedatos
<?php $db = Db::rawConnect(); $db->query("DELETE FROM customer WHERE status = 'I'"); print "Filas borradas = ".$db->affectedRows();

20.12 Administrar Transacciones


publicbooleanbegin() Permiteiniciarunatransaccinenlaconexinutilizada. Ejemplo:Usodetransaccionesabajonivel

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

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(); }

publicbooleanrollback() Permiteanularunatransaccinenlaconexinutilizada. publicbooleancommit() Permitehacercommitaunatransaccinpendienteenlaconexinactual. publicstringforUpdate(string$sqlQuery) GeneraunSQLqueefectaunbloqueonocompartidodelgrupoderegistrosseleccionados. publicstringsharedLock(string$sqlQuery) GeneraunSQLqueefectaunbloqueocompartidodelgrupoderegistrosseleccionados. publicvoidsetIsolationLevel(int$isolationLevel) Permite establecer el nivel de isolacin de la conexin. Los niveles de isolacin deben estar disponiblesenelgestorrelacional,consulteladocumentacinsitienedudasdeello.Elvalor delparmetro$isolationLevelesalgunadelasconstantes: Tabla:DescripcindeconstantesdenivelesdeIsolacin Valor 1 2 Nombre ISOLATION_READ_UNCOMMITED ISOLATION_READ_COMMITED Descripcin LosSELECTsseejecutanenun mododenobloqueo. Las consultas se ejecutan un un modo de lecturas

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

196

consistentesconnobloqueo. 3 ISOLATION_REPEATABLE_READ Gestores transaccionales normalmente trabajan sobre estemododeisolacin. 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 MODEbloqueandoelgrupode registros obtenidos en una consultaamodosololectura. publicbooleanisUnderTransaction() Permiteconocersilaconexinseencuentrabajounatransaccinactiva. publicvoidgetHaveAutoCommit() PermiteconocersilaconexintieneautocommitniveldeisolacinREADUNCOMMITED.

20.13 Crear, Cerrar y obtener informacin de conexiones


publicDbrawConnect(boolean$newConnection=false,boolean$renovate=false) Obtiene un objeto conexin a la base de datos del entorno actual con los parmetros establecidosenelarchivoconfig/enviroment.ini.EstemtodoimplementaelpatrnSingleton controlandoquesolounainstanciadelaconexinsecreecadavezquesehaceelllamadoal mismodesdecualquierpartedelaaplicacin. Ejemplo:Obtenerlaconexinpordefectoalgestorrelacional
<?php //Crear o obtener la ltima conexin creada $db = DbBase::rawConnect(); //Crear una nueva conexin sin cambiar la conexin del Singleton $db = DbBase::rawConnect(true); //Crear una nueva conexin renovando la conexin del Singleton $db = DbBase::rawConnect(true, true);

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

197

publicResourceConnectionconnect(stdClass$descriptor) Establecelaconexinalgestorrelacional. Ejemplo:CrearunaconexinusandoelmtodoDb::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"; }

publicresourcegetConnectionId() Obtiene el recurso interno de bajo nivel con el que se identifica la conexin al gestor relacional. publicvoidclose() Cierralaconexinactualconelgestorrelacional.Silaconexinespersistentenosecerrar. publicvoidsetReadOnly(boolean$readOnly) Establecesilaconexinserdesololectura.Enesteestadosegenerarunaexcepcincuando setratederealizarunainsercin,modificacineliminacindedatos. publicvoidisReadOnly() Permitesabersilaconexinesdesololecturano.

20.14 Informacin de Errores


publicstringerror(string$errorString=,resource$resultQuery=null) Devuelveinformacindelltimoerrorgeneradoeneladaptador. publicintegernoError(resource$resultQuery=null) Devuelveelnmerodelltimoerrorgenerado.

20.15 Obtener el valor de la columna identidad


Algunos gestores relacionales soportan columnas identidad, es decir, que manejan un consecutivoautonumricoparadiferenciarunvocamentecadaregistroenunatabla. publicintegerlastInsertId(string$table=,string$identityField=)

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

198

Obtieneelltimovalorinsertadoenunacolumnaidentidad.Algunosgestoresrelacionalesno soportanestetipodecolumnasyporelloesnecesarioobtenerelvalorbuscandoelmximo valorinsertadoenelcampollaveprimaria. publicbooleantableExists(string$table,string$schema=) Permite consultar si una relacin con el nombre $table existe en el schema de la conexin actualelindicadousandoelparmetro$schema.

20.16 Obtener informacin de Tablas


publicarraygetFieldsFromTable(string$tableName) Este mtodo obtiene los campos de una tabla en un vector. El vector puede ser indexado numricamenteasociativamente: Ejemplo:ObtenerloscamposdeunatablaconDb::getFieldsFromTable
<?php

$db = DbBase::rawConnect(); $fields = $db->getFieldsFromTable(customer);

publicstringfieldName(int$number,Resource$resultQuery=null) Obtiene el nombre de un campo en la posicin establecida por $number del resultado $resultQuery. publicarraylistTables(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 tambin se devuelven las vistas a las que tengaaccesoelusuariodelaconexinactiva. publicarraydescribeTable(string$tableName=,string$schemaName=) Devuelveunarrayconladescripcindeloscamposdeunatablajuntoconsustiposdedatos.

20.17 Crear y Eliminar Tablas


public boolean createTable(string $tableName, array $definition, array $index=array(), array $tableOptions=array()) Permitecreartablasfsicastemporalesenlaconexinactiva.Elparmetro$definitionesun vectorconlalistadecamposdelatablaysusatributos.Elparmetro$indexpermiteindicar

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

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 tablespaceenelcasodeOracle.Devuelveunvalorbooleanoindicandoelxitodelaoperacin. Ejemplo:Crearunatablausandounadaptadorenespecial
<?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) ));

Tambinesposiblecrearlatablausandolaconexinpredeterminadadelentornoactual: Ejemplo:Crearunatablausandolaconexinpredeterminada
<?php $db = Db::rawConnect(); $db->createTable(example, array( "id" => array(

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

200

), "nombre" => array( "type" => Db::TYPE_VARCHAR, "notNull" => true, "size" => 120 ) ));

"type" => "notNull" "primary" "auto" =>

Db::TYPE_INTEGER, => true, => true, true

Los tipos de atributos con los que se puede describir un campo en la definicin de las columnaseslasiguiente: Tabla:TiposdeatributosparadescribirunatablaconDb::createTable Atributo type Descripcin Eltipodedatoquesealmacenarenlacolumna,sepuedeutilizarun stringconeltipodedatousarlasconstantesdeladaptadorloquees msrecomendable. notNull primary auto size scale precision default publicbooleandropTable(string$tableName,$ifExists=false) Eliminaunatabladelschemaactualdelaconexin.Elparmetro$ifExistspermiteestablecer si se debe comprobar que la tabla exista antes de ser eliminada lo que evita una excepcin generada por el gestor relacional. Devuelve un valor booleano indicando el xito de la operacin. Ejemplo:EliminarunatablaconDb::dropTable
<?php $db = DbBase::rawConnect(); $db->dropTable(customer);

Indicasilacolumnadebepermitirnulosono. Indicasielcampohacepartedelallaveprimariadelatabla. Indicasielcampoesidentidad.Solopuedehaberuncampo autonumricoenlatabla. Tamaodelcampo. Permiteestablecerlaescaladelcampo. Permiteestablecerlaprecisindelcampo. Permiteestablecerelvalorpordefectodelacolumnacuandose insertaunvalornuloenella.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

201

20.18 Fecha del gestor relacional


publicstringgetDateUsingFormat(string$date,string$format=YYYYMMDD) Devuelvelafechadelgestorrelacionalenundeterminadoformato. publicstringgetCurrentDate() Obtienelafechaactualdesdeelgestorrelacional. publicstringaddQuotes(string$value) Agregacomillasespecialessoportadasporelgestorrelacionalaunvalor$value.

20.19 Debug, Seguimiento y Traza


protectedvoidlog(string$msg,int$type=Logger::DEBUG) Enviaunvaloralloginternodelobjetoconexin.Lavariable$typedebetenerelvalordeuna delasconstantesdelcomponenteLogger. protectedvoiddebug(string$sqlStatement) RealizaundebugdelainstruccinSQL$sqlStatementenviandolaapantalla.Generalmenteno esusadoexternamenteyseinvocacuandolaconexinseencuentraenmododebug. publicvoidsetDebug(boolean$debug) PermiteimprimirenpantallalasoperacionesinternasdeSQLgeneradasenelobjeto. publicvoidsetTracing(boolean$tracing) Establecesielobjetoestenmodotrazano. publicarraygetTracedSQL() DevuelveunvectorconlasoperacionesSQLejecutadasenlaconexinmientrasseencontraba enmodotraza. publicvoidsetLogger(mixed$logger) Establece el nombre del archivo con el que se har seguimiento a las operaciones SQL generadasenlaconexin.Siseenviatruecomoparmetrosecrearunlogconlaconvencin dbYYYYMMDD.txt.Siseestableceunainstanciadeunadaptadordeloggeresteestomadopara hacerelseguimiento.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

202

21 Componente Active Record - ORM


21.1 Introduccin
Muchos de los procesos crticos del software en una empresa estn relacionados con el funcionamiento,desarrolloymantenimientodelosdatosquerepresentanlainformacin,un activomuyvaliosodeunaorganizacin.Losentornosempresarialesactualesrequierendela integracin continua de requerimientos dadas las condiciones de un mundo cambiante y evolutivo.Lasaplicacionesdesarrolladasbajouncomponentedeaccesoalainformacinpoco escalabledemasiadodependientedecomponentesyproveedorestecnolgicos,puedellevar a que una organizacin pierda clientes dinero debido a la imposibilidad de adaptarse rpidamentealasnecesidadesrequeridassinperderestabilidadrequiriendomayortiempo dedesarrolloeimplementacingenerandosobrecostos. UncomponenteimportanteenKumbiaEnterpriseFrameworkeselcomponenteActiveRecord. Esteeselencargadoderealizarelmapeoobjetorelacionalydeencargarsedelosmodelosen la arquitectura MVC de las aplicaciones. El concepto de ORM se refiere a una tcnica de mapearlasrelacionesdeunabasededatosaobjetosnativosdellenguajeutilizado(PHPen estecaso),detalformaquesepuedainteractuarconellosenformamsnatural.Losobjetivos deestecomponentevanmsalldemapeartablasyconvertirlasenclases(incluyendotipos de datos, constraints, lgica de dominio, etc.) de convertir registros en objetos. La idea es reducirlosdetallesdelainteraccinconlasbasesdedatosengranmedidamediantevarias capas de abstraccin, incluyendo reducir el uso de SQL lidiar con conexiones y sintaxis programacionaldebajonivel. AlimplementarelaccesoalasbasesdedatosusandounORMsegana: Independencia de la base de datos utilizada en gran medida, esto aumenta las caractersticascomercialesdeunsoftwareyaqueesposiblecambiardeRBDMconun menorimpactosobrelasreasimplicadasalusoeimplementacindelmismo. Reduccindeltamaodelcdigohaciendomssimpleelusoyentendimientoanivel dedesarrollodesistemasqueutilicenbasesdedatos. La capa intermedia de acceso a loas RBDMs proporciona un mtodo potente de interceptacindecualquiereventorelacionadoconlasbasesdedatos,locualfacilita lavalidacindelalgicadedominio,integridaddedatos,definirnivelesdeseguridad,

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

203

logging,auditoriadesistemas,etc. ElORMpermiteadministrarlasasociacionesdelasentidadesdelmodeloinclusosiel backenddealmacenamientoesdistinto. LamayorpartedelaimplementacindeActiveRecordsebasaenelpatrndediseodeltipo Data Source Architectural del mismo nombre. En conjunto con el almacenamiento de meta datosylaadministracindetransaccionesserealizanlosprocesosdeinteraccinconbases dedatosamsaltonivel. ActiveRecord proporciona event handling en la capa intermedia, lo cual permite notificarcambiosenelmodelodeformauniformeyconsistente.

21.2 Cuando usar ActiveRecord


ActiveRecord es un patrn de diseo en los cual los datos y la estructura de los mismos se encuentranasociadosenunamismaclase.Losdatosgeneralmentesonpersistentes,esdecir queestnalmacenadosenalgngestorrelacional,archivomediofsico.Lalgicadeaccesoa losdatosesfcilmenteimplementableusandoActiveRecordyademslaconvierteenpartede lalgicadedominiodelaaplicacin. ActiveRecordesunabuenaopcincuandolalgicadedominionoesmuycompleja,esdecirse implementa un modelo isomorfico, se usan derivaciones, colecciones herencia nosencilla. Modelosentidadrelacinconundiseoconsistenteayudanamejorarlaimplementacinde patrndediseo.

21.3 Entidades
Lasentidadessonobjetospersistentesligerosquenormalmenterepresentanunatablaenuna base de datos relacional. El estado persistente de una entidad este representado usando atributospersistentesasociadosaloscamposdelastablas.Cadaentidadseimplementaenun modeloqueesunaclaseenunarchivoeneldirectoriomodels/. 21.3.1 RequerimientosdelasClasesdeEntidades Lasclasesdebentenerlossiguientesrequerimientos: Cadaarchivodebetenerelnombredelatablaylaextensin.php Debehaberunaentidadporarchivo Laclasedebesersubclase(heredar)delaclaseActiveRecord

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

204

Laclasenodebetenerconstructores Laclasesquerepresentenentidadesfinalesnodebeserabstracta

21.3.2 AtributosdelasEntidades DebidoaquePHPesunlenguajecontipificacindinmicalosatributosdelasclasesentidad norepresentaneltipodedatorealdelcampoenlabasededatos.Conobjetivosfuncionales los getters de algunos campos crean objetos asociados al tipo de dato real, por ejemplo, los campostipofechadevuelvenunobjetodelaclaseDateconelvalordelcampo. Es posible agregar casting al valor de cada objeto usando la opcin del script que crea modelosas:
php scripts/create_model.php -table-name customers -enable-casting yes

Lostiposdedatosalosquelesaplicacastingsonlossiguientes: Tabla:RelacindecastingentretipodedatodelabasededatosytipodedatodePHP TipoDatoBD Varchar,Char,Text,Blob Integer,smallint,tinyint decimal,float,Money date 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 construccindelframeworkissetusadaporelframework,yaquealgunasvecesconsideraque uncamponoestdefinidoperoenrealidadtieneunvalornulo(null). TipoDatoPHP/Kumbia Enterprise String Integer double Date Time

21.4 Atributos y Campos persistentes


La implementacin de los atributos de las entidades en las clases se puede realizar estticamente dinmicamente dependiendo de los requerimientos de la aplicacin. En generalunaimplementacinestticapropendepormejorespracticasdedesarrolloysoftware

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

205

msseguro. Enlaformaestticasedefinenloscamposdelatablacomoatributosprotegidosdelaclase. Estopermiteencapsularelestadointernodecadapropiedadyevitarqueseacambiadapor equivocacin a propsito en lgica de la aplicacin. En estos casos tambin es necesario implementar mtodos get/set para poder obtener/establecer el valor de los atributos. Los mtodos de ActiveRecord isAttribute($property), writeAttribute($property, $value) y readAttribute($property) permiten dinmicamente conocer si existe un atributo, obtener y devolver su valor en forma pblica. Por ejemplo isName(), getName() y setName() es una implementacinestticaparaelatributonamedeunaentidadCustomer. Laformageneralenlaquelosgetters/settersdebenserimplementadoseslasiguiente:
public function getProperty(); public function setProperty($valueOfProperty);

ElmtodoprotegidosetTrasient($attribute)permiteestablecerquecamposdelaentidadno deben ser persistidos. Las operaciones de insercin y actualizacin omiten los atributos marcadoscomoTrasient. Ejemplo:Estableceruncampotrasientenelmodelo
protected function initialize(){ $this->setTransient(user_code); }

Cuandoloscampossemapeandinmicamentesuvisibilidadquedaestablecidacomopblica pordefecto.

21.5 Llaves Primarias


Generalmente de entidades tienen una llave primaria que permite identificar un registro en forma nica. Kumbia Enterprise Framework lee los metadatos de la tabla mapeada directamente del gestor relacional e identifica la llave primaria con sus caractersticas: simples,compuestasy/oautonumricas. Eltipodedatodellavesprimariasdebeseruntipodedatointegral,engeneralsedebeevitar el uso de campos con tipo de dato flotante, decimal Money, ya que pueden variar ligeramenteynoofrecenseguridadenqueunregistroseaunivoco.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

206

Losaccesores(mtodosget)delosatributosquepertenezcanaunallaveprimariacompuesta simpledebensertodospblicos.

21.6 Convenciones en llaves primarias


KumbiaEnterpriseFrameworksoportaconvencinenllaveprimaria,paraestodebetenerlos siguientesrequisitos: Elcampodebellamarseid Elcampodebeestarmarcadocomollaveprimariaenelgestorrelacional Elcampodebeserenteropreferiblementeunsigned(sinsigno) El campo debe ser una columna identidad sea ser autonumrico (DB2, MySQL, Sybase, Microsoft SQL Server) estar asociado a una secuencia (Oracle, DB2, PostgreSQL,Interbase) Elusodeestaconvencinreducelacomplejidaddelaaplicacinyreducelacodificacinya quemuchosaspectoselframeworkpuedeasumiresto.

21.7 Fechas Auto-Asignables


ActiveRecordsoportafechasautoasignablesmedianteconvencinmediantelocualsepuede realizarversionamientoconcurrenteptimistasimplementellevarunregistrodefechasde creacinymodificacinderegistros. Lasconvencionesparafechasautoasignablessonlassiguientes: Para que un campo tome automticamente la fecha del sistema en la operacin de Para que un campo tome automticamente la fecha del sistema en la operacin de insertarestedebetenerelsufijo_atypermitirvaloresnulos. actualizarestedebetenerelsufijo_inypermitirvaloresnulos.

21.8 Multiplicidad en Relaciones de Entidades


Existencuatrotiposdemultiplicidadenrelaciones:unaauna,unaamuchos,muchosaunay muchosamuchos.Lamultiplicidadpuedeserunidireccionalbidireccionalycadaunapuede sersimplemediantecombinacindetablas.Eltipoderelacionesestablececomosellevaa

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

207

persistencia una instancia de una entidad. Normalmente el gestor relacional administra constraintsdellaveforneacorrespondientesaestasrelaciones,ladefinicindeestosayudaa que la integridad de datos sea confiable y las relaciones definidas obtengan los resultados esperados.Atravsdelaimplementacindelasrelacionesesposibleaccederalosregistros relacionadosacadaregistrodeformauniformeahorrandocdigo. 21.8.1 ConvencionesenRelaciones Los nombres de campos de las entidades con ciertas convenciones permiten que se establezcanautomticamenteloscamposreferenciasyseautomaticentareasdecodificacin medianteunaestructuranemotcnica: Paraespecificaruncampoqueesllaveforneaaotrarelacinseutilizaelnombrede camponombre_tabla_id La tabla referenciada debe tener un campo identidad que sea llave primaria con nombreid. Siesposible,loscamposrelacionadosdebentenerelmismotipodedato. 21.8.2 RelacionesUnidireccionales Las relaciones unidireccionales son aquellas que se generan de una relacin a otra pero no viceversa. Mediante los mtodos belongsTo, hasMany hasOne se establece que uno mas camposhacenreferenciaaotrosequivalentesenotraentidad. 21.8.3 RelacionesBidireccionales Lasrelacionesbidireccionalesestablecenasociacionesenlasquecadaunadeellastieneuna viceversacomplementaria. 21.8.4 Muchosauno La asociacin unidireccional muchosauno es la ms comn de todas. Para establecer una relacindeestetiposeutilizaelmtodoprotegidodeActiveRecordbelongsTo: Ejemplo:Multiplicidadmuchosaunorelacionadaconunsolocampo Para2Tablas:
CREATE TABLE `country` ( `code` int(11) NOT NULL, `name` varchar(20) default NULL,

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

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`) );

Elmodelodeciudadesconunarelacinmuchosaunoseimplementaas:
<?php class City extends ActiveRecord { protected function initialize(){ $this->belongsTo(country_code, country, code); } }

El primer parmetro de belongsTo indica el campo de la entidad que hace la asociacin, el segundoindicaelnombredelaentidadreferenciadayelterceroelnombredelcampoenla entidadreferenciada.Laasociacinunavezdefinidasepuedeutilizaras: Ejemplo:Utilizarunaasociacinmuchosauno
$city = EntityManager::getEntityInstance(City); $city->findByName(Bogot); $country = $city->getCountry() print $country->getNombre(); // => Colombia

UngetterconelnombredelarelacinCountrypermiteobtenerelregistroasociadoalpas enlaciudadconsultada. Relacionadaconvarioscampos: Elsiguienteejemploimplementaunarelacinmuchosaunocon2camposreferencia,eneste casolosnombresdeloscampossonigualesenambastablassifuesendiferentessepodran definireneltercerparmetrodebelongsTo. Ejemplo:Utilizarunarelacincompuestamuchosauno


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/KumbiaEnterpriseFrameworkManualdeReferencia

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`) );

ElmodeloFlightsseimplementaas: Ejemplo: Definir una relacin belongsTo en un modelo entidadrelacin sin convenciones
<?php class Flights extends ActiveRecord { protected function initialize(){ $this->belongsTo(array(identification_type, number), customer); } }

Larelacinpuedeserutilizadaas:
$flight = $this->Flights->findByDate(2008-11-01); $customer = $flight->getCustomer();

Ungetterconelnombredelarelacinpermiteobtenerelregistroasociadoalclienteenel vueloconsultado. 21.8.5 UnoaMuchos La asociacin unidireccional unoamuchos indica que para cada registro de una entidad existenunomsregistrosasociadoenlaentidadreferenciada.Paraestablecerunarelacin deestetiposeutilizaelmtodoprotegidodeActiveRecordhasMany. 21.8.6 UnoaUno La asociacin unidireccional unoauno es la ms inusual de todas. Indica que para cada registro de una entidad existe solo uno asociado en la entidad referenciada. Para establecer unarelacindeestetiposeutilizaelmtodoprotegidodeActiveRecordhasOne. 21.8.7 MuchosaMuchos FALTA

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

210

21.9 API de ActiveRecord


AcontinuacinsepresentaunareferenciadelosprincipalesmtodosdelaclaseActiveRecord. 21.9.1 OrigendeDatos publicvoidsetSource($source) Permiteestablecerlaentidaddelgestordedondesemapearanlosatributosdelmodelo. publicstringgetSource() Devuelveelnombredelaentidadusadainternamenteparamapearlosatributosdelmodelo. publicvoidsetSchema(string$schema) Estableceelnombredel$schemaendondeseencuentralatabladondesemapearanlosdatos. publicvoidsetConnection(Db$connection) Permite establecer un objeto Db dinmicamente sobrescribiendo la conexin actual del modelo. publicDbBasegetConnection() Obtiene el objeto Db utilizado para realizar las operaciones a bajo nivel con el gestor relacional. 21.9.2 VolcadodeMetaDatos publicbooleanisDumped() Indicasiyasehanobtenidolosmetadatosdelgestorrelacionalenelobjeto. publicvoiddumpModel() Forzaalmodeloaobtenerlosmetadatosdelgestorrelacional. protectedbooleandump() Obtienelosmetadatosdelgestorrelacional.Siyasehanobtenidonosevuelvenaconsultar publicvoidresetMetaData() Eliminalosmetadatosobtenidosdelgestorrelacionalcargandolosnuevamente. 21.9.3 DebugySeguimiento publicvoidsetDebug(boolean$debug)

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

211

Establece si el modelo esta en modo debug. Todas las operaciones internas de la conexin activasevisualizancomoFlash::noticesenlasalidaalnavegador. publicvoidsetLogger(mixed$logger) Estableceelmodeloenmododebug.Todaslasoperacionesinternasdelaconexinasociadaal modelosonalmacenadasenunarchivoconnombre$logger.Sielprimerparmetroestruese utilizalaconvencindbYYYYMMDD.txt
//Grabar todas las operaciones SQL internas a un archivo en logs/customersDebug.txt $this->Employees->setLogger(customersDebug.txt);

Tambin es posible pasar una instancia de logger utilizando cualquier adaptador disponible utilizandocomoparmetroelobjetocreado: Ejemplo: Loguear las operaciones internas de un modelo a un logger que usa compresin
$logger = new Logger(Compressed, log.employees.txt.gz); $logger->setPath(/usr/local/log/); $this->Employees->setLogger($logger);

Eldesarrolladortambinpuedepasarunainstanciadeunobjetoqueimplementeunmtodo logcomoparmetroeimplementaroperacionespersonalizadasmediantel. Ejemplo: Definir un Logger personalizado para hacer seguimiento a las operaciones internasdeunmodelo
$myLog = new MyUserLog(); $this->Employees->setLogger($myLog);

publicstringinspect() Obtieneunacadenadeinspeccinconlosvaloresinternosdecadaatributodelaentidad. 21.9.4 Transacciones publicvoidsetTransaction(ActiveRecordTransaction$transaction) Establecelatransaccinutilizadaparaefectuarlasoperacionesenelmodelo.Latransaccin debe haberse inicializado antes de asignarla al objeto generar una excepcin ActiveRecordException.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

212

21.9.5 Consultarregistros publicActiveRecordResulsetfindAllBySql(string$sqlQuery) Permite realizar una consulta en el modelo usando lenguaje de consulta SQL. Los valores obtenidossondevueltoscomoinstanciasdelaclase. publicActiveRecordResulsetfindBySql(string$sqlQuery) Permiterealizarunaconsultaenelmodeloquedevuelveunsoloregistrousandolenguajede consultaSQL.Losvaloresobtenidossondevueltoscomoinstanciasdelaclase. Ejemplo:RealizarunaconsultaenunmodelousandoSQL
//Obtener los empleados con una condicin 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);

publicDbResourcesql(string$sqlQuery) Permite realizar una consulta usando lenguaje SQL. El cursor de bajo nivel es devuelto directamente. publicActiveRecordfindFirst(mixed$params) Permite realizar una bsqueda de registros que devuelve un solo registro el primero que coincida con las condiciones indicadas. Los parmetros de consulta se establecen usando parmetrospornombre. Ejemplo:UtilizarfindFirstparaobtenerelprimerregistrodeunmodeloelprimero quecumpladeterminadascondiciones
//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);

publicActiveRecordResulsetfind(mixed$params) Permite realizar una bsqueda de registros que devuelve todos los que coincidan con las condicionesindicadas. Ejemplo:Utilizarfindparaconsultarlosregistrosdelmodelo

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

213

//Obtener todos los registros de una entidad $employees = $this->Employees->find(); //Obtener todos los registros que cumplan con una condicin $employees = $this->Employees->find(status = Active); //Obtener todos los registros que cumplan una condicin y aplicndoles 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);

publicActiveRecordResulsetfindForUpdate($params) Permite realizar una bsqueda de registros que devuelve todos los que coincidan con las condicionesindicadas.Losregistrosencontradossonbloqueadosenmodonocompartidopor lo que otras sesiones de aplicacin que traten de leer/escribir estos registros resultaran en unaespera. Ejemplo:Bloquearunconjuntoderegistrosenmodonocompartidoenunatransaccin
<?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()); } } }

publicActiveRecordResulsetfindWithSharedLock($params) Permite realizar una bsqueda de registros que devuelve todos los que coincidan con las condicionesindicadas.Losregistrosencontradossonbloqueadosenmodonocompartidopor loqueotrassesionesdeaplicacinquetratendeescribirenestosregistrosresultaranenuna esperaporpartedelgestorrelacional. publicstringconvertParamsToSql(mixed$params) CreaunaconsultadeSQLmediantelosparmetrospornombreindicados.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

214

publicarraydistinct(mixed$params) RealizaunasentenciaDISTINCTsobreunacolumnadelmodelodevolviendounlistadodelos valoresdiferentesencontrados. publicbooleanexists(string$wherePk) publicActiveRecordResultsetfindAllBy(string$field,mixed$value) publicstaticarraysingleSelect(string$sql) RealizaunaconsultaSQLsobreelgestorrelacionalenlatabladualenelcasodeOraclesolo hacelainstruccinSELECTsobreningunaentidadenotrosmotores. 21.9.6 Contarregistros publicintegercount(mixed$params) Devuelveunconteoderegistrosapartirdelascondicionesindicadas.Losparmetrospueden serestablecidosusandoparmetrospornombreunarraycuyosindicesindiqueneltipode parmtro a establecer. El parmetro especial group modifica el resultado obtenido agrupandolomedianteotrosatributosdelaentidad. Ejemplo:Realizarconteossobreatributosdelmodelo
//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; }

publicmixedcountBySql(string$sqlQuery) RealizaunconteoenelmodelomedianteunasentenciaSQL.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

215

21.9.7 Promediarregistros publicdoubleaverage($params) Devuelve un promedio de los valores de una columna numrica a partir de las condiciones indicadas.Elparmetroespecialgroupmodificaelresultadoobtenidoagrupndolomediante otrosatributosdelaentidad. Ejemplo:Realizarpromediossobreatributosdelmodelo
//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 Realizarsumatorias publicdoublesum($params) Estemtodopermiterealizarsumatoriasdelosatributosdelaentidad.Elparmetroespecial groupmodificaelresultadoobtenidoagrupandolomedianteotrosatributosdelaentidad. Ejemplo:Realizarsumatoriassobreatributosdelmodelo


//Cuanto suman los impuestos en las ordenes de compra? $this->Orders->sum(taxes); //Cuanto suman los impuestos del ao 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 Obtenerelvalormximodeunatributo publicmixedmaximum($params)

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

216

Devuelveunvalormximodeunacolumnanumricaapartirdelascondicionesindicadas.El parmetro especial group modifica el resultado obtenido agrupandolo mediante otros atributosdelaentidad. Ejemplo:Obtenerelvalormximodeunatributodeunmodelo
//Quien es el empleado ms antiguo? $this->Employees->maximum(contract_date, conditions: status=Active);

21.9.10

Obtenerelvalormnimodeunatributo

publicmixedminimum($params) Devuelveunvalormnimodeunacolumnanumricaapartirdelascondicionesindicadas.El parmetro especial group modifica el resultado obtenido agrupandolo mediante otros atributosdelaentidad. Ejemplo:Obtenerelvalormnimodeunatributodeunmodelo
//Quien es el empleado ms nuevo? $this->Employees->minimum(contract_date, conditions: status=Active);

21.9.11 Asignarvaloresainstancias

publicActiveRecorddumpResult(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 algn indice no correspondeaunatributodelmodelosegeneraunaexcepcin. publicvoiddumpResultSelf(array$result) Toma un vector cuyos indices coinciden con los nombres de los atributos del modelo y los asignaalmismoobjeto.Sialgnindicenocorrespondeaunatributodelmodelosegenerauna excepcin. 21.9.12 Validacin

publicarraygetMessages() Obtienelosmensajesdevalidacingeneradosenunprocesodeinsercinactualizacin. publicvoidappendMessage(ActiveRecordMessage$message) Agregaunmensajealbufferdemensajesdevalidacindelmodelo.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

217

21.9.13

Informacindeatributos

publicarraygetAttributes() Obtieneunvectorconlosnombresdelosatributosdelaentidad. publicarraygetAttributesNames() Obtiene un vector con los nombres de los atributos de la entidad. Es un alias de getAttributes(). publicbooleanhasField($stringfield) Permiteconsultarsiunaentidadtieneundeterminadocampo$field. publicarraygetPrimaryKeyAttributes() Obtieneunvectorconlosnombresdelosatributosdelaentidadquesonllaveprimaria. publicarraygetNonPrimaryKeyAttributes() Obtieneunvectorconlosnombresdelosatributosdelaentidadquenosonllaveprimaria. publicarraygetNotNullAttributes() Obtiene un vector con los nombres de los atributos de la entidad que no aceptan valores nulos. publicarraygetDatesAtAttributes() Obtiene un vector con los nombres de los atributos de la entidad que autoasignan la fecha actualcuandoserealizaunaoperacindeinsercin. publicarraygetDatesInAttributes() Obtiene un vector con los nombres de los atributos de la entidad que autoasignan la fecha actualcuandoserealizaunaoperacindemodificacin. publicbooleanisANumericType(string$field) Permiteconsultarsiunatributoenlatablatieneuntipodedatonmerico(int,integer,float, number,bigint,Money,etc).

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

218

21.9.14

Creacinyactualizacinderegistros

publicbooleancreate(array$values=array()) Estemtodopermitelacreacindeunregistroapartirdelosvaloresasignadospreviamentea losatributosdelmodelo asignando valores a estos a travs de un array asociativopasado comoparmetro.Debeusarseestemtodocuandoeldesarrolladorquieraasegurarsequese realiceunaactualizacinenvezdeusarsave(). publicbooleanupdate(array$values=array()) Este mtodo permite la actualizacin de un registro apartir de los valores asignados previamente a los atributos del modelo asignando valores a estos a travs de un array asociativopasadocomoparmetro.Debeusarseestemtodocuandoeldesarrolladorquiera asegurarsequeserealiceunaactualizacinenvezdeusarsave(). publicbooleansave() Estemtodopermitecrear/actualizarregistrosdeacuerdoasiestosyaexistenenlaentidad asociada a un modelo. El mtodo save es llamado tambin internamente por los mtodos createyupdatedeActiveRecord.Paraqueestemtodofuncionecomoseesperaesnecesario quesehayadefinidounallaveprimariacorrectamenteenlaentidadparapoderdeterminarsi unregistrodebeseractualizadocreado. Elmtodosave()ejecutalosvalidadoresasociados,llavesprimariasvirtualesyeventosquese hayandefinidoenelmodelo.Elgeneradordeidentificadoresasociadotambinesejecutadoy alterminarelprocesoelobjetoserefrescaconlosvaloresfinalesquequedaronenlabasede datos. Ejemplo:Crearunregistrousandoelmtodosave()deActiveRecord
<?php $product = new Products(); $product->setName('Potattos'); $product->setType('Food'); if($product->save()==false){ foreach($product->getMessages() as $message){ Flash::error($message->getMessage()); } }

Elejecutarsesave(),estedevuelveunvalorbooleanoindicandoelxitodelaoperacin.Enel ejemploanteriorseobtienenymuestranlosmensajesdevalidacinenpantallacuandosave()

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

219

devuelvefalse. 21.9.15 Eliminacinderegistros

publicbooleandelete($params) EliminaelregistroactivoasociadoalobjetoActiveRecord. 21.9.16 OperacionesenBatch

publicbooleanupdateAll(array$values,string$conditions=) Realiza una actualizacin en batch de todos los campos de una entidad asegurando alto rendimiento.Elparmetro$valuespermiteindicar,medianteunarrayasociativo,losvalores a actualizar, en donde los indices son los nombres de los campos. El parmetro $conditions permitedefinirlascondicionesquesedebencumplirparaqueelregistroseaactualizado.Si noseestableceunvalorpara$conditionsseactualizarntodoslosregistrosdelaentidad. publicbooleandeleteAll($conditions=) Realizaunaeliminacinderegistrosenbatchenunaentidadasegurandoaltorendimiento.El parmetro $conditions permite definir las condiciones que se deben cumplir para que el registro sea actualizado. Si no se establece un valor para $conditions se borrarn todos los registrosdelaentidad. 21.9.17 Lectura/escrituradeAtributos

publicmixedreadAttribute(string$attribute) Obtiene el valor de un atributo del modelo apartir de su nombre. Este mtodo lee el valor independientedelavisibilidaddelapropiedadenlaclase. publicmixedwriteAttribute(string$attribute,mixed$value) Asignaunvaloraunatributodelmodeloapartirdesunombre.Estemtodoescribeelvalor independientedelavisibilidaddelapropiedadenlaclase. 21.9.18 Validacin

protectedvoidvalidate(string$validatorClass,array$options) Agrega un validador a un modelo. Consulte el captulo de validadores de integridad para aprendermssobreestemtodo. publicbooleanvalidationHasFailed() Estemtodopuedeserusadodentrodeuneventodevalidacinparaindicarsielprocesode

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

220

completo de validacin ha fallado. Consulte el captulo de validadores de integridad para aprendermssobreestemtodo. 21.9.19 Multiplicidadderelaciones

protectedvoidhasOne(mixed$fields,string$referenceTable,mixed$referencedFields) Creaunarelacin1a1conotraentidadpresenteeneladministradordeentidades.Elprimer parmetroespecificaelatributoatributosenlaentidadlocaly$referencedFieldselatributo atributosenlatablareferenciada.Elparmetro$referenceTableindicalatablareferenciada. Ejemplo:EstablecerrelacioneshasOne(1a1)deacuerdoalmodeloentidadrelacion


//Relacin de un campo a otro por convencin $this->hasOne(tabla_id); //Relacin de un campo a otro $this->hasOne(campo, tabla_referenciada, campo_referenciado); //Relacin de varios campos a varios campos $this->hasOne( array(campo1, campo2), tabla_referenciada, array(campo_referenciado1, campo_referenciado2) );

protectedvoidbelongsTo(mixed$fields,string$referenceTable,mixed$referencedFields,string $relationName=) Creaunarelacin1a1inversaconotraentidadpresenteeneladministradordeentidades.El primerparmetroespecificaelatributoatributosenlaentidadlocaly$referencedFieldsel atributo atributos en la tabla referenciada. El parmetro $referenceTable indica la tabla referenciada. Ejemplo:EstablecerrelacionesbelongsTo(muchosa1)deacuerdoalmodeloentidad relacion
//Relacin de un campo a otro por convencin $this->belongsTo(tabla_id); //Relacin de un campo a otro $this->belongsTo(campo, tabla_referenciada, campo_referenciado); //Relacin de varios campos a varios campos $this->belongsTo( array(campo1, campo2), tabla_referenciada, array(campo_referenciado1, campo_referenciado2) );

protectedvoidhasMany(mixed$fields,string$referenceTable,mixed$referencedFields) Creaunarelacin1anconotraentidadpresenteeneladministradordeentidades.Elprimer parmetroespecificaelatributoatributosenlaentidadlocaly$referencedFieldselatributo

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

221

atributosenlatablareferenciada.Elparmetro$referenceTableindicalatablareferenciada. Ejemplo: Establecer relaciones hasMany (1 a muchos) de acuerdo al modelo entidad relacion
//Relacin de un campo a otro por convencin $this->hasMany(tabla_id); //Relacin de un campo a otro $this->hasMany(campo, tabla_referenciada, campo_referenciado); //Relacin de varios campos a varios campos $this->hasMany( array(campo1, campo2), tabla_referenciada, array(campo_referenciado1, campo_referenciado2) );

protectedvoidhasAndBelongsToMany(mixed$fields,string$referenceTable,string$gateTable, mixed$referencedFields) Creaunarelacinnaminversaconotraentidadpresenteeneladministradordeentidades.El primerparmetroespecificaelatributoatributosenlaentidadlocaly$referencedFieldsel atributo atributos en la tabla referenciada. El parmetro $referenceTable indica la tabla referenciaday$gateTablelatablapuenteparaaccederalatablareferenciada. 21.9.20 Herencia

publicvoidparentOf(string$parent) Estableceunarelacindeherenciaqueutilizaunaestrategadetablaporsubclasemediante undiscriminador.Elparmetro$parentindicalaentidadpadre. 21.9.21 Excepciones

protectedvoidexceptions($e) Al reescribir este mtodo es posible tratar las excepciones generadas dentro de un modelo antesqueseanlanzadasaotraspartesdelaaplicacin.

21.10 Identifiers
Las clases mapeadas con ActiveRecord que pretendan efectuar operaciones de manipulacin de datos deben declarar llaves primarias. Por defecto se utilizan estrategias para obtener el valordeestasalhacerunainsercin. Lostiposdeidentificadoressoportadosson: Tabla:Tiposdegeneradoressoportados

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

222

Tipo Increment Descripcin Generaidentificadoresdetipointeger,quesonnicossolo cuando otros procesos no generar operaciones de insercin concurrentes. Esta opcin no debera ser usada enclusteres. Identity No realiza ninguna operacin en especial ya que aprovecha una columna identidad presente en la entidad. Este tipo de columnas son soportadas por MySQL, IBM DB2,MicrosoftSQLServer,IBMInformixySQLite. Sequence Obtieneelvalordeunobjetodelgestorrelacionalllamado secuencias. Las secuencias son soportadas por Oracle, PostgreSQLeIBMDB2. Hilo UUID Assigned Uniqid 21.10.1 EstablecerelGenerador Utilizaunalgoritmotipohi/loparaeficientementegenerar losvaloresnicosdetipointeger. Genera identificadores unicos de 128bits tipo string basadosenelalgoritmoUUID(UniversalUniqueIdentifier. No aplica ninguna estratega y utiliza el valor asignado directamentealobjetoinstanciadelmodelo. Permiteobteneridentificadoresnicosde128bitsusando lafuncindePHPllamadauniqid.

ParaestablecerestetipodeidentificadoressedebeusarelmtodoprotegidodeActiveRecord llamado setIdGenerator. El primer parmetro indica que tipo de generador se usar y el segundopermiteestablecerlasopcionesdelgenerador. 21.10.2 AlgoritmoHi/Lo

ElgeneradorHi/Lopermiteobtenerelvalorquedebaseutilizadocomollaveprimariadeun campo en otra entidad en forma eficiente. En una transaccin al obtener el valor del identicadorseefecta(sisesoporta)unbloqueoporfilaenelregistroparaasegurarseque ningnotroprocesoobtengaelmismovalor. Ejemplo:EstablecerungeneradoreficienteHi/Loenunmodelo

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

223

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

Laopcinmax_loindicaelvalormnimoquedebetomarelconsecutivo. Tabla:ParmetrosdelgeneradorHi/Lo Tipo table columna source max_lo number UnodelosobjetivosdelalgoritmoHi/Loesaumentarlaeficienciamediantelareduccindela lectura/escritura de la tabla consecutivo. Esto solo es posible cuando la operacin se encuentraenmediodeunatransaccinadministradaporelTransactionManager. 21.10.3 AlgoritmoUUID Descripcin Tabledondeseencuentraelconsecutivo Columnaquellevaelconsecutivo Esopcional.Permiteestablecerquelatablaseencuentraenotroschema. Es opcional. Permite controlar el mnimo valor que debe almacenar la columna. Esopcional.Indicacuantosconsecutivossedebengenerarparaaumentarla eficiencia.

ElalgoritmoUUIDgeneraidentificadoresnicosquepuedenserusadoscomollaveprimaria mediante el algoritmo del mismo nombre. El sistemas UNIX utiliza /dev/urandom para generarelidentificador. UnUUIDtienelasiguienteforma:
4cfce7c2-6089-102c-91cf-d8dbbe268425

SeestableceungeneradorUUIDdeestaforma: Ejemplo:EstablecerungeneradordeidentificadoresqueuseelalgorimoUUID
<?php

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

224

class Media extends ActiveRecord { public function initialize(){ $this->setIdGenerator("Uuid", id); } }

21.10.4

GeneradorUniqId

El generador Uniqid genera identificadores nicos apartir de la funcin Uniqid de PHP. El valorgeneradoesunstringde32caracteres(unnmerohexadecimalde128bits)queesmuy difcilderepetir. Ejemplo:Establecerungeneradordeidentificadoresqueuseelalgoritmouniqid
<?php class Media extends ActiveRecord { public function initialize(){ $this->setIdGenerator("Uniqid", id); } }

21.10.5

GeneradorNative

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 estoscasosActiveRecordnoasignarningnvalorenlasentenciaINSERTcreadarespetando el consecutivo de la secuencia aunque si consultar su valor para actualizar el estado del objeto. ElgeneradorNativedebeestablecersedelasiguienteforma: Ejemplo:Establecerungeneradornativoenunmodelo
<?php class Orders extends ActiveRecord { public function sequenceName(){ return ORDERS_SEQ; } public function initialize(){ $this->setIdGenerator("Native", id); } }

21.10.6

ColumnasIdentidadySecuencias

Parabasesdedatosquesoportencolumnasidentidadelgeneradorasignaelvaloradecuado

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

225

paraquesegenerevalorautonumricoenlacolumnaadecuada.Enestoscasoselgenerador IdentitysepuedeusarconmotorescomoIBMDB2,MySQLyMicrosoftSQLServer. 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 cuandonoexistantriggersqueasignenelvalordelacolumnaenlatablayaqueestoharque sealtereelconsecutivoinnecesariamente. Ejemplo: Establecer un generador de secuencias para un modelo con un gestor relacionalquelosoporte
<?php class Orders extends ActiveRecord { public function initialize(){ $this->setIdGenerator("Sequence", id, array( name => ORDERS_ID )); } }

El nombre de la secuencia tambin puede ser establecido mediante el mtodo pblico sequenceNametantoparalosmodeloscongeneradorescomolosquetienenidentificadorpor convencin: Ejemplo:Definirelnombrelasecuenciadelgeneradordevaloresidentidad
<?php class Orders extends ActiveRecord { public function sequenceName(){ return ORDERS_ID_SEQ; } public function initialize(){ $this->setIdGenerator("Sequence", id); } }

21.11 Convenciones en Identificadores


ActiveRecordpuedeautomticamenteestablecereltipodegeneradoraIdentitysienlosmeta datos de la entidad encuentra que existe una columna identidad. Igualmente si el campo se llama explcitamente id igualmente se entender la convencin que se trata de un campo identidadgeneradoporelgestorrelacionalmedianteelgeneradorIncrement.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

226

Requisitosparautilizarlaconvencinenidentificadores: Elcampodebellamarseid Elcampodebeteneruntipodedatoenterno(bigint,int,integer,number) Elcampodebeserlallaveprimariadelatabla Elcampodebesernonulo

21.12 Los Meta-datos en ActiveRecordMetadata


Gran parte de la ciencia en la implementacin de ActiveRecord esta relacionada con la administracin de los metadatos de las tablas mapeadas. El almacenamiento de sus caractersticasespuntofundamentalparalautilizacindelosmtodosqueconsultan,borran, modifican, almacenan, etc. El subcomponente ActiveRecordMetadata implementa el patrn MetadataMappingelcualpermitecrearundatamapporschemasobrelainformacindelas tablasyasreducirelconsumodememoriaporobjetoActiveRecordyconsolidarunabasede datosinmemorydelascaractersticasdecadaentidadutilizadaenlaaplicacin. Normalmente los metadatos 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 autoactualizable que refleja cualquier cambio en la estructuradelmodelodedatos. 21.12.1 TiposdeMetaDatosAlmacenados

En ActiveRecordMetaData se almacenan varios tipos de informacin sobre entidades que pretenden acelerar las operaciones de manipulacin y consulta de datos en ActiveRecord. Estostiposdedatosson: Tabla:MetadatosalmacenadosparaunaentidadenelActiveRecordMetaData TipoMetaDato Camposdelatabla LlavesPrimarias Camposnollaveprimaria CamposNoNulos Descripcin Nombresdeloscamposdelastablas Camposquehacenpartedelallaveprimariadelas tablas. Conjuntodecamposquenopertenecealallave primariadelastablas. Camposquenopermitenvaloresnulos

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

227

TiposdeDatos CamposFechaAuto Asignables 21.12.2

Tipodedatosdecadacampoenunatabla. Camposqueporconvencinasignanautomticamente lafechadelsistemaalactualizarmodificar.

MetaDatosenetapasdeDesarrollo

Cuando las aplicaciones se encuentran en etapa de desarrollo es posible que el los desarrolladoresencuentrenqueloscambiosenlaestructurasdelabasededatosnoseven reflejadosenlasaplicaciones. Estosucedeporquelosmetadatosdelastablassoncacheadostemporalmenteensesinpara evitarquelabasededatosseaaccedidacontinuamentedisminuyendoelrendimiento. Para hacer que los metadatos sean cargados nuevamente es necesario cerrar y abrir el navegadorelclientewebyassevernloscambiosdelmodelodedatosreflejados. 21.12.3 APIdeActiveRecordMetaData

publicvoidstaticexistsMetaData(string$table,string$schema) Permitesabersiyasehadefinidolosmetadatosparaunatablayesquemaenespecial. publicvoidstaticcreateMetaData(string$table,string$schema) Creaunregistroparametadatosenelmetadatastore. publicvoidstaticsetAttributes(string$tableName,string$schemaName,array$attributes) Establecelosnombresdeloscamposdeunadeterminadatabla. publicarraystaticgetAttributes(string$tableName,string$schemaName) Obtienelosnombresdeloscamposdeunadeterminadatabla. public array static setPrimaryKeys(string $tableName, string $schemaName, array $primaryKey) Estableceloscamposquesonllaveprimariaaunadeterminadatabla. publicarraystaticgetPrimaryKeys(string$tableName,string$schemaName=)

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

228

Obtieneloscamposquesonllavaprimariaenunadeterminadatabla public void static setNonPrimaryKeys(string $tableName, string $schemaName, array $nonPrimaryKey) Estableceloscamposquenosonllaveprimariaaunadeterminadatabla. publicarraystaticgetNonPrimaryKeys($tableName,$schemaName) Obtieneloscamposquenosonllavaprimariaenunadeterminadatabla publicvoidstaticsetNotNull(string$tableName,string$schemaName,array$notNull) Estableceloscamposquenopuedentenervaloresnulos. publicarraystaticgetNotNull($tableName,$schemaName) Obtienelosvaloresquenosonnulosenunatabla. publicvoidstaticsetDataType(string$tableName,string$schemaName,array$dataType) Establecelostiposdedatosdeunatabla. publicarraystaticgetDataTypes(string$tableName,string$schemaName) Obtienelostiposdedatosdeunadeterminadatabla. publicvoidstaticsetDatesAt(string$tableName,string$schemaName,array$datesAt) Establecelosatributosdelatablaaloscualesselesasignafechaautomticaalinsertar. publicarraystaticgetDatesAt(string$tableName,string$schemaName) Obtienelosatributosdelatablaaloscualesselesasignafechaautomticaalinsertar. publicvoidstaticsetDatesIn(string$tableName,string$schemaName,array$datesIn) Establecelosatributosdelatablaaloscualesselesasignafechaautomticaalactualizar. publicarraystaticgetDatesIn(string$tableName,string$schemaName) Obtienelosatributosdelatablaaloscualesselesasignafechaautomticaalactualizar. publicvoidstaticdumpMetaData(string$table,string$schema,array$metaData)

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

229

Almacenalosmetadatosparaunadeterminadatablaenelmetadatastore.

21.13 Cursores y Resulsets de Consultas


LosresultadosdevueltosporlosmtodosdeconsultadeActiveRecordsonobjetosinstancias delaclaseActiveRecordResulsetqueencapsulanlamanipulacinyobtencindelosregistros individualesenelcursorenviadoporelRBDM. La clase implementa las interfaces Iterator, ArrayAccess, SeekableIterator y Countable con lo cul el objeto se puede recorrer usando una sentencia como foreach, acceder a indices individualesmedianteeloperadordeaccesodevectoresycontareltotalderegistrosusando funcionescomocountsizeof. Laimplementacindeesteobjetolograunaadministracindememoriamseficienteyaque 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 excesivodememoriaporpartedelaaplicacin. 21.13.1 UtilizarelcursorcomotipoForwardOnly

Los objetos de resultado de consulta pueden ser recorridos usando sentencias del lenguaje comoforeachywhileutilizandoloscomocursorestipoforwardonly.Alterminarderecorrer losregistrosloscursoressonautoresetadospermitiendovolverarecorrerlos. Ejemplo:Recorreruncursortipoforwardonly
//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

UtilizarelcursorcomoScrollable

Los resultsets tambin pueden ser recorridos en modo scrollable de esta forma se puede accederaunregistroenparticularusandounindiceparaestablecersuposicin.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

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

APIdeActiveRecordResulset

publicintegerkey() Obtieneelnmerodelregistroqueestactualmenteactivoenelcursor. publicbooleanoffsetExists(integer$index) Permiteconsultarsiexisteunregistroenunadeterminadaposicin. publicvoidrewind() Devuelveelcursorinternodelresulsetalprimerregistro. publicbooleanvalid() Indicalaposicinactualdelcursorinternoesvalida,esdecirqueaunquedanmsregistros pararecorrer. publicvoidnext() MueveelcursorinternoalsiguienteregistrodelResultset. publicvoidcurrent() DevuelveelobjetoActiveRecordactivoenelcursor. publicvoidseek(int$position) Mueve el cursor interno del resultset a la posicin indicada por $position, esta debe ser un nmeroenteromayora0. publicintegercount() ImplementaelmtodoqueexigelainterfaceCountableelcualpermitesabercuantosregistros hadevueltoelresultset. publicActiveRecordgetFirst()

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

231

Obtieneelprimerregistrodelcursor.Implicitamenterebobinaelpunteroalprimerregistro. publicActiveRecordgetLast() Obtiene el ltimo registro del cursor. Implicitamente mueve el puntero interno al ltimo registro. publicActiveRecordoffsetGet($index) Obtieneelregistroubicadoenlaposicin$indexdelcursor.Lasposicionesempiezanen0. publicbooleanoffsetExists($index) Permiteconsultarsiexisteunregistrounadeterminadaposicindelcursor. publicstringgetSQLQuery() DevuelveelSQLqueprodujolaconsulta. publicActiveRecordgetEntity() Devuelvelaentidadqueprodujolaconsulta.

21.14 Mensajes de ActiveRecord


ActiveRecord tiene un subsistema de mensajes que permite flexibilizar la forma en que se presentan almacena la salida de validacin que se genera en los procesos de insercin actualizacin.CadamensajeconstadeunainstanciadelaclaseActiveRecordMessage.Elgrupo de mensajes generado puede ser recogido usando el mtodo getMessages() del objeto ActiveRecorddondeseprodujolaoperacin. Cadamensajeofreceinformacinextendidacomoelnombredelcampoquegenerelmensaje yeltipodemensaje. En el siguiente ejemplo se ilustra como imprimir los mensajes que resultan de un proceso fallidodeinsercin: Ejemplo:Obtenerlosmensajesdevalidacindeunmodelo
<?php $customer = new Customer(); $customer->setName("Steve Conrad"); $customer->setEmail("s.conrad@mail.com");

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

232

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

21.14.1

APIdeActiveRecordMessage

ElAPIdelaclaseActiveRecordMessageeslasiguiente: publicvoidsetType(string$type) Estableceeltipodemensaje. publicstringgetType() Obtieneeltipodemensaje. publicvoidsetMessage(string$message) Estableceelmensajeinternodelobjeto. publicstringgetMessage() Obtieneelmensajegenerado. publicvoidsetField(string$field) Estableceelnombredelcampodecuyovalorsegenerelmensaje. publicstringgetField() Obtieneelnombredelcampoquegenerelmensaje.

21.15 Transacciones en ActiveRecord


Lasaplicacionesempresarialesgeneralmenteadministrandatoscuyovalorescriticoparalas 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 hayaintegridadenlosdatosyquesepuederecuperarlainformacinsiocurreunestadode fallo. LaimplementacindeTransaccionesdeNegocioparaActiveRecordestabasadaenlaideadel patrn del grupo ObjectRelational Behavioral llamado Unit of Work, aunque este sin

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

233

administrarellogdeobjetosutilizados.Sufuncionamientobsicamentepermitesepararlos objetosActiveRecordquepertenecenaunatransaccindetalformaquetodaslasoperaciones efectuadasporellosmantenganunestadodeconcurrenciaconsistenteysepuedacontrolarsi sealteralabasededatossehacerollbackencasoqueserequiera. LaimplementacindetransaccionesenActiveRecordtiene2ventajasprincipales: Seencapsulandetallessobrelaimplementacindetransaccionesdelgestorrelacional utilizado. Soportaadministracindetransaccionesdeclarativas. Esta integrado con el componente TransactionManager que reduce la codificacin y administraglobalmentelastransacciones. 21.15.1 AdministraciondeTransacciones

La administracin de transacciones puede ser utilizada a nivel global nivel local, independientementedelaformaenqueseutilicensuobjetivoesprimordialmentecontrolar la concurrencia a los recursos de persistencia de la aplicacin. La gestin de transacciones dependeexplcitamentedelosrequisitosdelaaplicacin: Globales:Lasglobalessonadministradasygestionadasporlaaplicacin,elbloqueo de recursos es dependiente de la naturaleza de los mismos. Como el estado de ejecucin de una aplicacin Web duerme entre una peticin y otra es necesario cancelary/oaceptarlastransaccionespendientescadavezqueterminanloshilosde ejecucin. Las transacciones pueden ser compartidas entre la ejecucin de varias acciones en un mismo hilo. Kumbia Enterprise Framework permite establecer transacciones en forma automtica para cualquier peticin a la aplicacin y cada objeto instanciado, sin embargo esta implementacin puede resultar demasiado incondicionalparalasreglasdenegociodeunaaplicacin.Sumayorventajaesquelas operaciones que se realizan a nivel global pueden ser replicadas a varios recursos transaccionales. Locales: Permiten al desarrollador establecer modelos de programacin ms naturales y faciles de implementar que cumplen detalladamente con la lgica de negocio de la aplicacin. La principal desventaja es que tiene a invadir el modelo de

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

234

programacindelaaplicacin. El componente TransactionManager administra la creacin, cancelacin, destruccin y aceptacindetransaccionescuandoseimplementanenmltiplesaccionesenundeterminado flujo de ejecucin cuando se usan transacciones globales. Este componente implementa la interfase TransactionManagerInterface, as el desarrollador puede implementar un componentepropiodeadministracindetransaccionesimplementandoesta:
interface TransactionManagerInterface { public public public public public public public } function getUserTransaction($definition=null); function commit(); function rollback(); function initializeManager(); function rollbackPendent(); static function notifyRollback(); static function notifyCommit();

El mtodo TransactionManager::getUserTransaction() devuelve la ltima transaccin crea unasiesnecesariodeacuerdoaladefinicinpasadacomoargumento.Ladefinicinesuna instancia de la clase TransactionDefinition. La definicin de la transaccin establece parmetroscomoelniveldeisolacinsilatransaccinespropagable: Ejemplo:EstablecerlosparmetrosdelatransaccinconunTransactionDefinition
<?php class AccountsController extends ApplicationController { public function createCustomerDataAction(){ $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()); } try {

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

235

} public function createCustomerDataAction($clientId){ $clientId = $this->filter($clientId, "int"); $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()); } } } try {

Elejemplomuestracomoseaplicalatransaccincreadamedianteladefinicinysereutiliza entrelasdiferentesaccionesqueconformanlaoperacindenegocio.Unadescripcindelos parmetrosquesepuedendefinirenTransactionDefinitioneslasiguiente: Isolacin: Permite establecer el grado de isolacin con el que trabajaran las transacciones.EsteserefierealestndarSQL92ydependedesiestasoportadoporel gestorrelacional. Propagation: La propagacin de transacciones permite que cuando una transaccin seacanceladasecancelenotrascreadasenlamismapeticinalaaplicacin. ReadOnly: Permite establecer una transaccin de solo lectura, cualquier intento de modificacin(insercin,actualizacin,borrado)deregistrosterminaenlageneracin deunaexcepcin. Timeout:Permiteestableceruntiempoensegundosdespusdelcuallatransaccin ser cancelada automticamente si no se ha realizado un commit. Esto permite controlarciertosprocesosdenegociodondeelaccesoalosrecursosespordemanda.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

236

El mtodo esttico TransactionManager::getUserTransaction() devuelve una instancia de la clase ActiveRecordTransaction quien administra el acceso al Data Source de la transaccin. Mltiples entidades comparten un mismo DataSource aunque esto sea transparentemente administrado. 21.15.2 SincronizacindeRecursosconTransacciones

El desarrollador debe tener cuidado al utilizar transacciones, ya que multiples administradores transaccionales que trabajen sobre un mismo gestor relacional podria realizarbloqueossobrerecursosnecesariosenunamismaoperacindenegocioquetermina enundeadlockyunaexcepcin. El uso de TransactionManager permite evitar esto en cierta medida ya que este controla la creacin, reutilizacin, propagacin, cancelacin y aceptacin de los procesos relacionados contransaccionesascomootrasoperaciones. 21.15.2.1 SincronizacindeAltoNivel

El mtodo de ActiveRecord::setTransaction() proporciona un mtodo para el objeto que representaunregistrocompartaunatransaccindeformatransparente.Lasincronizacinde altonivelpermitequevariosobjetosActiveRecordcompartanunmismoDataSourcebajouna transaccinytodassusoperacionesdebajonivelsonadministradasporloscomponentesdel framework lo cual aumenta la seguridad y confiabilidad que la operacin no se salga de controlyseejecutenlastareasdefinalizacindetransaccionesrequeridas. 21.15.2.2 SincronizacinaBajoNivel

La conexin al gestor relacional puede ser obtenida de un objeto ActiveRecord mediante el mtodo 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 mtodos begin(), rollback()ycommit()estanpresentesypermiteniniciaryterminartransaccionesabajonivel. Ejemplo:Utilizartransaccionesabajonivel
$invoice = new Invoice(); $db = $invoice->getConnection(); $db->begin(); $invoice->find(124); $invoice->setStatus(Cancelled); $invoice->save(); $db->commit();

21.15.3

ConsideracionesdeSincronizacin

Laimportanciadelasincronizacinyaceenlanecesidaddeunacorrectaimplementacindel

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

237

procesodenegocioendondeladisponibilidaddelosrecursosseaconsistenteentrelosque sontransaccionalesylosqueno. Es fundamental entender que los objetos que poseen una misma transaccin administran ciertos recursos y se debe controlar que no vayan a ser utilizados requeridos en otra transaccindentrodelmismoproceso,sinosecontrolanestassituacionesesposiblequese presenteninconsistenciasenlosprocesosdenegocio. Enelsiguienteprocesosepuedecomprenderlasituacinpresentada: Ejemplo:Sincronizacinderecursosencontroladores
<?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 pertenezcanaunclientedeterminadoparaluegoaplicarundescuentosobreestascuentas. El proceso espera que las cuentas recin actualizadas en el primer foreach se les haga igualmente el descuento del segundo, sin embargo esto no ser as ya que los resultados

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

238

devueltos por la transaccin base pertenecen a un espejo diferente al espejo de los objetos administradosporlatransaccin$transaction. Enresumen,losobjetosqueseesperaquetambinselesapliqueeldescuentoenelsegundo foreachquedaransineste,yaqueenelgestorrelacionalannosehareflejadolaactualizacin deestadosdelprimerforeach. Lasolucinaesteinconvenienteesseguirlassiguientesconsideraciones: Los procesos de negocio que accedan a un mismo recurso, en este caso la entidad Accountdebenasociartodaslasinstanciasaunamismatransaccin Si existe integridad referencial en el modelo de datos igualmente es necesario que todas las entidades relacionadas y sus procesos estn administradas por una misma transaccin. Si no es necesario que se reflejen los cambios en el modelo de datos dentro de un mismo procesodenegocioentoncespuedehacercasoomisoaestasconsideracionesyutilizartantos administradoresdetransaccionescomorequiera. Elejemplopresentadoanteriormentesinelinconvenientemencionadoseimplementaraas: Ejemplo:Sincronizacinderecursosencontroladores
<?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/KumbiaEnterpriseFrameworkManualdeReferencia

239

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

Cadainstanciadevueltaporfindestaautomticamenteasociadaalatransaccin$transaction ysecontrolaquetodaslasoperacionesefectuadassobrelaentidadAccountssereflejeentodo elprocesodenegocio. 21.15.4 APIdeTransactionDefinition

publicvoidsetIsolationLevel(int$isolationLevel) Establece el nivel de Isolacin que tendr la conexin asociada a la transaccin. El valor del parmetro $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 dependeexclusivamentedesiestasoportadaporelgestorrelacional. publicvoidsetPropagation(boolean$propagation) Estableceunvalorbooleanoqueindicasilastransaccionescreadasalcancelarsecualquierase propagarelestadoalasdemsdeladministradordetransacciones. publicvoidsetTimeout(int$timeout) Estableceeltiempomximoquepuedadurarunatransaccinantesqueseacancelada. publicvoidsetReadOnly(boolean$readOnly) Estableceelcarcterdesololecturadelaconexin 21.15.5 APIdeActiveRecordTransaction

public__construct(boolean$autoBegin=false,TransactionDefinition$definition=null) Constructordeladefinicindelatransaccin. publicbooleancommit() Realizalaoperacindecommitsobrelatransaccinadministrada. publicbooleanrollback() Realiza la operacin de rollback sobre la transaccin administrada. Si la transaccin es

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

240

propagablecancelarotrastransaccionescreadasbajoelmismoTransactionManager. publicbooleanbegin() Permiteiniciarlatransaccinenlaconexinactivaalgestorrelacional. publicDbBasegetConnection() Obtieneleobjetodeladaptadoralgestorrelacionalqueadministradalatransaccin. publicvoidsetIsNewTransaction(boolean$isNew) Establecesilatransaccinhacreadounanuevaconexinalgestorrelacionalestareusando unaexistente. protectedvoidsetPropagation(boolean$propagation) Establece si la transaccin esta en modo de propagacin. La propagacin solo funciona si la transaccinfuecreadaconelTransactionManager. publicboolgetPropagation() Devuelve el estado de propagacin de la transaccin. La propagacin solo funciona si la transaccinfuecreadaconelTransactionManager. 21.15.6 TimeoutsenTransacciones

KumbiaEnterpriseofreceunentornoadministradoparalaimplementacindetransacciones detalformaqueesposibleconocercuandoocurrealgunanovedadconunatransaccin.Los timeoutssonunejemplodeesto,cuandounprocedimientonopuedeobtenerunbloqueopara efectuarlaoperacinunaexcepcindetipoDbLockAdquisitionExceptionesgenerada. Ejemplo:Capturarunaexcepcinalnopoderobtenerunbloqueoenunatransaccin


<?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/KumbiaEnterpriseFrameworkManualdeReferencia

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 validacin definidas por el desarrolladorquegaranticenquelosdatosquesealmacenenenlapersistenciaseanntegros yseevitetodoloqueestoconlleva. Los eventos del modelo: beforeValidation, beforeValidationOnCreate, beforeValidationOnUpdateyvalidationpermitendefinirreglasdevalidacinenformageneral deacuerdoalaoperacinquesevayaarealizarsobreelmodelo: Ejemplo:Definirvalidadoresdeintegridaddedatosenunmodelo
<?php class Customers extends ActiveRecord { protected protected protected protected $id; $name; $e_mail; $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; } } }

ElmtodoprotegidodelosmodelosActiveRecord::validate()recibeensuprimerparmetroel validador con el que se efectuar la validacin y como segundo parmetro una lista de

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

242

opciones para el mismo. Algunos validadores pueden recibir simplemente el nombre del campoavalidarcomosegundoparmetro.Eldesarrolladorpuededeterminarsilavalidacin debe cancelar la accin que se est ejecutando sobre el modelo mediante el mtodo ActiveRecord::validationHasFailed() el cul indica si se han generado mensajes de validacin en las clases validadoras. El devolver false desde cualquiera de los eventos de validacin conllevaalacancelacindelaaccinactualyaqueelmtodosave,createupdatetambin devuelvanfalse. ElListadodevalidadorespordefectoquecontienelaversinestndardeKumbiaEnterprise Frameworksonlossiguientes: Tabla:ValidadorespordefectoquehacenpartedeActiveRecord Validador PresenceOf Descripcin Es un validador implicito para los modelos cuyas entidades tengan atributos NOT NULL y sean requeridos alinsertaractualizar. DateIn Length Validaqueelvalordeunatributodelaentidadtengaun formatodefechavalido. Validaqueelnumerodecaracteresdeunelvalordeun atributodelaentidadtipoStringtengaunlimiteinferior, superiorambos. InclusionIn Valida que el valor de un atributo de la entidad se encuentreenunlistadoestticodefinidoenunvector.El vectorsedefineusandolaopcindomain. ExclusionIn Valida que el valor de un atributo de la entidad no se encuentreenunlistadoestticodefinidoenunvector.El vectorsedefineusandolaopcindomain Numericality Format Valida que el valor de un atributo de la entidad sea numrico. Validaqueelvalordeunatributodelaentidadtengaun formato establecido en una expresin regular, esta se defineusandolaopcinformat. Email Validaqueelvalordeunatributodelaentidadtengaun formatodeemailcorrecto.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

243

Uniqueness

Permite validar que el valor de un atributo no exista en otroregistrodelaentidad.Laopcinfieldpuederecibir un Array cuando se debe validar combinaciones de campos.

21.16.1 ValidadoresparaatributosNoNulos

Cuandosedefineunvalidador,estevalidacualquiervalorquesevayaainsertaractualizar sobrelapersistencia.Algunasveceselatributopuedepermitirnulos,elvalornuloigualser validado por el Validador y si no cumple con las condiciones establecidas generar un mensajeydependiendodelascondicionespodradetenerlaejecucindelaoperacinactual. Una forma de establecer una regla de excepcin para estos casos es agregar la opcin requiredconvalorfalsealmtodovalidate: Ejemplo:Establecerreglasdevalidacindeintegridaddedatosenmodelos
protected function validation(){ $this->validate("Numericality", array(field" => precio_venta", required => false)); if($this->validationHasFailed()==true){ return false; } }

Ejemplo:Validarqueunacombinacindecamposnoserepita
protected function validation(){ $this->validate("Uniqueness", array( field" => array(invoice_number", invoice_preffix) ); if($this->validationHasFailed()==true){ return false; } }

21.16.2

TratarelresultadodeunprocesodeValidacin

Cuando se ejecuta el mtodo inteligente save() se ejecutan los procesos de validacin y los validators asociados al modelo, normalmente, el mtodo save devuelve un valor booleano indicando el xito de la operacin, cuando el valor devuelto es false es posible obtener los mensajesquesehangeneradoytratarlosadecuadamenteparaserpresentadosalusuario. Ejemplo: Obtener los mensajes de validacin cuando falla una operacin de manipulacindedatos

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

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()); } }

AplicandolaAPIdeActiveRecordMessageesposiblepersonalizarlosmensajesdevalidaciny laformaenquesetratan.Enelsiguienteejemplosemuestracomopresentarlosmensajesde validacindecorreoelectrnicocomoadvertenciasyelrestocomoerrores: Ejemplo:PersonalizarlapresentacindelosmensajesdevalidacinmedianteelAPIde 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()); } } }

Elcampoquegeneraelmensajetambinpermitepersonalizarlosmensajesgenerados: Ejemplo: Obtener informacin de los mensajes de validacin en un proceso de manipulacindedatos


<?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/KumbiaEnterpriseFrameworkManualdeReferencia

245

21.16.3

ValidadoresdeUsuario

Eldesarrolladorpuededefinirvalidadoresdeaplicacinqueextiendanseadecuenmejora las reglas de negocio de la aplicacin. Todos los validadores deben cumplir con unos requisitosparasuintegracinconActiveRecordysucorrectaejecucin: El Validador debe estar ubicado en el directorio validators en el directorio de la aplicacin.Siestedirectorionoexistesedebecrear. Los archivos donde se implementan las clases validadoras deben tener la siguiente convencin:NombreValidator.php LosvalidadorespuedenheredarlaclaseActiveRecordValidatorlacualimplementauna estructura consistente para el desarrollo de un validador eliminando detalles poco usables. LainterfaceActiveRecordValidatorInterfacetienelasiguienteestructura:
interface ActiveRecordValidatorInterface { public public public public } function function function function __construct($record, $field, $value, $options = array()); checkOptions(); getMessages(); validate();

Lasclasesvalidadorasdebenllamarseusandolaconvencin:NombreValidator LasclasesvalidadorasdebenimplementarlainterfaceActiveRecordValidatorInterface.

Tanto el constructor como el mtodo getMessages() se encuentran ya definidos en la clase ActiveRecordValidator. Un validador solo implementa validate y opcionalmente sobrescribe checkOptions.Elprimerorealizalavalidacinensiydevuelveunvalorbooleanoindicandosi elprocesofuesatisfactoriono.ElmtodocheckOptionspermitechequearsilosparmetros enviadosenlasopcionesdelvalidadorsoncorrectos. En el siguiente ejemplo se implementa un validador que proporciona a la aplicacin un servicio de validacin de nmeros de identificacin de acuerdo a las convenciones de algn pas. Los nmeros de identificacin deben ser de 20 dgitos, los 3 primeros deben ser las letrasABCsiesunaempresaXYZsiesunapersonanatural. Elarchivovalidators/IdentificationValidator.phpquedaas:

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

246

Ejemplo:Crearunvalidadorparaintegridaddedatosenmodelos
<?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; } } }

Paraaplicarelvalidadorseinvocaelmtodovalidateenlaimplementacindealgnevento delmodelodetipovalidation: Ejemplo:Implementaruneventodevalidacindeacuerdoalaoperacinejecutada


protected function beforeValidationOnCreate(){ $this->validate("Identification", array(field" => number_iden", type => any)); if($this->validationHasFailed()==true){ return false; } }

21.16.4

EventosenlaValidacin

Los modelos permiten la implementacin de eventos que se lanza cuando se efecta una operacindeinsercinactualizacinyquetienencomoobjetivodefinirlgicadevalidacin

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

247

eintegridaddedatosenlaaplicacin. Acontinuacinsenombranyexplicanloseventossoportadosascomosuordendeejecucin: Tabla:Tiposdeeventosdevalidacinysuordendeejecucin Puede cancelar Operacin Insercin Actualizacin Nombre y beforeValidation operacin: SI Explicacin Se ejecuta antes de que se validen los campos no nulos y se ejecuten validadores Insercin beforeValidationOnCreate SI los de

integridaddedatos. Se ejecuta antes de que se validen los campos no nulos y se ejecuten validadores los de

integridad de datos, solo cuando se realiza unainsercinsobreel modelo. Actualizacin beforeValidationOnUpdate SI Se ejecuta antes de que se validen los campos no nulos y se ejecuten validadores los de

integridad de datos, solo cuando se realiza una actulizacin del modelo Actualizacin Insercin onValidationFails SI(yaseha detenido) Se ejecuta despus que un validador de

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

248

integridadfalla. Insercin afterValidationOnCreate SI Se ejecuta despus de que se validen los campos no nulos y se ejecuten validadores los de

integridad de datos, solo cuando se realiza unainsercinsobreel modelo. Actualizacin afterValidationOnUpdate SI Se ejecuta despus de que se validen los campos no nulos y se ejecuten validadores los de

integridad de datos, solo cuando se realiza una actulizacin del modelo Insercin Actualizacin y afterValidation SI Se ejecuta despus de que se validen los campos no nulos y se ejecuten validadores Insercin Actualizacin y beforeSave SI los de

integridaddedatos. Se ejecuta antes de realizar la operacin requerida sobre el gestorrelacional. Actualizacin beforeUpdate SI Se ejecuta antes de realizar gestorrelacional. Insercin beforeCreate SI Se ejecuta antes de la actualizacin en el

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

249

realizar la insercin enelgestorrelacional. Actualizacin afterUpdate NO Se ejecuta despus de realizar gestorrelacional. Insercin afterCreate NO Se ejecuta despus de realizar la insercin enelgestorrelacional. Insercin Actualizacin y afterSave NO Se ejecuta despus de realizar la operacin requerida sobre el gestorrelacional. Eliminacin beforeDelete SI Se ejecuta antes de eliminar el registro delgestorrelacional. Eliminacin afterDelete NO Se ejecuta despus de eliminar el registro delgestorrelacional. 21.16.5 Implementaruneventodevalidacin la actualizacin en el

Cuando se ejecuta una operacin de insercin, actualizacin eliminacin sobre el modelo ActiveRecordverificasisehandefinidomtodosconlosnombresdeloseventosyencasode encontrarloslosejecutaenelordenmencionadoenlatablaanterior. Loseventosdevalidacindebensermtodosprotegidosrecomendablementeparaevitarque lalgicadedatosquecontienenseexpongapblicamente. En el siguiente ejemplo se implementa un evento que valida que la cantidad a actualizar insertarsobreelmodeloseamayora0segnlosrequerimientosdelnegocio: Ejemplo:Implementaruneventodevalidacinparamodelos
<?php class Products extends ActiveRecord {

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

250

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

21.16.6

Detener/Cancelarunaoperacin

Sidadaslascondicionesalejecutaruneventodevalidacinserequieredetenercancelarla operacinqueseestaejecutandosepuederealizarsieleventolopermiteyasevitarquese almacenendatosincorrectosfavoreciendolaintegridaddeldominiodedatos. Enlatabladeeventosdevalidacinesposibleverificarsieleventopermitelacancelacinde la operacin. Un mtodo que requiera detener la operacin debe devolver el valor boleano false,enestecasolosmtodossave,createyupdatetambindevolveranfalseindicandoque nosepudoefectuarlaoperacin. 21.16.7 Estableceruneventoconunnombrenoestndar

Los eventos de validacin tambin pueden ser definidos usando atributos protegidos en la clase del modelo. De esta forma se pueden definir uno ms eventos en forma dinmica flexibilizandolaimplementacindeestos: Ejemplo:Cambiarelnombreestndardeuneventoenunmodelo
<?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; } } }

Siserequiereejecutarvariosmtodosparaunmismoeventosepuedeindicarunvectorcon la lista de mtodos en el orden de ejecucin requerido. Si alguno falla los dems no sern ejecutados. Ejemplo:Definirmltiplescallbacksparaunmismoeventodeunmodelo

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

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; } } }

Loseventospuedenserestablecidosdinmicamentedesdeotroseventosenelinicializador del modelo. De esta forma se pueden crear potentes modelos de validacin de la lgica de datosenunaaplicacin: Ejemplo:Definireventosdelmodelodinmicamentemedianteatributos
<?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"); } protected function checkOtherQuantity(){ if($this->quantity>50){ Flash::error("La cantidad no puede ser mayor a 50"); return false; } } } } return false;

21.16.8

Eventocuandoelprocesodevalidacindetienelaoperacin

Lasoperacionesejecutadasenelmtodosavepuedenfallarsialmenosunvalidadorfallaen estecasodevelveelvalorbooleanofalseindicandoesteestado.Esposibledefinirunevento llamado onValidationFails que es ejecutado cuando el proceso de validacin devuelve un

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

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 operacin requerida. Ejemplo: Definir un evento a la espera de un fallo en el proceso de validacin de un modelo
<?php class Products extends ActiveRecord { protected function onValidationFails(){ if($this->operationWasCreate()==true){ Flash::error(La insercin fall); } if($this->operationWasUpdate()==true){ Flash::error(La actualizacin fall); } foreach($this->getMessages() as $message()){ Flash::error($message->getMessage()); } } }

21.16.9

Deshabilitareventosdevalidacin

Los eventos de validacin pueden ser deshabilitados para aumentar el rendimiento en aplicaciones que no requieren de ellos cuando se ejecutan procesos de manipulacin de datosquenorequierandeestacaracterstica. El mtodo ActiveRecord::disableEvents(bool $disable) permite cambiar este comportamiento. Un valor booleano true los deshabilita y un valor false los habilita nuevamente. Esta funcionalidadactaenformageneralparacualquiermodelodelaaplicacin.

21.17 Llaves Forneas Virtuales


ActiveRecordpermitedefinirllavesprimariasvirtualesquevalidenlaintegridadrelacionalen lasoperacionesdemanipulacindedatosasegurandoqueloscamposllavecontenganvalores queexistanenlasentidadesreferenciadas. Ventajassobreelcontrolconvencionalaniveldebasedatos: Esposiblevalidarintegridadrelacionalsobrecolumnascontiposdedatosdiferentes Sedisminuyelacargadelmotordebasededatos Es posible controlar la integridad sobre tablas en diferentes motores diferentes

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

253

servidores Sepuedegenerarmensajesdeusuariopersonalizadosdeacuerdoalintentofallidode efectuarunaoperacinporviolacindellavefornea. Sepuedevalidarlaintegridad en motores que no soporten llaves foraneas (MyISAM enMySQL). Se pueden definir llaves forneas que validen la integridad en objetos de la base de datoscomovistasysinonimos. Desventajasdelasllavesforneasvirtuales: El rendimiento no es tan ptimo como el de las administradas directamente por el motordebasededatos. La integridad solo es validada cuando las operaciones se realizan mediante eventos realizadosatravsdelosmodelos. 21.17.1 Crearunallaveforneavirtual Noserequierenindicesenlastablasreferenciadas(aunqueesrecomendadoquelos tengan).

El mtodo protegido de ActiveRecord llamado addForeignKey permite la definicin de llaves forneasvirtualesenelinicializadordelaclasemodelo. Medianteconvencionessecolocasolamenteelnombredelcampoydeestaformalatablay camporeferenciadoseintuyenormalmente: Ejemplo:Definirunallaveforneavirtualporconvencin
<?php class Products extends ActiveRecord { protected function initialize(){ $this->addForeignKey(categories_id); } }

Sinoseutilizaunmodeloentidadrelacinqueuseconvencioneslaformadeindicarlasllaves forneasserealizadeestamanera: Ejemplo:Establecerllavesforneasdeacuerdoalmodeloentidadrelacin

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

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

Opcionesdelasllavesforneas

El cuarto parmetro de addForeignKey permite establecer opciones adicionales como el mensajeagenerarcuandoseviolelaintegridadylasaccionesarealizarcuandoseactualiza borraunregistroyfallaelprocesodevalidacin. Ejemplo:Estableceraccionesdeunallaveforneavirtualenunmodelo
<?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:OpcionesdeaddForeignKey Opcin message on_delete Descripcin Mensaje del validador cuando se viola la llave fornea y la accinefectuadadeberestringirlaoperacin. Estableceunaaccinaejecutarcuandounallaveforneaes violada al hacer una eliminacin de datos en la entidad. El valor es alguna de las constantes ActiveRecord::ACTION_CASCADE ActiveRecord::ACTION_RESTRICT. on_update Estableceunaaccinaejecutarcuandounallaveforneaes violadaalhacerunaactualizacindedatosenlaentidad.El

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

255

valor

es

alguna

de

las

constantes

ActiveRecord::ACTION_CASCADE ActiveRecord::ACTION_RESTRICT. Tabla:Accionesdependiendodelaoperacin Opcin ActiveRecord::ACTION_CASCADE Descripcin

Cuando se realiza una eliminacin de datos indica que todas los datos en llaves dependientes deben ser eliminados antes de efectuar la operacin. Esto permite quenoquedenregistroshurfanos.Enunaactualizacin seactualizaelnuevovalorenlasrelacionesdependientes.

ActiveRecord::ACTION_RESTRICT Indicaquesedebecancelarlaoperacinactualdebidoa la violacin de la llave fornea. El objeto ActiveRecordMessage es cargado con el mensaje establecidoenlaopcinmessage.

21.18 Entidades Temporales


Administrardatosenunaentidadproporcionarecursosimportantesparalasaplicacionesde negocios.Enciertasocasionesserequiereutilizarentidadesparaalmacenardatostemporales quepermitanlaejecucindeprocesosdenegociosinqueestasafecteneldominiodedatos enformanotable. El componente ActiveRecord proporciona el subcomponente TemporaryActiveRecord el cual permite crear modelos que administran sus datos sobre entidades temporales en el gestor relacional. Estetipodeentidadespuedenserconsideradasdealtorendimientoyaquenorequierende escrituradediscoademsestetipodemodelosestnoptimizadosparaunprocesamientoms efectivoenmemoria. En estos casos la persistencia es temporal ya que todos los datos que administra el modelo existen en memoria mientras la conexin al gestor relacional esta activa. Como estas conexionesserealizanenmodonopersistentelosdatosenlasentidadescreadassoloexisten

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

256

durante el tiempo que emplee la peticin en ejecutarse por completo crendose y destruyndosecadavezqueseutilicen. 21.18.1 CrearunTemporaryActiveRecord

Losiguientesedebehacerparacrearunmodelotemporal: Se crea un modelo que extienda al subcomponente TemporaryActiveRecord en el directoriodemodelos. Se debe implementar un mtodo protegido que se debe llamar _tableDefinition es requeridoparaobtenerladefinicindelaentidad,estaconstituyeunarrayasociativo conlasllavesattributeseindexes. La llave attributes es obligatoria y contiene un vector asociativo cuyas llaves correspondenalosnombresdeloscamposycuyovaloresunadescripcindelcampo talycomoesaceptadaporelmtododelosadaptadoresdelcomponenteDbllamado createTable. Cuandosedefinanlosatributosdelmodelocomoprotegidossedebendefinirconlos mismosnombresutilizadosenladefinicindelmtodo_tableDefinition. Si no se definen los atributos protegidos ActiveRecord los definir como pblicos aunqueestonoesrecomendable. Las entidades temporales tambin soportan relaciones unidireccionales y bidireccionalesdefinindosecomoesusualenlosmodelospersistentes. 21.18.2 ComportamientodeunTemporaryActiveRecord

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 conexin por defecto al gestor relacional. La tabla temporal creada tiene el nombre de la clase utilizada las limitaciones del gestorrelacionalencuantoalosnombresdetablasyqueotrasentidadesnoexistan conestenombredebensertenidasencuenta. Las sentencias de creacin de la tabla temporal no corresponden a manipulacin de datos por lo tanto las transacciones globales y locales no tienen en cuenta esta operacin.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

257

Comolatablaescreadaencadapeticinendondesehagausodelmodelolosmeta datos de la tabla no son almacenados as que no es posible obtener informacin de estausandoActiveRecordMetaData. La tabla es destruida en cuanto se cierra la conexin con el gestor relacional, si es requeridodestruirladesdelaaplicacinsepuedeusarelmtododeladministradorde entidades EntityManager::destroyTemporaryEntity(string $name) donde $name es el nombredelmodelo,estemtododestruyelatablatemporalencadaconexinalgestor relacionaldondefuecreada.Siunanuevainstanciadellaclasemodeloesinvocada utilizadalatablatemporalsecrearnuevamente.

21.18.3

TransaccionesconEntidadesTemporales

Las operaciones de manipulacin de datos sobre las entidades temporales soportan transacciones en forma transparente, aunque se debe tener en cuenta que no todos los gestoresrelacionalessoportantransaccionesentablastemporales. Al crear una transaccin ya sea directamente con ActiveRecordTransaction usando TransactionManager se crea una nueva conexin temporal al gestor relacional y es posible quelatablatemporalestcreadasobrelaconexinnotransaccionalpordefecto. Cuando esto se detecta, ActiveRecord crea nuevamente la tabla en la conexin transaccional peroesseguroquelosdatosqueyasehayanalmacenadousandolosmodelosasociadosala conexinnotransaccionalnoestendisponiblesenlanueva. 21.18.4 UsarunTemporaryActiveRecord

Enelsiguienteejemploseilustracomoimplementarunaentidadtemporalycomoutilizarlo enunprocesodenegocio. Elmodelotemporalmodels/product_stadistics.phpquedaas: Ejemplo:Crearunaentidadtemporal


<?php class ProductStadistics extends TemporaryActiveRecord { protected $id; protected $product_id; protected $cantidad; public function getId(){ return $this->id;

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

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 ordenamientoyagrupamientoparaobtenerlasestadsticasdelaventadeunosproductos. Es necesario que las entidades relacionadas al proceso de negocio esten asociadas a la transaccin donde se manipulan los datos de la entidad temporal cuando se instancian directamentedelaclasemodeloseinyectanenelcontroladorusando$this. Ejemplo:Utilizarentidadestemporalescontransacciones
try { $transaction = TransactionManager::getUserTransaction(); $this->Movement->setTransaction($transaction); $this->Cart->setTransaction($transaction); $conditions = "sellDate = '".Date::getCurrentDate()."'";

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

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 mxima 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 modelodedatosparagenerarconsultassimplesconagrupamientosenmsde2entidades relacionadas no relacionadas, proponiendo una forma adicional de utilizar el Object RelationalMapping(ORM). Elconstructordelaclaseaceptaunvectorconlasopcionesdelaconsulta.Deacuerdoaltipo (consultasimple,agrupacindeconteo,sumatoria,mximo,mnimo)queserequierautilizar estosvarian. 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/KumbiaEnterpriseFrameworkManualdeReferencia

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`) );

Losmodelosdeestasentidadessonlossiguientes,(apropsitoseomitenlosgetters/setters): Ejemplo:DefinicindemodelosysusrelacionesparausoconActiveRecordJoin
<?php // Modelo de Categorias de Productos class ProductsCategories extends ActiveRecord { public function initialize(){ // Relacin 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/KumbiaEnterpriseFrameworkManualdeReferencia

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 utilizarlastantoparaobtenerregistrossimplescoleccionesmedianteActiveRecorJoin: Ejemplo:HacerunJoindetresentidades
//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 mtodo getResultSet() del objetoActiveRecordJoin.Elvalordecadacolumnadelaconsultapuedeserobtenidousando ungettervirtualcreadoimplcitamenteencadaobjetoresultadomedianteelnombredela columnacomounapropiedadpblica. Ejemplo:ObtenerlosregistrosgeneradosenunJoinconActiveRecordJoin
//Mediante getters foreach($query->getResultSet() as $result){ print $result->getName()." ". $result->getSellDate()." ". $result->getQuantity()."\n"; } //Mediante atributos pblicos foreach($query->getResultSet() as $result){ print $result->name." ".$result->sell_date." ".$result->quantity."\n"; }

La consulta interna SQL SELECT puede ser examinada mediante el mtodo getSQLQuery() ActiveRecordJoin.Laconsultaanteriorgeneralasiguientesentencia: Ejemplo:SQLgeneradoporActiveRecordJoin
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/KumbiaEnterpriseFrameworkManualdeReferencia

262

NotsecomolasrelacionesadecuadashacenpartedelasentenciaSELECTenformadinmica. 21.19.1 AgrupamientosconActiveRecordJoin

ActiveRecordJoin permite crear consultas avanzadas utilizando agrupamientos. Los agrupamientos soportados son: sumatorias, conteos, mnimos, mximos y promedios. Un agrupamientoseestablecedelasiguienteforma: Ejemplo:AgrupamientosdedatosconActiveRecordJoin
//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 cul 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

ParmetrosdeActiveRecordJoin

LosparmetrossoportadosporActiveRecordJoinson: Tabla:ParmetrossoportadosporActiveRecordJoin Opcin entities Descripcin Unvectorqueindicalosmodelosutilizadospararealizarel join.Nosedebeutilizarelmismonombrelastablassinoel nombre de las clases usadas como modelos para acceder a ellas. conditions Un string con condiciones adicionales del join. No se debe utilizarlosnombresdelastablasenlascondicionessinola convencin{#NombreClase}.(opcional) sumatory average Un vector con los campos en los cuales se debe aplicar un agrupamientodesumatoria.(opcional) Un vector con los campos en los cuales se debe aplicar un

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

263

agrupamientodepromedio.(opcional) count maximum minimum having noRelations Un vector con los campos en los cuales se debe aplicar un agrupamientodeconteo.(opcional) Un vector con los campos en los cuales se debe aplicar un agrupamientodevalormximo.(opcional) Un vector con los campos en los cuales se debe aplicar un agrupamientodevalormnimo.(opcional) Unstringconcondicionesparaelagrupamiento.(opcional). Con el valor true indica que no se deben construir dinmicamente las relaciones entre las entidades del join. Pordefectosuvaloresfalse.(opcional).

21.20 ActiveRecordUnion
El objetivo del subcomponente ActiveRecordUnion es unir dos ms objetos ActiveRecordResultsetActiveRecordRowsinvolcaramemorialosresultadosproducidospor ellosconsiguiendounagestindelosrecursosdelaaplicacinmseficiente.

21.21 SessionRecord
ElsubcomponenteSessionRecordpermiteadministrarentidadesdepersistenciadesesinde forma natural como si fuesen entidades pero destinadas a mantener registros de manera independiente por id de sesin. El estado de los objetos instanciados es trasient ya que al terminarselasesinlosdatossevuelveninusables. PordefectolasentidadestipoSessionRecordlocalizanelcamposidquedebenteneruntamao suficiente para almacenar un valor de identificador de sesin. El valor de la variable de configuracin de PHP session.hash_function establece el tipo de algoritmo utilizado para generar el identificador de sesin, si su valor es 0 indica que se usa md5 de 128 bits (35 caracteres)ycuandoes1indicaqueessha1de160bits(40caracteres). La siguiente tabla contiene la estructura necesaria para utilizar una entidad con SessionRecord.
CREATE TABLE `cart` ( `id` int(11) NOT NULL auto_increment,

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

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 definicin 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 ejecutannormalmenteconladiferenciaquelosregistrosgrabadosydevueltossiempreharn referenciaaaquellosdondeelsession_idactualseaeldelcamposiddelatabla.

21.22 PropertyAccessors y Mutators


ActiveRecordaccedealvalordelosatributosdelatablaalrealizarunaoperacinmediantelos mtodos readAttribute y writeAttribute heredados en cualquier modelo. El desarrollador puede sobreescribir estos atributos en la definicin del mdelo y controlar la forma en que obtienen/estableceninternamentelosvaloresdelosatributosdelaentidad. Ejemplo:SobreescribirunPropertyAccessorenunmodelo
<?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


Unmodelotienelapropiedaddeahorrartrabajoalgestorrelacionalmedianteestasopciones. Enelprimeroalrealizarunaoperacindeactualizacinsololoscamposquehancambiadoen la base de datos son actualizados, en la segunda solo los campos que contienen valores no nulosseinsertanenlaoperacin. Por defecto ambas propiedades estan desactivadas para cambiar su valor se deben usar los mtodos protegidos setDynamicUpdate y setDynamicInsert respectivamente. Al activarlas en contra prestacin por ejemplo al actualizar cada registro debe leerse antes de realizar la operacinycomparararcadavalordelosatributosconeldelobjetoactual.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

265

Ejemplo:Establecerlacreacindesentenciasdeinsercinyactualizacinsoloparalos atributosdelmodeloquehancambiando
<?php class Categories extends ActiveRecord { protected function initialize(){ $this->setDynamicUpdate(true); $this->setDynamicInsert(true); } }

21.24 Manejo de Excepciones


LassiguientesexcepcionessongeneradasyasociadasaoperacionesconActiveRecord: Tabla:ExcepcionesgeneradascuandosetrabajaconActiveRecord Excepcin DbException Db Componente Descripcin Excepcin generica lanzada por adaptador de conexin al gestor relacionalutilizado. DbLockAdquisitionException Db Excepcin lanzada cuando la transaccin actual en la conexin no puede efectuar un bloqueo sobre algn recurso por ejemplo unatablaunaseriederegistros. DbSQLGrammarException Db Excepcin lanzada cuando se envia una sentencia SQL mal formadaconerroresdesintaxis. DbInvalidFormatException Db Excepcin lanzada cuando se trata de asignar un valor con un formato invalido al tipo de dato delacolumnaenunaunaentidad. DbContraintViolationException Db Excepcin lanzada cuando la operacin de modificacin actualizacin viola un constraint dellavefornea. ActiveRecordException ActiveRecord Excepcin generica de

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

266

ActiveRecord. 21.24.1 Capturarexcepcionesdentrodemodelos

Si se requiere tratar las excepciones generadas dentro de un modelo en especfico se puede sobreescribir el mtodo protegido exceptions el cul recibe las excepciones generadas y por defectolasrelanzaalcontroladorlavistadondeseinvocelmodelo. Enelsiguienteejemploseilustracomoefectuarunprocedimientoquetratelasexcepciones porviolacindellavesforneasparaunmodeloenparticular: Ejemplo:Tratarexcepcionesporviolacindellavefornea
<?php class Inventory extends ActiveRecord { protected function exceptions($e){ if($e instanceof DbConstraintViolationException){ //Algn procedimiento } else { throw $e; } } }

21.24.2

InformacindeExcepciones

Lasexcepcionesgeneradasporeladaptadoralmotordebasededatosusualmentepermiten obtenermayorinformacinsobreelentornodelaexcepcinagregandodatoscomoelcdigo ydescripcindebajonivelgeneradasporelRTP. En el captulo del componente Db se explica como obtener mayor informacin sobre excepcionesgeneradasenlabasededatos.

21.25 Plugins de Modelos


LosPluginsdemodeloscapadedatospermitenextenderlafuncionalidaddelcomponente ActiveRecord y sus subcomponentes. La arquitectura de plugins de ActiveRecord permite observar,extenderymanipularelcomportamientodelosmodelosdelaaplicacinsegnlas condicionesloexijan. Los plugins permiten interceptar eventos de los modelos de tal forma que estos sean observables y adems ejecutrse uno tras otro de manera centralizada sin requerir

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

267

refactorizacinreintegracinenlaaplicacin. 21.25.1 CrearunPlugindeActiveRecord

LospluginsdeActiveRecordsonclasesqueimplementaneventosquesoninvocadosamedida queavanzalaejecucindelprocesodeaccesoalacapadedatosencualquierpeticin.Estas clasesdebencumplirconlossiguientesrequerimientos: Debenestarubicadoseneldirectoriodepluginsusualmenteapps/appname/plugins Elnombredelarchivoqueimplementalaclasedebeserelnombredelplugin ElnombredelaclasedebetenerlaextensinPlugin LospluginsdecontroladordebenheredardelaclaseModelPluginsersubclasedeella Las clases pueden implementar mtodos pblicos que referencian los eventos ocurridos en loscontroladores,lalistadeelloseslasiguiente: Tabla:EventosquesepuedenimplementarenpluginsdeActiveRecord NombreEvento afterInitialize onException Descripcin Ocurre despus de inicializar un modelo. Normalmente los modelossoninicializadossolounavezencadapeticin. Ocurrecuandosegeneraunaexcepcindentrodeunmodelo.

21.26 Organizacin de Modelos


Losarchivosdemodelosdebenestarubicadoseneldirectoriomodels/dondelavariablede configuracinmodelsDirloindique.Cuandolosmodelossecarganenmodoautoinicializador esposibleorganizarlosensubdirectoriosdetalformaquerepresentenungrupocategora lgicaalcualpertenezcan. Unejemplodeunaorganizacinlgicaeselsiguiente: Ejemplo:Organizacinlgicademodelos
models/ base/ modelBase.php security/ roles.php users.php access_list.php inventory/

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

268

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

21.27 Auto-inicializacin de Modelos


Los modelos pueden inicializarse de 2 formas, automticamente dinmicamente. Por defectolosmodelossonautoinicializadosestosignificaqueencadapeticintodaslasclases deldirectoriodemodelossonledasyseconstruyenlasrelacionesyrestriccionesdefinidas enellos. Elusarunaformalaotradependedeltipodeaplicacinquesetenga.Esrecomendableusar autoinicializacincuando: Elservidordondeestinstaladalamaquinatienebuenasprestaciones(discosduros rpidos,procesadoresdeltimageneracin,etc). Conrelacinalasprestacionesdelservidorelnmerodemodelosysucomplejidaden cuantoarelacionesyrestriccionesesmoderadobajo. Desventajasdelaautoinicializacin: Dependiendodelascondiciones,elaccesoadiscopuedeelevarseconsiderablemente encadapeticin Si los modelos tienen muchas relaciones y restricciones se podra aumentar el consumodememoriainnecesariamente Serecomiendautilizarinicializacindinmicacuando: Elservidortienebajasprestacionesunaconcurrenciaelevada Laaplicacinrequieredemodelosenformaselectivasinquehayaunpatrndefinido deaccesoaellos Elnmerodemodelosdelaaplicacinesaltoyhaymuchasrelacionesyrestricciones entreellas. Laaplicacinrequierefrecuentementedelaccesoalamayorpartedelosmodelosen lamayorpartedelosprocesosdenegocio.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

269

Desventajasdelainicializacindinmica: Procesosquerequieranvariosmodelossimultaneamentepuedeelevarlosrecursosde procesamientosolicitadosporlaaplicacin Sololosmodelosinicializadossonllevadosalasvistasasociadasalapeticin 21.27.1 Activarinicializacindinmica

Para activar la inicializacin dinmica se debe agregar la seccin entities con la variable de configuracinautoInitialize=Offalarchivodeconfiguracinconfig/config.inidelaaplicacin. Unarchivodeconfiguracinconfig.iniquedaas: Ejemplo:Definirautonicializacindemodelosenlaconfiguracin
[application] mode = development name = "Project Name" interactive = On dbdate = YYYY-MM-DD debug = On [entities] autoInitialize = Off

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

270

22 Componente EntityManager
22.1 Introduccin
ElcomponenteEntityManageresusadointernamenteporelframeworkyprincipalmentepor ActiveRecord y Controller para administrar las entidades, sus relaciones de asociacin, 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 mtodos solo pueden ser invocadosestticamente,deestaformaseaseguraquelosdatosdeentidadesysusrelaciones existansolounavezporprocesodenegocio.

22.2 Obtener una nueva instancia de un Modelo


CadavezquesellamaelconstructordeunaclasedeActiveRecordseejecutanprocedimientos internos como la inicializacin del modelo, tals como la localizacin del data source, la definicindelasrelacionesconotrosmodelosyenalgunoscasossetratadevolcarlosmeta datosdelatablasiestosnoseencuentrandisponiblesparalaaplicacin. El componente EntityManager proporciona el mtodo getEntityInstance(string $instanceName)quepermiteobtenerunainstanciadelaentidadyainicializadamejorandoel rendimientodeunprocesodenegocio. Enelsiguienteejemplosemuestracomosereemplazaelinstanciamientomediantenewporel mtododeobtenerinstanciasyainicializadasenblanco: Ejemplo:Obtenerinstanciasdemodelosenformaeficiente
<?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/KumbiaEnterpriseFrameworkManualdeReferencia

271

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

} } $transaction->commit();

} $transaction->rollback();

Nota: Podra 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 estableceelparmetrodegetEntityInstanceusandoelnombredelaclasemodelotalycomo fudefinidaenelarchivodelmodelo.

22.3 API del Componente EntityManager


El desarrollador no debera interactuar directamente con este componente ya que ActiveRecordysussubcomponentessonlosencargadosdeutilizaresteAPIparaadministrar las relaciones y la informacin de las entidades. La siguiente API es presentada buscando ayudaraextenderelcoredelframeworkreemplazarestecomponente. 22.3.1 Mtodosparainicializarmodelosyobtenerinstanciasdeellos staticfunctionarraygetEntities() Obtieneunvectorcontodaslasentidadesinicializadasenlapeticinactual. staticfunctionvoidsetAutoInitialize(boolean$autoInitialize) Establecesilosmodelossonautoinializadosno. staticfunctionbooleangetAutoInitialize() Indicasilosmodelosestnsiendoautoinicializadosno. staticfunctionvoidsetModelsDirectory(string$modelsDir) Estableceeldirectoriodesdedondedebensercargadoslosmodelos. staticfunctionmixedgetEntityInstance(string$entityName,boolean$newInstance=true) Obtieneunainstanciadeunaclasedeunmodelo.Sisepasafalseenelsegundoparmetrose obtieneunainstanciaexistente.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

272

staticfunctionvoidinitModelBase(string$modelsDir) CargalaclaseActiveRecordubicadaeneldirectoriodemodelosdelaaplicacin. staticfunctionvoidinitModels(string$modelsDir) Inicializaeldirectoriodemodeloscargandoloseinicializandolos. staticfunctionbooleanisEntity(string$entityName) Permiteconsultarsiexisteundeterminadomodeloenlapeticinactual. staticfunctionbooleanisModel(string$modelName) EsunaliasdelmtodoisEntity. staticfunctionstringgetEntityName(string$model) Obtieneelnombredeunaentidaddeacuerdoasuorigendedatos(tabla). staticfunctionvoidaddEntityByClass(string$entityClass) Inicializaundinmicamentemodeloporelnombredesuclase. 22.3.2 Mtodosparaadministrarrelacionesdemultiplicidad staticfunctionbooleanexistsBelongsTo(string$entityName,string$relationRequested) Permite consultar si una entidad est relacionada con otra mediante una relacin tipo belongsTo(muchosa1)almenosunidireccionalmente. staticfunctionbooleanexistsHasMany(string$entityName,string$relationRequested) Permite consultar si una entidad est relacionada con otra mediante una relacin tipo hasMany(1amuchos)almenosunidireccionalmente. staticfunctionbooleanexistsHasOne(string$entityName,string$relationRequested) PermiteconsultarsiunaentidadestrelacionadaconotramedianteunarelacintipohasOne (1a1)almenosunidireccionalmente. static function boolean getBelongsToRecords(string $entityName, string $relationRequested, ActiveRecord$record) Obtiene un resultado de los registros relacionados mediante una relacin de multiplicidad

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

273

belongsTo. El parmetro $record es la instancia de un modelo utilizada para efectuar la operacin. static function boolean getHasOneRecords(string $entityName, string $relationRequested, ActiveRecord$record) Obtiene un resultado de los registros relacionados mediante una relacin de multiplicidad hasOne. El parmetro $record es la instancia de un modelo utilizada para efectuar la operacin. static function boolean getHasManyRecords(string $entityName, string $relationRequested, ActiveRecord$record) Obtiene un resultado de los registros relacionados mediante una relacin de multiplicidad hasMany. El parmetro $record es la instancia de un modelo utilizada para efectuar la operacin. static function void addBelongsTo(string $entityName, string $fields='', string $referenceTable='',string$referencedFields='',string$relationName='') AgregaunarelacinbelongsToaladministradordeentidadesenformaprogramacional. staticfunctionvoidaddHasMany(string$entityName,mixed$fields='',string$referenceTable='', mixed$referencedFields='') AgregaunarelacinbelongsToaladministradordeentidadesenformaprogramacional. static function void addHasOne(string $entityName, mixed $fields='', string $referenceTable='', mixed$referencedFields='') AgregaunarelacinhasOnealadministradordeentidadesenformaprogramacional. staticfunctionvoidaddTrasientAttribute(string$entityName,string$attribute) Agregaunatributodeunaentidadquenodebeserpersistido. staticfunctionarraygetRelationsOf(string$entityName) Obtieneunarrayconlasrelacionesquehansidodefinidasparaunadeterminadaentidad. 22.3.3 MtodosadminitrarparaEntidadesTemporales staticfunctionbooleanexistsTemporaryEntity(string$entityName)

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

274

Permiteconsultarsiunaentidadtemporalyahasidodefinida. staticfunctionvoidaddTemporaryEntity(string$entityName) Agregaunaentidadtemporalaladministradordeentidades. staticfunctionvoiddestroyTemporaryEntity(string$entityName) Destruyeunaentidadtemporaldeladministradordeentidades. staticfunctionbooleanisCreatedTemporaryEntity(DbBase$connection,string$entityName) Consultasiunaentidadtemporalyahasidocreadaenunadeterminadaconexin. 22.3.4 Origenesdedatos staticfunctionstringgetSourceName(string$entityName) Obtieneelorigendedatos(tabla)deunadeterminadaentidad 22.3.5 Administrargeneradoresdeentidades static function void setEntityGenerator(string $entityName, string $adapter, string $column, array$options) Estableceelgeneradordeunadeterminadaentidad. staticfunctionbooleanhasGenerator(string$entityName) Indicasiunaentidadtienedefinidoalgungenerador. staticfunctionActiveRecordGeneratorgetEntityGenerator(string$entityName) Obtieneelgeneradordeunadeterminadaentidad. staticfunctionarraygetAllCreatedGenerators() Obtienetodoslosgeneradoresdefinidosenlapeticinactual. 22.3.6 LLavesforneasvirtuales static function void addForeignKey(string $entityName, array $fields='', string $referenceTable='',array$referencedFields='',array$options=array()) Estableceunallaveforneavirtualenunaentidad.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

275

staticfunctionarraygetForeignKeys(string$entityName) Obtienelasllavesforneasvirtualesdefinidasparaunaentidad. staticfunctionbooleanhasForeignKeys(string$entityName) Permiteconsultarunaentidadtienellavesforneasvirtualesdefinidas.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

276

23 Componente TransactionManager
23.1 Introduccin
Elobjetivodeestecomponenteesadministrarlastransaccionesglobalesrequeridasporlos procesosdenegociodeunaaplicacin.SuAPIesutilizadaparaaccederaungestorrelacional enunaunidaddetrabajoenparticular.Todalaarquitecturadeestecomponenteproporciona alasaplicacionesdesarrolladasenKumbiaEnterpriseuncontenedorparaadministracinde transaccionesenPHPcomolosusadosenJavaEE. Es responsable de abrir y cerrar transaciones manteniendo unidades de trabajo en forma controlada.Lastransaccionespuedensercreadasprogramacionalmentedeclarativamente.

23.2 Contexto de Scope Persistente


El TransactionManager es el puente para que objetos del ORM puedan interactuar con su contextopersistenteadecuado.Cadaobjetoqueesligadoaunatransaccinadministradapor elcontenedoresnotificadodeotrastransaccionesactivasenelmismocontexto.Losobjetos mantienensuestadoyesteesreplicadocuandoseabrecierralatransaccininformandoel estadodelamisma.

23.3 Event Listeners


El componente TransactionManager hace uso del CommonEventInfraestructure de Kumbia Enterprise para notificar eventos a los objetos dependientes de una transaccin y tambin entreellosmismos. Loseventossoportadosson: Tabla:EventListenersdeTransactionManager Evento delete create update preInsert preDelete mismoenlapersistencia. Ocurrecuandounobjetoescreado. Ocurrecuandounobjetoesactualizado. Ocurreantesderealizarunainsercindeunregistro. Ocurreantesderealizarunaeliminacindeunregistro. Descripcin Ocurre cuando un objeto es destruido cuando se replica el estado del

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

277

preLoad postInsert postDelete postUpdate

Ocurrealcrearunobjetoinstanciadocomoresultadodeunaconsulta. Ocurredespusderealizarunainsercin. Ocurredespusderealizarunaeliminacin. Ocurredespusderealizarunaactualizacin.

23.4 Estados de las entidades


Las entidades pueden tener los siguientes estados cuando intervienen en procesos transaccionales:

EstadoNew:Cuandounaentidadescreadamedianteeloperadornewpordefectose

encuentraligadaaunaconexinnotransaccionalynorepresentaningunregistrodelabase dedatos.

EstadoManaged:Cuandounaentidadestasociadaaunatransaccincreadaporel

TransactionManagersedicequeseencuentraenestadoadministrado. EstadoDetached:Cuandolaentidadperteneciaunatransaccinadministradapero latransaccinyafuecerradasucontextofuecambiadoalaconexinnotransaccional. EstadoRemoved:Cuandolaentidadfueeliminadadelapersistenciayporlotantono puedeestarasociadaauncontextotransaccional.

23.5 Asignar el objeto al estado administrado


Los mtodos de ActiveRecord llamados setTransaction() y detachTransaction() permiten cambiarprogramacionalmenteelestadotransaccionaldeunobjeto. Ejemplo:CambiarunobjetoActiveRecordaunestadoadministrado
<?php $transaction = TransactionManager::getUserTransaction(); $customer = new Customer(); $customer->setTransaction($transaction); $customer->setName(John); $customer->setSurname(Smith); $customer->save(); $transaction->commit(); $customer->detachTransaction();

Cuando la transaccin es cerrada ya sea por un rollback commit los objetos no son automticamentecambiadosalestadodetached.Lastransaccionescerradasyanosonusables perolaunidaddetrabajomantienesudependenciaalatransaccin.Eldesligamientodelos objetos de la transaccin puede realizarse manualmente llamar el mtodo

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

278

detachDependencies()deActiveRecordTransaction.

23.6 API de TransactionManager


static function ActiveRecordTransaction getUserTransaction(TransactionDefinition

$definition='') Crea obtiene una transaccin ActiveRecordTransaction. Si se define una definicin de transaccinsecreaunanueva. staticfunctionvoidinitializeManager() Inicializaeladministradordetransacciones.Eldesarrolladornodebeinvocarestemtodoya queesautomticamentellamadoporelcontenedordeaplicacionesaliniciarlapeticin. staticfunctionvoidrollbackPendent() Realiza un rollback sobre todas las transacciones administradas por el TransactionManager. Cuando ocurre una excepcin no capturada el framework llama este mtodo para cancelar cualquieroperacinpendienteyascuidarlaintegridaddelosdatos. staticfunctionvoidcommit() RealizauncommitsobretodaslastransaccionesadministradasporelTransactionManager. staticfunctionvoidrollback() RealizaunrollbacksobretodaslastransaccionesadministradasporelTransactionManager. staticfunctionvoidnotifyRollback(ActiveRecordTransaction$transaction) Permite notificar a otras transacciones administradas por el TransactionManager que una transaccinrealizounrollbackbuscandoquelasdemstambinlohagan. staticfunctionvoidnotifyCommit(ActiveRecordTransaction$transaction) Permite notificar a otras transacciones administradas por el TransactionManager que una transaccinrealizouncommitbuscandoquelasdemstambinlohagan.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

279

Parte4:Lacapadepresentacin

24 Presentacin
24.1 Introduccin
La capa de presentacin es la tercera de la arquitectura de una aplicacin Web y permite definir interfaces y mtodos para interactuar con el usuario final as como presentarle informacinalmismo.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

280

25 Componente View
25.1 Introduccin
El componente View se encarga de administrar la forma estndar en la que se genera la presentacinalusuariofinalensuexplorador. LapresentacinestndarenunaaplicacinenKumbiaEnterprisesebasaenvariospatrones de diseo que permiten reducir la codificacin y hacer ms mantenible esta parte del desarrollo. El primer patrn utilizado es Template View el cul habla de utilizar tags personalizados marcasembebidasenelcontenidodinmicoproporcionandoflexibilidadypoderparacrear interfacesweb. ElsegundopatrneselTwoStateViewelcualpermitedefinirmltiplesinterfacesdeacuerdo al dispositivo cliente desde el cul se este se accediendo a la aplicacin. Este tipo de implementacin favorece principalmente aplicaciones que accedan desde un browser un dispositivomvilcomountelefonocelular,endondeesnecesariopersonalizardetallespara cadatipodeinterfaz. LaarquitecturaMVCpresentaelconceptodevistalaculactacomopuenteentreelusuario finalylalgicadedominioenloscontroladores.

25.2 Jerarqua de vistas en la presentacin


UnajerarquadearchivosconvistasimbebiblessoportadasporelcomponenteViewpermite reducir la codificacin creando puntos de presentacin comunes para la aplicacin, controladoresmediantelaimplementacindeplantillas. Cadapartedelapresentacinsecreaenunarchivoubicadoenunaestructuraconvenidade directorioseneldirectoriodelaaplicacinllamadoviews/. El componente View permite definir la presentacin en varios niveles, cada uno contiene al siguiente:

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

281

Tabla:NivelesdepresentacinenelcomponenteView ArchivoUbicacin index.phtml directorioconnombredelcontrolador directorioconnombredel controlador/archivoconnombredela accin.phtml layouts/archivoconnombredel controlador.phtml layouts/nombretemplate.phtml directorioconnombredel controlador/_nombrevistaparcial.phtml partials/_nombrevistaparcial.phtml Permite establecer una vista comn para todaslasaccionesdelcontrolador. Permite establecer una plantilla comn para varioscontroladores. Permite establecer vistas parciales que se pueden incluir en varias vistas de acciones delcontroladoractivo. Permite establecer vistas parciales que se pueden incluir en cualquier vista template delaaplicacin. El componente View no requiere que exista cada componente de presentacin que se mencionanteriormente,elnicorequeridoeslavistaprincipal. 25.2.1 VistaPrincipal En el directorio views/ se puede encontrar el archivo index.phtml que implementa el encabezadoXHTMLestndarparacualquiervistadelaaplicacin: Ejemplo:Vistaprincipalviews/index.phtmlpordefecto
<?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>

Descripcin Contiene la vista principal y encabezado XHTMLdetodaslasvistas. Permite establecer archivos con vistas para cadaaccindelcontrolador. Permitecrearunapresentacinparalaaccin activaenelcontrolador.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

282

</html>

Por defecto se utiliza un encabezado XHTML 1.0 Strict el cul propende por aplicaciones basadasenestndaresyquefuncionanmejorenlosnavegadoresmsavanzadosdelmercado. Los helpers Core::stylesheetLinkTags() y Core::javascriptBase() incluyen archivos JavaScript comoframeworksyutilidadesademsdelosCSSincrustadosenotrasvistasactivas. ElXHTMLgeneradoporlavistaanteriores:
<?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='/apppath/css.php?c=style&p=/app-path' /> <script type='text/javascript' src='/apppath/javascript/scriptaculous/protoculous.js'></script> <script type='text/javascript' src='/hfos/javascript/core/base.js'></script> <script type='text/javascript' src='/apppath/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>

NoteseelllamadoaView::getContent(),esteimprimetodoelcontenidogeneradoenellayout vistasactivasenlaaplicacinenellugarqueseindique. 25.2.2 RequerimientosdelaVistaPrincipal Esrecomendablenoeliminarlosllamadosaloshelpersestndarenlavistaprincipalyaque esto puede impactar el comportamiento del framework. En general los requerimientos del contenidodelavistaprincipalsonlossiguientes: Sunombredebeserindex.phtmlymantenerseenlarazdeviews/ IncluirlosarchivosJavaScriptqueseutilicenencadapeticinalaaplicacin IncluirlosarchivosCSSqueseutilicenencadapeticinalaaplicacin IncluircodigoXHTMLqueseacomnacadacontroladoryaccindelaaplicacin

25.2.3 RequerimientosVistasaniveldeControlador Generalmentecadaaccinsolicitadapresentasolicitainformacindiferentealusuariodetal formaqueelflujodelaaplicacinseaconsistentetantoparaeldesarrolladorcomoparalos

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

283

usuarios.Losrequerimientosdelasvistasaniveldecontroladorson: Es necesario que exista un directorio con el nombre del controlador donde se encuentrelaaccin ElnombredeldirectoriodebeirenminsculasysinelsufijoController. Elarchivodelavistadebetenerlaextensin.phtmlyelnombredebeserelnombrede laaccinsinelsufijoAction. 25.2.4 RequerimientosdeLayoutsdeControladores Loslayoutsdecontroladoressonvistasquecontienenfragmentoscomunesdepresentacin que son validos para cualquier accin del controlador. Los requerimientos de los layouts de controladoresson: Unarchivoconelnombredelcontroladoreneldirectorioviews/layoutsdebeexistir. ElnombredelarchivodebeirenminsculasysinelsufijoController. Elarchivodebetenerextensin.phtml. 25.2.5 RequerimientosdeVistasParcialesenControladores Enocasionesfragmentosdepresentacincomomens,encabezados,piedepaginas,etcson comunes a varias acciones de un controlador pero no a todas, en estos casos se puede implementarvistasparciales.Losrequerimientosdelasvistasparcialesencontroladoresson: Es necesario que exista un directorio con el nombre del controlador donde se encuentrelavistaparcial. ElnombredeldirectoriodebeirenminsculasysinelsufijoController. El archivo de la vista parcial debe tener la extensin .phtml y el prefijo _ (underscore). 25.2.6 RequerimientosdeVistasParcialesGenerales Aligualquelasvistasparcialesdecontroladoreslasgeneralesrealizanlamismatareaconla diferenciaqueestandisponiblesparacualquierlayout,templatevistadelaaplicacin. Losrequerimientosdelasvistasparcialesgeneralesson:

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

284

Lavistaparcialdebeestarubicadaeneldirectorioviews/partials. El archivo de la vista parcial debe tener la extensin .phtml y el prefijo _ (underscore).

25.2.7 RequerimientosdePlantillasTemplates Lasplantillaspermitenestablecermltiplesfragmentosdepresentacinyaplicarsenantes despusdellayoutdelcontrolador.Losrequerimientosdelasplantallasson: Debenentasubicadoseneldirectorioviews/layouts/. Laextensindelarchivodebeser.phtml

25.3 Insercin automtica y manual de vistas


El componente View utiliza convenciones para insertar automticamente la presentacin correspondienteauncontroladorunaaccin,otroscomponentesdepresentacinrequiere queseestablezcaprogramacionalmentesurelacinconlapresentacindiseada. SiserealizaunapeticinalaaplicacinmediantelaURL:
http://172.16.5.2/company/categories/create

En donde company es el nombre de la instancia del framework, categories es el nombre del controladorycreatelaaccinrequerida. Gracias a la presentacin por convencin el componente View tratar de crear la presentacinapartirdelosarchivos: Si alguno de los archivos mencionados no existe se trata de ubicar el siguiente y as sucesivamente. EnestesegundocasolaURLsolicitadaes: default/views/categories/create.phtml default/views/layouts/categories.phtml default/views/index.phtml

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

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 aplicacin y categories es el nombre del controlador. El nombre de la accin no se ha establecidoporloqueseasumequeesindex. Losarchivosdepresentacinsonlossiguientes: press/views/categories/index.phtml press/views/layouts/categories.phtml default/views/index.phtml

25.4 Implementar los tipos de vistas


Enelsiguienteejemploseilustralostiposdevistasysuintegracinenlapresentacindeuna aplicacin.Elcontroladorcustomersseinicializacon3templates: Ejemplo:Aplicarmultiplestemplatesaunmismocontrolador
<?php class CustomersController extends ApplicationController { public function initialize(){ $this->setTemplateBefore("template1"); $this->setTemplateAfter(array("template2", "template3")); } public function createAction(){ } public function updateAction(){ } }

Los mtodos del controlador setTemplate y setTemplateAfter permiten insertar plantillas antes y despus del layout del controlador. Los templates como se mencion deben estar ubicadosenviews/layouts. Elarchivodeplantillaviews/layouts/template1.phtmltiene:
<div style='background:yellow;padding:10px'> <h2>Template 1</h2> <?php View::getContent(); ?> </div>

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

286

El llamado a View::getContent() indica donde se debe incrustar el contenido de otras vistas contenidasporelfragmentodepresentacin. Elarchivodeplantillaviews/layouts/template2.phtmltiene:
<div style='background:#faca22;padding:10px'> <h2>Template 2</h2> <?php View::getContent(); ?> </div>

Elarchivodeplantillaviews/layouts/template3.phtmltiene:
<div style='background:#ccccf2;padding:10px'> <h2>Template 3</h2> <?php View::getContent(); ?> </div>

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

El mtodo View::renderPartial inserta una vista parcial que esta ubicada en el mismo directoriodecontroladorviews/customers/.Notsequeelprefijo_delasvistasparcialeses omitidoapropsitoalestablecerelnombredeesta. Lavistaparcialviews/customers/_header.phtmltiene:
<h4>Este es el encabezado</h4>

Lavistaparcialviews/customers/_footer.phtmltiene:
<h4>Este es el pie de pgina</h4>

Lavistadelaaccincreateenelarchivoviews/customers/_create.phtmltiene:
<div style='background:#eac2ff;padding:10px'> <h3>Accin Create</h3> <?php View::getContent(); ?> </div>

Lavistadelaaccinupdateenelarchivoviews/customers/_update.phtmltiene:

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

287

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

Elresultadoobtenidoenelexploradoralinvocarlaaccincreatees:

Elresultadoobtenidoalinvocarlaaccinupdateencustomerses:

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

288

Como se mostr todos los tipos de fragmentos de presentacin proporcionan una poderosa formadecompartirelcdigoyconstruirinterfacesflexiblessiguiendounprincipiobsicode mantenibilidaddeunaaplicacin.

25.5 Transferir valores del controlador a la vista


Existen2formasdetransferirdatosdelcontroladoralapresentacin: 25.5.1 Transferirmedianteatributospblicos Sialprocesarunaaccinenuncontroladorserequierepresentarinformacinalclientefinal estadebesertransferidaalasvistasasociadasparasuposteriortratamiento.Pordefectolos atributos pblicos de los controladores son transferidos automticamente a la presentacin enformadevariableslocales. Elsiguientecontroladortiene2atributospblicosquesevisualizanalinvocarlaaccininfo: Ejemplo:Utilizaratributospblicosparatransferirvaloresalapresentacin
<?php class PressController extends ApplicationController { public $code; public $name;

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

289

public function indexAction(){ } public function infoAction(){ $this->code = 100; $this->name = Este es un nombre; } }

Todaslasvistasasociadasalapeticintienenaccesoalasvariableslocales$codey$nameque puedenserusadasaconveniencia: Elarchivoviews/layouts/press.phtmltiene:


<h1>El cdigo es <?php echo $code ?></h1>

Elarchivoviews/press/info.phtmltiene:
<p>El contenido de name es <?php echo $name ?></p>

Loqueenconjuntoproduceenelexplorador:

25.5.2 TransferirmediantesetParamToView Lasegundaformadetransferirvaloresdesdelasaccionesdelcontroladoresmedianteeluso delmtodosetParamToView.Estemtodoesespecialmentetilcuandoserequieratransferir grandescantidadesdedatosalasvistasdatospocorelevantesquenoameritenladefinicin deunatributopblicoenelcontrolador. Tambinsiseusancontroladoresconelestadopersistenteactivoesposiblequetambinse quierarestringirladefinicindeatributospblicosalosestrictamentenecesarios. Ejemplo:TransferirdatosalapresentacinmediantesetParamToView


<?php class PressController extends ApplicationController { public function indexAction(){

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

290

} public function showAllAction(){ $this->setParamToView(editions, $this->Editions>find(status=A)); } }

Enlavistasecreaunavariablelocalllamada$editionsconelvalorasignadoenlaaccin.

25.6 Controlar Niveles de Renderizacin


Endeterminadassituacionesesposiblequeserequieracontrolarelniveldeprofundidaddela visualizacin. El componente View permite establecer el nivel de renderizacin mediante el mtodosetRenderLevel(int$level). Est mtodo puede ser invocado desde el controlador desde una capa de visualizacin superiorparaevitarqueotrasseanpresentadas. Tabla:NivelesderenderizacinenView Valor 0 1 2 Constante LEVEL_NO_RENDER LEVEL_ACTION_VIEW LEVEL_BEFORE_TEMPLATE Descripcin Indica que se debe evitar generar cualquiertipodepresentacin. Genera la presentacin hasta la vista asociadaalaaccin. Genera la presentacin hasta las plantillas antes de el layout del controlador. 3 4 LEVEL_LAYOUT LEVEL_AFTER_TEMPLATE Genera la presentacin hasta el layout delcontrolador. Genera la presentacin hasta las plantillas despus de el layout del controlador. 5 LEVEL_MAIN_VIEW Genera la presentacin hasta la vista principal.Archivoviews/index.phtml

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

291

25.7 Utilizar modelos en la presentacin


Los modelos de la aplicacin siempre estn disponibles en la presentacin. Si la opcin de autoinicializacindemodelosestactivasecrearunareferenciadetodoslosmodelosdela aplicacin como variables globales con el nombre del modelo, si no est activa solo los modelosutilizadosenlapeticinactualsernllevadosalapresentacin. Dependiendo del caso se puede usar en forma natural dentro de cualquier tipo de vista los modelosdeestaforma: Ejemplo:Utilizarmodelosenlapresentacincuandosonautoinicializados
//Listar las ordenes de compra foreach($Orders->find() as $order){ print $order->getRecordedDate(); }

Si los modelos no son autoinicializados se puede obtener una instancia de ellos usando el mtododeEntityManagerllamadogetEntityInstance: Ejemplo:Usarmodelosenlapresentacincuandonosonautoinicializados
$orders = EntityManager::getEntityInstance(Orders); foreach($Orders->find() as $order){ print $order->getRecordedDate(); }

25.8 Plugins de View


Los Plugins de presentacin permiten extender la funcionalidad del componente View. La arquitecturadepluginsdeViewpermiteobservar,extenderymanipularelcomportamiento delasvistasdelaaplicacinsegnlascondicionesloexijan. Lospluginspermiteninterceptareventosenlasvistasdetalformaqueestosseanobservables y adems ejecutrse uno tras otro de manera centralizada sin requerir refactorizacin reintegracinenlaaplicacin. 25.8.1 CrearunPlugindeView Los plugins de View son clases que implementan eventos que son invocados a medida que avanza la ejecucin del proceso de presentacin en cualquier peticin. Estas clases deben cumplirconlossiguientesrequerimientos: Debenestarubicadoseneldirectoriodepluginsusualmenteapps/appname/plugins

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

292

Elnombredelarchivoqueimplementalaclasedebeserelnombredelplugin ElnombredelaclasedebetenerlaextensinPlugin LospluginsdecontroladordebenheredardelaclaseViewPluginsersubclasedeella Las clases pueden implementar mtodos pblicos que referencian los eventos ocurridos en loscontroladores,lalistadeelloseslasiguiente: Tabla:EventosquesepuedenimplementarenpluginsdeView NombreEvento beforeRender Descripcin Ocurre antes de empezar el proceso de visualizacin de las vistas asociadas a la peticin. El evento recibe la instancia de ControllerResponseactual afterRender Ocurre despus de terminar el proceso de visualizacin de las vistasasociadasalapresentacin.

25.9 API del Componente View


25.9.1 Jerarquiaderenderizacin staticfunctionstringgetContent(boolean$returnContent=false) ElllamadoaestemtodoleindicaalcomponenteViewdondedebeinsertarelsiguientenivel delajerarquaderenderizacin.Sisepasatrueen$returnContentdevuelveelcontenidodel bufferdesalidahastaelmomento. staticfunctionvoidsetRenderLevel(int$level) Establecehastaquenivelderenderizacinsedebegenerarlapresentacin.Consultelatabla denivelesdepresentacinparaobtenermsinformacinsobreelusodeestemtodo. 25.9.2 Administrarpresentacin staticfunctionvoidhandleViewRender(Controller$controller) Estemtodoactuacomoeladministradordepresentacinpredeterminadorecibiendocomo parmetro el ltimo controlador enrutado. No debera ser invocado directamente por el desarrolladoryaqueesllamadoporelcontenedordeaplicaciones. staticfunctionvoidhandleViewExceptions(Exception$e,Controller$controller) Este mtodo actua como el administrador de presentacin predeterminado cuando no se

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

293

captura una excepcin recibiendo como parmetro el ltimo controlador enrutado. No deberaserinvocadodirectamenteporeldesarrolladoryaqueesllamadoporelcontenedor deaplicacionescuandoestasituacinocurre. 25.9.3 Visualizarvistasprogramacionalmente staticfunctionvoidrenderPartial(string$_partialView,string$_partialValue='') Permite visualizar una vista parcial dentro de otra vista. El segundo parmetro permite transferirunvalordesdelavistadondeseinvocaestemtodoalinteriordelavistaparcial. Lavistaparcialesubicadaeneldirectoriodevistasdelcontroladoractual. Elmtodoseutilizadelasiguienteforma:
<?php View::renderPartial(nombreVista, Un Valor) ?>

Enelarchivo_nombreVista.phtmlelvalortransferidopuedeserusadoas:
<?php echo $nombreVista; ?>

Siserequierevisualizarunavistaparcialenotrocontroladordiferentealactualdebeusarse:
<?php echo View::renderPartial(nombreVista, controller: nombreControlador); ?>

staticfunctionvoidrenderView(string$_view) Permitevisualizarunavistadeaccindentrodeotravista.Lavistadeaccinesubicadaenel directoriodevistasdelcontroladoractual. Elmtodoseutilizadelasiguienteforma:


<?php View::renderView(nombreVista) ?>

Siserequierevisualizarunavistaparcialenotrocontroladordiferentealactualdebeusarse:
<?php echo View::renderView(nombreVista, controller: nombreControlador); ?>

staticfunctionarraygetValidationMessages() ObtienedesdeunavistalosmensajesdevalidacinproducidosporelcomponenteValidation otrocomponentedeusuario. staticfunctionvoidsetContent(string$content) Estableceprogramacionalmenteelcontenidodelbufferdesalidaactualdelapresentacin.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

294

staticfunctionvoidsetViewParam(string$index,string$value) Estableceunavariabledelavistaquesercreadaenunambitolocalcomo$indexconelvalor $value. staticfunctionarraygetViewParams() ObtieneunarrayconlasvariablespasadasalavistausandoView::setViewParam. staticfunctionvoidsetProxyProvider(string$proxy,array$options) Establece un proxyprovider que administre las peticiones de presentacin usando componentesdeterceros. staticfunctionvoidproxyHandler() Mtodopredeterminadoparalaadministracindepresentacincuandoseusancomponentes deterceros staticfunctionbooleanexistsActionView(string$name,string$controllerName='') Permite consultar si una vista de accin existe en el controlador actual en el definido en $controllerName.

25.10 Crear un componente de Presentacin personalizado


El desarrollador puede crear componentes de aplicacin que reemplacen al componente de presentacin View por defecto en Kumbia Enterprise. Como los dems componentes de usuarioestosdebenestarubicadoseneldirectoriolibrarydelaaplicacindondelavariable deconfiguracinlibraryDirindique. Los controladores deben establecer el administrador de presentacin requerido sobrescribiendoelmtodogetViewHandlerdeestaforma: Ejemplo:Cambiarelcomponentequeadministralageneracindelapresentacin
<?php class CustomersController extends ApplicationController { public function getViewHandler(){ return array("MyView", "handleViewRender"); } }

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

295

De esta forma cuando se requiera mostrar la presentacin para el controlador se pasar el control a el componente MyView invocando el mtodo esttico handleViewRender. Este mtodo recibe el objeto del controlador instanciado ( el ltimo que se utiliz despus de realizarenrutamientos)enlapeticin: Ejemplo:Definiruncomponentedeusuarioqueadministerlapresentacin
<?php class MyView { static public function handleViewRender($controller){ //Realizar la presentacin } }

SedebetenerencuentatodalafuncionalidadmencionadaenelcomponenteViewnoestar disponible si se reescribe el componente de presentacin. Los servicios de los componentes Core(CoreConfig,CoreLocale,etc),RouteryDispatcherpuedenresultartilesenestepunto.

25.11 Crear un componente de presentacin de Excepciones no capturadas


Aligualquelapresentacinnormal,ladeexcepcionestambinpuedeserreescritasiguiendo un procedimiento parecido al del anterior. En este caso el mtodo getViewExceptionHandler debeserreescritoenelcontrolador. EJemplo: Definir un componente de usuario que adminisre la presentacin de excepcionesnocapturadas
<?php class CustomersController extends ApplicationController { public function getViewExceptionHandler(){ return array("MyView", "handleViewExceptionRender"); } }

El mtodo recibe la excepcin y el ltimo controlador activo antes de que se generar. El componenteMyViewsera: Ejemplo: Definir un componente de usuario que administre la presentacin de excepcionesnocapturadas
<?php class MyView { static public function handleViewRender($controller){ //Realizar la presentacin normal

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

296

} static public function handleViewExceptions($e, $controller){ //Excepciones } }

ConsultelareferenciadeCoreExceptionyExceptionparaobtenermsinformacinsobrelas excepcionesgeneradasquenohansidocapturadas.

25.12 Integrar otros Engines de presentacin


Sieldesarrolladorrequiere,esposibleintegrarcomponentesdegeneracindepresentacin deterceros(otrosframeworksproyectos).Conestoseaprovechalafuncionalidaddeestos componentessinperderelcomportamientoypotenciadelcomponentedeKumbiaEnterprise View. 25.12.1 Comportamientodelaintegracin

Laintegracinconloscomponentesdetercerostieneelsiguientecomportamiento: Las variables pblicas del controlador, datos pasados mediante setViewParam y modelos utilizados en la peticin ( todos si la autoinicializacin de entidades est activa) son creados en el formato adecuado del componente utilizado. Por ejemplo en Zend_View se debeusar$thisparaaccederaestosvalores. Losnombresdelaextensionesdearchivosdevistaspuedenconfigurarsecomoserequiera ynosedebeusar.phtmlcomoesnormal. Lajerarquiadeinclusinvistaprincipal/templates/layouts/vista/partialssemantienesin cambio alguno con la nica diferencia que el resultado de cada vista es producido por el componenteseleccionado. Todo el framework aplicable puede utilizarse en las vistas creadas con otros engines sin restricciones. LospluginsdeViewfuncionannormalmente 25.12.2 ComponentesSoportados

Actualmente hay soporte para los componentes de presentacin Zend_View de Zend FrameworkySmarty. 25.12.2.1 ProxyaZend_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/KumbiaEnterpriseFrameworkManualdeReferencia

297

componentesedebecambiareladministradordepresentacinenelcontroladoras: Ejemplo:EstablecerunproxyalcomponentedepresentacinZend_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 mtodo View::setProxyProvider establece que se usar el Proxy a componentes terceros Zend.Elsegundoparmetropermiteindicarotrasopcionesopcionalesdelaintegracin. Tabla:ParmetrosdelProxyProvideraZend_View Opcin zendPath class Descripcin LarutaadondeestubicadoelZendFramework.Sihaceparte delinclude_pathdePHPentoncesnoesnecesarioestablecerla. La clase utilizada para administrar las vistas. Por defecto es Zend_View pero puede establecerse cualquier otra que implementelainterfazZend_View_Interface. extension encoding strictVars Consulteladocumentacindeesteframeworkenhttp://framework.zend.com/. 25.12.2.2 ProxyaSmarty Laextensinquetendrnlasvistas.Pordefectoes.phtml. EstaopcinaplicaalconstructordeZend_View. EstaopcinaplicaalcontructordeZend_View.

EsteProxyProviderpermitetratarvistasusandoelSmartyEngine.Laformaenquesedebe indicarqueseusaresteadaptadoreslasiguiente: Ejemplo:GenerarunproxydepresentacinaSmarty


<?php class MyController extends ApplicationController public function getViewHandler(){ {

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

298

View::setProxyProvider('Smarty', array( 'smartyPath' => 'Library', extension => tpl )); return array('View', 'proxyHandler');

OpcionesquerecibeelProxyProvider: Tabla:ParmetrosdelProxyProvideraSmarty Opcin smartyPath extension Descripcin La ruta a donde est ubicado Smarty. Si hace parte del include_pathdePHPentoncesnoesnecesarioestablecerla. Laextensinquetendrnlasvistas.Pordefectoes.tpl

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

299

26 Componente Tag
26.1 Introduccin
EstecomponenteactuacomounabibliotecadeetiquetasquepermitegenerartagsXHTMLen lapresentacindeunaaplicacinmediantemtodosestticosPHPpredefinidosflexiblesque integrantecnologadelladodelclientecomoCSSyJavascript. La ventaja de utilizar estos helpers en lugar de XHTML puro, es que acelera el desarrollo y haceconsistenteelcdigoXHTMLyotrosaspectoscomolasURLsyelconvencionalismodel framework. Cada mtodo esttico recibe sus opciones mediante parmetros por nombre que se pueden enviar en cualquier orden al mismo. En los tag que generan etiquetas es posible enviar parmetrosXHTMLCSSconsurespectivovalorasignandosealaetiquetagenerada.

26.2 Establecer el valor de helpers creados con Tag


UnadelasventajasmsimportantesdecrearcomponentesdeinterfazdeusuarioconTages losencilloquesepuedeasignarelvalordeestosdeformauniformeycontrolada. Cada componente localiza el valor que debe presentar mediante las siguientes reglas. Si algunareglasecumplelasdemsnosonvalidadas: VerificasiexistealgnvalorparalasignadoconTag::displayToylotomacomovalor Verificasihayalgnindiceen$_POSTquecoincidaconelatributoiddelytomacomo valor Verficasiexisteunatributopblicoenelltimocontroladorejecutadoquecoincidaconel atributoiddelylotomacomovalor. Si a algn helper se le asigna directamente con el parmetro value ninguna de las reglas anterioressetieneencuenta. El siguiente ejemplo ilustra la asignacin de un valor a componente de interfaz de usuario creadomedianteTag:

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

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'); } }

EnlavistaelcomoestticosevisualizarconelvalorFseleccionado:
<?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 visualizarlosvalorescapturadosporelusuarioenlapeticinPOST.

26.3 Comportamiento de helpers


Todos los helpers en el componente Tag devuelven cdigo HTML generado por cada uno lo que permite utilizar este para utilizarlo como parmetro de otros helpers usarlo como se requiera.
<?php echo Tag::linkTo(controlador/accion, Tag::image(foto.jpg)) ?>

Loshelperspuedenrecibirparmetrospornombreunarrayasociativocuyosindicessen losnombresdelosparmetros.
<?php echo Tag::form(controlador/accion, method: post) ?> method => post)) ?>

<?php echo Tag::form(array(controlador/accion,

26.4 API del Componente Tag


AcontinuacinsepresentaelAPIdelcomponente: 26.4.1 Crearenlaces publicstaticfunctionlinkTo(mixed$params) PermitecrearunenlaceaunapuntodelaaplicacinutilizandolasconvencionesdeKumbia

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

301

Enterprise;estemtodogenerauntagAdeXHTMLconlaposibilidaddeimplementartanto unaconfirmacinantesdeejecutarsecomodeaplicarcualquieratributoquesedeseeaeste tag. El label de la etiqueta puede ser un texto cualquier otro tag como por ejemplo una imagen. Lasopcionesextendidasdelcomponenteson: Tabla:ParmetrosquerecibelinkTo Nombre confirm text Ejemplo:UsodelinkTo
<?php echo Tag::linkTo(controlador/saludo, Saludar) ?>

Descripcin Permiteestablecerquesepresenteuncuadrodedialogodepresentacin alusuarioqueconfirmelapeticindelaURLeneltagA. Eseltextoqueaparecerenelenlace.

<?php echo Tag::linkTo(controlador/saludo,SALUDAR, class: css_saludo, border: 0, confirm: Desea ir a Saludo?) ?>

GeneraelsiguientecdigoXHTML:
<a onclick='if(!confirm("Desea ir a saludo?)) return false;' border="0" class="css_saludo" href="/instancia/controlador/saludo">SALUDAR</a>

publicstaticfunctionlinkToAction(mixed$params) Genera un enlace a una accin asociada al controlador actual. Al igual que linkTo es posible aplicaratributosHTMLpasandoloscomootrosparmetros. Ejemplo:UsodelinkToAction
<?php echo Tag::linkTo(cancelInvoice, Cancelar) ?>

<?php echo Tag::linkTo(cancelInvoice, Cancelar, class: css_saludo, border: 0, confirm: Desea cancelar la factura?); ?>

OpcionesextendidasdelinkToAction: Tabla:OpcionesextendidasdelinkToAction Nombre Descripcin

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

302

confirm text

Permiteestablecerquesepresenteuncuadrodedialogodepresentacin alusuarioqueconfirmelapeticindelaURLeneltagA. Eseltextoqueaparecerenelenlace.

publicstaticfunctionlinkToRemote(mixed$params) CargaelcontenidodeunaaccinenuncontenedorHTMLdentrodelapresentacinactual.La vistaseobtienemedianteAJAXporloquelapginanoesrecargada. Enelsiguienteejemplosecargarelcontenidodeunaaccineneldivconidthe_menu: Ejemplo:UsodelhelperlinkToRemote


<div id='the_menu'></div> <?php echo Tag::linkToRemote('main/getMenu', 'Texto del Enlace', 'the_menu') ?>

Comolapresentacinesparcialsedebemodificarlasalidadelcontroladorparasolomostrar lavistaasociadaysaltarlostemplateslayouts.
<?php class MainController extends ApplicationController { public function indexAction(){ } public function getMenuAction(){ $this->setResponse('ajax'); } }

TambinesposibleimplementareventosAJAXamedidaqueseprocesalapeticinmejorando laexperienciadeusuario:
<div id='the_menu'></div> <?php echo Tag::linkToRemote("main/getMenu", "Texto del Enlace", "the_menu", "onLoading: $('info').update('Cargando...')") ?>

OpcionesdelinkToRemote: Tabla:ParmetrosquerecibelinkToRemote Nombre confirm Descripcin Permiteestablecerquesepresenteuncuadrodedialogoqueconfirmela

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

303

peticindelaURL. text update onLoading onSuccess Es el texto que aparecer en el enlace. Si no se establece el segundo parmetrodelenlaceestomado. EselcontenedorHTMLdondesepresentarelcontenidodelavista. CdigoJavaScriptaejecutarantesderealizarlapeticinHTTPinterna. CdigoJavaScriptaejecutarcuandolapeticinsecompletaconxito.El objeto con la el resultado peticin puede obtenerse usando la variable transport. onComplete onFailure CdigoJavaScriptaejecutarcuandolapeticinsecompleta.Elobjetocon laelresultadopeticinpuedeobtenerseusandolavariabletransport. Cdigo JavaScript a ejecutar cuando la peticin falla se genera una excepcin.Elobjetoconlaelresultadopeticinpuedeobtenerseusando lavariabletransport.Enestemismoeventosecargaelcontenidodela presentacinenelcontenedor. asynchronous Adicional a lo anterior linkToRemote acepta como parmetro cualquier nombre de atributo aplicablealaetiquetaA. 26.4.2 Componentesdeinterfazdeusuario publicstaticfunctiontextField(mixed$params) Creaunacajadetextoconlosparmetrosestablecidos.
<?php echo Tag::textField("nombre") ?>

Permite establecer si la peticin es asincronica sincrnica. Se debe establecerunvalorbooleanotruefalse.Pordefectoesfalse.

ElcdigoHTMLgeneradoes:
<input type='text' id='nombre' value='' name='nombre' />

El helper textField acepta como parmetro cualquier nombre de atributo aplicable a la etiquetainputtype=text. publicstaticfunctiontextArea(mixed$params) Permitecrearunaareadetexto(textarea)conlosparmetrosestablecidos.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

304

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

LocalgeneraelsiguientecdigoHTML:
<textarea id="nombre" name="nombre" cols="120" rows="5"></textarea>

El helper textArea acepta como parmetro cualquier nombre de atributo aplicable a la etiquetatextarea. publicstaticfunctionnumericField(mixed$params) Crea una caja de texto con los parmetros establecidos validando que su entrada sea solo valoresnumricos. Ejemplo:UsodelhelperTag::numericField
<?php echo Tag::numericField("accountNumber") ?>

El helper numericField acepta como parmetro cualquier nombre de atributo aplicable a la etiquetainputtype=text. publicstaticfunctionnumericPasswordField(mixed$params) Crea una caja de texto para contraseas con los parmetros establecidos validando que su entradaseasolovaloresnumricos.Estecomponentedebeserusadoencasosespecialesde confianza ya que su naturaleza ayudara a un tercero malintencionado a conocer que el passwordsolicitadoesunalgnvalornumrico. Ejemplo:UsodelhelpernumericPasswordField
<?php echo Tag::numericPasswordField("password") ?>

El helper numericPasswordField acepta como parmetro cualquier nombre de atributo aplicablealaetiquetainputtype=password. 26.4.3 Componentesdelistas/combos publicstaticfunctionselectStatic(mixed$params) Creauncomboconvaloresestticosestablecidosenunvector. Ejemplo:UsodelhelperTag::selectStatic

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

305

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

LoculgeneraelsiguienteHTML:
<select id='estados' name='estados'> <option value='@'>Seleccione...</option> <option value='A'>ACTIVO</option> <option value='I'>INACTIVO</option> </select>

OpcionesdeselectStatic: Tabla:ParmetrosrecibidosporselectStatic Nombre useDummy dummyValue dummyText Adicional a lo anterior selectStatic acepta como parmetro cualquier nombre de atributo aplicablealaetiquetaSELECT. publicstaticfunctionselect(mixed$params) Permitegenerarunalistadesplegablemedianteunarray,unActiveRecordResultset(resultado deActiveRecord)unActiveRecordRow(resultadodeActiveRecordJoin): Ejemplo:UsodelhelperTag::select
<?php echo Tag::select('userId', $Users->find('order: name'), 'using: id,name', 'useDummy: yes') ?>

Descripcin Indica que se debe colocar una opcin adicional Seleccione al prinicipiodelalista.Elvalordeesteesuna@. PermitecambiarelvalordelaopcinDummyde@alvalorindicado. Permite cambiar el texto de la opcin Dummy de Seleccione al texto indicado.

Elprimerparmetrodeestehelpereselid/namequetomarlalista.Elsegundosonlosdatos de la lista. Cuando se usa un ActiveRecordResultset ActiveRecordRow se debe establecer el parmetro using, el cul es una pareja de atributos que ser utilizada como valor/texto de cadaopcindelaetiquetaSELECTgenerada.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

306

Opcionesdeselect: Tabla:ParmetrosrecibidosporTag::select Nombre useDummy dummyValue dummyText Adicionalaloanteriorselectaceptacomoparmetrocualquiernombredeatributoaplicablea laetiquetaSELECT. publicstaticfunctionlocaleSelect() Esidenticoalhelperselectperoenesteseaplicaunafuncindelocalizacinacadatextode lasopcinmedianteunobjetodetraduccin. Elsiguienteejemplomuestralosidiomasdisponiblesbasadoenunobjetodetraduccin: Ejemplo:UsodelhelperTag::localeSelect
<?php echo Tag::localeSelect('languageId', $Languages->find('order: name'), $traslate, 'using: id,name', 'useDummy: yes') ?>

Descripcin Indica que se debe colocar una opcin adicional Seleccione al prinicipiodelalista.Elvalordeesteesuna@. Permite cambiar el valor de la opcin Dummy de @ al valor indicado. Permite cambiar el texto de la opcin Dummy de Seleccione al textoindicado.

publicstaticfunctionselectMixed() Este mtodo permite crear listas combinando arrays de valores estticos y resultados dinmicos. Ejemplo:UsodelhelperTag::selectMixed
<?php $dynamicData = $Categories->find(); $staticData = array( N => NINGUNO DE LOS ANTERIORES ); echo Tag::selectMixed('categoriesId', $dynamicData, $staticData, 'using: id,name', 'useDummy: yes') ?>

LasopcionesadicionalesdeselectStaticyselecttambinaplicanaselectMixed.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

307

publicstaticfunctionsubmitImage($caption,$src) Permite crear un botn de envo de formulario con una imagen en vez de un texto. Recibe comoparmetroscaptionquecontendreltextoqueapareceencasodequelaimgenno puedasercargada.srcespecificalarutadelaimagen. Ejemplo:UsodelhelperTag::submitImage
<?php echo Tag::submitImage('Enviar', Core::getInstancePath.'img/submit.png') ?>

Adicionalmenteestehelperaceptacomoparmetrocualquieratributoopropiedadquepueda seraplicablealaetiquetainputtype='image'. publicstaticfunctionbutton() PermitecrearunbotntpicodeHTMLsinningunaaccinpordefecto. Ejemplo:UsodelhelperTag::button


<?php echo Tag::button('Actualizar','id: update','onclick: actualiza()') ?>

Recibeademsloscualquiereventoquepuedadefinirseparaelbotnconsucorrespondiente accinenjavascript. publicstaticfunctionimage($img) Incluyeunaimagenenunavistateniendoencuentaeldireccionamientodelosdirectoriosdel framework.Elparmetroimgdefineelnombredelaimagenquedebeestarincluidadentro delacarpeta'img'. Ejemplo:UsodelhelperTag::image


<?php echo Tag::image('imagen.png', 'alt: Imagen') ?>

Opcionesdeimage: Tabla:ParmetrosrecibidosporTag::image Nombre


alt

Descripcin
Especificauntextoalternativoparalaimagen.

publicstaticfunctionformRemote($params)

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

308

Permite generar un formulario remoto, que ser enviado con una peticin de Ajax. El parmetro params permite ingresar una serie de opciones para el helper.El primer parmetroingresadoeselquedefineelvalordelapropiedadactionparalaetiqueta'form'. Ejemplo:UsodelhelperTag::formRemote
<?php echo Tag::formRemote('usuarios/buscar','update: findResults','required: name') ?>

OpcionesdeformRemote: Tabla:ParmetrosquerecibeformRemote Nombre action complete Descripcin Valorquetendrlapropiedad'action'delformulario. Callbackquecontendrelcodigojavascriptqueseejecutarunavezse activeeleventocompletedelformulario. befote Callback que contendr el codigo javascript que se ejecutar antes de queelformularioseaenviado. success Callbackquecontendrelcodigojavascriptqueseejecutarunavezse activeeleventosuccessdelformulario. required Coleccindecamposquesonrequeridosparaelformulario,ocurreuna validacindedichoscamposantesdehacerelenvo. update publicstaticfunctionsubmitRemote($caption) Crea un botn de envo para el formulario remoto actual. El parmetro caption define el textoquesemuestraenelbotn. Ejemplo:UsodelhelperTag::submitRemote
<?php echo Tag::submitRemote('Buscar', 'update: findResults') ?>

Iddelaetiquetaqueseractualizadaunavezsecompleteelenvo.

OpcionesdesubmitRemote: Tabla:ParmetrosquerecibeTag::submitRemote

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

309

Nombre caption complete

Descripcin Valorquetendrlapropiedad'value'delbotn. Callbackquecontendrelcodigojavascriptqueseejecutarunavezse activeeleventocompletedelformulario.

before

Callback que contendr el codigo javascript que se ejecutar antes de queelformularioseaenviado.

success

Callbackquecontendrelcodigojavascriptqueseejecutarunavezse activeeleventosuccessdelformulario.

update

Iddelaetiquetaqueseractualizadaunavezsecompleteelenvo.

publicstaticfunctionform($action) Crea una etiqueta de apertura de un formulario. El parmetro action es el valor de la propiedad'action'delformulario. Ejemplo:UsodelhelperTag::form
<?php echo Tag::form('usuarios/buscar','id: formSearch') ?>

OpcionesdesubmitRemote: Tabla:ParmetrosquerecibeelhelperTag::form Nombre


action method confirm onsubmit

Descripcin
Valorquetendrlapropiedad'action'delformulario. Mtodoqueserusadoparaelenvodelformulario. Siesdeclaradodefineelmensajedeconfirmacinparaelenvodelformulario. Callback que contendr el codigo javascript que se ejecutar una vez se active el eventosubmitdelformulario.

publicstaticfunctionendForm() Etiquetaquefinalizaelformulario,correspondealcodigodecierrededichaetiqueta. Ejemplo:UsodelhelperTag::endForm()


<?php echo Tag::endForm() ?>

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

310

GeneraelsiguientecodigoXHTML:
</form>

publicstaticfunctionsubmitButton($caption) Permitecrearunbotndeenvoparaelformularioactual.Ingresacomoparmetroelvalor del texto que ser mostrado en el botn. Adems recibe cualquier atributo que pueda ser aplicableaunaetiquetainputtype='submit'. Ejemplo:UsodelhelperTag::submitButton
<?php echo Tag::submitButton('Buscar', 'id: submitSearch') ?>

26.4.4 TratamientodeetiquetasMETA publicstaticfunctionsetMeta(string$name,string$content) Carga en memoria una etiqueta Meta para las cabeceras del documento HTML. Recibe el nombredelaetiquetayuncontenidoparalamisma. Ejemplo:UsodelhelperTag::setMeta
<?php echo Tag::setMeta('description','Busqueda de usuarios.') ?>

publicstaticfunctiongetMetas() Imprime las etiquetas Meta que han sido cargadas previamente. No recibe parmetros e imprimeautomticamenteelresultadoeneldocumentoHTML. Ejemplo:UsodelhelperTag::getMetas()
<?php Tag::getMetas() ?>

26.4.5 TratamientoeInclusindearchivosCSS publicstaticfunctionstylesheetLink(string$src='',$useVariables=false) AdicionaunaetiquetadelinkqueincluyeunarchivoCSSteniendoencuentalasrutasquese definen en Kumbia Enterprise. El primer parmetro constituye la ruta de ubicacin del archivo CSS, el segundo determina si se usar un traductor de las variables globales que se puedenespecificarenlosarchivosCSS. Ejemplo:UsodelhelperTag::styleSheetLink
<?php echo Tag::stylesheetLink('calendar', true) ?>

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

311

Las variables CSS pueden usarse para reemplazar rutas absolutas que ayuden asegurar que imagenesuotrosrecursosseranestablecidoscorrectamente. Lasposiblesvariablesquesepuedenutilizarson: Tabla:VariablesCSSquesoportaelTag::styleSheetLink Variable
@path @img_path

Descripcin
Rutaabsolutadelservidorwebhacialainstanciadelframework. 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.

EnunaclaseCSSlasvariablesseutilizanas: Ejemplo:UsodevariablesCSSconTag::stylesheetLink
.header { background-image: url(@path/img/site/bg-header.gif); }

ParaaumentarelrendimientodelreemplazodevariablesenarchivosCSSestossecacheanen eldirectoriotemp/yserefrescancuandosedetectacambiosenellos. publicstaticfunctionremoveStylesheets() Remuevelostagsdecssagregados. 26.4.6 Componentesparafechas publicstaticfunctiondateField(mixed$params) Permite validar que los dato capturado sea una fecha. Este helper crea 3 listas una para los meses, das y otra para los aos. Los nombres de los meses se muestran en el idioma de la localizacin activa. El valor capturado se almacena en un input oculto con el nombre del dateField. Ejemplo:UsodehelperTag::dateField
<?php echo Tag::dateField("fechaInicial") ?>

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

312

PordefectodateFieldmuestralafecha1deenerodelaoencurso,sinembargoestafechano esvlida. OpcionesdedateField: Tabla:ParmetrosqueaceptaTag::dateField Nombre startYear finalYear useDummy Adicional a lo anterior dateField acepta como parmetro cualquier nombre de atributo aplicablealaetiquetatable. publicstaticfunctionlocaleDateField(mixed$params,Traslate$traslate) EsidenticoadateFieldperolosnombresdelosmesessontomadosdelalistadelocalizacin actualpermitiendomostrarlosvariosidiomas. Ejemplo:UsodelhelperTag::localeDateField
<?php echo Tag::localeDateField("fechaInicial", $traslate) ?>

Descripcin Indicaelaomenorquetendrlalistaao. Indicaelaomayorquetendrlalistaao. Indicasisedebeforzaralusuarioaseleccionarunvalorvalido.

ElhelperlocaleDateFieldaceptacomoparmetrocualquiernombredeatributoaplicableala etiquetatable. 26.4.7 IncluirrecursosJavascript publicstaticfunctionjavascriptInclude(string$src='',boolean$cache=true) Permiteinsertarunaetiqueta<script>conlareferenciaaunarchivojavascriptdelainstancia actual.Laextensin.jsdebeseromitidayaqueelhelperlaagregaautomticamente. Ejemplo:UsodelhelperTag::javascriptInclude


<?php echo Tag::javascriptInclude(lightbox) ?>

GeneraelcdigoHTML:
<script type='text/javascript' src='/instance/javascript/lightbox.js'></script>

Cuando se pasa false en el segundo parmetro se agrega a la URL del HTML generado el

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

313

parmetroGETnocache=valordondevaloresunenteroaleatorioentre0y999999.Deesta formaseobligaalnavegadorarecargarelrecursojavascriptencadapeticin. Ejemplo:UsodelhelperTag::javascriptIncludeconcache


<?php echo Tag::javascriptInclude(lightbox, false) ?>

GeneraelcdigoHTML:
<script type='text/javascript' src='/instance/javascript/lightbox.js?nocache=18261'></script>

SiseomiteelnombredelJavaScriptsetratadeinsertarunarchivoconelmismonombredel controladoractual. publicstaticfunctionjavascriptMinifiedInclude(string$src='') Permite insertar un javascript minimizado con JsMin. El parmetro $src es la ubicacin del archivoenelservidorunaversinpblicaesgeneradalaculesregeneradacadavezquese modificaelarchivooriginal.Losarchivosjavascriptminimizadosconsumenmenoranchode bandaypuedenaumentarlavelocidaddecargadelaaplicacinenclientesconvelocidadesde conexinreducidas. Ejemplo:UsodelhelperTag::javascriptMinifiedInclude
<?php echo Tag::javascriptMinifiedInclude(lightbox) ?>

GeneraelcdigoHTML:
<script type='text/javascript' src='/instance/javascript/lightbox.min.js'></script>

Eldirectoriopublic/javascriptdebetenerpermisosdeescrituraparausarestehelper. 26.4.8 Interaccinconlapresentacin staticfunctionvoiddisplayTo(string$id,string$value) Establece el valor para un componente visual del formulario que se va a presentar en la peticinactual.Elvalordefinidomedianteestehelpertienemayorprioridadcuandosetrata deobtenerelvalordeloscomponentesvisuales. Ejemplo:UsodelhelperTag::displayTo
<?php Tag::displayTo(nombre, Juanita Mendoza);

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

314

Enlavistalacajanombresemuestraconelvalorestablecido:
<?php echo Tag::textField(nombre) ?>

loqueproduce:
<input type=text id=nombre name=nombre value=Juanita Mendoza />

staticfunctionmixedgetValueFromAction(string$name) Permiteobtenerelvalorqueserpresentadoenuncomponentevisualcomoloesunacajade textounalista(combo).Todosloshelpersrealizanunllamadointernousandoestemtodo paraobtenerelvalorapresentardependiendolanaturalezadecadauno. Losvaloressonobtenidosenesteorden: SeverificasiexistealgnvalorparalasignadoconTag::displayToylotomacomovalor Severificasihayalgnindiceen$_POSTquecoincidaconelatributoiddelytomacomo valor Verficasiexisteunatributopblicoenelltimocontroladorejecutadoquecoincidacon Ejemplo:UsodelhelperTag::getValueFromAction
<?php $nameValue = Tag::getValueFromAction(nameValue);

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

315

27 Helpers JavaScript
27.1 Introduccin
EnestecaptulosedescribenclasesyfuncionesenJavaScriptqueproporcionaelframework al desarrollador para agilizar el proceso de creacin de capturas y presentacin de datos e informacinalusuariofinal.

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 usandoelframeworkPrototype.Tienelicenciadeusoymodifcacintotalmenteabiertayhace partedelproyectodeHerramientasJavaScriptdeusocomnenAplicacionesWeb. 27.2.1 Instanciandolaclase Para iniciar el uso de esta herramienta es necesario crear un objeto que definir las propiedades que se usarn para darle formato a los datos. Esto se logra de la siguiente manera: Ejemplo:UsodelhelperJavaScriptFormat
<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 defectoquesernusadosenprincipioparaelformato.Estaspropiedadessondeterminadas poreltipo,conlocualseusalanotacintype:'nombre_tipo',properties:{propiedades}. LostiposdedatossoportadosporelFormatson:numeric,quedefinelaspropiedadesparalos valoresquesernnumricos,tantoenteroscomopuntoflotante;percent,paralosvaloresque tienenunformatodeporcentaje;moneyenelcualseestablecenlosatributosparalosdatos tipomoneda.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

316

OpcionesdelconstructordeFormat:

Tabla:ParmetrosquerecibeelhelperjavascriptFormat Nombre decimals puntoDec sepMiles simbPer simbMon letNegative blankToZero leftZeros complete Valorpor Defecto 0 ',' '.' '%' '$' true true 0 0 todas todas todas percent money todas todas todas todas Establece decimales. Carcterparaelpuntodecimal. Carcter para el separador de Miles. Smbolodeporcentaje. Smbolodemoneda. Establecesipermitenegativoso no. Define si un valor vaco es puestocomocero. Nmero de ceros que sern aadidosalaizquierdadeldato. Tamao obligatorio que deben tener los datos en su parte entera. completeCaracter onCompleteTruncate '0' true todas todas Carcter que se usar para completarlosdatos. Define si se truncar un dato si este supera el tamao definido en complete. No aplica si completeescero. UsodelFormat:
<div><input id="temp" type="text" /></div>

Aplicablea

Descripcin el nmero de

Nmerico:
<input type='boton' onclick='formatoNumerico()' />

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

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>

Ntesequeunavezquehasidocreadoelobjetoformatlonicoquedebehacerseesusarlo para dar formato a los datos que se tengan, asimismo es posible deshacer dicho formato haciendousodelafuncindeFormat.Tambinesimportanteobservarquetodoslosllamados son dinmicos y debe usarse un objeto definido para ello es decir, antes de usar cualquier funcinesnecesariocrearunobjetocomoseindicaenelapartadoInstanciandolaclase,yuna vezhechoestotodaslasfuncionessedebeninvocarconvariable.funcin(parmetros). 27.2.2 FuncionesdeFormat numeric(number) Formatea un nmero que es ingresado como parmetro usando las propiedades definidas para los tipo numeric al instanciar la clase o que hayan sido establecidas con el mtodo changeProperties.Retornaunacadenadecaracteresqueposeeelformatoadecuado. money(number) Formatea un nmero que es ingresado como parmetro usando las propiedades definidas para los tipo money al instanciar la clase o que hayan sido establecidas con el mtodo changeProperties. Retorna una cadena de caracteres que posee el formato adecuado, agregandoelsmbolodepesosrequerido. percent(number) Formatea un nmero que es ingresado como parmetro usando las propiedades definidas para los tipo percent al instanciar la clase o que hayan sido establecidas con el mtodo changeProperties. Retorna una cadena de caracteres que posee el formato adecuado, agregandoelsmboloporcentualdefinido. changeProperties() Cambia las propiedades del tipo especificado. Las propiedades que no sean incluidas conservansuvaloranterior.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

318

format.changeProperties({type: 'numeric', properties: { letNegative: false } });

deFormat(str,type) Deformateaunacadenadecaracteres.Recibecomoparmetrosstrquerepresentalacadena detextoaprocesar;typequedebesereltipodeformatoalquefuesometidadichacadena.

27.3 Clase Validator


Estaclasepermiterealizarvalidacionesalosdiferentesdatosquepuedenserincluidosdentro deunacapturadedatosounavistatal.Estenteramentecodificadaenjavascriptusandoel frameworkPrototype.Tienelicenciadeusoymodifcacintotalmenteabiertayhacepartedel proyectodeHerramientasJavaScriptdeusocomnenaplicacionesWeb. 27.3.1 Instanciandolaclase Antesdehacerusodeestaclasedebeinstanciarseunobjetoquecontendrlaspropiedades paralasvalidacionesqueserequieran.Elconstructordelobjetoaceptatipospredefinidosy otrospersonalizadosquesedefinendinmicamente. TiposdedatopredefinidosenValidator: Tabla:TiposdedatosquerecibeelhelperJavascriptValidator Nombre text number decimal date select email format_number Descripcin Tipoquerepresentavalorestextuales. Seasociaalosnmerosenteros. Seasociaalosnmerosdecimales. Tipodefinidoparalasfechas. Estetipodedatoesusadoenloscombosdeseleccin. Tipo que se usa para los campos que deben contener un email. Se usa para definir los formatos numricos estableciendo una asociacin con algn objeto del tipo format que ser aplicadosobreesecampo. format_decimal format_money RelacionaunavariabledelaclaseFormatconuncampoque contendrvaloresdecimales. RelacionaunavariabledelaclaseFormatconuncampoque

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

319

contendrvaloresdemoneda. format_percent
<script type="text/javascript"> var val = new Validator(); </script>

RelacionaunavariabledelaclaseFormatconuncampoque contendrvaloresporcentaje.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

320

28 Componente PDFDocument
28.1 Introduccin
ElobjetivodelcomponentePDFDocumenteslageneracindedocumentosPDF.Estbasado en la estable librera FPDF pero adaptado y mejorado para ser integrado como parte del frameworkyhacerlopartedesugaranta. LasmejorasconrespectoaFPDFson: SoporteparamltiplescharsetsISO88591,UTF8,etc. Facilidadesparadefinircoloresyestilos SintaxisyAPImsregularacordealestndardelframework

28.2 Crear un documento PDF


UndocumentoPDFsecreainstanciandolaclasePdfDocument.Enelsiguienteejemplosecrea agregaunapginaconuntextoyseenviaalnavegador. Ejemplo:CrearundocumentoPDFconPDFDocument
<?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


PdfDocumentproporcionasoporteparaceldasymulticeldaslascualessontilescuandose creandocumentosquevanavisualizartablasdedatos.Enelsiguienteejemplosegeneraun documentoPDFconlosdatosobtenidosdeunmodelo: Ejemplo:CrearunatablacondatosenundocumentoPDF
<?php class ReportsController extends ApplicationController {

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

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 versin ms estilizada del reporte/listado se puede obtener agregando bordes, encabezadosycoloresdefondoaldocumento: Ejemplo:CrearundocumentoPDFconunatabladedatosmsestilizada
<?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, 'Cdigo', 1, 0, PdfDocument::ALIGN_JUSTIFY, 1); 1); $pdf->writeCell(90, 7, 'Nombre', 1, 0, PdfDocument::ALIGN_JUSTIFY, $pdf->lineFeed();

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

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


PdfDocumentsoportalossiguientestiposdepapel: Tabla:TiposdepapelsoportadosporPdfDocument ConstanteTipoPapel PAPER_A3 PAPER_A4 PAPER_A5 PAPER_LEGAL PAPER_LETTER TipodepapelA3 TipodepapelA4 TipodepapelA5 Tipodepapeloficio Tipodepapelcarta Descripcin

28.5 API de PdfDocument


function void __construct($orientation=self::ORI_PORTRAIT, $unit=self::UNIT_MM,

$format=self::PAPER_A4) EselconstructordePdfDocument.Pordefectoseestableceorientacinvertical,medidasen milimetrosypapeltipoA4. publicfunctionsetEncoding($encoding) Establece la codificacin del texto de entrada a mtodos como writeCell, writeText y writeMultiCell. Lascodificacionessoportadasson: Tabla:TiposdecodificacionessoportadasporPdfDocument

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

323

ConstanteCodificacin ENC_ISO88591 ENC_UTF8 ENC_ISO8022JP functionvoidsetDebug(boolean$debug)

Descripcin CodificacinISO88591latinoccidental. CodificacinUnicodeUTF8 CodificacinJaponesaISO8022JP

Establecesieldocumentosegeneraenmododebugno.Pordefectoesfalse.Siseenviael documentoalnavegadorenmododebugsevisualizaelformatointernodeldocumentoPDF. functionvoidsetMargins(integer$left,integer$top,integer$right=1) Permite establecer las margenes del documento PDF. El primer parmetro es la margen izquierda,elsegundolasuperioryelterceroladerecha.Sinoseindicaeltercerparmetrola margenderechaquedaigualalaizquierda. functionvoidsetLeftMargin(integer$margin) EstablecelamargenizquierdadeldocumentoPDF. functionvoidsetTopMargin(integer$margin) EstablecelamargensuperiordeldocumentoPDF. functionvoidsetRightMargin(integer$margin) EstablecelamargenderechadeldocumentoPDF. functionvoidsetAutoPageBreak(boolean$auto,integer$margin=0) Establecesisedebeagregarunapginaautomticamentecuandoseexcedaellimiteinferior aliragregandoregistros.Elparmetro$marginpermiteestablecerlamargeninferiordonde seexcedeellimitedecadapgina.Elcomportamientopordefectoesquesehagaelsaltode pginaautomticamente. functionvoidsetDisplayMode(int$zoom,string$layout=1) Permite establecer el tipo de visualizacin del documento que el software de visualizacin debetomarpordefecto.LosposiblesvaloressonconstantesdelaclasePdfDocument: Tabla:TiposdezoomendocumentosPDF

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

324

ConstanteZoom LAYOUT_DEFAULT LAYOUT_CONTINUOUS LAYOUT_SINGLE LAYOUT_TWO functionvoidsetCompression(boolean$compress)

Descripcin Es el tipo de zoom por defecto que tenga el software de visualizacinutilizadoparvereldocumentoPDF. Indicaquenosedebeverelpginadosinoqueunapgina sevisualizaunatrasotracomosiestuvieranunidas. Indicaquesedebevisualizarunapginacompletaalavez Indicaquesedebevisualizardospginascompletasalavez.

Indica si el documento PDF debe ser comprimido para reducir su tamao final. Para usar la opcindecompresinesnecesarioquelaextensindephpllamadazlibesthabilitada. functionvoidsetTitle(string$title) EstableceeltitulodeldocumentoPDF. functionvoidsetSubject(string$subject) EstableceelasuntodeldocumentoPDF. functionvoidsetAuthor(string$author) EstableceelautordeldocumentoPDF. functionvoidsetKeywords(string$keywords) EstablecelaspalabrasclavedeldocumentoPDF. functionvoidsetCreator(string$creator) EstableceelcreadordeldocumentoPDF. functionvoidaliasNbPages(string$alias='{nb}') Establece la cadena utilizada para reemplazar el nmero de pgina total de un documento PDFenencabezadosypiedepgina. functionvoidopen() Abre el documento PDF. Es necesario hacer el llamado a este mtodo para inicializar el documento.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

325

functionvoidclose() CierraeldocumentoPDF. functionvoidaddPage(int$orientation=PdfDocument::OR_PORTRAIT) Agrega una pgina al documento PDF. La orientacin por defecto es vertical. Las posibles orientacionesson: Tabla:TiposdeorientacindepginasoportadasporPdfDocument ConstanteOrientacin OR_PORTRAIT OR_LANDSCAPE EsposibleutilizardiferentesorientacionesenunmismodocumentoPDF. functionintegergetPageNumber() Obtieneelnmerodepginaactual. functionvoidsetDrawColor(integer$red,integer$green=1,integer$blue=1) functionvoidsetDrawColor(PdfColor$color) Establece el color con el que se dibujarn las lineas y bordes del documento. Este mtodo recibe3parmetrosquecorrespondenalosnivelesRGBdelcolordeseado.Cadanivelesun 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 paraestos. functionvoidcheckTTF(string$file) ConsultasiunarchivodefuenteTrueTypepermiteserembebidoendocumentosPDF. functionvoidsetFillColor(integer$red,integer$green=1,integer$blue=1) functionvoidsetFillColor(PdfColor$color) Establece el color con el que se har el relleno de cuadros y celdas del documento. Este mtodorecibe3parmetrosquecorrespondenalosnivelesRGBdelcolordeseado.Cadanivel es un entero entre 0 y 255. Adicionalmente puede recibir un objeto PdfColor con el color a Orientacinvertical. Orientacinhorizontal. Descripcin

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

326

establecer. Si no se indican valores para $green y $blue se utiliza el valor definido en $red paraestos. functionvoidsetTextColor(integer$red,integer$green=1,integer$blue=1) functionvoidsetFillColor(PdfColor$color) Establece el color de los textos del documento. Este mtodo recibe 3 parmetros 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 valorespara$greeny$blueseutilizaelvalordefinidoen$redparaestos. functiondoublegetStringWidth(string$s) Permite obtener el tamao de una cadena de carcteres de acuerdo a la fuente activa en el documento. functionvoidsetLineWidth(integer$width) Estableceelanchodelneadelapginaactivadeldocumento. functionvoiddrawLine(integer$x1,integer$y1,integer$x2,integer$y2) Permitedibujarunalnearectaenlapginaactivadeldocumento. functionvoiddrawRect(integer$x,integer$y,integer$w,integer$h,string$style='') Permitedibujaruncuadradorectnguloenlapginaactivadeldocumento. functionvoidaddFont(string$family,string$style='',string$file='') Agregaunafuentequenohagapartedelasfuentescore.Lasfuentescoreson:Helvetica,arial, times,symbolyzapfdingbats. functionvoidsetFont(string$family,string$style='',integer$size=0) Establecelafuenteactivaenel documento. Si es una fuente core puede ser: Helvetica,arial, times,symbolyzapfdingbats.SiesunafuenteagregadaconaddFontsedebeutilizarelmismo nombrepara$familyutilizadoenella. functionvoidsetFontSize(integer$size) Estableceeltamaodelafuenteactivaenpuntos(pt).

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

327

functionvoidlink(integer$x,integer$y,integer$width,integer$height,string$link) AgregaunenlacealdocumentoPDFenlasposicionesindicadas. functionvoidwriteText(integer$x,integer$y,string$txt) AgregauntextoaldocumentoPDFenlasposicionesindicadas. functionbooleanacceptPageBreak() Indica si el documento tiene el salto automtico de pgina al superar la margen inferior de unapgina. functionvoidwriteCell(integer$w,integer$h=0,string$txt='',integer$border=0,integer$ln=0, string$align='',integer$fill=0,string$link='') DibujaunaceldaeneldocumentoPDFconlosparmetrosdefinidos.Elparmetro$windica elanchodelacelda,$heselalto,$txteseltexto,$borderpuedeser10eindicasilacelda debe tener un borde visible, $ln puede ser 1 0 e indica si el contenido de la celda es un enlace,$fillpuedeser10eindicasilaceldadebesercoloreada,$linkeselenlaceyaplica solocuando$lnes1. function void writeMultiCell(integer $w, integer $h, string $txt, integer $border=0, string $align=PdfDocument::ALIGN_JUSTIFY,integer$fill=0) functionvoidwrite(integer$h,string$txt,string$link='') AgregauntextoaldocumentoPDFenlascoordenadasactuales. function void addImage(string $file, integer $x, integer $y, integer $w=0, integer $h=0, string $type='',string$link='') functionvoidlineFeed(string$h='') Realizaunsaltodelneaeneldocumentoaumentandolacoordenadayyreiniciandoxal valordelmargenizquierdo.Eltamaoopcionaldelsaltodelneapuedeindicarsecon$h. functionintegergetX() Devuelve el valor de la coordenada en x (horizontal) donde se producir la siguiente

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

328

renderizacindetextofigurasdeldocumento. functionvoidsetX(integer$x) Establecelacoordenadaenx(horizontal)dondeseproducirlasiguienterenderizacinde textofigurasdeldocumento. functionfloatgetY() Devuelve el valor de la coordenada en y (vertical) donde se producir la siguiente renderizacindetextofigurasdeldocumento. functionvoidsetY(integer$y) Establece la coordenada en y (vertical) donde se producir la siguiente renderizacin de textofigurasdeldocumento. functionvoidsetXY(integer$x,integer$y) Establece simultaneamente las coordenadas en y (vertical) y x (horizontal) donde se producirlasiguienterenderizacindetextofigurasdeldocumento. functionstringoutputDocument(string$name='',string$dest='') functionstringoutputToBrowser() Envia el reporte directamente al navegador. El desarrollador debe cerciorarse que otros contenidosnoseanenviadosjuntoconlasalidayaqueestogenerarunaexcepcin. functionintgetAvailableWidth() functionvoidsetFontPath(string$path)

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

329

29 Componente Report
29.1 Introduccin
El objetivo del componente Report es crear una capa de abstraccin consitente que permita mediante una misma API crear listados reportes a varios formatos aprovechando las caracteristicasdecadaunosinrequeriresfuerzoadicional. El alcance de la funcionalidad de este componente es limitado ya que cada muchas de las caractersticas de un tipo de formato no son fcilmente reproducibles en otros y viceversa. Reportesylistadosdecomplejidadmediaconrespectoasupresentacinsonlaaudiencia esperadadeestecomponente.

29.2 Alcance del componente


Lassiguientescaracteristicasdepresentacinestnsoportadasenlosreportesgenerados: Lassiguientescaracteristicasfuncionalesestansoportadasenlosreportesgenerados: Encabezadosypiedepgina Numeracindepginas Encabezadodetablasconcolumnasporpgina Sumatoradecamposporpginayalfinaldelreporte Conteoderegistros Paginacinautomticaatipodepapelcarta(letter),A4yoficio(legal). Tablasconencabezados Formatodecolores,fuentes,sombreado,subrayadoeitalicaalostextos Bordesconsincoloresenlastablas AlineacindeTextoIzquierda,CentroyDerecha

29.3 Adaptadores de Report


LosadaptadoresdeReportimplementanunamismainterfazauntipodeformatoespecifico de tal forma que la presentacin de un listado a otro en otro formato no varie considerablemente.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

330

Los adaptadores se apoyan el librerias externas estables para generar documentos con las caracteristicasrequeridasporeldesarrollador. Lossiguientesadaptadoresdetiposdeformatoseencuentrandisponiblesenelcomponente Report: Tabla:AdaptadoresdelcomponenteReport Nombre Html Es No Ventajas portable requiere a de Desventajas Librera Externa cualquier La paginacin de los Ninguna resultados no es muy plugins confiable soneditables Dependiendo utilizado a puede de del la ser la PDFDocument Kumbia en otras navegador exportacin aplicaciones compleja Pdf Los reportes generados no son modicables* cualquierplataforma esptima Dependiendo informacin generada los de sergrandesmuygrandes pluginsextra La informacin suele ser complicada de exportar a otras aplicaciones para su analisis Excel La informacin es editable y da El formato es privativo y Excel libertad al usuario de ajustar los requieredeMicrosoftExcel Kumbia informesdespusdegenerados generargrficasestadsticas parasuvisualizacinotra Enterprise en abrir este tipo de archivos PEAR Es posible analisar datos y hoja de calculo que pueda basado de navegador

adicionales para su visualizacin Los datos generados no inmediata Esrpidoenlamayoradecasos

La presentacin es la misma en documentos PDF pueden Enterprise basado La paginacin de los resultados Requiere de aplicaciones FPDF

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

331

comoOpenOffice informacin CSV no sea

Spreadsheet

No es seguro que la Excel_Writer alteradaporterceros Lainformacinsepuedeexportar No permiten formato a Ninguna aotrasaplicacionesdeterceros textos y no son fciles de aunasuiteofimatica leerporunhumano

29.4 Paginacin en reportes


FALTA

29.5 Ejemplo de un listado usando Report


Ejemplo:CrearunlistadousandoReport
<?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/KumbiaEnterpriseFrameworkManualdeReferencia

332

"center"))); "center"))); foreach($this->ReservationType->find() as $tipoReserva){ $report->addRow(array($tipoReserva->getId(), $tipoReserva>getDetail())); } } } $report->outputToBrowser(); $report->setColumnStyle(1, new ReportStyle(array("textAlign" =>

))); $report->setColumnStyle(0, new ReportStyle(array("textAlign" =>

29.6 Modo Vista Previa


CuandounreporteesgeneradoaformatoHTMLesposiblegenerarunasalidadevistaprevia permitiendolealusuarionavegarporelreporteenformamsefectiva.Estapresentacinno es apta para impresin ya que contiene colores y no representa lo que realmente ir a la impresora. ParaactivarestemododevisualizacinseinvocaelmtodosetDisplayModeconelparmetro Report::DISPLAY_PRINT_PREVIEWenelobjetoReportdeestaforma: Ejemplo:EstablecermododevistapreviaparareportesHTML
<?php // Para HTML $report = new Report('Html'); $report->setDisplayMode(Report::DISPLAY_PRINT_PREVIEW);

Esta opcin no tiene efecto en los reportes en los dems formatos. Un ejemplo de la visualizacindeestemodoeselsiguiente:

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

333

29.7 API de Report


LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

334

30 Componente Feed
30.1 Introduccin
ElobjetivodelcomponenteFeedeslalecturaygeneracindesindicacinusandoelformato RSS. Los documentos RSS generados siguen la especificacin RSS 2.0 segn el documento
http://cyber.law.harvard.edu/rss/rss.html http://www.rssboard.org/rss-specification.

de

la

universidad

de

Harvard

30.2 Leer/Importar documentos RSS


El siguiente ejemplo muestra como leer un rss desde un recurso remoto, la ruta tambin puedeserunaarchivolocal: Ejemplo:Leer/ImportardocumentosRSS
<?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(); }

Unavezcargadoslosdocumentospuedensermanipuladosmodificadosdeacuerdoaloque serequiera.

30.3 Crear documentos RSS


Este componente tambin permite la creacin desde cero y presentarlos como una salida estndardelapeticin. Ejemplo:CrearundocumentodesindicacinRSS
<?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/KumbiaEnterpriseFrameworkManualdeReferencia

335

} return $feed->getXMLFeed();

30.4 API de Feed


functionvoidsetTitle(string$title) Cambia/estableceelttulodelrecursoRSS. functionvoidsetDescription(string$description) Cambia/estableceladescripcindelrecursoRSS. functionvoidsetLink(string$link) Cambia/estableceelenlacealsitioaplicacinquegenerelrecursoRSS. functionvoidsetLanguage(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

functionvoidsetTtl(string$ttl) IndicacadacuantotiempoelclienteRSSdebereactualizarelrecurso. functionvoidsetGenerator(string$generator) Permitecambiar/establecerelsoftwareutilizadoparagenerarelcontenido. functionvoidsetDocs(string$docs) Permite establecer un enlace en donde haya documentacin sobre el formato utilizado para crearelrecursoRSS. functionvoidaddItem(FeedItem$item) AgregaunobjetoFeedItemalalistadeitemsdelrecursoRSS. functionstringgetXMLFeed() GeneraunaversinXMLaptaparapublicarelrecursoRSS.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

336

functionbooleanreadRss(string$url) LeeimportaunrecursoRSSdesdeunaubicacinlocalremota. functionbooleanreadRssString(string$rssString) ImportaunrecursoRSSapartirdeunstringconladescripcinXMLdeel.Devuelvefalseen casodequehayanerroresenelformatosintaxs. functionarraygetItems() ObtieneunarraydeobjetosFeedItemconcadaitemdelrecurso. 30.4.1 APIdeFeedItem ElobjetivodelaclaseFeedItemesencapsularlainformacinreferenteacadaitemdelrecurso RSSdetalformaquepuedasemanipuladadeunaformaorientadaaobjetos. functionvoidsetTitle(string$title) Estableceeltitulodelitem. functionstringgetTitle() Devuelveeltitulodelitem. functionvoidsetLink(string$link) Estableceelenlacedelitem. functionstringgetLink() Devuelveelenlacedelitem. functionvoidsetAuthor(string$author) Estableceelautordelitem. functionstringgetAuthor() Devuelveelautordelitem. functionvoidsetDescription(string$description) Estableceladescripcindelitem.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

337

functionstringgetDescription() Devuelveladescripcindelitem. functionvoidsetGuid(string$guid) Estableceelidentificadornicodelitem. functionstringgetGuid() Devuelveelidenticadornicodelitem. functionvoidsetPubDate(string$pubDate) Establecelafechadepblicacindelitem.EstadebeindicarseusandoformatoRFC2822. functionstringgetPubDate() Devuelve la fecha de pblicacin del item. La fecha se devuelve en formato RFC2822. El componenteDatepermitemanipularlasfechasdesdeesteformato. functionarraygetElementsAsArray() Obtiene un array asociativo con la informacin del item. Los indices corresponden a los atributosdelitem.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

338

Ncleoeintegracindecomponentesdelframework

31 Componente Core
31.1 Introduccin
ElcomponenteCoreactacomointegradoryorquestadordetodaslasoperacionesejecutadas enelFramework,ademsproporcionainformacinsobreelentornodeejecucinamltiples componentes.

31.2 Jerarqua de Clases


31.2.1 ClaseObject La mayor parte de las clases en Kumbia Enterprise Framework poseen una clase superior llamadaObject.EstaclaseimplementaelpatrnLayerSupertypeelcualpermiteimplementar mtodosquenopuedanserduplicadosalolargodetodalaimplementacindecomponentes enelFramework.LaclaseObjectseencuentraenLibrary/Kumbia/Object.php. 31.2.2 CoreConfig Se encarga de leer los archivos de configuracin de las aplicaciones e integrar las opciones definidasenellosaloscomponentesdelframework. 31.2.3 CoreLocale Suobjetivoesservirdepuenteentreloscomponentesdelaaplicacinyloscomponentesde localizacineinternacionalizacin.Cuandosegeneraunaexcepcinestecomponenteobtiene losmensajeslocalizadosapropiadosaldesarrollador. 31.2.4 CoreClassPath Mantieneundirectorioderutasalasclasesdelframeworkdetalformaquesepuedarealizar lainyeccindedependenciaenlaaplicacincuandoseanrequeridos. 31.2.5 CoreRemote Ofreceinformacinextendidasobreunentornodeejecucinremotoquepermitadeterminar problemaslocalmente.

31.3 Servicios del Componente Core


31.3.1 ObtenerelInstanceName Elnombredelainstanciaserefierealnombrelgicodelgrupodeaplicacionesinstaladasen unamismadistribucindelframework.Adicionalaloanteriortambinserefierealdirectorio

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

339

dondeseencuentrainstaladoelframework,esteesimportanteesmuchosaspectos. 31.3.2 ZonaHorariadelasAplicaciones KumbiaEnterpriseFrameworkpermiteestablecerunparmetrodezonahorariageneralpara todas las aplicaciones dentro de una misma instancia. Este parmetro se encuentra en la seccincoredelarchivoconfig/config.ini. Ejemplo:Establecerlazonahorariaenelarchivoconfig.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 horariasdelatierra. En tiempo de ejecucin puede cambiar la zona horaria usando el mtodo esttico Core::setTimeZone(string$timezone),siestableceunazonainvalidasegenerarunaexcepcin CoreException. 31.3.3 CambiarelCharsetdelaaplicacin PordefectounaaplicacinenKumbiaEnterpriseproducesalidasusandocodificacinUnicode UTF8. Para que toda la aplicacin utilice un mismo charset se requiere que multiples aspectosestnsincronizadosenestesentido. Servidor Web: La salida del servidor web en el caso de Apache Web Server es establecida dinmicamenteenelarchivopublic/.htaccessconlaopcin:
AddDefaultCharset UTF-8

Lavistaprincipal:LavistaprincipaldelaaplicacinproporcionaelmetaContentTypeque debeserestablecidadelasiguienteformaparadefinirelcharset:
<meta http-equiv='Content-type' content='text/html; charset=UTF-8' />

Archivos XML: La primera lnea del encabezado de un archivo XML tambin debe ser cambiadaparareflejarelcambiodelcharset.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

340

<?xml version="1.0" encoding="UTF-8" ?>

Basesdedatos:LosmotoresdebasededatoscomoMySQLOraclepermitenestablecerla codificacin en que se almacenan y devuelven los datos en las tablas. Consulte la documentacindelmotorutilizadoparaaprendercomomodificarlacodificacinpordefecto. JavaScript: Los archivos javascript deben estar guardados con la codificacin correcta sin embargo la etiqueta SCRIPT puede ser establecida de la siguiente forma para ayudar al navegadoradeterminarelcharsetcorrecto:
<script src="/instante/javascript/menu.js" type="text/javascript" charset="utf8"></script>

CSS: En los recursos CSS es posible usar establecer la codificacin del archivo tambin para ayudaralnavegadoraunmajorreconocimientodelamismaas:
@charset "utf-8";

31.3.4 Cambiarlalocalizacinpordefecto Es posible cambiar la localizacin por defecto usando el mtodo Locale::setDefault esto afectartodaslasoperacionesrealizadasconloscomponentesdeinternacionalizacincomo losonDate,TraslateyCurrency. Ejemplo:Cambiarlalocalizacinpordefectoprogramacionalmente
<?php Locale::setDefault(es_ES) ?>

31.3.5 ObtenerlaversindelFramework La constante Core::FRAMEWORK_VERSION permite obtener la versin del framework utilizado.Puedeutilizarestevalorparasepararlacompatibilidaddesusaplicacionescuando actualiceelframeworkysepresenteninconvenientes. Ejemplo:
<?php if(version_compare(Core::FRAMEWORK_VERSION, "1.0", ">=")){ //La versin del framework es mayor igual a la 1.0 }

Comparar

la

compatibilidad

de

una

aplicacin

usando

Core::FRAMEWORK_VERSION

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

341

31.4 Subcomponente CoreConfig


ElsubcomponenteCoreConfigpermiteleerlaconfiguracindelasaplicacionesyconvertirlas envaloresnativosdePHPparasuusoenprocesosdelaaplicacin. CoreConfig puede leer en forma sencilla archivos de configuracin de la instancia, de la aplicacinactualmenteenejecucinydeotrasaplicaciones. 31.4.1 APIdelsubcomponenteCoreConfig staticpublicvoidfunctionsetAdapter($adapterName) PermiteestablecereltipodeadaptadordelcomponenteConfigdebeserusadoparaleerlos archivos de configuracin de la aplicacin. Este cambio debe ser hecho en el boostrap de la instanciayafectaratodaslasaplicacionesenella. staticpublicConfigfunctionread(string$path,string$adapter) Lee un archivo de configuracin mediante su path. El path absoluto por defecto es el directorio raz de la instancia del framework. El parmetro $adapter indica el tipo de adaptadordelcomponenteConfigdebeserusadoparaleerelarchivo. staticpublicConfigfunctionreadAppConfig($applicationName=) Leeelarchivoconfig(normalmenteconfig.ini)delaaplicacinactivadevolviendounobjeto Config. Las secciones del archivo .ini son procesadas y devueltas como propiedades objetos delobjeto.Sinoseestableceelparmetro$applicationNameentoncesseleedelaaplicacin actual. staticpublicConfigfunctionreadBootConfig() Lee el archivo boot.ini (normalmente boot.ini) de la aplicacin activa devolviendo un objeto Config. Las secciones del archivo .ini son procesadas y devueltas como propiedades objetos delobjeto. staticpublicConfigfunctionreadEnviroment() Leeelarchivoenvironmentdelaaplicacinactiva.Losvaloresdelentornoactualpuedenser accedidosdirectamenteenelobjetoConfigdevuelto,losdemsentornosseaccedenmediante unapropiedaddelobjeto. publicstaticConfigfunctiongetConfigurationFrom(string$applicationName,string$file)

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

342

Devuelve la configuracin en un archivo ubicado en una aplicacin especifica. Este archivo debeestarubicadoeneldirectorioconfig/delaaplicacin. publicstaticfunctionreadFromActiveApplication(string$file,string$adapter=) Lee un archivo ubicado el directorio config/ de la aplicacin que est actualmente en ejecucin.Elparmetro$adapterindicaeltipodeadaptadordelcomponenteConfigdebeser usadoparaleerelarchivo

31.5 Subcomponente CoreClassPath


Gran parte de los componentes y subcomponentes en Kumbia Enterprise son cargados mediante inyeccin de dependencia usando autoload. Gracias a esto se reduce considerablemente la lectura de disco obteniendo lo que se requiere en forma dinmica a medidaqueessolicitadoporlaaplicacin. El ClassPath es un directorio interno que almacena las ubicaciones de las clases y componentesparasuposteriorinyeccincuandosonrequeridos.Pormotivosderendimiento notodosloscomponentessoninyectadossobretodolosquefuncionancomointegradoresy losqueatiendenlapeticin. EnsubcomponenteCoreClassPathofreceunainterfazdeaplicacinparalaadministracindel directorio de clases permitiendo agregar, cambiar eliminar entradas facilitando la modificacindelcomportamientodelframework. 31.5.1 ReemplazaruncomponentedelFramework Es posible reemplazar un componente del framework cambiando la ruta del directorio de clasesaladelnuevocomponente.Lanicarestriccinesutilizarelmismonombredelanueva claseenelcomponenteutilizado. En el siguiente ejemplo se muestra como reemplazar el componente de localizacin de Kumbia Enterprise por uno de la aplicacin. Notese que la extensin .php del archivo es omitidaapropsito: Ejemplo:Reemplazarlarutadeunaclaseaotradefinidaporelusuario
<?php CoreClassPath::replacePath('Locale', 'apps/my-app/library/Locale/Locale');

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

343

El path asignado no es comprobado por el framework por lo que debe cerciorarse que este existayqueelarchivocontengalaclasesolicitada. 31.5.2 APIdeCoreClassPath staticpublicfunctionlookupClass(string$className) Permiteconsultarsiunaclaseexisteeneldirectoriodeclases. staticpublicfunctiongetClassPath(string$className) Permiteconsultarlarutaexistenteenelframeworkparaunadeterminadaclase. staticpublicfunctionaddToPath(string$className,string$path) Agregaunanuevarutaaldirectoriodeclases.Siestayaexistenosereemplaza. staticpublicfunctionreplacePath(string$className,string$path) Reemplazaunaentradaeneldirectoriodeclases.

31.6 Subcomponente CoreType


El subcomponente CoreType permite realizar aserciones sobre los parmetros recibidos en diferentescomponentesdelframeworkasegurandoqueserecibeeltipodedatoadecuado.El trabajodeestesubcomponenteesfundamentalparaasegurarengranmedidaprocesosms confiables y seguros. Cuando las aserciones fallan se lanza una excepcin tipo CoreTypeException. 31.6.1 APIdeCoreType staticfunctionvoidassertNumeric(int$var) Realizaunaasercinsobreunvalornumrico staticfunctionvoidassertBool(bool$var) Realizaunaasercinsobreunvalorbooleano staticfunctionvoidassertString(string$str) Realizaunaasercinsobreunvalordecadenadecaracteres. staticfunctionvoidassertArray(array$var)

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

344

Realizaunaasercinsobreunvalorarray. staticfunctionvoidassertResource(resource$var) Realizaunaasercinsobreunavariablederecurso. staticfunctionvoidassertObject(object$var) Realizaunaasercinsobreunobjeto.

31.7 Crear Plugins de Aplicacin


La arquitectura de plugins de Aplicaciones permite observar, extender y manipular el comportamientodelaaplicacinsegncomolascondicionesloexijan. Los plugins permiten interceptar eventos de la aplicacin de tal forma que estos sean observables y adems ejecutrse uno tras otro de manera centralizada sin requerir refactorizacinreintegracinenlaaplicacin. 31.7.1 CrearunPlugindeAplicacin Lospluginssonclasesqueimplementaneventosgeneralesquesoninvocadosamedidaqueel flujodevida deunaaplicacin avanza en una sesin de usuario. Estas clases deben cumplir conlossiguientesrequerimientos: Deben estar ubicados en el directorio de plugins usualmente apps/appname/plugins dondelavariablepluginsDirindique. Elnombredelarchivoqueimplementalaclasedebeserelnombredelplugin ElnombredelaclasedebetenerlaextensinPlugin Los plugins de controlador deben heredar de la clase ApplicationPlugin ser subclase de ella Las clases pueden implementar mtodos pblicos que referencian los eventos ocurridos en loscontroladores,lalistadeelloseslasiguiente: Tabla:EventosquesepuedenimplementarenpluginsdeAplicacin NombreEvento beforeStartApplication Descripcin Ocurreenlaprimerapeticinalaaplicacinantesdeinvocarse

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

345

elmtododeControllerBaseonStartApplication afterStartApplication beforeChangeInstance afterChangeInstance beforeStartRequest beforeFinishRequest beforeUncaughtException onControllerException Ocurre en la primera peticin a la aplicacin despus de invocarseelmtododeControllerBaseonStartApplication Ocurrecuandoenunamismasesindeusuariosecambiaaotra instanciadelframeworkenelmismoservidordeaplicaciones. Ocurre despus de ejecutarse el mtodo de ControllerBase llamadoonChangeInstance. Ocurre antes de iniciar empezar a atender una peticin realizadaalaaplicacin. Ocurre cuando se termina de atender la peticin realizada a la aplicacin. Ocurre antes de lanzarse una excepcin que no fue capturada porlaaplicacin. Ocurrecuandosegeneraunaexcepcindentrodelcontrolador. SeejecutaantesdebeforeUncaughException

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

346

32 Componente PluginManager
32.1 Introduccin
Este componente permite administrar los plugins cargados en una aplicacin facilitando el agregarquitardinmicamenteplugins.

32.2 Arquitectura de Plug-Ins


KumbiaEnterpriseFrameworkproporcionaunaarquitecturadePlugInsflexiblequepermite notificaryregistrareventosdesdelosdiferentescomponentesdelframework.

32.3 Autoinicializacin de Plug-Ins


Por defecto los plugins encontrados en el directorio de plugins son cargados automticamenteporeladministradordeplugins.Cuandohaymuchospluginsestosno sonusadosfrecuentementeentrepeticionespuedencausarundeterioroenelrendimientode laaplicacin. En el archivo config/config.ini es possible configurar que los plugins no sean cargados automticamentesinoquetenganquesercargadosprogramacionalmenteasi: Ejemplo:Hacerquelospluginsnoseancargadosautomticamente
[plugins] autoInitialize = Off

Enestecasoesnecesarioregistrarlospluginsquesevayanautilizarentiempodeejecucin.

32.4 API de PluginManager


staticfunctionbooleaninitializePlugins() Inicializa los plugins cargados separandolos de acuerdo a su naturaleza: De controlador, modelos,vistasyaplicacin.Nodeberaserinvocadoporeldesarrolladoryaqueesllamado automticamenteporelcontenedordeaplicaciones. staticfunctionarrayloadApplicationPlugins() Carga los plugins almacenados en el directorio plugins el indicado en la variable de configuracinpluginsDir.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

347

staticfunctionarraygetPlugins() Obtieneunarraycontodaslasinstanciasdelospluginsregistradosenlapeticinactual. staticfunctionarraygetControllerPlugins() Obtiene un array con todas las instancias de los plugins de controlador registrados en la peticinactual. staticfunctionarraygetModelPlugins() Obtieneunarraycontodaslasinstanciasdelospluginsdemodelosregistradosenlapeticin actual. staticfunctionarraygetViewPlugins() Obtiene un array con todas las instancias de los plugins de presentacin registrados en la peticinactual. staticfunctionvoidnotifyFromApplication(string$event) Permitenotificaralospluginsdeaplicacinsobreuneventodeterminado$event. staticfunctionvoidnotifyFromController(string$event,Controller$controller) Permitenotificaralospluginsdecontroladorsobreuneventodeterminado$event. staticfunctionvoidnotifyFromView(string$event,ControllerResponse$controllerResponse) Permitenotificaralospluginsdepresentacinsobreuneventodeterminado$event. staticfunctionvoidnotifyFrom(string$component,string$event,string$reference) Permitenotificaralospluginsdecomponentessobreuneventodeterminado$event. staticfunctionvoidregisterControllerPlugin(ControllerPlugin$plugin) Permiteregistrarunobjetocomoplugindecontrolador.Sololoseventosproducidosdespues derealizarelregistrodelplugindecontrolador. staticfunctionvoidregisterApplicationPlugin(ApplicationPlugin$plugin) Permiteregistrarunobjetocomoplugindecontrolador.Sololoseventosproducidosdespues derealizarelregistrodelplugindeaplicacin.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

348

staticfunctionvoidregisterViewPlugin(ViewPlugin$plugin) Permite registrar un objeto como plugin de presentacin. Solo los eventos producidos despuesderealizarelregistrodelplugindepresentacin.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

349

Parte5:InternacionalizacinyLocalizacin

33 Internacionalizacin y Localizacin
33.1 Introduccin
Las actuales infraestructuras de computacin ofrecen localizacin de tal forma que un determinadousuariopuedaefectuaroperacionesdenegocioadecuadamente.Losobjetivosde lalocalizacinvanmuchomsalldequelapresentacinestetraducidaamltiplesidiomas, adems 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 implementaraplicacionesdenegociolocalizadas.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

350

34 Componente Locale
34.1 Introduccin
El componente Locale permite obtener y establecer informacin de localizacin en aplicaciones sobre datos especificos geogrficos, polticos, culturales regionales. Actualmenteesposibleobtenerinformacinde381localizaciones.

34.2 Definir la localizacin en una sesin de Usuario


Kumbia Enterprise permite establecer la localizacin por sesin, esta es definida usando un identificador de localizacin que sigue el formato idioma_REGION. Por ejemplo es_CO representalalocalizacinparaidiomaespaolypasColombia.Unlistadodelascadenasde localizacin El componente Locale utiliza localizacin independiente de la plataforma y que es segura cuandoseusaenentornomultithreadcomolosonlosservidoreswebmodernos.Elusodela funcin setlocale podra producir resultados inesperados si se usan aplicaciones con diferenteslocalizacionesenunmismoprocesodelservidordeaplicaciones. LalocalizacingeneralseestableceusandoelmtodoestticoLocale::setLocale(string$locale) pasandocomoparmetrounidentificador: Ejemplo:CrearunobjetoLocaleusandounacadenadelocalizacin
$locale = new Locale(es_CO);

puede

ser

encontrado

en:

http://unicode.org/cldr/data/diff/supplemental/languages_and_territories.html.

En caso de pasarse un identicador no valido, este es recortado hasta que sea valido. Por ejemplo: Ejemplo:Obtenerunalocalizacinvlidaalpasarunacadenaincorrecta
$locale = new Locale(es_XX); //Es recortado a localizacin es

UnainstanciadelaclaseLocaleesdevueltaaldefinirlalocalizacin. 34.2.1 Obtenerlalocalizacinadecuada La localizacin puede ser obtenida de 3 formas, del navegador del cliente, del archivo de configuracindelaaplicacinactivadelentornodeejecucindelaaplicacin.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

351

34.2.1.1 Leerlalocalizacindelnavegador LalocalizacinesleidadelavariabledelapeticinHTTP_ACCEPT_LANGUAGE.Laquetenga mayorcalidadeslaquesedevuelve: Ejemplo:Leerlaculturadelusuariofinalsegnelnavegador


$browserLocale = Locale::getBrowser();

Todas las localizaciones soportadas por el cliente HTTP pueden ser obtenidas usando Locale::getBrowserAll().Cadalocalizacinincluyeunvectorconidioma,regionycalidad. 34.2.1.2 Leerlalocalizacindelentornodeejecucin Lalocalizacinesleidadelvalorestablecidoporlafuncinsetlocaleenelmismoprocesode ejecucinactual. Ejemplo:Obtenerlalocalizacinsegnelentornodeejecucindelaaplicacin
$environLocale = Locale::getEnvironment();

Todas las localizaciones del entorno de ejecucin pueden ser obtenidas usando Locale::getEnviromentAll().Cadalocalizacinincluyeunvectorconidioma,regionycalidad. 34.2.1.3 Leerlalocalizacindelaconfiguracindelaaplicacin Lavariabledeconfiguracinlocalepuedeserestablecidatantoenelarchivoconfig.inidela aplicacincomoeldelainstancia: Ejemplo:Obtenerlalocalizacinsegnlaconfiguracindelaaplicacin
$applicationLocale = Locale::getApplication();

34.3 Establecer la localizacin por defecto


Cuandolalocalizacinnoesestablecidabajoningunodelosparmetrosanterioresseusael valorpordefecto.ElmtododelocalesetDefaultpermiteestableceresto. Ejemplo:Cambiarlalocalizacinpordefectoenformaprogramacional
// Localizacin por defecto para Espaol/Venezuela Locale::setDefault(es_VE);

34.4 Obtener traducciones localizadas


El objeto locale implementa traducciones localizadas para diversos criterios de acuerdo al idiomaypas.EnelsiguienteejemplosemuestracomoobtenerlatraduccinparaSIyNO

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

352

enFrancsyJapnes: Ejemplo:Obtenertraduccioneslocalizadasparadiferentesculturas
<?php //Mostrar las traducciones de SI y NO en Francs $locale = new Locale('fr_FR'); print $locale->getYesString()."\n"; // Imprime oui print $locale->getNoString(); // Imprime non

//Mostrar las traducciones de SI y NO en Japons $locale = new Locale('ja_JP'); print $locale->getYesString()."\n"; // Imprime print $locale->getNoString(); // Imprime

34.5 API del Componente Locale


functionvoid__construct($locale) Constructor del objeto locale. El parmetro $locale puede ser un string de identificacin de localizacinotroobjetoLocaledelculsetomarsuspropiedadesdelocalizacin. Ejemplo:CrearobjetosdeLocalizacin
$locale = new Locale(en_US); $copyLocale = new Locale($locale);

functionbooleanhasCountry() Permite consultar si una localizacin tiene un territorio pas vlido. Algunas funciones generarnexcepcionessisetrataconsultardatosdelterritorioyestenosehadefinido. Ejemplo:UsodeLocale::hasCountry
$locale = new Locale(en_US); $locale->hasCountry(); // true $locale = new Locale(es); $locale->hasCountry(); // false

functionvoidsetCountry(string$country) Permitecambiar/establecerelterritoriopasdelalocalizacin.Alutilizarseestemtodoel conjunto idioma/territorio es validado nuevamente para comprobar que es una localizacin vlida. Ejemplo:UsodeLocale::setCountry
$locale = new Locale(es); $locale->hasCountry(); // false

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

353

$locale->setCountry(AR); $locale->getLocaleString(); // es_AR $locale->hasCountry(); // true

functionstringgetLanguage() Obtieneelidiomadefinidoenlalocalizacin. Ejemplo:UsodeLocale::getLanguage


$locale = new Locale(en_US); $locale->getLanguage(); // en

functionstringgetCountry() Obtieneelpas/territorioenlalocalizacin. Ejemplo:UsodeLocale::getCountry


$locale = new Locale(en_US); $locale->getLanguage(); // US

functionstring|arraygetYesString($all=false) Obtiene la traduccin para Si segn la localizacin activa. Por defecto devuelve la primera traduccin para Si, en caso de que se pase true como segundo parmetro entonces se devuelveunarraycontodaslasposiblestraducciones. Ejemplo:UsodeLocale::getYesString
$locale = new Locale(es_ES); $locale->getYesString(); // Array ( [0] => s [1] => si [2] => s )

functionstringgetNoString($all=false) ObtienelatraduccinparaNosegnlalocalizacinactiva.Pordefectodevuelvelaprimera traduccin para No, en caso de que se pase true como segundo parmetro entonces se devuelveunarraycontodaslasposiblestraducciones. Ejemplo:UsodeLocale::getNoString
//No en alemn $locale = new Locale(de_DE); $locale->getNoString(); // Array ( [0] => nein [1] => n )

functionarraygetMonthList() Obtieneunarrayconlosnombrescompletosdelosmesessegnlalocalizacindelobjeto.Los indicesdelosmesesempiezanen0.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

354

Ejemplo:UsodeLocale::getMonthList
//Lista de meses en francs $locale = new Locale(fr_FR); $locale->getMonthList(); // Array ( [0] => janvier [1] => fvrier [2] => mars [3] => avril [4] => mai [5] => juin [6] => juillet [7] => aot [8] => septembre [9] => octobre [10] => novembre [11] => dcembre )

functionarraygetAbrevMonthList() Obtiene un array con los nombres abreviados de los meses segn la localizacin del objeto. Losindicesdelosmesesempiezanen0. functionarraygetDaysNamesList() Obtieneunarrayconlosnombrescompletosdelosdasdelasemanasegnlalocalizacindel objeto.Losindicesdelosmesesempiezanen0. functionarraygetAbrevDaysNamesList() Obtieneunarrayconlosnombresabreviadosdelosdasdelasemanasegnlalocalizacin delobjeto.Losindicesdelosmesesempiezanen0. functionstringgetDateFormat(string$type='full') Obtiene el formato de fecha a aplicar segn el tipo en la localizacin actual. Los posibles valorespara$typeson:full(completo),long(largo),medium(mediano)yshort(corto). Ejemplo:UsodeLocale::getDateFormat
//Formatos de fecha ISO vlidos para Espaol de Mxico $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

functionstringgetLanguageString() Obtienelatraduccinparalapalabraidiomadeacuerdoalalocalizacinactual. functionstringgetCurrencyFormat() DevuelveelformatoISOmonetarioutilizadosegnlalocalizacin. functionarraygetCurrency(string$codeISO=null,string$displayType='')

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

355

functionbooleanisDefaultLocale() PermiteconsultarsielobjetoLocaleactualcorrespondealalocalizacinactual. staticfunctionvoidsetDefault(string$locale) Establecelalocalizacinpordefectodelaaplicacinprogramacionalmente.Estevalornoes almacenadoensesinydebeindicarseencadapeticinenqueaplique. staticfunctionarraygetLocale(string$localeValue) Crea array de informacin de localizacin y comprueba que este sea vlido a partir de su identificadordelocalizacin. staticfunctionarraygetEnvironmentAll() Devuelvetodaslasposiblesidentificadoresdelocalizacinsegnelentornodeejecucindela aplicacin. staticfunctionLocalegetEnviroment() DevuelveunobjetoLocaleapartirdelalocalizacinobtenidasegnelentornodeejecucinde laaplicacin. staticfunctionarraygetBrowserAll() Obtieneunarraycontodoslosposiblesidentificadoresdelocalizacinysucalidadsegnel exploradordelcliente. 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 ) )

staticfunctionLocalegetBrowser() Obtiene un objeto de localizacin segn el identificador de localizacin de mayor calidad enviadoporelexplorador. staticfunctionLocalegetApplication() Obtienelalocalizacinqueestaconfiguradaenelarchivoconfig(config.ininormalmente)de laaplicacin.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

356

staticfunctionvoidsetApplication(Locale$locale) Estableceprogramacionalmentelalocalizacinpordefectodelaaplicacin. functionstringgetLocaleString() ObtieneelidentificadordelocalizacinconelquesecreoelobjetoLocale. functionstring__toString() Mtodomgicoquealconvertirelobjetoastringdevuelveelidentificadordelocalizacincon elquesecreelobjetoLocale. Nota:EsposiblequeelcomponenteLocalehagaconflictoconlaextensinIntldelrepositorio PECLasqueesreconmendabledesactivarla.ElcomponenteLocalereemplazayextendiende funcionalidaddeestaextensinporloquenorequerirdeella.

34.6 Subcomponente LocaleMath


Este subcomponente permite realizar operaciones matemticas de alta precisin que son usadasparatrabajarconfechascontimestampporfueradelrangodeladmitidoporeltipode mquinadondeseejecutalaaplicacinyquetambinpuedenserusadosporeldesarrollador ensusaplicaciones. LocaleMath requiere que la extensin php_bcmath este habilitada de lo contrario las operacionesrealizadasseejecutaranusandolascapacidadesmatemticasnormalesdePHP. Para todos los mtodos de LocaleMath las sumas deberan establecerse usando cadenas de caracteresparaevitarqueelinterpretephplasconviertaenenteros. 34.6.1 APIdeLocaleMath staticfunctionstringadd(double$value1,double$value2,int$scale=0) Realiza una operacin aritmtica de suma de alta precisin. El resultado final puede ser redondeadousandoelparmetro$scale. staticfunctionstringmul(string$value1,string$value2,int$scale=0) Realiza una operacin de multiplicacin con alta precisin. El resultado final puede ser redondeadousandoelparmetro$scale.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

357

staticfunctionstringsub(string$value1,string$value2,int$scale=0) Realiza una operacin aritmtica de resta con alta precisin. El resultado final puede ser redondeadousandoelparmetro$scale. staticfunctionstringdiv(string$value1,string$value2,int$scale=0) Realiza una operacin aritmtica de divisin de alta precisin. El resultado final puede ser redondeadousandoelparmetro$scale. staticfunctionstringmod(string$value1,string$value2) Realiza una operacin aritmtica de suma de alta precisin. El resultado final puede ser redondeadousandoelparmetro$scale. staticfunctionintcmp(string$value1,string$value2,int$scale=0) Realiza una operacin aritmtica de comparacin de alta precisin. El resultado final puede ser redondeado usando el parmetro $scale. Si el valor devuelto es 0 indica que los valores enviadossoniguales,1cuandoel$value1esmenora$value2y1encasocontrario. staticfunctionstringround(string$value,int$precision=0) Redondeaunvalorusandoaltaprecisin.Serecomiendaaltamenteelusodeestemtodoen vez de la funcin de php round. El nmero de decimales del resultado redondeado se establececon$precision. staticfunctionvoiddisableBcMath() Deshabilita el uso de la extensin bc_math para realizar las operaciones aritmticas de alta precisin. staticfunctionvoidenableBcMath() Habilita el uso de la extensin bc_math para realizar las operaciones aritmticas de alta precisin. El valor no queda activado durante el transcurso de la sesin sino solamente durantelaejecucindelapeticindondesehagaelllamado.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

358

35 Componente Traslate
35.1 Introduccin
El componente Traslate permite la creacin de aplicaciones multiidioma usando diferentes adaptadoresparaobtenerlaslistasdetraduccin.LaclaseimplementaelpatrnProxypara accederalafuncionalidaddelosadaptadoresdemanerauniforme.

35.2 Adaptadores soportados por Traslate


Lossiguientesadaptadoressonsoportadosporestecomponente: Tabla:TiposdeadaptadoressoportadosporTraslate TipoFormato Array CSV INI Database Descripcin Utiliza arrays nativos de PHP para almacenar las listas de traduccin. Las llavessonutilizadasparaaccederalvalortraducido. Utiliza archivos separados por comas. El primer campo representa la llave detraduccinyelsegundolatraduccinens. Utilizaarchivos.ini.Latraduccinseestablecenormalmentecomovariables ysuvaloreslatraduccin. Utilizaunatablaparaalmacenareldiccionariodetraduccin.

35.3 Como funciona la traduccin


Independientementedeladaptadorutilizado,elprocesodetraduccinsigueestosprincipios: Losrecursosdetraduccindebenestardisponiblesymantenerunaestructuraconsistente detalformaqueseaposiblecargarunoelotrodependiendodelalocalizacinactiva. Los diccionarios de traduccin deben tener una clave y un valor, en donde la clave es un cdigo interno convencin que usa el desarrollador para acceder a los valores de traduccin. Las claves deben ser las mismas para cada diccionario de traduccin de esta formaesposibleobtenerlosvaloresconsistentemente. El tipo de idioma a utilizar debe ser cargado por el desarrollador. El componente Locale permite obtener mediante varios mtodos el lenguaje ms adecuado dependiendo de los requerimientosdenegociodelaaplicacin. Una vez completados los pasos anteriores se instancia la clase Traslate indicando en el primerparmetrodelconstructoreltipodeadaptadorausar,seguidodeestelasopciones

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

359

delmismo. El recurso cargado en el objeto Traslate contiene las traducciones para la sesin activa. El usodelmtodo$traslate>_(string$key)permiteaccederalosvaloresdetraduccinsiendo $keylallavedeindexacindeldiccionario. El desarrollador debe controlar que el objeto traslate este creado y disponible para cada vistamultiidiomaenlaaplicacin.

35.4 Utilizar traducciones


ElcomponenteTraslatecargalosdatosdetraduccindeladaptadorindicadoyluegopermite obtener las traducciones. En el siguiente ejemplo se muestra como crear el objeto de traduccinencadapeticinauncontrolador: Ejemplo:Cargarlalistadetraduccinsegnlaculturaobtenidadelnavegador
<?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(); } }

Encadapeticinalcontroladorlavariable$traslateestransferidaalapresentacinparasu uso: Ejemplo:Obtenerlastraduccionesmediantelasllavesdefinidas


<?php echo $traslate->_(home) ?> <?php echo $traslate->_(exit) ?>

Sielarchivoes/LC_MESSAGES/messages.phptieneelsiguientediccionario:
<?php $messages = array(home => Inicio, exit => Salir) ?>

yelarchivoen/LC_MESSAGES/messages.phptieneelsiguientediccionario:
<?php $messages = array(home => Home) ?>

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

360

Entonces se produce la salida respectiva para los idiomas espaol e ingls: Inicio Salir y Homeexit. 35.4.1 ConsideracionesparaeladaptadorArray ComoseexplicesteadaptadorutilizaarraysnativosdePHPparaalmacenarlosdiccionarios detraduccin.Serecomiendaelusodeesteadaptadoryaqueofreceelmejorrendimientoen lamayoradeloscasos. 35.4.2 ConsideracionesparaeladaptadorCsv EladaptadorCSVpermitecargarlaslistasdetraduccindesdearchivosCSV(seperadospor comas)FALTA. 35.4.3 ConsideracionesparaeladaptadorIni EladaptadorINIpermitecargarlaslistasdetraduccindesdearchivosINIFALTA. 35.4.4 ConsideracionesparaeladaptadorDatabase EladaptadorDatabasepermitecargarlaslistasdetraduccindesdeunatablaenlabasede datos.FALTA

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

361

36 Componente Date
36.1 Introduccin
ElcomponenteDateestadiseadoparaextenderellenguajePHPagregandountipodedato para el manejo de fechas de forma orientada a objetos que permita las operaciones entre estas,obtenerfragmentoseinformacindelaspropiedadesdeltiempoteniendoencuentala configuracindelocalizacinrequeridaporlaaplicacin.

36.2 Porque debe usar este componente


ConDatesepuedenefectuaroperacionesusandofechasyfragmentosdefechasencualquier 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 conflictoscuandolasfechasestnfueraderangoFri,13Dec190120:45:54GMTaTue,19Jan 203803:14:07GMT. Lasrestriccionessedebenaquegranpartedelasoperacionesentrefechasyhorasserealizan usando marcas de tiempo que consisten en el nmero de segundos transcurridos antes despusdel1deEnerode1970,cuandoestenmeroesmuygrandeeltipodedatofloatde PHPresultainsuficienteparaalmacenarlo. La referencia del manual de PHP dice The size of a float is platformdependent, although a maximumof~1.8e308withaprecisionofroughly14decimaldigitsisacommonvalue(that's 64bitIEEEformat).. Cuando los nmeros de marcas de tiempo a almacenar son muy grandes es posible utilizar extensionesdePHPquesoportanprecisinarbitrariacomolosonbcmathgmp. Elcomponentetambinsoportalosajusteshorariosdeacuerdoaltimezonedelaaplicaciny establecelascorreccionesnecesariasparaelcalendariogregoriano.Igualmentesisetrabaja enunentornolocalizadoDateobtienelosnombresdedasymesesdeacuerdoalestablecido.

36.3 Timestamps ilimitados


ElcomponenteDaterealizagranpartedesusoperacionesbasadoenlasmarcasinternasde tiempoUnixquesegeneranapartirdelafechadelobjetoycondicionesdezonahorariaentre

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

362

otros.Cuandolasaplicacionesrequierensoportaroperacionesconfechasfueradelrangode Fri, 13 Dec 1901 20:45:54 GMT a Tue, 19 Jan 2038 03:14:07 GMT es necesario que el componenteDaterealicesusoperacionesutilizandomatemticadealtaprecisinmedianteel empleodelaextensindePHPbcmath. La extensin bcmath proporciona una calculadora binaria que sopora nmeros de precisin arbitrariarepresentandoloscomocadenasdecaracteres.Cuandolaextensinestadisponible se puede activar la integracin con el componente Date ejecutando el mtodo del subcomponentedeoperacionesmatemticaslocalizadasLocaleMathllamadoenableBcMath. Deestaformasepuedeusarfechasencualquierrangoyefectuaroperacionessobreellascon tranquilidad.

36.4 Establecer el Timezone


Parauncorrectofuncionamientodeestecomponenteesnecesarioestablecerlazonahoraria donde est ubicada la aplicacin y de donde tomar la informacin para realizar los ajustes adecuadosalasfechasyhoras. Kumbia Enterprise Framework permite configurar el timezone en el archivo config/config.ini en la seccin [kumbia] usando un CLDR Timezone Identifier que es aceptado por la funcin date_default_timezone_set()dePHP.Paramayorconsistenciadelasaplicacionesdesarrolladas enelframeworksedebeusarelmtodoestticoKumbia::setTimeZone(string$cldrIdentifier). Cuandoseestableceuntimezoneinvalidosegeneraunaexcepcin. Ejemplo:Cambiareltimezoneactivodeformaprogramacional
// 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


EsposiblecrearunobjetodefechainstanciandodirectamentelaclaseDate,elparmetroque recibeelconstructoresunafechaenformatoYYYYMMDD.Sinoseestableceesteseutilizala

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

363

fecha actual. Si el constructor recibe una fecha invalida se genera una excepcin DateException. Ejemplo:Obtenerfragmentosdefechas
//Crear Fecha $fecha = new Date("1986-02-17"); //Obtener el Nmero del Mes $fecha->getMonth(); // Devuelve 2 //Obtener el Ao $fecha->getYear(); // Devuelve 1986 //Obtener el Ao en formato corto $fecha->getShortYear(); // Devuelve 86 //Obtener el Nmero del Da $fecha->getDay(); // Devuelve 17 //Obtener el timestamp (marca de tiempo UNIX) $fecha->getTimestamp(); // Devuelve 509000400 //Obtener el nombre del mes abreviado segn la localizacin actual $fecha->getAbrevMonthName(); // Devuelve Feb /Obtener el nombre del mes segn la localizacin actual $fecha->getMonthName(); // Devuelve Febrero //Obtener el nombre del da segn la localizacin actual $fecha->getDayOfWeek(); //Devuelve Lunes //Obtener el nombre del da segn la localizacin actual en forma abreviada $fecha->getAbrevDayOfWeek(); //Devuelve Lun //Obtener el nmero del dia de la semana (Domingo=0 hasta Sbado=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 Posicin en el Tiempo


UnobjetoDatetambinpuedeproporcionarinformacinsobresuposicineneltiempo,las funcionesquerecibenotrasfechasaceptanstringsenelformatoYYYYMMDDotrosobjetos defechas:

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

364

Ejemplos:UsodemtodosdeposicindeltiempoconDate
//Indica si la fecha corresponde a la actual $fecha->isToday(); //Indica si la fecha corresponde a la fecha de maana $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 ao actual $fecha->isThisYear(); //Indica si el ao 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 Informacin de Fechas


El componente Date ofrece mtodos para obtener la fecha y hora actual, as como fechas inicialesyfinalesdeaosymeses: Ejemplo:Mtodosparaobtenerinformacindefechas
// 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/KumbiaEnterpriseFrameworkManualdeReferencia

365

//Obtener la fecha y hora actual en formato YYYY-MM-DD HH:MM:SS Date::now(); //Obtener el primer dia del ao actual Date::getFirstDayOfYear(); //Obtener el primer dia del ao 1999 Date::getFirstDayOfYear(1999); //Devuelve 1999-12-31 //Obtener el ltimo dia habil del ao 2006 print Date::getLastNonWeekendDayOfYear(2006); //2006-12-29

//Obtener el primer dia del ao 1980 Date::getFirstDayOfYear(1980); //Devuelve 1980-01-01

//Obtener el primer dia del mes de febrero del ao 1980 Date::getFirstDayOfMonth(2, 1980); //Devuelve 1980-02-01 //Obtener el ltimo dia del mes de febrero del ao actual Date::getLastDayOfMonth(2); //Obtener el ltimo dia del mes de febrero del ao 2000 Date::getLastDayOfMonth(2, 2000); //Devuelve 2000-02-29 //Obtener el ltimo dia habil del mes de julio del ao 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 manteniendolaconsistenciadelamisma: Ejemplo:Mtodosparamanipularfragmentosdefechas
$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 da automticamente) $fecha->setMonth(2); print $fecha; // Devuelve 2008-02-29 //Cambiar el ao de un ao 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 ao aos 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/KumbiaEnterpriseFrameworkManualdeReferencia

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 quedevuelvennuevosvalores: Ejemplo:Realizaroperacionesconfechas
//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 aos $fecha = new Date("2008-01-02"); $fecha->addYears(3); print $fecha; //2011-01-02 //Quitar aos $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 mtodo addInterval y diffInterval realiza sumas y restas de intervalos respectivamente a otras fechas, la funcin siempre suma resta por lo cual pasar nmeros negativos como segundoparmetrogeneraelmismoresultado. Las operaciones tienen en cuenta aos bisiestos, correcciones gregorianas, zonas horarias y rangosdefechadecualquierlongitud.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

367

Tabla:TiposdeintervalossoportadosporDate::addInterval Constante INTERVAL_DAY INTERVAL_WEEK INTERVAL_MONTH INTERVAL_YEAR Descripcin Estableceunintervalodedasdelcalendariogregoriano Estableceunintervalodesemanas Estableceunintervalodemesesdelcalendariogregoriano Estableceunintervalodeaosdelcalendariogregoriano

Ejemplo:UsodeaddIntervalparasumarintervalosafechas
//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 Localizacin de Fechas


Por defecto los nombres de meses, dias, eras y formatos de fechas son devueltos usando la localizacin de la aplicacin en config.ini. Es posible modificar la localizacin de un objeto fechausandoelmtodosetLocale()queaceptaunobjetoLocale: Ejemplo:Cambiarlalocalizacindelosobjetosdefecha
<?php $date = new Date('1986-02-02'); //Fecha en Ingls $date->setLocale(new Locale('en_US')); print $date->getLocaleDate(); //Fecha en Francs $date->setLocale(new Locale('fr_FR')); print $date->getLocaleDate(); //Fecha en Espaol $date->setLocale(new Locale('es_AR')); print $date->getLocaleDate(); //Fecha en Chino $date->setLocale(new Locale('zh_CN')); print $date->getLocaleDate();

Loanteriorgeneralasiguientesalida:
Sunday, February 2, 1986 Dimanche 2 Fvrier 1986 Domingo 2 de Febrero de 1986 198622

ElmtodogetLocaleDateobtieneunafechaaptaporlaculturaestablecidausandodiferentes

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

368

tipos de formatos. El mtodo acepta un parmetro indicando el tipo de formato de fecha a obtener: Tabla:TiposdeformatoslocalizadosquesoportaDate TipoFormato full long medium short Elsiguienteejemploilustralasfechasobtenidasdeacuerdoacadatipodeformatolocalizado. Lasvariacionesinclusodepaisesdelamismalenguasontenidasencuenta: Ejemplo:Obtenerfechasenformatoslocalizadosdeacuerdoalacultura
<?php $date = new Date('1985-11-01'); //Tipos de formatos en espaol 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 espaol de Colombia $date->setLocale(new Locale('es_CO')); print $date->getLocaleDate('full'); print $date->getLocaleDate('long'); print $date->getLocaleDate('medium'); print $date->getLocaleDate('short');

Descripcin Obtiene una fecha apta para la localizacin en formato completo extendido.EselformatopredeterminadodelmtodogetLocaleDate(). Formatolargoperomascortoquefull. Formatodefechamedio,tilenreporteslistados. Formatodefechacorto.

Generandolasiguientesalida:
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


LosformatosdefechadevueltosporgetLocaleDaterepresentanelestndarinternacionalde acuerdoalaUnicodeparacadalocalizacin(idiomayterritorio).Ademsdeestosesposible

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

369

obtener una fecha en un formato personalizado usando el mtodo 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. Losmodificadoresdetiposdeformatoaceptadosporestesonlossiguientes: Tabla: Tipos de modificadores de formatos de fecha aceptados por Date::getUsingFormat Tipo Modificador GGGG GGG GG G yy yyyy y dd d EEEE EEE MMMM MMM MM M r c z o L W Diadelmesusandounceroaliniciocuandoeldiaesmenora10. Diadelmes. Nombredeldadelasemana. Nombredeldadelasemanaabreviado. Nombredelmes. Nombredelmesabreviado. Numerodelmesusandounceroaliniciocuandoesmenora10. Nmerodelmes. FechaenformatoRFC2822 FechaISO8601 Dadelao. NmerodelaoISO8601. Muestraun1cuandoesaobiciestoycerodelocontrario. Nmerodelasemanaenelao. Aoabreviado.Elao1997sera97. Aocompleto. Nombre de la era de la fecha. Antes de cristo despus de cristo segn la localizacin. Nombreabreviadodelaera.a.c.yd.c. Descripcin

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

370

N t e

Representacinnmericadelafecha TimestampUnix IdenticadordeZonaHoraria

Unejemplodeusodelosmodificadoresdeformatoes: Ejemplo: Obtener la fecha con un formato personalizado y una localizacin 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 sern implementadas en diferentes paises y/o continentes y el servidor de aplicaciones reside en un punto central el componente Date proporcionadatosdefechayhoraquepermitenlograrestoapartirdelazonahoraria. Lainformacindezonahorariadependedelaplataformaenlaqueestinstaladalaaplicacin ydelaversindePHP,puedeinstalarunaversinactualizadadelaextensinphp_timezone disponibleenPECLparaobtenerlosltimosdatosdezonahoraria. Ejemplo: Obtener la fecha actual simultaneamente de acuerdo a diferentes zonas horarias
print print print print print print print print print print print Date::getNowFromTimezone("Arctic/Longyearbyen"); Date::now(); Date::getNowFromTimezone("America/Caracas"); Date::getNowFromTimezone("Europe/Amsterdam"); Date::getNowFromTimezone("Europe/Berlin"); Date::getNowFromTimezone("Europe/Stockholm"); Date::getNowFromTimezone("Africa/Cairo"); Date::getNowFromTimezone("Asia/Jerusalem"); Date::getNowFromTimezone("Asia/Tokyo"); Date::getNowFromTimezone("Australia/Sydney"); Date::getNowFromTimezone("Antarctica/South_Pole"); // // // // // // // // // // // 2009-02-12 2009-02-11 2009-02-11 2009-02-12 2009-02-12 2009-02-12 2009-02-12 2009-02-12 2009-02-12 2009-02-12 2009-02-12 03:20:52 21:20:52 21:50:52 03:20:52 03:20:52 03:20:52 04:20:52 04:20:52 11:20:52 13:20:52 15:20:52

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

371

37 Componente Currency
37.1 Introduccin
Elobjetivodeestecomponenteesproporcionarfacilidadesaldesarrolladorparatrabajarcon cantidadesnumricasrelacionadascondineroymonedas,surepresentacindeacuerdoala localizacinactivaylageneracindemontosenletrasendiferentesidiomas.Elcomponente soportadatosmonetariosparamsde90localizaciones.

37.2 Cantidades usando el formato adecuado


El componente Currency permite aplicar el formato correcto a cantidades de acuerdo a la localizacinactivalaqueseestablezca.Deestaformaesposibleutilizarlosseparadoresde decimales y miles adecuados para cada territorio, el nombre de la moneda y el simbolo de dineroadecuados. Currencypuedeserusadomediantemtodosestticoscreandoinstanciasdeestacuandose requiereutilizarmltipleslocalizacionesenunmismoproceso. Elseparadordecomasyagrupamientopuedecambiardeunalocalizacinaotra: Ejemplo:Imprimircantidadesmonetariasusandodiferenteslocalizaciones
<?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 conversin al formato numrico correcto y el nombredelamonedainclusocuandoesdiferentealalocalizacinactual.ElmtodogetMoney tambin acepta un formato con tipos de identificadores para indicar datos adicionales de la salidamonetaria: Ejemplo:Imprimirunacantidadmonetariausandounformatopersonalizado
<?php $currency = new Currency(new Locale('en_US'));

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

372

print $currency->getMoney(10000, '%symbol%%name% %quantity% (%displayName%)'); $currency->setLocale(new Locale('es_CO')); print $currency->getMoney(10000, '%symbol%%name% %quantity% (%displayName%)');

Generandolasalida:
$USD 10,000.00 (US Dollar) $COP 10.000,00 (Peso de Colombia)

Lostiposdeidentificadoressoportadosson: Tabla:TiposdemodificadoresdeformatosoportadosporCurrency Tipo Modificador %symbol% %name% %quantity SiserequiresepuedepasaruntercerparmetroagetMoneyindicandolamonedaenlaque estlacantidadperosincambiarlalocalizacin: Ejemplo:IndicareltipodemonedausadosegnlalocalizacinenCurrency
$currency->setLocale(new Locale('es_CO')); print $currency->getMoney(100, '%symbol%%name% %quantity% (%displayName%)', USD);

Descripcin Simbolopredeterminadodelamonedautilizada. CodigoISO3166delamoneda Ubicacindelacantidadaformatear.

%displayName% Nombredelamonedaenlalocalizacinactiva.

Elejemploanteriorimprime:
USD 100.00 (dlar 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 versionesescritasdecantidadessuperioresabillones:
//CUATROMIL QUINIENTOS BOLVARES FUERTES VENEZOLANOS $currency = new Currency(new Locale('es_VE')); print $currency->getMoneyAsText(4500);

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

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);

ElmtodogetMoneyAsTextrecibeunacantidadysegundoparmetroopcionalqueindicasise debeagregarlamoneda.Estemtodorealizaunacorrectapluralizacindeltextodeacuerdoa lacantidadyagregalascantidadesencentavossiaplica.

37.5 API del Componente Currency


functionvoid__construct(Locale$locale) ConstructordeCurrency.Opcionalmentepuedeestablecerselalocalizacinquedebeteneren cuentaelobjeto. functionvoidsetLocale(Locale$locale) PermiteestablecercambiarlalocalizacindelobjetoCurrency. functionstringgetMoney(double$quantity,string$format='',string$codeISO='') Obtieneunacantidadmonetariaformateadadeacuerdoalalocalizacindelobjetoladela aplicacin.Elparmetro$formatpermiteindicarelformatodelstringresultante. functionstringgetMoneySymbol(string$codeISO='') ObtieneelsimbolodemonedaparalalocalizacinactuallaindicadamedianteelcdigoISO delpascon$codeISO. functionstringgetMoneyDisplayName(string$codeISO='',string$type='') Obtieneelnombredelamonedaparalalocalizacinactuallaindicadamedianteelcdigo

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

374

ISOdelpascon$codeISO. functionstringgetMoneyISOCode(string$codeISO='') ObtieneelcdigoISOdeunamonedadeacuerdoalcdigoISOdelpas. functionarraygetCurrency(string$codeISO='',string$displayType='') Obtieneunarrayconelsimboloynombredelamonedaenlocalizacinactualdelobjeto. staticfunctionstringmoneyToWords(numeric$valor,string$moneda,string$centavos) Convierte un valor en monedas a su representacin en palabras. Actualmente solo genera textosenespaol.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

375

Parte6:MonitorizacindeAplicaciones

38 Componente ApplicationMonitor
38.1 Introduccin
KumbiaEnterpriseFrameworkofrececaractersticasparaelmonitoreodeaplicacionesysus componentesdetalformaquepuedamejorarlastareasdeadministracincomosintonizacin determinacin de problemas. El componente ApplicationMonitor est integrado con el Louder KEF Instance Administration Console permitiendo que personal noespecialista en reas de desarrollo pueda monitorizar las aplicaciones de una determinada instancia del framework. Al observar el flujo de ejecucin de una aplicacin es posible controlar que un proceso de negociogenerelosresultadosesperados. Gracias a los capacidades del framework de ejecucin horizontal, ApplicationMonitor puede recorrercadacomponenteenejecucinytomarlosdatosnecesariosparahacerseguimientoa unapeticin.

38.2 Infraestructura de Eventos comunes


La infraestructura de eventos comunes es una tecnologa embebible que proporciona serviciosbsicosdeadministracindeserviciosaaplicacionesquerequierenmonitorizacin. Esta infraestructura ofrece un punto de consolidacin y persistencia para eventos desde mltiples fuentes as como su distribucin a los consumidores de eventos. Cada evento es definidousandounaestructuraXMLquedefineladescripcindelmismo. Esta arquitectura de eventos permite que diversos productos que no estn fuertemente acopladoslosunosconlosotrospuedanintegrareventosdeadministracinproporcionando unavistafinalalosrecursosempresarialesexistentes. Esta infraestructura de eventos proporciona facilidades para la generacin, propagacin, persistencia y consumo de eventos sin definir los eventos en si mismos. El desarrollador puededefinirtiposdeeventos,grupos,filtrosyrelacionesentreellos.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

376

38.3 Componentes de la Infraestructura de Eventos


Lainfraestructuradecomndeeventosconstadelossiguientescomponentes: 38.3.1 CommonBaseEvent Permitelacreacindeeventosyaccesoasusdatos.LosrecursosdeeventosutilizanlaAPIde CommonBaseEvent para crear nuevos eventos en base al modelo de aplicacin. Los consumidores de eventos utilizan su API para leer la informacin en ellos. Aplicaciones de terceros pueden convertir los objetos en representaciones en XML para intercambiar los datos. 38.3.2 Emmiter ElemisorpermiteelenviodeeventosporuncanaldecomunicacinHTTP.Despusdequeun evento se alimenta de datos es transferido al emisor. Este puede opcionalmente completar datosdeleventoyhacerlospartedelapeticin.LoseventossonenviadosmedianteSOAP SCA. 38.3.3 EventService El servicio de eventos recibe los mensajes enviados por el Emmiter, los almacena en un almacen de datos persistente y luego los distribuye asincrnicamente a otros consumidores deeventos.

38.4 Porque usar monitorizacin?


LosserviciosdemonitoreodeKumbiaEnterpriseFrameworkpermitenevaluarrendimiento, encontrar problemas y evaluar el procesamiento normal de un conjunto de aplicaciones en unainstancia.Haytresrazonesprincipalesporlasquesedebemonitorizar: 38.4.1 Determinacindeproblemas Es posible diagnosticar errores particulares usando las capacidades de logging y traza que ofrece el framework. Por ejemplo si un determinada aplicacin no est produciendo los resultados esperados es posible activar un log que realice segumiento a los procesos de la mismayasdetectarlasrazonesdelfallo. 38.4.2 SintonizacindelRendimiento El componente ApplicationMonitor tambin puede obtener estadsticas de rendimiento de determinadosprocesosyaspoderencontrarcuellosdebotellagenerandolassintonizaciones correspondientesquemejorenelrendimiento.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

377

38.4.3 ConfiabildaddelaOperacin Lamonitorizacincontinuadelasaplicacionesayudaaestabilizarenformamseficienteuna aplicacin 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 lanzanendeterminadospuntosdelaejecucinenunapeticin.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

378

39 Componente CommonEvent
39.1 Introduccin
Elobjetivodeestecomponenteescreareventospropagablescomomensajesdeunaredyque puedanserprocesadospormltiplesendpointsendiferentesplataformas.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

379

Parte8:AdministracineInformacindeAplicaciones

40 Componentes de Propsito General


40.1 Introduccin
A continuacin se presenta la referencia de los componentes del framework que aplican a cualquierproyectodesoftware.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

380

41 Componente Config
41.1 Introduccin
Este componente permite al desarrollador leer archivos de configuracin en diferentes formatosenobjetosphpaptosparausarenprocesosdelasaplicaciones.

41.2 Adaptadores de Config


Elcomponentehaceusodeadaptadoresqueencapsulanlosdetallesdecadaformato. Tabla:AdaptadoresdelcomponenteConfig TipoFormato Ini Xml Array Yaml Descripcin UtilizaarchivosPHPparaalmacenarlaconfiguracin.Internamenteseusa lafuncindephpparse_ini_file. UtilizaarchivosdeconfiguracinenXML. UtilizaarraysmultidimencionalesnativosdePHPparaalmacenarla configuracin.Entrminosderendimientoeselmejor. UtilizaelformatoYAML(Yetanothermarkuplanguage)paraladefinicin dearchivosdeconfiguracin.Elrendimientopuedesermenordebidoaque seutilizaPHPparaparsearelarchivodeconfiguracin. Laflexibilidaddeestecomponentepermitequeeldesarrolladorutiliceelformatoquelesea ms familiar tanto para los archivos de configuracin de su aplicacin como los del framework. ElcomponenteConfigcacheaelresultadodeprocesarunarchivo,as,siesprocesadoenuna mismapeticinmsdeunavezesteesnoesreprocesadomejorandoelrendimiento. En los siguientes ejemplos se muestra como el mismo archivo de configuracin es representandoendiferentesformatos: 41.2.1 AdaptadordeconfiguracinIni Config soporta archivos INI estos son ampliamente usados por todo tipo de software que ademssonelformatopredeterminadodelframework.Eladaptadorprocesalasseccionesdel archivo y variables compuestas. Gracias a que se usan funciones nativas del lenguaje su procesadoesmsrpido.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

381

Ejemplo:ArchivodeconfiguracinenINI
[example] variable = valor [development] database.host = localhost database.user = jasmin database.password = secret

41.2.2 AdaptadordeconfiguracinXML EladaptadordeconfiguracinXMLpermiteprocesararchivosqueusenellenguajedemarcas XML. Los archivos XML son ampliamente reusables por otras tecnologas y lenguajes. El procesado de los archivos se hace usando funciones nativas del lenguaje PHP por lo que es muyrpida. Ejemplo:ArchivodeconfiguracinenXML
<?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 AdaptadordeconfiguracinArraysdePHP El adaptador de configuracin PHP permite definir la configuracin en arrays multidimensionalesnativosdellenguajeconlocualseobtienelamayorvelocidadalleerlosy procesarlos. Ejemplo:ArchivodeconfiguracinenPHP
<?php $config = array( 'example' => array( 'variable' => 'value' ), 'development' => array( 'database' => array( 'host' => 'localhost', 'username' => 'jasmin', 'password' => 'secret' ) ) );

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

382

41.2.4 AdaptadordeconfiguracinYaml Los archivos de configuracin Yaml son ampliamente usados por otros frameworks como SymfonyRubyOnRails.Sonconocidosporsusimplicidadyfacilidaddeentendimiento.Su procesamientoserealizaaniveldePHPporloquesuprocesamientopuedesermslento. Ejemplo:ArchivodeconfiguracinenYAML
# Archivo para adaptador Yaml example: variable: value development: database: host: localhost username: jasmin password: secret

41.2.5 Leerarchivosdeconfiguracin Para los ejemplos de archivos de configuracin el siguiente ejemplo sin importar el que se escogieseproduciraelmismoobjetoConfigcomoresultado: 41.2.6 Ejemplo:Leerunarchivodeconfiguracin
//Leer la configuracin $config = Config::read('myconfig/config.ini', 'ini'); //Comprobar los valores ledos assertEquals($config->example->variable, 'value'); assertEquals($config->development->database->host, 'localhost'); assertEquals($config->development->database->username, 'jasmin'); assertEquals($config->development->database->password, 'secret');

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

383

42 Componente Extensions
42.1 Introduccin
El componente Extensions se encarga de administrar las extensiones cargadas en una aplicacinyaseadeformadinmicaesttica. Una extensin es un componente del framework que no se carga por defecto y tampoco es inyectadoalrequerirseenunprocesodenegocio.

42.2 Cargar una extensin dinmicamente


Lacargadinmicadeextensionespermitecargarcomponentesdelframeworkdeusuarioen elmomentoenelquesenecesitenyporconsiguientereducirligeramentelacargadelectura dedisco. Ejemplo:CargarunaextensiondinmicamenteusandoelcomponenteExtensions
<?php class PressController extends ApplicationController { public function indexAction(){ //Cargar extensin de Localizacin Extensions::loadExtension("Kumbia.Locale"); } }

42.3 Cargar una extensin estticamente


Los extensiones que se usen ampliamente en la aplicacin pueden cargarse mediante el archivodeconfiguracindelasaplicacionesllamadoconfig/boot.ini.Laestructuradelarchivo eslasiguiente: Ejemplo:Cargarunaextensionestticamenteusandoboot.ini
; Cargar extensiones [modules] extensions = Kumbia.Acl,User.MyComponent,Mail.Phpmailer

Laseccinmodulestienelaopcindeconfiguracinextensionsenlacualsepuededefinirlas extensiones a cargar separandolas por comas. Las extensiones que estn en el namespace Kumbia hacen parte de la biblioteca de componentes de framework, las que empiezan por Usersoncomponentesqueeldesarrolladoracreadoyestnubicadaseneldirectoriolibrary

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

384

de la aplicacin, por ltimo, la extensin se localiza en el directorio principal Library de la instanciacomoeselcasodePhpMailer. 42.3.1 CargarcomponentesdeZendFramework Componentes especificos de Zend Framework pueden ser cargados estticamente dinmicamente usando la convencin Zend.Componente. Por defecto el framework es buscado en la ruta de la instancia Library/Zend, esta ruta puede ser modificada usando el mtodoExtensiones::setZendDirectory. Paracargarunaextensindinmicamenteseusa: Ejemplo:CargarcomponentesdeZendFramework
Load::extension(Zend.Dojo)

Paracargarlasenconfig/boot.iniseusa: Ejemplo:CargarcomponentesdeZendFrameworkestticamente
[modules] extensions = Zend.Amf

42.4 Cargar archivos individuales al iniciar la peticin


Estecomponentetambinpermitecargararchivosindividualesaliniciodecadapeticinque preferiblementeseanusadosconfrecuenciabuscandomejorarelrendimiento. Estosarchivossedefinendeclarativamenteseparandolosporcomasenelarchivoboot.inias: Ejemplo:CargararchivosPHPindividualesenboot.ini
[classes] files = apps/default/classes/MiClase.php, Library/Kumbia/ActiveRecord/SessionRecord/SessionRecord.php,Library/Kumbia/Local e/LocaleMath/LocaleMath.php

42.5 Obtener informacin de extensiones cargadas


Los siguientes mtodos de clase Extensions proporcionan informacin sobre las extensiones cargadas: publicbooleanstaticisLoaded(string$extensionName) Devuelvetruesilaextensinyahasidocargadaenlapeticinactual,falsedelocontrario.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

385

publicarraystaticgetLoadedExtensions() Devuelveunarregloconlosnombresdelasextensionescargadasenlapeticinactual.

42.6 Inyeccin de componentes


KumbiaEnterpriseFrameworkutilizainyeccindedependenciaparacargarloscomponentes justocuandosonrequeridos.Siuncomponenteesusadofrecuentementeporlaaplicacines probable que cargarlo estticamente mejore el rendimiento en los dems casos es recomendablepermitirqueseaninyectadosdurantelaejecucin.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

386

43 Componente Logger
43.1 Introduccin
El componente Logger es un componente cuyo propsito es el crear logs usando diferentes backends mediante adaptadores, opciones de generacin como formatos y filtros e implementacindetransacciones. EstecomponenteaccedeasusadaptadoresusandoelpatrnVirtualProxy,esdecir,elobjeto logger solo acta como un Proxy al objeto real instanciado que corresponde al tipo de adaptadorutilizadoporelmismo.LaclaseLoggerdelegatodaslastareasaladaptadorquepor defectoeselsubcomponenteFileLogger,elcualrealizaelalmacenamientoenarchivosplanos delservidor.

43.2 Adaptadores de Logger


TodoslosadaptadoresimplementanlainterfaceLoggerInterfacequedefinelosmtodosque cadaadaptadordebeimplementar.Lainterfacetienelasiguienteestructura:
interface LoggerInterface { public public public public public } function function function function function begin(); rollback(); commit(); close(); log($message, $type);

Losadaptadoresdisponiblessonlossiguientes: Tabla:AdaptadoresdisponiblesenelcomponenteLogger Adaptador FileLogger MailLogger SAMLogger DatabaseLogger CompressedLogger Descripcin Permiteescribirlogsaarchivosdetextoplanoenelservidorlocal. Permite enviar un log a un correo electrnico automticamente en cuantoescreado. Permite enviar logs como mensajes de un servidor de mensajera SimpleAsynchronousMessaging(SAM). Permitegrabarloslogsenunatablaenlabasededatos. Permite escribir logs a archivos de texto plano comprimidos usando

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

387

ZLibenelservidorlocal. StreamLogger SocketLogger El desarrollador puede implementar sus propios logs implementando la interface LoggerInterface. UnejemplodelusodelcomponenteLoggereselsiguiente: Ejemplo:CreacindelogsusandoelcomponenteLogger
<?php class TestController extends ApplicationController { public function testAction(){ $logger = new Logger(); $logger->log("Esto es una prueba"); } }

Permite escribir logs a envolturas y protocolos de PHP que soporten escritura. Permite escribir logs a puertos TCP/UDP que tengan servidores que aceptencadenasdetexto.

SehacreadounainstanciadelaclaseLoggerysehalogueadoeltextoEstoesunaprueba.El primer parmetro 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 nombredelloglaconvencinlogYYYYMMDD.txt. Los logs se almacenan por defecto en el directorio logs de la aplicacin, sin embargo esto puede modificarse usando el mtodo 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. Elcontenidoresultantedelarchivoeselsiguiente:
[Sun, 31 Aug 08 20:12:31 -0400][DEBUG] Esto es una prueba

Pordefectoelformatodelloges[%date%][%type%]%message%.Enelsiguienteejemplose cambiaelformatodefechayhoraydelalneadellogengeneral,ademssecambiaelnombre dellog:

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

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"); } }

ElformatodelloghasidomodificadousandoelmtodosetFormat,elcualrecibeunacadena conmodificadoresquesonreemplazadosporsuvalorcorrespondienteenelmomentoenque segeneraellog:


> DEBUG Esto es > DEBUG Esto es > test/test on default at Sun, 31 Aug 08 20:00:00 -0400 with message: una prueba > test/test on default at Sun, 31 Aug 08 20:00:00 -0400 with message: otra prueba

LosmodificadoresqueaceptalmtodosetFormatson: Tabla:ModificadoresquerecibeelmtodosetFormat Modificador %type% %message% %date% paramsinformacin. Eselmensajelogueadocomotal. Eslafechaenqueocurreelevento.Pordefectoutilizaelformatoqueesta asignadoalmodificadordelafuncindate(r)quecorrespondealformato
RFC 2822.

Descripcin Indica el tipo de evento logueado. Consulte la tabla de tipos de eventos

%controller% %action% %priority% %facility% %url% %application%

Elcontroladoractualenelquesellamaellog. Laaccinactualenlaquesellamaellog. Laprioridadconrespectoalcontextoyeltipodeevento. Indicaelcontextoenelseproduceellog. LaURLcompletapasadaalenrutadorantesdellamarallog. Laaplicacinactualenlaquesegeneraellog.

ElformatodefechasepuedemodificarusandoelmtodosetFormatDate: Ejemplo:CambiarelformatodefechadeunlogusandosetFormatDate

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

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"); } } ?>

Elloggeneradoeselsiguiente:
> DEBUG > test/test on default at 2008.10.21 00:14 with message: Esto es una prueba

43.3 Tipos de Eventos en Logs


ElcomponenteLoggerproporcionaunaseriedetiposdeeventosquepermitenclasificarcada uno de acuerdo a una gravedad prioridad en algunos contextos. Para definir el tipo de eventoenunalneadellogsepasacomosegundoparmetroalmtodologunaconstantedel componenteloggeras:
$logger->log("La memoria usada por la aplicacin es ".memory_get_usage(), Logger::INFO);

Los valores de las constantes coinciden con las severidades usadas por syslog y estandarizadasenelRFC3164:TheBSDsyslogProtocol(http://tools.ietf.org/html/rfc3164). Adicionales a los estndar, Logger agrega los eventos CUSTOM y SPECIAL con menor severidad que los dems pero que se utilizan en contextos menos crticos. Los tipos de eventossoportadosson: Tabla:Eventosysudescripcin TipodeEvento EMERGENCY ALERT CRITICAL ERROR Severidad 0 1 2 3 Descripcin Emergencia:Elsistemaestainutilizable. Alerta:Mensajesdealerta. Critico:Propendealaquesetomenaccionesde inmediato Errores:Erroresexcepcionesdelaaplicacin

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

390

WARNING NOTICE INFO DEBUG CUSTOM SPECIAL

4 5 6 7 8 9

Advertencias:CondicionesdeAdvertencia Mensajesqueocurrenencondicinnormal. Mensajesdeinformacin. Mensajesdedebug. Mensajes sin clasificar generandos por el usuariofinal. Condiciones especiales fuera de un contexto de criticidad. Como por ejemplo llevar un registro delosusuariosqueingresanalaaplicacin.

MtodosdelmismonombresonproporcionadosenlaclaseLoggeryrealizanlamismatarea quelog: Ejemplo:Usarmtodosaliasparaindicarlaseveridaddeunmensaje


$logger->log("Esto es una Advertencia!, Logger::WARNING); $logger->warning("Esto es una Advertencia!);

EltipodeeventopordefectoesLogger::DEBUG.

43.4 Logger Facilities


KumbiaEnterpriseFrameworkmantieneseparadoslosespaciosdememoriayejecucindesde el Sistema Operativo hasta el Nivel de Usuario esta informacin permite evaluar en que contextoseproducenlosmensajesdelog. LosFacilitysonlossiguientes: Tabla:NombresydescripcindeFacilities Cdigo 0 SO Nombre Descripcin Generada en el contexto de sistema operativo. Usualmente se relaciona con problemas con permisosalertasdelSO. 1 2 3 HARDWARE NETWORK FRAMEWORK_CORE Relacionadoconactividades Es el contexto de comunicaciones e infraestructuradered. ContextodelncleodelFramework.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

391

4 5 5 6

FRAMEWORK_COMPONENTS SECURITY AUDIT USER_LEVEL

Contexto de Componentes del Framework (bundled) ContextodeSeguridad ContextodeAuditoria Problemas ocurridos a nivel de usuario y aplicaciones.

Para obtener el cdigo numrico del Facility Actual se utiliza el mtodo esttico Facility::getFacility(). Por medio del facility es posible determinar el contexto en el que se originunlog.Eltipodeeventovistocomoseveridadyelfacilitycomoelcontextoenelque segener,permitencalcularlaPrioridad.staeselresultadodemultiplicarloscdigosde ambos,laseveridadyelfacility.

43.5 Transacciones con Logs


Cadaadaptadorrealizaunaimplementacinpropiadetransaccionessegnsunaturaleza.Las transaccionespermitenaldesarrolladordecidirsilosmensajesdelogacumuladosduranteun proceso de negocio es necesario almacenarlos en los backend anular la operacin. Los mtodos begin, commit y rollback familiares en un ambiente de base de datos pueden ser usadosenelarchivodelogparaadministrarelestadodelatransaccin. En el siguiente se ejemplo se ilustra mediante una transaccin de negocio como el log es creadoperosoloseguardasisecumplenciertascondicionesdelprocedimiento: Ejemplo:Crearunatransaccinenunlog
<?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 ao"); if($movement->getStatus()!="F"){

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

392

} if($totalPrice>=$cutomer->getMaxPrice()){ $logger->log("El cliente '{$customer->getId()}' ha sobrepasado su crdito"); $logger->commit(); } $logger->rollback(); } } ?>

} } else { if($movement->getStatus()!="H"){ $movement->moveToHistorical(); } }

$movement->setStatus("F"); $movement->save(); $totalPrice+=$movement->getPrice();

43.6 API de FileLogger


publicvoidsetPath(string$path) PermiteestablecerelPathdondesealmacenaranloslogs. publicvoidsetFormat(string$format) Estableceelformatoenelqueseproducircadalneadellog. publicvoidsetDateFormat(string$format) Establece el formato de fecha con los modificadores de las funcin date() para producir las fechasenlaslineasdellog. public$pathgetPath() Obtieneelpathactualdondeseestnalmacenandoloslogs. publicvoidlog(mixed$msg,$type=Logger::DEBUG) Agregaunalneallogdetipo$type. publicvoidbegin() Iniciaunatransaccinenellog. publicvoidrollback() Cancelaunatransaccinenellog. publicvoidcommit()

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

393

Aceptaunatransaccinenellogalmacenandolaslineaspendientes. publicvoidclose() Cierraellog.

43.7 Uso de MailLogger


El componente Logger soporta un adaptador especial que permite que este al cerrarse se envieautomticamenteauncorreoelectrnico.Laextensinhaceusodelalibreradeenvo decorreoelectrnicoSwiftquesedistribuyeconelframework. El adaptador est diseado para realizar el envo de emails usando el protocolo SMTP sin dependerdelafuncinmail()dePHPdelaherramientasendmail. Todaslosregistrosdellogquesonagregadossealmacenanenmemoriahastaquesecierrael log,seinvocaelmtodocommitsedestruyeelobjeto.Debidoaloanterioresrecomendable noalmacenarlogsmuygrandesyaquepuedenconsumirdemasiadamemoriaygeneraruna salidafatalporpartedelaaplicacin. Losregistrossolosepuedenagregarcuandoseactivaunatransaccinenellog,pordefecto unaesiniciadaautomticamente.Tambinsepuedeusarelmtodobegin()parainiciarla. Esnecesarioqueelservidorpuedaestablecerconexionessalientesapuertosseguros(465)e inseguros (25) y que el servidor SMTP est disponible al tratar de realizar el envio del log puesdelocontrariosegenerarunaexcepcin. LaextensindePHPphp_openssldebeestarcargadaparahacerusodeesteadaptador. ElsiguienteesunejemplodelusodeMailLoggerenviandounmensajedesdeunacuentade Gmail: Ejemplo:CrearunMailLoggerqueenvialosmensajesauncorreodeGmail
$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 aplicacin" ));

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

394

$log->log("Un Message de Error", Logger::ERROR); $log->log("Un Message Critico", Logger::CRITICAL); $log->close();

Alcerrarellogseenviaunmailconlos2mensajesacumuladosinternamenteenellog.Para realizar conexiones seguras por TLS se debe establecer el parmetro secureConnection a true. CuandonoseestableceelasuntodelmensajeMailLoggerutilizaelsiguienteformato: MailLog:nombreAplicacionFechausandoformatoRFC2822 Sisedeseaenviarellogavariosemailssepuedepasarunarraycomosegundoparmetroal instanciarellog: Ejemplo:EnviandolosmensajesdelMailLoggeravarioscorreoselectronicos
$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 aplicacin" )); $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


EladaptadorCompressedLoggerpermiteescribirlogsaarchivosdetextoplanocomprimidos usandozlibenelservidorlocal.LaextensindePHPzlibdebeestarcargadaparahaceruso deesteadaptador. La ventaja de el uso de este tipo de logs es que ahorran sustancialmente espacio de disco aunquerequierendemayoresrequerimientosdeprocesamiento. Ejemplo:CrearunlogcomprimidoconLogger
$logger = new Logger("Compressed", "my_app.log.gz");

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

395

$logger->log(Esta cadena ser comprimida en el log); $logger->close();

AligualqueFileLoggerlosregistroseagreganenmodoappendesdecirquenuevosmensajes seagreganalfinaldelarchivo. publicvoidsetPath(string$path) PermiteestablecerelPathdondesealmacenaranloslogs. publicvoidsetFormat(string$format) Estableceelformatoenelqueseproducircadalneadellog. publicvoidsetDateFormat(string$format) Establece el formato de fecha con los modificadores de las funcin date() para producir las fechasenlaslineasdellog. public$pathgetPath() Obtieneelpathactualdondeseestnalmacenandoloslogs. publicvoidlog(mixed$msg,$type=Logger::DEBUG) Agregaunalneallogdetipo$type. publicvoidbegin() Iniciaunatransaccinenellog. publicvoidrollback() Cancelaunatransaccinenellog. publicvoidcommit() Aceptaunatransaccinenellogalmacenandolaslineaspendientes. publicvoidclose() Cierraellog.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

396

43.10 Uso de SAMLogger


EladaptadorSAMLoggerpermiteenviarlogsaunserviciodemensajesquesoportenSimple Asynchronous Messaging como el IBM WebSphere MQSeries. Este adaptador requiere de a extensin 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).LaextensinpuedeserdescargadadePECL. Ejemplo:EnviarmensajesdelogaWebSphereMessagingServer
//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 aplicacin 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 ms flexible y potente de los adaptadores de Logger ya que permite escribirlogsadiferentesrecursoscuyaescrituraporstreamestesoportadaporPHP. Enlossiguientesejemplosseilustraelusodeesteadaptador: Ejemplo:EnviarmensajesdeLogusandoeladaptadorStreamLogger
//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/KumbiaEnterpriseFrameworkManualdeReferencia

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 estndar $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 tamao superior a 2MB sern escritos a disco $logger = new Logger("Stream", php://temp"); //Cambiar limite a 10MB 1073741824 bytes $logger = new Logger("Stream", php://temp/maxmemory:1073741824");

EnlasopcionesdelStreampuedeestablecerseelmododeescrituraquetendrenLogdeesta forma:
$logger = new Logger("Stream", file://my_log.txt", array( mode => a ));

Losposiblesmodosdeescriturason: Tabla:ModosdeescrituradelogsusandoStreamLogger Modo a ab Descripcin Agregalogsalfinaldelarchivoexistente.Sinoexistelocrea. Agrega logs al final del archivo existe. La escritura es binaria. Este es el modo w wb x predeterminado para StreamLogger, FileLogger y CompressedLogger. Escribelogsenelarchivo.Lotruncasiexisteylocreasinoexiste. Escribe logs en el archivo. Lo trunca si existe y lo crea si no existe. La escrituraesbinaria. Escribelogsenelarchivo.Siyaexistegeneraunaexcepcin.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

398

43.12 Uso de SocketLogger


Permite escribir logs a puertos TCP/UDP que tengan servidores servicios que acepten cadenasdetexto.Losservidoresdesocketspuedenreplicarlogsaotrosservidoresmediante carcteristicasdebajonivel. Ejemplo:EnviarmensajesdelogsusandosocketsTCP/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 conexin 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/KumbiaEnterpriseFrameworkManualdeReferencia

399

44 Componente Utils
44.1 Introduccin
Utils es un componente que principalmente es utilizado por el framework para centralizar funciones auxiliares de propsito general, su funcionalidad tambin est disponible al desarrollador.

44.2 API de Utils


staticfunctionarrayarrayMergeOverwrite(array$a1,array$a2) Este mtodo permite combinar 2 arrays asociativos multidimencionales devolviendo el resultado. staticfunctionvoidarrayInsert(array$form,mixed$index,mixed$value,mixed$key=null) Estemtodopermiteinsertarunvalorenunadeterminadaposicindeunarraymoviendolos elementosasuposicinsiguiente. staticfunctionarrayscandirRecursive(string$package_dir,array$files=array()) Devuelve un vector con todos los archivos que haya una ruta. Este mtodo recorre recursivamentelosdirectoriosencontrados. staticfunctionarraygetParams(array$params,int$numberArgs) Convierte los parmetros por nombre recibidos en una funcin y los convierte a un array asociativo. El primer parmetro normalmente es un array devuelto por la funcin func_get_args()yelsegundoelvalordevueltoporfunc_num_args(). staticfunctionarraygetParam(string$param) Devuelveunarrayasociativoconelresultadodeunparmetropornombre.Lallavedelitem eselnombredelparmetroysuvalorrespectivo. staticfunctionstringcamelize(string$str) Devuelveunacadenadecarcteresennotacincamelizada. staticfunctionstringuncamelize(string$str) Devuelveunacadenadecarcteresennoticacinunderscore(guionbajo).

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

400

staticfunctionstringlcfirst(string$s) Conviertelaprimeraletradeunapalabraaminsculas. staticfunctionstringgetKumbiaUrl(string$url) Obtiene una ruta valida segn el entorno de ejecucin de la aplicacin. Esta URL devuelta permitiraccederalaaplicacinusandounrecursoexterno. staticfunctionarraygetQuotedArray(array$toQuoteArray,string$quoteChar=''') Agrega comillas a cada elemento de un array. El carcter de comillas se establece con $quoteChar. staticfunctionstringucwords(string$words) Conviertelaprimeraletradecadapalabrade$wordsamayscularespetandoelcharsetenel queseencuentraelvalordeentrada.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

401

Parte8:RendimientoyOptimizacin

45 Rendimiento y Optimizacin
45.1 Introduccin
En este captulo se referencian los componentes y prcticas que ayudan a mejorar el rendimientodeaplicacindesarrolladaenKumbiaEnterprise.

45.2 Consideraciones de Rendimiento


En los siguientes apartados se recomiendan prcticas que mejoran el rendimiento de una aplicacin. 45.2.1 Utilizacindeparmetrospornombre Muchos de los componentes de framework como ActiveRecord, Router y Tag soportan parmetrospornombre.Estospermitenindicarlosvaloresdelosparmetrosrequeridosen cualquierordensolventandounalimitacindellenguajePHP. Cuandosetratademejorarelrendimientodeunaaplicacinesrecomendablereemplazarlos llamados a mtodos que utilicen parmetros por nombre por arrays cuyos indices representenlosnombresdeestos.Deestaformaseeliminaeloverheadquerequiereevaluar medianteexpresionesregulareslosparmetrospornombreyasoptimizalaejecucindela aplicacin. 45.2.2 InstalarunCachedeOpCode UnadelasmejoresprcticasparamejorarelrendimientodeaplicacionesenKumbiaEnteprise en fase de produccin es instalar un cacheador de cdigo intermedio. Debido a que en esta fase archivos que contienen cdigo PHP usualmente no se modifican, un software especializadopuedecachearelcodigointermedio(codigoPHPqueseharevisadosusintaxis ysehaeliminadofragmentosinnecesariosparalaejecucincomocomentariosyotraspartes) de esta forma cada vez que se carga un archivo PHP en el compilador parte del trabajo de interpretacinyaesthecho. NormalmenteloscachesdecdigointermedioleendatosdelosarchivosPHPcomoelinodoy el dispositivo donde esta almacenado para crear un identificador nico para el mismo y as evitarqueunmismoarchivosealeidovariasvecesenunamismapeticin.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

402

La eliminacin de la etapa de parseo del cdigo intermedio PHP no es la nica mejora que realizauncacheador.Otrasmejorasincluyenunconsumoreducidoderecursosdediscoduro yoptimizacionesalcdigointermedio.Lasaplicacionesquenormalmenterealicenpeticiones cortas con una inclusin moderada de otros archivos en la misma pueden obtener mejoras hastadel200%y300%.Paraprocesoslargoslaoptimizacinpuedeserdel30%al40%.En cualquiercasolamejorasiempreesconsiderable. La mayor ventaja de los cacheadores de cdigo intermedio es que no requiren que la aplicacinseadesarrolladabajoningntipodeestandarconalgnrequerimientoespecial. LanicalimitacinesquePHPdebeestarinstaladocomounmdulodelservidorusando FastCGI, esto se debe a que los datos del cdigo intermedio se almacenan en memoria compartidaystanoestdisponibleparamoduloscgi. 45.2.2.1 CacheadoresdeCdigoIntemerdioDisponibles Existen implementaciones de cacheadores tanto abiertas como cerradas. En las de cdigo abierto se encuentra la extensin y PECL Alternative PHP Cache (APC)
http://pecl.php.net/package/APC

Turck

MMCache y

http://turck-

mmcache.sourceforge.net/index_old.html. En las opciones de cdigo cerrado est Zend

Optimizer

http://www.zend.com/store/products/zend-platform/

phpAccelerator

http://freshmeat.net/projects/phpa/.

Las velocidades de todas las implementaciones son en promedio muy parecidas. La opcin APCnoimplementaoptimizacionesdecdigointemerdioporloqueenalgunassituacionesen rendimientopuedesermenor. 45.2.3 SintonizacindelServidorWeb AlgunasoptimizacionesreferentesaaplicacionesdesarrolladasenKumbiaEnterprisepueden ser realizadas a nivel del Web Server. A continuacin se presentan las que aplican para ApacheWebServerotrosbasadosenl,comoOracleHTTPServeryZendApplicationServer. 45.2.3.1 Eliminarencabezadosinnecesarios ElencabezadoHTTPquecontieneeltipodeservidorusadoesenviadoencadarespuestaque generaelservidorWeb.Enlamayorpartedeloscasosesteencabezadonotieneusoaplicable yporlotantohacealgomsgrandelarespuestadelservidorsinnecesidadalguna.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

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 configurcin de Apache la opcin ServerSignature a Off. De esta forma se puede ahorrar ms de 1GB de ancho de banda para unaaplicacinenproduccinduranteunmes. 45.2.4 SintonizacindePHP FALTA

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

404

46 Componente Cache
46.1 Introduccin
Lasaplicacionesdealtadisponibilidadrequierendependiendodelascondicionesdelnegocio sistemas de cache que ofrezcan la posibilidad de implementar transacciones, control de concurrencia y clusterizacin. LouderTechnology proporciona LouderCache un proyecto independienteperototalmenteintegrablealframeworkelcualhasidodesarrolladopensando enestascaractersticasempresariales. Cuandoserequieremejorarelrendimientoyoptimizarunaaplicacinmediantetareasms sencillascomocachearfragmentosdevistas,datosyregistrosKumbiaEnterpriseframework proporcionaelcomponenteCache. FALTA

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

405

47 Componente Compiler
47.1 Introduccin
Kumbia Enterprise Framework utiliza inyeccin de dependencias para instanciar cualquier componete a medida que se va requiriendo. Esto resulta ideal ya que evita que decenas de archivosseancargadosenunapeticinsinqueseanrequeridosencontradolamediaperfecta derequerimientosdedependenciasparacadaprocesodenegocio. Algunos componentes como Router, Dispatcher, Core, etc., no requieren de inyeccin ya que debido a la arquitectura del framework son requeridos siempre en cada peticin y de est forma se mejora el rendimiento de una aplicacin. Otros componentes son requeridos usualmente pero dependiendo de los objetivos de la aplicacin se puede decir que son utilizadosfrecuentemente. El desarrollador puede contar cuantos archivos son leidos en una determinada peticin de estaforma:
<?php echo print_r(get_required_files()); ?>

Sielnmerodearchivosesmuyelevado,laaplicacinpodraestarconsumiendorecursosde lecturadediscoaltoshaciendoqueelrendimientodeunaaplicacinsedisminuya. El componente Compiler resuelve estas situacin generando un solo archivo con todos los componentesyarchivosdelframeworkenunaversinoptimizadaquesonutilizadosenuna peticin regular y dejndole el resto del trabajo al inyector de dependencias. El uso de este componentepuedeaumentarelrendimientodelframeworkde4a5veces.Sisecuentano se cuenta con un optimizador y cacheador de cdigo intermedio este componente siempre puedeserdegranayudaparaelmejoramientodelrendimientodeunaaplicacin. Porserunasolucinbasada100%enPHPpuedetenerunpapelvitalcuandonosecuentacon controldelhardwaredondeseimplementalaaplicacin. Nota:Compilersolodebeserusadocuandolaaplicacinhayacumplidoengranmedidacon lasfasesdedesarrolloytesteoyaquealgunoscomponentesdelaaplicacinsonincluidosen lacompilacinconloculnosepodrarealizarcambiosaestos.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

406

47.2 Teoria de optimizacin avanzada


EnesteapartadosetratadeexplicarlasteoriasqueenLouderTechnologysehaninvestigado paratratardebscarunaejecucinmsoptimadeaplicacionesenPHP.Lasinvestigacionesse basanenbenchmarksadiferentestiposdeprocesos. 47.2.1 Optimizacindeciclos 47.2.1.1 Optimizacinporreemplazodefunciones SiparaunconjuntoXdeinstruccionesrepetitivasseevaluanvecesunamismafuncinf(x)> y, en donde x es un valor esttico para este contexto entonces podra decirse que hay una degradacindelrendimientoyaqueelvaloryesevaluadoalmenosnveces. Lafuncinentoncespuedesertraducidaaf(x)>zreemplazandoz>yenelconjuntoX. 47.2.2 Optimizacinporevaluacindeterminosestticos Definicin1:Siparaunaevaluacindelaexpresindecompilacinf:X>Y,losvaloresdex resultan de operaciones polimorficas deducibles entonces se puede decir que f : z > Y producirelmismoresultadoenejecucin. Definicin2:Siparaunaevaluacindelaexpresindecompilacinf:X>Y,losvaloresdex resultandereemplazarconstantesdeduciblesentoncessepuededecirquef:z>Yproducir elmismoresultadoenejecucin.

47.3 Comportamiento de Compiler


Elcomponentegeneraunnicoarchivocontodosloscomponentesyclasesutilizadosenuna peticin regular a una aplicacin. Otros componentes pueden ser agregados a este archivo parahacermsefectivoelobjetivoesperado. 47.3.1 Optimizacionesbsicasdelacompilacin El archivo generado es producido realizando las siguientes optmizaciones que pueden mejorarenmedidamenormediaelrendimientodeunapeticin: Todosloscomentariosdelineasencillaymultilineasoneliminados Espacios,tabulacionesysaltosdelneasoneliminados. Archivosqueseanincluidosenotrosarchivosyaincluidossonomitidos Lasconstantes__FILE__y__LINE__mantienensuvalororiginal

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

407

47.3.2 Optimizacionesavanzadasdelacompilacin Con base al funcionamiento interno del compilador de PHP es posible determinar que prcticas de programacin son ms reconmendables para obtener mejoras en velocidad y rendimiento.Compilerofreceunafasedecompilacindenominadaavanzadaenlaquerealiza lassiguientesoptimizaciones: Todoslosstringsdedoblecomillaquenocontengansustitucionesdevariables caracteresdebarrainvertidasonconvertidosastringsdecomillasencilla,exceptolos quesonmultilnea,deestaformaseevitaqueelanalizadorlxicodelinterpretePHP bsqueinnecesariamenteexpresionesregularesquenovanaserencontradas. Ejemplo:Optimizacinporeliminacindecalculosredundantes
<?php $unArrayGrande = range(1, 10000); for($i=0;$i<=count($unArrayGrande)-1;$i++){ print $unArrayGrande[$i]; }

Lassentenciasforsonoptimizadascuandorealizanconteossucesivosensu evaluacin.Elcdigoesmodificadohaciendoqueelconteoseejecuteunasolavez:

Esmodificadoa:
<?php $unArrayGrande = range(1, 10000); $_sp=count($unArrayGrande)-1; for($i=0;$i<=$_sp;$i++){ print $unArrayGrande[$i]; }


<?php $unaPalabra = "esto es un texto"; for($i=0;$i<=strlen($unaPalabra)-1;$i++){ if($i%2==0){ $unaPalabra.="x"; } if($i>10){ break; } }

Cuandoalgunadelasvariablesdelaevaluacinesmodificadaentonceslasentencia forsemantieneintacta:

Las asignaciones que no se hagan con el operador de incremento decremento son

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

408

convertidas a esta forma, por lo tanto $x = $x +1 se lleva a $x++ y $x = $x + $y se convierteen$x+=$y; Eldesarrolladorpuedetenerencuentalasoptimizacionesanterioreseimplementarlascomo buenasprcticasdedesarrollo.

47.4 Generar una Compilacin


Como se mencion anteriormente el objetivo de la compilacin es reunir todos aquellos componentesyrecursosqueconstituyenunamediadelecturadediscooptimizandolosyas mejorarelrendimientodelaaplicacin. En el proceso seleccionado por el desarrollador se invoca el mtodo compileFramework del componenteCompiler:
<?php Compiler::compileFramework() ?>

47.5 Limitaciones de Compiler


ElcomponenteCompilertienelassiguienteslimitaciones: FALTA

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

409

48 Componente GarbageCollector
48.1 Introduccin
El componente GarbageCollector permite de manera controlada comprimir eliminar datos del estado de persistencia y metadatos de entidades almacenados en el administrador de sesin.

48.2 Porque usar este componente?


Los controladores que implementan el estado de persistencia proporcionan un potente mtodo para mantener contextos de sesin que mejoran la experiencia de usuario en un determinandocomponentedelaaplicacin.Elusoexcesivodemltiplescontextos(mltiples controladores con estado de persitencia) podra sobrecargar la aplicacin ya que todos los datosdepersistenciasonparcialmentecargadosencadapeticin. Estecomponentepuededetectarquecontextoshanexpiradoyliberarlamemoriapersistente utilizadaaumentandoelrendimientodelaaplicacin.

48.3 Como funciona el GarbageCollector


El componente proporciona el mtodo GarbageCollector::startCollect() que con base a una probabilidad predefinida invoca una rutina en busca de datos del estado de persistencia metadatosdeentidadesqueseconsiderenendesusoexpirados.Larutinadelcolectorse ejecutaen2fases: 48.3.1 FasedeCompresin Primeroselocalizandatosquenosehayanusadoenuntiempopredefinidoysecomprimen los datos usando zlib en nivel de compresin 5 (normal). En este caso no se acta propiamente como recolector de datos en desuso pero da la oportunidad de reutilizar los datosahorrandoespacioalmismotiempo. 48.3.2 FasedeEliminacin Cuando los datos han superado un tiempo de desuso pronunciado se procede a su eliminacin.Enelcasodeloscontroladorespersistentesbsicamenteseproduceelefectode reiniciodesusatributosyeneldelosmetadatosdeentidadesseobligaaunnuevovolcado porpartedeActiveRecordMetaData.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

410

48.4 Activar el GarbageCollector


Por defecto el garbage collector se encuentra desactivado para cualquier aplicacin, su activacinpuedeserprogramacionaldeclarativa. 48.4.1 Activacindemaneraprogramacional La rutina de recoleccin puede ser invocada programacionalmente al finalizar una peticin. Unplugindeaplicacinresultaidealparainvocarelgarbagecollector.Serecomiendaquela recoleccinsehagasiemprealfinalizarlaspeticionesyaqueenestepuntoseaseguraquelos datosaliberarrealmenteestenendesusoexpirados. Ejemplo:Establecerlasopcionesdelcollectorprogramacionalmente
<?php class MyCollectorPlugin extends ApplicationPlugin { public function beforeFinishRequest(){ //Expirar objetos que tengan ms de una hora en desuso GarbageCollector::setCollectTime(3600); GarbageCollector::startCollect(); } }

48.4.2 Activacindemaneradeclarativa Enelarchivoconfig/config.iniesposibleactivardeformadeclarativaelrecolectormediantela siguienteconfiguracin: Ejemplo:Activarelcollectordesdeelarchivodeconfiguracinconfig.ini


[application] mode = development name = "APPLICATION NAME" debug = On [collector] probability = 100 compressionTime = 900 compressionLevel = 5 collectTime = 1800

La definicin de la seccin collector activa el componente GarbageCollector y su rutina de liberacinderecursosesejecutadaalfinaldecadapeticinalaaplicacin.

48.5 Parmetros del Collector


Lossiguientesparmetrosdeterminanelcomportamientodelcomponente: Tabla:ParmetrosdelcomponenteGarbageCollector

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

411

Parmetro probability

Descripcin Es un nmero entero positivo que determina la probabilidad que la rutina de recoleccin se ejecute. El collector se ejecuta cuando un nmeroaleatoriogeneradoentre1yprobabilitydaexactamenteensu mitad entera. Un nmero 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 compressin que se utilizara en la primera fase del colector.Esunenteroentre0paracerocompresiny9paramxima. Un nmero elevado aumenta los recursos utilizados para efectuar la operacinperoreducemsespacio.Lacompresinserealizausandoel formatoZlib(ZLIBCompressedDataFormatSpecificationversion3.3). SerequierequelaextensindePHPzlibestedisponible.Pordefectoes 5.

collectTime

Eseltiempoquedebepasarunobjetoendesusoparamarcarsecomo expirado y realizar su posterior eliminacin. Por defecto es 1800 segundos(30minutos).

48.6 API de GarbageCollector


FALTA

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

412

Parte9:ContextoyAdministracindeSesiones

49 Componente Session
49.1 Introduccin
El componente Session ofrece principalmente un mtodo orientado a objetos para la administracin de persistencia de una aplicacin Web. Con una arquitectura basada en adaptadoresesposibledemaneraflexibledefinirdiferentesbackenddealmacenamientode sesinacadaaplicacin. EsaltamenterecomendableutilizarelcomponenteSessionparaalmacenardatosdesesinen vez de utilizar la superglobal $_SESSION. Los mtodos estticos Session::set y Session::get administran la memoria de las aplicaciones de tal forma que los datos de sesin sean completamenteindependientesaotrasaplicacionesquecorranenelmismoservidorysobre elmismocliente. Esta independencia elimina posibles problemas de seguridad asociados a la utilizacin de aplicacionesconunaestructuradeautenticacinyvalidacindecredencialesidntica. En el siguiente ejemplo se visualiza como Session separa la persistencia en cada aplicacin. Tenemos2instanciasdelFrameworkeneldocumentrootdelservidorweb,laprimeraparala intranetylasegundaparalaintranet.Cadainstanciatieneunaseriedeaplicacionesasociadas acadaunajuntoconunbackenddesesindiferente. Ejemplo:EstructuradeaplicacionescondiferentesbackenddeSesin
intranet/ apps/ default/ produccion/ compras/ extranet/ apps/ default/ reservas/ informacion/ produccion/ | | | | files Database:Sqlite memcached files | memcached | files | Database:MySQL

En la aplicacin existe una variable de sesin llamada auth, esta variable controla que el usuario final est autenticado en una aplicacin. Normalmente utilizaramos esta variable usando la superglobal $_SESSION[auth]. Sin embargo el valor de esta variable estara

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

413

asociado a nuestro session id y si accedemos a otra aplicacin tambin estaramos autenticados.Silasreglasdelnegociolopermitenestoestaracorrecto,peroenlamayorade casoscadaaplicacinadministradiferentesmodelosdeseguridadyvalidacin. ElcomponenteSessionhacequelamismavariableauthseadiferenteencadaaplicacinde formaindependienteyenformatransparenteparaeldesarrollador. En el ejemplo tambin se visualiza que la aplicacin produccion existe tanto en intranet como en extranet sin embargo su finalidad es diferente. El componente Session separa la persistencia de sesin tomando en cuenta que se encuentra en diferentes instancias del Frameworkaselnombredelaaplicacinseaelmismo.

49.2 Adaptadores de Sesin


Cada aplicacin puede utilizar un backend diferente desacuerdo a las necesidades de la aplicacin. El componente Session implementa el patrn Gateway actuando como puerta de enlace al adaptador requerido cuando se efectan operaciones sobre el estado de la sesin. Unadescripcindelosbackenddisponibleses: Tabla:AdaptadoresdelcomponenteSession Adaptador Memcache Descripcin Ofrece mayor velocidad y rendimiento que los dems backend. El almacenamientoserealizaenmemoriaRAMporloqueseevitalaintensiva lectura/escrituradediscodelosdemsbackend.Suescalabilidadesmayor igualmente. Database Permite realizar el usando una tabla en una base de datos. En el caso de MySQLjuntoconNDBClusterpuedeaumentarlaescalabilidad,aunqueesto debe ser evaluado de acuerdo a las reglas del negocio. Este tipo de implementacindesesionesaplicaelpatrnDatabaseSessionState. Files EselmediodealmacenamientopordefectodePHPqueutilizaelsistemade archivos para guardar los datos de sesin. Optimizaciones al sistema de archivopodranmejorarelrendimiento. LouderCache Utiliza el Louder Cache como backend para almacenar los datos de sesin. De esta forma se puede conseguir un sistema escalable y de alta disponibilidadparaalmacenarelestadodesesindeunaaplicacin.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

414

LosadaptadoresdesesinimplementanlainterfaceSessionInterface:
interface SessionInterface { public function getSaveHandler(); public function initialize(); }

49.2.1 AdaptadordeSesinMemcache Para activar el adaptador Memcache se debe agregar a la seccin application del archivo config.inidelaaplicacinlosiguiente: Ejemplo:EstablecereladaptadordesesinaMemcached
sessionAdapter = memcache sessionSavePath = "tcp://127.0.0.1:11211?persistent=1&weight=2&timeout=2"

49.2.2 AdaptadordeSesinDatabase Parausareladaptadordesesionesusandounatabladelabasesdedatossedebeagregarala seccinapplicationdelarchivoconfig.inidelaaplicacinlosiguiente: Ejemplo:EstablecereladaptadordesesinaDatabase


sessionAdapter = database sessionSavePath = "mysql:host=127.0.0.1;username=root;password=mypass;name=mydb"

Enlabasededatosseleccionadasedebecrearlasiguientetabla:
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 sesin no utilizados es implementado en este adaptador para los datos de sesin que hayan expirado. Sesiones que tengan ms de 24 horas de expiracin serneliminadasdelatablasession_data. 49.2.3 AdaptadordesesinFiles Es el adaptador por defecto y no es necesario realizar configuraciones adicionales para establecerlo.Larutadealmacenamientodearchivospuedemodificarsebuscandoaprovechar optimizacionesdelsistemadearchivos.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

415

Ejemplo:Establecereladaptadordesesinafiles
sessionAdapter = files sessionSavePath = "/path/to/session/data"

Sistemas de archivos como ReiserFS en Linux pueden mejorar el rendimiento ya que estos administranmejorarchivospequeos. 49.2.4 AdaptadordesesinLouderCache ParausaresteadaptadorLouderCachedebeestarinstaladocomounalibreraenlainstancia delframework.

49.3 Comportamiento de Sesiones


Las sesiones Kumbia Enterprise Framework son inicializadas en un managed environment (entornoadministrado)conloqueelpuntodeinicializacinyfinalizacindesesionesnodebe ser un problema para el desarrollador. Los datos en el entorno de persistencia son serializados/deserializadosexactamentecuandoesnecesario,unmalmanejodeestopodra generar perdida de datos si se realizase manualmente, especialmente cuando se almacenan objetos se trabaja con Web services. El Framework implementa el patrn Server Session Stateparaconceptualmenteadministrarelestadodepersistenciadelaaplicacin. Las sesiones se inicializan justo despus de cargar la clase controladora, cualquier procedimientoprevioaestoendondeseinteracteconsesionespuedeproducirresultados confusos. Los plugins de controlador que implementen el mtodo Plugin::beforeDispatchLoop()sonunejemplodeesto.

49.4 Consideraciones de Seguridad


LassesionessonunblancodeataquesinformticosentreellosestanlosHijackingFixation. Una aplicacin Web mal diseada 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 configuracin de php session.use_cookies = 1 y ademssession.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 valoresdesesinvayanaserutilizadosparainsertardatosenlabasededatos:

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

416

Ejemplo:Filtrarlosdatosdesessionparaevitarhijacking
<?php class CustomerController extends ApplicationController { public function beforeFilter(){ $valor = Session::get(valor, int); $nombre = Session::get(nombre, alpha); } }

49.5 Variables de sesin


ElcomponenteSessionpermitelaadministracindevariablesdesesinquecorrespondena valoressimplesquesereferenciamedianteunndicenombreclave. Lasvariablesdesesinsealmacenanenespaciosdememoriaindependientesporaplicacin conloqueseevitasituacionesconfusasalutilizarndicescomunesendiferentesaplicaciones queseusenenunamismocontextodesesinconunusuario. 49.5.1 APIdelComponenteSession publicstaticvoidinitSessionData() Inicializalosdatosdesesinesdecirlosdeserializaycreaunvectorinternolistoparausar. Usualmenteestemtodonoesinvocadaporeldesarrolladoryesimplcitamentellamadoal usargetDatasetData. publicstaticvoidstoreSessionData() Estemtodoesllamadocomounregister_shutdown_functionyserializalosdatosdesesin. publicstaticvoidsetData(string$index,mixed$value) Permiteestablecerunvalordesesin$valuemediantelallave$index. publicstaticmixedgetData(string$index) Permiteobtenerunvalordesesindeunvalorestablecidoconlallave$index. publicstaticvoidset(string$index,mixed$value) Estableceelvalordeunavariabledesesinusandolaclave$indexyelvalor$value. publicstaticmixedget(string$index)

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

417

Obtenerelvalordeunavariabledesesinusandolaclave$index. publicstaticvoidunsetData(string$index) Eliminarunvariabledesesinusandolaclave$index publicstaticmixedissetData(string$index) Permiteconocersiunavariabledesesinyaexiste.Estemtododevuelveunvalorbooleano truecuandoyaexisteyfalseenelcasocontrario. publicstaticvoidisLocked() Permitesabersilasesinestabloqueadaparaescritura. publicstaticbooleanisStarted() Permitesabersiyasehainicializadoeladaptadordesesinytodoelcontextodesesincomo tal. publicstaticvoidstartSession() Iniciaelcontextodesesinincluyendoeladaptadordeadministracindesesiones.

49.6 SessionNamespace
LaclaseSessionNamespaceesunsubcomponentedeSessionelcualpermitelautilizacinde datos de sesin de manera orientada a objetos y manteniendo la independizacin de la memoriapersistentedelasaplicacionesdesarrolladas. Al crear un Namespace se asigna un nombre nico que permite identificar el espacio de nombresentodalaaplicacin.LosidentificadoresdelosNamespacesdebenserStrings,estos notienenconflictoconlosnombresutilizadosenlosmtodosSession::setySession::get. Los objetos de sesin creados en los SessionNamespace son objetos administrables que son automticamente serializados/deserializados al guardarse en el backend de sesin. Adems, estosobjetostienenlapropiedaddepodersebloquear/desbloquearparaevitarquesuvalor seamodificadoporerrorporcomponentesdeterceros. En el siguiente ejemplo se muestra un SessionNamespace para almacenar la informacin

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

418

relevante a los datos del usuario al inicio de una sesin. Como se ilustra, no es necesario ejecutar ningn procedimiento para almacenar los cambios del Namespace, el nombre UserDataesusadoposteriormentepararecuperarlainformacindelmismo. Ejemplo:UtilizacindeSessionNamespace
<?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"); } } }

Paraobtener/establecerlosvaloresdelnamespacesedebeutilizargetters/settersimplcitos en el objeto devuelto por SessionNamespace::add SessionNamespace::get. Estos utilizan notacincamelizadaylautilizacindelmismoayudaaqueelcomportamientodeesteseael esperado. Los objetos creados son instancias de NamespaceContainer quien adems proporcionalosmtodossetValueygetValuequepermitenobtener/establecerlosvaloresdel namespacedinmicamentemedianteclaves. 49.6.1 APIdeSessionNameSpace public static NamespaceContainer add(string $namespace, string $property=null, mixed $value=null) Crea un nuevo SessionNamespace devuelve uno existe. Es posible establecer un primer valorusandoelparmetro$propertyy$value. publicstaticvoidlock(string$namespace)

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

419

BloqueaelSessionNamespaceparaevitarcambiosensusdatosinternos. publicstaticvoidunlock(string$namespace) DesbloqueaelSessionNamespacepermitiendocambiosensusdatosinternos. publicstaticNamespaceContainerget(string$namespace) ObtieneunSessionNamespaceexistente. publicstaticbooleanexists(string$namespace) IndicasiunSessionNamespaceyaexisteno. publicstaticvoidreset(string$namespace) EliminalosdatosdelSessionNamespace. publicstaticvoiddrop(string$namespace) EliminaelSessionNamespace.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

420

Parte10:HerramientasdelDesarrollador

50 Herramientas del Desarrollador


50.1 Introduccin
En este captulo se explican comportamientos de las aplicaciones desarrolladas en Kumbia Enterrprise que sirvan de gua al desarrollador. Adems se presentan componentes que ofrecen facilidades para el testeo el rapid development como la generacin de cdigo acelerandoprocesosdedesarrolloenunaaplicacindenegocios.

51 Errores y Excepciones
51.1 Introduccin
Kumbia Enteprise es un framework diseado para sostener e implementar aplicaciones crticascuyosprocesosestenexcesivamentetesteadosycuandosellevenaproduccintengan una madurez considerablemente buena. Para lograr esto se ha diseado 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 situacin conllevanaqueprocesosabortennoseejecutencorrectamentedebidoamalasprcticasde desarrollo. Estas prcticas van desde crear dinmicamente atributos en objetos, obtener valores de indices que no se han definido en arrays, pasar argumentos del tipo incorrecto a mtodosyfuncionesyhastanoimplementarelmodoE_STRICT. Cuando usted desarrolla en Kumbia Enterprise el framework le ayuda a detectar cualquier malaprcticadedesarrollosituacionesdebajacriticidadadquemuchasvecessepasanpor altoobligandoaquesetomeuncorrectivoapropiado. ElcarcterinterpretadodePHPdificultaqueseencuentrenerroresinconvenientesdetipos en una primera fase de compilacin ya que esta es inexistente. Por esto es necesario hacer testeosatodoslosprocesosenmltiplesescenariosparadetectarproblemasycorregirlos.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

421

51.2 Modo SUPER_STRICT


Todaslassituacionesdeerror,advertenciaeinformacinquesegenerandesdePHPycomo parte del proceso de validacin riguroso implementado en una aplicacin se reportan al desarrolladorenformadeexcepciones. Algunassituacionesquegeneranexcepciones: Llamadosamtodosyfuncionesenviandotiposdedatosincorrectos.Funcionesque recibanarraysinstanciaspredefinidasdeobjetos. Llamadosamtodosyfuncionesconunnmeroincorrectodeparmetros Leerunapropiedaddeunobjetoquenohayadefinidopreviamente Escribirunapropiedaddeunobjetoquenosehayadefinidopreviamente Leerunavariablequenosehayadefinido Leerunvalordeunindicedeunarrayquenosehayadefinido Leerconincludeunarchivoquenoexista Invocarunmtodoenformaestticasinqueestedefinidocomotal Realizarunadivisinporcero Realizarunaoperacincuyosoperandosnoestensoporadosporlosoperadores Deserializarunobjetoincompleto Asignarunareferenciaaunobjetoinstanciadoconnew Indexarunvectorusandounaconstantenodefinida Tratardeconvertirunobjeto(sin__toString())definidoenunvalorescalar(entero, flotante) Variablesdeconfiguracinquegeneranexcepciones(puedenserdesactivadas): Tenerregister_globalsactivado Tenersession.use_only_cookies=0 TratardeconvertirunobjetostdClassenunacadena

51.3 Capturar excepciones de gravedad leve


Algunosdesarrolladorespuedenconsiderarquedeterminadoscomponentessonsusceptibles a excepciones leves y por lo tanto estas deban controlarse adecuadamente. Las excepciones por notificaciones, advertencias y otras son generadas con un cdigo que permite

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

422

identificarlas: Ejemplo:Capturarunaexcepcindegravedadleve
<?php try { //Imprimir una variable que no existe print $value; } catch(CoreException $e){ //Si es una excepcin leve la re-lanza if($e->getMessage()!=-8){ throw $e; } }

Loscdigosdelasexcepcioneslevessonlassiguientes: Tabla:Cdigosparaidentificarexcepcionesleves Cdigo 8 2 Tipo Notificaciones Advertencias Descripcin Indica que se ha encontrado situaciones que podran indicarunposibleerrorinconsistencia. Indica situaciones que indica que no se ha podido completar una operacin esperada pero que permiten quesecontinueconlaejecucindelaaplicacin. 16 2048 AdvertenciasdePHP ModoStrict SonsituacionesdeadvertenciageneradasporPHPcomo porejemploelnopodercargarunaextensin. Genera excepciones que previenen que el cdigo no se vuelva obsoleto a travs del tiempo y sea fcilmente portableanuevasversionesdePHP. Existenotrostiposdeexcepciones,suscdigoscoincidenconlosvaloresdelasconstantes E_USER_ERROR,E_USER_WARNING,E_USER_NOTICE,E_DEPRECATEDyotras.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

423

52 Componente Debug
52.1 Introduccin
ElcomponenteDebugofrecealdesarrolladorlaposibilidadderealizarseguimientoyobtener informacinextendidaenprocesosdenegociodeformatradicionalmediantelainsercinde banderasenelcdigoparaconocerelvaloryestadoenundeterminadopuntodelmismo.Es una buena prctica realizar previamente test de unidad a los procesos de negocio para automatizarlosprocesosdetesteomejorandolaestabilidaddeestos.

52.2 Seguimiento al estado de variables


El componente Debug proporciona el mtodo add(mixed $value, $showTrace=false) que permite agregar una variable a la lista de seguimiento. Los valores de seguimiento solo se agregansielprocedimientotrazadoejecutalalneadondeseencuentraelllamado. Enelsiguienteejemploseenviaalseguimiento2valoresendeterminadospuntosdelproceso. El primero visualiza el contenido de la variable $customerId y el segundo el contenido del vector$customerAccounts; Ejemplo:RealizarunDebugaunprocesodenegocio
<?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/KumbiaEnterpriseFrameworkManualdeReferencia

424

$this->setParamToView("movements", $movements); new DebugException(Visualizar el Debug);

Siempreserequierequeselanceunaexcepcinsincapturar.ElcomponenteDebugvisualiza el seguimiento sin importar el tipo de excepcin generada. En el ejemplo no se produce ningunaexcepcinporloqueapropsitoselanzaunDebugException. EnlapantalladeexcepcionesahorasemuestraelcuadrollamadoDatosdeDebugcomoel siguiente:

Laprimeracolumnaeselordenenelqueseagregaronalseguimientolosvalores,lasegunda es el valor que se pas al mtodo add(), luego la clase y el mtodo en donde se agreg el debug,lalinea,elarchivoyporltimoeltiempotranscurridoentreunseguimientoyotro.

52.3 Visualizar la traza del seguimiento de un valor


Paraciertoscasospuedequeseaimportanteverificarquemtodosseejecutaronparaqueun datosehayaagregadoalseguimiento.Elsegundoparmetrodeaddpermitequesemuestrela trazaasociadaalvalordeseguimiento.

Los valores resaltados en rosado indican que tienen una traza asociada que aparece a continuacin en gris. En la traza es posible visualizar que parmetros recibi cada mtodo ejecutadoyenquearchivoseencuentra.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

425

52.4 Detener un proceso mediante Aserciones


En un proceso de seguimiento tambin puede ser til detener el proceso cuando se cumpla una determinada condicin. 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 excepcin de tipo DebugException deteniendo el proceso y mostrando el segumiento hasta ese punto. Todas las aserciones que no se cumplieron tambin se muestran en el seguimiento.Lasasercionesdisponiblesson: Tabla:AsercionessoportadasenDebug Mtodo assertEquals(mixed$val1,mixed$val2,$showTrace=false) assertNotEquals(mixed$val1,mixed$val2,$showTrace=false) assertNull(mixed$val1,$showTrace=false) assertArray(mixed$val1,$showTrace=false) assetTrue(mixed$val1,$showTrace=false) assertFalse(mixed$val1,$showTrace=false) Elusodelasasercioneseselsiguiente: Ejemplo:UsodeasercionesenDebug
<?php $v = 100; Debug::assertEquals(1, $v); //No se lanza la excepcin Debug::assertNotEquals(1, $v); //Se lanza la excepcin Debug::assertTrue(100==$v); //Se lanza la excepcin $employees = $this->Employees->find(status=A); Debug::assertEquals(count($employees), 10); //Se lanza si hay 10 trabajadores

Descripcin Asercinsielvalor$val1 esiguala$val2. Asercinsielvalor$val1 noesiguala$val2. Asercin si $val1 es nulo. Asercin si $val1 es un array. Asercin si $val1 es verdadero. Asercin si $val1 es falso.

Tomandoelejemploanterior,elcuadrodedebugsevisualizaeltipodeasercinylosvalores delmismo:

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

426

52.5 Establecer una accin a ejecutar al finalizar el proceso de debug


El componente Debug puede aprovechar las capacidades para programar eventos del frameworkparaefectuaroperacionesalterminarlaprocesarunadeterminadapeticin.Las accionesquesepuedenprogramarsongenerarunaexcepcinquevisualiceelcontenidodel seguimientoalmacenarlosenunarchivodelog: Paradetenerlaejecucinalfinalizarlapeticinsedebehacerelllamadoa: Ejemplo:Establecerellanzamientodeunaexcepcincuandofinalicelapeticin
Debug::setActionOnFinish(Debug::ACTION_HALT);

Utilizarunloggerparaalmacenarelseguimiento: Ejemplo:AlmacenarelseguimientousandounLogger
$logger = new Logger(File, debug.txt); Debug::setActionOnFinish(Debug::ACTION_LOG, $logger);

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

427

53 Test de Unidad
53.1 Introduccin
El testeo unitario permite a desarrolladores e ingenieros de pruebas comprobar que cada unidad de cdigo fuente en el software funciona como se espera. Se puede decir que una unidadeslapartemspequeadeunaaplicacinquesepuedeprobar. Lostestdeunidadayudanaorganizacionesagenerarmejoresaplicacionesmsrpido,loque lesgeneraventajascompetitivasimportantes. KumbiaEnterpriseFrameworkposeesupropiocomponenteparaeldesarrolloyejecucinde pruebasunitariastantoparaaplicaciones,comoparaprobarseasmismo.Losingenierosde LouderTechnologyhandesarrolladomsde1500testunitariosparaprobarenprofundidad, cadafuncionalidaddelframeworkymejorarelcomponenteensimismo.

53.2 Tests para Componentes


Componentesdeusuariopuedenserprobadosusandotestdeunidad.Estosdebenresidiren unambienteexternoparacomprobarquelamismanaturalezadesuusoeslaesperada. FALTA

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

428

54 Componente Script
54.1 Introduccin
Este componente permite la creacin de scripts tipo shell que ayuden al desarrollador a optimizartareas.FALTA

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

429

55 Apendices
55.1 Estndares de Codificacin
Enesteapendiceseexplicalosestndaresquefueronseguidosparacodificarelframeworky quedebenserseguidosporcolaboradoresyempleadosdeLouderTechnology. 55.1.1 Objetivos Autodocumentarelframeworkdetalmaneraquelascaractersticasdeautocompletadode cdigoquetienenlosIDEsdedesarrollo 55.1.2 FormatodeArchivosPHP Laetiquetadecierre?>noestpermitidaparalosarchivosquecontienensolocdigo PHP. Laindentacindelosarchivosdebehacersecon4espaciossincaracterestabuladores. LacodificacindelosarchivosdebeserUTF8 Enarchivosnocomprimidos,cadalneadebetenermximo80caracteres. En archivos comprimidos cada lnea debe tener mximo 2048 caracteres 700 construccionesdellenguaje LaterminacindelneadeberealizarseconelcarcterLF,ASCII10correspondientea archivosUnix. 55.1.3 Clases Las clases correspondientes al framework deben estar ubicadas en el directorio Los nombres de las clases deben estar camelizados y contener solo caracteres Soloespermitidounaclaseporarchivo Elnombredelarchivocorrespondealnombredelaclaseenlmslaextensin.php.

Kumbia/. alfanumricos.

55.1.4 Interfaces Las interfaces deben estar definidas en un archivo llamado Interface.php en el LasinterfacesdebentenerelsufijoInterface.

directoriodelpaquetesubpaquetedondeapliquesuuso.

55.1.5 Mtodos Los nombres de los mtodos deben tener nomenclatura camelizada, es decir no se

permitenunderscores_ysiempredebenempezarporuncarcterenminsculas.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

430

55.1.6 Variables Las variables deben tener solo caracteres alfanumricos. Cuando son propiedades La visibilidad de las propiedades de las clases debe ser principalmente privada Losnombresdelasvariablesdebenserlomshumanizadasposibledetalformaque

privadasprotegidasdeclasesdebenempezarporununderscore_. protegida. se entienda el objetivo de la variable. Variables que almacenan valores auxiliares en ciclos puedentenernombrescomo$j$i. 55.1.7 Constantes Solo est permitido definir constantes de clase. Estas deben estar en maysculas y

cadapalabradebeestarseparadaporunderscore_. 55.1.8 Boleanosyvaloresnulos Losvalorestrue,falseynullsiempredebenirenminsculas.

55.1.9 LiteralesdeCadenasdeCaracteres Lascadenasdecaracteressiempredebenirencerradasusandocomillassimples()a $cadena=Estoesunacadena; Substitucionesdevariables

menosquecontengansubstitucionesotrascomillassencillas.

55.1.10

Serecomiendaevitarlassubstitucionesdevariablesporexpresionesdeconcatenacin. FALTA

55.2 Licencia de este Documento


55.2.1 CreativeCommonsAttribution3.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 AUTHORIZEDUNDERTHISLICENSEORCOPYRIGHTLAWISPROHIBITED. BYEXERCISINGANYRIGHTSTOTHEWORKPROVIDEDHERE,YOUACCEPTANDAGREETO 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 HEREINCONSIDERATIONOFYOURACCEPTANCEOFSUCHTERMSANDCONDITIONS.

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

431

1.Definitions "Adaptation"meansaworkbasedupontheWork,orupontheWorkandotherpreexisting 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,oradaptedincludinginanyformrecognizablyderivedfromtheoriginal,except thataworkthatconstitutesaCollectionwillnotbeconsideredanAdaptationforthepurpose ofthisLicense.Fortheavoidanceofdoubt,wheretheWorkisamusicalwork,performanceor phonogram, the synchronization of the Work in timedrelation with a moving image ("synching")willbeconsideredanAdaptationforthepurposeofthisLicense. "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 arrangementoftheircontents,constituteintellectualcreations,inwhichtheWorkisincluded 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(asdefinedabove)forthepurposesofthisLicense. "Distribute" means to make available to the public the original and copies of the Work or Adaptation,asappropriate,throughsaleorothertransferofownership. "Licensor" means the individual, individuals, entity or entities that offer(s) the Work under thetermsofthisLicense. "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, pamphletandotherwriting;alecture,address,sermonorotherworkofthesamenature;a dramaticordramaticomusicalwork;achoreographicworkorentertainmentindumbshow; a musical composition with or without words; a cinematographic work to which are assimilatedworksexpressedbyaprocessanalogoustocinematography;aworkofdrawing,

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

432

painting,architecture,sculpture,engravingorlithography;aphotographicworktowhichare assimilatedworksexpressedbyaprocessanalogoustophotography;aworkofappliedart;an illustration,map,plan,sketchorthreedimensionalworkrelativetogeography,topography, architectureorscience;aperformance;abroadcast;aphonogram;acompilationofdatatothe extent it is protected as a copyrightable work; or a work performed by a variety or circus performertotheextentitisnototherwiseconsideredaliteraryorartisticwork. "You" means an individual or entity exercising rights under this License who has not previouslyviolatedtheterms of this License with respect to the Work, or who has received expresspermissionfromtheLicensortoexerciserightsunderthisLicensedespiteaprevious 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 thatmembersofthepublicmayaccesstheseWorksfromaplaceandataplaceindividually 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;tobroadcastandrebroadcasttheWorkbyanymeansincludingsigns,soundsor images. "Reproduce"meanstomakecopiesoftheWorkbyanymeansincludingwithoutlimitationby sound or visual recordings and the right of fixation and reproducing fixations of the Work, includingstorageofaprotectedperformanceorphonogramindigitalformorotherelectronic medium. 2. Fair Dealing Rights. Nothing in this License is intended to reduce, limit, or restrict any usesfreefromcopyrightorrightsarisingfromlimitationsorexceptionsthatareprovidedfor inconnectionwiththecopyrightprotectionundercopyrightlaworotherapplicablelaws. 3.LicenseGrant.SubjecttothetermsandconditionsofthisLicense,Licensorherebygrants You a worldwide, royaltyfree, nonexclusive, perpetual (for the duration of the applicable copyright)licensetoexercisetherightsintheWorkasstatedbelow: to Reproduce the Work, to incorporate the Work into one or more Collections, and to

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

433

ReproducetheWorkasincorporatedintheCollections; 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"TheoriginalworkwastranslatedfromEnglishtoSpanish,"oramodificationcould indicate"Theoriginalworkhasbeenmodified."; toDistributeandPubliclyPerformtheWorkincludingasincorporatedinCollections;and, toDistributeandPubliclyPerformAdaptations. Fortheavoidanceofdoubt: NonwaivableCompulsoryLicenseSchemes.Inthosejurisdictionsinwhichtherighttocollect 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 rightsgrantedunderthisLicense; Waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royaltiesthroughanystatutoryorcompulsorylicensingschemecanbewaived,theLicensor waives the exclusive right to collect such royalties for any exercise by You of the rights grantedunderthisLicense;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 rightsgrantedunderthisLicense. Theaboverightsmaybeexercisedinallmediaandformatswhethernowknownorhereafter devised. The above rights include the right to make such modifications as are technically necessarytoexercisetherightsinothermediaandformats.SubjecttoSection8(f),allrights notexpresslygrantedbyLicensorareherebyreserved. 4. Restrictions. The license granted in Section 3 above is expressly made subject to and limitedbythefollowingrestrictions: You may Distribute or Publicly Perform the Work only under the terms of this License. You mustincludeacopyof,ortheUniformResourceIdentifier(URI)for,thisLicensewithevery copyoftheWorkYouDistributeorPubliclyPerform.Youmaynotofferorimposeanyterms ontheWorkthatrestrictthetermsofthisLicenseortheabilityoftherecipientoftheWorkto exercise the rights granted to that recipient under the terms of the License. You may not

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

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 technologicalmeasuresontheWorkthatrestricttheabilityofarecipientoftheWorkfrom You to exercise the rights granted to that recipient under the terms of the License. This Section4(a)appliestotheWorkasincorporatedinaCollection,butthisdoesnotrequirethe Collection apart from the Work itself to be made subject to the terms of this License. If You createaCollection,uponnoticefromanyLicensorYoumust,totheextentpracticable,remove from the Collection any credit as required by Section 4(b), as requested. If You create an Adaptation,uponnoticefromanyLicensorYoumust,totheextentpracticable,removefrom theAdaptationanycreditasrequiredbySection4(b),asrequested. IfYouDistribute,orPubliclyPerformtheWorkoranyAdaptationsorCollections,Youmust, unlessarequesthasbeenmadepursuanttoSection4(a),keepintactallcopyrightnoticesfor theWorkandprovide,reasonabletothemediumormeansYouareutilizing:(i)thenameof the Original Author (or pseudonym, if applicable) if supplied, and/or if the Original Author and/orLicensordesignateanotherpartyorparties(e.g.,asponsorinstitute,publishingentity, journal)forattribution("AttributionParties")inLicensor'scopyrightnotice,termsofservice orbyotherreasonablemeans,thenameofsuchpartyorparties;(ii)thetitleoftheWorkif supplied;(iii)totheextentreasonablypracticable,theURI,ifany,thatLicensorspecifiestobe associatedwiththeWork,unlesssuchURIdoesnotrefertothecopyrightnoticeorlicensing informationfortheWork;and(iv),consistentwithSection3(b),inthecaseofanAdaptation, 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, thenaspartofthesecreditsandinamanneratleastasprominentasthecreditsfortheother contributingauthors.Fortheavoidanceofdoubt,Youmayonlyusethecreditrequiredbythis Section for the purpose of attribution in the manner set out above and, by exercising Your rightsunderthisLicense,Youmaynotimplicitlyorexplicitlyassertorimplyanyconnection 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 writtenpermissionoftheOriginalAuthor,Licensorand/orAttributionParties. ExceptasotherwiseagreedinwritingbytheLicensororasmaybeotherwisepermittedby

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

435

applicablelaw,ifYouReproduce,DistributeorPubliclyPerformtheWorkeitherbyitselforas part of any Adaptations or Collections, You must not distort, mutilate, modify or take other derogatoryactioninrelationtotheWorkwhichwouldbeprejudicialtotheOriginalAuthor'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,asappropriate,thisSection,tothefullestextentpermittedbytheapplicablenational law,toenableYoutoreasonablyexerciseYourrightunderSection3(b)ofthisLicense(right tomakeAdaptations)butnototherwise. 5.Representations,WarrantiesandDisclaimer UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS THE WORK ASIS 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,SOSUCHEXCLUSIONMAYNOTAPPLYTOYOU. 6.LimitationonLiability.EXCEPTTOTHEEXTENTREQUIREDBYAPPLICABLELAW,INNO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL,CONSEQUENTIAL,PUNITIVEOREXEMPLARYDAMAGESARISINGOUTOFTHIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITYOFSUCHDAMAGES. 7.Termination. ThisLicenseandtherightsgrantedhereunderwillterminateautomaticallyuponanybreach byYouofthetermsofthisLicense.IndividualsorentitieswhohavereceivedAdaptationsor Collections from You under this License, however, will not have their licenses terminated providedsuchindividualsorentitiesremaininfullcompliancewiththoselicenses.Sections1, 2,5,6,7,and8willsurviveanyterminationofthisLicense. 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 reservestherighttoreleasetheWorkunderdifferentlicensetermsortostopdistributingthe Workatanytime;provided,howeverthatanysuchelectionwillnotservetowithdrawthis

LouderTechnology/KumbiaEnterpriseFrameworkManualdeReferencia

436

License(oranyotherlicensethathasbeen,orisrequiredtobe,grantedunderthetermsof thisLicense),andthisLicensewillcontinueinfullforceandeffectunlessterminatedasstated above. 8.Miscellaneous EachtimeYouDistributeorPubliclyPerformtheWorkoraCollection,theLicensoroffersto therecipientalicensetotheWorkonthesametermsandconditionsasthelicensegrantedto YouunderthisLicense. EachtimeYouDistributeorPubliclyPerformanAdaptation,Licensorofferstotherecipienta licensetotheoriginalWorkonthesametermsandconditionsasthelicensegrantedtoYou underthisLicense. If any provision of this License is invalid or unenforceable under applicable law, it shall not affectthevalidityorenforceabilityoftheremainderofthetermsofthisLicense,andwithout further action by the parties to this agreement, such provision shall be reformed to the minimumextentnecessarytomakesuchprovisionvalidandenforceable. No term or provision of this License shall be deemed waived and no breach consented to unlesssuchwaiverorconsentshallbeinwritingandsignedbythepartytobechargedwith suchwaiverorconsent ThisLicenseconstitutestheentireagreementbetweenthepartieswithrespecttotheWork 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 mayappearinanycommunicationfromYou.ThisLicensemaynotbemodifiedwithoutthe mutualwrittenagreementoftheLicensorandYou. 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 UniversalCopyrightConvention(asrevisedonJuly24,1971).Theserightsandsubjectmatter takeeffectintherelevant jurisdiction in which the License terms are sought to be enforced accordingtothecorrespondingprovisionsoftheimplementationofthosetreatyprovisionsin theapplicablenationallaw.Ifthestandardsuiteofrightsgrantedunderapplicablecopyright law includes additional rights not granted under this License, such additional rights are deemedtobeincludedintheLicense;thisLicenseisnotintendedtorestrictthelicenseofany rightsunderapplicablelaw.

You might also like