miércoles 18 de enero de 2012

Ajustar width del jqgrid a un div contenedor

Saludos, esta ocasión les comento como podemos hacer para que nuestro elemento jqgrid pueda ser ajustado al contenedor padre, en este caso solo debemos escribir la siguiente linea de código después de la llamada principal al jqgrid

$("#grid_id").setGridWidth($('#box-content').width(), true);

con esto no necesariamente deberemos asignar un width estático en las propiedades del elemento jqgrid

Nos leemos en la proxima entrada.

martes 6 de diciembre de 2011

Múltiples llamadas AJAX en CakePHP causa error 403 o logout

Situación:

Desarrollando una aplicación web, tiene un formulario que contenía entre otros elementos una etiqueta SELECT de HTML con varias etiquetas OPTION que al seleccionarlas hace una llamada AJAX (utilizando jQuery) para buscar una información en específica y desplegarla.

Problema:

Cuando haces rápidamente clicks a varias de las etiquetas OPTION, lo que resulta en varias llamadas AJAX simultáneas, la primera llamada es procesada y la segunda y/o posteriores dan un error 403, y si tienes activado un módulo de seguridad te devolverá la página de login.

Solución:

Luego de Googlear la solución y leer foros encontré que la solución es una modificación bien sencilla, simplemente debes de cambiar el valor de la constante ‘Security.level’ de ‘high’ a ‘medium’ que se encuentra en el archivo ‘/app/config/core.php’.

Explicación:

Cuando configuramos el nivel de seguridad de CakePHP a ‘high’ cada llamada que se realiza entre el cliente al servidor es encriptada con un valor diferente lo cual afecta al reseteo y cambia valor constante de las Cookies de seguridad utilizadas por CakePHP. Cuando reconfiguramos el nivel de seguridad a ‘medium’ la medida ya descrita es pasada por alto.

viernes 21 de octubre de 2011

Funciones de ordenamiento en php

Veamos directamente las funciones disponibles para ordenar arrays.

sort()

Es la función más básica para ordenar arrays en PHP. Ordena el array de valores menores a mayores. Lo vemos con un ejemplo.

//Ordenar desde el menor al mayor
$alumnos = array("Pepe", "Juan", "Marcelo", "Alberto", "Gerardo");
sort($alumnos);
foreach ($alumnos as $key => $val) {
echo "alumnos[" . $key . "] = " . $val . "
";
}

Que dará como resultado:
alumnos[0] = Alberto
alumnos[1] = Gerardo
alumnos[2] = Juan
alumnos[3] = Marcelo
alumnos[4] = Pepe

rsort()

Esta función ordena el array por valores. La "r" delante quiere decir que ordena en orden reverso, de mayor a menor.

//ordenar de mayor a menor (orden inverso... Reverse order)
$alumnos = array("Pepe", "Juan", "Marcelo", "Alberto", "Gerardo");
rsort($alumnos);
foreach ($alumnos as $key => $val) {
echo "alumnos[" . $key . "] = " . $val . "
";
}

Que daría como respuesta:
alumnos[0] = Pepe
alumnos[1] = Marcelo
alumnos[2] = Juan
alumnos[3] = Gerardo
alumnos[4] = Alberto

ksort()

También podemos ordenar un array por el índice o llave, que quiere decir que en lugar de ordenar atendiendo a los valores, se ordenaría atendiendo al índice que tienen. Para ver este ejemplo utilizaremos arrays asociativos, que son los que tienen índices de texto en vez de números.

En el array siguiente vemos que tenemos índices como "h", "e", "a", en lugar de números. Lo que hará este tipo de ordenación es fijarse en esos índices para poner el array ordenado por ellos.

//Ordenar arrays por su índice
$calles = array("h"=>"Leganitos", "e"=>"Castellana", "a"=>"Bailén", "z"=>"Fuencarral");
ksort($calles);
foreach ($calles as $key => $val) {
echo $key ." = " . $val . "
";
}

Esto dará como resultado esta ordenación:
a = Bailén
e = Castellana
h = Leganitos
z = Fuencarral

krsort()

También podemos ordenar por índices pero en sentido inverso. Es decir, por índices pero de mayor a menor.

//ordenar por índice o clave, pero en orden inverso
$calles = array("h"=>"Leganitos", "e"=>"Castellana", "a"=>"Bailén", "z"=>"Fuencarral");
krsort($calles);
foreach ($calles as $key => $val) {
echo $key ." = " . $val . "
";
}

En este caso el resultado sería el siguiente:
z = Fuencarral
h = Leganitos
e = Castellana
a = Bailén

asort()

