viernes, 21 de diciembre de 2012

Empezando con jQuery

Dentro de la serie de herramientas de programación web hoy le toca el turno a jQuery, que es una librería de JavaScript, que facilita el manejo de los objetos una página web (enlaces, capas, títulos, párrafos, etc), de forma que permite establecer ciertas acciones sobre ellos (movimiento, ocultación, efectos, etc). jQuery se distribuye con una licencia de software libre y código abierto, permitiendo su uso tanto en proyectos libres como privativos. jQuery ofrece una serie de funcionalidades que escritas en JavaScript requerirían de muchísimo más código. La filosofía de jQuery es que pequeñas funciones logran grandes resultados, reduciendo el tiempo de desarrollo y el tamaño del código. El autor de esta librería es John Resig que además trabaja para Mozilla Corporation.


Instalación:

Instalar jQuery es de lo más sencillo: basta con bajarse la librería del sitio web oficial y copiarla en una carpeta de nuestro proyecto. Luego hay que incluirla como una librería más de nuestro proyecto:

<script type="text/javascript" src="js/jquery.min.js"></script>

La función $:

El concepto básico de jQuery consiste en dos apartados: el primero es la captura o selección de elementos del documento HTML y el segundo en aplicar acciones o programar eventos sobre esos elementos. La función $ (dolar) es la encargada de seleccionar partes del documento HTML: etiquetas, clases, divisores, elementos, etc. Luego con esas partes capturadas haremos cosas como mostrarlas, ocultarlas, aplicarles efectos, etc. Veamos unos ejemplos:

  • $(document): Captura todo el documento HTML.
  • $("body"): Captura el cuerpo del documento HTML.
  • $("a"): Captura todos los enlaces del documento HTML.
  • $("#etiqueta"): Captura el elemento HTML con id="etiqueta".
  • $(".clase"): Captura todos los elementos HTML con class="clase".
  • $("div.clase"): Captura todos los divisores con class="clase".
  • $("#etiqueta a"): Captura todos los enlaces dentro del elemento con id="etiqueta".
  • $("div[name='nombre']"): Captura todos los divisores cuyo atributo name='nombre'.
  • $("[name!='nombre'][type='button']"): Captura todos los elementos cuyo atributo name sea distinto de "nombre" y cuyo atributo type valga "button".
  • $("input:button"): Captura todos los botones (<input type="button">).
  • $("div:hidden"): Captura todos los divisores ocultos.

Aquí podéis encontrar una referencia completa de todos los selectores jQuery. La función $ devuelve un objeto jQuery. Sobre ese objeto aplicaremos eventos, efectos y acciones.


Eventos en jQuery:

El primer evento que hay que conocer en jQuery es el evento ready() que se ejecutará cuando la selección haya acabado de cargarse. Suele usarse por ejemplo para evitar que se ejecute cualquier otra función jQuery antes de que se termine de cargar el documento HTML.

$(document).ready(function() {

  // Resto de funciones jQuery...
});

Otro evento importante es el evento click() que se ejecuta cuando el usuario pulsa sobre algún elemento de la selección. No es necesario que la selección sea un enlace o un botón; puede ser cualquier elemento HTML.

$(document).ready(function() {

  $("a").click(function() {
    alert("Se ha pulsado un enlace");
  });

  $("input:button").click(function() {
    alert("Se ha pulsado un botón");
  });
});

En este código hemos programado dos eventos dentro del evento ready(), por lo tanto no estarán disponibles hasta que no se cargue todo el documento HTML. El primer evento mostrará un mensaje cuando se pulse en cualquier enlace (<a href="...">) y el segundo hará lo propio cuando se pulse cualquier botón (<input type="button"...>). Como vemos la sintaxis de jQuery es muy sencilla aunque es relativamente fácil liarse con los paréntesis y las llaves. Pero no deja de ser código JavaScript, por lo que podemos escribirlo de forma más clara:

var d = $(document);
d.ready(onReadyDocument);

function onReadyDocument() {

  var anchors = $("a");
  var buttons = $("input:button");

  anchors.click(onClickAnchors);
  buttons.click(onClickButtons);
}

function onClickAnchors() {
    alert("Se ha pulsado un enlace");
}

function onClickButtons() {
  alert("Se ha pulsado un botón");
}

Otros eventos comunes en jQuery son los siguientes. Aquí podéis encontrar una referencia completa de todos los eventos jQuery.

  • click() Se ejecuta al hacer clic sobre un elemento de la selección.
  • dbclick() Se ejecuta al hacer doble clic sobre un elemento de la selección.
  • hover() Se ejecuta cuando el ratón está encima de un elemento de la selección.
  • mousemove() Se ejecuta cuando el ratón se mueve estando encima de un elemento de la selección.
  • mouseleave() Se ejecuta cuando el ratón sale de un elemento de la selección.
  • keydown() Se ejecuta cuando el usuario pulsa una tecla si el foco lo tiene un elemento de la selección.
  • keyup() Se ejecuta cuando el usuario suelta una tecla si el foco lo tiene un elemento de la selección.
  • keypress() Igual que keydown() pero se va repitiendo periódicamente hasta que el usuario suelte la tecla.
  • focus() Se ejecuta cuando un elemento de la selección recibe el foco. Generalmente se usa en formularios.
  • blur() Se ejecuta cuando un elemento de la selección pierde el foco. Generalmente se usa en formularios.
  • select() Se ejecuta cuando el usuario selecciona un texto. Generalmente se usa en formularios.
  • change() Se ejecuta cuando el contenido cambia. Generalmente se usa en formularios. Por ejemplo en un control <input> o <select>.
  • submit() Se ejecuta cuando cuando el usuario envía un formulario. Se usa para validar el contenido del formulario antes de enviarlo.

Acciones jQuery:

Existen multitud de acciones en jQuery. Unas permiten cambiar el aspecto de algún elemento HTML, otras sirven para aplicar efectos o animaciones y hay otras aun más complejas. Una de las primeras que se aprenden es la función css() que permite cambiar cualquier propiedad CSS de los elementos de la selección. Vamos a verlo con un ejemplo:

$(document).ready(function() {

  var theBody = $("body");
  var anchors = $("a");

  theBody.css("background-color": "white");

  anchors.mouseenter(function() {
    theBody.css("background-color", "red");
  });

  anchors.mouseleave(function() {
    theBody.css("background-color", "white");
  });
});

Lo que hace este código jQuery es poner el color de fondo de la página en blanco y luego programar dos eventos: El primero pondrá en rojo el color de fondo cuando el ratón esté sobre cualquier enlace. El segundo evento restaura el color de fondo blanco cuando el ratón sale de un enlace. No es que sea un código muy útil, pero nos sirve de ejemplo.

Otras acciones comunes en jQuery son los siguientes. Para una referencia completa de acciones podéis visitar referencia efectos jQuery y referencia métodos jQuery.

  • css() Modifica una propiedad CSS de todos los elementos de la selección.
  • addClass() Añade una clase CSS a todos los elementos de la selección.
  • removeClass() Elimina una clase CSS de todos los elementos de la selección.
  • height(), innerHeight(), outerHeight() Devuelven la altura actual del primer elemento de la selección.
  • width(), innerWidth(), outerWidth() Devuelven la anchura actual del primer elemento de la selección.
  • hide() Oculta todos los elementos de la selección.
  • show() Muestra todos los elementos de la selección.
  • fadeOff() Modifica la opacidad de los elementos de la selección haciendo que desaparezcan progresivamente.
  • fadeIn() Modifica la opacidad de los elementos de la selección haciendo que aparezcan progresivamente.
  • slideDown() Muestra los elementos de la selección de forma progresiva deslizando hacia abajo.
  • slideUp() Oculta los elementos de la selección de forma progresiva deslizando hacia arriba.
  • animate() Permite crear efectos más complejos aplicables sobre las propiedades numéricas de todos los elementos de la selección.
  • text() Sirve tanto para obtener como para establecer el texto de los elementos de la selección.
  • attr() Sirve tanto para obtener el valor de una propiedad del primer elemento de la selección como para establecer el valor de una propiedad de todos los elementos de la selección. Por ejemplo la propiedad "alt" de un elemento <img>.
  • removeAttr() Elimina una propiedad de los elementos de la selección. Por ejemplo la propiedad "alt" de un elemento <img>.
  • val() Sirve tanto para obtener como para establecer el valor de los elementos de la selección.
  • html() Sirve tanto para obtener como para establecer el contenido HTML de los elementos de la selección. Equivale a la propiedad innerHTML del DOM.

Hasta aquí este minitutorial de jQuery. En un artículo posterior hablaré de jQuery avanzado, ajax en jQuery, etc.


Enlaces:

jueves, 20 de diciembre de 2012

Tabla de países 2.0

Hace tiempo necesitamos una tabla de países para un proyecto web. Aprovechamos en ese momento para ofrecer de forma libre y gratuita un archivo SQL que generaba una tabla de países para una base de datos MySQL. Dicha tabla tenía el código del país en formato ISO 3166-1 alfa-2 y el nombre oficial del país en Español.

Actualmente hemos necesitado ampliar esa tabla de países con los códigos ISO 3166-1 alfa-3 y el nombre internacional (en Inglés) y hemos aprovechado para añadir el código ISO 3166-1 numérico y el código FIPS por si en un futuro los necesitamos en otro proyecto. Todos esos códigos definen de forma única un país o territorio:

  • Códigos ISO 3166-1: Se trata de distintos códigos de países otras dependencias administrativas definidos como parte de la norma ISO 3166:
    • alfa-2: Código de 2 letras.
    • alfa-3: Código de 3 letras.
    • numérico: Código numérico de 3 dígitos.
  • Código FIPS: FIPS son las siglas de (Federal Information Processing Standard) y son un conjunto de estándares definidos por el gobierno de los Estados Unidos para la utilización por parte de todas las agencias del gobierno no militares y por los contratistas del gobierno. Los códigos de países FIPS son una versión modificada del código ISO 3166-1 alfa-2.

Ejemplo:

alfa-2alfa-3num-3FIPSNombre [ES]Nombre [INT]
ESESP724SPEspañaSpain
PTPRT620POPortugalPortugal
FRFRA250FRFrancia France
GBGBR826UKReino UnidoUnited Kingdom
USUSA840USEstados UnidosUnited States

Tabla de países:

CREATE TABLE IF NOT EXISTS `countries` (
  `iso_a2` varchar(2) NOT NULL,
  `iso_a3` varchar(3) DEFAULT NULL,
  `iso_n3` varchar(3) DEFAULT NULL,
  `fips` varchar(10) DEFAULT NULL,
  `name_es` varchar(64) DEFAULT NULL,
  `name_int` varchar(64) DEFAULT NULL,
  PRIMARY KEY (`iso_a2`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

Como de costumbre ponemos a disposición de quien lo necesite, de forma libre y gratuita, un archivo que genera la versión 2.0 de la tabla de países en formato MySQL. Se permite explícitamente usar y alterar los datos contenidos en ese archivo para cualesquier fin, aunque no garantizamos que los datos sean correctos o estén totalmente actualizados.

Descargar paises-v2.0.zip (6,31 KB).


Fuentes:

martes, 18 de diciembre de 2012

Como extender clases en CodeIgniter (II)

El otro día hablábamos de Como extender clases del modelo en CodeIgniter sin recibir el temible error "Class not found". El método comentado consistía en cargar manualmente la clase base antes que la clase hija. Desgraciadamente este método no puede usarse para los controladores pues es el propio framework el que se encarga de cargar los controladores. Afortunadamente en PHP 5 hay un método adecuado para extender cualquier clase si recibir ese fatal error: La función __autoload()

Dicha función se diseñó para evitar que los desarrolladores de aplicaciones orientadas a objetos que escriben cada clase en un fichero fuente PHP separado tuvieran que poner una larga lista de includes al comienzo de cada script. La función __autoload() es invocada automáticamente por el motor PHP (si está definida) en caso de que se intente usar una clase o interfaz que todavía no hayan sido definidos. Es como una última oportunidad.

En el caso de CodeIgniter la siguiente función cargaría automáticamente cualquier clase del controlador o del modelo.

function __autoload($class_name) {

  $class_folders = array(
    'controllers',
    'models'
  );

  foreach ($class_folders as $folder_name) {

    $full_address = APPPATH . $folder_name . '/' . strtolower($class_name) . EXT;
    if (file_exists($full_address)) {
      require_once($full_address);
    }
  }
}

Ya solamente queda poner esa función en un lugar del código fuente de la aplicación que se ejecute siempre. Algunos autores recomiendan añadirla al final del archivo de configuraciones "/application/config/config.php". Yo he probado con el fichero "/application/config/autoload.php" porque me parecía un buen sitio pero el controlador se invoca antes, con lo que no funciona.

viernes, 14 de diciembre de 2012

Como extender clases del modelo en CodeIgniter

Una de las características de la Programación Orienta a Objetos es que las clases pueden heredar características de una clase base. En el patrón de diseño MVC que implementa CodeIgniter todas las clases que usamos al diseñar nuestra aplicación derivarán de alguna clase base del framework (CI_Model, CI_Controller, etc.) pero también es posible crear nuestras propias clases base.

Para ello la clase base derivará de alguna del framework y la clase definitiva derivará de nuestra clase base. Como en el siguiente ejemplo:

class Mybaseclass_model extends CI_Model {

  public function __construct() {
    parent::__construct();
  }

  // ...
}

class Myclass_model extends Mybaseclass_model {

  public function __construct() {
    parent::__construct();
  }

  // ...
}

class Myclass2_model extends Mybaseclass_model {

  public function __construct() {
    parent::__construct();
  }

  // ...
}

El problema de hacer esto es que las diferentes clases Mybaseclass_model, Myclass_model y Myclass2_model estarán definidas en archivos distintos, con lo que al intentar cargar una de las clases derivadas nos encontraremos con el error:

Fatal error: Class 'Mybaseclass_model' not found in
W:\www\test\application\models\myclass_model.php on line 17.

Para solucionarlo es necesario cargar la clase base antes que la derivada, ya sea manualmente, como vemos abajo, a sea agregando la clase base a la carga automática de componentes del modelo en el archivo "/application/config/autoload.php"

$this->load->model('Mybaseclass_model');
$this->load->model('Myclass_model');

ACTUALIZACIÓN:

El método descrito en este artículo para extender clases del modelo sin recibir el temible error "Class not found" no es válido para extender clases del controlador, pues éstas son cargadas por el propio framework. Por suerte en PHP 5 tenemos la función __autoload() que permite extender clases del modelo y del controlador en CodeIgniter.

Accediendo a web services desde PHP vía socket

Según la Wikipedia, un web service (o servicio web) es una tecnología que utiliza un conjunto de protocolos y estándares que sirven para intercambiar datos entre aplicaciones que pueden estar desarrolladas en lenguajes de programación diferentes, y ejecutadas sobre plataforma distintas.

El lenguaje PHP tiene diversas formas de acceder a un web service, siendo la más usada SOAP (Simple Object Access Protocol). Para tener una visión completa recomiendo el repaso de la sección Web Services del manual de PHP. Pero hay otra forma de acceder a un servicio web, una de muy bajo nivel. Al fin y al cabo un web service no es más que un protocolo basado en direcciones web (URLs), por lo tanto si conocemos los parámetros del servicio podemos acceder al servicio web usando un simple socket y la siguiente secuencia de comandos:

  • Abrir el socket con el servidor (host).
  • Enviar una petición HTTP a través del socket.
  • Leer la respuesta del servidor en un buffer.
  • Extraer el mensaje del buffer.

Algunos de los puristas de los estándares dirán que esa no es la forma adecuada de acceder a un web service, pero eso no quiere decir que no se pueda hacer. En cualquier caso voy a poner un ejemplo de como hacerlo.

function readWebService($url) {

  // Se elimina de la URL el nombre del protocolo
  $url = str_replace("http://", "", $url);

  // Se extrae el host de la URL
  $pos = strpos($url, "/");
  if($pos === false) {
    $host = $url;
    $page = "/";
  }
  else {
    $page = substr($url, $pos);
    $host = substr($url, 0, $pos);
  }

  // Se obtiene la IP del host
  $ip = gethostbyname($host);

  // Se abre un socket de comunicación con el host
  $socket = @fsockopen($ip, 80, $errno, $errstr, 60);
  if($socket === false) {
    return false;
  }

  // Preparación de la petición HTTP a enviar al host
  $send = "GET " . $page . " HTTP/1.0\r\n";
  $send .= "Host: " . $host . "\r\n";
  $send .= "Accept-Language: es-ES\r\n";
  $send .= "Content-Type: application/json; charset=UTF-8\r\n";
  $send .= "User-Agent: " . $_SERVER["HTTP_USER_AGENT"] . "\r\n";
  $send .= "Connection: Close\r\n\r\n";

  // Se envía la petición HTTP al host
  fputs($socket, $send);

  // Se lee la respuesta del host
  $buffer = "";
  while(!feof($socket)) {
    $buffer .= fgets($socket, 4096);
  }

  // Se cierra el socket
  fclose($socket);

  // Separación de la cabecera HTTP y el contenido.
  $response = @explode("\r\n\r\n", $buffer, 2);

  // Se devuelve el resultado
  return $response;
}

Si la función falla, bien sea porque no encuentra el host o porque expira el tiempo máximo de 60 segundos que hemos puesto, devuelve FALSE. Si la función se ejecuta correctamente devuelve un array donde la primera posición contendrá la respuesta HTTP del servidor y la segunda el contenido de la respuesta. La cabecera HTTP a enviar variará dependiendo de las necesidades del momento. Es recomendable entender bien el protocolo HTTP para hacer uso de esta función. Además la respuesta HTTP del servidor también debería ser interpretada para ver lo que ha ocurrido.

Para probarlo podemos usar un servicio web para desarrolladores de Yahoo que permite obtener el timestamp (hora actual en formato UNIX).

$url = "http://developer.yahooapis.com/TimeService/V1/getTime/";
$url .= "?appid=YahooDemo";
$url .= "&output=json";
$response = readWebService($url);
if(!$response)
  echo "ERROR";
else {
  $header = $response[0];
  $content = $response[1];
  echo $content;
}
El resultado será:
{"Result":{"Timestamp":1355482897}} 

Esta técnica la podemos usar tanto para obtener datos de un web service, ya sea en formato JSON, XML u otro, como para cargar una página HTML y explorar su contenido.

martes, 11 de diciembre de 2012

Tratamiento de idiomas en CodeIgniter

Siguiendo con la serie de artículos sobre la programación del framework CodeIgniter hoy hablaré de las posibilidades de CodeIgniter respecto al tratamiento de idiomas: Veremos como convertir todo el framework al español, como hacer un proyecto multiidioma y hablaremos de la clase Language y del helper Language.


Como poner CodeIgniter en Español.

CodeIgniter como la mayoría de frameworks PHP proporciona un mecanismo para poder cambiar el idioma en que se muestra un página web. Los archivos de idioma del framework se encuentran en la carpeta "/system/language/". Dentro de dicha carpeta habrá una carpeta para cada idioma: "english" para Inglés, "spanish" para español, etc. Inicialmente sólo se proporcionan traducciones para el idioma Inglés. Si queremos el framework en español tendremos que crear la carpeta "/system/language/spanish/", copiar los archivos de la versión inglesa y traducir los textos.

El formato de los archivos de idioma lo vemos en el siguiente ejemplo:

$lang['cal_sunday'] = "Sunday";
$lang['cal_monday'] = "Monday";
$lang['cal_tuesday'] = "Tuesday";
$lang['cal_wednesday'] = "Wednesday";
$lang['cal_thursday'] = "Thursday";
$lang['cal_friday'] = "Friday";
$lang['cal_saturday'] = "Saturday";

Este fragmento es parte del archivo "calendar_lang.php". Para crear la versión en español crearíamos el archivo "/system/languge/spanish/calendar_lang.php" y traduciríamos los textos, pero no los literales:

$lang['cal_sunday'] = "Domingo";
$lang['cal_monday'] = "Lunes";
$lang['cal_tuesday'] = "Martes";
$lang['cal_wednesday'] = "Miércoles";
$lang['cal_thursday'] = "Jueves";
$lang['cal_friday'] = "Viernes";
$lang['cal_saturday'] = "Sábado";

En Internet se pueden encontrar archivos con las traducciones para los distintos idiomas. Por ejemplo en una búsqueda rápida he encontrado en github un proyecto de traducción de CodeIgniter al Español, pero los packs de idiomas no están actualizados. Lo que sí hay es está actualizado a la última versión en un manual de CodeIgniter en Español (PDF). También he encontrado un "CodeIgniter 2.0.2 Spanish Pack" en el blog de César de la Cruz. A partir de ese trabajo que creado mi propio CodeIgniter Spanish Pack actualizado a la versión 2.1.3, que es la versión oficial de CodeIgniter en el momento de escribir este artículo.

CodeIgniter 2.1.3 Spanish Pack (ZIP/8Kb). Licencia libre.


Cambiando el idioma de un proyecto.

Además de los archivos de idioma del sistema, también podemos definir nuestros propios archivos de idioma para el proyecto PHP. Estos se guardarán en la carpeta "/application/language/{lang}/" donde {lang} es el nombre del idioma (english, spanish, etc). El nombre de los archivos de idioma debe acabar en "_lang.php". Por ejemplo un archivo con mensajes de error se llamaría "error_lang.php". El formato del archivo será el mismo que se ha comentado más arriba:

$lang['error_resource_not_found'] = "Recurso no encontrado.";
$lang['error_resource_unavailable'] = "Recurso no disponible.";
//... etc.

Para poder usar un archivo de idioma primero tendremos que cargarlo. Para ello se utiliza la clase Language. Esto se hará en el controlador:

$this->lang->load('error', 'spanish');

Si no se especifica idioma, se usará el idioma por defecto, definido como una variable dentro del archivo "/application/config/config.php". Generalmente su valor es "english", pero podemos modificarlo si hemos creado la carpeta de idiomas correspondiente:

$config['language'] = 'spanish';
Luego para obtener una cadena traducida hay que llamar a la función line():
$var = $this->lang->line('error_resource_unavailable');

Esto es todo lo que se necesita para cambiar de idioma en CodeIgniter. Si queremos hacer una web multi-idioma podemos crear una cookie con el idioma del usuario y usar ese valor al cargar los archivos de idioma.


El helper Language.

En CodeIgniter un helper es un conjunto de funciones que ayudan a realizar una tarea. Podríamos traducir helper como ayudante o asistente. En concreto el helper Language contiene funciones que ayudan al programador en el tratamiento con archivos de idioma. Para poder usar este helper lo primero será cargarlo, cosa que haremos en el controlador:

$this->load->helper('language');

Una ver cargado podemos usar la función global lang() para cargar los textos de los ficheros de idiomas en lugar de $this->lang->line(). Se aconseja el uso de este helper en las vistas para favorecer la lectura de los archivos fuente. Ejemplo:

<div class="error">
<h1><?= lang('error_heading'); ?></h1>
<p><?= lang('error_resource_unavailable'); ?></p>
</div>

Fuentes y referencias:

lunes, 26 de noviembre de 2012

Ejemplo de programación con CodeIgniter

El otro día hablábamos de CodeIgniter, un framework PHP muy ligero que he descubierto recientemente. CodeIgniter implementa el modelo-vista-controlador (MVC) y permite el desarrollo de aplicaciones web de forma rápida y eficiente. En este artículo vamos a ver un ejemplo de desarrollo de una aplicación web usando CodeIgniter. Va a ser un ejemplo muy sencillo que utiliza las características básicas de CodeIgniter.

Enunciado.

Vamos a suponer que tenemos una tabla de productos y que queremos una aplicación web que muestre por un lado la lista de productos con su precio y por otro lado todos los detalles de cada producto. A continuación la tabla de productos:

CREATE TABLE `products`
( `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY
, `name` VARCHAR(64) NOT NULL
, `descri` TEXT NOT NULL
, `price` FLOAT NOT NULL
);

Las únicas URLs permitidas para nuestra aplicación web serán las siguientes:

http://www.midominio.com/ Mostrará la lista de productos.
http://www.midominio.com/productos/ Mostrará la lista de productos.
http://www.midominio.com/productos/prod/1 Mostrará los datos del producto con ID=1.


PASO 1: Descargar e instalar CodeIgniter.

Lo primero de todo será descargar CodeIgniter desde la página web del producto. Instalar CodeIgniter es muy sencillo: basta descomprimir el contenido del archivo ZIP descargado en el directorio raíz o en una carpeta del servidor web.

Al acabar la instalación se habrán creado 3 carpetas: "application" contendrá los archivos fuente de nuestra aplicación; "system" contendrá las clases base y librerías necesarias para que todo funcione; "user_guide" es el manual de utilización y puede borrarse. También se habrá creado el archivo "index.php" que será el punto de entrada de nuestra aplicación. Por ahora no debe modificarse.


PASO 2: Configurar nuestro proyecto CodeIgniter.

  • Crear un archivo ".htaccess" en la carpeta raíz de nuestro proyecto. Esto sirve para hacer las URLs de CodeIgniter más amigables, eliminando la referencia a "index.php".
  • Options -Indexes +FollowSymLinks
    RewriteEngine on
    RewriteCond $1 !^(index.php|css|js|images|robots.txt)
    RewriteRule ^(.*)$ /index.php/$1 [L]
    
  • Editar el archivo "/application/config/config.php":
  • $config['base_url'] = 'http://www.midominio.com/';
    $config['index_page'] = '';
    
  • Editar el archivo "/application/config/database.php" sustituyendo los valores de "my_username", "my_password" y "my_database" por datos reales de acceso a la base de datos MySQL:
  • $db['default']['hostname'] = 'localhost';
    $db['default']['username'] = 'my_username';
    $db['default']['password'] = 'my_password';
    $db['default']['database'] = 'my_database';
    
  • Editar el archivo "/application/config/routes.php" para especificar que el controlador por defecto del proyecto será "products":
  • $route['default_controller'] = "products";
    

PASO 3: Crear el modelo.

Como sabemos el modelo es la parte del patrón de diseño MVC que permite el acceso a los datos y concretamente nuestros datos estarán en la tabla products de una base de datos MySQL. En CodeIgniter las clases del modelo derivarán de CI_Model y se guardarán en la carpeta "/application/models/".

Creamos el archivo "/application/models/products_model.php"

class Products_Model extends CI_Model {

  public function __construct() {
    parent::__construct();
    $this->load->database();
  }

  public function selectProducts() {

    $sql = "
      SELECT `id`
      , `name`
      , `price`
      FROM `products`
      ORDER BY `id` ASC;
      ";

    $result = $this->db->query($sql);
    if(!$result) {
      return false;
    }

    return $result;
  }

  public function selectProduct($id) {

    $sql = "
      SELECT `id`
      , `name`
      , `descri`
      , `price`
      FROM `products`
      WHERE `id` = ?;
      ";

    $bindings = array(
      $id
    );

    $result = $this->db->query($sql, $bindings);
    if(!$result) {
      return false;
    }

    return $result;
  }
}

Como vemos la clase Products_Model tiene constructor y dos métodos: selectProducts() y selectProduct(). En el constructor se carga la librería de acceso a base de datos. Los métodos realizan las queries y devuelven el resultado.


PASO 4: Crear el controlador.

Nuestra aplicación CodeIgniter sólo tendrá un controlador al que llamaremos Products. La clase derivará de CI_Controller y se guardará en la carpeta "/application/controllers/":

Creamos el archivo "/application/controllers/products.php"

class Products extends CI_Controller {

  public function __construct() {
    parent::__construct();
    $this->load->helper('url');
    $this->load->model('Products_Model');
  }

  public function index() {

  $data = array( );

    $query = $this->Products_Model->selectProducts();
    if(!$query || $query->num_rows() < 1) {
      $data['product_list'] = null;
    }
    else {

      $data['product_list'] = array( );
      foreach ($query->result() as $row) {
        $product = array( );
        $product['id'] = $row->id;
        $product['name'] = $row->name;
        $product['price'] = $row->price;
        $data['product_list'][] = $product;
      }
    }

    $this->load->view('product_list', $data);
  }

  public function prod($prod_id) {

    if(!$prod_id) {
      show_404();
      return;
    }

    $query = $this->Products_Model->selectProduct($prod_id);
    if(!$query || $query->num_rows() < 1) {
      show_404();
      return;
    }

    $row = $query->row();
    if(!$row) {
      show_404();
      return;
    }

    $product = array( );
    $product['id'] = $row->id;
    $product['name'] = $row->name;
    $product['descri'] = $row->descri;
    $product['price'] = $row->price;
    $data['product_data'] = $product;

    $this->load->view('product_data', $data);
  }
}

Nuestro controlador tendrá constructor, el método index() y el método prod(). El constructor cargará el modelo Products_Model, que hemos creado anteriormente, y el helper url. Un helper es como una librería que proporciona CodeIgniter con funciones comunes de ayuda a la programación. En este caso el helper url proporciona funciones para trabajar con las URLs del sitio web: site_url(), base_url(), current_url(), etc.

El método index() llama al modelo para cargar la lista de productos y posteriomente llama a la vista product_list pasándole un array con la lista de productos que tiene que mostrar. El método prod(), que recibe como parámetro el identificador del producto, carga los datos del producto a través del modelo e invoca la vista product_data pasándole esos datos. Si el producto no existe se muestra la página de error 404.


PASO 5: Crear las vistas.

Como hemos visto, nuestra aplicación web tendrá dos vistas: product_list y product_data. Las vistas en CodeIgniter son archivos PHP que se guardan en la carpeta "application/views/".

Creamos el archivo "/application/views/product_list.php"

<!DOCTYPE html>
<html>
<head>
<title>Lista de productos</title>
<meta http-equiv="content-type" content="text/html; charset=utf8">
</head>
<body>
<h1>
  Lista de productos
</h1>
<?php if(!$product_list) : ?>
<p>
  La lista de productos está vacía.
</p>
<?php else : ?>
<ul>
<?php
  reset($product_list);
  foreach ($product_list as $product) {
    echo "<li>";
    echo "<a ";
    echo "href='", site_url('/products/prod/' . $product['id']) . "'>";
    echo $product['name'];
    echo "</a>";
    echo " ";
    echo number_format($product['price'], 2, ',', '.');
    echo "€";
    echo "</li>";
    echo PHP_EOL;
  }
?>
</ul>
<?php endif; ?>
</body>
</html>

Creamos el archivo "/application/views/product_data.php"

<!DOCTYPE html>
<html>
<head>
<title><?php echo $product_data['name']; ?></title>
<meta name="description" content="<?php echo $product_data['descri']; ?>">
<meta http-equiv="content-type" content="text/html; charset=utf8">
</head>
<body>
<h1>
  <?php echo $product_data['name']; ?>
</h1>
<p>
  <?php echo $product_data['descri']; ?>
</p>
<p>
  Precio: <?php echo number_format($product_data['price'], 2, ',', '.'); ?>€
</p>
<p>
  <a href="<?php echo site_url(); ?>">Volver a la lista</a>.
</p>
</body>
</html>

Como vemos detro de las vistas podemos usar los datos pasados desde el controlador a través del segundo parámetro del método $this->load->view() como variables globales.


Y con esto ya tenemos acabada la primera aplicación web hecha con CodeIgniter.

viernes, 23 de noviembre de 2012

PHP avanzado: orientación a objeto

PHP A menudo suele decirse que PHP 5 es un lenguaje de programación Orientado a Objetos a diferencia de las versiones anteriores de PHP, pero ¿Que significa eso? En este artículo voy a tratar de explicar que es la programación Orientada a Objetos y cuales de las características de este paradigma de la programación implementa PHP 5.


¿Qué es la Programación Orientada a Objetos?

Sobre este tema hay amplia documentación en Internet, así que seré breve. La Programación Orientada a Objetos (OOP, Object Oriented Programming) es un conjunto de técnicas de programación que permiten encapsular los datos y las operaciones en unas estructuras llamadas Clases. A una instancia de una clase se la denomina Objeto. Los objetos interaccionan entre si a través de los Métodos que exponen las clases. Esta forma de programar permite describir de forma más adecuada el mundo real que la programación estructurada o tradicional.

En la actualidad, existen variedad de lenguajes de programación que soportan la orientación a objetos. Cada lenguaje aporta algo distinto, aunque la mayoría tiene características comunes. Las más importantes son:

PHP 5 incorpora estas características y algunas otras por eso se dice que es un lenguaje orientado a objetos. Lo veremos a continuación. PHP 4 permitía crear clases e incorporaba algunas características de la orientación a objetos, pero no todas por lo que no se consideraba un lenguaje de programación orientado a objetos.


Clases y objetos.

Una clase es una estructura que encapsula los datos y las operaciones a realizar sobre esos datos. En PHP 5 los datos serán variables miembro y las operaciones serán métodos (funciones miembro). Para acceder a los datos y métodos desde dentro de la clase se utiliza la meta variable $this junto al operador "->".

class NombreClase {

  var $dato1;
  var $dato2;

  function metodo1() {
    echo $this->dato1;
  }

  function metodo2() {
    echo $this->dato2;
  }
}

Por contra un objeto será una instancia de una clase. Para acceder a los datos y métodos de un objeto se utiliza el operador "->".

$objeto = new NombreClase();
$objeto->metodo1();
echo $objeto->dato1;

Visibilidad de datos y métodos.

En PHP 5 se pueden utilizar las palabras clase public, private y protected para definir la visibilidad de cada variable miembro y método de una clase. Si no se define se asume que tiene visibilidad pública.

  • public: Visibilidad pública. Todo el mundo puede acceder a esa estructura.
  • private: Visibilidad privada. Sólo los métodos de la propia clase pueden acceder a esa estructura.
  • protected: Visibilidad protegida. Sólo los métodos de la propia clase y de las clases derivadas pueden acceder a esa estructura. Lo veremos cuando hablemos de la herencia.
class NombreClase {

  public $datoPublico;
  private $datoPrivado;
  protected $datoProtegido;

  public function metodoPublico() { /* ... */ }
  private function metodoPrivado() { /* ... */ }
  protected function metodoProtegido() { /* ... */ }
}

$objeto = new NombreClase();

echo $objeto->datoPublico; // Correcto
echo $objeto->datoPrivado; // Error
echo $objeto->datoProtegido; // Error

$objeto->metodoPublico(); // Correcto
$objeto->metodoPrivado(); // Error
$objeto->metodoProtegido(); // Error

Constantes dentro de clases.

Una constante es una variable que mantiene el mismo valor durante toda su vida. Se puede definir constantes dentro de una clase utilizando la palabra clave const. Para acceder a una constante desde dentro de la clase se utilizará la palabra clave self junto al operador de ámbito "::". Para acceder a una constante desde fuera de la clase (si la constante es pública) se utilizará el nombre de la clase junto con el operador de ámbito "::".

class NombreClase
{
    const CONSTANTE = 'valor';

    function escribirConstante() {
        echo self::CONSTANTE;
    }
}

$objeto = new NombreClase();
$objeto->escribirConstante();

echo NombreClase::CONSTANTE;

Variables y métodos estáticos.

En PHP 5 además de constantes pueden definirse variables estáticas, que son aquellas que tienen una única instancia para todos los objetos de la clase. Una variables estática tiene el mismo valor en todos los objetos de la clase igual que las constantes, pero a diferencia de éstas, su valor puede ser modificado. No se puede acceder a las variables estáticas a través del operador "->". Hay que usar el operador de ámbito "::".

class UnaClase {

    public static $varEstatica = 1;

    public function valorVarStatica() {
        return self::$varEstatica;
    }

    public function establecerVarEstatica($valor) {
        self::$varEstatica = $valor;
    }
}

$objeto1 = new UnaClase();
$objeto2 = new UnaClase();

$objeto1->establecerVarEstatica(2);
echo $objeto1->valorVarStatica(); // Imprimirá 2
echo $objeto2->valorVarStatica(); // Imprimirá 2
echo UnaClase::$varEstatica; // Imprimirá 2

También pueden declararse métodos estáticos que son aquellos que se pueden invocar sin tener creada una instancia del objeto usando el operador de ámbito "::".

class UnaClase {

    private static $varEstatica = 1;

    public static function obtenerVarStatica() {
        return self::$varEstatica;
    }
}

echo UnaClase::obtenerVarStatica(); // Imprimirá 1

Herencia.

La herencia es un mecanismo por el cual una clase hereda características de otra clase (datos y métodos). Cuando una clase hereda de otra se dice que la primera (clase hija) deriva de la segunda (clase base). La clase hija tendrá acceso a los datos y métodos públicos o protegidos de la clase base, pero no a los privados. Para indicar herencia en PHP 5 se utiliza la palabra clave extends.

class ClaseBase {

  public $dato1;

  public function metodo1() { /* ... */ }
}

class ClaseHija extends ClaseBase {

  public $dato2;

  public function metodo2() { /* ... */ }
}

$objeto1 = new ClaseBase();
echo $objeto1->dato1;
$objeto1->metodo1();

$objeto2 = new ClaseHija();
echo $objeto2->dato1;
echo $objeto2->dato2;
$objeto2->metodo1();
$objeto2->metodo2();

Herencia múltiple.

La herencia múltiple es un tipo particular de herencia en que una clase hija deriva de más de una clase base. A pesar de que ésta es una característica presente en muchos lenguajes de programación orientados a objetos, PHP 5 no permite la herencia múltiple.


Clases abstractas.

Las clases abstractas son aquellas que no pueden ser instanciadas directamente, sino que necesitan tener una clase derivada. Las clases abstractas tienen métodos abstractos que son aquellos que se definen en la clase base y se implementan en las clases derivadas. En PHP 5 se utiliza la palabra clave abstract para definir clases y métodos abstractos. Veamoslo con un ejemplo:

abstract class Figura
{
  // Miembro protegido
  protected $color;

  // Métodos públicos
  public function establecerColor($color) { $this->color = $color; }
  public function obtenerColor() { return $this->color; }

  // Método abstracto
  abstract public function dibujar();
}

class Cuadrado extends Figura {

  // Miembros
  private $x1;
  private $y1;
  private $x2;
  private $y2;

  public function dibujar() {
    // Se dibuja el cuadrado...
  }
}

class Circulo extends Figura {

  // Miembros
  private $x;
  private $y;
  private $r;

  public function dibujar() {
    // Se dibuja el círculo...
  }
}

Si intentamos crear un objeto de clase Figura se producirá un error. En cambio podemos crear objetos de clase Cuadrado o Circulo. Si intentamos crear otra clase que derive de Figura (por ejemplo Pentagono) y no definimos el método dibujar() también se producirá un error.


Interfaces.

Una interfaz es una estructura similar a una clase abstracta en el sentido que permite definir métodos abstractos que deberán implementarse en las clases que implementen dicha interfaz. La diferencia es que en una interfaz no se pueden implementar métodos (todos los métodos son abstractos) mientras que una clase abstracta puede mezclar métodos abstractos y métodos "normales". En PHP 5 todos los métodos de una interfaz deben ser públicos.

interface NombreInterfaz {

    public function metodo1();
    public function metodo2();
}

class NombreClase implements NombreInterfaz {

    public function metodo1() { /* ... */ }
    public function metodo2() { /* ... */ }
}

Una interfaz es un "contrato" que deben cumplir todas las clases que la implementen. En PHP 5 una clase puede derivar de otra (herencia) y a la vez implementar uno o más interfaces. Hay una restricción que es que los nombres de los métodos abstractos no pueden repetirse entre las diferentes interfaces ni con la clase base.

abstract class ClaseBase {

  public function metodoBase1() { /* ... */ }
  abstract public function metodoBase2();
}

interface Interfaz1 {

  public function metodoInterfaz1();
}

interface Interfaz2 {

  public function metodoInterfaz2();
}

class ClaseHija extends ClaseBase implements Interfaz1, Interfaz2 {

  public function metodoBase2() { /* ... */ }
  public function metodoInterfaz1() { /* ... */ }
  public function metodoInterfaz2() { /* ... */ }
  public function metodoHijo1() { /* ... */ }
}

$objeto = new ClaseHija();
$objeto->metodoBase1();
$objeto->metodoBase2();
$objeto->metodoInterfaz1();
$objeto->metodoInterfaz2();
$objeto->metodoHijo1();

Constructores y destructores.

El constructor es un método especial que permite inicializar las variables miembro de la clase al crear un objeto. El constructor puede tener o no tener parámetros. El destructor también es único y por contra no tiene parámetros. Es invocado por el sistema cuando ya no hay referencias a un objeto y sirve para liberar memoria al destruir el objeto. En PHP 5 se llaman respectivamente __construct() y __destruct().

class Clase1 {
 
  private $var;
 
  public function __construct($var) {
    $this->var = $var;
  }
 
  public function __destruct() {
    $this->var = null;
  }
 
  public function escribir() {
    echo $this->var;
  }
}
 
// El resultado sería => 0
$objeto1 = new Clase1(0);
$objeto1->escribir();
 
// El resultado sería => 7
$objeto2 = new Clase1(7);
$objeto2->escribir();

Desde el constructor y el destructor de una clase derivada se puede llamar al constructor (o al destructor) de la clase padre usando la palabra clave "parent" y el operador de ámbito "::".

class ClaseBase {

  private $var;

  public function __construct($var) {
    $this->var = $var;
  }
}

class ClaseHija extends ClaseBase {

  public function __construct($var) {
    parent::__construct($var);
  }
}

$objeto = new ClaseHija(3);

Sobreescritura.

La sobreescritura consiste en una técnica que permite cambiar el comportamiento de un método de la clase base en la clase derivada.

class ClaseBase {
 
  public function metodo1() {
    echo "1";
  }
}
 
class ClaseHija extends ClaseBase {
 
  public function metodo1() {
    echo "2";
  }
}
 
$objeto1 = new ClaseBase();
$objeto1->metodo1(); // Escribe 1
 
$objeto2 = new ClaseHija();
$objeto2->metodo1(); // Escribe 2

Clases y métodos finales.

Una clase final es aquella que no puede ser derivada. Análogamente un método final es aquel que no puede ser sobreescrito en una clase derivada.

final class Clase1 {
  //...
}

class Clase2 extends Clase1 {
  // Esto da error porque Clase1 está declarado como final.
}

class Clase3 {

  public final function metodo3() {
    //...
  }
}

class Clase4 extends Clase3 {

  public function metodo3() {
    // Esto da error porque metodo3() está declarado como final.
  }
}

Con esto acabo esta guía rápida de referencia para programación orientada a objetos en PHP 5. Más información en el manual oficial de PHP.

miércoles, 21 de noviembre de 2012

La nueva web de iFraktal

iFraktal Internet Marketing Dice el refrán que "en que en casa del herrero cuchara de palo" y eso es algo que suele ser cierto. También era nuestro caso: hicimos la web de iFraktal en una tarde para tener algo cuanto antes y pensando en modificarla enseguida, pero nunca había tiempo para eso. Los demás proyectos pasaban siempre por delante y la verdadera web de iFraktal nunca estaba lista. De eso hacía 5 largos años. Pero hay otro refrán que dice que "no hay mal que por bien no venga" y es que ahora que estamos en una época de poco trabajo hemos tenido tiempo de acabar, pulir y publicar nuestra página web.

iFraktal.com

Os invitamos a entrar: http://www.ifraktal.com/

lunes, 19 de noviembre de 2012

Herramientas de programación web: CodeIgniter

El otro día me estuvieron hablado muy bien de CodeIgniter, un framework para PHP, totalmente orientado a objetos, sencillo pero muy potente, así que me he puesto a investigar y aquí está el resultado.

Para empezar, ¿Qué es un framework? En términos generales un framework es un conjunto de librerías y otras herramientas que facilitan y organizan el desarrollo de software (típicamente aplicaciones web), proporcionando un marco de trabajo común (framework), unas librerías extensibles y una determinada metodología de trabajo. Muchos frameworks, especialmente los orientados a web, implementan el llamado Modelo-Vista-Controlador (MVC) que separa los distintos componentes de la aplicación en:

  • Modelo: Gestiona los datos que generalmente se encontrarán en una base de datos MySQL, aunque podrían estar en ficheros o en cualquier otra fuente.

  • Vista: Interacciona con el usuario. Presenta los datos al usuario y recoge los datos proporcionados por el mismo. En los frameworks orientados a web el modelo es el que monta la salida HTML.

  • Controlador: Gestiona y controla lo que ocurre en la aplicación. El controlador recibe la petición, obtiene los datos del modelo y llama a la vista adecuada.

En concreto el framework CodeIgniter permite realizar nuestros desarrollos PHP de forma más rápida y eficiente, proporcionando una librería de clases altamente extensible que implementa el Modelo-Vista-Controlador. Sus principales ventajas son que es rápido, que es fácil de usar, que tiene una gran documentación y que detrás hay una amplia comunidad de desarrolladores. Además es un producto de código libre para cualquier aplicación, incluso comerciales. CodeIgniter tiene muchas ayudas para la creación de aplicaciones PHP avanzadas que hacen que el proceso de desarrollo sea más rápido, obteniendo aplicaciones web más profesionales y con código más reutilizable.

Enlaces de interés:

Técnicas de programación web: AJAX

Voy a empezar con este artículo una serie sobre las distintas técnicas de programación web que son necesarias hoy en día para desarrollar un sito web: PHP, HTML, CSS, JavaScript, AJAX, JSON, XML, jQuery... Hoy hablaré de AJAX: ¿Qué es? ¿Para que sirve? ¿Como se utiliza?

La Wikipedia nos dice que AJAX es un acrónimo de Asynchronous JavaScript And XML (JavaScript asíncrono y XML) y que es un técnica de desarrollo web usada para crear sitios web interactivos o RIA (Rich Internet Applications). También que AJAX es una tecnología asíncrona, en el sentido de que los datos adicionales se solicitan al servidor y se cargan en segundo plano sin interferir con la visualización ni el comportamiento de la página. ¿Pero para que sirve? Veamos algunos ejemplos.

Ejemplos de uso de AJAX.

Hay muchas las situaciones en las que es conveniente usar AJAX pero las más clara es cuando tenemos un formulario en el que las opciones de un cuadro de selección depende del valor seleccionado en otro. Por ejemplo provincias y municipios: Al seleccionar una provincia en el primer cuadro cargaremos los municipios de esa provincia en el segundo cuadro. Otro ejemplo sería marca y modelo (de coches, de ordenadores, de electrodomésticos, etc.)

Otro ejemplo claro de uso de AJAX es cuando los datos que queremos enseñar al usuario tardan más de 1 segundo en cargarse. Para no tener al usuario esperando con una pantalla en blanco, cargaremos la pantalla de la aplicación con su menú y los demás elementos y añadiremos un mensaje tipo "por favor espere" y un GIF animado tipo reloj de arena o similar. Una vez hecho esto usaremos AJAX para cargar los datos en segundo plano y los mostraremos cuando estén listos.

¿Como funciona AJAX?

AJAX es una técnica de programación que usa el lenguaje JavaScript y un objeto XMLHttpRequest para establecer una conexión en segundo plano con el servidor desde el lado del cliente. XMLHttpRequest es un objeto disponible en la mayoría de navegadores web existentes, aunque en cada uno la implementación es diferente, que permite establecer una conexión HTTP o HTTPS con un servidor web.

La secuencia de uso es la siguiente:

  1. Se crea el objeto XMLHttpRequest. En cada navegador es diferente. Lo veremos más adelante.

  2. Se preparan los parámetros de la llamada al servidor: método (GET, POST), URL destino, argumentos, etc. Los mismos parámetros que cualquier otra llamada HTTP o HTTPS.

  3. Se realiza la llamada HTTP o HTTPS al servidor usando el objeto XMLHttpRequest.

  4. El servidor recoge la solicitud HTTP o HTTPS como cualquier otra y la procesa, generando un resultado, el cual puede ser código HTML, XML, JSON, texto plano o cualquier otro formato que quiera el programador. Siguiendo con el ejemplo de las provincias y municipios, la respuesta del servidor podría ser una simple lista de municipios separadas por comas.

  5. El objeto XMLHttpRequest recoge el resultado del servidor actúa en consecuencia, modificando el aspecto de la página web de forma dinámica mediante el uso de Javascript y DOM (Document Object Model). En el ejemplo de las provincias y municipios, recogería la lista de municipios separados por comas y cargaría el cuadro de selección con esos valores.

Creación del objeto XMLHttpRequest.

Ya he comentado que el objeto XMLHttpRequest es diferente en los distintos tipos de navegadores (Internet Explorer, Mozilla Firefox, Google Chrome, ...). Con el tiempo y la ayuda de Internet he ido desarrollando una función que me ayuda a crear el objeto XMLHttpRequest en todos ellos. En Google se pueden encontrar decenas de funciones con el mismo propósito, todas ellas muy similares. Esta está creada a partir de la adaptación de varias de ellas.

function createXMLHttpRequest() {

  var http_request = null;
  if(window.XMLHttpRequest) {

    // Mozilla, Chrome, etc.
    http_request = new XMLHttpRequest();
    if(http_request.overrideMimeType) {
      http_request.overrideMimeType("text/xml");
    }
  }
  else if(window.ActiveXObject) {

    // IE
    try {
      http_request = new ActiveXObject("Msxml2.XMLHTTP");
    }
    catch(e) {

      try {
        http_request = new ActiveXObject("Microsoft.XMLHTTP");
      }
      catch(e) {}
    }
  }

  if(!http_request) {
    return null;
  }

  return http_request;
}

La función createXMLHttpRequest() devuelve el objeto XMLHttpRequest del navegador o bien devuelve NULL si no puede crearlo.

Preparación de argumentos y llamada HTTP.

var http_request = createAjaxObject();

function makeAjaxCall(url) {

  if(http_request == null) {
    return false;
  }

  http_request.onreadystatechange = ajaxResponse;
  http_request.open("GET", url, true);
  http_request.send(null);
  return true;
}
  • La función makeAjaxCall() prepara los parámetros del objeto XMLHttpRequest y realiza la llamada HTTP/GET.

  • El parámetro url será la URL destino. Por ejemplo podría ser algo similar a: "http://www.midominio.com/ajax/cargarmunicipios.php?provincia=08".

  • ajaxResponse() es el nombre de la función JavaScript que procesará la respuesta del servidor a la petición HTTP.

Procesamiento asíncrono del resultado.

function ajaxResponse() {

  // Validación de que haya un objeto AJAX
  if(!http_request)
    return;

  // Esperamos la respuesta correcta
  if(http_request.readyState != 4)
    return;

  // Página no disponible o URL erronea
  if(http_request.status != 200)
    return;

  // Obtención de la respuesta AJAX.
  var text = http_request.responseText;
  if(!text)
    return;

  // Aquí ya tenemos el resultado en la variable text
  // (...)
  • http_request.readyState almacena el estado de la solicitud HTTP: 0=No iniciado; 1=Cargando; 2=Cargado, 3=Datos parciales, 4=Completado. Sólo hay que tener el cuenta las respuestas con estado 4. Los otros estados pueden usarse para controlar que el proceso funciona correctamente.

  • http_request.status almacena el estado de la respuesta de la solicitud HTTP: 200=Correcto; 404=No encontrado, 500=Error de servidor, etc. La documentación completa de códigos de retorno HTTP puede consultarse en la Wikipedia.

  • http_request.responseText almacena el texto de respuesta de la solicitud HTTP. Dicha respuesta puede ser un texto plano, código HTML, código XML, código JSON, o incluso cualquier tipo MIME.

jueves, 15 de noviembre de 2012

Poner código fuente en colores en un blog

Gracias a un comentario en el artículo sobre como cargar más datos en un ListView al llegar al final, de la serie de programación Android, he descubierto como añadir colores y formato al código fuente en un artículo de blog. Doy las gracias a Juan Manuel Boehme por su aportación.

La verdad es que es bastante sencillo. Yo pensaba que sería bastante más complicado, pero no. El artículo Poner código fuente en colores en un blog lo explica perfectamente. Se puede encontrar más información en Publicar código fuente en Blogger.

El "truco" está en utlizar la librería JavaScript SyntaxHighlighter de Alex Gorbatchev. Dicha librería es un resaltador de código fuente en páginas HTML que funciona con múltiples lenguajes: PHP, Java, C++, Javascript, SQL, XML, HTML, etc.

Para usarlo en Blogger hay que incluir los archivos de la librería en la cabecera HTML del blog (). Para ello hay que entrar en Blogger -> Acceder al blog -> Plantilla -> Edición de HTML -> Continuar.


<link rel='stylesheet' type='text/css'
href='http://alexgorbatchev.com/pub/sh/current/styles/shCore.css' />

<link rel='stylesheet' type='text/css'
href='http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css' />

<script type='text/javascript'
src='http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js' />

<script type='text/javascript'
src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPhp.js' />

<script type='text/javascript'
src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJava.js' />

<script type='text/javascript'
src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js' />

<script type='text/javascript'
src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCss.js' />

<script type='text/javascript'
src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushSql.js' />

<script type='text/javascript'>
SyntaxHighlighter.config.bloggerMode = true;
SyntaxHighlighter.all();
</script>

En este ejemplo he añadido los archivos necesarios para colorear la sintaxis en PHP, Java, XML/HTML, CSS y SQL, pero se pueden incluir muchos más como C, C#, C++, Delphi o Ruby, entre muchos otros.

Luego para usarlo en el artículo basta escribir lo siguiente:

<pre class="brush: lenguaje">
 Aquí va el código fuente
</pre>

...sustituyendo lenguaje por el identificador del lenguaje de programación con que se coloreará la sintaxis: php, xml, css, sql, c, cpp, js, ...

Una cosa más a tener en cuenta es que en el código fuenta hay que sustituir los caracteres menor (<) y mayor (>) por sus correspondientes entidades HTML: &lt; y &gt;. Si no se hace así, la librería puede fallar.

lunes, 12 de noviembre de 2012

Como añadir publicidad a una página web II: Programas de afiliación

En el capítulo anterior explicábamos como podíamos usar Google Adsense para añadir un banner publicitario a una página web. El problema de Google Adsense es que los editores tienen poco control sobre los anuncios que realmente salen en su página web. Se supone que Adsense revisa el contenido de la página para publicar anuncios relevantes, pero no siempre funciona todo lo bien que sería deseable. Además puede ocurrir que lo que los editores quieran es que los anuncios que aparezcan en su web sean de una temática totalmente distinta al contenido, aunque relacionada. Un ejemplo podría ser una web de recetas de cocina que en lugar de aparecer anuncios de otras webs de recetas podía ser deseable que aparecieran anuncios por ejemplo de moda o clubs de compras. Esto con google Adsense también puede hacerse pero es complejo.

La solución en estos casos suele ser los programas de afiliación. En este artículo voy a tratar de explicar que son y como se utilizan los programas de afiliación. También daré una lista de los más importantes que operan en España.

¿Qué es un programa de afiliación?

De forma genérica se puede definir un programa de afiliación como un acuerdo entre un editor (el afiliado) y un vendedor (el anunciante), por el cual el afiliado promociona uno o varios productos o servicios del anunciante a través de medios electrónicos como una página web y a cambio recibe un beneficio económico (comisión).

Cómo funciona un programa de afiliación?

Existen distintos tipos de programas de afiliación pero lo más habitual consiste en que el afiliado incluya en su página web o blog bien un anuncio publicitario del anunciante (banner) o bien un enlace de texto (link). Ese anuncio o enlace se mostrará a los usuarios de la web de forma que cuando éste pulse en uno, se abrirá la página web del anunciante. Cuando el usuario realiza una determinada acción en la web del anunciante, como realizar una compra o rellenar un formulario de registro, se pagará la comisión correspondiente al afiliado.

Para ello tanto los anuncios como los enlaces de texto tienen un código especial que identifica al afiliado de forma única para el anunciante.

¿Qué tipos de comisiones hay?

La forma de la comisión puede ser de varios tipos y depende totalmente del acuerdo al que lleguen el anunciante y el afiliado:

  • CPM: Pago por mil impresiones. El anunciante pagará un determinado importe al afiliado por cada 1000 impresiones de sus anuncios. Este suele ser el tipo de comisión más deseado, pero es muy difícil que el anunciante lo ofrezca y si lo hace generalmente sólo se lo ofrece a unos pocos afiliados premium (páginas muy relevantes o con miles de visitas).

  • CPC: Pago por clic. El anunciante pagará un importe por cada clic en sus anuncios. Este sería el modelo de Google Adsense. Ahora muy pocos afiliados lo ofrecen directamente.

  • CPL: Pago por registro. El anunciante pagará un importe fijo por cada vez que un usuario rellene un formulario, ya sea para registrarse en una web, para apuntarse a un concurso, para recibir una newsletter o para solicitar información de algún producto o servicio. Este tipo de comisión es bastante común.

  • CPS o CPA: Pago por venta. Es el tipo de comisión más común en los programas de afiliación. El anunciante pagará bien una comisión fija o bien un porcentaje por cada venta realizada a un usuario que ha accedido a su web a través de un anuncio o enlace puesto en la web del afiliado. Por ejemplo el afiliado pone un anuncio de una agencia de viajes, el usuario hace clic en el anuncio y compra un vuelo de 100€ y el afiliado se lleva una comisión de ese vuelo (por ejemplo un 5%).

Los tipos de comisión más común suelen ser CPS y CPL, pero en ocasiones se ofrecen sistemas mixtos como CPC + CPS. Antes de afiliarse a un programa hay que leer y entender bien las condiciones para saber cuanto podemos ganar. Si se hace bien se puede ganar mucho más dinero con una comisión tipo CPS que con CPM o CPC, pero estas últimas son más estables.

También hay otros tipos de comisión menos comunes como doble clic que requiere que el usuario haga al menos un segundo clic dentro de la web del anunciante. Y es que cada programa de afiliación es un mundo...

Ejemplo:

El siguiente ejemplo es un banner publicitario del programa de afiliación de DELL que promociona el nuevo DLL XPS 12 Ultrabook. La comisión en este caso es 5% CPS. Es decir que DELL nos pagará un 5% del precio de compra de todos los productos comprados por el usuario en su web tras hacer clic en el anuncio.

Dell XPS 12 Ultrabook

Restricciones de los programas de afiliación

Algunos programas de afiliación tienen restricciones como que no se pueden incluir anuncios en páginas de contenido sexual o páginas que fomenten la violencia. Otros prohíben que las páginas donde se inserten los anuncios sean promocionadas a través de otros sistemas publicitarios como Google Adwords. Otras tienen restricciones aun más raras. Muchos anunciantes cuidan de forma especial su imagen de marca y establecen unas directrices que hay que cumplir.

Como dije arriba hay que leer bien las condiciones de cada programa de afiliación. En caso de que no se cumplan, si el anunciante se entera, puede cancela todas las comisiones generadas. No todos los anunciantes revisan las webs de los afiliados al 100%, pero hay algunos muy puñeteros.

¿Como me uno a un programa de afiliación?

Algunas empresas llevan sus propios programas de afiliación. Ellos buscan en Internet páginas donde promocionar sus productos y contactan con los editores, llevan un control de las ventas y pagan a los afiliados, pero no es lo habitual. Generalmente los anunciantes confían en las llamadas empresas de afiliación, las cuales ponen en contacto a afiliados y anunciantes, proporcionando sistemas de seguimiento de comisiones útiles tanto para los afiliados como para los anunciantes.

El funcionamiento es el siguiente:

  1. El editor se da de alta en la empresa de afiliación convirtiéndose en afiliado.

  2. El afiliado revisa los anunciantes que trabajan con la empresa de afiliación y solicita los programas de afiliación que le interese.

  3. El anunciante recibe la solicitud de afiliación y acepta al afiliado (o le rechaza). Esto puede tardar unos días.

  4. El afiliado revisa entonces el material publicitario disponible para ese anunciante e incluye en su página web los anuncios o enlaces que prefiera. Esos anuncios tendrán el código de seguimiento proporcionados por la empresa de afiliación.

  5. El afiliado puede revisar a diario el número de veces que se ha imprimido cada anuncio, el número de clics, los registros, las ventas y las comisiones. Todo ello a través de la empresa de afiliación.

  6. A final de mes, la empresa de afiliación se encarga de cobrar al anunciante y pagar al afiliado las comisiones conseguidas.

Las principales empresas de afiliación

  • Tradedoubler. Es una empresa de origen Sueco fundada en 1999 que cuenta con oficinas en 18 países, incluyendo España. Tienen más de 1800 programas de afiliación de muchos países. Está reconocida como una de las mejores plataformas de afiliación de Europa. Destaca la claridad de su página web, el gran número de estadísticas a disposición de los afiliados y la cantidad y calidad de sus anunciantes.

  • Zanox. Fundada en el año 2000 y de origen Alemán, Zanox cuenta con oficinas en España y en otros 12 países entre Europa y América. A nivel mundial tiene más de 600 empleados y unos 4000 anunciantes. Su gran ventaja es la cantidad de anunciantes diferentes y que cuentan con algunos programas válidos en muchos países con el mismo código. Como desventaja, las estadísticas no son tan claras, aunque han mejorado en este aspecto en los últimos tiempos.

  • Affilinet. Es una red de afiliación fundada en 1997 con presencia en varios países europeos. Desembarcó en España en 2008 y desde entonces tratan de afianzarse en nuestro mercado. Tiene más de 100 empleados a nivel internacional. Están haciendo un gran trabajo y cada vez cuentan con más anunciantes. Su página web es mejorable: ofrece mucha información al afiliado pero es poco intuitiva.

  • Webgains. Es otra red de afiliación fundada en 2004 con el propósito de alcanzar una presencia seria y profesional en el sector del marketing on-line. Llegaron más tarde, pero están recuperando terreno gracias a un buen trabajo, aunque su página web es claramente mejorable y sus estadísticas son difíciles de entender.

  • NetAffiliation. Empresa de afiliación internacional de origen Francés creada en 2004. Ha sido mejor plataforma de afiliación en Francia durante los años 2006, 2007 y 2008. Su página web es bastante caótica y sus estadísticas están muy limitadas, pero cuentan con buenos programas de afiliación.

  • Public-Ideées. Es otra compañía de origen francés especialista en marketing de resultados. Cuentan con más de 35 programas de afiliación sólo en España. Su página web es clara y está bien planteada pero sus estadísticas son las peores del sector.

  • Commision Junction. Es una compañía de origen Estadounidense fundada en 1998 que forma parte del grupo ValueClick. Tiene su sede en Santa Bárbara, California (EE.UU.) y cuenta con oficinas en todo el mundo. Probablemente sea la mayor empresa de afiliación del mundo. Pese a todo su página web está entre las peores del sector y sus estadísticas son totalmente incomprensibles. Su ventaja es la gran cantidad de anunciantes internacionales que tienen.

  • Netfilia. Es una empresa española especialista en marketing de resultados y programas de afiliación. Cuenta con una red de más de 30.000 afiliados y tiene presencia en Italia, Portugal, Francia, Alemania e Inglaterra, además de en España.

  • Argonas. Es una red de Afiliación perteneciente al Grupo Planeta, creada en 2008 y con sede en Barcelona. Fueron los últimos en llegar, pero se están poniendo rápidamente al día, operando principalmente con anunciantes Españoles.

miércoles, 7 de noviembre de 2012

Como añadir publicidad a una página web I: Google Adsense

Hoy quiero hablar de algo muy importante. Si tienes un blog o una página web con un cierto número de visitas y quieres sacar algún rendimiento económico a tu trabajo a lo mejor has pensado en añadir publicidad pero ¿Como hacerlo?. Algunas plataformas como Blogger te ayudan a añadir monetizar tu blog añadiendo publicidad a través del programa Google Adsense pero no es obligatorio usar Blogger para usar Adsense. Veamoslo...

¿Qué es Google Adsense?

Adsense es el programa de publicidad on-line de Google que permite a los editores alquilar parte de su página web para incluir anuncios publicitarios. Dichos anuncios pueden ser gráficos (banners), enlaces de texto o anuncios interactivos avanzados. El editor configura las preferencias del anuncio (tamaño, estilo, colores, etc.) y recibe un código javascript que debe incrustar en su página web.

¿Cómo funciona?

Una vez configurado el anuncio cada vez que se muestre la página web aparecerá la publicidad junto con el resto de elementos. Cuando el usuario que está viendo la página haga clic en uno de los anuncios será redirigido a la página del anunciante y el editor recibirá un importe por dicho clic que variará de un anuncio a otro. Generalmente serán unos pocos céntimos pero podría ser hasta 0,50€ o incluso más bajo ciertas condiciones. El importe se va acumulando y a final de mes si se llega a una cantidad mínima se realiza el pago mediante trasferencia bancaria. Si no se llega al importe mínimo, que actualmente es de 70€, se acumulará para el mes siguiente. Nunca se pierde.

Ejemplo: (cuadrado 250x250)

¿Qué tipos de anuncio muestra?

Todos los anuncios de Adsense provienen de Google Adwords, el programa publicitario on-line de Google para anunciantes, donde los anuncios compiten entre si en una especie de subasta virtual. En cualquier caso Adsense examina el contenido de la página y muestra anuncios relevantes. Por ejemplo en una web de viajes mostrará anuncios de vuelos o de hoteles; en una web tecnológica mostrará anuncios de ordenadores, antivirus o similares. Al menos en teoría porque esto no siempre es así. En realidad el editor puede tener control total sobre los anuncios que se muestran bloqueando URL's concretas, categorías o redes, pero entonces es posible que no se muestre ningún anuncio.

¿Cómo empezar?

Lo primero es tener una cuenta Google válida. Luego acceder al programa Google Adsense, registrarse, añadir los datos de facturación y crear el primer anuncio.

Basta introducir un nombre, elegir el tamaño y el tipo de anuncio. Opcionalmente se pueden crear criterios de seguimiento personalizados (útil si se insertan anuncios en webs diferentes) y definir estilos. Una vez acabado se pulsa Guardar y obtener código para conseguir el código Javascript que hay que insertaremos en nuestra web.

El propio programa Google Adsense proporciona estadísticas diarias de impresiones, clics e ingresos globales y por criterio de seguimiento. Aquí podéis encontrar más información las políticas del programa de AdSense.

Por último sólo me queda decir que si llegáis una página web cualquiera y os gusta el contenido hagáis clic de vez en cuando en la publicidad.

martes, 6 de noviembre de 2012

Pepephone, así sí

Hace tiempo que traspasamos las líneas de móvil a Pepephone gracias a las recomendaciones de los amigos. Desde entonces estamos contentísimos: redujimos la factura más de un 50% y no hemos tenido ni un solo problema con ellos. Anteriormente habíamos estado primero con Movistar (unos 5 años) y luego con Vodafone (más de 5 años) y en ambos casos tuvimos problemas diversos como errores de facturación, facturas imposibles de descifrar, teleoperadores inútiles, cabreos varios y todo ello con tarifas altas. Con Pepephone llevamos 6 meses y ni un sólo problema. Facturas claras, tarifas adecuadas para nuestro consumo, servicio excelente, ...

Ahora además Pepephone nos acaba de enviar un e-mail que dice que cambian las condiciones con el tratamiento de reclamaciones de facturación pero, y aquí está la novedad, las cambian para favorecer al cliente: Cuando un cliente reclame se le devolverá el dinero y si posteriormente comprueban que los cargos eran correctos se los explicarán y se los volverán a cobrar (como es lo justo).

Ya digo que con ellos aun no he tenido ningún problema pero se lo que es pelearme con los teleoperadores de las "telefónicas" de este país, por lo que iniciativas como esta se agradecen.

A continuación reproduzco la carta íntegra de Pepephone a sus clientes:

Estimado cliente,

A partir de hoy incorporamos una nueva forma de ver los cosas en nuestra atención al cliente.

Aunque seguimos siendo una compañía pequeñita y tenemos pocas reclamaciones, cada vez son más, y está ocurriendo un efecto sorprendentemente ridículo que nos gustaría explicarte:

1.- Un cliente tiene un problema pequeño, por ejemplo, unas llamadas que él cree que no ha hecho.

2.- El cliente se enfada un poco, o mucho, como es lógico, al menos mientras no reciba una explicación (que casi siempre la hay).

3.- El cliente nos llama para reclamar. Nosotros atendemos la llamada, pero necesitamos tiempo para poder examinar todo y verificar si es correcto o se trata de un error.

4.- El cliente, entre tanto, está enfadado porque piensa que está pagando una equivocación nuestra (o de alguien) y, por su experiencia, presupone que las compañías de telecomunicaciones acabamos siempre toreando al cliente y jamás devolviendo el dinero.

5.- Nosotros, por nuestra parte, también estamos preocupados porque somos conscientes de ello y porque también sabemos que pueden pasar días hasta que un técnico nuestro pueda analizar la reclamación.

El resultado es que, por una incidencia menor, el cliente se enfada, nosotros nos estresamos y al final los dos salimos perdiendo.

En teoría esto no tiene solución porque siguiendo la práctica habitual en telecomunicaciones, si hay un error de facturación, hasta que no se demuestre lo contrario, el cliente paga y, si se le hace esperar mucho tiempo, incluso consigues que renuncie a la reclamación.

Como no queremos estar estresados ni que vosotros estéis enfadados, vamos a darle la vuelta a las cosas y los dos salimos ganando:

A partir de hoy siempre que un cliente tenga una queja o duda menor sobre la facturación tendrá la razón por defecto y se le devolverá el dinero automáticamente. De esta forma, tú no tienes que hacer nada, ni siquiera enfadarte, y la presión para ver si el cargo era correcto o no recae en nosotros. Si no somos capaces de comprobar posteriormente que era correcto, los que perdemos el dinero somos nosotros. Y si tardamos tiempo, también. Eso sí, si posteriormente analizamos el cargo y te podemos explicar que era correcto, entonces te lo detallaremos y anularemos la devolución, tal y como entendemos que es justo. Si tardamos más de 45 días en averiguarlo, renunciaremos a ello.

Ahora el tiempo y las molestias sólo van en nuestra contra.

Esperamos que con esta forma de ver el problema tú como cliente estés más tranquilo. A cambio, nosotros estamos también más relajados porque, aunque todo el mundo piense lo contrario, agobia más tener detrás a un cliente enfadado que a un accionista

Gracias por tu confianza.
El equipo de Pepephone

Ya podían aprender las "grandes".

lunes, 5 de noviembre de 2012

Usando SHA1 y MD5 en Javascript

Buscando una implementación de las funciones sha1() y md5() en Javascript me he topado con la web PHPJS.org que ofrece una implementación de funciones PHP en Javascript bajo licencias de código abierto MIT y GPL, lo cual significa que podemos usarlo libremente en nuestros proyectos de software siempre que cumplamos los términos de la de la licencia.

Algunos ejemplos:

Como veis son funciones muy útiles y de uso muy común en PHP. Aquí se encuentra la lista completa de funciones PHP implementadas en Javascript.