entre Desarrolladores

Recibe ayuda de expertos

Registrate y pregunta

Es gratis y fácil

Recibe respuestas

Respuestas, votos y comentarios

Vota y selecciona respuestas

Recibe puntos, vota y da la solución

Pregunta

2votos

Acceder a una entidad directamente desde twig

Tengo la siguiente entidad:

<?php

namespace Proyecto\NosequeBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * MiEntidad
 *
 * @ORM\Table()
 * @ORM\Entity
 */
class MiEntidad
{ 

    /**
     * @var string
     *
     * @ORM\Column(name="nombre", type="string")
     */
    private $nombre;

y quiero acceder a ella desde twig SIN tener que enviarla a través de un controlador:

{{ MiEntidad.nombre }}

¿Cómo podría conseguirlo?

2 Respuestas

1voto

rubengc Puntos1090

Encontré la solución realizando una extensión de Twig que obtuviese dicho miembro de la entidad por su nombre

<?php

namespace Proyecto\ImaginarioBundle\Extension;

use Doctrine\ORM\EntityManager;
use Proyecto\ImaginarioBundle\Entity\MiEntidad;

class MiEntidadTwigExtension extends \Twig_Extension
{
    private $connection;

    public function __construct(EntityManager $entityManager) {
        $this->connection = $entityManager->getConnection();
    }

    public function getFunctions()
    {
        return array(
            'entidad' => new \Twig_Function_Method($this, 'getMiEntidad'),
        );
    }

    public function getMiEntidad($name)
    {
        $sql = "SELECT * FROM MiEntidad WHERE name='".$name."'";
        $result = $this->connection->fetchAll($sql);

        if($result)
            return $result[0];

        return array('value' => null);
    }

    public function getName()
    {
        return 'mientidad_twig_extension';
    }
}

Esto permite que después desde twig pueda obtener dicho valor de la siguiente forma

{{ entidad('foo').name }}

P.D: gracias por la ayuda Leonardo

Leonardo-Tadei comentado Nov 4, 2013

Por nada!

estás salvando la imposibilidad de acceder a un atributo privado encapsulándola en otro Objeto que la accede por su getter.

Saludos cordiales!

2votos

Leonardo-Tadei Puntos223480

Hola @rubengc,

Twig accede a los datos para rellenar la plantilla de esta forma:

You can use a dot (.) to access attributes of a variable (methods or properties of a PHP object, or items of a PHP array), or the so-called "subscript" syntax ([]):

{{ foo.bar }}
{{ foo['bar'] }}

Al definir el atributo "nombre" de tu clase como privado, queda inaccesible por la plantilla. Deberías ponerlo como público para que se pueda acceder.

Este es uno de los motivos por los cuales los puristas de la POO no usamos este tipo de herramientas, que para funcionar requieren que se viole el encapsulamiento.

Saludos!

PD: de paso, y ya que hablamos de puristas, en una arquitectura MVC el Controlador es quien recibe los mensajes de la Vista, y con ellos modifica el Modelo, pero nunca envía cosas a la Vista.

juan_carlos_clemente comentado Nov 6, 2013

Primero que nada ¿existen realmente los "puristas de la POO"?

Segundo, que TU no utilices Twig que realmente es excelente (deberias ver mas como está construido) no significa que este vaya contra los estándares que se han tratado de construir bajo el paradigma de orientado a objetos, de hecho cuando tu accedes a una propiedad

{{ foo.bar }} 

twig internamente busca el getter del objeto para regresar el valor de la propiedad si esta no es accesible públicamente.

Leonardo-Tadei comentado Nov 6, 2013

Hola Juan Carlos!

tengo evidencia de que sí existen los puristas de la POO: estás hablando con uno ;-)

También varios de mis colegas del LIFIA de la UNLP (unos chicos que han hecho software regional para JPMorgan en Smalltalk, el juego El Gran DT que almacena en Gemstone y otras cositas más)

Volviendo a Twig, que es el tema interesante de este post, decís que @rubengc podría haberse ahorrado escribir una clase extra agregando a su clase original este código?

<?php
namespace Proyecto\NosequeBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
 * MiEntidad
 *
 * @ORM\Table()
 * @ORM\Entity
 */
class MiEntidad { 
    /**
     * @var string
     *
     * @ORM\Column(name="nombre", type="string")
     */
    private $nombre;
    function setNombre($v){
       $this->nombre = $v;
    }
    function gsetNombre(v){
       return $this->nombre;
    }
...

Tal vez Rubén lo pueda implementar y simplificar su código.

rubengc comentado Nov 7, 2013

En el código de ejemplo no habia puesto nada de los getters y setters porque supuse que se sobrentendía que una entidad mapeada con doctrine, el cual es un ORM, había generado todo ese contenido

Si que es verdad que se puede acceder al getter de una entidad de esa forma, pero en primer lugar debes pasar dicho objeto por el controlador, y eso es lo que quería evitar

elporfirio comentado Nov 7, 2013

Creo que el paradigma de la POO se presta mucho a la interpretación, hay un patrón que podemos seguir pero no es necesariamente se debe seguir al pie de la letra.

como dice leonardo-tadei si es privado, debiste crear otro metodo publico para obtener la informacion del elemento privado.
Lo malo aquí es que muchas veces se le da muchas vueltas al asunto, un metodo publico que llama a 5 privados que definen una propiedad pubica.. en fin puras interpretaciones.

Gracias por la info.

Leonardo-Tadei comentado Nov 7, 2013

Hola @elporfirio!

Para el ejemplo que das de un metodo publico que llama a 5 privados que definen una propiedad publica, más que una interpretación parece una mala comprensión de la POO.

Lo que sí estamos de acuerdo es que en POO hay muchass variantes de diseño, pero el paradigma da unas pautas básicas elementales a seguir, y me parece que estas pautas sí hay que seguirlas al pie de la letra: encapsulamiento, polimorfismo y herencia.

Después encontramos como la de tu ejemplo malas implementaciones, frameworks que violan los principios y malas prácticas bien reconocidas como el "modelo anémico", la "clase Dios" o diseñar jerarquías de clases basadaos en los atributos en vez de en el comportamiento., por citar solo las cosas malas más vistas.

Gracias por tu comentario: me apasiona el tema de la POO, así que me disculpo si me pongo un poco extenso con estas cuestiones. Me divierte mucho charlar sobre esto!

Por favor, accede o regístrate para responder a esta pregunta.

¿Conoces alguien que puede responder?
¡Comparte esta pregunta!


Otras Preguntas y Respuestas


Actividad Reciente

  • carlossevi ganó una medalla hace 9 horas

    Buena Respuesta - Recibió +1 votos en respuesta
  • matrixmar8 ganó una medalla hace 1 día

    Club de los 100 - Recibió un total de 100 puntos
  • matrixmar8 ganó una medalla hace 1 día

    Humano Verificado - Verificó su email
  • JoseVillalta ganó una medalla hace 2 días

    Club de los 100 - Recibió un total de 100 puntos
  • JoseVillalta ganó una medalla hace 2 días

    Humano Verificado - Verificó su email
  • Tammya ganó una medalla hace 2 días

    Club de los 100 - Recibió un total de 100 puntos
  • Tammya ganó una medalla hace 2 días

    Humano Verificado - Verificó su email
  • edu_botero ganó una medalla hace 2 días

    Fotogénico - Subió un avatar
  • edu_botero ganó una medalla hace 2 días

    Club de los 100 - Recibió un total de 100 puntos
...

Bienvenido a entre Desarrolladores, donde puedes realizar preguntas y recibir respuestas de otros miembros de la comunidad.

Conecta