Esta función ordena los elementos de un array, pero manteniendo la correlación entre índices y valores a los que están asociados. Ordena por valores. Se utiliza generalmente en arrays asociativos.

//ordenar manteniendo los índices
$capitales = array("España" => "Madrid", "Argentina" => "Buenos Aires", "México" => "Ciudad de México", "Brasil" => "Brasilia");
asort($capitales);
foreach ($capitales as $key => $val) {
echo $key ." = " . $val . "
";
}

Dará como resultado el siguiente orden de array:
Brasil = Brasilia
Argentina = Buenos Aires
México = Ciudad de México
España = Madrid

arsort()

Es lo mismo que asort(), pero realiza el orden en inverso de los valores de los arrays. Como decíamos, lo habitual es realizar este tipo de orden en arrays asociativos, pero en este caso vamos a ver el orden en un array normal (con índices numéricos) para que se vea mejor cómo trabaja la función:

//ordenar manteniendo los índices, Reverso
$ciudades = array("Madrid", "Barcelona", "Valencia", "Sevilla", "Bilbao");
arsort($ciudades);
foreach ($ciudades as $key => $val) {
echo $key ." = " . $val . "
";
}

El resultado obtenido es este:
2 = Valencia
3 = Sevilla
0 = Madrid
4 = Bilbao
1 = Barcelona

natsort()

Para acabar vamos a ver esta función que hace una ordenación natural de los elementos del array, es decir, ordena tal como lo haría una persona. Hay una pequeña diferencia sobre el orden que haría sort(). La función natsort mantiene la asociación clave - valor.

$productos = array ("producto 11", "producto 1", "producto 12", "producto 2");
natsort($productos);
foreach ($productos as $key => $val) {
echo $key ." = " . $val . "
";
}

Esto daría como respuesta:
2 = producto 1
4 = producto 2
1 = producto 11
3 = producto 12
0 = producto 20

Ahora, para que se vea la diferencia con un orden normal, vamos a ordenar ese mismo array con la función sort(), que hace un orden alfanumérico normal.

$productos = array ("producto 11", "producto 1", "producto 12", "producto 2");
sort($productos);
foreach ($productos as $key => $val) {
echo $key ." = " . $val . "
";
}

El resultado de este orden será el siguiente:
0 = producto 1
1 = producto 11
2 = producto 12
3 = producto 2

Como se puede ver, el orden es distinto, porque en ese caso ordena por un orden alfanumérico estricto, sin tener en cuenta los valores como un humano lo haría.

martes 7 de diciembre de 2010

Implementando El Patrón De Diseño Mvc con PHP

Para implementar este patrón y entenderlo un poco más, veremos como convertir una aplicación PHP básica en una aplicación basada en la arquitectura MVC. En este caso, la aplicación será un listado de posts en un blog. En la manera tradicional de PHP, mostrar un listado de post desde la base de datos, se vería como el siguiente script:

<?php// Connecting, selecting database
$link = mysql_connect('localhost', 'myuser', 'mypassword');
mysql_select_db('blog_db', $link);

// Performing SQL query
$result = mysql_query('SELECT date, title FROM post', $link);
?>
<html>
<head>
<title>List of Posts</title>
</head>
<body>
<h1>List of Posts</h1>
<table>
<tr><th>Date</th><th>Title</th></tr>
<?php
// Printing results in HTML
while($row = mysql_fetch_array($result, MYSQL_ASSOC))
{
echo "<tr>";
printf("<td> %s </td>", $row['date']);
printf("<td> %s </td>", $row['title']);
echo "</tr>";
}
?>
</table>
</body>
</html>
<?php
// Closing connection
mysql_close($link);
?>


El script de arriba es rápido de escribir, rápido de ejecutar, pero es muy poco mantenible; algunos de los problemas que encontramos son que no hay chequeo de error (¿qué ocurre si la conexión a la base de datos falla?), el HTML y el código PHP están mezclados incluso entrelazados, y el código está atado a un base de datos MySQL.

Separando la Presentación

Las llamadas a las funciones echo y printf del script de arriba hacen el código difícil de leer. Modificar el código HTML para mejorar la presentación es un fastidio con la sintáxis actual. Por lo tanto, podemos separar el código en dos partes. Primero, el código PHP con toda la lógica de negocio en un script controlador (controller), como se muestra en el siguiente script (index.php):


<?php// Connecting, selecting database
$link = mysql_connect('localhost', 'myuser', 'mypassword');
mysql_select_db('blog_db', $link);

// Performing SQL query
$result = mysql_query('SELECT date, title FROM post', $link);

// Filling up the array for the view
$posts = array();
while($row = mysql_fetch_array($result, MYSQL_ASSOC))
{
$posts[] = $row;
}

