Este foro ya no está activo, así que no puedes publicar nuevas preguntas ni responder a las preguntas existentes.

Problema con getRoles, para conocer nombre del rol del usuario

24 de noviembre de 2015

Hola. Por favor una orientación.

Tengo dos tablas una que llamo usuarios y la otra rolesusuarios, la relación es de uno-a-uno. La llave primaria de roles se encuentra en usuarios para relacionar el tipo de rol de cada usuario.

He realizado toda la configuración de seguridad, todo funciona bien si hago lo siguiente, desde la clase Usuarios

function getRoles()
{
    return array('ROLE_USER');
}

Ahora mi consulta consiste en cómo puedo hacer para que en este método pueda obtener el nombre del tipo de rol que tiene el usuario, si este nombre se encuentra en la tabla rolesusuarios, se pude hacer esto o no se puede hacer ???.

Desde ya muy agradecido, por sus respuestas.


Respuestas

#1

Mi recomendación sería que pensaras si es absolutamente necesario guardar los roles en una tabla independiente. Si tienes miles de roles diferentes, entonces sí que tiene sentido. Si tienes unos pocos roles, no tiene sentido.

En este último caso, es mejor que guardes directamente los roles dentro de la entidad del usuario. Ten en cuenta que los roles son solo cadenas de texto que empiezan por ROLE_, así que no hay necesidad de complicarse.

Si tienes que guardar los roles en una tabla obligatoriamente, te recomiendo que leas este artículo que explica bien cómo hacerlo: Symfony2 Security: Creating dynamic roles (using RoleInterface)

@javiereguiluz

24 noviembre 2015, 21:56
#2

Hola Javier gracias por responder.

He estado trabajando en base a tu respuesta. Como lo que deseo es obtener de la tabla de roles el nombre del rol, debo de hacer una consulta esto lo tengo solventado. Si lo trabajo como servicio, todo funciona bien. El caso es que cuando lo invoco desde la Entity no me funciona, pues me indica que estoy tratando de llamar un método que no pertenece a la clase.

El problema que se me está presentado básicamente es porque no puedo obtener el EntityManager para poder ejecutar la consulta de búsqueda desde una clase que no se acceda como servicio.

Lo que tengo es lo de abajo, con esta clase se me presenta el error en esta línea $this->getDoctrine()->getManager():

namespace GestionUsuariosBundle\GestionUser;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
 
class UserSusRoles extends Controller
{
    private $elidrol, $elidusuario;
    private $entityManager;
 
   /* public function __construct(EntityManager $entityManager)
    {
 
        $this->entityManager = $entityManager;
 
    }*/
 
    public function getlosRoles($idusuar,$iddelrol)
    {
 
        $this->entityManager = $this->getDoctrine()->getManager();
 
         $this->elidrol=$iddelrol;
        $this->elidusuario=$idusuar;
 
        $dqlobtienedatos="select r.nombrerol from GestionUsuariosBundle\Entity\Usuarios u";
        $dqlobtienedatos.=" inner join u.idRol r where u.id=:iduser  and u.idRol=:idrol";
 
        $query = $this->entityManager->createQuery($dqlobtienedatos);
        $query->setParameter('iduser', $this->elidusuario);
        $query->setParameter('idrol', $this->elidrol);
        $xresultados=$query->getResult();
 
        foreach ($xresultados as $datox){
 
            foreach ($datox as $eldatox){
 
                $losdatos[]=$eldatox;
            }
        }
 
        return $losdatos;
    }

@BrandoSalamanTW

25 noviembre 2015, 22:43
#3

El problema de tu código es que estás extendiendo del controlador base (extends Controller) en una clase que no tiene nada que ver con un controlador. Además, con extender esa clase no es suficiente para tener acceso al contenedor de servicios, por eso te sale ese error. En realidad lo tienes que hacer así:

1) Código de tu clase UserSusRoles:

namespace GestionUsuariosBundle\GestionUser;
 
use Doctrine\ORM\EntityManager;
 
class UserSusRoles
{
    private $elidrol, $elidusuario;
    private $entityManager;
 
    public function __construct(EntityManager $entityManager)
    {
        $this->entityManager = $entityManager;
    }
 
    public function getlosRoles($idusuar, $iddelrol)
    {
        $this->entityManager = $this->getDoctrine()->getManager();
        $this->elidrol = $iddelrol;
        $this->elidusuario = $idusuar;
 
        $dqlobtienedatos = "select r.nombrerol from GestionUsuariosBundle\Entity\Usuarios u";
        $dqlobtienedatos .= " inner join u.idRol r where u.id=:iduser  and u.idRol=:idrol";
 
        $query = $this->entityManager->createQuery($dqlobtienedatos);
        $query->setParameter('iduser', $this->elidusuario);
        $query->setParameter('idrol', $this->elidrol);
        $xresultados=$query->getResult();
 
        foreach ($xresultados as $datox) {
            foreach ($datox as $eldatox) {
                $losdatos[] = $eldatox;
            }
        }
 
        return $losdatos;
    }
}

2) Define un servicio para poder usar tu clase en cualquier parte:

# app/config/services.yml
services:
    app.user_roles:
        class: GestionUsuariosBundle\GestionUser\UserSusRoles
        arguments: ['@doctrine.orm.entity_manager']

3) Usa tu clase por ejemplo en un controlador:

$roles = $this->get('app.user_roles')->getlosRoles('...', '...');

@javiereguiluz

26 noviembre 2015, 8:28
#4

Hola. Gracias Javier por tus respuestas, lo que me indicas ya lo había probando, pero el caso es que no pude invocar el servicio desde la clase pues me indicaba que estaba llamando un método que no pertenecía a la clase.

Lo otro erá que no quería crear un servicio para este caso, entonces en base a tu primera respuesta, logre encontrar una función para obtener el container desde cualquier clase https://gist.github.com/sebathomson/7e95119257802e5e4c54, gracias por compartir esto sebathomson.

Al final ha quedado así. La clase usuarios que contiene el método getRoles():

public function getRoles() {
        $losdatos = new \GestionUsuariosBundle\GestionUser\UserSusRoles();
 
        return $losdatos->getlosRoles($this->getId(), $this->getIdRol());
}

La clase UserSusRoles

<?php
 
namespace GestionUsuariosBundle\GestionUser;
 
class UserSusRoles  {
 
    private $elidrol, $elidusuario;
    private $entityManager;
 
    //Función compartida por sebathomson
//https://gist.github.com/sebathomson/7e95119257802e5e4c54,
    function obtenerContainer() {
        global $kernel;
        if ('AppCache' == get_class($kernel)) {
            $kernel = $kernel->getKernel();
        }
        return $kernel->getContainer();
    }
 
    public function getlosRoles($idusuar, $iddelrol) {
        $this->entityManager = $this->obtenerContainer();
 
        $this->elidrol = $iddelrol;
        $this->elidusuario = $idusuar;
 
        $dqlobtienedatos = "select r.nombrerol from GestionUsuariosBundle\Entity\Usuarios u";
        $dqlobtienedatos.=" inner join u.idRol r where u.id=:iduser  and u.idRol=:idrol";
 
        $query = $this->entityManager->get('doctrine')->getManager()->createQuery($dqlobtienedatos);
 
        $query->setParameter('iduser', $this->elidusuario);
        $query->setParameter('idrol', $this->elidrol);
 
        $xresultados = $query->getResult();
 
        foreach ($xresultados as $datox) {
 
            foreach ($datox as $eldatox) {
 
                $losdatos[] = $eldatox;
            }
        }
 
        return $losdatos;
    }
 
}

No se si es la solución más adecuada, pero soluciona el caso además que aprendí a obtener el container desde la clase que se desee.

Infinitas gracias por la ayuda Javier.

@BrandoSalamanTW

26 noviembre 2015, 17:35
#5

No es "la forma Symfony" de solucionarlo y podría llegar a darte problemas de rendimiento si ese método se usa mucho. Pero bueno, como solución temporal te puede servir.

Por cierto, si tienes dos minutos, me haría ilusión que votaras por mí en los premios de la comunidad Symfony: http://symfony.es/noticias/2015/11/25/anunciada-la-tercera-edicion-de-los-premios-symfony-community-business-awards/ ¡muchas gracias!

@javiereguiluz

26 noviembre 2015, 17:42
#6

Enterado un gusto poder hacerlo. Saludos.

@BrandoSalamanTW

27 noviembre 2015, 15:44