Hinweis: Dieses Tutorial wurde am 27.06.2009 überarbeitet. Die im Beispiel erstellten Felder können nun ebenfalls vorausgefüllt angezeigt werden!

Die dafür notwendigen Veränderungen innerhalb der Dateien sind im Download-Paket unten bereits enthalten.

Vielen Dank an Igor Jankovic von der Firma TMEDIA cross communications für den entscheidenden Tipp bei der Bereitstellung von vorausgefüllten Formularfeldern.

Das Magento Kontaktformular ist von Haus aus sehr spartanisch ausgestattet. So werden in der Standardinstallation lediglich die Felder Name, E-Mail, Telefon und die Mitteilungsbox bereit gestellt.

Was aber wenn ich mich mit meinem Angebot eher an Firmen wie Privatpersonen richte? Oder ich ganz einfach noch weitere Informationen wie etwa Fax zu Zwecken der Kontaktaufnahme übermittelt haben möchte?

Ganz klar es sollte die Möglichkeit bestehen das Kontaktformular um weitere Felder zu ergänzen & die eingegebenen Daten dann auch beim Shopbetreiber ankommen und das in einer übersichtlichen Form.

Im folgenden Tutorial werden wir ein eigenes Modul erstellen was in der Lage ist das Kontaktformular um entsprechende Funktionalitäten zu ergänzen. Es wird mit den Feldern „Firma“ & „Fax“ gearbeitet.

Ich bin der Meinung dass man diese Felder oft benötigt – sollte das bei Ihnen nicht der Fall sein, dann lassen Sie einfach die nicht benötigten Bereiche in Ihrem Projekt weg.

Orientierung / Vorbereitung:
Das Original-Modul findet man unter app/code/core/Mage/Contacts
Die zu bearbeitenden Template Datei unter app/design/frontend/ihr_interface/ihr_theme/template/contacts/form.phtml

Tipp für Nutzer der Fontis Recaptcha Extension:
Die folgenden Anpassungen müssen auf diese Erweiterung angelegt sein, da diese bereits das Template & und auch die Controller überschreibt.

Dies gilt so lange diese Erweiterung installiert ist – und ich muss an dieser Stelle darauf hinweisen, dass Veränderungen nach einem Update der Extension wieder überschrieben werden!

Erstellung des Moduls
Falls Sie noch nicht im Extension Tutorial oder auch anderen Workshops auf dieser Seite das Mxperts Shell Modul angelegt haben ist das nicht weiter tragisch. Legen Sie zu diesem Zweck unter app/code/local einen Ordner Mxperts an (optional Ihren Firmennamen). Darin bilden Sie in Form von neuen Ordnern die folgende Verzeichnisstruktur nach:
verzeichnisse-modul1

Unter app/etc/modules speichern wir die Datei Mxperts_Contacts.xml und füllen Sie mit dem folgenden Inhalt:

<?xml version="1.0"?>
<config>
    <modules>
		<Mxperts_Contacts>
            <active>true</active>
            <codePool>local</codePool>
        </Mxperts_Contacts>
    </modules>
</config>

Danach begeben wir uns nach app/code/local /Mxperts/Contacts/etc und speichern dort eine config.xml ab. Vorerst mit diesen Inhalten:

<?xml version="1.0"?>

<config>
    <global>

    </global>
</config>

Als nächstes erstellen wir den IndexController im Ordner “controllers”. Hier werden nun zum Zweck einer späteren Formularüberprüfung und Übermittlung der Felder erstmalig die neuen Felder mit eingebaut – die Datei hat den Inhalt:

<?php
class Mxperts_Contacts_IndexController extends Mage_Core_Controller_Front_Action
{

