PHP Modelo - Vista - Controlador

De MediaWiki
Saltar a: navegación, buscar

Introdución

  • Existen moitos frameworks PHP que nos permiten programar seguindo o patrón de deseño de software Model-View-Controller.


  • Nota: Como editor de texto para manexar os arquivos do proxecto no framework Laravel recomendo instalar Brackets.

Manuais

Instalación

  • Primeiro vídeo: basicamente fala de instalar composer e con el instalar Laravel.
Para instalar Laravel necesitamos:
  • Ter php instalado.
  • Ter composer instalador.
  • Ter git instalado.


  • Os pasos para instalar php os tedes na wiki.
  • Os pasos para instalar composer os tedes na wiki.
  • Os pasos para instalar git os tedes na wiki.
  • Os pasos para instalar Mysql, un xestor de bases de datos, os tedes na wiki.


  • Para instalar e crear un proxecto Laravel, dende consola, sen ser root,escribiremos situados no cartafol onde queiramos crear o proxecto: composer create-project laravel/laravel nome_proxecto "5.1.*"
Sendo 5.1 a versión de Laravel a utilizar
Nota: Se non poñemos a versión, descargará a última versión de Laravel que sexa compatible coa versión de PHP instalada.
  • Para lanzar o servidor web do proxecto creado, estando no cartafol raíz de dito proxecto, escribiremos: php artisan serve
Aparecerá unha mensaxe informando de que o servidor web está levantado e escoitando no porto 8000. Escribiremos na URL do navegador: http://localhost:8000
  • Para saber a versión do framework Laravel que temos instalado podemos escribir a seguinte orde dende o cartafol raíz do proxecto creado:
php artisan --version


  • Artisan é un comando de Laravel. Podedes consultalo neste enlace.
  • Para executar un comando de artisan temos que escribir: php artisan comando dende o raíz do sitio web creado.
  • Se escribimos soamente php artisan aparecen a lista de posibles comandos que podemos executar.
  • Para obter a axuda dun comando específico temos que escribir: php artisan help comando.
Por exemplo: php artisan make:controller

Primeiros pasos

