Files
grzanieplus.pl/web/baselinker.php.backup
2025-03-12 17:06:23 +01:00

1534 lines
58 KiB
Plaintext

<?php
/**
* Plik wymiany danych z systemem Baselinker
* @author Sewer Skrzypiński <info@baselinker.com>
* @version 4
* @package baselinker
*/
/** -----------------------------------------------------------------------------------------------------------
* Ustawienia wpisywane przez sprzedawcę
* - Należy uzupełnić dane wprowadzając je między apostrofy
*/
$options['baselinker_pass'] = 'rcszksgwexd171b6x4mz5m77n2psqpo3'; //hasło do komunikacji (dostępne w panelu Baselinkera w zakładce 'sklep internetowy')
$options['db_host'] = 'localhost'; //adres hosta bazy danych (najczęściej localhost)
$options['db_user'] = 'rsduvqkeer_grzanie'; //użytkownik bazy danych
$options['db_pass'] = '[QD-*l7%0M-Hicik'; //hasło bazy danych
$options['db_name'] = 'rsduvqkeer_grzanieplus-pl'; //nazwa bazy danych
$options['db_prefix'] = ''; //prefiks tabel bazy danych - domyślnie pozostaw pusty aby wykryć automatycznie
$options['images_folder'] = 'http://grzanieplus.pl/'; //adres folderu zawierającego zdjęcia produktów i producentów (rozpoczęty 'http://', zakończony /)
$options['special_price'] = 1; //czy używać ceny promocyjnej jeśli produkt jest w promocji? (0 - nie, 1 - tak)
$options['charset'] = 'UTF-8'; //zestaw znaków bazy danych (standardowo UTF-8)
$options['sote_shophash'] = 'f9862393534ee289a67584de0b0768a0'; // klucz rozkodowywania danych zamówienia (zawarty w pliku core/data/config/__stRegister.yml)
error_reporting(E_ERROR | E_WARNING);
date_default_timezone_set('Europe/Warsaw');
/** -----------------------------------------------------------------------------------------------------------
* Funkcje zarządzające komunikacją (przedrostek Conn_) oraz funkcje ułatwiające zapytania SQL (przedrostek DB_)
* - Jednakowe niezależnie od platformy
* - Nie należy edytować poniższego kodu
*/
/**
* Definicja funkcji json_encode oraz json_decode dla PHP4 (istnieją domyślnie w PHP5.2), iconv() dla tablic, oraz array_walk_recursive()
* Nie należy edytować. Credits goes to Steve http://usphp.com/manual/en/function.json-encode.php#82904
*/
if (!function_exists('json_encode'))
{
function json_encode($a=false,$is_key=false)
{if (is_null($a)) return 'null';if ($a === false) return 'false';if ($a === true) return 'true';
if (is_scalar($a)){if(is_int($a)&&$is_key){return '"'.$a.'"';} if (is_float($a)){return floatval(str_replace(",", ".", strval($a)));}if (is_string($a)){
static $jsonReplaces = array(array("\\", "/", "\n", "\t", "\r", "\b", "\f", '"'), array('\\\\', '\\/', '\\n', '\\t', '\\r', '\\b', '\\f', '\"'));
return '"' . str_replace($jsonReplaces[0], $jsonReplaces[1], $a) . '"';} else return $a;} $isList = true;
for ($i = 0, reset($a); $i < count($a); $i++, next($a)){if (key($a) !== $i){$isList = false;break;}}
$result = array(); if ($isList){foreach ($a as $v) $result[] = json_encode($v); return '[' . join(',', $result) . ']';}
else {foreach ($a as $k => $v) $result[] = json_encode($k,true).':'.json_encode($v); return '{' . join(',', $result) . '}';}}
}
if (!function_exists('json_decode'))
{
function json_decode($json, $assoc = true)
{$comment = false; $out = '$x='; for ($i=0; $i<strlen($json); $i++) { if (!$comment) {if (($json[$i] == '{') || ($json[$i] == '['))
$out .= ' array('; else if (($json[$i] == '}') || ($json[$i] == ']')) $out .= ')'; else if ($json[$i] == ':') $out .= '=>';
else $out .= $json[$i]; } else $out .= $json[$i]; if ($json[$i] == '"' && $json[($i-1)]!="\\") $comment = !$comment;} eval($out . ';'); return $x;}
}
if (!function_exists('array_walk_recursive'))
{
function array_walk_recursive(&$input, $funcname, $userdata = "")
{if (!is_callable($funcname)){return false;}if (!is_array($input)){return false;}foreach ($input AS $key => $value){
if (is_array($input[$key])){array_walk_recursive($input[$key], $funcname, $userdata);}else{$saved_value = $value;
if (!empty($userdata)){$funcname($value, $key, $userdata);}else{$funcname($value, $key);}if ($value != $saved_value)
{$input[$key] = $value;}}}return true;}
}
function array_iconv(&$val, $key, $userdata)
{$val = iconv($userdata[0], $userdata[1], $val);}
function recursive_iconv($in_charset, $out_charset, $arr)
{if (!is_array($arr)){return iconv($in_charset, $out_charset, $arr);}$ret = $arr;
array_walk_recursive($ret, "array_iconv", array($in_charset, $out_charset));return $ret;}
/**
* Funkcje wykonujące zapytania SQL
*/
function DB_Query($sql)
{
global $dbh;
if (func_num_args() > 1){$i = 0; foreach(func_get_args() as $val){if ($i==0){$i++; continue;}$sql = str_replace("{".($i-1)."}", substr($dbh->quote($val), 1, -1), $sql); $i++;}}
if (!($sth = $dbh->prepare($sql)))
{
$err = $dbh->errorInfo();
Conn_error('db_query', 'SQL error: ' . $err[2]);
}
if (!($sth->execute()))
{
$err = $sth->errorInfo();
Conn_error('db_query', 'SQL error: ' . $err[2]);
}
return $sth;
}
function DB_Result($sth, $num = 0) { if (DB_NumRows($sth) > $num){return $sth->fetchColumn($num);} return false; }
function DB_Identity() { global $dbh; return $dbh->lastInsertId(); }
function DB_NumRows($sth) { return $sth->rowCount(); }
function DB_Fetch($sth) { return $sth->fetch(PDO::FETCH_ASSOC); }
/**
* Funkcja obsługująca żądania i wysyłająca odpowiedź.
* Zalecane jest pozostawienie funkcji w tej postaci niezależnie od platformy
* @global array $options : tablica z ustawieniami ogólnymi
*/
function Conn_Init()
{
global $options;
//sprawdzanie poprawności hasła wymiany danych
if(!isset($_POST['bl_pass']))
{Conn_Error("no_password","Odwołanie do pliku bez podania hasła. Jest to poprawny komunikat jeśli plik integracyjny został otworzony w przeglądarce internetowej.");}
elseif($options['baselinker_pass'] == "" || $options['baselinker_pass'] !== $_POST['bl_pass'])
{Conn_Error("incorrect_password");}
//zmiana kodowania danych wejściowych
if($options['charset'] != "UTF-8")
{
foreach($_POST as $key => $val)
{$_POST[$key] = iconv('UTF-8', $options['charset'].'//IGNORE', $val);}
}
//łączenie z bazą danych sklepu
Shop_ConnectDatabase($_POST);
//rozbijanie tablic z danymi
if(isset($_POST['orders_ids'])){$_POST['orders_ids'] = explode(',', $_POST['orders_ids']);}
if(isset($_POST['products_id'])){$_POST['products_id'] = explode(',', $_POST['products_id']);}
if(isset($_POST['fields'])){$_POST['fields'] = explode(',', $_POST['fields']);}
if(isset($_POST['products'])){$_POST['products'] = json_decode(stripslashes($_POST['products']), true);}
//sprawdzanie czy podana metoda jest zaimplementowana
if(function_exists("Shop_".$_POST['action']))
{
$method = "Shop_".$_POST['action'];
Conn_SendResponse($method($_POST));
}
else
{Conn_Error("unsupported_action", "No action: ".$_POST['action']);}
}
/**
* Funkcja generująca odpowiedź do systemu w formacie JSON
* @global array $options tablica z ustawieniami ogólnymi
*/
function Conn_SendResponse($response)
{
global $options;
//zmiana kodowania danych wyjściowych
if($options['charset'] != "UTF-8" && count($response) > 0)
{
foreach($response as $key => $val)
{$response[$key] = recursive_iconv($options['charset'], 'UTF-8//IGNORE', $val);}
}
print json_encode($response);
exit();
}
/**
* Funkcja wypisująca kominukat błędu w formacie JSON i kończąca skrypt
* Zalecane jest pozostawienie funkcji w tej postaci niezależnie od platformy
* @param string $error_code kod błędu (standardowe wartości: db_connect, db_query, no_action)
* @param string $error_text opis błędu
*/
function Conn_Error($error_code, $error_text = '')
{
print json_encode(array('error' => true, 'error_code' => $error_code, 'error_text' => $error_text));
exit();
}
/**
* Ewentualne wczytanie dodatkowych funkcji z pliku baselinker_pm.php (BaseLinker Product Managment)
* Zawarte w dodatkowym pliku funkcje rozszerzają możliwości integracji ze sklepem o funkcje pozwalające dodawać i zmieniać kategorie, produkty oraz warianty.
* Obsługa tych funkcji jest wymagana przez niektóre moduły BaseLinkera (np. moduły integrujące system z programami typu ERP)
* Plik baselinker_pm.php jest dostępny dla wybranych platform sklepów. Skontaktuj się z administratorem w cely uzyskania pliku.
*/
if(file_exists("baselinker_pm.php"))
{include("baselinker_pm.php");}
//inicjacja komunikacji
Conn_Init();
/** -----------------------------------------------------------------------------------------------------------
* Funkcje obsługiwania żądań (przedrostek Shop_)
* - Zależne od platformy sklepu
* - Do edycji dla deweloperów
*/
/**
* Funkcja zwracająca wersję pliku wymiany danych
* Przy tworzeniu pliku należy skonsultować numer wersji i nazwę platformy
* z administracją systemu Baselinker
* @param array $request tablica z żadaniem od systemu, w przypadku tej funkcji nie używana
* @return array $response tablica z danymi platformy z polami:
* platform => nazwa platformy
* version => numer wersji pliku
*/
function Shop_FileVersion($request)
{
$response['platform'] = "SoteShop";
$response['version'] = "4.1.8"; //wersja pliku integracyjnego, nie wersja sklepu!
$response['standard'] = 4; //standard struktury pliku integracyjnego - obecny standard to 4.
return $response;
}
/**
* Funkcja zwracająca listę zaimplementowanych metod pliku
* Zalecane jest pozostawienie funkcji w tej postaci niezależnie od platformy
*/
function Shop_SupportedMethods()
{
$result = array();
$methods = get_defined_functions();
foreach($methods['user'] as $m)
{
if (stripos($m, 'shop_') === 0)
{$result[] = substr($m,5);}
}
return $result;
}
/**
* Funkcja nawiązująca komunikację z bazą danych sklepu
* @global array $options : tablica z ustawieniami ogólnymi z początku pliku
* @param array $request tablica z żadaniem od systemu, w przypadku tej funkcji nie używana
* @return boolean wartość logiczna określajaca sukces połączenia z bazą danych
*/
function Shop_ConnectDatabase($request)
{
global $options; //globalna tablica z ustawieniami
global $dbh; // handler bazy danych
$dbp = $options['db_prefix']; //Data Base Prefix - prefix tabel bazy
// wydzielenie portu z nazwy hosta
if (preg_match('/^\s*([\w\-\.]+):(\d+)\s*$/', $options['db_host'], $m))
{
$options['db_host'] = $m[1];
$options['db_port'] = $m[2];
}
// wygenerowanie DSN
$dsn = "mysql:dbname=${options['db_name']};host=${options['db_host']}";
if ($options['db_port'])
{
$dsn .= ";port=${options['db_port']}";
}
// nawiązanie połączenia z bazą danych sklepu
try {
$dbh = new PDO($dsn, $options['db_user'], $options['db_pass']);
} catch (Exception $ex) {
Conn_Error('db_connection', $ex->getMessage());
}
if($options['charset'] == "UTF-8")
{DB_Query("SET NAMES utf8");}
DB_Query("SET SESSION sql_mode = 'NO_ENGINE_SUBSTITUTION'");
// automatyczne wyszukiwanie prefiksu bazy danych
if ($dbp == '')
{
// wyszukiwanie tabeli z unikalną nazwą
$unique_table = 'st_product_has_attribute_field';
$search_table = DB_Query("SHOW TABLES LIKE '%${unique_table}'");
if (DB_NumRows($search_table) == 1)
{
$options['db_prefix'] = str_replace($unique_table, '', DB_Result($search_table));
$dbp = $options['db_prefix'];
}
else // nie wykryto jednoznacznie prefiksu
{
Conn_Error("database_prefix");
}
}
if (!$options['lang'])
{
$options['lang'] = DB_Result(DB_Query("SELECT language FROM `${dbp}st_language` WHERE active ORDER BY is_default DESC LIMIT 1"));
}
}
/**
* Funkcja zwraca listę kategorii sklepowych
* Zwracana tabela powinna być posortowana alfabetycznie
* W nazwie kategorii podrzędnej powinna być zawrta nazwa nadkategorii - np "Komputery/Karty graficzne" zamiast "Karty graficzne"
* @global array $options : tablica z ustawieniami ogólnymi z początku pliku
* @param array $request tablica z żadaniem od systemu, w przypadku tej funkcji nie używana
* @return array $response tablica z listą kategori sklepowch w formacie:
* id kategorii => nazwa kategorii
*/
function Shop_ProductsCategories($request)
{
global $options; // globalna tablica z ustawieniami
$dbp = $options['db_prefix']; // Data Base Prefix - prefix tabel bazy
// pobieranie kategorii z bazy i zapisywanie do tabeli
$sql = "SELECT * FROM `${dbp}st_category` c
WHERE is_active = 1 AND is_hidden = 0";
$res = DB_Query($sql);
while ($category = DB_Fetch($res))
{
$categories[$category['id']] = $category['opt_name'];
$parents[$category['id']] = $category['parent_id'];
}
// budowanie drzewa kategorii na podstawie tablicy
$category_tree = array();
foreach ($categories as $id => $name)
{
$cat_name = "";
$this_id = $id;
while ($parents[$this_id] != 0)
{
$cat_name = $categories[$parents[$this_id]] .'/' . $cat_name;
$this_id = $parents[$this_id];
}
$category_tree[$id] = $cat_name.$name;
}
// sortowanie alfabetycznie wg nazw
asort($category_tree);
return $category_tree;
}
/**
* Funkcja zwraca listę produktów z bazy sklepu
* Zwracane liczby (np ceny) powinny mieć format typu: 123456798.12 (kropka oddziela część całkowitą, 2 miejsca po przecinku)
* @global array $options : tablica z ustawieniami ogólnymi z początku pliku
* @param array $request tablica z żadaniem od systemu zawierająca pola:
* category_id => id kategori (wartość 'all' jeśli wszystkie przedmioty)
* filter_limit => limit zwróconych kategorii w formacie SQLowym ("ilość pomijanych, ilość pobieranych")
* filter_sort => wartość po której ma być sortowana lista produktów. Możliwe wartości:
* "id [ASC|DESC]", "name [ASC|DESC]", "quantity [ASC|DESC]", "price [ASC|DESC]"
* filter_id => ograniczenie wyników do konkretnego id produktu
* filter_ean => ograniczenie wyników do konkretnego ean
* filter_sku => ograniczenie wyników do konkretnego sku (numeru magazynowego)
* filter_name => filtr nazw przedmiotów (fragment szukanej nazwy lub puste pole)
* filter_price_from => dolne ograniczenie ceny (nie wyświetlane produkty z niższą ceną)
* filter_price_to => górne ograniczenie ceny
* filter_quantity_from => dolne ograniczenie ilości produktów
* filter_quantity_to => górne ograniczenie ilości produktów
* filter_available => wyświetlanie tylko produktów oznaczonych jako dostępne (wartość 1) lub niedostępne (0) lub wszystkich (pusta wartość)
* @return array $response tablica z listą produktów w formacie:
* id produktu =>
'name' => nazwa produktu
'quantity' => dostępna ilość
'price' => cena w PLN
*/
function Shop_ProductsList($request)
{
global $options; //globalna tablica z ustawieniami
$dbp = $options['db_prefix']; //Data Base Prefix - prefix tabel bazy
// wyrażenie SQL zwracające cenę, nazwę, stan mag.
$price_spec = 'p.opt_price_brutto';
$name_spec = 'p.opt_name';
$qty_spec = 'p.stock';
// zmiana nazw kolumn na nazwy pól
$request['filter_sort'] = str_replace(array('id', 'name', 'quantity', 'price'), array('p.id', $name_spec, $qty_spec, $price_spec), $request['filter_sort']);
//pobieranie produktow z bazy danych
$sql = "SELECT p.id, $name_spec name, code, $price_spec price, $qty_spec stock
FROM `${dbp}st_product` p
WHERE 1";
if ($request['category_id'] != 'all' && $request['category_id'] != '') // wybór kategorii
{
$sql = preg_replace('/(\s+WHERE\s+)/', "\nJOIN `${dbp}st_product_has_category` phc ON phc.product_id = p.id$1", $sql);
$sql .= " AND phc.category_id = '${request['category_id']}'";
}
if ($request['filter_id'] != '') { $sql .= " AND p.id = '${request['filter_id']}'"; } //filtrowanie id
if ($request['filter_name'] != '') { $sql .= " AND $name_spec LIKE '%${request['filter_name']}%'"; } //filtrowanie nazwy
if ($request['filter_sku'] != '') { $sql .= " AND p.code LIKE '%${request['filter_sku']}%'"; } //filtrowanie SKU
if ($request['filter_quantity_from'] != '') { $sql .= " AND $qty_spec >= '${request['filter_quantity_from']}'"; } //filtrowanie ilości
if ($request['filter_quantity_to'] != '') { $sql .= " AND $qty_spec <= '${request['filter_quantity_to']}'"; } //filtrowanie ilości
if ($request['filter_available'] != '') { $sql .= " AND p.active = '${request['filter_available']}'"; } //produkty dostępne/niedostępne
if ($request['filter_price_from'] != '') { $sql .= " AND $price_spec >= '${request['filter_price_from']}'"; }
if ($request['filter_price_to'] != '') { $sql .= " AND $price_spec <= '${request['filter_price_to']}'"; }
if ($request['filter_sort'] != '') { $sql .= " ORDER BY ${request['filter_sort']}"; }
if ($request['filter_limit'] != '') { $sql .= " LIMIT ${request['filter_limit']}"; }
$response = array();
$result = DB_Query($sql);
while ($prod = DB_Fetch($result))
{
$response[$prod['id']] = array('name' => $prod['name'], 'quantity' => (int)$prod['stock'], 'price' => $prod['price'], 'sku' => $prod['code']);
}
return $response;
}
/**
* Funkcja zwraca szczegółowe dane wybranych produktów
* Zwracane liczby (np ceny) powinny mieć format typu: 123456798.12 (kropka oddziela część całkowitą, 2 miejsca po przecinku)
* @global array $options : tablica z ustawieniami ogólnymi z początku pliku
* @param array $request tablica z żadaniem od systemu zawierająca pola:
* products_id => tablica z numerami id produktów
* fields => tablica z nazwami pól do zwrócenia (jeśli pusta zwracany jest cały wynik)
* @return array $response tablica z listą produktów w formacie:
* id produktu =>
'name' => nazwa produktu, 'ean' => Kod EAN, 'sku' => numer katalogowy, 'model' => nazwa modelu lub inny identyfikator np ISBN,
'description' => opis produktu (może zawierać tagi HTML), 'description_extra1' => drugi opis produktu (np opis krótki) 'weight' => waga produktu w kg,
'quantity' => dostępna ilość, 'man_name' => nazwa producenta, 'man_image' => pełny adres obrazka loga producenta,
'category_id' => numer ID głównej kategorii, 'category_name' => nazwa kategori do której należy przedmiot, 'tax' => wielkość podatku w formie liczby (np 23)
'price' => cena brutto w PLN,
'images' => tablica z pełnymi adresami dodatkowych obrazków (pierwsze zdjęcie główne, reszta w odpowiedniej kolejności),
'features' => tablica z opisem cech produktu. Poszczególny element tablicy zawiera nazwę i wartość cechy, np array('Rozdzielczość','Full HD')
'variants' => tablica z wariantami produktu do wyboru (np kolor, rozmiar). Format pola opisany jest w kodzie poniżej
*/
function Shop_ProductsData($request)
{
global $options; // globalna tablica z ustawieniami
$dbp = $options['db_prefix']; //Data Base Prefix - prefix tabel bazy
$category_tree = Shop_ProductsCategories($request);
$response = array();
$prodcat = array();
// mapowanie produktów do kategorii
$sql = "SELECT product_id, category_id
FROM `${dbp}st_product_has_category`
WHERE product_id IN ({0})
ORDER BY is_default";
$res = DB_Query($sql, implode(', ', $request['products_id']));
while ($map = DB_Fetch($res))
{
$prodcat[$map['product_id']] = $map['category_id'];
}
// pobieranie danych produktów z bazy danych
$sql = "SELECT p.id, p.code sku, p.code model, m.opt_name man_name,
m.image man_image, p.stock quantity,
p.opt_vat tax, p.weight, p.opt_price_brutto price, pi.name, pi.description,
pi.short_description description_extra1
FROM `${dbp}st_product` p
LEFT JOIN `${dbp}st_product_i18n` pi ON pi.id = p.id AND pi.culture = '{1}'
LEFT JOIN `${dbp}st_producer` m ON m.id = p.producer_id
WHERE
p.id IN ({0})";
$res = DB_Query($sql, implode(', ', $request['products_id']), $options['lang']);
while ($p = DB_Fetch($res))
{
$product_id = $p['id'];
// zdjęcie producenta
if ($p['man_image'])
{
$p['man_image'] = $options['images_folder'] . $p['man_image'];
}
// uzupełnienie powiązania z kategorią
if ($prodcat[$product_id])
{
$p['category_id'] = $prodcat[$product_id];
$p['category_name'] = $category_tree[$prodcat[$product_id]];
}
// warianty
$sql = "SELECT pov.id pov_id, if(isnull(povi.value), pov.opt_value, povi.value) name,
pov.price, pov.stock, depth, product_options_field_id field_id,
pov.use_product sku
FROM `${dbp}st_product_options_value` pov
LEFT JOIN `${dbp}st_product_options_value_i18n` povi ON povi.id = pov.id AND culture = '${options['lang']}'
WHERE pov.product_id = {0} AND NOT isnull(pov.opt_value)
ORDER by pov.depth, pov.lft";
$res2 = DB_Query($sql, $product_id);
$multiopt2 = array(array('name' => '', 'price' => $p['price']));
$depth = 0;
$field_id = 0;
while ($opt = DB_Fetch($res2))
{
if ($opt['depth'] != $depth)
{
$depth_col = 0;
$multiopt = $multiopt2;
$multiopt2 = array();
$depth = $opt['depth'];
}
elseif ($opt['field_id'] != $field_id)
{
$depth_col++;
}
$v = array(
'id' => $opt['pov_id'],
'name' => $multiopt[$depth_col]['name'] . ' ' . $opt['name'],
'quantity' => (int)$opt['stock'],
'price' => $opt['price'],
'sku' => $opt['sku'],
);
if (!$opt['price'])
{
$v['price'] = $multiopt[$depth_col]['price']; //cena z poprzedniego poziomu
}
// opcja zmienia cenę o N %
elseif (preg_match('/[\+-](\d+)%/', $v['price'], $m))
{
$v['price'] = number_format($multiopt[$depth_col]['price']*(100+$m[1])/100, 2, '.', '');
}
// opcja zmienia cenę o określoną kwotę
elseif (preg_match('/[\+-](\d+)/', $v['price'], $m))
{
$v['price'] = number_format($multiopt[$depth_col]['price']+$m[1], 2, '.', '');
}
$multiopt2[] = $v;
$field_id = $opt['field_id'];
}
$p['variants'] = array();
foreach ($multiopt2 as $v)
{
if (!$v['id']) { continue; }
$p['variants'][$v['id']] = array(
'full_name' => $p['name'] . ' ' . $v['name'],
'name' => $v['name'],
'price' => $v['price'],
'quantity' => $v['quantity'],
'sku' => $v['sku'],
);
}
// pobieranie obrazków
$p['images'] = array();
$sql = "SELECT relative_path, filename
FROM `${dbp}st_product_has_sf_asset` sphsa
JOIN `${dbp}sf_asset` sa ON sphsa.sf_asset_id = sa.id
JOIN `${dbp}sf_asset_folder` saf ON sa.folder_id = saf.id
WHERE sphsa.product_id = '{0}'
ORDER BY `is_default` DESC";
$res2 = DB_Query($sql, $product_id);
$images = array();
while ($img = DB_Fetch($res2))
{
$p['images'][] = "${options['images_folder']}${img['relative_path']}/${img['filename']}";
}
//pobieranie cech produktu (np. długość, kolor, rozmiar itp.)
$p['features'] = array();
$sql = "SELECT a.opt_name AS name, av.opt_value AS value
FROM `${dbp}app_product_attribute_variant_has_product` vhp
INNER JOIN `${dbp}app_product_attribute_variant` av ON av.id = vhp.variant_id
INNER JOIN `${dbp}app_product_attribute_has_variant` ahv ON ahv.variant_id = vhp.variant_id
INNER JOIN `${dbp}app_product_attribute` a ON a.id = ahv.attribute_id
WHERE vhp.product_id = '{0}' AND a.is_visible_on_pp";
$res2 = DB_Query($sql, $product_id);
while ($f = DB_Fetch($res2))
{
$p['features'][$f['name']] = isset($features[$f['name']]) ? ($features[$f['name']] . ", ${f['value']}") : $f['value'];
}
foreach (array_keys($p['features']) as $f)
{
$p['features'][] = array($f, $p['features'][$f]); unset($p['features'][$f]);
}
//pobieranie wartości tagu [special] z zewnętrznego skryptu
//poniższy warunek może pozostać identyczny niezależnie od platformy sklepu
if (file_exists("baselinker_extra.php"))
{
//pobranie dodatkowych informacji z zewnętrznego pliku pliku.
//Plik tworzony jest indywidualnie dla każdego sprzedawcy jeśli zgłosi potrzebę pobierania dodatkowych danych ze sklepu.
//Pozwala to uniknąć ingerowania w standardowy plik baselinker.php
include("baselinker_extra.php");
}
//wyrzucanie niepotrzebnych wartości jeśli określono pola do pobrania
//poniższy kod może pozostać identyczny niezależnie od platformy sklepu
if (!(count($request['fields']) == 1 && $request['fields'][0] == "") && !count($request['fields']) == 0)
{
$temp_p = array();
foreach($request['fields'] as $field)
{$temp_p[$field] = $p[$field];}
$p = $temp_p;
}
$response[$product_id] = $p;
}
return $response;
}
/**
* Funkcja zwraca stan magazynowy wszystkich produktów i ich wariantów
* @global array $options : tablica z ustawieniami ogólnymi z początku pliku
* @param array $request tablica z żadaniem od systemu, w przypadku tej funkcji nie używana
* @return array $response tablica ze stanem magazynowym wszystkich produktów, w formacie:
* id produktu => ID produktu jest kluczem tablicy, wartością jest tablica składająca się ze stanów wariantów
* id wariantu => kluczem tablicy jest ID wariantu (0 w przypadku produktu głównego)
* stan => wartościa jest stan magazynowy
* Przykład: array('432' => array('0' => 4, '543' => 2, '567' => 3)) - produkt ID 432, stan głównego produktu to 4, posiada dwa warianty (ID 543 i 563) o stanach 2 i 3.
*/
function Shop_ProductsQuantity($request)
{
global $options; //globalna tablica z ustawieniami
$dbp = $options['db_prefix']; //Data Base Prefix - prefix tabel bazy
$response = array();
$sql = "SELECT p.id product_id, p.stock qty,
pov.id pov_id, pov.stock, pov.depth
FROM `${dbp}st_product` p
LEFT JOIN `${dbp}st_product_options_value` pov ON pov.product_id = p.id AND NOT isnull(pov.product_options_value_id)
ORDER by p.id, pov.depth DESC";
$res = DB_Query($sql, $product_id);
//TODO join with product_options_value_id = null to get true main product count
//or check for null in the loop! Also fix PL with join to pov
//Actually here just use the last level without all this fuancy logic!
$prod_id = 0;
$depth = 0;
while ($opt = DB_Fetch($res))
{
if ($prod_id == $opt['product_id'] and $depth > $opt['depth'])
{
continue;
}
$response[$opt['product_id']][0] = (int)$opt['qty'];
if ($opt['pov_id'])
{
$response[$opt['product_id']][$opt['pov_id']] = (int)$opt['stock'];
}
$prod_id = $opt['product_id'];
$depth = $opt['depth'];
}
return $response;
}
/**
* Funkcja ustawia stan magazynowy wybranych produktów i ich wariantów
* @global array $options : tablica z ustawieniami ogólnymi z początku pliku
* @param array $request tablica z żadaniem od systemu:
* products => tablica zawierająca informacje o zmianach stanu produktu. Każdy element tablicy jest również tablicą składającą się z pól:
* product_id => ID produktu
* variant_id => ID wariantu (0 jeśli produkt główny)
* operation => rodzaj zmiany, dopuszczalne wartości to: 'set' (ustawia konkretny stan), 'change' (dodaje do stanu magazynowego, ujemna liczba w polu quantity zmniejszy stan o daną ilość sztuk, dodatnia zwiększy)
* quantity => zmiana stanu magazynowego (ilośc do ustawienia/zmniejszenia/zwiększenia zależnie od pola operation)
* @return array $response tablica zawierajaca pole z ilością zmienionych produktów:
* counter => ilość zmienionych produktów
*/
function Shop_ProductsQuantityUpdate($request)
{ global $options; // globalna tablica z ustawieniami
$dbp = $options['db_prefix']; // Data Base Prefix - prefix tabel bazy
foreach ($request['products'] as $prod)
{
$prod['quantity'] = (int)$prod['quantity'];
if ($prod['variant_id'])
{
$sql = "SELECT stock, lft, rgt FROM `${dbp}st_product_options_value`
WHERE product_id = '{0}' AND id = '{1}'";
$res = DB_Query($sql, $prod['product_id'], $prod['variant_id']);
if (!DB_NumRows($res))
{
continue; // nie znaleziono wariantu
}
$node = DB_Fetch($res);
}
if ($prod['operation'] == 'change') // zmiana względem aktualnego stanu
{
$mod = "if(stock >= -${prod['quantity']}, stock+${prod['quantity']}, 0)";
}
elseif ($prod['variant_id']) // podana liczba sztuk wariantu
{
// dla wszystkich powiązanych rekordów (gałęzie pov + produkt gł)
// używamy wartości względnej
$prod['quantity'] = $prod['quantity'] - (int)$node['stock'];
$mod = "if(stock >= -${prod['quantity']}, stock+${prod['quantity']}, 0)";
}
else // ustawienie konkretnej ilości sztuk dla produktu głównego
{
$mod = $prod['quantity'];
}
// aktualizacja stanu produktu głównego w tabeli st_product
DB_Query("UPDATE `${dbp}st_product` SET stock = $mod WHERE id = '{0}'", $prod['product_id']);
// aktualizacja stanu produktu głównego w tabeli st_product_options_value
DB_Query("UPDATE `${dbp}st_product_options_value` SET stock = $mod
WHERE product_id = '{0}' AND depth = 0", $prod['product_id']);
if ($prod['variant_id'])
{
$upd = "UPDATE `${dbp}st_product_options_value` SET stock = $mod
WHERE product_id = {0} AND id = {1}";
// aktualizacja stanów wszystkich atrybutów wariantu
$sql = "SELECT id FROM `${dbp}st_product_options_value`
WHERE product_id = {0} AND depth > 0 AND lft <= {1} AND rgt >= {2}";
$res = DB_Query($sql, $prod['product_id'], $node['lft'], $node['rgt']);
while ($opt = DB_Fetch($res))
{
DB_Query($upd, $prod['product_id'], $opt['id']);
}
}
}
return array('counter' => count($request['products']));
}
/**
* Funkcja tworzy zamówienie w sklepie na podstawie nadesłanych danych
* Jeśli funkcja otrzyuje na wejściu ID zamówienia, aktualizuje dane zamówienie zamiast tworzyć nowe
* @global array $options : tablica z ustawieniami ogólnymi z początku pliku
* @param array $request tablica z żadaniem od systemu, zawiera informacje o zamówieniu w formacie:
* previous_order_id => ID zamówienia (jeśli pierwszy raz dodawane do sklepu, wartość jest pusta. Jeśli było już wcześniej dodane, wartość zawiera poprzedni numer zamówienia)
* delivery_fullname, delivery_company, delivery_address, delivery_city, delivery_postcode, delivery_country => dane dotyczące adresu wysyłki
* invoice_fullname, invoice_company, invoice_address, invoice_city, invoice_postcode, invoice_country, invoice_nip => dane dotyczące adresu płatnika faktury
* phone => nr telefonu, email => adres email,
* delivery_method => nazwa sposóbu wysyłki, delivery_method_id => numer ID sposobu wysyłki, delivery_price => cena wysyłki
* user_comments => komentarz kupującego, currency => waluta zamówienia, status_id => status nowego zamówienia
* change_products_quantity => flaga (bool) informująca, czy po stworzeniu zamówienia zmniejszony ma zostać stan zakupionych produktów
* products => tablica z zakupionymi produktami w formacie:
* [] =>
* id => ID produktu
* variant_id => ID wariantu
* name => nazwa produktu (używana jeśli nie można pobrać jej z bazy na podstawie id)
* price => cena brutto w PLN
* currency => waluta
* quantity => zakupiona ilość
* attributes => tablica z atrybutami produktu w formacie:
* [] =>
* name => nazwa atrybutu (np. "kolor")
* value => wartość atybutu (np. "czerwony")
* price => różnica ceny dla tego produktu (np. "-10.00")
* zmiana ceny jest już uwzględniona w cenie produktu
* @return array $response tablica zawierająca numer nowego zamówienia:
* 'order_id' => numer utworzonego zamówienia
*/
function Shop_OrderAdd($request)
{
global $options; // globalna tablica z ustawieniami
$dbp = $options['db_prefix']; // Data Base Prefix - prefix tabel bazy
// zdefiniowanie waluty
$request['currency'] = $request['currency'] ? $request['currency'] : 'PLN';
$sql = "SELECT * FROM `${dbp}st_currency` WHERE shortcut = '${request['currency']}' LIMIT 1";
$res = DB_Query($sql);
$currency = DB_Fetch($res);
// jeśli zamówienie jest ponownie dodawane do bazy sklepu, wcześniejsze dane są usuwane
// przy ponownym dodawaniu zamówienia (aktualizowaniu), $request['previous_order_id'] zawiera poprzedni numer danego zamówienia w sklepie
if ($request['previous_order_id'] != "")
{
$sql = "SELECT o.* FROM `${dbp}st_order` o WHERE o.id = '${request['previous_order_id']}' ";
$old = DB_Fetch(DB_Query($sql));
DB_Query("DELETE FROM `${dbp}st_order_delivery` WHERE `id` = '{0}'", $old['order_delivery_id']);
DB_Query("DELETE FROM `${dbp}st_order_user_data_billing` WHERE `id` = '{0}'", $old['order_user_data_billing_id']);
DB_Query("DELETE FROM `${dbp}st_order_user_data_delivery` WHERE `id` = '{0}'", $old['order_user_data_delivery_id']);
DB_Query("DELETE FROM `${dbp}st_order_currency` WHERE `id` = '{0}'", $old['order_currency_id']);
DB_Query("DELETE FROM `${dbp}st_order_product` WHERE `order_id` = '{0}'", $old['id']);
DB_Query("DELETE FROM `${dbp}st_order` WHERE `id` = '{0}'", $old['id']);
}
// dodawanie waluty zamówienia
$sql = "INSERT INTO `${dbp}st_order_currency` (created_at, updated_at,
exchange, shortcut, front_symbol, back_symbol, name)
VALUES (now(), now(), '{0}', '{1}', '{2}', '{3}', '{4}')";
$res = DB_Query($sql, $currency['exchange'], $request['currency'], $currency['front_symbol'],
$currency['back_symbol'], $currency['opt_name']);
$currency_id = DB_Identity();
// pobieranie id kraju
$sql = "SELECT id FROM `${dbp}st_countries`
WHERE iso_a2 = '{0}' OR opt_name = '{1}' LIMIT 1";
$invoice_country_id = DB_Result(DB_Query($sql, $request['invoice_country_code'], $request['invoice_country']));
$sql = "SELECT id FROM `${dbp}st_countries`
WHERE iso_a2 = '{0}' OR opt_name = '{1}' LIMIT 1";
$delivery_country_id = DB_Result(DB_Query($sql, $request['delivery_country_code'], $request['delivery_country']));
// język
$culture = strtolower($request['invoice_country_code']);
if ($culture == 'pl')
{
$culture .= '_PL';
}
elseif ($culture == 'uk' or $culture == 'us' or $culture == 'au' or $culture == 'ca' or $culture == 'ie' or $culture == 'gb')
{
$culture = 'en_US';
}
// sprawdzanie czy użytkownik już istnieje w bazie danych
$sql = "SELECT id FROM `${dbp}sf_guard_user` WHERE username = '{0}'";
$res = DB_Query($sql, $request['email']);
if (DB_NumRows($res) > 0)
{
$user_id = DB_Result($res);
}
else
{
// dodawanie użytkownika do tabeli sf_guard_user
$sql = "INSERT INTO `${dbp}sf_guard_user`
(username, algorithm, salt, password, created_at,
last_login, is_active, is_super_admin, is_confirm, is_admin_confirm,
hash_code, language, external_account, wholesale, points,
points_available, points_release) VALUES
('{0}', 'sha1', 'allegro_user', 'allegro_user', '{1}',
'{1}', 1, 0, 0, 0,
'{2}', '{3}', NULL, NULL, 0,
1, 0);";
DB_Query($sql, $request['email'], date('Y-m-d H:i:s'), md5(microtime(true)*rand(10,10000000)), $culture);
$user_id = DB_Identity();
$sql = "INSERT INTO `sf_guard_user_group` (`user_id`, `group_id`) VALUES ('{0}', 2);";
DB_Query($sql, $user_id);
}
$invoice_street = explode(' ',$request['invoice_address']);
$invoice_house = array_pop($invoice_street);
$invoice_street = implode(' ',$invoice_street);
$request['invoice_country'] = $request['invoice_country'] ? $request['invoice_country'] : 'Polska';
$request['delivery_country'] = $request['delivery_country'] ? $request['delivery_country'] : 'Polska';
// dodawanie adresu płatnika do tabeli st_order_user_data_billing
$sql = "INSERT INTO `${dbp}st_order_user_data_billing` (
created_at, updated_at, country , full_name, company,
address ,code , town , street, house,
phone, vat_number, countries_id) VALUES (
'{0}', '{0}', '{1}', '{2}', '{3}',
'{4}', '{5}', '{6}', '{7}', '{8}',
'{9}' , '{10}', '{11}')";
DB_Query($sql, date('Y-m-d H:i:s'), $request['invoice_country'], $request['invoice_fullname'], $request['invoice_company'],
$request['invoice_address'], $request['invoice_postcode'], $request['invoice_city'], $invoice_street, $invoice_house,
$request['phone'] , $request['invoice_nip'], $invoice_country_id);
$invoice_address_id = DB_Identity();
$delivery_street = explode(' ', $request['delivery_address']);
$delivery_house = array_pop($delivery_street);
$delivery_street = implode(' ', $delivery_street);
// dodawanie adresu dostawy do tabeli st_order_user_data_delivery
$sql = "INSERT INTO `${dbp}st_order_user_data_delivery` (
created_at, updated_at, country, full_name, company,
address, code, town, street, house,
phone, countries_id) VALUES (
'{0}', '{0}', '{1}', '{2}', '{3}',
'{4}', '{5}', '{6}', '{7}', '{8}',
'{9}', '{10}')";
DB_Query($sql, date('Y-m-d H:i:s'), $request['delivery_country'], $request['delivery_fullname'], $request['delivery_company'],
$request['delivery_address'], $request['delivery_postcode'], $request['delivery_city'], $delivery_street, $delivery_house,
$request['phone'], $delivery_country_id);
$delivery_address_id = DB_Identity();
// VAT kosztów wysyłki
$sql = "SELECT d.tax_id, t.vat
FROM `${dbp}st_delivery` d JOIN `st_tax` t ON d.tax_id = t.id
ORDER BY (d.id = '{0}') DESC, d.is_default DESC, d.is_system_default DESC LIMIT 1";
$res = DB_Query($sql, $request['delivery_method_id']);
if (!($delivery_tax = DB_Fetch($res)))
{
$delivery_tax = array('tax_id' => 0, 'vat' => 23);
}
// dodawanie informacji o dostawie do tabeli st_order_delivery
$delivery_netto = number_format($request['delivery_price']/(100+$delivery_tax['vat'])*100, 2, '.', '');
$sql = "INSERT INTO `${dbp}st_order_delivery`
(created_at, updated_at, name, cost, opt_tax,
cost_brutto, delivery_id, tax_id)
VALUES ('{0}', '{0}', '{1}', '{2}', '{3}',
'{4}', '{5}', '{6}')";
DB_Query($sql, date('Y-m-d H:i:s'), $request['delivery_method'], $delivery_netto, $delivery_tax['vat'], $request['delivery_price'],
$request['delivery_method_id'], $delivery_tax['tax_id']);
$delivery_id = DB_Identity();
// karta klienta - adresy dostawy i płatności
$sql = "INSERT INTO `${dbp}st_user_data`
(crypt, created_at, updated_at, is_billing, is_default,
sf_guard_user_id, countries_id, street, house, code,
town, phone, full_name, address)
VALUES
(0, '{0}', '{0}', {10}, 0,
{1}, '{2}', '{3}', '{4}', '{5}',
'{6}', '{7}', '{8}', '{9}')";
DB_Query($sql, date('Y-m-d H:i:s'),
$user_id, $invoice_country_id, $invoice_street, $invoice_house, $request['invoice_postcode'],
$request['invoice_city'], $request['phone'], $request['invoice_fullname'], $request['invoice_address'], 1);
DB_Query($sql, date('Y-m-d H:i:s'),
$user_id, $delivery_country_id, $delivery_street, $delivery_house, $request['delivery_postcode'],
$request['delivery_city'], $request['phone'], $request['delivery_fullname'], $request['delivery_address'], 0);
// klucz bezpieczeństwa klienta
$secure_key = md5(microtime(true)*rand(10,10000000));
$secure_key2 = md5(microtime(true)*rand(10,10000000));
// wyliczanie całkowitego kosztu zamówienia
$total_sum = 0;
foreach ($request['products'] as $prod)
{
$total_sum += $prod['price'] * $prod['quantity'];
}
$total_sum += $request['delivery_price'];
// pobieranie numeru ostatniego zamowienia
if ($request['previous_order_id'] != '')
{
$last_nr = $request['previous_order_id'];
}
else
{
$sql = "SELECT number FROM `${dbp}st_order` ORDER BY ABS(number) DESC LIMIT 1";
$res = DB_Query($sql);
$last_nr = (int)DB_Result($res)+1;
}
// dodanie zamowienia do tabeli orders
$sql = "INSERT INTO `${dbp}st_order` (
created_at, updated_at, id, order_delivery_id, order_user_data_delivery_id,
order_user_data_billing_id, order_currency_id, order_status_id, sf_guard_user_id, hash_code,
number, description, client_culture, is_confirmed, opt_client_name,
opt_client_email, opt_client_company, opt_total_amount)
VALUES ('{0}', '{0}', '{1}' , '{2}', '{3}',
'{4}', '{5}', '{6}', '{7}', '{8}',
'{9}', '{10}', '{11}', '1', '{12}',
'{13}', '{14}', '{15}')";
DB_Query($sql, date('Y-m-d H:i:s'), $request['previous_order_id'], $delivery_id, $delivery_address_id,
$invoice_address_id, $currency_id, $request['status_id'], $user_id, $secure_key,
$last_nr, $request['user_comments'], $culture, $request['invoice_fullname'],
$request['email'], $request['invoice_company'], $total_sum);
// pobieranie numeru nowego zamówienia
$this_order_id = $request['previous_order_id'] ? $request['previous_order_id'] : DB_Identity();
// typ płatności
$sql = "SELECT id FROM `${dbp}st_payment_type`
WHERE active ORDER BY (module_name = 'stStandardPayment') DESC,
(opt_name {0} like '%pobran%') DESC LIMIT 1";
$res = DB_Query($sql, $request['payment_method_cod'] ? '' : 'not');
$payment_type_id = DB_Result($res);
// dodawanie płatności
$sql = "INSERT INTO `${dbp}st_payment`
(created_at, updated_at, sf_guard_user_id, payment_type_id, amount,
status, cancel, hash, version) VALUES
('{0}', '{0}', '{1}', '{2}', '{3}',
0, 0, '{4}', 2)";
DB_Query($sql, date('Y-m-d H:i:s'), $user_id, $payment_type_id, $total_sum, $secure_key2);
$this_payment_id = DB_Identity();
$sql = "INSERT INTO `${dbp}st_order_has_payment`
(created_at, updated_at, order_id, payment_id) VALUES
('{0}', '{0}', '{1}', '{2}')";
DB_Query($sql, date('Y-m-d H:i:s'), $this_order_id, $this_payment_id);
// obsługa produktów w zamówieniu
foreach ($request['products'] as $prod)
{
$sql = "SELECT * FROM `${dbp}st_product` p WHERE p.id = '{0}'";
$res = DB_Query($sql, $prod['id']);
$prod_data = DB_Fetch($res);
$price_netto = $prod['price'] / (1+$prod_data['opt_vat']/100);
$price_modifiers = array();
// obsługa wariantu
if ($prod['variant_id'])
{
$sql = "SELECT pov.depth, pov.lft, pov.rgt, pov.opt_value, pov.use_product,
pov.color, pof.opt_name
FROM `${dbp}st_product_options_value` pov
LEFT JOIN `${dbp}st_product_options_field` pof ON pof.id = pov.product_options_field_id
WHERE pov.product_id = '{0}' AND pov.id = '{1}'";
$res = DB_Query($sql, $prod['id'], $prod['variant_id']);
if (DB_NumRows($res))
{
$leaf = DB_Fetch($res);
$price_modifiers[] = array(
'value' => (float)0,
'type' => 'percent',
'level' => (int)$leaf['depth'],
'prefix' => '+',
'custom' => array(
'id' => (int)$prod['variant_id'],
'color' => $leaf['color'],
'field' => $leaf['opt_name'],
'type' => 'product_options',
),
'label' => $leaf['opt_value']
);
$prod_data['code'] = $leaf['use_product'];
// pozostałe opcje wyboru dla tego wariantu
$sql = "SELECT id, depth, opt_value
FROM `${dbp}st_product_options_value`
WHERE product_id = {0} AND depth > 0 AND lft < {1} and rgt > {2}
ORDER BY depth desc";
$res = DB_Query($sql, $prod['id'], $leaf['lft'], $leaf['rgt']);
while ($opt = DB_Fetch($res))
{
array_unshift($price_modifiers, array(
'value' => (float)0,
'type' => 'percent',
'level' => $opt['depth'],
'prefix' => '+',
'custom' => array(
'id' => (int)$opt['id'],
'type' => 'product_options',
),
'label' => $opt['opt_name'],
));
}
}
// nazwa produktu pobrana ze sklepu
if ($prod_data['name'] and $prod['name'])
{
$prod['name'] = $prod_data['name'];
}
}
// dodawanie produktu do zamowienia
$sql = "INSERT INTO `${dbp}st_order_product` (
created_at, updated_at, order_id, product_id, quantity,
code, name, image, price, price_brutto,
vat, price_modifiers, version, tax_id, discount)
VALUES (
'{0}', '{0}', '{1}', '{2}', '{3}',
'{4}', '{5}', '{6}', '{7}', '{8}',
'{9}', '{10}', '{11}', '{12}', '{13}')";
DB_Query($sql, date('Y-m-d H:i:s'), $this_order_id, $prod['id'], $prod['quantity'],
$prod_data['code'], $prod['name'], $prod_data['opt_image'], $price_netto, $prod['price'],
$prod_data['opt_vat'], serialize($price_modifiers), 3, $prod_data['tax_id'],
serialize(array()));
// zmniejszanie stanu magazynowego produktu (jeśli ustawiona flaga change_products_quantity)
if ($request['previous_order_id'] == '' and $request['change_products_quantity'])
{
Shop_ProductsQuantityUpdate(array('products' => array(array('product_id' => $prod['id'], 'variant_id' => $prod['variant_id'], 'operation' => 'change', 'quantity' => -1*$prod['quantity']))));
}
}
return array('order_id' => $this_order_id);
}
/**
* Funkcja pobiera zamówienia złożone w sklepie internetowym
* Zwracane liczby (np ceny) powinny mieć format typu: 123456798.12 (kropka oddziela część całkowitą, 2 miejsca po przecinku)
* @global array $options : tablica z ustawieniami ogólnymi z początku pliku
* @param array $request tablica z żadaniem od systemu, zawiera informacje o zamówieniu w formacie:
* time_from => czas od którego mają zastać pobrane zamówienia - format UNIX TIME
* id_from => ID od którego mają zastać pobrane zamówienia
* only_paid => flaga określająca czy pobierane mają być tylko zamówienia opłacone (0/1)
* @return array $response tablica zawierająca dane zamówień:
* id zamówienia => array:
* delivery_fullname, delivery_company, delivery_address, delivery_city, delivery_postcode, delivery_country => dane dotyczące adresu wysyłki
* invoice_fullname, invoice_company, invoice_address, invoice_city, invoice_postcode, invoice_country, invoice_nip => dane dotyczące adresu płatnika faktury
* phone => nr telefonu, email => adres email,
* date_add => data złożenia zamówienia,
* payment_method => nazwa metody płatności,
* user_comments => komentarz klienta do zamówienia,
* status_id => numer ID statusu zamówienia,
* delivery_method_id => numer ID metody wysyłki, delivery_method => nazwa metody wysyłki,
* delivery_price => cena wysyłki
* products => array:
* [] =>
* id => id produktu, variant_id => id wariantu produktu (0 jeśli produkt główny),
name => nazwa produktu
* quantity => zakupiona ilość, price => cena sztuki brutto (uwzględniająca atrybuty)
* weight => waga produktu w kg, tax => wysokość podatku jako liczba z zakresu 0-100
* attributes => array: - tablica z wybieralnymi atrybutami produktów (jeśli istnieją)
* [] =>
* name => nazwa atrybutu (np 'kolor'),
* value => wartość atrubutu (np 'czerwony'),
* price => różnica w cenie w stosunku do ceny standardowe
*/
function Shop_OrdersGet($request)
{
global $options; // globalna tablica z ustawieniami
$dbp = $options['db_prefix']; // Data Base Prefix - prefix tabel bazy
$response = array();
//dodatkowe dane dostawy w oddzielnej tabeli?
$sheepla_orders = DB_NumRows(DB_Query("SHOW TABLES LIKE '${dbp}sheepla_orders'"));
//formatowanie daty od której mają być pobrane zamówienia
$time_from = date("Y-m-d H:i:s", $request['time_from']);
$id_from = (int)$request['id_from'];
//zapytanie pobierające zamówienia od określonego czasu
$sql = "SELECT o.*, UNIX_TIMESTAMP(o.created_at) time_purchased, od.crypt od_crypt, ob.crypt ob_crypt,
od.full_name delivery_name, od.address delivery_street_address, od.address_more delivery_street_address2,
od.town delivery_city, od.code delivery_postcode, od.company delivery_company, od.phone delivery_phone,
ob.full_name customers_name, ob.address customers_street_address, ob.address_more customers_street_address2,
ob.town customers_city, ob.code customers_postcode, ob.company customers_company, ob.phone customers_phone,
ob.vat_number customers_nip, del.cost_brutto + if(del.payment_cost_brutto, del.payment_cost_brutto, 0) delivery_cost,
del.name delivery_method, oc.shortcut currency,
od.country delivery_country, ob.country customers_country, cod.name delivery_country_pl, cob.name customers_country_pl,
oc.exchange, obc.iso_a2 invoice_country_code, obd.iso_a2 delivery_country_code, del.delivery_id
FROM `${dbp}st_order` o
LEFT JOIN `${dbp}st_order_user_data_billing` ob ON ob.id = o.order_user_data_billing_id
LEFT JOIN `${dbp}st_order_user_data_delivery` od ON od.id = o.order_user_data_delivery_id
LEFT JOIN `${dbp}st_order_delivery` del ON del.id = o.order_delivery_id
LEFT JOIN `${dbp}st_order_currency` oc ON oc.id = o.order_currency_id
LEFT JOIN `${dbp}st_countries_i18n` cod ON cod.id = od.countries_id AND cod.culture LIKE 'pl%'
LEFT JOIN `${dbp}st_countries_i18n` cob ON cob.id = ob.countries_id AND cob.culture LIKE 'pl%'
LEFT JOIN `${dbp}st_countries` obc ON obc.id = od.countries_id
LEFT JOIN `${dbp}st_countries` obd ON obd.id = ob.countries_id
WHERE o.created_at >= '{0}' AND o.id >= {1}";
$res = DB_Query($sql, $time_from, $id_from);
while ($order = DB_Fetch($res))
{
$o = array('currency' => $order['currency']);
$o['delivery_fullname'] = $order['delivery_name'];
$o['delivery_company'] = $order['delivery_company'];
$o['delivery_address'] = Sote_Decrypt($order['delivery_street_address'], $order['od_crypt'])." ".Sote_Decrypt($order['delivery_street_address2'], $order['od_crypt']);
$o['delivery_city'] = Sote_Decrypt($order['delivery_city'], $order['od_crypt']);
$o['delivery_postcode'] = Sote_Decrypt($order['delivery_postcode'], $order['od_crypt']);
$o['delivery_country'] = $order['delivery_country_pl'] ? $order['delivery_country_pl'] : $order['delivery_country'];
$o['delivery_country_code'] = $order['delivery_country_code'];
$o['invoice_fullname'] = $order['customers_name'];
$o['invoice_company'] = $order['customers_company'];
$o['invoice_nip'] = $order['customers_nip'];
$o['invoice_address'] = Sote_Decrypt($order['customers_street_address'], $order['ob_crypt'])." ".Sote_Decrypt($order['customers_street_address2'], $order['ob_crypt']);
$o['invoice_city'] = Sote_Decrypt($order['customers_city'], $order['ob_crypt']);
$o['invoice_postcode'] = Sote_Decrypt($order['customers_postcode'], $order['ob_crypt']);
$o['invoice_country'] = $order['customers_country_pl'] ? $order['customers_country_pl'] : $order['customers_country'];
$o['invoice_country_code'] = $order['invoice_country_code'];
$o['phone'] = ($order['customers_telephone']!="")?Sote_Decrypt($order['customers_phone'], $order['ob_crypt']):Sote_Decrypt($order['delivery_phone'], $order['ob_crypt']);
$o['email'] = $order['opt_client_email'];
$o['date_add'] = $order['time_purchased'];
$o['payment_method'] = "";
$o['user_comments'] = $order['description'];
$o['delivery_method'] = $order['delivery_method'];
$o['delivery_method_id'] = $order['delivery_id'];
$o['status_id'] = $order['order_status_id'];
// dostawa do paczkomatu
if (preg_match('/^Paczkomat - (\w+)\s*$/', $o['delivery_company'], $m))
{
$o['delivery_point_name'] = $m[1];
foreach (array('address', 'city', 'country', 'postcode') as $fld)
{
$o["delivery_point_$fld"] = $o["delivery_$fld"];
}
}
elseif ($sheepla_orders)
{
$sql = "SELECT adddata FROM `${dbp}sheepla_orders` WHERE order_id = {0}";
if ($so_data = DB_Result(DB_Query($sql, $order['id'])))
{
if ($so_data = @unserialize($so_data))
{
if ($so_data['sheepla-widget-plinpost-paczkomat'])
{
$o['delivery_point_name'] = $so_data['sheepla-widget-plinpost-paczkomat'];
}
}
}
}
// jeśli zamówienie jest w walucie innej niż PLN, trzeba przeliczyć koszt wysyłki
if ($order['currency'] != 'PLN' and $order['exchange'])
{
$order['delivery_cost'] /= $order['exchange'];
}
$o['delivery_price'] = number_format($order['delivery_cost'], 2, ".", "");
// czy klient chce fakturę
if ($o['invoice_nip'])
{
$o['want_invoice'] = 1;
}
// sposób platności
$sql = "SELECT pt.opt_name, p.payed_at
FROM `${dbp}st_order_has_payment` op
JOIN `${dbp}st_payment` p ON p.id = op.payment_id
JOIN `${dbp}st_payment_type` pt ON pt.id = p.payment_type_id
WHERE op.order_id = '{0}' LIMIT 1";
$result = DB_Query($sql, $order['id']);
if ($payment = DB_Fetch($result))
{
$o['payment_method'] = $payment['opt_name'];
$o['paid'] = $payment['payed_at'] ? 1 : 0;
if (preg_match('/pobran|przy odb/i', $o['payment_method']))
{
$o['payment_method_cod'] = 1;
}
}
//produkty zamówienia
$o['products'] = array();
$total_products = 0;
$sql = "SELECT op.*, p.weight, p.code
FROM `${dbp}st_order_product` op
LEFT JOIN `${dbp}st_product` p ON p.id = op.product_id
WHERE op.order_id = '{0}' ";
$result = DB_Query($sql, $order['id']);
while ($product = DB_Fetch($result))
{
$op = array(
'id' => $product['product_id'],
'name' => $product['name'],
'quantity' => $product['quantity'],
'price' => $product['price_brutto'],
'tax' => $product['vat'],
'weight' => $product['weight'],
'sku' => $product['code'],
);
if ($product['price_modifiers'] != '')
{
$opts = unserialize($product['price_modifiers']);
$depth = 0;
foreach ($opts as $opt)
{
// modyfikacja ceny
if (!empty($opt['value']))
{
if ($opt['prefix'] == '-')
{
$opt['value'] = -$opt['value'];
}
if ($opt['type'] == 'percent')
{
$op['price'] = $opt['price'] + $opt['value']*$opt['price']/100;
}
else
{
if (is_array($opt['value']))
{
if ($opt['value']['brutto'])
{
$op['price'] = $opt['value']['brutto'];
}
}
else
{
$op['price'] += $opt['value'];
}
}
}
// id odstatniego poziomu zagłębienia identyfikuje wariant
if ($opt['level'] > $depth and !empty($opt['custom']) and $opt['custom']['type'] == 'product_options')
{
$op['variant_id'] = $opt['custom']['id'];
$depth = $opt['level'];
}
$op['name'] .= ' ' . $opt['label'];
}
$op['price'] = number_format($op['price'],2,".","");
}
if($product['discount'] != "")
{
$discounts = unserialize($product['discount']);
foreach($discounts as $d)
{
if($d['type'] == "%")
{$op['price'] *= 1-($d['value']/100);}
else
{$op['price'] -= $d['value'];}
$op['price'] = number_format($op['price'],2,".","");
}
}
$total_products += $op['price']*$op['quantity'];
$o['products'][] = $op;
}
// rabat od całości zamówienia
if ($order['discount_id'] and $order['order_discount'])
{
if ($discount = @unserialize($order['order_discount']))
{
if ($discount['value'])
{
$op = array('name' => 'Rabat', 'quantity' => 1, 'id' => '', 'tax' => 0);
// ustalenie nazwy rabatu
$sql = "SELECT name FROM `${dbp}st_discount` WHERE id = '{0}'";
if ($dname = DB_Result(DB_Query($sql, $order['discount_id'])))
{
$op['name'] = preg_match('/rabat/i', $dname) ? $dname : "Rabat $dname";
}
if ($discount['type'] == '%') // rabat procentowy
{
$op['price'] = number_format(-$discount['value']*$total_products/100, 2, '.', '');
}
else // rabat kwotowy
{
$op['price'] = -$discount['value'];
}
$o['products'][] = $op;
}
}
}
$response[$order['id']] = $o;
}
return $response;
}
/**
* Funkcja aktualizuje zamówienia wcześniej dodane do bazy
* W przypadku zapisywania numeru nadawaczego, parametr orders_ids będzie przyjmował zawsze tablicę z jedną pozycją
* @global array $options : tablica z ustawieniami ogólnymi z początku pliku
* @param array $request tablica z żadaniem od systemu, zawiera informacje o aktualizacji zamówienia w formacie:
* orders_ids => ID zamówień
* update_type => typ zmiany - 'status', `delivery_number`, lub 'paid' (aktualizacja statusu zamówienia, dodanie numeru nadawczego i dodanie/usunięcie wpłaty)
* update_value => aktualizowana wartość - ID statusu, numer nadawczy lub informacja o opłaceniu zamówienia (bool true/false)
* @return array $response tablica zawierająca potwierdzenie zmiany:
* 'counter' => ilość zamówień w których dokonano zmiany (nawet jeśli zamówienie pozostało takie jak wcześniej)
*/
function Shop_OrderUpdate($request)
{
global $options; // globalna tablica z ustawieniami
$dbp = $options['db_prefix']; // Data Base Prefix - prefix tabel bazy
$counter = 0;
// dla wszystkich nadesłanych numerów zamówień
foreach($request['orders_ids'] as $order_id)
{
// zmiana statusu
if ($request['update_type'] == 'status')
{
DB_Query("UPDATE `${dbp}st_order` SET order_status_id = '{0}', updated_at = '{1}' WHERE id = '{2}'",
$request['update_value'], date('Y-m-d H:i:s'), $order_id);
}
// zapisanie numeru nadawczego
elseif ($request['update_type'] == 'delivery_number')
{
DB_Query("UPDATE `${dbp}st_order_delivery` SET number = '{0}'
WHERE id = (SELECT order_delivery_id FROM `${dbp}st_order` WHERE id = '{1}')
LIMIT 1", $request['update_value'], $order_id);
}
// zmiana statusu wpłaty
elseif ($request['update_type'] == 'paid')
{
DB_Query("UPDATE `${dbp}st_payment` SET updated_at = '{0}', status = '{2}',
payed_at = " . ($request['update_value'] ? '"{0}"' : 'NULL') .
" WHERE id = (SELECT payment_id FROM `${dbp}st_order_has_payment`
WHERE order_id = '{1}' ORDER BY created_at DESC LIMIT 1) LIMIT 1",
date('Y-m-d H:i:s'), $order_id, $request['update_value'] ? 1 : 0);
DB_Query("UPDATE `${dbp}st_order` SET opt_is_payed = '{0}' WHERE id = '{1}'",
$request['update_value'] ? 1 : 0, $order_id);
}
$counter++;
}
return array('counter' => $counter);
}
/**
* Funkcja zwraca listę dostępnych statusów zamówień
* @global array $options : tablica z ustawieniami ogólnymi z początku pliku
* @param array $request tablica z żadaniem od systemu, w przypadku tej funkcji nie używana
* @return array $response tablica zawierająca dostępne statusy zamówień:
* 'status_id' => nazwa statusu
*/
function Shop_StatusesList($request)
{
global $options; // globalna tablica z ustawieniami
$dbp = $options['db_prefix']; // Data Base Prefix - prefix tabel bazy
$response = array();
$sql = "SELECT id, opt_name FROM `${dbp}st_order_status`
ORDER BY is_default DESC";
$res = DB_Query($sql);
while ($status = DB_Fetch($res))
{
$response[$status['id']] = $status['opt_name'];
}
return $response;
}
/**
* Funkcja zwraca listę dostępnych sposobów wysyłki
* @global array $options : tablica z ustawieniami ogólnymi z początku pliku
* @param array $request tablica z żadaniem od systemu, w przypadku tej funkcji nie używana
* @return array $response tablica zawierająca dostępne sposoby_wysyłki:
* 'delivery_id' => nazwa wysyłki
*/
function Shop_DeliveryMethodsList($request)
{
global $options; //globalna tablica z ustawieniami
$dbp = $options['db_prefix']; //Data Base Prefix - prefix tabel bazy
$response = array();
$sql = "SELECT id, opt_name
FROM `${dbp}st_delivery`
WHERE active ORDER BY is_default DESC";
$res = DB_Query($sql);
while ($method = DB_Fetch($res))
{
$response[$method['id']] = $method['opt_name'];
}
return $response;
}
function Sote_Decrypt($text, $decrypt = true)
{
global $options;
if($decrypt != "1"){return $text;}
$key = $options['sote_shophash'];
$string = $text;
$string = base64_decode($string);
$td = mcrypt_module_open('des', '','cfb', '');
$key = substr($key, 0, mcrypt_enc_get_key_size($td));
$iv_size = mcrypt_enc_get_iv_size($td);
$iv = substr($string,0,$iv_size);
$string = substr($string,$iv_size);
if (mcrypt_generic_init($td, $key, $iv) != -1) {
$c_t = @mdecrypt_generic($td, $string);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return $c_t;
}
}
?>