Puncte:2

Cum se folosesc valorile unei entități la care se face referire într-un TableSort?

drapel ai

Am o entitate personalizată cu un câmp care este definit după cum urmează.

$fields['file'] = BaseFieldDefinition::create('file')
  ->setDescription('Referință la tipul de entitate fișier principal încorporat.')
  ->setLabel('Fișier')
  ->setRequired(TRUE)
  ->setSetting('file_extensions', 'pdf rtf doc docx')
  ->setSetting('max_filesize', '20MB')
  ->setSetting('description_field', TRUE)
  ->setDisplayOptions('form', ['type' => 'fișier'])
  ->setDisplayOptions('view', ['type' => 'file']);

Nu am nicio problemă să ajung la câmpurile celor referiți Fişier entitate din instanțe de tipul meu de entitate. Deci, de exemplu, aceste linii funcționează conform așteptărilor.

$filename = $my_entity->file->entity->filename->value;
$username = $my_entity->file->entity->uid->entity->name->value;

Când încerc să folosesc câmpurile celor referite Fişier entitate cu a TableSort, pe care vreau să îl conectez la o interogare de entitate pe tipul meu personalizat de entitate, codul aruncă o excepție.

$header['nume'] = [
  'data' => 'Numele fișierului',
  'field' => 'file.entity.filename',
  'specifier' => 'file.entity.filename',
];
$header['utilizator'] = [
  'data' => 'Încărcat de',
  'field' => 'file.entity.uid.entity.name',
  'specifier' => 'file.entity.uid.entity.name',
];

// â¦

$interogare->tableSort($header);

Excepție PHP neprinsă Drupal\Core\Entity\Query\QueryException: „„fișierul” nu a fost găsit”

Pentru sintaxa lui $header matrice pe care mă bazez în mare măsură pe indicii de la care am primit Tablesort cu EntityQuery, în care Berdir recomandă să ne uităm la sarcină() și buildHeader() metode ale UserListBuilder clasă. Din păcate, acel exemplu pare să folosească valorile câmpurilor care sunt stocate direct în tabelul de bază, așa că mă întorc la presupunerea că, deoarece ne aflăm în terenul de interogare de entitate, aceeași sintaxă descrisă în QueryInterface::condition() ar fi de așteptat.

M-am uitat la o serie de probleme deschise, cum ar fi Sortarea tabelului ignoră „câmpul”, adaugă întotdeauna titlul antetului ca parametru de interogare de comandă și Curățare de sortare a mesei, dar nu am văzut nimic care să arunce o lumină asupra problemei.

drapel cn
Este cu siguranță acceptat cu sintaxa pe care o utilizați, deoarece funcționează bine pentru nodurile care folosesc de ex. `uid.entity.name` ca specificator. Ați avut probleme la instalarea acestui câmp de fișier? Sau poate l-ai schimbat după instalare? A schimbat cardinalitatea, așa ceva?
drapel ai
@Clive - Nicio problemă la instalarea câmpului și nicio modificare a configurației acestuia nu a fost făcută. Pot popula câmpul perfect atunci când creez sau actualizez entitățile și pot ajunge la oricare dintre proprietățile câmpului folosind sintaxa standard de acces la câmpul de entitate. Crezi că ar trebui să depun un raport de eroare (cu un caz repro)?
drapel cn
Nu sunt sigur dacă este o eroare sau doar ceva nedocumentat, există o sintaxă care funcționează pentru câmpurile de bază ale fișierului. Am pus un răspuns, dar sper să-l actualizez când voi avea timp să aflu mai multe
drapel ai
@Clive - În primul rând, sunt _foarte_ impresionat că ți-ai dat seama de asta. Mi-am actualizat [raportul de erori](https://www.drupal.org/project/drupal/issues/3278083) pentru a reflecta aceste noi informații. Versiune scurtă: este o eroare în documentație sau în software și cred că se poate face un caz mai puternic pentru ca software-ul să fie conform cu sintaxa documentată în prezent pentru _orice_ tip de câmp de referință de bază. Accept răspunsul tău genial, chiar înainte să fi avut ocazia să-l actualizezi.
Puncte:2
drapel cn

Există o eroare în nucleu și, deocamdată, o soluție este:

'specifier' => 'file.target_id.entity.filename',

Motivul pentru aceasta este sintaxa relației de interogare a entității a început ca suport de unire, este anterioară suportului de referință de entitate în bază și, ca atare, în timp ce $entity->fișier->target_id->entity nu este susținut de nucleu, file.target_id.entity este suportat de interogarea entitate pentru a indica că ar trebui să se alăture entității specificate de fişier câmpul și id-ul entității ar trebui să fie ceea ce este specificat de target_id. Este un pic neplăcut, dar la momentul respectiv, a fost ceea ce a funcționat.

Aceasta ar trebui să să poată da seama fișier.entitate.nume fișier precum și pentru că numele principal al proprietății pentru fişier câmp se întâmplă să fie target_id și astfel este capabil să-l extindă pentru tine în file.target_id.entity.filename. Cu toate acestea, clasa în caz Drupal\Core\Entity\Query\Sql\Tables este extrem de complicat și această expansiune are o eroare pentru cazul tabelului partajat care va fi remediat https://www.drupal.org/project/drupal/issues/3278083

drapel ai
Deci sugerați că documentația trebuie remediată, nu codul? N-ar fi prima dată.
drapel ai
Accept răspunsul tău excelent, deși nu sunt sigur că înțeleg ce vrei să spui în explicația ta.Am nenumărate exemple de condiții de referință la entități în interogările de entități care se bazează pe un câmp de referință stocat în tabelul de bază și funcționează foarte bine cu sintaxa documentată.
drapel cn
Da, referința la entitate vanilie ca câmp de bază pare să funcționeze așa cum v-ați aștepta. Dacă aș fi parior, fără să mă uit bine, aș spune că probabil că se datorează faptului că câmpul de referință al entității de bază are doar o singură coloană DB (`target_id`), deci nu ar fi nevoie ca sintaxa să accepte „sub-câmpurile”. "; coloana `fieldname__target_id` poate fi dedusă (sub-câmpurile probabil NU este un termen oficial apropo :) ). Câmpurile de fișiere au 3 coloane DB, așa că interogărilor trebuie să li se spună în mod explicit care coloană `file__*` din tabelul de bază trebuie utilizată, de aici cealaltă sintaxă. Ar putea fi totusi altceva
drapel cn
L-am găsit - `DefaultTableMapping::getFieldColumnName()` este pistolul fumegând. Dacă un câmp are o singură coloană, numele său de coloană DB este numele câmpului. Deci, un câmp de referință de entitate cu un ID de `uid`, are o coloană DB numită `uid`. Când interogați `uid.entity.*`, există o potrivire directă pe numele coloanei DB și totul este în regulă. Când un câmp are mai mult de o coloană, coloanele DB sunt denumite `fieldname__property_name`, deci atunci când interogați `fieldname.entity`, nu există nicio coloană DB `fieldname`. Sintaxa extinsă este acolo pentru a acoperi acest decalaj și vă permite să selectați coloana din dreapta
drapel ai
Mulțumesc pentru această spelă excelentă. Voi include un link către această pagină din raportul de eroare.
Smartsheet eng avatar
drapel um
Aceasta este o soluție care funcționează, dar nu este motivul pentru care `fieldname.entity.propertyname` nu funcționează. Cauza este că dacă 1) un câmp cu mai multe coloane 2) este stocat în tabelul partajat 3) și este utilizat într-o interogare în care specificatorii urmează numele câmpului - atunci codul de mapare a tabelului nu este apelat deloc. Există o eroare în Tables. Am lăsat un răspuns și am depus un patch. De asemenea, „sistemul pur și simplu nu știe ce fișier este”. cu siguranță știe, este un câmp. Codul pur și simplu nu apelează `$sql_column = $table_mapping->getFieldColumnName($field_storage, $column);` acest lucru este un caz marginal foarte rar.
drapel cn
@Smartsheeteng Într-adevăr, o eroare ar putea fi cu ușurință motivul pentru care _sistemul pur și simplu nu știe ce fișier este_ în acel moment (ceea ce nu știe, mapările tabelelor nu conțin `fișier`, ele conțin `fișier__*`)
Smartsheet eng avatar
drapel um
@Clive sistemul știe ce fișier este, este un câmp. Te uiți la clasa greșită, eroarea se află în Tabele, nu în clasa de mapare. Problema este că clasa nu este apelată în primul rând pentru acest specificator. Acest răspuns este complet greșit, îl voi edita și îl voi șterge pe al meu pentru că este superflu.
drapel cn
@Smartsheeteng Nu mi-am dat seama că ai scris codul original, așa că corect, răspunsul a fost editat
Puncte:1
drapel ai

Eșecul descris mai sus pare a fi rezultatul a gândac în FileItem conecteaza. Chiar dacă pluginul de tip câmp creanțe este o referință la entitate (the @FieldType adnotarea spune categorie = @Translation(„Referință”)), iar în toate celelalte privințe este adevărat, sprijinul pentru sintaxa de interogare documentată este rupt.

Până la remedierea erorii, soluția ar fi renunțarea la specializarea implementată de FileItem tip câmp și folosiți o câmpie entity_reference câmp în schimb. Cu acea schimbare TableSort codul de mai sus funcționează corect.

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.