I have two tables:
category
id | name
1 | Programming
2 | Designing
3 | PHP
4 | C#
5 | Adobe Photoshop
category_tree
category_id | parent_id
1 | NULL
2 | NULL
3 | 1
4 | 1
5 | 2
Here is the Entity class:
/**
* #ORM\Entity
* #ORM\Table(name="category")
*/
class Category
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/**
* #ORM\Column(type="text", name="name")
*/
protected $name;
/**
* #ORM\Column(type="text", name="description")
*/
/**
* #ORM\ManyToMany(targetEntity="Category")
* #ORM\JoinTable(name="category_tree",
* joinColumns={#ORM\JoinColumn(name="category_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="parent_id", referencedColumnName="id")}
* )
*/
protected $categories;
public function __construct()
{
$this->categories = new \Doctrine\Common\Collections\ArrayCollection();
}
public function addCategory(Category $category)
{
$this->categories[] = $category;
return $this;
}
public function getCategories()
{
return $this->categories;
}
public function getId()
{
return $this->id;
}
public function setName($name)
{
$this->name = $name;
return $this;
}
public function getName()
{
return $this->name;
}
}
I am using select form element to insert these values in database, When i selected any root category thats work fine , but when i select root or leave blank this can't insert NULL value in "category_tree" table. How can i add NULL value in "category_tree" table?
Related
I have the following:
User have one group, group can have many users
User
<?php namespace Application\Model;
use Doctrine\Common\Collections;
use Doctrine\ORM\Mapping as ORM;
/**
* User model
* Read-only entity
* #ORM\Table(name="VLOGGER_WEBCALENDAR_USR")
* #ORM\Entity
* #package Application\Model
*/
class User
{
/**
* #var int
* #ORM\Id
* #ORM\Column(name="USR_ID", type="integer")
*/
protected $id;
/**
* #var string
* #ORM\Column(name="USR_LOGIN", type="string")
*/
protected $login;
/**
* #var string
* #ORM\Column(name="USR_CODE", type="string")
*/
protected $code;
/**
* #var int
* #ORM\Column(name="GRP_ID", type="integer")
*/
protected $groupId;
/**
* #var string
* #ORM\Column(name="GRP_CODE", type="string")
*/
protected $groupCode;
/**
* #var User\Group
* #ORM\ManyToOne(targetEntity="Application\Model\User\Group",fetch="EAGER")
* #ORM\JoinColumn(name="GRP_ID", referencedColumnName="GRP_ID")
*/
protected $group;
/**
* #var Event
* #ORM\OneToMany(targetEntity="Application\Model\Event", mappedBy="user")
* #ORM\JoinColumn(name="USR_ID", referencedColumnName="USR_ID")
*/
protected $events;
/**
* Constructor
*/
public function __construct()
{
$this->events = new Collections\ArrayCollection();
}
/**
* #return string
*/
public function getCode()
{
return $this->code;
}
/**
* #param string $code
* #return User
*/
public function setCode($code)
{
$this->code = $code;
return $this;
}
/**
* #return Event
*/
public function getEvents()
{
return $this->events;
}
/**
* #param Event $events
* #return User
*/
public function setEvents($events)
{
$this->events = $events;
return $this;
}
/**
* #return User\Group
*/
public function getGroup()
{
return $this->group;
}
/**
* #param User\Group $group
* #return User
*/
public function setGroup($group)
{
$this->group = $group;
return $this;
}
/**
* #return string
*/
public function getGroupCode()
{
return $this->groupCode;
}
/**
* #param string $groupCode
* #return User
*/
public function setGroupCode($groupCode)
{
$this->groupCode = $groupCode;
return $this;
}
/**
* #return int
*/
public function getGroupId()
{
return $this->groupId;
}
/**
* #param int $groupId
* #return User
*/
public function setGroupId($groupId)
{
$this->groupId = $groupId;
return $this;
}
/**
* #return mixed
*/
public function getId()
{
return $this->id;
}
/**
* #param mixed $id
* #return User
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* #return string
*/
public function getLogin()
{
return $this->login;
}
/**
* #param string $login
* #return User
*/
public function setLogin($login)
{
$this->login = $login;
return $this;
}
}
Group
<?php namespace Application\Model\User;
use Application\Model;
use Doctrine\Common\Collections;
use Doctrine\ORM\Mapping as ORM;
/**
* User group model
* Read-only entity
* #ORM\Table(name="VLOGGER_WEBCALENDAR_GRP")
* #ORM\Entity
* #package Application\Model
*/
class Group
{
/**
* #var int
* #ORM\Id
* #ORM\Column(name="GRP_ID", type="integer")
*/
protected $id;
/**
* #var string
* #ORM\Column(name="GRP_CODE", type="string")
*/
protected $code;
/**
* #var Collections\ArrayCollection
* #ORM\OneToMany(targetEntity="Application\Model\User", mappedBy="group")
* #ORM\JoinColumn(name="GRP_ID", referencedColumnName="GRP_ID")
*/
protected $users;
/**
* Constructor
*/
public function __construct()
{
$this->users = new Collections\ArrayCollection();
}
/**
* #return mixed
*/
public function getCode()
{
return $this->code;
}
/**
* #param mixed $code
* #return Group
*/
public function setCode($code)
{
$this->code = $code;
return $this;
}
/**
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* #param int $id
* #return Group
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* #return mixed
*/
public function getUsers()
{
return $this->users;
}
/**
* #param mixed $users
* #return Group
*/
public function setUsers($users)
{
$this->users = $users;
return $this;
}
}
When I try to retrieve the relation from the groups, it works great, but when I slect the users and try to get their group, Doctrine create some proxy objects and the result is an empty object with only the relationship key filled.
Can someone point me to the good direction ?
Here my code:
$query = $em->createQueryBuilder()
->select('u')
->from('Application\Model\User', 'u');
$data = $query->getQuery()->getResult();
$data = reset($data);
var_dump($data->getGroup()); // proxy
###########################
$query = $em->createQueryBuilder()
->select('g')
->from('Application\Model\User\Group', 'g');
$data = $query->getQuery()->getResult();
$data = reset($data);
var_dump($data->getUsers()); // ok
you don't need the $GRP_ID in the User Entity - it's already mapped with the $group relation. Doctrine handles the IDs automatically.
Also your naming-convention looks a bit weird. Normally you should use lowe-camel-case (to save you from strange errors)
Example:
$USR_CODE should be $usrCode -> to match your getter/setter: setUsrCode(), getUsrCode().
just noticed: you don't have any setters. You have to define setters for your attributes, with the naming-convention (look at my example above)
Edit:
you can map the column with the doctrine orm notation:
/**
*
* #ORM\Column(name="USR_CODE", type="string")
*/
private $usrCode;
And yes, you need setters otherwise doctrine won't be able to set the values.
You also need addUser() and removeUser() functions (since user is a Collection):
public function addUsers(Collection $users)
{
foreach($users as $user)
{
if( ! $this->users->contains($user))
{
$this->users->add($user);
$user->setGroup($this);
}
}
}
public function removeUsers(Collection $users)
{
foreach($users as $user)
{
if($this->users->contains($user)){
$this->users->remove($user);
$user->setGroup(null);
}
}
}
I have a self referencing entity in Doctrine but I keep getting the following error when I try to persist them:
PHP Catchable fatal error: Object of class Category could not be converted to string in vendor/doctrine/dbal/lib/Doctrine/DBAL/Statement.php on line 165
Example:
$category1 = new Category();
$category1->setName("Foo");
$category1->setParent( NULL );
$category2 = new Category();
$category2->setName("Bar");
$category2->setParent( $category1 );
$manager->persist( $category1 );
$manager->persist( $category2 );
$manager->flush();
My entity looks like this:
/**
* #ORM\Table(name="categories")
* #ORM\Entity
*/
class Category {
/**
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(type="integer")
*/
protected $id;
/**
* #ORM\Column(type="string", length=64, unique=true)
*/
protected $name;
/**
* #ORM\Column(nullable=true)
* #ORM\ManyToOne(targetEntity="Category", inversedBy="children")
* #ORM\JoinColumn(name="parent_id", referencedColumnName="id")
*/
protected $parent;
/**
* #ORM\OneToMany(targetEntity="Category", mappedBy="parent")
*/
protected $children;
public function __construct()
{
$this->children = new ArrayCollection();
}
public function getId()
{
return $this->id;
}
public function getName()
{
return $this->name;
}
public function setName( $name )
{
$this->name = $name;
return $this;
}
public function getParent()
{
return $this->parent;
}
public function setParent( Category $parent = NULL )
{
$this->parent = $parent;
return $this;
}
public function getChildren()
{
return $this->children;
}
public function setChildren( ArrayCollection $children )
{
$this->children = $children;
return $this;
}
}
I have Googled and compared my code to other examples but I can't seem to spot the problem. I'm obviously overlooking something, but what?
Try to use
/**
* #ORM\ManyToOne(targetEntity="Category", inversedBy="children")
* #ORM\JoinColumn(name="parent_id", referencedColumnName="id", nullable=true)
*/
protected $parent;
But I also recommend you to set onDelete="SET NULL" on the parent column, like this:
/**
* #ORM\ManyToOne(targetEntity="Category", inversedBy="children")
* #ORM\JoinColumn(name="parent_id", referencedColumnName="id", onDelete="SET NULL")
*/
public $parent;
I know it's not part of the question, but you are probably going to need this in the near future. If you want the children column to give you the categories in a order that the user can choose, you may want to add a integer column named order and define children like this:
/**
* #ORM\OneToMany(targetEntity="Category", mappedBy="parent")
* #ORM\OrderBy({"order" = "ASC"})
*/
public $children;
I have two tables:
category
id | name
1 | Programming
2 | Designing
3 | PHP
4 | C#
5 | Adobe Photoshop
category_tree
category_id | parent_id
1 | NULL
2 | NULL
3 | 1
4 | 1
5 | 2
Here is the Entity class:
/**
* #ORM\Entity
* #ORM\Table(name="category")
*/
class Category
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/**
* #ORM\Column(type="text", name="name")
*/
protected $name;
/**
* #ORM\Column(type="text", name="description")
*/
/**
* #ORM\ManyToMany(targetEntity="Category")
* #ORM\JoinTable(name="category_tree",
* joinColumns={#ORM\JoinColumn(name="category_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="parent_id", referencedColumnName="id")}
* )
*/
protected $categories;
public function __construct()
{
$this->categories = new \Doctrine\Common\Collections\ArrayCollection();
}
public function addCategory(Category $category)
{
$this->categories[] = $category;
return $this;
}
public function getCategories()
{
return $this->categories;
}
public function getId()
{
return $this->id;
}
public function setName($name)
{
$this->name = $name;
return $this;
}
public function getName()
{
return $this->name;
}
}
How can i add NULL Value in "Category_tree" table?
I'm trying remove a registry from my database using doctrine 2, but I'm getting the follow error:
Catchable fatal error: Argument 1 passed to Doctrine\ORM\Mapping\DefaultQuoteStrategy::getJoinTableName() must be an array, null given, called in /home/triangulum/www/pedal/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php on line 1020 and defined in /home/triangulum/www/pedal/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/DefaultQuoteStrategy.php on line 86
I have 3 tables:
grupo = id, name
permissao = id, name
grupo_permissao = grupo_id, permissao_id
My entitys:
Grupo:
<?php
namespace User\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Entity
* #ORM\Table(name="grupo")
* #ORM\Entity(repositoryClass="User\Entity\GrupoRepository")
*/
class Grupo {
public function __construct($options=null) {
Configurator::configure($this, $options);
$this->permissoes = new ArrayCollection();
}
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue
* #var int
*/
protected $id;
/**
* #ORM\Column(type="text")
* #var string
*/
protected $nome;
/**
* #ORM\ManyToMany(targetEntity="User\Entity\Permissao", mappedBy="grupo", cascade={"remove"})
*/
protected $permissoes;
public function getPermissoes()
{
return $this->permissoes;
}
public function getId() {
return $this->id;
}
public function setId($id) {
$this->id = $id;
}
public function getNome() {
return $this->nome;
}
public function setNome($nome) {
$this->nome = $nome;
}
public function toArray()
{
return array
(
'id' => $this->getId(),
'nome' => $this->getNome()
);
}
}
?>
Permissao:
<?php
namespace User\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Entity
* #ORM\Table(name="permissao")
* #ORM\Entity(repositoryClass="User\Entity\PermissaoRepository")
*/
class Permissao {
public function __construct($options=null) {
Configurator::configure($this, $options);
$this->grupos = new ArrayCollection();
}
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue
* #var int
*/
protected $id;
/**
* #ORM\Column(type="text")
* #var string
*/
protected $nome;
/**
* #ORM\ManyToMany(targetEntity="User\Entity\Grupo", inversedBy="permissao", cascade={"persist", "remove"})
* #ORM\JoinTable(name="grupo_permissao",
* joinColumns={#ORM\JoinColumn(name="permissao_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="grupo_id", referencedColumnName="id")}
* )
*/
protected $grupos;
public function getGrupos() {
return $this->grupos;
}
public function getId() {
return $this->id;
}
public function setId($id) {
$this->id = $id;
}
public function getNome() {
return $this->nome;
}
public function setNome($nome) {
$this->nome = $nome;
}
public function toArray()
{
return array
(
'id' => $this->getId(),
'nome' => $this->getNome()
);
}
}
?>
remove:
public function delete($id)
{
$entity = $this->entityManager->find('User\Entity\Grupo', $id);
if($entity)
{
$this->entityManager->remove($entity);
$this->entityManager->flush();
return $id;
}
}
What am I doing wrong?
I think you have a problem with your mappedBy and inversedBy attributes in the manyToMany annotations. They should match the other entities property name, grupos and permissoes. Try this:
/**
* #ORM\ManyToMany(targetEntity="User\Entity\Permissao", mappedBy="grupos", cascade={"remove"})
*/
protected $permissoes;
/**
* #ORM\ManyToMany(targetEntity="User\Entity\Grupo", inversedBy="permissoes", cascade={"persist", "remove"})
* #ORM\JoinTable(name="grupo_permissao",
* joinColumns={#ORM\JoinColumn(name="permissao_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="grupo_id", referencedColumnName="id")}
* )
*/
protected $grupos;
I'm using Doctrine 2.2.0 together with Codeigniter. I'm new to Doctrine (or to ORM in general).
I'm setting up entity and proxy classes based on YAML files which works fine. I do have problems in reflecting a polymorphic association in my DB in my Doctrine classes. I'm looking for a concrete example on how to implement the following polymorphic association in Doctrine.
In my DB I have a table called products. Depending on the value of field object_type and object_id I want to relate either to a record in the table videos or the table cars (I simplified it here). I want to keep both product types in 2 separate table because one has nothing to do with the other and both tables relate to other tables.
I took a look at the Doctrine Inheritance documentation and other examples, but it doesn't seem to help me. If possible I want to avoid adding the columns description and price to the tables videos and cars.
Many thanks!
|Table: products |
|-----------------------------------------------------|
| ID | description | price | object_type | object_id |
|-----------------------------------------------------|
| 1 | A video | 20.00 | video | 12 |
| 2 | A car | 159.00 | car | 5 |
|Table: videos |
|--------------------------------------------|
| ID | filename | artist_id | date |
|--------------------------------------------|
| 12 | somename.mp4 | 189 | 2011-02-15 |
|Table: cars |
|------------------------------|
| ID | brand_id | model | year |
|------------------------------|
| 5 | 17 | astra | 2010 |
Found the solution myself. I've listed below the different steps I've done. This answer is very big, but I tried to be as complete as possible.
The most important things are in the Product YAML files inheritanceType: JOINED, discriminatorColumn:, discriminatorMap: and the Video and Car entity classes class Video extends Product, class Car extends Product.
1) DB Schema
CREATE TABLE IF NOT EXISTS `artists` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `brands` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `cars` (
`id` int(11) NOT NULL,
`model` varchar(255) NOT NULL,
`release_date` date NOT NULL,
`brand_id` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `products` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`description` varchar(255) NOT NULL,
`price` double NOT NULL,
`object_type` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `videos` (
`id` int(11) NOT NULL,
`file_name` varchar(255) NOT NULL,
`release_date` date NOT NULL,
`artist_id` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
2) Doctrine YAML files (from which you need to create the Entity and proxy classes)
Entities.Artist.dcm.yml
Entities\Artist:
type: entity
table: artists
id:
id:
type: integer
primary: true
notnull: true
generator:
strategy: AUTO
fields:
name:
type: string(255)
notnull: true
oneToMany:
videos:
targetEntity: Video
mappedBy: artist
options:
charset: utf8
type: InnoDB
Entities.Brand.dcm.yml
Entities\Brand:
type: entity
table: brands
id:
id:
type: integer
primary: true
notnull: true
generator:
strategy: AUTO
fields:
name:
type: string(255)
notnull: true
oneToMany:
cars:
targetEntity: Car
mappedBy: brand
options:
charset: utf8
type: InnoDB
Entities.Car.dcm.yml
Entities\Car:
type: entity
table: cars
fields:
model:
type: string
notnull: true
release_date:
type: date
notnull: true
oneToOne: #unidirectional
brand:
targetEntity: Brand
joinColumns:
brand_id:
referencedColumnName: id
options:
charset: utf8
type: InnoDB
Entities.Product.dcm.yml
Entities\Product:
type: entity
table: products
id:
id:
type: string
primary: true
notnull: true
generator:
strategy: AUTO
fields:
description:
type: string(255)
notnull: true
price:
type: decimal
notnull: true
inheritanceType: JOINED
discriminatorColumn:
name: object_type
type: string
length: 255
discriminatorMap:
video: Video
car: Car
options:
charset: utf8
type: InnoDB
Entities.Video.dcm.yml
Entities\Video:
type: entity
table: videos
fields:
file_name:
type: string
notnull: true
release_date:
type: date
notnull: true
oneToOne: #unidirectional
artist:
targetEntity: Artist
joinColumns:
artist_id:
referencedColumnName: id
options:
charset: utf8
type: InnoDB
3) Create Entity and Proxy classes
I use CodeIgniter. I've used Joel Verhagen's excellent guide
!! It's important you extend Video and Car with Product - See below !!
This results in the following Entity classes
Artist.php
namespace Entities;
use Doctrine\ORM\Mapping as ORM;
/**
* Entities\Artist
*
* #ORM\Table(name="artists")
* #ORM\Entity
*/
class Artist
{
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string $name
*
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* #var \Doctrine\Common\Collections\ArrayCollection
*
* #ORM\OneToMany(targetEntity="Entities\Video", mappedBy="artist")
*/
private $videos;
public function __construct()
{
$this->videos = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return Artist
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Add videos
*
* #param Entities\Video $videos
*/
public function addVideo(\Entities\Video $videos)
{
$this->videos[] = $videos;
}
/**
* Get videos
*
* #return Doctrine\Common\Collections\Collection
*/
public function getVideos()
{
return $this->videos;
}
}
Brand.php
namespace Entities;
use Doctrine\ORM\Mapping as ORM;
/**
* Entities\Brand
*
* #ORM\Table(name="brands")
* #ORM\Entity
*/
class Brand
{
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string $name
*
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* #var \Doctrine\Common\Collections\ArrayCollection
*
* #ORM\OneToMany(targetEntity="Entities\Car", mappedBy="brand")
*/
private $cars;
public function __construct()
{
$this->cars = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return Brand
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Add cars
*
* #param Entities\Car $cars
*/
public function addCar(\Entities\Car $cars)
{
$this->cars[] = $cars;
}
/**
* Get cars
*
* #return Doctrine\Common\Collections\Collection
*/
public function getCars()
{
return $this->cars;
}
}
Car.php
namespace Entities;
use Doctrine\ORM\Mapping as ORM;
/**
* Entities\Car
*
* #ORM\Table(name="cars")
* #ORM\Entity
*/
class Car extends Product //Important that Car extends Product
{
/**
* #var string $model
*
* #ORM\Column(name="model", type="string")
*/
private $model;
/**
* #var date $release_date
*
* #ORM\Column(name="release_date", type="date")
*/
private $release_date;
/**
* #var Entities\Brand
*
* #ORM\OneToOne(targetEntity="Entities\Brand")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="brand_id", referencedColumnName="id", unique=true)
* })
*/
private $brand;
/**
* Set model
*
* #param string $model
* #return Car
*/
public function setModel($model)
{
$this->model = $model;
return $this;
}
/**
* Get model
*
* #return string
*/
public function getModel()
{
return $this->model;
}
/**
* Set release_date
*
* #param date $releaseDate
* #return Car
*/
public function setReleaseDate($releaseDate)
{
$this->release_date = $releaseDate;
return $this;
}
/**
* Get release_date
*
* #return date
*/
public function getReleaseDate()
{
return $this->release_date;
}
/**
* Set brand
*
* #param Entities\Brand $brand
* #return Car
*/
public function setBrand(\Entities\Brand $brand = null)
{
$this->brand = $brand;
return $this;
}
/**
* Get brand
*
* #return Entities\Brand
*/
public function getBrand()
{
return $this->brand;
}
}
Product.php
namespace Entities;
use Doctrine\ORM\Mapping as ORM;
/**
* Entities\Product
*
* #ORM\Table(name="products")
* #ORM\InheritanceType("JOINED")
* #ORM\DiscriminatorColumn(name="", type="", length=)
* #ORM\DiscriminatorMap({"video" = "Entities\Video", "car" = "Entities\Car"})
* #ORM\Entity
*/
class Product
{
/**
* #var string $id
*
* #ORM\Column(name="id", type="string")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string $description
*
* #ORM\Column(name="description", type="string", length=255)
*/
private $description;
/**
* #var decimal $price
*
* #ORM\Column(name="price", type="decimal")
*/
private $price;
/**
* Get id
*
* #return string
*/
public function getId()
{
return $this->id;
}
/**
* Set description
*
* #param string $description
* #return Product
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set price
*
* #param decimal $price
* #return Product
*/
public function setPrice($price)
{
$this->price = $price;
return $this;
}
/**
* Get price
*
* #return decimal
*/
public function getPrice()
{
return $this->price;
}
}
Video.php
namespace Entities;
use Doctrine\ORM\Mapping as ORM;
/**
* Entities\Video
*
* #ORM\Table(name="videos")
* #ORM\Entity
*/
class Video extends Product //Important that Video extends Product
{
/**
* #var string $file_name
*
* #ORM\Column(name="file_name", type="string")
*/
private $file_name;
/**
* #var date $release_date
*
* #ORM\Column(name="release_date", type="date")
*/
private $release_date;
/**
* #var Entities\Artist
*
* #ORM\OneToOne(targetEntity="Entities\Artist")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="artist_id", referencedColumnName="id", unique=true)
* })
*/
private $artist;
/**
* Set file_name
*
* #param string $fileName
* #return Video
*/
public function setFileName($fileName)
{
$this->file_name = $fileName;
return $this;
}
/**
* Get file_name
*
* #return string
*/
public function getFileName()
{
return $this->file_name;
}
/**
* Set release_date
*
* #param date $releaseDate
* #return Video
*/
public function setReleaseDate($releaseDate)
{
$this->release_date = $releaseDate;
return $this;
}
/**
* Get release_date
*
* #return date
*/
public function getReleaseDate()
{
return $this->release_date;
}
/**
* Set artist
*
* #param Entities\Artist $artist
* #return Video
*/
public function setArtist(\Entities\Artist $artist = null)
{
$this->artist = $artist;
return $this;
}
/**
* Get artist
*
* #return Entities\Artist
*/
public function getArtist()
{
return $this->artist;
}
}
3) Creating a new Car and a new Video
This is what goes in my CodeIgniter controller. The code presumes you've created an artist with the name Metallica and a brand with the name Ford.
public function createVideo()
{
//Instantiate new Entities\Video object
$video = new Entities\Video;
//Since it extends Entities\Product you can set the common Product properties
$video->setDescription('This is a Metallica clip');
$video->setPrice(19.95);
//Setting the custom Video properties
$artist = $this->doctrine->em->getRepository('Entities\Artist')->findOneBy(array('name' => 'Metallica'));
$video->setArtist($artist);
$video->setReleaseDate(new DateTime());
$video->setFileName('metallica.mp4');
//Save
$this->doctrine->em->persist($video);
$this->doctrine->em->flush();
}
public function createCar()
{
//Instantiate new Entities\Car object
$car = new Entities\Car;
//Since it extends Entities\Product you can set the common Product properties
$car->setDescription('This is Ford Mondeo of 2011');
$car->setPrice(19.95);
//Setting the custom Car properties
$brand = $this->doctrine->em->getRepository('Entities\Brand')->findOneBy(array('name' => 'Ford'));
$car->setBrand($brand);
$car->setReleaseDate(DateTime::createFromFormat('Y-m-d', '2011-11-15'));
$car->setModel('Mondeo');
//Save
$this->doctrine->em->persist($car);
$this->doctrine->em->flush();
}
4) Extracting all products
An example on how to extract all Products
public function extractAllProducts()
{
$products = $this->doctrine->em->getRepository('Entities\Product')->findAll();
foreach($products as $product)
{
printf('%s for € %s<br />', $product->getDescription(), $product->getPrice());
}
}
This results into
This is a Metallica clip for € 19.95
This is Ford Mondeo of 2011 for € 19.95
An example onn how to extract all Videos
public function extractAllVideos()
{
$videos = $this->doctrine->em->getRepository('Entities\Video')->findAll();
foreach($videos as $video)
{
printf('%s, released %s for € %s<br />', $video->getDescription(), $video->getReleaseDate()->format('Y'), $video->getPrice());
}
}
This results into
This is a Metallica clip, released 2012 for € 19.95
You were looking in the right place, inheritance mapping is certainly what you need to achieve this. From what I can tell this is a perfect example of "class table inheritance".
Check out the manual for some example / explanation on how to implement this.
http://docs.doctrine-project.org/projects/doctrine-orm/en/2.0.x/reference/inheritance-mapping.html#class-table-inheritance