Mostrando entradas con la etiqueta PHP. Mostrar todas las entradas
Mostrando entradas con la etiqueta PHP. Mostrar todas las entradas

domingo, 17 de enero de 2016

9 - Tutorial de PHP7 - Operadores para Strings y Arrays




Bienvenid@s a un nuevo capítulo del Tutorial de PHP7 en cual continuamos con la referencia del lenguaje, concretamente con los operadores disponibles para Strings y Arrays.

Referencia del Lenguaje - Operadores para Strings y Arrays

Operadores para Strings: Existen dos operadores para datos tipo string. El primero es el operador de concatenación ('.'), el cual retorna el resultado de concatenar sus argumentos derecho e izquierdo. El segundo es el operador de asignación sobre concatenación ('.='), el cual añade el argumento del lado derecho al argumento en el lado izquierdo.
 

Operadores para Arrays:

EjemploNombreResultado
$a + $b Unión Unión de $a y $b.
$a == $b Igualdad TRUE si $a y $b tienen las mismas parejas clave/valor.
$a === $b Idéntico TRUE si $a y $b tienen las mismas parejas clave/valor en el mismo orden y de los mismos tipos.
$a != $b Desigualdad TRUE si $a no es igual a $b.
$a <> $b Desigualdad TRUE si $a no es igual a $b.
$a !== $b No idéntico TRUE si $a no es idéntica a $b.


Código del script del capítulo operadores-strings-arrays.php ...

<?php 
//Strings. Operador de concatenación '.'
$string1 = 'Hola ';
$string2 = $string1 . 'mundo';
echo '<p>' . $string2 . '</p>';

//Precedencia
$string3 = 'La suma total de 2+2 = ' . (2+2);
echo '<p>' . $string3 . '</p>';

//Operador de asignación sobre concatenación '.='
$string4 = 'político ';
$string4 .= 'corrupto ';
$string4 .= 'y ladrón';
echo '<p>' . $string4 . '</p>';

//Comparar arrays
$a = [0, 1, 2];
$b = ['0', '1', '2'];

//Operador de igualdad: TRUE si $a y $b tienen las mismas parejas clave/valor
echo '<p>Operador de igualdad ==</p>';
var_dump($a == $b);

/* 
Operador de idéntico: TRUE si $a y $b tienen las mismas parejas clave/valor en el mismo
orden y de los mismos tipos
*/
echo '<p>Operador de idéntico ===</p>';
var_dump($a === $b);

//Operador de desigualdad: TRUE si $a no es igual a $b 
echo '<p>Operador de desigualdad != &lt;&gt;</p>';
var_dump([0, 1, 2] != ['0', '1', '2']);







viernes, 15 de enero de 2016

8 - Tutorial de PHP7 - Operadores de ejecución (shell) y archivos .ini




Bienvenid@s, en este capítulo del Tutorial de PHP7 continuamos con la referencia del lenguaje, concretamente con los operadores de ejecución (comando de shell) y veremos como iniciar php con un archivo de configuración .ini.

Referencia del Lenguaje - Operadores de ejecución (shell) y archivos .ini

PHP soporta un operador de ejecución: las comillas invertidas (``). PHP intentará ejecutar el contenido entre las comillas invertidas como si se tratara de un comando del shell; la salida será retornada (es decir, no será simplemente volcada como salida; puede ser asignada a una variable). El uso del operador de comillas invertidas es idéntico al de la función shell_exec(). 
 
Nota: El operador de comillas invertidas se deshabilita cuando modo seguro esta activado o shell_exec() está desactivado. 
 
Archivos .ini: php.ini es leído por php al arrancar, en él se encuentran una serie de directivas que controlan el uso de php.

Objetivo del capítulo

- Crear una carpeta a través de una shell
 
- Eliminar esta misma carpeta
 
- Abrir un programa como por ejemplo notepad.exe
  
- Veremos un ejemplo de como desactivar funciones en el archivo .ini de desarrollo (php.ini-development), desactivaremos la función shell_exec() en la directiva disable_functions, importante, reiniciar el servidor de desarrollo con el argumento -c [ruta-de-archivo-ini]

Código del script del capítulo operadores-ejecucion.php ...

<?php 
//$output = `mkdir hola`; //Crear carpeta
//$output = `rmdir hola`; //Eliminar carpeta
//$output = `notepad.exe`; //Ejecutar un programa
$output = shell_exec("notepad.exe"); //shell_exec función equivalente al operador de ejecución ``
echo $output;




7 - Tutorial de PHP7 - Operadores Lógicos




Bienvenid@s, en este capítulo del Tutorial de PHP7 continuamos con la referencia del lenguaje, concretamente con los Operadores Lógicos.

Referencia del Lenguaje - Operadores lógicos

Los operadores lógicos sirven para combinar condiciones. Los operadores lógicos disponibles en PHP son:
 
EjemploNombreResultado
$a and $b And (y) TRUE si tanto $a como $b son TRUE.
$a or $b Or (o inclusivo) TRUE si cualquiera de $a o $b es TRUE.
$a xor $b Xor (o exclusivo) TRUE si $a o $b es TRUE, pero no ambos.
!$a Not (no) TRUE si $a no es TRUE.
$a && $b And (y) TRUE si tanto $a como $b son TRUE.
$a || $b Or (o inclusivo) TRUE si cualquiera de $a o $b es TRUE.


Código del script del capítulo operadores-logicos.php ...

<?php 
$var1 = 10;
$var2 = 10;
$var3 = 5;
$var4 = 5;

/* AND (y) - true si todas las condiciones son verdaderas */
echo '<p>Supuesto 1. Operadores: and &&</p>';
var_dump($var1 == $var2 && $var3 == $var4);

/* OR (o inclusivo) - true si cualquiera de las condiciones es verdadera */
echo '<p>Supuesto 2. Operadores: or ||</p>';
var_dump($var1 > $var2 || $var3 == $var4);

/* XOR (o exclusivo) - true si sólo una de las condiciones es verdadera */
echo '<p>Supuesto 3. Operador: xor</p>';
var_dump($var1 < $var2 xor $var3 == $var4);

/* NOT - true si la condición no es verdadera */
echo '<p>Supuesto 4. Operador: !</p>';
var_dump(!($var1 > $var2));





martes, 12 de enero de 2016

6 - Tutorial de PHP7 - Operadores de Comparación




En esta parte del Tutorial de PHP7 continuamos con la referencia del lenguaje, concretamente con los operadores de comparación, prestando especial atención a los dos nuevos operadores disponibles desde PHP 7, los operadores: nave espacial y fusión de null.

Referencia del Lenguaje - Operadores de comparación

Los operadores de comparación, como su nombre lo indica, permiten comparar dos valores. Los operadores de comparación disponibles en PHP son:
 
EjemploNombreResultado
$a == $b Igual TRUE si $a es igual a $b después de la manipulación de tipos.
$a === $b Idéntico TRUE si $a es igual a $b, y son del mismo tipo.
$a != $b Diferente TRUE si $a no es igual a $b después de la manipulación de tipos.
$a <> $b Diferente TRUE si $a no es igual a $b después de la manipulación de tipos.
$a !== $b No idéntico TRUE si $a no es igual a $b, o si no son del mismo tipo.
$a < $b Menor que TRUE si $a es estrictamente menor que $b.
$a > $b Mayor que TRUE si $a es estrictamente mayor que $b.
$a <= $b Menor o igual que TRUE si $a es menor o igual que $b.
$a >= $b Mayor o igual que TRUE si $a es mayor o igual que $b.
$a <=> $b Nave espacial Un integer menor que, igual a, o mayor que cero cuando $a es respectivamente menor que, igual a, o mayor que $b. Disponible a partir de PHP 7.
$a ?? $b ?? $c Fusión de null El primer operando de izquierda a derecha que exista y no sea NULL. NULL si no hay valores definidos y no son NULL. Disponible a partir de PHP 7.


El código del script del capítulo operadores-comparacion.php ...

<?php 
$numero1 = 2;
$numero2 = '2';

echo '<p>Supuesto 1. igual ==.</p>';
var_dump($numero1 == $numero2);

echo '<p>Supuesto 2. idéntico ===.</p>';
var_dump($numero1 === $numero2);

echo '<p>Supuesto 3. diferente != ó <></p>';
var_dump(3 <> 2);

echo '<p>Supuesto 4. menor que <</p>';
var_dump(3 < 2);

echo '<p>Supuesto 5. menor ó igual que. <=</p>';
var_dump(1 <= 2);

echo '<p>Supuesto 6. Nave espacial <=>.</p>';
$a = 0;
$b = 1;
echo '<p>Si $a es menor que $b regresa -1. Si $a es igual a $b regresa 0. Si $a es mayor que $b regresa 1</p>';
var_dump($a <=> $b);

