Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ a release.
- Sluggable: Allow ascii_string to validTypes
- IpTraceable: Allow ascii_string to validTypes
- Sluggable: Use `TranslationWalker` hint when looking for similar slugs (`getSimilarSlugs` method) for entities which implement `Translatable` interface and have `uniqueOverTranslations: true` Slug option (#100, #2530)
- Blameable/IpTraceable/SoftDeletable/Timestampable: Added functionality to use setter method instead of setting property values directly (#2644)

## [3.15.0]
### Added
Expand Down
31 changes: 24 additions & 7 deletions src/AbstractTrackingListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use Doctrine\Persistence\Mapping\ClassMetadata;
use Doctrine\Persistence\NotifyPropertyChanged;
use Doctrine\Persistence\ObjectManager;
use Gedmo\Exception\InvalidMappingException;
use Gedmo\Exception\UnexpectedValueException;
use Gedmo\Mapping\Event\AdapterInterface;
use Gedmo\Mapping\MappedEventSubscriber;
Expand Down Expand Up @@ -89,7 +90,7 @@ public function onFlush(EventArgs $args)
$new = array_key_exists($field, $changeSet) ? $changeSet[$field][1] : false;
if (null === $new) { // let manual values
$needChanges = true;
$this->updateField($object, $ea, $meta, $field);
$this->updateField($object, $ea, $meta, $field, $config);
}
}
}
Expand All @@ -101,7 +102,7 @@ public function onFlush(EventArgs $args)
&& null === $changeSet[$field][1];
if (!isset($changeSet[$field]) || $isInsertAndNull) { // let manual values
$needChanges = true;
$this->updateField($object, $ea, $meta, $field);
$this->updateField($object, $ea, $meta, $field, $config);
}
}
}
Expand Down Expand Up @@ -152,7 +153,7 @@ public function onFlush(EventArgs $args)

if (null === $configuredValues || ($singleField && in_array($value, $configuredValues, true))) {
$needChanges = true;
$this->updateField($object, $ea, $meta, $options['field']);
$this->updateField($object, $ea, $meta, $options['field'], $config);
}
}
}
Expand Down Expand Up @@ -184,14 +185,14 @@ public function prePersist(EventArgs $args)
if (isset($config['update'])) {
foreach ($config['update'] as $field) {
if (null === $meta->getReflectionProperty($field)->getValue($object)) { // let manual values
$this->updateField($object, $ea, $meta, $field);
$this->updateField($object, $ea, $meta, $field, $config);
}
}
}
if (isset($config['create'])) {
foreach ($config['create'] as $field) {
if (null === $meta->getReflectionProperty($field)->getValue($object)) { // let manual values
$this->updateField($object, $ea, $meta, $field);
$this->updateField($object, $ea, $meta, $field, $config);
}
}
}
Expand Down Expand Up @@ -219,7 +220,7 @@ abstract protected function getFieldValue($meta, $field, $eventAdapter);
*
* @return void
*/
protected function updateField($object, $eventAdapter, $meta, $field)
protected function updateField($object, $eventAdapter, $meta, $field, array $config = [])
{
$property = $meta->getReflectionProperty($field);
$oldValue = $property->getValue($object);
Expand All @@ -235,7 +236,23 @@ protected function updateField($object, $eventAdapter, $meta, $field)
}
}

$property->setValue($object, $newValue);
if (!empty($config['setterMethod'][$field])) {
$setterName = $config['setterMethod'][$field];

if (!method_exists($object, $setterName)) {
throw new InvalidMappingException(
sprintf(
"Setter method [%s] does not exist in class %s",
$setterName,
$meta->getName(),
),
);
}

$object->{$setterName}($newValue);
} else {
$property->setValue($object, $newValue);
}

