Foros del Web » Programando para Internet » PHP » Frameworks y PHP orientado a objetos »

Ordenando Repositories en Doctrine y otras dudas doctrine

Estas en el tema de Ordenando Repositories en Doctrine y otras dudas doctrine en el foro de Frameworks y PHP orientado a objetos en Foros del Web. Hola amigos, ¿ Quiero saber si hay algun metodo en Doctrine para traerte el repository ya ordenado, o hay que ordenarlo una vez te lo ...
  #1 (permalink)  
Antiguo 03/04/2012, 16:42
 
Fecha de Ingreso: enero-2012
Ubicación: España
Mensajes: 150
Antigüedad: 12 años, 2 meses
Puntos: 0
Ordenando Repositories en Doctrine y otras dudas doctrine

Hola amigos,

¿ Quiero saber si hay algun metodo en Doctrine para traerte el repository ya ordenado, o hay que ordenarlo una vez te lo has traido ?
¿ Hay que hacerlo con Custom Repositories o como ?
http://docs.doctrine-project.org/pro...m-repositories
Yo es que me quiero traer todos los registros de una tabla pero ordenados y no encuentro como se hace.
Código PHP:
$this->_categoria->_em->getRepository('Entidades\categoria')->findAll(); 
( Esto son solo pruebas, luego implementare los modelos para no hacer llamadas de este tipo si no $this->_categoria->findAll() )



Y otra preguntilla,
¿ Que tal idea es la de hacer modelos con metodos estaticos y hacer llamadas del tipo
Modelo::findAll();
Modelo::findBy( ... );
para no tener que instanciar nuestros modelos y hacer llamadas del tipo
$model = new Modelo;
$model->findAll();
?



Una mas,
¿ Que es mas rapido, mejor para nuestra proyecto web ? ¿ instanciar el Entity manager, guardarlo en el registry y que cada vez que en el codigo un modelo necesite hacer uso de ello, coja la instancia y la use o hacer que cada modelo cargue el Entity manager en su constructor por ejemplo ?

Gracias por vuestra ayuda compañeros, suerte.
Un saludo.
  #2 (permalink)  
Antiguo 03/04/2012, 19:55
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 17 años, 11 meses
Puntos: 2135
Respuesta: Ordenando Repositories en Doctrine y otras dudas doctrine

Para ordenar tienes que hacer uso del QueryBuilder: http://docs.doctrine-project.org/pro...y-builder.html y sí lo mejor es que sea en un custom repositorie.

Saludos.
  #3 (permalink)  
Antiguo 03/04/2012, 19:55
Avatar de maycolalvarez
Colaborador
 
Fecha de Ingreso: julio-2008
Ubicación: Caracas
Mensajes: 12.120
Antigüedad: 15 años, 9 meses
Puntos: 1532
Respuesta: Ordenando Repositories en Doctrine y otras dudas doctrine

En doctrine2 la lógica de negocios (modelo) recae en los repositorios, mientras la entidad se utiliza para mapear las instancias de los registros, lo que se llama lógica de registro, en pocas palabras en la entidad solo defines métodos que afecten ese registro, como por ejemplo un getNombreCompleto donde en una entidad persona concatenas getNombre y getApellido, mientras que en el repositorio defines métodos que afecten a n registros como getPersonaMayor, donde haces un dql interno para extraer las mayores de 18

Doctrine2 necesita el EntityManager, de otro modo ¿como mapeara las entidades? es el núcleo (core) de doctrine, sin el no funciona, si usas métodos estáticos en la entidad ¿para que el repositorio? No tiene sentido al igual si una entidad carece de repositorio para poder instanciar registros necesitas llamar al getReference del entityManager y estarías mezclando tu entidad con repositorio, al igual que el queryBuilder que necesita del entityManeger
__________________
¡Por favor!: usa el highlight para mostrar código
El que busca, encuentra...
  #4 (permalink)  
Antiguo 04/04/2012, 02:11
 
Fecha de Ingreso: enero-2012
Ubicación: España
Mensajes: 150
Antigüedad: 12 años, 2 meses
Puntos: 0
Respuesta: Ordenando Repositories en Doctrine y otras dudas doctrine

Cita:
Iniciado por GatorV Ver Mensaje
Para ordenar tienes que hacer uso del QueryBuilder: http://docs.doctrine-project.org/pro...y-builder.html y sí lo mejor es que sea en un custom repositorie.

Saludos.
Ok, gracias. Lo supuse pero no estaba seguro.

Cita:
Iniciado por maycolalvarez Ver Mensaje
En doctrine2 la lógica de negocios (modelo) recae en los repositorios, mientras la entidad se utiliza para mapear las instancias de los registros, lo que se llama lógica de registro, en pocas palabras en la entidad solo defines métodos que afecten ese registro, como por ejemplo un getNombreCompleto donde en una entidad persona concatenas getNombre y getApellido, mientras que en el repositorio defines métodos que afecten a n registros como getPersonaMayor, donde haces un dql interno para extraer las mayores de 18
Si, gracias por la aclaracion aunque esto mas o menos ya lo sabia. Pero a mi lo que se me ha pasado por la cabeza es, si haces un modelo por tabla mas o menos en un proyecto sencillo, por que no hacer metodos estaticos que no necesites instanciar cada modelo. Un ejemplo:

Código PHP:
class ProductoModelo{

    public static function 
findAll(){
        
$em Registry::get('em'); // cogemos el entity manager del registro.
        
return $em->getRepository('Entidades\producto')->findAll();
    }
    public static function 
findBy$var ){
        
$em Registry::get('em'); // cogemos el entity manager del registro.
        
return $em->getRepository('Entidades\producto')->findby$var );
    }