Nesta parte imos usar diferentes 'verbos' do protocolo HTTP.
Instalaremos o complemento de firefox HttpRequester para simular o envío utilizando os verbos (get, post, put,...).
Exercicios: Unha vez lido os puntos anteriores deberedes facer diferentes rutas utilizando diferentes verbos có complemento.
Coidado coa orde das rutas, xa que se temos varias rutas nas que especificamos verbos que coincidan, cargará primeiro as que estean ao final do arquivo (por exemplo, unha con get e outra con match(['get']).
No caso das rutas que veñen na URL, se temos varias entradas no arquivo routes.php que coincidan coa mesma URL, cargará primeiro a que estea antes no arquivo routes.php.
EXEMPLO:
Php laravel 1.jpg
Exemplo de envío utilizando o método POST a url http://localhost:8000/testpost, sendo 'testpost' unha ruta previamente definida:
  1. Route::post('/testpost',function() {
  2.    echo "Isto é un post a /testpost";
  3. });
  • Durante o manual fala de utilizar un controlador para recibir un parámetro.
Se queredes facer a proba teredes que definir un arquivo php no cartafol: /proxecto/app/Http/Controllers/ControladorProba.php
O nome ControladorProba.php é un exemplo.
O código de dito arquivo pode ser algo parecido a isto:
  1. <?php
  2.  
  3. namespace App\Http\Controllers;
  4.  
  5. use App\User;
  6. use App\Http\Controllers\Controller;
  7.  
  8. class ControladorProba extends Controller {
  9.    
  10.     public function funcionControlador($id){
  11.         return "Esta información ven dun controlador especifico. Recibido o dato $id";
  12.     }
  13.    
  14. }


Como se pode ver, o nome da clase é igual ao nome do arquivo php. Deriva da clase Controller.
Leva unha función de nome 'funcionControlador' cun parámetro.
Agora debemos crear a ruta que vai facer uso de esta clase controladora:
Modificamos o arquivo routes.php.
Route::get('controlador/{identificador}','ControladorProba@funcionControlador');
Como vemos, agora en vez de ter unha función anónima, temos o nome da clase controladora (ControladorProba) e o nome da función ao que vai chamar (funcionControlador). Dita función vai levar un parámetro que está definido na parte Get da orde route ({identificador}).
Agora podemos poñer unha URL da forma: http://localhost:8000/controlador/1000
Enviaremos o dato 1000 á clase controladora.


  • Recurso:
  • Páxina web para verificar unha expresión regular: regex101.com.


  • Exercicios:
  • Crea unha ruta con dous parámetros que sexan opcionais. Dalle un valor por defecto a cada un deles.
  • Crea unha ruta que acepte como parámetro unha expresión regular de 5 números do 0 ao 7.
  • Crea outra ruta que acepte como parámetro unha expresión regular que acepta un número-letras (número guión letras)


Solucións:
  1. Route::get('/opcionais/{param1?}/{param2?}',function($par1=1,$par2='valor defecto'){
  2.    echo "O param1 ten valor $par1 e o param2 ten valor $par2";
  3. });
  4.  
  5. Route::get('/rutaNumeros/{numero}',function($numero){
  6.    echo "5 números de 0 ao 7: $numero";    
  7. })->where(array('numero' => '[0-7]{5}'));
  8.  
  9. Route::get('/rutaNumerosCadea/{dato}',function($dato){
  10.    echo "Dato numérico-texto: $dato";    
  11. })->where(array('dato' => '[0-7]+-[a-z|A-Z]+'));



  • Mellora: A validación dos parámetros que enviamos dende a URL para que cumpran unhas determinadas condicións (por exemplo, no caso dun nif, que teña 8 números e unha letra), o podemos implementar da seguinte forma:
  1. Route::pattern('id', '\d+');
  2. Route::pattern('username', '[a-z]{3,16}');
  3.  
  4.  
  5. Route::get('usuarios/{id}', 'UserController@obterInformacion');
  6. Route::get('productos/{id}', 'ProductController@obterInformacion');
No exemplo, ao parámetro {id} estámoslle a indicar que sexa un número.
Establecemos con 'pattern' as condicións que teñen que cumprir os parámetros da URL.
Desta forma, o parámetro {id} terá que cumprir as regras indicadas en todas as rutas onde sexa empregado.
Máis información neste enlace.


  • Para poder ver as rutas que imos creando dispoñemos dun comando artisan:
  1. php artisan route:list
Amosa nunha táboa todas as rutas, métodos e accións. Por cada ruta amosa os filtros asociados (o veremos posteriormente). Este comando vainos servir para comprobar que todas as rutas e filtros definimos estean creados correctamente.


  • Se queremos xestionar calquera ruta que sexa enviada polo usuario temos que facer uso da ruta 'any' desta forma:
Arquivo: /app/Http/routes.php
  1. Route::get('/{any}',function(){
  2.    return 'Páxina non atopada';
  3. })->where('any','.*');

Importante: A ruta debe ir ao final do arquivo routes para que primeiro xestione as que ten definidas.


Vistas

Exemplo 1 do manual anterior. Creación dunha vista

  • Lembrar que as vistas é onde se atopa o código que vai amosarse ao usuario (html,css,javascript).
A vista foi creada previamente no cartafol: /raiz_proxecto/resources/views
Arquivo: algo.blade.php
  1. <!DOCTYPE html>
  2. <html lang="es">
  3. <head>
  4.         <meta charset="UTF-8">
  5.         <title>Isto é unha vista de proba</title>
  6. </head>
  7. <body>
  8.         <h1>Vista "algo"</h1>
  9.         <p>Esta é a miña primeira vista en Laravel</p>
  10. </body>
  11. </html>
Un exemplo de código dunha ruta (routes.php) cun if condicional para preguntar se a vista existe dende .
  1. Route::get('vistas',function(){
  2.    if(view()->exists("algo")){
  3.         return view('algo');
  4.    }else {
  5.        echo "A vista non existe";
  6.    }
  7. });

Exemplo 2 do manual anterior. Creación dunha vista nun cartafol e paso de parámetros á vista dende a ruta

  • Seguindo o exemplo do manual, imos crear unha vista no cartafol /sitio_raiz/resources/views/outro.
Arquivo: index.blade.php
  1. <!DOCTYPE html>
  2. <html lang="es">
  3. <head>
  4.         <meta charset="UTF-8">
  5.         <title>Isto é unha vista de proba dentro dun cartafol</title>
  6. </head>
  7. <body>
  8.         <h1>Vista "algo" dentro dun cartafol</h1>
  9.     <p>Benvido {{$nomeVista}}. Xa vexo que tes {{$idadeVista}} anos :)</p>
  10. </body>
  11. </html>
  • Liña 9: Como vemos imos facer uso de dúas variables que van vir dende a ruta (poderían vir da mesma forma dende o controlador). Como estamos nun arquivo blade.php podemos facer uso da sintaxe das plantillas, no que para 'imprimir as variables' utilizamos {{ }}. Se queremos podemos facer uso da sintaxe 'clásica' de PHP, poñendo <?php echo $variable ?> ou a sintaxe abreviada:<?= $variable ?>.
Como norma xeral imos utilizar a sintaxe 'blade' xa que fai que o código sexa moito mais lexible.
Podedes ver as normas xerais de uso neste enlace.



Arquivo: routes.php
  1. Route::get('vistas',function(){
  2.    if(view()->exists("outro.index")){
  3.        $nome='Angel';
  4.        $idade=45;
  5.        return view('outro.index',[
  6.             'nomeVista' => $nome,
  7.             'idadeVista' => $idade
  8.         ]);
  9.    }else {
  10.        echo "A vista non existe";
  11.    }
  12. });
  • Como vemos no return view enviamos en forma de array as variables que imos utilizar na vista (nomeVista e idadeVista) cos valores das variables definidas na ruta ($nome e $idade).
  • Exercicio proposto: Modifica a ruta anterior para que reciba dous parámetros e sexan os que se envíen á vista (Nota: podemos ter as dúas vistas á vez)



Solución:
  1. Route::get('vistas/{nome}/{idade}',function($nome,$idade){
  2.    if(view()->exists("outro.index")){
  3.        return view('outro.index',[
  4.             'nomeVista' => $nome,
  5.             'idadeVista' => $idade
  6.         ]);
  7.    }else {
  8.        echo "A vista non existe";
  9.    }
  10. });


Exercicio 1

  • Le o seguinte enlace e crea unha vista utilizando unha plantilla. Todo debe ser creado dentro dun cartafol de nome 'exemplo_plantillas'.
Deberás crear primeiro a plantilla cunha estrutura formada por un menú vertical na parte esquerda, cun ancho do 35% do total e un contido ao carón do menú.
Crea dúas vistas que herden esta plantilla e engade algún contido.
Fai que a vista sexa cargada cando na URL poñamos 'vista_plantilla/1' cargará a vista primeira e 'vista_plantilla/2' cargará a vista segunda.
Crea dúas entradas de menú e que cada un 'cargue' unha das vistas.

Solución Exercicio 1

Arquivo: /resources/views/exemplo_plantillas/plantilla.blade.php
  1. <!DOCTYPE html>
  2. <html>
  3.     <head>
  4.         <title>Laravel</title>
  5.  
  6.         <style>
  7.             .menu{
  8.                 float: left;
  9.                 width: 30%;
  10.                 padding-left: 5px;
  11.             }
  12.             .menu a{
  13.                 display: block;
  14.             }
  15.             .contido{
  16.                 float: left;
  17.                 width: 65%;
  18.             }
  19.        
  20.         </style>
  21.     </head>
  22.     <body>
  23.         <div class="menu">
  24.             <a href='/vista_plantilla/1/'>Vista 1</a>
  25.             <a href='/vista_plantilla/2/'>Vista 2</a>
  26.         </div>
  27.          <div class="contido">
  28.             @yield('content')
  29.         </div>
  30.     </body>
  31. </html>


Arquivo: /resources/views/exemplo_plantillas/vista1.blade.php
  1. @extends('exemplo_plantillas.plantilla');
  2.  
  3.  
  4. @section('content')
  5. <p>Este é o contido da vista 1</p>
  6. @endsection
Arquivo: /resources/views/exemplo_plantillas/vista2.blade.php
  1. @extends('exemplo_plantillas.plantilla');
  2.  
  3.  
  4. @section('content')
  5. <h5>Este é o contido da vista 2</h5>
  6. @endsection


Arquivo: /http/routes.php
  1. Route::get('vista_plantilla/{numero}',function($numero){
  2.     return view("exemplo_plantillas.vista$numero");
  3. })->where(['numero'=>'[1-2]']);

Controlador

A diferenza do feito ata o de agora, non imos a chamar á vista directamente dende a páxina 'router.php', se non que imos chamar a unha páxina 'controller' que é a que vai invocar a vista.
Ven ser unha ponte entre o controlador frontal e as vistas, e vai ser dende onde chamemos ao modelo para obter ou enviar datos á base de datos.
  • As páxinas controladoras se atopan no cartafol: app/Http/Controllers

Exercicio 1. Creación dun controlador

  • Para crear unha páxina controlador podemos facer uso do comando php artisan dende o raíz do noso proxecto laravel da forma:
  1. php artisan make:controller CategoriasController
Isto creará unha páxina de nome 'CategoriasController' no cartafol 'app/Http/Controllers'.


  • Para crear un controlador cuns métodos definidos por defecto (por exemplo, se crea o método create onde iría a vista (o formulario) que daría de alta) teríamos que escribir:
  1. php artisan make:controller --resource CategoriasController


  • Nota: Podemos crear clases controladoras dentro de cartafoles da seguinte forma:
  1. php artisan make:controller CARTAFOL/CategoriasController



  • Modifica o exercicio anterior e fai que a vista sexa cargada dende o controlador.
A forma de carga a vista é a mesma (return view) pero agora terás que enviarlle os datos que van chegar á clase controladora en forma de parámetros dende route.php.




Solución:

Arquivo routes.php

  1. Route::get('vistas/{nome}/{idade}','DatosController@amosarVista');


Arquivo DatosController.php

  1. <?php
  2.  
  3. namespace App\Http\Controllers;
  4.  
  5. use Illuminate\Http\Request;
  6.  
  7. use App\Http\Requests;
  8.  
  9. class DatosController extends Controller
  10. {
  11.     // Poñemos $param_ para amosar como non teñen que chamarse igual que os parámetros definidos en router.php
  12.     public function amosarVista($param_nome,$param_idade){
  13.       return view('outro.index',[
  14.             'nomeVista' => $param_nome,
  15.             'idadeVista' => $param_idade
  16.         ]);
  17.     }
  18. }


Nota: Indicar que tamén podemos enviar array de datos á vista da seguinte forma

Arquivo DatosController.php

  1.     public function amosarVista($param_nome,$param_idade){
  2.         $datos = array();
  3.         $datos[]=1;
  4.         $datos[]=2;
  5.         return view('outro.index',[
  6.             'nomeVista' => $param_nome,
  7.             'idadeVista' => $param_idade,
  8.             'datosArray' => $datos
  9.         ]);
  10.     }


Arquivo index.blade.php (a vista)

  1.     ...............
  2.    <p>Volcado dos datos do array como fixemos en PHP:
  3.     <?php
  4.         var_dump($datosArray);
  5.     ?>
  6.     </p>
  7.     <p>
  8.     Forma de percorrer un array en blade (máis lexible)<br />
  9.     @foreach ($datosArray as $n)
  10.         Valor: {{ $n }}
  11.     @endforeach
  12.     </p>    
  13.  
  14.     <p>
  15.         Un dato en PHP:<?= $datosArray[0]?><br />
  16.         Un dato en Blade:{{$datosArray[1]}}
  17.     </p>
  18. </body>


Exercicio 2. Creación dun controlador

  • Crea unha nova ruta que responda a petición get: www.oteusitio.es/buscar/nif/, sendo nif un nif válido (9 díxitos e unha letra).
En caso de que sexa correcto, enviarase a unha vista de nome DatosAlumnos.blade.php, creada no cartafol ALUMNOS/, o nif xunto cun array cos seguintes datos: 'nome'=>'Angel', 'Idade=>45'. Dita vista amosará dentro dun <h5> e en cor vermella os datos enviados, en forma de lista desordenada.
O control de se se carga unha vista ou outra deberase facerse dende unha clase Controller de nome AlumnosController, dentro dun cartafol ALUMNOS/, e unha función de nome 'buscarAlumnos'.



Solución:

Arquivo routes.php

  1. Route::get('buscar/{nif}','ALUMNOS\AlumnosController@buscarAlumnos')->where(['nif' => '[0-9]{8}[A-Z]']);


Arquivo ALUMNOS/AlumnosController.php

  1. <?php
  2.  
  3. namespace App\Http\Controllers\ALUMNOS;
  4.  
  5. use Illuminate\Http\Request;
  6.  
  7. use App\Http\Requests;
  8. use App\Http\Controllers\Controller;
  9.  
  10. class AlumnosController extends Controller
  11. {
  12.     public function buscarAlumnos($nif){
  13.         if (view()->exists('ALUMNOS.DatosAlumnos')){
  14.             $datos=['nome'=>'Angel','idade'=>45];
  15.             return view ('ALUMNOS.DatosAlumnos',[
  16.             'nif' => $nif,
  17.             'datos' => $datos]);
  18.         }
  19.         else{
  20.             return 'Non se pode cargar a páxina...';
  21.         }
  22.        
  23.        
  24.     }
  25. }


Arquivo ALUMNOS/DatosAlumnos.blade.php

  1. <!DOCTYPE html>
  2. <html lang="es">
  3. <head>
  4.         <meta charset="UTF-8">
  5.         <title>Datos do alumno buscado</title>
  6. </head>
  7. <body>
  8.  
  9.     <ul>
  10.         <li>Nif:{{ $nif }}</li>
  11.     @foreach ($datos as $key=>$valor)
  12.         <li>{{ $key }}:{{ $valor }}</li>
  13.     @endforeach
  14.     </ul>
  15.  
  16.  
  17. </body>
  18. </html>



  • Controladores implícitos.
En Laravel podemos definir unha ruta chamando a un controlador no que estean definidos diferentes métodos e automaticamente en función da ruta chamará a un método ou a outros.
Por exemplo:

Arquivo app/Http/routes.php

  1. Route::controller('proba','ControladorProbaController');
Esta ruta 'xestionará' calquera petición que teña na url: http://sitioweb/proba


Se agora definimos no controlador estas entradas:

Arquivo app/Http/Controllers/ControladorProbaController.php

  1.     public function getInicio(){
  2.         return 'Inicio';
  3.     }
  4.     public function getFinal(){
  5.         return 'Final';
  6.     }
  7.     public function postDatos(){
  8.         return 'Enviando datos';
  9.     }
Este controlador responderá a estas peticións:

HTTP Request


Exemplo 1 do manual anterior. Uso de Http request

  • Neste exemplo imos ver como a partires dun formulario no que se pide login-password imos recibir có método 'post' os datos do mesmo noutra vista.
Partimos do formulario.
Arquivo: /proxecto_raiz/resources/views/formulario/Formulario.blade.php
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  2.     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  3. <html xmlns="http://www.w3.org/1999/xhtml" lang="es" xml:lang="es">
  4.     <head>
  5.         <meta charset="utf-8" />
  6.         <title>Formulario</title>
  7.         <style>
  8.             .formularios{
  9.                 width: 30%;
  10.                 margin: 0px auto;
  11.             }
  12.             .etiqueta{
  13.                 float: left;
  14.                 width: 190px;
  15.             }
  16.             .botonesformularios{
  17.                 width: 50%;
  18.                 margin: 30px auto;
  19.                 text-align: center;
  20.             }
  21.             select {
  22.                 width:50%;
  23.             }
  24.         </style>
  25.     </head>
  26.     <body>
  27.         <form id="frmValidacion" class="formularios" method="post" action="/controlador">
  28.             <div>    
  29.                 <div class='etiqueta'>Login:</div>
  30.                 <input type="text" size="15" maxlength="15" name="txtLogin" />
  31.             </div>                
  32.             <div>
  33.                 <div class='etiqueta'>Password:</div>
  34.                 <input type="password" size="15" maxlength="15" name="txtPassword" />
  35.             </div>                
  36.             <div class="botonesformularios">
  37.                 <input type='submit' value="ENVIAR" />
  38.             </div>
  39.         </form>
  40.  
  41.     </body>    
  42. </html>


Liña 27: Como vemos na action do formulario imos invocar un controlador a través dunha ruta definida no arquivo routes.php.
  • Definimos unha ruta para cargar a vista do formulario:
Arquivo: proxecto_raiz/app/Http/routes.php
  1. Route::get('formulario/',function(){
  2.     return view('formulario.Formulario');
  3. });
Nota: Por practicar estamos amosando a vista directamente dende a ruta, cando deberíamos pasar por un controlador.
Se poñemos como url: http://localhost:8000/formulario aparecerá o formulario.
  • Indicamos no arquivo de routes.php que se ten que facer cando reciba unha chamada do formulario. Fixarse como o verbo da ruta é post.
Arquivo: proxecto_raiz/app/Http/routes.php
  1. Route::post('controlador/','ControladorProbaController@mostrarUriUrl');


  • Agora creamos a clase controladora e método mostrarUriUrl dentro dela.
  1. <?php
  2.  
  3. namespace App\Http\Controllers;
  4.  
  5. use App\User;
  6. use App\Http\Controllers\Controller;
  7. use Illuminate\Http\Request;
  8.  
  9. class ControladorProbaController extends Controller {
  10.    
  11.     public function procedementoControlador($id){
  12.         return "Esta información ven dun controlador especifico. Recibido o dato $id";
  13.     }
  14.    
  15.     public function mostrarUriUrl(Request $request){
  16.         echo $request->path();
  17.         echo "<br>";
  18.         echo $request->url();
  19.         echo "<br>";
  20.  
  21.        
  22.         var_dump($request->all());  // ou dd(($request->all())); ou print_r(($request->all()));
  23.        
  24.     }
  25.    
  26. }
