In Drupal 7 kann ich den Inhaltstyp eines Knotens mithilfe der Knotenkonvertierung problemlos ändern . Node Convert wurde jedoch weder auf Drupal 8 portiert , noch scheint es viel Begeisterung für den Port zu geben.
Wie kann ich in Drupal 8 einen Knoten von einem Inhaltstyp in einen anderen konvertieren, wenn ich zwei Inhaltstypen mit identischen Feldern habe? Welchen Code sollte ich für Drupal 8 verwenden, der dem folgenden Drupal 7-Code entspricht, der vom Node-Konvertierungsmodul verwendet wird? (Siehe node_convert_node_convert()
in node_convert.util.inc .)
// $nid, $destination_node_type, $source_fields, $destination_fields,
// $no_fields_flag, and $hook_options are the parameters passed to the function.
$node = node_load($nid);
if ($node == FALSE) {
return FALSE;
}
// Change the node type in the DB
db_update('node')->fields(array('type' => $destination_node_type))->condition('nid', $nid)->execute();
// If there are fields that can be converted
if ($no_fields_flag == FALSE) {
// Conversion process for each field
$re_save_body_field = FALSE;
// Use node revisions to extract all field revision in node_convert_field_convert
$node_revisions = node_revision_list($node);
foreach ($source_fields as $key => $field) {
$replaced_body = node_convert_field_convert($node, $field, $destination_fields[$key], $destination_node_type, $node_revisions);
if ($replaced_body == REPLACE_BODY) {
$re_save_body_field = TRUE;
}
}
// If something was appended to the body, or replaced the body, we update body field.
if ($re_save_body_field == TRUE) {
$field_body = field_info_fields();
$field_body = $field_body['body'];
$field_ids = array($field_body['id'] => $field_body['id']);
module_invoke($field_body['storage']['module'], 'field_storage_write', 'node', $node, FIELD_STORAGE_UPDATE, $field_ids);
}
}
// Omissis.
// Clear the node cache, so we have the latest information when saving the
// node.
$controller = entity_get_controller('node');
/* @var $controller DrupalEntityControllerInterface */
$controller->resetCache(array($node->nid));
cache_clear_all('field:node:' . $node->nid, 'cache_field');
node_convert_field_convert()
enthält den folgenden Code.
// &$node, $source_field, $destination_field, $destination_node_type,
// and $node_revisions are the parameters passed to node_convert_field_convert().
$field_info_source = field_info_fields(); // Get source field information
$field_info_source = $field_info_source[$source_field];
$db_info_source = $field_info_source['storage']; // Get DB specific source field information
if ($destination_field == 'discard') {
// Delete node info in the separate field table
node_convert_invoke_field_storage_delete($field_info_source, $db_info_source, $node);
return NULL;
}
$field_info_destination = array();
$db_info_destination = array();
if (!in_array($destination_field, array('discard', APPEND_TO_BODY, REPLACE_BODY))) {
$field_info_destination = field_info_fields($destination_field); // Get destination field information
$field_info_destination = $field_info_destination[$destination_field]; // Get destination field information
$db_info_destination = $field_info_destination['storage']; // Get DB specific destination field information
}
// We save each field value from the DB for transfer. (this only applies to the current revision of the field)
$source_values = field_get_items('node', $node, $source_field);
if (count($node_revisions) > 1 && !in_array($destination_field, array(APPEND_TO_BODY, REPLACE_BODY))) {
// Get all field revisions for current node
$field_revision_values = array();
$field_revision_source_table = current(array_keys($db_info_source['details']['sql']['FIELD_LOAD_REVISION']));
$field_revision_destination_table = current(array_keys($db_info_destination['details']['sql']['FIELD_LOAD_REVISION']));
$source_columns = array('entity_type', 'entity_id', 'revision_id', 'bundle', 'delta', 'language');
foreach ($field_info_source['columns'] as $column => $attributes) {
$source_columns[] = _field_sql_storage_columnname($source_field, $column);
}
$revision_query = db_select($field_revision_source_table, 'r', array('fetch' => PDO::FETCH_ASSOC))
->condition('entity_type', 'node')
->condition('bundle', $node->type)
->condition('entity_id', $node->nid)
->condition('revision_id', $node->vid, '<>')
->fields('r', $source_columns)->execute();
// Change the bundle to the destination type of the node
foreach ($revision_query as $row) {
$row['bundle'] = $destination_node_type;
$field_revision_values[] = $row;
}
// Remove all field revisions for current field in DB
node_convert_invoke_field_storage_delete($field_info_source, $db_info_source, $node);
// Reinsert the field revisions in the destination field revision table
$query = db_insert($field_revision_destination_table);
$columns = array('entity_type', 'entity_id', 'revision_id', 'bundle', 'delta', 'language');
foreach ($field_info_destination['columns'] as $column => $attributes) {
$columns[] = _field_sql_storage_columnname($destination_field, $column);
}
$query->fields($columns);
foreach ($field_revision_values as $row) {
$query->values(array_values($row));
}
$query->execute();
}
else {
// After getting the source field values, we delete the values stored in the DB (this deletes values for all field revisions)
node_convert_invoke_field_storage_delete($field_info_source, $db_info_source, $node);
}
// The source field value should be appended to the body or replaced.
if ($destination_field == APPEND_TO_BODY || $destination_field == REPLACE_BODY) {
static $node_body = '';
//static $node_teaser = '';
// We try to get the node body from a static variable, which means we did some body manipulations, otherwise load it.
if (empty($node_body)) {
$node_body_field = field_get_items('node', $node, 'body');
$node_body = $node_body_field[0]['value'];
//$node_teaser = $node_body_field[0]['summary'];
}
// Double check we have values in the field.
if (is_array($source_values)) {
// Get the field value.
$field_value = node_convert_format_field_value($node, $field_info_source, TRUE);
if ($destination_field == APPEND_TO_BODY) {
$node_body = $node_body . "\n" . $field_value;
//$node_teaser = $node_teaser . "\n" . $field_value['value'];
}
elseif ($destination_field == REPLACE_BODY) {
$node_body = $field_value;
//$node_teaser = $field_value['value'];
}
$lang_code = field_language('node', $node, $source_field);
$node->body[$lang_code][0]['value'] = $node_body;
//$node->body[$lang_code][0]['summary'] = $node_teaser;
}
return REPLACE_BODY;
}
// We put each field value back into the DB
// To do it we first get the id of the field, then we find its language code from the source value
// We add $source_values into the node object, and invoke field_storage write
$field_ids = array($field_info_destination['id'] => $field_info_destination['id']);
$lang_code = field_language('node', $node, $source_field);
// Make sure that we actually have values in the source field
if ($source_values !== FALSE) {
$node->{$destination_field}[$lang_code] = $source_values;
}
else {
$node->{$destination_field} = array();
}
// Give possibility to fields to pre-process their data
// (e.g., Link module transforms attribute array into a serialized array before insertion)
field_attach_presave('node', $node);
// For some reason link_field_presave doesn't exist anymore, so we have to call it the processing function used inside manually.
if ($field_info_destination['type'] == 'link_field') {
$instances = field_info_instances('node', $destination_node_type);
link_field_update('node', $node, $field_info_destination, $instances[$destination_field], $lang_code, $node->{$destination_field}[$lang_code]);
}
Antworten:
Einige Zeit ist vergangen und die gute Nachricht ist, dass es jetzt das convert_bundles- Modul für d8 gibt.
Es ist Alpha, aber ich konnte es verwenden, um Entitäten auf einer Entwicklungssite zu konvertieren.
quelle
Joachim Noreiko hat gerade einen Blog-Beitrag über das Ändern des Knotentyps gepostet . Sie müssen die folgenden Tabellen aktualisieren:
Der Beitrag enthält vollständige Anweisungen und Codefragmente. Befolgen Sie diese einfach Schritt für Schritt.
quelle
Hier ist eine Lösung zum Konvertieren von Artikelknoten in einen Blogtyp. Ich habe versucht, Bundles zu konvertieren, die in einer anderen Antwort vorgeschlagen wurden, konnte jedoch nicht filtern, welche Knoten konvertiert werden sollen. Auf diese Weise können Sie der Abfrage zusätzliche Bedingungen hinzufügen, z. B. einen Taxonomiebegriffswert.
quelle