<?php if (!defined('HTTP_SERVER')) die('You can not access this file directly!');
/**
  @licence GPL 2005-2010  The osCSS developers - osCSS Open Source E-commerce
  @portion code Copyright (c) 2002 osCommerce
  @package osCSS-2 <www http://www.oscss.org>
  @version 2.1.0
  @date  02/10/10, 10:32
  @author oscim <mail aurelien@oscim.fr> <www http://www.oscim.fr>
  @encode UTF-8
  @class ggsitemap
*/

class ggsitemap
  implements ExtModPage, InterfaceModule {

  const FILENAME=FILENAME_GOOGLE_SITEMAP;

  public static $code;

  public static $action;

  public static $list=array();

  /**
    class constructor
  */
  public function __construct() {
    self::$code=__CLASS__;

  }

  public function check_action($actions){
    global $messageStack;
    self::$action=$actions;
    return self::$action;
  }

  public function get_header(){
  }


  public static function load_db_values($ID){
  }

  public function display_view(){
    if(self::$action=='construct'){
      self::cstr_sitemap();
      return tep_get_include_contents(self::$code.'.construct');
    }
    else return tep_get_include_contents(self::$code.'.page');
  }



/** Public Specific module */
  public static function cstr_sitemap(){
    global $languages_id;

    define('GOOGLE_SITEMAP_COMPRESS', 'false' );
    define('GOOGLE_SITEMAP_PROD_CHANGE_FREQ', 'weekly' );
    define('GOOGLE_SITEMAP_CAT_CHANGE_FREQ', 'weekly' );


    if ( (_cst_bool('SEO_ENABLED')) ) {
      $seo_urls = seo_url::getInstance($languages_id);

      if ( file_exists('includes/seo_cache.php') ) include('includes/seo_cache.php' );
    }

    $google = new GoogleSitemap(DB_SERVER, DB_SERVER_USERNAME, DB_DATABASE, DB_SERVER_PASSWORD);
    $submit = true;

    if ($google->GenerateProductSitemap()){
      self::$list[]= __('google sitemaps product success');
    } else {
      $submit = false;
      self::$list[]= __('google sitemaps product error');
    }



    if ($google->GenerateCategorySitemap()){
      self::$list[]= __('google sitemaps category success');
    } else {
      $submit = false;
      self::$list[]= __('google sitemaps category error');
    }



    if ($google->GenerateSitemapIndex()){
      self::$list[]= __('google sitemaps index success');
    } else {
      $submit = false;
      self::$list[]= __('google sitemaps index error');
    }



    if ($submit){
      self::$list[]= __('google sitemaps congratulation');
      self::$list[]= __('google sitemaps already submitted');
      self::$list[]= __('google sitemaps highly reccommend');
      self::$list[]= urldecode($google->GenerateSubmitURL()) . "\n\n";

      self::$list[]= __('google sitemaps here index') .' '. $google->base_url . 'sitemapindex.xml' ;
      self::$list[]= __('google sitemaps here product').' ' . $google->base_url . 'sitemapproducts.xml' ;
      self::$list[]= __('google sitemaps here category').' ' . $google->base_url . 'sitemapcategories.xml' ;
    } else {
      print_r($google->debug);
    }

  }


  public static function GenerateSubmitURL() {
    return htmlspecialchars(utf8_encode('http://www.google.com/webmasters/sitemaps/ping?sitemap=' . urlencode(HTTP_SERVER . DIR_WS_CATALOG . 'sitemapindex.xml' ) ));
  }

/** Interface module */

  function check() { return false; }
  function install() { return false; }
  function remove() { return false;  }
  function keys() { return false; }

}



/**
 * Google XML Sitemap Feed
 *
 * The Google sitemap service was announced on 2 June 2005 and represents
 * a huge development in terms of crawler technology.  This contribution is
 * designed to create the sitemap XML feed per the specification delineated
 * by Google.
 * @package Google-XML-Sitemap-Feed
 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
 * @version 1.0
 * @link http://www.oscommerce-freelancers.com/ osCommerce-Freelancers
 * @link http://www.google.com/webmasters/sitemaps/docs/en/about.html About Google Sitemap
 * @copyright Copyright 2005, Bobby Easland
 * @author Bobby Easland
 * @version 2.0
 * @link http://www.eurobigstore.com
 * @link http://www.google.com/webmasters/sitemaps/docs/en/about.html About Google Sitemap
 * @copyright Copyright 2006, Davide Duca
 * @author Davide Duca
 * @filesource

 */



