Optimizing Doctine2 entities with Traits

Ivan Proskuryakov
2 min readSep 14, 2019

--

Original date: September 16, 2015

Since v5.4.0, PHP implements a method of code reuse — Traits.
This means all duplicated code, which was not impossible to implement as functions or classes could be grouped now. In large projects, Doctrine entities or documents(mongo) full of duplicated properties, setters, getters: Id, title, createdAt, updatedAt, etc. fields are common across all models and Traits are a perfect solution for them.

Bellow example for Id, CreatedAt, UpdatedAt and Name fields. I’m sure than 90% of doctrine fields could be unified and stored as traits.

With Traits Doctrine domain object becomes:

<?php

namespace Aisel\AddressingBundle\Document;

use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;
use JMS\Serializer\Annotation as JMS;
use Aisel\ResourceBundle\Domain\IdTrait;
use Aisel\ResourceBundle\Domain\UpdateCreateTrait;
use Aisel\ResourceBundle\Domain\NameTrait;

/**
* City
*
* @author Ivan Proskuryakov <volgodark@gmail.com>
*
* @ODM\HasLifecycleCallbacks()
* @ODM\Document(
* collection="aisel_addressing_city",
* repositoryClass="Aisel\ResourceBundle\Repository\CollectionRepository"
* )
*/
class City
{

use IdTrait;
use NameTrait;
use UpdateCreateTrait;

// ... other fields impossible to group

IdTrait.php

<?php

namespace Aisel\ResourceBundle\Domain;

use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;
use JMS\Serializer\Annotation as JMS;

/**
* IdTrait
*
* @author Ivan Proskuryakov <volgodark@gmail.com>
*
*/
trait IdTrait
{

/**
* @var string
* @ODM\Id
* @JMS\Expose
* @JMS\Type("string")
*/
private $id;

/**
* Get id
*
* @return string
*/
public function getId()
{
return $this->id;
}
}

NameTrait.php

<?php

namespace Aisel\ResourceBundle\Domain;

use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;
use JMS\Serializer\Annotation as JMS;

/**
* NameTrait
*
* @author Ivan Proskuryakov <volgodark@gmail.com>
*
*/
trait NameTrait
{

/**
* @var string
* @ODM\Field(type="string")
* @Assert\Type(type="string")
* @Assert\NotNull()
* @JMS\Expose
* @JMS\Type("string")
*/
private $name;

/**
* Set name
*
* @param string $name
* @return mixed
*/
public function setName($name)
{
$this->name = $name;

return $this;
}

/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}

}

UpdateCreateTrait.php

<?php

namespace Aisel\ResourceBundle\Domain;

use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;
use JMS\Serializer\Annotation as JMS;
use Gedmo\Mapping\Annotation as Gedmo;

/**
* UpdateCreateTrait
*
* @author Ivan Proskuryakov <volgodark@gmail.com>
*
*/
trait UpdateCreateTrait
{

/**
* @var \DateTime
* @ODM\Field(type="date")
* @Gedmo\Timestampable(on="create")
* @JMS\Expose
* @JMS\Type("DateTime")
*/
protected $createdAt;

/**
* @var \DateTime
* @ODM\Field(type="date")
* @Gedmo\Timestampable(on="update")
* @JMS\Expose
* @JMS\Type("DateTime")
*/
protected $updatedAt;

/**
* Get createdAt
*
* @return \DateTime
*/
public function getCreatedAt()
{
return $this->createdAt;
}

/**
* Get updatedAt
*
* @return \DateTime
*/
public function getUpdatedAt()
{
return $this->updatedAt;
}

}

--

--