domain = Configuration::get('PS_SHOP_DOMAIN'); require_once(dirname(__FILE__).'/../../../init.php'); } /****************************************************************************************************************************** * Génère le catalog dans le dossier ./catalogs ******************************************************************************************************************************/ public function generateCatalog($type) { if ($type === 'arthur_media') { $this->_filename = (new DateTime('+1 day'))->format('Ymd') . '_ventes.xml'; $this->_type = $type; $this->context = Context::getContext(); $this->context->controller = new FrontController(); $items = $this->getSales(true); $this->createSalesXml($items); } if (($handle = fopen(dirname(__FILE__).'/../catalogs/'.$this->_filename, 'w')) && $this->_xml !== null) { fwrite($handle, $this->_xml); } } /***************************************************************** * Renvoi la liste des Ventes actives *****************************************************************/ private function getChildren($sale) { $parent = Db::getInstance()->getRow(' SELECT c.`nleft`, c.`nright` FROM ' . _DB_PREFIX_ .'category c LEFT JOIN `'._DB_PREFIX_.'category_group` g ON (c.`id_category` = g.`id_category`) WHERE c.`id_category` = ' . pSQL($sale->id_category) . ' '); $maxdepth = Configuration::get('BLOCK_CATEG_MAX_DEPTH'); $range = 'AND nleft >= '.$parent['nleft'].' AND nright <= '.$parent['nright']; $resultIds = array(); $resultParents = array(); return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS(' SELECT c.id_parent, c.id_category, cl.name, cl.description, cl.link_rewrite FROM `'._DB_PREFIX_.'category` c INNER JOIN `'._DB_PREFIX_.'category_lang` cl ON (c.`id_category` = cl.`id_category` AND cl.`id_lang` = '.(int)$this->context->language->id.Shop::addSqlRestrictionOnLang('cl').') INNER JOIN `'._DB_PREFIX_.'category_shop` cs ON (cs.`id_category` = c.`id_category` AND cs.`id_shop` = '.(int)$this->context->shop->id.') WHERE (c.`active` = 1 OR c.`id_category` = '.(int)Configuration::get('PS_HOME_CATEGORY').') AND c.`id_category` != '.(int)Configuration::get('PS_ROOT_CATEGORY').' '.((int)$maxdepth != 0 ? ' AND `level_depth` <= '.(int)$maxdepth : '').' '.$range.' AND c.id_category IN ( SELECT id_category FROM `'._DB_PREFIX_.'category_group` WHERE `id_group` IN ('.pSQL(implode(', ', Customer::getGroupsStatic((int)$this->context->customer->id))).') ) ORDER BY `level_depth` ASC, '.(Configuration::get('BLOCK_CATEG_SORT') ? 'cl.`name`' : 'cs.`position`').' '.(Configuration::get('BLOCK_CATEG_SORT_WAY') ? 'DESC' : 'ASC')); } private function formatSale($sale, $future = false) { $item = array(); $item['id_de_la_vente'] = $sale->id_privatesales; $item['date_de_debut'] = substr($sale->date_start, 0, 10); $item['heure_de_debut'] = substr($sale->date_start, -8); $item['date_de_fin'] = substr($sale->date_end, 0, 10); $item['heure_de_fin'] = substr($sale->date_end, -8); $item['categorie_d_article'] = Db::getInstance()->getValue(' SELECT `title` FROM `'._DB_PREFIX_.'privatesales_category_lang` a LEFT JOIN `'._DB_PREFIX_.'privatesales_category_sales` b ON (a.`id_privatesales_category` = b.`id_privatesales_category`) WHERE b.`id_privatesales` = '.$sale->id_privatesales.' '); $item['nom_de_la_vente'] = $sale->title; if ($future === false) { $item['image_logo_marque'] = _PS_BASE_URL_.'/modules/privatesales/img/' . $sale->id_privatesales . '/logo/' . $sale->id_privatesales . '_' . Context::getContext()->language->id . '.jpg'; } $category = new Category($sale->id_category, (int) $this->context->cookie->id_lang); $item['slogan'] = $sale->subtitle; $item['sous_titre'] = $sale->subtitle; $item['description'] = $sale->description; $item['image_visuel_large_vente'] = _PS_BASE_URL_.'/modules/privatesales/img/'.$sale->id_privatesales.'/current/'.$sale->id_privatesales . '_' . Context::getContext()->language->id.'.jpg'; $item['url_de_la_vente'] = _PS_BASE_URL_.'/'.$sale->id_category.'-'.$sale->link_rewrite; $item['reduction'] = $sale->percent; //BUILD MENU CATEGORIES MENU $categories = $this->getChildren($sale); foreach ($categories as $i => $category) { $item['menu_'.$i.'_de_la_vente'] = $category['name']; $item['url_menu_'.$i] = _PS_BASE_URL_ . '/' . $category['id_category'] . '-' . $category['link_rewrite']; } return $item; } public function getSales($tomorrowMode = false) { $diff = null; $currentDay = date('N'); if ($currentDay === '5') $diff = '3'; elseif ($currentDay === '6') $diff = '2'; else $diff = '1'; $items = array(); $current = $this->getSalesTomorrow($diff, self::CURRENT); echo 'CURRENT' . PHP_EOL; foreach ($current as $sale) { var_dump($sale->title . ' ' . $sale->id); $items[] = $this->formatSale($sale);; } $tomorrow = $this->getSalesTomorrow($diff, self::TOMORROW); echo 'TOMORROW' . PHP_EOL; foreach ($tomorrow as $sale) { var_dump($sale->title . ' ' . $sale->id); $items[] = $this->formatSale($sale);; } $future = $this->getSalesTomorrow($diff, self::TOMORROW_FUTURE_SALES); echo 'FUTURE' . PHP_EOL; foreach ($future as $sale) { var_dump($sale->title . ' ' . $sale->id); $items[] = $this->formatSale($sale);; } return $items; } public static function getSalesTomorrow($diff, $type = self::CURRENT){ $collection = new Collection('SaleCore', Context::getContext()->language->id); if ($type === self::CURRENT) { $where = ' WHERE `date_start` < "' . (new DateTime())->format('Y-m-d H:i:s') . '" AND `date_end` > "' . (new DateTime())->format('Y-m-d H:i:s') . '" AND `active` = 1'; } elseif ($type === self::TOMORROW) { $where = ' WHERE `date_start` BETWEEN "' . (new DateTime())->format('Y-m-d H:i:s') . '" AND "' . (new DateTime('+' . $diff . ' day'))->format('Y-m-d H:i:s') . '"'; } elseif ($type === self::TOMORROW_FUTURE_SALES) { $where = ' WHERE `date_start` > "' . (new DateTime('+' . $diff . ' day'))->format('Y-m-d H:i:s') . '"'; } $sql = 'SELECT `id_privatesales` FROM `ps_privatesales` ' . $where; $id_sales = array_column(Db::getInstance()->executeS($sql), 'id_privatesales'); $sales = []; foreach ($id_sales as $id_sale) { $sales[] = new SaleCore($id_sale, Context::getContext()->cookie->id_lang); } return $sales; } /****************************************************************************************************************************** * Renvoi la liste des produits en vente aevc les informations suivantes : ******************************************************************************************************************************/ public function getProducts() { $return = array(); $buffer = array(); // pour éviter les doublons avec des produits appartenant à plusieurs ventes // Fetching products ID $context = Context::getContext(); $id_lang = $context->language->id; $products_id = array(); $currentSales = SaleCore::getSales(SaleCore::STATE_CURRENT); foreach ($currentSales as $privatesale) { // On ne veut que les ventes actives (groupe 1 default) if (isset($privatesale->id_groups[0]) && $privatesale->id_groups[0] != 1) { continue; } $sale = new SaleCore($privatesale->id); $products = $sale->getProducts(); foreach ($products as $product) { $products_id[] = $product; } } foreach ($products_id as $product_id) { $product = new Product($product_id, false, $id_lang, null, $context); $default_attribute_id = $this->getDefaultAttributeId($product->id); // On filtre les produits désactivés if (isset($product->active) && $product->active == 0) continue; // On esquive les doublons if (isset($buffer[$product->id]) && $buffer[$product->id] == $product->id) continue; /** Correctif pour aller chercher le prix réel **/ $product->specificPrice = SpecificPrice::getByProductId((int)($product->id)); if ($product->price == 0){ $realprice = Product::getPriceStatic($product->id, true, $default_attribute_id, 2); $product->realprice = $realprice; $product->price_ttc = Product::getPriceStatic($product->id, true, $default_attribute_id, 2, false, false); } else { $realprice = Product::getPriceStatic($product->id, true, null, 2); $product->realprice = $realprice; $product->price_ttc = $product->price * 1.2; } $margin = $product->realprice - (float)$product->wholesale_price; if ($margin < 3) $product->rentability = 5; //PAS RENTABLE elseif ($margin < 7) $product->rentability = 4; //PEU RENTABLE elseif ($margin < 10) $product->rentability = 3; //BREAK EVEN elseif ($margin < 20) $product->rentability = 2; //RENTABLE else $product->rentability = 1; //TRES RENTABLE /** Correctif pour aller chercher la quantité réelle **/ if ( !empty($default_attribute_id) ) { $realquantity = StockAvailable::getQuantityAvailableByProduct($product->id, $default_attribute_id); $product->realquantity = $realquantity; } else { $realquantity = StockAvailable::getQuantityAvailableByProduct($product->id); $product->realquantity = $realquantity; } /** on ajoute des infos sur la cover du produit **/ $images = $product->getImages($id_lang, $context); $id_image = 0; foreach($images as $image) { if (isset($image['cover']) && $image['cover'] == 1) { $id_image = $image['id_image']; break; } } if ($id_image != 0) { $uri_path = _PS_BASE_URL_._THEME_PROD_DIR_.Image::getImgFolderStatic($id_image).$id_image; $product->imgBig = $uri_path.'-large.jpg'; $product->imgMedium = $uri_path.'-medium.jpg'; $product->imgSmall = $uri_path.'-small.jpg'; } else { $id_image = Language::getIsoById($id_lang).'-default'; } /** on ajoute l'url **/ $link = new Link(); $url = $link->getProductLink($product); $url = preg_replace('#privilegedemarque.com\.\/#', 'privilegedemarque.com/', $url); $product->url = $url; // nouveau produit if( !isset($product->condition) || empty($product->condition) || $product->condition != 'new') $product->new = 0; else $product->new = 1; // discount if( !isset($product->quantity_discount) || empty($product->quantity_discount) || $product->quantity_discount <=0 ) $product->discount = 0; else $product->discount = 1; /** on ajoute les infos de la vente privée **/ $sale = SaleCore::getSaleByProductId($product->id); $product->privateSaleInfo = $sale[0]; $product->manufacturer_name = $this->getManufacturerNameById($product->id_manufacturer); $product->delivery_fee = round(Carrier::getCarrierByReference(104)->getDeliveryPriceByWeight($product->weight, 9) * 1.2, 2); $return[] = $product; $buffer[$product->id] = $product->id; } return $return; } /****************************************************************************************************************************** * Création du XML ******************************************************************************************************************************/ public function createSalesXml($items, $rss=false, $debug_mode=false) { $this->_xml = ''; $this->_xml .= ''; $this->_xml .= ''; $this->_xml .= 'http://www.privilegedemarque.com/img/logo.png'; $this->_xml .= 'privilegedemarque.com'; $this->_xml .= ''._PS_BASE_URL_.''; $this->_xml .= ''.count($items).''; $this->_xml .= ''; foreach ($items as $item) { $this->_xml .= ''; foreach ($item as $key => $value) { $this->_xml .= '<' . $key . '>'; $this->_xml .= $value; $this->_xml .= ''; } $this->_xml .= ''; } $this->_xml .= ''; $this->_xml = str_replace('&', 'et', $this->_xml); // $this->_xml = htmlspecialchars($this->_xml); } public function createXml($items, $rss=false, $debug_mode=false) { $this->_xml = ''; // Si on veut générer un flux RSS if( $rss ){ $this->_xml .= ''; $this->_xml .= ' '; $this->_xml .= ' Privilege de marque'; $this->_xml .= ' Catalogue de produits Privilege de marque'; $this->_xml .= ' '._PS_BASE_URL_.''; $this->_xml .= ' '; foreach ($items as $item){ $this->_xml.=''; $this->_xml.= '<![CDATA['.$item->name.']]>'; $this->_xml.= 'description_short.']]>'; $this->_xml.= 'date_add.']]>'; $this->_xml.= 'url.']]>'; $this->_xml.=''; } $this->_xml.=''; } // Si on veut générer le catalogue avec détail en XML else{ $this->_xml .= ''; //Infos boutique $this->_xml .= ''; $this->_xml .= 'http://www.privilegedemarque.com/img/logo.png'; $this->_xml .= ''._PS_BASE_URL_.''; $this->_xml .= ''._PS_BASE_URL_.''; $this->_xml .= ''.count($items).''; $this->_xml .= ''; // Infos Produits foreach ($items as $item){ $this->_xml .= ''; $this->_xml .= ''.$item->id.''; $this->_xml .= 'name.']]>'; $this->_xml .= 'sanitize($item->description).']]>'; $this->_xml .= ''.round($item->realprice,2).''; $this->_xml .= 'formatUrl($item->url, $item->name).']]>'; $this->_xml .= ''.$item->imgMedium.''; $this->_xml .= ''; $this->_xml .= 'category.']]>'; $this->_xml .= ''.$item->id_category_default.''; $this->_xml .= ''; if(isset($item->ean13) && !empty($item->ean_13)) $this->_xml .= ''.$item->ean13.''; // Infos vente privée if( isset($item->privateSaleInfo) && !empty($item->privateSaleInfo) ){ $this->_xml .= ''; $this->_xml .= 'privateSaleInfo->title.']]>'; $this->_xml .= ''.$item->privateSaleInfo->date_end.''; $this->_xml .= 'privateSaleInfo->description.']]>'; $this->_xml .= ''._PS_BASE_URL_.'/modules/privatesales/img/'.(int)$item->privateSaleInfo->id_privatesales.'/current/'.(int)$item->privateSaleInfo->id_privatesales.'_2.jpg'; $this->_xml .= ''._PS_BASE_URL_.'/'.(int)$item->privateSaleInfo->id_category.'-'.Category::getLinkRewrite((int)$item->privateSaleInfo->id_category, 2).''; $this->_xml .= ''; } if(isset($item->brand) && !empty($item->brand)) $this->_xml .= 'brand.']]>'; if(isset($item->price_ttc) && !empty($item->price_ttc)) $this->_xml .= ''.round($item->price_ttc,2).''; if(isset($item->specificPrice[0]) && $item->specificPrice[0]['reduction'] > 0){ $this->_xml .= ''; if( $item->specificPrice[0]['reduction_type'] == 'percentage' ){ $this->_xml .= ''.round(($item->specificPrice[0]['reduction']*100),2).''; $this->_xml .= '%'; } else { $this->_xml .= ''.round($item->specificPrice[0]['reduction'],2).''; $this->_xml .= ''; } $this->_xml .= ''; } if(isset($item->description_short) && !empty($item->description_short)) $this->_xml .= 'description_short.']]>'; $this->_xml .= ''.$item->delivery_fee.''; if(isset($item->additional_shipping_cost) && !empty($item->additional_shipping_cost)) $this->_xml .= ''.$item->additional_shipping_cost.''; if(isset($item->realquantity)){ if((int)$item->realquantity > 0) { $this->_xml .= 'Oui'; $this->_xml .= ''.(int)$item->realquantity.''; } else { $this->_xml .= 'Non'; } } $this->_xml.=''; } $this->_xml .= ''; } } /****************************************************************************************************************************** * Renvoi l'id attribute default d'un produit ******************************************************************************************************************************/ public function getDefaultAttributeId($product_id) { $sql = 'SELECT p.`cache_default_attribute` FROM `'._DB_PREFIX_.'product` p WHERE p.`id_product` ='.$product_id; $result = Db::getInstance()->executeS($sql); return $result[0]['cache_default_attribute']; } /****************************************************************************************************************************** * Retire les caractères MAC ******************************************************************************************************************************/ public function sanitize($str) { $str = preg_replace_callback('#[\\xA1-\\xFF](?![\\x80-\\xBF]{2,})#', function ($matches){return utf8_encode($matches[0]);}, $str ); return htmlentities(str_replace('', '', $str)); } /****************************************************************************************************************************** * Enlève les tags des URLs pour le catalogue CRITEO ******************************************************************************************************************************/ public function formatUrl($url, $name = NULL) { if (array_key_exists($this->_type, $this->tags)) { $tags = $this->tags[$this->_type]; $url .= '?'.$tags['utm']; } return $url; } /****************************************************************************************************************************** * Récupère le nom d'un fabricant (sans tenir compte de la row is_active) ******************************************************************************************************************************/ public function getManufacturerNameById($m_id) { return Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue(' SELECT `name` FROM `'._DB_PREFIX_.'manufacturer` WHERE `id_manufacturer` = '.(int)$m_id.' '); } }