first commit
This commit is contained in:
457
plugins/stSoteshopXmlPlugin/lib/stSoteshopXml.class.php
Normal file
457
plugins/stSoteshopXmlPlugin/lib/stSoteshopXml.class.php
Normal file
@@ -0,0 +1,457 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* SOTESHOP/stNokautPlugin
|
||||
*
|
||||
* Ten plik należy do aplikacji stNokautPlugin opartej na licencji (Professional License SOTE).
|
||||
* Nie zmieniaj tego pliku, jeśli chcesz korzystać z automatycznych aktualizacji oprogramowania.
|
||||
* Jeśli chcesz wprowadzać swoje modyfikacje do programu, zapoznaj się z dokumentacją, jak zmieniać
|
||||
* oprogramowanie bez zmiany kodu bazowego http://www.sote.pl/modifications
|
||||
*
|
||||
* @package stNokautPlugin
|
||||
* @subpackage libs
|
||||
* @copyright SOTE (www.sote.pl)
|
||||
* @license http://www.sote.pl/license/sote (Professional License SOTE)
|
||||
* @version $Id: stNokaut.class.php 6125 2010-07-07 11:35:39Z pawel $
|
||||
* @author Michal Prochowski <michal.prochowski@sote.pl>
|
||||
*/
|
||||
|
||||
/**
|
||||
* Klasa stNokaut
|
||||
*
|
||||
* @package stNokautPlugin
|
||||
* @subpackage libs
|
||||
*/
|
||||
class stSoteshopXml extends stPriceCompareGenerateFile implements stPriceCompareGenerateFileInterface
|
||||
{
|
||||
/**
|
||||
* Konstruktor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(__CLASS__);
|
||||
$this->config = stConfig::getInstance('stPriceCompare');
|
||||
}
|
||||
|
||||
/**
|
||||
* Generowanie nagłówka pliku
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getFileHead()
|
||||
{
|
||||
$content = xml_open_tag('?xml version="1.0" encoding="UTF-8"?');
|
||||
$content .= xml_open_tag('products');
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generowanie zawartości pliku
|
||||
*
|
||||
* @param $step integer numer kroku
|
||||
* @return string
|
||||
*/
|
||||
protected function getFileBody($step)
|
||||
{
|
||||
$priceCompareProducts = $this->getProducts($step);
|
||||
|
||||
$url_product_params = "";
|
||||
|
||||
$content = "";
|
||||
foreach ($priceCompareProducts as $priceCompareProduct)
|
||||
{
|
||||
$productContent = "";
|
||||
|
||||
$parsedProduct = new stPriceCompareProductParser($priceCompareProduct->getProduct());
|
||||
|
||||
if ($parsedProduct->checkProduct())
|
||||
{
|
||||
$product = $priceCompareProduct->getProduct();
|
||||
|
||||
$productContent .= xml_tag('url', $parsedProduct->getUrl() . $url_product_params);
|
||||
$productContent .= xml_cdata_tag('producer', $parsedProduct->getProducer());
|
||||
|
||||
$productContent .= xml_cdata_tag('name', $parsedProduct->getName());
|
||||
$productContent .= xml_cdata_tag('description', $parsedProduct->getDescription());
|
||||
$productContent .= xml_cdata_tag('shortDescription', $parsedProduct->getShortDescription());
|
||||
|
||||
$productContent .= xml_tag('weight', number_format($parsedProduct->getWeight(), 2, '.', ''));
|
||||
$productContent .= xml_tag('stock', $parsedProduct->getStock(), [
|
||||
'unit' => $product->getUom(),
|
||||
]);
|
||||
|
||||
$productContent .= xml_tag('tax', number_format($parsedProduct->getOptVat()), 2, '.', '');
|
||||
$productContent .= xml_tag('price', number_format($parsedProduct->getPriceNetto(), 2, '.', ''), [
|
||||
'type' => 'netto',
|
||||
]);
|
||||
$productContent .= xml_tag('oldPrice', number_format($parsedProduct->getOldPriceNetto(), 2, '.', ''), [
|
||||
'type' => 'netto',
|
||||
]);
|
||||
|
||||
$productContent .= $this->getProductWholesaleXml($product);
|
||||
$productContent .= $this->getProductCategoriesXml($product);
|
||||
$productContent .= $this->getProductAttributesXml($product);
|
||||
$productContent .= $this->getProductOptionsXml($product);
|
||||
$productContent .= $this->getProductPhotosXml($product);
|
||||
|
||||
$content .= price_compare_xml_tag('product', $productContent, [
|
||||
'code' => $product->getCode(),
|
||||
'active' => $product->getActive() ? 'true' : 'false',
|
||||
'ean' => $product->getManCode(),
|
||||
]);
|
||||
}
|
||||
|
||||
unset($parsedProduct);
|
||||
|
||||
if ($this->isCLI())
|
||||
{
|
||||
usleep(250000);
|
||||
}
|
||||
}
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generowanie stopki pliku
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getFileFoot()
|
||||
{
|
||||
$content = xml_close_tag('products');
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pobieranie infromacji o porównywarce podczas eksportu
|
||||
*
|
||||
* @param object $object
|
||||
* @return integer
|
||||
*/
|
||||
static public function getProduct($object = null)
|
||||
{
|
||||
return stPriceCompareGenerateFile::getProductForExport(__CLASS__, $object);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ustawianie infromacji o porównywarce podczas importu
|
||||
*
|
||||
* @param object $object
|
||||
* @param integer $value
|
||||
* @return boolean
|
||||
*/
|
||||
static public function setProduct($object = null, $active = 0)
|
||||
{
|
||||
return stPriceCompareGenerateFile::setProductForImport(__CLASS__, $object, $active);
|
||||
}
|
||||
|
||||
public function getCategoryPath($category, $separator = '/', $htmlspecialchars = false)
|
||||
{
|
||||
$c = array();
|
||||
foreach ($category->getPath() as $categoryPath)
|
||||
$c[] = $categoryPath->getName();
|
||||
$c[] = $category->getName();
|
||||
|
||||
if ($htmlspecialchars)
|
||||
foreach ($c as $k => $v)
|
||||
$c[$k] = htmlspecialchars($v);
|
||||
|
||||
if ($this->config->get('category_root'))
|
||||
unset($c[0]);
|
||||
|
||||
return implode($separator, $c);
|
||||
}
|
||||
|
||||
protected function getProductWholesaleXml(Product $product): string
|
||||
{
|
||||
if ($this->getConfig('none_whoolesale') != true)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
$wholesaleXml = "";
|
||||
|
||||
foreach (array('a', 'b', 'c') as $group)
|
||||
{
|
||||
$method = 'getWholesale' . ucfirst($group) . 'Netto';
|
||||
$wholesaleXml .= xml_tag('price', number_format($product->$method(), 2, '.', ''), [
|
||||
'type' => $this->getPriceType(),
|
||||
'group' => $group,
|
||||
]);
|
||||
}
|
||||
|
||||
return xml_tag('wholesale', $wholesaleXml);
|
||||
}
|
||||
|
||||
protected function getProductCategoriesXml(Product $product): string
|
||||
{
|
||||
$categoriesXml = "";
|
||||
|
||||
foreach ($product->getProductHasCategorys() as $category)
|
||||
{
|
||||
$categoryPath = $this->getCategoryPath($category->getCategory());
|
||||
|
||||
if ($category->getIsDefault() == 1)
|
||||
{
|
||||
$categoriesXml .= xml_cdata_tag('category', $categoryPath, array('main' => 'true'));
|
||||
}
|
||||
else
|
||||
{
|
||||
$categoriesXml .= xml_cdata_tag('category', $categoryPath);
|
||||
}
|
||||
}
|
||||
|
||||
return !empty($categoriesXml) ? xml_tag('categories', $categoriesXml) : '';
|
||||
}
|
||||
|
||||
protected function getProductPhotosXml(Product $product): string
|
||||
{
|
||||
$photosXml = "";
|
||||
|
||||
foreach ($product->getImages() as $image)
|
||||
{
|
||||
if ($image->getId() == $product->getDefaultAssetImage()->getId())
|
||||
{
|
||||
|
||||
$photosXml .= xml_tag('photo', htmlspecialchars(st_product_image_path($image, 'full', true, false, true)), array('id' => $image->getId(), 'main' => 'true'));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
$photosXml .= xml_tag('photo', htmlspecialchars(st_product_image_path($image, 'full', true, false, true)), array('id' => $image->getId()));
|
||||
}
|
||||
}
|
||||
|
||||
return !empty($photosXml) ? xml_tag('photos', $photosXml) : '';
|
||||
}
|
||||
|
||||
protected function getProductAttributesXml(Product $product): string
|
||||
{
|
||||
$productVariants = appProductAttributeVariantPeer::doSelectArrayWithAttribyteByProduct($product, stLanguage::getOptLanguage());
|
||||
|
||||
if (!empty($productVariants))
|
||||
{
|
||||
$attributesXml = "";
|
||||
$productAttributes = appProductAttributePeer::doSelectArrayByProduct($product, stLanguage::getOptLanguage(), false);
|
||||
|
||||
if (!empty($productAttributes))
|
||||
{
|
||||
foreach ($productVariants as $attributeId => $productVariant)
|
||||
{
|
||||
if (!isset($productAttributes[$attributeId]))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$valuesXml = "";
|
||||
$attribute = $productAttributes[$attributeId];
|
||||
|
||||
foreach ($productVariant as $value)
|
||||
{
|
||||
switch ($attribute['type'])
|
||||
{
|
||||
case "T":
|
||||
$valuesXml .= xml_cdata_tag('value', $value['value']);
|
||||
break;
|
||||
|
||||
case "B":
|
||||
$valuesXml .= xml_cdata_tag('value', '', array('checked' => 'true'));
|
||||
break;
|
||||
|
||||
case "C":
|
||||
$colorValue = $value['type'] == "C" ? "#" . $value['value'] : htmlspecialchars(image_path('/' . $value['value'], true));
|
||||
$valuesXml .= xml_cdata_tag('value', $value['name'], array('color' => $colorValue));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$attributesXml .= xml_tag('attribute', $valuesXml, array('name' => $attribute['name'], 'type' => $attribute['type']));
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($attributesXml))
|
||||
{
|
||||
return !empty($product->getAttributesLabel()) ? xml_tag('attributes', $attributesXml, array('title' => $product->getAttributesLabel())) : xml_tag('attributes', $attributesXml);
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
protected function getProductOptionsXml(Product $product): string
|
||||
{
|
||||
$root = ProductOptionsValuePeer::getOrCreateRoot($product);
|
||||
$options = $this->getProductOptions($product);
|
||||
|
||||
$helper = function (array $options) use (&$helper): string
|
||||
{
|
||||
$content = '';
|
||||
|
||||
foreach ($options as $fieldName => $values)
|
||||
{
|
||||
$valuesContent = '';
|
||||
|
||||
foreach ($values as $value => $params)
|
||||
{
|
||||
if ('@attributes' == $value)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$attributes = array_merge(['name' => $value], $params['@attributes']);
|
||||
|
||||
if (isset($params['@children']))
|
||||
{
|
||||
$valuesContent .= xml_tag('value', $helper($params['@children']), $attributes);
|
||||
}
|
||||
else
|
||||
{
|
||||
$valuesContent .= xml_cdata_tag('value', '', $attributes);
|
||||
}
|
||||
}
|
||||
|
||||
$optionAttributes = array_merge(['name' => $fieldName], isset($values['@attributes']) ? $values['@attributes'] : []);
|
||||
|
||||
$content .= xml_tag('option', $valuesContent, $optionAttributes);
|
||||
}
|
||||
|
||||
return $content;
|
||||
};
|
||||
|
||||
return !empty($options) ? xml_tag('options', $helper($options), array('priceType' => $root->getPriceType())) : '';
|
||||
}
|
||||
|
||||
protected function getPriceType(): string
|
||||
{
|
||||
return 'netto';
|
||||
}
|
||||
|
||||
private function getProductOptions(Product $product): array
|
||||
{
|
||||
sfLoader::loadHelpers(['Helper', 'Asset']);
|
||||
$c = new Criteria();
|
||||
$c->addSelectColumn(ProductOptionsValuePeer::ID);
|
||||
$c->addSelectColumn(ProductOptionsValuePeer::PRODUCT_OPTIONS_FIELD_ID);
|
||||
$c->addSelectColumn(ProductOptionsValuePeer::DEPTH);
|
||||
$c->addSelectColumn(ProductOptionsValuePeer::OPT_VALUE);
|
||||
$c->addSelectColumn(ProductOptionsValuePeer::LFT);
|
||||
$c->addSelectColumn(ProductOptionsValuePeer::RGT);
|
||||
$c->addSelectColumn(ProductOptionsFieldPeer::OPT_NAME);
|
||||
$c->addSelectColumn(ProductOptionsValuePeer::STOCK);
|
||||
$c->addSelectColumn(ProductOptionsValuePeer::WEIGHT);
|
||||
$c->addSelectColumn(ProductOptionsValuePeer::USE_PRODUCT);
|
||||
$c->addSelectColumn(ProductOptionsValuePeer::MAN_CODE);
|
||||
$c->addSelectColumn(ProductOptionsValuePeer::PRICE);
|
||||
$c->addSelectColumn(ProductOptionsValuePeer::OLD_PRICE);
|
||||
$c->addSelectColumn(ProductOptionsValuePeer::COLOR);
|
||||
$c->addSelectColumn(ProductOptionsValuePeer::USE_IMAGE_AS_COLOR);
|
||||
$c->addSelectColumn(ProductOptionsValuePeer::SF_ASSET_ID);
|
||||
$c->addSelectColumn(ProductOptionsFieldPeer::PRODUCT_OPTIONS_FILTER_ID);
|
||||
$c->addSelectColumn(ProductOptionsFieldPeer::OPT_DEFAULT_VALUE);
|
||||
|
||||
$c->add(ProductOptionsValuePeer::PRODUCT_ID, $product->getId());
|
||||
$c->add(ProductOptionsValuePeer::PRODUCT_OPTIONS_VALUE_ID, null, Criteria::ISNOTNULL);
|
||||
$c->addJoin(ProductOptionsValuePeer::PRODUCT_OPTIONS_FIELD_ID, ProductOptionsFieldPeer::ID);
|
||||
$c->addAscendingOrderByColumn(ProductOptionsFieldPeer::FIELD_ORDER);
|
||||
$c->addAscendingOrderByColumn(ProductOptionsValuePeer::LFT);
|
||||
|
||||
$rs = ProductOptionsValuePeer::doSelectRS($c);
|
||||
|
||||
$hydrate = function (ResultSet $rs, Product $product, int $depth = 1) use (&$hydrate): array
|
||||
{
|
||||
$results = [];
|
||||
|
||||
$rs->setFetchmode(ResultSet::FETCHMODE_ASSOC);
|
||||
|
||||
while ($rs->next())
|
||||
{
|
||||
if ($depth != $rs->getInt('DEPTH'))
|
||||
{
|
||||
$rs->previous();
|
||||
break;
|
||||
}
|
||||
|
||||
$fieldName = $rs->getString('OPT_NAME');
|
||||
$optionValue = $rs->getString('OPT_VALUE');
|
||||
$hasChildren = $rs->getInt('RGT') - $rs->getInt('LFT') > 1;
|
||||
|
||||
if (!isset($results[$fieldName]))
|
||||
{
|
||||
$fieldAttributes = [];
|
||||
|
||||
$filterId = $rs->getInt('PRODUCT_OPTIONS_FILTER_ID');
|
||||
|
||||
if ($filterId)
|
||||
{
|
||||
$filter = ProductOptionsFilterPeer::retrieveById($filterId);
|
||||
$fieldAttributes['filter'] = $filter->getOptName();
|
||||
}
|
||||
|
||||
$results[$fieldName] = ['@attributes' => $fieldAttributes];
|
||||
}
|
||||
|
||||
$attributes = [
|
||||
'price' => $rs->getString('PRICE'),
|
||||
'old_price' => $rs->getString('OLD_PRICE'),
|
||||
'weight' => $rs->getString('WEIGHT'),
|
||||
'color' => $rs->getString('USE_IMAGE_AS_COLOR') ? image_path(ProductOptionsValuePeer::getColorImagePath($product->getId(), $rs->getInt('ID'), $rs->getString('COLOR')), true) : '#' . $rs->getString('COLOR'),
|
||||
'product_image' => $rs->getInt('SF_ASSET_ID'),
|
||||
];
|
||||
|
||||
if (!$hasChildren)
|
||||
{
|
||||
$attributes['stock'] = $rs->getString('STOCK');
|
||||
$attributes['code'] = $rs->getString('USE_PRODUCT');
|
||||
$attributes['ean'] = $rs->getString('MAN_CODE');
|
||||
}
|
||||
|
||||
if ($rs->getInt('OPT_DEFAULT_VALUE') == $rs->getInt('OPT_VALUE'))
|
||||
{
|
||||
$attributes['default'] = 'true';
|
||||
}
|
||||
|
||||
$results[$fieldName][$optionValue] = [
|
||||
'@attributes' => $attributes
|
||||
];
|
||||
|
||||
|
||||
if ($hasChildren)
|
||||
{
|
||||
$results[$fieldName][$optionValue]['@children'] = $hydrate($rs, $product, $depth + 1);
|
||||
}
|
||||
}
|
||||
|
||||
return $results;
|
||||
};
|
||||
|
||||
return $hydrate($rs, $product);
|
||||
}
|
||||
|
||||
protected function getProducts($step)
|
||||
{
|
||||
$peerClass = $this->getConfiguration($this->priceCompareName, 'peer_name');
|
||||
|
||||
$c = new Criteria();
|
||||
$c->add(constant($peerClass.'::ACTIVE'), 1);
|
||||
|
||||
if ($this->getConfig('none_active')){
|
||||
$c->add(ProductPeer::ACTIVE, 1);
|
||||
}
|
||||
|
||||
if ($this->getConfig('none_stock'))
|
||||
{
|
||||
|
||||
$c4 = $c->getNewCriterion(ProductPeer::STOCK, null, Criteria::ISNULL);
|
||||
$c5 = $c->getNewCriterion(ProductPeer::STOCK, 0, Criteria::GREATER_THAN);
|
||||
$c4->addOr($c5);
|
||||
$c->add($c4);
|
||||
|
||||
}
|
||||
|
||||
$c->setOffset($this->productsByStep*$step);
|
||||
$c->setLimit($this->productsByStep);
|
||||
$c->addAscendingOrderByColumn(constant($peerClass.'::PRODUCT_ID'));
|
||||
return call_user_func($peerClass.'::doSelectJoinAll', $c);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user