Modifica un modulo esistente


12

Abbiamo appena iniziato con Drupal 8 e molto rapidamente abbiamo riscontrato il nostro primo problema.

Come devo modificare un modulo esistente in Drupal 8?

È necessario modificare il metodo di salvataggio per il modulo nodo per eseguire un reindirizzamento a un'altra pagina. Vogliamo modificare la forma del nodo per diventare qualcosa di simile a una forma a più fasi. Dopo che l'utente ha creato nuovi contenuti, vengono reindirizzati a un nuovo modulo (abbiamo creato) per ottenere ulteriori informazioni.

Abbiamo risolto il nostro problema di implementazione hook_entity_type_alter().

function mymodule_entity_type_alter(&$entity_info) {
  $handlers = $entity_info['node']->get('handlers');
  $handlers['form']['default'] =    'Drupal\mymodule\Form\MyExtendedNodeForm';
  $handlers['form']['edit'] = 'Drupal\mymodule\Form\MyExtendedNodeForm';
  $entity_info['node']->set('handlers', $handlers);
}

Abbiamo quindi creato una nuova classe di modulo che estende la forma del nodo e modifica il metodo di salvataggio.

class MyExtendedNodeForm extends NodeForm {

    public function save(array $form, FormStateInterface $form_state) {
      parent::save($form, $form_state);
      $node = $this->entity;
      $form_state->setRedirect('entity.regions.add_form', ['nid' => $node->id()]);
  }

}

Funziona perfettamente, ma va bene? Se un altro modulo fa lo stesso, il nostro codice non viene più eseguito.


2
Drupal 8 supporta ancora hook_form_alter(). Se devi solo reindirizzare il modulo, è sufficiente aggiungere un gestore di invio del modulo che esegua il reindirizzamento.
kiamlaluno

@kiamlaluno Questa dovrebbe essere la risposta penso :)
Berdir,

@Berdir Solo questo non sarebbe molto utile, temo: la mia conoscenza di Drupal 8 è piuttosto limitata. Inoltre, l'OP dovrebbe chiarire cosa save()significa effettivamente "alterare il metodo". Significa cambiare il modo in cui i dati vengono salvati o semplicemente reindirizzare? Nel primo caso, la risposta è più complessa.
kiamlaluno

@kiamlaluno Thx per la risposta. In questo caso dobbiamo solo fare un reindirizzamento dopo il salvataggio (), quindi la tua risposta dovrebbe funzionare. Ma ero anche interessato a come alterare altre cose nella forma nel modo giusto di Drupal 8. Ad esempio, modifica la modalità di salvataggio o aggiungi i campi al modulo .. ecc.
Jens Steppe,

Risposte:


4

Ho dovuto fare esattamente la stessa cosa ieri e sto ancora cercando un modo più Drupal 8 per farlo, ma non l'ho trovato. Ho finito per farlo in questo modo:

<?php

/**
 * @file
 * This is my module.
 */

use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\HttpFoundation\Request;

/**
 * Implements hook_form_alter().
 */
function MODULE_form_alter(array &$form, FormStateInterface $form_state, $form_id) {
  if ($form_id == 'user_form') {
    $form['actions']['submit']['#submit'][] = '_MODULE_goto';
  }
}

/**
 * Make the form go to route.id.
 */
function _MODULE_goto($form, FormStateInterface $form_state) {
  $form_state->setRedirect('route.id');
}

Sono ancora molto interessato a farlo in un modo diverso, il mio modulo sembrava così pulito senza il file .module :).


3

Sto usando Drupal 8.1.1 e stavo cercando di reindirizzare gli utenti dopo aver modificato il loro account, ovvero facendo clic sul pulsante Salva nella pagina / utente / modifica. Inizialmente ho provato questo:

/**
 * Implements hook_form_alter().
*/
function MODULE_form_alter(array &$form, FormStateInterface $form_state, $form_id) {
  if ($form_id == 'user_form') {
    $form['#submit'][] = '_MODULE_goto';
  }
}

Mentre quello ha funzionato per il user_login_form, non avrebbe funzionato per user_form. Perché user_formho dovuto usare

$form['actions']['submit']['#submit'][] = '_MODULE_goto';

Spero che ciò aiuti gli altri che si imbattono nello stesso problema!


1

Beh, volevo modificare il site_information_settingsmodulo per aggiungere alcuni campi.

Come te, ho potuto scegliere tra

  • hook_form_alter(o hook_form_FORM_ID_alter)
  • estendere la classe di forma originale

