Thay đổi loại nội dung của nút


8

Trong Drupal 7, tôi có thể dễ dàng chuyển đổi loại nội dung của nút bằng cách sử dụng chuyển đổi Node . Node Convert, tuy nhiên, đã không được chuyển sang Drupal 8, và dường như không có nhiều sự nhiệt tình cho cổng.

Nếu tôi có hai loại nội dung với các trường giống nhau, làm cách nào tôi có thể chuyển đổi một nút từ loại nội dung sang loại khác, trong Drupal 8? Mã tôi nên sử dụng cho Drupal 8 là gì, tương đương với mã Drupal 7 sau đây được sử dụng bởi mô-đun chuyển đổi Node ? (Xem node_convert_node_convert()trong 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() chứa mã sau đây.

  // &$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]);
  }

1
Về cơ bản, bạn đã đăng hầu hết các mô-đun ở đây và yêu cầu chuyển đổi được thực hiện cho bạn. Tại sao không thử phiên bản Drupal 8 và sau đó đăng câu hỏi cụ thể hơn tại đây khi bạn gặp khó khăn?
benjy

Một số người khác đề nghị đăng mã từ mô-đun D7, tăng cường câu hỏi ban đầu của tôi. Tôi rất thích thử điều này, nhưng tôi bị giới hạn bởi thực tế tôi không phải là lập trình viên.
Màn hình

2
Đủ công bằng, một người nào đó có thể đi qua và chuyển nó vào một ngày nào đó, tôi thấy bạn đã nhận xét về vấn đề Drupal 8, điều đó có thể nhận được một số quan tâm. Nếu không, bạn có thể trả tiền cho ai đó để chuyển đổi nó, tôi không nghĩ sẽ mất nhiều thời gian.
benjy

Câu trả lời:


2

Một thời gian đã trôi qua, và tin tốt là giờ đây đã có mô-đun convert_bundles cho d8.

Đó là bản alpha, nhưng tôi đã có thể sử dụng nó để chuyển đổi các thực thể trên trang dev.


1

Joachim Noreiko vừa đăng một bài đăng trên blog về việc thay đổi loại nút . Bạn sẽ cần cập nhật các bảng sau:

  • bảng cơ sở thực thể
  • bảng dữ liệu thực thể
  • bảng dữ liệu sửa đổi thực thể
  • mỗi bảng dữ liệu trường
  • mỗi bảng sửa đổi dữ liệu trường

Bài đăng đi kèm với hướng dẫn đầy đủ và đoạn mã, chỉ cần làm theo từng bước một.


0

Đây là một giải pháp để chuyển đổi các nút bài viết thành một loại blog. Tôi đã thử Chuyển đổi Gói được đề xuất trong một câu trả lời khác, nhưng không thể lọc các nút để chuyển đổi. Với điều này, bạn có thể thêm các điều kiện bổ sung vào truy vấn, chẳng hạn như giá trị thuật ngữ phân loại.

$query = \Drupal::entityQuery('node')
  ->condition('type', 'article')
$results = $query->execute();

foreach ($results as $nid) {
  $node = \Drupal\node\Entity\Node::load($nid);
  $node->set('type', 'blog');
  $node->save();
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.