symfony2: пароль пользователя становится пустым после запуска этого метода - PullRequest
1 голос
/ 05 февраля 2012

этот метод использует его для добавления новой работы, но когда я добавляю работу, пароль этого текущего пользователя получает его пароль, установленный равным пустому, потому что пользовательский объект, который я получаю, не имеет пароля, и symfony ведет себя так же, как и для защитыпароль любая помощь будет высоко ценится `public function addJobAction () {

    if(false === $this->get('security.context')
        ->isGranted('ROLE_ANNOUNCER') 
    )
    {           
        throw new AccessDeniedException();          
    }

    $job = new Job() ;
    $jobForm = $this->createForm( new JobType() ,$job) ;
    $request = $this->getRequest();

    if( $request->getMethod() == 'GET'){
        return
        $this->render('MyJobBundle:Job:addJob.html.twig' ,
            array('form'=> $jobForm->createView() )
        ) ;
    }

    if( $request->getMethod() == 'POST'){
        $jobForm->bindRequest($request);
        if( $jobForm->isValid() ){
            $user = $this->get('security.context')->getToken()
                    ->getUser();

            $job->setAnnouncer($user);
            $em = $this->getDoctrine()->getEntityManager();
            $em->persist($job) ;
            $em->flush() ;              
            return
            $this->redirect($this->generateUrl('show_job' ,
                array('id'=> $job->getId() ) ) 
            );              
        }else{
            return
            new Response('no');
        }       
    }       
}

вот моя работа сущность

namespace My\JobBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use My\UserBundle\Entity\User ;
use Symfony\Component\Validator\Constraints as Assert;


/**
 * My\JobBundle\Entity\Job
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="My\JobBundle\Entity\JobRepository")
 */
 class Job
 {
/**
 * @var integer $id
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

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

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



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


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

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


 /**
  * @ORM\ManyToOne(targetEntity="My\UserBundle\Entity\User")
  */
   private $announcer ;

  /**
   *  link a job to a user
   */
   public function setAnnouncer(User $a)
   {
    $this->announcer = $a;
   }   

 /**
  * return a user from a job  object
  */    
  public function getAnnouncer()
  {
    return $this->announcer;
  }


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

/**
 * Set title
 *
 * @param string $title
 */
public function setTitle($title)
{
    $this->title = $title;
}

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

/**
 * Set content
 *
 * @param string $content
 */
public function setContent($content)
{
    $this->content = $content;
}

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

/**
 * Set created_at
 *
 * @param datetime $createdAt
 */
public function setCreatedAt($createdAt)
{
    $this->created_at = $createdAt;
}

/**
 * Get created_at
 *
 * @return datetime 
 */
public function getCreatedAt()
{
    return $this->created_at;
}

/**
 * Set salary
 *
 * @param string $salary
 */
public function setSalary($salary)
{
    $this->salary = $salary;
}

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




public function setCity($c)
{
    $this->city = $c;
}

public function getCity()
{
    return $this->city ;
}


public function __construct(){

    $this->created_at = new \DateTime() ;
}

}

вот мой jobType

namespace My\JobBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;

class JobType extends AbstractType
{
  public function buildForm(FormBuilder $builder, array $options)
 {
    $builder
        ->add('title')
        ->add('content','textarea' )
        //->add('created_at')
        ->add('salary')
        ->add('city')
        //->add('announcer')
    ;
}

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

}

и вот мой журнал, где я вижу обновленный пароль

    INSERT INTO Job (title, content, city, created_at, salary, announcer_id) VALUES (?, ?, ?, ?, ?, ?) ({"1":"lfdgdfl;","2":";lkl;fdlgkdfl;","3":"lklkl;;l","4":{"date":"2012-02-05 23:39:16","timezone_type":3,"timezone":"Europe\/Paris"},"5":"333","6":1})
    UPDATE User SET password = ? WHERE id = ? ([null,1])

Ответы [ 3 ]

4 голосов
/ 08 февраля 2012

хорошо, я обнаружил, что проблема была вызвана этим методом eraseCredential объекта UserInterface в моей сущности User

<?php 
public function eraseCredential(){    
 $this->password = null ;
}

Мне просто нужно было очистить его, как это было сделано с моим паролем, комментируя эту строку; ]

4 голосов
/ 12 февраля 2012

2 косаидпо

Ваше решение работает, потому что метод eraseCredentials () используется для очистки конфиденциальных данных пользователя (означает НЕ секретный, но тот, который может быть восстановлен, смысл подобен __ sleep () ) при сериализации пользовательского объекта или сохранение его в базу данных (так говорится в руководстве). Поэтому, когда вы присоединяете пользователя к объекту задания и вызываете # flush () , doctrine проверит изменения во всех объектах, связанных с заданием, и обнаружит, что объект пользователя изменился, поскольку eraseCredentials () стерла пароль. Вот почему ваш пользователь обновляется.

Есть еще одно решение, которое может вам помочь:

Решение:

Изменение политики отслеживания из документации Doctrine.

Короче говоря, вы можете добавить аннотацию @ChangeTrackingPolicy ("DEFERRED_EXPLICIT") (как я сделал, потому что я использую аннотации. Captain Obvious =)) в реализацию UserInterface (в моем случае я использую класс User), и это скажет Doctrine не проверять все «связанные» с объектами работы.

В этом случае доктрина не будет проверять объект пользователя и сохранять его со стертым паролем, , если вы не заставите его сделать это с вызовом #persist ( Пользовательский объект ) вручную .

Но в любом случае вам не следует делать $ this-> password = null в вашем методе eraseCredentials ().

0 голосов
/ 05 февраля 2012

Это кажется странным, но вы всегда можете получить объект User до привязки его к вновь созданному заданию:

$token = $this->get('security.context')->getToken();
$user_repo = $this->getDoctrine()->getRepository('**NAMESPACE**:User');
$user = $user_repo->find($token->getUser()->getId());

$job->setAnnouncer($user);
$em = $this->getDoctrine()->getEntityManager();
$em->persist($job) ;
$em->flush();

Кроме того, я не совсем уверен, но я где-то читал, что токен не должен содержать пароль из-за его безопасности ... может быть, это ваша проблема ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...