Creating a password recovery table - Error when inserting a value - php

I have a User class with attributes like id, name, mail, etc.
I'm implementing the password recovery process, so I created a password_recovery table with these columns:
id
user_id
token
createdDate
expiryDate
isExpired
This is my PasswordRecovery Class:
namespace \UserBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ORM\Entity
* #ORM\Table(name="password_recovery")
*/
class PasswordRecovery {
/**
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="User")
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
private $idUser;
/**
* #ORM\Column(type="string")
*/
private $token;
/**
* #ORM\Column(type="datetime")
* #Assert\DateTime()
*/
private $createdDate;
/**
* #ORM\Column(type="datetime")
* #Assert\DateTime()
*/
private $expireDate;
/**
* #ORM\Column(type="boolean")
*/
private $expired; }
When the user wants to recover his password, he must enter his email. If the mail is in the db, I create a PasswordRecovery Object and store it in the db. This is how I'm doing that: (small part of the code)
if (!empty($resetMail))
{
$recovery = new PasswordRecovery();
$token = bin2hex(openssl_random_pseudo_bytes(16));
$recovery->setToken($token);
$userId = $resetMail->getId();
$recovery->setIdUser($userId);
$recovery->setCreatedDate(new \DateTime('now'));
$expiry = (new \DateTime('now + 1day'));
$recovery->setExpireDate($expiry);
$recovery->setExpired(false);
$em = $this->getDoctrine()->getManager();
$em->persist($recovery);
$em->flush(); }
I got this error:
Catchable Fatal Error: Argument 1 passed to \UserBundle\Entity\PasswordRecovery::setIdUser() must be an instance of \UserBundle\Entity\User, integer given, called in /home/user/project/src/UserBundle/Controller/AccountController.php on line 553 and defined
Why?

You need to use setIdDUser(User). This is a proxy object because it's a reference to another table (entity)
In the same way when you call getIdUser() you will get a proxy object again, which you will have to call getId() on if you want the int value.

Related

Symfony: The given entity of type cannot be added to the identity map

I am getting the following exception whilst trying to persist a entity and associative entity to the database. Not sure what i'm doing wrong here:
Exception:
The given entity of type 'AppBundle\Entity\User'
(AppBundle\Entity\User#0000000065c3019f00000000123d7c75) has no
identity/no id values set. It cannot be added to the identity map.
Entities:
/**
* #ORM\Entity
*/
class User
{
/**
* #ORM\Column(type="string")
*/
private $name;
/**
* #ORM\OneToOne(targetEntity="Address", inversedBy="user")
* #ORM\JoinColumn(name="address_id", referencedColumnName="id")
* #ORM\Id
*/
protected $address;
}
/**
* #ORM\Entity
*/
class Address
{
/**
* #ORM\Column(name="id", type="integer")
* #ORM\Id
*/
private $id
/**
* #ORM\OneToOne(targetEntity="User", mappedBy="address", cascade={"all"}, fetch="LAZY")
*/
private $user;
}
Entity creation:
$user = new User();
$address = new Address();
$address->setUser($user->setAddress($address));
$this->getDoctrine()->getManager()->persist($user);
$this->getDoctrine()->getManager()->persist($address);
$this->getDoctrine()->getManager()->flush();
Please see: Doctrine OneToOne identity through foreign entity exception on flush which helped to resolve this issue.
The actual object address needs to be saved by the EntityManager first. Just giving the class as reference to the other class does not make the entityManager aware of the fact both classes exists. With this in mind, the following code allows me to persist these objects to the database. I belive this is because doctrine needs to persist the address object first, so that it can retrieve the id for the primary & foreign key relationship in the User object.
$user = new User();
$address = new Address();
$this->getDoctrine()->getManager()->persist($address);
$this->getDoctrine()->getManager()->flush();
$address->setUser($user->setAddress($address));
$this->getDoctrine()->getManager()->persist($user);
$this->getDoctrine()->getManager()->flush();
You MUST specify an ID for doctrine entity
like this:
class User
{
/**
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(type="string")
*/
private $name;
/**
* #ORM\OneToOne(targetEntity="Address", inversedBy="user")
* #ORM\JoinColumn(name="address_id", referencedColumnName="id")
* #ORM\Id
*/
protected $address;
}

No identifier/primary key specified for Abstract Class

I am trying implement this mapping strategy. I defined abstract class with id and other fields. but I keep getting following error:
No identifier/primary key specified for Entity "AppBundle\Entity\AbstractItem". Every Entity must have an identifier/primary key. (500 Internal Server Error)
This is my class. As you can see, unique identifier $id was specified
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\InheritanceType("JOINED")
* #ORM\DiscriminatorColumn(name="type", type="string")
* #ORM\DiscriminatorMap({"post" = "Post", "group" = "Group"})
*/
class AbstractItem
{
/**
* #var int
*
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var \DateTime
*/
protected $published;
protected $object;
protected $target;
/**
* #return mixed
*/
public function getId()
{
return $this->id;
}
}
This abstract class shouldn't be an actual entity in the database.
Try to put #ORM\MappedSuperClass instead of #ORM\Entity
try this please:
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
Instead of this:
/**
* #var int
*
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
You need to specify the column id inside comment

set FOSUSERBUNDLE with existing table user (in symfony2)

I am supposed to built a project with symfony2 for a back end, and angular2 for front end.
For handling user action(authentification,remember me ...) I'am trying to used FOSUSERBUNDLE.
Let me specify that I'am using and existing database which contains a table with many attributes like (id, category, title, name, email, number, adress, ...). Some of attributes are not the same User in FOSUSERBUNDLE.
My question is how can I set FOSUSERBUNDLE to make it work with my existing table without brook it?
When I extend my class customer to BaserUser of FOSUserbundle it broke and changed my table structure
below
<?php
// src/AppBundle/Entity/User.php
namespace AppBundle\Entity;
use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="fos_user")
*/
class customer extends BaseUser
{
/**
* #var float
*
* #ORM\Column(name="scoring", type="float", precision=10, scale=0, nullable=false)
*/
private $scoring = '0';
/**
* #var integer
*
* #ORM\Column(name="id_type", type="integer", nullable=false)
*/
private $idType = '4';
/**
* #var integer
*
* #ORM\Column(name="id_categorie", type="integer", nullable=false)
*/
private $idCategorie = '0';
/**
* #var string
*
* #ORM\Column(name="autorisation_prelevement", type="string", nullable=false)
*/
private $autorisationPrelevement = 'N';
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string")
*/
protected $addresse;
public function __construct()
{
parent::__construct();
}
}

Error with relationships between entities and setter function

I'm from yesterday fighting with this problem, and I don`t find any solution.
I have two entities interrelated as follows:
// src/FEB/UserBundle/Entity/User.php
namespace FEB\UserBundle\Entity;
use FOS\UserBundle\Entity\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="feb_user")
*/
class User extends BaseUser
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
public function __construct()
{
parent::__construct();
// tu propia lógica
}
}
Account.php
namespace FEB\UserBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Account
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="FEB\UserBundle\Entity\AccountRepository")
*/
class Account
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* Many-To-Many, Unidirectional
*
* #var ArrayCollection $idusr
*
* #ORM\ManyToMany(targetEntity="\FEB\UserBundle\Entity\User")
* #ORM\JoinTable(name="accounts_users",
* joinColumns={#ORM\JoinColumn(name="account_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="usr_id", referencedColumnName="id")}
* )
*/
private $idusr;
public function __construct() {
$this->idusr = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Set idusr
*
* #param string $idusr
* #return Account
*/
public function setIdusr($idusr)
{
$this->idusr = $idusr;
return $this;
}
/**
* Get idusr
*
* #return integer
*/
public function getIdusr()
{
return $this->idusr;
}
There is no form to be built, since the user does not have to enter any data, only use the setter for this, not the buildForm method in AccountType.
In Account entity , all the setter function work fine except setter of the field related to the User entity, "setIdusr". It throws me this error:
Catchable Fatal Error: Argument 1 passed to Doctrine\Common\Collections\ArrayCollection::__construct() must be of the type array, string given, called in C:\xampp\htdocs\FEB\vendor\doctrine\orm\lib\Doctrine\ORM\UnitOfWork.php on line 528 and defined in C:\xampp\htdocs\FEB\vendor\doctrine\collections\lib\Doctrine\Common\Collections\ArrayCollection.php line 47
How I can fix this?
Thank you in advanced.
Edit: I will try to explain how it should be functioning: When I create a new account, it should automatically create an entry in the relationship table "account_user" with the id of the new account id and user id.
as far as i can see now, in the parent class you're $id is private and than in the child class you're defining it again as protected.
so either don't use the same variable name.
or define it in the parent as protected.
I've already solved!!!,
I had to create a "addUser" method in Account entity and then I had to pass a User object parameter.
I was passing a string as parameter and that was the error.

Symfony2 how to join on many-to-many relations using querybuilder?

Being new to symfony2 and querybuilder, I am trying to select all my containers but limiting the result to only those for which the logged-in user has access.
With the current code I get this error:
Notice: Undefined index: Container in /var/www/biztv_symfony/vendor/doctrine/lib/Doctrine/ORM/Query/SqlWalker.php line 746
Here is my attempt at the query (I have tried a couple of options from this and other forum sites and still can't seem to understand it right...)
public function indexAction()
{
//Get the requisits
$companyId = $this->container->get('security.context')->getToken()->getUser()->getCompany()->getId();
$em = $this->getDoctrine()->getEntityManager();
//Fetch the containers
$repository = $this->getDoctrine()->getRepository('BizTVContainerManagementBundle:Container');
$query = $repository->createQueryBuilder('c')
->innerJoin('c.users','u')
->where('c.company = :company')
->setParameter('company', $companyId)
->orderBy('c.name', 'ASC')
->getQuery();
$containers = $query->getResult();
I keep track of access with a many-to-many relation, this is my user entity...
<?php
// src/BizTV/UserBundle/Entity/User.php
namespace BizTV\UserBundle\Entity;
use FOS\UserBundle\Entity\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
use BizTV\BackendBundle\Entity\company as company;
/**
* #ORM\Entity
* #ORM\Table(name="fos_user")
*/
class User extends BaseUser
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var object BizTV\BackendBundle\Entity\company
*
* #ORM\ManyToOne(targetEntity="BizTV\BackendBundle\Entity\company")
* #ORM\JoinColumn(name="company", referencedColumnName="id", nullable=false)
*/
protected $company;
/**
* #ORM\ManyToMany(targetEntity="BizTV\ContainerManagementBundle\Entity\Container", inversedBy="User")
* #ORM\JoinTable(name="access")
*/
private $access;
public function __construct()
{
parent::__construct();
$this->access = new \Doctrine\Common\Collections\ArrayCollection();
}
//getters and setters...
This is my container entity:
<?php
namespace BizTV\ContainerManagementBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use BizTV\UserBundle\Entity\User as user;
/**
* BizTV\ContainerManagementBundle\Entity\Container
*
* #ORM\Table(name="container")
* #ORM\Entity
*/
class Container
{
/**
* #var integer $id
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string $name
* #Assert\NotBlank(message = "Du måste ange ett namn för området")
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
//TODO: form handler assuring no name is used twice in same company
/**
* #var object BizTV\BackendBundle\Entity\company
*
* #ORM\ManyToOne(targetEntity="BizTV\BackendBundle\Entity\company")
* #ORM\JoinColumn(name="company", referencedColumnName="id", nullable=false)
*/
protected $company;
/**
* #ORM\ManyToMany(targetEntity="BizTV\UserBundle\Entity\User", mappedBy="Container")
*/
private $users;
public function __construct() {
$this->users = new \Doctrine\Common\Collections\ArrayCollection();
}
In the Container entity, when you specify the $users property mapping, the value of mappedBy is important: you need to specify the name of the inverse property in the User class.
Here, we have, Container::$users <-> User::$access.
Change your annotations to:
class User
{
/**
* #ORM\ManyToMany(targetEntity="BizTV\ContainerManagementBundle\Entity\Container", inversedBy="users")
* #ORM\JoinTable(name="access")
*/
private $access;
}
class Container
{
/**
* #ORM\ManyToMany(targetEntity="BizTV\UserBundle\Entity\User", mappedBy="access")
*/
private $users;
}
I encourage you to read the doctrine orm documentation part about associations, and verify and fix this in all your associations.

Categories