privilegedemarque/modules/fluxcatalog/models/Flux.php

490 lines
23 KiB
PHP
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
// Config
if (!defined('_PS_VERSION_'))
exit;
class FluxCatalog
{
const TOMORROW = 1;
const CURRENT = 0;
const TOMORROW_FUTURE_SALES = 2;
private $_xml = null;
private $_filename = null;
private $_type = null; // type de catalogue généré (default, veoxa, criteo, idealo)
public $domain;
public $id_lang;
public $currentTime;
public $context;
public $url_additionnal_parameters = '';
public function __construct()
{
$this->domain = Configuration::get('PS_SHOP_DOMAIN');
$this->url_additionnal_parameters = str_replace('&', '&amp;', Configuration::get('FLUXCATALOG_TRACKING'));
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'.$this->url_additionnal_parameters;
}
$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'.$this->url_additionnal_parameters;
$item['url_de_la_vente'] = _PS_BASE_URL_.'/'.$sale->id_category.'-'.$sale->link_rewrite.$this->url_additionnal_parameters;
$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'].$this->url_additionnal_parameters;
}
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 = '<?xml version="1.0" encoding="UTF-8" ?>';
$this->_xml .= '<catalogue>';
$this->_xml .= '<infos_boutique>';
$this->_xml .= '<logo>http://www.privilegedemarque.com/img/logo.png'.$this->url_additionnal_parameters.'</logo>';
$this->_xml .= '<nom>privilegedemarque.com</nom>';
$this->_xml .= '<url>'._PS_BASE_URL_.$this->url_additionnal_parameters.'</url>';
$this->_xml .= '<nb_items>'.count($items).'</nb_items>';
$this->_xml .= '</infos_boutique>';
foreach ($items as $item) {
$this->_xml .= '<vente>';
foreach ($item as $key => $value) {
$this->_xml .= '<' . $key . '>';
$this->_xml .= $value;
$this->_xml .= '</' . $key . '>';
}
$this->_xml .= '</vente>';
}
$this->_xml .= '</catalogue>';
$this->_xml = str_replace('&amp;', '__et__', $this->_xml);
$this->_xml = str_replace('&', 'et', $this->_xml);
$this->_xml = str_replace('__et__', '&amp;', $this->_xml);
// $this->_xml = htmlspecialchars($this->_xml);
}
public function createXml($items, $rss=false, $debug_mode=false)
{
$this->_xml = '<?xml version="1.0" encoding="UTF-8" ?>';
// Si on veut générer un flux RSS
if( $rss ){
$this->_xml .= '<rss version="2.0">';
$this->_xml .= ' <channel>';
$this->_xml .= ' <title>Privilege de marque</title>';
$this->_xml .= ' <description>Catalogue de produits Privilege de marque</description>';
$this->_xml .= ' <link>'._PS_BASE_URL_.'</link>';
$this->_xml .= ' </channel>';
foreach ($items as $item){
$this->_xml.='<item>';
$this->_xml.= '<title><![CDATA['.$item->name.']]></title>';
$this->_xml.= '<description><![CDATA['.$item->description_short.']]></description>';
$this->_xml.= '<pubDate><![CDATA['.$item->date_add.']]></pubDate>';
$this->_xml.= '<link><![CDATA['.$item->url.']]></link>';
$this->_xml.='</item>';
}
$this->_xml.='</rss>';
}
// Si on veut générer le catalogue avec détail en XML
else{
$this->_xml .= '<catalogue>';
//Infos boutique
$this->_xml .= '<infos_boutique>';
$this->_xml .= '<logo>http://www.privilegedemarque.com/img/logo.png'.$this->url_additionnal_parameters.'</logo>';
$this->_xml .= '<nom>'._PS_BASE_URL_.'</nom>';
$this->_xml .= '<url>'._PS_BASE_URL_.$this->url_additionnal_parameters.'</url>';
$this->_xml .= '<nb_items>'.count($items).'</nb_items>';
$this->_xml .= '</infos_boutique>';
// Infos Produits
foreach ($items as $item){
$this->_xml .= '<produit>';
$this->_xml .= '<id_produit>'.$item->id.'</id_produit>';
$this->_xml .= '<nom_produit><![CDATA['.$item->name.']]></nom_produit>';
$this->_xml .= '<description><![CDATA['.$this->sanitize($item->description).']]></description>';
$this->_xml .= '<prix>'.round($item->realprice,2).'</prix>';
$this->_xml .= '<url_produit><![CDATA['.$this->formatUrl($item->url, $item->name).$this->url_additionnal_parameters.']]></url_produit>';
$this->_xml .= '<url_img>'.$item->imgMedium.$this->url_additionnal_parameters.'</url_img>';
$this->_xml .= '<categorie>';
$this->_xml .= '<nom_categorie><![CDATA['.$item->category.']]></nom_categorie>';
$this->_xml .= '<id_categorie>'.$item->id_category_default.'</id_categorie>';
$this->_xml .= '</categorie>';
if(isset($item->ean13) && !empty($item->ean_13))
$this->_xml .= '<code_ean>'.$item->ean13.'</code_ean>';
// Infos vente privée
if( isset($item->privateSaleInfo) && !empty($item->privateSaleInfo) ){
$this->_xml .= '<vente>';
$this->_xml .= '<nom><![CDATA['.$item->privateSaleInfo->title.']]></nom>';
$this->_xml .= '<date_fin>'.$item->privateSaleInfo->date_end.'</date_fin>';
$this->_xml .= '<description><![CDATA['.$item->privateSaleInfo->description.']]></description>';
$this->_xml .= '<image>'._PS_BASE_URL_.'/modules/privatesales/img/'.(int)$item->privateSaleInfo->id_privatesales.'/current/'.(int)$item->privateSaleInfo->id_privatesales.'_2.jpg</image>';
$this->_xml .= '<url>'._PS_BASE_URL_.'/'.(int)$item->privateSaleInfo->id_category.'-'.Category::getLinkRewrite((int)$item->privateSaleInfo->id_category, 2).$this->url_additionnal_parameters.'</url>';
$this->_xml .= '</vente>';
}
if(isset($item->brand) && !empty($item->brand))
$this->_xml .= '<marque><![CDATA['.$item->brand.']]></marque>';
if(isset($item->price_ttc) && !empty($item->price_ttc))
$this->_xml .= '<prix_barre>'.round($item->price_ttc,2).'</prix_barre>';
if(isset($item->specificPrice[0]) && $item->specificPrice[0]['reduction'] > 0){
$this->_xml .= '<remise>';
if( $item->specificPrice[0]['reduction_type'] == 'percentage' ){
$this->_xml .= '<valeur>'.round(($item->specificPrice[0]['reduction']*100),2).'</valeur>';
$this->_xml .= '<devise>%</devise>';
} else {
$this->_xml .= '<valeur>'.round($item->specificPrice[0]['reduction'],2).'</valeur>';
$this->_xml .= '<devise>€</devise>';
}
$this->_xml .= '</remise>';
}
if(isset($item->description_short) && !empty($item->description_short))
$this->_xml .= '<description_courte><![CDATA['.$item->description_short.']]></description_courte>';
$this->_xml .= '<frais_livraison>'.$item->delivery_fee.'</frais_livraison>';
if(isset($item->additional_shipping_cost) && !empty($item->additional_shipping_cost))
$this->_xml .= '<frais_livraison_supp>'.$item->additional_shipping_cost.'</frais_livraison_supp>';
if(isset($item->realquantity)){
if((int)$item->realquantity > 0) {
$this->_xml .= '<disponible>Oui</disponible>';
$this->_xml .= '<stock>'.(int)$item->realquantity.'</stock>';
} else {
$this->_xml .= '<disponible>Non</disponible>';
}
}
$this->_xml.='</produit>';
}
$this->_xml .= '</catalogue>';
}
}
/******************************************************************************************************************************
* 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.'
');
}
}