În Drupal 7, a fost capabil să recupereze numele fizice ale tabelelor bazei de date folosind un cod ca următorul, a fost destul de simplu.
$field_definitions = field_info_fields();
foreach ($field_definitions as $field => $definition) {
$current_storage = $definition['storage']['details']['sql'][FIELD_LOAD_CURRENT];
$tabel_curent = cheie($stocare_curentă);
$revision_storage = $definition['storage']['details']['sql'][FIELD_LOAD_REVISION];
$tabel_reviziune = cheie($stocare_reviziune);
}
În Drupal 9, API-ul entității s-a schimbat în bine și acum există clase și servicii pentru a extrage acest tip de informații.Toate acestea sunt bine și bine, înțeleg majoritatea conceptelor din jurul acestui lucru, dar nu pot, pentru viața mea, să par să extrapolez cum să obțin aceleași date.
Scopul meu este să fac bucla peste toate tipurile mele de entități care le implementează ContentEntityTypeInterface, obțineți câmpurile lor, apoi construiți o matrice care să arate așa, am un script Drush foarte specializat pe care încerc să îl port din Drupal 7.
$exemplu = [
'nod' => [
'field_something' => [
'current' => 'un nume_tabel'
'revision' => 'un nume_tabel'
]
],
'bloc' => [
'field_something' => [
'current' => 'un nume_tabel'
'revision' => 'un nume_tabel'
]
]
];
*Desigur, ținând cont dacă un câmp este de fapt revizuibil, în primul rând.
Pe cont propriu, am stabilit în cea mai mare parte că numele tabelelor ajung să fie ca $entityType . '__' . $field['nume'] și $entityType . '_reviziune__' . $field['nume'] dar codificarea scriptului meu se defectează când sunt folosite ID-uri unice. De exemplu, blocurile personalizate au nume de tabel precum block_content_r__7fe666c7a4. Trebuie să pot extrage acele date din „definiția de stocare a câmpului” de fel.
Soluţie:
Pentru @Clive, soluția a fost să obținem clasa de stocare pentru fiecare tip de entitate și apoi să o folosiți pentru a prelua mapările de tabel. Acest lucru funcționează excelent pentru câmpurile care nu sunt de bază, dar dacă doriți un câmp de bază, soluția ar fi diferită. Iată cu ce am ajuns:
$câmpuri = [];
foreach ($this->getContentEntityTypes() ca $contentEntityType) {
$tableMapping = $this->entityTypeManager->getStorage($contentEntityType->id())->getTableMapping();
foreach ($this->entityFieldManager->getFieldStorageDefinitions($contentEntityType->id()) ca $câmp) {
// Folosim requiresDedicatedTableStorage() pentru a filtra câmpurile de bază
dacă ($tableMapping->requiresDedicatedTableStorage($câmp)) {
$fieldInfo = [
'name' => $field->getName(),
'type' => $field->getType(),
'table' => $tableMapping->getDedicatedDataTableName($field)
];
dacă ($câmp->isRevizabil()) {
$fieldInfo['table_revision'] = $tableMapping->getDedicatedRevisionTableName($field);
}
$fields[$contentEntityType->id()][] = $fieldInfo;
}
}
}
returnează $câmpuri;
Am scris o metodă separată pentru a obține entitățile mele de conținut, pe care le-a folosit codul de mai sus.
funcția getContentEntityTypes() {
$contentEntityTypes = [];
$entity_type_definitions = $this->entityTypeManager->getDefinitions();
/* @var $definition EntityTypeInterface */
foreach ($entity_type_definitions ca $entityType) {
if ($entityType instanceof ContentEntityTypeInterface && in_array(SqlEntityStorageInterface::class, class_implements($entityType->getStorageClass()))) {
$contentEntityTypes[] = $entityType;
}
}
returnează $contentEntityTypes;
}