echo '<p>Supuesto 7. Fusión de null.</p>';
$e = 'hola soy e';
$c = $d ?? $e ?? 'nada';
var_dump($c);






viernes, 1 de enero de 2016

5 - Tutorial de PHP7 - Operadores Aritméticos




Bienvenid@s, en este capítulo del Tutorial de PHP7 continuamos con la referencia del lenguaje, concretamente con los Operadores Aritméticos y la precedencia de los operadores.

Referencia del Lenguaje - Operadores aritméticos

Los operadores aritméticos permiten realizar operaciones matemáticas. Los operadores aritméticos disponibles en PHP son:
  • Negación: Números negativos. Ejemplo: -$a | Resultado: opuesto de $a
  • Adicción: Sumar números. Ejemplo: $a + $b | Resultado: suma de $a y $b
  • Sustracción: Restar números. Ejemplo: $a - $b | Resultado: diferencia de $a y $b
  • Multiplicación: Multiplicar números. Ejemplo: $a * $b | Resultado: producto de $a y $b
  • División: Dividir números. Ejemplo: $a / $b | Resultado: cociente de $a y $b
  • Módulo: Resto de una división. Ejemplo: $a % $b | Resultado: resto de $a divido por $b
  • Exponenciación (disponible desde PHP 5.6): Elevar un número a una potencia dada. Ejemplo: $a ** $b | Resultado: resultado de elevar $a a la potencia $b.

Precedencia de los operadores

Los valores se calcularán de izquierda a derecha y de acuerdo a la precedencia de los operadores. Precedencia de los operadores:
  • 1 - Exponenciación **
  • 2 - Multiplicación * y división /
  • 3 - Suma + y resta -
Para forzar la precedencia de un operador se utilizarán los paréntesis (), no es lo misma la operación 3 + 3 * 3 = 12 que (3 + 3) * 3 = 18


Código del script operadores-aritmeticos.php del capítulo:

<?php 
$sumar = 2 + 2;
echo "<p>La suma de 2 + 2 es igual a " . $sumar . "</p>";
$restar = 4 - 3;
echo "<p>La resta de 4 - 3 es igual a " . $restar . "</p>";
$negativos = -20 + -20;
echo "<p>La suma de -20 + -20 es igual a " . $negativos . "</p>";
$string = "12.4";
$sumar = 3 + $string;
echo "<p>La suma de 3 + $string es igual a " . $sumar . "</p>";
echo "<p>Voy a sumar números en esta salida de datos " . (4+4) . "</p>";
$dividir = 4 / 2;
echo "<p>La división de 4 / 2 es igual a " . $dividir . "</p>";
$multiplicar = 3 * 3;
echo "<p>La multiplicación de 3 * 3 es igual a " . $multiplicar . "</p>";
$resto = 3 % 2;
echo "<p>El resto de la división de 3 / 2 es igual a " . $resto . "</p>";
$exponente = 2 ** 3;
echo "<p>Resultado de 2 elevado al cubo " . $exponente . "</p>";
$precedencia = 3 + 3 * 3;
echo "<p>3 + 3 * 3 = " . $precedencia . "</p>";
$precedencia = (3 + 3) * 3;
echo "<p>(3 + 3) * 3 = " . $precedencia . "</p>";




jueves, 31 de diciembre de 2015

4 - Tutorial de PHP7 - Arrays




Bienvenid@s, en este capítulo del Tutorial de PHP7 continuamos con la referencia del lenguaje, concretamente con los tipos de datos compuestos Arrays y el tipo de datos especial NULL.

Referencia del Lenguaje - Tipo de datos compuestos: Arrays | tipo de datos especiales: NULL

Definición de Array: Un array en PHP es en realidad un mapa ordenado. Un mapa es un tipo de datos que asocia valores con claves. Este tipo se optimiza para varios usos diferentes; se puede emplear como un array, lista (vector), tabla asociativa (tabla hash - una implementación de un mapa), diccionario, colección, pila, cola, y posiblemente más. Ya que los valores de un array pueden ser otros arrays, también son posibles árboles y arrays multidimensionales.
 
Definición de NULL: El valor especial NULL representa una variable sin valor.

Modos de crear arrays:
  • Un array puede ser creado con el constructor del lenguaje array()
  • A partir de PHP 5.4 también se puede usar la sintaxis de array corta, la cual reemplaza el constructor del lenguaje array() con los corchetes [].
Tipos de arrays que se practicarán:
  • Arrays unidimensionales: array que contiene como elementos valores unidimensionales como por ejemplo los tipos de datos escalares.
  • Arrays multidimensionales (árbol): array que contiene como elementos otros arrays, este tipo de arrays también pueden contener elementos unidimensionales.
  • Arrays asociativos: array cuyos elementos son asociados a través de una clave, la clave se asocia al valor del elemento, la clave puede ser del tipo integer ó string.
Funciones optimas para imprimir el contenido de un array: var_dump($array) y print_r($array)


Código de ejemplo del script arrays.php del capítulo:

<?php 
//Variable sin valor
$variable = null;

//Arrays unidimensionales, arrays indexados
//Array con el constructor del lenguaje array()
$array_1 = array(1, 2, 3, 4, 5, "string", 3.14, true, "más elementos");
//Array con la sintaxis corta []
$array_2 = [1, 2, 3, 4, 5];

//Mostrar información del array
var_dump($array_1);

echo "<p>Accediendo al primer elemento del array_1: " . $array_1[0] . "</p>";
echo "<p>Accediendo al elemento con index 5 en array_1: " . $array_1[5] . "</p>";
echo "<p>Total de elementos del array_2: " . count($array_2) . "</p>";

//Cambiar valor de un elemento del array en tiempo de ejecución
$array_2[1] = 'Me has cambiado de valor';
echo "<p>Accediendo al elemento con index 1 en array_2: " . $array_2[1] . "</p>";

//Arrays multidimensionales, entre sus elementos se encuentran otros arrays
$array_3 = ['uno', 2, ['tres', 'cuatro', [5, 6]], $array_2];

//Mostrar información del array
var_dump($array_3);
//Acceso a valores de elementos de arrays multidimensionales
echo "<p>" . $array_3[2][1] . "</p>";
echo "<p>" . $array_3[2][2][1] . "</p>";
echo "<p>" . $array_3[3][4] . "</p>";

/* Arrays asociativos, no indexados, se accede a los elementos a través de una clave que se asocia a un determinado valor */
$array_4 = ['uno' => 1, 'dos' => 2, 3 => 'hola', 'array' => $array_2, 'array1' => ['uno', 'dos']];
var_dump($array_4);
echo "<p>Accediendo al segundo elemento del array_4: " . $array_4['dos'] . "</p>";
echo "<p>Accediendo al tercer elemento del array_4: " . $array_4[3] . "</p>";
$array_4[3] = 'cambiando de valor';
echo "<p>Accediendo al tercer elemento del array_4: " . $array_4[3] . "</p>";

echo "<p>" . $array_4['array'][0] . "</p>";





martes, 29 de diciembre de 2015

3 - Tutorial de PHP7 - Variables, constantes y Tipo de datos escalares




Bienvenid@s, en este capítulo del Tutorial de PHP7 continuamos con la referencia del lenguaje, veremos como crear variables y constantes y asignarle valores del tipo de datos escalar. También veremos la principal diferencia entre comillas simples y dobles y la concatenación (unión de strings).

Referencia del Lenguaje - Variables, constantes y Tipo de datos escalares:

Definición de variable: En programación, una variable está formada por un espacio en el sistema de almacenaje (memoria principal de un ordenador) y un nombre simbólico (un identificador) que está asociado a dicho espacio. Ese espacio contiene una cantidad o información conocida o desconocida, es decir un valor. Su principal diferencia respecto a una constante es que ésta puede modificar su valor a lo largo de la ejecución del programa.
 
Definición de constante: En programación, una constante consta de un identificador y un valor que no puede ser alterado/modificado durante la ejecución de un programa, únicamente puede ser leído. Una constante corresponde a una longitud fija de un área reservada en la memoria principal del ordenador, donde el programa almacena valores fijos.
 
Definición de Tipo de datos escalar: Un tipo de dato escalar puede ser una variable o una constante que contiene un dato unidimensional. En PHP El tipo de una variable ó constante usualmente no lo declara el programador; al contrario, es decidido en tiempo de ejecución por PHP dependiendo del contexto en el que se emplea dicha variable.
  • Tipos de datos escalares:
    • Booleanos: Puede tener uno de los dos siguientes valores: true (verdadero) ó false (falso). Este tipo de datos es normalmente pasado a una estructura de control.
    • Integer: Números enteros
    • Float: Números de punto flotante
    • String: Cadenas de texto


