Curso Laravel
Curso Laravel
1
Eloquent..............................................................................................................................32
Model Factories......................................................................................................................37
Enrutamiento básico............................................................................................................39
Tipos de rutas por encabezado Http...................................................................42
Rutas de tipo get............................................................................................................42
Parametros en las rutas de tipo get...................................................................43
Vistas y Blade..........................................................................................................................45
Blade.............................................................................................................................................48
Templates y Partials............................................................................................................50
Templates..........................................................................................................................50
Partials................................................................................................................................52
Resumen, Anotaciones e informacion adicional..............................................53
Enrutamiento básico...............................................................¡Error! Marcador no definido.
Tipos de rutas por encabezado Http......................¡Error! Marcador no definido.
Rutas de tipo get...............................................................¡Error! Marcador no definido.
Parametros en las rutas de tipo get.......................¡Error! Marcador no definido.
Vistas y Blade.............................................................................¡Error! Marcador no definido.
Blade................................................................................................¡Error! Marcador no definido.
Templates y Partials................................................................¡Error! Marcador no definido.
Templates..............................................................................¡Error! Marcador no definido.
Partials....................................................................................¡Error! Marcador no definido.
Resumen, Anotaciones e informacion adicional..¡Error! Marcador no definido.
Controladores..........................................................................................................................55
Validaciones en Laravel....................................................................................................59
Validación del lado del cliente:.................................................................................60
Validación del lado del servidor (Request).........................................................63
Middlewares.............................................................................................................................70
Creando nuestros propios Middlewares...................................................................73
Preparativos.........................................................................................................................73
Crear el middleware IsAdmin......................................................................................77
¿Qué es HTML5?....................................................................................................................80
2
¿Qué hay de nuevo en HTML5?......................................................................................80
Nuevos tags (etiquetas).............................................................................................80
Nuevas API's.....................................................................................................................80
Plantilla básica de un documento en HTML5........................................................81
Encabezados............................................................................................................................82
Secciones (divisiones)........................................................................................................82
Formato de texto...................................................................................................................83
Formularios...............................................................................................................................84
Atributos de los formularios........................................................................................84
Tablas..........................................................................................................................................85
Hipervínculos e imágenes................................................................................................85
CSS3 (Hojas de estilo en cascada)..............................................................................87
Sintaxis...................................................................................................................................87
Formas de insertar CSS en nuestro documento HTML.................................88
Comentarios en CSS........................................................................................................90
Selectores..............................................................................................................................90
Selector por clase.........................................................................................................91
Creacion del CRUD con Laravel desde 0..................................................................93
Vistas del CRUD...................................................................................................................100
Template App.................................................................................................................100
Vista Index......................................................................................................................102
Partials: table y fields...............................................................................................102
Vista Create....................................................................................................................106
Vista Edit..........................................................................................................................107
DataTable.................................................................................................................................108
¿Cómo usar DataTables?.................................................................................................109
Crear un DataTable.............................................................................................................110
Ocupando el DOM (etiqueta <table>)...................................................................110
Ocupando un dataset en Javacript........................................................................111
Ocupando AJAX................................................................................................................112
Internacionalizar un dataTable....................................................................................113
3
Filtrar datos de un DataTable.......................................................................................113
Users.............................................................................................................................................149
Controller......................................................................................................................................150
Model............................................................................................................................................151
Assets...........................................................................................................................................151
Storage.........................................................................................................................................152
Database......................................................................................................................................152
Multilingual....................................................................................................................................153
Dashboard....................................................................................................................................154
Primary color................................................................................................................................156
Show developer tips....................................................................................................................156
Additional stylesheets.................................................................................................................157
Additional Javascript...................................................................................................................157
Google Maps................................................................................................................................158
4
Introducción a Laravel 5
Laravel es un framework para aplicaciones web con sintaxis expresiva y
elegante. Creemos que el desarrollo debe ser una experiencia agradable y
creativa para que sea verdaderamente enriquecedora. Laravel busca
eliminar el sufrimiento del desarrollo facilitando las tareas comunes
utilizadas en la mayoría de los proyectos web, como la autenticación,
enrutamiendo, sesiones y almacenamiento en caché.
5
proyectos basados en web, si no que también intenta arreglar alguna de
las flaquezas de PHP.
Beneficios de Laravel
6
8. Se actualiza facilmente desde la línea de comandos: El framework
es actualizable utilizando composer update y listo, nada de descargar un
ZIP y estar remplazando.
Requerimientos iniciales
7
Composer no es un administrador de paquetes. Sí, él trata con "paquetes"
o "librerías", pero las gestiona en función de cada proyecto y no instala
nada globalmente en tu equipo, por lo cual solo administra las
dependencias del mismo.
8
"homepage": La configuración de la página es útil para paquetes
que van a ser de código libre. Puedes usar esta página para el proyecto o
quizá para la URL del repositorio. Lo que creas que es más informativo.
Gestor de dependencias
composer install
9
Preparando nuestro entorno de
trabajo.
Laravel necesita un servidor web. No importa cuál sea pero la
mayoría de la comunidad usa Apache o Nginx y hacer lo mismo te
pondrá las cosas más fáciles a la hora de buscar ayuda si la
necesitas.
10
Despues de tener instalado nuestro Servidor web, es necesario
instalar composer el cuál es un gestor de dependencias php muy
útil y del cuál se hablará más tarde.
Instalación de Laravel
11
Existen diferentes formas de instalar laravel en nuestra
computadora.
Usando composer:
composer create-project laravel/laravel --prefer-dist Proyecto
composer update
php artisan key:generate
php artisan app:name Curso
a partir de la versión 6 instalar el siguiente comando
composer require andrey-helldar/laravel-app –dev
y ya podra usar php artisan app:name <name>
o visite https://github.com/andrey-helldar/laravel-app
PSR-4 y namespaces
¿Qué es PSR-4?
12
ocaciones existirán clases con el mismo nombre que las
nuestras y podrían sobreescribirse o usar una que no queremos.
¿Qué es un autoloader?
13
{
"autoload":{
"psr-4":{
"Taller\\": "app/"
}
}
}
use Taller\Clase;
¿Qué es classmap?
Ejemplo:
{
"classmap": [
"database"
],
}
14
Nota a partir de laravel 6 no viene el comando app:name, para agregar se
hace con el siguiente comando composer require andrey-helldar/laravel-app –
dev
Luego se usa el comando de siempre php artisan app:name nombre_del_proyecto
MySQL
Postgresql
SQLite3
SQL Server
15
Una vez que tengamos todo configurado, nos dirigimos a la
terminal y ejecutamos el comando php artisan migrate para crear
las migraciones, si todo ha salido bien tendremos que ver las
tablas:
migrations
password_resets
users
Estructura de un proyecto en
Laravel
Todos los proyectos nuevos en Laravel 5.1 tienen la siguiente
estructura de directorios:
app/
bootstrap/
config/
database/
public/
16
resources/
storage/
tests/
vendor/
.env
.env.example
.gitattributes
.gitignore
artisan
composer.json
composer.lock
gulpfile.js
package.json
phpspec.yml
phpunit.xml
readme.md
server.php
El directorio app
17
Es considerado el directorio más importante de nuestro proyecto
ya que es en el que más trabajaremos.
El directorio config
18
Laravel existe como un conjunto de archivos PHP que contienen
matrices clave-valor. Entre los archivos más usados del
directorio config se encuentran:
El directorio database
El directorio public
19
Dentro de este directorio colocaremos todos los recursos
estáticos de nuestra aplicación, es decir, archivos css, js,
imágenes y fuentes.
El directorio resources
20
El directorio storage
El directorio tests
21
servidor de correo electronico. El archivo .env lo creamos
copiando el archivo .env.example y renombrando la copia
como .env.
JSON
22
uso de ellos para hacerlo un poco más legible. JSON es un
formato de transferencia de dato y no un lenguaje.
Por ejemplo:
{
"Frutas":[
{
"Nombre": "Manzana",
"Cantidad": 20,
"Precio": 10.50,
"Podrida": false
},
{
"Nombre": "Pera",
"Cantidad": 100,
"Precio": 1.50,
"Podrida": true
}
]
23
Strings o cadenas (entre comillas dobles)
Booleans (true o false)
Arrays o arreglos (entre corchetes [] )
Objetos (entre llaves {})
Null
Validación de JSON
24
JSONLint nos informará si es correcto el formato o en caso
contrario nos mostrará los errores sintácticos de nuestro JSON.
Migraciones
El comando php artisan migrate:rollback te permite deshacer la última migración
ejecutada.
Puedes ejecutar php artisan migrate:reset para deshacer todas las migraciones.
Cuando creamos nuestras bases de datos solemos crear
diagramas que nos facilitan la abstracción de como se va a
almacenar nuestra información, pero la forma de llevarlo a la
realidad en algun gestor de bases de datos, como por
ejemplo: MySQL, SQLite, PostgreSQL, SQL Server, etc., lo más
comun es meternos al lenguaje de script encargado de
implementar nuestra idea de la BD y ejecutar dicho script, o
incluso ocupar programas más avanzados que nos sirven como
interfaz para crearlas de una forma más gráfica y sin la
necesidad de profundizar demasiado en el lenguaje,
como Workbench o Navicat.
25
necesita al momento debemos re-escribir todo otra vez, cosa que
con la migraciones se soluciona instantaneamente.
26
Ahora bien se puede observar que el archivo como tal no se
llama
simplemente crear_tabla_pasteles sino 2015_06_23_054801_crea
r_tabla_pasteles , esto pasa porque Laravel al crear una
migración agrega como préfijo la fecha y hora en la que fué
creada la migración para poder ordenar qué migración va antes
que otra, por lo cual si tu ejecutas este comando, obviamente el
nombre de tu archivo será diferente pues la fecha y hora no
pueden ser las mismas que la mia al crear este ejemplo. Además
las migraciones que vienen por defecto en Laravel también se
27
encuentran con este formato por lo cual podemos observar que
estos dos archivos si tienen el mismo nombre.
28
son created_at y updated_at que son campos que se usan para
(como su nombre lo dice) guardar el registro de cuando fue
creado y cuando fue actualizado el registro, detalles muy
importantes cuando queremos obtener informes con base en el
tiempo de la información de nuestra tabla, por ejemplo si
quisieramos saber cuales son los pasteles que se dieron de alta
en el catálogo en el mes de abril podriamos crear un filtro para
obtener solo los pasteles de ese mes usando el campo
generado created_at.
Ahora bien si la función up crea nuestra tabla en la base de
datos, la función down logicamente hace lo opuesto, y eso es
eliminar la tabla de la base de datos, por eso dentro de esta
función podemos observar que de la misma clase Schema se llama
al método drop que significa dejar caer o dar de baja.
Si bien cada función realiza una tarea en especifico, ¿Cuando es
que se usan? o ¿Como se mandan a llamar?. Bueno para esto
iremos nuevamente a nuestra linea de comandos.
29
base de datos se agregará la tabla pasteles y en la
tabla migrations se añadirá el registro de la migración recien
ejecutada.
Pero, ¿si quisiera eliminar la tabla con la función down de la
migración crear_tabla_pasteles ?
30
1. Primero ejecutamos el comando: php artisan make:migration
agregar_campos_tabla_pasteles , para crear la migración simple sin la
plantilla.
2. Dentro de la función up agregamos los campos que
necesitamos, en este caso solo agregaremos el nombre y el
sabor.
31
Para poder agregar más columnas a las tablas desde Laravel en
vez de llamar al método createllamamos al método table de la
clase Schema pasandole como primer parámetro a que tabla se va
a agregar los campos y como segundo parámetro la función
anónima donde definimos que columnas se agregaran.
Y en la función down para eliminar columnas que vendría siendo
lo opuesto de agregarlas, se llama al método table y dentro de la
función anónima del objeto $table se usa el
método dropColumn() que recibe como parámetro ya sea el nombre
32
de una sola columna o un arreglo con todas las columnas que se
desean eliminar.
Y ¡listo!, con esto podemos tener una idea inicial de como usar
las migraciones, lo que para este ejemplo podría continuar sería
agregar más columnas a la tabla pasteles y probar los comandos
necesarios para poder deshacer los cambios de la primera vez
que se corrio la migración con una nueva versión, ya sea sobre el
mismo archivo o sobre otro nuevo.
Beneficios
Seeders
33
Los Seeders por otra parte son archivos que nos van a permitir
poblar nuestra base de datos para no tener que perder el tiempo
escribiendo de forma manual todos los datos, un ejemplo,
imagina llenar 15 tablas con 100 registros cada una y piensa en
que entre cada tabla deben existir registros que se relacionan
entre sí, eso suena de verdad horrible y tedioso, por lo cual
Laravel nos salva con estos archivos Seeders.
34
idea más clara podemos ir a la página de Packagist donde se
encuetra Faker o a su Repositorio en Github y ahí nos muestra
que es lo que se debe agregar.
35
Después crearemos una variable llamada $faker que nos servira
para poblar la base de datos, ahora bien usando la clase DB, si
bien dentro del ejemplo queremos crear 50 pasteles vamos a
crear un for para que ejecute nuestro código de inserción 50
veces y el componente de Faker en cada pasada cambiará los
valores del registro que se va a agregar, quedando de esta forma:
$faker = Faker::create();
for ($i=0; $i < 50; $i++) {
\DB::table('pasteles')->insert(array(
'nombre' => $faker->firstNameFemale,
'sabor' => $faker-
>randomElement(['chocolate','vainilla','cheesecake']),
'created_at' => date('Y-m-d H:m:s'),
'updated_at' => date('Y-m-d H:m:s')
));
}
36
Y ahora lo que sigue es abrir un archivo llamado DatabaseSeeder.php ,
en este archivo se mandan a llamar todos los seeders en el orden
que los necesitemos, en este archivo se agregará la linea:
$this->call('PastelesSeeder');
Eloquent
37
En Laravel podemos hacer uso de un ORM llamado Eloquent,
un ORM es un Mapeo Objeto-Relacional por sus siglas en ingles
(Object-Relational mapping), que es una forma de mapear los
datos que se encuentran en la base de datos almacenados en un
lenguaje de script SQL a objetos de PHP y viceversa, esto surge
con la idea de tener un codigo portable con el que no tengamos
la necesidad de usar lenguaje SQL dentro de nuetras clases de
PHP.
38
Y esto aplica para cuando queremos crear nuestros modelos, si
tenemos una tabla en la base de datos con la que queremos
trabajar que se llama user_profiles, vemos que se encuentra con
las convenciones para tablas de bases de datos (plural y
underscore), entonces el modelo para esta tabla cambiando las
convenciones seria: UserProfile (singular y UpperCamelCase).
39
plural no es la misma que la forma en que se hace en ingles,
debido a esto nos vemos forzados a definir el nombre de la tabla.
Bien una vez creado nuestro modelo pasaremos a crear una ruta
de tipo get en nuestro archivo routes.php , posteriormente
estudiaremos el enrutamiento básico en Laravel en el
Route::get('pruebasPastel', function(){
});
use Curso\Pastel;
$pastel = Pastel::where('sabor','vainilla')->first();
40
Esto nos va a dar el primer pastel sabor vainilla, pero si
quisieramos todos los pasteles de vainilla cambiariamos el
metodo first() por el metodo get() para obtener todos.
Y si queremos ver el resultado de esto y que de verdad estamos
haciendo lo correcto podemos usar la funcion dd() para mostrar
en pantalla el valor de una variable, con esto entonces nuestra
ruta le agregariamos lo siguiente:
Route::get('pruebasPastel', function(){
$pasteles = Pastel::where('sabor','vainilla')->get();
dd($pasteles);
});
41
herramienta llamada scopes que lo que realizan son consultas
en especifico encapsulandolas dentro de funciones en el modelo,
por ejemplo si quisieramos que el modelo Pastel tuviera una
funcion que me diera todos los pasteles de vainilla, otra de
chocolate y otra función mas para cheesecake, entonces podria
crear un scope para cada una.
Con el ejemplo de la ruta pruebasPastel para el sabor vainilla:
Route::get('pruebasPastel', function(){
$pasteles = Pastel::vainilla()->get();
dd($pasteles);
});
Esto nos daria una función genérica para obtener los pasteles de
cierto sabor y su implementación sería asi:
Route::get('pruebasPastel', function(){
$pasteles = Pastel::sabor('vainilla')->get();
dd($pasteles);
});
42
Además con Eloquent tambien podemos insertar, actualizar o
eliminar registros, por ejemplo:
$pastel->save();
$pastel = Pastel::find(51);
$pastel->sabor = 'chocolate';
$pastel->save();
$pastel = Pastel::find(51);
$pastel->delete();
Pastel::destroy(51);
Model Factories
Los model factories son una excelente forma de poblar nuestra
base de datos con datos de prueba generados automáticamente.
Laravel en su versión 5.1 incorpora este nuevo componente por
defecto, en versiones anteriores a Laravel 5.1 era necesario
43
agregar el componente faker en nuestro composer.jsony realizar
el proceso de manera manual en los archivos seeders, para más
información sobre estre proceso puedes visitar el link de github
del componente Faker.
44
un tipo especifico de poblado y como tercer parámetro una
función que recibe como parámetro un objeto $faker.
Ejemplo:
45
Model::unguard();
factory('Curso\User', 50)->create();
factory('Curso\User','administrador',1)->create();
// $this->call('UserTableSeeder');
Model::reguard();
}
Ejemplos:
factory('Curso\User',100)->create();
Rutas
Enrutamiento básico
La siguiente imágen muestra el proceso que se realiza cuando
ingresamos a una URL. Además muestra la arquitectura del
patrón MVC que utiliza laravel para el desarrollo de proyectos.
46
Cuando ingresamos a una url directamente desde el navegador lo
hacemos mediante una petición http de tipo GET, esta solicitud
se envía al archivo routes.php ubicado dentro
de app/Http/routes.php, en caso de no existir nos dará un error,
si la ruta existe, nos llevará a un controlador en el cuál se
encuentra la lógica , el controlador interaccionará con un modelo
(opcionalmente) para recuperar información de una base de
datos. Esta información llega al controlador y desde el
controlador invocamos una vista, las vistas se encuentran en el
directorio resources/views, finalmente la vista se carga y se
muestra en el navegador.
47
mensaje “Bienvenido :)”. En laravel la porción /saludo
pertenecería a una ruta que regresa una respuesta o una vista
dependiendo lo complejo que llegue a ser lo que queramos
mostrar. La parte de dominio.com pertenecería a localhost si lo
andamos probando de manera local. En nuestro ejemplo lo que
mostraremos es un mensaje muy simple por lo cual no es
necesario hacer mostrar una vista. Para lograrlo haremos lo
siguiente:
Route::get('saludo', function () {
return "Bienvenido :)";
});
48
HTTP
49
CONNECT
El método CONNECT establece un túnel hacia el servidor identificado por el
recurso.
OPTIONS
El método OPTIONS es utilizado para describir las opciones de comunicación
para el recurso de destino.
TRACE
El método TRACE realiza una prueba de bucle de retorno de mensaje a lo
largo de la ruta al recurso de destino.
PATCH
El método PATCH es utilizado para aplicar modificaciones parciales a un
recurso.
50
Hay otros verbos HTTP disponibles. He aquí algunos de los
métodos que la clase de enrutado tiene disponible para ti:
Route::get();
Route::post();
Route::any();
Route::delete();
Route::put();
Cualquier método de la clase Route recibe siempre dos
argumentos, el primero es la URI con la que queremos hacer
coincidir la URL y el segundo es la función a realizar que en este
caso es un Clousure que no es otra cosa que una función
anonima, es decir, que no tiene un nombre.
51
// ruta de tipo GET que devuelve un simple string
Route::get('/', function () {
return "Hola mundo";
});
Route::get('home', 'HomeController@index');
52
De igual forma es posible restringir rutas por medio de
expresiones regulares como por ejemplo:
53
Vistas y Blade
Las vistas en Laravel son la parte pública que el usuario de
nuestro sistema va a poder ver, se escriben en HTML junto con
un motor de plantillas llamado Blade. Las vistas se encuentran
ubicadas en la carpeta resources/views/ y Laravel por defecto
trabaja con la idea de que tenemos que escribir la menor
cantidad de código repetido, modularizar nuestro código en
donde mas se pueda, y si esto lo aplicamos en nuestros modelos,
controladores y demás partes de nuestro proyecto,
entonces, ¿Por que no hacerlo tambien en las vistas?.
Laravel usa unos archivos que se llaman plantillas
o templates que suelen ser nuestros archivos principales, que
tienen los segmentos de código que se repiten en mas de una
vista, como por ejemplo la barra de navegacion, un menú de
opciones, la estructura del acomodo de nuestro proyecto, etc. y
como deben de estar practicamente presentes en todos lados, no
tiene sentido estarlos repitiendo en todas las vistas. Por defecto
Laravel contiene un template llamado app.blade.php,
usualmente los templatescontienen el head del HTML, las ligas
del CSS del sistema y una seccion exclusiva para los archivos
Javascript.
54
estos archivos surgen por el código que es mas pequeño que
repetimos mucho pero no es lo suficientemente grande como
para considerarlo un template.
Esto hace que las vistas de cada parte del proyecto, que suelen
ser llamadas por una ruta o controlador sean mucho mas
pequeñas que usando otro tipo de frameworks para desarrollo
Web, y para poder unir todos estos archivos o piezas del
rompecabezas usamos el motor de plantillas de Laravel
llamado BLADE.
Route::get('saludo', function(){
return view('saludo');
55
});
Route::get('saludo', function(){
$pastel = Pastel::sabor('chocolate')->first();
return view('saludo')->with('pastel', $pastel->nombre);
56
});
Blade
57
Blade nos provee de muchas ventajas (asi como casi todo en
Laravel), además de modularizar nuestras vistas de una forma
sorprendente, tambien nos permite usar estructuras de control y
variables de PHP directamente en ellas, aunque esto ya era
posible antes usando las etiquetas de php, por ejemplo:
{{ $pastel }}
58
definimos el fin de una estructura con un @end seguido del
nombre de la estructura que usamos, por ejemplo:
<h1>Lista de pasteles</h1>
@foreach($pasteles as $pastel)
<h2>{{ $pastel->nombre }}</h2>
@endforeach
Templates y Partials
59
Anteriormente hablabamos de templates y partials,
describiremos un poco de como se trabaja con esta estructuras
de Blade y sus beneficios:
Templates
@yield('nombre_seccion')
@section('nombre_seccion')
60
Definiremos nuestra vista recien creada saludo.blade.php para
que use un template, por defecto Laravel trae uno que se
llama app.blade.php, ese es el que usaremos para este ejemplo.
@extends('app')
@section('content')
<h1>Lista de pasteles</h1><br>
@if( $pasteles->count() > 10 )
<h2>Hay muchos Pasteles</h2><br>
@endif
@foreach($pasteles as $pastel)
<h4>{{ $pastel->nombre }}</h4>
@endforeach
@stop
61
Nos podemos dar cuenta que cambiaron muchas cosas, ahora
tenemos una barra de navegacion en la parte superior de la
ventana y el debugbar en la parte inferior, además de que la
tipografia ha cambiado. Esto es porque dentro del template app
se estan agregando hojas de estilo CSS.
Partials
62
Dentro la actual vista saludo.blade.php, vamos a quitar todo el
HTML Blade que definimos para crear esta lista pequeña de
pasteles y lo vamos a guardar en nuevo archivo, para esto vamos
a crear una carpeta llamada pasteles y dentro otra carpeta
llamada partials, donde vamos a guardar la vista de nuestro
nuevo partial, quedando la ruta de la siguiente
forma: resources/views/pasteles/partials/ .
Ahi vamos a crear un archivo llamado lista.blade.php y dentro
de este archivo vamos a cortar el código de nuestra vista saludo,
quedando asi:
<h1>Lista de pasteles</h1><br>
@if( $pasteles->count() > 10 )
<h2>Hay muchos Pasteles</h2><br>
@endif
<ul>
@foreach($pasteles as $pastel)
<li>{{ $pastel->nombre }}</li>
@endforeach
</ul>
@extends('app')
@section('content')
@include('pasteles.partials.lista')
@stop
63
hacer un @include('pasteles.partials.lista') y con eso ya tendremos
nuestra lista agregada en cualquier vista donde la necesitemos.
64
se usa en una vista hija entonces termina la seccion con
un @stop.
@show: Esta sentencia se usa para decir donde termina
el section definido en el template.
@parent: Esta sentencia nos ayuda a cargar el contenido
por defecto de un section del template, esto podemos usarlo
cuando queremos agregar mas contenido dentro pero sin alterar
el contenido por defecto, es decir agregarle mas HTML, esta
sentencia se usa dentro de un section, podemos hacer un simil
con el super() de Java que sirve para llamar al contructor de la
superclase de la que se hereda.
@stop: Esta sentencia nos permite decir donde termina
un section cuando se usa el section dentro de las vistas hijas.
@include('ruta.nombre'): Esta sentencia nos agrega en el
lugar donde sea usada un archivo blade.php que contiene
un partial o fragmento parcial de HTML, si ese partial se
encuentra en la raíz de las vistas no necesita mas que el nombre
sin la extension blade.php, pero si esta dentro de, por ejemplo,
la carpeta "views/admin/users/" llamado table.blade.php para
poder ser incluido se usaría la ruta junto con el nombre quedando
como @include('admin.users.table') , views no se contempla pues es
la raiz de las vistas.
65
Controladores
En lugar de definir en su totalidad la lógica de las peticiones en
el archivo routes.php, es posible que desee organizar este
comportamiento usando clases tipo Controller.
Los Controladores puede agrupar las peticiones HTTP
relacionada con la manipulación lógica en una clase.
Los Controladoresnormalmente se almacenan en el directorio de
aplicación app/Http/Controllers/ .
Un controller usualmente trabaja con las peticiones:
GET.
POST.
PUT.
DELETE.
PATCH.
66
Esta ruta nos creara un grupo de rutas de recursos con las
peticiones que estas mencionadas arriba: index, create, show,
edit, store, update, destroy. Estas son las operaciones mas
usadas en una clase y para no tener que crear una ruta para cada
método es que Laravel agrupa todo esto con una ruta de tipo
resource que se liga a un controlador.
67
update: Al igual que el store, solo que en vez de provenir de
create proviene de edit y en vez de crear un nuevo registro,
busca un existente y lo modifica, tambien suele redirigir al index.
68
En la linea de comandos podemos ver todas las rutas que nuestro
proyecto tiene registradas:
69
Este comando nos va a mostrar en la consola un resultado
similar a esto:
70
de Controladores y de Enrutamiento en la version 5.1 de
Laravel.
Validaciones en Laravel
Existen varias formas de validar nuestra aplicación para cubrir
aspectos de seguridad como SQL Injection, ataques XSS o CSRF,
algunas de ellas son:
text
search
url
tel
71
email
password
data pickers
number
checkbox
El atributo pattern
72
Bootstrap
Foundation
Pure
Semantic UI
Otros
Validación de formularios .
Sistema de notificaciones .
Progressbar .
Soporte para fullscreen .
Agregar funcionalidad extra a los paneles de bootstrap .
Helpers para conversión de tipos .
public/
assets/
css/
smoke.css
smoke.min.css
js/
smoke.js
smoke.min.js
lang/
73
es.js
es.min.js
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Ejemplo Smoke</title>
{!! Html::style('assets/css/smoke.css') !!}
</head>
<body>
74
verlo en el Anexo C. CRUD con Laravel para comprender su
funcionamiento:
Ejemplo:
app/Http/Request/CrearPastelesRequest
Su contenido es el siguiente:
<?php
namespace Curso\Http\Requests;
use Curso\Http\Requests\Request;
75
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
//
];
}
}
<?php
namespace Curso\Http\Requests;
76
use Curso\Http\Requests\Request;
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'nombre' => 'required|string|max:60',
'sabor' => 'required|in:chocolate,vainilla,cheesecake'
];
}
}
<?php
namespace Curso\Http\Requests;
77
use Curso\Http\Requests\Request;
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'nombre' => 'required|string|size:60',
'sabor' => 'required|in:chocolate,vainilla,cheesecake'
];
}
}
use Curso\Http\Requests\CrearPastelesRequest;
use Curso\Http\Requests\EditarPastelesRequest;
78
En el modelo Pastel agregaremos una propiedad $fillable para
indicar que atributos de la tabla pasteles podrán ser ocupados
con el método $request->all().
El modelo pasteles quedaría así:
<?php
namespace Curso;
use Illuminate\Database\Eloquent\Model;
<?php
namespace Curso\Http\Controllers;
use Illuminate\Http\Request;
use Curso\Http\Requests;
79
use Curso\Http\Controllers\Controller;
use Curso\Pastel;
use Curso\Http\Requests\CrearPastelesRequest;
use Curso\Http\Requests\EditarPastelesRequest;
/**
* Show the form for creating a new resource.
*
* @return Response
*/
public function create()
{
return view('pasteles.create');
}
/**
* Store a newly created resource in storage.
*
* @return Response
*/
public function store(CrearPastelesRequest $request)
{
$pastel = Pastel::create($request->all());
80
return redirect()->route('pasteles.index');
}
/**
* Display the specified resource.
*
* @param int $id
* @return Response
*/
public function show($id)
{
//
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return Response
*/
public function edit($id)
{
$pastel = Pastel::find($id);
return view('pasteles.edit')->with('pastel',$pastel);
}
/**
* Update the specified resource in storage.
*
* @param int $id
* @return Response
*/
public function update(EditarPastelesRequest $request, $id)
{
$pastel = Pastel::find($id);
$pastel->fill($request->all());
$pastel->save();
81
return redirect()->route('pasteles.index');
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return Response
*/
public function destroy($id)
{
$pastel = Pastel::find($id);
$pastel->delete();
Pastel::destroy($id);
return redirect()->route('pasteles.index');
}
}
Middlewares
En este punto debemos tener nuestro CRUD para la clase
Pasteles, en caso de no tenerlo recomiendo ver el Anexo C.
CRUD con Laravel para poder continuar. Ahora bien si ya
podemos realizar las operaciones básicas no podemos pensar en
llevar a un ambiente real o comercial un proyecto en este nivel.
Aun si funciona correctamente no hemos contemplado todos los
82
posibles casos o amenazas que se encuentran afuera en la Web,
tales como son hackers, estafadores o incluso las fallas usuales
de los usuarios finales.
83
Con este cambio se daran cuenta de que si ingresan a las rutas
en las cuales ya antes podiamos ver nuestro crud los redirige al
login, si crean una cuenta de usuario y lo intentan nuevamente
veran que el acceso ya se les va a conceder, además el nombre y
usuario con el que accedan se vera en la barra superior de
navegacion al lado derecho, comprobando las sesiones que
Laravel nos da como un regalo.
84
en el podemos ver una variable protegida
llamada $routeMiddleware donde estan definidos los middleware del
sistema, podemos observar tanto la ubicacion como el nombre
con el cual podemos usarlo, estos
son auth, auth.basic y guest.
El archivo que hace referencia al middleware auth se
llama Authenticate.php que se encuentra en app/Http/Middleware/ ,
dentro de este archivo podemos observar la estructura de un
Middleware normal, este tipo de archivos cuentan con una
función llamada handle() que es la que se ejecuta cuando se
85
llama al middleware, la función hadle de este archivo es la
siguiente:
86
Preparativos
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
87
$table->enum('type', ['admin','user']);
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('users');
}
}
88
}
@section('content')
<div class="container">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<div class="panel panel-default">
<div class="panel-heading">Sign Up</div>
<div class="panel-body">
{!! Form::open(['route' => 'auth/register', 'class' =>
'form']) !!}
<div class="form-group">
<label>Name</label>
{!! Form::input('text', 'name', '', ['class'=>
'form-control']) !!}
</div>
<div class="form-group">
<label>Email</label>
{!! Form::email('email', '', ['class'=> 'form-
control']) !!}
</div>
89
<div class="form-group">
<label for="type"> Type</label>
<select name="type" class="form-control">
<option value="" disabled selected>Elige una
opcion...</option>
<option value="admin">Administrador</option>
<option value="user">Usuario normal</option>
</select>
</div>
<div class="form-group">
<label>Password</label>
{!! Form::password('password', ['class'=> 'form-
control']) !!}
</div>
<div class="form-group">
<label>Password confirmation</label>
{!! Form::password('password_confirmation',
['class'=> 'form-control']) !!}
</div>
<div>
{!! Form::submit('send',['class' => 'btn btn-
primary']) !!}
</div>
{!! Form::close() !!}
</div>
</div>
</div>
</div>
</div>
@endsection
90
Crear el middleware IsAdmin
namespace Curso\Http\Middleware;
use Illuminate\Contracts\Auth\Guard;
use Closure;
class IsAdmin
{
protected $auth;
91
$this->auth = $auth;
}
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if ($this->auth->user()->type != 'admin') {
$this->auth->logout();
if ($request->ajax()) {
return response('Unauthorized.', 401);
} else {
return redirect()->to('auth/login');
}
}
return $next($request);
}
}
92
destino a la que queremos llegar y nunca vamos a poder iniciar
sesion con usuarios normales.
protected $routeMiddleware = [
'auth' => \Curso\Http\Middleware\Authenticate::class,
'auth.basic' =>
\Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'guest' => \Curso\Http\Middleware\RedirectIfAuthenticated::class,
'is_admin' => \Curso\Http\Middleware\IsAdmin::class,
];
93
Para mas informacion lean la documentacion oficial sobre
Middlewares de Laravel 5.
¿Qué es HTML5?
HTML5 es la nueva versión del lenguaje de marcado que se usa
para estructurar páginas web, actualmente sigue en evolucion,
HTML5 incorpora características nuevas y modificaciones que
mejorará significativamente la forma de construir sitios web.
<!DOCTYPE html>
<meta charset="UTF-8">
<article>, y <section> .
94
Nuevas API's
HTML Geolocation
HTML SSE
Plantilla básica de un
documento en HTML5
Cualquier documento en HTML5 debe contener la siguiente
estructura básica.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Título de la página</title>
</head>
<body>
Cuerpo del documento
</body>
</html>
En la sección de la cabecera <head> escribiremos:
95
El título de la página
Los elementos link para utilizar los archivos CSS.
Barrá de navegación
Encabezados
Secciones
Parrafos
Elementos multimedia : audio, video, img
Texto en negritas, cursiva y subrayado.
Tablas
Listas
Formularios
Hipervínculos
etc.
Encabezados
Los encabezados en html tienen 6 tamaños diferentes y se
escriben de la siguiente forma:
96
HTML Resultado
Secciones (divisiones)
Podemos dividir nuestro documento en secciones distintas con la
etiqueta <div> para tener un mayor orden sobre nuestro
documento y aplicar diferentes estilos según la sección.
HTML Resultado
Formato de texto
97
HTML Resultado
<p> Parrafo
<p> Parrafo
Formularios
HTML Resultado
98
HTML Resultado
<input>
Seccion en desarrollo.
Tablas
Ejemplo de una tabla básica:
<table>
<thead>
<tr>
<th>cabecera</th>
<th>cabecera</th>
<th>cabecera</th>
</tr>
</thead>
<tfoot>
99
<tr>
<td>celda</td>
<td>celda</td>
<td>celda</td>
</tr>
</tfoot>
<tbody>
<tr>
<td>celda</td>
<td>celda</td>
<td>celda</td>
</tr>
</tbody>
</table>
Hipervínculos e imágenes
Las imágenes pueden ser de formato png, jpg o gif y se escriben
con la etiqueta <img> entre sus principales atributos tenemos:
Ejemplo:
100
<img src="html5.gif" alt="HTML5 Icon" width="128" height="128">
Ejemplo de un link:
<a href="https://www.facebook.com/oca159">Facebook</a>
101
<a href="#Encabezado">Visitar la sección de encabezado</a>
Sintaxis
102
nombre (name), ID, clase (class), posición dentro del Document
Object Model, etcétera.
/* comentarios */
Hemos estado hablando un poco de todo, incluso que a ciertas cosas podemos darle el
diseño que queramos, pero no hemos explicado como se incluyen estos archivos JS y CSS.
103
Hoy vamos a explicar como hacerlo y también explicaremos una herramienta que tiene
Laravel llamada Laravel Mix.
Laravel Mix es una herramienta que nos permite compilar y minificar nuestros assets
(soporta preprocesadores CSS y JS) muy fácilmente.
104
</head>
Una hoja de estilos interna puede ser usada si una única página
tiene un único estilo.
h1 {
color: maroon;
margin-left: 40px;
}
</style>
</head>
Estilos inline
Un estilo inline puede ser usado para aplicar un úncio estilo para
un único elemento de una página.
105
Comentarios en CSS
/* This is
a multi-line
comment */
Selectores
106
p {
text-align: center;
color: red;
}
Selector por id
107
En el ejemplo de abajo seleccionaremos todos los elementos
HTML con class="center" y los alinearemos al centro.
.center {
text-align: center;
color: red;
}
Agrupar selectores
h1 {
text-align: center;
color: red;
}
h2 {
text-align: center;
color: red;
}
p {
108
text-align: center;
color: red;
}
h1, h2, p {
text-align: center;
color: red;
}
109
Nota. Para ver la lista de comandos de escribe en la terminal php artisan y
nos da la lista de comandos
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
/**
* Reverse the migrations.
*
* @return void
110
*/
public function down()
{
Schema::drop('pasteles');
}
}
<?php
use Illuminate\Database\Seeder;
use Faker\Factory as Faker;
111
Con esto ya tendremos la estructura de la tabla y un seeder para poblar,
con esto ahora usaremos el siguiente comando para crear la tabla en la
BD y llenarla:
namespace Curso;
use Illuminate\Database\Eloquent\Model;
112
Para comenzar vamos a crear nuestro controlador con el comando:
113
Eloquent para obtener todos los pasteles y enviarlos a una vista que
vamos a definir mas adelante, quedando de la siguiente forma:
Eloquent nos facilita mucho las consultas a la BD y hace que sea portable
nuestro codigo, en el metodo decimos que seleccione todos los pasteles y
os envie a una vista llama index ubicada en la
carpeta resoures/views/pasteles/ , como vimos en el capitulo 10 las rutas en
blade cambian la /(diagonal) por un .(punto), la
funcion view('pasteles.index'); toma como carpeta raiz a resources/views/ por
lo que no tenemos la necesidad de agregarlo en la ruta. Ademas se esta
concatenando el metodo with('nombre', $var); que como primer parametro
pide el nombre con el cual se va a poder usar una variable del lado de la
vista, y como segundo parametro recibe la variable que se va a mandar a
la vista.
Este metodo es muy sencillo puesto que solo va a devolver una vista sin
ninguna variable ni uso de Eloquent, por lo cual queda de la siguiente
manera:
114
es una clase que Laravel agrega por nosotros cuando creamos el
controlador, vamos a pasar por parametro la peticion en el metodo
definiendo que es una variable de la clase Request y despues de eso
podemos recuperar por el nombre del campo del
formulario(atributo name) la informacion enviada, entonces el metodo
quedaria de la siguiente forma:
$pastel->save();
return redirect()->route('pasteles.index');
}
115
Edit - Pagina de edicion
116
return redirect()->route('pasteles.index');
}
117
resources/
views/
pasteles/
partials/
fields.blade.php
table.blade.php
create.blade.php
edit.blade.php
index.blade.php
Template App
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Laravel</title>
@section('styles_laravel')
{!! Html::style('assets/css/bootstrap.css') !!}
{!! Html::style('assets/css/datatable-bootstrap.css') !!}
<!-- Fonts -->
<link href='//fonts.googleapis.com/css?family=Roboto:400,300' rel='stylesheet'
type='text/css'>
@show
@yield('my_styles')
</head>
<body>
@include('partials.layout.navbar')
@include('partials.layout.errors')
118
<div class="container">
<div class="row">
<div class="col-md-10 col-md-offset-1">
@yield('content')
</div>
</div>
</div>
<!-- Scripts -->
{!! Html::script('assets/js/jquery.js') !!}
{!! Html::script('assets/js/jquery.dataTables.js') !!}
{!! Html::script('assets/js/bootstrap.min.js') !!}
{!! Html::script('assets/js/datatable-bootstrap.js') !!}
<script>
$(document).ready(function(){
$('#MyTable').dataTable();
});
</script>
@yield('my_scripts')
</body>
</html>
Nota: para poder hacer esto soN necesarios los archivos que se incluyen
con blade, si no los agregan la tabla se vera mas sencilla pero esto no
quiere decir que no va a funcionar, ya solo es cuestion de estilo, si quieren
obtener los archivos dejamos los links a continuacion para que los
descarguen y los guarden dentro de la carpeta respectiva, es decir
los CSS en public/assets/css/ y los JS dentro de public/assets/js/ :
Estilos para el DataTable: datatable-bootstrap.css .
Archivo JQuery: jquery.js.
Archivo JQuery para DataTable: jquery.dataTables.js.
Archivo JQuery para DataTable de bootstrap: datatable-
bootstrap.js.
119
Nota: tambien les invito a ver el anexo de DataTable para mayor
informacion.
Vista Index
@section('content')
<a class="btn btn-success pull-right" href="{{ url('/pasteles/create') }}"
role="button">Nuevo pastel</a>
@include('pasteles.partials.table')
@endsection
Table
120
ahora bien esos pasteles los vamos a vaciar en la tabla pues si bien no
especificamos que esa variable va a llegar al partial table como lo
estamos incluyendo en el index tambien comparte las variables que tenga
index, entonces el envio puede verse de la siguiente manera:
<td class="text-center">
<button type="submit" class="btn btn-danger btn-xs">
121
<span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
</button>
<a href="{{ url('/pasteles/'.$pastel->id.'/edit') }}" class="btn btn-info
btn-xs">
<span class="glyphicon glyphicon-edit" aria-hidden="true"></span>
</a>
</td>
</tr>
@endforeach
</tbody>
<tfoot>
<tr>
<th class="text-center">ID</th>
<th class="text-center">Nombre</th>
<th class="text-center">Sabor</th>
<th class="text-center">Fecha</th>
<th class="text-center">Acciones</th>
</tr>
</tfoot>
</table>
122
que se agrega el tag <span>, para mas informacion ir a la pagina oficial
de Bootstrap.
Con esto debemos ser capaces de poder ver ahora nuestra tabla como un
DataTable(en caso de haber agregado lo necesario) llena con la
informacion de pasteles:
Fields
Ahora vamos a crear un partials con los campos que va a requerir nuestro
proyecto, si bien sabemos es necesario pedir al usuario el nombre y sabor
del pastel, pero la fecha de creacion y ultima actualizacion son campos
que Laravel pone automaticamente cuando se ejecuta el metodo save() en
el controlador, por lo cual nuestro partial solo debera tener dos campos de
entrada y un boton para enviar la solicitud.
Entonces para este archivo solo vamos a agregar como su nombre lo
indica los campos de entrada para un paste, dejandolo de la siguiente
forma:
<div class="form-group">
{!! Form::label('nombre', 'Nombre', ['for' => 'nombre'] ) !!}
{!! Form::text('nombre', null , ['class' => 'form-control', 'id' => 'nombre',
'placeholder' => 'Escribe el nombre del pastel...' ] ) !!}
123
</div>
<div class="form-group">
{!! Form::label('sabor', 'Sabor', ['for' => 'sabor'] ) !!}
<select name="sabor" class="form-control">
<option value="" disabled selected>Elige un sabor...</option>
<option value="chocolate">Chocolate</option>
<option value="vainilla">Vainilla</option>
<option value="cheesecake">Cheesecake</option>
</select>
</div>
Vista Create
@extends('app')
@section('content')
{!! Form::open([ 'route' => 'pasteles.store', 'method' => 'POST']) !!}
@include('pasteles.partials.fields')
<button type="submit" class="btn btn-success btn-block">Guardar</button>
{!! Form::close() !!}
@endsection
124
Vista Edit
@extends('app')
@section('content')
<h4 class="text-center">Editar Pastel: {{ $pastel->nombre }}</h4>
{!! Form::model($pastel, [ 'route' => ['pasteles.update', $pastel], 'method' => 'PUT'])
!!}
@include('pasteles.partials.fields')
<button type="submit" class="btn btn-success btn-block">Guardar cambios</button>
{!! Form::close() !!}
@endsection
125
nuestra variable $pastel que enviamos desde el controlador y crea un
formulario lleno a partir de los valores del modelo, claro que esto solo
para los campos que coincidan con los nombres de los atributos del
modelo.
El resultado seria algo similar a esto:
DataTable
Los DataTables son un plug-in para la librería JQuery de
Javascript. Nos permiten un mayor control sobre un
126
elemento <table> de HTML. Algunas de sus caracteristicas
principales son:
Paginación automática
Búsqueda instantánea
Ordenamiento multicolumna
Soporta una gran cantidad de datos fuente.
o DOM (Convertir un elemento HTML <table> en un
DataTable).
o Javascript (Un arreglo de arreglos en Javascript puede ser
el dataset de un DataTable).
o AJAX (Un DataTable puede leer los datos de una tabla de
un json obtenido vía AJAX, el json puede ser servido mediante un Web
Service o mediante un archivo.txt que lo contenga).
o Procesamiento del lado del servidor (Un DataTable puede
ser creado mediante la obtención de datos del procesamiento de un
script en el lado del servidor, este script comúnmente tendrá
interacción con la base de datos).
Habilitar temas CSS para el DataTable fácilmente.
o Crear un tema
o Tema JQuery UI
o Tema Bootstrap
o Tema Foundation
Amplia variedad de extensiones.
Altamente internacionalizable.
Es open source (Cuenta con una licencia MIT).
127
Para ocupar datables tenemos dos formas:
Ejemplo:
public/
assets/
css/
datatable-bootstrap.css
js/
datatable-bootstrap.js
jquery.dataTables.js
jquery.js
128
<!-- Scripts -->
{!! Html::script('assets/js/jquery.js') !!}
{!! Html::script('assets/js/jquery.dataTables.js') !!}
{!! Html::script('assets/js/bootstrap.min.js') !!}
{!! Html::script('assets/js/datatable-bootstrap.js') !!}
<script>
$(document).ready(function(){
$('#MyTable').dataTable();
});
</script>
</body>
Crear un DataTable
Existen diversas formas de llenar un DataTable con datos,
veremos algunas de las más usadas.
129
Ocupando el DOM (etiqueta <table>)
Ocuparemos una tabla HTML con un id="example",
posteriormente convertiremos la tabla en un DataTable mediante
un script.
HTML de la tabla
$(document).ready(function() {
$('#example').dataTable();
} );
Javascript del dataset
$(document).ready(function() {
$('#demo').html( '<table cellpadding="0" cellspacing="0" border="0"
class="display" id="example"></table>' );
$('#example').dataTable( {
"data": dataSet,
"columns": [
130
{ "title": "Engine" },
{ "title": "Browser" },
{ "title": "Platform" },
{ "title": "Version", "class": "center" },
{ "title": "Grade", "class": "center" }
]
} );
} );
<html>
<head>
</head>
<body>
<div id="demo">
</div>
</body>
</html>
Ocupando AJAX
El archivo JSON
$(document).ready(function() {
$('#example').dataTable( {
"ajax": 'json.txt'
} );
} );
131
El archivo HTML contiene una tabla con un id="example".
<tfoot>
<tr>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Extn.</th>
<th>Start date</th>
<th>Salary</th>
</tr>
</tfoot>
</table>
Internacionalizar un dataTable
Es posible cambiar el idioma de las etiquetas de un datatable si
bajamos el archivo de la traducción en el siguiente link.
132
<script type="text/javascript">
$(document).ready(function() {
$('#example').dataTable( {
"language": {
"url": "dataTables.spanish.lang"
}
} );
} );
</script>
Ejemplo:
Notas
href="{{asset(“assets/$theme/bower_components/font-awesome/css/font-
awesome.min.css")}}”>
133
public function boot()
//
DB_CONNECTION = mysql
DB _PORT = 3306
134
DB_PASSWORD = aquí contraseña de la base de datos
( root )
vamos a crear una aplicación cruda para el producto. así que tenemos que
crear la migración para la tabla de "productos" usando el comando
Laravel 6 php artisan, así que primero comience el siguiente comando:
<? php
/ **
* *
135
* @return void
* /
función pública up ()
});
/ **
* *
* @return void
* /
136
}
137
3) tienda ()
4) mostrar ()
5) editar ()
6) actualizar ()
7) destruir ()
Entonces, copiemos el siguiente código y coloquemos el archivo
ProductController.php.
app / Http / Controllers / ProductController.php
<? php
/ **
* *
* /
138
índice de función pública ()
/ **
* *
* /
/ **
139
* Almacene un recurso recién creado en el
almacenamiento.
* *
* /
]);
/ **
140
* Mostrar el recurso especificado.
* *
* /
/ **
* *
* /
141
}
/ **
* *
* /
]);
142
-> con ( 'éxito' , 'Producto
actualizado con éxito' );
/ **
* *
* /
143
Ok, entonces, después de ejecutar el siguiente comando, encontrará
"app / Product.php" y colocará el siguiente contenido en el archivo
Product.php:
app / Product.php
<? php
protegido $ rellenable = [
'nombre' , 'detalle'
];
144
3) create.blade.php
4) edit.blade.php
5) show.blade.php
Así que vamos a crear el siguiente archivo y poner el siguiente código.
resources / views / products / layout.blade.php
<html>
<head>
<link href =
"https://cdnjs.cloudflare.com/ajax/libs/twitter-
bootstrap/4.0.0-alpha/css/bootstrap.css" rel =
"stylesheet" >
</head>
<cuerpo>
@yield ('contenido')
</div>
</body>
</html>
145
recursos / vistas / productos / index.blade.php
@extends ('products.layout')
@section ('contenido')
</div>
</div>
</div>
</div>
</div>
146
@terminara si
<tr>
<th> No </th>
</tr>
<tr>
<td>
147
<a class = "btn btn-primary" href
= "{{ route('products.edit',$product-> id)}} ">
Editar </a>
@csrf
@method ('BORRAR')
</form>
</td>
</tr>
@endforeach
</table>
@endsection
@extends ('products.layout')
@section ('contenido')
148
<div class = "row" >
</div>
</div>
</div>
</div>
<ul>
@endforeach
</ul>
149
</div>
@terminara si
@csrf
</div>
</div>
150
</div>
</div>
</div>
</div>
</form>
@endsection
@extends ('products.layout')
@section ('contenido')
</div>
151
<a class = "btn btn-primary" href =
"{{ route('products.index') }}"> Volver </a>
</div>
</div>
</div>
<ul>
@endforeach
</ul>
</div>
@terminara si
@csrf
152
@method ('PUT')
</div>
</div>
</div>
</div>
153
<button type = "submit" class = "btn
btn-primary" > Enviar </button>
</div>
</div>
</form>
@endsection
@extends ('products.layout')
@section ('contenido')
</div>
</div>
</div>
</div>
154
<div class = "row" >
</div>
</div>
</div>
</div>
</div>
@endsection
155
Otro ejemplo
CÓMO CREAR UN CRUD EN LARAVEL 5.5 DESDE CERO
Hola que tal, bienvenido a este nuevo artículo en donde aprenderás cómo crear un crud en
Laravel 5.5 desde cero, este es un articulo que por así decirlo es una continuación del
artículo Cómo instalar y configurar Laravel 5.5 y lo que vamos hacer es básicamente crear
las opciones de crear, leer, actualizar y eliminar que son las opciones básicas que tiene una
tabla, para esto usaremos Laravel que es un Framework para PHP que como se verá a
continuación nos ayuda y nos abstrae la creación de un motón de código simplemente con
usar comandos vía consola.
156
artículo anterior Cómo instalar y configurar Laravel 5.5 donde explico como hacerlo. El
nombre de la base de datos le llamaremos del mismo nombre del proyecto crudlaravel,
posteriormente deberás crear la base de datos en MySQL.
CREACIÓN DE MIGRACIONES
El tema de migraciones en Laravel tiene que ver con el diseño de tablas de nuestra base de
datos, y aunque podemos directamente crear nuestra tabla en MySQL crear el controlador y
el modelo, lo vamos hacer usando migraciones, cual es la diferencia? Pues la diferencia es
que usando migraciones diseñas las tablas como si de modelos se tratarán y luego las
puedes generar a MySQL con un sólo comando, además puedes llevar la cronología de la
creación de tus tablas y si algo salió mal, por ejemplo te olvidaste de crear un campo,
fácilmente haces un rollback y deshaces los cambios. Pero bueno para que se entienda
mejor vamos al ejemplo.
La tabla que vamos a crear para el ejemplo se va llamar Libros y contendrá los campos:
nombre, resumen, número de páginas, edición, autor y precio.
Para crear la tabla creamos un archivo de migración, para esto vamos a la ventana de
comandos abierta anteriormente y usamos el siguiente comando:
1 <?php
2
3 use Illuminate\Support\Facades\Schema;
4 use Illuminate\Database\Schema\Blueprint;
5 use Illuminate\Database\Migrations\Migration;
6
7 class CreateLibrosTable extends Migration
8 {
9 /**
10 * Run the migrations.
11 *
12 * @return void
157
13 */
14 public function up()
15 {
16 Schema::create('libros', function (Blueprint $table) {
17 $table->increments('id');
18 $table->string('nombre');
19 $table->string('resumen');
20 $table->integer('npagina');
21 $table->integer('edicion');
22 $table->string('autor');
23 $table->decimal('precio',5,2);
24 $table->timestamps();
25 });
26 }
27
28 /**
29 * Reverse the migrations.
30 *
31 * @return void
32 */
33 public function down()
34 {
35 Schema::dropIfExists('libros');
36 }
37 }
Ahora lo que nos queda es ejecutar la migración, esto para que se cree nuestra
tabla libros, para esto ejecutamos el siguiente comando:
CREAR EL MODELO
Ahora que, y tenemos la tabla creada, necesitamos un modelo que mapee los campos a la
tabla libros y para esto usamos el comando:
1 php artisan make:model Libro
Si vas a la carpeta app del proyecto vas a encontrar un nuevo archivo llamado Libro.php,
como te darás cuenta es una clase vacía y en teoría deberíamos crear las propiedades, los
158
setter y getter, pero con la ayuda de Laravel sólo creamos un array $fillable y le pasamos
los campos que queremos llenar, así de fácil como se muestra a continuación:
1 <?php
2
3 namespace App;
4
5 use Illuminate\Database\Eloquent\Model;
6
7 class Libro extends Model
8 {
9 //
10 protected $fillable = ['nombre', 'resumen', 'npagina','edicion','autor','precio'];
11 }
CREAR EL CONTROLLER
Laravel es un Framework que usa el patrón MVC (Modelo, Vista, Controlador), por lo que
ahora tenemos que crear el controlador con los métodos index, show, update, delete.
Como te habrás dado cuenta hasta ahora hemos generado todo básicamente a través de
comandos y bueno esta vez no es la excepción, así que para crear el controlador usamos el
siguiente comando:
1 php artisan make:controller LibroController --resource
Si ahora vas a la carpeta app/Http/Controllers puedes ver que se generó un nuevo archivo
VideoController.php y como por arte de magia se crearon todos los métodos que
necesitamos, a continuación dejo el código para cada uno de los métodos, que como te
darás cuenta es corto y sencillo, puesto que el framework prácticamente hace todo por
nosotros.
1 <?php
2
3 namespace App\Http\Controllers;
4
5 use Illuminate\Http\Request;
6 use App\Libro;
7
8 class LibroController extends Controller
9 {
10 /**
11 * Display a listing of the resource.
12 *
13 * @return \Illuminate\Http\Response
14 */
15 public function index()
16 {
17 //
18 $libros=Libro::orderBy('id','DESC')->paginate(3);
19 return view('Libro.index',compact('libros'));
20 }
21
22 /**
23 * Show the form for creating a new resource.
24 *
25 * @return \Illuminate\Http\Response
159
26 */
27 public function create()
28 {
29 //
30 return view('Libro.create');
31 }
32
33 /**
34 * Store a newly created resource in storage.
35 *
36 * @param \Illuminate\Http\Request $request
37 * @return \Illuminate\Http\Response
38 */
39 public function store(Request $request)
40 {
41 //
42 $this->validate($request,[ 'nombre'=>'required', 'resumen'=>'required',
43 'npagina'=>'required', 'edicion'=>'required', 'autor'=>'required', 'npagina'=>'required',
44 'precio'=>'required']);
45 Libro::create($request->all());
46 return redirect()->route('libro.index')->with('success','Registro creado
47 satisfactoriamente');
48 }
49
50 /**
51 * Display the specified resource.
52 *
53 * @param int $id
54 * @return \Illuminate\Http\Response
55 */
56 public function show($id)
57 {
58 $libros=Libro::find($id);
59 return view('libro.show',compact('libros'));
60 }
61
62 /**
63 * Show the form for editing the specified resource.
64 *
65 * @param int $id
66 * @return \Illuminate\Http\Response
67 */
68 public function edit($id)
69 {
70 //
71 $libro=libro::find($id);
72 return view('libro.edit',compact('libro'));
73 }
74
75 /**
76 * Update the specified resource in storage.
77 *
78 * @param \Illuminate\Http\Request $request
79 * @param int $id
80 * @return \Illuminate\Http\Response
81 */
82 public function update(Request $request, $id) {
83 //
84 $this->validate($request,[ 'nombre'=>'required', 'resumen'=>'required',
85 'npagina'=>'required', 'edicion'=>'required', 'autor'=>'required', 'npagina'=>'required',
86 'precio'=>'required']);
160
libro::find($id)->update($request->all());
return redirect()->route('libro.index')->with('success','Registro actualizado
satisfactoriamente');
87
88
}
89
90
/**
91
* Remove the specified resource from storage.
92
*
93
* @param int $id
94
* @return \Illuminate\Http\Response
95
*/
96
public function destroy($id)
97
{
98
//
99
Libro::find($id)->delete();
100
return redirect()->route('libro.index')->with('success','Registro eliminado
satisfactoriamente');
}
}
1 <?php
2
3 /*
4 |--------------------------------------------------------------------------
5 | Web Routes
6 |--------------------------------------------------------------------------
7 |
8 | Here is where you can register web routes for your application. These
9 | routes are loaded by the RouteServiceProvider within a group which
10 | contains the "web" middleware group. Now create something great!
11 |
12 */
13
14 Route::resource('libro', 'LibroController');
1 <!DOCTYPE html>
2 <html lang="es">
161
<head>
3 <meta charset="utf-8">
4 <meta name="viewport"
5 content="width=device-width, initial-scale=1, user-scalable=yes">
6 <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"
7 rel="stylesheet">
8 <script
9 src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
10 </head>
11 <body>
12
13 <div class="container-fluid" style="margin-top: 100px">
14
15 @yield('content')
16 </div>
17 <style type="text/css">
18 .table {
19 border-top: 2px solid #ccc;
20
21 }
22 </style>
23 </body>
</html>
ARCHIVO INDEX.BLADE.PHP
Posteriormente en la ruta /resources/views/ creamos una nueva carpeta llamada Libro que
va contener las vistas (index, create, show, edit). Dentro de esta carpeta creamos el archivo
index.blade.php como se muestra a continuación:
1 @extends('layouts.layout')
2 @section('content')
3 <div class="row">
4 <section class="content">
5 <div class="col-md-8 col-md-offset-2">
6 <div class="panel panel-default">
7 <div class="panel-body">
8 <div class="pull-left"><h3>Lista Libros</h3></div>
9 <div class="pull-right">
10 <div class="btn-group">
11 <a href="{{ route('libro.create') }}" class="btn btn-info" >Añadir Libro</a>
12 </div>
13 </div>
14 <div class="table-container">
15 <table id="mytable" class="table table-bordred table-striped">
16 <thead>
17 <th>Nombre</th>
18 <th>Resumen</th>
19 <th>No. Páginas</th>
20 <th>Edicion</th>
21 <th>Autor</th>
22 <th>Precio</th>
23 <th>Editar</th>
24 <th>Eliminar</th>
25 </thead>
26 <tbody>
27 @if($libros->count())
28 @foreach($libros as $libro)
162
<tr>
<td>{{$libro->nombre}}</td>
29
<td>{{$libro->resumen}}</td>
30
<td>{{$libro->npagina}}</td>
31
<td>{{$libro->edicion}}</td>
32
<td>{{$libro->autor}}</td>
33
<td>{{$libro->precio}}</td>
34
<td><a class="btn btn-primary btn-xs" href="{{action('LibroController@edit',
35
$libro->id)}}" ><span class="glyphicon glyphicon-pencil"></span></a></td>
36
<td>
37
<form action="{{action('LibroController@destroy', $libro->id)}}"
38
method="post">
39
{{csrf_field()}}
40
<input name="_method" type="hidden" value="DELETE">
41
42
<button class="btn btn-danger btn-xs" type="submit"><span class="glyphicon
43
glyphicon-trash"></span></button>
44
</td>
45
</tr>
46
@endforeach
47
@else
48
<tr>
49
<td colspan="8">No hay registro !!</td>
50
</tr>
51
@endif
52
</tbody>
53
54
</table>
55
</div>
56
</div>
57
{{ $libros->links() }}
58
</div>
59
</div>
60
</section>
61
@endsection
ARCHIVO CREATE.BLADE.PHP
1 @extends('layouts.layout')
2 @section('content')
3 <div class="row">
4 <section class="content">
5 <div class="col-md-8 col-md-offset-2">
6 @if (count($errors) > 0)
7 <div class="alert alert-danger">
8 <strong>Error!</strong> Revise los campos
9 obligatorios.<br><br>
10 <ul>
11 @foreach ($errors->all() as $error)
12 <li>{{ $error }}</li>
13 @endforeach
14 </ul>
15 </div>
16 @endif
17 @if(Session::has('success'))
18 <div class="alert alert-info">
19 {{Session::get('success')}}
20 </div>
163
21 @endif
22
23 <div class="panel panel-default">
24 <div class="panel-heading">
25 <h3 class="panel-title">Nuevo Libro</h3>
26 </div>
27 <div class="panel-body">
28 <div class="table-container">
29 <form method="POST"
30 action="{{ route('libro.store') }}" role="form">
31 {{ csrf_field() }}
32 <div class="row">
33 <div class="col-xs-6 col-sm-6
34 col-md-6">
35 <div class="form-
36 group">
37 <input
38 type="text" name="nombre" id="nombre" class="form-control input-sm"
39 placeholder="Nombre del libro">
40 </div>
41 </div>
42 <div class="col-xs-6 col-sm-6
43 col-md-6">
44 <div class="form-
45 group">
46 <input
47 type="text" name="npagina" id="npagina" class="form-control input-sm"
48 placeholder="Número de Páginas">
49 </div>
50 </div>
51 </div>
52
53 <div class="form-group">
54 <textarea name="resumen"
55 class="form-control input-sm" placeholder="Resumen"></textarea>
56 </div>
57 <div class="row">
58 <div class="col-xs-6 col-sm-6
59 col-md-6">
60 <div class="form-
61 group">
62 <input
63 type="text" name="edicion" id="edicion" class="form-control input-sm"
64 placeholder="Edición del libro">
65 </div>
66 </div>
67 <div class="col-xs-6 col-sm-6
68 col-md-6">
69 <div class="form-
70 group">
71 <input
72 type="text" name="precio" id="precio" class="form-control input-sm" placeholder="Precio
73 del libro">
74 </div>
75 </div>
76 </div>
<div class="form-group">
<textarea name="autor"
class="form-control input-sm" placeholder="Autor"></textarea>
</div>
<div class="row">
164
<div class="col-xs-12 col-sm-
12 col-md-12">
<input
type="submit" value="Guardar" class="btn btn-success btn-block">
<a
href="{{ route('libro.index') }}" class="btn btn-info btn-block" >Atrás</a>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</section>
@endsection
ARCHIVO EDIT.BLADE.PHP
1 @extends('layouts.layout')
2 @section('content')
3 <div class="row">
4 <section class="content">
5 <div class="col-md-8 col-md-offset-2">
6 @if (count($errors) > 0)
7 <div class="alert alert-danger">
8 <strong>Error!</strong> Revise los campos
9 obligatorios.<br><br>
10 <ul>
11 @foreach ($errors->all() as $error)
12 <li>{{ $error }}</li>
13 @endforeach
14 </ul>
15 </div>
16 @endif
17 @if(Session::has('success'))
18 <div class="alert alert-info">
19 {{Session::get('success')}}
20 </div>
21 @endif
22
23 <div class="panel panel-default">
24 <div class="panel-heading">
25 <h3 class="panel-title">Nuevo Libro</h3>
26 </div>
27 <div class="panel-body">
28 <div class="table-container">
29 <form method="POST"
30 action="{{ route('libro.update',$libro->id) }}" role="form">
31 {{ csrf_field() }}
32 <input name="_method"
33 type="hidden" value="PATCH">
34 <div class="row">
35 <div class="col-xs-6 col-sm-6
36 col-md-6">
37 <div class="form-
38 group">
165
39 <input
40 type="text" name="nombre" id="nombre" class="form-control input-sm" value="{{$libro-
41 >nombre}}">
42 </div>
43 </div>
44 <div class="col-xs-6 col-sm-6
45 col-md-6">
46 <div class="form-
47 group">
48 <input
49 type="text" name="npagina" id="npagina" class="form-control input-sm" value="{{$libro-
50 >npagina}}">
51 </div>
52 </div>
53 </div>
54
55 <div class="form-group">
56 <textarea name="resumen"
57 class="form-control input-sm" placeholder="Resumen">{{$libro->resumen}}</textarea>
58 </div>
59 <div class="row">
60 <div class="col-xs-6 col-sm-6
61 col-md-6">
62 <div class="form-
63 group">
64 <input
65 type="text" name="edicion" id="edicion" class="form-control input-sm" value="{{$libro-
66 >edicion}}">
67 </div>
68 </div>
69 <div class="col-xs-6 col-sm-6
70 col-md-6">
71 <div class="form-
72 group">
73 <input
74 type="text" name="precio" id="precio" class="form-control input-sm" value="{{$libro-
75 >precio}}">
76 </div>
77 </div>
</div>
<div class="form-group">
<textarea name="autor"
class="form-control input-sm" placeholder="Autor">{{$libro->autor}}</textarea>
</div>
<div class="row">
<div class="col-xs-12 col-sm-
12 col-md-12">
<input
type="submit" value="Actualizar" class="btn btn-success btn-block">
<a
href="{{ route('libro.index') }}" class="btn btn-info btn-block" >Atrás</a>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
166
</section>
@endsection
Y bien como puedes ver que en cuestión de minutos puedes crear un CRUD con Laravel,
Voyager
APP_URL=http://localhost
DB_HOST=localhost
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret
con datos ficticios o sin los datos ficticios. Los datos ficticios incluirán 1
configuraciones.
167
php artisan voyager: instalar
comando:
long-error
Inicie un servidor de desarrollo local con php artisan serve y visite la URL
Si instaló con los datos ficticios, se ha creado un usuario para usted con
contraseña: contraseña
Nota rápida
datos.
--create, así:
168
php artisan voyager: admin [email protected] --crear
https://voyager-docs.devdojo.com/getting-started/installation
Configuraciones
Users
<?php
'user' => [
169
'redirect' => '/admin'
],
Controller
<?php
'controllers' => [
],
170
AppServiceProvider class in the register method. $this->app-
>bind(VoyagerBreadController::class, MyBreadController::class);
Model
<?php
'models' => [
],
Assets
<?php
Es posible que desee especificar una ruta de activos diferente. Si su sitio vive en
una subcarpeta, es posible que deba incluir ese directorio al comienzo de la ruta.
Esto también se puede usar en caso de que desee duplicar los activos publicados
y personalizar los suyos.
Al actualizar a una nueva versión de Voyager, los activos ubicados en el directorio
/ vendor / tcg / voyager / assets pueden necesitar sobrescribirse, por lo que si
desea personalizar cualquier estilo, querrá duplicar ese directorio y especificar la
nueva ubicación de su ruta de activos .
171
Storage
<?php
'storage' => [
],
Database
<?php
'database' => [
'tables' => [
],
],
172
Es posible que desee ocultar algunas tablas de base de datos en la sección de
base de datos Voyager. En la configuración de la base de datos, puede elegir qué
tablas desea ocultar.
Multilingual
<?php
'multilingual' => [
'locales' => [
'en',
//'pt',
],
],
173
Dashboard
<?php
'dashboard' => [
'navbar_items' => [
'Profile' => [
],
'Home' => [
],
'Logout' => [
],
174
],
'widgets' => [
'TCG\\Voyager\\Widgets\\UserDimmer',
'TCG\\Voyager\\Widgets\\PostDimmer',
'TCG\\Voyager\\Widgets\\PageDimmer',
],
],
In the dashboard config you can add navbar_items, make the data_tables
responsive, and manage your dashboard widgets.
navbar_items Include a new route in the main user navbar dropdown by including
a 'route', 'icon_class', and 'target_blank'.
widgets Here you can manage the widgets that live on your dashboard. You can
take a look at an example widget class by viewing the current widgets inside of
175
Primary color
<?php
The default primary color for the Voyager admin dashboard is a light blue color.
You can change that primary color by changing the value of this config.
<?php
In the Voyager admin there are developer tips or notifications that will show you
how to reference certain values from Voyager. You can choose to hide these
notifications by setting this configuration value to false.
176
Additional stylesheets
<?php
'additional_css' => [
//'css/custom.css',
],
You can add your own custom stylesheets that will be included in the Voyager
admin dashboard. This means you could technically create a whole new theme for
Voyager by adding your own custom stylesheet.
Additional Javascript
<?php
'additional_js' => [
//'js/custom.js',
177
],
The same goes for this configuration. You can add your own javascript that will be
executed in the Voyager admin dashboard. Add as many javascript files as
needed.
Google Maps
<?php
'googlemaps' => [
'center' => [
],
],
There is a new data type called coordinates that allow you to add a google map
as a datatype. The user can then drag and drop a pin in the Google Maps to save
a longitude and latitude value in the database.
178
In this config you can set the default Google Maps Keys and center location. This
can also be added to your .env file.
179