I want to automatically add columns (that are in all my entities) like 'lastEditedTime' and 'createdTime' to DQL queries but I don't know if it is possible?
I already did a SQLFilter to add constraint, but didn't find a solution to add columns automatically to each results...
Does someone have an idea?
Regards
CodePudding user response:
From your question it is not completely clear what you would like to achieve. Do you want to add shared/common properties to entities? This can be done using by extending a common parent class.
Or, if the entity classes do not / cannot extend a common parent class, you could use a trait
to add the common code to your classes.
The following example shows how to use a common parent calls and HasLifecycleCallbacks
which will take care of automatically updating the timestamps:
Example:
/**
* @ORM\MappedSuperclass
* @HasLifecycleCallbacks
*/
abstract class TimeLoggedEntity {
/**
* @ORM\Column(type="datetime", nullable=true)
*/
protected $lastEditedTime;
/**
* @ORM\Column(type="datetime", nullable=true)
*/
protected $createdTime;
...
/**
* @ORM\PrePersist
*/
public function prePersist() {
$this->createdTime = \DateTime();
$this->lastEditedTime = \DateTime();
}
/**
* @ORM\PreUpdate
*/
public function preUpdate() {
$this->lastEditedTime = \DateTime();
}
}
/**
* @ORM\Entity
*/
class SomeEntityA extends TimeLoggedEntity {
/**
* @ORM\Column(type="string", nullable=true)
*/
protected $someProperty;
}
/**
* @ORM\Entity
*/
class OtherEntityB extends TimeLoggedEntity {
/**
* @ORM\Column(type="string", nullable=true)
*/
protected $otherProperty;
}
In this example Doctrine would create tables for SomeEntityA
and OtherEntityB
which both have column for your timestamps.
Note that TimeLoggedEntity
does not to be abstract necessarily.
CodePudding user response:
One of the best ways to do this is to use extentions or filters or entity manager hooks
Filter to add SQL More about them check symfonycast
<?php
namespace Example;
use Doctrine\ORM\Mapping\ClassMetadata,
Doctrine\ORM\Query\Filter\SQLFilter;
class MyLocaleFilter extends SQLFilter
{
public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias)
{
// Check if the entity implements the LocalAware interface
if (!$targetEntity->reflClass->implementsInterface('LocaleAware')) {
return "";
}
return $targetTableAlias.'.locale = ' . $this->getParameter('locale'); // getParameter applies quoting automatically
}
}
Hooks :
<?php
/** @Entity @HasLifecycleCallbacks */
class User
{
// ...
/**
* @Column(type="string", length=255)
*/
public $value;
/** @Column(name="created_at", type="string", length=255) */
private $createdAt;
/** @PrePersist */
public function doStuffOnPrePersist()
{
$this->createdAt = date('Y-m-d H:i:s');
}
/** @PrePersist */
public function doOtherStuffOnPrePersist()
{
$this->value = 'changed from prePersist callback!';
}
/** @PostPersist */
public function doStuffOnPostPersist()
{
$this->value = 'changed from postPersist callback!';
}
/** @PostLoad */
public function doStuffOnPostLoad()
{
$this->value = 'changed from postLoad callback!';
}
/** @PreUpdate */
public function doStuffOnPreUpdate()
{
$this->value = 'changed from preUpdate callback!';
}
}
This will allow you to write logic at desired point.
There are Doctrine Events as well, which you can utilize if your logic is complex or you want to move out and manage code separately.
If you have ability to change schema, you can use prebuilt traits that has all the logic you need as described in doctrine extensions package and avoid rewriting logic for many common usecases.