Pobieranie obiektu węzła w hook_form_FORM_ID_alter

13

Kontynuuj to pytanie, ale nie mam wystarczającej reputacji, aby poprosić o wyjaśnienie w komentarzu.

Przesyłam moduł wnoszony do Drupala 8. Sugerowany kod na wyżej wspomnianym CR i postu nie działa:

$node = $form_state->getFormObject()->getEntity();

Nic nie jest ładowane do zmiennej $ node.

Moje PHPStorm IDE daje ostrzeżenie dla getEntity (): Nie znaleziono metody „getEntity” w klasie Drupal \ Core \ Form \ FormInterface mniej ... W klasie podmiotu nie znaleziono metody referencyjnej.

Nie przedstawia również tej metody uzupełniania kodu.

W przypadku użycia odnoszę się do:

use Drupal\Core\Entity;
use Drupal\Core\Entity\EntityInterface;
use Drupal\node\Entity\Node;
use Drupal\Core\Render\Element;
Bundio
źródło

Odpowiedzi:

13

PhpStorm nie wie, ponieważ typ obiektu formularza jest dynamiczny, ale jest w porządku.

Jeśli chcesz go uszczęśliwić, zawiń go w taki stan:

if ($form_state->getFormObject() instanceof EntityForm) {
  ...
}

Tak czy inaczej, na pewno powinno działać, jeśli wprowadzisz poprawną zmianę formularza. Jeśli tego nie zrobisz, powinieneś skończyć z błędem krytycznym nie tylko bez obiektu węzła.

Musisz podać swój dokładny kod, jeśli chcesz uzyskać bardziej szczegółową odpowiedź, to wszystko, co mogę ci powiedzieć.

Berdir
źródło
Dzięki Berdir. Nie wiedziałem, że $ node nie jest obiektem węzła jak w D7. Więc $ node-> nid nie działa, ale $ node-> Id () działa.
Bundio,
7

Chociaż wybrano prawidłową odpowiedź, wydaje mi się, że trzeba wyjaśnić kilka rzeczy:

  • Ta metoda getFormObject()jest dostępna tylko na formularzach typu EntityForm.
  • Jeśli to robisz hook_form_node_form_alter(), wiesz, że formularz jest zawsze formularzem węzła, więc możesz bezpiecznie wywoływać getEntity()obiekt formularza.
  • Jednakże, jeśli robisz ogólny hook_form_alter()haczyk, może chcesz sprawdzić prawidłowe $form_idlub sprawdzić, czy obiekt jest w rzeczywistości formą NodeFormlub EntityForm. Zapobiegnie to błędom PHP, jeśli formularz nie jest formularzem encji / węzła.
  • Jeśli chodzi o IDE i uzupełnianie kodu, możesz powiedzieć IDE, że $form_objectmasz do czynienia z a NodeFormlub an EntityForm. Dzięki temu będzie wyświetlać bardziej odpowiednie wskazówki.
/** @var \Drupal\Core\Entity\EntityForm $form_object */
$form_object = $form_state->getFormObject();
if ($form_object instanceof EntityForm) {
  $entity = $form_object->getEntity();
  // Do something with the entity.
}
Jigarius
źródło
1
najlepsze ze wszystkich, dziękuję za wyjaśnienie!
Dazag
2

Aby twoje IDE wiedziało, jaki jest typ zmiennej i co jest dla niego dostępne, musisz wpisać podpowiedź do zmiennych.

Wskazówka dotycząca typu to typ zmiennej dodany przed nazwą zmiennej parametru (w poniższym przykładzie arrayi FormStateInterFace).

Przykład:

/**
 * On form submit, do something.
 *
 * @param array
 *   The form array.
 *
 * @param \Drupal\Core\Form\FormStateInterface
 *   The form state array.
 */
function _submit_hook_name(array $form, FormStateInterface $form_state) {
  $node = $form_state->getFormObject();
  // Do something...
}

Do przesyłania haków powinieneś używać Drupal\Core\Form\FormStateInterfacetypu ... dlatego na górze pliku upewnij się, że używasz tej klasy use Drupal\Core\Form\FormStateInterface;.

Standardy kodowania Drupal mówią, że powinieneś pisać cast, a także wyjaśniać typ w docblock. Dodatkowy wysiłek pomaga w przyszłości. ;)

Seb
źródło