domingo, 20 de octubre de 2013

Arrancando Ubuntu 13.10 desde Grub Rescue

Tras actualizar uno de nuestros PCs a Ubuntu 13.10 Saucy Salamander he visto que quedaba poco espacio en disco y he decidido eliminar el otro sistema operativo que había instalado (que era Windows 7, pero eso da igual). Tras borrar la partición de Windows he intentado hacer más grande la partición de Linux y ahí han empezado los problemas. Para empezar no se puede tocar la partición en uso, así que he arrancado con el Live CD de Ubuntu y lo he intentado de nuevo con GParted...

La partición sobre la que estaba instalado Ubuntu era una partición lógica dentro de una partición extendida y se encontraba al final del disco. Mal asunto. He intentado mover las particiones al principio para hacerlas más grandes pero GParted no me lo ha permitido, así que he hecho una copia de la partición entera, proceso que ha tardado más una hora. He probado de arrancar Ubuntu desde esa partición y todo ha ido bien así que he vuelto arrancar desde el Live CD, he eliminado la partición extendida y he agrandado al máximo la nueva partición.

Todo ha ido aparentemente bien pero al reiniciar el sistema ha salido un error y ha aparecido Grub Rescue que es una especie de intérprete de comandos de Grub que permite reparar una instalación. Entonces me he puesto a investigar en Internet y he encontrado la solución:

  1. Lo primero que hay que hacer es averiguar cual es el disco duro y la partición sobre la que tienes instalado Ubuntu. Eso se hace con el comando ls:
  2. Grub Rescue> ls
    (hd0) (hd0,msdos1) (hd0,msdos2) (hd1) (hd1,msdos2) (hd2,msdos1)
    Grub Rescue> ls (hd0)/
    Error: Unknown filesystem.
    Grub Rescue> ls (hd0,msdos2)/
    Error: Unknown filesystem.
    Grub Rescue> ls (hd0,msdos1)/
    bin/  boot/  cdrom/  dev/  etc/  home/  lib/  lib64/
    media/  mnt/  opc/  proc/  root/  run/  sbin/  selinux/
    srv/  sys/  tmp/  usr/  var/
    

    Se trata de averiguar que partición tiene instalado nuestro Linux. Para ello hay que mirar una a una el contenido de las particiones ls (hdx,y)/ (ojo con la barra final), hasta dar con la adecuada que en mi caso es la (hd0,msdos1)

  3. Una vez sabemos el nombre interno de la partición a iniciar hay que arrancar Ubuntu desde esa partición. Pare ello basta con ejecutar las siguientes instrucciones, cambiando (hd0,msdos1) por el nombre real de la partición:
  4. Grub Rescue> set root=(hd0,msdos1)
    Grub Rescue> set prefix=(hd0,msdos1)/boot/grub
    Grub Rescue> insmod normal
    Grub Rescue> normal
    
  5. Por último una vez arrancado Ubuntu hay que arreglar Grub para que la siguiente vez funcione correctamente. Para ello hay que abrir un terminar y ejecutar las siguientes instrucciones:
  6. $ sudo update-grub2
    $ sudo grub-install /dev/sda
    

    Hay que elegir bien en que dispositivo instalamos Grub: /dev/sda se corresponde con el primer disco duro (hd0) en Grub Rescue. /dev/sdb sería el segundo disco duro (hd1), /dev/sdc sería (hd2), etc.

Y ya está. Con esto debería funcionar. Puedes encontrar más información aquí, aquí y aquí.

jueves, 10 de octubre de 2013

Symfony 2: Primer proyecto

En este segundo capítulo del mini-curso de Symfony 2 explicaré como crear un proyecto Symfony 2 desde cero para entornos Linux. Por supuesto existe la posibilidad de utilizar Symfony 2 en Windows y en Mac OS X, pero yo voy a centrarme en Linux y concretamente en Ubuntu, que es lo que uso habitualmente. La instalación en Mac OS X probablemente sea similar a la de Linux y para Windows seguro que existen otros manuales.

