Drupal 8 或 9 将数据从自定义模块保存到内容类型

Drupal 8 or 9 Save data to the content type from a custom module

我正在使用 drupal 8.9.*,我想将数据保存到自定义模块的内容类型,以便我可以看到在 Drupal 的公共内容列表页面中输入的数据。

我不知道如何将数据保存到内容类型,我尝试使用 $node 的对象来保存它(以及我尝试但后来知道的其他一些方法它已弃用)。我还传递了内容类型的机器名称。我在这方面出错的地方,所有 Drupal 文档都被扭曲了,很难找到 8 的正确版本 || 9. 这是我的代码。

路由数据文件,birth_details.routing.yml

birth_details.newreading:
  path: '/new-reading'
  defaults: 
    _title: 'Enter the birth details for reading'
    _form: '\Drupal\birth_details\Form\BirthDetails'
  requirements: 
    _permission: 'access content'

我的表单 BirthDetails.php,(为了测试目的硬编码了一些值)

<?php
    namespace Drupal\birth_details\Form;

    use Drupal\Core\Form\FormBase;
    use Drupal\Core\Form\FormStateInterface;

    class BirthDetails extends FormBase {

        public function getFormId(){
            return 'birth_data';
        }

        public function buildForm(array $form, FormStateInterface $form_state){

            $form['title'] =  [
                '#type' => 'textfield',
                '#description' => $this->t('Enter your name here!'),
            ];
            $form['field_birth_date'] =  [
                '#type' => 'textfield',
                '#description' => $this->t('Enter your field_birth_date here!'),
            ];
            $form['field_birth_location'] =  [
                '#type' => 'textfield',
                '#description' => $this->t('Enter your field_birth_location here!'),
            ];
            $form['field_email_id'] =  [
                '#type' => 'textfield',
                '#description' => $this->t('Enter your field_email_id here!'),
            ];
            $form['field_gender'] =  [
                '#type' => 'textfield',
                '#description' => $this->t('Enter your field_gender here!'),
            ];

            $form['actions']['#type'] = 'actions';
            $form['actions']['submit'] = [
                '#type' => 'submit',
                '#value' => $this->t('Save data'),
                
            ];

            return $form;
        }

        public function submitForm(array &$form, FormStateInterface $form_state){
            $node = new stdClass();
            $node = Node::create([
              'type' => 'birth_data',
              'title' => 'first lastname',
              'field_birth_date' => '23 NOV 2020 11:11:11',
              'field_birth_location' => 'Osaka',
              'field_email_id' => 'test@myid.com',
              'field_gender' => 'Male',
            ]);
            $node->save();  
            echo "<pre>";
            print_r($form_state);
            exit;

        }
    }

最后,自定义内容类型的机器名称是 birth_data,我对 form unique id 使用了相同的名称和节点创建类型 type

这行是多余的,你可以舍弃它:

$node = new stdClass();

创建节点的可能示例,假设您有内容类型,即。 page:

use Drupal\node\Entity\Node;

...

// Initialise a node object with several field values.
$node = Node::create([
  'type' => 'page',
  'title' => 'foo',
  'field_birth_date' => ['value' => 'bar'],
]);

// Set field values.
$node->field_birth_date->value = 'bar';
$node->field_birth_location->value = 'US';
$node->field_email_id->value = 'hello@example.com';
$node->field_gender->value = 'm'

// You can also use setters but you need to check on the available ones. They are also chainable:
$node
  ->setTitle('foo')
  ->setPromoted(TRUE)
  ->setPublished();

// Save the node.
$node->save();

Baikho的回答很好。还是尽量避免使用静态调用(比如Node::create());我们可以轻松地在构造函数中注入依赖项。

<?php

namespace Drupal\birth_details\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Entity\EntityTypeManager;
use Drupal\Core\Session\AccountProxyInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

class BirthDetails extends FormBase {

  /**
   * Current user account.
   *
   * @var \Drupal\Core\Session\AccountProxyInterface
   */
  protected $currentUser;

  /**
   * Node storage.
   *
   * @var \Drupal\node\NodeStorageInterface
   */
  protected $nodeManager;

  /**
   * {@inheritdoc}
   */
  public function __construct(
    EntityTypeManager $entity_type_manager,
    AccountProxyInterface $current_user
  ) {
    $this->currentUser = $current_user;
    $this->nodeManager = $entity_type_manager->getStorage('node');
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('entity_type.manager'),
      $container->get('current_user')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function getFormId(){
    return 'birth_data';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $form['title'] =  [
      '#type' => 'textfield',
      '#description' => $this->t('Enter your name here!'),
    ];
    $form['field_birth_date'] =  [
      '#type' => 'textfield',
      '#description' => $this->t('Enter your field_birth_date here!'),
    ];
    $form['field_birth_location'] =  [
      '#type' => 'textfield',
      '#description' => $this->t('Enter your field_birth_location here!'),
    ];
    $form['field_email_id'] =  [
      '#type' => 'textfield',
      '#description' => $this->t('Enter your field_email_id here!'),
    ];
    $form['field_gender'] =  [
      '#type' => 'textfield',
      '#description' => $this->t('Enter your field_gender here!'),
    ];

    $form['actions']['#type'] = 'actions';
    $form['actions']['submit'] = [
      '#type' => 'submit',
      '#value' => $this->t('Save data'),
    ];

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state) {

  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $node = $this->nodeManager->create([
      'type' => 'birth_data',
      'title' => $values['title'],
      'uid' => $this->currentUser->id(),
      'status' => 1,
    ]);

    $node->field_birth_date->value = "23 NOV 2020 11:11:11";
    $node->field_birth_location->value = "Osaka";
    $node->field_email_id->value = "test@myid.com";
    $node->field_gender->value = "Male";
    
    $node->save();
  }
}

根据 Baikho or MacSim 的建议,您的解决方案应该可行,但这并没有充分利用 Drupal 的自定义内容类型设计。您正在创建一个表单,并使用它来将信息路由到一个节点,该节点提供了无需维护您自己的表单即可执行您想要的操作的机制。

如果你想create a custom node type, you can have your module define the node bundle type during install and then use the standard interface to enter and edit that content. If you want to modify the form from there you should use the hook_BASEID_form_alter()

您的另一个选择是创建一个 custom content entity,这实际上是创建另一个与节点平行的元素。