Symfony perfect entity, dates and data
How to set a date and data in Entity ? DateTime, createAt, updateAt and entities data
A lot of companies have some trobles with entities. It looks like this is the easiest part of your project. But here is two questions I would like to discuss :
- dates
- entity data
Dates with \DateTime
What is the best way to work with dates in php ? In my opinion the answer DateTime class. This is the officiel php documentation http://php.net/manual/ru/class.datetime.php
So in your class you can add two properties createdAt, updatedAt
/**
* @var \DateTime
*/
protected $createdAt;
/**
* @var \DateTime
*/
protected $updatedAt;/**
* @return \DateTime
*/
public function getCreatedAt()
{
return $this->createdAt;
}
/**
* @param \DateTime $createdAt
*/
public function setCreatedAt($createdAt)
{
$this->createdAt = $createdAt;
}
/**
* @return \DateTime
*/
public function getUpdatedAt()
{
return $this->updatedAt;
}
/**
* @param \DateTime $updatedAt
*/
public function setUpdatedAt($updatedAt)
{
$this->updatedAt = $updatedAt;
}
Doctrine and Lifecycle Callbacks
If you use Doctrine in your Symfony project you can make your life much easier. Doctrine supports entity lificycle http://symfony.com/doc/current/doctrine/lifecycle_callbacks.html
So I would like to advise you to use traits TimestampableEntity and create one trait for all entities http://php.net/manual/en/language.oop5.traits.php
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
trait TimestampableEntity
{
/**
* @var \DateTime
*
* @ORM\Column(type="datetime", nullable=true)
*/
protected $createdAt;
/**
* @var \DateTime
*
* @ORM\Column(type="datetime", nullable=true)
*/
protected $updatedAt;
/**
* @return \DateTime
*/
public function getCreatedAt()
{
return $this->createdAt;
}
/**
* @param \DateTime $createdAt
*/
public function setCreatedAt($createdAt)
{
$this->createdAt = $createdAt;
}
/**
* @return \DateTime
*/
public function getUpdatedAt()
{
return $this->updatedAt;
}
/**
* @param \DateTime $updatedAt
*/
public function setUpdatedAt($updatedAt)
{
$this->updatedAt = $updatedAt;
}
/**
* @ORM\PrePersist
* @ORM\PreUpdate
*/
public function updatedTimestamps()
{
$this->setUpdatedAt(new \DateTime('now'));
if ($this->getCreatedAt() == null) {
$this->setCreatedAt(new \DateTime('now'));
}
}
}
And now all you need is to add a @ORM\HasLifecycleCallbacks annotation and use TimestampableEntity trait in your Entity.
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass="AppBundle\Repository\AppRepository")
* @ORM\Table(name="PRODUCT")
* @ORM\HasLifecycleCallbacks
*/
class Product
{
use TimestampableEntity;
/**
* @var int
*
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var float
*
* @ORM\Column(type="float", nullable=true)
*/
protected $price;
/**
* @var int
*
* @ORM\Column(type="integer", nullable=true)
*/
protected $amount;
/**
* @return int
*/
public function getId(): int
{
return $this->id;
}
/**
* @return float
*/
public function getPrice(): float
{
return $this->price;
}
/**
* @param float $price
*/
public function setPrice(float $price)
{
$this->price = $price;
}
/**
* @return int
*/
public function getAmount(): int
{
return $this->amount;
}
/**
* @param int $amount
*/
public function setAmount(int $amount)
{
$this->amount = $amount;
}
}
In this case, all your entities have the same format of dates and you need to create or update your entities dates.
Entity data
To load all data at the same time from the array we use the same solution (trait). For example, we can name it DataLoader.
<?php
namespace AppBundle\Traits;
use Doctrine\Common\Inflector\Inflector;
trait DataLoader
{
/**
* @param array $data
*
* @return $this
*/
public function loadData(array $data)
{
foreach ($data as $key => $value) {
$method = Inflector::camelize('set_' . $key);
if (method_exists($this, $method)) {
$this->$method($value);
}
}
return $this;
}
}
In this case, in our Product we need to add the second trait
...
class Product
{
use TimestampableEntity;
use DataLoader;...
To use it :
$product = new Product();
$product->loadData(
[
'price' => 12.23,
'amount' => 10,
]
);
Entity properties to Array
If you need to convert our entity to the array, in this case, I use the other trait
<?php
namespace AppBundle\Traits;
trait RawLoader
{
/**
* @return array
*/
public function toArray()
{
return get_object_vars($this);
}
}
Use trait in class :
...
class Product
{
use TimestampableEntity;
use DataLoader;
use RawLoader;...
And then you can get all product’s properties as an array
$product->toArray();
GitHub
I added two simple repositories with these traits.
Other articles
By the way, probably Logging with Monolog article can be interesting for you.
Thank you for your attention!
Thank you very much for your attention! If you have any question or advice please feel free to contact me. I will be glad to help you.
Need professional help in web or mobile development?
Recommendation for planning or estimation of your project?
Feel free to contact me here.
P.S. I really appreciate your like or share.