Nota:
  • $request->all(): Devolve todos os datos enviados polo formulario.
  • $request->input('txtLogin'): Devolve o texto do campo con name 'login' do formulario.


  • Dará como resultado:
controlador
http://localhost:8000/controlador

/home/angel/laravel/first_steps/app/Http/Controllers/ControladorProbaController.php:22:
array (size=2)
  'txtLogin' => string 'dfsdf' (length=5)
  'txtPassword' => string 'dsfds' (length=5)


Exercicio 1

  • Modifica o código anterior e crea unha vista de nome 'DatosFormulario.blade.php' que se atopa no cartafol 'formulario' dentro das views, que visualice o login e password enviado polo formulario.



  • Solución

Páxina: DatosFormulario.blade.php

  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  2.     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  3. <html xmlns="http://www.w3.org/1999/xhtml" lang="es" xml:lang="es">
  4.     <head>
  5.         <meta charset="utf-8" />
  6.         <title>Formulario</title>
  7.     </head>
  8.     <body>
  9.         LOGIN:{{$datos['txtLogin']}}<br />
  10.         PASSWORD:{{$datos['txtPassword']}}
  11.        
  12.  
  13.     </body>    
  14. </html>


Páxina: ControladorProbaController.blade.php

  1. <?php
  2.     ...................
  3.    
  4.     public function mostrarUriUrl(Request $request){
  5.         return view('formulario/DatosFormulario',['datos'=>$request->all()]);
  6.        
  7.        
  8.     }
  9. }

Reponse

  • Lembrar que xa vimos como enviar información de cabeceira ao navegador utilizando a función header de PHP.
Podedes comprobar o código de retorno da función 'response' có programa HttpRequester:
Php laravel response 1.jpg


  • Tedes neste enlace os diferentes content-type que podedes utilizar para enviar na cabeceira.


Exercicio 1

  • Crea unha ruta que teña unha URL deste tipo: /dato_response/{param} sendo {param} un número.
Fai que no caso de que dito número sexa maior que 100, se informe ao usuario cunha páxina de tipo 'non atopada' e dentro dun <h1> que o número non pode exceder de 100, amosando o número, e fai que o cabo de 3 segundos cargue a páxina /dato_response/1.
A páxina /dato_response/{param} amosará un texto de benvida amosando o número enviado como parámetro.

Solución Exercicio 1

  • Arquivo: proxecto_raiz/app/Http/routes.php
  1. Route::get('/dato_response/{numero}','ControladorProbaController@controlarDatoResponse')->where(['numero' => '[0-9]+']);


  • Arquivo: proxecto_raiz/app/Http/Controlllers/ControladorProbaController.php
  1. ..............
  2.     public function controlarDatoResponse($num){
  3.         if ($num>100) {
  4.             return response("<h1>O número enviado non é válido:$num</h1>")
  5.                 ->header('Content-Type', 'text/html')
  6.                 ->header('status', 404)
  7.                 ->header('Refresh', '3; url=/dato_response/1');            
  8.         }
  9.         else{
  10.             return view('DatoResponse',['numero' => $num]);
  11.         }
  12.            
  13.     }
  14. ..............


  • Arquivo: proxecto_raiz/resources/views/DatosResponse.blade.php
  1. <!DOCTYPE html>
  2. <html>
  3.     <head>
  4.         <title>Laravel</title>
  5.     </head>
  6.     <body>
  7.         <div class="container">
  8.             <h1>Benvido. O teu número é {{$numero}}</h1>
  9.         </div>
  10.     </body>
  11. </html>

Validación de formularios


  • No manual fala de que é posible instalar os arquivos necesarios para que en caso de erro de validación, as mensaxes do array $errors saian no noso idioma.
Para iso tedes que ir a este enlace
Nel indica o seguinte:
  • Descargar por composer (no enlace tedes outros métodos) os arquivos de tradución.
  1. composer require caouecs/laravel-lang:~3.0
Nota: A orde anterior é para versión de Laravel 5.* . Se tedes outra visitade o enlace.
  • Copiamos o cartafol da linguaxe de idioma (neste caso é o español)
  1. cp -r vendor/caouecs/laravel-lang/src/es/ resources/lang/
Estando situados no cartafol onde temos o proxecto laravel.


  • Modifica o arquivo config/app.php e substitúe as liñas de 'locale' polo idioma español:
  1.    ......
  2.  
  3.   'locale' => 'es',
  4.  
  5.    ..........


Exercicio 1

  • Crea unha táboa de nome AUTORES coas columnas: id_autor PK AU, apelido varchar(100), nome varchar(50)

Nota: Para crear o controlador fai uso do parámetro --resource como está indicado neste enlace.

  • Crea unha vista dentro do cartafol autores, de nome form_alta_autores.blade.php que teña un formulario para dar de alta a un novo autor, enviando como datos o nome e os apelidos.
Utiliza o método post no formulario e que o action apunte á páxina '/autores/alta
  • Modifica o arquivo de rutas para que recolla este tipo de solicitude:
  • http://sitioweb/autores/form/alta: Chamará ao controlador AutoresController e método create. Cargará a vista form_alta_autores.blade.php
  • http://sitioweb/autores/alta: Chamará ao controlador AutoresController e método store para gardar os datos do novo autor. Como aínda non vimos o acceso a datos, amosaremos unha cadea de texto indicando que foi dado de alta correctamente e cargaremos a vista do formulario de alta ao cabo de 5 segundos.
  • Valida os datos para que sexan obrigatorios e que a lonxitude do campo nome non sexa superior a 50 caracteres e a lonxitude do campo apelido non sexa superior a 100 caracteres. En caso de non cumprir os criterios, volver a cargar a páxina do formulario indicando os erros atopados e que os campos do formulario estean cubertos cos datos enviados.


Solución Exercicio 1

Arquivo: app/Http/routes.php

  1. Route::get('/autores/form/alta','AutoresController@create');
  2. Route::post('/autores/alta','AutoresController@store');


Arquivo: app/Http/Controllers/AutoresController.php

  1.     public function create()
  2.     {
  3.         return view('autores.form_alta_autores');
  4.     }
  5.  
  6.     public function store(Request $request)
  7.     {
  8.         $this->validate($request,[
  9.             'txtNome' => 'required|max:50',
  10.             'txtApelidos' => 'required|max:100',
  11.         ]);
  12.  
  13.         return response("<h1>Autor dado de alta correctamente</h1>")
  14.                 ->header('Content-Type', 'text/html')
  15.                 ->header('status', 200)
  16.                 ->header('Refresh', '3; url=/autores/form/alta');
  17.     }


Arquivo: resources/views/autores/form_alta_autores.blade.php

  1. <!DOCTYPE html>
  2. <html lang="es">
  3. <head>
  4.         <meta charset="UTF-8">
  5.         <title>Alta de autores</title>
  6. </head>
  7. <body>
  8.  
  9.   <form action="/autores/alta" method="post">
  10.     <div>
  11.         Apelidos: <input type="text" maxlength="100" size="60" name="txtApelidos" value="{{old('txtApelidos')}}"/>
  12.     </div>
  13.     <div>
  14.         Nome: <input type="text" maxlength="50" size="30" name="txtNome" value="{{old('txtNome')}}" />
  15.     </div>
  16.     <div>
  17.         <input type="submit" value="Enviar" />
  18.         <input type="reset" value="Borrar" />
  19.     </div>  
  20.    
  21.   </form>
  22.  
  23.     @if(count($errors) > 0)
  24.         <div class="errors">
  25.             <ul>
  26.             @foreach($errors->all() as $error)
  27.                 <li>{{ $error }}</li>
  28.             @endforeach
  29.             </ul>
  30.         </div>
  31.     @endif
  32.    
  33. </body>
  34. </html>

Modelos en Laravel

Introdución

Exemplo 1 do manual anterior

  • Temos que ter creada unha base de datos Mysql cun usuario e password que teña permiso sobre dita base de datos.
  • Os pasos para instalar Mysql, un xestor de bases de datos, os tedes na wiki.
Unha vez creada debemos editar o arquivo proxecto_raiz/app/.env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_DATABASE=homestead
DB_USERNAME=laravel
DB_PASSWORD=laravel

Unha vez cambiado debemos parar o servidor laravel e volvelo a iniciar coa orde: php artisan serve dende o raíz do proxecto.

  • Partindo que xa temos a táboa e a base de datos seguindo o manual...
  • Imos facer que se amosen os datos nunha vista en forma de lista.
  • Arquivo: proxecto_raiz/resources/views/basedatos/articles.blade.php
  1. <!DOCTYPE html>
  2. <html lang="es">
  3. <head>
  4.         <meta charset="UTF-8">
  5.         <title>Isto é unha vista de proba dunha táboa mysql</title>
  6. </head>
  7. <body>
  8.     <!-- Formato utilizando blade -->
  9.     <ul>
  10.     @foreach ($datos as $fila)
  11.         <li>{{ $fila->id }}---->{{ $fila->name }}</li>
  12.     @endforeach
  13.     </ul>
  14.  
  15.  
  16.     <!-- Formato utilizando php tradicional -->
  17.     <ul>
  18.         <?php
  19.             foreach($datos as $fila){
  20.                 printf("<li>%s--->%s",$fila->id,$fila->name);
  21.             }
  22.  
  23.         ?>
  24.        
  25.     </ul>
  26. </body>
  27. </html>
Liña 10: Nomeamos $datos á variable que vai vir do controlador cos datos da táboa. Segundo o manual isto non é necesario xa que podemos acceder dende calquera parte aos datos do modelo coa orde: \App\Article::all(); Pero desta forma practicamos o paso de datos dende o controlador e ademáis supoño que será a forma correcta :)


  • Arquivo: /proxecto_raiz/app/Http/Controllers/ArticulosController.php
  1. <?php
  2.  
  3. namespace App\Http\Controllers;
  4.  
  5. use App\User;
  6. use App\Http\Controllers\Controller;
  7. use Illuminate\Http\Request;
  8.  
  9. class ArticulosController extends Controller {
  10.    
  11.     public function amosarArticulos(){
  12.         $datos=\App\Article::all();
  13.         return view('basedatos.articles',[
  14.             'datos' => $datos
  15.         ]);
  16.  
  17.     }
  18.    
  19.    
  20. }
Liñas 13,14: Dende este método do controlador enviamos os datos da táboa á vista.


  • Arquivo: /proxecto_raiz/app/Http/routes.php
  1. Route::get('articulos/','ArticulosController@amosarArticulos');
Cando na url poñamos: http://localhost:8000/articulos chamará ao método amosarArticulos do controlador ArticulosController.


  • Resultado:
    1--->Probando
    2--->Algo
    3--->Lindo

Acceso a base de datos


  • O que devolve Eloquent cando facemos consultas á base de datos son 'coleccións'.
Podemos ver neste enlace todas as funcións dispoñibles.
Por exemplo, se queremos engadir un rexistro (unha instancia dun modelo) a unha colección (por exemplo a que ven de chamar a ::all()) podemos facer uso da función prepend.

Middleware

  • Son 'programas' ou anacos de código que se executan antes de chamar a un controlador.
