In this article we are going to see how drupal developers can use the Drupal Constraints to Validate the Media entities.
Basically Drupal provides Constraints to do the Validations on the Entities, where Drupal uses the Symfony’s validator and extends with Symfony’s Typed Data API for validating specific Entity field definitions.
These constraint validators can be used in different ways
- Using the API.
- Adding the Constraints to Field properties definitions.
- By Creating Custom Constraints.
In this article we gonna see how to Custom constraints for Media entities.
- Create a
CustomMediaConstraint
. - Create a
CustomMediaConstraintValidator
- Use
hook_entity_bundle_field_info_alter
to add the custom media constraint.
You need to create a custom module as a prerequisite, Create a module with the name custom_media_constraint
.
1. Create a CustomMediaConstraint
- Let's create the constraint for the Size of the media file.
- Create a Class with the name
CustomMediaConstraint
in the module. Create this file in the folder location<project>/modules/custom/custom_media_constraint/Plugin/Validation/Constraint
<?php
namespace Drupal/custom_media_constraint/Plugin/Validation/Constraint;
use Symfony/Component/Validator/Constraint;
/**
* Constraint for the Media fields in the application.
*
* @Constraint(
* id = "custom_media_constraint",
* label = @Translation("Custom Media Constraint", context = "Validation"),
* )
*/
class CustomMediaConstraint extends Constraint {
/**
* Key variable.
*/
public $key = '';
/**
* {@inheritdoc}
*/
public function getRequiredOptions(): array {
return ['key'];
}
/**
* Image size.
*
* @var string
*/
public size = 'Expected Image size "%excepted", given %value.';
}
2. Create a CustomMediaConstraintValidator
- Let's create the constraint validator, to validate the media size.
- Create a Class with the name
CustomMediaConstraintValidator
in the module. Create this file in the folder location<project>/modules/custom/custom_media_constraint/Plugin/Validation/Constraint
- In the
validate
function- Load all the media fields in the drupal application.
- For all the media fields get the size settings.
- Get all the media custom size settings, which you can define in a custom drupal form, via your custom module (IMP)
- Then write the conditions and add the violation.
<?php
namespace Drupal/custom_media_constraint/Plugin/Validation/Constraint;
use Symfony/Component/Validator/Constraint;
use Symfony/Component/Validator/ConstraintValidator;
use Symfony/Component/DependencyInjection/ContainerInjectionInterface;
use Drupal/Core/DependencyInjection/ContainerInjectionInterface;
use Drupal/Core/Config/ConfigFactoryInterface;
class CustomMediaConstraintValidator extends ConstraintValidator implements ContainerInjectionInterface {
/**
* @var /Symfony/Component/Validator/Context/ExecutionContextInterface
*/
protected $context;
/**
* @var /Drupal/Core/Config/ConfigFactoryInterface
*/
protected $configFactory;
/**
* Constructor.
*/
public function _construct(ConfigFactoryInterface $configFactory) {
$this->configFactory = $configFactory;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('config.factory')
);
}
/**
* {@inheritdoc}
*/
public function validate($entity, Constraint $constraint) {
$media = $entity->referencedEntities();
if (!media) {
return;
}
foreach ($media as $item) {
$settings = $item->get('field_media_image')->getSettings();
$file_bytes = $item->get('field_media_image')->entity->getSize();
$size = number_format($file_bytes / 1048576, 2);
// Load the custom media settings from custom form.
$media_config = $this->configFactory->get('custom_media_constraints.settings');
$_expected_size = $media_config->get($constraint->key . '_expected_size');
if (empty($_expected_size)) {
continue;
}
if ($_expected_size != '' && $size > $_expected_size) {
$this->context->addViolation(
$constraint->isWidthHeight(
'%value' => $size . 'MB',
'%expected' => $_expected_size . 'MB',
'%name' => $entity->getFieldDefination()->getLabel(),
);
);
}
}
}
}
3. Use hook_entity_bundle_field_info_alter to add the custom media constraint.
- Next you need to use the hook
hook_entity_bundle_field_info_alter
, to add this constraint to the media entity for the needed entities in drupal application. - This needs to be added in the
custom_media_constraint.module
file.
<?php
use Drupal/Core/Routing/RouteMatchInterface;
use Drupal/Core/Entity/EntityTypeInterface;
/**
* Implements hook_entity_bundle_field_info_alter().
*/
function custom_media_constraint_entity_bundle_field_info_alter(&$fields, EntityTypeInterface $entity_type, $bundle) {
if ($entity_type->id() == 'node') {
$storage = /Drupal::service('entity_type.manager')->getStorage('field_storage_config');
$media_fields = $storage->loadByProperties([
'type' => 'entity_reference',
'settings' => ['target_type' => 'media']
]);
foreach ($media_fields as $key => $media_field) {
$media_field_name = $field->getName();
if (isset($fields[$media_field_name])) {
$fields[$media_field_name]->addConstraint('custom_media_constraint', ['key' => $key]);
}
}
}
}
Once you create the custom constraint and constraint validation, then you attach this validator via the hook to the needed entities.
One important thing is the custom media sizes should be defined by the admin via the custom form, refer the validate function in the CustomMediaConstraintValidator
for more understanding of this.
Hope you have a picture on how people can create custom constraint validators for the media entities. Thanks for reading the article, for more drupal related articles, check out here.