Programmierung & Softwareentwicklung für Modified-Shop*
*ehemaliger Projektname: xtcModified

Info zur Shoperweiterung TEXTFELD (FREITEXT) Modified-Shop:

Attributmerkmal TEXTFELD für XTC / Modified Shop* (Freitext Modul)

Version 1.00f - Anleitung geändert für includes/classes/shopping_cart.php
Version 1.00e - Fix in inc/xtc_get_uprid.inc.php - verhindert negative Werte
Version 1.00d - Anleitung geändert für includes/classes/shopping_cart.php
Version 1.00c - Fix in includes/classes/shopping_cart.php und checkout_process.php
Version 1.00b - Anleitung angepasst für checkout_confirmation.php von XTC-Standard und Modified 1.03
Version 1.00 - Erste Veröffentlichung
 
 
Erweiterungsmodul für das Shopsystem xt-Commerce / Modified

Das Textfeld-Modul ermöglicht die Eingabe individueller Texte und Daten zu einem Artikel. Es ist besonders geeignet für Shops, die individualisierte Artikel anbieten oder Ihren Kunden die Möglichkeit geben wollen, Daten zu einem Artikel mitzusenden (zum Beispiel Texte für den Druck auf T-Shirts, Aufklebern, Tassen).
 
Funktionsübersicht :  
 
beliebig viele Text-Eingabefelder pro Artikel möglich
Text wird als Artikeloption in den Bestellungen, im Admin und in den Mails aufgeführt
jeder Artikel ist mehrmals individuell bestellbar, die Artikel werden dabei einzeln in den Warenkorb gelegt
bei Login, Logout, Login bleiben die Textfelder im Warenkorb erhalten
Installationsservice für; Modified ab 1.06: Preis auf Anfrage
 
Erweitere Version inkl. Fileupload und Definition als Pflichtfeld: Preis auf Anfrage
ACHTUNG:
Die folgende Anleitung ist nicht für Modified-Shop 1.06 geeignet. Für Modified-Shop ab Version 1.06 empfehlen wir unseren preiswerten Einbauservice! In Modified 1.06 wurden diverse Sicherheitslücken geschlossen, die beim Einbau berücksichtigt werden.

Für das Bearbeiten der PHP Dateien sollte man unbedingt einen guten Texteditor verwenden, wie z.B Notepad++
 
Damit Textfelder in der Produktansicht richtig angezeigt und weiterverarbeitet werden, sind einige Vorüberlegungen nötig.
Den Artikelmerkmale (Optionen) sowie den einzelnen Optionswerten werden in der Datenbank eindeutige IDs zugewiesen. Diese IDs werden bei XTC / Modified für den Warenkorb und den Bestellablauf verwendet.
 
Artikelmerkmale: products_options_id (Tabelle products_options)

Optionswerte: products_options_values_id (Tabelle products_options_values)

Damit überhaupt ein Textfeld in der Produktansicht angezeigt wird muss die Templatedatei entsprechend angepasst warden: (Bsp. für Optionsfelder)

 
Originalcode:
<input type="radio" name="id[{$options_data.ID}]" value="{$item_data.ID}"
 
Anhand von $options_data.ID (Artikelmerkmal) und $item_data.ID (Optionswert) werden im XTC , Modified System alle Anzeigen und Berechnungen durchgeführt. Dieses Input Feld ändern wir für unser Textfeld einfach von type=“radio“ auf type=“hidden“ (versteckt).
 
<input type=" hidden" name="id[{$options_data.ID}]" value="{$item_data.ID}"
 
Dann benötigen wir natürlich noch ein zusätzliches Textfeld für die Texteingabe. Zur eindeutigen Kennzeichnung bekommt das Feld als Namen die $item_data.ID zugewiesen, allerdings noch mit dem Prefix txt_, also
 
<input type="text" name="txt_{$item_data.ID}" value=""/>
 
Zur richtigen Anzeige benötigen wir noch eine IF-Abfrage, damit man die normalen Artikelmerkmale von den Textfeldern unterscheiden kann. Hierfür gilt die Vereinbarung, das alle Textfelder nur EINEN Optionswert mit der Bezeichnung TEXTFELD erhalten.