    public function postAction()
    {
        $post = $this->getRequest()->getPost();
        if ( $post ) {
            $translate = Mage::getSingleton('core/translate');
            /* @var $translate Mage_Core_Model_Translate */
            $translate->setTranslateInline(false);
            try {
                $postObject = new Varien_Object();
                $postObject->setData($post);

                $error = false;

                if (!Zend_Validate::is(trim($post['name']) , 'NotEmpty')) {
                    $error = true;
                }

                if (!Zend_Validate::is(trim($post['comment']) , 'NotEmpty')) {
                    $error = true;
                }

                if (!Zend_Validate::is(trim($post['email']), 'EmailAddress')) {
                    $error = true;
                }

				if (!Zend_Validate::is(trim($post['telephone']) , 'NotEmpty')) {
                    $error = true;
                }

				if (!Zend_Validate::is(trim($post['company']), 'NotEmpty')) {
                    $error = true;
                }

				if (!Zend_Validate::is(trim($post['fax']), 'NotEmpty')) {
                    $error = true;
                }

                if ($error) {
                    throw new Exception();
                }
                $mailTemplate = Mage::getModel('core/email_template');
                /* @var $mailTemplate Mage_Core_Model_Email_Template */
                $mailTemplate->setDesignConfig(array('area' => 'frontend'))
                    ->setReplyTo($post['email'])
                    ->sendTransactional(
                        Mage::getStoreConfig(self::XML_PATH_EMAIL_TEMPLATE),
                        Mage::getStoreConfig(self::XML_PATH_EMAIL_SENDER),
                        Mage::getStoreConfig(self::XML_PATH_EMAIL_RECIPIENT),
                        null,
                        array('data' => $postObject)
                    );

                if (!$mailTemplate->getSentSuccess()) {
                    throw new Exception();
                }

                $translate->setTranslateInline(true);

                Mage::getSingleton('customer/session')->addSuccess(Mage::helper('contacts')->__('Your inquiry was submitted and will be responded to as soon as possible. Thank you for contacting us.'));
                $this->_redirect('*/*/');

                return;
            } catch (Exception $e) {
                $translate->setTranslateInline(true);

                Mage::getSingleton('customer/session')->addError(Mage::helper('contacts')->__('Unable to submit your request. Please, try again later'));
                $this->_redirect('*/*/');
                return;
            }

        } else {
            $this->_redirect('*/*/');
        }
    }

}

Im Ordner Helper wird nun die Datei Data.php erstellt:

<?php
class Mxperts_Contacts_Helper_Data extends Mage_Contacts_Helper_Data
{
    public function getUserName()
    {
        if (!Mage::getSingleton('customer/session')->isLoggedIn()) {
            return '';
        }
        $customer = Mage::getSingleton('customer/session')->getCustomer();
        return trim($customer->getName());
    }

	public function getUserCompany()
    {
        if (!Mage::getSingleton('customer/session')->isLoggedIn()) {
            return '';
        }
        $customer = Mage::getSingleton('customer/session')->getCustomer()->getDefaultBillingAddress();
        return trim($customer->getCompany());
    }

    public function getUserEmail()
    {
        if (!Mage::getSingleton('customer/session')->isLoggedIn()) {
            return '';
        }
        $customer = Mage::getSingleton('customer/session')->getCustomer();
        return $customer->getEmail();
    }

	public function getUserTelephone()
    {
        if (!Mage::getSingleton('customer/session')->isLoggedIn()) {
            return '';
        }
        $customer = Mage::getSingleton('customer/session')->getCustomer()->getDefaultBillingAddress();
        return $customer->getTelephone();
    }

	public function getUserFax()
    {
        if (!Mage::getSingleton('customer/session')->isLoggedIn()) {
            return '';
        }

		$customer = Mage::getSingleton('customer/session')->getCustomer()->getDefaultBillingAddress();
		return $customer->getFax();

    }
}

Diese Datei hat die Aufgabe, sofern ein Kunde bereits eingeloggt ist oder innerhalb dieser Sitzung schon einmal Daten wie E-Mail eingetragen hat diese im Formular im Voraus auszufüllen. Magento unterscheidet intern zwischen Kundendaten (reine Nutzerdaten) & Kunden-Addressdaten. Der Zugriff auf letztere wird in den Feldern “Telefon”, “Fax” & “Firma” mit der folgenden Anweisung realisiert: getCustomer()->getDefaultBillingAddress();

Wenn Sie für Ihr Projekt an dieser Stelle lieber auf die Standard Lieferanschrift zugreifen wollen, so ändern Sie diese Angabe in “getCustomer()->getDefaultShippingAddress();” ab.