Lo primero y más importante: Vamos a suponer que el usuario dispone de un PC con sistema operativo Linux y que ha instalado tanto el servidor web Apache como el lenguaje PHP. Symfony 2 requiere al menos la versión 5.3.3 de PHP y algunas extensiones específicas. Aquí puede consultar todos los requerimientos de Symfony 2.


Composer

Empezaremos por el principio: Instalando Composer.

Composer es una herramienta imprescindible para desarrollar aplicaciones y sitios web en Symfony 2. Los proyectos Symfony utilizan diversas librerías externas (llamadas dependencias) que a su vez puede que usen otras librerías y Composer es la herramienta que se encarga de mantener actualizadas esas dependencias. Por ejemplo cuando queremos cambiar la versión usada de una librería o del propio Symfony, Composer se encarga de comprobar la compatibilidad de las otras librerías del proyecto, descargando si es necesario las versiones compatibles o avisando de las posibles incompatibilidades. A la hora de crear un proyecto Symfony 2, Composer comprueba la lista de dependencias del proyecto, decide qué librerías hay que instalar, qué versiones concretas se instalan y el orden correcto de instalación. Es una herramienta muy potente.

Para instalar Composer globalmente hay que seguir los siguientes pasos:

  1. Abre una terminal y escribe:
  2. $ curl -s https://getcomposer.org/installer | php
  3. Aparecerá un nuevo archivo llamado composer.phar. Para comprobar que se ha instalado correctamente, ejecuta el siguiente comando que muestra el menú de opciones de Composer:
  4. $ php composer.phar
  5. Por último mueve el archivo composer.phar a un directorio de ejecutables del sistema:
  6. $ sudo mv composer.phar /usr/local/bin/composer
  7. Comprueba que todo funciona como es debido ejecutando el comando composer sin opciones desde cualquier directorio.

Con esto habremos instalado Composer de forma global en el ordenador. De esta forma para actualizar la versión de Composer de todos los proyectos bastará con ejecutar el siguiente comando desde un terminal:

$ sudo composer self-update

Creando un proyecto base

Una vez hemos instalado Composer, podemos usarlo para crear un proyecto Symfony 2 básico:

$ composer create-project symfony/framework-standard-edition
<carpeta> <version>

En este caso <carpeta> es el directorio raíz del proyecto (por ejemplo "/var/www/vhosts/masquecursos/") y <version> es la versión de Symfony 2 a instalar. En el momento de escribir estas líneas la última versión estable de Symfony es la 2.3.5 y otras versiones disponibles serían la anterior 2.2.8 y la siguiente 2.4.0-BETA1. Más información en la página de instalación de Symfony.

El programa de instalación pedirá algunos datos necesarios para la misma:

  • Driver de base de datos: Generalmente será MySQL (pdo_mysql), pero podría ser SQLite (pdo_sqlite), PostgreSQL (pdo_pgsql), Microsoft SQL Server (pdo_sqlsrv), Oracle-PDO (pdo_oci), Oracle-No PDO (oci8), etc.
  • Host de base de datos: Por defecto 127.0.0.1.
  • Puerto de base de datos: Por defecto null.
  • Nombre de base de datos: Depende del proyecto.
  • Nombre del usuario de base de datos: Depende del proyecto.
  • Clave de acceso del usuario de base de datos: Depende del proyecto.
  • Protocolo de transporte para envío de emails: Por defecto smtp.
  • Host para envío de emails: Por defecto 127.0.0.1.
  • Nombre del usuario para envío de emails: Depende del proyecto.
  • Clave de acceso del usuario para envío de emails: Depende del proyecto.
  • Identificador local (locale): Por defecto en.
  • Clave secreta: Para configurar el sistema de seguridad.

Se pueden dejar los valores por defecto pues más adelante podremos cambiarlos. El programa de instalación creará la estructura básica de directorios de un proyecto Symfony 2 que es la siguiente:

  • proyecto/
    • composer.json
    • composer.lock
    • app/
      • check.php
      • console
      • cache/
      • config/
      • logs/
    • bin/
    • src/
    • vendor/
    • web/
      • app.php
      • app_dev.php
      • config.php

