0

我正在使用 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,我对表单唯一ID和节点创建类型使用相同

4

3 回答 3

4

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();
  }
}
于 2020-11-23T22:47:29.333 回答
3

此行是多余的,您可以丢弃它:

$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();
于 2020-11-23T17:30:23.660 回答
1

您使用BaikhoMacSim的建议的解决方案应该可以工作,但这并没有完全利用 Drupal 的自定义内容类型设计。您正在创建一个表单,并使用它将信息路由到一个节点,该节点提供了在不维护自己的表单的情况下执行您想要的操作的机制。

如果要创建自定义节点类型,可以让模块在安装期间定义节点包类型,然后使用标准界面输入和编辑该内容。如果你想从那里修改表单,你应该使用hook_BASEID_form_alter()

您的另一个选择是创建一个自定义内容实体,它本质上是创建另一个与节点平行的元素。

于 2020-11-24T16:28:00.603 回答