if ($object instanceof NotifyPropertyChanged) {
$uow = $eventAdapter->getObjectManager()->getUnitOfWork();
Expand Down
2 changes: 2 additions & 0 deletions src/Blameable/Mapping/Driver/Annotation.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ public function readExtendedMetadata($meta, array &$config)
'value' => $blameable->value,
];
}
// add the setter method for the field
$this->setSetterMethod($property->getName(), $blameable->setterMethod, $config);
// properties are unique and mapper checks that, no risk here
$config[$blameable->on][] = $field;
}
Expand Down
5 changes: 4 additions & 1 deletion src/Blameable/Mapping/Driver/Xml.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,10 @@ public function readExtendedMetadata($meta, array &$config)
if (!$this->_isAttributeSet($data, 'on') || !in_array($this->_getAttribute($data, 'on'), ['update', 'create', 'change'], true)) {
throw new InvalidMappingException("Field - [{$field}] trigger 'on' is not one of [update, create, change] in class - {$meta->getName()}");
}

if ($this->_isAttributeSet($data, 'setterMethod')) {
$setterMethod = $this->_getAttribute($data, 'setterMethod');
$this->setSetterMethod($field, $setterMethod, $config);
}
if ('change' === $this->_getAttribute($data, 'on')) {
if (!$this->_isAttributeSet($data, 'field')) {
throw new InvalidMappingException("Missing parameters on property - {$field}, field must be set on [change] trigger in class - {$meta->getName()}");
Expand Down
4 changes: 4 additions & 0 deletions src/Blameable/Mapping/Driver/Yaml.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ public function readExtendedMetadata($meta, array &$config)
throw new InvalidMappingException("Field - [{$field}] trigger 'on' is not one of [update, create, change] in class - {$meta->getName()}");
}

if (isset($mappingProperty['setterMethod'])) {
$this->setSetterMethod($field, $mappingProperty['setterMethod'], $config);
}

if ('change' === $mappingProperty['on']) {
if (!isset($mappingProperty['field'])) {
throw new InvalidMappingException("Missing parameters on property - {$field}, field must be set on [change] trigger in class - {$meta->getName()}");
Expand Down
2 changes: 2 additions & 0 deletions src/IpTraceable/Mapping/Driver/Annotation.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ public function readExtendedMetadata($meta, array &$config)
'value' => $ipTraceable->value,
];
}
// add the setter method for the field
$this->setSetterMethod($property->getName(), $ipTraceable->setterMethod, $config);
// properties are unique and mapper checks that, no risk here
$config[$ipTraceable->on][] = $field;
}
Expand Down
5 changes: 4 additions & 1 deletion src/IpTraceable/Mapping/Driver/Xml.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,10 @@ public function readExtendedMetadata($meta, array &$config)
if (!$this->_isAttributeSet($data, 'on') || !in_array($this->_getAttribute($data, 'on'), ['update', 'create', 'change'], true)) {
throw new InvalidMappingException("Field - [{$field}] trigger 'on' is not one of [update, create, change] in class - {$meta->getName()}");
}

if ($this->_isAttributeSet($data, 'setterMethod')) {
$setterMethod = $this->_getAttribute($data, 'setterMethod');
$this->setSetterMethod($field, $setterMethod, $config);
}
if ('change' === $this->_getAttribute($data, 'on')) {
if (!$this->_isAttributeSet($data, 'field')) {
throw new InvalidMappingException("Missing parameters on property - {$field}, field must be set on [change] trigger in class - {$meta->getName()}");
Expand Down
3 changes: 3 additions & 0 deletions src/IpTraceable/Mapping/Driver/Yaml.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ public function readExtendedMetadata($meta, array &$config)
if (!isset($mappingProperty['on']) || !in_array($mappingProperty['on'], ['update', 'create', 'change'], true)) {
throw new InvalidMappingException("Field - [{$field}] trigger 'on' is not one of [update, create, change] in class - {$meta->getName()}");
}
if (isset($mappingProperty['setterMethod'])) {
$this->setSetterMethod($field, $mappingProperty['setterMethod'], $config);
}

if ('change' === $mappingProperty['on']) {
if (!isset($mappingProperty['field'])) {
Expand Down
13 changes: 11 additions & 2 deletions src/Mapping/Annotation/Blameable.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,21 @@ final class Blameable implements GedmoAnnotation
public $field;
/** @var mixed */
public $value;
/** @var string */
public $setterMethod;

/**
* @param array<string, mixed> $data
* @param string|string[]|null $field
* @param mixed $value
*/
public function __construct(array $data = [], string $on = 'update', $field = null, $value = null)
{
public function __construct(
array $data = [],
string $on = 'update',
$field = null,
$value = null,
string $setterMethod = ''
) {
if ([] !== $data) {
Deprecation::trigger(
'gedmo/doctrine-extensions',
Expand All @@ -55,12 +62,14 @@ public function __construct(array $data = [], string $on = 'update', $field = nu
$this->on = $this->getAttributeValue($data, 'on', $args, 1, $on);
$this->field = $this->getAttributeValue($data, 'field', $args, 2, $field);
$this->value = $this->getAttributeValue($data, 'value', $args, 3, $value);
$this->setterMethod = $this->getAttributeValue($data, 'setterMethod', $args, 4, $setterMethod);

return;
}

$this->on = $on;
$this->field = $field;
$this->value = $value;
$this->setterMethod = $setterMethod;
}
}
13 changes: 11 additions & 2 deletions src/Mapping/Annotation/IpTraceable.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,21 @@ final class IpTraceable implements GedmoAnnotation
public $field;
/** @var mixed */
public $value;
/** @var string */
public $setterMethod;

/**
* @param array<string, mixed> $data
* @param string|string[]|null $field
* @param mixed $value
*/
public function __construct(array $data = [], string $on = 'update', $field = null, $value = null)
{
public function __construct(
array $data = [],
string $on = 'update',
$field = null,
$value = null,
string $setterMethod = ''
) {
if ([] !== $data) {
Deprecation::trigger(
'gedmo/doctrine-extensions',
Expand All @@ -56,12 +63,14 @@ public function __construct(array $data = [], string $on = 'update', $field = nu
$this->on = $this->getAttributeValue($data, 'on', $args, 1, $on);
$this->field = $this->getAttributeValue($data, 'field', $args, 2, $field);
$this->value = $this->getAttributeValue($data, 'value', $args, 3, $value);
$this->setterMethod = $this->getAttributeValue($data, 'setterMethod', $args, 4, $setterMethod);

return;
}

$this->on = $on;
$this->field = $field;
$this->value = $value;
$this->setterMethod = $setterMethod;
}
}
14 changes: 12 additions & 2 deletions src/Mapping/Annotation/SoftDeleteable.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,19 @@ final class SoftDeleteable implements GedmoAnnotation

public bool $hardDelete = true;

/** @var string */
public $setterMethod;

/**
* @param array<string, mixed> $data
*/
public function __construct(array $data = [], string $fieldName = 'deletedAt', bool $timeAware = false, bool $hardDelete = true)
{
public function __construct(
array $data = [],
string $fieldName = 'deletedAt',
bool $timeAware = false,
bool $hardDelete = true,
string $setterMethod = ''
) {
if ([] !== $data) {
Deprecation::trigger(
'gedmo/doctrine-extensions',
Expand All @@ -53,12 +61,14 @@ public function __construct(array $data = [], string $fieldName = 'deletedAt', b
$this->fieldName = $this->getAttributeValue($data, 'fieldName', $args, 1, $fieldName);
$this->timeAware = $this->getAttributeValue($data, 'timeAware', $args, 2, $timeAware);
$this->hardDelete = $this->getAttributeValue($data, 'hardDelete', $args, 3, $hardDelete);
$this->setterMethod = $this->getAttributeValue($data, 'setterMethod', $args, 4, $setterMethod);

return;
}

$this->fieldName = $fieldName;
$this->timeAware = $timeAware;
$this->hardDelete = $hardDelete;
$this->setterMethod = $setterMethod;
}
}
13 changes: 11 additions & 2 deletions src/Mapping/Annotation/Timestampable.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,21 @@ final class Timestampable implements GedmoAnnotation
public $field;
/** @var mixed */
public $value;
/** @var string */
public $setterMethod;

/**
* @param array<string, mixed> $data
* @param string|string[] $field
* @param mixed $value
*/
public function __construct(array $data = [], string $on = 'update', $field = null, $value = null)
{
public function __construct(
array $data = [],
string $on = 'update',
$field = null,
$value = null,
string $setterMethod = ''
) {
if ([] !== $data) {
Deprecation::trigger(
'gedmo/doctrine-extensions',
Expand All @@ -55,12 +62,14 @@ public function __construct(array $data = [], string $on = 'update', $field = nu
$this->on = $this->getAttributeValue($data, 'on', $args, 1, $on);
$this->field = $this->getAttributeValue($data, 'field', $args, 2, $field);
$this->value = $this->getAttributeValue($data, 'value', $args, 3, $value);
$this->setterMethod = $this->getAttributeValue($data, 'setterMethod', $args, 4, $setterMethod);

return;
}

$this->on = $on;
$this->field = $field;
$this->value = $value;
$this->setterMethod = $setterMethod;
}
}
16 changes: 16 additions & 0 deletions src/Mapping/Driver/AbstractAnnotationDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -135,4 +135,20 @@ protected function getRelatedClassName($metadata, $name)

return class_exists($className) ? $className : '';
}

/**
* Set the setter method for the given field.
*/
protected function setSetterMethod(string $field, string $method, array &$config): void
{
if ('' === $method) {
return;
}

if (!isset($config['setterMethod'])) {
$config['setterMethod'] = [];
}

$config['setterMethod'][$field] = $method;
}
}
16 changes: 16 additions & 0 deletions src/Mapping/Driver/File.php
Original file line number Diff line number Diff line change
Expand Up @@ -160,4 +160,20 @@ protected function getRelatedClassName($metadata, $name)

return class_exists($className) ? $className : '';
}

/**
* Set the setter method for the given field.
*/
protected function setSetterMethod(string $field, ?string $method, array &$config): void
{
if (empty($method)) {
return;
}

if (!isset($config['setterMethod'])) {
$config['setterMethod'] = [];
}

$config['setterMethod'][$field] = $method;
}
Comment on lines +163 to +178
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code doesn't seem to belong to File, if we don't use it in Yaml drivers, I'd move it to Xml

}
5 changes: 5 additions & 0 deletions src/SoftDeleteable/Mapping/Driver/Annotation.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ public function readExtendedMetadata($meta, array &$config)
}
$config['hardDelete'] = $annot->hardDelete;
}

// add the setter method for the field?
if (isset($annot->setterMethod)) {
$this->setSetterMethod($annot->fieldName, $annot->setterMethod, $config);
}
}

$this->validateFullMetadata($meta, $config);
Expand Down
5 changes: 5 additions & 0 deletions src/SoftDeleteable/Mapping/Driver/Xml.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ public function readExtendedMetadata($meta, array &$config)
if ($this->_isAttributeSet($xml->{'soft-deleteable'}, 'hard-delete')) {
$config['hardDelete'] = $this->_getBooleanAttribute($xml->{'soft-deleteable'}, 'hard-delete');
}

if ($this->_isAttributeSet($xml, 'setterMethod')) {
$setterMethod = $this->_getAttribute($xml, 'setterMethod');
$this->setSetterMethod($field, $setterMethod, $config);
}
}
}

Expand Down
4 changes: 4 additions & 0 deletions src/SoftDeleteable/Mapping/Driver/Yaml.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ public function readExtendedMetadata($meta, array &$config)

Validator::validateField($meta, $fieldName);

if (isset($classMapping['soft_deleteable']['setterMethod'])) {
$this->setSetterMethod($fieldName, $classMapping['soft_deleteable']['setterMethod'], $config);
}

$config['fieldName'] = $fieldName;

$config['timeAware'] = false;
Expand Down
Loading