XML;
$xml = new SimpleXMLElement($xmlString);
if (Configuration::get('PS_REWRITING_SETTINGS') && count($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'));
/* Product Generator */
$sql = 'SELECT p.id_product, pl.link_rewrite, DATE_FORMAT(IF(ps.date_upd,ps.date_upd,ps.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
'.Shop::addSqlAssociation('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 product_shop.`active` = 1 AND c2.`active` = 1) AS level_depth
FROM '._DB_PREFIX_.'product p
LEFT JOIN '._DB_PREFIX_.'product_shop ps ON (ps.id_product = p.id_product AND ps.id_shop = '.(int)$id_shop.')
LEFT JOIN '._DB_PREFIX_.'product_lang pl ON (p.id_product = pl.id_product)
LEFT JOIN '._DB_PREFIX_.'category_lang cl ON (ps.id_category_default = cl.id_category AND pl.id_lang = cl.id_lang AND cl.id_shop = '.(int)$id_shop.')
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)
LEFT JOIN '._DB_PREFIX_.'lang l ON (pl.id_lang = l.id_lang)
WHERE l.`active` = 1
AND ps.`active` = 1
AND ps.id_shop = '.(int)$id_shop.'
'.(Configuration::get('GSITEMAP_ALL_PRODUCTS') ? '' : 'HAVING level_depth IS NOT NULL').'
ORDER BY pl.id_product, pl.id_lang ASC';
$resource = Db::getInstance(_PS_USE_SQL_SLAVE_)->query($sql);
// array used to know which product/image was already added (blacklist)
$done = null;
$sitemap = null;
// iterates on the products, to gather the image ids
while ($product = Db::getInstance()->nextRow($resource))
{
// if the product has not been added
$id_product = $product['id_product'];
if (!isset($done[$id_product]['added']))
{
// priority
if (($priority = 0.7 - ($product['level_depth'] / 10)) < 0.1)
$priority = 0.1;
// adds the product
$tmpLink = $this->context->link->getProductLink((int)($product['id_product']), $product['link_rewrite'], $product['category'], $product['ean13'], (int)($product['id_lang']));
$sitemap = $this->_addSitemapNode($xml, $tmpLink, $priority, 'weekly', substr($product['date_upd'], 0, 10));
// considers the product has added
$done[$id_product]['added'] = true;
}
// if the image has not been added
$id_image = $product['id_image'];
if (!isset($done[$id_product][$id_image]) && $id_image)
{
// adds the image
$this->_addSitemapNodeImage($sitemap, $product);
// considers the image as added
$done[$id_product][$id_image] = true;
}
}
/* Categories Generator */
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
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
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') ?
$this->context->link->getCategoryLink((int)$category['id_category'], $category['link_rewrite'], (int)$category['id_lang'])
: $this->context->link->getCategoryLink((int)$category['id_category']);
$this->_addSitemapNode($xml, htmlspecialchars($tmpLink), $priority, 'weekly', substr($category['date_upd'], 0, 10));
}
/* 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';
else if (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') ?
$this->context->link->getCMSLink((int)$cms['id_cms'], $cms['link_rewrite'], false, (int)$cms['id_lang'])
: $this->context->link->getCMSLink((int)$cms['id_cms']);
$this->_addSitemapNode($xml, $tmpLink, '0.8', 'daily');
}
/* Add classic pages (contact, best sales, new products...) */
$pages = array(
'supplier' => false,
'manufacturer' => false,
'new-products' => false,
'prices-drop' => false,
'stores' => false,
'authentication' => true,
'best-sales' => false,
'contact-form' => true);
// 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, $this->context->link->getPageLink($page, $ssl, $lang['id_lang']), '0.5', 'monthly');
else
foreach($pages as $page => $ssl)
$this->_addSitemapNode($xml, $this->context->link->getPageLink($page, $ssl), '0.5', 'monthly');
$xml_string = $xml->asXML();
// Replace URL in XML strings by real shops URL
if ($replace_url)
$xml_string = str_replace(array(Tools::getShopDomain(true).__PS_BASE_URI__, Tools::getShopDomainSsl(true).__PS_BASE_URI__), $replace_url, $xml_string);
$fp = fopen($filename, 'w');
fwrite($fp, $xml_string);
fclose($fp);
return file_exists($filename);
}
private function _addSitemapIndexNode($xml, $loc, $last_mod)
{
$sitemap = $xml->addChild('sitemap');
$sitemap->addChild('loc', htmlspecialchars($loc));
$sitemap->addChild('lastmod', $last_mod);
return $sitemap;
}
private function _addSitemapNode($xml, $loc, $priority, $change_freq, $last_mod = NULL)
{
$sitemap = $xml->addChild('url');
$sitemap->addChild('loc', htmlspecialchars($loc));
$sitemap->addChild('priority', number_format($priority,1,'.',''));
if ($last_mod)
$sitemap->addChild('lastmod', $last_mod);
$sitemap->addChild('changefreq', $change_freq);
return $sitemap;
}
private function _addSitemapNodeImage($xml, $product)
{
$image = $xml->addChild('image', null, 'http://www.google.com/schemas/sitemap-image/1.1');
$image->addChild('loc', htmlspecialchars($this->context->link->getImageLink($product['link_rewrite'], (int)$product['id_product'].'-'.(int)$product['id_image'])), 'http://www.google.com/schemas/sitemap-image/1.1');
$legend_image = preg_replace('/(&+)/i', '&', $product['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 (Shop::isFeatureActive())
{
$sql = 'SELECT s.id_shop, su.domain, su.domain_ssl, CONCAT(su.physical_uri, su.virtual_uri) as uri
FROM '._DB_PREFIX_.'shop s
INNER JOIN '._DB_PREFIX_.'shop_url su ON s.id_shop = su.id_shop AND su.main = 1
WHERE s.active = 1
AND s.deleted = 0
AND su.active = 1';
if (!$result = Db::getInstance()->executeS($sql))
return '';
$this->_html .= ''.$this->l('Sitemap index').' ';
$this->_html .= ''.$this->l('Your Google sitemap file is online at the following address:').'
'.Tools::getShopDomain(true, true).__PS_BASE_URI__.'sitemap.xml
';
$info = pathinfo(GSITEMAP_FILE);
foreach ($result as $shop)
{
$filename = $info['dirname'].'/'.$info['filename'].'-'.$shop['id_shop'].'.'.$info['extension'];
if (file_exists($filename) && filesize($filename))
{
$fp = fopen($filename, 'r');
$fstat = fstat($fp);
fclose($fp);
$xml = simplexml_load_file($filename);
$nbPages = count($xml->url);
$sitemap_uri = 'http://'.$shop['domain'].$shop['uri'].$info['filename'].'-'.$shop['id_shop'].'.'.$info['extension'];
$this->_html .= ''.$this->l('Sitemap for: ').$shop['domain'].$shop['uri'].' ';
$this->_html .= ''.$this->l('Your Google sitemap file is online at the following address:').'
'.$sitemap_uri.'
';
$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.' ';
}
}
}
elseif (file_exists(GSITEMAP_FILE) && filesize(GSITEMAP_FILE))
{
$fp = fopen(GSITEMAP_FILE, 'r');
$fstat = fstat($fp);
fclose($fp);
$xml = simplexml_load_file(GSITEMAP_FILE);
$nbPages = count($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()
{
if (Tools::usingSecureMode())
$domain = Tools::getShopDomainSsl(true);
else
$domain = Tools::getShopDomain(true);
$this->_html .= '
'.$this->l('Use cron job to re-build the sitemap:').'
'.$domain.__PS_BASE_URI__.'modules/gsitemap/gsitemap-cron.php?&token='.substr(Tools::encrypt('gsitemap/cron'),0,10).'&GSITEMAP_ALL_CMS='.((int)Configuration::get('GSITEMAP_ALL_CMS')).'&GSITEMAP_ALL_PRODUCTS='.((int)Configuration::get('GSITEMAP_ALL_PRODUCTS')).'
';
}
public function getContent()
{
if (Tools::isSubmit('btnSubmit'))
{
$this->_postValidation();
if (!count($this->_postErrors))
$this->_postProcess();
else
foreach ($this->_postErrors as $err)
$this->_html .= ''.$err.'
';
}
$this->_html .= '
'.$this->l('Search Engine Optimization').'
'.$this->l('See').'
'.$this->l('this page').' '.$this->l('for more information').'
';
$this->_displaySitemap();
$this->_displayForm();
$this->_html .= ' ';
return $this->_html;
}
}