Hallo zusammen, ich hab auf Basis des Thread “Hinzufügen eines 2. Beschreibungstextes für Produkt” von jensfiedler sowie der Developer-Schulung vom vergangengen Montag nun erfolgreich weitere Attribute zum Artikel-Stamm hinzugefügt und sie sowohl im Frontend als auch im Backend erreichbar gemacht. Das Ergebnis möchte ich hier allen zur Verfügung stellen. Wer den Code übernehmen möchte, sollte darauf achten, das Präfix von “my” in etwas sinnvolles zu ändern. Im Anschluss habe ich noch eine Frage betreffend der Ausgabe im Backend. zunächst die [color=blue]bootstrap.php[/color]: [code]<?php class Shopware_Plugins_Backend_additionalArticleAttributes_Bootstrap extends Shopware_Components_Plugin_Bootstrap
{
public function getVersion()
{
return ‘1.0.0’;
}
public function getLabel()
{
return 'zusätzliche Artikel-Attribute';
}
public function getInfo()
{
return array(
'version' => $this-\>getVersion(), 'label' =\> $this-\>getLabel(), 'description' =\> ''); } public function getCapabilities() { return array( 'install' =\> true, 'enable' =\> true, 'update' =\> false ); } public function install() { /\* Model erweitern \*/ $this-\>addAttributes(); /\* Event-Listener für Frontend-Erweiterung: Artikel-Detailseite \*/ $this-\>subscribeEvent( 'Shopware\_Modules\_Articles\_GetArticleById\_FilterArticle', 'onArticle' ); /\* Event-Listener für Backend-Erweiterung \*/ $this-\>subscribeEvent( 'Enlight\_Controller\_Action\_PostDispatch\_Backend\_Article', 'postDispatchBackendArticle' ); return array('success' =\> true, 'invalidateCache' =\> array('backend', 'proxy')); } public function uninstall() { /\* Model-Erweiterungen wieder löschen \*/ $this-\>removeAttributes(); return true; } /\* Sub-Routinen für Install \*/ private function addAttributes() { $metaDataCache = Shopware()-\>Models()-\>getConfiguration()-\>getMetadataCacheImpl(); $metaDataCache-\>deleteAll(); Shopware()-\>Models()-\>addAttribute( 's\_articles\_attributes', 'my', 'Additional\_Attribute\_One', 'varchar(255)', true, null ); Shopware()-\>Models()-\>addAttribute( 's\_articles\_attributes', 'my', 'Additional\_Attribute\_Two', 'varchar(255)', true, null ); $metaDataCache = Shopware()-\>Models()-\>getConfiguration()-\>getMetadataCacheImpl(); $metaDataCache-\>deleteAll(); Shopware()-\>Models()-\>generateAttributeModels( array('s\_articles\_attributes') ); } /\* Sub-Routinen für Uninstall \*/ private function removeAttributes() { $metaDataCache = Shopware()-\>Models()-\>getConfiguration()-\>getMetadataCacheImpl(); $metaDataCache-\>deleteAll(); Shopware()-\>Models()-\>removeAttribute( 's\_articles\_attributes', 'my', 'Additional\_Attribute\_One' ); Shopware()-\>Models()-\>removeAttribute( 's\_articles\_attributes', 'my', 'Additional\_Attribute\_Two' ); $metaDataCache = Shopware()-\>Models()-\>getConfiguration()-\>getMetadataCacheImpl(); $metaDataCache-\>deleteAll(); Shopware()-\>Models()-\>generateAttributeModels( array('s\_articles\_attributes') ); } /\* Event-Listener Funktion(en) im Backend \*/ public function postDispatchBackendArticle(Enlight\_Event\_EventArgs $args) { $args-\>getSubject()-\>View()-\>addTemplateDir( $this-\>Path() . 'Views/' ); //if the controller action name equals "load" we have to load all application components. if ($args-\>getRequest()-\>getActionName() === 'load') { $args-\>getSubject()-\>View()-\>extendsTemplate( 'backend/additionalArticleAttributes/article/model/article.js' ); $args-\>getSubject()-\>View()-\>extendsTemplate( 'backend/additionalArticleAttributes/article/view/detail/base.js' ); } } /\* Event-Listener Funktion(en) im Frontend \*/ public function onArticle(Enlight\_Event\_EventArgs $args) { $sArticle = $args-\>getReturn(); $additionalAttributes = $this-\>getAdditionalArticleAttributes($sArticle["articleID"]); if($additionalAttributes) { foreach($additionalAttributes as $additionalAttributeName =\> $additionalAttributeValue) { $sArticle[$additionalAttributeName] = $additionalAttributeValue; } } return $sArticle; } /\* eigene Funktionen \*/ private function getAdditionalArticleAttributes($articleID) { /\* \* gibt ein assoziatives Array mit den Feldnamen und deren Inhalte \* der zusätzlichen Eigenschaften-Felder dieses Plugins zurück \*/ $dbResult = Shopware()-\>Db()-\>fetchAll( "SELECT at.my\_Additional\_Attribute\_One ,at.my\_Additional\_Attribute\_Two FROM s\_articles\_attributes at INNER JOIN s\_articles a ON a.id = at.articleID WHERE a.id = ?",array($articleID)); return $dbResult[0]; /\* fetchAll gibt folgendes zurück: \* array(2) { \* [my\_Additional\_Attribute\_One] =\> string(nnn) "(Wert)" \* [my\_Additional\_Attribute\_Two] =\> string(nnn) "(Wert)" \* } \*/ } /\* protected functions \*/ protected $manager = null; protected function getManager() { if ($this-\>manager === null) { $this-\>manager = Shopware()-\>Models(); } return $this-\>manager; } }[/code] Nun noch die Dateien zur Erweiterung von Model und View im Backend. Bitte die Ordner-Struktur gemäß [i]postDispatchBackendArticle[/i] in der bootstrap.php beachten: [color=blue][b]article.js[/b][/color] [code]//{block name="backend/article/model/attribute/fields" append} { name: 'myAdditionalAttributeOne', type: 'string' }, { name: 'myAdditionalAttributeTwo', type: 'string' }, //{/block}[/code] [color=blue][b]base.js[/b][/color] [code]//{block name="backend/article/view/detail/base" append} Ext.override(Shopware.apps.Article.view.detail.Base, { createRightElements: function() { var me = this, fields = me.callParent(arguments); fields.push({ xtype: 'textfield', name: 'attribute[myAdditionalAttributeOne]', translatable: false, allowBlank: true, fieldLabel: 'zusätzliches Attribut 1' }); fields.push({ xtype: 'textfield', name: 'attribute[myAdditionalAttributeTwo]', translatable: false, allowBlank: true, fieldLabel: 'zusätzliches Attribut 2' }); return fields; } }); //{/block}[/code] Der Aufruf im Frontend ist gemäß Event-Listener nun auf der Artikel-Detailseite möglich. Zum Testen einfach mal folgenden Code in das lokal angepasste Template aufnehmen: [code]
zusätzliches Attribut 1: {$sArticle.my_Additional_Attribute_One}
zusätzliches Attribut 2: {$sArticle.my_Additional_Attribute_Two}
[/code] Damit haben wir 2 neue Attribute, die man im Backend und Frontend sehen kann. Analog könnte man natürlich noch mehr machen. Und sicher könnte man die Aufrufe zum Anlegen, löschen und Platzieren im Backend noch verbessern, aber so fand ich es verständlicher. [color=red]Wichtiger Hinweis:[/color] Ich habe nicht umsonst in den Bezeichnern die Zahlen ausgeschrieben! Natürlich hatte ich erst Additional_Attribute_1 und Additional_Attribute_2 verwendet. Es gab zwar keine Fehlermeldung, im Backend wurden die Inhalte aber weder gespeichert noch angezeigt. (Frontend habe ich nicht mehr geprüft.) Der Bug-Tracker bekommt gleich noch Bescheid hierzu. [color=red]Ganz wichtiger Hinweis:[/color] Es gibt noch massive Probleme mit dem Import-/Export-Plugin! Die XML-Ausgabe gibt mir zwar die Felder aus (als myAdditionalAttributeOne und myAdditionalAttributeTwo), einen Import habe ich aber noch nicht erfolgreich durchgeführt. Viel schlimmer noch: Sobald das Model erweitert wurde, stürzt der CSV-Export ab! :shock: Fehlermeldung: SQLSTATE[42S22]: Column not found: 1054 Unknown column ‘at.myAdditionalAttributeOne’ in ‘field list’ in Zend/Db/Statement/Pdo.php on line 234 Auch dies wird noch an den Bug-Tracker gemeldet. [color=green]Nun zu meiner Frage:[/color] Ich habe ewig gebraucht, um die Felder in die Eingabemaske im Backend zu bekommen. (Vor allem deshalb, weil man nicht einfach vom Beispiel-Plugin “ExtendBackendExample5” der Developer-Schulung abschreiben kann: Dort reichten name und fieldLabel für die Erweiterung von fields.) Kann mir jemand erklären, wie ich die Felder im Backend unter die ab Werk vorhandenen “Zusatzfelder” bekomme? Gruß, Nico.