Điểm:2

thêm trường cho người dùng trong hook_update_n

lá cờ pl

Bản phát hành mới nhất của mô-đun hiện có của chúng tôi cần xác định NHIỀU trường mới được đính kèm với người dùng drupal. Đối với mỗi trường, trong {module}/config/tùy chọn có cấu hình trường và cấu hình lưu trữ trường. Sau đó, tôi triển khai hook_update_n trong {module}/{module}.install để phát hiện các mục cấu hình mới và thêm chúng nếu chúng không tồn tại. Chạy mã sẽ cài đặt cấu hình (tôi có thể thấy nó bằng drush cget), nhưng không tạo các bảng DB tương ứng cho các trường mới.

Nếu tôi đi đến hầu hết các trang, chẳng hạn như /admin/config/người/tài khoản/trường, tôi nhận được "Trang web gặp phải lỗi không mong muốn. Vui lòng thử lại sau."

Nếu tôi xóa bộ nhớ cache (drush cr), tôi gặp lỗi cho biết,

Trong ExceptionHandler.php dòng 53:

  SQLSTATE[42S02]: Không tìm thấy bảng cơ sở hoặc dạng xem: 1146 Bảng 'intranet.user__field_s_uid' không tồn tại: CHỌN "t".*
  TỪ
  "user__field_s_uid" "t"
  WHERE ("entity_id" IN (:db_condition_placeholder_0)) AND ("đã xóa" = :db_condition_placeholder_1) AND ("langcode" IN (:db_condition_placeholder_2, :db_c
  ondition_placeholder_3, :db_condition_placeholder_4))
  ĐẶT HÀNG BẰNG ASC "delta"; Mảng
  (
      [:db_condition_placeholder_0] => 0
      [:db_condition_placeholder_1] => 0
      [:db_condition_placeholder_2] => vi
      [:db_condition_placeholder_3] => không
      [:db_condition_placeholder_4] => zxx
  )

Trong StatementWrapper.php dòng 116:

  SQLSTATE [42S02]: Không tìm thấy bảng cơ sở hoặc dạng xem: 1146 Bảng 'intranet.user__field_s_uid' không tồn tại

Để trang web hoạt động trở lại, tôi phải xóa cấu hình (drush cdel ...).

Tôi đang thiếu điều gì khiến bộ lưu trữ db không được tạo? Tôi có cần tạo bảng db theo chương trình cho trường để sử dụng không? (nếu vậy, làm thế nào?)

tệp: {module}.install

<?php                                                              
sử dụng Drupal\Component\Serialization\Yaml;                           
sử dụng Drupal\Thành phần\Tiện ích\NestedArray;                          
sử dụng Drupal\field\Entity\FieldStorageConfig;                        
sử dụng Drupal\field\Entity\FieldConfig;                               
                                                                   
hàm {module}_update_9001(&$sandbox = NULL){             
  $modulePath = \Drupal::service('extension.list.module')          
        ->getPath('{module}');                      
  $config_factory = \Drupal::configFactory();                      
  $configPathObjects = \Drupal::service('file_system')             
    ->scanDirectory($modulePath.'/config/tuỳ chọn','~field.*~');   
                                                                   
  foreach ($configPathObjects dưới dạng $configPath){                     
                                                                   
    $config = $config_factory->getEditable($configPath->name);     
    if($config->isNew()){                                          
      $configSettings = NestedArray::mergeDeep(                    
          Yaml::giải mã(                                            
            file_get_contents(                                     
              "$modulePath/config/tùy chọn/{$configPath->tên tệp}"
              )                                                    
            ),$config                                              
          );                                                       
      $config->setdata($configSettings);                           
      $config->save(TRUE);                                         
    }                                                              
  }                                                                
}                                                                  

tệp: config/tùy chọn/field.field.user.user.field_s_uid.yml

mã ngôn ngữ: en                                                                   
trạng thái: đúng                                                                   
phụ thuộc:                                                                  
  cấu hình:                                                                      
    - trường.storage.user.field_s_uid                                           
  mô-đun:                                                                      
    - người dùng                                                                     
id: user.user.field_s_uid                                                      
tên_trường: field_s_uid                                                        
entity_type: người dùng                                                              
gói: người dùng                                                                   
nhãn: s_uid                                                                   
description: 'ID duy nhất cho người dùng này, được đặt tự động bởi DB, không được sửa đổi bởi người dùng/quản trị viên.'                                              
bắt buộc: sai                                                                
có thể dịch: sai                                                            
giá trị mặc định: {  }                                                            
default_value_callback: ''                                                     
cài đặt:                                                                      
  tối thiểu: không                                                                    
  tối đa: không                                                                    
  tiếp đầu ngữ: ''                                                                   
  hậu tố: ''                                                                   
field_type: số nguyên                                                            

tệp: config/tùy chọn/field.storage.user.field_s_uid.yml

mã ngôn ngữ: en
trạng thái: đúng
phụ thuộc:
  mô-đun:
    - người dùng
id: user.field_s_uid
tên_trường: field_s_uid
entity_type: người dùng
loại: số nguyên
cài đặt:
  không dấu: sai
  kích thước: bình thường
mô-đun: lõi
bị khóa: sai
quân số: 1
có thể dịch: đúng
chỉ mục: { }
kiên trì_with_no_fields: sai
custom_storage: sai
lá cờ ru
Bạn phải chắc chắn rằng FieldStorage đã được cài đặt trước
Điểm:2
lá cờ pl

