The idea is that extending my Employee class and setting my isManager property would store it as true in the database whenever a DepartmentHead entity was created. This isn't working. Does anyone know why DepartmentHead entities are being stored with isManager equal to false?
/**
* #Entity
* #InheritanceType("JOINED")
* #DiscriminatorColumn(name="discr", type="string")
* #DiscriminatorMap({"employee" = "Employee", "dphead" = "DepartmentHead"})
*/
class Employee
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
protected $id;
/**
* #ORM\Column(type="boolean")
*/
protected static $isManager = false;
/**
* #return bool
*/
public static function isManager(): bool
{
return static::$isManager;
}
/**
* #param bool $isManager
*/
public static function setIsManager(bool $isManager): void
{
static::$isManager = $isManager;
}
}
/**
* #Entity()
*/
class DepartmentHead extends Employee
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
protected $id;
protected static $isManager = true;
}
Do not use static properties, Doctrine cannot cope with them properly.
With a common property, everything works as expected.
/**
* #ORM\Column(type="boolean")
*/
protected $isManager = true;
Related
I'm trying to fetch an object from MySQL database using doctrine. It has one-to-one relation with other one. I'm getting this error: Notice: Undefined index: id
What I should correct to make this working?
My fetch code is very simple, I try to fetch all objects:
$emArt = $this->getDoctrine()->getRepository(Article::class);
$articles = $emArt->findAll();
Model is as following:
Article.php
/**
* #ORM\Entity
* #ORM\Table(name="Article")
*/
class Article
{
/**
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $ID;
/**
* #ORM\OneToOne(targetEntity="ArticleTypes", inversedBy="articleTypeId")
* #ORM\JoinColumn(name="articleTypeId", referencedColumnName="id")
*/
private $articleType;
/**
* #ORM\Column(name="articleName", type="text")
*/
private $articleName;
/**
* #ORM\Column(name="content", type="text")
*/
private $content;
/**
* #ORM\Column(name="image", type="string")
* #Assert\File(mimeTypes={ "image/png" })
*/
public $image;
public function getArticleImage()
{
return $this->image;
}
public function setArticleImage($newImage)
{
$this->image = $newImage;
}
public function getArticleContent()
{
return $this->content;
}
public function setArticleContent($name)
{
$this->content = $name;
}
public function getArticleName()
{
return $this->articleName;
}
public function setArticleName($name)
{
$this->articleName = $name;
}
public function getArticleType()
{
return $this->articleType;
}
public function setArticleType($type)
{
$this->articleType = $type;
}
}
ArticleTypes.php
/**
* #ORM\Entity
* #ORM\Table(name="ArticleTypes")
*/
class ArticleTypes
{
/**
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\OneToOne(targetEntity="Article", mappedBy="articleTypeId")
*/
private $ID;
/**
* #ORM\Column(name="articleType", type="text")
*/
private $articleType;
public function getArticleType()
{
return $this->articleType;
}
public function setArticleType($newType)
{
$this->articleType = $newType;
}
}
It's a PHP Notice no ? You should have also the line number in a file with the error ?
But I saw errors in your doctrine mapping too : You can't use doctrine annotation like this with fields, you should link your relationship to objects :
/**
* #ORM\Entity
* #ORM\Table(name="Article")
*/
class Article
{
/**
* #ORM\OneToOne(targetEntity="ArticleTypes", inversedBy="article")
* #ORM\JoinColumn(name="articleTypeId", referencedColumnName="id")
*/
private $articleType;
....
}
And :
/**
* #ORM\Entity
* #ORM\Table(name="ArticleTypes")
*/
class ArticleTypes
{
/**
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var Article $article
* #ORM\OneToOne(targetEntity="Article", mappedBy="articleType")
*/
private $article;
....
}
Even if you have a one to one relationship you can have different ids.
I am working on a login page, where it should be possible to login with different socialnetwork logins (facebook, twitter, google, etc).
It should work like this: every user has the possibility to add the socialnetwork login that he/she wants, so I want to have it as an One User-> Many Socialnetworklogins relation.
What works: Data is stored in Database, but in the line
var_dump($user->getSocialnetworks());
I just get one Object, not all the ones that should be related to this user. I know that the function justATest adds just a socialnetworklogin to user 1, this was just a test.
<?php
namespace AppBundle\Entity\Registration;
use Doctrine\Common\Collections\ArrayCollection;
use HWI\Bundle\OAuthBundle\OAuth\Response\UserResponseInterface;
use HWI\Bundle\OAuthBundle\Security\Core\User\FOSUBUserProvider as BaseClass;
use Symfony\Component\Security\Core\User\UserInterface;
class FOSUBUserProvider extends BaseClass
{
public function justATest(UserResponseInterface $response)
{
// get user_id and socialnetworkname from response
$userIdInSocialNetwork = $response->getUsername();
$socialnetwork = $response->getResourceOwner()->getName();
$login= new UserInSocialNetworks();
$login->setSocialIdentyfier($response->getEmail());
$login->setSocialNetworkSlug($socialnetwork);
$user = $this->userManager->findUserBy(array(
'id' => 1)
);
$login->setUserId($user);
$user->addSocialNetwork($login);
$this->userManager->updateUser($user);
$users= $this->userManager->findUsers();
var_dump($users);
var_dump($socialnetwork);
var_dump($user->getSocialnetworks());
die();
} }
The User Class:
<?php
/*
* This is the User class, depending on fos_userBundle
*/
namespace AppBundle\Entity\Registration;
use Doctrine\Common\Collections\ArrayCollection as ArrayCollection;
use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="user")
*/
class User extends BaseUser
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\OneToMany(targetEntity="UserInSocialNetworks", mappedBy="user_id", cascade={"persist", "remove"})
* #var ArrayCollection|null
*/
private $socialnetworks;
/**
* #var string
*
* #ORM\Column(name="family_name",type="string", length=255, nullable=true)
*/
private $familyName;
/**
* #var string
*
* #ORM\Column(name="given_name",type="string", length=255, nullable=true)
*/
private $givenName;
public function __construct()
{
parent::__construct();
$this->socialnetworks = new ArrayCollection();
}
/**
* #return string
*/
public function getFamilyName()
{
return $this->familyName;
}
/**
* #param string $familyName
*/
public function setFamilyName($familyName)
{
$this->familyName = $familyName;
}
/**
* #return string
*/
public function getGivenName()
{
return $this->givenName;
}
/**
* #param string $givenName
*/
public function setGivenName($givenName)
{
$this->givenName = $givenName;
}
/**
* #return ArrayCollection
*/
public function getSocialnetworks()
{
return $this->socialnetworks;
}
/**
* #param Collection UserInSocialNetworks
*/
public function setSocialnetworks($socialnetworks)
{
$this->socialnetworks = $socialnetworks;
}
/**
* #param UserInSocialNetwork
*/
public function addSocialNetwork($socialnetwork)
{
$this->getSocialnetworks()->add($socialnetwork);
}
}
The Class where Socialnetworks for Users are stored:
<?php
namespace AppBundle\Entity\Registration;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* UserInSocialNetworks
*
* #ORM\Table(name="user_in_social_networks")
* #ORM\Entity(repositoryClass="AppBundle\Repository\Registration\UserInSocialNetworksRepository")
*/
class UserInSocialNetworks
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="User", inversedBy="socialnetworks")
* #ORM\JoinColumn(name="user_id")
* #var User
*
*/
private $userId;
/**
* #var int
*
* #ORM\Column(name="social_network_slug", type="string", length=255, nullable=true)
*/
private $socialNetworkSlug;
/**
* #var string
*
* #ORM\Column(name="social_identifier", type="string", length=255, nullable=true)
*/
private $socialIdentyfier;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set userId
*
* #param integer $userId
*
* #return UserInSocialNetworks
*/
public function setUserId($userId)
{
$this->userId = $userId;
return $this;
}
/**
* Get userId
*
* #return int
*/
public function getUserId()
{
return $this->userId;
}
/**
* #return int
*/
public function getSocialNetworkSlug()
{
return $this->socialNetworkSlug;
}
/**
* #param int $socialNetworkSlug
*/
public function setSocialNetworkSlug($socialNetworkSlug)
{
$this->socialNetworkSlug = $socialNetworkSlug;
}
/**
* #return string
*/
public function getSocialIdentyfier()
{
return $this->socialIdentyfier;
}
/**
* #param string $socialIdentyfier
*/
public function setSocialIdentyfier($socialIdentyfier)
{
$this->socialIdentyfier = $socialIdentyfier;
}
}
This is what I get
object(Doctrine\ORM\PersistentCollection)[545]
private 'snapshot' =>
array (size=1) <------- just one
0 =>
object(AppBundle\Entity\Registration\UserInSocialNetworks)[336]
private 'id' => int 5 <---- I added already 5 line with my code to database
private 'userId' =>
object(AppBundle\Entity\Registration\User)[516]
...
private 'socialNetworkSlug' => string 'google' (length=6)
private 'socialIdentyfier' => string 'blablabla#googlemail.com' (length=24)
sorry, my fault,
the solution was to correct the relations:
class UserInSocialNetworks
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* Many Socialnetwork Logins have one User
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Registration\User", inversedBy="socialnetworks")
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
*
*/
private $user;
and
class User extends BaseUser
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* One User can have many social networks
* #ORM\OneToMany(targetEntity="UserInSocialNetworks", mappedBy="user", cascade={"remove"})
*/
private $socialnetworks;
im new to Doctrine and ORM in general.
I got 4 user types (Admin, Caretaker, Child, Personal).
They all got some of the same columns (id, name, mail, password, created, type & group)
and they got a few columns special to each of them (Caretaker has a child id etc.)
I'm not quite sure how i should map this.
Like should i make my user types extend the User, giving the Child table the user columns, or what would be best practice here?
I assume the the option to use extend would force some more work when doing a login?
User.php
/**
* #MappedSuperclass
* #Entity #Table(name="users")
*/
class User
{
/**
* #Id #GeneratedValue #Column(type="integer")
* #var int
**/
protected $id;
/**
* #Column(type="string")
* #var string
**/
protected $name;
/**
* #Column(type="string")
* #var string
**/
protected $mail;
/**
* #Column(type="string")
* #var string
**/
protected $password;
/**
* #Column(type="datetime")
**/
protected $created;
/**
* #Column(type="datetime")
**/
protected $lastlogin;
/**
* #ManyToOne(targetEntity="Group")
* #JoinColumn(name="group_id", referencedColumnName="id")
*/
protected $group;
/**
* #ManyToOne(targetEntity="Type")
* #JoinColumn(name="type_id", referencedColumnName="id")
*/
protected $type;
public function __construct() {}
public function getId() { return $this->id; }
public function getName() { return $this->name; }
public function getMail() { return $this->mail; }
public function getCreated() { return $this->mail; }
public function getLastLogin() { return $this->lastlogin; }
public function getGroup() { return $this->group; }
public function getType() { return $this->type; }
public function setName($name) { $this->name = $name; }
public function setMail($mail) { $this->mail = $mail; }
public function setCreated() { $this->created = new DateTime("now"); }
public function setLastLogin() { $this->lastlogin = new DateTime("now"); }
public function setGroup($group) { $this->group = $group; }
public function setType($type) { $this->type = $type; }
}
Child.php
// src/Child.php
use Doctrine\Common\Collections\ArrayCollection;
/**
* #Entity #Table(name="child")
*/
class Child extends User
{
/**
* #Id #OneToOne(targetEntity="User")
* #JoinColumn(name="id", referencedColumnName="id")
**/
protected $id;
/**
* #Column(type="string")
*/
protected $image;
/**
* #ManyToMany(targetEntity="User")
* #JoinTable(name="child_Contacts",
* joinColumns={#JoinColumn(name="child_id", referencedColumnName="id")},
* inverseJoinColumns={#JoinColumn(name="contact_id", referencedColumnName="id")}
* )
*/
protected $currentContacts;
/**
* #OneToMany(targetEntity="Alarm", mappedBy="child")
*/
protected $alarms;
public function __construct()
{
$this->alarms = new ArrayCollection();
}
}
You can easily solve this problem with doctrine and InheritanceType mapping.
Basically, you can do something like this :
/**
* #MappedSuperclass
* #Entity #Table(name="users")
* #InheritanceType("JOINED")
* #DiscriminatorColumn(name="discr", type="string")
* #DiscriminatorMap({"Admin" = "Admin", "Caretaker" = "Caretaker", "Child" = "Child", "Personal" = "Personal"})
*/
class User
{
/**
* #Id #GeneratedValue #Column(type="integer")
* #var int
**/
protected $id;
/**
* #Column(type="string")
* #var string
**/
protected $name;
/**
* #Column(type="string")
* #var string
**/
protected $mail;
/**
* #Column(type="string")
* #var string
**/
protected $password;
/**
* #Column(type="datetime")
**/
protected $created;
/**
* #Column(type="datetime")
**/
protected $lastlogin;
/**
* #ManyToOne(targetEntity="Group")
* #JoinColumn(name="group_id", referencedColumnName="id")
*/
protected $group;
}
And then, in each 4 different classes,
// src/Child.php
use Doctrine\Common\Collections\ArrayCollection;
/**
* #Entity #Table(name="child")
*/
class Child extends User
{
/**
* #Id #OneToOne(targetEntity="User")
* #JoinColumn(name="id", referencedColumnName="id")
**/
protected $id;
/**
* #Column(type="string")
*/
protected $image;
/**
* #ManyToMany(targetEntity="User")
* #JoinTable(name="child_Contacts",
* joinColumns={#JoinColumn(name="child_id", referencedColumnName="id")},
* inverseJoinColumns={#JoinColumn(name="contact_id", referencedColumnName="id")}
* )
*/
protected $currentContacts;
/**
* #OneToMany(targetEntity="Alarm", mappedBy="child")
*/
protected $alarms;
public function __construct()
{
$this->alarms = new ArrayCollection();
}
}
The doctrine docs is really good for this problem : http://doctrine-orm.readthedocs.io/projects/doctrine-orm/en/latest/reference/inheritance-mapping.html
And you don't need an extra check at login because doctrine create automatically the right class for you.
I have a many to one relation between my entities.
An application can have activities
<?php
namespace AppAcademic\ApplicationBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Activity
*
* #ORM\Table()
* #ORM\Entity
*/
class Activity
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="AppAcademic\ApplicationBundle\Entity\Application", inversedBy="activity")
* #ORM\JoinColumn(name="application_id", referencedColumnName="id", onDelete="CASCADE")
*/
private $application;
/**
* #var string
*
* #ORM\Column(name="title", type="string", length=255)
*/
private $title;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
public function setApplication($application)
{
$this->application = $application;
return $this;
}
public function getApplication()
{
return $this->application;
}
/**
* Set title
*
* #param string $title
* #return Activity
*/
public function setTitle($title)
{
$this->title = $title;
return $this;
}
/**
* Get title
*
* #return string
*/
public function getTitle()
{
return $this->title;
}
}
And the application
/**
* Application
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="AppAcademic\ApplicationBundle\Entity\ApplicationRepository")
*/
class Application
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\OneToMany(targetEntity="AppAcademic\ApplicationBundle\Entity\Activity", mappedBy="application")
*/
protected $activities;
...
}
I have this in the profiler:
AppAcademic\ApplicationBundle\Entity\Application
The mappings AppAcademic\ApplicationBundle\Entity\Application#activities and AppAcademic\ApplicationBundle\Entity\Activity#application are inconsistent with each other.
AppAcademic\ApplicationBundle\Entity\Application
The mappings AppAcademic\ApplicationBundle\Entity\Application#activities and AppAcademic\ApplicationBundle\Entity\Activity#application are inconsistent with each other.
AppAcademic\ApplicationBundle\Entity\Activity
The association AppAcademic\ApplicationBundle\Entity\Activity#application refers to the inverse side field AppAcademic\ApplicationBundle\Entity\Application#activity which does not exist.
For the mapping annotation ManyToOne on the Activity::$application property, the attribute
inversedBy="activity"
This should be
inversedBy="activities"
I'm having trouble with a Doctrine 2 mapped superclass, to define a ManyToMany Relation.
My code is :
use Doctrine\Common\Collections\ArrayCollection;
/** #MappedSuperclass */
abstract class MyAbstractClassA
{
/**
* #Id
* #GeneratedValue
* #Column(type="integer")
* #var int
*/
protected $id;
/**
* #ManyToMany(targetEntity="MyClassE")
* #var MyClassE[]
*/
protected $my_class_es;
// ... Other fields and methods
}
/** #Entity() */
class MyConcreteClassAa extends MyAbstractClassA
{
/**
* #Column(type="string")
* #var string
*/
public $aa_param;
// ... Other fields and methods
}
/** #Entity() */
class MyConcreteClassAb extends MyAbstractClassA
{
/**
* #Column(type="string")
* #var string
*/
public $ab_param;
// ... Other fields and methods
}
/** #Entity() */
class MyClassE
{
/**
* #Id
* #Column(type="integer")
* #var int
*/
protected $id;
/**
* #Column(type="string")
* #var string
*/
protected $e_param;
/**
* #ManyToOne(targetEntity="MyClassF")
* #var MyClassF
*/
protected $my_class_f;
// ... Other fields and methods
}
/** #Entity() */
class MyClassF
{
/**
* #Id
* #Column(type="integer")
* #var int
*/
protected $id;
// ... Other fields and methods
}
So here is the schema of what i have : http://pix.toile-libre.org/upload/original/1385651287.png
And there is what i want : http://pix.toile-libre.org/upload/original/1385651300.png
I don't know how to obtain this result, could someone tell me if it's possible ?
Thank you for helping me.