Skip to content

Instantly share code, notes, and snippets.

@sandermarechal
Last active December 17, 2015 19:29
Show Gist options
  • Save sandermarechal/5661187 to your computer and use it in GitHub Desktop.
Save sandermarechal/5661187 to your computer and use it in GitHub Desktop.
Design idea for a new Doctrine Translatable extension
<?php
namespace Prezent\Translatable\Entity;
use Doctrine\ORM\Mapping as ORM;
use Prezent\Translatable\Entity\AbstractTranslation;
/**
* @ORM\MappedSuperClass
*/
abstract class AbstractTranslation
{
/**
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
* @ORM\Column(name="id", type="integer")
*/
protected $id;
/**
* Mapping must be supplied by implementation class
*/
protected $object;
/**
* @ORM\Column(name="locale", type="string")
*/
protected $locale;
/**
* Getter for id
*
* @return string
*/
public function getId()
{
return $this->id;
}
/**
* Getter for object
*
* @return object
*/
public function getObject()
{
return $this->object;
}
/**
* Setter for object
*
* @param object $object
* @return self
*/
public function setObject($object = null)
{
if ($this->object == $object) {
return $this;
}
$old = $this->object;
$this->object = $object;
if ($old !== null) {
$old->removeTranslation($this);
}
if ($object !== null) {
$object->addTranslation($this);
}
return $this;
}
/**
* Getter for locale
*
* @return string
*/
public function getLocale()
{
return $this->locale;
}
/**
* Setter for locale
*
* @param string $locale
* @return self
*/
public function setLocale($locale)
{
$this->locale = $locale;
return $this;
}
}
<?php
namespace Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Prezent\Translatable\Annotation as Prezent;
/**
* @ORM\Entity
*/
class Post
{
/**
* @Prezent\CurrentTranslation
*/
private $currentTranslation;
/**
* @ORM\OneToMany(targetEntity="PostTranslations", mappedBy="object")
* @Prezent\Translations
*/
private $translations;
/**
* Constructor
*/
public function __construct()
{
$this->translations = new ArrayCollection();
}
/**
* Getter for name
*
* @return string
*/
public function getName()
{
return $this->getCurrentTranslation()->getName();
}
/**
* Setter for name
*
* @param string $name
* @return self
*/
public function setName($name)
{
$this->getCurrentTranslation()->setName();
return $this;
}
/**
* Getter for slug
*
* @return string
*/
public function getSlug()
{
return $this->getCurrentTranslation()->getSlug();
}
/**
* Get the current translation
*
* @return string
*/
public function getCurrentTranslation()
{
return $this->translation;
}
/**
* Set the current translation
*
* @param string $translation
* @return self
*/
public function setCurrentTranslation($translation)
{
if (is_string($translation)) {
$translation = $this->getTranslation($translation);
}
if (!$this->translations->contains($translation)) {
throw new \InvalidArgumentException('Unknown translation');
}
$this->currentTranslation = $translation;
return $this;
}
/**
* Get all translations
*
* @return ArrayCollection
*/
public function getTranslations()
{
return $this->translations;
}
/**
* Get a translation in a locale
*
* @param string $locale
* @return PostTranslation
*/
public function getTranslation($locale)
{
return $this->translations->filter(function ($object) use ($locale) {
return $object->getLocale() === $locale;
})->first();
}
/**
* Add a translation
*
* @param Translation $translation
* @return self
*/
public function addTranslation(PostTranslation $translation)
{
if ($this->translations->contains($translation)) {
return $this;
}
if ($existingTranslation = $this->getTranslation($locale)) {
$this->removeTranslation($existingTranslation);
}
$this->translations[] = $translation;
$translation->setObject($this);
return $this;
}
/**
* Remove a translation
*
* @param Translation $translation
* @return self
*/
public function removeTranslation(PostTranslation $translation)
{
if ($this->translations->removeElement($translation)) {
$translation->setObject(null);
}
return $this;
}
}
<?php
namespace Entity;
use Doctrine\ORM\Mapping as ORM;
use Prezent\Translatable\Entity\AbstractTranslation;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @ORM\Entity
* @ORM\Table(name="post_translation", uniqueConstraints={
* @UniqueConstraint(name="object_locale_idx", columns={"object_id", "locale"})
* })
* @UniqueEntity({"locale", "slug"})
*/
class PostTranslation extends AbstractTranslation
{
/**
* @ORM\ManyToOne(targetEntity="Post", inversedBy="translation")
* @ORM\JoinColumn(name="object_id", referencedColumnName="id", onDelete="CASCADE", nullable=false)
*/
protected $object;
/**
* @ORM\Column(name="name", type="string")
* @Assert\NotBlank
*/
private $name;
/**
* @ORM\Column(name="slug", type="string")
* @Gedmo\Sluggable(fields={"name"}, unique_base="locale")
*/
private $slug;
/**
* Getter for name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Setter for name
*
* @param string $name
* @return self
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Getter for slug
*
* @return string
*/
public function getSlug()
{
return $this->slug;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment