ここに明らかなものが欠けているかもしれません。したがって、Drupal 8にはコンテンツタイプがあります。これには、日付範囲フィールドがあり、段落を使用します。段落には、日付フィールドを含む複数のフィールドがあります。
したがって、日付範囲フィールド(field_A)が開始と終了が正しいことを確認できるように、検証する必要があります。つまり、開始は終了時または終了前です。問題ありません、それが行われ、散りばめられます-FirstConstraintValidator.php。
次に(SecondConstraintValidator.php)そのコンテンツタイプの段落について、日付フィールドを確認する必要があります。これをfield_Bと呼び、Field_Bの開始日と終了日の間またはその間にあります。これは私が問題を抱えているところです。できない方法でやろうとしているのかもしれません。
だから私は持っています(私はそれが乱雑で不完全であることを知っています):
my_module.module
function my_module_entity_bundle_field_info_alter(&$fields, \Drupal\Core\Entity\EntityTypeInterface $entity_type, $bundle) {
if ($entity_type->id() === 'paragraph' && $bundle === 'bundle_B') {
$fields['field_B']->addConstraint('SecondConstraint', []);
} else if ($entity_type->id() === 'node' && $bundle === 'bundle_A') {
$fields['field_A']->addConstraint('FirstConstraint', []);
}
}
FirstConstraintValidator.php
class FirstConstraintValidator extends ConstraintValidator {
public function validate($items, Constraint $constraint) {
$entity = $items->getEntity();
$start_date = date("Y-m-d",strtotime($entity->get('field_A')->getValue()[0]['value']));
$end_date = date("Y-m-d",strtotime($entity->get('field_A')->getValue()[0]['end_value']));
if ($start_date > $end_date) {
// Start date must be on or before end date...
$this->context->addViolation( xxxxxx );
}
}
}
SecondConstraintValidator.php
class SecondConstraintValidator extends ConstraintValidator {
public function validate($items, Constraint $constraint) {
$entity = $items->getEntity();
$parentEntity = $entity->getParentEntity();
// THIS IS WHERE I NEED TO GET SUBMITTED VALUES.
// LINES BELOW RETURNED ORIGINAL STORED VALUE, NOT UPDATED VALUE
$start_date = date("Y-m-d",strtotime($parentEntity->get('field_A')->getValue()[0]['value']));
$end_date = date("Y-m-d",strtotime($parentEntity->get('field_A')->getValue()[0]['end_value']);
// field_a is valid (i.e. start date is before or on end date)
if ($start_date <= $end_date) {
if ($items->value > $end_date || $items->value < $start_date) {
// The date is after the end date of field_a
// OR
// the date is before the start date of field_a
$this->context->addViolation( xxxxx );
}
}
}
}
ノードを保存すると、残りのノードの前に段落が検証されることに気づきました。とにかく、代わりの方法はform_alterと$ form ['#validate'] []を使用することですが、私の理解はD8であったため、ConstraintValidatorなどを使用する必要があります。質問は、私はこれを正しい方法でやっているのですか?何か不足していますか?
ありがとう
-------更新-部分的に解決-------
@ 4k4のおかげで部分的に機能するソリューションがあります。これは他の人を助けるかもしれません。
my_module.moduleがオリジナルから(つまり、段落フィールドに制約を追加する)に変更されました。
function my_module_entity_bundle_field_info_alter(&$fields, \Drupal\Core\Entity\EntityTypeInterface $entity_type, $bundle) {
if ($entity_type->id() === 'node' && $bundle === 'bundle_A') {
$fields['field_A']->addConstraint('FirstConstraint', []);
$fields['field_B']->addConstraint('SecondConstraint', []);
}
}
field_Aは日付範囲ですfield_Bは、日付フィールドなどが含まれる段落を参照します。
SecondConstraintValidator.phpに変更:
class SecondConstraintValidator extends ConstraintValidator {
public function validate($items, Constraint $constraint) {
$entity = $items->getEntity();
$start_date = date("Y-m-d",strtotime($parentEntity->get('field_A')->getValue()[0]['value']));
$end_date = date("Y-m-d",strtotime($parentEntity->get('field_A')->getValue()[0]['end_value']);
// field_a is valid (i.e. start date is before or on end date)
if ($start_date <= $end_date) {
if ($items->value > $end_date || $items->value < $start_date) {
// field_A is valid, but field_B is not. show an error for field_B
$this->context->addViolation( xxxxx );
}
}
}
}
上記は問題なく、段落が1つしかない場合に機能します。複数を許可する場合、これが正しく機能していないことに注意してください。次のようなものが必要です。
SecondConstraintValidator.php
class SecondConstraintValidator extends ConstraintValidator {
public function validate($items, Constraint $constraint) {
$entity = $items->getEntity();
$start_date = date("Y-m-d",strtotime($entity->get('field_a')->getValue()[0]['value']));
$end_date = date("Y-m-d",strtotime($entity->get('field_a')->getValue()[0]['end_value']));
// field_a is valid (i.e. start date is before or on end date)
if ($start_date <= $end_date) {
foreach ($items as $activity) {
$date = $activity->getValue()['subform']['field_b'][0]['value']->format('Y-m-d');
if ($date > $end_date || $date < $start_date) {
$this->context->addViolation( xxxxx );
}
}
}
}
}
上記も、最善の解決策ではない可能性があります。これはすべてのfield_Bに違反を追加するため、段落のコピーを2つ追加し、そのうちの1つだけを検証しないと、すべてにエラーが表示されます。 $ this-> context-> addViolation(xxxxx);変更を加えて、その段落のフィールドにのみ違反を追加する必要があります。
すべてのコメントのおかげで、他の人を助けることができる実用的な解決策があります。
my_module.moduleがオリジナルから(つまり、段落フィールドに制約を追加する)に変更されました。
function my_module_entity_bundle_field_info_alter(&$fields, \Drupal\Core\Entity\EntityTypeInterface $entity_type, $bundle) {
if ($entity_type->id() === 'node' && $bundle === 'bundle_A') {
$fields['field_A']->addConstraint('FirstConstraint', []);
$fields['field_B']->addConstraint('SecondConstraint', []);
}
}
field_Aは日付範囲ですfield_Bは、日付フィールドなどが含まれる段落を参照します。 field_Cは段落内の日付フィールドです
SecondConstraintValidator.phpに変更:
class SecondConstraintValidator extends ConstraintValidator {
public function validate($items, Constraint $constraint) {
$entity = $items->getEntity();
$start_date = date("Y-m-d",strtotime($parentEntity->get('field_A')->getValue()[0]['value']));
$end_date = date("Y-m-d",strtotime($parentEntity->get('field_A')->getValue()[0]['end_value']);
// field_a is valid (i.e. start date is before or on end date)
if ($start_date <= $end_date) {
if ($items->value > $end_date || $items->value < $start_date) {
// field_A is valid, but field_B is not. show an error for field_B
$this->context->addViolation( xxxxx );
}
}
}
}
上記は問題なく、段落が1つしかない場合に機能します。複数を許可する場合は、次のようなものが必要です。
SecondConstraintValidator.php
class SecondConstraintValidator extends ConstraintValidator {
public function validate($items, Constraint $constraint) {
$entity = $items->getEntity();
$start_date = date("Y-m-d",strtotime($entity->get('field_a')->getValue()[0]['value']));
$end_date = date("Y-m-d",strtotime($entity->get('field_a')->getValue()[0]['end_value']));
// field_a is valid (i.e. start date is before or on end date)
if ($start_date <= $end_date) {
foreach ($items as $key as $activity) {
$date = $activity->getValue()['subform']['field_c'][0]['value']->format('Y-m-d');
if ($date > $end_date || $date < $start_date) {
$this->context->buildViolation("message")->atPath($key.'.field_c')->addViolation();
}
}
}
}
}
上記も、最善の解決策ではない可能性があります。コメントを受け付けますが、機能します!