Symfony 多用户类

Symfony 多用户类,symfony,Symfony,我在一个系统中有4种不同的用户类型(在Symfony 2之上)。每种类型都有一些特定的字段和行为,但它们都有一个共同的基础。因此,为扩展同一超类的每个用户实现单个类似乎是个好主意 如何实现这一目标?我在这个主题上找到的只是一些RollerworksMultiUserBundle。在ORM级别使用表继承和OOP继承。如果性能非常关键(没有连接),或者您是一个纯粹主义者,那么请选择 例如 公共基类: use Symfony\Component\Security\Core\User\AdvancedU

我在一个系统中有4种不同的用户类型(在Symfony 2之上)。每种类型都有一些特定的字段和行为,但它们都有一个共同的基础。因此,为扩展同一超类的每个用户实现单个类似乎是个好主意


如何实现这一目标?我在这个主题上找到的只是一些RollerworksMultiUserBundle。

在ORM级别使用表继承和OOP继承。如果性能非常关键(没有连接),或者您是一个纯粹主义者,那么请选择

例如

公共基类:

use Symfony\Component\Security\Core\User\AdvancedUserInterface;

/**
  * @ORM\Entity(repositoryClass="Some\Bundle\Repository\UserRepository")
  * @ORM\InheritanceType("SINGLE_TABLE")
  * @ORM\DiscriminatorColumn(name="userType", type="string")
  * @ORM\DiscriminatorMap({
  *         "userType1" = "UserType1",
  *         "userType2" = "UserType2",
  *         "userType3" = "UserType3",
  *         "userType4" = "UserType4"
  * })
  */
abstract class User implements AdvancedUserInterface
{
    /**
     * @ORM\Id()
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\Column(type="string", length=250, unique=true)
     */
    protected $email;

    /**
     * @ORM\Column(type="string", length=128, nullable=true)
     */
    protected $password;

    // other fields

    public function getSalt()
    {
       return "some salt number";
    }

    public function getUsername()
    {
       return $this->email;
    }

    public function getPassword()
    {
       return $this->password;
    }

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

    public function eraseCredentials() {}

    public function isCredentialsNonExpired() 
    {
       return true;
    }

    public function isAccountNonLocked() 
    {
       return true;
    }

    public function isAccountNonExpired() 
    {
        return true;
    }

    public function isEnabled()
    {
       return true;
    }

    public function equals(UserInterface $user)
    {
         return $user->getUsername() === $this->getUsername() || $user->getEmail() === $this->getEmail();
    }
}
子类很简单(下面是class
UserType1
的示例):

其余部分与示例中的内容非常相似。在
security.yml
中:

security:
    encoders:
        Some\Bundle\Repository\User:
            algorithm: sha512
            encode_as_base64: false
            iterations: 1000

    providers:
        provider1:
            entity: { class: "SomeBundle:User" }

    role_hierarchy:
        ROLE_USER_TYPE_1:  ROLE_USER
        ROLE_USER_TYPE_2:  ROLE_USER
        ROLE_USER_TYPE_3:  ROLE_USER
        ROLE_USER_TYPE_4:  ROLE_USER

    firewalls:
        firewall1:
            pattern: ^/
            provider: provider1
            form_login:
                login_path: /login
                check_path: /auth
                post_only: true
                username_parameter: email
                password_parameter: password
                always_use_default_target_path: true
                default_target_path: /
            logout:
                path: /logout
                target: /login
            anonymous: ~
存储库类:

use Doctrine\ORM\EntityRepository;
use Symfony\Component\Security\Core\User\UserInterface;

class UserRepository extends EntityRepository implements UserProviderInterface
{
    public function loadUserByUsername($username)
    {
        $qb = $this->createQueryBuilder('u');

        $query = $qb->where('LOWER(u.email) = :email')
                    ->setParameter('email', strtolower($username))
                    ->getQuery();

        try {
            $user = $query->getSingleResult();
        }
        catch (NoResultException $e) {
            throw new UsernameNotFoundException('User not found.', null, $e);
        }
        return $user;
    }

    public function supportsClass($class)
    {
        return $this->getEntityName() === $class || 
                    is_subclass_of($class, $this->getEntityName());
    }

    public function refreshUser(UserInterface $user)
    {
        $class = get_class($user);

        if (!$this->supportsClass($class)) {
            throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', $class));
        }

        return $this->find($user->getId());
    }
}

@瓦迪马什曼谢谢,这包括一部分:)。我也在寻找用Symfony(用UserProvider)绑定多个用户的方法,以便在每次请求时都能检索到一个合适的用户对象。如果无法获得正确的用户类实例,您可以始终覆盖默认的symfony用户提供程序。好的,谢谢。据我所知,您的代码将为所有用户提供一个相同类型的用户对象-user,否则我会出错吗?其中定义了一条规则,即必须为具有ROLE\u user\u TYPE\u 1 ROLE的用户提供UserType1用户对象。Class
UserType1
通过方法
getRoles()
定义其对象将具有哪些角色,在上例中为roles
ROLE\u user\u TYPE\u 1
ROLE\u user
。但是,您可以为角色指定任何名称。所有用户也将是
用户
的实例。
use Doctrine\ORM\EntityRepository;
use Symfony\Component\Security\Core\User\UserInterface;

class UserRepository extends EntityRepository implements UserProviderInterface
{
    public function loadUserByUsername($username)
    {
        $qb = $this->createQueryBuilder('u');

        $query = $qb->where('LOWER(u.email) = :email')
                    ->setParameter('email', strtolower($username))
                    ->getQuery();

        try {
            $user = $query->getSingleResult();
        }
        catch (NoResultException $e) {
            throw new UsernameNotFoundException('User not found.', null, $e);
        }
        return $user;
    }

    public function supportsClass($class)
    {
        return $this->getEntityName() === $class || 
                    is_subclass_of($class, $this->getEntityName());
    }

    public function refreshUser(UserInterface $user)
    {
        $class = get_class($user);

        if (!$this->supportsClass($class)) {
            throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', $class));
        }

        return $this->find($user->getId());
    }
}