Auch hier werden die 2 neuen Felder mit eingepflegt. Wir kommen im Template-Umbau noch einmal kurz auf die Helper-Funktionen zurück.

Nachdem wir die 2 Überschreibungen bzw. Klassen in den Dateien IndexController.php & Data.php bereits realisiert haben müssen wir das nur noch in der Datei etc/config.xml entsprechend bekannt machen.

Nun sollte die config.xml so aussehen:

<config>
	<global>
		<controllers>
            <contacts>
                <rewrite>
                    <indexcontroller>Mxperts_Contacts_controllers_IndexController</indexcontroller>
                </rewrite>
			</contacts>
        </controllers>
		<helpers>
            <contacts>
                <rewrite>
                    <data>Mxperts_Contacts_Helper_Data</data>
                </rewrite>
			</contacts>
        </helpers>
    </global>
</config>

Das kleine Modul mit unseren 2 neuen Feldern ist an sich fertig – nun müssen wir aber noch an die eine Template-Datei ran um die neuen Felder auch im Shop-Frontend anzeigen zu können.

Wir begeben uns daher nach app/design/frontend/ihr_interface/ihr_theme/template/contacts/form.phtml
Wichtig ist bei der Ein pflege der Felder, dass man innerhalb von Listen und Div Blöcken arbeitet.

Innerhalb eines Listenpunks li und umgeben der div class=”input-box” wird ein kleines Feld dargestellt.
Wenn man ein langes Feld haben möchte, dann legt man hierfür einen eigenen Listenpunkt an & lässt die DIV einfach weg.

Im Beispiel habe ich beide möglichen Wege verbaut. Oben im Formular wird ein längeres Feld für den Firmennamen erscheinen & unten neben der Telefonnummer soll ein kleines Feld für Fax angezeigt werden.

mit-neuenfeldern

Damit das auch später nachvollziehbar ist, habe ich die Stellen wo die neuen Felder integriert wurden entsprechend kommentiert.

<?php
/**
 * Magento
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Academic Free License (AFL 3.0)
 * that is bundled with this package in the file LICENSE_AFL.txt.
 * It is also available through the world-wide-web at this URL:
 * http://opensource.org/licenses/afl-3.0.php
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@magentocommerce.com so we can send you a copy immediately.
 *
 * DISCLAIMER
 *
 * Do not edit or add to this file if you wish to upgrade Magento to newer
 * versions in the future. If you wish to customize Magento for your
 * needs please refer to http://www.magentocommerce.com for more information.
 *
 * @category   design_default
 * @package    Mage
 * @copyright  Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
 * @license    http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
 */
?>
<div id="messages_product_view"><?php echo $this->getMessagesBlock()->getGroupedHtml() ?></div>
<div class="page-head">
    <h3><?php echo Mage::helper('contacts')->__('Contact Us') ?></h3>
