View source
<?php
namespace Drupal\node_title_validation\Plugin\Validation\Constraint;
use Drupal\Core\Config\ConfigFactory;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\StringTranslation\TranslationInterface;
use Drupal\node\NodeInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
class NodeTitleConstraintValidator extends ConstraintValidator implements ContainerInjectionInterface {
use StringTranslationTrait;
protected $entityTypeManager;
protected $configFactory;
public static function create(ContainerInterface $container) {
return new static($container
->get('entity_type.manager'), $container
->get('config.factory'), $container
->get('string_translation'));
}
public function __construct(EntityTypeManagerInterface $entityTypeManager, ConfigFactory $configFactory, TranslationInterface $stringTranslation) {
$this->entityTypeManager = $entityTypeManager;
$this->configFactory = $configFactory;
$this->stringTranslation = $stringTranslation;
}
public function validate($items, Constraint $constraint) {
if ($items
->isEmpty()) {
return;
}
$value_title = $items->value;
if (empty($value_title)) {
return;
}
$node = $items
->getEntity();
if (!$node instanceof NodeInterface) {
return;
}
$node_type = $node
->getType();
if (empty($node_type)) {
return;
}
$node_title_validation_config = $this->configFactory
->getEditable('node_title_validation.node_title_validation_settings')
->get('node_title_validation_config');
if (empty($node_title_validation_config)) {
return;
}
$title = explode(' ', $value_title);
$nodeStorage = $this->entityTypeManager
->getStorage('node');
$exclude_comma = [];
if (!empty($node_title_validation_config['comma-' . $node_type])) {
$exclude_comma[] = ',';
}
$type_exclude = isset($node_title_validation_config['exclude-' . $node_type]) ? $node_title_validation_config['exclude-' . $node_type] : '';
if (!empty($type_exclude) || $exclude_comma) {
$type_exclude = str_replace("\r\n", ',', $type_exclude);
$type_exclude = explode(',', $type_exclude);
$type_exclude = array_merge($type_exclude, $exclude_comma);
$findings = _node_title_validation_search_excludes_in_title($value_title, $type_exclude);
if ($findings) {
$message = $this
->t("This characters/words are not allowed to enter in the title - @findings", [
'@findings' => implode(', ', $findings),
]);
$this->context
->addViolation($message);
}
}
$include_comma = [];
foreach ($node_title_validation_config as $config_key => $config_value) {
if ($config_value && $config_key == 'comma-' . $node_type) {
$include_comma[] = ',';
}
if ($config_key == 'exclude-' . $node_type || $include_comma) {
if (!empty($config_value)) {
$config_values = array_map('trim', explode(',', $config_value));
$config_values = array_merge($config_values, $include_comma);
$findings = [];
foreach ($title as $title_value) {
if (in_array(trim($title_value), $config_values)) {
$findings[] = $title_value;
}
}
if ($findings) {
$message = $this
->t("These characters/words are not permitted in the title - @findings", [
'@findings' => implode(', ', $findings),
]);
$this->context
->addViolation($message);
}
}
}
if ($config_key == 'min-' . $node_type) {
if (mb_strlen($value_title) < $config_value) {
$message = $this
->t("Title should have a minimum @config_value character(s)", [
'@config_value' => $config_value,
]);
$this->context
->addViolation($message);
}
}
if ($config_key == 'max-' . $node_type) {
if (mb_strlen($value_title) > $config_value) {
$message = $this
->t("Title should not exceed @config_value character(s)", [
'@config_value' => $config_value,
]);
$this->context
->addViolation($message);
}
}
if ($config_key == 'min-wc-' . $node_type) {
if (count(explode(' ', $value_title)) < $config_value) {
$message = $this
->t("Title should have a minimum word count of @config_value", [
'@config_value' => $config_value,
]);
$this->context
->addViolation($message);
}
}
if ($config_key == 'max-wc-' . $node_type) {
if (count(explode(' ', $value_title)) > $config_value) {
$message = $this
->t("Title should not exceed a word count of @config_value", [
'@config_value' => $config_value,
]);
$this->context
->addViolation($message);
}
}
if ($config_key == 'unique-' . $node_type || $config_key == 'unique') {
if ($config_value == 1) {
$properties = [
'title' => $value_title,
];
if ($config_key == 'unique-' . $node_type) {
$properties['type'] = $node_type;
}
$nodes = $nodeStorage
->loadByProperties($properties);
if (isset($nodes[$node
->id()])) {
unset($nodes[$node
->id()]);
}
if (!empty($nodes)) {
$message = $this
->t("The title must be unique. Other content is already using this title: @title", [
'@title' => $value_title,
]);
$this->context
->addViolation($message);
}
}
}
}
}
}
function _node_title_validation_search_excludes_in_title($input, array $find) {
$findings = [];
foreach ($find as $char) {
if (mb_strlen(trim($char)) == 1) {
if (strpos($input, trim($char)) !== FALSE) {
$characters = $char == ',' ? '<b>,</b>' : trim($char);
$findings[] = $characters;
}
}
}
$words = explode(' ', $input);
if (!empty($find)) {
$find = array_map('trim', $find);
}
foreach ($words as $word) {
if (mb_strlen(trim($word)) > 1) {
if (in_array($word, $find)) {
$findings[] = $word;
}
}
}
return $findings;
}