Diseño y programación de un portfolio web con CakePHP

Una de las secciones que más he cuidado de dejandomarcas.com v2.0 es el portfolio. Al programar con CakePHP he podido diseñar un controlador que me obtenga todos los datos de mis trabajos de forma clara y ordenada, dejando a la vista que se encargue de cómo quiero mostrarlo en pantalla.

A continuación voy a explicar cómo lo he hecho, tanto el código del controlador, como el diseño de la vista, para que si quereis montar una galería de imágenes o un portfolio personal, podais hacerlo de una forma sencilla, siempre utilizando CakePHP, así aprendemos un poquito de este maravilloso framework.

Creo el modelo -> app/models/portfolio.php

<?php 

// Este es el modelo que uso para trabajar con la bd
class Portfolio extends AppModel {
	
  // Nombre modelo
  public $name = 'Portfolio';
	
  // Nombre tabla BD
  public $useTable = 'portfolio';

  // Campo de ordenación por defecto
  public $order = 'Portfolio.id DESC';
	
  // Usado para la validacion de los datos de entrada dentro del panel de administracion
  public $validate = array(
    'nombre' => array('required' => array('rule' => 'notEmpty', 'message' => 'name can not be empty')),
    'descripcion' => array('required' => array('rule' => 'notEmpty', 'message' => 'description can not be empty'))
  );
}

?>

Creo el controlador -> app/controllers/home_controller.php


<?php

class HomeController extends AppController {

  // Nombre controlador
  public $name = 'Home';

  // Modelos empleados
  public $uses = array('Portfolio');

  // Disposición de diseño por defecto
  public $layout = 'main';

  // Componentes utilizados	
  public $components = array('String');

  // Helpers utilizados
  public $helpers = array('String');

  /* METODOS PUBLICOS */
	
  // Indice de trabajos
  public function index() {
	
    // Busco todos los registros
    $registers = $this->Portfolio->find("all", array("conditions" => array("Portfolio.ver" => 1)));
				
    // Seteo el registro y los medios
    $this->set('registers', $registers);
  }
	
  // Metodo para lanzar una URL del portfolio sumando uno a las visitas que ya tenia
  public function getURL($id) {

    // No renderizo la vista
    $this->autoRender = false;
		
    // Busco el registro correspondiente a la id recibida
    $register = $this->Portfolio->find("first", array("conditions" => array("Portfolio.id" => $id)));
		
    // Recupero la id
    $this->Portfolio->id = $id;
		
    // Sumo uno a las visitas
    $visitas = $register['Portfolio']['visitas'] + 1;

    // Guardo los datos
    if ($this->Portfolio->saveField('visitas', $visitas)) {
			
      // Lanzo la URL
      $this->redirect($register['Portfolio']['enlace']);
    }
  }
}
?>

Y por último, la vista -> app/views/themed/default/home/index.ctp


<div id="bread">
  <?php echo $html->image('main/blue-folder-open-document.png')?><?php echo __('latest works');?>
</div>
<?php
  // Recorro los registros del controlador
  foreach ($registers as $register) {
?>
  <div class="project">
    <div class="box">
      <a href="<?php echo $html->url(array('controller' => 'home', 'action' => 'getURL', $register['Portfolio']['id'])); ?>" target="_blank">
        <?php echo $html->image($register['Portfolio']['imagen'], array('alt' => __($register['Portfolio']['nombre'], true)))?>			
      </a>
    </div>
    <h2><?php echo $register['Portfolio']['nombre'];?></h2>
    <p>» <?php echo utf8_encode($register['Portfolio']['descripcion']);?></p>
  </div>
<?php
}
?>

Con estos tres archivos ya tengo declarado el modelo de datos que voy a utilizar junto con sus validaciones para el panel de administración, el controlador que me ayuda a declarar todos los métodos para gestionar los datos, y por último, la vista, que mostrará en pantalla los datos obtenidos.

El resultado es el que veis en http://www.dejandomarcas.com/index.php/home

¿Tenéis dudas?, pues animaros y comentar!

Anuncios

Comprobar user-agent iphone o android con PHP

¿Cómo puedo comprobar si el cliente que visita mi web usa iPhone o Android?

Mi solución personal en forma de función:

<?php

// Compruebo el user-agent mediante una expresion regular
function iPhoneCheck() {
    if (preg_match('/iPhone/i', $_SERVER['HTTP_USER_AGENT']) || preg_match('/Android/i', $_SERVER['HTTP_USER_AGENT']))
        return true;
    else
        return false;
}

// Forma de uso
if (iPhoneCheck()) {
    
    // Resto de codigo y acciones

}

?>

¿Cómo lo haceis vosotros?

Dejandomarcas.com V2.0

Ya está arriba la nueva versión de Dejandomarcas.com

He procedido a reprogramar toda la aplicación usando CakePHP. El diseño también ha sufrido un cambio drástico, mostrando una cara mucho más limpia, más fresca y mucho más intuitiva.

Espero que os guste :]

Una oferta de trabajo bastante curiosa

Creías haberlo visto todo en las ofertas de trabajo? yo creo que no…

<?php

define('LATITUDE',40.4222691);
define('LONGITUDE',-3.699632);
define('HOST_URL', 'http://simbiotica.es');
define('AVAILABILITY','<<Insert your avaiability here>>');
define('MIN_EXPERIENCE',86400*30*12);
$langs = array('es', 'en');
define('LANGS', serialize($langs));
define('DEBUG_TIME',86400*30*3);
define('RUN_TIME',86400*30*6-DEBUG_TIME);
set_time_limit(0);
//needed to run.
require 'php.inc';
require 'sql.inc';
//highly recommended.
include 'webServices.inc';
include 'oop.inc';
include 'javaScript.inc';
include 'jQuery.inc';
//not needed, but would improve performance.
include 'gmapsAPI.inc';
include 'facebookAPI.inc';
include 'serverConfig.inc';
include 'as3.inc';

public function daylyWork(){
	backendProgramming();
	backendIntegration();
	dataModeling();
	databaseMaintenance();
}

private function checkAvailability(){
	switch (AVAILABILITY){
		case 'in house freelance':
		return true;
		break;
		
		case 'part time':
		return true;
		break;
		
		case 'full time':
		return true;
		break;
		
		case 'work from home':
		return false;
		break;
	
 	}
}

private function calculateSalary($experience, $work_hours, $responsibility, $added_value){
	//human interaction needed here
	//No reliable algorithm
}

if(interested && checkAvailability(AVAILABILITY)){
	$toEmail= 'info@simbiotica.es';
	$subject = 'Oferta de empleo';
	$html = '<html>
					<head>					
					</head>					
					<body>
							
					<< Insert your online portfolio & comments here >>
					
					</body>
				</html>';
	$headers = "From: YOUR NAME HERE <YOUR E-MAIL HERE>\r\n";
	$headers .= "MIME-Version: 1.0\r\n";
	$headers .= "Content-type: text/html; charset=utf-8\r\n";
			
	mail($toEmail, $subject, $html, $headers);
}

?>

Visto en Simbiotica.es

CakePHP – Cómo hacer un contador de visitas

Desde hace unos meses estoy programando con CakePHP y no deja de asombrarme su simplicidad y su potencia a la hora de programar cualquier aplicación web. Haciendo mi portfolio, se me ocurrió la idea de montar un contador de clics para mis diferentes trabajos, de manera tal que cuando un usuario haga clic en un trabajo para lanzar la URL, el sistema registra ese clic en la base de datos.

Cómo se haría esto?, fácil:

<?php

/* Esto es un metodo del controlador, por tanto, debera estar en app/controllers/controller.php

// Metodo para lanzar una URL del portfolio sumando uno a las visitas que ya tenia
public function getURL($id) {

     // Lo defino en false para no renderizar la vista
     $this->autoRender = false;
		
     // Busco el registro correspondiente a la id recibida
     $register = $this->Portfolio->find("first", 
                                   array("conditions" => array("Portfolio.id" => $id)));
		
     // Recupero la id
     $this->Portfolio->id = $id;
		
     // Sumo uno a las visitas
     $visitas = $register['Portfolio']['visitas'] + 1;

     // Guardo los datos
     if ($this->Portfolio->saveField('visitas', $visitas)) {
			
          // Lanzo la URL
          $this->redirect($register['Portfolio']['enlace']);
     }	
}

?>

De esta manera, cuando alguien haga clic sobre uno de mis proyectos, primero lo localizo, después le sumo uno a las visitas y después utilizo el método redirect para redirigirlo a la URL del proyecto que ha elegido.

Para usar este método, en la vista habrá que montar el link de la siguiente manera:

<?php

// Sobre el enlace HTML, definimos el nombre del controlador, la accion, y el registro
<a href="<?php echo $html->url(array('controller' => 'Name',
                                     'action' => 'getURL', 
                                     $register['Portfolio']['id'])); ?>" target="_blank">Link</a>

?>

De esta manera, ya podemos saber cuántos clics recibe un vínculo de nuestra web.

Referencia CakePHP Cookbook

Buenas prácticas a la hora de programar

Muchas veces, cuando empezamos un nuevo proyecto, nos sentamos como locos y nos ponemos a escribir como alma que lleva el diablo. A la hora de programar o de realizar cualquier tarea en nuestra vida cotidiana, es recomendable pensar durante unos mínutos qué voy a hacer, cómo lo voy a hacer y con qué objetivo tengo que hacerlo.

A lo largo de mi experiencia como programador web, he aprendido una serie de buenas prácticas a la hora de desarrollar un proyecto. De la misma manera que calentamos y estiramos los músculos antes de salir a correr, debemos analizar la situación antes de liarnos a escribir líneas y líneas de código.

He aquí mi lista de buenas prácticas a la hora de programar:

  1. Antes de encender si quiera el ordenador, toma papel y lápiz y empieza a plasmar todo lo que se te ocurra del proyecto que tienes entre manos. Muchas veces necesitamos ver las cosas en papel para que nuestra mente se abra más de lo que pensábamos que estaba abierta.
  2. Organiza, plantea y asegura un buen plan de trabajo. Divide el proyecto por partes y asigna prioridades o fases de desarrollo.
  3. Si no usas un framework o ningún patrón de diseño, diseña un buen árbol de archivos para organizar el trabajo, evitarás tener carpetas duplicadas y archivos en lugares que no deberían estar.
  4. Organiza un entorno de desarrollo, uno de pre-producción y otro de producción.
  5. No diseñes/programes solo para un navegador, lamentablemente más del 80% de los usuarios siguen navegando con Iexplorer, incluso con la versión 6.
  6. A la hora de escribir tu código, es aconsejable comentar la fecha, hora, lugar, proyecto, etc. en la cabecera, nos ayudará a tener un plano temporal de cuándo programaste y por qué lo hiciste.
  7. Organiza bien el código, indenta, COMENTA, separa los diferentes bloques, indica qué estás haciendo y qué resultados necesitas.
  8. Hago incapie en comentar el código. Recuerda que no solo programas para tí. Si estás en una empresa o en un grupo de trabajo, el código que programes posiblemente pasará a otra persona, cuyos comentarios que incluiste le ayudarán a entender lo que has hecho y a seguir el trabajo. También es bueno comentar lo que haces porque, nunca se sabe cuándo tendrás que retomar un proyecto, o reutilizar una clase o un conjunto de funciones. Deja tus migas de pan y nunca perderás tu camino.
  9. Utiliza nombres de variables y funciones que sean acordes con lo que estás programando. Por ejemplo, si necesitas guardar la fecha de alta de un registro en el sistema, no uses $var o $fecha a secas, sé más intuitivo pues el nombre de las variables nos ayudan a comprender qué guardan en su interior. $created o $modified son términos de ejemplo.
  10. Documéntate, comparte, lee mucho código de otras personas. Tu mente es un lugar con espacio infinito para guardar información, no pienses que tu código es perfecto, pues millones de personas posiblemente ya han programado lo que estás haciendo y tienen un punto de vista muy interesante sobre tu problema. No dudes en leer el código de los demás, te ayudarán a enteder mejor el lenguaje de programación viendo su solución.
  11. Respalda tu información, haz backups de tu proyecto pues, no hay nada peor que estar trabajando y que por un corte de luz todo tu trabajo se vaya al traste.
  12. Reutiliza tu código todo lo que puedas, no repitas los mismos bloques una y otra vez. Recuerda que al modular estás ahorrando tiempo, costes, trabajo y lo más importante, factor de errores.
  13. Depura, depura y depura. No pares de depurar todo lo que hagas. Hasta el más mínimo error debería ser cotejado y tenido en cuenta antes de que un maravilloso FATAL ERROR arruine todo tu trabajo.
  14. Sal con tus amigos, haz deporte, come de forma sana y saludable, tómate dos cervezas a mi salud y recuerda, tienes una vida ahí fuera libre de ceros y de unos, de bucles y funciones, de clientes que no saben lo que quieren y de proyectos que nunca acaban. Disfruta!

Cuáles son vuestras prácticas a la hora de programar?

Pirámide de asteriscos con PHP – Esta vez, con OOP

Tras crear nuestra pirámide de un modo simple y después de un modo un poquito más complicado, cómo podríamos unir las dos formas en una sola?. El método es bastante sencillo. He creado una clase que, dependiendo de los valores que reciba, nos va a dibujar una pirámide u otra. Es imprescindible entender cómo funciona la programación orientada a objetos para entender esta solución.

Aquí va el código, podéis guardar el archivo como piramide.class.php

<?php

class piramide {
	
	// Propiedades de la clase
	public $plane = array();
	public $range = null;
	public $piramide = null;
	public $cols = 0;
	public $cont_pos = 0;
	public $cont_neg = 0;
	public $char = "*";
	public $salto = "<br />";
	
	// Constructor de la clase
	public function __construct($rows, $cartesian = true) {
	
		// Compruebo que tipo de piramide se va a dibujar
		if ($cartesian) {
			echo $this->makeCartesianPiramide($rows);
		} else {
			echo $this->makePiramide($rows);
		}
	}
	
	// Metodo publico para crear la piramide sobre arrays o plano cartesiano
	public function makeCartesianPiramide($rows) {
	
		// Calculo el numero de columnas teniendo en cuenta el numero de filas
		if (($rows % 2) != 0) {

			// El numero de filas es impar, calculo las columnas
			$this->cols = ($rows * 3) - 4;

		} else {

			// El numero de filas es par, calculo las columnas
			$this->cols = ($rows * 2) - 1;
		}

		// Creo los acumuladores para calcular los rangos que tengo que marcar
		$this->cont_pos = (($this->cols + 1) / 2) - 1;

		// Al ser el pico de la piramide, los contadores son iguales
		$this->cont_neg = $this->cont_pos;

		// Recorro todas las filas
		for ($i = 0; $i < $rows; $i++) {

			// Creo el rango que quiero marcar dentro de cada fila
			$this->range = range($this->cont_neg, $this->cont_pos);

			// Recorro todas las columnas
			for ($j = 0; $j < $this->cols; $j++) {

				// Si la columna obtenida esta dentro de mi rango
				if (in_array($j, $this->range)) {

		            // Guardo valor 1 y pinto el asterisco
					$c[$j] = '1';
					$this->piramide .= $this->char;

				} else {

					// Si no esta, guardo valor 0
					$c[$j] = '0';
				}
			}

			// Guardo la fila generada dentro del plano cartesiano
			array_push($this->plane, $c);

			// Añado un salto de carro para seguir con la siguiente linea
			$this->piramide .= $this->salto;

			// Actualizo los contadores para volver a calcular los rangos
			$this->cont_pos++;
			$this->cont_neg--;
		}
		
		// Devuelvo la piramide completa
		return $this->piramide;
	}
	
	// Metodo publico para crear la piramide de un modo mas sencillo
	public function makePiramide($rows) {
	
		// Recorro el numero de filas
		for ($a = 1; $a <= $rows; $a++) {

			// Voy creando las columnas
			for ($h = 1; $h <= $a; $h++) {

				// Pinto el asterisco
				$this->piramide .= $this->char;
			}
			
			// Añado un salto de carro
			$this->piramide .= $this->salto;
		}
		
		// Devuelvo la piramide completa
		return $this->piramide;
	}
}

/* Forma de uso */

