简体   繁体   English

在Form Field上进行Symfony2 Advanced操作以设置用户角色

[英]Symfony2 Advanced operations on Form Field to set user roles

I'm actually developing an application in Symfony2. 我实际上是在Symfony2中开发应用程序。 I've already built a weel working system of authentication with different roles, setting the structure of my tables according to the suggestion by the official documentation: http://symfony.com/doc/current/cookbook/security/entity_provider.html 我已经建立了一个具有不同角色的身份验证工作系统,根据官方文档的建议设置了表的结构: http : //symfony.com/doc/current/cookbook/security/entity_provider.html

I have two page that using a Form permits me to create a new user and edit the existing users and now I need to implement a form field (choice) to select the role associated to the users. 我有两个页面,使用表单可以创建新用户并编辑现有用户,现在需要实现一个表单字段(选择)以选择与用户相关联的角色。 Anyway I found some difficults due this scructure: 无论如何,由于这种结构,我发现了一些困难:

This is my ORM definition for \\Entity\\User.php 这是我对\\ Entity \\ User.php的ORM定义

<?php

namespace Acme\MyBundle\Entity;

use Symfony\Component\Security\Core\User\UserInterface;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\AdvancedUserInterface;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * @ORM\Entity
 * @ORM\Table(name="Users")
 */
class User implements UserInterface, AdvancedUserInterface, \Serializable
{

    // Definizione campi

    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

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

    /**
     * @ORM\Column(type="string")
     */
    protected $password;

    /**
     * @ORM\Column(type="string")
     */
    protected $salt;

    /**
     * @ORM\ManyToMany(targetEntity="Role", inversedBy="users")
     *
     */
    private $roles;

    /**
    * @ORM\Column(type="integer", nullable=true)
    */
    protected $idAnagrafica;

    /**
    * @ORM\Column(type="integer", nullable=true)
    */
    protected $idTipoVisita;

    /**
    * @ORM\Column(type="boolean", nullable=true)
    */
    protected $attivo;


    // Definizioni delle funzioni Get

    /**
    * @return integer
    */
    public function getId()
    {
        return $this->id;
    }

    /**
    * @return string
    */
    public function getUsername()
    {
        return $this->username;
    }

    /**
    * @return string
    */
    public function getPassword()
    {
        return $this->password;
    }

    /**
    * @return string
    */
    public function getSalt()
    {
        if (null === $this->salt)
        {
            $this->salt = sha512(sprintf('%s_%d_%f',uniqid(),rand(0, 99999),microtime(true)));
        }

        return $this->salt;
    }

     /**
     * @return array
     */
     public function getRoles()
     {
         return $this->roles->toArray();
     }

    /**
    * @return integer
    */
    public function getIdRole()
    {
        return $this->idRole;
    }

    /**
    * @return integer
    */
    public function getIdAnagrafica()
    {
        return $this->idAnagrafica;
    }

    /**
    * @return integer
    */
    public function getIdTipoVisita()
    {
        return $this->idTipoVisita;
    }

    /**
    * @return boolean
    */
    public function getAttivo()
    {
        return $this->attivo;
    }

    // Funzioni di servizio

    public function __construct()
    {
        $this->roles = new ArrayCollection();
    }

    /**
    * @see \Serializable::serialize()
    */
    public function serialize()
    {
        return serialize(array($this->id,));
    }

    /**
    * @see \Serializable::unserialize()
    */
    public function unserialize($serialized)
    {
        list ($this->id,) = unserialize($serialized);
    }

    // Definizione delle funzioni Set

    /**
    * @return void
    */
    public function eraseCredentials()
    {
        $this->roles = null;
    }

    /**
     * Set username
     *
     * @param string $username
     * @return User
     */
    public function setUsername($username)
    {
        $this->username = $username;
        return $this;
    }

    /**
     * Set password
     *
     * @param string $password
     * @return User
     */
    public function setPassword($password)
    {
        $this->password = $password;
        return $this;
    }