</div>
<form action="<?php echo $this->getFormAction(); ?>" id="contactForm" method="post">
    <fieldset class="group-select">
        <h4 class="legend"><?php echo Mage::helper('contacts')->__('Contact Information') ?></h4>
        <ul>
		    <li>    <!--Das Feld für den Firmennamen ohne <div class="input-box"> in einem eigenen Listenpunkt-->
					<label for="company"><?php echo Mage::helper('contacts')->__('Company') ?> </label><br />
                    <input name="company" id="company" title="<?php echo Mage::helper('contacts')->__('Company') ?>" value="<?php echo $this->htmlEscape($this->helper('contacts')->getUserCompany()) ?>" class="input-text" />
		    </li>
		    <li>
		        <div class="input-box">
                    <label for="name"><?php echo Mage::helper('contacts')->__('Name') ?> <span class="required">*</span></label><br />
                    <input name="name" id="name" title="<?php echo Mage::helper('contacts')->__('Name') ?>" value="<?php echo $this->htmlEscape($this->helper('contacts')->getUserName()) ?>" class="required-entry input-text" type="text" />
                </div>

                <div class="input-box">
                    <label for="email"><?php echo Mage::helper('contacts')->__('Email') ?> <span class="required">*</span></label><br />
                    <input name="email" id="email" title="<?php echo Mage::helper('contacts')->__('Email') ?>" value="<?php echo $this->htmlEscape($this->helper('contacts')->getUserEmail()) ?>" class="required-entry input-text validate-email" type="text" />
                </div>
            </li>
                <!--<div class="clear"></div>-->
			<li>
                <div class="input-box">
                    <label for="telephone"><?php echo Mage::helper('contacts')->__('Telephone') ?> </label><br />
                    <input name="telephone" id="telephone" title="<?php echo Mage::helper('contacts')->__('Telephone') ?>" value="<?php echo $this->htmlEscape($this->helper('contacts')->getUserTelephone()) ?>" class="input-text" type="text" />
                </div>
				<div class="input-box"> <!--das Eingabe-Feld für die Fax Nummer innerhalb einer Liste (neben der Telefonnummer)-->
                    <label for="fax"><?php echo Mage::helper('contacts')->__('Fax') ?> </label><br />
                    <input name="fax" id="fax" title="<?php echo Mage::helper('contacts')->__('Fax') ?>" value="<?php echo $this->htmlEscape($this->helper('contacts')->getUserFax()) ?>" class="input-text" type="text" />
                </div>
			</li>
                <!--<div class="clear"></div>-->
			<li>
                <div class="input-box">
                    <label for="comment"><?php echo Mage::helper('contacts')->__('Comment') ?></label><br />
                    <textarea name="comment" id="comment" title="<?php echo Mage::helper('contacts')->__('Comment') ?>" class="required-entry input-text" style="height:150px;width:525px;" cols="50" rows="5"></textarea>
                </div>
                </li>
                </ul>
    </fieldset>
    <div class="button-set">
        <p class="required"><?php echo Mage::helper('contacts')->__('* Required Fields') ?></p>
        <button class="form-button" type="submit"><span><?php echo Mage::helper('contacts')->__('Submit') ?></span></button>
    </div>
</form>
<script type="text/javascript">
    var contactForm = new VarienForm('contactForm', true);
</script>

Tipp zu den Pflichtfeldern:
Die Formularüberprüfung bzw. Validierung wird innerhalb von Magento sowohl Serverseitig wie auch per JavaScript realisiert.

Um Einfluss darauf zu haben, schaut man sich im Template die Eingabefelder mal etwas genauer an.
Mit dem HTML-Tag:

<span class="required">*</span>

wird zunächst von JavaScript Seite ein Feld global als Pflichtfeld markiert. Diese kommen bei den erstellten Feldern nicht zum Einsatz, da ich gerne offen halten würde ob es sich um eine Firma handelt oder eine Privatperson. Bei Fax lasse ich ebenfalls diesen Tag weg, da ich diese Angabe nicht zwingend benötige.

Nachdem die JavaScript Überprüfung für unsere neuen Felder ausgeschaltet wurde werden wir nun noch die Serverseite ausschalten. Dazu machen wir für unsere 2 Felder am Ende aus

class="required-entry input-text"

folgende Klasse:

class="input-text"

Info – Vorausgefüllte Felder:
Über die Helper-Funktionen werden standardmäßig nur einmalige Kundenattribute wie Name & E-Mail Adresse aus der Sitzung des eingeloggten Kunden impotiert. Firma, Telefonnummer & auch Fax gehören zu den Kundenaddressattributen & werden nicht automatisch ausgefüllt. Das hat damit zu tun, dass man pro Kunden / Nutzer verschiedene Rechnungs- und Lieferadressen anlegen kann und in diesen Bereich fallen nun einmal diese Art von Daten rein.

In der Datei Data.php wurde es so gehalten, dass Diese 3 Felder nun auch vorausgefüllt werden, da mit der Anweisung “getCustomer()->getDefaultBillingAddress();” auf die hinterlegten Kunden Adress-Attribute zugegriffen wird.

Generell werden diese Felder durch die folgende Anweisung innerhalb eines Textfeldes hervorgerufen:

value="<?php echo $this->htmlEscape($this->helper('contacts')->getUserName()) ?>"

Auch für die neuen Felder ändert sich an dieser Form der Anforderung von Daten im Template nichts.