Damit kann dann folgende einfache IF-Abfrage erstellt werden ( rot ):

templates/.../module/product_options/product_options_selection.html

Schwarzen und roten Code hinzufügen: ( Originalcode blau damit ergänzen!)
{if $options!=''} <table width="100%" border="0" cellspacing="0" cellpadding="0">
{foreach name=outer item=options_data from=$options}
< tr>
< td valign="top" class="main" width="1%"><b>{$options_data.NAME}:</b>&nbsp;</td>
< td class="main" width="99%">
{foreach key=key_data name=key_data item=item_data from=$options_data.DATA}

{if $item_data.TEXT =='TEXTFELD'}
<input type="hidden" name="id[{$options_data.ID}]" value="{$item_data.ID}"/>&nbsp;<input type="text" name="txt_{$item_data.ID}" value=""/>
{else}
<input type="radio" name="id[{$options_data.ID}]" value="{$item_data.ID}" {if $smarty.foreach.key_data.first}checked="checked" {/if} />
{$item_data.TEXT} {if $item_data.PRICE!=''}( {$item_data.PREFIX}{$item_data.PRICE} ){/if}
< br />

{/if}
{/foreach}
< /td>
< /tr>
{/foreach}
< /table>
{/if}
 

Jetzt legen wir im Admin ein neues Artikelmerkmal an, der Optionsname ist beliebig, als Beispiel nehmen wir den Begriff Beschreibung. Anschließend definieren wir für diesen Optionsnamen genau einen Options wert.

Dieser muss für ein Textfeld lauten - (alles in Großbuchstaben):

TEXTFELD

Wir können beliebig vielen Optionsnamen den Optionswert TEXTFELD zuweisen!
Diese Optionsnamen können beliebig vielen Artikeln zugewiesen werden! Diesen Artikeln müssen wir natürlich unsere angepasste Templatedatei zuordnen!

 
Die Textfelder werden jetzt auf der Produktseite angezeigt. Jetzt kümmern wir uns um die Übergabe der Texte an den Warenkorb.
 
 
Zur Übergabe in den Warenkorb wird zuerst die Datei includes/cart_actions.php benutzt, genauer der case Block “add_products“.
Nach Überprüfung der Stückzahl und der Zuweisung einer eindeutigen CartProduktID für den Warenkorb werden die Produktdaten in die Session “cart“ übergeben. Diese Sessiondaten werden im gesamten Bestellablauf für die Bearbeitung und Anzeige der Bestellung herangezogen. Da wir an dieser Methode nichts ändern wollen, müssen wir uns also darum kümmern, die Texte der Textfelder auszulesen und ebenfalls per Session diese Daten für den Bestellablauf bereit zu halten.
 