Cada una de las subcarpetas contiene a su vez otros archivos y carpetas, pero los que aparecen aquí son los más importantes. Más adelante hablaremos de lo que hay en cada carpeta y para que sirve cada archivo. Por ahora basta con saber que Composer nos crea todo esta estructura de carpetas y archivos.


Comprobaciones post-instalación

Todo proyecto Symfony 2 viene con un programa que permite comprobar si el ordenador cumple todos los requerimientos necesarios para el correcto funcionamiento del framework. Para ejecutarlo basta con abrir el terminal, entrar en el directorio del proyecto y teclear:

$ php app/check.php

Al ejecutar dicha utilidad, obtendremos una lista de requerimientos indicando en cada caso si tenemos la instalación correcta (OK) o si hay algún error (ERROR) o aviso (WARNING). Los errores (mandatory requirements) es necesario corregirlos antes de nada porque sino probablemente el proyecto no funcionará. Los avisos (optional checks) es conveniente corregirlos, pero no obligatorio.

Una vez comprobado que todos los requisitos están soportados por nuestra instalación se debe ejecutar otra utilidad llamada console.

$ app/console

Si todo es correcto se nos mostrará una lista de opciones de la consola Symfony. Más adelante veremos que esta consola es muy útil y se usa mucho para acciones comunes: limpiar la cache, crear la base de datos, crear entidades Doctrine, crear bundles, etc.


El problema de los permisos

Symfony 2 necesita permisos de escritura sobre dos carpetas del proyecto app/cache/ y app/logs/. Todas las demás carpetas pueden ser de sólo lectura, pero esas dos no. El problema es que el usuario Linux de la consola no es el mismo que el del navegador web (Apache) y ambos necesitan acceso a esos directorios, lo que puede provocar diversos problemas tipo "RuntimeException: Could not create cache directory" y otros similares. Para solucionarlo basta dar permisos de escritura a todos los usuarios para esos dos directorios concretos:

$ sudo chmod -R 777 app/cache/ app/logs/

Siendo puristas habría que dar permisos de escritura sólo al usuario www-data (Apache) o arreglar el tema de permisos vía grupo de trabajo que son las opciones recomendadas para entornos de producción, pero para el entorno de desarrollo sirve el chmod 777. Aquí puedes encontrar más información sobre cómo solucionar el problema de los permisos de Symfony 2.


Configurando el entorno

Para que el entorno de desarrollo sea lo más parecido posible al entorno de producción y aprovechando las características del servidor web Apache, vamos a crear un virtual host para este proyecto. Para ello en Ubuntu crearemos un archivo en la carpeta /etc/apache2/sites-available/ (ojo se necesitan permisos de root) y lo llamaremos como el proyecto (por ejemplo masquecursos). El contenido será el siguiente:

<VirtualHost *:80>
  ServerName masquecursos.me
  ServerAdmin webmaster@masquecursos.me
  DocumentRoot /var/www/vhosts/masquecursos/web
  DirectoryIndex app.php
  <Directory /var/www/vhosts/masquecursos/web>
    AllowOverride All
    Allow from All
  </Directory>
</VirtualHost>

Cada distribución de Linux es distinta y dicho archivo puede ser necesario crearlo en otra carpeta, aunque el contenido será el mismo. En Ubuntu posteriormente a la creación del archivo en /etc/apache2/sites-available/ es necesario crear un enlace simbólico en /etc/apache2/sites-enabled/. También habrá que editar el archivo /etc/hosts y asociar el nombre del virtual host con la IP 127.0.0.1. Posteriormente será necesario reiniciar el servidor Apache. La secuencia completa sería la siguiente:

$ sudo gedit /etc/apache2/sites-available/masquecursos
$ cd /etc/apache2/sites-enabled/
$ ln -s /etc/apache2/sites-available/masquecursos
$ sudo gedit /etc/hosts
$ sudo service apache2 restart

