Puncte:1

ConstraintValidator nu reușește să valideze constrângerea în câmpul de referință al termenului de taxonomie

drapel nr

Clientul are o taxonomie ierarhică simplă și consistentă.

Orașe la nivelul superior și școli la nivelul doi.

.
âââ Oraş1
â  âââ Scoala1
â  âââ Scoala2
â  âââ Scoala5
âââ Oraş2
    âââ Scoala3
    âââ Scoala4

Pachetul de entitate cont de utilizator conține un câmp Referință de entitate la termenii taxonomiei școlii.

Încerc să impun o constrângere pentru a împiedica crearea sau salvarea unui cont de utilizator dacă termenul selectat se află la nivelul superior al ierarhiei (și, prin urmare, un oraș, nu o școală).

Iată un exemplu de cod, omitând injecția de dependență a $this->entityTypeManager pentru concizie.

TermParentConstraint.php:

<?php

spațiu de nume Drupal\entity_validation_examples\Plugin\Validation\Constraint;

utilizați Symfony\Component\Validator\Constraint;

/**
 * Preveniți crearea contului dacă termenul de taxonomie școlară nu are părinte.
 *
 * @Constraint(
 * id = „TermParent”,
 * label = @Translation ("Preveniți crearea contului dacă termenul nu are părinte", context = "Validare"),
 * tip = „entitate”
 * )
 */
clasa TermParentConstraint extinde Constraint {

  /**
   * Mesaj afișat când se încearcă crearea unui cont dacă școala nu are oraș părinte.
   *
   * @var șir
   * Mesajul școlii.
   */
  public $schoolMessage = 'Trebuie să selectați atât un oraș, cât și o școală.';

}

TermParentConstraintValidator.php:

<?php

spațiu de nume Drupal\entity_validation_examples\Plugin\Validation\Constraint;

utilizați Drupal\utilizator\Entitate\Utilizator;
utilizați Symfony\Component\Validator\Constraint;
utilizați Symfony\Component\Validator\ConstraintValidator;

/**
 * Validează constrângerea TermParent.
 */
clasa TermParentConstraintValidator extinde ConstraintValidator {

  /**
   * {@inheritdoc}
   */
  validare funcție publică($entitate, Constrângere $constrângere) {
    dacă (!isset($entitate)) {
      întoarcere;
    }

    if ($entity->getEntityTypeId() == 'utilizator') {

      $school = $entity->get('field_select_a_school')->getValue();

      // Termenii taxonomiei școlilor orfane trebuie să fie orașe, nu școli.
      $parent = \Drupal::entityTypeManager()
        ->getStorage('termen_taxonomie')
        ->loadParents($school[0]['target_id']);
      dacă (gol ($părinte)) {
        $this->context->addViolation($constraint->schoolMessage);
      }
    }
  }

}

Comportament asteptat: Când creez un nou cont de utilizator și selectez Orașul 1 ca valoare a Şcoală, crearea contului ar trebui să eșueze și ar trebui să fie afișat un mesaj de eroare.

Comportament real: Când creez un nou cont de utilizator și selectez Orașul 1 ca valoare a Şcoală, crearea contului reușește și nu este afișat niciun mesaj de eroare.

Jurnalele Drupal Watchdog conțin unele erori, dar nu sunt sigur că sunt relevante:

 drush ws
 --------- -------------- ------ ---------- ----------- --------------------------------------------- --------------------------------------------- --------------------------------------------- ------------------------------ 
  ID Data Tip Severitate Mesaj                                                                                                                                                                                       
 --------- -------------- ------ ---------- ----------- --------------------------------------------- --------------------------------------------- --------------------------------------------- ------------------------------ 
  5298867 18/Oct 22:57 php Avertisment Avertisment: Tip offset ilegal în isset sau gol în Drupal\Core\Entity\EntityStorageBase->load() (linia 246 din /app/docroot/core/lib/Drupal/Core/Entity/ EntityStorageBase.php) #0 /app/docroot/  
  5298866 18/Oct 22:57 php Notice Notificare: Conversie matrice în șir în Drupal\Core\Entity\EntityStorageBase->buildCacheId() (linia 126 din /app/docroot/core/lib/Drupal/Core/Entity/Base.phpStorage ) #0 /app/docroot/core  
  5298865 18/Oct 22:57 php Avertisment Avertisment: array_flip(): Poate răsturna numai valorile STRING și INTEGER! în Drupal\Core\Entity\EntityStorageBase->loadMultiple() (linia 261 din /app/docroot/core/lib/Drupal/Core/Entity/EntityStorageB  
  5298864 18/Oct 22:57 php Notice Notice: iconv(): set de caractere greșit, conversia din „HTML-ENTITIES” în „UTF-8” nu este permisă în twig_convert_encoding() (linia 1009 din /app/vendor/twig/twig) /src/Extension/CoreExtension.php) #0  
  5298863 18/Oct 22:57 php Notice Notice: iconv(): set de caractere greșit, conversia din „HTML-ENTITIES” în „UTF-8” nu este permisă în twig_convert_encoding() (linia 1009 din /app/vendor/twig/twig) /src/Extension/CoreExtension.php) #0  
  5298862 18/Oct 22:57 php Notice Notice: iconv(): set de caractere greșit, conversia din „HTML-ENTITIES” în „UTF-8” nu este permisă în twig_convert_encoding() (linia 1009 din /app/vendor/twig/twig /src/Extension/CoreExtension.php) #0  
  5298861 18/Oct 22:57 php Notice Notice: iconv(): set de caractere greșit, conversia din „HTML-ENTITIES” în „UTF-8” nu este permisă în twig_convert_encoding() (linia 1009 din /app/vendor/twig/twig /src/Extension/CoreExtension.php) #0  
  5298860 18/Oct 22:57 php Notice Notice: iconv(): set de caractere greșit, conversia din „HTML-ENTITIES” în „UTF-8” nu este permisă în twig_convert_encoding() (linia 1009 din /app/vendor/twig/twig) /src/Extension/CoreExtension.php) #0  
  5298859 18/Oct 22:57 php Notice Notice: iconv(): set de caractere greșit, conversia din „HTML-ENTITIES” în „UTF-8” nu este permisă în twig_convert_encoding() (linia 1009 din /app/vendor/twig/twig /src/Extension/CoreExtension.php) #0  
  5298858 18/Oct 22:57 php Notice Notice: iconv(): set de caractere greșit, conversia din „HTML-ENTITIES” în „UTF-8” nu este permisă în twig_convert_encoding() (linia 1009 din /app/vendor/twig/twig /src/Extension/CoreExtension.php) #0  
 --------- -------------- ------ ---------- ----------- --------------------------------------------- --------------------------------------------- --------------------------------------------- ------------------------------ 

L-am văzut pe iconv() erori de la actualizarea acestui proiect de la Drupal 8 la Drupal 9, deci nu cred că sunt relevante. Cele mai importante trei mesaje de eroare de aici pot fi legate de validarea constrângerii, dar sunt și erori destul de comune în acest proiect (și depanarea lor este o prioritate mult mai mică decât funcționalitatea esențială care se va datora foarte curând).

Vreo idee? Sunt măcar pe drumul cel bun?

Puncte:1
drapel ph

The loadParents() apeluri de metodă loadMultiple(), și acolo este locul array_flip() se întâmplă o eroare:

Avertisment: array_flip(): Se pot inversa numai valorile STRING și INTEGER! în Drupal\Core\Entity\EntityStorageBase->loadMultiple() (linia 261 din /app/docroot/core/lib/Drupal/Core/Entity/EntityStorageB

Deci, cel mai probabil, ceva se întâmplă acolo.

The loadParents() metoda este diferită în funcție de versiunea dvs. Drupal.

hotwebmatter avatar
drapel nr
Multumesc pentru sfat! Iată `starea drush` parțială: Versiunea Drupal: `9.2.7` Bază de date: `Conectat` Drupal bootstrap: `Success` Tema implicită: `projectname` Tema admin: `projectname_admin` Versiunea Drush: `10.6.0` Profil de instalare: ` standard` rădăcină Drupal: `/app/docroot`
Puncte:1
drapel cn

Problema este că încărcați părinții într-o matrice și apoi verificați dacă există o valoare goală. Termenii de la nivelul superior pot avea un părinte rădăcină (ID=0), deci acesta ar fi și un element din matrice, chiar dacă nu indică un termen existent.

Puteți încerca să simplificați codul, deoarece D8.6 nu mai trebuie să utilizați termenul de stocare pentru a gestiona câmpul părinte. empty() pe capturile ID țintă NUL pentru un câmp gol și 0 pentru părintele rădăcină.

 validare funcție publică($entitate, Constrângere $constrângere) {
    dacă (!isset($entitate)) {
      întoarcere;
    }

    if ($entity->getEntityTypeId() == 'utilizator') {
      $term = $entity->get('field_select_a_school')->entity;
      dacă ($term) {
        if (gol ($term->parent->target_id)) {
          $this->context->addViolation($constraint->schoolMessage);
        }
      }
    }

  }
Puncte:0
drapel nr

În acest caz, se dovedește că cea mai rapidă soluție este configurarea Selectare ierarhică simplă widget-ul corect. (Modulul SHS este deja instalat, așa că aș putea la fel de bine să-l folosesc!)

Pentru înregistrare, aceasta este configurația problematică a widgetului.

INAINTE DE:

Caseta de selectare cu eticheta „Forțați selecția nivelului cel mai profund” debifată

DUPĂ:

Caseta de selectare etichetată „Forțați selecția nivelului cel mai profund” bifată

Mulțumesc pentru toate răspunsurile, tuturor! Am învățat destul de multe despre validarea constrângerilor și taxonomia ierarhică, ceea ce mă va ajuta data viitoare când trebuie să mă ocup de arbori de taxonomie sau să implementez un ConstraintValidator clasă.

Postează un răspuns

Majoritatea oamenilor nu înțeleg că a pune multe întrebări deblochează învățarea și îmbunătățește legătura interpersonală. În studiile lui Alison, de exemplu, deși oamenii își puteau aminti cu exactitate câte întrebări au fost puse în conversațiile lor, ei nu au intuit legătura dintre întrebări și apreciere. În patru studii, în care participanții au fost implicați în conversații ei înșiși sau au citit transcrieri ale conversațiilor altora, oamenii au avut tendința să nu realizeze că întrebarea ar influența – sau ar fi influențat – nivelul de prietenie dintre conversatori.