// Piramide cartesiana
$piramide_cartesiana = new piramide(9);

// Piramide simple
$piramide = new piramide(9, false);

?>

Una forma más de solucionar nuestro problema, os animáis?

Dejandomarcas.com y cakePHP

Estoy programando de nuevo mi site principal usando el framework cakePHP.

Pronto estará en producción corriendo con este framework cuyo trabajo me ha agilizado bastante. Espero que os gusten los cambios ya que hacía bastante tiempo que no actualizaba mi web (en cuanto a diseño y programación). Decir también que me mudo de Arsys, ya que, después de muchos años con muchísimos errores, he decidido mudarme de servidor a uno más barato y con más opciones de configuración, ya que desde el servidor compartido que tengo contratado con ellos me es imposible editar el .htaccess, imprescindible para que cakePHP trabaje con URLs amigables

Os dejo un pequeño pantallazo para que veais cómo está quedando:

Nuevo diseño y programación

Pirámide de asteriscos con PHP – Modo avanzado

Tras explicar una forma básica de dibujar una pirámide de asteriscos con PHP, voy a tratar de explicar una forma un poquito más avanzada de hacerlo.

Lo bonito de la programación es que no hay una sola forma de hacer las cosas. Todo se puede analizar de muchas maneras y los resultados pueden ser los mismos. No obstante, dependiendo de nuestro análisis y de nuestra programación, podemos optimizar los resultados y conseguir que sean mucho más viables dependiendo de nuestro objetivo final.