Con esto habremos configurado el entorno de ejecución y podremos acceder a nuestro sitio web desde http://masquecursos.me/, pero no lo pruebes todavía pues aun no funcionará. Por ahora para ver el contenido del proyecto es necesario usar el controlador de desarrollo http://masquecursos.me/app_dev.php. Más adelante veremos que es eso y porque aun no funciona con el controlador frontal app.php.


Configuraciones finales

Si entramos en nuestro navegador preferido y escribimos http://masquecursos.me/config.php veremos una página web con una bienvenida de Symfony. En caso de que la instalación no cumpla los requerimientos técnicos se mostrará una pantalla de error con la misma información que nos daba el archivo app/check.php. A estas alturas esos errores ya deberían estar corregidos. Desde la pantalla de bienvenida podemos acceder a otra de configuración del entorno desde la que se pueden configurar los mismos parámetros que cuando creamos el proyecto con Composer. En cualquier caso esos parámetros de configuración del entorno están en el archivo app/config/parameters.yml por lo que pueden modificarse a mano de forma sencilla.

¡Y ya está! Ya hemos creado un primer proyecto Symfony 2 vacío. En el siguiente capítulo veremos como crear el primer bundle y haremos el típico Hola Mundo con Symfony.


Más información


Mini-curso de Symfony 2

  • Primeros pasos: Conceptos y definiciones sobre Symfony 2.
  • Primer proyecto: Como empezar un proyecto Symfony 2.

sábado, 5 de octubre de 2013

Symfony 2: Primeros pasos

Llevo algún tiempo trabajando con Symfony 2 y, aunque aun no soy un experto, voy a intentar explicar cual es la estructura global de una aplicación Symfony y cuales son los primeros pasos para desarrollar una página web este popular framework PHP. Voy a dar por supuesto que ya sabéis qué es Symfony. Empezaré por algunos conceptos:


Bundles

Toda aplicación Symfony 2 está formada por bundles. Básicamente un bundle es una carpeta que contiene tu código fuente PHP, archivos de configuración y otros recursos como imágenes, hojas de estilos CSS, archivos HTML, javascripts, etc. Todo ello dentro de una estructura predeterminada de subcarpetas jerarquizadas.

Una aplicación Symfony 2 debe contener al menos un bundle, pero no hay límite en el número de bundles que se pueden crear. Algunos programadores ponen todo el código en un único bundle gigantesco mientras que otros prefieren crear un bundle por cada división lógica de la aplicación. Por ejemplo se puede crear un MainBundle para la parte principal de la web y un AdminBundle para la parte de administración.


Entidades (Doctrine)

Symfony es un framework PHP que implementa el patrón MVC (Modelo-Vista-Controlador), en el cual toda aplicación de divide en tres capas: modelo, vista y controlador. La primera capa es el modelo y se encarga del manejo y persistencia de los datos de la aplicación. En Symfony la capa del modelo está controlada por una herramienta llamada Doctrine que se encarga precisamente del acceso a los datos y su persistencia. Doctrine hace que nuestra aplicación sea independiente del motor de bases de datos, de forma que no será necesario escribir ni una sola sentencia SQL sino que tendremos que definir una serie de objetos PHP llamados entidades y Doctrine se encargará de lo demás.

A priori puede parece complicado pero es justo lo contrario. Las entidades se guardan como archivos PHP en una carpeta llamada Entity dentro de cada bundle.


Vistas (Twig)

En el patrón MVC, la capa vista es la que se encarga de la presentación en pantalla y de la interacción con el usuario. En symfony se utiliza un motor de plantillas llamado Twig que simplifica la creación de las vistas. Aquí puedes consultar más información sobre Twig en Español. Las vistas se guardan como archivos Twig en una carpeta llamada Resources/views dentro de cada bundle.


Controladores

En el patrón MVC, la capa controlador se encarga de procesar las peticiones, obtener los datos a través del modelo y lanzar las vistas. En symfony 2 los controladores son clases PHP que se derivan de la clase Controller y que se guardan como archivos PHP en una carpeta llamada Controller dentro de cada bundle.


Enrutamiento

Symfony permite controlar todas las rutas que acepta un sitio web. Cada ruta puede ser estática de tipo /seccion/accion/ o tener parámetros, que se encierran entre corchetes, como /seccion/ver/{param}. Al final cada ruta se corresponde a un método de uno de los controladores y los parámetros serán los argumentos del método. Por ejemplo el sitio MasQueCursos.org podría configurar las siguientes rutas:

  • "/" Página principal.
  • "/cursos" Lista de cursos.
  • "/cursos/buscar" Buscador avanzado de cursos.
  • "/cursos/{nombre}" Detalle de un curso.
  • "/centros" Lista de centros de formación.
  • "/centros/{nombre}" Detalle de un centro de formación.
  • "/temas" Lista de temas disponibles.
  • "/temas/{nombre}" Lista de cursos de un tema.
  • Etc.

Además en Symfony cada ruta debe tener un nombre único que lo identifique y estar asociada a un controlador y a una acción (método de la clase). Por ejemplo:

  • Página principal:
    • Nombre="indice", Ruta="/"
    • Controlador="@MasQueCursosBundle/Controller/DefaultController"
    • Accion="indexAction"
  • Lista de cursos:
    • Nombre="lista_cursos", Ruta="/cursos"
    • Controlador="@MasQueCursosBundle/Controller/CursosController"
    • Accion="listaAction"
  • Buscardor de cursos:
    • Nombre="buscar_cursos", Ruta="/cursos/buscar"
    • Controlador="@MasQueCursosBundle/Controller/CursosController"
    • Accion="buscarAction"
  • Detalle de un curso:
    • Nombre="ver_curso", Ruta="/cursos/{nombre}"
    • Controlador="@MasQueCursosBundle/Controller/CursosController"
    • Accion="verAction"
  • Etc.

Todo el sistema de rutas se puede configurar en Symfony de dos formas: a través de los archivos de configuración o a través de anotaciones, un sistema directamente heredado de Java, que consiste en poner datos de configuración directamente en los comentarios. Por ejemplo la siguiente clase es un controlador con anotaciones: Hay una anotación @Route a nivel del controlador y otra para cada método de la clase.

namespace Ifraktal\MasQuecursosBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;

/**
 * @Route("/cursos")
 */
class CursosController extends Controller {

    /**
     * @Route("/", name="lista_cursos")
     */
    public function listaAction()
    {
        // ...
    }

    /**
     * @Route("/buscar", name="buscar_cursos")
     */
    public function buscarAction()
    {
        // ...
    }

    /**
     * @Route("/{nombre}", name="ver_curso")
     */
    public function verAction($nombre)
    {
        // ...
    }

    // ...
}

Hasta aquí la primera entrada. En próximas entradas explicaré la estructura de carpetas de un proyecto symfony; cómo crear un proyecto Symfony 2 desde cero; etc.

jueves, 3 de octubre de 2013

devs.info - una web de atajos para programadores

Navegando por ahí me he encontrado con devs.info, una web de atajos para programadores. Se trata de una sencilla página web que contiene accesos directos a los más importantes recursos que puede necesitar un programador: documentación, libros, trucos, FAQ, etc. Ha sido creada por Miquel Camps Orteza y me ha parecido muy útil y completa.

Además proporciona una forma muy sencilla de recordar estos atajos. Por ejemplo si queremos acceder a la documentación oficial de Symfony basta que escribamos http://devs.info/symfony.doc en el navegador. Si queremos consultar una página de preguntas frecuentes sobre css sólo tenemos que poner http://devs.info/css.faq. Si necesitamos comprar un libro de programación Android, http://devs.info/android.book. Y así con todo.

La cantidad de recursos disponibles en devs.info es enorme: lenguajes de programación (PHP, Java, Javascript, Pyton, Ruby, HTML, ...), CMS's (Wordpress, Drupal, Joomla, ...), frameworks (Symfony, Codeigniter, Rails, Spring, Bootstrap, jQuery, ...), bases de datos (MySQL, MariaDB, ProtgreSQL, mongoDB, ...), motores de plantillas (Twig, Smarty, ...), servidores web (Apache, ...), desarrollo de juegos, servicios y otras herramientas variadas.