Para crear una variable utilizaremos en el identificador como primer carácter el signo de dollar $, a continuación el carácter que le puede preceder puede ser una letra ó un guión bajo.

$variable = 1; //Correcto
$_variable = 2; //Correcto
$_variable_ = "hola"; //Correcto
$_variable_1 = 3.11; //Correcto
$1variable = true; //Incorrecto


La principal diferencia entre comillas simples y dobles. Si incluimos el identificador entre comillas dobles al realizar la salida de datos se mostrará el valor de la variable, entre comillas simples se mostrará el identificador. Por ejemplo ...

$integer = 2;
echo "<p>$integer</p>"; //Se mostrará 2
echo '<p>$integer</p>'; //Se mostrará $integer


La concatenación. La concatenación consiste en la unión de strings, en PHP la concatenación la haremos separando cada string con un punto ".", es válido para comillas simples y dobles. Ejemplo ...

$variable1 = "hola";
$variable2 = 4;
echo '<p>' . $variable1 . '</p>' . '<p>' . $variable2 . '</p>';


A continuación podéis ver el código del script del capítulo variables-constantes.php:

<?php 

/* Variables */
$boolean = true;
$integer = 20;
$float = -45.12;
$string_1 = "String entre comillas dobles";
$string_2 = 'String entre comillas simples';

echo "<p>" . $boolean . "</p>" . "<strong>Valor boolean</strong>";
echo '<p>' . $integer . '</p>';
echo "<p>$float</p>";
echo "<p>$string_1</p>";
echo "<p>$string_2</p>";

$integer = 3;
echo "<p>$integer</p>";

/* Constantes */
define("pi", 3.14);
echo "<p>" . pi . "</p>";

define("pi", 2);
echo "<p>" . pi . "</p>";






2 - Tutorial de PHP7 - Sintaxis básica y salida de datos




Bienvenid@s en este capítulo del Tutorial de PHP7 empezamos a ver la Referencia del Lenguaje, concretamente, aspectos básicos como la salida de datos, PHP en Html, separación de bloques de instrucciones y los comentarios.