includes/cart_actions.php
Suchen nach:
$_SESSION['cart']->add_cart((int) $_POST['products_id'] ... ;
In die nächste Zeile einfügen
//BOF TEXTFELD
$params = $_POST['id'];
if (is_array($params) && (sizeof($params) > 0)) {
reset($params);
while (list($option, $value) = each($params)) {
if (xtc_oe_get_options_values_name($value,'') == 'TEXTFELD') {
$textfeld[$value] = $_POST['txt_'.$value];
}
}
$_SESSION['cart_textfeld'. $_SESSION['new_products_id_in_cart']] = $textfeld;
unset($textfeld);
}
//EOF TEXTFELD
 
Mit dieser Funktion werden alle per $_POST[’id’] übermittelten Daten auf den Wert TEXTFELD geprüft und bei Übereinstimmung wird der Wert von $_POST[’txt_’ . $value] in das Array $textfeld geschrieben.
Anschließend wird für das Produkt anhand der ProduktID ($_SESSION[’new_products_id_in_cart’] eine neue Sessionvariable angelgt und mit dem $textfeld-Werten gefüllt. Diese Methode erleichtert im weiteren Verlauf den Zugriff auf die benötigten Daten.
 
Für den Zugriff auf die Funktion xtc_oe_get_options_values_name benötigen wir noch ein require once am Dateianfang.
 
Suchen nach:
// Shopping cart actions
Danach einfügen
//BOF TEXTFELD
require_once (DIR_FS_INC.'xtc_oe_get_options_values_name.inc.php');
//EOF TEXTFELD
 
In der gleichen Datei kümmern wir uns jetzt noch um den case-Block “update_product“, genauer wenn ein Produkt aus dem Warenkorb entfernt wird, dann sollten wir natürlich auch die entsprechnde Sessionvariable löschen:
 
Suchen nach:
$_SESSION['cart']->remove($_POST['products_id'][$i]);
Danach einfügen
//EOF TEXTFELD
unset($_SESSION['cart_textfeld'.$_POST['products_id'][$i]]);
//BOF TEXTFELD
 
Wie schon erwähnt, bekommt jedes Produkt für den Warenkorb eine eindeutige CartProduktID zugewiesen. Diese setzt sich aus der ProduktID und den IDs der Artikelmerkmale und des ausgewählten Optionswertes zusammen. Damit ist dann gewährleistet, das bei der Bestellungen von einem Produkt mit z.B. unterschiedlichen Farben, diese Produkte jeweils einzeln in den Warenkorb gelegt werden. Damit das auch mit den Textfeldern funktioniert, müssen wir die dafür zuständige Funktion anpassen.
 
inc/xtc_get_uprid.inc.php
Suchen nach:
while (list($option, $value) = each($params)) {
Danach einfügen
//BOF TEXTFELD
if (xtc_oe_get_options_values_name($value,'') == 'TEXTFELD') {
$value = abs( crc32($_POST['txt_'.$value]) ) ; //FIX v.1.00e
}
//EOF TEXTFELD
 
Hier prüfen wir erneut auf den Optionswertbezeichnung TEXTFELD und bei Übereinstimmung weisen wir der OptionswertID die Prüfsumme(crc32) des Textfeldinhalts zu. Durch dieser Trick wandeln wir den eingegebenen Text in einen eindeutigen Zahlenwert um.
Wenn zum Beispiel eine Tasse mit dem Namensaufdruck Klaus bestellt wird und die gleiche Tasse mit dem Aufdruck Gaby, werden dadurch 2 Produkte in den Warenkorb gelegt, eine Tasse mit Klaus und eine Tasse mit Gaby. Wenn die gleiche Tasse nochmals mit Gaby bestellt wird, ist diese Tasse mit Stückzahl 2 im Warenkorb enthalten.
 
Damit das ganze auch überhaupt im Warenkorb angezeigt wird bearbeiten wir die Datei
includes/modules/order_details_cart.php
Suchen nach:
if (ATTRIBUTE_STOCK_CHECK == 'true' && STOCK_CHECK == 'true') {
$attribute_stock_check = xtc_check_stock_attributes($products[$i][$option]['products_attributes_id'], $products[$i]['quantity']);
if ($attribute_stock_check)
$_SESSION['any_out_of_stock'] = 1;
}
Danach einfügen/ändern ( Originalcode blau damit ergänzen bzw. ändern ! )
//BOF TEXTFELD
$options_values = trim($products[$i][$option]['products_options_values_name'].$attribute_stock_check);

if($products[$i][$option]['products_options_values_name'] == 'TEXTFELD'){
$options_values = trim($_SESSION['cart_textfeld'. $products[$i]['id']][$value]);
}
if ($options_values != '') {
$module_content[$i]['ATTRIBUTES'][] = array ('ID' => $products[$i][$option]['products_attributes_id'], 'MODEL' => xtc_get_attributes_model(xtc_get_prid($products[$i]['id']), $products[$i][$option]['products_options_values_name'], $products[$i][$option]['products_options_name']), 'NAME' => $products[$i][$option]['products_options_name'], 'VALUE_NAME' => $options_values );
}
//EOF TEXTFELD
 
Hier werden jetzt nach einer TEXTFELD if-Abfrage die zugehörigen Werte aus der Sessionvariable in das Ausgabe-Array $module_content geschrieben.
 
Mit dem Warenkorb sind wir jetzt fertig, wir können Artikel mit den Textfeldern einfügen, ändern oder löschen.
 
 
Jetzt folgen nur noch die Änderungen für den Bestellablauf. Zuerst geht es an die Datei
 
checkout_confirmation.php
ACHTUNG:
Diese Anleitung gilt nur für checkout_confirmation.php mit Tabellenlayout (Original XTC und Modified 1.03) und gilt deshalb nicht für die checkout_confirmation.php mit <div>-Layout von Modified 1.01 und 1.02!
Suchen nach:
for ($j = 0, $n2 = sizeof($order->products[$i]['attributes']); $j < $n2; $j++) {
Danach einfügen/ändern ( Originalcode blau damit ergänzen bzw. ändern ! )
(Roter Code nur vorhanden ab Modified 1.03)
//BOF TEXTFELD
$attributes_value = trim($order->products[$i]['attributes'][$j]['value']);

if($order->products[$i]['attributes'][$j]['value'] == 'TEXTFELD'){
$value = $order->products[$i]['attributes'][$j]['value_id'];
$attributes_value = trim($_SESSION['cart_textfeld'. $order->products[$i]['id']][$value]);
}
if ($attributes_value != '') {
$data_products .= '<tr>
<td class="main" align="left" valign="top">&nbsp;</td>
<td class="main" align="left" valign="top">
<nobr><small>&nbsp;<i> - ' . $order->products[$i]['attributes'][$j]['option'] . ': '
. $attributes_value .'
</i></small><nobr></td>
<td class="main" align="right" valign="top">&nbsp;</td>
<td class="main" align="right" valign="top">&nbsp;</td></tr>';

}
//EOF TEXTFELD
 
Mit der If-Abfrage für TEXTFELD wird entwender der Textfeldinhalt oder die Optionswertbezeichnung der neuen Variablen $attributes_value zugewiesen.

Jetzt fehlt nur noch eine Anpassung in der Datei checkout_process.php. In dieser Datei wird die Bestellung in der Datenbank abgepeichert.

 
checkout_process.php
Suchen nach:
$attributes_values = xtc_db_fetch_array($attributes);
Danach einfügen/ändern: (Originalcode blau damit ergänzen bzw. ändern!)
//BOF TEXTFELD
$options_values = trim($attributes_values['products_options_values_name']);
if($attributes_values['products_options_values_name'] == 'TEXTFELD'){
$value = $order->products[$i]['attributes'][$j]['value_id'];
$options_values = trim($_SESSION['cart_textfeld'. $order->products[$i]['id']][$value]);
unset ($_SESSION['cart_textfeld'. $order->products[$i]['id']][$value]); //Fix v.1.00c
}
if ($options_values != '') {
$sql_data_array = array ('orders_id' => $insert_id, 'orders_products_id' => $order_products_id, 'products_options' => $attributes_values['products_options_name'], 'products_options_values' => $options_values, 'options_values_price' => $attributes_values['options_values_price'], 'price_prefix' => $attributes_values['price_prefix']);
xtc_db_perform(TABLE_ORDERS_PRODUCTS_ATTRIBUTES, $sql_data_array);

}
//EOF TEXTFELD
 
Fertig!
Es können jetzt beliebige Textfelder eingefügt werden und die Inhalte dieser Felder sind im gesamten Bestellablauf und im Admin einschließlich der Emails sichtbar!
 
Bestellbestätigung
 
Email
 
Was passiert wenn sich ein Kunde einloggt, Artikel in den Warenkorb legt, sich wieder ausloggt und sich später wieder einloggt? Die Textfelder mit ihren Einträgen sind verschwunden. Das ist natürlich äußerst unschön und deshalb müssen wir noch einige Anpassungen vornehmen.
Dazu müssen wir als erstes eine Anpassung in der Datenbank vornehmen, und zwar in der Tabelle

customers_basket_attributes

Hier benötigen wir ein Feld für die Texte der Textfelder und fügen es deshalb hinzu:

products_options_value_text

Als Typ definieren wir varchar(64), das sollte für die meisten ausreichend sein.

 
Update SQL:
ALTER TABLE `customers_basket_attributes` ADD `products_options_value_text` VARCHAR( 64 ) NOT NULL ;
 
Jetzt kümmern wir uns um das Speichern und Auslesen der Texte bei Login/Logout:
 
includes/classes/shopping_cart.php
Suchen nach - in der Funktion restore_contents(): (Anleitung geändert 1.00f)
while (list ($option, $value) = each($this->contents[$products_id]['attributes'])) {
xtc_db_query("insert into ".TABLE_CUSTOMERS_BASKET_ATTRIBUTES." (customers_id, products_id, products_options_id, products_options_value_id) values ('".$_SESSION['customer_id']."', '".$products_id."', '".$option."', '".$value."')");
Ändern in: (Originalcode blau damit ergänzen bzw. ändern!)
while (list ($option, $value) = each($this->contents[$products_id]['attributes'])) {
//BOF TEXTFELD
if (xtc_oe_get_options_values_name($value,'') == 'TEXTFELD') {
$textfeld = trim($_SESSION['cart_textfeld'. $products_id][$value]);
} else $textfeld = '';
xtc_db_query("insert into ".TABLE_CUSTOMERS_BASKET_ATTRIBUTES. " (customers_id,
products_id, products_options_id, products_options_value_id, products_options_value_text) values ('".$_SESSION['customer_id']."', '".$products_id."', '".$option."', '".$value."'
, '".$textfeld."')");
//EOF TEXTFELD
 
Suchen nach - ebenfalls in der Funktion restore_contents():
$this->contents[$products['products_id']] = array ('qty' => $products['customers_basket_quantity']);
// attributes
Danach einfügen/ändern:
//BOF TEXTFELD - Restore $_SESSION['cart_textfeld'
$attributes_query = xtc_db_query("select products_options_id, products_options_value_id, products_options_value_text from ".TABLE_CUSTOMERS_BASKET_ATTRIBUTES.
" where customers_id = '".$_SESSION['customer_id']."' and products_id = '". $products['products_id']."'");
$textfeld= array(); //Fix v.1.00c
while ($attributes = xtc_db_fetch_array($attributes_query)) {
$this->contents[$products['products_id']]['attributes']
[$attributes['products_options_id']] = $attributes['products_options_value_id'];
$value_text = trim($attributes['products_options_value_text']);
if ($value_text != '') $textfeld[$attributes['products_options_value_id']] = $value_text;
}
unset($_SESSION['cart_textfeld'. $products['products_id']]); //Fix v.1.00c
$_SESSION['cart_textfeld'. $products['products_id']] = $textfeld;
unset($textfeld);
//EOF TEXTFELD
 
Suchen nach - in der Funktion add_cart() (Anleitung geändert 1.00d):
if (isset ($_SESSION['customer_id']))
xtc_db_query("insert into ".TABLE_CUSTOMERS_BASKET_ATTRIBUTES." (customers_id, products_id, products_options_id, products_options_value_id) values ('".$_SESSION['customer_id']."', '".$products_id."', '".$option."', '".$value."')"); 
Ändern in: (Originalcode blau damit ergänzen bzw. ändern!)
if (isset ($_SESSION['customer_id'])) {
//BOF TEXTFELD
if (xtc_oe_get_options_values_name($value,'') == 'TEXTFELD') {
$textfeld = $_POST['txt_'.$value];
} else $textfeld = '';
xtc_db_query("insert into ".TABLE_CUSTOMERS_BASKET_ATTRIBUTES." (customers_id, products_id, products_options_id, products_options_value_id, products_options_value_text) values ('".$_SESSION['customer_id']."', '".$products_id."', '".$option."', '".$value."', '".$textfeld."')");
//EOF TEXTFELD
}
 
 

Fragen und Anregungen bitte hier posten:

http://www.xtc-modified.org/forum/topic.php?id=1830