Cogemos el Entity Manager del registro, que ya lo habiamos inicializado y guardado en el bootstrap de nuestra aplicacion, que evidentemente se ejecuta en cada llamada al navegador.

Yo veo factible el hacer esto que estoy preguntando, pero me gustaria saber si alguien mas entendido sabe si es de verdad buena practica o tiene sus contras.

Cita:
Iniciado por maycolalvarez Ver Mensaje
Doctrine2 necesita el EntityManager, de otro modo ¿como mapeara las entidades? es el núcleo (core) de doctrine, sin el no funciona, si usas métodos estáticos en la entidad ¿para que el repositorio? No tiene sentido al igual si una entidad carece de repositorio para poder instanciar registros necesitas llamar al getReference del entityManager y estarías mezclando tu entidad con repositorio, al igual que el queryBuilder que necesita del entityManeger
"¿ instanciar el Entity manager, guardarlo en el registry y que cada vez que en el codigo un modelo necesite hacer uso de ello, coja la instancia y la use o hacer que cada modelo cargue el Entity manager en su constructor por ejemplo ?"

Ya se que necesitas del Entity Manager tanto para hacer uso de las entidades, como de los repository, etc.
Pero lo que yo digo es, si en una unica ejecucion en tu aplicacion web tu haces varias consultas a la base de datos, es decir, varios usos de entidades y repositorios, ¿ que es mejor practica ?
- ¿ En cada uso de entidad o repositorio que necesitas el EM, instancias un nuevo EM con el lanzador de doctrine ?
- ¿ O es mejor instanciar el EM en el bootstrap de tu aplicacion y guardarlo en el registro, y recuperarlo de este cada vez que en una unica ejecucion lo necesitas ?

Espero haberme explicado.

Un saludo.

Última edición por chemajmb; 04/04/2012 a las 02:17
  #5 (permalink)  
Antiguo 04/04/2012, 04:24
Avatar de masterpuppet
Software Craftsman
 
Fecha de Ingreso: enero-2008
Ubicación: Montevideo, Uruguay
Mensajes: 3.550
Antigüedad: 16 años, 3 meses
Puntos: 845
Respuesta: Ordenando Repositories en Doctrine y otras dudas doctrine

Para ordenar puedes "setear" un order por defecto por medio de @OrderBy, lo puedes hacer en el DQL o como te comenta GatorV utilizar el QueryBuilder.

Cita:
Yo veo factible el hacer esto que estoy preguntando, pero me gustaria saber si alguien mas entendido sabe si es de verdad buena practica o tiene sus contras.
Para mi es una mala practica, un registro global es un tipo de variable global deberías en lo posible evitarlo, preferible pasar las dependencias e instanciar y si estas utilizando una herramienta como doctrine realmente te parece que puedes ganar algo evitando un new ?

Cita:
- ¿ En cada uso de entidad o repositorio que necesitas el EM, instancias un nuevo EM con el lanzador de doctrine ?
- ¿ O es mejor instanciar el EM en el bootstrap de tu aplicacion y guardarlo en el registro, y recuperarlo de este cada vez que en una unica ejecucion lo necesitas ?
Utiliza el mismo em, no tiene sentido instanciar varias veces un em con la misma configuración, diferentes em se utilizan para mapear datos a diferentes bbdd.

Te dejo un pequeño ejemplo de como se suele utilizar con managers para que te hagas una idea http://pastebin.com/VhCLMK5J

Saludos.
__________________
http://es.phptherightway.com/
thats us riders :)
  #6 (permalink)  
Antiguo 04/04/2012, 08:05
 
Fecha de Ingreso: enero-2012
Ubicación: España
Mensajes: 150
Antigüedad: 12 años, 2 meses
Puntos: 0
Respuesta: Ordenando Repositories en Doctrine y otras dudas doctrine

A ver,

A lo que me refiero con instanciar varias veces el em es a que por ejemplo en este codigo se instancian varias veces el em, tantas veces como veces usas un manejador en tu ejemplo.
Código PHP:
namespace Application/Controller;
 
class 
ProductController extends Controller
{
    public function 
showAction()
    {
        
//DiC container, encargado de ensamblar el manager inyectando las dependencias
        
$product $this->get('product_manager')->findOneBy('slug''my-custom-product');
        
$category $this->get('category_manager')->findAll();
        return array(
'product' => $product'category' => $category);
    }

me imagino que $this->get('X_manager') es un metodo de los controladores tipo un autoload, para cargar/instanciar un manager especifico que le pasas como parametro. Asi que devuelve una instancia del manager que le pasas como parametro. Para instanciar el manager en el metodo get, debes de instanciar antes el EM puesto que es parametro obligatorio del constructor del manejador.
Entonces tanto en
$product = $this->get('product_manager') como en
$category = $this->get('category_manager')
instancias 2 veces, una en cada, el entity manager aunque lo hagas con el mismo bootstrap.
¿ o como se hace ?
¿ Voy bien o me pierdo ? heheehe :)

---

Viendo ese ejemplo me surgen otras dudas/preguntas:
1º.-
¿ Las interfaces simplemente se hacen para poder ver rapidamente que metodos se han implementado de un manejador ?
¿ O cual es el por que de su existencia en este ejemplo ?
Ya se que definen comportamientos y tal, se lo que son las interfaces pero quiero tenerlo mas claro.

2º.-
Código PHP:
namespace Application/Entity;
 
use 
Application/Model/ProductManagerInterface;
 
class 
ProductManager implements ProductManagerInterface
... 
¿ Esta bien tener los manejadores en la misma carpeta que las entidades ?
¿ o las entidades las tiene en namespace Application\Entity\Entities; ?

3º.-
Tengo que leer acerca del uso de namespace y use por que no lo tengo claro, lo comprendo, pero no se como aplicarlo bien realmente, ni que pros tiene el usarlo.
Voy a echar un vistazo, pero si podeis darme una pequeña explicacion os estaria agradecido.

Un saludo.
Gracias por vuestros comentarios y vuestra ayuda de verdad.

Última edición por chemajmb; 04/04/2012 a las 08:18
  #7 (permalink)  
Antiguo 04/04/2012, 11:05
Avatar de masterpuppet
Software Craftsman
 
Fecha de Ingreso: enero-2008
Ubicación: Montevideo, Uruguay
Mensajes: 3.550
Antigüedad: 16 años, 3 meses
Puntos: 845
Respuesta: Ordenando Repositories en Doctrine y otras dudas doctrine

En realidad no, los dos managers comparten el mismo EntityManager, deberías leer sobre DI http://fabien.potencier.org/article/...ency-injection y acá tienes un DiC extremadamente sencillo pero funcional https://github.com/fabpot/Pimple que puedes integrar rápidamente.

Con respecto al resto de preguntas:
  1. No deberías preocuparte no es mas que un ejemplo y la fuerza de la costumbre :P.
  2. Es a gusto del consumidor, también podrías tener una carpeta Manager y dentro definir los managers, es un tema de preferencias.
  3. Te sugiero que te des una vuelta por la doc de php y googles un poco hay mucha info al respecto, te dejo una referencia http://www.phparch.com/2010/03/namespaces-in-php/
__________________
http://es.phptherightway.com/
thats us riders :)
  #8 (permalink)  
Antiguo 04/04/2012, 16:31
 
Fecha de Ingreso: enero-2012
Ubicación: España
Mensajes: 150
Antigüedad: 12 años, 2 meses
Puntos: 0
Respuesta: Ordenando Repositories en Doctrine y otras dudas doctrine

Cita:
Iniciado por masterpuppet Ver Mensaje
...
Para mi es una mala practica, un registro global es un tipo de variable global deberías en lo posible evitarlo, preferible pasar las dependencias e instanciar
...
¿ Que diferencias hay entre la clase Registry y el Pimple este ?
Por que para mi que es lo mismo.

Es que no se, me has dejado un poco liado, por que en principio me dices que no utilizar la clase registry para guardar la instancia del EM y luego cogerla de ahi siempre que la necesite en una ejecucion. Y ahora me dices esto del Pimple que para mi entender es lo mismo.

¿ Podria tambien hacer el lanzador de Doctrine para instanciar el EM utilizando el patron SINGELTON ?

No se, decirme la manera mas comun y elegante de hacerlo y lo hare de esa manera, sin mas.


Mañana le echo un vistazo al dependency injection.

Gracias por los tips, buenas noches. un saludo.
  #9 (permalink)  
Antiguo 04/04/2012, 17:27
Avatar de masterpuppet
Software Craftsman
 
Fecha de Ingreso: enero-2008
Ubicación: Montevideo, Uruguay
Mensajes: 3.550
Antigüedad: 16 años, 3 meses
Puntos: 845
Respuesta: Ordenando Repositories en Doctrine y otras dudas doctrine

A ver, son dos formas de hacer lo mismo, la forma correcta y elegante es utilizar DI, lo mas sencillo es utilizar Registry.

Te propuse Pimple porque es una clase bien sencilla y te puede servir de reemplazo para tu Registry con unos pocos cambios:

Creas el container con las dependencias
Código PHP:
Ver original
  1. class Container extends Pimple
  2. {
  3.     public function __construct()
  4.     {
  5.         $this['product_class']  = 'Application\Entity\Product';
  6.         $this['category_class'] = 'Application\Entity\Category';
  7.         $this['entity_manager'] = $container->share(function ($c) {
  8.             return EntityManager::create($c['db_params'], $c['entity_manager_config']);
  9.         });
  10.         $this['product_manager'] = $container->share(function ($c) {
  11.             return new ProductManager($c['entity_manager'], $c['product_class']);
  12.         });
  13.         $this['category_manager'] = $container->share(function ($c) {
  14.             return new CategoryManager($c['entity_manager'], $c['category_class']);
  15.         });
  16.     }
  17. }

Reemplazas tu Registry por el Container
Código PHP:
Ver original
  1. ...
  2. $container   = new Container();
  3. $controlador = new $controlador($peticion, $container);
  4. ...

Utilizas el DiC
Código PHP:
Ver original
  1. public function index()
  2. {
  3.      $products = $this->container->get('product_manager')->findAll();
  4. }

de todas formas si te lía quédate con el Registry, no es lo mas limpio pero te va a funcionar, la idea es que veas las opciones que tienes tu luego utilizas lo que creas mas conveniente.

Con respecto a Singleton, tiene los mismos vicios de Registry y mas, puedes buscar en el foro o googlear que hay bastante material sobre el tema.

Cita:
Mañana le echo un vistazo al dependency injection.
Échale un ojo al link que te deje en el post anterior, es simple y claro.

Saludos.
__________________
http://es.phptherightway.com/
thats us riders :)
  #10 (permalink)  
Antiguo 06/04/2012, 04:26
 
Fecha de Ingreso: enero-2012
Ubicación: España
Mensajes: 150
Antigüedad: 12 años, 2 meses
Puntos: 0
Respuesta: Ordenando Repositories en Doctrine y otras dudas doctrine

Buenas,

A ver, varias cosas:
1º.- He hecho un metodo en los controladores para escribir menos codigos en las llamadas al contenedor.
Código PHP:
protected function get($nombre)
    {
        return 
$this->_contenedor->get($nombre);
    } 
Asi en los controladores puedo hacer llamadas como en el ejemplo
$product = $this->get('product_manager')->findOneBy('slug', 'my-custom-product');
en vez de
$product = $this->_container->get('product_manager')->findOneBy('slug', 'my-custom-product');
Bien, esto es sencillo y una tonteria. Pero lo comento por si acaso.

2º.-
Ahora vamos con algo mas interesante:
Antes ejecutaba el lanzador de doctrine y guardaba el em por algun sitio. Ahora que el em lo tengo guardado/definido en el contenedor. Me gustaria saber exactamente como tengo que ejecutar el lanzador de doctrine.
Mi clase contenedor
Código PHP:
Ver original
  1. <?php
  2. require_once DIR_LIBRERIAS_PRINCIPAL . 'pimple' . DS . 'Pimple.php';
  3. require_once DIR_MODELOS . 'manejadores' . DS . 'categoriaManejador.php';
  4.  
  5. class Contenedor extends Pimple
  6. {
  7.     public function __construct()
  8.     {
  9.         $this['parametros_bd'] = array( 'driver' => 'pdo_mysql',
  10.                                         'user' => DB_USER,
  11.                                         'password' => DB_PASS,
  12.                                         'dbname' => DB_NAME );
  13.         $this['manejador_entidad_config'] = \Doctrine\ORM\Tools\Setup::createAnnotationMetadataConfiguration( array( DIR_ENTIDADES ), true);
  14.         $this['clase_producto'] = 'entidades\producto';
  15.         $this['clase_categoria'] = 'entidades\categoria';
  16.         $this['manejador_entidad'] = $this->share(function ($c) {
  17.             return \Doctrine\ORM\EntityManager::create($c['parametros_bd'], $c['manejador_entidad_config']);
  18.         });
  19.         $this['manejador_producto'] = $this->share(function ($c) {
  20.             return new productoManejador($c['manejador_entidad'], $c['clase_producto']);
  21.         });
  22.         $this['manejador_categoria'] = $this->share(function ($c) {
  23.             return new categoriaManejador($c['manejador_entidad'], $c['clase_categoria']);
  24.         });
  25.     }
  26. }
  27. ?>

He escrito un poco mas de lo que tu me pusiste masterpuppet y me han surgido unas dudas:
¿ Como queda mi DoctrineBootstrap ahora ?
Antes lo tenia asi:
Código PHP:
Ver original
  1. <?php
  2.     function DoctrineLanzador(){
  3.    
  4.         require_once 'Doctrine/Common/ClassLoader.php';
  5.         $loader = new \Doctrine\Common\ClassLoader("Doctrine");
  6.         $loader->register();
  7.        
  8.         $classLoader = new \Doctrine\Common\ClassLoader('Entidades', DIR_MODELOS );
  9.         $classLoader->register();
  10.        
  11.         $dbParams = array(
  12.             'driver' => 'pdo_mysql',
  13.             'user' => DB_USER,
  14.             'password' => DB_PASS,
  15.             'dbname' => DB_NAME
  16.         );
  17.         $path = array( DIR_ENTIDADES );
  18.         $config = \Doctrine\ORM\Tools\Setup::createAnnotationMetadataConfiguration($path, true);
  19.        
  20.         $em = \Doctrine\ORM\EntityManager::create($dbParams, $config);
  21.  
  22.         return $em;
  23.     }
  24.  
  25. ?>

Ahora introdujendo la clase contenedor ¿ deberia dejarlo asi ?
Código PHP:
Ver original
  1. <?php
  2.     function DoctrineLanzador(){
  3.    
  4.         require_once 'Doctrine/Common/ClassLoader.php';
  5.         $loader = new \Doctrine\Common\ClassLoader("Doctrine");
  6.         $loader->register();
  7.        
  8.         $classLoader = new \Doctrine\Common\ClassLoader('Entidades', DIR_MODELOS );
  9.         $classLoader->register();
  10.        
  11.     }
  12.  
  13. ?>

Y ¿ deberia en el bootstrap de mi aplicacion ejecutar doctrinelanzador y luego instanciar el contenedor y guardarlo en el controlador que ejecute ?
Código PHP:
Ver original
  1. ...
  2. DoctrineLanzador();
  3. $container   = new Container();
  4. $controlador = new $controlador($peticion, $container);
  5. ...

Última edición por chemajmb; 06/04/2012 a las 12:01
  #11 (permalink)  
Antiguo 07/04/2012, 05:28
Avatar de masterpuppet
Software Craftsman
 
Fecha de Ingreso: enero-2008
Ubicación: Montevideo, Uruguay
Mensajes: 3.550
Antigüedad: 16 años, 3 meses
Puntos: 845
Respuesta: Ordenando Repositories en Doctrine y otras dudas doctrine

1)
2) Con las modificaciones lo que necesitas es solo el autoloader, así que esta bien, aunque recuerda que estas en OOP, que hace esa funcion suelta ahí ?, podría ser algo asi:

Código PHP:
Ver original
  1. Autoloader::registerNamespaces(array('Doctrine', array('Entity' => ENTITY_PATH)));

Con respecto al container, al menos en tu fw según la estructura que recuerdo creo que debería ser exactamente como lo tienes.

Saludos.
__________________
http://es.phptherightway.com/
thats us riders :)
  #12 (permalink)  
Antiguo 07/04/2012, 09:17
 
Fecha de Ingreso: enero-2012
Ubicación: España
Mensajes: 150
Antigüedad: 12 años, 2 meses
Puntos: 0
Respuesta: Ordenando Repositories en Doctrine y otras dudas doctrine

Jejeje, muchas gracias por la ayuda campeon!!

Al final mi lanzador de doctrine ha quedado asi:
Código PHP:
Ver original
  1. <?php
  2.  
  3.     require_once 'Doctrine/Common/ClassLoader.php';
  4.     $loader = new \Doctrine\Common\ClassLoader("Doctrine");
  5.     $loader->register();
  6.    
  7.     $loader = new \Doctrine\Common\ClassLoader('Entidad', DIR_RAIZ . 'modelos' );
  8.     $loader->register();
  9.    
  10.     $loader = new \Doctrine\Common\ClassLoader('Repositorio', DIR_RAIZ . 'modelos');
  11.     $loader->register();
  12.  
  13. ?>
Lo ejecuto en mi lanzador de la aplicacion:
Código PHP:
...
        require_once 
DIR_APLICACION_PRINCIPAL 'Contenedor.php';
        require_once 
DIR_APLICACION_PRINCIPAL 'DoctrineLanzador.php';
        
        
Lanzador::run(new Peticion, new Contenedor);
... 
Y las carpetas las he organizado en modelos:
Código:
mi proyecto
    aplicacion
    librerias
    modelos
        entidad
        manejadores
        repositorio
    privada
        aplicacion
        controladores
        librerias
        publico
            css
            html
            img
            js
        vistas
    publica
        aplicacion
        controladores
        librerias
        publico
            css
            html
            img
            js
        vistas
Privada y publica son los modulos, estoy haciendo una tienda virtual con parte de gestion y parte publica.



Me ha funcionado a la primera por lo cual estoy bastante contento, pero cuando me he puesto con los repositorios, me sale un error. A ver si sabes que puede ser
Código PHP:
Ver original
  1. <?php
  2. namespace Repositorio;
  3.  
  4. use Doctrine\ORM\EntityRepository;
  5.  
  6. class categoriaRepositorio extends EntityRepository
  7. {
  8.     public function findPrincipales()
  9.     {
  10.         $query = $this->_em->createQuery('SELECT c FROM Entidad\Categoria c WHERE c.padrecategoria = null');
  11.         return $query->getResult();
  12.     }    
  13. }
  14.  
  15. ?>
La clase manejador
Código PHP:
Ver original
  1. <?php
  2. require_once 'claseManejador.php';
  3.  
  4. class categoriaManejador extends claseManejador
  5. {
  6.     protected $em;
  7.     protected $class;
  8.     protected $repository;    
  9.      
  10.     public function __construct(\Doctrine\ORM\EntityManager $em, $class)
  11.     {
  12.         parent::__construct($em,$class);
  13.     }
  14.  
  15.     public function findDeletedCategorias()
  16.     {
  17.         return $this->getRepository()->findDeletedCategorias();
  18.     }
  19.    
  20.     public function findPrincipales()
  21.     {
  22.         return $this->getRepository()->findPrincipales();
  23.     }
  24.    
  25. }
  26. ?>
Extiende esta otra clase manejador principal:
Código PHP:
Ver original
  1. <?php
  2. class claseManejador
  3. {
  4.     protected $_em;
  5.     protected $_class;
  6.     protected $_repository;    
  7.      
  8.     public function __construct(\Doctrine\ORM\EntityManager $em, $class)
  9.     {
  10.         $this->_em = $em;
  11.         $this->_class = $class;
  12.     }
  13.     public function findAll($field = null, $value = null)
  14.     {
  15.         return $this->getRepository()->findAll($field, $value);
  16.     }
  17.     public function findOneBy($field, $value)
  18.     {
  19.         return $this->getRepository()->findOneBy($field, $value);
  20.     }
  21.  
  22.     public function getRepository()
  23.     {
  24.         return $this->_em->getRepository($this->_class);
  25.     }
  26. }
  27. ?>

El error que me da es este:
Código:
[Syntax Error] line 0, col 59: Error: Expected Literal, got 'null'
¿ Como puedo investigar o analizar mas profunda o detalladamente los errores ?

Un saludo.

Última edición por chemajmb; 07/04/2012 a las 09:57
  #13 (permalink)  
Antiguo 07/04/2012, 10:35
Avatar de masterpuppet
Software Craftsman
 
Fecha de Ingreso: enero-2008
Ubicación: Montevideo, Uruguay
Mensajes: 3.550
Antigüedad: 16 años, 3 meses
Puntos: 845
Respuesta: Ordenando Repositories en Doctrine y otras dudas doctrine

Recuerda que es DQL no SQL, para comprobar si un valor es nulo debes utilizar IS NULL

Código DQL:
Ver original
  1. SELECT c FROM Category c WHERE c.parent IS NULL

http://docs.doctrine-project.org/pro...-language.html
__________________
http://es.phptherightway.com/
thats us riders :)

Última edición por masterpuppet; 07/04/2012 a las 11:40 Razón: Links
  #14 (permalink)  
Antiguo 07/04/2012, 16:00
 
Fecha de Ingreso: enero-2012
Ubicación: España
Mensajes: 150
Antigüedad: 12 años, 2 meses
Puntos: 0
Respuesta: Ordenando Repositories en Doctrine y otras dudas doctrine

Ok, es que como no controlo aun, supuse que seria "= null" por un ejemplo que vi, pero ya veo que es "IS NULL". Tengo que aprender de DQL.

Ya me ha funcionado a la perfeccion y te estoy muy agradecido.


Me da verguenza preguntar esto, pero no encuentro la biblioteca con la informacion acerca de las funciones findAll, findBy, findOneby, cuantos parametros admiten y como son esos parametros.

He encontrado lo que estaba buscando en el propio codigo pero necesito saber mas informacion acerca del tipo de datos de los parametros
Código PHP:
Ver original
  1. public function findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
  2.     {
  3.         return $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->loadAll($criteria, $orderBy, $limit, $offset);
  4.     }
¿ donde puedo encontrarlo ?



A ver, una pregunta al menos para mi con peso.
Tengo el siguiente dilema.
Me traigo un repositorio de mi entidad CATEGORIA, esta entidad tiene una relacion con la categoria padre.
Asi bien el objeto de la entidad categoria consta de varios tipo de objetos simples como el nombre, descripcion... y otro tipo de objetos compuesto que es la categoria padre.
Cuando en la vista muestro los datos de cada categoria cuando me traigo todas las categorias con findAll, lo hago de la sigueinte forma
un bucle para recorrer el repositorio y en cada posicion
echo $categoria->nombre
echo $categoria->descripcion
echo $categoria->visible
echo $categoria->padrecategoria->nombre

Entonces claro, ahora queria traerme las categorias de la tabla de categorias ordenadas por diferentes campos.
Lo he intentado con la funcion findby
$this->_vista->categorias = $this->get('manejador_categoria')->findby( array(), array('padrecategoria' => 'ASC' );
he probado con varios campos y funciona, excepto con padrecategoria, y es evidente, pues este es una relacion, es un objeto.
Mi pregunta es, para ordenarlo por este campo ¿ debo de crear una consulta en el repositorio trayendome los campos necesarios para ordenar ?
Es decir, traerme el nombre de la categoria padre y el resto de campos de la categoria para luego asi poder ordenar por el campo del nombre de la categoria padre.

Creo que es asi y tiene bastante logica, pero como no estoy seguro, estoy empezando, no controlo mucho tampoco de sql, evidentemente tampoco de dql, preferia preguntar, para no perder tiempo intentando algo que no se puede hacer asi o se hace de otra manera.

Ok arreglado, juan palomo, yo me lo guiso, yo me lo como.

Código PHP:
Ver original
  1. public function findprueba(){
  2.         $query = $this->_em->createQuery('SELECT c FROM Entidad\Categoria c JOIN c.padrecategoria p ORDER BY p.nombre ASC');
  3.         return $query->getResult();
  4.     }

Última edición por chemajmb; 08/04/2012 a las 02:09
  #15 (permalink)  
Antiguo 08/04/2012, 08:05
Avatar de masterpuppet
Software Craftsman
 
Fecha de Ingreso: enero-2008
Ubicación: Montevideo, Uruguay
Mensajes: 3.550
Antigüedad: 16 años, 3 meses
Puntos: 845
Respuesta: Ordenando Repositories en Doctrine y otras dudas doctrine

Te dejo la referencia a los finders http://readthedocs.org/docs/doctrine...ple-conditions y efectivamente cuando lo que quieres es mas complejo debes utilizar DQL o el QueryBuilder.
Y te hago una sugerencia, si bien en el ejemplo que utilizas el UoW(Unit of Work) es solo para lectura, no deberías meterte con el a menos que sepas realmente que estas haciendo, el UoW es e el encargado de llevar el tracking de los cambios, un error en el puede llevar a inconsistencias.

Saludos.
__________________
http://es.phptherightway.com/
thats us riders :)
  #16 (permalink)  
Antiguo 08/04/2012, 08:25
 
Fecha de Ingreso: enero-2012
Ubicación: España
Mensajes: 150
Antigüedad: 12 años, 2 meses
Puntos: 0
Respuesta: Ordenando Repositories en Doctrine y otras dudas doctrine

Cita:
Iniciado por masterpuppet Ver Mensaje
Te dejo la referencia a los finders http://readthedocs.org/docs/doctrine...ple-conditions y efectivamente cuando lo que quieres es mas complejo debes utilizar DQL o el QueryBuilder.
Y te hago una sugerencia, si bien en el ejemplo que utilizas el UoW(Unit of Work) es solo para lectura, no deberías meterte con el a menos que sepas realmente que estas haciendo, el UoW es e el encargado de llevar el tracking de los cambios, un error en el puede llevar a inconsistencias.

Saludos.
Gracias.

No no masterpuppet, si el codigo que puse es el metodo "findBy" real de la clase EntityRepository real.
Gracias de todas formas por estar tan atento y aconsejar.
Código PHP:
Ver original
  1. public function findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
  2. * * {
  3. * * * * return $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->loadAll($criteria, $orderBy, $limit, $offset);
  4. * * }

A ver, ahora tengo otro dilema, un amigo mio me dijo que el lo que haces es PROCEDIMIENTOS ALMACENADOS en MySql y luego los llama desde el lenguaje que este utilizando.
¿ Cual es mejor tecnica ?
¿ Implementar ( complejo ) en php cada consulta o hacer llamadas ( mas simples ) a cada procedimiento almacenado ?

Última edición por chemajmb; 09/04/2012 a las 02:59
  #17 (permalink)  
Antiguo 09/04/2012, 07:54
 
Fecha de Ingreso: enero-2012
Ubicación: España
Mensajes: 150
Antigüedad: 12 años, 2 meses
Puntos: 0
Respuesta: Ordenando Repositories en Doctrine y otras dudas doctrine

Buenas a todos,

Tengo algunos problemillas trabajando con Doctrine 2 y quiero pedir consejo.
El problema que tengo es que quiero ordenar un repositorio de entidades por un campo de una relacion.
Me explico mejor:
En la parte de gestion de mi proyecto tengo la parte de administracion de categorias de la tienda online.
Ahi hago un listado de categorias donde muestro varios campos:
padrecategoria->nombre, nombre, urlrelativa, descripcion, visible
Como podeis ver muestro el nombre de la categoria padre a traves de la relacion.

Ordenar por nombre, urlrelativa, descripcion o visible no es problema,
Código PHP:
public function findprueba(){
        
$query $this->_em->createQuery("SELECT c FROM Entidad\Categoria c WHERE c.id > 1 ORDER BY c.nombre ASC");
        return 
$query->getResult();
    } 
pero cuando quiero ordenar por el nombre de la categoria padre. La consulta se complica un poco mas. ( Tambien se puede hacer con un join )
Código PHP:
public function findprueba(){
        
$query $this->_em->createQuery("SELECT c FROM Entidad\Categoria c, Entidad\Categoria p WHERE c.id > 1 AND c.padrecategoria = p ORDER BY p.nombre ASC");
        return 
$query->getResult();
    } 
Ambas funciones me devuelven un vector de objetos entidad categoria.
Ahora bien me surgen varias preguntas relacionadas entre si.
1º.- ¿ Deberia devolver un vector de objetos mas simples en vez de un vector de entidades que es un tipo de datos mas pesado ?
Código PHP:
public function dameTodas(){
        
$query $this->_em->createQuery"SELECT p.nombre AS padrecategoria, c.nombre, c.urlrelativa, c.descripcion, c.visible FROM Entidad\Categoria c, Entidad\Categoria p
                                            WHERE c.padrecategoria = p AND c.id > 1 AND c.activo = 1
                                            ORDER BY p.nombre DESC, c.visible DESC" 
);
        return 
arrayToObject($query->getResult());
    } 
Código:
object(stdClass)[144]
  
    object(stdClass)[92]
      public 'padrecategoria' => string 'Sección Roedores' (length=17)
      public 'nombre' => string 'Pipas de calabaza' (length=17)
      public 'urlrelativa' => string 'pipas-calabaza' (length=14)
      public 'descripcion' => null
      public 'visible' => boolean false
  
    object(stdClass)[142]
      public 'padrecategoria' => string 'Sección Reptiles' (length=17)
      public 'nombre' => string 'Escamas' (length=7)
      public 'urlrelativa' => string 'asdas' (length=5)
      public 'descripcion' => string 'asdas' (length=5)
      public 'visible' => boolean true
...
o asi
Código PHP:
public function damePrincipales(){
        
$query $this->_em->createQuery("SELECT c FROM Entidad\Categoria c, Entidad\Categoria p
                                            WHERE c.padrecategoria = p AND c.id > 1 AND c.activo = 1 AND p.id = 1
                                            ORDER BY p.nombre ASC"
);
        return 
$query->getresult();
    } 
Código:
array
  0 => 
    object(Entidad\Categoria)[141]
      public 'id' => int 2
      public 'padrecategoria' => 
        object(DoctrineProxies\__CG__\Entidad\Categoria)[99]
          private '_entityPersister' => 
            object(Doctrine\ORM\Persisters\BasicEntityPersister)[93]
              ...
          private '_identifier' => 
            array
              ...
          public '__isInitialized__' => boolean false
          public 'id' => null
          public 'padrecategoria' => null
          public 'hijocategorias' => 
            object(Entidad\Categoria)[176]
              ...
          public 'productos' => null
          public 'nombre' => null
          public 'urlrelativa' => null
          public 'descripcion' => null
          public 'visible' => null
          public 'activo' => null
      public 'hijocategorias' => 
        object(Doctrine\ORM\PersistentCollection)[150]
          private 'snapshot' => 
            array
              ...
          private 'owner' => 
            &object(Entidad\Categoria)[141]
          private 'association' => 
            array
              ...
          private 'em' => 
            object(Doctrine\ORM\EntityManager)[48]
              ...
          private 'backRefFieldName' => string 'padrecategoria' (length=14)
          private 'typeClass' => 
            object(Doctrine\ORM\Mapping\ClassMetadata)[103]
              ...
          private 'isDirty' => boolean false
          private 'initialized' => boolean false
          private 'coll' => 
            object(Doctrine\Common\Collections\ArrayCollection)[153]
              ...
      public 'productos' => 
        object(Doctrine\ORM\PersistentCollection)[137]
          private 'snapshot' => 
            array
              ...
          private 'owner' => 
            &object(Entidad\Categoria)[141]
          private 'association' => 
            array
              ...
          private 'em' => 
            object(Doctrine\ORM\EntityManager)[48]
              ...
          private 'backRefFieldName' => string 'categoria' (length=9)
          private 'typeClass' => 
            object(Doctrine\ORM\Mapping\ClassMetadata)[152]
              ...
          private 'isDirty' => boolean false
          private 'initialized' => boolean false
          private 'coll' => 
            object(Doctrine\Common\Collections\ArrayCollection)[136]
              ...
      public 'nombre' => string 'Sección Perros' (length=15)
      public 'urlrelativa' => string 'perros' (length=6)
      public 'descripcion' => string 'AquÃ* puedes encontrar todo lo relacionado con el mundo de los perros.' (length=70)
      public 'visible' => boolean false
      public 'activo' => boolean true
  1 => 
...
2º.- ¿ Que es mejor ? ¿ hacer la consulta con order by para traerte los datos ordenados o ordenar los datos una vez te los has traido ?
Claro, yo queria hacer una funcion dameOrdenadoPor( $orderby ) a la cual le paso un parametro para ordenar, pero como hemos visto, cuando tengo que ordenar por una relacion, la consulta se complica y transformar el paso de parametros a consulta también.
No es lo mismo pasar un array ( 'nombre' , 'DESC' ) para ordenar por el campo nombre, que tener que organizar por el campo nombre de la relacion con la categoria padre "padrecategoria". Hacer la consulta a partir del parametro en este caso es mas complicado, ademas la consulta cambia bastante.
Es por eso que quiero saber como se hace, consejos, pros y contras. Por que yo soy novato en esto pero estoy seguro que alguien sabra decirme como se suelen hacer estas cosas.

