No Drupal 7, eu posso alternar facilmente o tipo de conteúdo de um nó usando a conversão de nó . O Node Convert, no entanto, não foi portado para o Drupal 8, nem parece haver muito entusiasmo pela porta.
Se eu tiver dois tipos de conteúdo com campos idênticos, como posso converter um nó de um tipo de conteúdo para outro no Drupal 8? Qual é o código que devo usar para o Drupal 8, que é equivalente ao seguinte código do Drupal 7 usado pelo módulo de conversão de Nó ? (Veja node_convert_node_convert()
em 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()
contém o seguinte 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]);
}
Respostas:
Já passou algum tempo, e a boa notícia é que agora existe o módulo convert_bundles para o d8.
É alfa, mas consegui usá-lo para converter entidades em um site de desenvolvimento.
fonte
Joachim Noreiko acaba de postar uma postagem no blog sobre como alterar o tipo de um nó . Você precisará atualizar as seguintes tabelas:
A postagem vem com instruções completas e trechos de código, basta segui-los passo a passo.
fonte
Aqui está uma solução para converter nós de artigo em um tipo de blog. Tentei converter pacotes sugeridos em outra resposta, mas não consegui filtrar quais nós converter. Com isso, você pode adicionar condições adicionais à consulta, como um valor do termo de taxonomia.
fonte