it-swarm.com.de

Wie generiere ich programmgesteuert ein Entitätsformular?

Ich muss das Entitätsformular für meine benutzerdefinierte Entität programmgesteuert generieren - im Grunde die gleiche Ausgabe erhalten, die beim Aufrufen auftritt

\Drupal::formBuilder()->getForm('form namespace')

Wenn ich versuche, dies mit meinem Entitätsformular zu tun ich erhalte den Fehler:

Call to a member function getEntityTypeId() on null in Drupal\Core\Entity\EntityForm->getBaseFormId() (line 77 of core/lib/Drupal/Core/Entity/EntityForm.php).

Wirklich ratlos, wie es weitergehen soll.


Hier ist eine verschleierte Version des Codes, den ich verwende

Entitätsdefinition:

/**
 * Defines the My Entity entity.
 *
 * @ingroup my_module
 *
 * @ContentEntityType(
 *   id = "my_entity",
 *   label = @Translation("My Entity"),
 *   handlers = {
 *     "view_builder" = "Drupal\Core\Entity\EntityViewBuilder",
 *     "list_builder" = "Drupal\my_module\MyEntityListBuilder",
 *     "views_data" = "Drupal\my_module\Entity\MyEntityViewsData",
 *     "translation" = "Drupal\my_module\MyEntityTranslationHandler",
 *
 *     "form" = {
 *       "default" = "Drupal\my_module\Form\MyEntityForm",
 *       "add" = "Drupal\my_module\Form\MyEntityForm",
 *       "edit" = "Drupal\my_module\Form\MyEntityForm",
 *       "delete" = "Drupal\my_module\Form\MyEntityDeleteForm",
 *     },
 *     "access" = "Drupal\my_module\MyEntityAccessControlHandler",
 *     "route_provider" = {
 *       "html" = "Drupal\my_module\MyEntityHtmlRouteProvider",
 *     },
 *   },
 *   base_table = "my_entity",
 *   data_table = "my_entity_field_data",
 *   translatable = TRUE,
 *   admin_permission = "administer as my_entity entities",
 *   entity_keys = {
 *     "id" = "id",
 *     "label" = "name",
 *     "uuid" = "uuid",
 *     "uid" = "user_id",
 *     "langcode" = "langcode",
 *     "status" = "status",
 *   },
 *   links = {
 *     "canonical" = "/admin/structure/my_entity/{my_entity}",
 *     "add-form" = "/admin/structure/my_entity/add",
 *     "edit-form" = "/admin/structure/my_entity/{my_entity}/edit",
 *     "delete-form" = "/admin/structure/my_entity/{my_entity}/delete",
 *     "collection" = "/admin/structure/my_entity",
 *   },
 *   field_ui_base_route = "my_entity.settings",
 *   constraints = {
 *     "CustomContraint" = {}
 *   }
 * )
 */
class MyEntity extends ContentEntityBase implements MyEntityInterface {

Formular-Namespace

namespace Drupal\my_module\Form;

use Drupal\Core\Entity\ContentEntityForm;
use Drupal\Core\Form\FormStateInterface;

/**
 * Form controller for My Entity edit forms.
 *
 * @ingroup my_module
 */
class MyEntityForm extends ContentEntityForm {

Okay, das habe ich bisher gefunden. Die Antwort von Benutzer oknate funktioniert teilweise; Ich musste meiner Containerformularklasse auch eine Dummy-Funktion hinzufügen, um einen Rückruffehler zu umgehen, der folgendermaßen aussah:

 public function processForm($element, FormStateInterface $form_state, $form)
  {
    return $element;
  }

Dies ist wahrscheinlich nicht der richtige Weg, aber es führt zu einem Formularobjekt, das in einem anderen Formular gerendert wird.

7
elstevenson

Sie können den Entity Form Builder-Service verwenden. Ich konnte das Benutzerformular auf diese Weise laden (wobei $ entity der aktuelle Benutzer ist):

$entity = User::load($uid);
$user_form = \Drupal::service('entity.form_builder')->getForm($entity, 'default');

Wenn Sie das Benutzerregisterformular erhalten möchten (das im Grunde ein Entitätsformular ohne gespeicherte Entität ist), können Sie einfach die Methode create für Ihre Entitätsklasse verwenden, bevor Sie es an das Formular übergeben:

$entity = User::create();
$user_form = \Drupal::service('entity.form_builder')->getForm($entity, 'default');
12
oknate

Entitätsformulare funktionieren ohne Entität nicht. Wenn Sie ein leeres Formular möchten, verwenden Sie eine neu erstellte Entitätsinstanz. Sie können dieses Beispiel aus der Knotenentität verwenden:

/**
   * Provides the node submission form.
   *
   * @param \Drupal\node\NodeTypeInterface $node_type
   *   The node type entity for the node.
   *
   * @return array
   *   A node submission form.
   */
  public function add(NodeTypeInterface $node_type) {
    $node = $this->entityManager()->getStorage('node')->create(array(
      'type' => $node_type->id(),
    ));

    $form = $this->entityFormBuilder()->getForm($node);

    return $form;
  }

Der Entity Form Builder wird in die Controller-Basisklasse eingefügt. Normalerweise verwenden Sie einen Controller, um Entitätsformulare zu erstellen.

Beim Erstellen eines Knotens müssen Sie ein Bundle (Inhaltstyp) definieren, für das das Entitätsformular erstellt wird. Wenn Ihre Entität keine Bundles hat, können Sie ein leeres Array verwenden.


Kommentare

Kommentare erfordern mehr Arbeit, da sie an ein Entitätsfeld angehängt sind.

Beispiel zum Erstellen eines Formulars für das Kommentarfeld eines Knotens:

$comment = $this->entityTypeManager()->getStorage('comment')->create([
  'entity_type' => 'node',
  'entity_id' => $node->id(),
  'field_name' => 'comment',
]);
$build = $this->entityFormBuilder()->getForm($comment);

Oder dasselbe außerhalb eines Controllers ohne injizierte Dienste:

$comment = \Drupal::entityTypeManager()->getStorage('comment')->create([
  'entity_type' => 'node',
  'entity_id' => $node->id(),
  'field_name' => 'comment',
]);
$build = \Drupal::service('entity.form_builder')->getForm($comment);
5
4k4

Zur Verdeutlichung funktioniert der folgende Code für mich in Drupal 8.2.x:

$form = \Drupal::formBuilder()->getForm(Drupal\user\Form\UserLoginForm::class);
3
Kevin