Tôi đã xây dựng một mô-đun tùy chỉnh để tạo loại trường tùy chỉnh (với trình định dạng và tiện ích con) và tôi muốn tăng dần một thuộc tính của trường (để tăng giá trị của nó lên một cho mỗi phiên bản của trường.)
Những gì tôi có cho đến nay là:
- web/modules/custom/asciinema/src/Plugin/Field/FieldType/AsciinemaItem.php (định nghĩa trường)
lược đồ hàm tĩnh công khai (FieldStorageDefinitionInterface $field_definition) {
trở lại [
// các cột chứa các giá trị mà trường sẽ lưu trữ
'cột' => [
// Liệt kê các giá trị mà trường sẽ lưu.
'viện trợ' => [
'loại' => 'nối tiếp',
'kích thước' => 'bình thường',
'description' => 'Id của phiên bản asciinema.',
'không dấu' => ĐÚNG,
'không rỗng' => ĐÚNG,
],
],
.....
'khóa duy nhất' => [
'viện trợ' => ['viện trợ'],
],
];
// Hàm này đảm bảo rằng giá trị được tăng lên mỗi khi một phiên bản trường mới được lưu.
chức năng công cộng preSave() {
if ($this->getEntity()->isNew()) {
// Tăng giá trị của viện trợ khi xử lý một thực thể mới.
$fieldConfig = $this->getFieldDefinition();
$field_name = $fieldConfig->getName();
$entity_type = $fieldConfig->getTargetEntityTypeId();
$query = \Drupal::database()->select($entity_type . '__' . $field_name, 'ef')
->trường('ef', [$field_name . '_' . 'aid'])
->orderBy($field_name . '_' . 'aid', 'DESC');
$lastIndex = $query->execute()->fetchField();
$result = !empty($lastIndex) ? $last Index + 1 : 1;
$this->values['aid'] = $result;
$this->setValue($this->values);
}
}
- web/modules/custom/asciinema/src/Plugin/Field/FieldWidget/AsciinemaDefaultWidget.php (tiện ích trường).
hàm công khai formElement(
FieldItemListInterface $items,
$đồng bằng,
mảng $element,
mảng &$dạng,
FormStateInterface $form_state
) {
// Giá trị hiện tại có dự phòng.
$aid = isset($items[$delta]->aid) ? $items[$delta]->aid : 0;
....
$element['asciinema']['id']['aid'] = [
'#title' => t('AID'),
'#description' => t('ID Asciinema.'),
'#disabled' => ĐÚNG,
'#type' => 'trường văn bản',
'#default_value' => $aid,
];
....
trả lại phần tử $;
....
chức năng công khai massageFormValues(
mảng giá trị $,
mảng $form,
FormStateInterface $form_state
) {
foreach ($values as &$value) {
// TÔI.
$value['aid'] = $value['asciinema']['id']['aid'];
....
bỏ đặt($value['asciinema']);
}
trả lại giá trị $;
}
- web/modules/custom/asciinema/src/Plugin/Field/FieldFormatter/AsciinemaDefaultFormatter.php (Trình định dạng):
chức năng công khai viewElements(FieldItemListInterface $items, $langcode) {
phần tử $ = [];
nguồn $ = [];
foreach ($items as $delta => $item) {
// Kết xuất đầu ra bằng chủ đề asciinema_default.
$source['asciinema'] = [
'#theme' => 'asciinema_default',
'#asciinema' => [
'viện trợ' => $item->viện trợ,
],
];
...
$elements[$delta] = [
'#markup' => \Drupal::service('renderer')->render($source),
];
}
trả lại các phần tử $;
Hiện tại, tôi có thể lưu các giá trị đã nhập vào trường tùy chỉnh của mình và sự giúp đỡ
được tăng lên cho mỗi trường hợp trường. Tuy nhiên, tôi không thể chỉnh sửa bất kỳ dữ liệu nào trong quá khứ vì điều đó sẽ tạo ra:
THÔNG BÁO: Thông báo PHP: Uncaught PHP Exception Drupal\Core\Entity\EntityStorageException: "SQLSTATE[23505]: Vi phạm duy nhất: 7 LỖI: giá trị khóa trùng lặp vi phạm ràng buộc duy nhất "node_revision__asciinema__asciinema_aid__key"
php_1 | CHI TIẾT: Khóa (asciinema_aid)=(4) đã tồn tại.:
Tôi rất muốn tìm ra những gì còn thiếu hoặc tìm ra cách tốt hơn và rõ ràng hơn để xử lý các trường gia tăng.
CHỈNH SỬA:
Tôi đã xoay sở để khắc phục những hạn chế bằng cách xóa:
'khóa duy nhất' => [
'viện trợ' => ['viện trợ'],
],
... từ các định nghĩa lược đồ và thêm một điều kiện bổ sung trong hàm presave().
chức năng công cộng preSave() {
if ($this->getEntity()->isNew() || empty($this->values['aid'])) {
...
}
Tuy nhiên, tôi không coi đây là một câu trả lời dứt khoát, mà là một cách giải quyết khác.Tôi cũng muốn sử dụng các ràng buộc cơ sở dữ liệu như AUTO INCREMENT hoặc UNIQUE KEY. Cho đến ngày nay, tôi vẫn chưa tìm ra cách để nó hoạt động với các thuộc tính trường tùy chỉnh.