<?php
/**
  \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  29/11/10, 11:33
  \author oscim <mail aurelien@oscim.fr> <www http://www.oscim.fr>
  \encode UTF-8

*/


/**
  \class categorie
  \brief Control init et gestion des data product
*/
class categorie {

  //! @p object
  protected static $_instance;

  public static $modules;

  /**
  */
  protected function __construct($full) {
    global $languages_id;
//     productData::start();
    if($full) self::start_module();
  }

  protected static function start_module(){
    $pdm=categorieModule::getInstance();
    self::$modules=$pdm->ret_modules();
    return $pdm;
  }

  public static function getInstance($full=true) {
    if(self::$_instance == null) self::$_instance = new self($full);
    return self::$_instance;
  }

  public static function resetInstance(){
    self::$_instance = null;
    return self::getInstance();
  }

  /**
    Module configuration
  */
//   public function ret_modules(){ self::start_module(); return self::$modules;}


  /**
    Data function
  */
  public static function get_path($current_category_id = '',$value=false){ return categorieData::get_path($current_category_id,$value); }
  public static function get_count_products_in_category($category_id, $include_inactive = false){ return categorieData::get_count_products_in_category($category_id,$include_inactive); }
  public static function get_count_content_in_category($category_id){ return categorieData::get_count_content_in_category($category_id); }
  public static function get_has_category_subcategories($category_id){ return categorieData::get_has_category_subcategories($category_id); }
  public static function get_parent_categories(&$categories, $categories_id) { return categorieData::get_parent_categories($categories, $categories_id); }
  public static function get_subcategories(&$subcategories_array, $parent_id = 0){ return categorieData::get_subcategories($subcategories_array, $parent_id); }
  public static function get_categories($categories_array = '', $parent_id = '0', $indent = '') { return categorieData::get_categories($categories_array , $parent_id, $indent); }

  public static function get_query($id='',$search='',$exclude='',$option=''){ global $languages_id; return categorieData::get_query($id,$search,$exclude,$option); }
  public static function get_item($id){ return categorieData::get_item($id); }
  public static function add_where_query($where){ return categorieData::add_where_query($where); }

  /**
    \fn categorie::resetCacheId($id);
    \brief delet item in cache
    \param $id integer id cat
  */
  public static function resetCacheId($id){ return categorieData::resetCacheId($id); }

  /**
   * \fn ret_modules()
   * \brief Retour tableau des modules type products actif
   * @return plusieurs modules via array(object)
   */
  public function ret_modules(){ self::start_module(); return self::$modules;}
  /**
   * \fn get_option_data($product_array)
   * \brief adjust products, depend class price, execute by productData
   * @param $product_array array
   */
  public static function get_option_data($_array){ $pdm=self::start_module();return $pdm->get_option_data($_array);}

}


/**
  @class productData
  Traitement sql des cat
*/
class categorieData
  extends DataStatmentFO
    implements Interfacedata{

  //! @p int
  public static $lg_id;
  //! @p obj res db
  public static $obj_language;
  //! @p array
  public static $cache=array();

  //! @p object cache
  public static $object_data;
  //! @p array cache
  public static $array_data=array();

  //! @p string
  private static $where_query='';


  /**
  */
  public static function start(){
    global $languages_id;
    self::$lg_id=(int)$languages_id;
    $DB=Database::getInstance();
    self::$obj_language = $DB->query("select code from " . TABLE_LANGUAGES . " where languages_id='" .self::$lg_id . "'");
  }

  /**
    \brief delet item in cache
    \param $id integer id cat
  */
  public static function resetCacheId($id){
    foreach(self::$cache as $k=>$v)
      if($v==$id) {
	unset(self::$cache[$k]);
    }
  }

  /**
   * \brief Mise en pile de toutes les element des page de cms
   * @param $id int
  */
  private static function add_cache($id){
    self::$cache[]=$id;
  }

  /**
   * \brief Appel et recup des element du cache
  */
  private static function in_cache(){
    return implode("," ,self::$cache);
  }

  /**
   * \brief Prepa donnée sortie
   * @param $content_query
   * @param $exclude array
   * @param $search string
  */
  protected static function statment_query($content_query,$exclude='',$search=''){

    $display_lang=self::$obj_language->fetchAssoc();
    if (empty($exclude))$exclude=array();
    $tabl=$res=array();
    while ($content = $content_query->fetchAssoc()) {
      if(count(self::$cache)>0 && in_array($content['categories_id'],self::$cache) ) $tabl[$content['categories_id']]=self::$object_data[$content['categories_id']];
      elseif (!in_array($content['categories_name'],$exclude)) {
	$res=$content;
	$res['href']=tep_href_link(FILENAME_PRODUCT_INFO,'categories_id=' . $content['categories_id'] . '&amp;language=' . $display_lang['code']);
	$res['key']=$content['categories_id'];
	$res['id']=$content['categories_id'];
	$res['title']=$content['categories_name'];
	$res['name']=$content['categories_name'];

	$res=categorie::get_option_data($res);

	self::$object_data[$content['categories_id']]=$tabl[$content['categories_id']]=new objectInfo($res);
	self::add_cache($content['categories_id']);
      }
    }
    return $tabl;
  }

  /**
   * \brief Ajout constrainte clause where
   * @param $add
  */
  public static function add_where_query($add){ self::$where_query .=' '.$add.' '; }

  /**
   * \fn reset_query()
  */
  protected static function reset_query() { self::$where_query=''; }



  /**
   * \fn cstr_query($orderby='', $limit='', $option='')
   * \brief Requeteur
   * @param $orderby
   * @param $limit
   * @param $option
   */
  protected static function cstr_query($orderby='', $limit='', $option=''){
    $query="SELECT c.categories_id, parent_id, cd.categories_description, c.categories_image, cd.categories_name, sortchids_products, sortchids_content FROM " . TABLE_CATEGORIES . " c, " . TABLE_CATEGORIES_DESCRIPTION . " cd WHERE c.categories_status='1' AND c.categories_id = cd.categories_id AND cd.language_id = '" . self::$lg_id  . "' ";

    $query .=self::$where_query;
    $query .=' ORDER BY ' .(!tep_not_null($orderby)? '  c.sort_order, cd.categories_name  ASC ' : $orderby) ;
    if($limit!='0')
      $query .=' LIMIT '.(!tep_not_null($limit)? '50' : $limit) ;

    return $query;
  }





  /**
   * \brief Appel item

   * @param $id int l'Id
   * @param $search string content_name le nom du titre
   * @param $exclude array tableau d'exclusion de nom
   * @param $option array option
  */
  public static function get_query($id='',$search='', $exclude='',$option=''){
    global $languages_id;

    self::start();
    $DB=Database::getInstance();
    self::$lg_id=(int)$languages_id;
    $search=tep_db_prepare_input($search);

    //! soit id soit sherach name key
    self::add_where_query((tep_not_null($id) && is_numeric($id) ? " AND c.categories_id = '" . (int)$id . "' ": (!empty($search)?" AND cd.categories_name LIKE '%" . tep_db_input($search) . "%' ":'') ));
    $sql=self::cstr_query( (isset($option['orderby'])?(string)$option['orderby']:''),(isset($option['limit'])?(int)$option['limit']:''),(array)@$option) ;

    $content_query = $DB->query($sql);
    self::reset_query();
    return self::statment_query($content_query,$exclude,$search);
  }

  /**
   * \brief Alias unique ID
   * @param $id int
  */
  public static function get_item($id){
    self::reset_query();
    $db_list=self::get_query($id);

    if(is_numeric($id) && isset($db_list[(int)$id])){
      return $db_list[$id];
    }else{
      $db_list=self::get_query('',$id);
      foreach($db_list as $item)
	if((string)$id==(string)$item->name)return $item;
    }
    return false;
  }

  /**
   * \fn get_path($current_category_id = '',$value=false)
   * \brief Generate a path to categories
   * @param $current_category_id int cat ID
   * @param $value bool si false, sortie string "cPath=1_3" si true, sortie string "1_3"
  */
  public static function get_path($current_category_id = '',$value=false) {
      global $cPath_array;

      if (tep_not_null($current_category_id)) {
	$cp_size = sizeof($cPath_array);
	if ($cp_size == 0) {
	  $cPath_new = $current_category_id;
	} else {
	  $cPath_new = '';
	  $last_category_query = tep_db_query("select parent_id from " . TABLE_CATEGORIES . " where categories_id = '" . (int)$cPath_array[($cp_size-1)] . "'");
	  $last_category = tep_db_fetch_array($last_category_query);

	  $current_category_query = tep_db_query("select parent_id from " . TABLE_CATEGORIES . " where categories_id = '" . (int)$current_category_id . "'");
	  $current_category = tep_db_fetch_array($current_category_query);

	  if ($last_category['parent_id'] == $current_category['parent_id']) {
	    for ($i=0; $i<($cp_size-1); $i++) {
	      $cPath_new .= '_' . $cPath_array[$i];
	    }
	  } else {
	    for ($i=0; $i<$cp_size; $i++) {
	      $cPath_new .= '_' . $cPath_array[$i];
	    }
	  }
	  $cPath_new .= '_' . $current_category_id;

	  if (substr($cPath_new, 0, 1) == '_') {
	    $cPath_new = substr($cPath_new, 1);
	  }
	}
      } else {
	$cPath_new = implode('_', $cPath_array);
      }

    if ($value) return 'cPath=' . $cPath_new;
    else return $cPath_new;
  }


  /**
   * \brief Return the number of products and category child  in a category
  // TABLES: products, products_to_categories, categories
  */
  public static function get_count_products_in_category($category_id, $include_inactive = false) {

//     if(isset(self::$object_data[$category_id]->count_products)) return self::$object_data[$category_id]->count_products;

    $products_count = 0;
    $DB=Database::getInstance();
    if ($include_inactive == true) {
      $products_query = $DB->query("select count(p.products_id) as total from " . TABLE_PRODUCTS . " p, " . TABLE_PRODUCTS_TO_CATEGORIES . " p2c where p.products_id = p2c.products_id and p2c.categories_id = '" . (int)$category_id . "'");
    } else {
      $products_query = $DB->query("select count(p.products_id) as total from " . TABLE_PRODUCTS . " p, " . TABLE_PRODUCTS_TO_CATEGORIES . " p2c where p.products_id = p2c.products_id and p.products_status = '1' and p2c.categories_id = '" .(int) $category_id . "' ");
    }
    if($products_query->__get('numRows')>0 ) $products = $products_query->fetchAssoc();
    else $products['total']= 0;
    $products_count += $products['total'];

    if(!isset(self::$object_data[$category_id]) || !self::get_item($category_id)) return false;
    self::$object_data[$category_id]->count_products=(int)$products_count;

    self::add_where_query(" AND parent_id = '" . (int)$category_id . "' ");
    $db_list=self::get_query('','','',array('limit'=>'30'));

    foreach($db_list as $cat)
      if($cat->key !=(int)$category_id && (int)$category_id ==$cat->parent_id) {
	$products_count +=(isset($cat->count_products) ? $cat->count_products : self::get_count_products_in_category($cat->categories_id) );
      }

    return $products_count;
  }

  /**
   * \brief Return the number of products and category child  in a category
  // TABLES: products, products_to_categories, categories
  */
  public static function get_count_content_in_category($category_id) {
    $products_count = 0;
    $DB=Database::getInstance();

    $products_query = $DB->query("select count(c.content_id) as total from " . TABLE_CONTENT . " c ,  " . TABLE_CONTENT_TO_CATEGORIES . " c2c where c.content_id = c2c.content_id and c2c.categories_id = '" .  (int)$category_id . "' and c.content_status='1' ");

    if($products_query->__get('numRows')>0 ) $products = $products_query->fetchAssoc();
    else $products['total']= 0;
    $products_count += $products['total'];

    if(!isset(self::$object_data[$category_id]) || !self::get_item($category_id)) return false;
    self::$object_data[$category_id]->count_products=(int)$products_count;

    self::add_where_query(" AND parent_id = '" . (int)$category_id . "' ");
    $db_list=self::get_query('','','',array('limit'=>'30'));

    foreach($db_list as $cat)
      if($cat->key !=(int)$category_id && (int)$category_id ==$cat->parent_id) {
	$products_count +=(isset($cat->count_products) ? $cat->count_products : self::get_count_products_in_category($cat->categories_id) );
      }

    return $products_count;
  }

  /**
   * \brief Return false if not the category has subcategories or nbr category
  */
  public static function get_has_category_subcategories($category_id) {

    self::add_where_query(" AND  parent_id = '" . (int)$category_id . "' ");
    $db_list=self::get_query();

    if (($count=count($db_list)) &&  $count > 0)  return $count;
    else  return 0;

  }

  /**
   * \brief Recursively go through the categories and retreive all parent categories IDs
  // TABLES: categories
  */
  public static function get_parent_categories(&$categories, $categories_id) {

  if(!isset(self::$object_data[$categories_id]->parent_array)) {
    $db_list=self::get_query((int)$categories_id);
    foreach($db_list as $cats) {
      if ($cats->parent_id == 0) return true;
      $categories[sizeof($categories)] = $cats->parent_id;
      if ($cats->parent_id != $categories_id) {
	self::get_parent_categories($categories, $cats->parent_id);
      }
    }
//     self::$object_data[$categories_id]->parent_array=$categories;
  } else  $categories=self::$object_data[$categories_id]->parent_array;


//     $parent_categories_query = tep_db_query("select parent_id from " . TABLE_CATEGORIES . " where categories_id = '" . (int)$categories_id . "' ");
//     while ($parent_categories = tep_db_fetch_array($parent_categories_query)) {
//       if ($parent_categories['parent_id'] == 0) return true;
//       $categories[sizeof($categories)] = $parent_categories['parent_id'];
//       if ($parent_categories['parent_id'] != $categories_id) {
// 	self::tep_get_parent_categories($categories, $parent_categories['parent_id']);
//       }
//     }

  }

/**
 * \brief
  Return all subcategory IDs. Recursivite
  TABLES: categories
*/
public static function get_subcategories(&$subcategories_array, $parent_id = 0) {
  $subcategories_query = tep_db_query("select categories_id from " . TABLE_CATEGORIES . " where parent_id = '" . (int)$parent_id . "' and categories_status='1' ");
  while ($subcategories = tep_db_fetch_array($subcategories_query)) {
    $subcategories_array[sizeof($subcategories_array)] = $subcategories['categories_id'];
    if ($subcategories['categories_id'] != $parent_id)
      tep_get_subcategories($subcategories_array, $subcategories['categories_id']);
  }
}

/**
 * \brief Construction d'un select sur les catégories actives
*/
public static function get_categories($categories_array = '', $parent_id = '0', $indent = '') {
  global $languages_id;
  if (!is_array($categories_array)) $categories_array = array();
  $categories_query = tep_db_query("select c.categories_id, cd.categories_name from " . TABLE_CATEGORIES . " c, " . TABLE_CATEGORIES_DESCRIPTION . " cd where parent_id = '" . (int)$parent_id . "' and c.categories_status='1' and c.categories_id = cd.categories_id and cd.language_id = '" . (int)$languages_id . "' order by sort_order, cd.categories_name");
  while ($categories = tep_db_fetch_array($categories_query)) {
    $categories_array[] = array('id' => $categories['categories_id'], 'text' => $indent . $categories['categories_name']);

    if ($categories['categories_id'] != $parent_id) $categories_array = tep_get_categories($categories_array, $categories['categories_id'], $indent . '&nbsp;&nbsp;');
  }

  return $categories_array;
}

}




/**
 * \class productModule
 * \brief Traitement des modules associé
*/
class categorieModule
  extends AbstractAcaModule
    implements InterfaceAcaGene{

  /**
    flag de la class
    @param string
  */
  var $name;
  /**
    Les modules actif
    @param string
  */
  var $modules;
  /**
    Pile des images du porduit
    @param array
  */
  var $pile_img;


  protected static $_instance;

  /**
  */
  protected function __construct() {
    global $language, $page;
    $this-> name=__CLASS__;
    $this->type_flag=1;
    $this-> products_id='';
    $this-> image_handler='';

    $this->modules=array();
    $this->pile_img=array();
    $list_mod=array();

    foreach(parent::initialise_type('MODULE_ACACAT_INSTALLED','categories') as $class){
      $cl[$class]=new $class ();
      $list_mod[$class] = $cl[$class]->sort_order;
    }
    asort($list_mod);
    foreach($list_mod as $class=>$s){
      $this->modules[$class] =$cl[$class];
    }
    unset($cl);unset($list_mod);
    return $this->modules;
  }


  public static function getInstance() {
    if(self::$_instance == null) self::$_instance = new self();
    return self::$_instance;
  }

  public static function resetInstance(){
    self::$_instance = null;
    return self::getInstance();
  }

  public function get_option_data($_array){
    if(isset($this->modules) && is_array($this->modules))
    foreach ($this->modules as $key=>$module) {
      if ( $module->enabled && (method_exists($module, 'get_option_data' ))) {
	$_array=$this->modules[$key]->get_option_data($_array);
      }
    }
    return $_array;
  }

 /**
  * \brief  Affiche module elemennt html
  *  Block principal d'affichage, liste ou vue des élément. Block principal de page
  * @param $pID int  $pID le Id du produits
  * @param @classe string le nom de la class appelé, ou vide pour toutes les class enfants
  */
  public function display_view($pID,$classe=''){
    global  $page;
    if (!empty($classe)) {
      if (isset($this->modules[$classe]) && $this->modules[$classe]->enabled and (method_exists($classe, 'display_view' ))){
        $this->modules[$classe]->load_db_values($pID);
        return $this->modules[$classe]->display_view($pID);
      }
    } else {
       $c='';
      if(isset($this->modules) && is_array($this->modules))
      foreach ($this->modules as $key=>$module) {
        if (($module->enabled)  and (method_exists($module, 'display_view' ))) {
          $this->modules[$key]->load_db_values($pID);
          $c .=$this->modules[$key]->display_view($pID);
        }
      }
      return $c;
    }
  }

  /**
   * \brief Affiche module display_view mini
   * @param $cID int  cID le Id du customers
   * @param $class string class le nom de la class appelé, ou vide pour toutes les class enfants
  */
  public function display_view_min($cID,$class=''){
    global  $page;
    if (!empty($class)) {
      if (isset($this->modules[$class]) && $this->modules[$class]->enabled and (method_exists($module, 'display_view_min' ))){
        $this->modules[$class]->load_db_values($cID);
        return $this->modules[$class]->display_view_min($cID);
      }
    } else {
       $c='';
      foreach ($this->modules as $key=>$module) {
        if (($module->enabled)  and (method_exists($module, 'display_view_min' ))) {
          $this->modules[$key]->load_db_values($cID);
          $c .=$this->modules[$key]->display_view_min($cID);
        }
      }
      return $c;
    }
  }


}
?>