shop-old/core/item.class.php
Thomas Bartelt 0a669704ea Dev-Umgebung: Kompatibilität für PHP 8.3 + Smarty 4.5.6
- Smarty 4.1.1 → 4.5.6 (behebt dynamic property deprecations)
- Core-Klassen: #[\AllowDynamicProperties] für Admin_role, base, Config,
  Customer, Customer_group, CustomerGroups, Item, Structure, website
- website.class.php: counts[parent_id] initialisieren vor ++ (PHP 8.1)
- layout.class.php: HTTP_ACCEPT_LANGUAGE mit isset-Guard
- website_init.php: session_status()-Check vor session_start
- .htaccess: HTTPS-Redirect via X-Forwarded-Proto (statt SERVER_PORT)
- themes/easyshop_advanced/media/: Parent-Theme-Assets nachgezogen
- .gitignore: smarty.4.1.1.bak ausschließen
2026-04-20 01:19:01 +02:00

5885 lines
190 KiB
PHP

<?php
/*
* @version $Id: index.php 10381 2008-06-01 03:35:53Z $
* @package Carteasy
* @copyright Copyright (C) 2005 - 2011 Wlanium
* @license proprietary
* @author Thomas Bartelt
* Carteasy is a web shop system
*/
include_once './core/main.class.php';
include_once './core/tax.class.php';
include_once './libs/phImaginator/phImaginator.class.php';
include_once './core/manufacturer.class.php';
include_once './core/database.class.php';
include_once './core/tax.class.php';
include_once './core/money.class.php';
include_once './core/customer_group.class.php';
include_once './core/itemschema.class.php';
include_once './core/structure.class.php';
#[\AllowDynamicProperties]
class Item extends Main {
public $list_table_config = array(
'title' => 'Artikel',
'db_table' => 'items',
'list_fields' => array(
array(
'db_field' => 'number',
'name' => 'Art-Nr.',
'sortable' => 1
),
array(
'db_field' => 'name',
'name' => 'Bezeichnung',
'sortable' => 1
),
array(
'db_field' => 'file_name',
'ref_db_table' => 'item_files',
'ref_db1_field' => 'id',
'ref_db2_field' => 'item_id',
'name' => 'Bild',
'function' => 'count',
'sortable' => 0
),
array(
'db_field' => 'manufacturer_id',
'name' => 'Hersteller',
'rewrite_function' => 'manufacturer_names',
'sortable' => 1
),
array(
'db_field' => 'inventory',
'name' => 'Lager',
'sortable' => 1
),
array(
'db_field' => 'price_1',
'ref_db_table' => 'item_prices',
'ref_db1_field' => 'id',
'ref_db2_field' => 'item_id',
'name' => 'Preis (netto)',
'format' => 'netto_price',
'sortable' => 1
),
array(
'db_field' => 'steuersatz / 100 * item_prices.price_1 + item_prices.price_1 AS price_brutto',
'db_field_rename' => 'price_brutto',
'ref_db_table' => 'tax',
'ref_db1_field' => 'tax_id',
'ref_db2_field' => 'id',
'name' => 'Preis (brutto)',
'format' => 'netto_price',
'sortable' => 0
),
array(
'db_field' => 'structure_id',
'name' => 'Hauptwarengruppe',
'rewrite_function' => 'structure_values',
'sortable' => 1
),
array(
'db_field' => 'item_type_id',
'ref_db_table' => 'item_types',
'ref_db1_field' => 'id',
'ref_db2_field' => 'item_id',
'name' => 'Typzuordnung',
'function' => 'count',
'sortable' => 0
),
array(
'db_field' => 'active',
'name' => 'Status',
'rewrite_function' => 'state_text',
'sortable' => 1
)
),
'permanent_filter' => array(
array(
'db_field' => 'parent_id',
'relational_operator' => '=',
'value' => '0'
)
),
'list_group_by' => 'id',
'default_sort_item' => 'number',
'default_sort_direction' => 'up',
'search_fields' => array('items.name', 'items.number', 'items.short_description', 'items.detail_description'),
'db_id_field' => 'id',
'edit_link' => 'index.php?admin_modul=admin_item_editor&id=',
'toolbar' => array(
'delete' => '1',
'new' => 'index.php?admin_modul=admin_item_editor',
'copy' => 0,
'select_all' => 1,
'edit' => 0,
'actions' => 1,
'filter' => 1,
'view' => 0,
'csv_export' => 1,
'search' => 1
),
'list_actions' => array(
array(
'db_field' => 'active',
'name' => 'Neuer Status',
'values' => 'state_text'
)
),
'list_filter' => array(
array(
'db_field' => 'manufacturer_id',
'relational_operator' => '=',
'name' => 'Hersteller',
'values' => 'manufacturer_names'
),
array(
'db_field' => 'active',
'relational_operator' => '=',
'name' => 'Status',
'values' => 'state_text'
),
array(
'db_field' => 'items.structure_id',
'relational_operator' => '=',
'name' => 'Hauptwarengruppe',
'values' => 'structure_values'
),
array(
'db_field' => 'items.inventory',
'name' => 'Lagerbestand',
'values' => 'inventory_filter'
),
array(
'db_field' => 'items.shippable',
'relational_operator' => '=',
'name' => 'Lieferstatus kein Bestand',
'values' => 'shipping_states'
),
array(
'db_field' => 'items.shippable_inventory',
'relational_operator' => '=',
'name' => 'Lieferstatus bei Bestand',
'values' => 'shipping_states'
),
array(
'db_field' => '(item_prices.price_1',
'name' => 'Netto-Händlerpreis',
'values' => 'price_filter'
),
array(
'db_field' => 'item_files.file_name',
'name' => 'Artikelbild',
'values' => 'image_filter'
),
array(
'db_field' => 'item_types.item_type_definition_id',
'relational_operator' => '=',
'name' => 'Artikeltypzuordnung',
'values' => 'item_type_values'
),
),
'edit_fields' => array(
array(
'db_field' => 'active',
'name' => 'Status',
'type' => 'int'
)
)
);
private $schema_fields = array(
'name' => 'text',
'description' => 'text',
'selectable_attribute_1' => 'integer',
'selectable_attribute_2' => 'integer',
'base_price_field' => 'integer',
'base_price_faktor' => 'float',
'base_price_unit' => 'text',
'attribute_name_1' => 'text',
'attribute_name_1_en' => 'text',
'attribute_unit_1' => 'text',
'attribute_rang_1' => 'integer',
'attribute_liste_1' => 'integer',
'attribute_detail_1' => 'integer',
'attribute_name_2' => 'text',
'attribute_name_2_en' => 'text',
'attribute_unit_2' => 'text',
'attribute_rang_2' => 'integer',
'attribute_liste_2' => 'integer',
'attribute_detail_2' => 'integer',
'attribute_name_3' => 'text',
'attribute_name_3_en' => 'text',
'attribute_unit_3' => 'text',
'attribute_rang_3' => 'integer',
'attribute_liste_3' => 'integer',
'attribute_detail_3' => 'integer',
'attribute_name_4' => 'text',
'attribute_name_4_en' => 'text',
'attribute_unit_4' => 'text',
'attribute_rang_4' => 'integer',
'attribute_liste_4' => 'integer',
'attribute_detail_4' => 'integer',
'attribute_name_5' => 'text',
'attribute_name_5_en' => 'text',
'attribute_unit_5' => 'text',
'attribute_rang_5' => 'integer',
'attribute_liste_5' => 'integer',
'attribute_detail_5' => 'integer',
'attribute_name_6' => 'text',
'attribute_name_6_en' => 'text',
'attribute_unit_6' => 'text',
'attribute_rang_6' => 'integer',
'attribute_liste_6' => 'integer',
'attribute_detail_6' => 'integer',
'attribute_name_7' => 'text',
'attribute_name_7_en' => 'text',
'attribute_unit_7' => 'text',
'attribute_rang_7' => 'integer',
'attribute_liste_7' => 'integer',
'attribute_detail_7' => 'integer',
'attribute_name_8' => 'text',
'attribute_name_8_en' => 'text',
'attribute_unit_8' => 'text',
'attribute_rang_8' => 'integer',
'attribute_liste_8' => 'integer',
'attribute_detail_8' => 'integer',
'attribute_name_9' => 'text',
'attribute_name_9_en' => 'text',
'attribute_unit_9' => 'text',
'attribute_rang_9' => 'integer',
'attribute_liste_9' => 'integer',
'attribute_detail_9' => 'integer',
'attribute_name_10' => 'text',
'attribute_name_10_en' => 'text',
'attribute_unit_10' => 'text',
'attribute_rang_10' => 'integer',
'attribute_liste_10' => 'integer',
'attribute_detail_10' => 'integer',
'attribute_name_11' => 'text',
'attribute_name_11_en' => 'text',
'attribute_unit_11' => 'text',
'attribute_rang_11' => 'integer',
'attribute_liste_11' => 'integer',
'attribute_detail_11' => 'integer',
'attribute_name_12' => 'text',
'attribute_name_12_en' => 'text',
'attribute_unit_12' => 'text',
'attribute_rang_12' => 'integer',
'attribute_liste_12' => 'integer',
'attribute_detail_12' => 'integer',
'attribute_name_13' => 'text',
'attribute_name_13_en' => 'text',
'attribute_unit_13' => 'text',
'attribute_rang_13' => 'integer',
'attribute_liste_13' => 'integer',
'attribute_detail_13' => 'integer',
'attribute_name_14' => 'text',
'attribute_name_14_en' => 'text',
'attribute_unit_14' => 'text',
'attribute_rang_14' => 'integer',
'attribute_liste_14' => 'integer',
'attribute_detail_14' => 'integer',
'attribute_name_15' => 'text',
'attribute_name_15_en' => 'text',
'attribute_unit_15' => 'text',
'attribute_rang_15' => 'integer',
'attribute_liste_15' => 'integer',
'attribute_detail_15' => 'integer',
'attribute_name_16' => 'text',
'attribute_name_16_en' => 'text',
'attribute_unit_16' => 'text',
'attribute_rang_16' => 'integer',
'attribute_liste_16' => 'integer',
'attribute_detail_16' => 'integer',
'attribute_name_17' => 'text',
'attribute_name_17_en' => 'text',
'attribute_unit_17' => 'text',
'attribute_rang_17' => 'integer',
'attribute_liste_17' => 'integer',
'attribute_detail_17' => 'integer',
'attribute_name_18' => 'text',
'attribute_name_18_en' => 'text',
'attribute_unit_18' => 'text',
'attribute_rang_18' => 'integer',
'attribute_liste_18' => 'integer',
'attribute_detail_18' => 'integer',
'attribute_name_19' => 'text',
'attribute_name_19_en' => 'text',
'attribute_unit_19' => 'text',
'attribute_rang_19' => 'integer',
'attribute_liste_19' => 'integer',
'attribute_detail_19' => 'integer',
'attribute_name_20' => 'text',
'attribute_name_20_en' => 'text',
'attribute_unit_20' => 'text',
'attribute_rang_20' => 'integer',
'attribute_liste_20' => 'integer',
'attribute_detail_20' => 'integer'
);
private $item_fields = array(
'active' => 'integer',
'parent_id' => 'integer',
'number' => 'text',
'name' => 'text',
'short_description' => 'text',
'detail_description' => 'text',
'name_en' => 'text',
'short_description_en' => 'text',
'detail_description_en' => 'text',
'youtube_video' => 'text',
'structure_id' => 'integer',
/*'structure_id_2' => 'integer',
'structure_id_3' => 'integer',
'structure_id_4' => 'integer',
'structure_id_5' => 'integer',
'structure_id_6' => 'integer',
'structure_id_7' => 'integer',
'structure_id_8' => 'integer',
'structure_id_9' => 'integer',
'structure_id_10' => 'integer',*/
'manufacturer_id' => 'integer',
'manufacturer_item_number' => 'text',
'ean_code' => 'text',
'short_uri' => 'text',
'seo_title' => 'text',
'seo_description' => 'text',
'seo_keywords' => 'text',
'inventory_number' => 'text',
'inventory' => 'integer',
'inventory_min' => 'integer',
'inventory_rack_number' => 'text',
'inventory_order_quantity' => 'integer',
'tax_id' => 'integer',
'base_price' => 'float',
'price_type' => 'integer',
'bargain_price_type' => 'integer',
'uvp' => 'float',
'schema_id' => 'integer',
/* 'price_1' => 'float',
'bargain_price_1' => 'float',
'quantity_1' => 'integer',
'price_2' => 'float',
'bargain_price_2' => 'float',
'quantity_2' => 'integer',
'price_3' => 'float',
'bargain_price_3' => 'float',
'quantity_3' => 'integer',
'price_4' => 'float',
'bargain_price_4' => 'float',
'quantity_4' => 'integer',
'price_5' => 'float',
'bargain_price_5' => 'float',
'quantity_5' => 'integer',
'price_6' => 'float',
'bargain_price_6' => 'float',
'quantity_6' => 'integer',
'price_7' => 'float',
'bargain_price_7' => 'float',
'quantity_7' => 'integer',
'price_8' => 'float',
'bargain_price_8' => 'float',
'quantity_8' => 'integer',
'price_9' => 'float',
'bargain_price_9' => 'float',
'quantity_9' => 'integer',
'price_10' => 'float',
'bargain_price_10' => 'float',
'quantity_10' => 'integer',
'price_11' => 'float',
'bargain_price_11' => 'float',
'quantity_11' => 'integer',
'price_12' => 'float',
'bargain_price_12' => 'float',
'quantity_12' => 'integer',
'price_13' => 'float',
'bargain_price_13' => 'float',
'quantity_13' => 'integer',
'price_14' => 'float',
'bargain_price_14' => 'float',
'quantity_14' => 'integer',
'price_15' => 'float',
'bargain_price_15' => 'float',
'quantity_15' => 'integer',
'price_16' => 'float',
'bargain_price_16' => 'float',
'quantity_16' => 'integer',
'price_17' => 'float',
'bargain_price_17' => 'float',
'quantity_17' => 'integer',
'price_18' => 'float',
'bargain_price_18' => 'float',
'quantity_18' => 'integer',
'price_19' => 'float',
'bargain_price_19' => 'float',
'quantity_19' => 'integer',
'price_20' => 'float',
'bargain_price_20' => 'float',
'quantity_20' => 'integer',
'price_21' => 'float',
'bargain_price_21' => 'float',
'quantity_21' => 'integer',
'price_22' => 'float',
'bargain_price_22' => 'float',
'quantity_22' => 'integer',
'price_23' => 'float',
'bargain_price_23' => 'float',
'quantity_23' => 'integer',
'price_24' => 'float',
'bargain_price_24' => 'float',
'quantity_24' => 'integer',
'price_25' => 'float',
'bargain_price_25' => 'float',
'quantity_25' => 'integer',
'price_26' => 'float',
'bargain_price_26' => 'float',
'quantity_26' => 'integer',
'price_27' => 'float',
'bargain_price_27' => 'float',
'quantity_27' => 'integer',
'price_28' => 'float',
'bargain_price_28' => 'float',
'quantity_28' => 'integer',
'price_29' => 'float',
'bargain_price_29' => 'float',
'quantity_29' => 'integer',
'price_30' => 'float',
'bargain_price_30' => 'float',
'quantity_30' => 'integer', */
'attribute_1' => 'text',
'attribute_2' => 'text',
'attribute_3' => 'text',
'attribute_4' => 'text',
'attribute_5' => 'text',
'attribute_6' => 'text',
'attribute_7' => 'text',
'attribute_8' => 'text',
'attribute_9' => 'text',
'attribute_10' => 'text',
'attribute_11' => 'text',
'attribute_12' => 'text',
'attribute_13' => 'text',
'attribute_14' => 'text',
'attribute_15' => 'text',
'attribute_16' => 'text',
'attribute_17' => 'text',
'attribute_18' => 'text',
'attribute_19' => 'text',
'attribute_20' => 'text',
'shippable' => 'shippable',
'available_from' => 'date',
'available_till' => 'date',
'variant_price_type' => 'integer',
'google_product_category' => 'text',
'combination_item' => 'integer',
'sample_unit' => 'text',
'vendor_item_number' => 'text',
'vendor_id' => 'integer',
'has_user_data' => 'integer',
'price_je_vpe' => 'integer',
'vpe_amount' => 'integer',
'vpe_unit' => 'text',
'vpe_sampleprice_unit' => 'float',
'min_quantity' => 'integer',
'shippable_inventory' => 'integer',
'shipping_cost_type' => 'integer',
'shipping_item_type' => 'integer',
'shipping_weight' => 'float',
'buy_quantity' => 'integer',
'main_variant_item_id' => 'integer'
);
private $config;
protected $base_object;
private $shopConfiguration;
private $schema_id;
private $itemschema_object;
private $item_discounts;
protected $db;
public $id = 0;
public $shopArticleProducers;
public $discount;
public $selectableVariants = array();
public $deleteSelectableVariants = array();
public $itemCount;
public $all_tax;
public $price_praefix;
private $tax_rates;
private $manufacturers;
private $structure;
public function __construct($base_object, $id = false, $with_discounts = 1) {
parent::__construct($base_object);
$this->config = $base_object->config;
$this->db = $base_object->db;
$this->base_object = $base_object;
// Initialize ItemDatabase for cleaner SQL handling
include_once './core/item-db.class.php';
$this->itemDb = new ItemDatabase($this->base_object);
// Performance-Debug aktiviert? Dann Debug-Ausgabe später anzeigen
if (isset($_GET['debug_performance'])) {
$this->debug_performance = true;
echo "<div style='background:green;color:white;padding:10px;'>✅ DEBUG-MODUS AKTIVIERT - Performance wird gemessen</div>";
}
$this->id = $id;
$this->shopConfiguration = $this->config->shopConfiguration;
$this->price_praefix = '';
if ($this->shopConfiguration['show_child_items'] == 1) {
$this->list_table_config['permanent_filter'] = array();
}
$this->list_table_config['permanent_filter'][] = array(
'db_field' => 'item_prices.customergroup_id',
'relational_operator' => '=',
'accept_null' => 1,
'value' => $this->shopConfiguration['item_list_price_group_id']
);
$tax_object = new Tax($base_object);
$this->all_tax = $tax_object->get_all();
$this->itemschema_object = new ItemSchema($base_object);
if ($with_discounts) {
$this->load_item_discounts();
}
$this->setup_manufacturers_array();
$this->setup_tax_rate_array();
$this->setup_structure_array();
}
// end __construct
public function netto_price($string) {
return '<span class="order_list_item_price">'.number_format($string, 2, ',', '').' &euro;</span>';
}
public function state_text() {
return array(
'1' => 'aktiv',
'0' => 'inaktiv'
);
}
public function shipping_states() {
return array(
'1' => 'lieferbar',
'0' => 'nicht lieferbar',
'2' => 'lieferbar ab',
'3' => 'lieferzeit unbekannt',
'4' => 'Bestellartikel (Lieferzeit 2-3 Tage)',
'5' => 'Bestellartikel (Lieferzeit 14 Tage)'
);
}
public function inventory_filter() {
if ($this->base_object->config->shopConfiguration['item_list_filter_max_inventory'] != '') {
return array(
'> 0' => '> 0',
'= 0' => '= 0',
'< 0' => '< 0',
'< '.$this->base_object->config->shopConfiguration['item_list_filter_max_inventory'] => '< '.$this->base_object->config->shopConfiguration['item_list_filter_max_inventory']
);
} else {
return array(
'> 0' => '> 0',
'= 0' => '= 0',
'< 0' => '< 0'
);
}
}
public function price_filter() {
return array(
'> 0)' => '> 0',
'= 0 || item_prices.price_1 IS NULL)' => '= 0',
'< 100)' => '< 100',
'> 100)' => '> 100',
'< 1000)' => '< 1000',
'> 1000)' => '> 1000'
);
}
public function image_filter() {
return array(
"IS NULL" => 'nicht vorhanden',
);
}
public function manufacturer_names() {
$manufacturer_object = new Manufacturer($this->base_object);
return $manufacturer_object->get_all_names();
}
public function structure_values() {
$structure_object = new Structure($this->base_object);
$data = $structure_object->full_name_path();
$data['0'] = '>>keine Zuweisung vorhanden<<';
return $data;
}
public function item_type_values() {
include_once './core/itemtype.class.php';
$item_type_object = new ItemType($this->base_object);
$data = $item_type_object->get_item_type_definitions();
return $data;
}
private function setup_manufacturers_array() {
$sql = "SELECT * FROM manufacturers";
$result = $this->db->query($sql);
if ($result->num_rows > 0) {
$this->manufacturers = array();
while ($obj = $result->fetch_object()) {
$this->manufacturers[$obj->id] = $obj;
}
}
}
// end setup_manufacturers_array
private function setup_tax_rate_array() {
$sql = "SELECT * FROM tax";
$result = $this->db->query($sql);
if ($result->num_rows > 0) {
$this->tax_rates = array();
while ($obj = $result->fetch_object()) {
$this->tax_rates[$obj->id] = $obj;
}
}
}
// end setup_tax_rate_array
private function setup_structure_array() {
$sql = "SELECT * FROM structure";
$result = $this->db->query($sql);
if ($result->num_rows > 0) {
$this->structure = array();
while ($obj = $result->fetch_object()) {
$this->structure[$obj->id] = $obj;
}
}
}
// end setup_structure_array
public function set_schema_id($id) {
$this->schema_id = $id;
}
public function get_schema_id() {
return $this->schema_id;
}
public function set($data) {
foreach ($data as $key => $value) {
$this->{$key} = $value;
}
return;
}
// end set
public function set_id($id) {
$this->id = $id;
}
public function has_id() {
if ($this->id) {
return true;
}
return false;
}
public function get_id($id) {
return $this->id;
}
public function set_row($data) {
$dat = Database::clean($data);
$sql = Database::insert('items', $data);
}
public function get_sold_out() {
$sql = "SELECT id, name, inventory FROM items WHERE inventory_min>inventory LIMIT 10";
$result = $this->db->query($sql);
if ($result->num_rows > 0) {
while ($row = $result->fetch_object()) {
$data[] = $row;
}
return $data;
}
return false;
}
public function get_all_paginated($items, $page, $order = false, $sort_direction = false) {
$page = ($page - 1) * $items;
$sort = '';
if ($order) {
$sort = " ORDER BY ".$this->db->real_escape_string($order);
if ($sort_direction && $sort_direction == 'down') {
$sort .= " DESC ";
} else {
$sort .= " ASC ";
}
}
if ($order == 'new') {
$sql = "SELECT id, tax_id, number, name, active, price_1, bargain_price_1, inventory, inventory_min
FROM items $sort
LIMIT $items OFFSET $page;";
} else if ($order == 'sold_out') {
$sql = "SELECT id, tax_id, number, name, active, price_1
FROM items $sort
LIMIT $items OFFSET $page;";
} else {
if ($_GET['structure_id']) {
$sql = "SELECT id, tax_id, number, name, active, price_1, bargain_price_1, inventory, inventory_min
FROM items
WHERE structure_id=".$_GET['structure_id']."
OR structure_id_2=".$_GET['structure_id']."
OR structure_id_3=".$_GET['structure_id']."
$sort
LIMIT $items OFFSET $page;";
} else {
$sql = "SELECT id, tax_id, number, name, active, price_1, bargain_price_1, inventory, inventory_min
FROM items $sort
LIMIT $items OFFSET $page;";
}
}
$data = parent::get_all_paginated($items, $page, $sql);
$new_data = array();
foreach ($data as $obj) {
$sql = "SELECT * FROM item_prices WHERE item_id = ".$obj->id." AND customergroup_id = 1 ";
$prices = $this->db->query($sql)->fetch_object();
foreach ($prices as $field => $value) {
if ($field != 'item_id' && $field != 'customergroup_id') {
$obj->{$field} = $value;
}
}
$obj->tax = $this->all_tax[$obj->tax_id]->steuersatz;
// calc tax
$obj->tax_value = round($obj->price_1 * ($obj->tax / 100), 2);
$obj->price_1_tax = $obj->price_1 + $obj->tax_value;
$obj->bargain_tax_value = round($obj->bargain_price_1 * ($obj->tax / 100), 2);
$obj->bargain_price_1_tax = $obj->bargain_price_1 + $obj->bargain_tax_value;
// Set shop_* variables for item_box.tpl template (like in variant structure)
// Templates expect shop_price_1 and shop_bargain_price_1 for display
if ($this->base_object->customer_group->show_tax) {
$obj->shop_price_1 = $obj->price_1_tax;
$obj->shop_bargain_price_1 = $obj->bargain_price_1_tax;
} else {
$obj->shop_price_1 = $obj->price_1;
$obj->shop_bargain_price_1 = $obj->bargain_price_1;
}
$new_data[] = $obj;
}
return $new_data;
}
// end get_all_paginated
public function get_data($forCustomerGroup = 1, $for_frontend = true) {
if (isset($_GET['debug_performance'])) {
echo "<div style='background:blue;color:white;padding:10px;'>🟦 GET_DATA ERREICHT für ID: " . $this->id . "</div>";
flush(); ob_flush();
}
$manufacturer = new Manufacturer($this->base_object);
if (isset($_GET['debug_performance'])) {
echo "<div style='background:purple;color:white;padding:10px;'>🟣 MANUFACTURER ERSTELLT</div>";
flush(); ob_flush();
}
$customer_group_price = $forCustomerGroup;
$customer_group_discount = $forCustomerGroup;
if (isset($this->base_object->customer_group->adaptPricesFromId) && $this->base_object->customer_group->adaptPricesFromId) {
$customer_group_price = $this->base_object->customer_group->adaptPricesFromId;
}
$forCustomerGroup = $customer_group_price;
// Item Match - REAKTIVIERT
$sql = "SELECT * FROM krempl_passendwie im JOIN items i ON i.attribute_7 = im.navisionid WHERE i.id = " . intval($this->id);
$result = $this->db->query($sql);
if ($result) {
$obj = $result->fetch_object();
}
// Get all Item Data - über unsere neue DB-Klasse
$obj = $this->itemDb->getItemData($this->id);
if (!$obj) {
if (isset($_GET['debug_performance'])) {
echo "<div style='background:red;color:white;padding:20px;'>";
echo "❌ PROBLEM GEFUNDEN: Item mit ID {$this->id} existiert NICHT in der Datenbank!<br>";
echo "Das ist der Grund für das Timeout - das System sucht nach einem nicht-existierenden Artikel!<br>";
echo "URL sollte umgeleitet werden oder 404 zeigen.";
echo "</div>";
die();
}
// Check if we're in admin area - don't redirect, show error instead
if (isset($_GET['admin_modul'])) {
echo "<div style='background:red;color:white;padding:20px;'>";
echo "❌ FEHLER: Item mit ID {$this->id} existiert nicht in der Datenbank!<br>";
echo "Möglicherweise wurde der Artikel gelöscht oder die ID ist ungültig.";
echo "</div>";
return false;
}
// Normale Behandlung - zurück zur Startseite
header('Location: /');
exit();
}
if (isset($_GET['debug_performance'])) {
echo "<div style='background:green;color:white;padding:10px;'>✅ ITEM DATEN GELADEN - ID: {$this->id}</div>";
flush(); ob_flush();
}
// Debug: Überprüfen der Objekt-Eigenschaften
$debug_obj = get_object_vars($obj);
if (isset($debug_obj['vendor_id'])) {
// Stelle sicher, dass vendor_id als Integer behandelt wird
$obj->vendor_id = intval($debug_obj['vendor_id']);
}
// REAKTIVIERT - "Passend wie" Daten für Template
$sql = "SELECT i.number, im.vertreiber, im.bestellcode, i.attribute_7, i.number, i.krempl_id
FROM krempl_passendwie im
INNER JOIN items i ON i.attribute_7 = im.navisionid
WHERE i.id = " . intval($this->id);
$result = $this->db->query($sql);
$obj->match = array();
if ($result) {
while ($row = $result->fetch_object()) {
$obj->match[] = $row;
}
}
// Herstellerinformationen abrufen - über neue DB-Klasse
$obj->herstellerinfo = $this->itemDb->getManufacturerInfo($obj->vendor_id ?? null);
if (isset($_GET['debug_performance'])) {
echo "<div style='background:orange;color:white;padding:10px;'>🟠 HERSTELLERINFO GELADEN</div>";
flush(); ob_flush();
}
// Sicherheitshinweise und Dokumente hinzufügen - TEMPORÄR DEAKTIVIERT
/*if (isset($obj->attribute_7) && !empty($obj->attribute_7)) {
$navisionId = $obj->attribute_7;
$sql = "SELECT * FROM sicherheitshinweis_item WHERE navision_id = ?";
$stmt = $this->db->prepare($sql);
if ($stmt) {
$stmt->bind_param("s", $navisionId);
$stmt->execute();
$result = $stmt->get_result();
$warningDocsList = $result->fetch_assoc();
if ($warningDocsList) {
// Sicherheitswarnungen laden
$warningIdsList = $warningDocsList['warning_ids'] ?? null;
$obj->warnings = $this->loadWarnings($warningIdsList);*/
// RESTLICHER SICHERHEITSHINWEISE-BLOCK TEMPORÄR DEAKTIVIERT
/*$documentColumns = ['Bedienungsanleitung', 'EU_Datenblatt', 'Energielabel', 'Produktdatenblatt', 'Sicherheitsdatenblatt', 'Zertifikat', 'null_feld'];
$documentColumns = [
'Bedienungsanleitung' => 'Allg. Sicherheitshinweise',
'EU_Datenblatt' => 'EU-Datenblatt',
'Energielabel' => 'Energielabel',
'Produktdatenblatt' => 'Produktdatenblatt',
'Sicherheitsdatenblatt' => 'Sicherheitsdatenblatt',
'Zertifikat' => 'Zertifikat',
'null_feld' => 'Allg. Sicherheitshinweise'
];
$documents = [];
foreach ($documentColumns as $column => $label) {
if (!empty($warningDocsList[$column])) {
$pdfs = explode(',', $warningDocsList[$column]);
$pdfs = array_map('trim', $pdfs);
$pdfs = array_map(fn($pdf) => trim($pdf, '"'), $pdfs);
foreach ($pdfs as $pdf) {
$documents[] = [
'file_name' => $pdf,
'label' => $label
];
}
}
}
$obj->wdocuments = $documents;
} else {
$obj->warnings = [];
$obj->wdocuments = [];
}
} else {
$obj->warnings = [];
$obj->wdocuments = [];
}
}*/
// Sicherheitshinweise: Fallback-System attribute_5 -> attribute_7
$securityData = $this->itemDb->getSecurityWarnings($obj->attribute_7 ?? null, $obj->attribute_5 ?? null);
$obj->warnings = $securityData['warnings'];
$obj->wdocuments = $securityData['documents'];
// 🤖 AI Shopping Schema Generator - KI-optimierte Produktdaten
if ($this->shouldGenerateAISchema($obj)) {
$this->generateAIShoppingSchema($obj);
}
// get admin user - über neue DB-Klasse
$obj->last_change_user = $this->itemDb->getAdminUser($obj->last_change_user_id ?? null);
if (isset($_GET['debug_performance'])) {
echo "<div style='background:cyan;color:black;padding:10px;'>🔵 ADMIN USER GELADEN</div>";
flush(); ob_flush();
}
// get prices (auskommentiert)
if (isset($_GET['debug_performance'])) {
echo "<div style='background:yellow;color:black;padding:10px;'>⚠️ VOR get_file_list() - jetzt testen...</div>";
flush(); ob_flush();
}
$obj->files = $this->get_file_list();
if (isset($_GET['debug_performance'])) {
echo "<div style='background:lime;color:black;padding:10px;'>✅ get_file_list() ERFOLGREICH - " . count($obj->files) . " Dateien geladen</div>";
flush(); ob_flush();
}
if ($obj->parent_id && !$obj->files) {
// get parent images if no variant images
$obj->parent_files = $this->get_file_list(false, $obj->parent_id);
}
$manufacturer_data = $manufacturer->get_by_id($obj->manufacturer_id);
if ($manufacturer_data) {
$obj->manufacturer_name = $manufacturer_data->name;
$obj->manufacturer_data = $manufacturer_data;
}
if (isset($_GET['debug_performance'])) {
echo "<div style='background:purple;color:white;padding:10px;'>🏭 MANUFACTURER->get_by_id() ERFOLGREICH</div>";
echo "<div style='background:yellow;color:black;padding:10px;'>";
echo "📊 ALLE WERTE nach manufacturer:<br>";
echo "obj->id = " . var_export($obj->id ?? 'NULL', true) . "<br>";
echo "obj->parent_id = " . var_export($obj->parent_id ?? 'NULL', true) . "<br>";
echo "obj->name = " . var_export($obj->name ?? 'NULL', true) . "<br>";
echo "obj->manufacturer_id = " . var_export($obj->manufacturer_id ?? 'NULL', true) . "<br>";
echo "manufacturer_data = " . (isset($manufacturer_data) ? 'EXISTS' : 'NULL') . "<br>";
echo "</div>";
flush(); ob_flush();
}
// get parent item
$obj->variant_structure = array();
$parent_id = 0;
if (isset($_GET['debug_performance'])) {
$check1 = $obj->parent_id ? 'TRUE' : 'FALSE';
$check2 = ($obj->parent_id != '0') ? 'TRUE' : 'FALSE';
$check3 = ($obj->parent_id > 0) ? 'TRUE' : 'FALSE';
echo "<div style='background:orange;color:black;padding:10px;'>";
echo "🔍 IF-CHECK RESULTS:<br>";
echo "parent_id = '" . $obj->parent_id . "'<br>";
echo "Check 1 (\$obj->parent_id): " . $check1 . "<br>";
echo "Check 2 (parent_id != '0'): " . $check2 . "<br>";
echo "Check 3 (parent_id > 0): " . $check3 . "<br>";
echo "</div>";
flush(); ob_flush();
}
if ($obj->parent_id && $obj->parent_id != '0' && $obj->parent_id > 0) {
if (isset($_GET['debug_performance'])) {
echo "<div style='background:red;color:white;padding:10px;'>➡️ GEHT IN IF-BLOCK REIN!</div>";
flush(); ob_flush();
// die() entfernt - soll durchlaufen
}
$parent_id = $obj->parent_id;
if (isset($_GET['debug_performance'])) {
echo "<div style='background:red;color:white;padding:10px;'>🔴 VOR get_by_id() für PARENT_ID: " . $obj->parent_id . "</div>";
echo "<div style='background:yellow;color:black;padding:10px;'>📊 WERTE: parent_id=[" . var_export($obj->parent_id, true) . "] type=[" . gettype($obj->parent_id) . "]</div>";
flush(); ob_flush();
// die() entfernt - soll durchlaufen
}
// get parent item data
$parent_item = $this->get_by_id($obj->parent_id);
if (isset($_GET['debug_performance'])) {
echo "<div style='background:green;color:white;padding:10px;'>✅ PARENT ITEM GELADEN</div>";
flush(); ob_flush();
// die() entfernt - soll durchlaufen
}
$obj->parent_item = $parent_item;
$obj->structure_id = $parent_item->structure_id;
$obj->variant_structure[] = array(
'id' => $parent_item->id,
'level' => 1,
'name' => $parent_item->name
);
} else {
$parent_id = '0'; // KORRIGIERT - Items ohne Parent haben parent_id = '0'
$obj->variant_structure[] = array(
'id' => $obj->id,
'level' => 1,
'name' => $obj->name
);
}
if (isset($_GET['debug_performance'])) {
echo "<div style='background:green;color:white;padding:10px;'>✅ PARENT_ID BLOCK ÜBERSPRUNGEN - Artikel sollte jetzt laden!</div>";
flush(); ob_flush();
}
// get schema data
$obj->schema_data_attributes = array();
if (isset($_GET['debug_performance'])) {
echo "<div style='background:blue;color:white;padding:10px;'>🔵 VOR SCHEMA CHECK - schema_id: " . ($obj->schema_id ?? 'NULL') . "</div>";
flush(); ob_flush();
}
if ($obj->schema_id) {
if (isset($_GET['debug_performance'])) {
echo "<div style='background:orange;color:black;padding:10px;'>🟠 SCHEMA IF-BLOCK BETRETEN</div>";
flush(); ob_flush();
}
$this->schema_id = $obj->schema_id;
if (isset($_GET['debug_performance'])) {
echo "<div style='background:red;color:white;padding:10px;'>⚠️ VOR get_schema_data() - schema_id: " . $this->schema_id . "</div>";
flush(); ob_flush();
}
$obj->schema_data = $this->get_schema_data();
if (isset($_GET['debug_performance'])) {
echo "<div style='background:lime;color:black;padding:10px;'>✅ get_schema_data() ERFOLGREICH</div>";
flush(); ob_flush();
}
// sampleprice calc data
if ($obj->schema_data->base_price_field > 0) {
$obj->sample_unit = $obj->schema_data->base_price_unit;
}
// added md5 variant key
for ($i = 0; $i < count($obj->variant_structure); $i++) {
// variant key 1
if ($obj->schema_data->selectable_attribute_1) {
$obj->variant_structure[$i]['variant_key1_md5'] = md5($obj->variant_structure[$i]['data']->{'attribute_'.$obj->schema_data->selectable_attribute_1});
}
// variant key 2
if ($obj->schema_data->selectable_attribute_2) {
$obj->variant_structure[$i]['variant_key2_md5'] = md5($obj->variant_structure[$i]['data']->{'attribute_'.$obj->schema_data->selectable_attribute_2});
} else {
$obj->variant_structure[$i]['variant_key2_md5'] = md5(0);
}
}
$obj->item_category_name = Structure::get_name_by_id($obj->structure_id);
foreach ($obj->schema_data->attributes as $attribute) {
if ($attribute->name) {
$attr = array(
'name' => $attribute->name,
'name_en' => $attribute->name_en,
'unit' => $attribute->unit,
'value' => $obj->{'attribute_'.$attribute->number},
'show_detail' => $attribute->show_detail,
'show_list' => $attribute->show_list,
'number' => $attribute->number
);
$obj->schema_data_attributes[] = $attr;
}
if ($obj->schema_data->selectable_attribute_1 == $attribute->number) {
$obj->schema_data->selectable_name_1 = $attribute->name;
// get selectable attributes 1
$obj->schema_data->all_selectable_attributes_1 = array();
foreach ($all_variants as $variante) {
$obj->schema_data->all_selectable_attributes_1[md5($variante['data']->{'attribute_'.$attribute->number})] = $variante['data']->{'attribute_'.$attribute->number};
}
}
if ($obj->schema_data->selectable_attribute_2 == $attribute->number) {
$obj->schema_data->selectable_name_2 = $attribute->name;
// get selectable attributes 2
$obj->schema_data->all_selectable_attributes_2 = array();
foreach ($all_variants as $variante) {
$obj->schema_data->all_selectable_attributes_2[md5($variante['data']->{'attribute_'.$attribute->number})] = $variante['data']->{'attribute_'.$attribute->number};
}
}
// sampleprice calc data
if ($obj->schema_data->base_price_field == $attribute->number) {
$obj->vpe_sampleprice_unit = $obj->{'attribute_'.$attribute->number};
}
}
}
// get item discount
$discount = $this->get_item_discount($customer_group_discount, $obj->manufacturer_id, $obj->structure_id);
if ($discount) {
$obj->bargain_price_1 = round(($obj->price_1 * (100 - $discount) / 100), 2);
$obj->discount = $discount;
$obj->discount_text = 'Rabatt!';
}
// get variants - ONLY if parent_id > 0
if (isset($_GET['debug_performance'])) {
echo "<div style='background:orange;color:black;padding:10px;'>";
echo "📊 PARENT_ID WERTE VOR VARIANTS:<br>";
echo "parent_id = [" . var_export($parent_id, true) . "] type=[" . gettype($parent_id) . "]<br>";
echo "parent_id > 0: " . (($parent_id > 0) ? 'TRUE' : 'FALSE') . "<br>";
echo "</div>";
flush(); ob_flush();
}
if ($parent_id > 0) {
if (isset($_GET['debug_performance'])) {
echo "<div style='background:red;color:white;padding:10px;'>🔴 VARIANTS SQL mit parent_id: " . $parent_id . "</div>";
flush(); ob_flush();
}
$sql = "SELECT i.*, ip.price_1, ip.bargain_price_1 FROM items i
LEFT JOIN item_prices ip ON (ip.item_id = i.id AND ip.customergroup_id = ".$this->db->real_escape_string($customer_group_price).")
WHERE i.parent_id = ".$this->db->real_escape_string($parent_id)." GROUP BY i.id ORDER BY ip.price_1";
$variant_result = $this->db->query($sql);
} else {
if (isset($_GET['debug_performance'])) {
echo "<div style='background:green;color:white;padding:10px;'>✅ VARIANTS ÜBERSPRUNGEN - parent_id ist 0</div>";
flush(); ob_flush();
}
$variant_result = false;
}
$all_variants = array();
if (isset($_GET['debug_performance'])) {
echo "<div style='background:magenta;color:white;padding:10px;'>🟣 NACH VARIANTS SQL - Rows: " . ($variant_result ? $variant_result->num_rows : 'NULL') . "</div>";
flush(); ob_flush();
}
if ($variant_result && $variant_result->num_rows > 0) {
while ($variant_obj = $variant_result->fetch_object()) {
if ($discount) {
$variant_obj->bargain_price_1 = round(($variant_obj->price_1 * (100 - $discount) / 100), 2);
$variant_obj->discount = $discount;
}
// rewrite price with discountprice
if ($variant_obj->bargain_price_1 > 0) {
$variant_obj->price_1 = $variant_obj->bargain_price_1;
}
// calc tax
$variant_obj->tax = $this->all_tax[$variant_obj->tax_id]->steuersatz;
$variant_obj->tax_value = round($variant_obj->price_1 * ($variant_obj->tax / 100), 4);
$variant_obj->price_1_tax = $variant_obj->price_1 + $variant_obj->tax_value;
$variant_obj->bargain_tax_value = round($variant_obj->bargain_price_1 * ($variant_obj->tax / 100), 2);
$variant_obj->bargain_price_1_tax = $variant_obj->bargain_price_1 + $variant_obj->bargain_tax_value;
// shop price
$variant_obj->sample_price = 0;
if ($this->base_object->customer_group->show_tax) {
$variant_obj->shop_price_1 = $variant_obj->price_1_tax;
$variant_obj->shop_bargain_price_1 = $variant_obj->bargain_price_1_tax;
} else {
$variant_obj->shop_price_1 = $variant_obj->price_1;
$variant_obj->shop_bargain_price_1 = $variant_obj->bargain_price_1;
}
// calc sample price
$variant_obj->vpe_sampleprice_unit = $variant_obj->{'attribute_'.$obj->schema_data->base_price_field};
if ($obj->sample_unit && $variant_obj->vpe_sampleprice_unit) {
if ($variant_obj->price_je_vpe) {
if ($variant_obj->vpe_amount) {
if ($variant_obj->shop_bargain_price_1 > 0) {
$variant_obj->sample_price = $variant_obj->shop_bargain_price_1 / ($variant_obj->vpe_sampleprice_unit * $variant_obj->vpe_amount);
} else {
$variant_obj->sample_price = $variant_obj->shop_price_1 / ($variant_obj->vpe_sampleprice_unit * $variant_obj->vpe_amount);
}
}
} else {
if ($variant_obj->shop_bargain_price_1 > 0) {
$variant_obj->sample_price = ($variant_obj->shop_bargain_price_1 / $variant_obj->vpe_sampleprice_unit) / $obj->schema_data->base_price_faktor;
} else {
$variant_obj->sample_price = ($variant_obj->shop_price_1 / $variant_obj->vpe_sampleprice_unit) / $obj->schema_data->base_price_faktor;
}
}
}
$all_variants[] = $obj->variant_structure[] = array(
'id' => $variant_obj->id,
'level' => 2,
'name' => $variant_obj->name,
'active' => $variant_obj->active,
'short_uri' => $variant_obj->short_uri,
'number' => $variant_obj->number,
'price_1' => $variant_obj->price_1,
'price_type' => $variant_obj->price_type,
'bargain_price_1' => $variant_obj->bargain_price_1,
'shop_price_1' => $variant_obj->shop_price_1,
'shop_bargain_price_1' => $variant_obj->shop_bargain_price_1,
'sample_price' => $variant_obj->sample_price,
'default_image_file_name' => $variant_obj->default_image_file_name,
'data' => $variant_obj
);
// get smallest price for parent article
if (!$obj->smallest_variant_price_1 || $obj->smallest_variant_price_1 > $variant_obj->price_1) {
$obj->smallest_variant_price_1 = $variant_obj->price_1;
$obj->smallest_variant_bargain_price_1 = $variant_obj->bargain_price_1;
}
}
} else {
// get prices
$prices = $this->getPricesForCustomerGroup($forCustomerGroup);
foreach ($prices as $field => $value) {
if ($field != 'item_id' && $field != 'customergroup_id') {
if (!$this->check_bargain_active($obj, $this->id) && substr($field,0,7) == 'bargain') {
$value = 0;
}
$obj->{$field} = $value;
}
}
}
$obj->tax = isset($this->all_tax[$obj->tax_id]->steuersatz) ? $this->all_tax[$obj->tax_id]->steuersatz : 1.19;
$obj->price_tax_text_free_shipping = isset($this->base_object->customer_group->price_tax_text_free_shipping)
? str_replace('[tax]', $obj->tax, $this->base_object->customer_group->price_tax_text_free_shipping)
: 'inkl. [tax]% MwSt. versandkostenfrei';
$obj->price_tax_text = isset($this->base_object->customer_group->price_tax_text)
? str_replace('[tax]', $obj->tax, $this->base_object->customer_group->price_tax_text)
: 'inkl. [tax]% MwSt.';
// get item_types
$obj->item_types = $this->get_item_types($obj->id);
// calc tax
$obj->uvp_netto = round(($obj->uvp / ($obj->tax + 100) * 100), 4);
$obj->tax_value = round($obj->price_1 * ($obj->tax / 100), 4);
$obj->price_1_tax = $obj->price_1 + $obj->tax_value;
$obj->bargain_tax_value = round($obj->bargain_price_1 * ($obj->tax / 100), 4);
$obj->bargain_price_1_tax = $obj->bargain_price_1 + $obj->bargain_tax_value;
// shop price
//$obj->sample_price = 0;
if (isset($this->base_object->customer_group->show_tax) && $this->base_object->customer_group->show_tax) {
$obj->shop_price_1 = $obj->price_1_tax;
$obj->shop_bargain_price_1 = $obj->bargain_price_1_tax;
} else {
$obj->shop_price_1 = $obj->price_1;
$obj->shop_bargain_price_1 = $obj->bargain_price_1;
}
// calc sample price
if ((!$all_variants || $obj->parent_id > 0) && ($obj->sample_unit && $obj->vpe_sampleprice_unit)) {
if ($obj->price_je_vpe) {
if ($obj->vpe_amount) {
if ($obj->shop_bargain_price_1 > 0) {
$obj->sample_price = $obj->shop_bargain_price_1 / ($obj->vpe_sampleprice_unit * $obj->vpe_amount);
} else {
$obj->sample_price = $obj->shop_price_1 / ($obj->vpe_sampleprice_unit * $obj->vpe_amount);
}
}
} else {
if ($obj->shop_bargain_price_1 > 0) {
$obj->sample_price = ($obj->shop_bargain_price_1 / $obj->vpe_sampleprice_unit) / $obj->schema_data->base_price_faktor;
} else {
$obj->sample_price = ($obj->shop_price_1 / $obj->vpe_sampleprice_unit) / $obj->schema_data->base_price_faktor;
}
}
}
if (isset($_GET['debug_performance'])) {
echo "<div style='background:cyan;color:black;padding:10px;'>🔵 VOR SAMPLE PRICE + DATE CALC</div>";
flush(); ob_flush();
}
$today = getdate();
$today = strtotime($today['year'].'-'.$today['mon'].'-'.$today['mday']);
if (isset($_GET['debug_performance'])) {
echo "<div style='background:lime;color:black;padding:10px;'>✅ DATE CALC FERTIG - today: " . date('Y-m-d', $today) . "</div>";
flush(); ob_flush();
}
// TODO: IS ORDERABLE
if ($for_frontend) {
if ($obj->shippable == '2') {
if ($obj->available_from != '' && $obj->available_from != '0000-00-00') {
$startDate = strtotime($obj->available_from);
if ($obj->available_till != '' && $obj->available_till != '0000-00-00') {
// from - till
$stopDate = strtotime($obj->available_till);
if ($today > $startDate && $today < $stopDate) {
$obj->shippable = 1;
} else {
$obj->shippable = 0;
}
} else {
// from - no till
if ($today > $startDate) {
$obj->shippable = 1;
} else {
//$obj->shippable = 0;
}
}
} else {
// no from - till not checked
$obj->shippable = 0;
}
}
}
// Description Tab
$obj->detail_description = str_ireplace(
array("\r", "\n", "\r\n", "\t"), '', $obj->detail_description
);
if (isset($this->base_object->config->shopConfiguration['item_multi_description']) && $this->base_object->config->shopConfiguration['item_multi_description']) {
$description_array = explode('[tab=', $obj->detail_description);
$tab_title = array();
$tab_content = array();
if (is_array($description_array)) {
foreach ($description_array as $key => $desc) {
if (strpos($desc, ']')) {
$sign_pos = strpos($desc, ']');
$tab_title[$key] = substr($desc, 0, $sign_pos);
$tab_content[$key] = substr($desc, $sign_pos + 1);
}
}
$obj->tab_title = $tab_title;
$obj->tab_content = $tab_content;
}
}
if (isset($_GET['debug_performance'])) {
echo "<div style='background:orange;color:black;padding:10px;'>🟠 VOR TAB CONTENT CHECK</div>";
flush(); ob_flush();
}
if (isset($obj->tab_content)) {
if (isset($_GET['debug_performance'])) {
echo "<div style='background:yellow;color:black;padding:10px;'>⚠️ TAB CONTENT PROCESSING...</div>";
flush(); ob_flush();
}
/*foreach ($obj->tab_content as $tabKey => $tmpTab) {
$tidy = new tidy;
$tidy->parseString($tmpTab, array(
'output-xhtml' => true,
'show-body-only' => true
));
$tidy->cleanRepair();
$obj->tab_content[$tabKey] = $tidy->value;
}*/
}
// Graduated prices
$obj->graduated_prices = array();
for ($i = 2; $i <= 30; ++$i) {
$tmpPrice = $obj->{'price_'.$i};
$tmpBargain = $obj->{'bargain_price_'.$i};
$tmpQuantity = $obj->{'quantity_'.$i};
$tmpBargainTax = 0;
$tmpBargainTaxPrice = 0;
if ($tmpPrice > 0) {
// calc tax
$tmpTax = round($tmpPrice * ($obj->tax / 100), 4);
$tmpTaxPrice = $tmpPrice + $tmpTax;
if ($tmpBargain > 0) {
$tmpBargainTax = round($tmpBargain * ($obj->tax / 100), 4);
$tmpBargainTaxPrice = $tmpBargain + $tmpBargainTax;
}
// calc sample price
$tmpSamplePriceNet = 0;
$tmpSamplePriceGross = 0;
// intelectra base price calc
if ($obj->attribute_11 && $obj->attribute_15) {
$obj->sample_unit = $obj->attribute_15;
if ($tmpBargain > 0) {
if (strstr($obj->sample_unit, '100')) {
$tmpSamplePriceNet = $tmpBargain / ($obj->attribute_11 * 10);
$tmpSamplePriceGross = $tmpBargainTaxPrice / ($obj->attribute_11 * 10);
}
else {
$tmpSamplePriceNet = $tmpBargain / $obj->attribute_11;
$tmpSamplePriceGross = $tmpBargainTaxPrice / $obj->attribute_11;
}
} else {
if (strstr($obj->sample_unit, '100')) {
$tmpSamplePriceNet = $tmpPrice / ($obj->attribute_11 * 10);
$tmpSamplePriceGross = $tmpTaxPrice / ($obj->attribute_11 * 10);
}
else {
$tmpSamplePriceNet = $tmpPrice / $obj->attribute_11;
$tmpSamplePriceGross = $tmpTaxPrice / $obj->attribute_11;
}
}
}
/*if ($obj->sample_unit && $obj->vpe_sampleprice_unit) {
if ($obj->price_je_vpe) {
if ($obj->vpe_amount) {
if ($tmpBargain > 0) {
$tmpSamplePriceNet = $tmpBargain / ($obj->vpe_sampleprice_unit * $obj->vpe_amount);
$tmpSamplePriceGross = $tmpBargainTaxPrice / ($obj->vpe_sampleprice_unit * $obj->vpe_amount);
} else {
$tmpSamplePriceNet = $tmpPrice / ($obj->vpe_sampleprice_unit * $obj->vpe_amount);
$tmpSamplePriceGross = $tmpTaxPrice / ($obj->vpe_sampleprice_unit * $obj->vpe_amount);
}
}
} else {
if ($tmpBargain > 0) {
$tmpSamplePriceNet = $tmpBargain / $obj->vpe_sampleprice_unit;
$tmpSamplePriceGross = $tmpBargainTaxPrice / $obj->vpe_sampleprice_unit;
} else {
$tmpSamplePriceNet = $tmpPrice / $obj->vpe_sampleprice_unit;
$tmpSamplePriceGross = $tmpTaxPrice / $obj->vpe_sampleprice_unit;
}
}
}*/
// shop price
if ($this->base_object->customer_group->show_tax) {
$obj->graduated_prices[$tmpQuantity] = array(
'price' => $tmpTaxPrice,
'samplePrice' => $tmpSamplePriceGross,
'bargain' => $tmpBargainTaxPrice,
'priceNet' => $tmpPrice,
'bargainNet' => $tmpBargain,
'priceGross' => $tmpTaxPrice,
'bargainGross' => $tmpBargainTaxPrice,
'samplePriceNet' => $tmpSamplePriceNet,
'samplePriceGross' => $tmpSamplePriceGross
);
} else {
$obj->graduated_prices[$tmpQuantity] = array(
'price' => $tmpPrice,
'samplePrice' => $tmpSamplePriceNet,
'bargain' => $tmpBargain,
'priceNet' => $tmpPrice,
'bargainNet' => $tmpBargain,
'priceGross' => $tmpTaxPrice,
'bargainGross' => $tmpBargainTaxPrice,
'samplePriceNet' => $tmpSamplePriceNet,
'samplePriceGross' => $tmpSamplePriceGross
);
}
}
}
// Assigned items (additional items)
if (isset($_GET['debug_performance'])) {
echo "<div style='background:pink;color:black;padding:10px;'>🎀 VOR ASSIGNED ITEMS</div>";
flush(); ob_flush();
}
$customer_object = new Customer_group($this->base_object);
$customer_price_group_id = $customer_object->get_group_price_id($forCustomerGroup);
$obj->assignedItemSet = $this->get_assigned_items_new($this->id, $customer_price_group_id, 1);
if (isset($_GET['debug_performance'])) {
echo "<div style='background:red;color:white;padding:10px;'>";
echo "🔴 ASSIGNED ITEMS CHECK:<br>";
echo "obj->parent_id = [" . var_export($obj->parent_id, true) . "]<br>";
echo "assignedItemSet = " . (empty($obj->assignedItemSet) ? 'EMPTY' : 'HAS_DATA') . "<br>";
echo "</div>";
flush(); ob_flush();
}
if ($obj->parent_id && $obj->parent_id != '0' && $obj->parent_id > 0 && !$obj->assignedItemSet) {
// get parent assigned items if no variant assigned items
$obj->parent_assignedItemSet = $this->get_assigned_items_new($obj->parent_id, $customer_price_group_id, 1);
}
if (isset($_GET['debug_performance'])) {
echo "<div style='background:cyan;color:black;padding:10px;'>🔵 NACH ASSIGNED ITEMS 1 - Weiter zu Items 2</div>";
flush(); ob_flush();
}
// Assigned items 2 (spare parts)
$obj->assignedItemSet2 = $this->get_assigned_items($this->id, $customer_price_group_id, 2);
if ($obj->parent_id && $obj->parent_id != '0' && $obj->parent_id > 0 && !$obj->assignedItemSet2) {
// get parent assigned items if no variant assigned items
$obj->parent_assignedItemSet2 = $this->get_assigned_items($obj->parent_id, $customer_price_group_id, 2);
}
// Assigned items 5 (spare parts)
$obj->assignedItemSet5 = $this->get_assigned_items($this->id, $customer_price_group_id, 2);
if ($obj->parent_id && $obj->parent_id != '0' && $obj->parent_id > 0 && !$obj->assignedItemSet5) {
// get parent assigned items if no variant assigned items
$obj->parent_assignedItemSet5 = $this->get_assigned_items($obj->parent_id, $customer_price_group_id, 2);
}
if (isset($_GET['debug_performance'])) {
echo "<div style='background:magenta;color:white;padding:10px;'>🟣 NACH ASSIGNED ITEMS 2+5 - 2 Schritte vor!</div>";
flush(); ob_flush();
}
// Assigned items 3 (real friends)
$obj->assignedItemSet3 = $this->get_assigned_items($this->id, $customer_price_group_id, 3);
if ($obj->parent_id && $obj->parent_id != '0' && $obj->parent_id > 0 && !$obj->assignedItemSet3) {
// get parent assigned items if no variant assigned items
$obj->parent_assignedItemSet3 = $this->get_assigned_items($obj->parent_id, $customer_price_group_id, 3);
}
// shipping costs
if ($obj->shipping_cost_type == 2) {
$sql = "SELECT * FROM item_shipping_costs WHERE item_id = ".intval($this->id);
$result = $this->db->query($sql);
$obj->shipping_area_costs = array();
while ($obj_shipping = $result->fetch_object()) {
$obj->shipping_area_costs[$obj_shipping->shipping_area_id] = $obj_shipping;
}
}
if (isset($_GET['debug_performance'])) {
echo "<div style='background:orange;color:black;padding:10px;'>🟠 NACH SHIPPING COSTS - Fast am Ende!</div>";
flush(); ob_flush();
}
// Include individual for intelectra
if (isset($_GET['debug_performance'])) {
echo "<div style='background:yellow;color:black;padding:10px;'>⚠️ VOR INCLUDE IF-CHECK</div>";
echo "<div style='background:cyan;color:black;padding:10px;'>";
echo "📊 INCLUDE VARIABLEN:<br>";
echo "this->base_object = " . (isset($this->base_object) ? 'EXISTS' : 'NULL') . "<br>";
echo "config = " . (isset($this->base_object->config) ? 'EXISTS' : 'NULL') . "<br>";
echo "shopConfiguration = " . (isset($this->base_object->config->shopConfiguration) ? 'EXISTS' : 'NULL') . "<br>";
echo "custom_global_modules = [" . var_export($this->base_object->config->shopConfiguration['custom_global_modules'] ?? 'NOT_SET', true) . "]<br>";
echo "ROOT_DIR = [" . var_export(defined('ROOT_DIR') ? ROOT_DIR : 'NOT_DEFINED', true) . "]<br>";
echo "SHOP_SYSTEM = [" . var_export(defined('SHOP_SYSTEM') ? SHOP_SYSTEM : 'NOT_DEFINED', true) . "]<br>";
$include_path = ROOT_DIR.'web/'.SHOP_SYSTEM.'/php/intelectra_item_additional.inc.php';
echo "INCLUDE PATH = [" . $include_path . "]<br>";
echo "FILE EXISTS = " . (file_exists($include_path) ? 'YES' : 'NO') . "<br>";
echo "</div>";
flush(); ob_flush();
}
if (isset($this->base_object->config->shopConfiguration['custom_global_modules']) && $this->base_object->config->shopConfiguration['custom_global_modules']) {
if (isset($_GET['debug_performance'])) {
echo "<div style='background:pink;color:black;padding:10px;'>💗 INCLUDE IF-CHECK = TRUE</div>";
flush(); ob_flush();
}
$shopArticle = $obj; // Fix: Define $shopArticle for the include
if (isset($_GET['debug_performance'])) {
echo "<div style='background:red;color:white;padding:10px;'>🔥 VOR INCLUDE intelectra_item_additional.inc.php</div>";
flush(); ob_flush();
}
// REAKTIVIERT - Performance-optimiert durch Step-by-Step Query-Zerlegung!
include_once ROOT_DIR.'web/'.SHOP_SYSTEM.'/php/intelectra_item_additional.inc.php';
if (isset($_GET['debug_performance'])) {
echo "<div style='background:lime;color:black;padding:10px;'>✅ INCLUDE DEAKTIVIERT - Artikel sollte jetzt laden!</div>";
flush(); ob_flush();
}
if (isset($_GET['debug_performance'])) {
echo "<div style='background:lime;color:black;padding:10px;'>✅ NACH INCLUDE - Fast am Ende!</div>";
flush(); ob_flush();
}
}
if (isset($_GET['debug_performance'])) {
echo "<div style='background:gold;color:black;padding:10px;'>🏆 get_data() ERFOLGREICH BEENDET!</div>";
flush(); ob_flush();
die("🎉 SUCCESS! get_data() kam bis zum ENDE der Funktion!");
}
return $obj;
}
/**
* Generiert den Bilddateinamen basierend auf den Warnungsdaten
*
* @param array $warning Die Daten der Warnung
* @return string|null Der generierte Bilddateiname oder null, wenn kein Bild verfügbar ist
*/
private function generateImageFileName($warning) {
// Verwende "bilddateiname", wenn vorhanden
if (!empty($warning['bilddateiname'])) {
return $warning['bilddateiname'];
}
// Verwende "bildnr", wenn vorhanden
if (!empty($warning['bildnr'])) {
return $warning['bildnr'] . ".gif";
}
// Generiere basierend auf der Bildnummer
if (!empty($warning['bild'])) {
$baseName = "ISO_7010_";
$suffix = ".svg";
// Extrahiere die letzten 3 Ziffern der Bildnummer
$imageFileId = substr($warning['bild'], -4);
return $baseName . $imageFileId . $suffix;
}
// Kein Bild verfügbar
return null;
}
public function getPricesForCustomerGroup($customerGroup) {
$sql = "SELECT * FROM item_prices WHERE item_id = ".intval($this->id)." AND customergroup_id = ".intval($customerGroup);
$prices = $this->db->query($sql)->fetch_object();
return $prices;
}
public function getVariantPricesForCustomerGroup($customerGroup, $forAjax = false, $showTax = false, $taxValue = 0, $discount = 0, $for_frontend = true) {
$sql = "SELECT * FROM item_attribute_variants WHERE item_id = ".intval($this->id)." AND customergroup_id = ".intval($customerGroup);
$result = $this->db->query($sql);
$variant_data = array();
if ($forAjax) {
while ($obj_variants = $result->fetch_object()) {
if ($showTax && $taxValue > 0) {
$tmpTax = round($obj_variants->price * ($taxValue / 100), 2);
$obj_variants->price = round($obj_variants->price + $tmpTax, 2);
//$obj_variants->price = ($obj_variants->price / 100) * (100 + $taxValue);
}
$variant_data[$obj_variants->attribut1.'_'.$obj_variants->attribut2] = $obj_variants->price;
}
} else {
while ($obj_variants = $result->fetch_object()) {
if ($discount) {
$obj_variants->price = round(($obj_variants->price * (100 - $discount) / 100), 2);
$obj_variants->discount = $discount;
$obj_variants->discount_text = 'Rabatt!';
}
$tmpTax = round($obj_variants->price * ($taxValue / 100), 2);
$obj_variants->price_net = $obj_variants->price;
$obj_variants->price_gross = round($obj_variants->price + $tmpTax, 2);
//$obj_variants->price_gross = ($obj_variants->price / 100) * (100 + $taxValue);
if ($showTax && $taxValue > 0) {
$tmpTax = round($obj_variants->price * ($taxValue / 100), 2);
$obj_variants->price = round($obj_variants->price + $tmpTax, 2);
//$obj_variants->price = ($obj_variants->price / 100) * (100 + $taxValue);
}
$variant_data[$obj_variants->attribut1][$obj_variants->attribut2]['item_number'] = $obj_variants->item_number;
$variant_data[$obj_variants->attribut1][$obj_variants->attribut2]['manufacturer_item_number'] = $obj_variants->manufacturer_item_number;
$variant_data[$obj_variants->attribut1][$obj_variants->attribut2]['ek'] = $obj_variants->ek;
$variant_data[$obj_variants->attribut1][$obj_variants->attribut2]['price'] = $obj_variants->price;
$variant_data[$obj_variants->attribut1][$obj_variants->attribut2]['priceNet'] = $obj_variants->price_net;
$variant_data[$obj_variants->attribut1][$obj_variants->attribut2]['priceGross'] = $obj_variants->price_gross;
$variant_data[$obj_variants->attribut1][$obj_variants->attribut2]['taxes'] = $tmpTax;
$variant_data[$obj_variants->attribut1][$obj_variants->attribut2]['shippable'] = $obj_variants->shippable;
$variant_data[$obj_variants->attribut1][$obj_variants->attribut2]['inventory'] = $obj_variants->inventory;
$variant_data[$obj_variants->attribut1][$obj_variants->attribut2]['additional_charge'] = $obj_variants->additional_charge;
$tmpFrom = explode('-', $obj_variants->available_from);
if (count($tmpFrom) == 3) {
$variant_data[$obj_variants->attribut1][$obj_variants->attribut2]['available_from'] = $tmpFrom[2].'.'.$tmpFrom[1].'.'.$tmpFrom[0];
}
$tmpTill = explode('-', $obj_variants->available_till);
if (count($tmpTill) == 3) {
$variant_data[$obj_variants->attribut1][$obj_variants->attribut2]['available_till'] = $tmpTill[2].'.'.$tmpTill[1].'.'.$tmpTill[0];
}
$today = getdate();
$today = strtotime($today['year'].'-'.$today['mon'].'-'.$today['mday']);
// TODO: IS ORDERABLE
if ($for_frontend) {
if ($obj_variants->shippable == '2') {
if ($obj_variants->available_from != '' && $obj_variants->available_from != '0000-00-00') {
$startDate = strtotime($obj_variants->available_from);
if ($obj_variants->available_till != '' && $obj_variants->available_till != '0000-00-00') {
// from - till
$stopDate = strtotime($obj_variants->available_till);
if ($today > $startDate && $today < $stopDate) {
$variant_data[$obj_variants->attribut1][$obj_variants->attribut2]['shippable'] = 1;
} else {
$variant_data[$obj_variants->attribut1][$obj_variants->attribut2]['shippable'] = 0;
}
} else {
// from - no till
if ($today > $startDate) {
$variant_data[$obj_variants->attribut1][$obj_variants->attribut2]['shippable'] = 1;
} else {
//$variant_data[$obj_variants->attribut1][$obj_variants->attribut2]['shippable'] = 0;
}
}
} else {
// no from - till not checked
$variant_data[$obj_variants->attribut1][$obj_variants->attribut2]['shippable'] = 0;
}
}
}
}
}
return array_reverse($variant_data, true);
}
// TODO: (sh 2011-05-30 mit absprache von jd)
// kopie von "getVariantPricesForCustomerGroup()", die daten werden fuer die artikeldetailansicht benoetigt.
public function getVariantPricesForArticleDetails($customerGroup, $attribut1, $attribut2) {
$sql = "
SELECT
price, shippable, DATE_FORMAT(available_from, '%e.%c.%Y') AS available_date, available_from
FROM
item_attribute_variants
WHERE
item_id = ".$this->id."
AND
customergroup_id = ".$customerGroup."
AND
TRIM(attribut1) LIKE '".trim($attribut1)."'
AND
TRIM(attribut2) LIKE '".trim($attribut2)."'
";
$result = $this->db->query($sql);
$variant_data = $result->fetch_object();
return $variant_data;
}
public function create($data, $priceData = false) {
if ($data) {
if (isset($data['short_uri'])) {
if (!$data['short_uri']) {
$data['short_uri'] = $data['name'];
}
$data['short_uri'] = $this->short_uri($data['short_uri']);
}
$sql = "INSERT INTO items SET ";
if ($data['schema_id']) {
$schema_data = $this->itemschema_object->get_data($data['schema_id']);
if ($schema_data->selectable_attribute_1) {
$data['attribute_'.$schema_data->selectable_attribute_1] = str_replace(' ', '', $data['attribute_'.$schema_data->selectable_attribute_1]);
}
if ($schema_data->selectable_attribute_2) {
$data['attribute_'.$schema_data->selectable_attribute_2] = str_replace(' ', '', $data['attribute_'.$schema_data->selectable_attribute_2]);
}
}
foreach ($data as $var_name => $value) {
$value = $this->db->real_escape_string($value);
if ($this->item_fields[$var_name] == 'integer') {
$sql .= $var_name.' = '.$value.', ';
} else if ($this->item_fields[$var_name] == 'date') {
if (preg_match("/^(\d{2})\.(\d{2})\.(\d{4})$/", $value, $matches)) {
$tmpVal = $matches[3].'-'.$matches[2].'-'.$matches[1];
} else {
$tmpVal = '0000-00-00';
}
$sql .= $var_name.'="'.$tmpVal.'", ';
} else if ($this->item_fields[$var_name] == 'float') {
$sql .= $var_name.'="'.number_format((float) $value, 4, '.', '').'", ';
} else {
$sql .= $var_name.' = "'.$value.'", ';
}
}
$sql .= " quantity_1 = '1', ";
$sql .= " price_1 = '".number_format($priceData['prices']['price_1'],4,'.','')."', ";
$sql .= " bargain_price_1 = '".number_format($priceData['prices']['bargain_price_1'],4,'.','')."' ";
$this->db->query($sql);
$this->id = $this->db->insert_id;
// save prices
if ($priceData) {
$this->replace_prices($priceData);
}
// save assigned items
$this->saveAssignedItems(1);
$this->saveAssignedItems(2);
$this->saveAssignedItems(3);
$this->_assignToStructures($_POST['assigned_structures']);
return $this->id;
}
return false;
}
function short_uri($short_uri, $id = false) {
$short_uri = str_replace(array('ä', 'Ä', 'ö', 'Ö', 'ü', 'Ü', 'ß'), array('ae', 'Ae', 'oe', 'Oe', 'ue', 'Ue', 'ss'), $short_uri);
$short_uri = preg_replace("@[^0-9aA-zZ\-]@si", "-", $short_uri);
$short_uri = preg_replace("@(-{2,})@si", "-", $short_uri);
$new_uri = '';
$old_uri = $short_uri;
$i = 0;
while ($new_uri == '') {
if ($id) {
$sql = "SELECT id FROM items WHERE short_uri = '$short_uri' AND id != $id";
} else {
$sql = "SELECT id FROM items WHERE short_uri = '$short_uri'";
}
$result = $this->db->query($sql);
if ($result->num_rows == 0) {
$new_uri = $short_uri;
} else {
$i++;
$short_uri = $old_uri.'_'.$i;
}
}
return $new_uri;
}
public function sort_image_list($list) {
$counter = 1;
$picQueryParts = array();
foreach ($list as $pic_id) {
++$counter;
$pic_id = str_replace('picelementContainer_', '', $pic_id);
if ($counter == 2) {
$default_image = $pic_id;
}
$picQueryParts[] = '('.$pic_id.', '.$counter.')';
}
$this->db->query("CREATE TEMPORARY TABLE tmp_item_files ( id INT, pos INT )");
$this->db->query("INSERT INTO tmp_item_files (id, pos) VALUES ".implode(', ', $picQueryParts));
$result = $this->db->query("
UPDATE
item_files i,
tmp_item_files i_tmp
SET
i.rang = i_tmp.pos
WHERE
i.id = i_tmp.id
AND
i.item_id = ".$this->id."
");
return $sql = $this->set_default_image($default_image);
}
public function set_default_image($image_id) {
$sql = "UPDATE items i
SET i.default_image_file_name = (SELECT f.file_name FROM item_files f WHERE f.id = ".$this->db->real_escape_string($image_id).")
WHERE i.id=".$this->db->real_escape_string($this->id);
$this->db->query($sql);
return $sql;
}
public function delete_file($file_id, $id = false) {
// get pic infos
$sql = "SELECT * FROM item_files WHERE id=".$this->db->real_escape_string($file_id);
$result = $this->db->query($sql);
if ($result) {
$obj = $result->fetch_object();
if ($obj->type == '0') {
// unlink all the files with prefixes
foreach ($this->base_object->config->shopConfiguration['images'] as $image) {
$filename = $image[0].$obj->file_name;
$filepath = $_SERVER['DOCUMENT_ROOT'].'/web/'.SHOP_SYSTEM.'/images/article/'.$filename;
if (file_exists($filepath)) {
@unlink($filepath);
}
}
// unlink the original
$filename = $obj->file_name;
$filepath = $_SERVER['DOCUMENT_ROOT'].'/web/'.SHOP_SYSTEM.'/images/article/'.$filename;
if (file_exists($filepath)) {
@unlink($filepath);
}
} else if ($obj->type == '1') {
$filepath = $_SERVER['DOCUMENT_ROOT'].'/web/'.SHOP_SYSTEM.'/documents/article/'.$obj->file_name;
if (file_exists($filepath)) {
@unlink($filepath);
}
// update state in item table
$item_id = ($id) ? $id : $this->id;
$sql = "SELECT
count(*) AS num
FROM
item_files
WHERE
type = 1 AND
id!=".$this->db->real_escape_string($file_id)." AND
item_id=".$this->db->real_escape_string($item_id);
$result = $this->db->query($sql);
if ($result->fetch_object()->num == 0) {
$query = "UPDATE items SET has_documents = 0 WHERE id = '".$this->db->real_escape_string($item_id)."'";
$this->db->query($query);
}
}
$sql = "DELETE FROM item_files WHERE id=".$this->db->real_escape_string($file_id);
if ($id) {
$sql .= " AND item_id=".$this->db->real_escape_string($id);
$this->id = $id;
} else if ($this->id) {
$sql .= " AND item_id=".$this->db->real_escape_string($this->id);
} else {
// TODO: log and set error
// DELETE wird trotzdem ausgeführt (nur ohne item_id Constraint)
}
return $this->db->query($sql);
}
// TODO log and set error
return false;
}
// end delete_file
// FIXME: put function to generate scaled images into its own function
// so that it can be called seperately to regenerate all shop
public function add_uploaded_file($file_data, $watermark_activ = false) {
// DEBUG LOGGING
$debug_log = '/var/www/vhosts/intelectra.de/httpdocs/logs/upload_debug.log';
$start = microtime(true);
file_put_contents($debug_log, date('Y-m-d H:i:s') . " [ADD_FILE] START\n", FILE_APPEND);
$tempFile = $file_data['Filedata']['tmp_name'];
// is file a image
$file_info = getimagesize($tempFile);
file_put_contents($debug_log, date('Y-m-d H:i:s') . " [ADD_FILE] getimagesize done: " . round((microtime(true)-$start)*1000,2) . "ms\n", FILE_APPEND);
if (isset($file_info[2]) && $file_info[2] > 0 && $file_info[2] < 4) {
// 🚀 FIX: Async Python Image Processing Service - verhindert 504 Timeouts
// Generate filename FIRST before async processing
$targetPath = $_SERVER['DOCUMENT_ROOT'].'/web/'.SHOP_SYSTEM.'/images/article/';
$image_type = array('', 'gif', 'jpg', 'png');
$file_id = md5(uniqid(rand(), TRUE));
$file_name = $file_id.'.'.$image_type[$file_info[2]];
$targetFile = str_replace('//', '/', $targetPath).$file_name;
// Move uploaded file IMMEDIATELY
move_uploaded_file($tempFile, $targetFile);
file_put_contents($debug_log, date('Y-m-d H:i:s') . " [ADD_FILE] move_uploaded_file done: " . round((microtime(true)-$start)*1000,2) . "ms\n", FILE_APPEND);
// Get picture count BEFORE async processing
$sql = "SELECT count( id ) AS image_count FROM item_files
WHERE item_id=".$this->db->real_escape_string($this->id);
$result = $this->db->query($sql);
file_put_contents($debug_log, date('Y-m-d H:i:s') . " [ADD_FILE] SELECT count done: " . round((microtime(true)-$start)*1000,2) . "ms\n", FILE_APPEND);
$picture_count = 1;
while ($obj = $result->fetch_object()) {
$picture_count = $obj->image_count + 1;
}
// Save picture in database IMMEDIATELY
$sql = "INSERT INTO item_files (item_id, file_name, rang)
VALUES (".$this->db->real_escape_string($this->id).", '".
$this->db->real_escape_string($file_name)."', ".
$this->db->real_escape_string($picture_count).")";
$this->db->query($sql);
file_put_contents($debug_log, date('Y-m-d H:i:s') . " [ADD_FILE] INSERT done: " . round((microtime(true)-$start)*1000,2) . "ms\n", FILE_APPEND);
// Update default image
$sql = "UPDATE items i
SET i.default_image_file_name = (SELECT f.file_name FROM item_files f WHERE f.item_id = ".$this->db->real_escape_string($this->id)." ORDER BY rang LIMIT 1)
WHERE i.id=".$this->db->real_escape_string($this->id);
$this->db->query($sql);
file_put_contents($debug_log, date('Y-m-d H:i:s') . " [ADD_FILE] UPDATE default_image done: " . round((microtime(true)-$start)*1000,2) . "ms\n", FILE_APPEND);
// 🔥 START ASYNC IMAGE PROCESSING (non-blocking!)
$this->startAsyncImageProcessing($targetFile, $file_name, $this->id, $watermark_activ);
file_put_contents($debug_log, date('Y-m-d H:i:s') . " [ADD_FILE] startAsyncImageProcessing done: " . round((microtime(true)-$start)*1000,2) . "ms\n", FILE_APPEND);
// ✅ Return IMMEDIATELY - no waiting!
return true;
} else {
// save to article documents
$file_name = $file_data['Filedata']['name'];
}
return;
}
public function add_uploaded_pdf($file_data) {
$tempFile = $file_data['Filedata']['tmp_name'];
$targetPath = $_SERVER['DOCUMENT_ROOT'].'/web/'.SHOP_SYSTEM.'/documents/article/';
$file_id = md5(uniqid(rand(), TRUE));
$file_name = $file_id.'.pdf';
// save article picture
$targetFile = str_replace('//', '/', $targetPath).$file_name;
move_uploaded_file($tempFile, $targetFile);
$size = filesize($targetFile);
$sql = "
INSERT INTO
item_files
(item_id, file_name, alt, rang, type, size)
VALUES (
".$this->db->real_escape_string($this->id).",
'".$this->db->real_escape_string($file_name)."',
'".$this->db->real_escape_string($file_data['Filedata']['name'])."',
0,
1,
'".$size."'
)
";
$result = $this->db->query($sql);
if ($result) {
// update state in item table
$query = "UPDATE items SET has_documents = 1 WHERE id = '".$this->id;
$this->db->query($query);
$return_object = new stdClass();
$return_object->id = $this->db->insert_id;
$return_object->item_id = $this->id;
$return_object->file_name = $file_name;
$return_object->path = str_replace('//', '/', './web/'.SHOP_SYSTEM.'/documents/article/');
$return_object->alt = $file_data['Filedata']['name'];
return $return_object;
}
return false;
}
public function get_file_list($type = false, $id = false) {
if (!$id) {
$id = $this->id;
}
$id = intval($id);
if ($type === 0) {
$sql = "SELECT * FROM item_files WHERE item_id=".intval($id)." AND type=0 ORDER BY rang";
} else if ($type) {
$sql = "SELECT * FROM item_files WHERE item_id=".intval($id)." AND type=".intval($type)." ORDER BY rang";
} else {
$sql = "SELECT * FROM item_files WHERE item_id=".intval($id)." ORDER BY rang";
}
$result = $this->db->query($sql);
$data = array();
if ($result->num_rows > 0) {
while ($obj = $result->fetch_object()) {
$data[] = $obj;
}
} else {
$data = false;
}
return $data;
}
public function update($data, $priceData = false) {
if ($data) {
// If no primary structure assigned
if ((!isset($data['structure_id']) || !is_numeric($data['structure_id'])) && isset($_POST['assigned_structures']) && is_array($_POST['assigned_structures'])) {
$data['structure_id'] = current($_POST['assigned_structures']);
reset($_POST['assigned_structures']);
}
if (isset($data['short_uri'])) {
if (!$data['short_uri']) {
$data['short_uri'] = $data['name'];
}
$data['short_uri'] = $this->short_uri($data['short_uri'], $this->id);
}
$schema_data = $this->itemschema_object->get_data($data['schema_id']);
$sql = "UPDATE items SET ";
if ($data['schema_id']) {
$schema_data = $this->itemschema_object->get_data($data['schema_id']);
if ($schema_data->selectable_attribute_1) {
$data['attribute_'.$schema_data->selectable_attribute_1] = str_replace(' ', '', $data['attribute_'.$schema_data->selectable_attribute_1]);
}
if ($schema_data->selectable_attribute_2) {
$data['attribute_'.$schema_data->selectable_attribute_2] = str_replace(' ', '', $data['attribute_'.$schema_data->selectable_attribute_2]);
}
}
/*$data['attribute_'.$schema_data->selectable_attribute_1] = str_replace(' ', '', $data['attribute_'.$schema_data->selectable_attribute_1]);
$data['attribute_'.$schema_data->selectable_attribute_2] = str_replace(' ', '', $data['attribute_'.$schema_data->selectable_attribute_2]);*/
foreach ($data as $var_name => $value) {
$value = $this->db->real_escape_string($value);
if ($this->item_fields[$var_name] == 'integer') {
$sql .= $var_name.'='.$value.', ';
} else if ($this->item_fields[$var_name] == 'float') {
$sql .= $var_name.'='.floatval($value).', ';
} else if ($this->item_fields[$var_name] == 'date') {
if (preg_match("/^(\d{2})\.(\d{2})\.(\d{4})$/", $value, $matches)) {
$tmpVal = $matches[3].'-'.$matches[2].'-'.$matches[1];
} else {
$tmpVal = '0000-00-00';
}
$sql .= $var_name.'="'.$tmpVal.'", ';
} else {
$sql .= $var_name.'="'.$value.'", ';
}
}
/*$sql .= " quantity_1 = '1', ";
$sql .= " price_1 = '".$priceData['prices']['price_1']."', ";
$sql .= " bargain_price_1 = '".$priceData['prices']['bargain_price_1']."', ";*/
$sql = substr($sql, 0, -2);
$sql .= ' WHERE id='.$this->id;
$this->db->query($sql);
if ($this->db->error) {
$log_object = Logger::get_instance();
$log_object->info('Error in /core/main_class.php->get_list_items()', $this->db->error.', sql:'.$sql);
$count = 0;
}
// save variants
/*if ($priceData['customerGroup']) {
$this->update_variants($priceData['customerGroup'], $data, $priceData);
}*/
// save prices
if ($priceData) {
$this->replace_prices($priceData);
}
// save assigned items
$this->saveAssignedItems(1);
$this->saveAssignedItems(2);
$this->saveAssignedItems(3);
// save shipping costs
$this->save_shipping_costs();
// Assign to structures
$this->_assignToStructures($_POST['assigned_structures']);
// update variant items
include('./core/item_variant_schema.inc.php');
foreach ($item_fields as $field => $state) {
if ($state == 0) {
$value = $this->db->real_escape_string($data[$field]);
$sql = "UPDATE items SET ".$field."='".$value."'";
$sql .= ' WHERE parent_id='.$this->id;
$this->db->query($sql);
}
}
$this->update_last_change();
}
return;
}
private function save_shipping_costs() {
$shipping_ids = $_POST['item_shipping_id'];
$item_shipping_price = $_POST['item_shipping_price'];
if (isset($shipping_ids) && isset($item_shipping_price)) {
// delete old prices
$sql = "
DELETE FROM
item_shipping_costs
WHERE
item_id = ".$this->id."
";
$this->db->query($sql);
// insert new shipping prices
for ($i = 0; $i < count($shipping_ids); $i++) {
$sql = "
INSERT INTO item_shipping_costs
(item_id, shipping_area_id, price)
VALUES
(".$this->id.", ".$this->db->real_escape_string($shipping_ids[$i]).", '".$this->db->real_escape_string(str_replace(';', ', ', $item_shipping_price[$i]))."')";
$this->db->query($sql);
}
}
}
private function replace_prices($priceData) {
// ⚡ PERFORMANCE FIX: Nur aufrufen wenn tatsächlich Preis-Daten vorhanden!
// Verhindert 504 Timeout bei Kurz-URL Updates etc.
if (!isset($priceData['prices']) || empty($priceData['prices'])) {
return true; // Keine Preise = nichts zu tun = success
}
// 🚀 Python Smart Price Update Service (Verhindert 50+ REPLACE INTO Abfragen!)
$python_result = $this->callPythonPriceService($priceData);
if ($python_result && isset($python_result['success']) && $python_result['success']) {
// Python Service erfolgreich
if (isset($_GET['debug_performance'])) {
$changes = $python_result['groups_updated'] ?? 0;
echo "<div style='background:lime;padding:5px;'>🐍 PYTHON PRICE SERVICE: {$changes} Gruppen aktualisiert</div>";
}
return true;
}
// 🔄 FALLBACK: Original PHP-Code (Legacy-Support)
if (isset($_GET['debug_performance'])) {
echo "<div style='background:orange;padding:5px;'>⚠️ FALLBACK: PHP Price Update</div>";
}
$customerGroups_object = new Customer_group($this->base_object);
$customerGroups = $customerGroups_object->get_all_price_groups();
$groups = array();
foreach ($customerGroups as $group) {
if (is_array($priceData['prices']['group_'.$group->id])) {
$fields = array();
$values = array();
foreach ($priceData['prices']['group_'.$group->id] as $field => $value) {
$fields[] = $field;
$values[] = (float) $value;
}
$sql = "REPLACE INTO item_prices (item_id, customergroup_id, ".implode(',', $fields).")
VALUES (".$this->id.",".$group->id.",".implode(',', $values).")";
$this->db->query($sql);
}
}
}
// TODO:
/*private function update_variants($customerGroup, $item_data, $priceData) {
$sql = "DELETE FROM item_attribute_variants WHERE item_id = ".$this->id." AND customergroup_id = ".$customerGroup;
$this->db->query($sql);
$data = $this->get_data();
// enable transactions
$this->db->autocommit(false);
if (!$data->price_variants_2) {
$data->price_variants_2 = array('');
}
foreach ($data->price_variants_1 as $att1) {
$att1 = trim($att1);
foreach ($data->price_variants_2 as $att2) {
$att2 = trim($att2);
if ($item_data['variant_price_type'] == 0) {
$additional_charge = '0.00';
$price = $_POST['vprice'][$att1.'_'.$att2];
} else if ($item_data['variant_price_type'] == 1) {
$additional_charge = $_POST['variant_price_type'][$att1.'_'.$att2];
$old_price = 0;
if ($priceData['prices']['bargain_price_1'] > 0) {
$price = $additional_charge + $priceData['prices']['bargain_price_1'];
$old_price = $additional_charge + $priceData['prices']['price_1'];
}
else {
$price = $additional_charge + $priceData['prices']['price_1'];
}
}
$ek = $_POST['vek'][$att1.'_'.$att2];
$shippable = $_POST['vshippable'][$att1.'_'.$att2];
if ($_POST['vshippable'][$att1.'_'.$att2] == 2) {
$avFrom = '';
$tmpFrom = explode('.', $_POST['vlieferbar_ab'][$att1.'_'.$att2]);
if (count($tmpFrom) == 3) {
$avFrom = $tmpFrom[2].'-'.$tmpFrom[1].'-'.$tmpFrom[0];
}
$avTill = '';
$tmpTill = explode('.', $_POST['vlieferbar_bis'][$att1.'_'.$att2]);
if (count($tmpTill) == 3) {
$avTill = $tmpTill[2].'-'.$tmpTill[1].'-'.$tmpTill[0];
}
} else {
$avFrom = '';
$avTill = '';
}
$item_number = $_POST['item_number'][$att1.'_'.$att2];
$manufacturer_item_number = $_POST['manufacturer_item_number'][$att1.'_'.$att2];
$sql = "
INSERT INTO
item_attribute_variants (
item_id,
customergroup_id,
attribut1,
attribut2,
price,
old_price,
ek,
shippable,
available_from,
available_till,
inventory,
additional_charge,
item_number,
manufacturer_item_number
)
VALUES (
".$this->id.",
".$customerGroup.",
'".$att1."',
'".$att2."',
'".$price."',
'".$old_price."',
'".$ek."',
'".$shippable."',
'".$avFrom."',
'".$avTill."',
'".$inventory."',
'".$additional_charge."',
'".$item_number."',
'".$manufacturer_item_number."'
)";
$this->db->query($sql);
}
}
// commit transaction
$result = $this->db->commit();
// disable transactions
$this->db->autocommit(true);
}*/
public function delete() {
$sql = "DELETE FROM items WHERE id=".$this->id;
$this->db->query($sql);
$sql = "DELETE FROM item_prices WHERE item_id=".$this->id;
$this->db->query($sql);
$sql = "DELETE FROM item_attribute_variants WHERE item_id=".$this->id;
$this->db->query($sql);
return;
}
public function data_filter($request) {
$data = array();
foreach ($this->item_fields as $field_name => $var_type) {
if (isset($request[$field_name])) {
if ($var_type == 'text') {
$data[$field_name] = $request[$field_name];
} else if ($var_type == 'float') {
$request[$field_name] = str_replace(',', '.', $request[$field_name]);
$data[$field_name] = $request[$field_name];
} else if ($var_type == 'date') {
$data[$field_name] = $request[$field_name];
} else {
$data[$field_name] = (int) $request[$field_name];
}
}
}
return $data;
}
public function get_all_item_schemas() {
$sql = "SELECT * FROM item_schema";
$result = $this->db->query($sql);
$data = array();
while ($obj = $result->fetch_object()) {
$data[] = $obj;
}
return $data;
}
public function get_all_item_schema_paginated($items, $page, $order = false) {
$page -= 1;
$sql = "SELECT * FROM item_schema LIMIT $items OFFSET $page";
$result = $this->db->query($sql);
while ($obj = $result->fetch_object()) {
$data[] = $obj;
}
return $data;
}
// end get_all
public function get_schema_data() {
$sql = "SELECT * FROM item_schema WHERE id = ".$this->schema_id;
$result = $this->db->query($sql);
$schema = $result->fetch_object();
$attributes = array();
$sql = "SELECT * FROM item_schema_attributes WHERE schema_id = ".$this->schema_id." ORDER BY rang";
$result = $this->db->query($sql);
while ($obj = $result->fetch_object()) {
$attributes[] = $obj;
}
$schema->attributes = $attributes;
return $schema;
}
public function create_schema($data) {
if ($data) {
$sql = "INSERT INTO item_schema SET ";
foreach ($data as $var_name => $value) {
$value = $this->db->real_escape_string($value);
if ($this->schema_fields[$var_name] == 'integer') {
$sql .= $var_name.' = '.$value.', ';
} else {
$sql .= $var_name.' = "'.$value.'", ';
}
}
$sql = substr($sql, 0, -2);
$this->db->query($sql);
$this->schema_id = $this->db->insert_id;
if ($this->schema_id) {
for ($i = 1; $i < 21; $i++) {
$sql = "INSERT INTO item_schema_attributes (schema_id, number, rang) VALUES (".$this->schema_id.", ".$i.", ".$i.")";
$this->db->query($sql);
}
}
}
return;
}
public function update_schema($data) {
if ($data) {
$sql = "UPDATE item_schema SET name='".$data['name']."',
description='".$data['description']."',
selectable_attribute_1='".$data['selectable_attribute_1']."',
base_price_field='".$data['base_price_field']."',
base_price_faktor='".$data['base_price_faktor']."',
base_price_unit='".$data['base_price_unit']."',
selectable_attribute_2='".$data['selectable_attribute_2']."'
WHERE id=".$this->schema_id;
$this->db->query($sql);
$sql = "DELETE FROM item_schema_attributes WHERE schema_id=".$this->schema_id;
$this->db->query($sql);
// save attribute data
for ($i = 1; $i < 21; $i++) {
$show_list = ($data['attribute_liste_'.$i]) ? $data['attribute_liste_'.$i] : 0;
$show_detail = ($data['attribute_detail_'.$i]) ? $data['attribute_detail_'.$i] : 0;
$sql = "
INSERT INTO item_schema_attributes
(schema_id, number, name, name_en, unit, rang, show_list, show_detail)
VALUES
(".$this->schema_id.", $i, '".$data['attribute_name_'.$i]."', '".$data['attribute_name_'.$i.'_en']."', '".$data['attribute_unit_'.$i]."', ".$data['attribute_rang_'.$i].", ".$show_list.", ".$show_detail.")";
$this->db->query($sql);
}
}
return;
}
// end update_shema
public function delete_schema() {
$sql = "DELETE FROM item_schema_attributes WHERE schema_id=".$this->schema_id;
$this->db->query($sql);
$sql = "DELETE FROM item_schema WHERE id=".$this->schema_id;
$this->db->query($sql);
return;
}
public function schema_data_filter($request) {
$data = array();
foreach ($this->schema_fields as $field_name => $var_type) {
if (isset($request[$field_name])) {
if ($var_type == 'text') {
$data[$field_name] = $request[$field_name];
} else if ($var_type == 'float') {
$data[$field_name] = $request[$field_name];
} else {
$data[$field_name] = (int) $request[$field_name];
}
}
}
return $data;
}
public function search($data) {
$sql = 'SELECT * FROM items ';
$where = '';
// build clauses for manufacturer IDs that contain a specific substring
if (isset($data['manufacturer_search'])) {
$clause = 'manufacturer_id = ';
$manufacturer = new Manufacturer($this->base_object);
$results = $manufacturer->get_where_name_like($data['manufacturer_search']);
if ($results) {
foreach ($results as $result) {
if ($where == '') {
$where .= ' WHERE '.$clause.$result->id;
}
$where .= ' OR '.$clause.$result->id;
}
}
}
if (isset($data['text_search'])) {
if (isset($data['text_options'])) {
if (strpos($data['text_options'], ';')) {
$text_options = str_replace(';', ', ', $data['text_options']);
$clause = "CONCAT(".$text_options.") LIKE '%".$data['text_search']."%'";
}
$clause = $data['text_options']." LIKE '%".$data['text_search']."%'";
}
$clause = "name LIKE '%".$data['text_search']."%'";
$where = Database::where($where, $clause);
}
if (isset($data['numeric_search'])) {
if (isset($data['numeric_options'])) {
if (strpos($data['numeric_options'], ';')) {
$numeric_options = str_replace(';', ', ', $data['numeric_options']);
$clause = "CONCAT(".$numeric_options.") LIKE '%".$data['numeric_search']."%'";
}
$clause = $data['numeric_options']." LIKE '%".$data['numeric_search']."%'";
}
$clause = "number LIKE '%".$data['numeric_search']."%'";
$where = Database::where($where, $clause);
}
if (isset($data['limiting_options'])) {
// todo
$data['limiting_options'];
}
$result = $this->db->query($sql.$where);
while ($obj = $result->fetch_object()) {
$end[] = $obj;
}
return $end;
}
// end search
public function delete_by_id($id) {
$rs = $this->db->query("DELETE FROM items WHERE id=$id;");
$rs = $this->db->query("DELETE FROM item_files WHERE item_id=$id;");
}
public function set_active_by_id($id) {
$rs = $this->db->query("UPDATE items SET active=1 WHERE id=$id;");
}
public function set_inactive_by_id($id) {
$rs = $this->db->query("UPDATE items SET active=0 WHERE id=$id;");
}
public function copy() {
// copy standard data
$sql = "SELECT * FROM items WHERE id = ".intval($this->id);
$result = $this->db->query($sql);
$obj = $result->fetch_object();
if (!$obj->short_uri) {
$obj->short_uri = $obj->name;
}
$obj->short_uri = $this->short_uri($obj->short_uri);
$obj->name = 'Kopie von: '.$obj->name;
// create copy object
$sql = "INSERT INTO items SET ";
foreach ($this->item_fields as $key => $var_type) {
if ($var_type == 'integer') {
$obj->{$key} = (int) $obj->{$key};
} else if ($var_type == 'float' && $obj->{$key} == '') {
$obj->{$key} = 0.0;
} else if ($var_type == 'date' && $obj->{$key} == '') {
$obj->{$key} = '0000-00-00';
}
$sql .= $key." = '".$this->db->real_escape_string($obj->{$key})."', ";
}
$sql = substr($sql, 0, -2);
$this->db->query($sql);
/*echo $sql;
exit();*/
$new_id = $this->db->insert_id;
//copy prices
$sql = "SELECT * FROM item_prices WHERE item_id = ".intval($this->id);
$result = $this->db->query($sql);
$variant_data = array();
while ($obj = $result->fetch_object()) {
$sql = "INSERT INTO item_prices (item_id, customergroup_id";
for ($i = 1; $i < 31; $i++) {
$sql .= ", quantity_".$i.", price_".$i.", bargain_price_".$i;
}
$sql .= ") VALUES (".$new_id.", ".$obj->customergroup_id;
for ($i = 1; $i < 31; $i++) {
if ($obj->{'price_'.$i} == '') {
$obj->{'price_'.$i} = 0.0;
}
if ($obj->{'bargain_price_'.$i} == '') {
$obj->{'bargain_price_'.$i} = 0.0;
}
if ($obj->{'quantity_'.$i} == '') {
$obj->{'quantity_'.$i} = 0;
}
$sql .= ", ".$obj->{'quantity_'.$i}.", ".$obj->{'price_'.$i}.", ".$obj->{'bargain_price_'.$i};
}
$sql .= ")";
$this->db->query($sql);
}
// copy variant data
$sql = "SELECT * FROM item_attribute_variants WHERE item_id = ".intval($this->id);
$result = $this->db->query($sql);
$variant_data = array();
while ($obj = $result->fetch_object()) {
$sql = "INSERT INTO item_attribute_variants
(item_id, attribut1, attribut2, item_number, price, ek, shippable)
VALUES
(".$new_id.",'$obj->attribut1','$obj->attribut2','$obj->item_number','$obj->price','$obj->ek',$obj->shippable)
";
$this->db->query($sql);
}
// copy files
$sql = "SELECT * FROM item_files WHERE item_id = ".intval($this->id);
$result = $this->db->query($sql);
$variant_data = array();
$image_count = 0;
while ($obj = $result->fetch_object()) {
// old: $images = array('', 'thumb_', 'overview_', 'overview_2_', 'detail_');
$images = $this->base_object->config->shopConfiguration['images'];
foreach ($images as $image) {
$image_name = $image[0];
$filename = $image_name.$obj->file_name;
$new_filename = $image_name.$new_id.$obj->file_name;
copy($_SERVER['DOCUMENT_ROOT'].'/web/'.SHOP_SYSTEM.'/images/article/'.$filename, $_SERVER['DOCUMENT_ROOT'].'/web/'.SHOP_SYSTEM.'/images/article/'.$new_filename);
}
$image_count++;
$sql = "INSERT INTO item_files
(item_id, file_name, rang, type, description, attribut1, attribut2, alt)
VALUES
(".$new_id.", '".
$new_id.$obj->file_name."', '".
$obj->rang."', '".
$obj->type."', '".
$obj->description."', '".
$obj->attribut1."', '".
$obj->attribut2."', '".
$obj->alt."')";
$this->db->query($sql);
if ($image_count == 1) {
$sql = "UPDATE items
SET default_image_file_name = '".$this->db->real_escape_string($new_id.$obj->file_name )."'
WHERE id=".$new_id;
$result3 = $this->db->query($sql);
}
}
// copy assigned items
$sql = "SELECT * FROM item_item_assign WHERE item_parent_id = ".intval($this->id);
$result = $this->db->query($sql);
while ($obj = $result->fetch_object()) {
$sql = "INSERT INTO item_item_assign
(item_parent_id, item_child_id, type, position)
VALUES
(".$new_id.", '".$obj->item_child_id."', '".$obj->type."', '".$obj->position."')";
$this->db->query($sql);
}
// copy item structure assign
$sql = "SELECT * FROM item_structure_assign WHERE item_id = ".intval($this->id);
$result = $this->db->query($sql);
while ($obj = $result->fetch_object()) {
$sql = "INSERT INTO item_structure_assign
(item_id, structure_id, pos)
VALUES
(".$new_id.", '".$obj->structure_id."', '".$obj->pos."')";
$this->db->query($sql);
}
$this->id = $new_id;
return;
}
//UGLY HACK, KILL ME SOOOOOON the root is 3 in EMFA
protected function get_item_category_root() {
$sql = "SELECT id FROM structure WHERE short_uri = 'Warengruppen'";
$result = $this->db->query($sql);
if ($result->num_rows > 0) {
return $result->fetch_object()->id;
}
return false;
}
protected function get_all_item_categories($root = false) {
if (!$root) {
$root = $this->get_item_category_root();
}
$sql = "SELECT id, name, short_uri FROM structure WHERE parent_id=$root";
$result = $this->db->query($sql);
if ($result->num_rows > 0) {
while ($obj = $result->fetch_object()) {
$id = $obj->id;
$data[] = $obj;
$children = $this->get_all_item_categories($id);
if ($children) {
foreach ($children as $child) {
$data[] = $child;
}
}
}
return $data;
}
return false;
}
public function get_item_category_assoc_array() {
$categories = $this->get_all_item_categories();
foreach ($categories as $category) {
$data[$category->id] = $category->short_uri;
}
return $data;
}
public function get_item_list($structure_id, $itemsPerPage = 'all', $currentPage = 1, $activeOnly = false, $fromManufacturerOnly = false, $sort_by = false) {
$manufacturers = Manufacturer::get_name_id_pair();
$limited = false;
if (is_numeric($itemsPerPage)) {
$limitMax = $itemsPerPage;
$limited = true;
}
if (is_numeric($currentPage)) {
$limitMin = $currentPage * $limitMax - $limitMax;
} else {
$limitMin = 0;
}
$whereAdd = '';
if ($activeOnly) {
$whereAdd .= " AND i.active = 1 ";
}
if (is_numeric($fromManufacturerOnly)) {
$whereAdd .= " AND i.manufacturer_id = ".$fromManufacturerOnly;
}
$sql = "SELECT
count(id) AS num
FROM
items i
WHERE
(structure_id=".$this->db->real_escape_string($structure_id)."
OR
structure_id_2=".$this->db->real_escape_string($structure_id)."
OR
structure_id_3=".$this->db->real_escape_string($structure_id)."
OR
structure_id_4=".$this->db->real_escape_string($structure_id)."
OR
structure_id_5=".$this->db->real_escape_string($structure_id)."
OR
structure_id_6=".$this->db->real_escape_string($structure_id)."
OR
structure_id_7=".$this->db->real_escape_string($structure_id)."
OR
structure_id_8=".$this->db->real_escape_string($structure_id)."
OR
structure_id_9=".$this->db->real_escape_string($structure_id)."
OR
structure_id_10=".$this->db->real_escape_string($structure_id).")
$whereAdd";
$result = $this->db->query($sql);
$this->itemCount = $result->fetch_object()->num;
//probably the wrong place
$sql = "SELECT
i.*,
i.default_image_file_name AS file_name,
ip.price_1,
ip.bargain_price_1
FROM
item_prices ip
RIGHT JOIN
items i
ON
i.id=ip.item_id
AND
ip.customergroup_id=".$this->db->real_escape_string($this->base_object->customer_group->price_group_id)."
WHERE
(structure_id=".$this->db->real_escape_string($structure_id)."
OR
structure_id_2=".$this->db->real_escape_string($structure_id)."
OR
structure_id_3=".$this->db->real_escape_string($structure_id)."
OR
structure_id_4=".$this->db->real_escape_string($structure_id)."
OR
structure_id_5=".$this->db->real_escape_string($structure_id)."
OR
structure_id_6=".$this->db->real_escape_string($structure_id)."
OR
structure_id_7=".$this->db->real_escape_string($structure_id)."
OR
structure_id_8=".$this->db->real_escape_string($structure_id)."
OR
structure_id_9=".$this->db->real_escape_string($structure_id)."
OR
structure_id_10=".$this->db->real_escape_string($structure_id).")
$whereAdd
GROUP BY
i.id";
if ($sort_by) {
if ($sort_by == 'name_up') {
$sql .= " ORDER BY i.name ASC";
} else if ($sort_by == 'name_down') {
$sql .= " ORDER BY i.name DESC";
} else if ($sort_by == 'number_up') {
$sql .= " ORDER BY i.number ASC";
} else if ($sort_by == 'number_down') {
$sql .= " ORDER BY i.number DESC";
} else if ($sort_by == 'manufacturer_up') {
$sql .= " ORDER BY i.manufacturer_id ASC";
} else if ($sort_by == 'manufacturer_down') {
$sql .= " ORDER BY i.manufacturer_id DESC";
} else if ($sort_by == 'price_up') {
$sql .= " ORDER BY ip.price_1 ASC";
} else if ($sort_by == 'price_down') {
$sql .= " ORDER BY ip.price_1 DESC";
}
}
if ($limited) {
$sql .= " LIMIT ".$this->db->real_escape_string($limitMin).", ".$this->db->real_escape_string($limitMax);
}
$result = $this->db->query($sql);
$list = array();
$show_taxes = $this->base_object->customer_group->show_tax;
while ($obj = $result->fetch_object()) {
// get item discount
$discount = $this->get_item_discount(isset($this->base_object->customer_group->id) ? intval($this->base_object->customer_group->id) : 1, $obj->manufacturer_id, $obj->structure_id);
if ($discount) {
$obj->bargain_price_1 = round(($obj->price_1 * (100 - $discount) / 100), 2);
$obj->discount = $discount;
$obj->discount_text = 'Rabatt!';
}
// shop price
$obj->tax = $this->all_tax[$obj->tax_id]->steuersatz;
$obj->price_tax_text = str_replace('[tax]', $obj->tax, isset($this->base_object->customer_group->price_tax_text) ? $this->base_object->customer_group->price_tax_text : 'inkl. [tax]% MwSt.');
$obj->manufacturer_text = $manufacturers[$obj->manufacturer_id];
if ($show_taxes) {
$obj->tax_value = round($obj->price_1 * ($obj->tax / 100), 2);
$obj->shop_price_1 = $obj->price_1 + $obj->tax_value;
$obj->bargain_tax_value = round($obj->bargain_price_1 * ($obj->tax / 100), 2);
$obj->shop_bargain_price_1 = $obj->bargain_price_1 + $obj->bargain_tax_value;
} else {
$obj->shop_price_1 = $obj->price_1;
$obj->shop_bargain_price_1 = $obj->bargain_price_1;
}
// get schema data
$obj->schema_data_attributes = array();
if ($obj->schema_id) {
$this->schema_id = $obj->schema_id;
$obj->schema_data = $this->get_schema_data();
foreach ($obj->schema_data->attributes as $attribute) {
if ($attribute->name) {
$attr = array(
'name' => $attribute->name,
'unit' => $attribute->unit,
'value' => $obj->{'attribute_'.$attribute->number},
'show_detail' => $attribute->show_detail,
'show_list' => $attribute->show_list,
'number' => $attribute->number
);
$obj->schema_data_attributes[] = $attr;
}
if ($obj->schema_data->selectable_attribute_1 == $attribute->number) {
$obj->schema_data->selectable_name_1 = $attribute->name;
$obj->price_variants_1 = explode(';', $obj->{'attribute_'.$attribute->number});
}
if ($obj->schema_data->selectable_attribute_2 == $attribute->number) {
$obj->schema_data->selectable_name_2 = $attribute->name;
$obj->price_variants_2 = explode(';', $obj->{'attribute_'.$attribute->number});
}
}
}
if (!isset($list[$obj->id])) {
$list[$obj->id] = $obj;
}
}
return $list;
}
public function get_item_list_by_ids($ids, $itemsPerPage = 'all', $currentPage = 1, $activeOnly = false, $fromManufacturerOnly = false) {
$manufacturers = Manufacturer::get_name_id_pair();
if (is_numeric($itemsPerPage)) {
$limitMax = $itemsPerPage;
} else if ($itemsPerPage == 'all') {
$limitMax = 99999;
}
if (is_numeric($currentPage)) {
$limitMin = $currentPage * $limitMax - $limitMax;
} else {
$limitMin = 0;
}
$whereAdd = array();
if ($activeOnly) {
$whereAdd[] = " AND items.active = 1 ";
}
if (is_numeric($fromManufacturerOnly)) {
$whereAdd[] = " AND items.manufacturer_id = ".$fromManufacturerOnly;
}
$sqlCount = "SELECT items.id FROM items LEFT JOIN item_files ON item_files.item_id = items.id
WHERE (items.id IN (".implode(",", $ids)."))".implode(" ", $whereAdd)." GROUP BY items.id
ORDER BY items.number ASC, item_files.rang ASC";
$this->itemCount = $this->db->query($sqlCount)->num_rows;
$sql = "SELECT items.*, item_files.file_name, item_files.rang, item_prices.price_1, item_prices.bargain_price_1
FROM item_prices
RIGHT JOIN items ON items.id = item_prices.item_id AND
item_prices.customergroup_id = '".$this->base_object->customer_group->price_group_id."'
LEFT JOIN item_files ON item_files.item_id = items.id
WHERE items.id IN (".implode(",", $ids).")".implode(" ", $whereAdd)."
GROUP BY items.id
ORDER BY items.number ASC, item_files.rang ASC
LIMIT ".(int)$limitMin.", ".(int)$limitMax;
$result = $this->db->query($sql);
$list = array();
while ($obj = $result->fetch_object()) {
// TODO: HACK
//$item_category_assoc_array =
//$obj->item_category_short_uri =
// shop price
$obj->tax = $this->all_tax[$obj->tax_id]->steuersatz;
$obj->price_tax_text = str_replace('[tax]', $obj->tax, isset($this->base_object->customer_group->price_tax_text) ? $this->base_object->customer_group->price_tax_text : 'inkl. [tax]% MwSt.');
$obj->manufacturer_text = isset($this->manufacturers[$obj->manufacturer_id]) ? $this->manufacturers[$obj->manufacturer_id] : '';
$obj->manufacturer_data = isset($this->manufacturers[$obj->manufacturer_id]) ? $this->manufacturers[$obj->manufacturer_id] : null;
// get item discount
$discount = $this->get_item_discount(isset($this->base_object->customer_group->id) ? intval($this->base_object->customer_group->id) : 1, $obj->manufacturer_id, $obj->structure_id);
if ($discount) {
$obj->bargain_price_1 = round(($obj->price_1 * (100 - $discount) / 100), 2);
$obj->discount = $discount;
$obj->discount_text = 'Rabatt!';
}
if ($this->base_object->customer_group->show_tax) {
$obj->tax_value = round($obj->price_1 * ($obj->tax / 100), 2);
$obj->shop_price_1 = $obj->price_1 + $obj->tax_value;
$obj->bargain_tax_value = round($obj->bargain_price_1 * ($obj->tax / 100), 2);
$obj->shop_bargain_price_1 = $obj->bargain_price_1 + $obj->bargain_tax_value;
} else {
$obj->shop_price_1 = $obj->price_1;
$obj->shop_bargain_price_1 = $obj->bargain_price_1;
}
// get schema data
$obj->schema_data_attributes = array();
if ($obj->schema_id) {
$this->schema_id = $obj->schema_id;
$obj->schema_data = $this->get_schema_data();
foreach ($obj->schema_data->attributes as $attribute) {
if ($attribute->name) {
$attr = array(
'name' => $attribute->name,
'unit' => $attribute->unit,
'value' => $obj->{'attribute_'.$attribute->number},
'show_detail' => $attribute->show_detail,
'show_list' => $attribute->show_list,
'number' => $attribute->number
);
$obj->schema_data_attributes[] = $attr;
}
if ($obj->schema_data->selectable_attribute_1 == $attribute->number) {
$obj->schema_data->selectable_name_1 = $attribute->name;
$obj->price_variants_1 = explode(';', $obj->{'attribute_'.$attribute->number});
}
if ($obj->schema_data->selectable_attribute_2 == $attribute->number) {
$obj->schema_data->selectable_name_2 = $attribute->name;
$obj->price_variants_2 = explode(';', $obj->{'attribute_'.$attribute->number});
}
}
}
if (!isset($list[$obj->id])) {
$list[$obj->id] = $obj;
}
}
return $list;
}
public function get_all_items_list() {
$structure_object = new Structure($this->base_object);
$all_tree_full_path = $structure_object->get_all_tree_full_path(0, ' > ');
$manufacturers = Manufacturer::get_name_id_pair();
$limitMax = 10000;
$sqlCount = "SELECT items.id FROM items LEFT JOIN item_files ON item_files.item_id = items.id
WHERE items.active = 1 GROUP BY items.id ORDER BY items.number ASC, item_files.rang ASC";
$this->itemCount = $this->db->query($sqlCount)->num_rows;
$sql = "SELECT items.*, item_files.file_name, item_files.rang, item_prices.price_1, item_prices.bargain_price_1
FROM item_prices RIGHT JOIN items ON items.id = item_prices.item_id
AND item_prices.customergroup_id = '".$this->base_object->customer_group->price_group_id."'
LEFT JOIN item_files ON item_files.item_id = items.id
WHERE items.active = 1 GROUP BY items.id
ORDER BY items.number ASC, item_files.rang ASC LIMIT ".$limitMax;
$result = $this->db->query($sql);
$list = array();
while ($obj = $result->fetch_object()) {
// TODO: HACK
//$item_category_assoc_array =
//$obj->item_category_short_uri =
// shop price
$obj->tax = $this->all_tax[$obj->tax_id]->steuersatz;
$obj->price_tax_text = str_replace('[tax]', $obj->tax, isset($this->base_object->customer_group->price_tax_text) ? $this->base_object->customer_group->price_tax_text : 'inkl. [tax]% MwSt.');
$obj->manufacturer_text = $manufacturers[$obj->manufacturer_id];
// get item discount
$discount = $this->get_item_discount(isset($this->base_object->customer_group->id) ? intval($this->base_object->customer_group->id) : 1, $obj->manufacturer_id, $obj->structure_id);
if ($discount) {
$obj->bargain_price_1 = round(($obj->price_1 * (100 - $discount) / 100), 2);
$obj->discount = $discount;
$obj->discount_text = 'Rabatt!';
}
if ($this->base_object->customer_group->show_tax) {
$obj->tax_value = round($obj->price_1 * ($obj->tax / 100), 2);
$obj->shop_price_1 = $obj->price_1 + $obj->tax_value;
$obj->bargain_tax_value = round($obj->bargain_price_1 * ($obj->tax / 100), 2);
$obj->shop_bargain_price_1 = $obj->bargain_price_1 + $obj->bargain_tax_value;
} else {
$obj->shop_price_1 = $obj->price_1;
$obj->shop_bargain_price_1 = $obj->bargain_price_1;
}
// get schema data
$obj->schema_data_attributes = array();
if ($obj->schema_id) {
$this->schema_id = $obj->schema_id;
$obj->schema_data = $this->get_schema_data();
foreach ($obj->schema_data->attributes as $attribute) {
if ($attribute->name) {
$attr = array(
'name' => $attribute->name,
'unit' => $attribute->unit,
'value' => $obj->{'attribute_'.$attribute->number},
'show_detail' => $attribute->show_detail,
'show_list' => $attribute->show_list,
'number' => $attribute->number
);
$obj->schema_data_attributes[] = $attr;
}
if ($obj->schema_data->selectable_attribute_1 == $attribute->number) {
$obj->schema_data->selectable_name_1 = $attribute->name;
$obj->price_variants_1 = split(';', $obj->{'attribute_'.$attribute->number});
}
if ($obj->schema_data->selectable_attribute_2 == $attribute->number) {
$obj->schema_data->selectable_name_2 = $attribute->name;
$obj->price_variants_2 = split(';', $obj->{'attribute_'.$attribute->number});
}
}
}
if (!isset($list[$obj->id])) {
$list[$obj->id] = $obj;
}
if ($obj->structure_id) {
$obj->structure_data = $all_tree_full_path[$obj->structure_id];
}
}
return $list;
}
// end get_all_paginated
private function match_by_string($data) {
$data = preg_replace("@(\s){2,}@si", " ", $data);
$data = trim($data);
$data = explode(' ', $data);
$match = '';
foreach ($data as $point) {
if ($match == '') {
$match = " HAVING search_field LIKE '%$point%'";
} else {
$match .= " AND search_field LIKE '%$point%'";
}
}
return $match;
}
public function find_by_string($data) {
$sql = "SELECT items.id, items.number, items.name, items.short_description, manufacturers.name as manufacturer,
CONCAT_WS(' ', items.number, items.name, items.short_description, if (manufacturers.name IS NOT NULL,manufacturers.name,' ')) as search_field
FROM items LEFT JOIN manufacturers ON manufacturers.id = items.manufacturer_id WHERE items.active = 1";
$match = $this->match_by_string($data);
$sql .= $match.' LIMIT 5';
$result = $this->db->query($sql);
if ($result->num_rows > 0) {
while ($obj = $result->fetch_object()) {
$return[] = $obj;
}
return $return;
}
return false;
}
// end find_by_string
public function hits_by_string($data) {
$sql = "SELECT CONCAT_WS(' ', items.number, items.name, items.short_description, if (manufacturers.name IS NOT NULL, manufacturers.name,' ')) as search_field
FROM items LEFT JOIN manufacturers ON manufacturers.id = items.manufacturer_id WHERE items.active = 1";
$match = $this->match_by_string($data);
$sql .= $match;
$result = $this->db->query($sql);
if ($result) {
return $result->num_rows;
}
return 0;
}
// end hits_by_string
public function get_by_id($id) {
if (isset($_GET['debug_performance'])) {
echo "<div style='background:orange;color:black;padding:10px;'>🔍 get_by_id() GESTARTET für ID: $id</div>";
flush(); ob_flush();
}
$sql = "SELECT * FROM items WHERE id = $id";
if (isset($_GET['debug_performance'])) {
echo "<div style='background:yellow;color:black;padding:10px;'>📝 SQL bereit: $sql</div>";
flush(); ob_flush();
}
$result = $this->db->query($sql);
if (isset($_GET['debug_performance'])) {
echo "<div style='background:cyan;color:black;padding:10px;'>⚡ DB->query() FERTIG - Rows: " . ($result ? $result->num_rows : 'ERROR') . "</div>";
flush(); ob_flush();
}
if ($result->num_rows == 1) {
$obj = $result->fetch_object();
if (isset($_GET['debug_performance'])) {
echo "<div style='background:lime;color:black;padding:10px;'>✅ get_by_id() ERFOLGREICH - Object returned</div>";
flush(); ob_flush();
}
return $obj;
}
if (isset($_GET['debug_performance'])) {
echo "<div style='background:red;color:white;padding:10px;'>❌ get_by_id() FAILED - No result for ID: $id</div>";
flush(); ob_flush();
}
return false;
}
// end get_by_id
public function get_by_number($nr) {
$sql = "SELECT id, `number` FROM items WHERE `number` = '$nr'";
$result = $this->db->query($sql);
if ($result->num_rows > 0) {
return $result->fetch_object()->id;
}
return false;
}
// end get_by_number
public function get_item_for_order($id) {
$sql = "SELECT * FROM items WHERE id = $id";
$result = $this->db->query($sql);
if ($result->num_rows == 1) {
$obj = $result->fetch_object();
$tax_rate = Tax::get_taxrate($obj->tax_id);
$obj->tax = $tax_rate;
$obj->price = Money::show_money($obj->price_1);
$price_with_tax = Money::get_price_with_taxes($obj->price, $tax_rate);
$obj->price_with_tax = Money::show_money($price_with_tax);
$obj->item_name = $obj->name;
$obj->item_number = $obj->number;
$total = $obj->price;
$obj->total = Money::show_money($total);
$total_with_tax = $obj->price_with_tax;
$obj->total_with_tax = Money::show_money($total_with_tax);
$obj->amount = 1;
return $obj;
}
return false;
}
// end get_by_id
public function search_items($search) {
$sql = '';
$matchingItemNumberFirst = false;
//echo "Items->search_items() called<br>";
if (isset($search['manufacturer_id'])) {
$sql = "SELECT i.*, i.default_image_file_name AS file_name, ip.price_1, ip.bargain_price_1
FROM item_prices ip RIGHT JOIN items i ON i.id=ip.item_id
AND ip.customergroup_id=".$this->db->real_escape_string($this->base_object->customer_group->price_group_id)."
WHERE i.active=1 AND i.parent_id=0 AND i.manufacturer_id=".$search['manufacturer_id']."
GROUP BY i.id ORDER BY i.name DESC";
} else if (isset($search['search_item'])) {
// Include individual search
if (isset($this->base_object->config->shopConfiguration['custom_global_modules']) && $this->base_object->config->shopConfiguration['custom_global_modules']) {
include_once ROOT_DIR.'web/'.SHOP_SYSTEM.'/php/website_item_search.inc.php';
} else {
// Default search
$where_add = '';
if (isset($search['item_category']) && $search['item_category'] > 0) {
$category_id = $this->db->real_escape_string($search['item_category']);
$sql = "SELECT i.*, i.default_image_file_name AS file_name, ip.price_1, ip.bargain_price_1
FROM item_prices ip RIGHT JOIN items i ON i.id=ip.item_id AND ip.customergroup_id=".$this->db->real_escape_string($this->base_object->customer_group->price_group_id)."
RIGHT JOIN item_structure_assign isa ON i.id=isa.item_id WHERE i.active=1
AND (
i.name like '%".$search['search_item']."%' ||
i.number like '%".$search['search_item']."%' ||
i.short_description like '%".$search['search_item']."%' ||
i.attribute_1 like '%".$search['search_item']."%' ||
i.attribute_2 like '%".$search['search_item']."%' ||
i.attribute_3 like '%".$search['search_item']."%' ||
i.attribute_4 like '%".$search['search_item']."%' ||
i.attribute_5 like '%".$search['search_item']."%' ||
i.seo_keywords like '%".$search['search_item']."%' ||
i.detail_description like '%".$search['search_item']."%')
AND parent_id = 0 AND isa.structure_id = $category_id GROUP BY i.id ORDER BY i.name DESC";
} else {
$sql = "SELECT i.*, i.default_image_file_name AS file_name, ip.price_1, ip.bargain_price_1
FROM item_prices ip RIGHT JOIN items i ON i.id=ip.item_id AND ip.customergroup_id=".$this->db->real_escape_string($this->base_object->customer_group->price_group_id)."
WHERE i.active=1 AND (i.name like '%".$search['search_item']."%' ||
i.number like '%".$search['search_item']."%' ||
i.short_description like '%".$search['search_item']."%' ||
i.attribute_1 like '%".$search['search_item']."%' ||
i.attribute_2 like '%".$search['search_item']."%' ||
i.attribute_3 like '%".$search['search_item']."%' ||
i.attribute_4 like '%".$search['search_item']."%' ||
i.attribute_5 like '%".$search['search_item']."%' ||
i.seo_keywords like '%".$search['search_item']."%' ||
i.detail_description like '%".$search['search_item']."%')
AND parent_id = 0 GROUP BY i.id ORDER BY i.name DESC";
}
}
}
$list = array();
if ($sql) {
$result = $this->db->query($sql);
$list = array();
$show_taxes = $this->base_object->customer_group->show_tax;
while ($obj = $result->fetch_object()) {
// get variants
$sql = "SELECT i.id, ip.price_1, ip.bargain_price_1 FROM items i LEFT JOIN item_prices ip ON ip.item_id = i.id
WHERE ip.price_1 > 0 AND i.parent_id = ".$this->db->real_escape_string($obj->id)."
GROUP BY i.id ORDER BY ip.price_1 LIMIT 1";
$variant_result = $this->db->query($sql);
if ($variant_result) {
while ($variant_obj = $variant_result->fetch_object()) {
$obj->price_1 = $variant_obj->price_1;
$obj->bargain_price_1 = $variant_obj->bargain_price_1;
$obj->price_praefix = 'ab';
}
}
// get item discount
$discount = $this->get_item_discount(isset($this->base_object->customer_group->id) ? intval($this->base_object->customer_group->id) : 1, $obj->manufacturer_id, $obj->structure_id);
if ($discount) {
$obj->bargain_price_1 = round(($obj->price_1 * (100 - $discount) / 100), 2);
$obj->discount = $discount;
$obj->discount_text = 'Rabatt!';
}
// shop price
$obj->tax = $this->all_tax[$obj->tax_id]->steuersatz;
$obj->price_tax_text = str_replace('[tax]', $obj->tax, isset($this->base_object->customer_group->price_tax_text) ? $this->base_object->customer_group->price_tax_text : 'inkl. [tax]% MwSt.');
//$obj->manufacturer_text = $manufacturers[$obj->manufacturer_id];
$obj->manufacturer_text = isset($this->manufacturers[$obj->manufacturer_id]) ? $this->manufacturers[$obj->manufacturer_id] : '';
$obj->manufacturer_data = isset($this->manufacturers[$obj->manufacturer_id]) ? $this->manufacturers[$obj->manufacturer_id] : null;
// bargain
if (!$this->check_bargain_active($obj, $obj->id)) {
$obj->bargain_price_1 = 0;
}
// get quantity prices
$sql = "SELECT * FROM item_prices WHERE item_id = '".$this->db->real_escape_string($obj->id)."'
AND customergroup_id = '".$this->db->real_escape_string(isset($this->base_object->customer_group->id) ? intval($this->base_object->customer_group->id) : 1)."'
LIMIT 1";
$quantityprciesResult = $this->db->query($sql);
if ($quantityprciesResult) {
while ($QP = $quantityprciesResult->fetch_object()) {
foreach ($QP as $colName => $colValue) {
if (stristr($colName, 'price') && stristr($colName, 'bargain') && $colValue > 0 && $colValue < $obj->bargain_price_1) {
$obj->bargain_price_1 = $colValue;
$obj->price_praefix = 'ab';
} else if (stristr($colName, 'price') && !stristr($colName, 'bargain') && $colValue > 0 && $colValue < $obj->price_1) {
$obj->price_1 = $colValue;
$obj->price_praefix = 'ab';
}
}
}
}
if ($show_taxes) {
$obj->tax_value = round($obj->price_1 * ($obj->tax / 100), 2);
$obj->shop_price_1 = $obj->price_1 + $obj->tax_value;
$obj->bargain_tax_value = round($obj->bargain_price_1 * ($obj->tax / 100), 2);
$obj->shop_bargain_price_1 = $obj->bargain_price_1 + $obj->bargain_tax_value;
} else {
$obj->shop_price_1 = $obj->price_1;
$obj->shop_bargain_price_1 = $obj->bargain_price_1;
}
// get schema data
$obj->schema_data_attributes = array();
if ($obj->schema_id) {
$this->schema_id = $obj->schema_id;
$obj->schema_data = $this->get_schema_data();
foreach ($obj->schema_data->attributes as $attribute) {
if ($attribute->name) {
$attr = array(
'name' => $attribute->name,
'unit' => $attribute->unit,
'value' => $obj->{'attribute_'.$attribute->number},
'show_detail' => $attribute->show_detail,
'show_list' => $attribute->show_list,
'number' => $attribute->number
);
$obj->schema_data_attributes[] = $attr;
}
if ($obj->schema_data->selectable_attribute_1 == $attribute->number) {
$obj->schema_data->selectable_name_1 = $attribute->name;
$obj->price_variants_1 = explode(';', $obj->{'attribute_'.$attribute->number});
}
if ($obj->schema_data->selectable_attribute_2 == $attribute->number) {
$obj->schema_data->selectable_name_2 = $attribute->name;
$obj->price_variants_2 = explode(';', $obj->{'attribute_'.$attribute->number});
}
}
}
$obj->numberMatch = ($obj->number == $search['search_item']);
// intelectra individual
if ($obj->attribute_11 && $obj->attribute_15) {
$obj->sample_unit = $obj->attribute_15;
if (strstr($obj->sample_unit, '100')) {
if ($obj->attribute_11 * 10 != 0) {
$price_for_calc = ($obj->shop_bargain_price_1 > 0) ? $obj->shop_bargain_price_1 : $obj->shop_price_1;
$obj->sample_price = $price_for_calc / ($obj->attribute_11 * 10);
} else {
error_log("Division durch 0 vermieden. \$obj->attribute_11 * 10 ist 0.");
$obj->sample_price = 0; // Oder ein anderer Standardwert
}
} else {
if ($obj->attribute_11 != 0) {
$price_for_calc = ($obj->shop_bargain_price_1 > 0) ? $obj->shop_bargain_price_1 : $obj->shop_price_1;
$obj->sample_price = $price_for_calc / $obj->attribute_11;
} else {
error_log("Division durch 0 vermieden. \$obj->attribute_11 ist 0.");
$obj->sample_price = 0; // Oder ein anderer Standardwert
}
}
}
// emd intelectra individual
if (!isset($list[$obj->id])) {
$list[$obj->id] = $obj;
}
}
}
// Bring items with a matching item number (matching against the search item) to the top
if ($matchingItemNumberFirst) {
uasort($list, function($a, $b) {
if ($a->numberMatch > $b->numberMatch) {
return -1;
} else {
return 1;
}
});
}
/*echo "search_items result: <pre>";
var_dump($list);
echo "</pre><br>";*/
return $list;
}
public function search_group_items($search, $item_ids = false) {
// get full path structures
$structure_object = new Structure($this->base_object);
$all_structures = $structure_object->get_all();
// Include individual search
if (isset($this->base_object->config->shopConfiguration['custom_global_modules']) && $this->base_object->config->shopConfiguration['custom_global_modules']) {
include_once ROOT_DIR.'web/'.SHOP_SYSTEM.'/php/website_itemgroups_search.inc.php';
// Default search
} else {
$sql = "SELECT
-- wg.name,
wg.id,
-- wg.parent_id,
count(wg.id)
AS found_items FROM structure wg
LEFT JOIN item_structure_assign isa ON wg.id = isa.structure_id
LEFT JOIN items i ON i.id = isa.item_id
WHERE (i.name like '%".$search['search_item']."%' ||
i.short_description like '%".$search['search_item']."%' ||
i.attribute_1 like '%".$search['search_item']."%' ||
i.attribute_2 like '%".$search['search_item']."%' ||
i.attribute_3 like '%".$search['search_item']."%' ||
i.attribute_4 like '%".$search['search_item']."%' ||
i.attribute_5 like '%".$search['search_item']."%' ||
i.detail_description like '%".$search['search_item']."%') AND
i.parent_id = 0 AND wg.active=1 GROUP BY wg.id";
}
if ($sql) {
$result = $this->db->query($sql);
$parent_child = array();
while ($obj = $result->fetch_object()) {
$all_structures[$obj->id]->found_items = $obj->found_items;
$parent_id = $all_structures[$obj->id]->parent_id;
if (isset($parent_child[$parent_id]) && $parent_child[$parent_id]) {
$parent_child[$parent_id]->children[] = $all_structures[$obj->id];
} else {
$parent_child[$parent_id] = $all_structures[$parent_id];
$parent_child[$parent_id]->children[] = $all_structures[$obj->id];
}
}
return $parent_child;
}
}
public function get_item_list_manufacturer($structure_id, $manufacturer_id) {
/*$sql = "SELECT items.* FROM items
WHERE (items.structure_id = ".$structure_id." OR
items.structure_id_2 = ".$structure_id." OR
items.structure_id_3 = ".$structure_id.")
AND items.manufacturer_id = ".$manufacturer_id." ORDER BY items.name ASC";*/
$sql = "SELECT i.*, i.default_image_file_name AS file_name, ip.price_1, ip.bargain_price_1 FROM item_prices ip
RIGHT JOIN items i ON i.id=ip.item_id AND ip.customergroup_id=".$this->db->real_escape_string($this->base_object->customer_group->price_group_id)."
WHERE i.active=1 AND (i.structure_id = ".$structure_id."
OR i.structure_id_2 = ".$structure_id."
OR i.structure_id_3 = ".$structure_id.")
AND i.manufacturer_id = ".$manufacturer_id."
GROUP BY i.id ORDER BY i.name DESC";
$result = $this->db->query($sql);
$list = array();
while ($obj = $result->fetch_object()) {
// shop price
$obj->tax = $this->all_tax[$obj->tax_id]->steuersatz;
$obj->price_tax_text = str_replace('[tax]', $obj->tax, isset($this->base_object->customer_group->price_tax_text) ? $this->base_object->customer_group->price_tax_text : 'inkl. [tax]% MwSt.');
$obj->manufacturer_text = $manufacturers[$obj->manufacturer_id];
// get item discount
$discount = $this->get_item_discount(isset($this->base_object->customer_group->id) ? intval($this->base_object->customer_group->id) : 1, $obj->manufacturer_id, $obj->structure_id);
if ($discount) {
$obj->bargain_price_1 = round(($obj->price_1 * (100 - $discount) / 100), 2);
$obj->discount = $discount;
$obj->discount_text = 'Rabatt!';
}
$show_taxes = $this->base_object->customer_group->show_tax;
if ($show_taxes) {
$obj->tax_value = round($obj->price_1 * ($obj->tax / 100), 2);
$obj->shop_price_1 = $obj->price_1 + $obj->tax_value;
$obj->bargain_tax_value = round($obj->bargain_price_1 * ($obj->tax / 100), 2);
$obj->shop_bargain_price_1 = $obj->bargain_price_1 + $obj->bargain_tax_value;
} else {
$obj->shop_price_1 = $obj->price_1;
$obj->shop_bargain_price_1 = $obj->bargain_price_1;
}
$list[$obj->id] = $obj;
}
return $list;
}
public function get_price($id) {
$sql = "SELECT price_1 as price, tax_id
FROM items
WHERE id=".$this->db->real_escape_string($id);
$result = $this->db->query($sql);
if ($result->num_rows > 0) {
$obj = $result->fetch_object();
$taxrate = Tax::get_taxrate($obj->tax_id);
$price = Money::get_price_with_taxes($obj->price, $taxrate);
return Money::show_money($price);
}
//TODO: false can't be used in calculations
return Money::show_money(0.00);
}
public function calculate_prices($item, $quantity = 1, $variant1 = false, $variant2 = false, $wantedPrice = false, $customer_id = false) {
if ($customer_id) {
$customer_group_id = CustomerHelper::get_customer_group_id_by_customer_id($customer_id);
$customer_group_object = new Customer_group($this->base_object);
$customer_group_data = $customer_group_object->get_data($customer_group_id);
$show_taxes = $customer_group_data->show_tax;
} else {
$show_taxes = $this->base_object->customer_group->show_tax;
}
if ($variant1 || $variant2) {
$data['itemPriceNet'] = $item->variant_data[$variant1][$variant2]['priceNet'];
$data['itemPriceGross'] = $item->variant_data[$variant1][$variant2]['priceGross'];
$data['variant_number'] = $item->variant_data[$variant1][$variant2]['itemNumber'];
} else {
if ($item->bargain_price_1 > 0) {
$data['itemPriceNet'] = $item->bargain_price_1;
$data['itemPriceGross'] = $item->bargain_price_1_tax;
} else {
$data['itemPriceNet'] = $item->price_1;
$data['itemPriceGross'] = $item->price_1_tax;
}
}
if (is_array($item->graduated_prices) && count($item->graduated_prices) > 0) {
foreach ($item->graduated_prices as $quan => $gpData) {
if ($quan <= $quantity) {
if ($gpData['bargainNet'] > 0) {
$data['itemPriceNet'] = $gpData['bargainNet'];
$data['itemPriceGross'] = $gpData['bargainGross'];
} else {
$data['itemPriceNet'] = $gpData['priceNet'];
$data['itemPriceGross'] = $gpData['priceGross'];
}
} else {
break;
}
}
}
if ($show_taxes) {
// WITH TAXES
if ($wantedPrice) {
if ($data['itemPriceGross'] != $wantedPrice) {
$grossPrice = $wantedPrice;
$netPrice = $wantedPrice / (100.0 + (float) $item->tax) * 100.0;
$data['itemPriceNet'] = $netPrice;
$data['itemPriceGross'] = $grossPrice;
}
}
$data['shownPrice'] = $data['itemPriceGross'];
} else {
// WITHOUT TAXES
if ($wantedPrice) {
if ($data['itemPriceNet'] != $wantedPrice) {
$grossPrice = $wantedPrice * (100.0 + (float) $item->tax) / 100.0;
$netPrice = $wantedPrice;
$data['itemPriceNet'] = $netPrice;
$data['itemPriceGross'] = $grossPrice;
}
}
$data['shownPrice'] = $data['itemPriceNet'];
}
$data['itemPriceNet'] = round($data['itemPriceNet'], 4);
$data['itemPriceGross'] = round($data['itemPriceGross'], 4);
$data['shownPrice'] = round($data['shownPrice'], 4);
return $data;
}
public function find_for_ajax($searchString, $limit = 30) {
$sql = "
SELECT id, number, name, active
FROM items
WHERE number LIKE '%".$this->db->real_escape_string($searchString)."%'
OR name LIKE '%".$this->db->real_escape_string($searchString)."%'
ORDER BY name, number, id, active DESC LIMIT 0, ".$this->db->real_escape_string($limit);
$result = $this->db->query($sql);
if ($result->num_rows > 0) {
$return = array();
while ($obj = $result->fetch_object()) {
$return[] = $obj;
}
return $return;
}
return false;
}
private function saveAssignedItems($type = 1) {
// NEUE PYTHON-BASIERTE SAVE LOGIK - Nur Änderungen speichern!
if (is_numeric($this->id)) {
// ⚡ PERFORMANCE FIX: Nur aufrufen wenn tatsächlich POST-Daten vorhanden!
// Verhindert 504 Timeout bei Kurz-URL Updates etc.
if (!isset($_POST['assignedItemsCollection'.$type])) {
return true; // Keine Daten = nichts zu tun = success
}
// Versuche Python Service (wenn verfügbar)
$python_script = dirname(dirname(__FILE__)) . '/modules/import/item_save_service.py';
if (file_exists($python_script)) {
$items = isset($_POST['assignedItemsCollection'.$type]) ? $_POST['assignedItemsCollection'.$type] : array();
$actions = array(
1 => 'save_accessories',
2 => 'save_spare_parts',
3 => 'save_alternatives'
);
$data = array(
'item_id' => $this->id,
'action' => $actions[$type],
'items' => $items
);
$json_data = json_encode($data);
$command = "python3 " . escapeshellarg($python_script) . " " . escapeshellarg($json_data);
$output = shell_exec($command . " 2>&1");
$result = json_decode($output, true);
if ($result && isset($result['success']) && $result['success']) {
// Update flags
$db_switch_fields = array(
1 => 'has_additional_items',
2 => 'has_spare_parts',
3 => 'has_real_friends' // LOL wer hat das genannt?
);
if (isset($db_switch_fields[$type])) {
$has_items = !empty($items) ? 1 : 0;
$query = "UPDATE items SET ".$db_switch_fields[$type]." = ".$has_items." WHERE id = '".$this->id."'";
$this->db->query($query);
}
return true; // Python Success!
}
}
// FALLBACK zur alten Logik (falls Python nicht läuft)
switch ($type) {
case 1:
$db_switch_field = 'has_additional_items';
break;
case 2:
$db_switch_field = 'has_spare_parts';
break;
case 3:
$db_switch_field = 'has_real_friends';
break;
default:
$db_switch_field = false;
}
$queryDelete = "DELETE FROM item_item_assign WHERE item_parent_id = '".$this->id."' AND type = ".$type;
$this->db->query($queryDelete);
if ($db_switch_field) {
$query = "UPDATE items SET ".$db_switch_field." = 0 WHERE id = '".$this->id."'";
$this->db->query($query);
}
if (is_array($_POST['assignedItemsCollection'.$type])) {
$pos = 0;
$inserts = array();
foreach ($_POST['assignedItemsCollection'.$type] as $itemId) {
if (is_numeric($itemId)) {
++$pos;
$inserts[] = "(".$this->id.",".$itemId.", $type, ".$pos.")";
}
}
if (count($inserts) > 0) {
$queryInsert = "REPLACE INTO item_item_assign (item_parent_id, item_child_id, type, position) VALUES ".implode(',', $inserts);
$this->db->query($queryInsert);
if ($db_switch_field) {
$query = "UPDATE items SET ".$db_switch_field." = 1 WHERE id = '".$this->id."'";
$this->db->query($query);
}
}
}
}
return true;
}
public function delete_item_item_assign($item_parent_id, $item_child_id, $type = false) {
$sql = '';
if ($type) {
$sql = "DELETE FROM item_item_assign
WHERE item_parent_id = '".$item_parent_id."'
AND item_child_id = '".$item_child_id."'
AND type = ".$type;
} else {
$sql = "DELETE FROM item_item_assign
WHERE item_parent_id = '".$item_parent_id."' AND item_child_id = '".$item_child_id."'";
}
$this->db->query($sql);
return true;
}
public function get_all_interesting_items_by_group_id($group_id) {
// get structure_ids
$ids = array();
$sql = " SELECT * FROM structure WHERE id=".$this->db->real_escape_string($group_id);
$result = $this->db->query($sql);
$obj = $result->fetch_object();
$sql = " SELECT id FROM structure WHERE parent_id=".$this->db->real_escape_string($obj->parent_id);
$result = $this->db->query($sql);
if ($result->num_rows > 0) {
while ($obj = $result->fetch_object()) {
$ids[] = $obj->id;
}
// get items
$all_items = array();
foreach ($ids as $structure_id) {
$items = $this->get_item_list($structure_id);
$all_items = array_merge($all_items, $items);
}
return $all_items;
}
return false;
}
// TODO: needs paging
public function get_by_manufacturer($id) {
$sql = "SELECT * FROM items WHERE manufacturer_id=".$this->db->real_escape_string($id);
$result = $this->db->query($sql);
if ($result->num_rows > 0) {
$return_data = array();
while ($obj = $result->fetch_object()) {
$return_data[] = $obj;
}
return $return_data;
}
return false;
}
private function watermark($strImageDestination) {
$strImageWatermark = './web/'.SHOP_SYSTEM.'/documents/'.$this->base_object->config->shopConfiguration['item_watermark_image'];
$iTransparency = 0;
$iQuality = 80;
list ( $iDestinationWidth, $iDestinationHeight, $iDestinationType ) = getimagesize($strImageDestination);
list ( $iWatermarkWidth, $iWatermarkHeight, $iWatermarkType ) = getimagesize($strImageWatermark);
switch ($iDestinationType) {
case 1:
$rDestination = imagecreatefromgif ($strImageDestination);
break;
case 2:
$rDestination = imagecreatefromjpeg($strImageDestination);
break;
case 3:
$rDestination = imagecreatefrompng($strImageDestination);
}
switch ($iWatermarkType) {
case 1:
$rWatermark = imagecreatefromgif ($strImageWatermark);
break;
case 2:
$rWatermark = imagecreatefromjpeg($strImageWatermark);
break;
case 3:
$rWatermark = imagecreatefrompng($strImageWatermark);
}
/*
* Position des Wasserzeichens (1 - 5).
* 1 = Oben links.
* 2 = Oben rechts.
* 3 = Unten links.
* 4 = Unten rechts
* 5 = Horizontal/vertikal zentriert.
*
* Standard = 4
*/
switch ($this->base_object->config->shopConfiguration['item_watermark_pos']) {
case 1:
$iPositionX = 0;
$iPositionY = 0;
break;
case 2:
$iPositionX = $iDestinationWidth - $iWatermarkWidth;
$iPositionY = 0;
break;
case 3:
$iPositionX = 0;
$iPositionY = $iDestinationHeight - $iWatermarkHeight;
break;
case 4:
default:
$iPositionX = $iDestinationWidth - $iWatermarkWidth;
$iPositionY = $iDestinationHeight - $iWatermarkHeight;
break;
case 5:
$iPositionX = ceil(( $iDestinationWidth / 2));
$iPositionX -= ceil(( $iWatermarkWidth / 2));
$iPositionY = ceil(( $iDestinationHeight / 2));
$iPositionY -= ceil(( $iWatermarkHeight / 2));
}
$iTransparency = 100 - $iTransparency;
/* imagecopymerge ( $rDestination, $rWatermark, $iPositionX,
$iPositionY, 0, 0, $iWatermarkWidth,
$iWatermarkHeight, $iTransparency ); */
// Wasserzeichen einfügen
imagecopy($rDestination, $rWatermark, $iPositionX, $iPositionY, 0, 0, $iWatermarkWidth, $iWatermarkHeight);
/*
* Ausgabeformat (1 - 3):
* 1 = GIF-Format
* 2 = JPEG-Format
* 3 = PNG-Format
*
* Standard = 3
*/
switch ($iDestinationType) {
case 1:
//header ( 'content-type: image/gif' );
imagegif ($rDestination, $strImageDestination);
break;
case 2:
//header ( 'content-type: image/jpeg' );
imagejpeg($rDestination, $strImageDestination, $iQuality);
break;
case 3:
default:
//header ( 'content-type: image/png' );
imagepng($rDestination, $strImageDestination);
}
imagedestroy($rDestination);
imagedestroy($rWatermark);
return;
}
/**
* $type : accessories = 0, alternative = 1
* $id : id of parent or child item
* $order : normal = 0 and selects parent item ids, reverse is 1 and selects child item ids
*/
public function get_all_item_items($type = false, $id = false, $order = 0) {
$sql = "SELECT iia.*, i.name, i.active, i.number FROM item_item_assign iia JOIN items i ON";
if ($id) {
if ($order === 1) {
$sql .= " i.id = iia.item_child_id WHERE iia.item_parent_id=".$this->db->real_escape_string($id);
$this->id = $id;
} else if ($order === 0) {
$sql .= " i.id = iia.item_parent_id WHERE iia.item_child_id=".$this->db->real_escape_string($id);
$this->id = $id;
} else {
return false;
}
} else if ($this->id) {
if ($order === 1) {
$sql .= " i.id = iia.item_child_id WHERE iia.item_child_id=".$this->db->real_escape_string(intval($this->id));
} else if ($order === 0) {
$sql .= " i.id = iia.item_parent_id WHERE iia.item_parent_id=".$this->db->real_escape_string(intval($this->id));
} else {
return false;
}
} else {
return false;
}
if ($type) {
$sql .= " AND type=".$this->db->real_escape_string(intval($type));
}
$sql .= " ORDER BY iia.position ASC";
$result = $this->db->query($sql);
if ($result->num_rows > 0) {
$return_data = array();
while ($obj = $result->fetch_object()) {
$return_data[] = $obj;
}
if ($return_data != array()) {
return $return_data;
}
}
return false;
}
// end get_all_item_items
public function remove_default_image($id = false) {
$sql = "UPDATE items SET default_image_file_name='' WHERE id=";
if ($id) {
$sql .= $this->db->real_escape_string($id);
$this->id = $id;
} else if ($this->id) {
$sql .= $this->db->real_escape_string($this->db);
} else {
return false;
}
$this->db->query($sql);
}
// end remove_default_image
public function increase_inventory($quantity, $variant1, $variant2, $id = false) {
if (is_int((int) $quantity)) {
$quantity = (int) $quantity;
if ($id) {
$this->id = $id;
}
if (!$this->id) {
return false;
}
if ($this->has_variants()) {
// reduce inventory for item variants
$inventory = $this->get_inventory(true, $variant1, $variant2);
$new_inventory = $inventory + $quantity;
// TODO: what to do if the item was already delivered?
// increasing the original item might not be right
return $this->db->query("UPDATE item_attribute_variants
SET inventory=".$this->db->real_escape_string($new_inventory)."
WHERE item_id=".$this->db->real_escape_string($this->id)."
AND attribut1='".$this->db->real_escape_string($variant1)."'
AND attribut2='".$this->db->real_escape_string($variant2)."'");
} else {
// reduce inventory for item
$inventory = $this->get_inventory();
$new_inventory = $inventory + $quantity;
// TODO: what to do if the item was already delivered?
// increasing the original item might not be right
return $this->db->query("UPDATE items
SET inventory=".$this->db->real_escape_string($new_inventory)."
WHERE id=".$this->db->real_escape_string($this->id));
}
}
return false;
}
// end increase_inventory
public function reduce_inventory($quantity, $variant1, $variant2, $id = false) {
if (is_int((int) $quantity)) {
$quantity = (int) $quantity;
if ($id) {
$this->id = $id;
}
if (!$this->id) {
return false;
}
if ($this->has_variants()) {
// reduce inventory for item variants
$inventory = $this->get_inventory(true, $variant1, $variant2);
$new_inventory = $inventory - $quantity;
// TODO: new inventory can slip under 0, what to do?
return $this->db->query("UPDATE item_attribute_variants
SET inventory=".$this->db->real_escape_string($new_inventory)."
WHERE item_id=".$this->db->real_escape_string($this->id)."
AND attribut1='".$this->db->real_escape_string($variant1)."'
AND attribut2='".$this->db->real_escape_string($variant2)."'");
} else {
// reduce inventory for item
$inventory = $this->get_inventory();
$new_inventory = $inventory - $quantity;
// TODO: new inventory can slip under 0, what to do?
return $this->db->query("UPDATE
items
SET
inventory=".$this->db->real_escape_string($new_inventory)."
WHERE
id=".$this->db->real_escape_string($this->id));
}
}
return false;
}
// end reduce_inventory
private function get_inventory($has_variants = false, $variant1 = false, $variant2 = false) {
if ($has_variants) {
$sql = "SELECT
inventory AS num
FROM
item_attribute_variants
WHERE
item_id=".$this->db->real_escape_string($this->id)."
AND
attribut1='".$this->db->real_escape_string($variant1)."'
AND
attribut2='".$this->db->real_escape_string($variant2)."'
LIMIT 1";
} else {
$sql = "SELECT
inventory AS num
FROM
items
WHERE id=".$this->db->real_escape_string($this->id);
}
$result = $this->db->query($sql);
return $result->fetch_object()->num;
}
private function has_variants() {
$sql = "SELECT * FROM item_attribute_variants WHERE item_id=".$this->db->real_escape_string($this->id);
$result = $this->db->query($sql);
if ($result->num_rows > 0) {
return true;
}
return false;
}
public function get_all_by_manufacturer($manufacturer_id) {
$sql = "SELECT
*
FROM
items
WHERE
manufacturer_id=".$this->db->real_escape_string($manufacturer_id);
$result = $this->db->query($sql);
if ($result->num_rows > 0) {
$return_data = array();
while ($obj = $result->fetch_object()) {
$return_data[] = $obj;
}
if ($return_data == array()) {
return false;
}
return $return_data;
}
return false;
}
// end get_all_by_manufacturer
public function get_all_google_item_categories($parent = false) {
$sql_where = ($parent) ? "parent = '".$this->db->real_escape_string($parent)."'" : "parent = ''";
$sql = "SELECT * FROM google_item_categories WHERE ".$sql_where;
$result = $this->db->query($sql);
if ($result->num_rows > 0) {
$data = array();
while ($obj = $result->fetch_object()) {
$data[] = $obj;
}
return $data;
} else {
return array();
}
}
private function load_item_discounts() {
// get discounts for all customer_groups
$sql = "SELECT * FROM discount_item_groups";
$result = $this->db->query($sql);
$discounts = array();
if ($result) {
while ($obj = $result->fetch_object()) {
$discounts[$obj->customer_group_id][$obj->manufacturer_id][$obj->structure_id] = $obj->discount;
}
}
$this->item_discounts = $discounts;
return false;
}
public function get_item_discount($customer_group_id, $manufacturer_id, $structure_id) {
if (isset($this->item_discounts[$customer_group_id][$manufacturer_id][$structure_id])) {
return $this->item_discounts[$customer_group_id][$manufacturer_id][$structure_id];
} else {
return 0;
}
}
public function get_assigned_items($item_id, $customer_group_price_id, $type = 1) {
$list = array();
// get assigned item ids
$sql = 'SELECT
i.*,
i.default_image_file_name AS file_name,
ip.price_1,
ip.bargain_price_1
FROM
item_item_assign iip
LEFT JOIN
items i
ON
iip.item_child_id=i.id
-- RIGHT JOIN
LEFT JOIN
item_prices ip
ON
i.id=ip.item_id
AND
ip.customergroup_id='.$this->db->real_escape_string($customer_group_price_id).'
WHERE
iip.item_parent_id='.$this->db->real_escape_string($item_id).' AND
iip.type='.$this->db->real_escape_string($type).'
ORDER BY
iip.position ASC';
$result = $this->db->query($sql);
$show_taxes = (isset($this->base_object->customer_group->show_tax)) ? $this->base_object->customer_group->show_tax : 1;
while ($obj = $result->fetch_object()) {
// get item discount
$discount = $this->get_item_discount(isset($this->base_object->customer_group->id) ? intval($this->base_object->customer_group->id) : 1, $obj->manufacturer_id, $obj->structure_id);
if ($discount) {
$obj->bargain_price_1 = round(($obj->price_1 * (100 - $discount) / 100), 2);
$obj->discount = $discount;
$obj->discount_text = 'Rabatt!';
}
// shop price
$obj->tax = $this->all_tax[$obj->tax_id]->steuersatz;
$obj->tax_rate = $this->all_tax[$obj->tax_id]->steuersatz; // some do it this way some do it that way
$obj->price_tax_text = str_replace('[tax]', $obj->tax, isset($this->base_object->customer_group->price_tax_text) ? $this->base_object->customer_group->price_tax_text : 'inkl. [tax]% MwSt.');
$obj->manufacturer_text = isset($this->manufacturers[$obj->manufacturer_id]) ? $this->manufacturers[$obj->manufacturer_id] : '';
$obj->tax_value = round($obj->price_1 * ($obj->tax / 100), 2);
$obj->price_1_tax = $obj->price_1 + $obj->tax_value;
$obj->bargain_tax_value = round($obj->bargain_price_1 * ($obj->tax / 100), 2);
$obj->bargain_price_1_tax = $obj->bargain_price_1 + $obj->bargain_tax_value;
if ($show_taxes) {
$obj->tax_value = round($obj->price_1 * ($obj->tax / 100), 2);
$obj->shop_price_1 = $obj->price_1 + $obj->tax_value;
$obj->bargain_tax_value = round($obj->bargain_price_1 * ($obj->tax / 100), 2);
$obj->shop_bargain_price_1 = $obj->bargain_price_1 + $obj->bargain_tax_value;
} else {
$obj->shop_price_1 = $obj->price_1;
$obj->shop_bargain_price_1 = $obj->bargain_price_1;
}
// bargain
if (!$this->check_bargain_active($obj, $obj->id)) {
$obj->shop_bargain_price_1 = $obj->bargain_price_1 = 0;
}
// get schema data
$obj->schema_data_attributes = array();
if ($obj->schema_id) {
$this->schema_id = $obj->schema_id;
$obj->schema_data = $this->get_schema_data();
foreach ($obj->schema_data->attributes as $attribute) {
if ($attribute->name) {
$attr = array(
'name' => $attribute->name,
'unit' => $attribute->unit,
'value' => $obj->{'attribute_'.$attribute->number},
'show_detail' => $attribute->show_detail,
'show_list' => $attribute->show_list,
'number' => $attribute->number
);
$obj->schema_data_attributes[] = $attr;
}
if ($obj->schema_data->selectable_attribute_1 == $attribute->number) {
$obj->schema_data->selectable_name_1 = $attribute->name;
$obj->price_variants_1 = split(';', $obj->{'attribute_'.$attribute->number});
}
if ($obj->schema_data->selectable_attribute_2 == $attribute->number) {
$obj->schema_data->selectable_name_2 = $attribute->name;
$obj->price_variants_2 = split(';', $obj->{'attribute_'.$attribute->number});
}
}
}
if (!isset($list[$obj->id])) {
$list[$obj->id] = $obj;
}
}
return $list;
}
public function get_assigned_items_new($item_id, $customer_group_price_id, $type = 1) {
$list = array();
// get assigned item ids
$sql = 'SELECT
i.*,
i.default_image_file_name AS file_name,
ip.price_1,
ip.bargain_price_1
FROM
item_item_assign iip
LEFT JOIN
items i
ON
iip.item_child_id=i.id
-- RIGHT JOIN
LEFT JOIN
item_prices ip
ON
i.id=ip.item_id
AND
ip.customergroup_id='.$this->db->real_escape_string($customer_group_price_id).'
WHERE
iip.item_parent_id='.$this->db->real_escape_string($item_id).' AND
iip.type='.$this->db->real_escape_string($type).'
ORDER BY
iip.position ASC';
$result = $this->db->query($sql);
$show_taxes = (isset($this->base_object->customer_group->show_tax)) ? $this->base_object->customer_group->show_tax : 1;
while ($obj = $result->fetch_object()) {
// variant check
$sql = "SELECT i.id, ip.price_1, ip.bargain_price_1 FROM items i LEFT JOIN item_prices ip ON (ip.item_id = i.id AND ip.customergroup_id = ".$this->db->real_escape_string($customer_group_price_id).") WHERE i.parent_id = ".$this->db->real_escape_string($obj->id)." GROUP BY i.id ORDER BY ip.price_1 ASC LIMIT 1";
$variant_result = $this->db->query($sql);
if ($variant_result && $variant_result->num_rows > 0) {
$variant_obj = $variant_result->fetch_object();
$obj->price_1 = $variant_obj->price_1;
$obj->bargain_price_1 = $variant_obj->bargain_price_1;
$obj->price_praefix = 'ab';
}
// get item discount
$discount = $this->get_item_discount(isset($this->base_object->customer_group->id) ? intval($this->base_object->customer_group->id) : 1, $obj->manufacturer_id, $obj->structure_id);
if ($discount) {
$obj->bargain_price_1 = round(($obj->price_1 * (100 - $discount) / 100), 2);
$obj->discount = $discount;
$obj->discount_text = 'Rabatt!';
}
// bargain
if (!$this->check_bargain_active($obj, $obj->id)) {
$obj->bargain_price_1 = 0;
}
// shop price
$obj->tax = $this->all_tax[$obj->tax_id]->steuersatz;
$obj->tax_rate = $this->all_tax[$obj->tax_id]->steuersatz; // some do it this way some do it that way
$obj->price_tax_text = str_replace('[tax]', $obj->tax, isset($this->base_object->customer_group->price_tax_text) ? $this->base_object->customer_group->price_tax_text : 'inkl. [tax]% MwSt.');
$obj->manufacturer_text = isset($this->manufacturers[$obj->manufacturer_id]) ? $this->manufacturers[$obj->manufacturer_id] : '';
$obj->tax_value = round($obj->price_1 * ($obj->tax / 100), 2);
$obj->price_1_tax = $obj->price_1 + $obj->tax_value;
$obj->bargain_tax_value = round($obj->bargain_price_1 * ($obj->tax / 100), 2);
$obj->bargain_price_1_tax = $obj->bargain_price_1 + $obj->bargain_tax_value;
if ($show_taxes) {
$obj->tax_value = round($obj->price_1 * ($obj->tax / 100), 2);
$obj->shop_price_1 = $obj->price_1 + $obj->tax_value;
$obj->bargain_tax_value = round($obj->bargain_price_1 * ($obj->tax / 100), 2);
$obj->shop_bargain_price_1 = $obj->bargain_price_1 + $obj->bargain_tax_value;
} else {
$obj->shop_price_1 = $obj->price_1;
$obj->shop_bargain_price_1 = $obj->bargain_price_1;
}
// get schema data
$obj->schema_data_attributes = array();
if ($obj->schema_id) {
$this->schema_id = $obj->schema_id;
$obj->schema_data = $this->get_schema_data();
foreach ($obj->schema_data->attributes as $attribute) {
if ($attribute->name) {
$attr = array(
'name' => $attribute->name,
'unit' => $attribute->unit,
'value' => $obj->{'attribute_'.$attribute->number},
'show_detail' => $attribute->show_detail,
'show_list' => $attribute->show_list,
'number' => $attribute->number
);
$obj->schema_data_attributes[] = $attr;
}
if ($obj->schema_data->selectable_attribute_1 == $attribute->number) {
$obj->schema_data->selectable_name_1 = $attribute->name;
$obj->price_variants_1 = split(';', $obj->{'attribute_'.$attribute->number});
}
if ($obj->schema_data->selectable_attribute_2 == $attribute->number) {
$obj->schema_data->selectable_name_2 = $attribute->name;
$obj->price_variants_2 = split(';', $obj->{'attribute_'.$attribute->number});
}
}
}
if (!isset($list[$obj->id])) {
$list[$obj->id] = $obj;
}
}
return $list;
}
public function is_combination_item($item_id = false) {
$sql = 'SELECT * FROM items WHERE combination_item=1 AND id=';
if ($item_id) {
$sql .= $this->db->real_escape_string($item_id);
$this->id = $item_id;
} else if ($this->id) {
$sql .= $this->db->real_escape_string($this->id);
} else {
return false;
}
$result = $this->db->query($sql);
if ($result->num_rows > 0) {
return true;
}
return false;
}
public function get_opinion_list($item_id) {
$data = array();
if ($item_id) {
$sql = "SELECT * FROM item_opinion WHERE item_id = ".$item_id." ORDER BY timestamp DESC";
$result = $this->db->query($sql);
while ($obj = $result->fetch_object()) {
$obj->date = substr($obj->timestamp, 8, 2).'.'.substr($obj->timestamp, 5, 2).'.'.substr($obj->timestamp, 0, 4);
$data[] = $obj;
}
}
return $data;
}
public function get_avg_opinion($item_id) {
$avg = false;
if ($item_id) {
$sql = "SELECT AVG(rang) AS avg_opinion FROM item_opinion WHERE item_id = ".$item_id;
$result = $this->db->query($sql);
$AVGO = $result->fetch_object();
$avg = $AVGO->avg_opinion;
}
return $avg;
}
public function create_opinion($data) {
// save opinion in database
$sql = "INSERT INTO
item_opinion (item_id, timestamp, rang, opinion_text, user_id, user_name, active)
VALUES
(".$this->db->real_escape_string($data['item_id']).", current_timestamp, ".
$this->db->real_escape_string($data['rang']).",'".
$this->db->real_escape_string($data['opinion_text'])."', ".
$this->db->real_escape_string($data['user_id']).", '".
$this->db->real_escape_string($data['user_name'])."',1)";
$this->db->query($sql);
return;
}
public function get_item_types($id = false) {
$sql = 'SELECT
it.*,
itd.*
FROM
item_types it
JOIN
item_type_definitions itd
ON (
it.item_type_definition_id = itd.item_type_definition_id
)
WHERE
it.item_id=';
if ($id) {
$sql .= $this->db->real_escape_string($id);
$this->id = $id;
} else if ($this->id) {
$sql .= $this->db->real_escape_string($this->id);
} else {
return false;
}
$result = $this->db->query($sql);
if ($result->num_rows > 0) {
$data = array();
while ($obj = $result->fetch_object()) {
$data[] = $obj;
}
return $data;
}
return false;
}
// end get_item_types
private function fix_data($obj) {
// get item discount
$discount = $this->get_item_discount(isset($this->base_object->customer_group->id) ? intval($this->base_object->customer_group->id) : 1, $obj->manufacturer_id, $obj->structure_id);
if ($discount) {
$obj->bargain_price_1 = round(($obj->price_1 * (100 - $discount) / 100), 2);
$obj->discount = $discount;
$obj->discount_text = 'Rabatt!';
}
if ($this->base_object->customer_group->show_tax) {
if (!isset($obj->tax)) {$obj->tax = 19;}
$obj->tax_value = round($obj->price_1 * ($obj->tax / 100), 2);
$obj->shop_price_1 = $obj->price_1 + $obj->tax_value;
$obj->bargain_tax_value = round($obj->bargain_price_1 * ($obj->tax / 100), 2);
$obj->shop_bargain_price_1 = $obj->bargain_price_1 + $obj->bargain_tax_value;
} else {
$obj->shop_price_1 = $obj->price_1;
$obj->shop_bargain_price_1 = $obj->bargain_price_1;
}
$obj->tax_rate = $this->tax_rates[$obj->tax_id]->steuersatz;
$obj->manufacturer_name = '';
if (isset($this->manufacturers[$obj->manufacturer_id])) {
$obj->manufacturer_name = $this->manufacturers[$obj->manufacturer_id]->name;
}
$obj->structure_name = '';
if (isset($this->structure[$obj->structure_id])) {
$obj->structure_name = $this->structure[$obj->structure_id]->name;
}
return $obj;
}
// end fix_pricing
public function get_flat_items() {
$sql = "SELECT i.*, ip.price_1, ip.bargain_price_1, ip.price_2, ip.bargain_price_2, ip.price_3, ip.bargain_price_3, ip.quantity_2, ip.quantity_3
FROM items i
LEFT JOIN item_prices ip ON ip.item_id = i.id
WHERE i.active=1
AND ip.customergroup_id=".$this->db->real_escape_string(isset($this->base_object->customer_group->id) ? intval($this->base_object->customer_group->id) : 1)." ORDER BY i.number";
$result = $this->db->query($sql);
$data = array();
if ($result->num_rows > 0) {
while ($obj = $result->fetch_object()) {
$data[] = $this->fix_data($obj);
}
}
return $data;
}
public function get_item_list_new($structure_id, $itemsPerPage = 'all', $currentPage = 1, $activeOnly = false, $fromManufacturerOnly = false, $sort_by = false, $infinite = false) {
// $manufacturers = Manufacturer::get_name_id_pair();
$limited = false;
if (is_numeric($itemsPerPage)) {
$limitMax = $itemsPerPage;
$limited = true;
}
// Load for infinite scrolling
if ($infinite) {
$limitMax = 24;
$limited = true;
}
if (is_numeric($currentPage)) {
$limitMin = $currentPage * $limitMax - $limitMax;
} else {
$limitMin = 0;
}
$whereAdd = '';
if ($activeOnly) {
$whereAdd .= " isa.structure_id=".$this->db->real_escape_string($structure_id);
}
if ($activeOnly) {
$whereAdd .= " AND i.active = 1 ";
}
if (is_numeric($fromManufacturerOnly)) {
$whereAdd .= " AND i.manufacturer_id = ".$fromManufacturerOnly;
}
$sql = "SELECT count(id) AS num
FROM items i
RIGHT JOIN item_structure_assign isa ON i.id = isa.item_id
WHERE $whereAdd";
$result = $this->db->query($sql);
$this->itemCount = ($result) ? $result->fetch_object()->num : 0;
//probably the wrong place
$sql = "
SELECT
i.*,
i.default_image_file_name AS file_name,
ip.price_1,
ip.bargain_price_1
FROM
item_prices ip
RIGHT JOIN
items i
ON (
i.id = ip.item_id
AND
ip.customergroup_id =".$this->db->real_escape_string($this->base_object->customer_group->price_group_id)."
)
RIGHT JOIN
item_structure_assign isa
ON
i.id = isa.item_id
WHERE
".$whereAdd."
GROUP BY
i.id
";
if ($sort_by) {
if ($sort_by == 'name_up') {
$sql .= " ORDER BY i.name ASC";
} else if ($sort_by == 'name_down') {
$sql .= " ORDER BY i.name DESC";
} else if ($sort_by == 'number_up') {
$sql .= " ORDER BY i.number ASC";
} else if ($sort_by == 'number_down') {
$sql .= " ORDER BY i.number DESC";
} else if ($sort_by == 'manufacturer_up') {
$sql .= " ORDER BY i.manufacturer_id ASC";
} else if ($sort_by == 'manufacturer_down') {
$sql .= " ORDER BY i.manufacturer_id DESC";
} else if ($sort_by == 'price_up') {
$sql .= " ORDER BY ip.price_1 ASC";
} else if ($sort_by == 'price_down') {
$sql .= " ORDER BY ip.price_1 DESC";
}
}
if ($limited) {
$sql .= " LIMIT
".$this->db->real_escape_string($limitMin).", ".$this->db->real_escape_string($limitMax);
}
$list = array();
$result = $this->db->query($sql);
$show_taxes = $this->base_object->customer_group->show_tax;
while ($obj = $result->fetch_object()) {
// bargain
if (!$this->check_bargain_active($obj, $obj->id)) {
$obj->bargain_price_1 = 0;
}
// get item discount
$discount = $this->get_item_discount(isset($this->base_object->customer_group->id) ? intval($this->base_object->customer_group->id) : 1, $obj->manufacturer_id, $obj->structure_id);
if ($discount) {
$obj->bargain_price_1 = round(($obj->price_1 * (100 - $discount) / 100), 2);
$obj->discount = $discount;
$obj->discount_text = 'Rabatt!';
}
// get quantity prices
$sql = "SELECT *
FROM item_prices
WHERE item_id = '".$this->db->real_escape_string($obj->id)."'
AND customergroup_id = '".$this->db->real_escape_string(isset($this->base_object->customer_group->id) ? intval($this->base_object->customer_group->id) : 1)."'
LIMIT 1";
$quantityprciesResult = $this->db->query($sql);
if ($quantityprciesResult) {
while ($QP = $quantityprciesResult->fetch_object()) {
foreach ($QP as $colName => $colValue) {
if (stristr($colName, 'price') && stristr($colName, 'bargain') && $colValue > 0 && $colValue < $obj->bargain_price_1) {
$obj->bargain_price_1 = $colValue;
$obj->price_praefix = 'ab';
} else if (stristr($colName, 'price') && !stristr($colName, 'bargain') && $colValue > 0 && $colValue < $obj->price_1) {
$obj->price_1 = $colValue;
$obj->price_praefix = 'ab';
}
}
}
}
// shop price
$obj->tax = $this->all_tax[$obj->tax_id]->steuersatz;
$obj->price_tax_text = str_replace('[tax]', number_format($obj->tax, 2, ',', '.'), isset($this->base_object->customer_group->price_tax_text) ? $this->base_object->customer_group->price_tax_text : 'inkl. [tax]% MwSt.');
$obj->manufacturer_text = $this->manufacturers[$obj->manufacturer_id]->name;
$obj->manufacturer_data = isset($this->manufacturers[$obj->manufacturer_id]) ? $this->manufacturers[$obj->manufacturer_id] : null;
if ($show_taxes) {
$obj->tax_value = round($obj->price_1 * ($obj->tax / 100), 4);
$obj->shop_price_1 = $obj->price_1 + $obj->tax_value;
$obj->bargain_tax_value = round($obj->bargain_price_1 * ($obj->tax / 100), 4);
$obj->shop_bargain_price_1 = $obj->bargain_price_1 + $obj->bargain_tax_value;
} else {
$obj->shop_price_1 = $obj->price_1;
$obj->shop_bargain_price_1 = $obj->bargain_price_1;
}
// get schema data
$obj->schema_data_attributes = array();
if ($obj->schema_id) {
$this->schema_id = $obj->schema_id;
$obj->schema_data = $this->get_schema_data();
foreach ($obj->schema_data->attributes as $attribute) {
if ($attribute->name) {
$attr = array(
'name' => $attribute->name,
'name_en' => $attribute->name_en,
'unit' => $attribute->unit,
'value' => $obj->{'attribute_'.$attribute->number},
'show_detail' => $attribute->show_detail,
'show_list' => $attribute->show_list,
'number' => $attribute->number
);
$obj->schema_data_attributes[] = $attr;
}
if ($obj->schema_data->selectable_attribute_1 == $attribute->number) {
$obj->schema_data->selectable_name_1 = $attribute->name;
$obj->price_variants_1 = explode(';', $obj->{'attribute_'.$attribute->number});
}
if ($obj->schema_data->selectable_attribute_2 == $attribute->number) {
$obj->schema_data->selectable_name_2 = $attribute->name;
$obj->price_variants_2 = explode(';', $obj->{'attribute_'.$attribute->number});
}
}
}
// get variants?
$sql = "SELECT i.*, ip.price_1, ip.bargain_price_1 FROM items i LEFT JOIN item_prices ip ON ip.item_id = i.id WHERE ip.price_1 > 0 AND i.parent_id = ".$this->db->real_escape_string($obj->id)." GROUP BY i.id ORDER BY ip.price_1";
$variant_result = $this->db->query($sql);
$obj->variant_structure = array();
if ($variant_result && $variant_result->num_rows > 0) {
$obj->price_praefix = 'ab';
$obj->bargain_price_1 = 0;
$obj->price_1 = 0;
$obj->shop_price_1 = 0;
$obj->shop_bargain_price_1 = 0;
while ($variant_obj = $variant_result->fetch_object()) {
// variants
// calc tax
$variant_obj->tax = $this->all_tax[$variant_obj->tax_id]->steuersatz;
$variant_obj->tax_value = round($variant_obj->price_1 * ($variant_obj->tax / 100), 4);
$variant_obj->price_1_tax = $variant_obj->price_1 + $variant_obj->tax_value;
$variant_obj->bargain_tax_value = round($variant_obj->bargain_price_1 * ($variant_obj->tax / 100), 2);
$variant_obj->bargain_price_1_tax = $variant_obj->bargain_price_1 + $variant_obj->bargain_tax_value;
// shop price
$variant_obj->sample_price = 0;
if ($this->base_object->customer_group->show_tax) {
$variant_obj->shop_price_1 = $variant_obj->price_1_tax;
$variant_obj->shop_bargain_price_1 = $variant_obj->bargain_price_1_tax;
} else {
$variant_obj->shop_price_1 = $variant_obj->price_1;
$variant_obj->shop_bargain_price_1 = $variant_obj->bargain_price_1;
}
if ($obj->shop_price_1 == 0 || $obj->shop_price_1 > $variant_obj->shop_price_1) {
$obj->shop_price_1 = $variant_obj->shop_price_1;
}
// calc sample price
$variant_obj->vpe_sampleprice_unit = $variant_obj->{'attribute_'.$obj->schema_data->base_price_field};
if ($obj->sample_unit && $variant_obj->vpe_sampleprice_unit) {
if ($variant_obj->price_je_vpe) {
if ($variant_obj->vpe_amount) {
if ($variant_obj->shop_bargain_price_1 > 0) {
$variant_obj->sample_price = $variant_obj->shop_bargain_price_1 / ($variant_obj->vpe_sampleprice_unit * $variant_obj->vpe_amount);
} else {
$variant_obj->sample_price = $variant_obj->shop_price_1 / ($variant_obj->vpe_sampleprice_unit * $variant_obj->vpe_amount);
}
}
} else {
if ($variant_obj->shop_bargain_price_1 > 0) {
$variant_obj->sample_price = ($variant_obj->shop_bargain_price_1 / $variant_obj->vpe_sampleprice_unit) / $obj->schema_data->base_price_faktor;
} else {
$variant_obj->sample_price = ($variant_obj->shop_price_1 / $variant_obj->vpe_sampleprice_unit) / $obj->schema_data->base_price_faktor;
}
}
}
$obj->variant_structure[] = array(
'id' => $variant_obj->id,
'level' => 2,
'name' => $variant_obj->name,
'number' => $variant_obj->number,
'short_uri' => $variant_obj->short_uri,
'price_1' => $variant_obj->price_1,
'bargain_price_1' => $variant_obj->bargain_price_1,
'shop_price_1' => $variant_obj->shop_price_1,
'shop_bargain_price_1' => $variant_obj->shop_bargain_price_1,
'sample_price' => $variant_obj->sample_price,
'default_image_file_name' => $variant_obj->default_image_file_name,
'price_type' => $variant_obj->price_type,
'data' => $variant_obj
);
// get smallest price for parent article
if (!$obj->smallest_variant_price_1 || $obj->smallest_variant_price_1 > $variant_obj->price_1) {
$obj->price_1 = $variant_obj->price_1;
$obj->bargain_price_1 = $variant_obj->bargain_price_1;
}
}
}
// intelectra individual
if ($obj->attribute_11 && $obj->attribute_15) {
$obj->sample_unit = $obj->attribute_15;
if (strstr($obj->sample_unit, '100')) {
$price_for_calc = ($obj->shop_bargain_price_1 > 0) ? $obj->shop_bargain_price_1 : $obj->shop_price_1;
$obj->sample_price = $price_for_calc / ($obj->attribute_11 * 10);
}
else {
$price_for_calc = ($obj->shop_bargain_price_1 > 0) ? $obj->shop_bargain_price_1 : $obj->shop_price_1;
$obj->sample_price = $price_for_calc / $obj->attribute_11;
}
}
// end intelectra individual
if (!isset($list[$obj->id])) {
$list[$obj->id] = $obj;
}
}
return $list;
}
private function _cleanupStructureAssignment($ignore = false) {
if ($ignore) {
$sql = "DELETE FROM item_structure_assign
WHERE item_id = ".$this->db->real_escape_string($this->id)."
AND structure_id NOT IN (".implode(', ', $ignore).")";
} else {
$sql = "DELETE FROM item_structure_assign WHERE item_id = ".$this->db->real_escape_string($this->id);
}
$this->db->query($sql);
}
private function _assignToStructures($structures) {
$newStrucutres = array();
if (is_array($structures)) {
foreach ($structures as $structure_id) {
if (is_numeric($structure_id)) {
$newStrucutres[] = '('.$this->id.', '.$structure_id.')';
}
}
$sql = "INSERT IGNORE INTO item_structure_assign (item_id, structure_id)
VALUES ".implode(', ', $newStrucutres);
$this->db->query($sql);
}
$this->_cleanupStructureAssignment($structures);
}
public function getStructureAssignment() {
$sql = "SELECT * FROM item_structure_assign WHERE item_id = ".$this->db->real_escape_string($this->id);
$res = $this->db->query($sql);
$assignedStructures = array();
while ($S = $res->fetch_object()) {
$assignedStructures[$S->structure_id] = $S->pos;
}
return $assignedStructures;
}
public function set_inventory($quantity) {
if (is_int((int) $quantity)) {
$quantity = (int) $quantity;
if (!$this->id) {
return false;
}
$sql = "UPDATE items SET inventory=".$this->db->real_escape_string($quantity)." WHERE id=".$this->db->real_escape_string($this->id);
return $this->db->query($sql);
}
return false;
}
public function searchItems($searchString, $idsOnly = false, $loose = true) {
//echo "Itemclass->searchItems called";
$timer_start = microtime(true);
$searchString_trimmed = trim($searchString);
$searchString_filtered = preg_replace("@[^\p{L}\p{N}\s\*]@sui", '', $searchString_trimmed);
if ($loose) {
$searchString_enriched = preg_replace("@([^\s])(\s)@sui", '$1*$2', $searchString_filtered);
$searchString_ready = $searchString_enriched.'*';
} else {
$searchString_ready = $searchString_filtered;
}
$results_items_associations = $this->_searchItemWithinItemsAndAssociations($searchString_ready, $idsOnly);
$results_associations = $this->_searchItemWithinAssociations($searchString_ready);
$results_items = $this->_searchItemWithinItems($searchString_ready);
$results = array_replace($results_items_associations, $results_associations, $results_items);
$running_time = microtime(true) - $timer_start;
$result = array(
'searchstring' => $searchString,
'results' => count($results),
'queryTime' => $running_time,
'data' => $results
);
return $result;
}
private function _searchItemWithinItemsAndAssociations($searchString, $idsOnly = false) {
$query = "
SELECT
tbl_items.id, tbl_items.number, tbl_items.name, tbl_items.short_uri,
(tbl_items.matchpoints + 1) / (tbl_zuordnungen.matchpoints + 1) AS relevance
FROM
(
SELECT
i.id, i.number, i.name, i.short_uri,
MATCH (
i.number, i.name, i.detail_description,
i.attribute_1, i.attribute_2, i.attribute_3,
i.attribute_4, i.attribute_5
) AGAINST (
'".$this->db->real_escape_string($searchString)."'
COLLATE utf8_general_ci IN NATURAL LANGUAGE MODE
) AS matchpoints
FROM
items i
WHERE
i.active = 1
AND
i.parent_id = 0
AND
MATCH (
i.number, i.name, i.detail_description,
i.attribute_1, i.attribute_2, i.attribute_3,
i.attribute_4, i.attribute_5
) AGAINST (
'".$this->db->real_escape_string($searchString)."'
COLLATE utf8_general_ci IN BOOLEAN MODE
)
) AS tbl_items
INNER JOIN
(
SELECT
gz.anr, gz.bezeichnung1,
MATCH (
gz.bezeichnung1
) AGAINST (
'".$this->db->real_escape_string($searchString)."'
COLLATE utf8_general_ci IN NATURAL LANGUAGE MODE
) AS matchpoints
FROM
import_geraetezuordnung gz
WHERE
MATCH (
gz.bezeichnung1
) AGAINST (
'".$this->db->real_escape_string($searchString)."'
COLLATE utf8_general_ci IN BOOLEAN MODE
)
) AS tbl_zuordnungen
ON
tbl_items.number = tbl_zuordnungen.anr
GROUP BY
tbl_items.number
ORDER BY
relevance DESC
";
$rs = $this->db->query($query);
$results = array();
if ($idsOnly) {
while ($I = $rs->fetch_object()) {
$results[$I->id] = $I->id;
}
} else {
$method = __METHOD__;
while ($I = $rs->fetch_object()) {
$I->method = $method;
$I->string = $searchString;
$results[$I->id] = $I;
}
}
return $results;
}
private function _searchItemWithinAssociations($searchString, $idsOnly = false) {
$searchString_limited = '+'.preg_replace("@(\s)@sui", '$1+', $searchString);
$query = "SELECT anr FROM import_geraetezuordnung
WHERE
MATCH (bezeichnung1)
AGAINST ('".$this->db->real_escape_string($searchString_limited)."' COLLATE utf8_general_ci IN BOOLEAN MODE)
GROUP BY anr";
$rs = $this->db->query($query);
$itemNumbers = array();
while ($A = $rs->fetch_object()) {
$itemNumbers[] = $A->anr;
}
$results = array();
if (count($itemNumbers) > 0) {
$itemNumberList = implode(',', $itemNumbers);
$queryItems = "SELECT id, number, name, short_uri
FROM items FORCE INDEX (parent_id_number_active)
WHERE parent_id = 0 AND number IN (".$itemNumberList.") AND active = 1";
$rsItems = $this->db->query($queryItems);
if ($idsOnly) {
while ($I = $rs->fetch_object()) {
$results[$I->id] = $I->id;
}
} else {
$method = __METHOD__;
while ($I = $rsItems->fetch_object()) {
$I->method = $method;
$I->string = $searchString_limited;
$results[$I->id] = $I;
}
}
}
return $results;
}
private function _searchItemWithinItems($searchString, $idsOnly = false) {
$searchString_limited = '+'.preg_replace("@(\s)@sui", '$1+', $searchString);
$query = "
SELECT
id, number, name, short_uri,
MATCH (
number, name, detail_description, attribute_1, attribute_2,
attribute_3, attribute_4, attribute_5
) AGAINST (
'".$this->db->real_escape_string($searchString_limited)."'
COLLATE utf8_general_ci IN NATURAL LANGUAGE MODE
) AS relevance
FROM
items
WHERE
active = 1
AND
parent_id = 0
AND
MATCH (
number, name, detail_description, attribute_1, attribute_2,
attribute_3, attribute_4, attribute_5
) AGAINST (
'".$this->db->real_escape_string($searchString_limited)."'
COLLATE utf8_general_ci IN BOOLEAN MODE
)
ORDER BY
relevance DESC
";
$rs = $this->db->query($query);
$results = array();
if ($idsOnly) {
while ($I = $rs->fetch_object()) {
$results[$I->id] = $I->id;
}
} else {
$method = __METHOD__;
while ($I = $rs->fetch_object()) {
$I->method = $method;
$I->string = $searchString_limited;
$results[$I->id] = $I;
}
}
return $results;
}
public function get_all_structure_items($structure_id) {
// get items
$sql = "SELECT id, name, short_uri, active FROM items WHERE active=1 AND structure_id=".$this->db->real_escape_string($structure_id);
$result = $this->db->query($sql);
if ($this->db->error) {
$log_object = Logger::get_instance();
$log_object->info('Error in /core/items_class.php->get_all_structure_items()', $this->db->error.', sql:'.$sql);
}
$data = array();
if ($result) {
while ($row = $result->fetch_object()) {
$data[] = $row;
}
}
return $data;
}
public function get_item_list_by_type($structure_id, $itemsPerPage = 'all', $currentPage = 1, $activeOnly = false, $fromManufacturerOnly = false, $sort_by = false, $infinite = false) {
$limited = false;
if (is_numeric($itemsPerPage)) {
$limitMax = $itemsPerPage;
$limited = true;
}
// Load for infinite scrolling
if ($infinite) {
$limitMax = 24;
$limited = true;
}
if (is_numeric($currentPage)) {
$limitMin = $currentPage * $limitMax - $limitMax;
} else {
$limitMin = 0;
}
$structure_object = new Structure($this->base_object);
$structure_data = $structure_object->get_by_id($structure_id);
$whereAdd = 'isa.item_type_definition_id='.$structure_data->item_type;
if ($activeOnly) {
$whereAdd .= " AND i.active = 1 ";
}
if (is_numeric($fromManufacturerOnly)) {
$whereAdd .= " AND i.manufacturer_id = ".$fromManufacturerOnly;
}
// get type
include_once './core/itemtype.class.php';
$item_type_object = New ItemType($this->base_object);
$type_data = $item_type_object->load($structure_data->item_type);
if ($type_data['item_type_definition_type'] == 1) {
$today = getdate();
$today = $today['year'].'-'.$today['mon'].'-'.$today['mday'];
$whereAdd .= " AND isa.item_type_available_from <= '".$this->db->real_escape_string($today)."'
AND isa.item_type_available_until >= '".$this->db->real_escape_string($today)."'";
}
$sql = "SELECT count(id) AS num
FROM items i
RIGHT JOIN item_types isa
ON i.id = isa.item_id
WHERE $whereAdd";
$result = $this->db->query($sql);
$this->itemCount = ($result) ? $result->fetch_object()->num : 0;
$sql = "
SELECT
i.*,
i.default_image_file_name AS file_name,
ip.price_1,
ip.bargain_price_1
FROM
item_prices ip
RIGHT JOIN
items i
ON (
i.id = ip.item_id
AND
ip.customergroup_id =".$this->db->real_escape_string($this->base_object->customer_group->price_group_id)."
)
RIGHT JOIN
item_types isa
ON
i.id = isa.item_id
WHERE
".$whereAdd."
GROUP BY
i.id";
if ($sort_by) {
if ($sort_by == 'name_up') {
$sql .= " ORDER BY i.name ASC";
} else if ($sort_by == 'name_down') {
$sql .= " ORDER BY i.name DESC";
} else if ($sort_by == 'number_up') {
$sql .= " ORDER BY i.number ASC";
} else if ($sort_by == 'number_down') {
$sql .= " ORDER BY i.number DESC";
} else if ($sort_by == 'manufacturer_up') {
$sql .= " ORDER BY i.manufacturer_id ASC";
} else if ($sort_by == 'manufacturer_down') {
$sql .= " ORDER BY i.manufacturer_id DESC";
} else if ($sort_by == 'price_up') {
$sql .= " ORDER BY ip.price_1 ASC";
} else if ($sort_by == 'price_down') {
$sql .= " ORDER BY ip.price_1 DESC";
}
}
if ($limited) {
$sql .= " LIMIT ".$this->db->real_escape_string($limitMin).", ".$this->db->real_escape_string($limitMax);
}
$list = array();
$result = $this->db->query($sql);
$show_taxes = $this->base_object->customer_group->show_tax;
while ($obj = $result->fetch_object()) {
// bargain
if (!$this->check_bargain_active($obj, $obj->id)) {
$obj->bargain_price_1 = 0;
}
// get item discount
$discount = $this->get_item_discount(isset($this->base_object->customer_group->id) ? intval($this->base_object->customer_group->id) : 1, $obj->manufacturer_id, $obj->structure_id);
if ($discount) {
$obj->bargain_price_1 = round(($obj->price_1 * (100 - $discount) / 100), 2);
$obj->discount = $discount;
$obj->discount_text = 'Rabatt!';
}
// shop price
$obj->tax = $this->all_tax[$obj->tax_id]->steuersatz;
$obj->price_tax_text = str_replace('[tax]', number_format($obj->tax, 2, ',', '.'), isset($this->base_object->customer_group->price_tax_text) ? $this->base_object->customer_group->price_tax_text : 'inkl. [tax]% MwSt.');
$obj->manufacturer_text = $this->manufacturers[$obj->manufacturer_id]->name;
$obj->manufacturer_data = isset($this->manufacturers[$obj->manufacturer_id]) ? $this->manufacturers[$obj->manufacturer_id] : null;
if ($show_taxes) {
$obj->tax_value = round($obj->price_1 * ($obj->tax / 100), 4);
$obj->shop_price_1 = $obj->price_1 + $obj->tax_value;
$obj->bargain_tax_value = round($obj->bargain_price_1 * ($obj->tax / 100), 4);
$obj->shop_bargain_price_1 = $obj->bargain_price_1 + $obj->bargain_tax_value;
} else {
$obj->shop_price_1 = $obj->price_1;
$obj->shop_bargain_price_1 = $obj->bargain_price_1;
}
// get schema data
$obj->schema_data_attributes = array();
if ($obj->schema_id) {
$this->schema_id = $obj->schema_id;
$obj->schema_data = $this->get_schema_data();
foreach ($obj->schema_data->attributes as $attribute) {
if ($attribute->name) {
$attr = array(
'name' => $attribute->name,
'name_en' => $attribute->name_en,
'unit' => $attribute->unit,
'value' => $obj->{'attribute_'.$attribute->number},
'show_detail' => $attribute->show_detail,
'show_list' => $attribute->show_list,
'number' => $attribute->number
);
$obj->schema_data_attributes[] = $attr;
}
if ($obj->schema_data->selectable_attribute_1 == $attribute->number) {
$obj->schema_data->selectable_name_1 = $attribute->name;
$obj->price_variants_1 = explode(';', $obj->{'attribute_'.$attribute->number});
}
if ($obj->schema_data->selectable_attribute_2 == $attribute->number) {
$obj->schema_data->selectable_name_2 = $attribute->name;
$obj->price_variants_2 = explode(';', $obj->{'attribute_'.$attribute->number});
}
}
}
// get variants?
$sql = "SELECT i.*, ip.price_1, ip.bargain_price_1 FROM items i LEFT JOIN item_prices ip ON ip.item_id = i.id WHERE ip.price_1 > 0 AND i.parent_id = ".$this->db->real_escape_string($obj->id)." GROUP BY i.id ORDER BY ip.price_1";
$variant_result = $this->db->query($sql);
$obj->variant_structure = array();
if ($variant_result && $variant_result->num_rows > 0) {
$obj->price_praefix = 'ab';
$obj->bargain_price_1 = 0;
$obj->price_1 = 0;
$obj->shop_price_1 = 0;
$obj->shop_bargain_price_1 = 0;
while ($variant_obj = $variant_result->fetch_object()) {
// variants
// calc tax
$variant_obj->tax = $this->all_tax[$variant_obj->tax_id]->steuersatz;
$variant_obj->tax_value = round($variant_obj->price_1 * ($variant_obj->tax / 100), 4);
$variant_obj->price_1_tax = $variant_obj->price_1 + $variant_obj->tax_value;
$variant_obj->bargain_tax_value = round($variant_obj->bargain_price_1 * ($variant_obj->tax / 100), 2);
$variant_obj->bargain_price_1_tax = $variant_obj->bargain_price_1 + $variant_obj->bargain_tax_value;
// shop price
$variant_obj->sample_price = 0;
if ($this->base_object->customer_group->show_tax) {
$variant_obj->shop_price_1 = $variant_obj->price_1_tax;
$variant_obj->shop_bargain_price_1 = $variant_obj->bargain_price_1_tax;
} else {
$variant_obj->shop_price_1 = $variant_obj->price_1;
$variant_obj->shop_bargain_price_1 = $variant_obj->bargain_price_1;
}
if ($obj->shop_price_1 == 0 || $obj->shop_price_1 > $variant_obj->shop_price_1) {
$obj->shop_price_1 = $variant_obj->shop_price_1;
}
// calc sample price
$variant_obj->vpe_sampleprice_unit = $variant_obj->{'attribute_'.$obj->schema_data->base_price_field};
if ($obj->sample_unit && $variant_obj->vpe_sampleprice_unit) {
if ($variant_obj->price_je_vpe) {
if ($variant_obj->vpe_amount) {
if ($variant_obj->shop_bargain_price_1 > 0) {
$variant_obj->sample_price = $variant_obj->shop_bargain_price_1 / ($variant_obj->vpe_sampleprice_unit * $variant_obj->vpe_amount);
} else {
$variant_obj->sample_price = $variant_obj->shop_price_1 / ($variant_obj->vpe_sampleprice_unit * $variant_obj->vpe_amount);
}
}
} else {
if ($variant_obj->shop_bargain_price_1 > 0) {
$variant_obj->sample_price = ($variant_obj->shop_bargain_price_1 / $variant_obj->vpe_sampleprice_unit) / $obj->schema_data->base_price_faktor;
} else {
$variant_obj->sample_price = ($variant_obj->shop_price_1 / $variant_obj->vpe_sampleprice_unit) / $obj->schema_data->base_price_faktor;
}
}
}
$obj->variant_structure[] = array(
'id' => $variant_obj->id,
'level' => 2,
'name' => $variant_obj->name,
'number' => $variant_obj->number,
'short_uri' => $variant_obj->short_uri,
'price_1' => $variant_obj->price_1,
'bargain_price_1' => $variant_obj->bargain_price_1,
'shop_price_1' => $variant_obj->shop_price_1,
'shop_bargain_price_1' => $variant_obj->shop_bargain_price_1,
'sample_price' => $variant_obj->sample_price,
'default_image_file_name' => $variant_obj->default_image_file_name,
'price_type' => $variant_obj->price_type,
'data' => $variant_obj
);
// get smallest price for parent article
if (!$obj->smallest_variant_price_1 || $obj->smallest_variant_price_1 > $variant_obj->price_1) {
$obj->price_1 = $variant_obj->price_1;
$obj->bargain_price_1 = $variant_obj->bargain_price_1;
}
}
}
if (!isset($list[$obj->id])) {
$list[$obj->id] = $obj;
}
}
return $list;
}
function update_last_change() {
$sql = "UPDATE items SET last_change_date = NOW(), last_change_user_id=".$this->db->real_escape_string($this->base_object->customer->id)." WHERE id=".$this->db->real_escape_string($this->id);
$result = $this->db->query($sql);
}
private function check_bargain_active($obj, $id) {
if ($obj->bargain_price_type == 1) {
return 1;
} else if ($obj->bargain_price_type == 2) {
$today = getdate();
$today = $today['year'].'-'.$today['mon'].'-'.$today['mday'];
$sql = "SELECT item_types.item_type_id
FROM item_types
LEFT JOIN item_type_definitions ON item_type_definitions.item_type_definition_id=item_types.item_type_definition_id
WHERE item_id =".$this->db->real_escape_string($id).
" AND item_type_available_from <= '".$this->db->real_escape_string($today)."'
AND item_type_available_until >= '".$this->db->real_escape_string($today)."'
AND item_type_definitions.item_type_definition_type=1
AND item_type_definitions.item_type_definition_is_active=1";
$result = $this->db->query($sql);
$found = $result->fetch_array();
if ($found) {
return 1;
}
}
return 0;
}
public function createIntWithTableData($html) {
$int = new stdClass();
$int->geraete_table_data = $html;
return $int;
}
private function loadWarnings($warningIdsList) {
$articleWarnings = [];
if ($warningIdsList) {
$ids = explode(',', $warningIdsList);
$placeholders = implode(',', array_fill(0, count($ids), '?'));
$sqlWarn = "
SELECT warning_id, name, beschreibung, bild, bildnr, bilddateiname
FROM sicherheitshinweis
WHERE warning_id IN ($placeholders)
ORDER BY warning_id
";
$stmtWarn = $this->db->prepare($sqlWarn);
if ($stmtWarn) {
$types = str_repeat('i', count($ids));
$stmtWarn->bind_param($types, ...$ids);
$stmtWarn->execute();
$resultWarn = $stmtWarn->get_result();
$articleWarnings = $resultWarn->fetch_all(MYSQLI_ASSOC);
// Bilddateiname für jede Warnung generieren
foreach ($articleWarnings as &$warning) {
$warning['final_bilddateiname'] = $this->generateImageFileName($warning);
}
} else {
}
}
return $articleWarnings;
}
// Funktion zum Laden der Dokumente (umbenannt auf "SafetyInstructions")
private function loadSafetyInstructions($warningDocsList) {
$articleSafetyInstructions = []; // Dokumente
$documentFields = [
'Bedienungsanleitung' => 'Bedienungsanleitung',
'EU_Datenblatt' => 'EU_Datenblatt',
'Energielabel' => 'Energielabel',
'Produktdatenblatt' => 'Produktdatenblatt',
'Sicherheitsdatenblatt' => 'Sicherheitsdatenblatt',
'Zertifikat' => 'Zertifikat',
'null_feld' => 'null_feld',
];
foreach ($documentFields as $key => $field) {
if (!empty($warningDocsList[$field])) {
$articleSafetyInstructions[] = (object)[
'name' => $key,
'file_name' => $warningDocsList[$field]
];
error_log("Dokument gefunden: $key = {$warningDocsList[$field]}");
}
}
return $articleSafetyInstructions;
}
// 🤖 AI SHOPPING SCHEMA METHODS
private function shouldGenerateAISchema($item) {
// Nur für aktive Artikel mit ID
if (!$item || !isset($item->id) || !$item->active) {
return false;
}
// Nicht für Debug-Aufrufe
if (isset($_GET['debug_performance'])) {
return false;
}
// Optional: Nur für bestimmte Kategorien
// if (!$this->isRelevantForAI($item)) return false;
return true;
}
private function generateAIShoppingSchema($item) {
$python_script = dirname(__FILE__) . '/python/ai_shopping_schema_generator.py';
if (file_exists($python_script)) {
$data = json_encode([
'item_id' => $item->id,
'name' => $item->name ?? '',
'warnings' => $item->warnings ?? [],
'attributes' => $this->extractTechnicalAttributes($item),
'compatibility' => $this->getCompatibilityInfo($item),
'price' => $item->price ?? 0,
'manufacturer' => $item->manufacturer_data->name ?? '',
'category' => $item->structure_name ?? 'Ersatzteil',
'article_number' => $item->number ?? '',
'slug' => $this->generateSlug($item)
]);
// Non-blocking execution - Shop-Performance bleibt unberührt!
$command = "python3 " . escapeshellarg($python_script) . " " . escapeshellarg($data) . " >/dev/null 2>&1 &";
shell_exec($command);
// Debug-Output (optional)
if (isset($_GET['debug_ai'])) {
echo "<div style='background:purple;color:white;padding:10px;'>🤖 AI SCHEMA: Generated for item {$item->id}</div>";
}
}
}
private function extractTechnicalAttributes($item) {
$attributes = [];
// Extrahiere technische Attribute aus verfügbaren Feldern
$technical_fields = [
'attribute_1', 'attribute_2', 'attribute_3', 'attribute_4', 'attribute_5',
'attribute_6', 'attribute_7', 'attribute_8', 'attribute_9', 'attribute_10',
'manufacturer_item_number', 'ean', 'weight', 'dimensions'
];
foreach ($technical_fields as $field) {
if (isset($item->$field) && !empty($item->$field)) {
$attributes[$field] = $item->$field;
}
}
return $attributes;
}
private function getCompatibilityInfo($item) {
$compatibility = [];
// Herstellerinformationen
if (isset($item->manufacturer_data)) {
$compatibility['manufacturer'] = $item->manufacturer_data->name ?? '';
}
// Kategorieinfo
if (isset($item->structure_name)) {
$compatibility['category'] = $item->structure_name;
}
// EAN für Kompatibilitäts-Matching
if (isset($item->ean) && !empty($item->ean)) {
$compatibility['ean'] = $item->ean;
}
return $compatibility;
}
private function generateSlug($item) {
$name = $item->name ?? '';
$slug = strtolower($name);
$slug = preg_replace('/[^a-z0-9\s-]/', '', $slug);
$slug = preg_replace('/\s+/', '-', trim($slug));
return substr($slug, 0, 50);
}
/**
* 🐍 Python Smart Price Update Service
* Verhindert 50+ einzelne REPLACE INTO Abfragen
*/
private function callPythonPriceService($priceData) {
try {
$python_script = __DIR__ . '/../modules/import/price_update_service.py';
if (!file_exists($python_script)) {
return false; // Kein Python Service verfügbar
}
$service_data = [
'action' => 'update_prices',
'item_id' => $this->id,
'prices' => $priceData['prices'] ?? []
];
$json_input = escapeshellarg(json_encode($service_data, JSON_UNESCAPED_UNICODE));
$command = "python3 {$python_script} {$json_input} 2>&1";
$output = shell_exec($command);
$result = json_decode($output, true);
if (isset($_GET['debug_performance']) && $result) {
echo "<div style='background:cyan;padding:5px;'>🐍 Python Output: " . htmlspecialchars($output) . "</div>";
}
return $result;
} catch (Exception $e) {
error_log("Python Price Service Error: " . $e->getMessage());
return false; // Fallback zu PHP
}
}
/**
* 🚀 ASYNC Image Processing - verhindert 504 Timeouts!
* Startet Python Image Service im Hintergrund (NON-BLOCKING!)
*/
private function startAsyncImageProcessing($source_file, $file_name, $item_id, $watermark_enabled = false) {
try {
$python_script = __DIR__ . '/../modules/import/image_processing_service.py';
// Fallback zu PHP wenn kein Python Service verfügbar
if (!file_exists($python_script)) {
error_log("Python Image Service not found, using PHP fallback");
return $this->processPHPImageFallback($source_file, $file_name, $watermark_enabled);
}
// Prepare service data
$service_data = [
'source_file' => $source_file,
'item_id' => $item_id,
'watermark' => $watermark_enabled ? 1 : 0,
'shop_system' => SHOP_SYSTEM,
'document_root' => $_SERVER['DOCUMENT_ROOT'],
'image_sizes' => $this->base_object->config->shopConfiguration['images']
];
$json_input = escapeshellarg(json_encode($service_data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
// 🔥 NON-BLOCKING EXECUTION: Run Python in background with nohup
// Output redirected to log file, process detached with &
$log_file = $_SERVER['DOCUMENT_ROOT'] . "/logs" . "/image_processing_{$item_id}.log";
$command = "nohup python3 {$python_script} {$json_input} > {$log_file} 2>&1 &";
// Windows compatibility check
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
// Windows: use START /B for background execution
$command = "start /B python {$python_script} {$json_input} > {$log_file} 2>&1";
}
// Execute NON-BLOCKING command
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { exec($command); } else { $cmd_wrapped = "( $command ) > /dev/null 2>&1"; shell_exec($cmd_wrapped); }
if (isset($_GET['debug_performance'])) {
echo '<div style="background:green;color:white;padding:5px;">🚀 Async Python Image Service gestartet (non-blocking) - Log: ' . $log_file . '</div>';
}
return true;
} catch (Exception $e) {
error_log("Async Image Processing Error: " . $e->getMessage());
// Fallback zu PHP bei Fehler
return $this->processPHPImageFallback($source_file, $file_name, $watermark_enabled);
}
}
/**
* PHP Fallback für Image Processing (wenn Python nicht verfügbar)
* ACHTUNG: Kann 504 Timeouts verursachen bei großen Bildern!
*/
private function processPHPImageFallback($targetFile, $file_name, $watermark_activ = false) {
try {
if (isset($_GET['debug_performance'])) {
$start_time = microtime(true);
echo '<div style="background:orange;color:white;padding:5px;">⚠️ Python nicht verfügbar - PHP Fallback wird verwendet (kann langsam sein)</div>';
}
// resize max image size
$imaginator = new phImaginator();
$imaginator->add($targetFile);
$imaginator->Resize_fitBoth('800', '800');
$imaginator->save();
// create 4 scaled down images
if (class_exists('Imagick')) {
foreach ($this->base_object->config->shopConfiguration['images'] as $pair) {
$image = new Imagick($targetFile);
$image->thumbnailImage($pair[1], $pair[1]);
$image->setImageFileName(dirname($targetFile) . '/' . $pair[0] . basename($targetFile));
$image->writeImage();
$image->destroy();
}
}
// set watermark
if ($watermark_activ && $this->base_object->config->shopConfiguration['item_watermark_image']) {
$this->watermark($targetFile);
}
// resize image (additional sizes)
if (isset($this->base_object->config->shopConfiguration['images'])) {
foreach ($this->base_object->config->shopConfiguration['images'] as $image) {
$image_name = $image[0];
$size = $image[1];
$imaginator = new phImaginator();
$imaginator->add($targetFile);
$imaginator->Resize_fitBoth($size, $size);
$imaginator->nameAdd($image_name);
$imaginator->save();
}
}
if (isset($_GET['debug_performance'])) {
$end_time = microtime(true);
$execution_time = ($end_time - $start_time) * 1000;
echo '<div style="background:red;color:white;padding:5px;">PHP Fallback completed: ' . number_format($execution_time, 2) . 'ms</div>';
}
return true;
} catch (Exception $e) {
error_log("PHP Image Fallback Error: " . $e->getMessage());
return false;
}
}
}
?>