*/ /** * 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); } }