Volevo fare un po 'di OOP, quindi ho iniziato a scrivere un servizio di abbonato route modificando l' attributo system.site_information_settingsdel percorso _form.

Quindi nella mia nuova classe che estende il SiteInformationForm, dopo che i campi e i loro validatori sono stati aggiunti e la funzione di invio estesa mi sono sentito esattamente allo stesso modo di te ... E se un altro modulo riscrivesse il percorso del modulo anche per usare la propria classe?

All'inizio, ho potuto scegliere tra due opzioni ... sembra che abbia scelto quella sbagliata.

hook_form_alter/ hook_form_FORM_ID_altersembra essere il modo migliore per modificare una forma esistente.


0

Sembra quello che vuoi fare, non è in realtà modificare il metodo di salvataggio, ma cambiare il reindirizzamento quando viene salvato un nodo.

In questa situazione, fare molto simile a Drupal 7, hook_form_alterinsieme a un gestore di invio personalizzato (sul modulo o sul pulsante, a seconda del modulo e dei requisiti) sarebbe una buona soluzione.

Anche quello che descrivi nella domanda funziona, ma eviterei di sovrascrivere la classe base, a meno che non voglia davvero cambiare qualcosa nella classe.

Il metodo save utilizza comunque appena usato come gestore di invio, quindi non ha molto senso sovrascrivere solo per aggiungere un reindirizzamento.


0

Penso che il metodo migliore sia usare ancora uno degli hook della famiglia form_alter, allegare un gestore di invio e all'interno di quel set il tuo reindirizzamento.

Contribuire ad estendere le classi base per fare questo è peloso secondo me. Soprattutto perché nessuna funzione sta cambiando, solo il reindirizzamento.


0

È possibile creare un nuovo EventSubscriber, che ascolta l'evento KernelEvents :: RICHIESTA, e poi reagire quando si sta presentando una forma di nodo, qualcosa di simile a questo

Comunque il modo hook_form_alter funziona bene.


0

Quello che ho trovato finora: L'implementazione di un hook di modifica del modulo e il tentativo di modificare i gestori di validazione / invio nel modulo di modifica del modulo stesso funzionano solo se si cambiano i gestori $ form ['# validate] / $ form [#submit']. (chiamando le funzioni form_state per questo non funzionerà nel form alter hook stesso)

Ma quando lo provi all'interno di un gestore di convalida, tende a funzionare:

// Load form submit handlers.
$submit_handlers = $form_state->getSubmitHandlers();

// Drop the core entity submitForm function.
$key_core_submit = array_search('::submitForm', $submit_handlers);
if ($key_core_submit !== FALSE) {
  unset($submit_handlers[$key_core_submit]);
  // Add your own submit handler.
  array_unshift($submit_handlers, 'yourmodule_submit_handler');
}
// Update submit handlers.
$form_state->setSubmitHandlers($submit_handlers);

Questo perché il modulo è stato ora creato completamente, non è il caso nel modulo stesso.

L'idea è: è possibile aggiungere un gestore di convalida come l'ultimo, valutare altri gestori esistenti per l'invio e modificarli immediatamente.

Se si desidera modificare anche i gestori di convalida, assicurarsi che i propri vengano eseguiti prima di qualsiasi altro e modificare ciò che si desidera nel gestore di convalida.

Sempre alla ricerca di un modo migliore, devo solo sostituire i gestori di convalida / invio per il modulo di registrazione utente. Ma potrebbero esistere altri moduli che interrompono l'implementazione dei miei moduli. Quindi il mio modulo dovrebbe essere in grado di verificarli, e questo è possibile in questo modo. Mi chiedo se esiste qualche forma di entità dopo la funzione di costruzione per farcela. (qualcosa che viene eseguito quando il modulo è stato completato e sta per essere consegnato) (non è così complesso per questo semplice caso)

Bypassare il reindirizzamento del metodo save () non è possibile, ma annullare il salvataggio () avviene in questo modo (+ implementa il tuo). È vero, una classe è più bella e offre un accesso più facile agli oggetti / ecc., Ma l'override di una classe principale porta effettivamente a problemi quando altri moduli vogliono usarli. Questo non è il caso se si utilizza questo codice.


0

Dopo aver verificato questo problema, questo è quello che ho trovato che dovrebbe adattarsi al tuo caso:

/**
 * Implements hook_entity_type_alter().
 */
function mymodule_entity_type_alter(&$entity_info) {
 $entity_info['node']->setFormClass('edit','Drupal\mymodule\Form\CustomNodeForm');
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.