Не видя весь код, используемый для custom_type сущность, включая код для ее обработчиков и отвечая на вопрос, почему код не находит дубликаты, я могу предположить, что в показанном коде есть два «недостатка».
Первый «недостаток» заключается в том, что запрос на поиск существующих сущностей более ограничен, чем должен. Это означает, что он проверяет поля сущностей, которые должны быть нерелевантными, чтобы сущности были дубликатами, например:
- положение дел поле, предполагая, что это положение дел поле, используемое основными объектами Drupal
- датировать поле, при условии, что оно содержит дату/временную метку создания
Единственная основная сущность Drupal, которая использует проверку сущности, чтобы избежать создания дублирующихся сущностей, — это path_alias организация, реализуемая Псевдоним пути
учебный класс. Эта сущность имеет положение дел поле, оно поддерживает ревизии, но у него нет ни поля для хранения, когда оно было создано, ни сущности-владельца (как у узлов).
Валидатор UniquePathAliasConstraintValidator
является его средством проверки ограничения сущности; код для UniquePathAliasConstraintValidator::validate()
является следующим.
$path = $entity->getPath();
$alias = $entity->getAlias();
$langcode = $entity->language()->getId();
$storage = $this->entityTypeManager->getStorage('path_alias');
$запрос = $хранилище->getQuery()
->Проверка доступа(ЛОЖЬ)
->условие('псевдоним', $псевдоним, '=')
->условие('langcode', $langcode, '=');
если (!$entity->isNew()) {
$query->условие('id', $entity->id(), '<>');
}
если ($путь) {
$query->условие('путь', $путь, '<>');
}
если ($результат = $запрос->диапазон(0, 1)->выполнить()) {
$existing_alias_id = сброс($результат);
$existing_alias = $storage->load($existing_alias_id);
если ($existing_alias->getAlias() !== $alias) {
$this->context->buildViolation($constraint-> DifferentCapitalizationMessage, ['%alias' => $alias, '%stored_alias' => $existing_alias->getAlias()])
->добавитьнарушение();
}
еще {
$this->context->buildViolation($constraint->message, ['%alias' => $alias])
->добавитьнарушение();
}
}
}
Используя этот код в качестве примера и используя только код, который строго проверяет наличие дубликатов, в вашем случае я бы использовал следующий код. (Я показываю только код для уникальный()
.)
частная функция isUnique (CustomType $entity) {
$date = $entity->get('date')->value;
$type = $entity->bundle();
$employee = $entity->get('employee')->target_id;
$query = $this->entityTypeManager->getStorage('custom_type')
-> получить запрос ()
->Проверка доступа(ЛОЖЬ)
->условие('тип', $тип)
->условие('сотрудник', $сотрудник)
->условие('дата', $дата);
если (!$entity->isNew()) {
$query->условие('id', $entity->id(), '<>');
}
$result = $query->range(0, 1)->execute();
вернуть пустой ($ результат);
}
Я добавил звонок в проверка доступа(ЛОЖЬ)
потому что, не видя кода, используемого обработчиком доступа к сущности, и не зная, есть ли у сущности сущность-владелец, я не могу исключить реализацию уникальный()
не находит дубликатов, потому что текущий пользователь, вошедший в систему, не имеет доступа к дубликатам (или любому объекту этого типа). Без звонка проверка доступа(ЛОЖЬ)
, запрос вернет сущности, к которым имеет доступ текущий пользователь, вошедший в систему.
(пропущенный вызов проверка доступа(ЛОЖЬ)
это другой возможный «недостаток», который я вижу в показанном коде.)