Câu trả lời:
Có thể thực hiện rất nhiều thứ trong Drupal chỉ bằng cách thực hiện các truy vấn SQL, thông qua Drupal hoặc bên ngoài. Nói chung, bạn không bao giờ muốn thực hiện phương pháp này. Có một số trường hợp nó có thể hoạt động tốt, nhưng hầu hết thời gian không có lý do để làm theo cách này.
Drupal có API phong phú, điều này đúng với Drupal 6, 7 và 8, vì chúng luôn là một tính năng chính trong Drupal. Trong ví dụ đồng tình của bạn, bạn có thể sử dụng taxonomy_term_load
và taxonomy_term_save
để tạo điều kiện cập nhật một thuật ngữ. Làm theo cách này, bạn có thể chỉnh sửa bất kỳ phần dữ liệu bao gồm vid
. Chỉ vì bạn làm điều đó với API, những thứ bị cấm sẽ không tự động hoạt động, nhưng cơ hội để mọi thứ diễn ra tốt đẹp được cải thiện mạnh mẽ.
Trong ví dụ cụ thể này, API không làm bất cứ điều gì cần thiết. Nó thiết lập một số dữ liệu nội bộ về thuật ngữ và gọi mô-đun hook hook biết rằng nó đã được cập nhật.
Bạn nên lưu ý rằng mọi thứ có thể bị phá vỡ, nếu thuật ngữ bạn muốn thay đổi là một phần của hệ thống phân cấp. Mọi thứ cũng có thể phá vỡ đối với các nút tham chiếu thuật ngữ, nếu trường không được phép tham chiếu các thuật ngữ trong từ vựng mới.
Di chuyển dữ liệu là giải pháp chống đạn, và trừ khi bạn có một bộ dữ liệu khổng lồ, nó có thể được phát triển và thực hiện khá dễ dàng. Ý tưởng là tạo ra một thuật ngữ mới và di chuyển nội dung bạn muốn di chuyển và sau đó xóa thuật ngữ cũ. Là một móc cập nhật, mã mẫu có thể trông như thế này:
/**
* Put in modules .install file, replace xxxx with 7000 or higher
*/
function MODULE_NAME_update_XXXX(&$sandbox) {
$term = taxonomy_term_load(CONSTANT_WITH_TID);
$new_term = clone $term;
unset($new_term->tid);
unset($new_term->tid);
$new_term->vid = CONSTANT_WITH_VID;
taxonomy_term_save($term);
// Find all nodes we want to update and update them.
// If there is a lot of nodes, can use $sandbox to make this a batch job.
$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'node')
->fieldCondition('field_which_is_term_reference', 'tid', $term->tid);
$result = $query->execute();
foreach (node_load_multiple(array_keys($result['node'])) as $node) {
$node->field_which_is_term_reference[LANGUAGE_NONE][0]['tid'] = $term->tid;
node_save($node);
}
// Migration all done - delete the old term.
taxonomy_term_delete($term->tid);
}
Xin lưu ý rằng mã trên là mã ví dụ thuần túy, được viết bằng trái tim. Có thể có lỗi cú pháp hoặc các lỗi khác và đưa ra rất nhiều giả định. Đây chỉ là để minh họa một ý tưởng và chứng minh rằng việc di chuyển có thể không phải là một vấn đề lớn.
Không nên thay đổi cơ sở dữ liệu trực tiếp khi làm việc với Drupal. Nhưng Vâng, nếu chúng ta biết nơi mà tất cả nó có thể ảnh hưởng và làm thay đổi cần thiết cho phù hợp, đó là OK để làm thay đổi trực tiếp trong cơ sở dữ liệu. Bởi vì trong trường hợp này, điều này là không thể thông qua UI. LƯU Ý: Nếu bạn có các nút được liên kết với Điều khoản, bạn cũng sẽ phải xử lý thủ công đó.
Kiểm tra liên kết này giải thích cách chúng tôi có thể thay đổi từ vựng trong Drupal 7: Thay đổi từ vựng của thuật ngữ phân loại trong Drupal 7 bằng cơ sở dữ liệu .
Tôi không khuyên bạn nên thay đổi thuật ngữ đó theo cách bạn mô tả nó trong câu hỏi của bạn. Thay vào đó, tôi sử dụng một cách tiếp cận khác để đạt được kết quả tương tự (theo thứ tự được chỉ định), chi tiết hơn dưới đây.
Tạo trường thuật ngữ phân loại mới, để "từ bây giờ" mọi cập nhật nút trong tương lai (hoặc các nút mới được tạo) sẽ sử dụng trường mới đó. Tôi giả sử các thuật ngữ này được sử dụng cho các nút (nếu bạn sử dụng nó cho một số loại thực thể khác, như người dùng, v.v.), cách tiếp cận tương tự cũng có thể được sử dụng cho các thực thể đó.
Sử dụng mô-đun Rules để tạo quy tắc như vậy:
before saving content
.entity has field
, với trường = trường cũ.entity has field
, với trường = trường mới).set Drupal message
, chứa một số hướng dẫn rằng trường cũ phải được xóa trắng và trường mới phải chứa (các) giá trị thích hợp.Rõ ràng, cách tiếp cận trong Bước 1 sẽ mất "một số" thời gian nếu việc này phải được thực hiện thủ công, mỗi lần 1 nút. Nhưng bằng cách sử dụng Chế độ xem (để xây dựng danh sách các nút tương tự sẽ được cập nhật) và VBO (để cập nhật hàng loạt danh sách đó), bạn có thể (nên!) Có thể tăng tốc quá trình này khá nhiều.
Đặc biệt nếu bạn sử dụng Quy tắc để tạo thao tác hàng loạt tùy chỉnh cho chế độ xem VBO như vậy, như được giải thích trong câu trả lời cho " Cách sử dụng Quy tắc để tạo thao tác hàng loạt tùy chỉnh cho chế độ xem VBO? ". Dưới đây là nguyên mẫu của Thành phần quy tắc sẽ giúp triển khai thao tác hàng loạt tùy chỉnh như vậy (ở định dạng Xuất quy tắc):
{ "rules_replace_a_term_field_by_another_term_field" : {
"LABEL" : "Replace a term field by another term field",
"PLUGIN" : "rule",
"OWNER" : "rules",
"REQUIRES" : [ "rules" ],
"USES VARIABLES" : { "node" : { "label" : "Node", "type" : "node" } },
"IF" : [
{ "entity_has_field" : { "entity" : [ "node" ], "field" : "field_sample_tags" } },
{ "entity_has_field" : { "entity" : [ "node" ], "field" : "field_demo_tags" } },
{ "data_is" : { "data" : [ "node:field-demo-tags" ], "value" : "1" } }
],
"DO" : [
{ "data_set" : { "data" : [ "node:field-sample-tags" ], "value" : "31" } },
{ "drupal_message" : { "message" : "Term updated in node with id = [node:nid]" } }
]
}
}
Một số chi tiết để giải thích nguyên mẫu trên:
Đây là các điều kiện quy tắc:
field_sample_tags
.field_demo_tags
.field_demo_tags
tương ứng với thuật ngữ chúng tôi muốn thay thế không (trong ví dụ này, thuật ngữ này có id = 1
). Lưu ý rằng nếu điều kiện này không được thỏa mãn, sẽ không có Hành động quy tắc nào được thực hiện.Đây là các quy tắc hành động:
field_sample_tags
bằng với thuật ngữ id = 31
(là thuật ngữ trong từ vựng mới được tạo phù hợp với thuật ngữ trong từ vựng sẽ được thay thế).Term updated in node with id = 72
, trong khi đó 72
là id nút của nút được cập nhật.Nếu bạn muốn, điều chỉnh tên máy của tên trường trong nguyên mẫu ở trên và ID thuật ngữ được sử dụng. Sau đó nhập nó vào trang web của riêng bạn (sử dụng UI UI) và kiểm tra QA bằng cách sử dụng liên kết "thực thi" ở bên phải Thành phần quy tắc đã nhập (và nhập một số id nút để kiểm tra nó, sau khi bạn chuyển sang "nhập trực tiếp chế độ "để có thể chỉ định id nút). Nếu trong quá trình thử nghiệm của bạn, bạn không nhận được Term updated in node ...
thông báo như vậy , thì đó phải là do nút bạn đã chọn không sử dụng giá trị thuật ngữ được chỉ định trong quy tắc của bạn.
Sau khi bạn hoàn thành kiểm tra QA Thành phần quy tắc này từ Bước 2, hãy tạo chế độ xem VBO của các nút cần xử lý, trong đó bạn tham khảo nguyên mẫu Quy tắc ở trên (hoặc một biến thể của nó để phù hợp với nhu cầu của bạn).
Sử dụng phương pháp này, bạn giảm thiểu rủi ro để đưa ra sự không nhất quán dữ liệu (so với việc cập nhật cơ sở dữ liệu trực tiếp), không có mã tùy chỉnh nào liên quan (bạn chỉ sử dụng Giao diện người dùng và Giao diện người dùng quy tắc).
Tôi biết rằng bạn nói theo lập trình nhưng nếu bạn muốn sử dụng một mô-đun, bạn có thể sử dụng Trình quản lý phân loại
Mô-đun này cung cấp một giao diện mạnh mẽ để quản lý các nguyên tắc phân loại. Một từ vựng được hiển thị trong chế độ xem dạng cây động, trong đó các thuật ngữ gốc có thể được mở rộng để liệt kê các thuật ngữ con lồng nhau của chúng hoặc có thể được thu gọn.
Trình quản lý phân loại có các hoạt động và tính năng chính sau:
- treeview năng động
- xóa hàng loạt
- bổ sung hàng loạt các điều khoản mới
- di chuyển các thuật ngữ trong phân cấp hợp nhất các thuật ngữ (sử dụng mô đun hợp nhất Term trong 7.x)
- thay đổi trọng lượng nhanh với mũi tên lên và xuống (và tiết kiệm AJAX)
- Mẫu chỉnh sửa thuật ngữ AJAX
- giao diện tìm kiếm đơn giản
- Xuất khẩu thuật ngữ CSV
- i18n hỗ trợ cho các từ vựng đa ngôn ngữ (theo ngôn ngữ)
- Giao diện Double Tree để di chuyển các thuật ngữ theo thứ bậc, thêm bản dịch mới và chuyển đổi thuật ngữ giữa các từ vựng khác nhau