Un saludo.

Última edición por chemajmb; 09/04/2012 a las 11:48
  #18 (permalink)  
Antiguo 09/04/2012, 20:53
Avatar de masterpuppet
Software Craftsman
 
Fecha de Ingreso: enero-2008
Ubicación: Montevideo, Uruguay
Mensajes: 3.550
Antigüedad: 16 años, 3 meses
Puntos: 845
Respuesta: Ordenando Repositories en Doctrine y otras dudas doctrine

1) Depende, si no hay lógica alguna y el proceso es solo de lectura preferible hidratar arrays, es tan sencillo como:

Código PHP:
Ver original
  1. $query->getArrayResult();

2) Lo ideal es traerlos ordenados, pero todo depende, si son pocos datos el costo de ordenar es mínimo.

Saludos.
__________________
http://es.phptherightway.com/
thats us riders :)
  #19 (permalink)  
Antiguo 11/04/2012, 16:41
 
Fecha de Ingreso: enero-2012
Ubicación: España
Mensajes: 150
Antigüedad: 12 años, 2 meses
Puntos: 0
Respuesta: Ordenando Repositories en Doctrine y otras dudas doctrine

Busco buenas ideas

Estoy haciendo este proyecto

En el formulario cojo los filtros para el listado de la tabla y me gustaria saber como hacer el metodo para conseguir el repositorio con el que luego creo la tabla. Me refiero a si puedo hacer el metodo mas sencillo que como yo lo he hecho, mas reducido de codigo, de otra forma

Fijarse solamente en el metodo dameOrdenadoPor
Código PHP:
Ver original
  1. <?php
  2. namespace Repositorio;
  3.  
  4. use Doctrine\ORM\EntityRepository;
  5.  
  6. class categoriaRepositorio extends EntityRepository{
  7.    
  8.     public function damePrincipales(){
  9.         $query = $this->_em->createQuery("SELECT c.id, c.nombre FROM Entidad\Categoria c, Entidad\Categoria p
  10.                                            WHERE c.categoriapadre = p AND c.activo = 1 AND p.id = 1
  11.                                            ORDER BY p.nombre ASC");
  12.         return arrayToObject($query->getResult());
  13.     }
  14.     public function dameOrdenadoPor(array $whereparam = null, array $orderbyparam = null ){
  15.         $where = '';
  16.         $orderby = '';
  17.         if ( isset($whereparam) && !empty($whereparam) && is_array($whereparam) ){
  18.             foreach( $whereparam AS $akey => $avalue){
  19.                 if ( !( $avalue === '' ) && !( $avalue === null ) ){
  20.                     if ( $akey == 'categoriapadre')
  21.                         $where .= " AND p.id = $avalue";
  22.                     else
  23.                         $where .= " AND c.$akey LIKE '$avalue'";
  24.                 }
  25.             }
  26.         }
  27.         if ( isset($orderbyparam) && !empty($orderbyparam) && is_array($orderbyparam) && ( count($orderbyparam) == 2 ) )
  28.             $orderby = "ORDER BY $orderbyparam[0] $orderbyparam[1]";
  29.         $query = $this->_em->createQuery( "SELECT p.nombre AS categoriapadre, c.id, c.nombre AS nombre, c.urlrelativa AS urlrelativa, c.descripcion AS descripcion, c.visible AS visible FROM Entidad\Categoria c, Entidad\Categoria p
  30.                                            WHERE c.categoriapadre = p AND c.id > 1 AND c.activo = 1$where
  31.                                            $orderby" );
  32.         //var_dump($query);
  33.         return arrayToObject($query->getResult());
  34.     }
  35.  
  36. }
  37.  
  38. ?>

Lo que quiero saber es como hacer metodos mas genericos que me sirvan para todos mis repositorios para transformar los parametros del $whereparam que le paso al metodo a la parte de la consulta de WHERE ... y lo mismo para el $orderby ORDER BY.
Me gustaria hacer metodos genéricos para transformar los parametros en sentencias string para el where y el order by de todos mis repositorios. Hacerlo en un repositorio base y que luego todos los repositorios desciendan de este y los hereden. Bueno, no se si se puede hacer, me gustaria alguien me aconsejara.
Tambien me gustaria
Pero fijaros en el dilema que me encuentro. Pues no es lo mismo filtrar por la categoria padre recogida en el formulario, que contiene la id de la relacion categoriapadre de la entidad. Es decir, no es lo mismo filtrar por categoriapadre->id que por el nombre de la categoria.
Código PHP:
Ver original
  1. if ( $akey == 'categoriapadre')
  2.                         $where .= " AND p.id = $avalue";
  3.                     else
  4.                         $where .= " AND c.$akey LIKE '$avalue'";

Creo que no podre simplificarlo ni hacerlo generico, pues en cada tabla puedo listar variados datos provenientes tanto de campos de relaciones con otras tablas, con lo que en cada repositorio de cada entidad tendre que implementarlo, pues va a depender siempre de lo que quiera en la tabla y eso como digo puede variar mucho.

La cosa es que estoy hecho un lio, y simplemente quiero mostrar como lo hago yo, para que la gente que lleva tiempo en esto, me de sus ideas de como suele hacer esto, pues yo acabo de empezar y seguro que hay gente que esto lo tiene trilladisimo, que le ha dado ya 400 mil vueltas.

Saludos.

Última edición por chemajmb; 11/04/2012 a las 16:51

Etiquetas: doctrine, dudas
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 11:17.