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

0voto

Leonardo-Tadei comentado

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 Puntos227320

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.

0voto

juan_carlos_clemente comentado

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.

0voto

Leonardo-Tadei comentado

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.

0voto

rubengc comentado

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

0voto

elporfirio comentado

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.

0voto

Leonardo-Tadei comentado

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.

Otras Preguntas y Respuestas


...

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

Conecta