Kapcsolat űrlap és levél módosítása a Drupalban

Korábban már írtam a hook_form_alter() előnyeiről és működéséről. Ennek segítségével – némi programozással – elérhetjük, hogy a Drupal módosítása nélkül a rendszer űrlapjai kedvünkre változzanak meg. De mi van akkor, ha az űrlapok változtatása nem elegendő? Az utóbbi hetekben a Weblabor.hu 4.6.x-es rendszerről 5.x-es Drupal rendszerre frissítésén is munkálkodom szabadidőmben, és éppen ma értem el a Weblabor szerkesztőit is megcímző kapcsolati űrlap funkcióhoz. Lássuk mi az igényelt funkció, és milyen kényelmes megtenni a módosításainkat Drupal 5.1-gyel!

A kérdéses szolgáltatás csak az adminisztrátorok számára érhető el a Weblaboron, és azt teszi lehetővé, hogy amikor egy levelet küldünk (jellemzően valamilyen moderációs lépésről) egy felhasználó kapcsolat űrlapjáról az adott tagnak, akkor azt egyben cc-zzük is a Weblabor szerkesztőinek. Fontos, hogy egy cc fejléc elemet veszünk fel a levélbe, és a Drupal beépített 'másolatot kérek' funkciójával ellentétben nem új levelet küldünk. A cc fejléc használata ugyanis lehetővé teszi, hogy a szerkesztők is azonnal reagáljanak, hozzátegyék saját véleményünket a levélhez úgy, hogy azt a szerkesztők és a felhasználónk is megkapja. Ráadásul szálkövető marad a levelezés.

A fejlesztői alapproblémám egy a korábbi Drupal 4.6-os rendszerkód módosításával megvalósított szolgáltatás átültetése ezúttal már oly módon, hogy ne kelljen Drupal kódot módosítanom. Szerencsére a két ehhez szükséges eszköz a Drupal 5.0-val megérkezett, tudok megjelenített űrlapot és elküldött levelet is módosítani. A demonstráció kedvéért nevezzük a modulunkat wlcontact-nak, a domain pedig legyen example.com (így aki innen másolja a kódot, az nem rögtön nekünk címzi a leveleit).

Először is az űrlapot kell megváltoztatnom. Itt azonosítani kell, hogy a felhasználói kapcsolat űrlapról van szó, és adminisztrátorral van dolgunk. Ha ez teljesül, akkor felveszünk egy új 'toeditors' elemet az űrlapba, ami jelölőnégyzet típusú. Magyarázatot is adunk, hiszen a működés eltérő a beépített másolat funkciótól (és az összekeverés elkerülése érdekében arra a beépített elemre is adunk magyarázatot). Meg kell még oldanunk, hogy az új elemünk a submit gomb fölött jelenjen meg. Mivel ebben az űrlapban nincsenek megadott súlyozások, a submit gombnak nagyobb súlyt adunk meg, mint a saját jelölőnégyzetünknek. Ezzel kész is az űrlap külalakja. Még egy dologra kell figyelnünk, mégpedig, hogy értesüljünk az űrlap elküldéséről és feldolgozzuk a másolat kérést. Ennek érdekében az űrlap elküldése után lefutó függvények elejére regisztrálunk egy saját eseménykezelőt, ami így befolyásolni tudja majd a további működést. Fontos, hogy az elejére regisztráljunk, hiszen az alapértelmezett eseménykezelő küldi a levelet, és nekünk azelőtt kell közbelépnünk a folyamatba.

function wlcontact_form_alter($form_id, &$form) {
  if($form_id == 'contact_mail_user' && user_access('access administration pages')) {
    $form['toeditors'] = array(
      '#title' => 'Másolat az Example.com szerkesztőknek',
      '#type' => 'checkbox',
      '#description' => 'Másolat küldése a szerkesztőségi email címre is.',
      '#weight' => 9,
    );
    $form['copy']['#description'] = 'Másolat küldése a személyes email címre.';
    $form['submit']['#weight'] = 10;
    $form['#submit'] = array('wlcontact_mail_user_submit' => array()) + $form['#submit'];
  }
}

Felmerülhet a kérdés, hogy miként ismertem fel az űrlap azonosítóját és elemeit. Ilyen részletek érdekében nem szeretem a forráskódot böngészni, ezért egyszerűen a var_dump($form_id) és var_dump($form) használatával derítettem fel a struktúrát, illetve, hogy mit hol kell módosítanom, milyen nevű kulcsok vannak a tömbben. Ez éppen elegendő volt a céljaimra.

Nos, lássuk mit tudunk tenni, ha az űrlapot elküldik. Mivel a követelményünk az volt, hogy nem második levelet küldünk, hanem a contact modul által egyébként is elküldött levelet módosítjuk, nem tudunk azonnal levelet küldeni. Meg kell viszont jegyeznünk, hogy a szerkesztőségnek is el kell küldeni a levelet, mert erre még később szükségünk lesz. A submit függvények két paramétert kapnak, az űrlap azonosítóját és a beküldött értékeket. Most biztosak vagyunk az űrlap azonosítóját illetően, hiszen csak egy űrlaphoz kötöttük ezt az eseménykezelőt, ezért annak értékével nem foglalkozunk, csak azzal, hogy be legyen állítva. Amennyiben pedig az űrlap értékek között a szerkesztőknek való elküldést kérték, ezt egy statikus értékben megjegyezzük. Ha úgy hívjuk meg ezt a függvényt, hogy nem adunk meg semmilyen űrlap azonosítót, akkor fogjuk visszakapni a megjegyzett értéket.

function wlcontact_mail_user_submit($form_id = NULL, $form_values = array()) {
  static $toeditors = FALSE;
  if (isset($form_id)) {
    $toeditors = (bool) $form_values['toeditors'];
  }
  else {
    return $toeditors;
  }
}

Végül szükségünk van arra, hogy a megjegyzett értéknek megfelelően elhelyezzünk egy cc fejlécet a kiküldött levelekben. Erre a célra tavaly nyár óta a hook_mail_alter() használható. Ezt kell tehát már csak megvalósítanunk. Itt a levél részletes adatait kapjuk meg külön-külön paraméterekben. Most számunkra az az érdekes, hogy melyik levéllel van dolgunk. Szerencsére a contact modul fejlesztői okosan megkülönböztették a normál kapcsolat levelet a (beépített képességgel előállított) másolat levéltől, így csak a normál kapcsolat levélre tudunk koncentrálni. Itt ellenőrizni kell, hogy a korábban megjegyzett űrlap mező érték mi volt. Ha kérték a cc fejléc beállítását, akkor a fejlécek tömbjéhez adjuk ezt hozzá.

function wlcontact_mail_alter(&$mailkey, &$to, &$subject, &$body, &$from, &$headers) {
  if ($mailkey == 'contact-user-mail' && wlcontact_mail_user_submit()) {
    $headers['Cc'] = '[email protected]';
  }
}

Voilá! Készen is vagyunk a kapcsolat űrlap funkcionalitásának kiterjesztésével, anélkül, hogy bármit módosítani kellett volna az alaprendszeren.