Eigene Formularelemente im Produkt erstellen, gestalten und benutzen
In Magento lassen sich über die Attribute-Sets ohne weiteres Felder zum Produkt hinzufügen. Die Typen der Felder sind auf Text Field, Text Area, Date, Yes/No, Multiple Select, Dropdown, Price, Gallery, Media Image und Fixed Product Tax beschränkt. Im folgenden möchte ich zeigen wie ein eigenes Datenfeld gestaltet und und implementiert wird. Das Ziel soll es sein dem Shopbetreiber die Möglichkeit zu geben beliebig viele Datenblätter zu einem Produkt hochzuladen.
1. Attribute anlegen
Zuerst müssen wir ein einfaches Attribute anlegen. Dazu wählen wir Catalog/ Attributes/ Manage Attributes. Ich gehe bei dem neuen Attribute davon aus das als Code “datenblatt” gewählt wurde. Der Einfachhalt halber verzichte ich darauf die Datenblätter in einer separaten Kreuztabelle zu speichern – stattdessen werden die Zuordnungen direkt in das Datenbankfeld geschrieben. Aus diesem Grund sollte der Typ des Attributes auf “TextArea” stehen. Zusätzlich muss das neue Attribute, damit es sichtbar ist, noch dem Default-Set zugeordnet werden.
2. Datenbank anpassen
Magento baut die Formulare teilweise anhand der Felder in der Datenbank zusammen. Es nutzt dafür ein sogenanntes EAV-Model. Dieses Model sorgt salopp gesagt dafür das wir fast beliebig viele neue Felder schaffen können ohne unser Datenbank-Layout zu verändern. Zudem haben wir die Möglichkeit anzugeben wie die Formularfelder erstellt und gespeichert werden. Hierzu gibt es den Frontend-Input-Renderer (Feldname: . Dieser kümmert sich vollständig um die Darstellung der Formularelemente. Das Gegenstück hierzu ist das Backend-Model (Feldname: ) welches sich um die Speicherung und Validierung der Eingaben kümmert.
Um nun unser Feld “datenblatt” optisch und funktional anzupassen gehen wir wie folgt vor:
Zuerst Datenbank z.B. im phpMyAdmin öffnen. Dann zur Tabelle eav_attribute wechseln und dort den Datensatz mit attribute_code = “datenblatt” heraussuchen und bearbeiten:
| backend_model: | test/product_backend_datenblatt |
| frontend_input_renderer: | Test_Test_Renderer_Datenblatt |
In diesem Fall weisen wir Magento an das Model Product/Backend/Datenblatt aus dem Modul Test zum Speichern unserer Daten zu verwenden. Im zweiten geben wir an das die Darstellung über die Class Test_Test_Renderer_Datenblatt erfolgt. Wichtig ist das, warum auch immer, das Backend-Model auf ein Model verweist – es muss also vor dem Slash das Modul stehen. Der Frontend-Input-Renderer dagegen erwartet direkt eine Class!
3. Frontend-Input-Renderer erstellen
Hierzu erstellen wir in app/code/local/Test/Test/Renderer die Datei Datenblatt.php mit folgendem Inhalt:
Datei: app/code/local/Test/Test/Renderer/Datenblatt.php
class Test_Test_Renderer_Datenblatt extends Varien_Data_Form_Element_File
{
/**
* Retrieve Element HTML fragment
*
* @return string
*/
public function getElementHtml()
{
$html = '';
// Value lesen und Zeilenweise trennen
$data = $this->getData('value');
$lines = explode("\n", $data);
$html .= '<table>';
$html .= '<col width="110" /> ';
$html .= '<col width="150" /> ';
$html .= '<col /> ';
$html .= ' <thead> <tr> <th>Datenblatt-Nr.</th> <th>Aktuelle Datei</th> <th>Neue Datei</th> </tr> </thead> ';
$html .= ' <tbody>';
$i = 0;
foreach( $lines AS $cur ) {
$i++;
// pro Zeile wird genau ein Datensatz getrennt mit einem Gleich-Zeichen erwartet
$tmp = explode('=', $cur);
if ( count($tmp) != 2 ) {
continue;
}
list($nr, $file) = $tmp;
$nr = trim($nr);
$file = trim($file);
// Eine leere Datenblatt-Nummer akzeptieren wir nicht
if ( $nr == '' ) {
continue;
}
// HTML-Table aufbauen
$html .= ' <tr>';
$html .= ' <td> <input type="text" name="'.$this->getName().'[nr]['.$i.']" style="width: 100px" value="'.$this->_escape( $nr ).'" /> </td> ';
$html .= ' <td> '.$file;
$html .= ' <input type="hidden" name="'.$this->getName().'[filename]['.$i.']" value="'.$this->_escape($file).'" />';
$html .= ' </td> ';
$html .= ' <td> <input type="file" name="datenblatt_file_'.$i.'" style="width: 100px" /> </td> ';
$html .= ' </tr>';
}
$html .= ' </tbody>';
$html .= ' <tr>';
$html .= ' <td> <input type="text" name="'.$this->getName().'[nr][new]" style="width: 100px" /> </td> ';
$html .= ' <td> Neues Datenblatt </td>';
$html .= ' <td> <input type="file" name="datenblatt_file_new" style="width: 100px" /> </td> ';
$html .= ' </tr>';
$html .= '</table>';
// und ein kleiner Hinweis wie man Datenblätter löschen kann
$html .= '<small>Entfernen Sie die Datenblatt-Nr. um das Datenblatt zu löschen.</small>';
return $html;
}
}
4. Backend-Model zum Speichern der Daten
Wie sich unschwer erkenne lässt können wir unsere Daten nun hübsch darstellen. Was fehlt ist der Teil unserer Anwendung der sich darum kümmert das die Daten in Datenbank bzw. Dateisystem abgelegt werden. Hier kommt das Backend-Model ins Spiel: Datei: app/code/local/Test/Test/Renderer/Datenblatt.php
<?php
class Test_Test_Model_Product_Backend_Datenblatt extends Mage_Eav_Model_Entity_Attribute_Backend_Abstract
{
public function beforeSave($object)
{
$path = Mage::getBaseDir('media') . DS . 'catalog' . DS . 'datenblatt';
$name = $this->getAttribute()->getName();
$inputs = $object->getData( $name );
if ( !is_array($inputs['nr']) ) {
return;
}
$res = array();
foreach( $inputs['nr'] AS $i => $nr ) {
if ( $nr == '' ) {
continue;
}
try {
$uploader = new Varien_File_Uploader( 'datenblatt_file_'.$i );
//$uploader->setAllowedExtensions(array('pdf'));
$uploader->setAllowRenameFiles(true);
$uploader->save($path);
$res[] = $nr.'='.$uploader->getUploadedFileName();
} catch (Exception $e) {
if( isset($inputs['filename'][$i]) ) {
$res[] = $nr.'='.$inputs['filename'][$i];
}
}
}
$object->setData($this->getAttribute()->getName(), join("\n", $res) );
return;
}
}
Fazit
In Magento ist es sehr einfach Produkte um weitere Standard-Eingabefelder zu erweitern. Sollen diese Eingaben jedoch besondere Eigenschaften bzw. Features aufweisen wird die Aufgabe ein wenig komplexer ist jedoch durchaus zu bewältigen. Der Aufwand lohnt sich in der Regel jedoch: das Pflegen von Produkten wird durch spezialisierte Eingaben deutlich einfacher und ist weniger fehleranfällig.




Hallo,
erstmal danke für das tolle Tutorial! Ich habe aber ledier Probleme beim Einbau!
2 Fragen:
1.app/local/Test/Test/Renderer
Bei mir gibt es unter apps nur einen Ordner der locale heißt aber nicht local ! Meisnt du diesen Ordner?
2. Den zweiten Code für das Backend Model, wo muss ich den einfügen bzw. wo muss ich Dateien und Ordner anlegen? Würde mic hsehr über Antwort von Dir freuen.
LG
cominaction
Hallo Philipp,
ich werde schauen das ich mir deine Frage morgen im Laufe des Tages ein wenig näher anschaue – heute ist es schon zu spät
Lg,
Tobi
alles klar kein Problem! Ach übrigens, du hattest mir auch einen Link zu dem Tut mit den Attributsets geschickt im Magento Forum! Danke, hatte ich schon selber gelöst siehe hier :
http://shop.isetsolar.eu/index.php/inverters/sma/sunny-boy-1200.html
Aber danke für deinen Link, mach weiter so, zwar bis jetzt nicht viele Beiträge aber dafür sehr gute! Wenn du magst, würde mich vllt auch an dem Füllen von Beiträgen hier beteiligen! Sag mal bescheid
Hallo Phillip,
zu Frage 1: Nein “local” ist richtig. In locale liegen Übersetzungen, in local dagegen eigene Erweiterungen von Magento. Der Pfad im Artikel ist jedoch falsch: Richtig ist app/code/local. Das habe ich soeben korrigiert.
Zusätzlich musst du noch eine config.xml für das Modul erstellen. Sonst ist das Modul nicht aktiviert bzw. der Namespace nicht aktiv. Wie das mit dem Modulen geht findest du z.B. dort: http://rackspeed.de/forum/magento-faq-extensions/modulerstellung-erstelle-modul-funktion-ueberschreiben-19
Zur Frage 2: Ich habe den Artikel um einen Pfad ergänzt. Du kannst in der Regel am Class-Namen den Pfad ableiten. Ein Unterstrich (_) stellt hier immer einen Ordnerwechsel dar. Ein Slash öffnet immer den Namespace eines Moduls.
schönen Gruß und vielen Dank fürs Lob
Tobi
P.S. Zur Artikel schreiben muss ich erst mit meinem Mitschreiber sprechen. Da haben wir uns noch keine echten Gedanken zu gemacht
Hallo,
ich bekomme es trotzdem nicht zum Laufen! Hast du eine Magento Installation wo ich mir das mal LIVE anschauen kann. Oder kannst du mir eine richtige step by step Anleitung geben! Ist für mich sehr Wichtig das ich das zum Laufen bekomme!
Grüße aus HH
Phil
Hallo Philipp,
leider gibt es im Moment keine Magento-Installation wo du dir das näher anschauen könntest. Das Beispiel läuft ähnlich wie hier auf einer Kundenseite
Eine Step-By-Step Anleitung ist eigentlich nicht im Rahmen des Blocks der mehr unter dem Motto “Hilfe-Zur-Selbsthilfe” steht. Ich studiere neben meinen Job noch, muss noch eine Facharbeit schreiben und ähnliches – da ist es mir im Moment leider nicht möglich mich hinzusetzen und eine deutliche Anleitung zu schreiben, sorry!
Ich hoffe du verstehst das!
Tobi