name = 'googlesitemap'; $this->tab = 'seo'; $this->version = '1.2'; $this->author = 'Antadis'; $this->need_instance = 0; parent::__construct(); $this->displayName = $this->l('Google sitemap with private sales support'); $this->description = $this->l('Generate your Google sitemap file'); if(!defined('GSITEMAP_FILE')) { define('GSITEMAP_FILE', dirname(__FILE__).'/../../sitemap.xml'); } } public function install() { if(!parent::install()) { return FALSE; } if(Module::isInstalled('privatesales')) { Db::getInstance()->Execute(' INSERT INTO `'._DB_PREFIX_.'privatesale_module` VALUES ( (SELECT `id_module` FROM `'._DB_PREFIX_.'module` WHERE `name` = "googlesitemap"), "googlesitemap" ) '); } return TRUE; } public function uninstall() { file_put_contents(GSITEMAP_FILE, ''); if(Module::isInstalled('privatesales')) { Db::getInstance()->Execute('DELETE FROM `'._DB_PREFIX_.'privatesale_module` WHERE `modulename` = "googlesitemap"'); } return parent::uninstall(); } private function _postValidation() { file_put_contents(GSITEMAP_FILE, ''); if(!($fp = fopen(GSITEMAP_FILE, 'w'))) { $this->_postErrors[] = $this->l('Cannot create').' '.realpath(dirname(__FILE__.'/../..')).'/'.$this->l('sitemap.xml file.'); } else { fclose($fp); } } public function generateSitemap() { global $cookie; $link = new Link(); $langs = Language::getLanguages(); $iso_code = Language::getIsoById((int) $cookie->id_lang); $xmlString = << XML; $xml = new SimpleXMLElement($xmlString); if(Configuration::get('PS_REWRITING_SETTINGS') && sizeof($langs) > 1) { foreach($langs as $lang) { $this->_addSitemapNode($xml, Tools::getShopDomain(true, true).__PS_BASE_URI__.$lang['iso_code'].'/', '1.00', 'daily', date('Y-m-d')); } } else { $this->_addSitemapNode($xml, Tools::getShopDomain(true, true).__PS_BASE_URI__, '1.00', 'daily', date('Y-m-d')); } /* CMS Generator */ if(Configuration::get('GSITEMAP_ALL_CMS') || !Module::isInstalled('blockcms')) { $sql_cms = ' SELECT DISTINCT '.(Configuration::get('PS_REWRITING_SETTINGS')? 'cl.id_cms, cl.link_rewrite, cl.id_lang': 'cl.id_cms').' FROM `'._DB_PREFIX_.'cms_lang` cl LEFT JOIN `'._DB_PREFIX_.'lang` l ON (cl.id_lang = l.id_lang) WHERE l.`active` = 1 ORDER BY cl.id_cms, cl.id_lang ASC '; } elseif (Module::isInstalled('blockcms')) { $sql_cms = ' SELECT DISTINCT '.(Configuration::get('PS_REWRITING_SETTINGS')? 'cl.id_cms, cl.link_rewrite, cl.id_lang': 'cl.id_cms').' FROM `'._DB_PREFIX_.'cms_block_page` b LEFT JOIN `'._DB_PREFIX_.'cms_lang` cl ON (b.id_cms = cl.id_cms) LEFT JOIN '._DB_PREFIX_.'lang l ON (cl.id_lang = l.id_lang) WHERE l.`active` = 1 ORDER BY cl.id_cms, cl.id_lang ASC '; } $cmss = Db::getInstance(_PS_USE_SQL_SLAVE_)->ExecuteS($sql_cms); foreach($cmss as $cms) { $tmpLink = Configuration::get('PS_REWRITING_SETTINGS')? $link->getCMSLink((int)$cms['id_cms'], $cms['link_rewrite'], FALSE, (int) $cms['id_lang']): $link->getCMSLink((int)$cms['id_cms']); $this->_addSitemapNode($xml, $tmpLink, '0.8', 'daily'); } /* Categories Generator */ $exclude_categories = array(); if(Module::isInstalled('privatesales')) { include(dirname(__FILE__).'/../privatesales/Sale.php'); $has_trailers = file_exists(dirname(__FILE__).'/../privatesales/trailer.php'); $sales = Sale::getSales(TRUE, NULL, NULL, 'not_ended'); foreach($sales as $sale) { $exclude_categories = array_merge($exclude_categories, Sale::getCategoriesFromCache($sale->id)); if($has_trailers) { $trailers_i18n = array( 'fr' => 'bande-annonce', 'en' => 'trailer', ); if(Configuration::get('PS_REWRITING_SETTINGS')) { if(count($langs) > 1) { $this->_addSitemapNode($xml, Tools::getShopDomain(TRUE, TRUE).__PS_BASE_URI__.$iso_code.'/'.(isset($trailers_i18n[$iso_code])? $trailers_i18n[$iso_code]: $trailers_i18n['en']).'/'.$sale->id.'-'.Tools::str2url($sale->title[$cookie->id_lang]), '0.8', 'weekly'); } else { $this->_addSitemapNode($xml, Tools::getShopDomain(TRUE, TRUE).__PS_BASE_URI__.(isset($trailers_i18n[$iso_code])? $trailers_i18n[$iso_code]: $trailers_i18n['en']).'/'.$sale->id.'-'.Tools::str2url($sale->title[$cookie->id_lang]), '0.8', 'weekly'); } } else { $this->_addSitemapNode($xml, Tools::getShopDomain(TRUE, TRUE).__PS_BASE_URI__.'modules/privatesales/trailer.php?id_sale='.$sale->id, '0.8', 'weekly'); } } } $ordering = (int) Configuration::get('PRIVATESALES_FEATURED_ORDER'); if($ordering == 0) { if(Module::isInstalled('privatesales_brands')) { $sales = Sale::getSales(TRUE, (int) Configuration::get('PRIVATESALES_FEATURED_IGNORE') == 1? NULL: !((bool) Configuration::get('PRIVATESALES_GUESTLIST')), TRUE, (bool) Configuration::get('PRIVATESALES_FEATURED_CURRENT'), TRUE); $brands = array(); foreach(Db::getInstance()->ExecuteS(' SELECT `id_brand` FROM `'._DB_PREFIX_.'privatesale_brands` WHERE `id_sale` IN ('.implode(', ', $sales).') GROUP BY `id_brand` ') as $b) { $brands[] = $b['id_brand']; } $manufacturers = Db::getInstance()->ExecuteS(' SELECT m.*, ml.`short_description` FROM `'._DB_PREFIX_.'manufacturer` m LEFT JOIN `'._DB_PREFIX_.'manufacturer_lang` ml ON ( m.`id_manufacturer` = ml.`id_manufacturer` AND ml.`id_lang` = '.(int) $cookie->id_lang.' ) WHERE m.`active` = 1 AND m.`id_manufacturer` IN ('.implode(', ', $brands).') ORDER BY m.`name` ASC '); } else { $manufacturers = Manufacturer::getManufacturers(TRUE, (int) $cookie->id_lang, TRUE, FALSE, FALSE, TRUE); } $brands_i18n = array( 'fr' => 'marques', 'en' => 'brands', ); foreach($manufacturers as $manufacturer) { if(Configuration::get('PS_REWRITING_SETTINGS')) { if(count($langs) > 1) { $this->_addSitemapNode($xml, Tools::getShopDomain(true, true).__PS_BASE_URI__.$iso_code.'/'.(isset($brands_i18n[$iso_code])? $brands_i18n[$iso_code]: $brands_i18n['en']).'/'.$manufacturer['id_manufacturer'].'-'.Tools::str2url($manufacturer['name']), '0.8', 'weekly'); } else { $this->_addSitemapNode($xml, Tools::getShopDomain(true, true).__PS_BASE_URI__.(isset($brands_i18n[$iso_code])? $brands_i18n[$iso_code]: $brands_i18n['en']).'/'.$manufacturer['id_manufacturer'].'-'.Tools::str2url($manufacturer['name']), '0.8', 'weekly'); } } else { $this->_addSitemapNode($xml, Tools::getShopDomain(true, true).__PS_BASE_URI__.'modules/privatesales/featured.php?id_brand='.$manufacturer['id_manufacturer'], '0.8', 'weekly'); } } } } if(Configuration::get('PS_REWRITING_SETTINGS')) { $categories = Db::getInstance()->ExecuteS(' SELECT c.id_category, c.level_depth, link_rewrite, DATE_FORMAT(IF(date_upd,date_upd,date_add), \'%Y-%m-%d\') AS date_upd, cl.id_lang FROM '._DB_PREFIX_.'category c LEFT JOIN '._DB_PREFIX_.'category_lang cl ON c.id_category = cl.id_category LEFT JOIN '._DB_PREFIX_.'lang l ON cl.id_lang = l.id_lang WHERE l.`active` = 1 AND c.`active` = 1 AND c.id_category != 1 '.(count($exclude_categories) > 0? ' AND c.id_category NOT IN ('.implode(', ', $exclude_categories).')': '').' ORDER BY cl.id_category, cl.id_lang ASC '); } else { $categories = Db::getInstance()->ExecuteS(' SELECT c.id_category, c.level_depth, DATE_FORMAT(IF(date_upd,date_upd,date_add), \'%Y-%m-%d\') AS date_upd FROM '._DB_PREFIX_.'category c '.(count($exclude_categories) > 0? ' AND c.id_category NOT IN ('.implode(', ', $exclude_categories).')': '').' ORDER BY c.id_category ASC '); } foreach($categories as $category) { if(($priority = 0.9 - ($category['level_depth'] / 10)) < 0.1) { $priority = 0.1; } $tmpLink = Configuration::get('PS_REWRITING_SETTINGS')? $link->getCategoryLink((int)$category['id_category'], $category['link_rewrite'], (int)$category['id_lang']): $link->getCategoryLink((int)$category['id_category']); $this->_addSitemapNode($xml, htmlspecialchars($tmpLink), $priority, 'weekly', substr($category['date_upd'], 0, 10)); } $products = Db::getInstance(_PS_USE_SQL_SLAVE_)->ExecuteS(' SELECT p.id_product, pl.link_rewrite, DATE_FORMAT(IF(date_upd,date_upd,date_add), \'%Y-%m-%d\') date_upd, pl.id_lang, cl.`link_rewrite` category, ean13, i.id_image, il.legend legend_image, ( SELECT MIN(level_depth) FROM '._DB_PREFIX_.'product p2 LEFT JOIN '._DB_PREFIX_.'category_product cp2 ON p2.id_product = cp2.id_product LEFT JOIN '._DB_PREFIX_.'category c2 ON cp2.id_category = c2.id_category WHERE p2.id_product = p.id_product AND p2.`active` = 1 AND c2.`active` = 1 ) AS level_depth FROM '._DB_PREFIX_.'product p LEFT JOIN '._DB_PREFIX_.'product_lang pl ON (p.id_product = pl.id_product) LEFT JOIN `'._DB_PREFIX_.'category_lang` cl ON (p.`id_category_default` = cl.`id_category` AND pl.`id_lang` = cl.`id_lang`) LEFT JOIN '._DB_PREFIX_.'image i ON p.id_product = i.id_product LEFT JOIN `'._DB_PREFIX_.'image_lang` il ON (i.`id_image` = il.`id_image` AND pl.`id_lang` = il.`id_lang`) LEFT JOIN '._DB_PREFIX_.'lang l ON (pl.id_lang = l.id_lang) WHERE l.`active` = 1 AND p.`active` = 1 '.(count($exclude_categories) > 0? ' AND p.id_category_default NOT IN ('.implode(', ', $exclude_categories).')': '').' '.(Configuration::get('GSITEMAP_ALL_PRODUCTS') ? '' : 'HAVING level_depth IS NOT NULL').' ORDER BY pl.id_product, pl.id_lang ASC '); $tmp = NULL; $res = NULL; foreach($products as $product) { if($tmp == $product['id_product']) { $res[$tmp]['images'][] = array('id_image' => $product['id_image'], 'legend_image' => $product['legend_image']); } else { $tmp = $product['id_product']; $res[$tmp] = $product; unset($res[$tmp]['id_image'], $res[$tmp]['legend_image']); $res[$tmp]['images'][] = array('id_image' => $product['id_image'], 'legend_image' => $product['legend_image']); } } foreach($res as $product) { if(($priority = 0.7 - ($product['level_depth'] / 10)) < 0.1) { $priority = 0.1; } $tmpLink = $link->getProductLink((int) $product['id_product'], $product['link_rewrite'], $product['category'], $product['ean13'], (int) $product['id_lang']); $sitemap = $this->_addSitemapNode($xml, htmlspecialchars($tmpLink), $priority, 'weekly', substr($product['date_upd'], 0, 10)); $sitemap = $this->_addSitemapNodeImage($sitemap, $product); } /* Add classic pages (contact, best sales, new products...) */ $pages = array( 'authentication' => TRUE, 'best-sales' => FALSE, 'contact-form' => TRUE, 'discount' => FALSE, 'index' => FALSE, 'manufacturer' => FALSE, 'new-products' => FALSE, 'prices-drop' => FALSE, 'supplier' => FALSE, 'store' => FALSE, ); // Don't show suppliers and manufacturers if they are disallowed if(!Module::getInstanceByName('blockmanufacturer')->id && !Configuration::get('PS_DISPLAY_SUPPLIERS')) { unset($pages['manufacturer']); } if(!Module::getInstanceByName('blocksupplier')->id && !Configuration::get('PS_DISPLAY_SUPPLIERS')) { unset($pages['supplier']); } // Generate nodes for pages if(Configuration::get('PS_REWRITING_SETTINGS')) { foreach($pages as $page => $ssl) { foreach($langs as $lang) { $this->_addSitemapNode($xml, $link->getPageLink($page.'.php', $ssl, $lang['id_lang']), '0.5', 'monthly'); } } } else { foreach($pages as $page => $ssl) { $this->_addSitemapNode($xml, $link->getPageLink($page.'.php', $ssl), '0.5', 'monthly'); } } $xmlString = $xml->asXML(); $fp = fopen(GSITEMAP_FILE, 'w'); fwrite($fp, $xmlString); fclose($fp); } private function _postProcess() { Configuration::updateValue('GSITEMAP_ALL_CMS', (int) Tools::getValue('GSITEMAP_ALL_CMS')); Configuration::updateValue('GSITEMAP_ALL_PRODUCTS', (int) Tools::getValue('GSITEMAP_ALL_PRODUCTS')); $this->generateSitemap(); $res = file_exists(GSITEMAP_FILE); $this->_html .= '

'; $this->_html .= $res? $this->l('Sitemap file generated'): $this->l('Error while creating sitemap file'); $this->_html .= '

'; } private function getUrlWith($url, $key, $value) { if(empty($value)) { return $url; } if(strpos($url, '?') !== FALSE) { return $url.'&'.$key.'='.$value; } return $url.'?'.$key.'='.$value; } private function _addSitemapNode($xml, $loc, $priority, $change_freq, $last_mod=NULL) { $sitemap = $xml->addChild('url'); $sitemap->addChild('loc', $loc); $sitemap->addChild('priority', $priority); if($last_mod) { $sitemap->addChild('lastmod', $last_mod); } $sitemap->addChild('changefreq', $change_freq); return $sitemap; } private function _addSitemapNodeImage($xml, $product) { foreach($product['images'] as $img) { $link = new Link(); $image = $xml->addChild('image', NULL, 'http://www.google.com/schemas/sitemap-image/1.1'); $image->addChild('loc', $link->getImageLink($product['link_rewrite'], (int) $product['id_product'].'-'.(int) $img['id_image']), 'http://www.google.com/schemas/sitemap-image/1.1'); $legend_image = preg_replace('/(&+)/i', '&', $img['legend_image']); $image->addChild('caption', $legend_image, 'http://www.google.com/schemas/sitemap-image/1.1'); $image->addChild('title', $legend_image, 'http://www.google.com/schemas/sitemap-image/1.1'); } } private function _displaySitemap() { if(file_exists(GSITEMAP_FILE) && filesize(GSITEMAP_FILE)) { $fp = fopen(GSITEMAP_FILE, 'r'); $fstat = fstat($fp); fclose($fp); $xml = simplexml_load_file(GSITEMAP_FILE); $nbPages = sizeof($xml->url); $this->_html .= '

'.$this->l('Your Google sitemap file is online at the following address:').'
'.Tools::getShopDomain(true, true).__PS_BASE_URI__.'sitemap.xml


'; $this->_html .= $this->l('Update:').' '.utf8_encode(strftime('%A %d %B %Y %H:%M:%S', $fstat['mtime'])).'
'; $this->_html .= $this->l('Filesize:').' '.number_format(($fstat['size']*.000001), 3).'MB
'; $this->_html .= $this->l('Indexed pages:').' '.$nbPages.'

'; } } private function _displayForm() { $this->_html .= '
'; } public function getContent() { $this->_html .= '

'.$this->l('Search Engine Optimization').'

'.$this->l('See').' '.$this->l('this page').' '.$this->l('for more information').'

'; if(Tools::isSubmit('btnSubmit')) { $this->_postValidation(); if (!sizeof($this->_postErrors)) { $this->_postProcess(); } else { foreach ($this->_postErrors as $err) { $this->_html .= '
'.$err.'
'; } } } $this->_displaySitemap(); $this->_displayForm(); return $this->_html; } }