// Closing connection
mysql_close($link);

// Requiring the view
require('view.php');


El código HTML, el cual contiene algo de código PHP, es guardado en un script de vista (view.php):


<html>
<head>
<title>List of Posts</title>
</head>
<body>
<h1>List of Posts</h1>
<table>
<tr><th>Date</th><th>Title</th></tr>
<?php foreach($posts as $post): ?><tr>
<td><?php echo $post['date'] ?></td>
<td><?php echo $post['title'] ?></td>
</tr><?php endforeach; ?>
</table>
</body>
</html>


Una buena regla para determinar si la vista esta lo suficientemente limpia es que esta debería de contener la mínima cantidad de código PHP posible, de este modo la vista puede ser entendida por un diseñador HTML sin conocimientos de PHP. La sintaxis PHP más comunes en la vista son echo, if/endif, foreach/endforeach, y nada más. Además, no debería haber código PHP imprimiendo tags HTML.

Por ende, toda la lógica es movida al controlador, y contiene solo código PHP, sin HTML. Como algo importante, deberías imaginar que el mismo controlador debería poder ser usado para diferentes presentaciones (vistas), tales como paginas HTML, archivos PDF, o en una estructura XML.

Separando la manipulación de datos

La mayoría del código del controlador esta dedicado a la manipulación de datos. Pero que pasa si necesitas listar los posts para otro controlador, por ejemplo, uno que tenga una salida en un feed RSS, o si quieres mantener todas las consultas a la base de datos en un solo lugar, para evitar duplicar código, o bien si decides cambiar el modelo de datos, en donde la table post pase a llamarse weblog_post, o por un requerimiento necesitas cambiarte desde MySQL a PostgreSQL. Para hacer todo esto posible, lo que necesitamos hacer es remover la manipulación de datos del controlador, y poner toda esa lógica en otro script (model.php), el cual será nuestro modelo:


<?phpfunction getAllPosts()
{
// Connecting, selecting database
$link = mysql_connect('localhost', 'myuser', 'mypassword');
mysql_select_db('blog_db', $link);

// Performing SQL query
$result = mysql_query('SELECT date, title FROM post', $link);

// Filling up the array
$posts = array();
while($row = mysql_fetch_array($result, MYSQL_ASSOC))
{
$posts[] = $row;
}

// Closing connection
mysql_close($link);

return $posts;
}


Y modificando el controlador (index.php) para incluir el modelo, tenemos:


<?php// Requiring the model
require_once('model.php');

// Retrieving the list of posts
$posts = getAllPosts();

// Requiring the view
require('view.php');


De este modo, el controlador es totalmente leible, ya que su única tarea es obtener los datos desde el modelo y pasarselo a la vista. En aplicaciones más complejas, el controlador además maneja la petición, la sesión de usuario, la autenticación, y demàs cosas.

El modelo esta dedicado a acceder a los datos y puede ser organizado acordemente. Todos los parametros que no dependen de la capa de datos (como ser los parametros de la petición) deben ser provistos por el controlador y no accedidos directamente por el modelo. De este modo, las funciones del modelo pueden ser facilmente utilizadas en otro controlador.

viernes 26 de noviembre de 2010

Generar archivos pdf con Dompdf en Codeigniter

Después de haber buscado librerías de pdf para integrarlas al codeigniter llego la conclusión de que la que más se adapta a mis necesidades es dompdf, dado que le puedo pasar una pagina HTML y este la pasa a PDF incluyendo las imágenes y algunas reglas de estilo, a continuación presento el procedimiento.

1. Descargamos la librería en su versión 0.5 dado que no funciona con su versión beta me deje llevar por la manía de usar siempre la última versión en fin descárgala de aquí.
2. Descomprimir el archivo en la ruta ./system/plugins/ lo dejamos con el nombre de dompdf.
3. Creamos un plugin con el nombre to_pdf_pi.php el código para este plugin es el siguiente te recuerdo no dejar espacios porque te generaría el error Unable to stream pdf: headers already sent.


function pdf_create($html, $filename, $stream=TRUE)
{
require_once("dompdf/dompdf_config.inc.php");

$dompdf = new DOMPDF();
$dompdf->load_html($html);
$dompdf->render();
if ($stream) {
$dompdf->stream($filename.".pdf");
} else {
$CI =&amp; get_instance();
$CI->load->helper('file');
write_file("./invoices_temp/invoice_$filename.pdf", $dompdf->output());
}
}


4. En el controlador ingresaremos el siguiente código.


function pdf ()
{
$data = 0;
$this ->load->plugin('to_pdf');
$html = $this->load->view( 'welcome_message' , $data , true );

pdf_create ($html,'pruebas');
}

ShareThis