Symfony 3.0: How I will know when an Entry Successfully Inserted? - php

I have made on my Symfony 3.0 project a User Entity:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="users")
* #ORM\Entity(repositoryClass="AppBundle\Entity\UserRepository")
*/
class Users
{
/**
* #ORM\Column(type="string", length=60)
* #ORM\Id
* #ORM\GeneratedValue(strategy="CUSTOM")
* #ORM\CustomIdGenerator(class="AppBundle\Doctrine\AutoIdGenerate")
*/
private $id;
/**
* #ORM\Column(type="string", length=15)
*/
private $username;
/**
* #ORM\Column(type="string", length=30)
*/
private $password;
/**
* #ORM\Column(type="string", length=60)
* #ORM\GeneratedValue(strategy="CUSTOM")
* #ORM\CustomIdGenerator(class="AppBundle\Doctrine\AutoIdGenerate")
*/
private $token;
/**
* #ORM\Column(type="boolean")
*/
private $activated;
/**
* Get id
*
* #return string
*/
public function getId()
{
return $this->id;
}
/**
* Set username
*
* #param string $username
*
* #return Users
*/
public function setUsername($username)
{
$this->username = strip_tags($username);
return $this;
}
/**
* Get username
*
* #return string
*/
public function getUsername()
{
return $this->username;
}
/**
* Set password
*
* #param string $password
*
* #return Users
*/
public function setPassword($password)
{
$options = ['cost' => 42];
$this->password = password_hash ($password,CRYPT_BLOWFISH,$options);
return $this;
}
/**
* Get password
*
* #return string
*/
public function getPassword()
{
return $this->password;
}
/**
* Set token
*
* #param string $token
*
* #return Users
*/
public function setToken($token)
{
$this->token = $token;
return $this;
}
/**
* Get token
*
* #return string
*/
public function getToken()
{
return $this->token;
}
/**
* Set activated
*
* #param boolean $activated
*
* #return Users
*/
public function setActivated($activated)
{
$this->activated = $activated;
return $this;
}
/**
* Get activated
*
* #return boolean
*/
public function getActivated()
{
return $this->activated;
}
}
And a Repository that Iplements My logic:
<?php
namespace AppBundle\Entity;
use AppBundle\Entity\Product;
use Doctrine\ORM\EntityRepository;
class UserRepository extends EntityRepository
{
public function register($username,$password,$email)
{
//A Generic return Object
$status=array('status'=>'true','data'=>"");
if(empty($username))
{
$status['status']=-1;
$status['data']='Username not given';
return $status;
}
if(empty($password))
{
$status['status']=-1;
$status['data']='Password not given';
return $status;
}
if(empty($email))
{
$status['status']=-1;
$status['data']='Email not given';
return $status;
}
$user=new User();
$user->setUsername($username)->setPassword($password);
$em=$this->getEntityManager();
$em->persist($user);
$em->flush();
return $status;
}
}
What I wanna know is when an Entry Sucessfully Inserted to send the email to verify the registration. How I will know That the User Has Sucessfully Inserted In the DB; Also How I will take any Sort of AutoGenerated Fields such as id and token in order to verify the mail address.
I Found that In order to Use Email I can Use the Swiftmailer so the Question
Is NOT hoiw to send an Email, but how I will know that the user successfully inserted.

If your entry is correctly inserted, you'll not have any error.
Otherwise, you'll have one (unless you have a mistake that is not coming from the insertion).
To catch a possible error, you can do this :
// ...
$em->persist($user);
try {
$em->flush();
// Success
} catch (\Exception $e) {
$result['data'] = $e->getMessage(); // The exact message of the exception thrown during INSERT
// Error
}
Otherwise, you can consider the entry has been stored.
For the auto-generated fields, they are immediately available through getters after calling $em->flush().

You can register Event Listener for Doctrine postFlush event.
Example listener:
<?php
use Doctrine\ORM\Event\PostFlushEventArgs;
class PostFlushExampleListener
{
public function postFlush(PostFlushEventArgs $args)
{
// ...
}
}
Service registration in Symfony:
services:
my.listener:
class: PostFlushExampleListener
tags:
- { name: doctrine.event_listener, event: postFlush }
Symfony documentation: http://symfony.com/doc/current/cookbook/doctrine/event_listeners_subscribers.html
Doctrine documentation: http://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/reference/events.html#listening-and-subscribing-to-lifecycle-events
You should have all autogenerated fields available just after calling flush action there where you call it. Doctrine events are non mandatory in your case. I would just assume that after flush i will have all needed data and data will be set in database.

Related

Google+ authentication with FOSUserBundle

i was learning OAuth2 in order to login an account with Google+ , Facebook, etc. on a web site.
I have followed a tutorial about it, and i have an issue when i clicked on my button "Connect with Google+" :
In the tutorial, he created a User.php but i had already one with FOS User.
Here is my code :
User.php :
<?php
// src/AppBundle/Entity/User.php
namespace App\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* #ORM\Entity
* #ORM\Table(name="fos_user")
*/
class User extends BaseUser implements UserInterface
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string")
*/
protected $nom;
/**
* #ORM\Column(type="string")
*/
protected $prenom;
/**
* #ORM\Column(type="string")
*/
protected $nationalite;
/**
* #ORM\Column(type="datetime")
*/
protected $birthday;
/**
* #ORM\Column(type="string")
*/
protected $sexe;
/**
* #ORM\OneToOne(targetEntity="App\Entity\AnnonceColocation", mappedBy="User", cascade={"persist", "remove"})
*/
private $annonceColocation;
/**
* #ORM\OneToOne(targetEntity="App\Entity\AnnonceColocataire", mappedBy="User", cascade={"persist", "remove"})
*/
private $annonceColocataire;
/**
* #ORM\OneToMany(targetEntity="App\Entity\Message", mappedBy="expediteur", orphanRemoval=true)
*/
private $sendMessage;
/**
* #ORM\OneToMany(targetEntity="App\Entity\Message", mappedBy="destinataire", orphanRemoval=true)
*/
private $receivedMessage;
public function __construct()
{
parent::__construct();
$this->sendMessage = new ArrayCollection();
$this->receivedMessage = new ArrayCollection();
// your own logic
}
/**
* #return mixed
*/
public function getNom()
{
return $this->nom;
}
/**
* #param mixed $nom
*/
public function setNom($nom)
{
$this->nom = $nom;
}
/**
* #return mixed
*/
public function getPrenom()
{
return $this->prenom;
}
/**
* #param mixed $prenom
*/
public function setPrenom($prenom)
{
$this->prenom = $prenom;
}
public function getNationalite()
{
return $this->nationalite;
}
/**
* #param mixed $nationalite
*/
public function setNationalite($nationalite)
{
$this->nationalite = $nationalite;
}
public function getBirthday()
{
return $this->birthday;
}
/**
* #param mixed $birthday
*/
public function setBirthday($birthday)
{
$this->birthday = $birthday;
}
public function getSexe()
{
return $this->sexe;
}
/**
* #param mixed $sexe
*/
public function setSexe($sexe)
{
$this->sexe = $sexe;
}
public function getPicture()
{
return $this->picture;
}
/**
* #param mixed $picture
*/
public function setPicture($picture)
{
$this->picture = $picture;
}
public function getAnnonceColocation(): ?AnnonceColocation
{
return $this->annonceColocation;
}
public function setAnnonceColocation(AnnonceColocation $annonceColocation): self
{
$this->annonceColocation = $annonceColocation;
// set (or unset) the owning side of the relation if necessary
$newUser = $annonceColocation === null ? null : $this;
if ($newUser !== $annonceColocation->getUser()) {
$annonceColocation->setUser($newUser);
}
return $this;
}
public function getAnnonceColocataire(): ?AnnonceColocataire
{
return $this->annonceColocataire;
}
public function setAnnonceColocataire(?AnnonceColocataire $annonceColocataire): self
{
$this->annonceColocataire = $annonceColocataire;
// set (or unset) the owning side of the relation if necessary
$newUser = $annonceColocataire === null ? null : $this;
if ($newUser !== $annonceColocataire->getUser()) {
$annonceColocataire->setUser($newUser);
}
return $this;
}
/**
* #return Collection|Message[]
*/
public function getSendMessage(): Collection
{
return $this->sendMessage;
}
public function addSendMessage(Message $sendMessage): self
{
if (!$this->sendMessage->contains($sendMessage)) {
$this->sendMessage[] = $sendMessage;
$sendMessage->setExpediteur($this);
}
return $this;
}
public function removeSendMessage(Message $sendMessage): self
{
if ($this->sendMessage->contains($sendMessage)) {
$this->sendMessage->removeElement($sendMessage);
// set the owning side to null (unless already changed)
if ($sendMessage->getExpediteur() === $this) {
$sendMessage->setExpediteur(null);
}
}
return $this;
}
/**
* #return Collection|Message[]
*/
public function getReceivedMessage(): Collection
{
return $this->receivedMessage;
}
public function addReceivedMessage(Message $receivedMessage): self
{
if (!$this->receivedMessage->contains($receivedMessage)) {
$this->receivedMessage[] = $receivedMessage;
$receivedMessage->setDestinataire($this);
}
return $this;
}
public function removeReceivedMessage(Message $receivedMessage): self
{
if ($this->receivedMessage->contains($receivedMessage)) {
$this->receivedMessage->removeElement($receivedMessage);
// set the owning side to null (unless already changed)
if ($receivedMessage->getDestinataire() === $this) {
$receivedMessage->setDestinataire(null);
}
}
return $this;
}
public function getRoles()
{
return array('ROLE_USER');
}
/**
* Returns the password used to authenticate the user.
*
* This should be the encoded password. On authentication, a plain-text
* password will be salted, encoded, and then compared to this value.
*
* #return string The password
*/
public function getPassword()
{
return null;
}
/**
* Returns the salt that was originally used to encode the password.
*
* This can return null if the password was not encoded using a salt.
*
* #return string|null The salt
*/
public function getSalt()
{
return null;
}
/**
* Returns the username used to authenticate the user.
*
* #return string The username
*/
public function getUsername()
{
return $this->email;
}
/**
* Removes sensitive data from the user.
*
* This is important if, at any given point, sensitive information like
* the plain-text password is stored on this object.
*/
public function eraseCredentials()
{
return null;
}
}
UserProvider.php :
<?php
/**
* Created by IntelliJ IDEA.
* User: mert
* Date: 12/18/17
* Time: 12:58 PM
*/
namespace App\Security;
use Doctrine\ORM\EntityManagerInterface;
use App\Entity\User;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
class UserProvider implements UserProviderInterface
{
private $entityManager;
/**
* UserProvider constructor.
* #param EntityManagerInterface $entityManager
* #internal param Client $httpClient
* #internal param UserOptionService $userOptionService
* #internal param ProjectService $projectService
* #internal param SessionService $sessionService
* #internal param Session $session
* #internal param UserOptionService $userOptionsService
*/
public function __construct(EntityManagerInterface $entityManager)
{
$this->entityManager = $entityManager;
}
/**
* Loads the user for the given username.
*
* This method must throw UsernameNotFoundException if the user is not
* found.
*
* #param string $username The username
*
* #return UserInterface
*
* #throws \Doctrine\ORM\NonUniqueResultException
*/
public function loadUserByUsername($username)
{
return $this->entityManager->createQueryBuilder('u')
->where('u.email = :email')
->setParameter('email', $username)
->getQuery()
->getOneOrNullResult();
}
/**
* Refreshes the user.
*
* It is up to the implementation to decide if the user data should be
* totally reloaded (e.g. from the database), or if the UserInterface
* object can just be merged into some internal array of users / identity
* map.
*
* #param UserInterface $user
* #return UserInterface
*
*/
public function refreshUser(UserInterface $user)
{
if (!$user instanceof User) {
throw new UnsupportedUserException(
sprintf('Instances of "%s" are not supported.', get_class($user))
);
}
return $user;
}
/**
* Whether this provider supports the given user class.
*
* #param string $class
*
* #return bool
*/
public function supportsClass($class)
{
return $class === 'App\Security\User';
}
}
GoogleController.php :
<?php
namespace App\Controller;
use KnpU\OAuth2ClientBundle\Client\ClientRegistry;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
class GoogleController extends AbstractController
{
/**
* Link to this controller to start the "connect" process
*
* #Route("/connect/google", name="connect_google")
* #param ClientRegistry $clientRegistry
* #return \Symfony\Component\HttpFoundation\RedirectResponse
*/
public function connectAction(ClientRegistry $clientRegistry)
{
return $clientRegistry
->getClient('google')
->redirect();
}
/**
* Facebook redirects to back here afterwards
*
* #Route("/connect/google/check", name="connect_google_check")
* #param Request $request
* #return JsonResponse|\Symfony\Component\HttpFoundation\RedirectResponse
*/
public function connectCheckAction(Request $request)
{
if (!$this->getUser()) {
return new JsonResponse(array('status' => false, 'message' => "User not found!"));
} else {
return $this->redirectToRoute('default');
}
}
}
and my GoogleAuthenticator.php :
<?php
namespace App\Security;
use App\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
use KnpU\OAuth2ClientBundle\Client\ClientRegistry;
use KnpU\OAuth2ClientBundle\Security\Authenticator\SocialAuthenticator;
use League\OAuth2\Client\Provider\GoogleUser;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
/**
* Created by IntelliJ IDEA.
* User: mert
* Date: 12/18/17
* Time: 12:00 PM
*/
class GoogleAuthenticator extends SocialAuthenticator
{
private $clientRegistry;
private $em;
private $router;
public function __construct(ClientRegistry $clientRegistry, EntityManagerInterface $em, RouterInterface $router)
{
$this->clientRegistry = $clientRegistry;
$this->em = $em;
$this->router = $router;
}
public function supports(Request $request)
{
return $request->getPathInfo() == '/connect/google/check' && $request->isMethod('GET');
}
public function getCredentials(Request $request)
{
return $this->fetchAccessToken($this->getGoogleClient());
}
public function getUser($credentials, UserProviderInterface $userProvider)
{
/** #var GoogleUser $googleUser */
$googleUser = $this->getGoogleClient()
->fetchUserFromToken($credentials);
$email = $googleUser->getEmail();
$user = $this->em->getRepository('App:User')
->findOneBy(['email' => $email]);
if (!$user) {
$user = new User();
$user->setEmail($googleUser->getEmail());
$user->setFullname($googleUser->getName());
$user->setCreatedAt(new \DateTime(date('Y-m-d H:i:s')));
$this->em->persist($user);
$this->em->flush();
}
return $user;
}
/**
* #return \KnpU\OAuth2ClientBundle\Client\OAuth2Client
*/
private function getGoogleClient()
{
return $this->clientRegistry
->getClient('google');
}
/**
* Returns a response that directs the user to authenticate.
*
* This is called when an anonymous request accesses a resource that
* requires authentication. The job of this method is to return some
* response that "helps" the user start into the authentication process.
*
* Examples:
* A) For a form login, you might redirect to the login page
* return new RedirectResponse('/login');
* B) For an API token authentication system, you return a 401 response
* return new Response('Auth header required', 401);
*
* #param Request $request The request that resulted in an AuthenticationException
* #param \Symfony\Component\Security\Core\Exception\AuthenticationException $authException The exception that started the authentication process
*
* #return \Symfony\Component\HttpFoundation\Response
*/
public function start(Request $request, \Symfony\Component\Security\Core\Exception\AuthenticationException $authException = null)
{
return new RedirectResponse('/login');
}
/**
* Called when authentication executed, but failed (e.g. wrong username password).
*
* This should return the Response sent back to the user, like a
* RedirectResponse to the login page or a 403 response.
*
* If you return null, the request will continue, but the user will
* not be authenticated. This is probably not what you want to do.
*
* #param Request $request
* #param \Symfony\Component\Security\Core\Exception\AuthenticationException $exception
*
* #return \Symfony\Component\HttpFoundation\Response|null
*/
public function onAuthenticationFailure(Request $request, \Symfony\Component\Security\Core\Exception\AuthenticationException $exception)
{
// TODO: Implement onAuthenticationFailure() method.
}
/**
* Called when authentication executed and was successful!
*
* This should return the Response sent back to the user, like a
* RedirectResponse to the last page they visited.
*
*
If you return null, the current request will continue, and the user
* will be authenticated. This makes sense, for example, with an API.
*
* #param Request $request
* #param \Symfony\Component\Security\Core\Authentication\Token\TokenInterface $token
* #param string $providerKey The provider (i.e. firewall) key
*
* #return void
*/
public function onAuthenticationSuccess(Request $request, \Symfony\Component\Security\Core\Authentication\Token\TokenInterface $token, $providerKey)
{
// TODO: Implement onAuthenticationSuccess() method.
}
}
Hope some of you could help on this. Thanks a lot.
Since Google plus doesn't exist anymore you need to change the Google API for the login. Check the official Google Oauth2.0 for Google APIs (https://developers.google.com/identity/protocols/googlescopes). For this you need to change the scope inside the config.yml file. Instead of "https://www.googleapis.com/auth/plus.login" you can use "https://www.googleapis.com/auth/cloud-platform" or you can use scope: "openid". That at least works for me.

