<?php
ClassLoader::import('application.helper.CreateHandleString');
require_once dirname(__file__) . '/../LiveCartImportDriver.php';
class ShopScriptImport extends LiveCartImportDriver
{
protected $categoryMap = null;
protected $productSql;
private $specFieldSql;
private $defLang;
private $attributes = array();
private $statusMap = array();
private $countryMap = array();
private $countryNameMap = array();
public function getName()
{
return 'Shop-Script';
}
public function isPathValid()
{
// no path provided - won't be able to import images
if (!$this->path)
{
return true;
}
if (substr(strtolower($this->path), 0, 7) == 'http://')
{
return true;
}
foreach (array('admin.php', 'core_functions', 'checklogin.php') as $file)
{
if (!file_exists($this->path . '/' . $file))
{
return false;
}
}
return true;
}
public function isLanguage()
{
return true;
}
public function isCurrency()
{
return true;
}
public function isManufacturer()
{
return false;
}
public function isState()
{
return false;
}
public function isUser()
{
return true;
}
public function isBillingAddress()
{
return true;
}
public function isCategory()
{
return true;
}
public function isProduct()
{
return true;
}
public function isCustomerOrder()
{
return true;
}
public function isProductRelationship()
{
return true;
}
public function isNewsletterSubscriber()
{
return true;
}
public function isStaticPage()
{
return true;
}
public function isSpecField()
{
return true;
}
public function getVerificationTableNames()
{
return array('categories', 'custgroups', 'customer_addresses', 'product_options', 'products_opt_val_variants', 'shopping_cart_items_content');
}
public function getTableMap()
{
return array(
'Category' => $this->getTablePrefix() . 'categories',
'Currency' => $this->getTablePrefix() . 'currency_types',
'CustomerOrder' => $this->getTablePrefix() . 'orders',
'BillingAddress' => $this->getTablePrefix() . 'customer_addresses',
'Product' => $this->getTablePrefix() . 'products',
'ProductRelationship' => $this->getTablePrefix() . 'related_items',
'User' => $this->getTablePrefix() . 'customer_addresses',
'NewsletterSubscriber' => $this->getTablePrefix() . 'subscribers',
'SpecField' => $this->getTablePrefix() . 'product_options',
'StaticPage' => $this->getTablePrefix() . 'aux_pages',
);
}
public function getNextLanguage()
{
if ($this->defLang)
{
return null;
}
// default language is set to English
$id = 'en';
if (!$lang = ActiveRecordModel::getInstanceByIdIfExists('Language', $id, false))
{
$lang = ActiveRecordModel::getNewInstance('Language');
$lang->setID($id);
$lang->isEnabled->set(true);
$lang->isDefault->set(true);
}
$this->defLang = $lang->getID();
return $lang;
}
public function getNextState()
{
if (!$data = $this->loadRecord('SELECT * FROM ' . $this->getTablePrefix() . 'states'))
{
return null;
}
$rec = ActiveRecordModel::getNewInstance('State');
foreach (array(
'countryID' => 'country_code',
'code' => 'code',
'name' => 'state',
) as $lc => $xc)
{
$rec->$lc->set($data[$xc]);
}
return $rec;
}
public function getNextCurrency()
{
if (!$data = $this->loadRecord('SELECT * FROM ' . $this->getTablePrefix() . 'currency_types ORDER BY sort_order ASC'))
{
return null;
}
if (!$currency = ActiveRecordModel::getInstanceByIDIfExists('Currency', $data['currency_iso_3'], false))
{
$currency = Currency::getNewInstance($data['currency_iso_3']);
$currency->rate->set($data['currency_value']);
}
$currency->isEnabled->set(true);
if ($this->getConfigValue('CONF_DEFAULT_CURRENCY') == $data['CID'])
{
$f = new ARUpdateFilter();
$f->addModifier('Currency.isDefault', 0);
ActiveRecordModel::updateRecordSet('Currency', $f);
$currency->isDefault->set(true);
}
return $currency;
}
public function getNextUser()
{
if (!$data = $this->loadRecord('SELECT DISTINCT(Email) AS em, ' . $this->getTablePrefix() . 'customers.* FROM ' . $this->getTablePrefix() . 'customers GROUP BY em'))
{
return null;
}
if (!$rec = User::getInstanceByEmail($data['Email']))
{
$rec = User::getNewInstance($data['Email']);
foreach (array(
'firstName' => 'first_name',
'lastName' => 'last_name',
'dateCreated' => 'reg_datetime',
) as $lc => $xc)
{
$rec->$lc->set($data[$xc]);
}
$rec->setPassword(base64_decode($data['cust_password']));
$rec->isEnabled->set(1);
$rec->setID($data['customerID']);
}
return $rec;
}
public function getNextBillingAddress()
{
$addressTable = $this->getTablePrefix() . 'customer_addresses';
$userTable = $this->getTablePrefix() . 'customers';
if (!$data = $this->loadRecord('SELECT * FROM ' . $addressTable . ' LEFT JOIN ' . $userTable . ' ON ' . $userTable . '.addressID = ' . $addressTable . '.customerID WHERE ' . $userTable .'.customerID IS NOT NULL'))
{
return null;
}
$address = UserAddress::getNewInstance();
$map = array(
'address' => 'address1',
'city' => 'city',
'zip' => 'postalCode',
'state' => 'stateName',
'first_name' => 'firstName',
'last_name' => 'lastName',
);
foreach ($map as $osc => $lc)
{
if (isset($data[$osc]))
{
$address->$lc->set($data[$osc]);
}
}
$address->countryID->set($this->getCountryByID($data['countryID']));
$user = ActiveRecordModel::getInstanceByIDIfExists('User', $this->getRealId('User', $data['customerID']), false);
if (!$user || !$user->isExistingRecord())
{
return $this->getNextBillingAddress();
}
$billing = BillingAddress::getNewInstance($user, $address);
$billing->save();
// default address
if ($data['Email'])
{
$user->defaultBillingAddress->set($billing);
$user->save();
}
return $billing;
}
public function getNextCategory()
{
if (is_null($this->categoryMap))
{
// get all categories
$sql = 'SELECT * FROM ' . $this->getTablePrefix() . 'categories WHERE categoryID > 1';
foreach ($this->getDataBySQL($sql) as $category)
{
$this->categoryMap[$category['categoryID']] = $category;
}
// get level for each category
foreach ($this->categoryMap as $id => &$category)
{
if (1 == $category['parent'])
{
$category['parent'] = 0;
}
$level = 0;
while ($id != 0 && ($level < 100))
{
$level++;
if (isset($this->categoryMap[$id]['parent']))
{
$id = $this->categoryMap[$id]['parent'];
}
// parent category does not exist, so remove the category
else if (!isset($this->categoryMap[$id]) || ($this->categoryMap[$id]['parent'] != 0))
{
unset($this->categoryMap[$id]);
$level = 101;
}
}
// circular reference
if ($level >= 100)
{
unset($this->categoryMap[$category['categoryID']]);
}
else
{
$category['level'] = $level;
}
}
$this->categoryIds = array_keys($this->categoryMap);
usort($this->categoryMap, array($this, 'sortCategories'));
}
// root level categories first
if ($data = array_shift($this->categoryMap))
{
$parentNode = 0 == $data['parent'] ? Category::getRootNode() : Category::getInstanceById($this->getRealId('Category', $data['parent']));
$rec = Category::getNewInstance($parentNode);
}
else
{
return null;
}
$rec->setID($data['categoryID']);
$rec->isEnabled->set(true);
$rec->keywords->set($data['meta_keywords']);
$rec->setValueByLang('name', $this->defLang, $data['name']);
$rec->setValueByLang('description', $this->defLang, $data['description']);
//images
if ($data['picture'])
{
//$this->importCategoryImage($rec, $this->path . '/' . $data['picture']);
}
$rec->rawData = $data;
return $rec;
}
public function getNextProductRelationship()
{
if (!$data = $this->loadRecord('SELECT * FROM ' . $this->getTablePrefix() . 'related_items'))
{
return null;
}
$owner = Product::getInstanceByID($this->getRealId('Product', $data['Owner']), Product::LOAD_DATA);
$target = Product::getInstanceByID($this->getRealId('Product', $data['productID']), Product::LOAD_DATA);
return ProductRelationship::getNewInstance($owner, $target);
}
public function getNextNewsletterSubscriber()
{
if (!$data = $this->loadRecord('SELECT * FROM ' . $this->getTablePrefix() . 'subscribers LEFT JOIN ' . $this->getTablePrefix() . 'customers ON ' . $this->getTablePrefix() . 'customers.customerID=' . $this->getTablePrefix() . 'subscribers.customerID WHERE ' . $this->getTablePrefix() . 'subscribers.customerID IS NULL OR (' . $this->getTablePrefix() . 'customers.customerID IS NOT NULL)'))
{
return null;
}
if (empty($data['Email']))
{
return $this->getNextNewsletterSubscriber();
}
$subscriber = NewsletterSubscriber::getNewInstanceByEmail($data['Email']);
if ($data['customerID'])
{
if ($user = ActiveRecordModel::getInstanceByIDIfExists('User', $this->getRealId('User', $data['customerID'], false)))
{
if ($user->isExistingRecord())
{
$subscriber->user->set($user);
}
}
}
else
{
if ($user = User::getInstanceByEmail($data['Email']))
{
$subscriber->user->set($user);
}
}
$subscriber->isEnabled->set(true);
return $subscriber;
}
public function getNextStaticPage()
{
if (!$data = $this->loadRecord('SELECT * FROM ' . $this->getTablePrefix() . 'aux_pages'))
{
return null;
}
$page = StaticPage::getNewInstance();
$page->setValueByLang('title', $this->defLang, $data['aux_page_name']);
$page->setValueByLang('text', $this->defLang, $data['aux_page_text']);
$page->menu->set(array('INFORMATION' => true));
return $page;
}
public function getNextSpecField()
{
if (is_null($this->specFieldSql))
{
// get all categories
$this->specFieldSql = 'SELECT * FROM ' . $this->getTablePrefix() . 'product_options ORDER BY sort_order ASC';
}
if (!$data = $this->loadRecord($this->specFieldSql))
{
return null;
}
$this->attributes[] = $data;
$rec = SpecField::getNewInstance(Category::getRootNode(), SpecField::DATATYPE_TEXT, SpecField::TYPE_TEXT_SIMPLE);
$rec->setID($data['optionID']);
$rec->handle->set(createHandleString($data['name']));
$rec->setValueByLang('name', $this->defLang, $data['name']);
$rec->isDisplayed->set(true);
return $rec;
}
public function getNextProduct()
{
if (!$this->productSql)
{
$fields = array($this->getTablePrefix() . 'products.*');
$join = array();
foreach ($this->attributes as $attr)
{
$join[] = 'LEFT JOIN ' . $this->getTablePrefix() . 'product_options_values AS extra_' . $attr['optionID'] . ' ON (extra_' . $attr['optionID'] . '.productID=' . $this->getTablePrefix() . 'products.productID AND extra_' . $attr['optionID'] . '.optionID=' . $attr['optionID'] . ')';
$fields[] = 'extra_' . $attr['optionID'] . '.option_value AS extrafield_' . $attr['optionID'];
}
$validCats = implode(',', $this->categoryIds);
$this->productSql = 'SELECT ' . implode(',', $fields) . ' FROM ' . $this->getTablePrefix() . 'products ' . implode(' ', $join) . ' LEFT JOIN ' . $this->getTablePrefix() . 'categories AS cat ON cat.categoryID=' . $this->getTablePrefix() . 'products.categoryID WHERE cat.categoryID IS NOT NULL AND cat.categoryID IN (' . $validCats . ')';
}
if (!$data = $this->loadRecord($this->productSql))
{
return null;
}
$rec = Product::getNewInstance(Category::getInstanceById($this->getRealId('Category', $data['categoryID'])));
$rec->setID($data['productID']);
$rec->keywords->set($data['meta_keywords']);
$rec->setValueByLang('name', $this->defLang, $data['name']);
$rec->setValueByLang('longDescription', $this->defLang, $data['description']);
$rec->setValueByLang('shortDescription', $this->defLang, $data['brief_description']);
foreach ($this->attributes as $attr)
{
if (!empty($data['extrafield_' . $attr['optionID']]))
{
$rec->setAttributeValueByLang(SpecField::getInstanceByID($this->getRealId('SpecField', $attr['optionID']), SpecField::LOAD_DATA), $this->defLang, $data['extrafield_' . $attr['optionID']]);
}
}
$data['voteSum'] = round($data['customers_rating'] * $data['customer_votes']);
if ($data['product_code'])
{
$rec->sku->set($data['product_code']);
}
foreach (array(
'shippingWeight' => 'weight',
'stockCount' => 'in_stock',
'shippingSurchargeAmount' => 'shipping_freight',
'minimumQuantity' => 'min_order_amount',
'dateCreated' => 'date_added',
'ratingSum' => 'voteSum',
'rating' => 'customers_rating',
'ratingCount' => 'customer_votes',
) as $lc => $xc)
{
$rec->$lc->set($data[$xc]);
}
$rec->isEnabled->set(1 == $data['enabled']);
$rec->setPrice($this->getDefaultCurrency(), $data['Price']);
if ($data['list_price'])
{
$price = $rec->getPricingHandler()->getPriceByCurrencyCode($this->getDefaultCurrency());
$price->listPrice->set($data['list_price']);
}
// images
foreach ($this->getDataBySQL('SELECT * FROM ' . $this->getTablePrefix() . 'product_pictures WHERE productID=' . $data['productID'] . ' ORDER BY (photoID=' . (int)$data['default_picture'] . '), photoID ASC') as $image)
{
$file = $image['enlarged'] ? $image['enlarged'] : $image['filename'];
$this->importProductImage($rec, $this->path . '/products_pictures/' . $file);
}
$rec->rawData = $data;
return $rec;
}
public function getNextCustomerOrder()
{
if (!$data = $this->loadRecord('SELECT * FROM ' . $this->getTablePrefix() . 'orders WHERE customerID > 0'))
{
return null;
}
$user = ActiveRecordModel::getInstanceByIDIfExists('User', $this->getRealId('User', $data['customerID'], false));
if (!$user || !$user->isExistingRecord())
{
return $this->getNextCustomerOrder();
}
$currCode = $data['currency_code'];
if (!$currency = ActiveRecordModel::getInstanceByIDIfExists('Currency', $currCode, false))
{
$currency = Currency::getNewInstance($currCode);
$currency->save();
}
$order = CustomerOrder::getNewInstance($user);
$order->currency->set($currency);
$order->dateCompleted->set($data['order_time']);
// products
foreach ($this->getDataBySql('SELECT * FROM ' . $this->getTablePrefix() . 'ordered_carts WHERE orderID=' . $data['orderID']) as $item)
{
$product = null;
// try to identify product by SKU
preg_match('/\[(.*)\]/', $item['name'], $sku);
if (isset($sku[1]))
{
$product = Product::getInstanceBySKU($sku[1]);
}
// if that doesn't work, then try to match the exact name
if (!$product)
{
$productData = array_shift($this->getDataBySQL('SELECT productID FROM ' . $this->getTablePrefix() . 'products WHERE name="' . addslashes($item['name']) . '"'));
if ($productData && is_array($productData))
{
$product = Product::getInstanceByID($this->getRealId('Product', $productData['productID']), Product::LOAD_DATA);
}
}
if ($product)
{
$order->addProduct($product, $item['Quantity'], true);
$orderedItem = array_shift($order->getItemsByProduct($product));
$orderedItem->price->set($item['Price']);
}
}
// addresses
$order->shippingAddress->set($this->getUserAddress($data, 'shipping_'));
$order->billingAddress->set($this->getUserAddress($data, 'billing_'));
$order->status->set($this->getOrderStatus($data['statusID']));
if ($order->status->get() == CustomerOrder::STATUS_SHIPPED)
{
$order->isPaid->set(true);
}
$order->rawData = $data;
return $order;
}
private function getUserAddress($data, $prefix)
{
$address = UserAddress::getNewInstance();
$map = array(
'address' => 'address1',
'city' => 'city',
'zip' => 'postalCode',
'state' => 'stateName',
'first_name' => 'firstName',
'last_name' => 'lastName',
);
foreach ($map as $osc => $lc)
{
if (isset($data[$prefix . $osc]))
{
$address->$lc->set($data[$prefix . $osc]);
}
}
$address->countryID->set($this->getCountryByName($data[$prefix . 'country']));
return $address;
}
public function saveCustomerOrder(CustomerOrder $order)
{
$order->shippingAddress->get()->save();
$order->billingAddress->get()->save();
$order->save();
$shipment = $order->getShipments()->get(0);
if ($shipment)
{
$shipment->shippingAmount->set($order->rawData['shipping_cost']);
if ($order->status->get() == CustomerOrder::STATUS_SHIPPED)
{
$shipment->status->set(Shipment::STATUS_SHIPPED);
}
$shipment->save();
}
return parent::saveCustomerOrder($order);
}
private function sortCategories($a, $b)
{
if ($a['level'] == $b['level'])
{
if ($a['sort_order'] == $b['sort_order'])
{
return 0;
}
else
{
return $a['sort_order'] > $b['sort_order'] ? 1 : -1;
}
}
return $a['level'] > $b['level'] ? 1 : -1;
}
protected function getConfigData()
{
$map = array();
foreach ($this->getDataBySQL('SELECT * FROM ' . $this->getTablePrefix() . 'settings') as $row)
{
$map[$row['settings_constant_name']] = $row['settings_value'];
}
return $map;
}
private function getCountryByID($id)
{
if (!$this->countryMap)
{
foreach ($this->getDataBySQL('SELECT * FROM ' . $this->getTablePrefix() . 'countries') as $row)
{
$this->countryMap[$row['countryID']] = strtoupper($row['country_iso_2']);
}
}
return $this->countryMap[$id];
}
private function getCountryByName($name)
{
if (!$this->countryNameMap)
{
foreach ($this->getDataBySQL('SELECT * FROM ' . $this->getTablePrefix() . 'countries') as $row)
{
$this->countryNameMap[$row['country_name']] = strtoupper($row['country_iso_2']);
}
}
return $this->countryNameMap[$name];
}
private function getOrderStatus($shopScriptStatusCode)
{
if (!$this->statusMap)
{
// it seems that the status codes are editable by user, so we have to detect them by names
$stringMap = array(
'STRING_CANCELED_ORDER_STATUS' => null,
'Pending' => CustomerOrder::STATUS_NEW,
'Processing' => CustomerOrder::STATUS_PROCESSING,
'Shipped' => CustomerOrder::STATUS_SHIPPED,
'Delivered' => CustomerOrder::STATUS_SHIPPED,
);
$idMap = array(
1 => null,
2 => CustomerOrder::STATUS_NEW,
3 => CustomerOrder::STATUS_PROCESSING,
4 => CustomerOrder::STATUS_SHIPPED,
5 => CustomerOrder::STATUS_SHIPPED,
);
foreach ($this->getDataBySQL('SELECT * FROM ' . $this->getTablePrefix() . 'order_status') as $row)
{
if (isset($stringMap[$row['status_name']]))
{
$this->statusMap[$row['statusID']] = $stringMap[$row['status_name']];
}
else if (isset($idMap[$row['statusID']]))
{
$this->statusMap[$row['statusID']] = $idMap[$row['statusID']];
}
}
}
return isset($this->statusMap[$shopScriptStatusCode]) ? $this->statusMap[$shopScriptStatusCode] : CustomerOrder::STATUS_PROCESSING;
}
}
?>