Es kann aber nur auf Attribute zugegriffen werden, die auch hinterlegt sind. Wenn Sie in Ihr Formular etwa ein Feld “Kundennummer” verwenden möchten, dass so in den gespeicherten Kundendaten nicht existiert, so können diese Daten auch nicht für die Vorausfüllung herangezogen werden!

Erstellung & Zuweisung des Mail-Templates
Nun wollen wir noch zum Schluss unseres Tutorials über das Magento-Admin Panel ein Template für das neue Kontaktformular erstellen, was in der Lage ist die Daten aus den neuen Feldern zu übermitteln & entsprechend zu formatieren.

Dazu begeben wir uns im Backend nach System->Transaktions-E-Mails und legen eine neue Vorlage und klicken dort auf „Neue Vorlage“.

Als Vorlage wird hier „Contact Form“ ausgewählt & als Lokalisierung verwenden wir „Deutsch“. Nach einem Klick auf „Vorlage laden“ wird unser Mail-Template aus der Lokalisierung heraus geladen.

Hier werden nun die neuen Variablen ergänzt & an den gewünschten Stellen positioniert.

Firma: {{var data.company}}
Fax: {{var data.fax}}

neue-mailvorlage

Die Vorlage kann nun abgespeichert werden.

Unter System->Konfiguration->Kontakte weisen wir dieses neue Template nun noch zu & stellen zudem sicher das unter „Store E-Mail Adressen“ ein Absender für das Kontaktformular konfiguriert wurde – wenn dies noch nicht der Fall ist dann bitte aller spätestens jetzt nachholen!

zuweisung-template

Als letzte Amtshandlung im Backend gehen wir noch nach System->Cache Verwaltung & aktualisieren alle Caches.

Nun können wir das neue Kontaktformular mit zusätzlichen Feldern im Frontend aufrufen & versenden. Die Mail die dann ankommt sollte aussehen wie auf dem Bild.
formular-mit-text
email-mit-daten

Diese Beispielfelder können bei Ihnen völlig anders heißen, da Sie offenbar nicht zwingend den hinterlegten Daten des Kunden entsprechen müssen. Daher wäre hier auch ein Feld „Kundennummer“ oder auch „Vorgangsnummer“ möglich. Aber das überlasse ich Ihnen wie Sie diese Informationen für eigene Projekte verwenden.

Fazit: Kleine Module bedeuten nicht zwangsläufig wenig Arbeit, da man anhand dieses Beispiels sieht das man oft dadurch mehr anpassen muss als man zunächst vermutet.

Info: Wer sich genauer für dieses kleine Modul interessiert, sollte sich in jedem Fall das Original ansehen – dann wird man auch feststellen das ich nicht alle Klassen sondern eben nur die überschrieben habe, die zur Realisierung notwendig waren. Somit wird der Pflegeaufwand minimiert & zudem wurde der Code kurz & knackig gehalten. Das hat Performance-Gründe denn bei allen Überschreibungen egal ob Modul oder Template wird immer erst default bzw. die Core-Module geladen – erst danach werden Klassen überladen & werden wie eine Hülle darüber gestülpt bevor dann die Seite an den Browser ausgeliefert wird.

Ich hoffe es hat Ihnen Spaß gemacht einen Weg kennen zulernen das Magento-Kontaktformular um eigene Felder zu erweitern.

Download der Dateien zum Tutorial: eigene-felder-magento-kontaktformular.zip

Die folgenden Tutorials befinden sich zu diesem Thema von meiner Seite bereits in Planung (Realisierung noch offen):
- „Überschreibung der Extension Fontis Recaptcha“
- „Mehrere Kontaktformulare für verschiedene Zwecke auf einer Seite nutzen“
Es gibt mittlerweile
- „Nutzung verschiedener Feldtypen wie etwa DropDown, Mehrfachauswahl, Checkboxen usw.“

Jedoch kann ich nicht versprechen, dass diese Tutorials so in der Form realisiert werden können. Meine innere Stimme sagt zwar „JA“ aber oft ist der Wunsch bekanntlich Vater des Gedankens.

Liebe Grüße – Daniel Sasse