Puncte:2

adăugați câmp la utilizator în hook_update_n

drapel pl

Cea mai recentă versiune a modulului nostru existent trebuie să definească MULTE câmpuri noi care sunt atașate utilizatorului drupal. Pentru fiecare câmp, în {module}/config/optional există o configurație de câmp și o configurare de stocare a câmpului. Apoi implementez hook_update_n în {module}/{module}.install pentru a detecta noile intrări de configurare și pentru a le adăuga dacă nu există. Rularea codului instalează configurația (o pot vedea cu drush cget), dar nu creează tabelele DB corespunzătoare pentru noile câmpuri.

Dacă merg la majoritatea paginilor, cum ar fi /admin/config/people/accounts/fields, primesc „Site-ul web a întâmpinat o eroare neașteptată. Vă rugăm să încercați din nou mai târziu.”

Dacă șterg memoria cache (drush cr), primesc o eroare care spune:

În linia 53 ExceptionHandler.php:

  SQLSTATE[42S02]: Tabelul de bază sau vizualizarea nu a fost găsită: 1146 Tabelul „intranet.user__field_s_uid” nu există: SELECT „t”.*
  DIN
  „user__field_s_uid” „t”
  WHERE ("entity_id" IN (:db_condition_placeholder_0)) AND ("deleted" = :db_condition_placeholder_1) AND ("langcode" IN (:db_condition_placeholder_2, :db_c
  ondition_placeholder_3, :db_condition_placeholder_4))
  COMANDA PENTRU „delta” ASC; Matrice
  (
      [:db_condition_placeholder_0] => 0
      [:db_condition_placeholder_1] => 0
      [:db_condition_placeholder_2] => ro
      [:db_condition_placeholder_3] => und
      [:db_condition_placeholder_4] => zxx
  )

În linia 116 StatementWrapper.php:

  SQLSTATE[42S02]: Tabelul de bază sau vizualizarea nu a fost găsită: 1146 Tabelul „intranet.user__field_s_uid” nu există

Pentru ca site-ul să funcționeze din nou, trebuie să șterg configurația (drush cdel...).

Ce îmi lipsește care împiedică crearea stocării db? Trebuie să creez în mod programatic tabelul db pentru ca câmpul să fie utilizat? (dacă da, cum?)

fișier: {modul}.install

<?php                                                              
utilizați Drupal\Component\Serialization\Yaml;                           
utilizați Drupal\Component\Utility\NestedArray;                          
utilizați Drupal\field\Entity\FieldStorageConfig;                        
utilizați Drupal\field\Entity\FieldConfig;                               
                                                                   
funcția {module}_update_9001(&$sandbox = NULL){             
  $modulePath = \Drupal::service('extension.list.module')          
        ->getPath('{modul}');                      
  $config_factory = \Drupal::configFactory();                      
  $configPathObjects = \Drupal::service('sistem_fișier')             
    ->scanDirectory($modulePath.'/config/optional','~field.*~');   
                                                                   
  foreach ($configPathObjects ca $configPath){                     
                                                                   
    $config = $config_factory->getEditable($configPath->name);     
    if($config->isNew()){                                          
      $configSettings = NestedArray::mergeDeep(                    
          Yaml::decode(                                            
            file_get_contents(                                     
              „$modulePath/config/optional/{$configPath->filename}”
              )                                                    
            ),$config                                              
          );                                                       
      $config->setdata($configSettings);                           
      $config->salvare(ADEVĂRAT);                                         
    }                                                              
  }                                                                
}                                                                  

fișier: config/optional/field.field.user.user.field_s_uid.yml

langcode: en                                                                   
stare: adevărat                                                                   
dependențe:                                                                  
  config:                                                                      
    - field.storage.user.field_s_uid                                           
  modul:                                                                      
    - utilizator                                                                     
id: user.user.field_s_uid                                                      
field_name: field_s_uid                                                        
entity_type: utilizator                                                              
pachet: utilizator                                                                   
etichetă: s_uid                                                                   
descriere: „ID-ul unic pentru acest utilizator, setat automat de DB, nu ar trebui să fie modificat de utilizatori/administratori”.                                              
cerut: fals                                                                
traducabil: fals                                                            
valoare implicită: {  }                                                            
default_value_callback: ''                                                     
setari:                                                                      
  min: nul                                                                    
  max: nul                                                                    
  prefix: ''                                                                   
  sufix: ''                                                                   
tip_câmp: întreg                                                            

fișier: config/optional/field.storage.user.field_s_uid.yml

langcode: en
stare: adevărat
dependențe:
  modul:
    - utilizator
id: user.field_s_uid
field_name: field_s_uid
entity_type: utilizator
tip: întreg
setari:
  nesemnat: fals
  dimensiune: normală
modul: nucleu
blocat: fals
cardinalitate: 1
traducebil: adevărat
indexuri: { }
persist_with_no_fields: false
stocare_personalizată: fals
drapel ru
Trebuie să vă asigurați că FieldStorage este instalat mai întâi
Puncte:2
drapel pl

Soluție finală bazată pe soluția acceptată de la @4k4 (vezi raspunsul).

<?php
utilizați Drupal\Core\Database\Database;
utilizați Drupal\Component\Serialization\Yaml;
utilizați Drupal\Component\Utility\NestedArray;
utilizați Drupal\field\Entity\FieldStorageConfig;
utilizați Drupal\field\Entity\FieldConfig;
utilizați Drupal\Core\Utility\UpdateException;

/**
 * Adăugați câmpuri obligatorii la entitățile utilizator.
 */
funcția {module}_update_9001(){
  $modulePath = \Drupal::service('extension.list.module')
        ->getPath('{modul}');
  $configPathStorageObjects = \Drupal::service('sistem_fișier')
    ->scanDirectory($modulePath.'/config/optional','~field\.storage\.user\..*~');
  \Drupal::logger('staffdb')->notice('obiecte de stocare: <pre>'.print_r($configPathStorageObjects,true).'</pre>');

  //adăugați spațiul de stocare lipsă
  foreach ($configPathStorageObjects ca $configPath){
    $config = FieldStorageConfig::loadByName('utilizator',str_replace('field.storage.user.','',$configPath->nume));
    if(este_null($config)){
      $configSettings = Yaml::decode(
          file_get_contents(
            „$modulePath/config/optional/{$configPath->filename}”
            )
          );
      $fieldStorage = FieldStorageConfig::create($configSettings);
      $fieldStorage->salvare();
    }
  }

  //adăugați câmpurile lipsă utilizatorilor
  $configPathFieldObjects = \Drupal::service('sistem_fișier')
    ->scanDirectory($modulePath.'/config/optional','~field\.field\.user\.user\..*~');
  foreach ($configPathFieldObjects ca $configPath){
    $config = FieldConfig::loadByName('utilizator', 'utilizator', str_replace('field.field.user.user.','',$configPath->name));
    if(este_null($config)){
      $configSettings = Yaml::decode(
          file_get_contents(
            „$modulePath/config/optional/{$configPath->filename}”
            )
          );
      $field = FieldConfig::create($configSettings);
      $câmp->salvare();
    }
  }
}
Puncte:2
drapel cn

Aveți nevoie de clasele de entități de configurare FieldStorageConfig::create() și FieldConfig::create(). Aveți deja instrucțiunile de utilizare și nu le folosiți. În caz contrar, evenimentele de entitate precum postcreate și presava nu sunt invocate.

BTW dacă modificați configurația unei entități de configurare prin $config_factory->getEditable() acest lucru funcționează doar atâta timp cât nu modificați nimic care afectează evenimentele entității menționate.Dacă trebuie să salvați în mod gratuit entitățile de configurare, atunci mai bine încărcați-le cu ConfigEntityStorageInterface::loadOverrideFree().

drapel ru
Utilizarea `FieldStorageConfig` sau `FieldConfig` înseamnă că trebuie să treceți în mod explicit peste fiecare configurație (-tip) una câte una. Nu există posibilitatea de a instala simultan un întreg director de fișiere de configurare arbitrare? Am folosit o metodă similară ca @Kevin Finkenbinder, pe care am văzut-o în [fișierul de instalare a distribuției Varbase](https://git.drupalcode.org/project/varbase_bootstrap_paragraphs/-/blob/9.0.x/varbase_bootstrap_paragraphs. install#L39): FieldStorage mai întâi, apoi totul. Această abordare nu salvează?
4uk4 avatar
drapel cn
Codul legat funcționează numai din cauza $config_installer->installOptionalConfig(), care salvează ulterior entitățile de configurare adăugate.
4uk4 avatar
drapel cn
iar la sfârșit codul folosește un truc pentru a corecta orice erori de actualizare https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Entity%21EntityDefinitionUpdateManager.php/function/EntityDefinitionUpdateManager%3A%3AapplyUpdates /8.9.x. Această metodă nu mai este disponibilă.
drapel pl
Mulțumesc. Acest lucru mi-a dat ceea ce aveam nevoie și este atât de marcat ca răspuns acceptat. Pentru ajutorul altora, cum ar fi @Hudri, am postat și prin codul final de mai jos (https://drupal.stackexchange.com/a/307977/19071) care îmi permite să iterez prin mai multe fișiere adăugate.

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.