Giải pháp cuối cùng dựa trên giải pháp được chấp nhận từ @4k4 (xem câu trả lời).

<?php
sử dụng Drupal\Core\Database\Database;
sử dụng Drupal\Component\Serialization\Yaml;
sử dụng Drupal\Thành phần\Tiện ích\NestedArray;
sử dụng Drupal\field\Entity\FieldStorageConfig;
sử dụng Drupal\field\Entity\FieldConfig;
sử dụng Drupal\Core\Utility\UpdateException;

/**
 * Thêm các trường bắt buộc vào thực thể người dùng.
 */
hàm {module}_update_9001(){
  $modulePath = \Drupal::service('extension.list.module')
        ->getPath('{module}');
  $configPathStorageObjects = \Drupal::service('file_system')
    ->scanDirectory($modulePath.'/config/tuỳ chọn','~field\.storage\.user\..*~');
  \Drupal::logger('staffdb')->notice('đối tượng lưu trữ: <pre>'.print_r($configPathStorageObjects,true).'</pre>');

  // thêm bộ nhớ trường bị thiếu
  foreach ($configPathStorageObjects as $configPath){
    $config = FieldStorageConfig::loadByName('user',str_replace('field.storage.user.','',$configPath->name));
    if(is_null($config)){
      $configSettings = Yaml::decode(
          file_get_contents(
            "$modulePath/config/tùy chọn/{$configPath->tên tệp}"
            )
          );
      $fieldStorage = FieldStorageConfig::create($configSettings);
      $fieldStorage->save();
    }
  }

  // thêm các trường còn thiếu cho người dùng
  $configPathFieldObjects = \Drupal::service('file_system')
    ->scanDirectory($modulePath.'/config/tùy chọn','~field\.field\.user\.user\..*~');
  foreach ($configPathFieldObjects as $configPath){
    $config = FieldConfig::loadByName('user', 'user', str_replace('field.field.user.user.','',$configPath->name));
    if(is_null($config)){
      $configSettings = Yaml::decode(
          file_get_contents(
            "$modulePath/config/tùy chọn/{$configPath->tên tệp}"
            )
          );
      $field = FieldConfig::create($configSettings);
      $field->save();
    }
  }
}
Điểm:2
lá cờ cn

Bạn cần các lớp thực thể cấu hình FieldStorageConfig::create() và FieldConfig::create(). Bạn đã có câu lệnh sử dụng và hiện không sử dụng chúng. Mặt khác, các sự kiện thực thể như postcreate và presave sẽ không được gọi.

BTW nếu bạn sửa đổi cấu hình của thực thể cấu hình thông qua $config_factory->getEditable() điều này chỉ hoạt động miễn là bạn không sửa đổi bất kỳ điều gì ảnh hưởng đến các sự kiện thực thể được đề cập.Nếu bạn cần lưu các thực thể cấu hình ghi đè miễn phí, thì tốt hơn là tải chúng thay vì ConfigEntityStorageInterface::loadOverrideFree().

lá cờ ru
Việc sử dụng `FieldStorageConfig` hoặc `FieldConfig` có nghĩa là bạn rõ ràng phải xem qua từng cấu hình (-type) từng cái một. Không có khả năng cài đặt toàn bộ thư mục chứa các tệp cấu hình tùy ý cùng một lúc phải không? Tôi đã sử dụng một phương pháp tương tự như @Kevin Finkenbinder mà tôi đã thấy trong [tệp cài đặt phân phối Varbase](https://git.drupalcode.org/project/varbase_bootstrap_paragraphs/-/blob/9.0.x/varbase_bootstrap_paragraphs. install#L39): FieldStorage trước, rồi đến mọi thứ khác. Là phương pháp này không tiết kiệm?
4uk4 avatar
lá cờ cn
Mã được liên kết chỉ hoạt động vì $config_installer->installOptionalConfig() sẽ lưu lại các thực thể cấu hình đã thêm sau đó.
4uk4 avatar
lá cờ cn
và cuối cùng, mã đang sử dụng một mẹo để sửa mọi lỗi cập nhật https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Entity%21EntityDefinitionUpdateManager.php/feft/EntityDefinitionUpdateManager%3A%3AapplyUpdates /8.9.x. Phương pháp này không còn nữa.
lá cờ pl
Cảm ơn bạn. Điều này đã cho tôi những gì tôi cần và được đánh dấu là câu trả lời được chấp nhận. Để được hỗ trợ bởi những người khác, chẳng hạn như @Hudri, tôi cũng đã đăng mã cuối cùng bên dưới (https://drupal.stackexchange.com/a/307977/19071) cho phép tôi lặp qua nhiều tệp được thêm vào.

Đăng câu trả lời

Hầu hết mọi người không hiểu rằng việc đặt nhiều câu hỏi sẽ mở ra cơ hội học hỏi và cải thiện mối quan hệ giữa các cá nhân. Ví dụ, trong các nghiên cứu của Alison, mặc dù mọi người có thể nhớ chính xác có bao nhiêu câu hỏi đã được đặt ra trong các cuộc trò chuyện của họ, nhưng họ không trực giác nhận ra mối liên hệ giữa câu hỏi và sự yêu thích. Qua bốn nghiên cứu, trong đó những người tham gia tự tham gia vào các cuộc trò chuyện hoặc đọc bản ghi lại các cuộc trò chuyện của người khác, mọi người có xu hướng không nhận ra rằng việc đặt câu hỏi sẽ ảnh hưởng—hoặc đã ảnh hưởng—mức độ thân thiện giữa những người đối thoại.