    /**
     * Set salt
     *
     * @param string $salt
     * @return User
     */
    public function setSalt($salt)
    {
        $this->salt = $salt;
        return $this;
    }

    /**
     * Set idAnagrafica
     *
     * @param integer $idAnagrafica
     * @return User
     */
    public function setIdAnagrafica($idAnagrafica)
    {
        $this->idAnagrafica = $idAnagrafica;
        return $this;
    }

    /**
     * Set riferimento idTipoVisita
     *
     * @param integer $idTipoVisita
     * @return User
     */
    public function setIdTipoVisita($idTipoVisita)
    {
        $this->idTipoVisita = $idTipoVisita;
        return $this;
    }

    /**
     * Set attivo
     *
     * @param boolean $attivo
     * @return User
     */
    public function setAttivo($attivo)
    {
        $this->attivo = $attivo;
        return $this;
    }

    // Funzioni advance user interface

    public function isAccountNonExpired()
    {
        return true;
    }

    public function isAccountNonLocked()
    {
        return true;
    }

    public function isCredentialsNonExpired()
    {
        return true;
    }

    public function isEnabled()
    {
        return $this->attivo;
    }


    /**
     * Add roles
     *
     * @param \Acme\MyBundle\Entity\Role $roles
     * @return User
     */
    public function addRole(\Acme\MyBundle\Entity\Role $roles)
    {
        $this->roles[] = $roles;

        return $this;
    }

    /**
     * Remove roles
     *
     * @param \Acmee\MyBundle\Entity\Role $roles
     */
    public function removeRole(\Acme\MyBundle\Entity\Role $roles)
    {
        $this->roles->removeElement($roles);
    }
}

In the DB is reported like this: 在数据库中报告如下:

ID | USERNAME | PASSWORD | ATTIVO | SALT | IDANAGRAFICA | IDTIPOVISITA
----------------------------------------------------------------------
...| ...      | ...      | ...    | ...  | ...          | ...

This is my ORM definition for \\Entity\\Role.php 这是我对\\ Entity \\ Role.php的ORM定义

<?php

namespace Acme\MyBundle\Entity;

use Symfony\Component\Security\Core\Role\RoleInterface;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * @ORM\Entity
 * @ORM\Table(name="roles")
 */
class Role implements RoleInterface
{
    // Definizione campi

    /**
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id()
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

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

    /**
     * @ORM\Column(name="role", type="string", unique=true)
     */
    private $role;

    /**
     * @ORM\ManyToMany(targetEntity="User", mappedBy="roles")
     */
    private $users;

    // Funzioni di servizio

    public function __construct()
    {
        $this->users = new ArrayCollection();
    }

    // Funzioni di tipo Get

    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Get name
     *
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * @see RoleInterface
     */
    public function getRole()
    {
        return $this->role;
    }

    /**
     * Set role
     *
     * @param string $role
     * @return Role
     */
    public function setRole($role)
    {
        $this->role = $role;
        return $this;
    }

    /**
     * Set name
     *
     * @param string $name
     * @return Role
     */
    public function setName($name)
    {
        $this->name = $name;
        return $this;
    }
}

In the DB is reported like this: 在数据库中报告如下:

ID | NAME | ROLE
----------------
...| ...  | ...

In addition the ORM commands generates automatically (without writing a custom class in my Entity folder) for me the table user_roles that manage for me relationship between User and Roles. 另外,ORM命令会自动为我生成(无需在我的Entity文件夹中编写自定义类的)表user_roles,该表对我来说管理用户和角色之间的关系。

ID_USER | ID_ROLE
-----------------
...     | ...

This is my Form: 这是我的表格:

<?php
// src/Acme/MyBundle/Form/Type/UserType.php

namespace Acme\MyBundle\Form\Type;
use  Acme\MyBundle\Entity\User;
use  Acme\MyBundle\Entity\Role;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Doctrine\ORM\EntityRepository;

class UserType extends AbstractType
{

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array('data_class' => 'Acme\MyBundle\Entity\User', 'Acme\MyBundle\Entity\Role'));
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        // Crezione del form
        $builder->add('username', 'text', array('label' => 'Username: ', 'required' => false));
        $builder->add('password', 'repeated', array('first_name' => 'password', 'second_name' => 'confirm', 'type' => 'password'));
        $builder->add('attivo', 'checkbox', array('label' => 'Attivo', 'required'  => false));
        $builder->add('idTipoVisita', 'choice', array('choices' => array('1' => 'Fisiatra', '2' => 'Genetista'), 'required'  => false));
// $builder->add( ***I NEED TO INSERT HERE THE DROPODOWN FIELD TO SELECT THE ROLE*** );
            $builder->add('save', 'submit');
            $builder->add('annulla', 'submit');
        }

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

And this is my Controller: 这是我的控制器:

<?php
// src/Acme/MyBundle/Controller/UserController.php

namespace Acme\MyBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Acme\MyBundle\Form\Type\UserType;
use Acme\MyBundle\Entity\User;

class UserController extends Controller
{
    // Funzione per la modifica dei dati dell utente
    public function editAction($id, Request $request)
    {
        $em = $this->getDoctrine()->getManager();
        $user = $em->getRepository('AcmeMyBundle:User')->find($id);
        $form = $this->createForm(new UserType(), $user );

        if (!$user) { throw $this->createNotFoundException('Non esiste nessun utente associato a questo id.'); }

        if ($request->isMethod('POST'))
        {
            $form->bind($request);

            // Gestione bottone Annulla
            if ($form->get('annulla')->isClicked())
            {
                return $this->redirect($this->generateUrl('AcmeMyBundle_showAnag', array('id' => $anagrafica->getId())));
            }

            if ($form->isValid())
            {
                $user = $form->getData();
                $user->setSalt(md5(uniqid()));
                $encoder = $this->container
                ->get('security.encoder_factory')
                ->getEncoder($user);

                $user->setPassword($encoder->encodePassword($user->getPassword(), $user->getSalt()));
                $em->persist($user);
                $em->flush();

                return $this->redirect($this->generateUrl('AcmeMyBundle_showAnag', array('id' => $user->getIdAnagrafica($id))));
            }
        }
        return $this->render('AcmeMyBundle:User:edit.html.twig', array('form' => $form->createView(),'user' => $user));
    }

    // Funzione per la creazione di un nuovo utente
    public function newAction($id, Request $request)
    {
        $em = $this->getDoctrine()->getManager();
        $anagrafica = $em->getRepository('AcmeMyBundle:Anagrafiche')->find($id);

        if (!$anagrafica) { throw $this->createNotFoundException('Non esiste nessuna anagrafica associata a questo id.'); }

        $query = $em->getRepository('AcmeMyBundle:User')->createQueryBuilder('p')
            ->where('p.idAnagrafica = :id')
            ->setParameter('id', $id)
            ->getQuery();

        $user = $query->getOneOrNullResult();

        if ($user)
        {
            throw $this->createNotFoundException('Non puoi accedere a questa pagina perchè esiste già un utente associato a questo id anagrafica.');
        }

        $form = $this->createForm(new UserType(), new User() );

        if ($request->isMethod('POST'))
        {
            $form->bind($request);

            // Gestione bottone Annulla
            if ($form->get('annulla')->isClicked())
            {
                return $this->redirect($this->generateUrl('AcmeMyBundle_showAnag', array('id' => $anagrafica->getId())));
            }

            if ($form->isValid())
            {
                $user = $form->getData();
                $user->setSalt(md5(uniqid()));
                $encoder = $this->container
                ->get('security.encoder_factory')
                ->getEncoder($user);

                $user->setPassword($encoder->encodePassword($user->getPassword(), $user->getSalt()));
                $user->setIdAnagrafica($id);
                $em->persist($user);
                $em->flush();

                return $this->redirect($this->generateUrl('AcmeMyBundle_showAnag', array('id' => $user->getIdAnagrafica($id))));
            }
        }
        return $this->render('AcmeMyBundle:User:new.html.twig', array('form' => $form->createView(),'anagrafica' => $anagrafica));
    }

    // Funzione per la selezione della modifica o della creazione di un nuovo record
        public function selectAction($id, Request $request)
        {
            $em = $this->getDoctrine()->getManager();
            $anagrafica = $em->getRepository('AcmeMyBundle:Anagrafiche')->find($id);

            if (!$anagrafica) { throw $this->createNotFoundException('Non esiste nessuna anagrafica associata a questo id.'); }

            $query = $em->getRepository('AcmeMyBundle:User')->createQueryBuilder('p')
                ->where('p.idAnagrafica = :id')
                ->setParameter('id', $id)
                ->getQuery();

            $user = $query->getOneOrNullResult();

            if ($user)
            {
                return $this->redirect($this->generateUrl('AcmeMyBundle_editUser', array('id' => $user->getId())));
            }

            else
            {
                return $this->redirect($this->generateUrl('AcmeMyBundle_newUser', array('id' => $id)));
            }

            return NULL;
    }
}

1)My Form is mapped on the User.php entity and I do not know how to add a Form field referenced to another entity (Role.php) different form the default 'data_class' . 1)我的表格被映射到User.php实体上, 我不知道如何添加引用另一个与默认'data_class'形式不同的另一个实体(Role.php)的Form字段

2)Another problem is that I need to extract an orray of string (the human readeble name of roles) to display the choices on my Dropdown, but I need to insert in the DB the related id and not the string . 2)另一个问题是,我需要提取一个字符串字符串(角色的人类可读名称)以显示我的Dropdown上的选择,但是我需要在数据库中插入相关的id而不是字符串 How can I make this? 我该怎么做? Have I to done something like this : http://symfony.com/doc/current/cookbook/form/data_transformers.html ? 我是否要做过这样的事情: http : //symfony.com/doc/current/cookbook/form/data_transformers.html

3)I suppose that the form field instance (dropdown) do not permit me to autamitacally insert a new record with 2 field in my DB (the association ID_USER and ID_ROLE). 3)我想表单字段实例(下拉列表)不允许我在数据库中自动添加一个新的记录,其中包含2个字段 (关联ID_USER和ID_ROLE)。 What is the best way to make this possible? 使之成为可能的最佳方法是什么? I suppose I need to exctract the value from my dropdown field and built a query in the controller, but how can I do this? 我想我需要从下拉字段中提取值并在控制器中建立查询,但是我该怎么做呢?

Thanks a lot for your suggestion, Regards. 非常感谢您的建议,问候。

In your UserType : 在您的UserType

// ...
$builder
   ->add('userroles', 'entity', array(
      'class' => 'AcmeMyBundle:Role',
      'property' => 'name'
      'multiple'  => true));
// ...

In your User entity: 在您的User实体中:

// ...
public function setUserroles($roles)
{
   $this->roles = $roles;

   return $this;
}

public function getUserroles()
{
   return $this->roles;
}
// ...

In your php template: 在您的php模板中:

<?php if ($view['form']->errors($form['userroles'])): ?>
   <div class="error">
       <?php echo $view['form']->errors($form['userroles']) ?>
   </div>
<?php endif; ?>

<?php echo $view['form']->widget($form['userroles']) ?>

Update: In your User.php : 更新:在您的User.php

/**
 * @var \Doctrine\Common\Collections\Collection
 *
 * @ORM\ManyToMany(targetEntity="Role", inversedBy="users")
 * @ORM\JoinTable(name="User_Role",
 *   joinColumns={
 *     @ORM\JoinColumn(name="user_id", referencedColumnName="id")
 *   },
 *   inverseJoinColumns={
 *     @ORM\JoinColumn(name="role_id", referencedColumnName="id")
 *   }
 * )
 */
private $roles;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM