Last active
August 29, 2015 14:26
-
-
Save geerteltink/84159f006616b4029623 to your computer and use it in GitHub Desktop.
Doctrine embedded value objects with single table inheritance
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| namespace ContentBundle\Entity; | |
| use Doctrine\ORM\Mapping as ORM; | |
| use DateTime; | |
| use DateTimeZone; | |
| /** | |
| * @ORM\Entity | |
| * @ORM\Table(name="content") | |
| * @ORM\InheritanceType("SINGLE_TABLE") | |
| * @ORM\DiscriminatorColumn(name="type", type="string") | |
| * @ORM\DiscriminatorMap({ | |
| * "default"="Content", | |
| * "page"="PageContent", | |
| * "post"="PostContent" | |
| * }) | |
| */ | |
| class Content | |
| { | |
| /** | |
| * @var integer | |
| * | |
| * @ORM\Column(type="integer") | |
| * @ORM\Id | |
| * @ORM\GeneratedValue(strategy="AUTO") | |
| */ | |
| private $id; | |
| /** | |
| * @var Guid | |
| * | |
| * @ORM\Embedded(class="Guid") | |
| */ | |
| private $guid; | |
| /** | |
| * @var string | |
| * | |
| * @ORM\Column(type="text") | |
| */ | |
| private $title; | |
| /** | |
| * @var string | |
| * | |
| * @ORM\Column(type="text") | |
| */ | |
| private $body; | |
| /** | |
| * @var PublishStatus | |
| * | |
| * @ORM\Embedded(class="PublishStatus") | |
| */ | |
| private $status; | |
| /** | |
| * @var \DateTime | |
| * | |
| * @ORM\Column(type="datetime") | |
| */ | |
| private $created; | |
| /** | |
| * @var \DateTime | |
| * | |
| * @ORM\Column(type="datetime") | |
| */ | |
| private $modified; | |
| /** | |
| * @var \DateTime | |
| * | |
| * @ORM\Column(type="datetime") | |
| */ | |
| private $published; | |
| /** | |
| * @var \DateTime | |
| * | |
| * @ORM\Column(type="datetime") | |
| */ | |
| private $embargoed; | |
| /** | |
| * @var \DateTime | |
| * | |
| * @ORM\Column(type="datetime") | |
| */ | |
| private $expires; | |
| public function __construct( | |
| $title, | |
| $body | |
| ) { | |
| $this->title = $title; | |
| $this->body = $body; | |
| $this->status = PublishStatus::draft(); | |
| $this->created = new DateTime('now', new DateTimeZone('UTC')); | |
| } | |
| public function publish(DateTime $published = null) | |
| { | |
| if (!$published) { | |
| $published = new DateTime('now', new DateTimeZone('UTC')); | |
| } | |
| $this->status = PublishStatus::usable(); | |
| $this->published = clone $published; | |
| } | |
| public function withGuid(Guid $guid) | |
| { | |
| $this->guid = $guid; | |
| } | |
| public function withEmbargo(DateTime $embargoed = null) | |
| { | |
| $this->embargoed = clone $embargoed; | |
| } | |
| public function withExpiration(DateTime $expires = null) | |
| { | |
| $this->expires = clone $expires; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| namespace ContentBundle\Entity; | |
| use Doctrine\ORM\Mapping as ORM; | |
| /** | |
| * @ORM\Embeddable | |
| */ | |
| class Guid | |
| { | |
| /** | |
| * @ORM\Column(type="string", nullable=true) | |
| */ | |
| protected $value; | |
| public function __construct($value) | |
| { | |
| $this->value = \strval($value); | |
| } | |
| /** | |
| * @return string | |
| */ | |
| public function __toString() | |
| { | |
| return $this->value; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| namespace ContentBundle\Entity; | |
| use Doctrine\ORM\Mapping as ORM; | |
| /** | |
| * @ORM\Entity | |
| */ | |
| class PageContent extends Content | |
| { | |
| public function __construct( | |
| $title, | |
| $body | |
| ) { | |
| parent::__construct($title, $body); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| namespace ContentBundle\Entity; | |
| use Doctrine\ORM\Mapping as ORM; | |
| /** | |
| * @ORM\Entity | |
| */ | |
| class PostContent extends Content | |
| { | |
| /** | |
| * @var string | |
| * | |
| * @ORM\Column(type="text") | |
| */ | |
| private $excerpt; | |
| public function __construct( | |
| $title, | |
| $body, | |
| $excerpt = null | |
| ) { | |
| parent::__construct($title, $body); | |
| $this->excerpt = $excerpt; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| namespace ContentBundle\Entity; | |
| use Doctrine\ORM\Mapping as ORM; | |
| /** | |
| * @ORM\Embeddable | |
| */ | |
| class PublishStatus | |
| { | |
| const STATE_DRAFT = 'draft'; | |
| const STATE_USABLE = 'usable'; | |
| const STATE_WITHHELD = 'withheld'; | |
| const STATE_CANCELED = 'canceled'; | |
| /** | |
| * @ORM\Column(type="string") | |
| */ | |
| private $status; | |
| /** | |
| * @param string $status | |
| * @throws \Exception | |
| */ | |
| public function __construct($status) | |
| { | |
| if (!in_array($status, [self::STATE_DRAFT, self::STATE_USABLE, self::STATE_WITHHELD, self::STATE_CANCELED])) { | |
| throw new \Exception(sprintf('Invalid status: %s', $status)); | |
| } | |
| $this->status = $status; | |
| } | |
| public static function draft() | |
| { | |
| return new self(self::STATE_DRAFT); | |
| } | |
| public static function usable() | |
| { | |
| return new self(self::STATE_USABLE); | |
| } | |
| public static function withheld() | |
| { | |
| return new self(self::STATE_WITHHELD); | |
| } | |
| public static function canceled() | |
| { | |
| return new self(self::STATE_CANCELED); | |
| } | |
| public function equals(PublishStatus $status) | |
| { | |
| return ($this->status == (string) $status); | |
| } | |
| /** | |
| * @return string | |
| */ | |
| public function __toString() | |
| { | |
| return $this->status; | |
| } | |
| } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
When updating the schema I get this:
Without the single table inheritance it works perfectly and it creates the correct table structure.