El método que voy a tratar de explicar es una forma más avanzada de entender el problema. Para ello, voy a dibujar la pirámide dentro de un plano cartesiano.

<?php

/* 

 * Para trazar la piramide usare un plano cartesiano hecho con matrices

 * Este es un ejemplo de como quedara el plano sin valores

 *

 * $plane = array (0 => array(0 => 0, 1 => 0, 2 => 0, 3 => 0, 4 => 0, 5 => 0),

 *           	   1 => array(0 => 0, 1 => 0, 2 => 0, 3 => 0, 4 => 0, 5 => 0),

 *           	   2 => array(0 => 0, 1 => 0, 2 => 0, 3 => 0, 4 => 0, 5 => 0),

 *           	   3 => array(0 => 0, 1 => 0, 2 => 0, 3 => 0, 4 => 0, 5 => 0),

 *           	   4 => array(0 => 0, 1 => 0, 2 => 0, 3 => 0, 4 => 0, 5 => 0),

 *           	   5 => array(0 => 0, 1 => 0, 2 => 0, 3 => 0, 4 => 0, 5 => 0),

 *           	   6 => array(0 => 0, 1 => 0, 2 => 0, 3 => 0, 4 => 0, 5 => 0)

 *                );

 *

 * Los parametros que voy a usar son los siguientes

 *

 * @param $rows int indica el numero de filas que va a tener la piramide

 * @param $char string indica el simbolo que vamos a usar para pintar la piramide
 * @Param $view int (opcional) indica si quiero pintar la piramide o el plano cartesiano
 *
 * return $piramide string si $view es true
 * return $plane array si $view es false
 *

**/

