mirror of
https://github.com/farmOS/farmOS.git
synced 2024-02-23 11:37:38 +01:00
Issue #3239940: UniqueBirthLogConstraint allows creating two birth logs for the same child
This commit is contained in:
commit
986c7a8331
|
@ -43,31 +43,33 @@ class UniqueBirthLogConstraintValidator extends ConstraintValidator implements C
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function validate($value, Constraint $constraint) {
|
public function validate($value, Constraint $constraint) {
|
||||||
/** @var \Drupal\Core\Field\FieldItemListInterface[] $value */
|
/** @var \Drupal\Core\Field\EntityReferenceFieldItemList $value */
|
||||||
/** @var \Drupal\farm_birth\Plugin\Validation\Constraint\UniqueBirthLogConstraint $constraint */
|
/** @var \Drupal\farm_birth\Plugin\Validation\Constraint\UniqueBirthLogConstraint $constraint */
|
||||||
foreach ($value as $item) {
|
foreach ($value->referencedEntities() as $delta => $asset) {
|
||||||
|
|
||||||
// Get the referenced asset ID.
|
// If the log is not new, skip validation.
|
||||||
$item_value = $item->getValue();
|
// A birth log exits so there is no need to check if one can be created.
|
||||||
$asset_id = $item_value['target_id'] ?? FALSE;
|
/** @var \Drupal\log\Entity\LogInterface $log */
|
||||||
|
$log = $value->getParent()->getValue();
|
||||||
// If there is no asset, skip.
|
if (!$log->isNew()) {
|
||||||
if (empty($asset_id)) {
|
return;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perform an entity query to find logs that reference the asset.
|
// Query the number of birth logs that reference the asset.
|
||||||
// We do not check access to ensure that all matching logs are found.
|
// We do not check access to ensure that all matching logs are found.
|
||||||
$query = $this->entityTypeManager->getStorage('log')->getQuery()
|
$count = $this->entityTypeManager->getStorage('log')->getAggregateQuery()
|
||||||
->accessCheck(FALSE)
|
->accessCheck(FALSE)
|
||||||
->condition('type', 'birth')
|
->condition('type', 'birth')
|
||||||
->condition('asset', $asset_id);
|
->condition('asset', $asset->id())
|
||||||
$ids = $query->execute();
|
->count()
|
||||||
|
->execute();
|
||||||
|
|
||||||
// If more than 1 birth logs reference the asset, add a violation.
|
// If more than 0 birth logs reference the asset, add a violation.
|
||||||
if (count($ids) > 1) {
|
if ($count > 0) {
|
||||||
$asset = $this->entityTypeManager->getStorage('asset')->load($asset_id);
|
$this->context->buildViolation($constraint->message, ['%child' => $asset->label()])
|
||||||
$this->context->addViolation($constraint->message, ['%child' => $asset->label()]);
|
->atPath((string) $delta . '.target_id')
|
||||||
|
->setInvalidValue($asset->id())
|
||||||
|
->addViolation();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ class BirthTest extends KernelTestBase {
|
||||||
'farm_birth',
|
'farm_birth',
|
||||||
'farm_entity',
|
'farm_entity',
|
||||||
'farm_entity_fields',
|
'farm_entity_fields',
|
||||||
|
'farm_entity_views',
|
||||||
'farm_field',
|
'farm_field',
|
||||||
'farm_id_tag',
|
'farm_id_tag',
|
||||||
'farm_log',
|
'farm_log',
|
||||||
|
@ -35,6 +36,7 @@ class BirthTest extends KernelTestBase {
|
||||||
'image',
|
'image',
|
||||||
'options',
|
'options',
|
||||||
'state_machine',
|
'state_machine',
|
||||||
|
'system',
|
||||||
'user',
|
'user',
|
||||||
'taxonomy',
|
'taxonomy',
|
||||||
'text',
|
'text',
|
||||||
|
@ -51,6 +53,7 @@ class BirthTest extends KernelTestBase {
|
||||||
$this->installEntitySchema('taxonomy_term');
|
$this->installEntitySchema('taxonomy_term');
|
||||||
$this->installEntitySchema('user');
|
$this->installEntitySchema('user');
|
||||||
$this->installConfig([
|
$this->installConfig([
|
||||||
|
'farm_entity_views',
|
||||||
'farm_animal',
|
'farm_animal',
|
||||||
'farm_animal_type',
|
'farm_animal_type',
|
||||||
'farm_birth',
|
'farm_birth',
|
||||||
|
@ -162,25 +165,33 @@ class BirthTest extends KernelTestBase {
|
||||||
'timestamp' => \Drupal::time()->getRequestTime(),
|
'timestamp' => \Drupal::time()->getRequestTime(),
|
||||||
'asset' => [['target_id' => $asset->id()]],
|
'asset' => [['target_id' => $asset->id()]],
|
||||||
]);
|
]);
|
||||||
$log1->save();
|
|
||||||
|
|
||||||
// Confirm that there were no validation errors.
|
// Confirm that there are no validation errors.
|
||||||
$errors = $log1->validate();
|
$errors = $log1->validate();
|
||||||
$this->assertCount(0, $errors);
|
$this->assertCount(0, $errors);
|
||||||
|
|
||||||
|
$log1->save();
|
||||||
|
|
||||||
// Create a second birth log that references the asset.
|
// Create a second birth log that references the asset.
|
||||||
$log2 = Log::create([
|
$log2 = Log::create([
|
||||||
'type' => 'birth',
|
'type' => 'birth',
|
||||||
'timestamp' => \Drupal::time()->getRequestTime(),
|
'timestamp' => \Drupal::time()->getRequestTime(),
|
||||||
'asset' => [['target_id' => $asset->id()]],
|
'asset' => [['target_id' => $asset->id()]],
|
||||||
]);
|
]);
|
||||||
$log2->save();
|
|
||||||
|
|
||||||
// Confirm that validation fails.
|
// Confirm that validation fails.
|
||||||
$errors = $log2->validate();
|
$errors = $log2->validate();
|
||||||
$this->assertCount(1, $errors);
|
$this->assertCount(1, $errors);
|
||||||
$this->assertEquals(new FormattableMarkup('%child already has a birth log. More than one birth log cannot reference the same child.', ['%child' => $asset->label()]), $errors[0]->getMessage());
|
$this->assertEquals(new FormattableMarkup('%child already has a birth log. More than one birth log cannot reference the same child.', ['%child' => $asset->label()]), $errors[0]->getMessage());
|
||||||
$this->assertEquals('asset', $errors[0]->getPropertyPath());
|
$this->assertEquals('asset.0.target_id', $errors[0]->getPropertyPath());
|
||||||
|
|
||||||
|
// Try updating the original birth log.
|
||||||
|
$log1->set('name', $this->randomMachineName());
|
||||||
|
|
||||||
|
// Confirm there are no validation errors.
|
||||||
|
$errors = $log1->validate();
|
||||||
|
$this->assertCount(0, $errors);
|
||||||
|
$log1->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue