Edición de «KumbiaPHP Framework Versión 1.0 Spirit»

De KumbiaPHP Framework Wiki

Advertencia: no has iniciado sesión. Tu dirección IP se hará pública si haces cualquier edición. Si inicias sesión o creas una cuenta, tus ediciones se atribuirán a tu nombre de usuario, además de otros beneficios.

Puedes deshacer la edición. Antes de deshacer la edición, comprueba la siguiente comparación para verificar que realmente es lo que quieres hacer, y entonces guarda los cambios para así efectuar la reversión.

Revisión actual Tu texto
Línea 1: Línea 1:
{{cleanupbox
 
|image=[[Archivo:Information_icon4.png|45px]]
 
|imageright=[[Archivo:Information_icon4.png|45px]]
 
|texto ='''Este manual corresponde la versión 1.0 beta 1(Desaconsejada). <br />Se recomienda ver la última versión del [https://github.com/KumbiaPHP/Documentation/tree/master/es Manual de KumbiaPHP 1.0]'''
 
}}
 
 
 
== Introducción ==
 
== Introducción ==
 
En la [https://launchpad.net/kumbia/1.0 versión 1.0](<s>antigua 0.5.1</s>) el enfoque primordial que ha considerado el [[Team_Development_KumbiaPHP_Framework|Equipo de Desarrollo]] gira en torno al rendimiento del framework a nivel de velocidad y mantenibilidad del framework en este sentido hemos desacoplado el core de kumbiaphp framework en una nueva estructura obteniendo grandes resultados, de manera que las pruebas en base a esta versión nos indica que vamos en buen camino y ademas es bastante rápida con los cambios aplicados siempre con las mejores practicas de desarrollo.
 
En la [https://launchpad.net/kumbia/1.0 versión 1.0](<s>antigua 0.5.1</s>) el enfoque primordial que ha considerado el [[Team_Development_KumbiaPHP_Framework|Equipo de Desarrollo]] gira en torno al rendimiento del framework a nivel de velocidad y mantenibilidad del framework en este sentido hemos desacoplado el core de kumbiaphp framework en una nueva estructura obteniendo grandes resultados, de manera que las pruebas en base a esta versión nos indica que vamos en buen camino y ademas es bastante rápida con los cambios aplicados siempre con las mejores practicas de desarrollo.
Línea 24: Línea 18:
 
Como se menciona al principio muchos de estos cambios son a nivel de '''core''', esto significa que haremos pocas adecuaciones para migrar nuestras aplicaciones que hayan sido desarrolladas con la [https://launchpad.net/kumbia/0.5 versión 0.5] para llevarlas hasta la [https://launchpad.net/kumbia/1.0 versión 1.0](<s>antigua 0.5.1</s>), esto con la finalidad de garantizar compatibilidad entre versiones.
 
Como se menciona al principio muchos de estos cambios son a nivel de '''core''', esto significa que haremos pocas adecuaciones para migrar nuestras aplicaciones que hayan sido desarrolladas con la [https://launchpad.net/kumbia/0.5 versión 0.5] para llevarlas hasta la [https://launchpad.net/kumbia/1.0 versión 1.0](<s>antigua 0.5.1</s>), esto con la finalidad de garantizar compatibilidad entre versiones.
 
===¿Por qué Spirit?===
 
===¿Por qué Spirit?===
"Hemos llamado Spirit a la versión 1.0 porque Spirit, [http://es.wikipedia.org/wiki/Spirit nuestro robot de Marte], tiene como características principales, fuerza y velocidad. Fuerza, porque su comunidad cada vez mas grande hace que nuestro framework KumbiaPHP avance a pasos agigantados. Velocidad, porque nuestro core team que pertenece a otro planeta, continuamente esta aplicando las ultimas técnicas y haciendo que otros framework's se queden atrás día a día. En definitiva Spirit, hace que tus aplicaciones vuelen, resulten mas atractivas y fáciles de mantener."
+
"Hemos llamado Spirit a la versión 1.0 porque Spirit, [http://es.wikipedia.org/wiki/Spirit nuestro robot de Marte], tiene como características principales, fuerza y velocidad. Fuerza, porque su comunidad cada vez mas grande hace que nuestro framework KumbiaPHP avance a pasos agigantados. Velocidad, porque nuestro core team que pertenece a otro planeta, continuamente esta aplicando las ultimas técnicas y haciendo que otros frameworks se queden atrás día a día. En definitiva Spirit, hace que tus aplicaciones vuelen, resulten mas atractivas y fáciles de mantener."
  
 
== Migración Rápida ==
 
== Migración Rápida ==
Línea 30: Línea 24:
  
 
*Con la nueva estructura de directorio migrar nuestras aplicaciones de la <s>versión [https://launchpad.net/kumbia/0.5 0.5]</s> es sumamente simple solo se ha copiar nuestra carpeta '''apps/default/''' (donde estan los controllers, models, views, etc) hacia el directorio '''app/''' de [[KumbiaPHP_Framework_Versi%C3%B3n_1.0_Spirit#Nueva_Estructura_de_Directorios |Nueva Estructura]]
 
*Con la nueva estructura de directorio migrar nuestras aplicaciones de la <s>versión [https://launchpad.net/kumbia/0.5 0.5]</s> es sumamente simple solo se ha copiar nuestra carpeta '''apps/default/''' (donde estan los controllers, models, views, etc) hacia el directorio '''app/''' de [[KumbiaPHP_Framework_Versi%C3%B3n_1.0_Spirit#Nueva_Estructura_de_Directorios |Nueva Estructura]]
 
*En el Controlador los métodos '''initialize, finalize, before_filter y after_filter''' ahora son '''protected''' por motivos de seguridad.
 
  
 
*Si has modificado el archivo '''views/index.phtml''' este fue ubicado en el directorio '''views/templates/default.phtml''', es decir que le debes  aplicar los cambios que quieras.
 
*Si has modificado el archivo '''views/index.phtml''' este fue ubicado en el directorio '''views/templates/default.phtml''', es decir que le debes  aplicar los cambios que quieras.
Línea 38: Línea 30:
  
 
*Para inicializar tu aplicación se ha de utilizar el '''config/routes.ini''' agregando una regla de enrutamiento estático, por ejemplo:
 
*Para inicializar tu aplicación se ha de utilizar el '''config/routes.ini''' agregando una regla de enrutamiento estático, por ejemplo:
  ;con esta regla cada vez que inicie la aplicación http://localhost/kumbia/ irá hacia un controlador  
+
  ;con esta regla cada vez que inicie la aplicación http://localhost/kumbia/ irá hacia un controlador admin y una acción autenticar
admin y una acción autenticar / = admin/autenticar
+
/ = admin/autenticar
  
 
Esto sustituye editar el archivo '''<s>apps/default/controllers/application.php</s>''' en su acción '''init()''', solo se ha de agregar en el '''routes.ini''' la ruta que hacemos en el método '''<s>init()</s>'''
 
Esto sustituye editar el archivo '''<s>apps/default/controllers/application.php</s>''' en su acción '''init()''', solo se ha de agregar en el '''routes.ini''' la ruta que hacemos en el método '''<s>init()</s>'''
  
 
*Si en tus modelos utilizas el atributo '''$mode''' para establecer otros datos de conexión, debes reemplazarlo por '''$database''', [[KumbiaPHP_Framework_Versión_1.0_Spirit#databases.ini| ver mas]].
 
*Si en tus modelos utilizas el atributo '''$mode''' para establecer otros datos de conexión, debes reemplazarlo por '''$database''', [[KumbiaPHP_Framework_Versión_1.0_Spirit#databases.ini| ver mas]].
*Si Cargas librerias vía boot.ini ahora se usa libs= en vez de extensions= Y también se quita el prefijo '''kumbia.'''
 
  
'''KumbiaPHP 0.5'''
+
== Nueva Estructura de Directorios ==
<pre>
+
En la versión de KumbiaPHP se incorpora la siguiente estructura de directorios, a continuación se detallan los elementos mas relevantes:
[modules]
 
extensions = kumbia.logger, kumbia.auth
 
</pre>
 
'''KumbiaPHP 1.0'''
 
<pre>
 
[modules]
 
libs = logger, auth
 
</pre>
 
 
 
== Constante en KumbiaPHP==
 
En la version 1.0 Spirit, se ha creado tres constantes cada cual cumple un objetivo especifico con el fin de brindar mayor flexibilidad al momento de manejar rutas (paths) en el framework.
 
 
 
=== APP_PATH ===
 
Constante que contiene la ruta absoluta al directorio donde se encuentra nuestra aplicación (app).
 
 
 
Ejemplo:
 
<pre>
 
echo APP_PATH; //la salida es: /var/www/kumbiaphp/app/ 
 
</pre>
 
 
 
Esta constante es posible utilizarla para incluir archivos que se encuentre bajo el arbol de directorio de la aplicación, por ejemplo imagine que quiere incluir un archivo que esta en el directio '''app/libs/test.php''' la forma de hacerlo seria.
 
  
 
<pre>
 
<pre>
  include_once APP_PATH.'libs/test.php';
+
spirit/
</pre>
+
|-- app
 
+
|   |-- application.php
'''NOTA: siempre será mejor utilizar el [[KumbiaPHP_Framework_Versión_1.0_Spirit#Carga_Selectiva.2C_Inyecci.C3.B3n_de_Dependencias_y_el_Componente_Load |Componente Load]] para incluir dependencias.'''
+
|  |-- config
 
+
|  |-- controllers
=== CORE_PATH ===
+
|   |-- extensions
Constante que contiene la ruta absoluta al directorio donde se encuentra el [[KumbiaPHP_Framework_Versión_1.0_Spirit#Explicando_dir_core.2F |core]] de KumbiaPHP.
+
|  |  |-- filters
 
+
|  |  |-- helpers
Ejemplo:
+
|  |  `-- scaffolds
<pre>
+
|   |-- index.php
echo CORE_PATH; //la salida es: /var/www/kumbiaphp/core/ 
+
|  |-- libs
</pre>
+
|  |-- locale
 
+
|  |-- model_base.php
Para incluir archivos que se encuentre bajo este arbol de directorio es el mismo procedimiento que se explico para la constante APP_PATH
+
|  |-- models
 
+
|  |-- public
'''NOTA: El core de KumbiaPHP en la version 1.0 esta totalmente desacoplado del directorio de la aplicación. [[KumbiaPHP_Framework_Versión_1.0_Spirit#Ventajas_de_esta_nueva_estructura_de_directorios|Ventajas de la Estructura de directorio]]'''
+
|  |-- temp
 
+
|  `-- views
=== PUBLIC_PATH ===
+
|      |-- errors
Constante que contiene la URL para el navegador (browser) y apunta a '''app/public/''' para enlazar imágenes, CSS, JavaScript y todo lo que sea ruta para browser.
+
|      |-- pages
 
+
|      |-- partials
Ejemplo:
+
|       `-- templates
<pre>
+
|-- core
//Genera un link que ira al controller: controller y action: action
+
|  |-- console
<a href="<?php echo PUBLIC_PATH ?>controller/action/" title="Mi Link">Mi Link</a>
+
|  |-- docs
 
 
//Enlaza una imagen que esta en public/img/imagen.jpg
 
<img src="<?php echo PUBLIC_PATH ?>img/imagen.jpg" alt="Una Imagen" />
 
 
 
//Enlaza el archivo CSS en public/css/style.css
 
<link rel="stylesheet" type="text/css" href="<?php echo PUBLIC_PATH ?>css/style.css"/>
 
</pre>
 
 
 
'''NOTA: siempre será mejor hacer uso de los helpers'''
 
 
 
== Nueva Estructura de Directorios ==
 
En la versión de KumbiaPHP se incorpora la siguiente estructura de directorios, a continuación se detallan los elementos mas relevantes:
 
 
 
<pre>
 
spirit/
 
|-- app
 
|-- application.php
 
|  |-- config
 
|  |-- controllers
 
 
|  |-- extensions
 
|  |-- extensions
|  |  |-- filters
 
 
|  |  |-- helpers
 
|  |  |-- helpers
 
|  |  `-- scaffolds
 
|  |  `-- scaffolds
|  |-- index.php
+
|  |-- kumbia
 
|  |-- libs
 
|  |-- libs
|  |-- locale
+
|  |-- tests
|  |-- model_base.php
+
|  |-- vendors
|  |-- models
 
|  |-- public
 
|  |-- temp
 
|  `-- views
 
|      |-- errors
 
|      |-- pages
 
|      |-- partials
 
|      `-- templates
 
|-- core
 
|  |-- console
 
|  |-- docs
 
|  |-- extensions
 
|  |  |-- helpers
 
|  |  `-- scaffolds
 
|  |-- kumbia
 
|  |-- libs
 
|  |-- tests
 
|  |-- vendors
 
 
|  `-- views
 
|  `-- views
 
|      |-- errors
 
|      |-- errors
Línea 173: Línea 105:
 
|views||Estan agrupados las vistas de los controladores (controllers). Por defecto se encuentran los directorios '''templates/''', '''pages/''', '''partials/''' y '''errors/'''
 
|views||Estan agrupados las vistas de los controladores (controllers). Por defecto se encuentran los directorios '''templates/''', '''pages/''', '''partials/''' y '''errors/'''
 
|-
 
|-
|extensions||En este directorio se ubican las extensiones para nuestra aplicación, una extensión te permite adicionar nuevas características que serán utilizadas e integradas a la aplicación por medio de las librerías que proporciona [http://www.kumbiaphp.com KumbiaPHP]
+
|extensions||En este directorio se ubican las extensiones para nuestra aplicación, una extensión te permite adicionar nuevas características que serán utilizadas he integradas a la aplicación por medio de las librerías que proporciona [http://www.kumbiaphp.com KumbiaPHP]
 
|-
 
|-
 
|libs||En este directorio se pueden colocar clases propias con fines específicos o librerías externas al framework (vendors). Estas para ser utilizadas en los controladores (controllers) y/o Modelos (models).
 
|libs||En este directorio se pueden colocar clases propias con fines específicos o librerías externas al framework (vendors). Estas para ser utilizadas en los controladores (controllers) y/o Modelos (models).
Línea 193: Línea 125:
 
[[Archivo:Application_kumbiaphp_framework.png|center|thumb|200px|application.php]]
 
[[Archivo:Application_kumbiaphp_framework.png|center|thumb|200px|application.php]]
  
Como se aprecia en la imagen existe una estrecha relación entre '''application.php''' y los controladores disponibles en el directorio controllers/. Esta relación se basa principalmente en que las variables y métodos creados en el '''ApplicationController''' (application.php) estarán disponibles para ser usados en cualquier controlador que tengamos en nuestra aplicación.
+
Como se aprecia en la imagen existe una estrecha relación entre '''apllication.php''' y los controladores disponibles en el directorio controllers/. Esta relación se basa principalmente en que las variables y metodos creados en el '''ApplicationController''' (application.php), estarán disponibles para ser usados en cualquier controlador que tengamos en nuestra aplicación.
  
 
En esta clase se encuentran dos métodos principales, dichos métodos se comportan como un filtro antes y después de ejecutar un controller.
 
En esta clase se encuentran dos métodos principales, dichos métodos se comportan como un filtro antes y después de ejecutar un controller.
Línea 241: Línea 173:
 
Se agregan opciones para un manejo mas apropiado de la configuración del framework, para la aplicación.
 
Se agregan opciones para un manejo mas apropiado de la configuración del framework, para la aplicación.
  
 +
*'''models_autoload''' Auto carga de modelos, útil para cuando se manejan muchos modelos no tener la necesidad de cargarlos todos en un momento, sino que se cargan se de acuerdo lo que se necesiten en el controller, todo esto se traduce en mejor rendimiento, [[KumbiaPHP_Framework_Versi%C3%B3n_1.0_Spirit#Carga_selectiva_de_modelos| leer mas]]
 
*'''metadata_lifetime''' Tiempo de vida de la metadata cacheada.
 
*'''metadata_lifetime''' Tiempo de vida de la metadata cacheada.
 
*'''database''' Base de datos a utilizar, especificada en databases.ini.
 
*'''database''' Base de datos a utilizar, especificada en databases.ini.
 
*'''production''' Indica si se encuentra en producción.
 
*'''production''' Indica si se encuentra en producción.
 
*'''cache_driver''' driver que se utilizara para el manejo de cache. KumbiaPHP cuenta con tres (3) driver: file, sqlite y memsqlite.
 
*'''cache_driver''' driver que se utilizara para el manejo de cache. KumbiaPHP cuenta con tres (3) driver: file, sqlite y memsqlite.
*'''locale''' Localización.
+
*'''locale''' Localicazión
*'''routes''' Activar enrutamiento estatico.
 
  
 
<pre>;; Configuracion de Aplicacion
 
<pre>;; Configuracion de Aplicacion
Línea 260: Línea 192:
 
; log_exceptions: muestra las excepciones en pantalla (On|off)
 
; log_exceptions: muestra las excepciones en pantalla (On|off)
 
; charset: codificacion de caracteres
 
; charset: codificacion de caracteres
 +
; models_autoload: Habilita la autocarga de modelos
 
; cache_driver: driver para la cache (file, sqlite, memsqlite)
 
; cache_driver: driver para la cache (file, sqlite, memsqlite)
 
; metadata_lifetime: Tiempo de vida de la metadata cacheada
 
; metadata_lifetime: Tiempo de vida de la metadata cacheada
; locale: Localizacion
+
; locale: Localicazion
; routes: Activar enrutamiento estatico
 
  
  
Línea 280: Línea 212:
 
log_exceptions = On
 
log_exceptions = On
 
charset = UTF-8
 
charset = UTF-8
 +
models_autoload = On
 
cache_driver = file
 
cache_driver = file
 
;metadata_lifetime = "+1 year"
 
;metadata_lifetime = "+1 year"
 
;locale = es_ES
 
;locale = es_ES
;routes = On
 
 
</pre>
 
</pre>
  
Línea 311: Línea 243:
 
host = localhost
 
host = localhost
 
username = root
 
username = root
password = 1qaz2WSX
+
password =
name = test
+
name = innogest
 
type = mysql
 
type = mysql
  
Línea 318: Línea 250:
 
host = localhost
 
host = localhost
 
username = root
 
username = root
password = 1qaz2WSX
+
password =
 
name = test
 
name = test
type = mssql
+
type = mysql
  
 
[test]
 
[test]
 
host = localhost
 
host = localhost
 
username = root
 
username = root
password = 1qaz2WSX
+
password =
 
name = test
 
name = test
type = mssql
+
type = mysql
 
</pre>
 
</pre>
  
 
== boot.ini ==
 
== boot.ini ==
En este archivo fue eliminado, ahora se recomienda la carga explicita con '''require''' o '''include''' o en su defecto aprovechar la autocarga de librerias de KumbiaPHP.
+
En este archivo es donde el usuario carga las extensiones (librerías) que trae el framework o bien alguna que deseen agregar.
O mejor usar el Load::lib('lib')
+
 
 +
Extensiones Propias de Kumbiaphp Framework
 +
*session
 +
*logger
 +
*auth
 +
*date
 +
*filter
 +
*acl
 +
*benchmark
 +
*security
 +
 
 +
Extensiones externas al framework
 +
*excel
 +
*fpdf
 +
*phpmailer
 +
*libchart
 +
 
 +
<pre>
 +
; LIBRERIAS DISPONIBLES
 +
; Librerias Propias de KumbiaPHP Framework (libraries)
 +
;  * session
 +
;  * logger
 +
;  * auth
 +
;  * date
 +
;  * filter
 +
;  * acl
 +
;  * benchmark
 +
;  * security
 +
;
 +
; Cargadores en libraries para librerias de terceros (vendors)
 +
;  * excel
 +
;  * fpdf
 +
;  * phpmailer
 +
;  * libchart
 +
 
 +
 
 +
[modules]
 +
libs = logger
 +
</pre>
  
 
== Router ==
 
== Router ==
Línea 356: Línea 326:
 
Los [http://en.wikipedia.org/wiki/Template_(file_format) Template] son un tipo de archivo pre-formateado utilizado como base para otros archivos.
 
Los [http://en.wikipedia.org/wiki/Template_(file_format) Template] son un tipo de archivo pre-formateado utilizado como base para otros archivos.
  
En este directorio esta la capa mas externa de nuestras vistas, para aclarar esta idea en esta es donde se coloca la estructura del documento XHTML (doctype, html, head, etc) en la forma como se trabaja en la <s>versión 0.5</s> esto es representado por el archivo <s>'''views/index.phtml'''</s> de esta forma no existe una flexibilidad de manera que podamos cambiar ese template, en la [https://launchpad.net/kumbia/1.0 versión 1.0] se crea un directorio '''views/templates/''' por defecto existe el archivo '''default.phtml''' pero podemos agregar cuantos se desee y poderlo cambiar desde nuestro controlador de la siguiente forma:
+
En este directorio esta la capa mas externa de nuestras vistas, para aclarar esta idea en esta es donde se coloca la estructura del documento XHTML (doctype, html, head, etc) en la forma como se trabaja en la <s>versión 0.5</s> esto es representado por el archivo <s>'''views/index.phtml'''</s> de esta forma no existe una flexibilidad de manera que podamos cambiar ese template, en la [https://launchpad.net/kumbia/1.0 versión 1.0] se crea un directorio '''views/templates/''' por defecto existe el archivo '''default.phtml''' pero podemos podemos agregar cuantos se desee y poderlo cambiar desde nuestro controlador de la siguiente forma:
  
 
<source lang=php>  
 
<source lang=php>  
Línea 391: Línea 361:
 
</source>
 
</source>
  
Como se aprecia este partials solo mostrará la fecha actual cuando sea invocado, pero como se menciono antes puede contener cualquier información para el usuario, pero aun falta hacer un llamado a este partials para que el mismo sea mostrado este llamado puede ser desde cualquier nivel del sistema de plantilla que ofrece el framework, en la'''versión 0.5''' se hacia uso de la funcion "render_partial", sin embargo con la finalidad de obtener mayor orden e intuitividad, esta función se encapsulo en la clase '''View''',  y basta con hacer en la vista (Templates, views) lo siguiente.
+
Como se aprecia este partials solo mostrará la fecha actual cuando sea invocado, pero como se menciono antes puede contener cualquier información para el usuario, pero aun falta hacer un llamado a este partials para que el mismo sea mostrado este llamado puede ser desde cualquier nivel del sistema de plantilla que ofrece el framework, en la'''versión 0.5''' se hacia uso de la funcion "render_partial", sin embargo con la finalidad de obtener myor orden e intuitividad, esta función se encapsulo en la clase '''View''',  y basta con hacer en la vista (Templates, views) lo siguiente.
  
 
<source lang=php >
 
<source lang=php >
Línea 415: Línea 385:
 
</source>  
 
</source>  
  
También es posible pasar variables al partial utilizando parámetros con nombre o utilizando como argumento un array. Si estos parámetros se pasan en forma de array soporta cualquier tipo de dato (objecto, array, etc).
+
También es posible pasar variables al partial utilizando parámetros con nombre o utilizando como argumento un array. Si estos parámetros son se pasan en forma de array soporta cualquier tipo de dato (objecto, array, etc).
  
 
<source lang=php >
 
<source lang=php >
Línea 447: Línea 417:
 
</source>
 
</source>
  
Con la intención de ofrecer mayor comodidad, KumbiaPHP también hace posible obtener una instancia de un modelo directamente haciendo uso del método '''[[KumbiaPHP_Framework_Versión_1.0_Spirit#Load::model.28.24model.29 |Load::model($modelo)]]'''.
+
KumbiaPHP con la intención de ofrecer mayor comodidad tambien posible obtener una instancia de un modelo directamente haciendo uso del método '''[[KumbiaPHP_Framework_Versión_1.0_Spirit#Load::model.28.24model.29 |Load::model($modelo)]]'''.
  
 
<source lang=php >
 
<source lang=php >
Línea 458: Línea 428:
 
Este método de la clase '''View''' viene a remplazar la función '''content()''', esta se utiliza para indicar donde [http://www.kumbiaphp.com KumbiaPHP] debe renderizar (mostrar) el contenido almacenado en el buffer de salida, es decir el próximo nivel de la vista.
 
Este método de la clase '''View''' viene a remplazar la función '''content()''', esta se utiliza para indicar donde [http://www.kumbiaphp.com KumbiaPHP] debe renderizar (mostrar) el contenido almacenado en el buffer de salida, es decir el próximo nivel de la vista.
  
Su uso para las vistas de las acciones esta íntimamente ligado a los '''echo''' o '''print''' que efectué el usuario, asimismo determina el lugar donde se mostrarán los mensajes '''Flash''' provenientes de ActiveRecord o los propios. Ejemplo:
+
Su uso para las vistas de las acciones esta íntimamente ligado a los '''echo''' o '''print''' que efectué el usuario, asimismo determina el lugar donde se mostrarán los los mensajes '''Flash''' provenientes de ActiveRecord o los propios. Ejemplo:
  
 
<source lang=php >
 
<source lang=php >
Línea 481: Línea 451:
  
 
===View::helpers($helper)===
 
===View::helpers($helper)===
Un '''''helpers''''' representa una ayuda a nivel de las vistas (view), esto quiere decir siendo consistente con el m'''V'''c solo deben ser utilizados en las vistas.
+
Un '''''helpers''''' representa una ayuda a nivel de las vistas (view), esto quiere decir siendo consistente con el m'''V'''c solo deben ser utilizados en las vitas.
  
 
Los '''''helpers''''' estan ubicados en '''miapp/extensions/helpers/''', en ese directorio pueden existir tantos helpers como necesitemos [http://www.kumbiaphp.com KumbiaPHP], pero tambien pueden existir helpers en '''core/extensions/helpers/''' en estos casos el framework da prioridad a los helpers ubicados en el directorio de la aplicación, esto quiere decir que si existen dos archivos con el mismo nombre en los directorios helpers antes descrito [http://www.kumbiaphp.com KumbiaPHP] cargara el que se encuentra ubicado en el directorio de la aplicación (app).
 
Los '''''helpers''''' estan ubicados en '''miapp/extensions/helpers/''', en ese directorio pueden existir tantos helpers como necesitemos [http://www.kumbiaphp.com KumbiaPHP], pero tambien pueden existir helpers en '''core/extensions/helpers/''' en estos casos el framework da prioridad a los helpers ubicados en el directorio de la aplicación, esto quiere decir que si existen dos archivos con el mismo nombre en los directorios helpers antes descrito [http://www.kumbiaphp.com KumbiaPHP] cargara el que se encuentra ubicado en el directorio de la aplicación (app).
Línea 512: Línea 482:
  
 
     echo $code;
 
     echo $code;
 +
}
 
}
 
}
 
</source>
 
</source>
Línea 532: Línea 503:
 
</source>
 
</source>
  
=== Utilizando el método render($view, [$template]) ===
+
== Utilizando el render($view, [$template]) ==
El método '''render($view, [$template])''' se encuentra en la super clase ApplicationController es decir lo tenemos disponible solo en los controladores.
 
  
Este es un método que es muy poderoso con una utilización correcta del mismo, en la versión 1.0 lo hemos extendido para ofrecer mas flexibilidad en el manejo de las vistas, el cual nos permite de forma dinámica poder cambiar un view y un [[#views.2Ftemplates.2F | Template]] (el template es opcional) esto nos permite tener varias vistas (views) para la misma action incluso varios [[#views.2Ftemplates.2F | Template]].
+
== Logger ==
 +
La clase Logger para el manejo de [http://es.wikipedia.org/wiki/Log_(registro) Log] fue reescrita de forma estática, esto quiere decir ya no es necesario crear una instancia de la clase Logger. Esta clase dispone de una variedad de métodos para manejar distintos tipos de Log.
 +
<pre>
 +
<?php Logger::error('Mensaje de Error')?>
 +
</pre>
 +
La salida de la instrucción anterior será lo siguiente:
 +
<pre>[Thu, 05 Feb 09 15:19:39 -0500][ERROR] Mensaje de Error</pre>
 +
Por defecto los archivos log tienen el siguiente nombre '''logDDMMYYY.txt''' este nombre puede ser cambiado si así lo deseamos a través de un parámetro adicional al método.
 +
<pre>
 +
<?php Logger::error('Mensaje de Error', 'mi_log')?>
 +
</pre>
 +
Se puede apreciar el segundo parámetro ahora el archivo tendrá como nombre '''mi_log.txt'''
 +
=== Métodos de la Clase Logger ===
  
==== ¿De que sirve esto? ====
+
Logger::warning ($msg);
Esto es una de las ventajas del manejo de vistas de [http://www.kumbiaphp.com KumbiaPHP] y nos sirve para muchas cosas. Por ej: Si tenemos una aplicación web y también se quiere que esta pueda ser accedida desde dispositivos móviles (celular, PDA, etc.) no es necesario programar toda la aplicación de nuevo, sino que simplemente se cambia la vista pero lo mas importante es que el controlador sigue siendo el mismo.
 
  
==== Vamos a lo Práctico ====
+
Logger::error ($msg)
Tenemos un controlador con una acción, pero deseamos que dicha acción tenga dos vistas asociadas y poderlas cambiar según sea el caso, el cambio de vista se dará de acuerdo a un parámetro que recibirá la acción del controlador.
 
  
'''NOTA: KumbiaPHP muestra el view con el mismo nombre de la acción.'''
+
Logger::debug ($msg)
  
<source lang=php>
+
Logger::alert ($msg)
<?php
 
class BlogController extends ApplicationController
 
{
 
    public function saludo($var=null)
 
    {
 
        $this->usuario = 'Usuario';
 
    if($var == 'adios'){
 
            //cambiamos el view
 
            $this->render('adios');
 
    }
 
    }
 
}
 
</source>
 
  
Como se aprecia se cambiara el view de la acción si el parámetro es "adios" sino es pasado ningún parámetro KumbiaPHP seguirá la convención que buscara el directorio de views la vista asociada al nombre de la acción.
+
Logger::critical ($msg)
  
Ahora tenemos las vistas.
+
Logger::notice ($msg)
  
'''app/views/blog/saludo.phtml'''  (vista por defecto de la acción).
+
Logger::info ($msg)
  
<source lang=php>
+
Logger::emergence ($msg)
  <?php echo "Bienvenido $usuario" ?>
 
</source>
 
  
La vista anterior se renderizara (mostrar) cuando tengamos la siguiente URL:
+
Logger::custom ($type='CUSTOM', $msg)
  
  http://dominio.com/blog/saludo/
+
==Cache==
 +
El componente cache fué mejorado y ahora posee una implementación estática, para hacer uso de la cache es necesario tener permisos de escritura en el directorio "cache". Los métodos de la clase Cache son los siguientes:
  
'''app/views/blog/adios.phtml'''  (vista cuando existe el parámetro).
+
===Cache::get($id, $group='default')===
 +
Obtiene los datos cacheados. Los elementos cacheados pueden agruparse en grupos, lo cual permite evitar colisiones entre elementos cacheados con igual $id.
  
<source lang=php>
+
string '''$id''': identificador del elemento cacheado<br>
  <?php echo "Adios $usuario" ?>
+
string '''$group''': grupo al cual pertenece el elemento cacheado (por defecto "default")
</source>
 
  
La vista anterior se renderizara (mostrar) cuando tengamos la siguiente URL:
+
<pre>
 +
$data = Cache::get('data');
 +
</pre>
  
  http://dominio.com/blog/saludo/adios/
+
===Cache::save($value, $lifetime=null, $id=false, $group='default')===
 +
Guarda los datos a cachear.
  
===== Cambiando el Template con método render($view, $template) =====
+
mixed '''$value''': valor a cachear (automaticamente es serializado antes de guardar)<br>
Pero también es posible cambiar el [[#views.2Ftemplates.2F | Template]] veamos la misma acción pero ahora cambiara el template.
+
string '''$lifetime''': tiempo de vida de los datos (formato de [http://fr.php.net/manual/es/function.strtotime.php strtotime]), si es null, los datos no expiran nunca.<br>
 +
string '''$id''': identificador del elemento a almacenar, si no se especifica, se toma el id y grupo del ultimo get efectuado<br>
 +
string '''$group''': grupo al cual pertenece
  
 
<source lang=php>
 
<source lang=php>
<?php
+
<?php if($data = Cache::get('data')): ?>
class BlogController extends ApplicationController
+
    <?php echo $data ?>
{
+
<?php else: ?>
     public function saludo($var=null)
+
     <?php ob_start() ?>
     {
+
     Hola
         $this->usuario = 'Usuario';
+
    <?php
    if($var == 'adios'){
+
         $data = ob_get_contents();
            //cambiamos el view y el template
+
        Cache::save($data, '+21 days');
            $this->render('adios', 'otro_template');
+
        ob_end_flush();      
    }
+
     ?>
     }
+
<?php endif; ?>   
}
 
 
</source>
 
</source>
  
Ahora mostramos un nuevo [[#views.2Ftemplates.2F | Template]] llamado '''otro_template''' para cuando cambiamos el views a '''adios'''.
 
 
===== Ahora sin Template render($view, null) =====
 
Ahora indicamos que no deseamos mostrar el [[#views.2Ftemplates.2F | Template]] veamos la misma acción pero sin el template.
 
  
 
<source lang=php>
 
<source lang=php>
<?php
+
Cache::save('hola', null, 'data');
class BlogController extends ApplicationController
+
$data = Cache::get('hola');
{
 
    public function saludo($var=null)
 
    {
 
        $this->usuario = 'Usuario';
 
    if($var == 'adios'){
 
            //cambiamos el view y sin template
 
            $this->render('adios', null);
 
    }
 
    }
 
}
 
 
</source>
 
</source>
  
Cuando vayan a http://dominio.com/blog/saludo/adios/ KumbiaPHP cargara solamente el view adios.phtml sin template ya que así lo indicamos.
+
Nota: el grupo "kumbia.*" esta reservado para el uso exclusivo de KumbiaPHP.
 +
 
 +
===Cache::start($lifetime, $id, $group='default')===
 +
Cachea capturando el buffer de salida, se debe utilizar en conjunto a "Cache::end()" para terminar la captura, si el elemento esta cacheado entonces lo retorna.
  
===== Ahora sin view render(null, [$template]) =====
+
string '''$lifetime''': tiempo de vida de los datos (formato de strtotime), si es null, los datos no expiran nunca.<br>
Ahora indicamos que no deseamos mostrar el View de la acción, veamos la misma acción pero sin el view.
+
string '''$id''': identificador del elemento a almacenar, si no se especifica, se toma el id y grupo del ultimo get efectuado<br>
 +
string '''$group''': grupo al cual pertenece
  
 
<source lang=php>
 
<source lang=php>
<?php
+
<?php if($data = Cache::start('+1 day','data')): ?>
class BlogController extends ApplicationController
+
     <?php echo $data ?>
{
+
<?php else: ?>
    public function saludo($var=null)
+
    Hola
     {
+
    <?php Cache::end()?>
        $this->usuario = 'Usuario';
+
<?php endif; ?>   
    if($var == 'adios'){
+
</source>
            //Mostrando un mensaje desde la acción
 
            Flash::notice('Adios '.$this->usuario);
 
  
            //sin el view y con el template por defecto
+
===Cache::end()===
            $this->render(null);
+
Guarda los datos en la cache tomados del buffer de salida.
    }
+
 
    }
+
===Cache::clean($group=false)===
}
+
Limpia la cache. Si no se indica grupo limpia toda la cache.
 +
 
 +
<source lang=php>
 +
Cache::clean('default');
 
</source>
 
</source>
  
===== Ahora sin view y sin template render(null, null) =====
+
===Cache::remove($id, $group='default')===
Ahora indicamos que no deseamos mostrar el View de la acción y el Template, veamos la misma acción pero sin el view y sin template.
+
Elimina un elemento específico de la cache
  
 
<source lang=php>
 
<source lang=php>
<?php
+
Cache::remove('data');
class BlogController extends ApplicationController
 
{
 
    public function saludo($var=null)
 
    {
 
        $this->usuario = 'Usuario';
 
    if($var == 'adios'){
 
            //KumbiaPHP no mostrará nada
 
            $this->render(null, null);
 
           
 
            //enrutamos a otro controller
 
            return Router::route_to('controller: otro_controller');
 
    }
 
    }
 
}
 
 
</source>
 
</source>
  
== Logger ==
+
 
La clase Logger para el manejo de [http://es.wikipedia.org/wiki/Log_(registro) Log] fue reescrita de forma estática, esto quiere decir ya no es necesario crear una instancia de la clase Logger. Esta clase dispone de una variedad de métodos para manejar distintos tipos de Log.
+
 
 +
==Cacheo automático de views y templates==
 +
Ahora el cacheo de views y templates desde el controller se hará utilizando el método '''cache()'''.
 +
 
 +
=== cache($time, $type='view') ===
 +
Para cachear una vista desde la acción:
 
<pre>
 
<pre>
<?php Logger::error('Mensaje de Error')?>
+
$this->cache('+1 day');
 
</pre>
 
</pre>
La salida de la instrucción anterior será lo siguiente:
+
 
<pre>[Thu, 05 Feb 09 15:19:39 -0500][ERROR] Mensaje de Error</pre>
+
Para cachear un template:
Por defecto los archivos log tienen el siguiente nombre '''logDDMMYYY.txt''' este nombre puede ser cambiado si así lo deseamos a través de un parámetro adicional al método.
 
 
<pre>
 
<pre>
<?php Logger::error('Mensaje de Error', 'mi_log')?>
+
$this->cache('+1 day', 'template');
 
</pre>
 
</pre>
Se puede apreciar el segundo parámetro ahora el archivo tendrá como nombre '''mi_log.txt'''
 
=== Métodos de la Clase Logger ===
 
  
Logger::warning ($msg);
+
Si no desea cachear:
 +
<pre>
 +
$this->cache(false);
 +
</pre>
  
Logger::error ($msg)
+
==ActiveRecord==
 +
Ahora se ha definido una forma concreta para el paso de parámetros en los validadores y asimismo se adicionaron parámetros para personalizar los mensajes de error.
  
Logger::debug ($msg)
+
<source lang=php>
 +
class Model extends ActiveRecord
 +
{
 +
    public function initialize()
 +
    {
 +
        //valida que la cedula sea unica
 +
        $this->validates_uniqueness_of('cedula', 'message: La cedula ya existe');
 +
    }
 +
}
 +
</source>
  
Logger::alert ($msg)
+
NOTA: El método '''initialize''' hace las veces de constructor y se ejecuta siempre por eso nuestros validadores deberían estar alli...
  
Logger::critical ($msg)
+
===validates_uniqueness_of($field, $params=array())===
 +
Valida que el campo sea único
  
Logger::notice ($msg)
+
string '''$field''': campo a validar<br>
 +
array '''$params''': array de parametros con nombre
  
Logger::info ($msg)
+
Parametros con nombre:<br>
 +
message: mensaje a mostrar<br>
 +
field: nombre del campo
  
Logger::emergence ($msg)
+
<source lang=php>
 +
...
 +
$this->validates_uniqueness_of('cedula', 'message: La cedula ya existe')
 +
$this->validates_uniqueness_of('cedula', array('message'=>'La cedula ya existe'))
 +
...
 +
</source>
  
Logger::custom ($type='CUSTOM', $msg)
+
===validates_date_in($field, $params=array())===
 +
Valida que el campo sea tipo fecha
  
==Cache==
+
string '''$field''': campo a validar<br>
El componente cache fué mejorado y ahora posee una implementación utilizando los patrones de diseño factory y singleton, para hacer uso de la cache es necesario tener permisos de escritura en el directorio "cache" (para el caso de los manejadores "sqlite" y "file").
+
array '''$params''': array de parametros con nombre
  
Puedes obtener un driver de Cache utilizando el metodo '''driver''' que te proporciona la clase Cache.
+
Parametros con nombre:<br>
 
+
message: mensaje a mostrar<br>
===Cache::driver($driver=null)===
+
field: nombre del campo
Este metodo permite obtener un manejador de cache específico, si no se indica, se obtiene el manejador de cache por defecto indicado en el '''config.ini'''.
 
 
 
Ejemplos:
 
  
 
<source lang=php>
 
<source lang=php>
// cache por defecto
+
...
$data = Cache::driver()->get('data');
+
$this->validates_date_in('fecha', 'message: Fecha invalida')
 
+
$this->validates_date_in('fecha', array('message'=>'Fecha invalida'))
// manejador para memcache
+
...
$data_memcache = Cache::driver('memcache')->get('data');
 
 
 
// manejador para cache con APC
 
$data_apc = Cache::driver('APC')->get('data');
 
 
</source>
 
</source>
  
  
Todos los manejadores de cache comparten métodos comunes indicados através de la clase abstracta '''Cache''' he implementados especificamente en cada manejador, los metodos de los manejadores de cache son los siguientes:
+
===validates_presence_of($field, $params=array())===
 +
Valida que el campo no sea nulo
  
===get($id, $group='default')===
+
string '''$field''': campo a validar<br>
Obtiene los datos cacheados. Los elementos cacheados pueden agruparse en grupos, lo cual permite evitar colisiones entre elementos cacheados con igual $id.
+
array '''$params''': array de parametros con nombre
  
string '''$id''': identificador del elemento cacheado<br>
+
Parametros con nombre:<br>
string '''$group''': grupo al cual pertenece el elemento cacheado (por defecto "default")
+
message: mensaje a mostrar<br>
 +
field: nombre del campo
  
 
<source lang=php>
 
<source lang=php>
$data = Cache::driver()->get('data');
+
...
 +
$this->validates_presence_of('fecha_opt', 'field: Fecha')
 +
...
 
</source>
 
</source>
  
===save($value, $lifetime=null, $id=false, $group='default')===
 
Guarda los datos a cachear.
 
  
mixed '''$value''': valor a cachear (automaticamente es serializado antes de guardar)<br>
+
===validates_length_of($field, $max, $min=0, $params=array())===
string '''$lifetime''': tiempo de vida de los datos (formato de [http://es2.php.net/manual/en/function.strtotime.php strtotime]), si es null, los datos no expiran nunca.<br>
+
Valida que el campo no sea nulo
string '''$id''': identificador del elemento a almacenar, si no se especifica, se toma el id y grupo del ultimo get efectuado<br>
 
string '''$group''': grupo al cual pertenece
 
  
<source lang=php>
+
string '''$field''': campo a validar<br>
<?php if($data = Cache::driver()->get('data')): ?>
+
int '''$max''': valor maximo<br>
    <?php echo $data ?>
+
int '''$min''': valor minimo<br>
<?php else: ?>
+
array '''$params''': array de parametros con nombre
    <?php ob_start() ?>
 
    Hola
 
    <?php
 
        $data = ob_get_contents();
 
        Cache::driver()->save($data, '+21 days');
 
        ob_end_flush();       
 
    ?>
 
<?php endif; ?>   
 
</source>
 
  
 +
Parametros con nombre:<br>
 +
too_long: mensaje a mostrar cuando sea muy largo<br>
 +
too_short: mensaje a mostrar cuando sea muy corto<br>
 +
field: nombre del campo
  
 
<source lang=php>
 
<source lang=php>
Cache::driver()->save('hola', null, 'data');
+
...
$data = Cache::driver()->get('data');
+
$this->validates_length_of('nombre', '25')
</source>
+
$this->validates_length_of('nombre', '25', 0,'too_long: Nombre muy largo')
 
+
$this->validates_length_of('nombre', '25', 0,array('too_long'=>'Nombre muy largo'))
Nota: el grupo "kumbia.*" esta reservado para el uso exclusivo de KumbiaPHP.
+
...
 +
</source>
 +
 
 +
 
 +
===validates_inclusion_in($field, $list, $params=array())===
 +
Valida que el campo este incluido en los valores de la lista
  
===start($lifetime, $id, $group='default')===
+
string '''$field''': campo a validar<br>
Cachea capturando el buffer de salida, se debe utilizar en conjunto a "end()" para terminar la captura, si el elemento esta cacheado entonces lo retorna.
+
array '''$list''': lista de elementos<br>
 +
array '''$params''': array de parametros con nombre
  
string '''$lifetime''': tiempo de vida de los datos (formato de strtotime), si es null, los datos no expiran nunca.<br>
+
Parametros con nombre:<br>
string '''$id''': identificador del elemento a almacenar, si no se especifica, se toma el id y grupo del ultimo get efectuado<br>
+
message: mensaje a mostrar<br>
string '''$group''': grupo al cual pertenece
+
field: nombre del campo
  
 
<source lang=php>
 
<source lang=php>
<?php if($data = Cache::driver()->start('+1 day','data')): ?>
+
...
    <?php echo $data ?>
+
$this->validates_inclusion_in('seleccion', array('a', 'b'))
<?php else: ?>
+
...
    Hola
 
    <?php Cache::driver()->end()?>
 
<?php endif; ?>   
 
 
</source>
 
</source>
  
===end()===
 
Guarda los datos en la cache tomados del buffer de salida.
 
  
===clean($group=false)===
+
===validates_exclusion_of($field, $list, $params=array())===
Limpia la cache. Si no se indica grupo limpia toda la cache.
+
Valida que el campo no este incluido en los valores de la lista
  
<source lang=php>
+
string '''$field''': campo a validar<br>
Cache::driver()->clean('default');
+
array '''$list''': lista de elementos<br>
</source>
+
array '''$params''': array de parametros con nombre
  
===remove($id, $group='default')===
+
Parametros con nombre:<br>
Elimina un elemento específico de la cache
+
message: mensaje a mostrar<br>
 +
field: nombre del campo
  
 
<source lang=php>
 
<source lang=php>
Cache::driver()->remove('data');
+
...
 +
$this->validates_exclusion_of('seleccion', array('a', 'b'))
 +
...
 
</source>
 
</source>
  
==Cacheo automático de views y templates==
+
===validates_format_of($field, $pattern, $params=array())===
Ahora el cacheo de views y templates desde el controller se hará utilizando el método '''cache()'''.
+
Valida que el campo coincida con el patron indicado
 +
 
 +
string '''$field''': campo a validar<br>
 +
array '''$pattern''': expresion regular compatible con perl<br>
 +
array '''$params''': array de parametros con nombre
  
=== cache($time, $type='view') ===
+
Parametros con nombre:<br>
Para cachear una vista desde la acción:
+
message: mensaje a mostrar<br>
<pre>
+
field: nombre del campo
$this->cache('+1 day');
 
</pre>
 
  
Para cachear un template:
+
<source lang=php>
<pre>
+
...
$this->cache('+1 day', 'template');
+
$this->validates_format_of('seleccion', '/^\d{3}[A-Z]/')
</pre>
+
...
 +
</source>
  
Si no desea cachear:
+
===validates_format_of($field, $pattern, $params=array())===
<pre>
+
Valida que el campo coincida con el patron indicado
$this->cache(false);
 
</pre>
 
  
==ActiveRecord==
+
string '''$field''': campo a validar<br>
Ahora se ha definido una forma concreta para el paso de parámetros en los validadores y asimismo se adicionaron parámetros para personalizar los mensajes de error.
+
array '''$pattern''': expresion regular compatible con perl<br>
 +
array '''$params''': array de parametros con nombre
 +
 
 +
Parametros con nombre:<br>
 +
message: mensaje a mostrar<br>
 +
field: nombre del campo
  
 
<source lang=php>
 
<source lang=php>
class Model extends ActiveRecord
+
...
{
+
$this->validates_format_of('seleccion', '/^\d{3}[A-Z]/')
    public function initialize()
+
...
    {
 
        //valida que la cedula sea unica
 
        $this->validates_uniqueness_of('cedula', 'message: La cedula ya existe');
 
    }
 
}
 
 
</source>
 
</source>
  
NOTA: El método '''initialize''' hace las veces de constructor y se ejecuta siempre por eso nuestros validadores deberían estar alli...
 
  
===validates_uniqueness_of($field, $params=array())===
+
===validates_numericality_of($field, $params=array())===
Valida que el campo sea único
+
Valida que el campo sea numerico
  
 
string '''$field''': campo a validar<br>
 
string '''$field''': campo a validar<br>
Línea 838: Línea 802:
 
Parametros con nombre:<br>
 
Parametros con nombre:<br>
 
message: mensaje a mostrar<br>
 
message: mensaje a mostrar<br>
field: nombre del campo (muestra un mensaje con el valor del campo)
+
field: nombre del campo
 
 
'''Nota:''' Solo un parametro con nombre se muestra a la vez, teniendo prioridad el parametro con nombre '''message'''.
 
  
 
<source lang=php>
 
<source lang=php>
 
...
 
...
$this->validates_uniqueness_of('cedula', 'message: La cedula ya existe')
+
$this->validates_numericality_of('cedula')
$this->validates_uniqueness_of('cedula', array('message'=>'La cedula ya existe'))
 
 
...
 
...
 
</source>
 
</source>
  
o
 
  
<source lang=php>
+
===validates_email_in($field, $params=array())===
...
+
Valida que el campo sea un correo electronico
$this->validates_uniqueness_of('cedula', 'field: cedula')
 
$this->validates_uniqueness_of('cedula', array('field'=>'cedula'))
 
...
 
</source>
 
 
 
===validates_date_in($field, $params=array())===
 
Valida que el campo sea tipo fecha
 
  
 
string '''$field''': campo a validar<br>
 
string '''$field''': campo a validar<br>
Línea 870: Línea 823:
 
<source lang=php>
 
<source lang=php>
 
...
 
...
$this->validates_date_in('fecha', 'message: Fecha invalida')
+
$this->validates_email_in('email')
$this->validates_date_in('fecha', array('message'=>'Fecha invalida'))
 
 
...
 
...
 
</source>
 
</source>
  
 +
==Modos de una Aplicación==
 +
'''KumbiaPHP''' ofrece dos modos de ejecución de una aplicación el cual es indicado en el '''config.ini''', estos se describen a continuación:
  
===validates_presence_of($field, $params=array())===
+
===Production===
Valida que el campo no sea nulo
+
Indicando en el config.ini '''"production = On"''', se entra en el modo de producción, en este la cache de kumbiaphp framework esta activada y se cachea información necesaria para agilizar la carga de la aplicación tal como la metadata de la base datos (información de tablas y campos), asimismo las vistas que el usuario desee cachear.
  
string '''$field''': campo a validar<br>
+
===Development===
array '''$params''': array de parametros con nombre
+
Indicando en el config.ini '''"production = Off"''', se entra en el modo de desarrollo, en este la cache de [http://www.kumbiaphp.com KumbiaPHP] esta desactivada y cualquier cambio que se haga en los campos y tablas de la base de datos (adición de campos, etc), vistas de la aplicación que se cacheen, surtirán efecto inmediatamente.
  
Parametros con nombre:<br>
+
La para utilizar manualmente la cache de [http://www.kumbiaphp.com KumbiaPHP] debes cargarla explicitamente indicándola en el boot.ini o utilizando el componente '''Load'''.
message: mensaje a mostrar<br>
 
field: nombre del campo
 
  
 
<source lang=php>
 
<source lang=php>
...
+
Load::lib('cache');
$this->validates_presence_of('fecha_opt', 'field: Fecha')
+
</source>
...
 
</source>
 
  
 +
'''Cuando se cambia de modo, es necesario limpiar la cache que [http://www.kumbiaphp.com KumbiaPHP] ha creado para que se pueda renovar los nuevos metadatos y vistas, esto se hace simplemente eliminando el contenido del directorio de cache para la aplicación.'''
  
===validates_length_of($field, $max, $min=0, $params=array())===
+
== Carga selectiva de modelos ==
Valida el tamaño mínimo y máximo de caracteres permitidos en el campo
+
En la [https://launchpad.net/kumbia/0.5.1 versión 1.0](<s>antigua 0.5.1</s>) se puede cargar solo los modelos que el controlador requiera, de esa manera se optimiza los procesos de la aplicación y consume menos recursos. Para utilizar la carga selectiva, es conveniente deshabilitar la autocarga de modelos en el config.ini con '''"models_autoload = Off"'''.
  
string '''$field''': campo a validar<br>
+
==== Load::models($model) ====
int '''$max''': valor maximo<br>
+
Carga los modelos, se pueden cargar varios de manera simultánea indicándolos como argumentos múltiples del método o mediante un array. Asimismo se pueden cargar directorios completos de modelos.
int '''$min''': valor minimo<br>
 
array '''$params''': array de parametros con nombre
 
  
Parametros con nombre:<br>
+
Si la carga se efectúa en el controlador, automaticamente una instancia del modelo es cargada en un atributo del controlador correspondiente al nombre del modelo en notación camelcase.
too_long: mensaje a mostrar cuando sea muy largo<br>
 
too_short: mensaje a mostrar cuando sea muy corto<br>
 
field: nombre del campo
 
  
<source lang=php>
+
''NOTA: El parámetro '''$model''' puede ser un directorio y/o archivo, en el caso de ser el archivo debe ser igual al nombre del mismo.''  
...
 
$this->validates_length_of('nombre', '25')
 
$this->validates_length_of('nombre', '25', 0,'too_long: Nombre muy largo')
 
$this->validates_length_of('nombre', '25', 0,array('too_long'=>'Nombre muy largo'))
 
...
 
</source>
 
  
===validates_inclusion_in($field, $list, $params=array())===
+
<source lang=php >
Valida que el campo este incluido en los valores de la lista
+
class UsuarioController extends ApplicationController
 +
{
 +
  public function index()
 +
  {
 +
    //Se cargan los modelos Usuario y DatosPersonales
 +
    //usuario.php y datos_personales.php
 +
    Load::models('usuario', 'datos_personales');
 +
  }
 +
}
 +
</source>
  
string '''$field''': campo a validar<br>
+
Asimismo se puede indicar con el atributo de controlador $models y estos serán cargados en cada acción.
array '''$list''': lista de elementos<br>
 
array '''$params''': array de parametros con nombre
 
  
Parametros con nombre:<br>
+
<source lang=php >
message: mensaje a mostrar<br>
+
class UsuarioController extends ApplicationController {
field: nombre del campo
 
  
<source lang=php>
+
  //Se cargan los modelos Usuario y DatosPersonales
...
+
  public $models = array('usuario', 'datos_personales');
$this->validates_inclusion_in('seleccion', array('a', 'b'))
+
 
...
+
  public function index()
 +
  {}
 +
}
 
</source>
 
</source>
  
 +
Cargando un directorio de modelos
  
===validates_exclusion_of($field, $list, $params=array())===
+
<source lang=php >
Valida que el campo no este incluido en los valores de la lista
+
class UsuarioController extends ApplicationController {
 +
 
 +
  public function index()
 +
  {
 +
    /** se cargan los modelos en:
 +
    * mi_app/models/dir/*
 +
    * mi_app/models/dir2/model1.php
 +
    * mi_app/models/model2.php
 +
    */
 +
    Load::models('dir', 'dir2/model1', 'model2')
 +
  }
  
string '''$field''': campo a validar<br>
+
}
array '''$list''': lista de elementos<br>
+
</source>
array '''$params''': array de parametros con nombre
 
  
Parametros con nombre:<br>
+
==== Load::model($model) ====
message: mensaje a mostrar<br>
+
Obtiene una instancia del modelo indicado, esto permite hacer uso de modelos en cualquier lugar de la aplicación de manera intuitiva.
field: nombre del campo
 
  
<source lang=php>
+
'''NOTA: el nombre del modelo que recibe como parámetro este método debe ser pasado en notación smallcase'''
...
 
$this->validates_exclusion_of('seleccion', array('a', 'b'))
 
...
 
</source>
 
  
===validates_format_of($field, $pattern, $params=array())===
+
<source lang=php >
Valida que el campo coincida con el patron indicado
+
/**
 +
* Construye una lista desplegable para países
 +
**/
 +
function pais_select($id, $value=null) {
 +
    //carga el modelo models/pais.php
 +
    $Pais = Load::model('pais');
  
string '''$field''': campo a validar<br>
+
    $code = "<select name=\"$id\" id=\"$id\">";
array '''$pattern''': expresion regular compatible con perl<br>
+
    foreach($Pais->find() as $pais) {
array '''$params''': array de parametros con nombre
+
        $code .= "<option value=\"$pais->id\"";
 +
        if($pais->id == $value) {
 +
            $code .= ' selected="selected"';
 +
        }
 +
        $nombre = htmlspecialchars($pais->nombre);
 +
        $code .= ">$nombre</option>";
 +
    }
 +
    $code .= '</select>';
  
Parametros con nombre:<br>
+
    return $code;
message: mensaje a mostrar<br>
+
}
field: nombre del campo
+
</source>
 +
 
 +
Uso avanzado...
  
<source lang=php>
+
<source lang=php >
 
...
 
...
$this->validates_format_of('seleccion', '/^\d{3}[A-Z]/')
+
    //busca el país con ID 1
...
+
    Load::model('pais')->find(1);
</source>
 
  
 +
    //carga el modelo ubicado en models/dir/user.php
 +
    Load::model('dir/user')->find();
  
 +
    //carga el modelo ubicado en models/user_group.php
 +
    Load::model('user_group')->find();
  
===validates_numericality_of($field, $params=array())===
 
Valida que el campo sea numerico
 
 
string '''$field''': campo a validar<br>
 
array '''$params''': array de parametros con nombre
 
 
Parametros con nombre:<br>
 
message: mensaje a mostrar<br>
 
field: nombre del campo
 
 
<source lang=php>
 
...
 
$this->validates_numericality_of('cedula')
 
 
...
 
...
 
</source>
 
</source>
  
 +
== Pages Controller ==
 +
Es un nuevo controlador para el manejo de páginas estáticas (views estáticos), aunque se puede utilizar como cualquier otro controlador haciendo uso de los [[KumbiaPHP_Framework_Versión_1.0_Spirit#Vistas |Templates y Partials]].
  
===validates_email_in($field, $params=array())===
+
Los parámetros pasados al método '''show()''' indican vistas que están en views/pages/  manteniendo su estructura de directorios
Valida que el campo sea un correo electronico
 
 
 
string '''$field''': campo a validar<br>
 
array '''$params''': array de parametros con nombre
 
 
 
Parametros con nombre:<br>
 
message: mensaje a mostrar<br>
 
field: nombre del campo
 
  
 +
Ejemplos:
 +
<pre>
 +
http://www.dominio.com/pages/show/organizacion/privacidad
 +
</pre>
 +
enseñará la vista views/pages/organizacion/privacidad.phtml
 +
<pre>
 +
http://www.dominio.com/pages/show/aviso
 +
</pre>
 +
enseñara la vista views/pages/aviso.phtml
 +
 +
También se puede usar el routes.ini para llamarlo con otro nombre,
 +
<pre>
 +
/aviso = pages/show/aviso
 +
</pre>
 +
Asi al ir a www.dominio.com/aviso enseñara la vista views/pages/aviso.phtml
 +
<pre>
 +
/organizacion/* = pages/show/organizacion/*
 +
</pre>
 +
Al ir a www.dominio.com/organizacion/privacidad enseñará la vista en views/pages/organizacion/privacidad.phtml (si existe).
 +
 +
Ademas se pueden utilizar los Helpers y Partials dentro de estos views.
 
<source lang=php>
 
<source lang=php>
...
+
<?php echo link_to('pages/show/aviso', 'Ir Aviso') ?>
$this->validates_email_in('email')
 
...
 
 
</source>
 
</source>
 +
Mostrará un enlace que al hacer clic ira a dominio.com/pages/show/aviso
  
==Modos de una Aplicación==
+
== Nuevo Helper ==
'''KumbiaPHP''' ofrece dos modos de ejecución de una aplicación el cual es indicado en el '''config.ini''', estos se describen a continuación:
 
  
===Production===
+
=== swf_tag($src) ===
Indicando en el config.ini '''"production = On"''', se entra en el modo de producción, en este la cache de kumbiaphp framework esta activada y se cachea información necesaria para agilizar la carga de la aplicación tal como la metadata de la base datos (información de tablas y campos), asimismo las vistas que el usuario desee cachear.
 
  
===Development===
+
Con este helper tendremos la posibilidad de agregar archivos flash a nuestras páginas de una manera fácil, rápida y sencilla, este helper utiliza una librería hecha en JavaScript y lo mejor de todo es que es Open Source, el helper object_tag("archivo.swf"), recibe como parámetro el nombre del archivo flash el cual debe estar ubicado en la carpeta public/swf, además de eso recibe parámetros por nombre como son "width", "height" y "wmode", el ancho y alto deben ser colocados para que el flash sea visible, de otra manera no se vera por las dimensiones. Veamos el siguiente ejemplo realizado en la vista '''index.phtml'''
Indicando en el config.ini '''"production = Off"''', se entra en el modo de desarrollo, en este la cache de [http://www.kumbiaphp.com KumbiaPHP] esta desactivada y cualquier cambio que se haga en los campos y tablas de la base de datos (adición de campos, etc), vistas de la aplicación que se cacheen, surtirán efecto inmediatamente.
 
  
La para utilizar manualmente la cache de [http://www.kumbiaphp.com KumbiaPHP] debes cargarla explicitamente indicándola en el boot.ini o utilizando el componente '''Load'''.
+
<source lang="php" line>
 
+
<?php echo swf_tag("archivo.swf", "height: 300", "width: 300", "wmode: transparent") ?>
<source lang=php>
 
Load::lib('cache');
 
 
</source>
 
</source>
  
'''Cuando se cambia de modo, es necesario limpiar la cache que [http://www.kumbiaphp.com KumbiaPHP] ha creado para que se pueda renovar los nuevos metadatos y vistas, esto se hace simplemente eliminando el contenido del directorio de cache para la aplicación.'''
+
Este Helper nos garantiza que el código XHTML generado es validado por la W3C.
  
== Carga selectiva de modelos ==
+
== Filter ==
En la [https://launchpad.net/kumbia/0.5.1 versión 1.0](<s>antigua 0.5.1</s>) se puede cargar solo los modelos que el controlador requiera, de esa manera se optimiza los procesos de la aplicación y consume menos recursos. Para utilizar la carga selectiva, es conveniente deshabilitar la autocarga de modelos en el config.ini con '''"models_autoload = Off"'''.
 
  
==== Load::models($model) ====
+
=== Uso de Filter ===
Carga los modelos, se pueden cargar varios de manera simultánea indicándolos como argumentos múltiples del método o mediante un array. Asimismo se pueden cargar directorios completos de modelos.
 
  
Si la carga se efectúa en el controlador, automaticamente una instancia del modelo es cargada en un atributo del controlador correspondiente al nombre del modelo en notación camelcase.
+
El componente Filter, es un componente que permite filtrar y validar datos de una manera intuitiva, facil y simple.
  
''NOTA: El parámetro '''$model''' puede ser un directorio y/o archivo, en el caso de ser el archivo debe ser igual al nombre del mismo.''
+
Filter dispone de una serie de métodos estaticos que le permitirán filtrar los elementos indicados.
  
<source lang=php >
+
=== Filter::get($s, $options=array()) ===
class UsuarioController extends ApplicationController
+
 
{
+
'''$s (mixed)''': el valor a filtrar.
  public function index()
+
<br>
  {
+
'''$options (array)''': array de configuración del filtro.
    //Se cargan los modelos Usuario y DatosPersonales
 
    //usuario.php y datos_personales.php
 
    Load::models('usuario', 'datos_personales');
 
  }
 
}
 
</source>
 
  
Asimismo se puede indicar con el atributo de controlador $models y estos serán cargados en cada acción.
+
Los filtros se aplican al valor indicado.
  
<source lang=php >
+
Ejemplo:
class UsuarioController extends ApplicationController {
+
<source lang=php>  
 +
$value = Filter::get($s, 'htmlspecialchars', array('charset' => 'UTF-8'));
 +
</source>
  
  //Se cargan los modelos Usuario y DatosPersonales
+
Asimismo se pueden aplicar filtros en cadena.
  public $models = array('usuario', 'datos_personales');
+
<source lang=php>
 
+
$value = Filter::get($s, 'trim', 'addslashes');
  public function index()
 
  {}
 
}
 
 
</source>
 
</source>
  
Cargando un directorio de modelos
+
Los filtros en cadena no aceptan opciones de configuración, por lo tanto toman las opciones por defecto.
  
<source lang=php >
+
=== Filter::get_array($array, $options=array()) ===
class UsuarioController extends ApplicationController {
 
 
 
  public function index()
 
  {
 
    /** se cargan los modelos en:  
 
    * mi_app/models/dir/*
 
    * mi_app/models/dir2/model1.php
 
    * mi_app/models/model2.php
 
    */
 
    Load::models('dir', 'dir2/model1', 'model2')
 
  }
 
  
}
+
'''$array (array)''': un array de elementos a filtrar.
</source>
+
<br>
 +
'''$options (array)''': array de configuración del filtro.
 +
 
 +
Los filtros se aplican a cada elemento del array.
 +
 
 +
Ejemplo:
 +
<source lang=php>
 +
$array = Filter::get_array(array('<b>Hola</b>', '<b>Adios</b>'), 'htmlspecialchars', array('charset' => 'UTF-8'));
 +
</source>
  
==== Load::model($model) ====
 
Obtiene una instancia del modelo indicado, esto permite hacer uso de modelos en cualquier lugar de la aplicación de manera intuitiva.
 
  
'''NOTA: el nombre del modelo que recibe como parámetro este método debe ser pasado en notación smallcase'''
+
<source lang=php>
 +
$array = Filter::get_array(array('saludo' => '<b>Hola</b>'), 'htmlspecialchars', array('charset' => 'UTF-8'));
 +
</source>
  
<source lang=php >
+
=== Filter::get_object($object, $options=array()) ===
/**
 
* Construye una lista desplegable para países
 
**/
 
function pais_select($id, $value=null) {
 
    //carga el modelo models/pais.php
 
    $Pais = Load::model('pais');
 
  
    $code = "<select name=\"$id\" id=\"$id\">";
+
'''$object (object)''': objeto a filtrar.
    foreach($Pais->find() as $pais) {
+
<br>
        $code .= "<option value=\"$pais->id\"";
+
'''$options (array)''': array de configuración del filtro.
        if($pais->id == $value) {
+
 
            $code .= ' selected="selected"';
+
Los filtros se aplican a cada atributo del objeto.
        }
 
        $nombre = htmlspecialchars($pais->nombre);
 
        $code .= ">$nombre</option>";
 
    }
 
    $code .= '</select>';
 
  
    return $code;
+
Ejemplo:
}
+
<source lang=php>
 +
$object = Filter::get_object($usuario, 'htmlspecialchars', array('charset' => 'UTF-8'));
 
</source>
 
</source>
  
Uso avanzado...
+
=== Filtros ===
 +
Los filtros que existen actualmente son los siguientes:
  
<source lang=php >
+
==== addslashes ====
...
+
Escapa las comillas dobles y simples en una cadena de texto.
    //busca el país con ID 1
 
    Load::model('pais')->find(1);
 
  
    //carga el modelo ubicado en models/dir/user.php
+
<source lang=php>
    Load::model('dir/user')->find();
+
$value = Filter::get('hola "gente"', 'addslashes');
 +
</source>
  
    //carga el modelo ubicado en models/user_group.php
+
==== alnum ====
    Load::model('user_group')->find();
+
Filtra la cadena eliminando los caracteres que no son alfanumericos o espacios.
  
...
+
<source lang=php>
 +
$value = Filter::get('hola "gente112"', 'alnum');
 
</source>
 
</source>
  
== Pages Controller ==
+
==== alpha ====
Es un nuevo controlador para el manejo de páginas estáticas (views estáticos), aunque se puede utilizar como cualquier otro controlador haciendo uso de los [[KumbiaPHP_Framework_Versión_1.0_Spirit#Vistas |Templates y Partials]].
+
Filtra la cadena eliminando los caracteres que no son alfabéticos o espacios.
 +
 
 +
<source lang=php>
 +
$value = Filter::get('hola "gente112"', 'alpha');
 +
</source>
  
Los parámetros pasados al método '''show()''' indican vistas que están en views/pages/  manteniendo su estructura de directorios
+
==== date ====
 +
Verifica que sea una fecha valida en el formato YYYY-MM-DD.
  
Ejemplos:
+
<source lang=php>
<pre>
+
if(Filter::date($s, 'date')) {
http://www.dominio.com/pages/show/organizacion/privacidad
+
    ...
</pre>
+
}
enseñará la vista views/pages/organizacion/privacidad.phtml
 
<pre>
 
http://www.dominio.com/pages/show/aviso
 
</pre>
 
enseñara la vista views/pages/aviso.phtml
 
 
También se puede usar el routes.ini para llamarlo con otro nombre,
 
<pre>
 
/aviso = pages/show/aviso
 
</pre>
 
Asi al ir a www.dominio.com/aviso enseñara la vista views/pages/aviso.phtml
 
<pre>
 
/organizacion/* = pages/show/organizacion/*
 
</pre>
 
Al ir a www.dominio.com/organizacion/privacidad enseñará la vista en views/pages/organizacion/privacidad.phtml (si existe).
 
 
Ademas se pueden utilizar los Helpers y Partials dentro de estos views.
 
<source lang=php>
 
<?php echo link_to('pages/show/aviso', 'Ir Aviso') ?>
 
 
</source>
 
</source>
Mostrará un enlace que al hacer clic ira a dominio.com/pages/show/aviso
 
  
== Nuevo Helper ==
+
==== digits ====
 +
Filtra la cadena eliminando los caracteres que nos son digitos.
  
=== swf_tag($src) ===
+
<source lang=php>
 +
$value = Filter::get('hola "gente112"', 'digits');
 +
</source>
  
Con este helper tendremos la posibilidad de agregar archivos flash a nuestras páginas de una manera fácil, rápida y sencilla, este helper utiliza una librería hecha en JavaScript y lo mejor de todo es que es Open Source, el helper object_tag("archivo.swf"), recibe como parámetro el nombre del archivo flash el cual debe estar ubicado en la carpeta public/swf, además de eso recibe parámetros por nombre como son "width", "height" y "wmode", el ancho y alto deben ser colocados para que el flash sea visible, de otra manera no se vera por las dimensiones. Veamos el siguiente ejemplo realizado en la vista '''index.phtml'''
+
==== htmlentities ====
 +
Escapa los elementos del lenguaje html con sus correspondientes entidades.
  
<source lang="php" line>
+
<source lang=php>
<?php echo swf_tag("archivo.swf", "height: 300", "width: 300", "wmode: transparent") ?>
+
$value = Filter::get('<p>"hola"</p>', 'htmlentities');
 
</source>
 
</source>
  
Este Helper nos garantiza que el código XHTML generado es validado por la W3C.
+
'''Opciones:'''<br>
 +
'''charset''': codificación de caracteres de la cadena a escapar.
  
== Filter ==
+
==== htmlspecialchars ====
 +
Escapa caracteres especial de html.
  
=== Uso de Filter ===
+
<source lang=php>
 +
$value = Filter::get('<p>"hola"</p>', 'htmlspecialchars');
 +
</source>
  
El componente Filter, es un componente que permite filtrar y validar datos de una manera intuitiva, facil y simple.
+
'''Opciones:'''<br>
 +
'''charset''': codificación de caracteres de la cadena a escapar.
  
Filter dispone de una serie de métodos estaticos que le permitirán filtrar los elementos indicados.
+
==== int ====
 +
Convierte un valor a tipo entero.
  
=== Filter::get($s, $options=array()) ===
+
<source lang=php>
 +
$value = Filter::get('1.2', 'int');
 +
</source>
  
'''$s (mixed)''': el valor a filtrar.
+
==== ipv4 ====
<br>
+
Verifica si la cadena tiene el formato ipv4.
'''$options (array)''': array de configuración del filtro.
 
  
Los filtros se aplican al valor indicado.
+
<source lang=php>
 +
if(Filter::get($s, 'ipv4')) {
 +
    ...
 +
}
 +
</source>
  
Ejemplo:
+
==== lower ====
<source lang=php>
+
Convierte una cadena de texto a minusculas.
$value = Filter::get($s, 'htmlspecialchars', array('charset' => 'UTF-8'));
 
</source>
 
  
Asimismo se pueden aplicar filtros en cadena.
+
<source lang=php>
<source lang=php>  
+
$value = Filter::get('TEXTO', 'lower');
$value = Filter::get($s, 'trim', 'addslashes');
 
 
</source>
 
</source>
  
Los filtros en cadena no aceptan opciones de configuración, por lo tanto toman las opciones por defecto.
+
==== md5 ====
 +
Calcula el hash md5 para el valor indicado.
  
=== Filter::get_array($array, $options=array()) ===
+
<source lang=php>
 +
$value = Filter::get('TEXTO', 'md5', array('binary' => true));
 +
</source>
  
'''$array (array)''': un array de elementos a filtrar.
+
'''Opciones:'''<br>
<br>
+
'''binary:''' indica si se usa modo binario
'''$options (array)''': array de configuración del filtro.
 
  
Los filtros se aplican a cada elemento del array.
+
==== nl2br ====
 +
Convierte el caracter de nueva linea a "&lt;br&gt;".
  
Ejemplo:
+
<source lang=php>
<source lang=php>  
+
$value = Filter::get('TEXTO\nTexto2', 'nl2br');
$array = Filter::get_array(array('<b>Hola</b>', '<b>Adios</b>'), 'htmlspecialchars', array('charset' => 'UTF-8'));
 
 
</source>
 
</source>
  
 +
==== numeric ====
 +
Filtra una cadena solo permitiendo valores numericos.
  
<source lang=php>  
+
<source lang=php>
$array = Filter::get_array(array('saludo' => '<b>Hola</b>'), 'htmlspecialchars', array('charset' => 'UTF-8'));
+
$value = Filter::get('a1.2', 'numeric');
 
</source>
 
</source>
  
=== Filter::get_object($object, $options=array()) ===
+
==== stripslashes ====
 +
Filtra una cadena haciendo la operación inversa a addslashes.
  
'''$object (object)''': objeto a filtrar.
 
<br>
 
'''$options (array)''': array de configuración del filtro.
 
 
Los filtros se aplican a cada atributo del objeto.
 
 
Ejemplo:
 
 
<source lang=php>
 
<source lang=php>
$object = Filter::get_object($usuario, 'htmlspecialchars', array('charset' => 'UTF-8'));
+
$value = Filter::get('\"Hola\"', 'stripslashes');
 
</source>
 
</source>
  
=== Filtros ===
+
==== stripspace ====
Los filtros que existen actualmente son los siguientes:
+
Elimina los espacios.
 
 
==== addslashes ====
 
Escapa las comillas dobles y simples en una cadena de texto.
 
  
 
<source lang=php>
 
<source lang=php>
$value = Filter::get('hola "gente"', 'addslashes');
+
$value = Filter::get('a1.2', 'numeric');
 
</source>
 
</source>
  
==== alnum ====
+
==== striptags ====
Filtra la cadena eliminando los caracteres que no son alfanumericos o espacios.
+
Elimina las etiquetas HTML.
  
 
<source lang=php>
 
<source lang=php>
$value = Filter::get('hola "gente112"', 'alnum');
+
$value = Filter::get('<p>Hola</p>', 'striptags');
 
</source>
 
</source>
  
==== alpha ====
+
==== trim ====
Filtra la cadena eliminando los caracteres que no son alfabéticos o espacios.
+
Elimina los espacios en blanco a la izquiera y a la derecha.
  
 
<source lang=php>
 
<source lang=php>
$value = Filter::get('hola "gente112"', 'alpha');
+
$value = Filter::get('   Hola  ', 'trim');
 
</source>
 
</source>
  
==== date ====
+
==== upper ====
Verifica que sea una fecha valida en el formato YYYY-MM-DD.
+
Convierte la cadena a mayúsculas.
  
 
<source lang=php>
 
<source lang=php>
if(Filter::get($s, 'date')) {
+
$value = Filter::get('hola', 'upper');
    ...
 
}
 
 
</source>
 
</source>
  
==== digits ====
+
=== Extendiendo el componente Filter ===
Filtra la cadena eliminando los caracteres que no son digitos.
+
El componente Filter puede extenderse permitiendo al usuario crear sus propios filtros, para este fin el usuario debe hacer uso de la interface "FilterInterface", la cual se describe a continuación:
  
 
<source lang=php>
 
<source lang=php>
$value = Filter::get('hola "gente112"', 'digits');
+
interface FilterInterface
</source>
+
{
 
+
    /**
==== htmlentities ====
+
    * Metodo para ejecutar el filtro
Escapa los elementos del lenguaje html con sus correspondientes entidades.
+
    *
 
+
    * @param string $s cadena a filtrar
<source lang=php>
+
    * @param array $options opciones para el filtro
$value = Filter::get('<p>"hola"</p>', 'htmlentities');
+
    **/
 +
    public static function execute ($s, $options);
 +
}
 
</source>
 
</source>
  
'''Opciones:'''<br>
+
Los filtros de usuario deben ubicarse en el directorio "app/filters".
'''charset''': codificación de caracteres de la cadena a escapar.
 
  
==== htmlspecialchars ====
+
Por convenio la clase que corresponde al filtro debe llevar el sufijo "Filter" y el archivo debe llamarse igual que la clase pero en notación smallcase.
Escapa caracteres especial de html.
 
  
<source lang=php>
+
'''Ejemplo:'''
$value = Filter::get('<p>"hola"</p>', 'htmlspecialchars');
+
Un filtro que permite obtener la extension de un archivo, pasandole como valor el nombre del archivo.
</source>
 
  
'''Opciones:'''<br>
+
app/extensions/filters/file_extension_filter.php
'''charset''': codificación de caracteres de la cadena a escapar.
+
<source lang=php >
 
+
/**
==== int ====
+
* Filtro para obtener la extensión de un archivo
Convierte un valor a tipo entero.
+
**/
 
+
class FileExtensionFilter implements FilterInterface
<source lang=php>
+
{
$value = Filter::get('1.2', 'int');
+
  public static function execute($s, $options=array())
 +
  {
 +
      return strchr($s,".");
 +
  }
 +
}
 
</source>
 
</source>
  
==== ipv4 ====
+
Y se utilizaría de la siguiente manera:
Verifica si la cadena tiene el formato ipv4.
 
 
 
 
<source lang=php>
 
<source lang=php>
if(Filter::get($s, 'ipv4')) {
+
$ext = Filter::get('/home/yo/prueba.php', 'file_extension');
    ...
 
}
 
 
</source>
 
</source>
  
==== lower ====
+
=== Filtrando datos enviados en el Request ===
Convierte una cadena de texto a minusculas.
+
El controller dispone de ciertas facilidades, en sus métodos: post, get y request, se puede indicar diversos filtros para aplicar al valor recibido.
  
<source lang=php>
+
Ejemplo:
$value = Filter::get('TEXTO', 'lower');
+
<source lang=php >
 +
class UsuarioController extends ApplicationController
 +
{
 +
    public function save()
 +
    {
 +
        if($this->has_post('usuario')) {
 +
            $usuario = new Usuario($this->post('usuario', 'trim'));
 +
            $usuario->save();
 +
        }
 +
    }
 +
}
 
</source>
 
</source>
  
==== md5 ====
+
En el ejemplo anterior, los datos enviados en el array de campos "usuario", son filtrados con un trim, cargados por el constructor del objecto ActiveRecord y posteriormente se guarda en la base de datos.
Calcula el hash md5 para el valor indicado.
 
  
<source lang=php>
+
== Carga Selectiva, Inyección de Dependencias y el Componente Load ==
$value = Filter::get('TEXTO', 'md5', array('binary' => true));
+
El componente '''Load''', esta diseñado especialmente para satisfacer las necesidades de Carga Selectiva e Inyección de Dependencias, con este componente disponemos de los elementos de [http://www.kumbiaphp.com KumbiaPHP Framework] (vendors, libraries y models) donde así lo necesite nuestra aplicación.
</source>
 
  
'''Opciones:'''<br>
+
=== Load::lib($lib) ===
'''binary:''' indica si se usa modo binario
 
  
==== nl2br ====
+
El método library del componente Load nos permite cargar dinámicamente aquellas clases que tengamos definidas en el dir '''app/libs/''' a fin de utilizarlas en los controladores(controllers) y/o Modelos(models).
Convierte el caracter de nueva linea a "&lt;br&gt;".
 
  
<source lang=php>
+
<source lang=php >
$value = Filter::get('TEXTO\nTexto2', 'nl2br');
+
class UsuarioController extends ApplicationController
 +
{
 +
  public function index()
 +
  {
 +
    //Se carga la librería app/libs/my_util.php
 +
    Load::lib('my_util');
 +
  }
 +
}
 
</source>
 
</source>
  
==== numeric ====
+
'''NOTA: Por convención del método Load::lib($lib) busca primero en el directorio app/libs/ y en caso de no encontrar la biblioteca requerida pasaría a buscar en el directorio core/libs/, por lo que podríamos cargar dinámicamente la librería Auth del core de la siguiente forma'''
Filtra una cadena solo permitiendo valores numericos.
 
  
<source lang=php>
+
<source lang=php >
$value = Filter::get('a1.2', 'numeric');
+
class UsuarioController extends ApplicationController
 +
{
 +
  public function index()
 +
  {
 +
    //Se carga core/libs/auth/auth.php, siempre que no exista algún archivo
 +
    //con el mismo nombre en app/libs/ ya que KumbiaPHP da prioridad a tu app sobre el core.
 +
    Load::lib('Auth');
 +
  }
 +
}
 
</source>
 
</source>
  
==== stripslashes ====
+
==Persistencia de Datos en el Controller==
Filtra una cadena haciendo la operación inversa a addslashes.
+
En ocasiones se necesita la persistencia de algunas variables en la ejecución de nuestros controladores, lo mas común en estos casos es guardar consultas avanzadas o bien pudiera los articulos de carro de compras. Para estos casos y mas que se puedan presentar [http://www.kumbiaphp.com KumbiaPHP] hace persistente las variables para el controlador dependiendo el caso.
 +
 
 +
Para suplir esta necesidad se incoporan los siguientes métodos.
  
 
<source lang=php>
 
<source lang=php>
$value = Filter::get('\"Hola\"', 'stripslashes');
+
...
 +
//hace persistente la variable $data
 +
$this->set_persistent('data', 'valor');
 +
...
 
</source>
 
</source>
  
==== stripspace ====
 
Elimina los espacios.
 
  
 
<source lang=php>
 
<source lang=php>
$value = Filter::get(' Hola  ', 'stripspace');
+
...
 +
//recupera la persistencia de la variable $data
 +
$this->get_persistent('data');
 +
...
 
</source>
 
</source>
  
==== striptags ====
 
Elimina las etiquetas HTML.
 
  
 
<source lang=php>
 
<source lang=php>
$value = Filter::get('<p>Hola</p>', 'striptags');
+
...
 +
//destruye la persistencia de la variable $data
 +
$this->destroy_persistent('data');
 +
...
 
</source>
 
</source>
  
==== trim ====
+
==Session==
Elimina los espacios en blanco a la izquiera y a la derecha.
+
En la extensions ''Session'' se quitan dos métodos que estaban descontinuado ('''deprecated''') los cuales son:
 +
* set_data()
 +
* get_data()
 +
 
 +
Quedando la extensions Session con los siguientes métodos para el manejo de la sessiones.
 +
 
 +
===set($index, $value, $namespace='default')===
 +
Crear o especifica el valor para un indice de la sesión actual.
  
 
<source lang=php>
 
<source lang=php>
$value = Filter::get('   Hola  ', 'trim');
+
Session::set('usuario', 'Administrador');
 
</source>
 
</source>
  
==== upper ====
+
===get($index, $namespace='default')===
Convierte la cadena a mayúsculas.
+
Obtener el valor para un indice de la sesión actual.
  
 
<source lang=php>
 
<source lang=php>
$value = Filter::get('hola', 'upper');
+
Session::get('usuario');//retorna 'Administrador'
 
</source>
 
</source>
  
=== Extendiendo el componente Filter ===
+
===unset_data($index, $namespace='default')===
El componente Filter puede extenderse permitiendo al usuario crear sus propios filtros, para este fin el usuario debe hacer uso de la interface "FilterInterface", la cual se describe a continuación:
+
Elimina el valor para un indice de la sesión actual.
  
 
<source lang=php>
 
<source lang=php>
interface FilterInterface
+
Session::unset_data('usuario');
{
+
</source>
    /**
+
 
    * Metodo para ejecutar el filtro
+
===isset_data($index, $namespace='default')===
    *
+
Verifica que este definido el indice en la sesión actual.
    * @param string $s cadena a filtrar
+
 
    * @param array $options opciones para el filtro
+
<source lang=php>
    **/
+
Session::isset_data('id_usuario');//retorna false.
    public static function execute ($s, $options);
 
}
 
 
</source>
 
</source>
  
Los filtros de usuario deben ubicarse en el directorio "app/extensions/filters/".
 
  
Por convenio la clase que corresponde al filtro debe llevar el sufijo "Filter" y el archivo debe llamarse igual que la clase pero en notación smallcase.
+
NOTA: '''$namespace''' es un espacio individual en el cual se pueden contener las variables de sesión, permitiendo evitar colisiones con nombres de variables.
 +
 
 +
 
 +
==Upload==
 +
Anteriormente en los controladores, estaban disponibles los métodos
 +
'''upload_file''' y '''upload_image''', ya que realmente el controlador no depende de estos para su correcto funcionamiento, estos fueron agrupados en el componente '''Upload'''. Este componente permite subir tanto archivos e imagenes al servidor donde se aloja tu aplicación.
  
'''Ejemplo:'''
+
=== Upload::file_in_path($name, $path, $new_name=null) ===
Un filtro que permite obtener la extension de un archivo, pasandole como valor el nombre del archivo.
+
Sube un archivo la ruta indicada.
  
app/extensions/filters/file_extension_filter.php
+
$name (string): nombre del archivo en el formulario (se revisa en $_FILES)
<source lang=php >
+
 
/**
+
$path (string): ruta donde se subira. Ejemplo: "/var/www/public/app/temp/files/"
* Filtro para obtener la extensión de un archivo
+
 
**/
+
$new_name (string): indica el nuevo nombre para el archivo, por defecto se toma el nombre original.
class FileExtensionFilter implements FilterInterface
 
{
 
  public static function execute($s, $options=array())
 
  {
 
      return strchr($s,".");
 
  }
 
}
 
</source>
 
  
Y se utilizaría de la siguiente manera:
 
 
<source lang=php>
 
<source lang=php>
$ext = Filter::get('/home/yo/prueba.php', 'file_extension');
+
...
 +
Upload::file_in_path('archivo', APP_PATH . 'temp/mis_archivos/');
 +
...
 
</source>
 
</source>
  
=== Filtrando datos enviados en el Request ===
 
El controller dispone de ciertas facilidades, en sus métodos: post, get y request, se puede indicar diversos filtros para aplicar al valor recibido.
 
  
Ejemplo:
+
=== Upload::file($name, $new_name=null) ===
<source lang=php >
+
Sube un archivo al directorio público "files/upload".
class UsuarioController extends ApplicationController
+
 
{
+
$name (string): nombre del archivo en el formulario
    public function save()
+
 
    {
+
$new_name (string): indica el nuevo nombre para el archivo
        if($this->has_post('usuario')) {
+
 
            $usuario = new Usuario($this->post('usuario', 'trim'));
+
<source lang=php>
            $usuario->save();
+
...
        }
+
Upload::file('archivo');
    }
+
...
}
 
 
</source>
 
</source>
  
En el ejemplo anterior, los datos enviados en el array de campos "usuario", son filtrados con un trim, cargados por el constructor del objecto ActiveRecord y posteriormente se guarda en la base de datos.
 
  
== Carga Selectiva, Inyección de Dependencias y el Componente Load ==
+
=== Upload::img($name, $new_name=null) ===
El componente '''Load''', esta diseñado especialmente para satisfacer las necesidades de Carga Selectiva e Inyección de Dependencias, con este componente disponemos de los elementos de [http://www.kumbiaphp.com KumbiaPHP Framework] (vendors, libraries y models) donde así lo necesite nuestra aplicación.
+
Sube una imagen al directorio público "img/upload".
  
=== Load::lib($lib) ===
+
$name (string): nombre del archivo en el formulario
  
El método library del componente Load nos permite cargar dinámicamente aquellas clases que tengamos definidas en el dir '''app/libs/''' a fin de utilizarlas en los controladores(controllers) y/o Modelos(models).
+
$new_name (string): indica el nuevo nombre para el archivo
  
<source lang=php >
+
<source lang=php>
class UsuarioController extends ApplicationController
+
...
{
+
Upload::img('archivo');
  public function index()
+
...
  {
 
    //Se carga la librería app/libs/my_util.php
 
    Load::lib('my_util');
 
  }
 
}
 
 
</source>
 
</source>
  
'''NOTA: Por convención del método Load::lib($lib) busca primero en el directorio app/libs/ y en caso de no encontrar la biblioteca requerida pasaría a buscar en el directorio core/libs/, por lo que podríamos cargar dinámicamente la librería Auth del core de la siguiente forma'''
+
==Vistas de Paginación==
 +
Como complemento para el paginador de ActiveRecord, através de vistas parciales se implementan los tipos de vistas de paginación más comunes, estos se ubican en el directorio "core/views/partials/paginators" y estas en capacidad de personalizarlos en tu aplicación aprovechando las características de renderizado de vistas parciales.
  
<source lang=php >
+
=== Classic ===
class UsuarioController extends ApplicationController
+
Vista de paginación clásica.  
{
 
  public function index()
 
  {
 
    //Se carga core/libs/auth/auth.php, siempre que no exista algún archivo
 
    //con el mismo nombre en app/libs/ ya que KumbiaPHP da prioridad a tu app sobre el core.
 
    Load::lib('auth');
 
  }
 
}
 
</source>
 
  
==Persistencia de Datos en el Controller==
+
Parametros de configuración:
En ocasiones se necesita la persistencia de algunas variables en la ejecución de nuestros controladores, lo mas común en estos casos es guardar consultas avanzadas o bien pudiera los articulos de carro de compras. Para estos casos y mas que se puedan presentar [http://www.kumbiaphp.com KumbiaPHP] hace persistente las variables para el controlador dependiendo el caso.
 
  
Para suplir esta necesidad se incoporan los siguientes métodos.
+
'''page:''' objeto obtenido al invocar al paginador.
 +
 
 +
'''show:''' número de paginas que se mostraran en el paginador, por defecto 10.
  
<source lang=php>
+
'''url:''' url para la accion que efectua la paginacion, por defecto "module/controller/page/" y se envia por parametro el numero de pagina.
...
 
//hace persistente la variable $data
 
$this->set_persistent('data', 'valor');
 
...
 
</source>
 
  
  
 
<source lang=php>
 
<source lang=php>
...
+
View::partial('paginators/classic', false, array('page' => $page, 'show' => 8, 'url' => 'usuario/lista'))
//recupera la persistencia de la variable $data
 
$this->get_persistent('data');
 
...
 
 
</source>
 
</source>
  
  
<source lang=php>
+
=== Digg ===
...
+
Vista de paginación estilo digg.  
//destruye la persistencia de la variable $data
 
$this->destroy_persistent('data');
 
...
 
</source>
 
  
==Session==
+
Parametros de configuración:
En la extensions ''Session'' se quitan dos métodos que estaban descontinuado ('''deprecated''') los cuales son:
 
* set_data()
 
* get_data()
 
  
Quedando la extensions Session con los siguientes métodos para el manejo de la sessiones.
+
'''page:''' objeto obtenido al invocar al paginador.
  
===set($index, $value, $namespace='default')===
+
'''show:''' número de paginas que se mostraran en el paginador, por defecto 10.
Crear o especifica el valor para un indice de la sesión actual.
 
  
<source lang=php>
+
'''url:''' url para la accion que efectua la paginacion, por defecto "module/controller/page/" y se envia por parametro el numero de pagina.
Session::set('usuario', 'Administrador');
 
</source>
 
  
===get($index, $namespace='default')===
 
Obtener el valor para un indice de la sesión actual.
 
  
 
<source lang=php>
 
<source lang=php>
Session::get('usuario');//retorna 'Administrador'
+
View::partial('paginators/digg', false, array('page' => $page, 'show' => 8, 'url' => 'usuario/lista'))
 
</source>
 
</source>
  
===delete($index, $namespace='default')===
 
Elimina el valor para un indice de la sesión actual.
 
  
<source lang=php>
+
=== Extended ===
Session::delete('usuario');
+
Vista de paginación extendida.
</source>
 
  
===has($index, $namespace='default')===
+
Parametros de configuración:
Verifica que este definido el indice en la sesión actual.
 
  
<source lang=php>
+
'''page:''' objeto obtenido al invocar al paginador.
Session::has('id_usuario');//retorna false.
+
 
</source>
+
'''url:''' url para la accion que efectua la paginacion, por defecto "module/controller/page/" y se envia por parametro el numero de pagina.
  
  
NOTA: '''$namespace''' es un espacio individual en el cual se pueden contener las variables de sesión, permitiendo evitar colisiones con nombres de variables.
+
<source lang=php>
 +
View::partial('paginators/extended', false, array('page' => $page, 'url' => 'usuario/lista'))
 +
</source>
 +
 
 +
 
 +
=== Punbb ===
 +
Vista de paginación estilo punbb.  
  
==Upload==
+
Parametros de configuración:
Anteriormente en los controladores, estaban disponibles los métodos
 
'''upload_file''' y '''upload_image''', ya que realmente el controlador no depende de estos para su correcto funcionamiento, estos fueron agrupados en el componente '''Upload'''. Este componente permite subir tanto archivos e imagenes al servidor donde se aloja tu aplicación.
 
  
=== Upload::file_in_path($name, $path, $new_name=null) ===
+
'''page:''' objeto obtenido al invocar al paginador.
Sube un archivo la ruta indicada.
 
  
$name (string): nombre del archivo en el formulario (se revisa en $_FILES)
+
'''show:''' número de paginas que se mostraran en el paginador, por defecto 10.
  
$path (string): ruta donde se subira. Ejemplo: "/var/www/public/app/temp/files/"
+
'''url:''' url para la accion que efectua la paginacion, por defecto "module/controller/page/" y se envia por parametro el numero de pagina.
  
$new_name (string): indica el nuevo nombre para el archivo, por defecto se toma el nombre original.
 
  
 
<source lang=php>
 
<source lang=php>
...
+
View::partial('paginators/punbb', false, array('page' => $page, 'show' => 8, 'url' => 'usuario/lista'))
Upload::file_in_path('archivo', APP_PATH . 'temp/mis_archivos/');
 
...
 
 
</source>
 
</source>
  
  
=== Upload::file($name, $new_name=null) ===
+
=== Simple ===
Sube un archivo al directorio público "files/upload".
+
Vista de paginación simple.  
 
 
$name (string): nombre del archivo en el formulario
 
 
 
$new_name (string): indica el nuevo nombre para el archivo
 
 
 
<source lang=php>
 
...
 
Upload::file('archivo');
 
...
 
</source>
 
 
 
 
 
=== Upload::image($name, $new_name=null) ===
 
Sube una imagen al directorio público "img/upload".
 
 
 
$name (string): nombre del archivo en el formulario
 
 
 
$new_name (string): indica el nuevo nombre para el archivo
 
 
 
<source lang=php>
 
...
 
Upload::image('archivo');
 
...
 
</source>
 
 
 
==Partials de Paginación==
 
Como complemento para el paginador de ActiveRecord, através de vistas parciales se implementan los tipos de vistas de paginación más comunes, estos se ubican en el directorio "core/views/partials/paginators" y estas en capacidad de personalizarlos en tu aplicación aprovechando las características de renderizado de vistas parciales.
 
 
 
=== Classic ===
 
[[Archivo:Paginado classic.JPG|thumb|right|Resultado Final]]
 
 
 
 
 
Vista de paginación clásica.
 
 
 
Parametros de configuración:
 
 
 
'''page:''' objeto obtenido al invocar al paginador.
 
 
 
'''show:''' número de paginas que se mostraran en el paginador, por defecto 10.
 
 
 
'''url:''' url para la accion que efectua la paginacion, por defecto "module/controller/page/" y se envia por parametro el numero de pagina.
 
 
 
 
 
<source lang=php>
 
View::partial('paginators/classic', false, array('page' => $page, 'show' => 8, 'url' => 'usuario/lista'))
 
</source>
 
 
 
=== Digg ===
 
Vista de paginación estilo digg.
 
 
 
Parametros de configuración:
 
 
 
'''page:''' objeto obtenido al invocar al paginador.
 
 
 
'''show:''' número de paginas que se mostraran en el paginador, por defecto 10.
 
 
 
'''url:''' url para la accion que efectua la paginacion, por defecto "module/controller/page/" y se envia por parametro el numero de pagina.
 
 
 
 
 
<source lang=php>
 
View::partial('paginators/digg', false, array('page' => $page, 'show' => 8, 'url' => 'usuario/lista'))
 
</source>
 
 
 
 
 
=== Extended ===
 
[[Archivo:paginado_extended.JPG|thumb|right|Resultado Final]]
 
 
 
 
 
 
 
Vista de paginación extendida.  
 
  
 
Parametros de configuración:
 
Parametros de configuración:
Línea 1619: Línea 1472:
  
 
<source lang=php>
 
<source lang=php>
View::partial('paginators/extended', false, array('page' => $page, 'url' => 'usuario/lista'))
+
View::partial('paginators/simple', false, array('page' => $page, 'url' => 'usuario/lista'))
</source>
 
 
 
=== Punbb ===
 
Vista de paginación estilo punbb.
 
 
 
Parametros de configuración:
 
 
 
'''page:''' objeto obtenido al invocar al paginador.
 
 
 
'''show:''' número de paginas que se mostraran en el paginador, por defecto 10.
 
 
 
'''url:''' url para la accion que efectua la paginacion, por defecto "module/controller/page/" y se envia por parametro el numero de pagina.
 
 
 
 
 
<source lang=php>
 
View::partial('paginators/punbb', false, array('page' => $page, 'show' => 8, 'url' => 'usuario/lista'))
 
 
</source>
 
</source>
  
 
=== Simple ===
 
[[Archivo:paginado_simple.JPG|thumb|right|Resultado Final]]
 
 
 
Vista de paginación simple.
 
 
 
Parametros de configuración:
 
 
'''page:''' objeto obtenido al invocar al paginador.
 
 
'''url:''' url para la accion que efectua la paginacion, por defecto "module/controller/page/" y se envia por parametro el numero de pagina.
 
 
 
 
<source lang=php>
 
View::partial('paginators/simple', false, array('page' => $page, 'url' => 'usuario/lista'))
 
</source>
 
  
 
=== Ejemplo de uso ===
 
=== Ejemplo de uso ===
Línea 1679: Línea 1497:
 
     }  
 
     }  
 
}
 
}
?>
 
 
</source>
 
</source>
  
Línea 1701: Línea 1518:
 
     }  
 
     }  
 
}
 
}
?>
 
 
</source>
 
</source>
  
Línea 1715: Línea 1531:
 
  <tr>
 
  <tr>
 
   <td><?php echo $p->id; ?></td>
 
   <td><?php echo $p->id; ?></td>
   <td><?php echo $p->nombre; ?></td>
+
   <td><?php echo $p->nombre ?></td>
 
  </tr>
 
  </tr>
 
  <?php endforeach; ?>
 
  <?php endforeach; ?>

Ten en cuenta que todas las contribuciones a KumbiaPHP Framework Wiki pueden ser editadas, modificadas o eliminadas por otros colaboradores. Si no deseas que las modifiquen sin limitaciones, no las publiques aquí.
Al mismo tiempo, asumimos que eres el autor de lo que escribiste, o lo copiaste de una fuente en el dominio público o con licencia libre (véase Proyecto:Derechos de autor para más detalles). ¡No uses textos con copyright sin permiso!

Para editar esta página, responde la pregunta que aparece abajo (más información):

Cancelar Ayuda de edición (se abre en una ventana nueva)

Plantilla usada en esta página: