I am trying to move from manually specified users in security.yml to database users. I have read http://symfony.com/doc/current/book/security.html#loading-users-from-the-database and implemented their example, then expanded on it using a friend's user class. When I try to run php app/console doctrine:generate:entities I get the following error: Class MyFreelancer\PortalBundle\Entity\User contains 7 abstract methods and must therefor be declared abstract or implement the remaining methods and then a list of methods that goes off the page.
My code is as follows:
<?php
namespace MyFreelancer\PortalBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\Criteria;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Validator\Constraints as Assert;
use JMS\Serializer\Annotation as Ser;
use Gedmo\Mapping\Annotation as Gedmo;
use Symfony\Component\Security\Core\User\Role;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* User
*
* #ORM\Entity
* #ORM\Table(name="users")
* #Ser\ExclusionPolicy("all")
*/
class User implements UserInterface, \Serializable
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #Ser\Expose
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="role_id", type="integer")
* #Assert\Range(min=1)
*/
private $roleId;
/**
* #var string
*
* #ORM\Column(name="username", type="string", length=100)
* #Assert\Length(min=3, max=100)
* #Ser\Expose()
*/
private $username;
/**
* #var string
*
* #ORM\Column(name="password", type="string", length=2048)
* #Assert\Length(min=8, max=2048)
*/
private $password;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=100)
* #Assert\Length(min=3, max=100)
* #Ser\Expose()
*/
private $name;
/**
* #var string
*
* #ORM\Column(name="surname", type="string", length=100)
* #Assert\Length(min=3, max=100)
* #Ser\Expose()
*/
private $surname;
/**
* #var string
*
* #ORM\Column(name="email", type="string", length=200)
* #Assert\Email(checkMX=true)
* #Ser\Expose()
*/
private $email;
/**
* #var string
*
* #ORM\Column(name="cell", type="string", length=20, nullable=true)
* #Assert\Length(min=10, max=20)
* #Ser\Expose()
*/
private $cell;
}
?>
I have looked at Symfony2 Fatal error in Users Entity Provider, but I do not know what has to go into those methods if I have to implement them manually. Also, isn't doctine:generate:entities supposed to do that for you? If declaring the class as abstract is easier, how do I do that? What does that entail?
While we are on the topic, how do I save/retrieve the save user roles to the database, such as (from security.yml)
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
This is actually a second question and if it cannot be answered here then I will open a new topic. Thank you to everyone who has read this question.
The cookbook article about the entity provider at http://symfony.com/doc/current/cookbook/security/entity_provider.html shows how to set this up correctly.
Related
I am trying to use inside an entity another entity from another namespce but all I got is an error:
The class 'App\Entity\Gui\User' was not found in the chain configured namespaces App\Entity\Upv6
and the code:
namespace App\Entity\Upv6;
use App\Entity\Gui\User as User;
use Doctrine\ORM\Mapping as ORM;
/**
* ConfigSet
*
* #ORM\Table(name="config_set")
* #ORM\Entity(repositoryClass="App\Repository\ConfigSetRepository")
*/
class ConfigSet
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var User
*
* #ORM\ManyToOne(targetEntity="App\Entity\Gui\User")
* #ORM\JoinColumn(name="id", referencedColumnName="id",
nullable=false)
*/
private $user;
Looks like it is still searching in same namespace.
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();
}
}
I have these 3 entitites
Users.php
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Users
*
* #ORM\Table(name="users")
* #ORM\Entity(repositoryClass="AppBundle\Repository\UsersRepository")
*/
class Users
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="email", type="string", length=255, unique=true)
*/
private $email;
/**
* #var string
*
* #ORM\Column(name="password", type="string", length=20)
*/
private $password;
/**
* #var string
*
* #ORM\Column(name="phone", type="string", length=20)
*/
private $phone;
/**
* #var string
*
* #ORM\Column(name="type", type="string")
*/
private $type;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* #var int
*
* #ORM\Column(name="feedback", type="integer")
*/
private $feedback;
/**
* #var string
*
* #ORM\Column(name="picture", type="blob")
*/
private $picture;
/**
* #var int
*
* #ORM\Column(name="rating", type="integer", length=255)
*/
private $rating;
/**
* #var string
*
* #ORM\Column(name="info", type="text")
*/
private $info;
/**
* #var \DateTime
*
* #ORM\Column(name="datecreated", type="datetime")
*/
private $datecreated;
/**
* #ORM\Column(name="is_active", type="boolean")
*/
private $isActive;
}
client.php
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* client
*
* #ORM\Table(name="client")
* #ORM\Entity(repositoryClass="AppBundle\Repository\clientRepository")
*/
class client extends Users
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var int
*
* #ORM\Column(name="numberofjobsposted", type="integer")
*/
private $numberofjobsposted;
/**
* #var string
*
* #ORM\Column(name="clienttype", type="string", length=255)
*/
private $clienttype;
}
sprovider.php
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* sprovider
*
* #ORM\Table(name="sprovider")
* #ORM\Entity(repositoryClass="AppBundle\Repository\sproviderRepository")
*/
class sprovider extends Users
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var array
*
* #ORM\Column(name="interestedin", type="simple_array")
*/
private $interestedin;
/**
* #var int
*
* #ORM\Column(name="numofsuccjobs", type="integer")
*/
private $numofsuccjobs;
/**
* #var string
*
* #ORM\Column(name="sprovidertype", type="string", length=255)
*/
private $sprovidertype;
/**
* #var string
*
* #ORM\Column(name="address", type="string", length=255)
*/
private $address;
/**
* #var string
*
* #ORM\Column(name="postcode", type="string", length=255)
*/
private $postcode;
}
So I achieved that the extends statement provides the Users properties in the client and sprovider tables in MySQL. That's awesome. What I want now is to make the relations so that when I add a new client for example, both the tables Users and client add a new user/client in MySQL, and they have same id too.
the type() property in the Users entity i would like to be optional for the type of user I create. Example : I create a new client and in the Users table in MySQL the type is set to "CLIENT".
I read this and so far I think it has to be ManyToMany relation but It's quite confusing to me.
How to make those relations in the entities and then how to use them in the controller? If possible, please provide an example.
I think you're confused about the reasons to use inheritance.
The idea is that you have base class, in this case User, and that can be extended to provide variations of that class, in this case client (you should capitalise this) and sprovider.
Ideally, you would not have a User table, only the other 2.
In doctrine, this is called a mapped super-class.
A mapped superclass is an abstract or concrete class that provides persistent entity state and mapping information for its subclasses, but which is not itself an entity. Typically, the purpose of such a mapped superclass is to define state and mapping information that is common to multiple entity classes.
see the documentation here
you can link properties using relationships, this is their example.
<?php
/** #MappedSuperclass */
class MappedSuperclassBase
{
/** #Column(type="integer") */
protected $mapped1;
/** #Column(type="string") */
protected $mapped2;
/**
* #OneToOne(targetEntity="MappedSuperclassRelated1")
* #JoinColumn(name="related1_id", referencedColumnName="id")
*/
protected $mappedRelated1;
// ... more fields and methods
}
/** #Entity */
class EntitySubClass extends MappedSuperclassBase
{
/** #Id #Column(type="integer") */
private $id;
/** #Column(type="string") */
private $name;
// ... more fields and methods
}
I know this seems like a very basic question but PLEASE before voting down, read until the end.
This question came to my mind when using Codeigniter along with Doctrine 2.
I have noticed that, at least when using annotation, the synthax is slightly different than when using Doctrine 2 with Symfony2 and I am wondering why.
I'll provide an example:
This is a class in Symfony2 with a Many To One relation:
<?php
namespace Pondip\LakeBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\ORM\Mapping as ORM;
/**
* Lake
*
* #ORM\Table(name="pondip_lake")
* #ORM\Entity(repositoryClass="Pondip\LakeBundle\Entity\LakeRepository")
*/
class Lake
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var integer
* #Assert\Type(type="Pondip\LakeBundle\Entity\Venue")
*
* #ORM\ManyToOne(targetEntity="Pondip\LakeBundle\Entity\Venue")
* #ORM\JoinColumn(name="venue_id", referencedColumnName="id")
*/
private $venue;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* #var text
*
* #ORM\Column(name="description", type="text", nullable=true)
*/
private $description;
/**
* #var integer
*
* #ORM\ManyToOne(targetEntity="Pondip\UserAccountBundle\Entity\User")
* #ORM\JoinColumn(name="created_by", referencedColumnName="id", nullable=true)
*/
private $createdBy;
please pay attention to all the #ORM\ everywhere.
Now, when using this with codeigniter2/Doctrine2.3.0 I have Mapping errors in my console.
But, when following some tuts, I ended up removing all of the ORM\ (and the corresponding use Doctrine\ORM\Mapping as ORM) and it worked.
This work :
<?php
namespace Entity;
/**
* Friend Model
*
* #Entity
* #Table(name="friend")
* #author Miles Yohann Merran <hello_miles#hotmail.com>
*/
class Friend
{
/**
* #Id
* #Column(type="integer", nullable=false)
* #GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #Column(type="string", length=32, unique=true, nullable=false)
*/
protected $name;
/**
* #Column(type="text", nullable=false)
*/
protected $description;
/**
* #Column(type="string", length=64, nullable=false)
*/
protected $picture;
/**
* #Column(type="string", length=64, nullable=false)
*/
protected $genre;
/**
* #ManyToOne(targetEntity="User", inversedBy="friends")
* #JoinColumn(nullable=false)
*/
protected $user;
/**
* #var datetime $date
*
* #Column(name="date", type="datetime")
*/
protected $date;
When this doesn't work (pay attention at the ORM)
<?php
namespace Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Friend Model
*
* #Entity
* #Table(name="friend")
* #author Miles Yohann Merran <hello_miles#hotmail.com>
*/
class Friend
{
/**
* #Id
* #Column(type="integer", nullable=false)
* #GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #Column(type="string", length=32, unique=true, nullable=false)
*/
protected $name;
/**
* #Column(type="text", nullable=false)
*/
protected $description;
/**
* #Column(type="string", length=64, nullable=false)
*/
protected $picture;
/**
* #Column(type="string", length=64, nullable=false)
*/
protected $genre;
/**
* #ORM\ManyToOne(targetEntity="User", inversedBy="friends")
* #ORM\JoinColumn(nullable=false)
*/
protected $user;
/**
* #var datetime $date
*
* #ORM\Column(name="date", type="datetime")
*/
protected $date;
Why ? What is the difference ?
EDIT: To be exact, I tried 2 entites, with the same structure, one with #ORM\ before avery annotation sentence, and one without. The one with #ORM\ wasn't managed properly by Doctrine 2 when using the terminal commands and the one without works perfectly well. I wasn't able to find any documentation about that even if I clearly see both in the doc and the src that there is Doctrine Common, Doctrine ORM and Doctrine DBAL. Aren't they compatible between each other ? how to properly manage this difference ? especially when working with another framework than S (like CI2)
Thank you
Long story short, in symfony the doctrine annotation reader is an AnnotationReader, whereas in CI using the doctrine Setup::createAnnotationMetadataConfiguration helper, you have the SimpleAnnotationReader by default.
You should be able to have the same behavior as in symfony by passing false to the 5th argument $useSimpleAnnotationReader of Setup::createAnnotationMetadataConfiguration.
I am trying to remove comments from a parent entity, I remember doing this on my last website but now it's not working..
My entity - users
namespace Application\Entities;
use Doctrine\ORM\Mapping AS ORM,
Doctrine\Common\Collections\ArrayCollection;
/**
* Loan
*
* #ORM\Table(name="users")
* #ORM\Entity
*/
class Users{
/**
* #var integer $id
*
* #ORM\Column(type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string $username
*
* #ORM\Column(type="string", length=45, nullable=false)
*/
private $username;
/**
* #var ArrayCollection
*
* #ORM\OneToMany(targetEntity="Comments", mappedBy="author", cascade={"persist", "remove"})
*/
private $comments;
public function getComments(){
return $this->comments;
}
and my comments table:
namespace Application\Entities;
use Doctrine\ORM\Mapping AS ORM,
Doctrine\Common\Collections\ArrayCollection;
/**
* Loan
*
* #ORM\Table(name="comments")
* #ORM\Entity
*/
class Comments{
/**
* #var integer $id
*
* #ORM\Column(type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var integer $user_id
*
* #ORM\Column(type="integer", length=15, nullable=false)
*/
private $user_id
/**
* #var Loan
*
* #ORM\ManyToOne(targetEntity="Users", inversedBy="comments",cascade={"persist"})
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
* })
*/
private $author;
This is fine, it works and I get all collections called comments in the users repository..
Now, I usually do this when I need to delete:
$commentToDelete = $this->em->getRepository('Entities\Comments')->findOneById(375);
$userResults = $this->em->getRepository('Entities\Users')->findOneById(23);
$userResults->getComments()->removeElement($commentToDelete);
$this->em->flush();
Nothing deletes, neither it throws an exception to tell me it hasn't.
I doctrine flushed it too, checked the db, and it's still there..
UPDATE:
Straight after I removeElement, I looped through the user id = 23 dataset, and the comment data for id375 is not there... so it removed it from the collection but not from the DB, and I thought $em->flush() is supposed to do this?
Please advise
Thanks
You need to use
$em->remove($commentToDelete);
$em->flush();
Because the mapping is held in the comment you need to remove this entity to remove the reference before you flush which will save the state to the db.