En Drupal 7, puedo cambiar fácilmente el tipo de contenido de un nodo utilizando Node convert . Node Convert, sin embargo, no se ha portado a Drupal 8, ni parece haber mucho entusiasmo por el puerto.
Si tengo dos tipos de contenido con campos idénticos, ¿cómo puedo convertir un nodo de un tipo de contenido a otro, en Drupal 8? ¿Cuál es el código que debo usar para Drupal 8, que es equivalente al siguiente código Drupal 7 utilizado por el módulo de conversión de Nodo ? (Ver node_convert_node_convert()
en 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()
contiene el siguiente código.
// &$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]);
}
Respuestas:
Ha pasado algún tiempo, y la buena noticia es que ahora existe el módulo convert_bundles para d8.
Es alfa, pero pude usarlo para convertir entidades en un sitio de desarrollo.
fuente
Joachim Noreiko acaba de publicar una publicación de blog sobre cómo cambiar el tipo de nodo . Deberá actualizar las siguientes tablas:
La publicación viene con instrucciones completas y fragmentos de código, solo sígalos paso a paso.
fuente
Aquí hay una solución para convertir nodos de artículos en un tipo de blog. Intenté Convertir paquetes sugeridos en otra respuesta, pero no pude filtrar qué nodos convertir. Con esto, puede agregar condiciones adicionales a la consulta, como un valor de término de taxonomía.
fuente