Referencia del Lenguaje - Sintaxis básica y salida de datos:



  • Salida de datos con las funciones print, echo y la etiqueta especial de apertura <?=
  • PHP en Html
  • Separación de bloque de instrucciones
  • Comentarios

  • Para la salida de datos podemos utilizar las funciones print y echo y la etiqueta especial de apertura <?= disponible desde la versión de PHP 5.4.0. En el siguiente ejemplo estamos realizando una salida de tres párrafos ...

    <?php
    echo "<p>Hola mundo</p>";
    print '<p>Una nueva línea</p>';
    ?>
    <?= "<p>Etiqueta especial</p>" ?>
    


    Como puedes ver cada instrucción se cierra con el punto y coma ";", si se trata de la última instrucción o única instrucción del bloque no es necesario incluir el punto y coma de fin de la instrucción. En el caso anterior ...

    <?php
    echo "<p>Hola mundo</p>";
    print '<p>Una nueva línea</p>'
    ?>
    <?= "<p>Etiqueta especial</p>" ?>
    


    PHP en Html. Una de las características de PHP es que podemos escribir PHP en Html, por ejemplo, podemos encerrar los tres párrafos anteriores entre unas etiquetas html "div" ...

    <div>
    <?php
    echo "<p>Hola mundo</p>";
    print '<p>Una nueva línea</p>'
    ?>
    <?= "<p>Etiqueta especial</p>" ?>
    </div>
    


    Otro aspecto importante es cuando se trata del último bloque de instrucciones y no le precede otro contenido, en este caso, podemos ignorar la inclusión de la etiqueta de cierre ?> de PHP, aunque por supuesto, la podemos incluir, de ambas formas sería correcto. Continuando con el código anterior, agregaremos un último bloque de instrucciones de PHP. Por ejemplo ...

    <div>
    <?php
    echo "<p>Hola mundo</p>";
    print '<p>Una nueva línea</p>'
    ?>
    <?= "<p>Etiqueta especial</p>" ?>
    </div>
    
    <?php
    echo "<p>Bloque final de php</p>";
    


    Otro aspecto importante es la inclusión de comentarios en los scripts php, los comentarios no son interpretados como código y para el programador son muy útiles, para ir comentando las diferentes partes de la estructura de código.

    Para una sóla línea de comentario utilizaremos:

    // comentario

    Para varias líneas de comentario utilizaremos:

    /* una línea de comentario
    otra línea de comentario
    otra línea más de comentario */


    El código completo del script de este capítulo sintaxis-basica.php es el siguiente:

    <div>
    <?php
    echo "<p>Hola mundo</p>";
    print '<p>Una nueva línea</p>'
    ?>
    <?= "<p>Etiqueta especial</p>" ?>
    </div>
    
    <?php
    //Comentarios en una sola línea
    /* 
    una línea
    otra línea
    */
    echo "<p>Bloque final de php</p>";
    





    lunes, 28 de diciembre de 2015

    1 - Tutorial de PHP7 - Introducción e instalación en Windows




    Bienvenid@s a este primer capítulo del Tutorial de PHP7, a continuación podéis seguir la guía con una breve introducción de los temas que veremos en el tutorial, la instalación de PHP7, herramientas, la puesta en marcha de un servidor de desarrollo y la ejecución del primer script PHP.

    Introducción al Curso de PHP7

    - ¿Qué es y que podemos hacer con PHP?

    PHP es un lenguaje de programación interpretado de alto rendimiento que es de código abierto y muy popular especialmente adecuado para el desarrollo web y que tiene como especial característica que puede ser incrustado en HTML.
     
    En lugar de usar muchos comandos para mostrar HTML (como en C o en Perl), las páginas de PHP contienen HTML con código incrustado. El código de PHP está encerrado entre las etiquetas especiales de comienzo y final <?php y ?> que permiten entrar y salir del "modo PHP". 
     
    A diferencia del código Javascript que es ejecutado del lado del cliente, el código PHP es ejecutado en el servidor, aunque el código php esté incrustado en el HTML este código es innaccesible para el usuario, de lo contrario el código Javascript si. 
     
    PHP está enfocado principalmente a la programación de scripts del lado del servidor, por lo que se puede hacer cualquier cosa que pueda hacer otro programa CGI, como recopilar datos de formularios, generar páginas con contenidos dinámicos, o enviar y recibir cookies. Aunque PHP puede hacer mucho más.

    - Objetivo del curso

    • Referencia del Lenguaje: Sintaxis básica, Tipos, Variables, Constantes, Expresiones, Operadores, Estructuras de Control, Funciones, POO, ...
    • Seguridad: Envío de formularios seguros, consultas a bases de datos, expresiones regulares, ...
    • Referencia de funciones: uso de extensiones básicas para el manejo de ficheros, envío de correos electrónicos, manejo de bases de datos, ...
    • Manejo de librerías populares desarrolladas con PHP

    Instalación en Windows de PHP7

    Una vez descargado crear una carpeta, por ejemplo, en el escritorio llamada "php7" y extraer los ficheros descargados en esta carpeta.

    Herramientas para escribir código:


    Poniendo en marcha un servidor de desarrollo

    • Crear el directorio que utilizaremos como "document root", normalmente lo llamaremos como "public", en este directorio incluiremos los scripts php, archivos html o cualquier otro que pueden ser accesibles (públicos). Para el Tutorial crearemos una carpeta, por ejemplo, en el escritorio llamada "tutorial-php7" en el interior de esta carpeta crearemos la carpeta pública "public"
    • Poner en marcha el servidor:
      • Abrir una consola, ir a la raiz de la carpeta dónde hemos alojado los archivos descargados de PHP, por ejemplo:
        • cd c:\Users\usuario\Desktop\php7
      • Ejecutar el siguiente comando:
        php -S localhost:8080 -t c:\Users\usuario\Desktop\tutorial-php7\public

    Mi primer script PHP

    Abrir el editor de código, crear un nuevo archivo y guardarlo como "index.php" en la carpeta "public" de la carpeta "tutorial-php7".

    Incluye el siguiente código en el archivo "index.php":
     
    <?php echo "Tutorial de PHP7"; ?>

    Ve al navegador, abre una nueva pestaña e incluye la dirección del servidor de desarrollo: 

    http://localhost:8080

    Verás el texto "Tutorial de PHP7", este código ha sido ejecutado en el servidor y ha regresado esta respuesta, si ves el código fuente de la página podrás comprobar como el código php no está disponible en el cliente (Navegador).




    martes, 15 de diciembre de 2015

    25 - Tutorial de Laravel 5 - OAuth2 Socialite (Registrar y autenticar al usuario)




    En este capítulo del Tutorial de Laravel 5 continuamos dándole forma a la autenticación y registro de usuarios a través de proveedores como Facebook y Google, este capítulo es la continuación del anterior.

    Para empezar realizamos una modificación en la tabla "users" agregándole una nueva columna llamada "social" del tipo BOOLEAN y con valor por defecto 0 (false). Esta columna nos permitirá determinar saber si el usuario autenticado es un usuario registrado de forma normal o a través de un proveedor de servicios. También editaremos la columna "password" de la tabla "users" permitiendo valores nulos.

    Crearemos una nueva tabla con artisan llamada "user_social_accounts" en la cual guardaremos información extra de los usuarios, tales como el id de registro del usuario de la tabla "users", el proveedor y el id del proveedor.

    Abrir una consola, ir a la raiz del proyecto Laravel y ejecutar el siguiente comando para crear la clase ...

    php artisan make:migration user_social_accounts --create=user_social_accounts
    


    En la carpeta "database\migrations" se ha generado un nuevo archivo "xxx_user_social_accounts.php", abrirlo y agregar el método up() el siguiente código ...

            Schema::create('user_social_accounts', function (Blueprint $table) {
                $table->increments('id');
    	    $table->integer('user_id');
    	    $table->string('provider');
    	    $table->string('uid_provider');
            });
    


    Guardar el archivo, regresar a la consola y realizar la migración con el siguiente comando ...

    php artisan migrate
    


    A continuación crearemos un modelo que nos permita utilizar eloquent para esta nueva tabla, en la carpeta "app" crearemos un nuevo archivo llamado "Social.php" y le agregaremos el siguiente código ...

    <?php
    namespace App;
    
    use Illuminate\Database\Eloquent\Model;
    
    class Social extends Model
    {
        protected $table = 'user_social_accounts';
        public $timestamps = false;
    }
    


    A continuación nos dirigimos al controlador que creamos en el capítulo anterior SocialController para realizar las modificaciones necesarias para la acción que recibe la respuesta del proveedor con la información del usuario, primero agregamos el nuevo modelo: 

    use App\Social;

    Y luego modificamos la acción getSocialAuthCallback ...

      public function getSocialAuthCallback($provider=null)
           {
              if($user = Socialite::driver($provider)->user()){
    			  
                 if ($the_user = User::select()->where('email', '=', $user->email)->first())
    			 {
    				 Auth::login($the_user);
    			 }	else{
    				 $new_user = new User;
    				 $new_user->name = $user->name;
    				 $new_user->email = $user->email;
    				 $new_user->perfiles = $user->avatar;
    				 $new_user->active = 1;
    				 $new_user->social = 1;
    				 $new_user->save();
    				 Auth::login($new_user);
    				 
    				 //Registrar Información extra
    				 $social = new Social;
    				 $social->user_id = $new_user->id;
    				 $social->provider = $provider;
    				 $social->uid_provider = $user->id;
    				 $social->save();
    			 }
    			 return redirect('home');
              }else{
                 return '¡¡¡Algo fue mal!!!';
              }
           }
    


    En esta acción comprobamos primeramente si hemos podido obtener información del usuario, si es así, comprobamos si se encuentra registrado en la tabla "users" a través de su email, de ser así, autenticamos el usuario, de lo contrario, si el usuario no se encuentra registrado, lo registramos y lo autenticamos y guardamos la información extra del usuario en la nueva tabla "user_social_accounts".

    Ahora realicen la prueba de registrarse en la aplicación a través de Facebook y Google. Otra cosa que se muestra en el vídeo es como establecer a través de una condición si el usuario es registrado normal o a través de un proveedor, el ejemplo se muestra en la vista user.blade.php que muestra el panel de usuario, donde se muestran distintas opciones, entre ellas la posibilidad de cambiar el password, para el caso de los usuarios autenticados a través de un proveedor, esta opción no debe estar disponible, de modo que con una simple condición podemos mostrar o no la opción de cambiar el password ...

    	@if(Auth::user()->social == 0)
        <li><a href="{{url('user/password')}}">Cambiar mi password</a></li>
    	@endif
    


    Como pueden ver en esta condición entra en juego la columna "social", 0 es para usuarios registrados de forma normal y 1 para usuarios registrados a través de un proveedor.




    lunes, 14 de diciembre de 2015

    24 - Tutorial de Laravel 5 - OAuth2 Socialite (Facebook & Google)




    En este capítulo del Tutorial de Laravel 5 veremos como podemos integrar servicios como Google y Facebook para autenticar usuarios en nuestra aplicación.


    Lo primero es crear ambas aplicaciones para obtener las claves de acceso a las apis de Facebook y Google, el proceso de creación de las aplicaciones se muestran al inicio del vídeo.


    Seguiremos las instrucciones de la documentación de Laravel para instalar Socialite a través de composer, Socialite nos ofrece soporte para los siguientes proveedores: Facebook, Twitter, LinkedIn, Google, GitHub y Bitbucket.


    Abrir una consola, ir a la raíz del proyecto laravel, en el vídeo se utiliza composer.phar para su instalación y ejecutar el siguiente comando ...


    php composer.phar require laravel/socialite
    


    Agregar el nuevo proveedor y el alias en el archivo "config\app.php" ...


    //Providers
    Laravel\Socialite\SocialiteServiceProvider::class,
    
    //Aliases
    'Socialite' => Laravel\Socialite\Facades\Socialite::class,
    


    Agregar las credenciales de acceso a los servicios de google y facebook en el archivo "config\service.php" ...


     'facebook' => [
      'client_id' => '',
      'client_secret' => '',
      'redirect' => 'http://localhost/tutorial-laravel/public/social/callback/facebook',
     ],
     
     'google' => [
      'client_id' => '',
      'client_secret' => '',
      'redirect' => 'http://localhost/tutorial-laravel/public/social/callback/google',
     ],
    


    Crear un nuevo controlador llamado "SocialController.php" con el siguiente código ...


    <?php 
    
    namespace App\Http\Controllers;
    use App\Http\Controllers\Controller;
    use Illuminate\Http\Request;
    use App\User;
    use Auth;
    use Socialite;
    
    class SocialController extends Controller {
    
        public function __construct(){
         $this->middleware('guest');
        }
    
           public function getSocialAuth($provider=null)
           {
               if(!config("services.$provider")) abort('404');
    
               return Socialite::driver($provider)->redirect();
           }
    
    
           public function getSocialAuthCallback($provider=null)
           {
              if($user = Socialite::driver($provider)->user()){
                 dd($user);  
              }else{
                 return '¡¡¡Algo fue mal!!!';
              }
           }
    }
    


    A este controlador sólo tendrán acceso los usuarios invitados, la acción getSocialAuth es la encargada de realizar la petición al proveedor y la acción getSocialAuthCallback es la encargada de obtener la respuesta con los datos del usuario.


    Agregaremos las nuevas rutas en routes.php ...


    //Social Login
    Route::get('social/{provider?}', 'SocialController@getSocialAuth');
    Route::get('social/callback/{provider?}', 'SocialController@getSocialAuthCallback');
    


    El argumento provider es opcional y tendrá como valor el nombre del proveedor a acceder, en nuestro caso, Google ó Facebook.


    En el vídeo se comenta la posibilidad de obtener un error en Windows al obtener la respuesta de los proveedores "cURL error 60: SSL certificate problem: unable to get local issuer certificate (see http://curl.haxx.se/libcurl/c/libcurl-errors.html ...", para solventar este error descargaremos el siguiente certificado ... cacert.pem, lo guardaremos en la carpeta "xampp", abriremos la carpeta php y abriremos el archivo "php.ini" para agregar la siguiente línea al final ...

    curl.cainfo = "C:\xampp\cacert.pem"

    Guardar el archivo y reiniciar nuevamente apache.


    Para ver la prueba agregaremos dos links a la vista "auth\login.blade.php" para acceder a los proveedores ...


     ...
     <br />
     <a href='{{url("social/facebook")}}'>Iniciar sesión con Facebook</a>
     <br />
     <a href='{{url("social/google")}}'>Iniciar sesión con Google</a>
    


    Ahora prueben a iniciar sesión con Facebook ó Google para ver como los proveedores te solitican la primera vez que permitas a la aplicación tener información tuya y como posteriormente te redirecciona mostrando la información de usuario.





    lunes, 7 de diciembre de 2015

    23 - Tutorial de Laravel 5 - Admin Panel (Panel de Administrador)




    En este capítulo del Tutorial de Laravel 5 veremos un supuesto en el cual tenemos que crear un Panel de Administrador. La condición de administrador o no, la realizaremos desde la tabla users, para esta tarea crearemos una nueva columna llamada "user" del tipo integer y con un valor por defecto 0, el valor de esta columna nos determinará el tipo de usuario del que se trata, 0 para usuario normal y 1 para usuario administrador.


    Empezaremos con el uso de artisan para realizar la migración, primero generaremos la clase, abrir una consola, dirigirnos a la raiz de nuestro proyecto e introducir el siguiente comando ...


    php artisan make:migration add_user_to_users
    


    Una vez se ha generado el archivo, nos dirigimos a "database\migrations" y abrimos el archivo xxx_add_user_to_users.php e incluimos el siguiente código dentro del método up() para crear la nueva columna ...


            Schema::table('users', function($table){
                $table->integer('user')->default(0);
            });
    


    A continuación regresamos a la consola y realizamos la migración ...


    php artisan migrate
    


    Ok, ya tenemos la nueva columna "user" en la tabla "users".


    Para el acceso al panel de administrador crearemos un nuevo controlador "AdminController", el controlador lo crearemos con artisan, desde la consola ...


    php artisan make:controller AdminController
    


    Nos dirigimos al nuevo controlador que se encuentra en "app\Http\Controllers" y dejamos la clase vacía, es decir, quitamos todos los métodos que se incluyen por defecto e importamos las siguientes clases ...


    use App\User;
    use Validator;
    use Auth;
    


    A continuación crearemos una acción-ruta "createAdmin" que permitirá al propietario de la aplicación crear un administrador o administradores, esta acción-ruta ha de ser usada y posteriormente comentada para evitar el acceso a cualquier usuario ...


    Agregar el código de la acción "createAdmin" al controlador AdminController ...


    public function createAdmin(Request $request){
      
      if ($request->isMethod('post'))
      {
       //Roles de validación
       $rules = [
        'name' => 'required|min:3|max:16|regex:/^[a-záéíóúàèìòùäëïöüñ\s]+$/i',
        'email' => 'required|email|max:255|unique:users,email',
        'password' => 'required|min:6|max:18|confirmed',
       ];
       
       //Posibles mensajes de error de validación
       $messages = [
        'name.required' => 'El campo es requerido',
        'name.min' => 'El mínimo de caracteres permitidos son 3',
        'name.max' => 'El máximo de caracteres permitidos son 16',
        'name.regex' => 'Sólo se aceptan letras',
        'email.required' => 'El campo es requerido',
        'email.email' => 'El formato de email es incorrecto',
        'email.max' => 'El máximo de caracteres permitidos son 255',
        'email.unique' => 'El email ya existe',
        'password.required' => 'El campo es requerido',
        'password.min' => 'El mínimo de caracteres permitidos son 6',
        'password.max' => 'El máximo de caracteres permitidos son 18',
        'password.confirmed' => 'Los passwords no coinciden',
       ];
       
       $validator = Validator::make($request->all(), $rules, $messages);
       
       //Si la validación no es correcta redireccionar al formulario con los errores
       if ($validator->fails()){
        return redirect()->back()->withErrors($validator);
       }
       else{ // De los contrario guardar al usuario
        $user = new User;
        $user->name = $request->name;
        $user->email = $request->email;
        $user->password = bcrypt($request->password);
        $user->remember_token = str_random(100);
        $user->confirm_token = str_random(100);
        //Activar al administrador sin necesidad de enviar correo electrónico
        $user->active = 1;
        //El valor 1 en la columna determina si el usuario es administrador o no
        $user->user = 1;
        
        if ($user->save()){
         return redirect()->back()->with('message', 'Enhorabuena nuevo administrador creado correctamente');
        } else{
         return redirect()->back()->with('error', 'Ha ocurrido un error al guardar los datos');
        }
       }
      }
      
      return View('admin.createadmin');
     }
    


    Esta acción estará disponible tanto para los métodos get y post, get para mostrar la vista "createadmin" que contiene el formulario de registro de administradores y post para recibir los argumentos del formulario. Si el formulario es enviado se valida, si pasa la validación se registra el nuevo usuario activándolo y con permisos de administrador.


    A continuación creamos una nueva ruta para asociarla a esta acción en routes.php ...

    Route::match(['get', 'post'], 'admin/createadmin', 'AdminController@createAdmin');
    


    Y creamos una nueva carpeta para las vistas del controlador "AdminController", en "resources\views", creamos una carpeta con nombre "admin" y agregamos la vista "createadmin.blade.php" que contiene el formulario de registro de administradores, el código es el siguiente ...

    @extends('layouts.home')
    @section('content')
    <h1>Crear un nuevo administrador</h1>
    <div class='bg-danger' style='padding: 20px'>¡¡¡Una vez termines de crear el administrador desactiva esta acción-ruta!!!</div>
    <hr />
    @if (Session::has('message'))
     <div class='bg-info' style='padding: 20px'>
      {{Session::get('message')}}
     </div>
     <hr />
    @endif
    @if (Session::has('error'))
     <div class='bg-danger' style='padding: 20px'>
      {{Session::get('error')}}
     </div>
     <hr />
    @endif
    <form method="POST" action="{{url('admin/createadmin')}}">
        {!! csrf_field() !!}
    
        <div class='form-group'>
            <label for="name">Nombre:</label>
            <input type="text" name="name" class="form-control" value="{{ old('name') }}" />
            <div class="text-danger">{{$errors->first('name')}}</div>
        </div>
    
        <div class="form-group">
            <label for="email">Email:</label>
            <input type="email" name="email" class="form-control" value="{{ old('email') }}" />
            <div class="text-danger">{{$errors->first('email')}}</div>
        </div>
    
        <div class="form-group">
            <label for="password">Password:</label>
            <input type="password" class="form-control" name="password">
            <div class="text-danger">{{$errors->first('password')}}</div>
        </div>
    
        <div class="form-group">
            <label for="password_confirmation">Confirmar Password:</label>
            <input type="password" class="form-control" name="password_confirmation">
        </div>
    
        <div>
            <button type="submit" class="btn btn-primary">Crear administrador</button>
        </div>
    </form>
    <br /><br /><br /><br />
    @stop
    


    Como podéis ver el formulario es prácticamente igual al formulario de registro que ya creamos en un capítulo anterior.

    Ahora en el navegador, vamos a la nueva ruta "admin/createadmin" para registrar un administrador. Una vez que hemos creado el/los administrador/es es muy importante que comentemos la acción "createAdmin" y la ruta que la conecta.

    Ahora incluiremos la lógica al controlador "AdminController", para ello incluiremos el método constructor y haremos uso de middleware para permitir el acceso al mismo sólo a los usuarios autenticados, excepto a la acción createAdmin.

        public function __construct(){
            $this->middleware('auth', ['except' => 'createAdmin']);
        }
    


    A continuación crearemos un método privado que será el encargado de comprobar si el usuario autenticado es administrador o no. Este método luego será utilizado en cada una de las acciones del controlador. Código del método privado isAdmin() ...

        private function isAdmin(){
            if (Auth::user()->user == 1) return true;
            else return false;
        }
    


    El método anterior regresa un valor boolean. Si la columna "user" del usuario autenticado es igual 1 es que es administrador. Para ver la prueba crearemos una nueva acción-ruta llamada "admin" con el siguiente código ...

        public function admin(){
            if ($this->isAdmin()){
                return View('admin.admin');
            } else{
                return redirect()->back();
            }
        }
    


    Si el usuario es administrador mostramos una vista de lo contrario lo expulsamos redireccionándolo de dónde vino.

    Esta acción "admin" la conectaremos a una nueva ruta en routes.php ...

    Route::get('admin', 'AdminController@admin');
    


    Y crearemos la nueva vista "admin.blade.php" en la carpeta "admin" con el siguiente código ...

    @extends('layouts.home')
    @section('content')
    <h1>Bienvenid@ {{Auth::user()->name}} a su Panel de Administrador</h1>
    @stop
    


    Otra cosa que podemos hacer para finalizar es agregar un link al ménu del layout "home.blade.php" que permita al usuario administrador, ir al panel de administrador ...

              <ul class="nav navbar-nav navbar-right">
       @if (Auth::check())
                            @if (Auth::user()->user == 1)
       <li><a href="{{url('admin')}}">Panel de Administrador</a></li>
                            @endif
       <li><a href="{{url('user')}}">{{Auth::user()->name}}</a></li>
       <li><a href="{{url('auth/logout')}}">Salir</a></li>
       @else
                <li><a href="{{url('auth/login')}}">Iniciar sesión</a></li>
       @endif
              </ul>
    


    Ahora prueben a iniciar sesión como usuarios normales y como administradores. 







    viernes, 4 de diciembre de 2015

    22 - Tutorial de Laravel 5 - Download Files (Descargar archivos del servidor)




    En este capítulo del Tutorial de Laravel 5 veremos un nuevo supuesto, en el cual nos solicitan incluir una opción en el Panel de Usuario para descargar un archivo pdf con los "términos y condiciones de uso del portal". La descarga de archivos sólo estará permitida a los usuarios autenticados.

    Lo primero que haremos es agregar esta nueva opción a la vista "user.blade.php" ...

    <li><a href="{{url('user/download')}}">Descargar términos y condiciones de uso</a></li>
    


    A continuación crearemos la carpeta donde se incluirán los archivos descargables, si creamos esta carpeta en la carpeta "public" cometemos el error de que estará disponible a cualquier usuario, así que la crearemos en la carpeta "app" con el nombre "files" y le agregaremos un archivo pdf con el nombre "terminos.pdf".

    A continuación agregaremos la ruta de descarga en routes.php, lógicamente es la misma que estamos indicando en el link de la opción ...

    Route::get('user/download', 'UserController@download');
    


    Esta ruta está conectada al controlador "UserController" y a una acción llamada "download", recuerden que sólo los usuarios autenticados pueden tener acceso a las acciones de este controlador.

    Para la reutilización de código crearemos un nuevo método protegido llamado downloadFile, sólo accesible desde la clase y clases heredadas, este método lo podremos migrar a otra clase en caso de ser necesario. A este método tenemos que pasar un argumento, el cual es la ruta del archivo, este método regresa un valor boolean, si el archivo existe se procede a su descarga y retorna true, de lo contrario false. En el controlador UserController agregaremos el método ...

        protected function downloadFile($src){
            if(is_file($src)){
                $finfo = finfo_open(FILEINFO_MIME_TYPE);
                $content_type = finfo_file($finfo, $src);
                finfo_close($finfo);
                $file_name = basename($src).PHP_EOL;
                $size = filesize($src);
                header("Content-Type: $content_type");
                header("Content-Disposition: attachment; filename=$file_name");
                header("Content-Transfer-Encoding: binary");
                header("Content-Length: $size");
                readfile($src);
                return true;
            } else{
                return false;
            }
        }
    


    También en el controlador UserController agregaremos la acción "download", en esta acción haremos uso del método downloadFile comprobando si la descarga se ha realizado con éxito o no, si no es así, redireccionamos atrás nuevamente ...

        public function download(){
            if(!$this->downloadFile(app_path()."/files/terminos.pdf")){
                return redirect()->back();
            }
        }
    


    Finalmente probaremos en el Panel de Control de usuario esta nueva opción.






    jueves, 3 de diciembre de 2015

    21 - Tutorial de Laravel 5 - Public Profile (Perfil público de usuario)




    En este capítulo del Tutorial de Laravel 5 veremos un supuesto en el cual tenemos que crear un perfil público de usuario, a partir, de la aplicación desarrollada hasta el momento.

    Lo primero será crear una nueva ruta en la cual se muestre el perfil, esta ruta se la agregaremos a los nombres de usuario que aparecen en las vistas home.blade.php y search.blade.php.

    En home.blade.php estas modificaciones las haremos en la sección para públicar comentarios y en la sección en la que se muestran los comentarios. Código completo de la vista home.blade.php ...

    @extends('layouts.home')
    
    @section('content')
    <h1>Bienvenid@s a la aplicación Laravel</h1>
    <hr />
    @if (Session::has('status'))
     <div class="bg-success" style="padding: 20px;">
      {{Session::get('status')}}
     </div>
     <hr />
    @endif
    @if (Session::has('error'))
     <div class="bg-danger" style="padding: 20px;">
      {{Session::get('error')}}
     </div>
     <hr />
    @endif
    @if (Auth::check())
     <form method="post" action="{{url('user/createcomment')}}">
      {{csrf_field()}}
      <div class="form-group">
       <div class="row">
        <div class="col-md-1">
         <img src="{{url(Auth::user()->perfiles)}}" class='img-responsive' style='max-width: 60px' />
                                            <strong><a href="{{url('home/user/'.Auth::user()->id)}}">{{Auth::user()->name}}</a></strong>
        </div>
        <div class="col-md-6">
         <textarea name="comment" class="form-control"></textarea>
         <br />
         <button type="submit" class="btn btn-primary">Publicar</button>
        </div>
       </div>
      </div>
     </form>
     <hr />
            <?php 
            $comments = App\Comments::select()->orderBy('id', 'desc')->simplePaginate(5);
            $modal = 0;
            foreach($comments as $comment):
                $user = App\User::select()->where('id', '=', $comment->id_user)->first();
            ?>
            <div class="row">
                <div class="col-md-1">
                    <img src='{{url($user->perfiles)}}' class='img-responsive' style='max-width: 60px' />
                    <strong><a href="{{url('home/user/'.$user->id)}}">{{$user->name}}</a></strong>
                </div>
                <div class='col-md-6'>
                   {{$comment->comment}} 
                   <br />
                   <i>Fecha: {{$comment->date}} · Hora: {{$comment->time}}</i>
                   
                   
                   
                   @if($comment->id_user == Auth::user()->id)
                   <hr />
                    <!-- Botón que abre la ventana modal eliminar -->
                    <button type="button" class="btn btn-danger" data-toggle="modal" data-target="#deleteComment{{$modal}}">
                      Eliminar
                    </button>
    
                    <!-- Ventana modal para eliminar -->
                    <div class="modal fade" id="deleteComment{{$modal}}" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
                      <div class="modal-dialog" role="document">
                        <div class="modal-content">
                          <div class="modal-header">
                            <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
                            <h4 class="modal-title" id="myModalLabel">¿Realmente quieres eliminar este comentario?</h4>
                          </div>
                          <div class="modal-body">
                            <form method="post" action="{{url('user/deletecomment')}}">
                                {{csrf_field()}}
                                <input type="hidden" name="id_comment" value="{{$comment->id}}" />
                                <button type="submit" class="btn btn-danger">Eliminar</button>
                            </form>
                          </div>
                          <div class="modal-footer">
                            <button type="button" class="btn btn-default" data-dismiss="modal">Cerrar</button>
                          </div>
                        </div>
                      </div>
                    </div>
    
                    <!-- Botón para abrir la ventana modal de editar -->
                    <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#editComment{{$modal}}">
                      Editar
                    </button>
    
                    <!-- Ventana modal editar -->
                    <div class="modal fade" id="editComment{{$modal}}" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
                      <div class="modal-dialog" role="document">
                        <div class="modal-content">
                          <div class="modal-header">
                            <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
                            <h4 class="modal-title" id="myModalLabel">Editar comentario</h4>
                          </div>
                          <div class="modal-body">
                            <form method="post" action="{{url('user/editcomment')}}">
                                {{csrf_field()}}
                                <div class="form-group">
                                <textarea name="comment" rows="10" class="form-control">{{$comment->comment}}</textarea>
                                </div>
                                <input type="hidden" name="id_comment" value="{{$comment->id}}" />
                                <button type="submit" class="btn btn-primary">Editar</button>
                            </form>
                          </div>
                          <div class="modal-footer">
                            <button type="button" class="btn btn-default" data-dismiss="modal">Cerrar</button>
                          </div>
                        </div>
                      </div>
                    </div>
                    <?php $modal++ ?>
                   @endif
                </div>
            </div>
            <hr />
            <?php endforeach ?>
            <div class='text-center'>
            <?php /*Nuevo*/ $comments->setPath('') ?>
            <?php echo $comments->render() ?>
               <p>Página {{$comments->currentPage()}}</p>
            </div>
            <br /><br /><br /><br />
    @else
     <hr />
     <p class="bg-info" style="padding: 20px;">Para poder publicar comentarios tienes que <a href="{{url('auth/login')}}">iniciar sesión</a></div>
     <hr />
    @endif
    @stop
    


    En la vista search.blade.php esta modificación será realizada sólo en la sección donde se muestran los comentarios:

    @extends('layouts.home')
    @section('search', $search)
    @section('content')
    <h3>Resultado de la búsqueda: {{$search}}</h3>
    @if (isset($message))
    <div class='bg-warning' style='padding: 20px'>
        {{$message}}
    </div>
    @endif
    <hr />
    @if (isset($comments))
    <?php 
            $modal = 0;
            foreach($comments as $comment):
                $user = App\User::select()->where('id', '=', $comment->id_user)->first();
            ?>
            <div class="row">
                <div class="col-md-1">
                    <img src='{{url($user->perfiles)}}' class='img-responsive' style='max-width: 60px' />
                    <strong><a href="{{url('home/user/'.$user->id)}}">{{$user->name}}</a></strong>
                </div>
                <div class='col-md-6'>
                   {{$comment->comment}} 
                   <br />
                   <i>Fecha: {{$comment->date}} · Hora: {{$comment->time}}</i>
                   
                   
                   @if(isset(Auth::user()->id))
                   @if($comment->id_user == Auth::user()->id)
                   <hr />
                    <!-- Botón que abre la ventana modal eliminar -->
                    <button type="button" class="btn btn-danger" data-toggle="modal" data-target="#deleteComment{{$modal}}">
                      Eliminar
                    </button>
    
                    <!-- Ventana modal para eliminar -->
                    <div class="modal fade" id="deleteComment{{$modal}}" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
                      <div class="modal-dialog" role="document">
                        <div class="modal-content">
                          <div class="modal-header">
                            <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
                            <h4 class="modal-title" id="myModalLabel">¿Realmente quieres eliminar este comentario?</h4>
                          </div>
                          <div class="modal-body">
                            <form method="post" action="{{url('user/deletecomment')}}">
                                {{csrf_field()}}
                                <input type="hidden" name="id_comment" value="{{$comment->id}}" />
                                <button type="submit" class="btn btn-danger">Eliminar</button>
                            </form>
                          </div>
                          <div class="modal-footer">
                            <button type="button" class="btn btn-default" data-dismiss="modal">Cerrar</button>
                          </div>
                        </div>
                      </div>
                    </div>
    
                    <!-- Botón para abrir la ventana modal de editar -->
                    <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#editComment{{$modal}}">
                      Editar
                    </button>
    
                    <!-- Ventana modal editar -->
                    <div class="modal fade" id="editComment{{$modal}}" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
                      <div class="modal-dialog" role="document">
                        <div class="modal-content">
                          <div class="modal-header">
                            <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
                            <h4 class="modal-title" id="myModalLabel">Editar comentario</h4>
                          </div>
                          <div class="modal-body">
                            <form method="post" action="{{url('user/editcomment')}}">
                                {{csrf_field()}}
                                <div class="form-group">
                                <textarea name="comment" rows="10" class="form-control">{{$comment->comment}}</textarea>
                                </div>
                                <input type="hidden" name="id_comment" value="{{$comment->id}}" />
                                <button type="submit" class="btn btn-primary">Editar</button>
                            </form>
                          </div>
                          <div class="modal-footer">
                            <button type="button" class="btn btn-default" data-dismiss="modal">Cerrar</button>
                          </div>
                        </div>
                      </div>
                    </div>
                    <?php $modal++ ?>
                   @endif
          @endif
                </div>
            </div>
            <hr />
            <?php endforeach ?>
            <?php
            $currentPage = $comments->currentPage(); //Página actual
            $maxPages = $currentPage + 3; //Máxima numeración de páginas
            $firstPage = 1; //primera página
            $lastPage = $comments->lastPage(); //última página
            $nextPage = $currentPage+1; //Siguiente página
            $forwardPage = $currentPage-1; //Página anterior
            $comments->setPath('');
            ?>
    <ul class="pagination">
            <!-- Botón para navegar a la primera página -->
            <li class="@if($currentPage==$firstPage){{'disabled'}}@endif">
                    <a href="@if($currentPage>1){{$comments->url($firstPage)}}@else{{'#'}}@endif" class='btn'>Primera</a>
            </li>
            <!-- Botón para navegar a la página anterior -->
            <li class="@if($currentPage==$firstPage){{'disabled'}}@endif">
                    <a href="@if($currentPage>1){{$comments->url($forwardPage)}}@else{{'#'}}@endif" class='btn'>«</a>
            </li>
            <!-- Mostrar la numeración de páginas, partiendo de la página actual hasta el máximo definido en $maxPages -->
            @for($x=$currentPage;$x<$maxPages;$x++)
                    @if($x <= $lastPage)
                    <li class="@if($x==$currentPage){{'active'}}@endif">
                            <a href="{{$comments->url($x)}}" class='btn'>{{$x}}</a>
                    </li>
                    @endif
            @endfor
            <!-- Botón para navegar a la pagina siguiente -->
            <li class="@if($currentPage==$lastPage){{'disabled'}}@endif">
                    <a href="@if($currentPage<$lastPage){{$comments->url($nextPage)}}@else{{'#'}}@endif" class='btn'>»</a>
            </li>
            <!-- Botón para navegar a la última página -->
            <li class="@if($currentPage==$lastPage){{'disabled'}}@endif">
                    <a href="@if($currentPage<$lastPage){{$comments->url($lastPage)}}@else{{'#'}}@endif" class='btn'>Última</a>
            </li>
    </ul>
    @endif
    @stop
    


    A continuación crearemos la nueva ruta en routes.php, en esta ruta capturaremos el id del usuario, el id es validado para aceptar sólo números enteros:

    Route::get("home/user/{id}", "HomeController@user")->where(['id' => '[0-9]+']);
    


    A continuación crearemos la nueva acción "user" en HomeController, pero antes importaremos la clase user al controlador: use App\User;, en la nueva acción realizaremos una consulta buscando al usuario a través del id enviado, si el usuario no existe redireccionamos atrás, de lo contrario mostramos una nueva vista "user" y le pasamos la información del usuario.

        public function user($id){
            $user = User::select()
                    ->where('id', '=', $id)
                    ->first();
            if (count($user) == 0){
                return redirect()->back();
            }
            else{
                return View('home.user')->with('user', $user);
            }
        }
    


    A continuación crearemos la nueva vista "user.blade.php" en la carpeta "home" con el siguiente código:

    @extends('layouts.home')
    @section('content')
    <h1>Perfil público de <a href="{{url('home/user/'.$user->id)}}">{{$user->name}}</a></h1>
    <img src="{{url($user->perfiles)}}" class="img-responsive" style="max-width: 150px" />
    <hr />
    @if(Session::has('status'))
     <div class="bg-info" style="padding: 20px">{{Session::get('status')}}</div>
     <hr />
    @endif
    @if(Session::has('error'))
     <div class="bg-danger" style="padding: 20px">{{Session::get('error')}}</div>
     <hr />
    @endif
    <!-- Si el usuario está autenticado -->
    @if (Auth::check())
     <!-- Y este es su id de perfil posibilitar la creación de comentarios -->
     @if($user->id == Auth::user()->id)
     <form method="post" action="{{url('user/createcomment')}}">
      {{csrf_field()}}
      <div class="form-group">
       <div class="row">
        <div class="col-md-1">
         <img src="{{url(Auth::user()->perfiles)}}" class='img-responsive' style='max-width: 60px' />
         <strong><a href="{{url('home/user/'.Auth::user()->id)}}">{{Auth::user()->name}}</a></strong>
        </div>
        <div class="col-md-6">
         <textarea name="comment" class="form-control"></textarea>
         <br />
         <button type="submit" class="btn btn-primary">Publicar</button>
        </div>
       </div>
      </div>
     </form>
     <hr />
     @endif
    @endif
     <!-- Seleccionar los comentarios del usuario -->
     <?php 
      $modal = 0;
      $comments = App\Comments::where('id_user', '=', $user->id)->orderBy('id', 'desc')->simplePaginate(5);
      foreach($comments as $comment):
     ?>
      <div class="row">
                <div class="col-md-1">
                    <img src='{{url($user->perfiles)}}' class='img-responsive' style='max-width: 60px' />
                    <strong><a href="{{url('home/user/'.$user->id)}}">{{$user->name}}</a></strong>
                </div>
                <div class='col-md-6'>
                   {{$comment->comment}} 
                   <br />
                   <i>Fecha: {{$comment->date}} · Hora: {{$comment->time}}</i>
          
          <!-- Si el usuario está autenticado, es decir, la propiedad id existe -->
          @if(isset(Auth::user()->id))
          <!-- Si el usuario está autenticado agregar las opciones editar y eliminar cuando visite en su perfil -->
                   @if($comment->id_user == Auth::user()->id)
                   <hr />
                    <!-- Botón que abre la ventana modal eliminar -->
                    <button type="button" class="btn btn-danger" data-toggle="modal" data-target="#deleteComment{{$modal}}">
                      Eliminar
                    </button>
    
                    <!-- Ventana modal para eliminar -->
                    <div class="modal fade" id="deleteComment{{$modal}}" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
                      <div class="modal-dialog" role="document">
                        <div class="modal-content">
                          <div class="modal-header">
                            <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
                            <h4 class="modal-title" id="myModalLabel">¿Realmente quieres eliminar este comentario?</h4>
                          </div>
                          <div class="modal-body">
                            <form method="post" action="{{url('user/deletecomment')}}">
                                {{csrf_field()}}
                                <input type="hidden" name="id_comment" value="{{$comment->id}}" />
                                <button type="submit" class="btn btn-danger">Eliminar</button>
                            </form>
                          </div>
                          <div class="modal-footer">
                            <button type="button" class="btn btn-default" data-dismiss="modal">Cerrar</button>
                          </div>
                        </div>
                      </div>
                    </div>
    
                    <!-- Botón para abrir la ventana modal de editar -->
                    <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#editComment{{$modal}}">
                      Editar
                    </button>
    
                    <!-- Ventana modal editar -->
                    <div class="modal fade" id="editComment{{$modal}}" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
                      <div class="modal-dialog" role="document">
                        <div class="modal-content">
                          <div class="modal-header">
                            <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
                            <h4 class="modal-title" id="myModalLabel">Editar comentario</h4>
                          </div>
                          <div class="modal-body">
                            <form method="post" action="{{url('user/editcomment')}}">
                                {{csrf_field()}}
                                <div class="form-group">
                                <textarea name="comment" rows="10" class="form-control">{{$comment->comment}}</textarea>
                                </div>
                                <input type="hidden" name="id_comment" value="{{$comment->id}}" />
                                <button type="submit" class="btn btn-primary">Editar</button>
                            </form>
                          </div>
                          <div class="modal-footer">
                            <button type="button" class="btn btn-default" data-dismiss="modal">Cerrar</button>
                          </div>
                        </div>
                      </div>
                    </div>
                    <?php $modal++ ?>
                   @endif
          @endif
       </div>
      </div>
      <hr />
     <?php endforeach ?>
     
     <!-- Agregar la paginación simple -->
     <div class='text-center'>
     <?php /*Nuevo*/ $comments->setPath('') ?>
     <?php echo $comments->render() ?>
        <p>Página {{$comments->currentPage()}}</p>
     </div>
     <br /><br /><br /><br />
    
    @stop
    
    


    En el perfil público de usuario se realizan distintas comprobaciones, una de ellas es verificar si el perfil pertenece al usuario actualmente autenticado, de ser así, se le incluye el formulario para crear comentarios y a la lista de comentarios las opciones de editar y eliminar.

    Otra cosa, es el manejo de las variables flash 'status' y 'error' al inicio de la vista, esto permitirá que si el usuario realiza alguna acción como crear, editar o eliminar se le muestra esa información. Para que esto ocurra habrá que realizar unas pequeñas modificaciones en las acciones createComment, deleteComment y editComment del controlador UserController, modificando las redirecciones, en lugar de redireccionar a "home", redireccionar atrás con el método "back()", simplemente tenemos que reemplazar:

    return redirect('home')->...
    


    Por ...

    return redirect()->back()->...
    


    Otra cosa es mostrar la opción de ir al perfil público en el panel del usuario, abrir la vista "user.blade.php" de la carpeta "user" e incluirla ...

        <li><a href="{{url('home/user/'.Auth::user()->id)}}">Ir a mi perfil público</a></li>
    





    miércoles, 2 de diciembre de 2015

    20 - Tutorial de Laravel 5 - Pagination (Paginación personalizada)




    En esta parte del Tutorial de Laravel 5 continuamos viendo la paginación, concretamente utilizaremos los helpers para crear una paginación personalizada.

    Esta paginación tendrá el siguiente formato:



    Previamente incluiremos el método setPath a la paginación con la cual trabajamos en el capítulo anterior, este método nos permitirá generar las rutas para los links correctamente. Código modificado en la vista "home" ...

    <div class='text-center'>
    <?php /*Nuevo*/ $comments->setPath('') ?>
    <?php echo $comments->render() ?>
       <p>Página {{$comments->currentPage()}}</p>
    </div>
    <br /><br /><br /><br />
    


    Empezamos a crear la paginación personalizada. En la acción search del controlador HomeController reemplazamos el método get de la consulta por el método paginate:

    $comments = Comments::select()
      ->where('comment', 'LIKE', '%'.$search.'%')
      ->orderBy('id', 'desc')
      ->paginate(3);
    


    En la vista "search" utilizamos los helpers para crear una serie de variables, que posteriormente nos serviran para crear los links de la paginación, código completo de la vista "search" ...

    @extends('layouts.home')
    @section('search', $search)
    @section('content')
    <h3>Resultado de la búsqueda: {{$search}}</h3>
    @if (isset($message))
    <div class='bg-warning' style='padding: 20px'>
        {{$message}}
    </div>
    @endif
    <hr />
    @if (isset($comments))
    <?php 
            $modal = 0;
            foreach($comments as $comment):
                $user = App\User::select()->where('id', '=', $comment->id_user)->first();
            ?>
            <div class="row">
                <div class="col-md-1">
                    <img src='{{url($user->perfiles)}}' class='img-responsive' style='max-width: 60px' />
                    <strong>{{$user->name}}</strong>
                </div>
                <div class='col-md-6'>
                   {{$comment->comment}} 
                   <br />
                   <i>Fecha: {{$comment->date}} · Hora: {{$comment->time}}</i>
                   
                   
                   @if(isset(Auth::user()->id))
                   @if($comment->id_user == Auth::user()->id)
                   <hr />
                    <!-- Botón que abre la ventana modal eliminar -->
                    <button type="button" class="btn btn-danger" data-toggle="modal" data-target="#deleteComment{{$modal}}">
                      Eliminar
                    </button>
    
                    <!-- Ventana modal para eliminar -->
                    <div class="modal fade" id="deleteComment{{$modal}}" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
                      <div class="modal-dialog" role="document">
                        <div class="modal-content">
                          <div class="modal-header">
                            <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
                            <h4 class="modal-title" id="myModalLabel">¿Realmente quieres eliminar este comentario?</h4>
                          </div>
                          <div class="modal-body">
                            <form method="post" action="{{url('user/deletecomment')}}">
                                {{csrf_field()}}
                                <input type="hidden" name="id_comment" value="{{$comment->id}}" />
                                <button type="submit" class="btn btn-danger">Eliminar</button>
                            </form>
                          </div>
                          <div class="modal-footer">
                            <button type="button" class="btn btn-default" data-dismiss="modal">Cerrar</button>
                          </div>
                        </div>
                      </div>
                    </div>
    
                    <!-- Botón para abrir la ventana modal de editar -->
                    <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#editComment{{$modal}}">
                      Editar
                    </button>
    
                    <!-- Ventana modal editar -->
                    <div class="modal fade" id="editComment{{$modal}}" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
                      <div class="modal-dialog" role="document">
                        <div class="modal-content">
                          <div class="modal-header">
                            <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
                            <h4 class="modal-title" id="myModalLabel">Editar comentario</h4>
                          </div>
                          <div class="modal-body">
                            <form method="post" action="{{url('user/editcomment')}}">
                                {{csrf_field()}}
                                <div class="form-group">
                                <textarea name="comment" rows="10" class="form-control">{{$comment->comment}}</textarea>
                                </div>
                                <input type="hidden" name="id_comment" value="{{$comment->id}}" />
                                <button type="submit" class="btn btn-primary">Editar</button>
                            </form>
                          </div>
                          <div class="modal-footer">
                            <button type="button" class="btn btn-default" data-dismiss="modal">Cerrar</button>
                          </div>
                        </div>
                      </div>
                    </div>
                    <?php $modal++ ?>
                   @endif
          @endif
                </div>
            </div>
            <hr />
            <?php endforeach ?>
            <?php
            $currentPage = $comments->currentPage(); //Página actual
            $maxPages = $currentPage + 3; //Máxima numeración de páginas
            $firstPage = 1; //primera página
            $lastPage = $comments->lastPage(); //última página
            $nextPage = $currentPage+1; //Siguiente página
            $forwardPage = $currentPage-1; //Página anterior
            $comments->setPath('');
            ?>
    <ul class="pagination">
            <!-- Botón para navegar a la primera página -->
            <li class="@if($currentPage==$firstPage){{'disabled'}}@endif">
                    <a href="@if($currentPage>1){{$comments->url($firstPage)}}@else{{'#'}}@endif" class='btn'>Primera</a>
            </li>
            <!-- Botón para navegar a la página anterior -->
            <li class="@if($currentPage==$firstPage){{'disabled'}}@endif">
                    <a href="@if($currentPage>1){{$comments->url($forwardPage)}}@else{{'#'}}@endif" class='btn'>«</a>
            </li>
            <!-- Mostrar la numeración de páginas, partiendo de la página actual hasta el máximo definido en $maxPages -->
            @for($x=$currentPage;$x<$maxPages;$x++)
                    @if($x <= $lastPage)
                    <li class="@if($x==$currentPage){{'active'}}@endif">
                            <a href="{{$comments->url($x)}}" class='btn'>{{$x}}</a>
                    </li>
                    @endif
            @endfor
            <!-- Botón para navegar a la pagina siguiente -->
            <li class="@if($currentPage==$lastPage){{'disabled'}}@endif">
                    <a href="@if($currentPage<$lastPage){{$comments->url($nextPage)}}@else{{'#'}}@endif" class='btn'>»</a>
            </li>
            <!-- Botón para navegar a la última página -->
            <li class="@if($currentPage==$lastPage){{'disabled'}}@endif">
                    <a href="@if($currentPage<$lastPage){{$comments->url($lastPage)}}@else{{'#'}}@endif" class='btn'>Última</a>
            </li>
    </ul>
    @endif
    @stop
    


    Ahora prueben la páginación al realizar búsquedas.