Atópanse entre o controlador frontal que recibe as peticións dos usuarios e a chamada aos controladores por parte deste controlador frontal.
Poden ir enlazados varios middlewares un detrás doutro.


  • Lembrar que para crear un middleware podemos facer uso do comando artisan:
  1. php artisan make:middleware nome_middleware
  • Normalmente os imos utilizar cando teñamos implementado un sistema de autenticación de usuarios, no que en función do rol do mesmo redireccionaremos a unha páxina ou outra.
Outro exemplo de código podería ser este código, obtido de este enlace, no que se verifica se o país de procedencia da petición é de Estados Unidos...
  1. class AdMiddleware
  2. {
  3.     /**
  4.      * Handle an incoming request.
  5.      *
  6.      * @param  \Illuminate\Http\Request  $request
  7.      * @param  \Closure  $next
  8.      * @return mixed
  9.      */
  10.     public function handle($request, Closure $next)
  11.     {
  12.         // Test to see if the requesters have an ip address.
  13.         if($request->ip() == null){
  14.             throw new \Exception("IP ADDRESS NOT SET");  
  15.         }
  16.         $country=file_get_contents('http://api.hostip.info/get_html.php?ip=' . $request->ip());
  17.         echo $country;
  18.         if(strpos($country, "UNITED STATES")){
  19.            throw new \Exception("NOT FOR YOUR EYES, NSA");  
  20.         } else {
  21.             return redirect("index");  
  22.         }
  23.        
  24.         return $next($request);
  25.     }
  26. }



Exercicio 1

  • Crea unha vista que pida introducir a idade a un usuario.
Fai que se a idade do usuario é menor de 18 volva á vista do formulario.
Fai que se a idade do usuario é maior de 18 cargue outra vista no que se da a benvida ao usuario amosando a súa idade.
  • Utiliza un middleware para facelo e que soamente se execute cando enviemos a idade dende o formulario.


