web-dev-qa-db-fra.com

Comment générer par programme un formulaire d'entité?

Je dois générer par programme le formulaire d'entité pour mon entité personnalisée - obtenir essentiellement la même sortie que celle qui se produit lorsque vous appelez

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

Lorsque j'essaie de le faire avec mon formulaire d'entité j'obtiens l'erreur:

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

Vraiment perplexe sur la façon de procéder.


Voici une version obscurcie du code que j'utilise

Définition de l'entité:

/**
 * 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 {

Espace de noms de formulaire

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 {

D'accord, c'est ce que j'ai trouvé jusqu'à présent. La réponse de l'utilisateur oknate fonctionne partiellement; J'ai également dû ajouter une fonction factice à ma classe de formulaire de conteneur pour contourner une erreur de rappel, qui ressemblait à ceci:

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

Ce n'est probablement pas la bonne façon de procéder, mais cela aboutit à un objet de formulaire qui sera rendu dans un autre formulaire.

7
elstevenson

Vous pouvez utiliser le service de création de formulaire d'entité. J'ai pu charger le formulaire utilisateur de cette façon (avec $ entity étant l'utilisateur actuel):

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

Si vous souhaitez obtenir le formulaire d'enregistrement d'utilisateur (qui est essentiellement un formulaire d'entité sans entité enregistrée), vous pouvez simplement utiliser la méthode create sur votre classe d'entité avant de la transmettre au formulaire:

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

Les formulaires d'entité ne fonctionnent pas sans entité. Si vous voulez un formulaire vide, utilisez une instance d'entité nouvellement créée. Vous pouvez utiliser cet exemple à partir de l'entité de nœud:

/**
   * 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;
  }

Le générateur de formulaire d'entité est injecté dans la classe de base du contrôleur. Donc, généralement, vous utilisez un contrôleur pour créer des formulaires d'entité.

Lors de la création d'un nœud, vous devez définir un ensemble (type de contenu) pour lequel le formulaire d'entité sera créé. Si votre entité n'a pas de bundles, vous pouvez utiliser un tableau vide.


Commentaires

Les commentaires nécessitent plus de travail, car ils sont attachés à un champ d'entité.

Exemple de création d'un formulaire pour le champ de commentaire d'un nœud:

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

Ou le même en dehors d'un contrôleur sans services injectés:

$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

Juste pour clarifier, le code ci-dessous fonctionne pour moi dans Drupal 8.2.x:

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