客户端有一个简单而一致的分层分类法。
最高层次的城市和二级的学校。
.
├── City1
│ ├── School1
│ ├── School2
│ └── School5
└── City2
├── School3
└── School4用户帐户实体包包含一个指向学校分类法术语的实体引用字段。
如果所选术语位于层次结构的顶层(因此是城市,而不是学校),我试图强制执行限制,以防止创建或保存用户帐户。
下面是一些示例代码,为了简洁起见,跳过了$this->entityTypeManager的依赖项注入。
TermParentConstraint.php:
TermParentConstraintValidator.php:
getEntityTypeId() == 'user') {
$school = $entity->get('field_select_a_school')->getValue();
// Orphaned school taxonomy terms must be Cities, not Schools.
$parent = \Drupal::entityTypeManager()
->getStorage('taxonomy_term')
->loadParents($school[0]['target_id']);
if (empty($parent)) {
$this->context->addViolation($constraint->schoolMessage);
}
}
}
}Expected行为:当我创建一个新的用户帐户并选择City1作为School的值时,帐户创建应该失败,并显示一条错误消息。
Actual行为:当我创建一个新的用户帐户并选择City1作为School的值时,帐户创建成功,并且不会显示错误消息。
Drupal看门狗日志包含一些错误,但我不确定它们是否相关:
drush ws
--------- -------------- ------ ---------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ID Date Type Severity Message
--------- -------------- ------ ---------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
5298867 18/Oct 22:57 php Warning Warning: Illegal offset type in isset or empty in Drupal\Core\Entity\EntityStorageBase->load() (line 246 of /app/docroot/core/lib/Drupal/Core/Entity/EntityStorageBase.php) #0 /app/docroot/
5298866 18/Oct 22:57 php Notice Notice: Array to string conversion in Drupal\Core\Entity\EntityStorageBase->buildCacheId() (line 126 of /app/docroot/core/lib/Drupal/Core/Entity/EntityStorageBase.php) #0 /app/docroot/core
5298865 18/Oct 22:57 php Warning Warning: array_flip(): Can only flip STRING and INTEGER values! in Drupal\Core\Entity\EntityStorageBase->loadMultiple() (line 261 of /app/docroot/core/lib/Drupal/Core/Entity/EntityStorageB
5298864 18/Oct 22:57 php Notice Notice: iconv(): Wrong charset, conversion from `HTML-ENTITIES' to `UTF-8' is not allowed in twig_convert_encoding() (line 1009 of /app/vendor/twig/twig/src/Extension/CoreExtension.php) #0
5298863 18/Oct 22:57 php Notice Notice: iconv(): Wrong charset, conversion from `HTML-ENTITIES' to `UTF-8' is not allowed in twig_convert_encoding() (line 1009 of /app/vendor/twig/twig/src/Extension/CoreExtension.php) #0
5298862 18/Oct 22:57 php Notice Notice: iconv(): Wrong charset, conversion from `HTML-ENTITIES' to `UTF-8' is not allowed in twig_convert_encoding() (line 1009 of /app/vendor/twig/twig/src/Extension/CoreExtension.php) #0
5298861 18/Oct 22:57 php Notice Notice: iconv(): Wrong charset, conversion from `HTML-ENTITIES' to `UTF-8' is not allowed in twig_convert_encoding() (line 1009 of /app/vendor/twig/twig/src/Extension/CoreExtension.php) #0
5298860 18/Oct 22:57 php Notice Notice: iconv(): Wrong charset, conversion from `HTML-ENTITIES' to `UTF-8' is not allowed in twig_convert_encoding() (line 1009 of /app/vendor/twig/twig/src/Extension/CoreExtension.php) #0
5298859 18/Oct 22:57 php Notice Notice: iconv(): Wrong charset, conversion from `HTML-ENTITIES' to `UTF-8' is not allowed in twig_convert_encoding() (line 1009 of /app/vendor/twig/twig/src/Extension/CoreExtension.php) #0
5298858 18/Oct 22:57 php Notice Notice: iconv(): Wrong charset, conversion from `HTML-ENTITIES' to `UTF-8' is not allowed in twig_convert_encoding() (line 1009 of /app/vendor/twig/twig/src/Extension/CoreExtension.php) #0
--------- -------------- ------ ---------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 自从将这个项目从Drupal 8升级到Drupal 9之后,我就看到了iconv()错误,所以我不认为它们是相关的。此处的前三条错误消息可能与约束验证有关,但它们也是该项目中相当常见的错误(而且调试它们的优先级要比即将完成的基本功能低得多)。
有什么想法吗?我至少在正确的轨道上吗?
发布于 2021-10-19 13:19:44
在本例中,最快速的解决方案是正确配置简单分层选择小部件。( SHS模块已经安装好了,所以我也可以使用它!)
对于记录而言,这是有问题的小部件配置。
之前:

之后:

谢谢大家的回答!我学习了很多关于约束验证和层次分类法的知识,这将帮助我下次必须处理分类法树或实现ConstraintValidator类。
发布于 2021-10-19 00:00:51
loadParents()方法调用loadMultiple(),这就是array_flip()错误发生的地方:
Warning: array_flip(): Can only flip STRING and INTEGER values! in Drupal\Core\Entity\EntityStorageBase->loadMultiple() (line 261 of /app/docroot/core/lib/Drupal/Core/Entity/EntityStorageB所以很可能发生了什么事。
根据您的Drupal版本,loadParents()方法是不同的。
发布于 2021-10-19 07:54:50
问题是,您正在数组中加载父级,然后检查是否为空值。顶层的术语可以有根父项(ID=0),因此这也是数组中的一个项,即使没有指向现有的术语。
您可以尝试简化代码,因为D8.6不再需要使用术语存储来处理父字段。目标ID上的空()捕获空字段的NULL和根父字段的0。
public function validate($entity, Constraint $constraint) {
if (!isset($entity)) {
return;
}
if ($entity->getEntityTypeId() == 'user') {
$term = $entity->get('field_select_a_school')->entity;
if ($term) {
if (empty($term->parent->target_id)) {
$this->context->addViolation($constraint->schoolMessage);
}
}
}
}https://drupal.stackexchange.com/questions/307695
复制相似问题