Solución Exercicio 1

  • Arquivo: /proxecto_raiz/app/Http/Router.php
  1. Route::get('getIdade/',function(){
  2.     return view('idade');
  3. });
  4.  
  5. Route::post('amosaridade/','IdadeController@amosarIdade')->middleware('idade_middleware');
  • Liña 6: Fixarse como o verbo debe ser 'post' para capturar o evento do formulario cando introducimos a idade.


  • Arquivo: /proxecto_raiz/app/Http/Kernel.php
  1. .......
  2.  
  3. 'idade_middleware' => \App\Http\Middleware\IdadeMiddleware::class,
  4.  
  5. .......


  • Arquivo: /proxecto_raiz/app/Http/Middleware/IdadeMiddleware.php
  1. <?php
  2.  
  3. namespace App\Http\Middleware;
  4.  
  5. use Closure;
  6.  
  7. class IdadeMiddleware
  8. {
  9.     public function handle($request, Closure $next)
  10.     {
  11.       if(!empty($request->input('txtIdade')) &&
  12.           $request->input('txtIdade')<18){
  13.             return redirect('getIdade/')->withInput()->withErrors(['msg'=>'A idade non pode ser menor que 18']);
  14.         }
  15.        
  16.       return $next($request);
  17. }
  • Liña 13: En caso de que non cumpra as condicións, enviamos nunha 'variable' especial de nome $errors (withErrors) a mensaxe que queremos que se amose na pantalla do formulario. Tamén enviamos de volta o dato introducido (withInput) que será posto outra vez no value da caixa de texto.
Para comprobar se ven a idade podemos facer uso da función 'has' da clase Request desta forma: if(!$request->has('txtIdade')).
Fixarse que poderíamos poñer dúas condicións distintas, unha para cando non recibe datos e outra para cando a idade é menor que 18, e enviar á paxina do formulario dous erros diferentes.
Neste exemplo deixamos introducir unha idade baleira e a mensaxe de erro será amosada na pantalla que visualiza a idade.
  • Arquivo: /proxecto_raiz/app/Http/Controller/IdadeController.php
  1. <?php
  2.  
  3. namespace App\Http\Controllers;
  4.  
  5. use Illuminate\Http\Request;
  6.  
  7. use App\Http\Requests;
  8. use App\Http\Controllers\Controller;
  9.  
  10. class IdadeController extends Controller
  11. {
  12.  
  13.     public function amosarIdade(Request $request){
  14.        
  15.         $datos_form=$request->all();
  16.        
  17.         return view('amosaridade',[
  18.             'datos' => $datos_form
  19.         ]);
  20.        
  21.     }
  22. }


  • Arquivo: /proxecto_raiz/Resource/Views/idade.blade.php
  1. <!DOCTYPE html>
  2. <html>
  3.     <head>
  4.         <title>Laravel</title>
  5.  
  6.         <link href="https://fonts.googleapis.com/css?family=Lato:100" rel="stylesheet" type="text/css">
  7.  
  8.     </head>
  9.     <body>
  10.         <div class="container">
  11.             <div class="content">
  12.                 <form name='frmIdade' action="/amosaridade" method="post">
  13.                     Idade: <input type="text" name="txtIdade" maxlength="3" size="3" value="{{old('txtIdade')}}"/>
  14.                     <div><input type="submit" value="ENVIAR" /></div>
  15.                 </form>
  16.             </div>
  17.             @if ($errors->any())
  18.                 <h4>{{$errors->first('msg')}}</h4>
  19.             @endif
  20.         </div>
  21.     </body>
  22. </html>

Cookies en Laravel


Aspectos varios

Así podemos abrir e pechar formularios con etiquetas Laravel. A particularidade de facelo desta forma é que ampliamos a funcionalidade. Así, podo definir unha apertura dun formulario que se vai basear nun modelo. Cando envíe como dato á vista un obxecto de dito modelo, se teño definidos os names das caixas de texto igual ao nome das columnas, ditas caixas énchense automaticamente cos datos do modelo.

Bootstrap 3

  • BootStrap é un framework para o deseño de sitios web utilizando javascript e CSS.
A principal vantaxe é que permite a adaptación do contido ao tipo de dispositivo que vai visualizar o sitio web. É o que se coñece como Deseño adaptativo ou Design Adapter.
  • Na web bootswatch.com podemos ver diferentes deseños para un sitio web utilizando bootstrap.



  • Un dos conceptos máis importantes consiste en dividir o contido da páxina en filas e columnas. O número máximo de columnas que podemos ter é de 12. A cada contido podemos indicarlle cantas columnas vai ocupar, axustándose o espazo total ao espazo de cada elemento.


Instalando Bootstrap con Laravel 5

  • Primeiro debemos instalar o paquete Laravel / Colletive.
Para iso seguiredes os pasos indicados na web https://laravelcollective.com escollendo na parte superior a versión de Laravel que teñades instalada ata o punto Opening form (non facelo).


Chega con descargar a 'Compiled and minified CSS, JavaScript, and fonts. No docs or original source files are included.' (a opción da esquerda).
Unha vez baixada e descomprimida, teredes tres cartafoles (css,fonts e js). Imos mover ditos cartafoles ao cartafol 'public/assets' do voso proxecto Laravel. O cartafol 'assets' teredes que crealo.
  • Agora imos crear unha 'plantilla' para todas as vistas (información obtida desde enlace).


Arquivo: resources/views/layout.blade.php

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.  <meta charset="utf-8">
  5.  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6.  <meta name="viewport" content="width=device-width, initial-scale=1">
  7.  <title>Laravel</title>
  8.  
  9.  {!! Html::style('assets/css/bootstrap.css') !!}
  10.  
  11.  <!-- Fonts -->
  12.  <link href='//fonts.googleapis.com/css?family=Roboto:400,300' rel='stylesheet' type='text/css'>
  13.  
  14.  <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
  15.  <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
  16. <!--[if lt IE 9]>
  17. <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
  18. <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
  19. <![endif]-->
  20. </head>
  21. <body>
  22. <nav class="navbar navbar-default">
  23. <div class="container-fluid">
  24. <div class="navbar-header">
  25. <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
  26. <span class="sr-only">Toggle Navigation</span>
  27. <span class="icon-bar"></span>
  28. <span class="icon-bar"></span>
  29. <span class="icon-bar"></span>
  30. </button>
  31. <a class="navbar-brand" href="#">Laravel</a>
  32. </div>
  33.  
  34.  
  35. </div>
  36. </nav>
  37.  
  38. @yield('content')
  39.  
  40.  
  41. <!-- Scripts -->
  42. <script src="http://code.jquery.com/jquery.js"></script>
  43. {!! Html::script('assets/js/bootstrap.min.js') !!}
  44. </body>
  45. </html>
  • Liñas 9 e 43: Estamos a cargar o arquivo CSS e Javascript necesarios para bootstrap. Fixarse como na ruta vai o cartafol 'assets' (parte do cartafol 'public', cando a páxina se carga).
  • Liña 38: Definimos unha etiqueta que vai ser o contido que van utilizar as vistas do noso sitio web.
Neste caso estamos poñendo 'en común' a todas as páxinas a cabeceira e a barra de navegación. Nada impide crear etiquetas para cada un delas e ter un contido diferente para cada vista do noso sitio web.
  • Liña 42: A librería jquery é necesaria para executar os scripts de javascript. Podería descargarse a local.
  • Como a esta vista dámoslle o nome de 'layout.blade.php', as vistas que cremos que teñan como base esta, deberán 'extender' dese nome:

Arquivo: resources/views/inicio.blade.php

  1. @extends('layout')
  2.  
  3. @section('content')
  4. <div class="container">
  5.  <div class="row">
  6.  <div class="col-md-10 col-md-offset-1">
  7.  <div class="panel panel-default">
  8.  <div class="panel-heading">Inicio</div>
  9.  
  10.  <div class="panel-body">
  11. Usando bootstrap
  12.  </div>
  13.  </div>
  14.  </div>
  15.  </div>
  16. </div>
  17. @endsection
Como vemos estamos a substituír o 'content' do layout.blade.php.


  • Temos neste enlace un exemplo para facer unha vista para o rexistro e validación de usuarios tendo ao final de todo a versión para Laravel utilizando 'Blade'.
Neste enlace incorpora dunha forma diferente o framework bootstrap, xa que o carga dende Internet utilizando Content Delivery Network (CDN). Todas as clases, CSS e código javascript está aloxado en servidores de Internet, de tal forma que todo o código para incorporar bootstrap ao teu proxecto non se carga dende o teu sitio web, se non que está repartido en diferentes servidores en Internet, reducindo a carga de traballo do teu servidor.

Modificando o theme (aspecto)

Existen multitude de sitios onde podedes atopar outros themes.
  • Para modificar o theme, temos dúas opcións:
  • Se estamos a utilizar CDN, soamente debemos cambiar a URL a cargar.
Podemos ver nesta web as diferentes 'rutas' CDN en función do theme escollido.
  • Se estamos a utilizar bootstrap copiado 'localmente' deberemos substituír o arquivo 'bootstrap.css' que se atopa (se seguíchedes o exemplo) en 'public/assets/css', polo do theme seleccionado.
Despois teremos que descubrir como se chaman as clases de cada un dos controis para que se visualicen de acordo ao theme seleccionado.
Vexamos un exemplo:





-- Ángel D. Fernández González -- (2016).