/**
 * Google Sitemap Base Class
 *
 * The MySQL_Database class provides abstraction so the databaes can be accessed
 * @package Google-XML-Sitemap-Feed
 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
 * @version 1.2
 * @link http://www.oscommerce-freelancers.com/ osCommerce-Freelancers
 * @link http://www.google.com/webmasters/sitemaps/docs/en/about.html About Google Sitemap
 * @copyright Copyright 2005, Bobby Easland
 * @author Bobby Easland
 */
class GoogleSitemap{

	/**
 	* $DB is the database object
	* @var object
 	*/
	var $DB;
	/**
 	* $filename is the base name of the feeds (i.e. - 'sitemap')
	* @var string
 	*/
	var $filename;
	/**
 	* $savepath is the path where the feeds will be saved - store root
	* @var string
 	*/
	var $savepath;
	/**
 	* $base_url is the URL for the catalog
	* @var string
 	*/
	var $base_url;
	/**
 	* $debug holds all the debug data
	* @var array
 	*/
	var $debug;



/**
 * GoogleSitemap class constructor
 * @author Bobby Easland
 * @version 1.0
 * @param string $host Database host setting (i.e. - localhost)
 * @param string $user Database user
 * @param string $db Database name
 * @param string $pass Database password
 */
  function GoogleSitemap($host, $user, $db, $pass){
    $this->DB = Database::getInstance();
    $this->filename = "sitemap";
    $this->savepath = DIR_FS_CATALOG;
    $this->base_url =  HTTP_SERVER.DIR_WS_CATALOG;
    $this->debug = array();
  }


/**
 * Function to save the sitemap data to file as either XML or XML.GZ format
 * @author Bobby Easland
 * @version 1.1
 * @param string $data XML data
 * @param string $type Feed type (index, products, categories)
 * @return boolean
 */
  function SaveFile($data, $type){
    $filename = $this->savepath . $this->filename . $type;
    $compress = defined('GOOGLE_SITEMAP_COMPRESS') ? GOOGLE_SITEMAP_COMPRESS : 'false';
    if ($type == 'index') $compress = 'false';
    switch($compress){
      case 'true':
	$filename .= '.xml.gz';
	if ($gz = gzopen($filename,'wb9')){
	  gzwrite($gz, $data);
	  gzclose($gz);
	  $this->debug['SAVE_FILE_COMPRESS'][] = array('file' => $filename, 'status' => 'success', 'file_exists' => 'true');
	  return true;
	} else {
	  $file_check = file_exists($filename) ? 'true' : 'false';
	  $this->debug['SAVE_FILE_COMPRESS'][] = array('file' => $filename, 'status' => 'failure', 'file_exists' => $file_check);
	  return false;
	}
	break;
      default:
	$filename .= '.xml';
	if ($fp = fopen($filename, 'w+')){
	  fwrite($fp, $data);
	  fclose($fp);
	  $this->debug['SAVE_FILE_XML'][] = array('file' => $filename, 'status' => 'success', 'file_exists' => 'true');
	  return true;
	} else {
	  $file_check = file_exists($filename) ? 'true' : 'false';
	  $this->debug['SAVE_FILE_XML'][] = array('file' => $filename, 'status' => 'failure', 'file_exists' => $file_check);
	  return false;
	}
	break;
    } # end switch
  }


/**
 * Function to compress a normal file
 * @author Bobby Easland
 * @version 1.0
 * @param string $file
 * @return boolean
 */
  function CompressFile($file){
    $source = $this->savepath . $file . '.xml';
    $filename = $this->savepath . $file . '.xml.gz';
    $error_encountered = false;

    if( $gz_out = gzopen($filename, 'wb9') ){
	    if($fp_in = fopen($source,'rb')){
		    while(!feof($fp_in)) gzwrite($gz_out, fread($fp_in, 1024*512));
			    fclose($fp_in);

	    } else {
		    $error_encountered = true;
	    }
	    gzclose($gz_out);
    } else {
	    $error_encountered = true;
    }
    if($error_encountered){
	    return false;
    } else {
	    return true;
    }
  }


/**
 * Function to generate sitemap file from data
 * @author Bobby Easland
 * @version 1.0
 * @param array $data
 * @param string $file
 * @return boolean
 */
  function GenerateSitemap($data, $file){
    $content = '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
    $content = '<?xml-stylesheet type="text/xsl" href="gss.xsl"?>' . "\n";
    $content .= '<urlset xmlns="http://www.google.com/schemas/sitemap/0.9">' . "\n";

    foreach ($data as $url){
	    $content .= "\t" . '<url>' . "\n";
	    $content .= "\t\t" . '<loc>'.$url['loc'].'</loc>' . "\n";
	    $content .= "\t\t" . '<lastmod>'.$url['lastmod'].'</lastmod>' . "\n";
	    $content .= "\t\t" . '<changefreq>'.$url['changefreq'].'</changefreq>' . "\n";
	    $content .= "\t\t" . '<priority>'.$url['priority'].'</priority>' . "\n";
	    $content .= "\t" . '</url>' . "\n";
    } # end foreach

    $content .= '</urlset>';
    return $this->SaveFile($content, $file);
  }



/**
 * Function to generate sitemap index file
 * @author Bobby Easland
 * @version 1.1
 * @return boolean
 */
  function GenerateSitemapIndex(){
    $content = '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
    $content = '<?xml-stylesheet type="text/xsl" href="gss.xsl"?>' . "\n";
    $content .= '<sitemapindex xmlns="http://www.google.com/schemas/sitemap/0.84">' . "\n";
    $pattern = defined('GOOGLE_SITEMAP_COMPRESS')

      ?	GOOGLE_SITEMAP_COMPRESS == 'true'
			?	"sitemap*.xml.gz"
			: 	"sitemap*.xml"
	  :	"sitemap*.xml";

    foreach ( array_merge(glob($this->savepath . $pattern)) as $filename ) {
	if ( preg_match('/index/i', $filename) ) continue;
	$content .= "\t" . '<sitemap>' . "\n";
	$content .= "\t\t" . '<loc>'.$this->base_url . basename($filename).'</loc>' . "\n";
	$content .= "\t\t" . '<lastmod>'.date ("Y-m-d", filemtime($filename)).'</lastmod>' . "\n";
	$content .= "\t" . '</sitemap>' . "\n";
    } # end foreach

    $content .= '</sitemapindex>';
    return $this->SaveFile($content, 'index');
  }



/**
 * Function to generate product sitemap data
 * @author Bobby Easland
 * @version 1.1
 * @return boolean
 */
  function GenerateProductSitemap(){
    $sql = "SELECT p.products_id as pID, products_date_added as date_added, products_last_modified as last_mod, products_ordered FROM " . TABLE_PRODUCTS . " p, " . TABLE_PRODUCTS_TO_CATEGORIES . " p2c, " . TABLE_CATEGORIES . " c WHERE products_status='1'  and p.products_id=p2c.products_id and c.categories_id=p2c.categories_id and c.categories_status ORDER BY products_ordered DESC";

    if ( $products_query = $this->DB->query($sql) ){
      $this->debug['QUERY']['PRODUCTS']['STATUS'] = 'success';
      $this->debug['QUERY']['PRODUCTS']['NUM_ROWS'] = $products_query->__get('numRows');
      $container = array();
      $number = 0;
      $top = 0;

      while( $result = $products_query->fetchAssoc() ){
	$top = max($top, $result['products_ordered']);
	//$location = $this->hrefLink('product' . $result['pID'] . FILENAME_PRODUCT_INFO, 'source=google', 'NONSSL', false);
	$location = $this->hrefLink(FILENAME_PRODUCT_INFO, 'products_id=' . $result['pID'], 'NONSSL', false);
	$lastmod = tep_not_null($result['last_mod']) ? $result['last_mod'] : $result['date_added'];
	$changefreq = GOOGLE_SITEMAP_PROD_CHANGE_FREQ;
	$ratio = $top > 0 ? $result['products_ordered']/$top : 0;
	$priority = $ratio < .1 ? .1 : number_format($ratio, 1, '.', '');

	$container[] = array('loc' => htmlspecialchars(utf8_encode($location)),
			      'lastmod' => date ("Y-m-d", strtotime($lastmod)),
						  'changefreq' => $changefreq,
						  'priority' => $priority
			      );

	if ( sizeof($container) >= 50000 ){
	  $type = $number == 0 ? 'products' : 'products' . $number;
	  $this->GenerateSitemap($container, $type);
	  $container = array();
	  $number++;
	}
      } # end while
      $products_query->__destruct();
      if ( sizeof($container) > 1 ) {
	$type = $number == 0 ? 'products' : 'products' . $number;
	return $this->GenerateSitemap($container, $type);
      } # end if
    } else {
      $this->debug['QUERY']['PRODUCTS']['STATUS'] = 'false';
      $this->debug['QUERY']['PRODUCTS']['NUM_ROWS'] = '0';
    }
  }


/**
 * Funciton to generate category sitemap data
 * @author Bobby Easland
 * @version 1.1
 * @return boolean
 */
  function GenerateCategorySitemap(){
    $sql = "SELECT categories_id as cID, date_added, last_modified as last_mod FROM " . TABLE_CATEGORIES . " WHERE categories_status='1' ORDER BY parent_id ASC, sort_order ASC, categories_id ASC";

    if ( $categories_query = $this->DB->query($sql) ){
      $this->debug['QUERY']['CATEOGRY']['STATUS'] = 'success';
      $this->debug['QUERY']['CATEOGRY']['NUM_ROWS'] = $categories_query->__get('numRows');
      $container = array();
      $number = 0;

      while( $result = $categories_query->fetchAssoc() ){
	//$location = $this->hrefLink('category' . $this->GetFullcPath($result['cID']) . FILENAME_DEFAULT, 'source=google', 'NONSSL', false);
	$location = $this->hrefLink(FILENAME_DEFAULT, 'cPath=' . $this->GetFullcPath($result['cID']), 'NONSSL', false);
	$lastmod = tep_not_null($result['last_mod']) ? $result['last_mod'] : $result['date_added'];
	$changefreq = GOOGLE_SITEMAP_CAT_CHANGE_FREQ;
	$priority = .5;

	$container[] = array('loc' => htmlspecialchars(utf8_encode($location)),
			      'lastmod' => date ("Y-m-d", strtotime($lastmod)),
						  'changefreq' => $changefreq,
						  'priority' => $priority
			      );

	if ( sizeof($container) >= 50000 ){
	  $type = $number == 0 ? 'categories' : 'categories' . $number;
	  $this->GenerateSitemap($container, $type);
	  $container = array();
	  $number++;
	}
      } # end while

      $categories_query->__destruct();

      if ( sizeof($container) > 1 ) {
	$type = $number == 0 ? 'categories' : 'categories' . $number;
	return $this->GenerateSitemap($container, $type);
      } # end if

    } else {
      $this->debug['QUERY']['CATEOGRY']['STATUS'] = 'false';
      $this->debug['QUERY']['CATEOGRY']['NUM_ROWS'] = '0';
    }
  }


/**
 * Function to retrieve full cPath from category ID
 * @author Bobby Easland
 * @version 1.0
 * @param mixed $cID Could contain cPath or single category_id
 * @return string Full cPath string
 */
  function GetFullcPath($cID){
    if ( preg_match('/_/', $cID) ){
      return $cID;
    } else {
      $c = array();
      $this->GetParentCategories($c, $cID);
      $c = array_reverse($c);
      $c[] = $cID;
      $cID = sizeof($c) > 1 ? implode('_', $c) : $cID;
      return $cID;
    }
  }



/**
 * Recursion function to retrieve parent categories from category ID
 * @author Bobby Easland
 * @version 1.0
 * @param mixed $categories Passed by reference
 * @param integer $categories_id
 */
  function GetParentCategories(&$categories, $categories_id) {
    $sql = "SELECT parent_id FROM " . TABLE_CATEGORIES . " WHERE categories_id='" . (int)$categories_id . "' and categories_status='1' ";
    $parent_categories_query = $this->DB->query($sql);
    while ($parent_categories = $parent_categories_query->fetchAssoc()) {
      if ($parent_categories['parent_id'] == 0) return true;
      $categories[sizeof($categories)] = $parent_categories['parent_id'];
      if ($parent_categories['parent_id'] != $categories_id) {
	$this->GetParentCategories($categories, $parent_categories['parent_id']);
      }
    }
  }


/**
 * Function to return href_link
 * @author Bobby Easland
 * @version 1.1
 * @param mixed $value
 * @return boolean
 */
  function hrefLink($page, $parameters, $connection, $add_session_id) {
//     if (_cst_bool('SEO_ENABLED')) {
      return tep_catalog_href_link($page, $parameters, $connection, $add_session_id);
//     } else {
//       return $this->base_url . $page . '?' . $parameters;
//     }
  }


/**
 * Utility function to read and return the contents of a GZ formatted file
 * @author Bobby Easland
 * @version 1.0
 * @param string $file File to open
 * @return string
 */
  function ReadGZ( $file ){
    $file = $this->savepath . $file;
    $lines = gzfile($file);
    return implode('', $lines);
  }


/**
 * Utility function to generate the submit URL
 * @author Bobby Easland
 * @version 1.0
 * @return string
 */
  function GenerateSubmitURL(){
    $url = urlencode($this->base_url . 'sitemapindex.xml');
    return htmlspecialchars(utf8_encode('http://www.google.com/webmasters/sitemaps/ping?sitemap=' . $url));
  }

}
?>