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">&times;</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 %}