PHP server terminated unexpectedly (Symfony)

I've just started to learn Symfony framework and I noticed that almost every time there is some meaningful error in my code (for example I missed some "use" statement) my server terminates unexpectedly and I don't know how to get any information about what exactly caused it.
Most of the time I was able to figure it out on my own, but now I've just started to use Doctrine and I want to save some object to the database, but when I run the code my server terminates. I figured out that the "flush()" method is causing the problem, but now I'm stuck as I can't get any more information about the error. So I actually have two questions - how can I get more information about errors like this and how to solve this particiular one?
The codes are below:
The controller
/* UserController.php */
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use AppBundle\Entity\User;
use Symfony\Component\HttpFoundation\Response;
class UserController extends Controller
{
/**
* #Route("/user/test")
*/
public function testAction(Request $request)
{
$user = new User();
$user->setLogin("Test");
$user->setEmail("test#test.com");
$user->setPassword(hash("sha256", "test"));
$user->setJoined(date("Y-m-d H:i:s"));
$user->setActivationCode(NULL);
$em = $this->getDoctrine()->getManager();
$em->persist($user);
$em->flush(); /* The line that causes server to terminate! */
return new Response("Hello");
}
}
And the entity
/* User.php (Entity) */
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="`user`")
*/
class User
{
/**
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(type="string", length=128)
*/
private $email;
/**
* #ORM\Column(type="string", length=64)
*/
private $login;
/**
* #ORM\Column(type="string", length=64)
*/
private $password;
/**
* #ORM\Column(type="datetime")
*/
private $joined;
/**
* #ORM\Column(type="string", length=64, nullable=TRUE)
*/
private $activation_code;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set email
*
* #param string $email
*
* #return User
*/
public function setEmail($email)
{
$this->email = $email;
return $this;
}
/**
* Get email
*
* #return string
*/
public function getEmail()
{
return $this->email;
}
/**
* Set login
*
* #param string $login
*
* #return User
*/
public function setLogin($login)
{
$this->login = $login;
return $this;
}
/**
* Get login
*
* #return string
*/
public function getLogin()
{
return $this->login;
}
/**
* Set password
*
* #param string $password
*
* #return User
*/
public function setPassword($password)
{
$this->password = $password;
return $this;
}
/**
* Get password
*
* #return string
*/
public function getPassword()
{
return $this->password;
}
/**
* Set joined
*
* #param \DateTime $joined
*
* #return User
*/
public function setJoined($joined)
{
$this->joined = $joined;
return $this;
}
/**
* Get joined
*
* #return \DateTime
*/
public function getJoined()
{
return $this->joined;
}
/**
* Set activationCode
*
* #param string $activationCode
*
* #return User
*/
public function setActivationCode($activationCode)
{
$this->activation_code = $activationCode;
return $this;
}
/**
* Get activationCode
*
* #return string
*/
public function getActivationCode()
{
return $this->activation_code;
}
}
Use web/app_dev.php as your endpoint.
So your url will be like localhost:8000/app_dev.php/<your-routing-alias>
Are you using a web browser to access your Symfony instance on a remote host - I mean a machine that is not the 'localhost'? If so, you'll need to edit the 'web/app_dev.php' file where it has a line like so:
|| !(in_array(#$_SERVER['REMOTE_ADDR'], ['192.168.40.208', '192.168.255.74',
'127.0.0.1', 'fe80::1', '::1']) || php_sapi_name() === 'cli-server')
Enter in the IP address of the remote host that you are trying to access your web URL from. Using the DEV URL: of "http://ip_address/app_dev.php/" would be the best way to troubleshoot.
You'll see useful help information when you use this link - I highly recommend it.
I also notice this one line:
#ORM\Table(name="`user`")
I'm not sure if you need those backticks. Try this:
#ORM\Table(name="user")
I recently had this issue and after a lot of investigation discovered the date was causing my issue. I can see this is an old question, but the answer may help someone.
It looks like Doctrine requires a full date time object when inserting into a datetime / datetimetz field:
Try replacing
$user->setJoined(date("Y-m-d H:i:s"));
With
$user->setJoined(new \DateTime("now"));

Doctrine isn't saving my entities?

I have the following model, or as you call them entity, and I also have a controller, everything works in this action, but when I check the database there is no user. So I am curious as what I am missing. So lets start at the beginning as to what I have:
bootstrap.php contains the following code, among other things.
...
/** ---------------------------------------------------------------- **/
// Lets Setup Doctrine.
/** ---------------------------------------------------------------- **/
require_once 'vendor/autoload.php';
$loader = require 'vendor/autoload.php';
\Doctrine\Common\Annotations\AnnotationRegistry::registerLoader(array($loader, 'loadClass'));
use Doctrine\ORM\Tools\Setup;
use Doctrine\ORM\EntityManager;
/**
* Set up Doctrine.
*/
class DoctrineSetup {
/**
* #var array $paths - where the entities live.
*/
protected $paths = array(APP_MODELS);
/**
* #var bool $isDevMode - Are we considered "in development."
*/
protected $isDevMode = false;
/**
* #var array $dbParams - The database paramters.
*/
protected $dbParams = null;
/**
* Constructor to set some core values.
*/
public function __construct(){
if (!file_exists('db_config.ini')) {
throw new \Exception(
'Missing db_config.ini. You can create this from the db_config_sample.ini'
);
}
$this->dbParams = array(
'driver' => 'pdo_mysql',
'user' => parse_ini_file('db_config.ini')['DB_USER'],
'password' => parse_ini_file('db_config.ini')['DB_PASSWORD'],
'dbname' => parse_ini_file('db_config.ini')['DB_NAME']
);
}
/**
* Get the entity manager for use through out the app.
*
* #return EntityManager
*/
public function getEntityManager() {
$config = Setup::createAnnotationMetadataConfiguration($this->paths, $this->isDevMode, null, null, false);
return EntityManager::create($this->dbParams, $config);
}
}
/**
* Function that can be called through out the app.
*
* #return EntityManager
*/
function getEntityManager() {
$ds = new DoctrineSetup();
return $ds->getEntityManager();
}
/**
* Function that returns the conection to the database.
*/
function getConnection() {
$ds = new DoctrineSetup();
return $ds->getEntityManager()->getConnection();
}
...
So now that we have doctrine set up its time to create a model (entity) and set which fields can and cannot be blank and so on and so forth.
Note At this point, you should know that I am not using Symfony other then its components on top of Doctrine. I am using Slim Framework. So if any suggestion is to use x or y from symfony, please make sure its a component.
Models/User.php
<?php
namespace ImageUploader\Models;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ORM\Entity
* #ORM\Table(name="users", uniqueConstraints={
* #ORM\UniqueConstraint(name="user", columns={"userName", "email"})}
* )
*/
class User {
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue
*/
protected $id;
/**
* #ORM\Column(type="string", length=32, nullable=false)
* #Assert\NotBlank()
*/
protected $firstName;
/**
* #ORM\Column(type="string", length=32, nullable=false)
* #Assert\NotBlank()
*/
protected $lastName;
/**
* #ORM\Column(type="string", length=100, unique=true, nullable=false)
* #Assert\NotBlank(
* message = "Username cannot be blank"
* )
*/
protected $userName;
/**
* #ORM\Column(type="string", length=100, unique=true, nullable=false)
* #Assert\NotBlank(
* message = "Email field cannot be blank."
* )
* #Assert\Email(
* message = "The email you entered is invalid.",
* checkMX = true
* )
*/
protected $email;
/**
* #ORM\Column(type="string", length=500, nullable=false)
* #Assert\NotBlank(
* message = "The password field cannot be empty."
* )
*/
protected $password;
/**
* #ORM\Column(type="datetime", nullable=true)
*/
protected $created_at;
/**
* #ORM\Column(type="datetime", nullable=true)
*/
protected $updated_at;
/**
* Get the value of Created At
*
* #return mixed
*/
public function getCreatedAt()
{
return $this->created_at;
}
/**
* Set the value of Created At
*
* #param mixed created_at
*
* #return self
*/
public function setCreatedAt(\DateTime $created_at = null)
{
$this->created_at = $created_at;
return $this;
}
/**
* Get the value of Updated At
*
* #return mixed
*/
public function getUpdatedAt()
{
return $this->updated_at;
}
/**
* Set the value of Updated At
*
* #param mixed updated_at
*
* #return self
*/
public function setUpdatedAt(\DateTime $updated_at = null)
{
$this->updated_at = $updated_at;
return $this;
}
/**
* Get the value of First Name
*
* #return mixed
*/
public function getFirstName()
{
return $this->firstName;
}
/**
* Set the value of First Name
*
* #param mixed firstName
*
* #return self
*/
public function setFirstName($firstName)
{
$this->firstName = $firstName;
return $this;
}
/**
* Get the value of Last Name
*
* #return mixed
*/
public function getLastName()
{
return $this->lastName;
}
/**
* Set the value of Last Name
*
* #param mixed lastName
*
* #return self
*/
public function setLastName($lastName)
{
$this->lastName = $lastName;
return $this;
}
/**
* Get the value of User Name
*
* #return mixed
*/
public function getUserName()
{
return $this->userName;
}
/**
* Set the value of User Name
*
* #param mixed userName
*
* #return self
*/
public function setUserName($userName)
{
$this->userName = $userName;
return $this;
}
/**
* Get the value of Email
*
* #return mixed
*/
public function getEmail()
{
return $this->email;
}
/**
* Set the value of Email
*
* #param mixed email
*
* #return self
*/
public function setEmail($email)
{
$this->email = $email;
return $this;
}
/**
* Set ths password.
*
* #param string password
*
* #return self
*/
public function setPassword($password) {
$this->password = password_hash($password, PASSWORD_DEFAULT);
return $this;
}
/**
* Check the users password against that which is enterd.
*
* #param string password
*
* #return bool
*/
public function checkPassword($password) {
if (password_hash($password, PASSWORD_DEFAULT) === $this->getPassword()) {
return true;
}
return false;
}
/**
* Return the password value.
*
* #return hash
*/
private function getPassword(){
return $this->password;
}
/**
* #ORM\PrePersist
*/
public function setCreatedAtTimeStamp() {
if (is_null($this->getCreatedAt())) {
$this->setCreatedAt(new \DateTime());
}
}
/**
* #ORM\PreUpdate
*/
public function setUpdatedAtTimeStamp() {
if (is_null($this->getUpdatedAt())) {
$this->setUpdatedAt(new \DateTime());
}
}
}
The above model is correct, as far as I know, I mean when I run "vendor/bin/doctrine migrations:migrate" a database table is created.
Now, where is all this used? it's used in a controller called SignupController under an action called createAction($params)
**createAction($params)**
public static function createAction($params){
$postParams = $params->request()->post();
$flash = new Flash();
if ($postParams['password'] !== $postParams['repassword']) {
$flash->createFlash('error', 'Your passwords do not match.');
self::$createEncryptedPostParams($postParams);
$params->redirect('/signup/error');
}
$user = new User();
$user->setFirstName($postParams['firstname'])
->setLastName($postParams['lastname'])
->setUserName($postParams['username'])
->setEmail($postParams['email'])
->setPassword($postParams['password'])
->setCreatedAtTimeStamp();
$validator = Validator::createValidatorBuilder();
$validator->enableAnnotationMapping();
$errors = $validator->getValidator()->validate($user);
if (count($errors) > 0) {
foreach($errors as $error) {
$flash->createFlash(
$error->getPropertyPath() . 'error',
$error->getMessage()
);
}
self::createEncryptedPostParams($postParams);
$params->redirect('/signup/error');
}
$anyEncryptedErors = self::getEncryptedPostParams();
if ($anyEncryptedErors !== null) {
$anyEncryptedErors->destroy('error');
}
getEntityManager()->flush();
getEntityManager()->persist($user);
$flash->createFlash('success', ' You have signed up successfully! Please sign in!');
$params->redirect('/signin');
}
Now should you enter everything in correctly I show a flash of success and redirect you. THIS WORKS it redirects, it shows a flash message. But its the:
getEntityManager()->flush();
getEntityManager()->persist($user);
That I don't think is working. Why? Because doing a select * from users on the database in question comes back with no records.
Why?
Flush statement should be execute after persist. So Code should be:
getEntityManager()->persist($user);
getEntityManager()->flush();
I had a similar issue and thought I would post it here. I was creating an entity and everything was responding correctly, but when I checked the database no record had been created.
Just wrapped the flush in a try-catch and logged the error.
$this->em->persist($insectLifeCycle);
try {
$this->em->flush();
} catch (\Exception $error) {
$this->logger->debug($error);
}
It turns out that one of properties was exceeding its character limit and the database was throwing an error. Also found out I need to improve my error handling....
As Samiul Amin Shanto said:
getEntityManager()->persist($user);
getEntityManager()->flush();
will be correct way, because persist action prepare the data to be stored in DB and flush "Flushes all changes to now to the database."
If you have the object id and then, the database is not showing it, you might have a "START TRANSACTION" and then you have your insert, after this insert you will have a "COMMIT". If any error appears between your persist and the COMMIT, object won't be stored in your database.
Check your Symfony request profiler information.
You can find it using the developer tool and checking your response for it.

Symfony2 Login SHA512 - Bad Credentials

I've been through literally every SO post regarding this issue but I still can't find my bug. I'm trying to get my login working using sha512. I don't think the password is being encoded correctly, as I've checked on this site. The password I used was "asdf", the salt being generated is "fe739a9eafaff0a5b5091d51e1642a34", and the password stored in my DB is "HzK/fSfJjLQAuAgUhxBzQaPT8cJQ0/05pt5zcYoSM4d7Dxd/WDBiJYXIMmFF70I+". Is this my problem? I simply cannot get past the damned "Bad Credentials" thing. My code is below...
security.yml
security:
encoders:
MyBundle\MainBundle\Entity\SystemUser:
algorithm: sha512
iterations: 1
role_hierarchy:
ROLE_STUDENT:
ROLE_GUARDIAN:
ROLE_TEACHER:
ROLE_SCHOOL_ADMIN: ROLE_STUDENT, ROLE_GUARDIAN
ROLE_ADMIN: ROLE_SCHOOL_ADMIN, ROLE_STUDENT, ROLE_GUARDIAN
ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
providers:
users:
entity: { class: MyBundleMainBundle:SystemUser }
firewalls:
secured_area:
pattern: ^/
anonymous: ~
form_login:
login_path: login
check_path: login_check
csrf_provider: form.csrf_provider
csrf_parameter: _csrf_token
always_use_default_target_path: true
default_target_path: /dashboard
logout: true
anonymous: true
Then, my SystemUser class (sorry it's so long, just want to be comprehensive here)
<?php
namespace MyBundle\MainBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\AdvancedUserInterface;
use Symfony\Component\Validator\Constraints\Collection;
/**
* SystemUser
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="MyBundle\MainBundle\Entity\Repository\SystemUserRepository")
* #ORM\InheritanceType("JOINED")
* #ORM\DiscriminatorColumn(name="discr", type="integer")
* #ORM\DiscriminatorMap({"0" = "SystemUser", "1" = "SchoolAdmin", "2" = "Teacher", "3" = "Student", "4" = "Guardian"})
*/
class SystemUser implements AdvancedUserInterface, \Serializable {
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string
*
* #ORM\Column(type="string", length=50)
*/
protected $username;
/**
* #var string
*
* #ORM\Column(type="string", length=255)
*/
protected $email;
/**
* #var string
*
* #ORM\Column(type="string", length=32)
*/
protected $salt;
/**
* #var string
*
* #ORM\Column(type="string", length=64)
*/
protected $password;
/**
* #var bool
*
* #ORM\Column(type="boolean", name="is_active")
*/
protected $isActive;
/**
* #var string
* #ORM\Column(name="birth_date", type="date")
*/
protected $birthDate;
/**
* #var string
* #ORM\Column(name="cellphone", type="string", length=10)
*/
protected $cellphone;
/**
* #var ArrayCollection
* #ORM\ManyToMany(targetEntity="Role", inversedBy="users")
*/
protected $roles;
/**
* #var integer
* Use this to map to the discr column...
*/
protected $discr;
/**
*
*
*
*
* Begin methods
*
*
*
*/
public function __construct() {
$this->isActive = true;
$this->salt = md5(uniqid(null, true));
$this->roles = new ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set birthDate
*
* #param \DateTime $birthDate
* #return SystemUser
*/
public function setBirthDate($birthDate)
{
$this->birthDate = $birthDate;
return $this;
}
/**
* Get birthDate
*
* #return \DateTime
*/
public function getBirthDate()
{
return $this->birthDate;
}
/**
* Set cellphone
*
* #param string $cellphone
* #return SystemUser
*/
public function setCellphone($cellphone)
{
$this->cellphone = $cellphone;
return $this;
}
/**
* Get cellphone
*
* #return string
*/
public function getCellphone()
{
return $this->cellphone;
}
/**
* (PHP 5 >= 5.1.0)<br/>
* String representation of object
* #link http://php.net/manual/en/serializable.serialize.php
* #return string the string representation of the object or null
*/
public function serialize()
{
return serialize(array(
$this->id,
));
}
/**
* (PHP 5 >= 5.1.0)<br/>
* Constructs the object
* #link http://php.net/manual/en/serializable.unserialize.php
* #param string $serialized <p>
* The string representation of the object.
* </p>
* #return void
*/
public function unserialize($serialized)
{
list($this->id) = unserialize($serialized);
}
/**
* Returns the roles granted to the user.
*
* <code>
* public function getRoles()
* {
* return array('ROLE_USER');
* }
* </code>
*
* Alternatively, the roles might be stored on a ``roles`` property,
* and populated in any number of different ways when the user object
* is created.
*
* #return Role[] The user roles
*/
public function getRoles()
{
return $this->roles;
}
/**
* Returns the password used to authenticate the user.
*
* This should be the encoded password. On authentication, a plain-text
* password will be salted, encoded, and then compared to this value.
*
* #return string The password
*/
public function getPassword()
{
return $this->password;
}
/**
* Returns the salt that was originally used to encode the password.
*
* This can return null if the password was not encoded using a salt.
*
* #return string|null The salt
*/
public function getSalt()
{
return $this->salt;
}
/**
* Returns the username used to authenticate the user.
*
* #return string The username
*/
public function getUsername()
{
return $this->username;
}
/**
* Removes sensitive data from the user.
*
* This is important if, at any given point, sensitive information like
* the plain-text password is stored on this object.
*/
public function eraseCredentials()
{
// TODO: Implement eraseCredentials() method.
}
/**
* Checks whether the user's account has expired.
*
* Internally, if this method returns false, the authentication system
* will throw an AccountExpiredException and prevent login.
*
* #return Boolean true if the user's account is non expired, false otherwise
*
* #see AccountExpiredException
*/
public function isAccountNonExpired()
{
return true;
}
/**
* Checks whether the user is locked.
*
* Internally, if this method returns false, the authentication system
* will throw a LockedException and prevent login.
*
* #return Boolean true if the user is not locked, false otherwise
*
* #see LockedException
*/
public function isAccountNonLocked()
{
return true;
}
/**
* Checks whether the user's credentials (password) has expired.
*
* Internally, if this method returns false, the authentication system
* will throw a CredentialsExpiredException and prevent login.
*
* #return Boolean true if the user's credentials are non expired, false otherwise
*
* #see CredentialsExpiredException
*/
public function isCredentialsNonExpired()
{
return true;
}
/**
* Checks whether the user is enabled.
*
* Internally, if this method returns false, the authentication system
* will throw a DisabledException and prevent login.
*
* #return Boolean true if the user is enabled, false otherwise
*
* #see DisabledException
*/
public function isEnabled()
{
return $this->isActive;
}
/**
* Set username
*
* #param string $username
* #return SystemUser
*/
public function setUsername($username)
{
$this->username = $username;
return $this;
}
/**
* Set email
*
* #param string $email
* #return SystemUser
*/
public function setEmail($email)
{
$this->email = $email;
return $this;
}
/**
* Get email
*
* #return string
*/
public function getEmail()
{
return $this->email;
}
/**
* Set salt
*
* #param string $salt
* #return SystemUser
*/
public function setSalt($salt)
{
$this->salt = $salt;
return $this;
}
/**
* Set password
*
* #param string $password
* #return SystemUser
*/
public function setPassword($password)
{
$this->password = $password;
return $this;
}
/**
* Set isActive
*
* #param boolean $isActive
* #return SystemUser
*/
public function setIsActive($isActive)
{
$this->isActive = $isActive;
return $this;
}
/**
* Get isActive
*
* #return boolean
*/
public function getIsActive()
{
return $this->isActive;
}
/**
* Add roles
*
* #param \MyBundle\MainBundle\Entity\Role $role
* #return SystemUser
*/
public function addRole(\MyBundle\MainBundle\Entity\Role $role)
{
$this->roles[] = $role;
return $this;
}
public function removeRole(\MyBundle\MainBundle\Entity\Role $role) {
$this->roles->removeElement($role);
}
/**
* Get discr
*
* #return int
*/
public function getDiscr() {
return $this->discr;
}
/**
* Set discr
*
* #param $discr
* #return \MyBundle\MainBundle\Entity\SystemUser
*/
public function setDiscr($discr) {
$this->discr = $discr;
return $this;
}
}
My SystemUserRepository
class SystemUserRepository extends EntityRepository implements UserProviderInterface
{
public function loadUserByUsername($username)
{
$query = $this->createQueryBuilder('su')
->select('su, sr') //SystemUser, SystemRoles
->leftJoin('su.roles', 'sr')
->where('su.username = :username OR su.email = :email')
->setParameter('username', $username)
->setParameter('email', $username)
->getQuery();
try {
$user = $query->getSingleResult();
} catch (NoResultException $e) {
$message = 'Unable to find user \'' . $username . '\'';
throw new UsernameNotFoundException($message, 0, $e);
}
return $user;
}
public function refreshUser(UserInterface $user)
{
$class = get_class($user);
if (!$this->supportsClass($class)) {
throw new UnsupportedUserException(
'Instances of \'' . $class . '\' are not supported'
);
}
return $this->find($user->getId());
}
public function supportsClass($class)
{
return $this->getEntityName() === $class
|| is_subclass_of($class, $this->getEntityName());
}
}
and finally my Login
public function loginAction() {
$request = $this->getRequest();
$session = $request->getSession();
if ($request->attributes->has(SecurityContext::AUTHENTICATION_ERROR)) {
$error = $request->attributes->get(SecurityContext::AUTHENTICATION_ERROR);
} else {
$error = $session->get(SecurityContext::AUTHENTICATION_ERROR);
$session->remove(SecurityContext::AUTHENTICATION_ERROR);
}
return $this->render(
'MyBundleMainBundle:Security:login.html.twig',
array(
'last_username' => $session->get(SecurityContext::LAST_USERNAME),
'error' => $error,
'csrf_token' => $this->container->get('form.csrf_provider')->generateCsrfToken('authenticate'),
)
);
}
Oh, and if it's of any consequence, my registration controller.
public function createUserAction(Request $request) {
$entityManager = $this->getDoctrine()->getManager();
$form = $this->createForm('user_registration', new Registration());
$form->handleRequest($request);
if ($form->isValid()) {
$registration = $form->getData();
//Handle encoding here...
$encoderFactory = $this->get('security.encoder_factory');
$encoder = $encoderFactory->getEncoder($registration->getUser());
$password = $encoder->encodePassword($registration->getUser()->getPassword(), $registration->getUser()->getSalt());
$registration->getUser()->setPassword($password);
$entityManager->persist($registration->getUser());
$entityManager->flush();
return $this->redirect($this->generateUrl('dashboard_homepage'));
}
return $this->render(
'MyBundleMainBundle:Security:registration.html.twig',
array(
'form' => $form->createView()
)
);
}
Sorry for the long post, hope someone can help me out here! Thanks so much!
change the following code in your SystemUser class:
/**
* #var string
*
* #ORM\Column(type="string", length=64)
*/
protected $password;
to
/**
* #var string
*
* #ORM\Column(type="string", length=255)
*/
protected $password;
I stumbled upon the same problem as you after following the guides on symfony.com. By comparing the results from the hashed password before and after being persisted to the database I could see that the length of the hashed password was 88 characters long, thus it was being truncated to 64 characters after being persisted to the database.
FOSUserBundle is also using a length of 255 on their password field, so I suppose it's a legit change.
I'm guessing you have already solved this problem since it was a while ago you posted it, but i thought I would help others out who, like I did, came here with the same problem.

symfony2 : user password set to empty after running this method

this methodi use it to add a new job but when i add a job the password of the that current user get its password set to empty cus the user object that i retrieve has no password and
symfony behaves like so for to secure the password any help would be much appreciated
` 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');
}
}
}
heres my job entity
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() ;
}
}
heres my 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';
}
}
and heres my log where i see the password updated
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])
well i found the issue it was caused by that eraseCredential method of the UserInterface in my User entity
<?php
public function eraseCredential(){
$this->password = null ;
}
i just had to empty it as it was doin to my password by commenting that line ; ]
2 kosaidpo
Your solution works because eraseCredentials() method is used to clear user sensitive data (means NOT secret, but the one that can be restored, the sense is like __sleep()) when serializing user object or saving it to database (that is what manual says). So when you attach user to job object and call #flush(), doctrine will check for changes in all objects connected with job and find that user object has changed because eraseCredentials() has erased password. That is why your user gets updated.
There is one more solution which could help you:
The Solution:
Change Tracking Policies from Doctrine documentation.
In short, you can add #ChangeTrackingPolicy("DEFERRED_EXPLICIT") annotation (as I did, because I'm using annotations. Captain Obvious =) ) to UserInterface implementation (in my case I'm using User class) and this will tell Doctrine not to check all 'connected' to job objects.
In this case doctrine will not check user object and save it with erased password, unless you will force it to do it with calling #persist(User object) manually.
But anyway, you should not do $this->password = null in your eraseCredentials() method.
It does seem strange, but you could always retrieve User object prior to binding it to a newly created job:
$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();
Also, I'm not really sure but I read somewhere that token isn't supposed to carry password due to it's security nature.... maybe that is your problem...

Categories