mirror of
https://github.com/farmOS/farmOS.git
synced 2024-02-23 11:37:38 +01:00
Validate that only one birth log can reference an asset.
This commit is contained in:
parent
3a649a8b42
commit
92cef7f8f8
|
@ -7,6 +7,7 @@
|
|||
|
||||
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
|
||||
/**
|
||||
|
@ -38,3 +39,15 @@ function farm_birth_log_view_alter(array &$build, EntityInterface $entity, Entit
|
|||
$build['asset']['#title'] = t('Children');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_entity_base_field_info_alter().
|
||||
*/
|
||||
function farm_birth_entity_base_field_info_alter(&$fields, EntityTypeInterface $entity_type) {
|
||||
/** @var \Drupal\field\Entity\FieldConfig[] $fields */
|
||||
|
||||
// Validate that only one birth log references an asset.
|
||||
if ($entity_type->id() == 'log' && !empty($fields['asset'])) {
|
||||
$fields['asset']->addConstraint('UniqueBirthLog');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\farm_birth\Plugin\Validation\Constraint;
|
||||
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
|
||||
/**
|
||||
* Checks that only one birth log references an asset.
|
||||
*
|
||||
* @Constraint(
|
||||
* id = "UniqueBirthLog",
|
||||
* label = @Translation("Unique birth log", context = "Validation"),
|
||||
* )
|
||||
*/
|
||||
class UniqueBirthLogConstraint extends Constraint {
|
||||
|
||||
/**
|
||||
* The default violation message.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $message = '%child already has a birth log. More than one birth log cannot reference the same child.';
|
||||
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\farm_birth\Plugin\Validation\Constraint;
|
||||
|
||||
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
|
||||
use Drupal\Core\Entity\EntityTypeManagerInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
use Symfony\Component\Validator\ConstraintValidator;
|
||||
|
||||
/**
|
||||
* Validates the UniqueBirthLog constraint.
|
||||
*/
|
||||
class UniqueBirthLogConstraintValidator extends ConstraintValidator implements ContainerInjectionInterface {
|
||||
|
||||
/**
|
||||
* The entity type manager.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
|
||||
*/
|
||||
protected $entityTypeManager;
|
||||
|
||||
/**
|
||||
* Constructs a UniqueBirthLogConstraintValidator object.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
|
||||
* The entity type manager.
|
||||
*/
|
||||
public function __construct(EntityTypeManagerInterface $entity_type_manager) {
|
||||
$this->entityTypeManager = $entity_type_manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('entity_type.manager')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validate($value, Constraint $constraint) {
|
||||
/** @var \Drupal\Core\Field\FieldItemListInterface[] $value */
|
||||
/** @var \Drupal\farm_birth\Plugin\Validation\Constraint\UniqueBirthLogConstraint $constraint */
|
||||
foreach ($value as $item) {
|
||||
|
||||
// Get the referenced asset ID.
|
||||
$item_value = $item->getValue();
|
||||
$asset_id = $item_value['target_id'] ?? FALSE;
|
||||
|
||||
// If there is no asset, skip.
|
||||
if (empty($asset_id)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Perform an entity field query to find logs that reference the asset.
|
||||
$query = $this->entityTypeManager->getStorage('log')->getQuery();
|
||||
$ids = $query->condition('type', 'birth')
|
||||
->condition('asset', $asset_id)
|
||||
->execute();
|
||||
|
||||
// If more than 1 birth logs reference the asset, add a violation.
|
||||
if (count($ids) > 1) {
|
||||
$asset = $this->entityTypeManager->getStorage('asset')->load($asset_id);
|
||||
$this->context->addViolation($constraint->message, ['%child' => $asset->label()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -3,6 +3,7 @@
|
|||
namespace Drupal\Tests\farm_birth\Kernel;
|
||||
|
||||
use Drupal\asset\Entity\Asset;
|
||||
use Drupal\Component\Render\FormattableMarkup;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
use Drupal\log\Entity\Log;
|
||||
use Drupal\taxonomy\Entity\Term;
|
||||
|
@ -36,6 +37,7 @@ class BirthTest extends KernelTestBase {
|
|||
'user',
|
||||
'taxonomy',
|
||||
'text',
|
||||
'views',
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -130,4 +132,54 @@ class BirthTest extends KernelTestBase {
|
|||
$this->assertEquals($timestamp, $child2->get('birthdate')->value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that only one birth log can reference an asset.
|
||||
*/
|
||||
public function testUniqueBirthLogConstraint() {
|
||||
|
||||
// Create a Cow animal type term.
|
||||
/** @var \Drupal\taxonomy\TermInterface $cow */
|
||||
$cow = Term::create([
|
||||
'name' => 'Cow',
|
||||
'vid' => 'animal_type',
|
||||
]);
|
||||
$cow->save();
|
||||
|
||||
// Create an asset.
|
||||
/** @var \Drupal\asset\Entity\AssetInterface $animal */
|
||||
$asset = Asset::create([
|
||||
'name' => $this->randomMachineName(),
|
||||
'type' => 'animal',
|
||||
'animal_type' => ['tid' => $cow->id()],
|
||||
'status' => 'active',
|
||||
]);
|
||||
$asset->save();
|
||||
|
||||
// Create a birth log that references the asset.
|
||||
$log1 = Log::create([
|
||||
'type' => 'birth',
|
||||
'timestamp' => \Drupal::time()->getRequestTime(),
|
||||
'asset' => [['target_id' => $asset->id()]],
|
||||
]);
|
||||
$log1->save();
|
||||
|
||||
// Confirm that there were no validation errors.
|
||||
$errors = $log1->validate();
|
||||
$this->assertCount(0, $errors);
|
||||
|
||||
// Create a second birth log that references the asset.
|
||||
$log2 = Log::create([
|
||||
'type' => 'birth',
|
||||
'timestamp' => \Drupal::time()->getRequestTime(),
|
||||
'asset' => [['target_id' => $asset->id()]],
|
||||
]);
|
||||
$log2->save();
|
||||
|
||||
// Confirm that validation fails.
|
||||
$errors = $log2->validate();
|
||||
$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('asset', $errors[0]->getPropertyPath());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue