Hallo. Ich hatte bisher eigene Felder für die Artikel im Adminbereich angelegt. Diese wurden über die admin/includes/classes/categories.php mit der Funktion Code: insert_product($products_data, $dest_category_id, $action = 'insert') ab ca. Zeile 913 gespeichert. Nun musste ich feststellen daß in der Version 2.7.x dies nicht mehr funktioniert. Diese Funktion ist scheinbar unwirksam. Kann mir jemand sagen wo sich diese Funktion jetzt befindet? Danke und Gruß
push... Ich habe in der neuen Beta gesehen daß es neue overloads/_samples gibt. Hier gibt es jetzt auch "ProductWriteService". Kann mir jemand auf die Sprünge helfen wie ich hier neue Artikelfelder integriere? Danke und Gruß
Hallo Javier, wo speicherst du aktuell die Daten in der Datenbank? Also in welcher Tabelle/Spalte? Davon ausgehend können wir dir weiterhelfen.
Hallo. Ich habe die Tabelle PRODUCTS um das Feld products_region (und einige mehr) erweitert. Die würde ich gerne speichern wie früher mit Hilfe der admin/includes/classes/categories.php (siehe oben) Gruß
Das Klingt nach den Extrafeldern, für die Cyrus für die Version 2.1 - 2.6 Anleitungen geschrieben hat. Die Anleitung für 2.6 geht auch in der 2.7 noch. Schau bitte mal, ob es das ist: (Link nur für registrierte Nutzer sichtbar.) Die dazugehörenden Overloads findest du hier: (Link nur für registrierte Nutzer sichtbar.)
Das kann man mittlerweile elegant mit dem ProductService über AddOn-Values lösen. Heute Abend bekomme ich das nicht mehr erklärt. Wir haben in den letzten 2 Wochen auch einiges an Dokumentation geschrieben. Die Inhalte werden gerade aufbereitet, damit sie in Kürze auf http://developers.gambio.de online gestellt werden. Ich versuche morgen ins Detail zu gehen.
Danke für den Hinweis Barbara... Für die Versionen bis 2.6 gilt das alles noch. Bis dahin ging das Speichern der Zusatzfelder tadellos (siehe oben). Ab 2.7 kann ich nur über die Veränderungen der Dateien im GXEngine und der admin/includes/modules/set_product_data.inc.php speichern. Das ist aber nicht Sinn der Sache. Ich warte mal auf die Doku von Moritz...
Hallo, ich habe heute viel um die Ohren, so dass ich es voraussichtlich nicht mehr heute mit einer Antwort schaffe. Ich habe es aber nicht vergessen!
Hallo, mit etwas Verspätung hier nun das versprochene Tutorial. Ich habe mich für das Speichern eines Einkaufpreises entschieden. Als Erstes benötigen wir also ein Eingabefeld auf der "Artikel bearbeiten"-Seite. Das funktioniert über den AdminEditProduct-Extender. Dazu wird ein Overload der AdminEditProductExtenderComponent-Klasse angelegt (user_classes/overloads/AdminEditProductExtenderComponent/EkpFormExtender.inc.php) PHP: /** * Class EkpFormExtender * * Adds a form for a EKP value to the edit product page * * @see AdminEditProductExtenderComponent */class EkpFormExtender extends EkpFormExtender_parent{ /** * Overloaded "proceed" method. */ public function proceed() { parent::proceed(); $ekp = 0; if(isset($this->v_data_array['GET']['pID'])) { $productId = (int)$this->v_data_array['GET']['pID']; /** @var ProductReadService $productReadService */ $productReadService = StaticGXCoreLoader::getService('ProductRead'); /** @var StoredProduct $product */ $product = $productReadService->getProductById(new IdType($productId)); try { $ekp = $product->getAddonValue(new StringType('ekp')); } catch(InvalidArgumentException $e) { // product has no EKP yet } } $html = '<div class="grid control-group span6 remove-border"> <div class="span6"> <label>EKP</label> </div> <div class="span6"> <input name="ekp" type="text" value="' . $ekp . '" /> </div> </div>'; $this->v_output_buffer['top']['ekp'] = array('title' => 'EKP', 'content' => $html); }} Das wars auch schon für die Anzeige des EKP-Felds mit dem aktuellen Wert. Jetzt kümmern wir uns um das Speichern. Dazu nutzen wir den AdminCategories-Extender, der für das Verändern von Kategorie- und Artikeldaten der passende Einstiegspunkt ist. Dazu wird ein Overload der AdminCategoriesExtenderComponent-Klasse angelegt (user_classes/overloads/AdminCategoriesExtenderComponent/StoreEkpExtender.inc.php): PHP: /** * Class StoreEkpExtender * * Store product's EKP * * @see AdminCategoriesExtenderComponent */class StoreEkpExtender extends StoreEkpExtender_parent{ /** * Overloaded "proceed" method. */ public function proceed() { parent::proceed(); if(isset($this->v_data_array['GET']['action']) && $this->v_data_array['GET']['action'] === 'update_product') { $productId = (int)$this->v_data_array['GET']['pID']; /** @var ProductReadService $productReadService */ $productReadService = StaticGXCoreLoader::getService('ProductRead'); /** @var StoredProduct $product */ $product = $productReadService->getProductById(new IdType($productId)); $addonValues = $product->getAddonValues()->getArray(); $addonValues['ekp'] = (double)$this->v_data_array['POST']['ekp']; $addonValueCollection = MainFactory::create('KeyValueCollection', $addonValues); $product->addAddonValues($addonValueCollection); /** @var ProductWriteService $productWriteService */ $productWriteService = StaticGXCoreLoader::getService('ProductWrite'); $productWriteService->updateProduct($product); } }} Das wars auch schon! Der EKP wird als AddonValue gespeichert und benötigt daher keine Anpassungen in der Datenbank. Optional: Angenommen wir möchten aber in eine neue Spalte in der Tabelle products speichern. Nennen wir sie "einkaufspreis". So sagen wir dem Product-Service, dass er den AddonValue "ekp" in der Spalte "einkaufspreis" speichern soll: Wir benötigen einen Overload der Klasse ProductAddonValueStorage (user_classes/overloads/ProductAddonValueStorage/AddEkpField.inc.php) PHP: /** * Class AddEkpField * * @category System * @package Product * @subpackage Storages * * @see ProductAddonValueStorage */class AddEkpField extends AddEkpField_parent{ /** * Maps ekp addon value to einkaufspreis field in products table * * @return array */ protected function _getExternalFieldsArray() { $externalFields = parent::_getExternalFieldsArray(); $externalFields['products']['fields']['einkaufspreis'] = 'ekp'; return $externalFields; }} Bei dieser Variante ist der Wert aber nicht mehr über den Product-Service auslesbar. Entsprechend müsste man sich beim Auslesen für die Artikelbearbeitung selbst darum kümmern: PHP: $db = StaticGXCoreLoader::getDatabaseQueryBuilder();$ekp = (double)$db->select('einkaufspreis')->from('products')->where('products_id', $productId)->get()->row()->einkaufspreis; In der Shopversion 2.7.1 und 2.7.2 gibt es leider einen blöden Bug der verursacht, dass das Speichern nur über den Button "Speichern" jedoch nicht "Aktualisieren" funktioniert. Um das zu beheben muss in der Datei admin/categories.php für die action-Fälle "update_product" und "insert_product" am Ende das xtc_redirect ersetzt werden durch eine Wertzuweisung der Url in die Variable $redirectUrl. Das ist in ca. Zeile 269 und Folgende zu finden. Der Fix wird im nächsten SP enthalten sein. Seit heute Abend gibt es übrigens eine Menge neuer Dokumentation auf http://developers.gambio.de. Schaut euch das am besten mal an . Passende Themen: Class-Overloading, Extender-System, Liste aller Extender
Danke Moritz. Funktioniert auf Anhieb. Da ich die Felder bereits vorher schon in der Tabelle products hatte habe ich mich für Deine optionale Lösung entschieden und alle drei Dateien verwendet. Sehe ich das richtig daß in diesem Falle die Tabelle addon_values_storage nur temporär verwendet wird? Gruß
Stimmt. Die ist leer... Kann ich dann die (user_classes/overloads/AdminCategoriesExtenderComponent/StoreEkpExtender.inc.php) weglassen oder brauche ich die trotzem? Dann hätte ich noch eine Frage: In der (user_classes/overloads/AdminEditProductExtenderComponent/EkpFormExtender.inc.php) steht u.a.: <input name="ekp" type="text" value="' . $ekp . '" /> Wie kann ich hier eine Checkbox realisieren wenn der Feldinhalt nur 1 oder null ist? Gruß Edit: Habs gefunden: Man braucht die php innerhalb des html-Containers nur in Anführungszeichen zu setzen... ' . xtc_draw_radio_field('ekp', '1', ($ekp ? True : False)) . '
Hallo Moritz, bin jetzt gerade dabei und habe eine frage: der Ordner "ProductAddonValueStorage" mit der Datei "AddEkpField.inc.php" muss nur in den Ordner user_classes und nicht in user_classes/ overloads?
Hallo. Danke dafür... Geht das analog auch für die Kategorien? Kann man diese AddonValue auch für die Kategorien verwenden? Ich denke das müsste dann die AdminEditCategoryExtenderComponent sein. Gruß Mike
Rein aus Neugierde : Was für Zusatzfelder willst Du in der Kategorie? Bei mir funkt das irgendwie nicht , Da habe ich wohl nicht einen Fehler irgendwo... Die Extrafelder werden zwar angezeigt, aber ich bekomme weder den Inhalt aus der Datenbank zu sehen, noch wird etwas in der DB gespeichert. Mal sehen welchen "." ich übersehen habe.
Hallo Barbara. Ich möchte eine zweite Kategoriegruppe (section) erstellen bzw habe diese schon erstellt. Das stammt aus den alten xtc/modified Zeiten für eine zweite Kategoriebox, deren Kategorien unabhängig voneinander sind. Dazu gibt es ein neues Feld in der Tabelle categories. Die Anzeige im Frontend habe ich bereits vorher gelöst. Nur die "Deaktivierung" der /admin/includes/classes/categories.php in den neuen Versionen macht mir Kopfschmerzen. Da war alles noch einfacher... Die Lösung von Moritz für ein Artikelfeld habe ich 1zu1 eingebaut, funktioniert auf Anhieb. Analog dazu sind jetzt vermutlich die AdminEditCategoryExtenderComponent und CategoryAddonValueStorage zuständig. Ich komme nicht weiter mit dem Befehl für die Kategorien analog zu if(isset($this->v_data_array['GET']['pID'])) { $productId = (int)$this->v_data_array['GET']['pID']; Wie ist denn der Aufruf für das Öffnen der Kategorie? Gruß Mike (wie kann ich hier ein Code-Fenster einfügen???) EDIT: Habs gefunden: if(isset($this->v_data_array['GET']['id']))
Für das Schreiben des Werts in der Kategorie wird wieder ein Overload der Klasse AdminCategoriesExtenderComponent benötigt. Der Code darin sieht beispielsweise so aus (Zusatzfeld ist eine Url): PHP: class StoreUrlExtender extends StoreUrlExtender_parent{ /** * Overloaded "proceed" method. */ public function proceed() { parent::proceed(); if(isset($this->v_data_array['GET']['action']) && $this->v_data_array['GET']['action'] === 'update_category') { $categoryId = (int)$this->v_data_array['GET']['cID']; /** @var CategoryReadService $categoryReadService */ $categoryReadService = StaticGXCoreLoader::getService('CategoryRead'); /** @var StoredCategory $category */ $category = $categoryReadService->getCategoryById(new IdType($categoryId)); $addonValues = $category->getAddonValues()->getArray(); $addonValues['url'] = $this->v_data_array['POST']['url']; $addonValueCollection = MainFactory::create('KeyValueCollection', $addonValues); $category->addAddonValues($addonValueCollection); /** @var CategoryWriteService $categoryWriteService */ $categoryWriteService = StaticGXCoreLoader::getService('CategoryWrite'); $categoryWriteService->updateCategory($category); } }} Für die Ausgabe ist ein Overload der Klasse AdminEditCategoryExtenderComponent notwendig. Das passende Beispiel dazu: PHP: class AddUrlFormExtender extends AddUrlFormExtender_parent{ /** * Overloaded "proceed" method. */ public function proceed() { parent::proceed(); $url = ''; if(isset($this->v_data_array['GET']['cID'])) { $categoryId = (int)$this->v_data_array['GET']['cID']; /** @var CategoryReadService $categoryReadService */ $categoryReadService = StaticGXCoreLoader::getService('CategoryRead'); /** @var StoredCategory $category */ $category = $categoryReadService->getCategoryById(new IdType($categoryId)); try { $url = $category->getAddonValue(new StringType('url')); } catch(InvalidArgumentException $e) { // category has no URL yet } } $html = '<div class="grid control-group span6 remove-border"> <div class="span6"> <label>URL</label> </div> <div class="span6"> <input name="url" type="text" value="' . $url . '" /> </div> </div>'; $this->v_output_buffer['left']['sample'] = array('title' => 'Url', 'content' => $html); }} Soll wieder außerhalb der addon_values_storage-Tabelle gespeichert werden, ist ein Overload der Klasse CategoryAddonValueStorage notwendig. Die Vorgehensweise ist beim Produkt abzuschauen. Im Anhang ein Bild, wie man im Forum Code einfügen kann.
Danke Moritz, So ähnlich hab ich mir das heute Nacht selbst zusammen gepfrimelt. Allerdings geht der CategoryAddonValueStorage nur so: PHP: protected function _getExternalFieldsArray() { $externalFields = parent::_getExternalFieldsArray(); $externalFields = array(); $externalFields['categories']['primary_key'] = 'categories_id'; $externalFields['categories']['fields'] = array('section' => 'section'); return $externalFields; } Wenn ich es analog zum Product mache kommt "sql error" Super Support.... Gruß Mike