https://www.youtube.com/channel/UCpSt6arMgODWN5584jZ41TQ/videos?shelf_id=0&view=0&sort=dd
Categoría: symfony
Subir imágenes a Symfony
La plantilla:
<form action="areas/imagen" method="post" enctype="multipart/form-data">
<input type="file" name="imagen"><br/>
<input type="submit">
</form>
El controlador:
/**
* @Route("/areas/imagen", name="imagen")
*/
public function imagen() {
$destino= $this->get('kernel')->getProjectDir()."/public/upload";
$request = Request::createFromGlobals();
$archivo = $request->files->get('imagen');
$archivo->move($destino,$archivo->getClientOriginalName());
return $this->render('areas/index.html.twig');
}
Ejemplos de consultas
/**
* @return Producto[] Returns an array of Producto objects
*/
public function findByPrecioMayor($value) {
return $this->createQueryBuilder('c')
->andWhere('c.precio > :val')
->setParameter('val', $value)
->orderBy('c.id', 'ASC')
->getQuery()
->getResult()
;
}
/**
* @return Producto[] Returns an array of Producto objects
*/
public function findByNombre($value) {
return $this->createQueryBuilder('c')
->select('c.nombre')
->where('c.nombre like :val')
->setParameter('val', "%$value%")
->orderBy('c.id', 'ASC')
->getQuery()
->getArrayResult()
;
}
/**
* @return Producto[] Returns an array of Producto objects
*/
public function countProductos() {
return $this->createQueryBuilder('c')
->select('count(c) as total')
->getQuery()
->getSingleScalarResult()
;
}
/**
* @return Producto[] Returns an array of Producto objects
*/
public function countProductosByTipo() {
return $this->createQueryBuilder('c')
->select('c.tipo, count(c) as total')
->groupBy('c.tipo')
->getQuery()
->getArrayResult()
;
}
Añadir entidades relacionadas
Si tenemos una entidad producto relacionada con categorías, y queremos dar de alta un producto, tendremos que indicar cual es su categoría y esto lo tenemos que hacer con entidades. Si la categoría no existe lo hacemos así:
$categoria=new Categoria();
$categoria->setNombre('Tornillería');
$producto = new Producto();
$producto->setNombre('Tornillo');
$producto->setPrecio(20);
$producto->setCategoria($categoria);
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($categoria);
$entityManager->persist($producto);
$entityManager->flush();
Si la categoría ya existe lo hacemos así:
$categoria = $this->getDoctrine()
->getRepository(Categoria::class)
->find(1);
$producto = new Producto();
$producto->setNombre('Arandela');
$producto->setPrecio(30);
$producto->setCategoria($categoria);
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($producto);
$entityManager->flush();
o así:
$categoria = $this->getDoctrine()
->getRepository(Categoria::class)
->find(1);
$producto = new Producto();
$producto->setNombre('Arandela');
$producto->setPrecio(30);
$categoria->addProducto($producto);
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($producto);
$entityManager->flush();
Para acceder a los productos de una categoría lo podemos hacer así:
$categoria = $this->getDoctrine()
->getRepository(Categoria::class)
->find(1);
$productos = $categoria->getProductos();
foreach($productos as $producto){
echo $producto->getNombre();
}
Obtener entidades desde la base de datos
Teniendo bien configurado el archivo .env, nos colocamos en la raiz de nuestro sitio y ponemos lo siguiente:
php bin/console doctrine:mapping:import App\Entity annotation --path=src/Entity
Y después regeneramos las entidades para que se pongan los getters y setters:
php bin/console make:entity --regenerate App
Ejemplos de plantillas
Controlador:
public function index()
{
$tabla=['a','b','c'];
$usuario="Juan";
$notas=[1,5,23,78,5];
$actores=['Penelope','Alec','Fernando'];
return $this->render('plantillas/index.html.twig', [
'tabla' => $tabla,
'usuario'=>$usuario,
'notas'=>$notas,
'actores'=>$actores
]);
}
Vista:
{% extends 'base.html.twig' %}
{% block body %}
{# funciones de twig #}
{{max(1,2,3)}}
{{max(tabla)}}
{{ random(['apple', 'orange', 'citrus']) }} {# example output: orange #}
{{ random('ABC') }} {# example output: C #}
{{ random() }} {# example output: 15386094 (works as the native PHP mt_rand function) #}
{{ random(5) }} {# example output: 3 #}
{{ random(10) }} {# example output: 3 #}
{{date()|date('d/m/Y')}}
{{date('2020-1-2')|date('d/m/Y')}}
{{date('-2days')|date('d/m/Y')}}
{{date('+2month')|date('d/m/Y')}}
{# filtros usando | (pipe) #}
{{usuario}}
{{usuario | upper}}
{{usuario | lower}}
{{usuario | reverse}}
{{tabla|sort|join(', ')|upper}}
{% set cadena='4,2,8,4,1,9,34' %}
{{cadena | split(',') |sort|join(',')}}
<table>
<tr><td>Nombre</td></tr>
{% for actor in actores %}
<tr><td>{{actor}}</td></tr>
{% endfor %}
</table>
{% set a=5 %}
{% set b=[1,2,3,4] %}
{% set c={'nombre':'Juan','Apellidos':'Pi'} %}
{{a +3}}
{{a * 3}}
{{a // 4}} {# division entera #}
{{a / 4}} {# division normal #}
{{a **2}} {# potencia (elevar a un número #}
{{a % 2}}
{% if a>10 %}
<h1>A es mayor que 10</h1>
{% else %}
<h1>A es menor que 10</h1>
{% endif %}
{% if a>10 %}
<h1>A es mayor que 10</h1>
{% elseif a>5 %}
<h1>A es menor que 5</h1>
{% else %}
<h1>A vale muy poco</h1>
<h2>Todo el código que quiera</h2>
{% endif %}
{# >,<,>=,<=,!=,==,===, starts width ends with matches #}
{% if usuario starts with 'J' %}
<p>Usuario empieza con j</p>
{% endif %}
{% if b[0] matches '/\\d+/' %}
<p>Es numérico</p>
{% endif %}
{% if 2 in b %}
<p>Tenemos 2 en b</p>
{% endif %}
{% if 2 is even %}
<p>Tenemos 2 en b</p>
{% endif %}
<ul>
{% for i in 0..10 if i is odd %}
<li>{{i}}</li>
{% endfor %}
{% for i in 'a'..'z' %}
<li>{{i}}</li>
{% endfor %}
{% for i in b %}
<li>{{i}}</li>
{% endfor %}
{% for i in tabla %}
<li>{{i}}</li>
{% endfor %}
</ul>
{% endblock %}
Symfony ecuación segundo grado
Controlador:
/**
* @Route("/areas/ecuacion", name="ecuacion")
*/
public function ecuacion() {
$request = Request::createFromGlobals();
$a = $request->request->get('a');
$b = $request->request->get('b', 1);
$c = $request->request->get('c', 1);
if (!is_numeric($c) || !is_numeric($b) || !is_numeric($a)) {
return $this->render('areas/error.html.twig',
['mensaje' => 'Los valores deben ser numéricos',
'url'=>'/areas']);
}
$raiz = $b * $b - 4 * $a * $c;
if ($raiz < 0) {
$raiz1 = "No existe";
$raiz2 = "No existe";
} elseif ($raiz == 0) {
$raiz1 = -$b / ($a * 2);
$raiz2 = $raiz1;
} else {
$raiz1 = (-$b + sqrt($raiz)) / ($a * 2);
$raiz2 = (-$b - sqrt($raiz)) / ($a * 2);
}
return $this->render('areas/ecuacion.html.twig', ['raiz1' => $raiz1,
'raiz2' => $raiz2,
'valores'=>[$a,$b,$c]]);
}
Vistas:
<form action="areas/ecuacion" method="post">
<input type="number" name="a">x<sup>2</sup>+ <input type="number" name="b"> x+
<input type="number" name="c"><br/>
<input type="submit">
</form>
{% extends 'base.html.twig' %}
{% block title %}Hello!{% endblock %}
{% block body %}
<h1>Las soluciones de la ecuación {{valores[0]}}x<sup>2</sup>+{{valores[1]}}x+{{valores[2]}} son:</h1>
{% if raiz1=='No existe' %}
<p>La ecuación no tiene soluciones reales, quizás imaginarias</p>
<!-- <img src="{{ asset('img/ninguna.gif') }}" alt=""/>-->
{% elseif raiz1==raiz2 %}
<p>La ecuación tiene una sóla raiz: {{raiz1}}</p>
<!-- <img src="{{ asset('img/una.png') }}" alt=""/>-->
{% else %}
<p>Raiz 1: {{raiz1}}</p>
<p>Raiz 2: {{raiz2}}</p>
<!-- <img src="{{ asset('img/dos.png') }}" alt=""/>-->
{% endif %}
<iframe src="http://graph.tk/" id="my_graph" style="width:500px;height:400px">
</iframe>
<script>
var my_graph=document.getElementById("my_graph");
my_graph.onload=function(){
function g(m){
my_graph.contentWindow.postMessage(m,"http://graph.tk");
};
g("add:{{valores[0]}}x^2+{{valores[1]}}x+{{valores[2]}}");
g("center:0,0");
}
</script>
{% endblock %}
Symfony obtener parámetros
Controlador:
/**
* @Route("/areas/cuadrado", name="cuadrado")
*/
public function cuadrado() {
$request = Request::createFromGlobals();
$lado = $request->request->get('lado');
return $this->render('areas/cuadrado.html.twig', ['lado' => $lado]);
}
Vista:
<h1>Cálculo de áreas</h1>
<a href="/areas/cuadrado">Cuadrado</a>
<form action="/areas/cuadrado" method="post">
<input type="text" name="lado"><input type="submit">
</form>
Resultado:
{% extends 'base.html.twig' %}
{% block title %}Hello!{% endblock %}
{% block body %}
<h1>El área del cuadrado es el lado al cuadrado</h1>
<p>Un cuadrado de lado {{lado}} tiene un área de {{lado*lado}}</p>
{% endblock %}
Symfony pasar html a la vista
Controlador:
/**
* @Route("/tabla/pintar", name="pintar")
*/
public function pintar() {
$request = Request::createFromGlobals();
$ancho = $request->query->get('ancho');
$alto = $request->query->get('alto');
$tabla = "<table>";
for ($i = 0; $i < $alto; $i++) {
$tabla .= "<tr>";
for ($j = 0; $j < $ancho; $j++) {
$tabla .= "<td>" . ($j + $i * $ancho) . "</td>";
}
$tabla .= "</tr>";
}
$tabla .= "</table>";
return $this->render('tabla/tabla.html.twig', [
'tabla' => $tabla,
]);
}
vista:
{% extends 'base.html.twig' %}
{% block title %}Tabla{% endblock %}
{% block styles %}
<style>
footer{
background-color: red;
}
</style>
{% endblock %}
{% block body %}
{# esto es un comentario #}
<h1>Esta es la tabla que ha pedido</h1>
{{tabla | raw}}
<img src="{{ asset('img/gato.jpg') }}" alt=""/>
{% endblock %}
CRUD Producto Symfony
Entidad Producto:
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass="App\Repository\ProductoRepository")
*/
class Producto
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
*/
private $nombre;
/**
* @ORM\Column(type="integer")
*/
private $precio;
/**
* @ORM\Column(type="integer", nullable=true)
*/
private $stock;
public function getId(): ?int
{
return $this->id;
}
public function getNombre(): ?string
{
return $this->nombre;
}
public function setNombre(string $nombre): self
{
$this->nombre = $nombre;
return $this;
}
public function getPrecio(): ?int
{
return $this->precio;
}
public function setPrecio(int $precio): self
{
$this->precio = $precio;
return $this;
}
public function getStock(): ?int
{
return $this->stock;
}
public function setStock(?int $stock): self
{
$this->stock = $stock;
return $this;
}
}
Controlador:
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Request;
use App\Entity\Producto;
class ProductoController extends AbstractController {
/**
* @Route("/producto", name="producto")
*/
public function index() {
/*
$entityManager = $this->getDoctrine()->getManager();
for ($i = 1; $i <= 10; $i++) {
$producto = new Producto();
$producto->setNombre('Producto '.$i);
$producto->setPrecio($i);
// Guardamos el producto
$entityManager->persist($producto);
}
// Actualizamos los datos en la BD
$entityManager->flush();
*/
/*
//Producto es un objeto del tipo Producto Entity
//Con sus propiedades y métodos (concretamente los get y set de las columnas)
$producto = $this->getDoctrine()
->getRepository(Producto::class)
->find($id);
$producto->setNombre('Nuevo nombre cool para mi producto ¡Mola!');
$entityManager = $this->getDoctrine()->getManager();
$entityManager->remove($producto);
$entityManager->flush();
$producto = $this->getDoctrine()
->getRepository(Producto::class)
->findOneBy(['nombre'=>'Producto 5']);
*
*/
$productos = $this->getDoctrine()
->getRepository(Producto::class)
->findAll();
$salida = [];
foreach ($productos as $producto) {
$salida[] = [$producto->getId(),
$producto->getNombre(),
$producto->getPrecio()];
}
return $this->render('producto/index.html.twig', [
'productos' => $salida]);
}
/**
* @Route("/producto/nuevo", name="nuevo")
*/
public function nuevo() {
$request = Request::createFromGlobals();
$nombre = $request->request->get('nombre');
$precio = $request->request->get('precio');
$stock = $request->request->get('stock');
$id = '';
if (!empty($nombre) && !empty($precio)) {
//Añadir el producto
$producto = new Producto();
$producto->setNombre($nombre);
$producto->setPrecio($precio);
if (empty($stock)) {
$stock = 0;
}
$producto->setStock($stock);
$entityManager = $this->getDoctrine()->getManager();
// Guardamos el producto
$entityManager->persist($producto);
// Actualizamos los datos en la BD
$entityManager->flush();
$id = $producto->getId();
}
return $this->render('producto/nuevo.html.twig', ['id' => $id]);
}
/**
* @Route("/producto/eliminar/{id}", name="eliminar")
*/
public function eliminar(Producto $producto) {
$nombre = $producto->getNombre();
$entityManager = $this->getDoctrine()->getManager();
$entityManager->remove($producto);
$entityManager->flush();
return $this->render('producto/eliminar.html.twig', ['nombre' => $nombre]);
}
/**
* @Route("/producto/editar/{id}", name="editar")
*/
public function editar(Producto $producto) {
$request = Request::createFromGlobals();
$nombre = $request->request->get('nombre');
$precio = $request->request->get('precio');
$stock = $request->request->get('stock');
if (!empty($nombre) && !empty($precio)) {
$producto->setNombre($nombre);
$producto->setPrecio($precio);
if (empty($stock)){$stock=0;}
$producto->setStock($stock);
$entityManager = $this->getDoctrine()->getManager();
$entityManager->flush();
}
return $this->render('producto/editar.html.twig', [
'nombre' => $producto->getNombre(),
'precio' => $producto->getPrecio(),
'stock' => $producto->getStock(),
]);
}
}
Plantillas:
index:
{% extends 'base.html.twig' %}
{% block title %}{% endblock %}
{% block body %}
<div class="container">
<h1>Productos</h1>
<a href="/producto/nuevo" class="btn btn-success">Nuevo producto</a>
<table class="table">
<tr><td>Id</td><td>Nombre</td><td>Precio</td><td>Acciones</td></tr>
{% for producto in productos %}
<tr><td>{{producto[0]}}</td><td>{{producto[1]}}</td><td>{{producto[2]}}</td>
<td><a href="/producto/editar/{{producto[0]}}" class="btn btn-info">Editar</a>
<a href="/producto/eliminar/{{producto[0]}}" class="btn btn-danger">Eliminar</a></td></tr>
{% endfor %}
</table>
</div>
{% endblock %}
nuevo
{% extends 'base.html.twig' %}
{% block title %}{% endblock %}
{% block body %}
<div class="container">
<h1>Nuevo Producto</h1>
{% if id %}
<div class="alert alert-success alert-dismissible">
<a href="#" class="close" data-dismiss="alert" aria-label="close">×</a>
<strong>Correcto</strong> Se ha insertado con éxito el producto con id {{id}}.
</div>
{% endif %}
<form method="post">
<div class="form-group">
Nombre: <input class="form-control" type="text" name="nombre"></div>
<div class="form-group">
Precio: <input class="form-control" type="text" name="precio"></div>
<div class="form-group">
Stock: <input class="form-control" type="text" name="stock"></div>
<input type="submit" class="btn btn-info">
</form>
</div>
{% endblock %}
editar:
{% extends 'base.html.twig' %}
{% block title %}{% endblock %}
{% block body %}
<div class="container">
<h1>Editar Producto</h1>
<form method="post">
<div class="form-group">
Nombre: <input class="form-control" type="text" value="{{nombre}}" name="nombre"></div>
<div class="form-group">
Precio: <input class="form-control" type="text" value="{{precio}}" name="precio"></div>
<div class="form-group">
Stock: <input class="form-control" type="text" value="{{stock}}" name="stock"></div>
<input type="submit" class="btn btn-info">
</form>
<a href="/producto">Volver al listado</a>
</div>
{% endblock %}
eliminar:
{% extends 'base.html.twig' %}
{% block title %}{% endblock %}
{% block body %}
<div class="container">
<h1>Eliminar Producto</h1>
<p>Has eliminado el producto <b>{{nombre}}</b></p>
<a href="/producto">Volver al listado</a>
</div>
{% endblock %}