function crear_piramide ($rows, $char, $view = true) {



	// Creo el plano cartesiano, la piramide, las columnas y los acumuladores

	$plane = array();
	$range = null;
	$piramide = null;
	$cols = 0;
	$cont_pos = 0;
	$cont_neg = 0;



	/* Calculo el numero de columnas a partir de las filas. Hay que tener en cuenta 
	 * si el numero es par o impar para que la piramide quede bien dibujada en el 
	 * centro del plano cartesiano
	**/
	if (($rows % 2) != 0) {

		// El numero de filas es impar, calculo las columnas

		$cols = ($rows * 3) - 4;
	
	} else {

		// El numero de filas es par, calculo las columnas
		$cols = ($rows * 2) - 1;
	}
	
	// Creo los acumuladores para calcular los rangos que tengo que marcar
	$cont_pos = (($cols + 1) / 2) - 1;
	
	// Al ser el primer valor o pico de la piramide, el contador negativo es igual que el positivo

	$cont_neg = $cont_pos;
	

	// Recorro todas las filas

	for ($i = 0; $i < $rows; $i++) {
	
		// Creo el rango que quiero marcar dentro de cada fila
		$range = range($cont_neg, $cont_pos);

	

		// Recorro todas las columnas

		for ($j = 0; $j < $cols; $j++) {
		
			// Si la columna obtenida esta dentro de mi rango
			if (in_array($j, $range)) {
			
       
                                // Guardo valor 1 y pinto el asterisco
				$c[$j] = '1';
				$piramide .= $char;
				
			} else {
				
				// Si no esta, guardo valor 0
				$c[$j] = '0';
			}

		}
		

		// Guardo la fila generada dentro del plano cartesiano

		array_push($plane, $c);
		
		// Añado un salto de carro para seguir con la siguiente linea
		$piramide .= "<br />";
		
		// Actualizo los contadores para volver a calcular los rangos

		$cont_pos++;

		$cont_neg--;

	}
	
	// Devuelvo la opcion elegida en el parametro $view
	if ($view)
		return $piramide;
	else
		print_r($plane);

}

// Forma de uso

$piramides = crear_piramide (5, '*');

echo $piramides;

?>

Si ejecutáis esta función, el resultado por defecto será este:

          *
         ***
        *****
       *******
      *********

También podéis cambiar el asterisco por cualquier otro símbolo:

<?php

$piramides = crear_piramide (5, '[]');
echo $piramides;

// Resultado
         []
       [][][]
     [][][][][]
   [][][][][][][]
 [][][][][][][][][]

?>

Si quereis ver cómo ha quedado nuestro plano cartesiano, solo tenéis que modificar el tercer parámetro pasándolo como false:

<?php

$piramides = crear_piramide (5, '*', false);

echo $piramides;

// Resultado
Array ([0] => Array([0] => 0 [1] => 0 [2] => 0 [3] => 0 [4] => 0 [5] => 1 [6] => 0 [7] => 0 [8] => 0 [9] => 0 [10] => 0)
          [1] => Array([0] => 0 [1] => 0 [2] => 0 [3] => 0 [4] => 1 [5] => 1 [6] => 1 [7] => 0 [8] => 0 [9] => 0 [10] => 0)
          [2] => Array([0] => 0 [1] => 0 [2] => 0 [3] => 1 [4] => 1 [5] => 1 [6] => 1 [7] => 1 [8] => 0 [9] => 0 [10] => 0)
          [3] => Array([0] => 0 [1] => 0 [2] => 1 [3] => 1 [4] => 1 [5] => 1 [6] => 1 [7] => 1 [8] => 1 [9] => 0 [10] => 0)
          [4] => Array([0] => 0 [1] => 1 [2] => 1 [3] => 1 [4] => 1 [5] => 1 [6] => 1 [7] => 1 [8] => 1 [9] => 1 [10] => 0)
)

?>

Como siempre, esta no es ni mucho menos la forma más eficiente ni definitiva de resolver el problema. También hay que tener en cuenta que este tipo de ejercicios nos ayudan a comprender cómo funciona un lenguaje de programación y cómo debemos abordar un problema real.

Os animo a que comenteis vuestra solución.

// Don’t forget to comment your code

Cada vez que escribes un bloque de código sin comentar, dios mata a un gatito… Por favor, hagamos algo para evitar esta masacre…

<?php

$cat = new cat();

// Comentarios? para que??
if (!isset($comments)) {
     $cat->getLightningBolt();
     $god->say("Cuando aprendereis...");
}

?>
A %d blogueros les gusta esto: