<?php if (!defined('HTTP_SERVER')) die('You can not access this file directly!');
/**
  @licence GPL 2005-2011  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  10/04/11, 09:56
  @author oscim <mail aurelien@oscim.fr> <www http://www.oscim.fr>
  @encode UTF-8
  @class package
  @brief manage , install, remove extension , plugin and module in core osCSS
*/

class package
  implements ExtModPage, InterfacedTJsonS, InterfaceModule {

  /**
    Configuration
  */
  /**
    File xml source
  */
  const REPOSITORY_SOURCE = 'repository_sources.xml';
  /**
    File xml global detail package repository
  */
  const REPOSITORY_DATA = 'repository_data.xml';
  /**
    File cache, info repository
  */
  const REPOSITORY_CACHE = 'repository-source';
  /**
    this file url
  */
  const FILENAME = FILENAME_PACKAGE;
  /**
    @var obj
  */
  public static $FeedItem;
  /**
    @var array Global object repository s
  */
  public static $objRepos;
  /**
    @var bool
  */
  public static  $in_table;
  /**
    @var string
  */
  public static $code;
  /**
    @var string
  */
  public static $action;
  /**
    @var array
  */
  public static $list=array();
  /**
    @var array
  */
  public static $Rightlist=array();

  /**
    @var string
  */
  public static $set;
  /**
    @var string
  */
  public static $class;
  /**
    @var array
  */
  public static $code_inistalletd_array=array();
  /**
    @var array
  */
  public static $modules_array=array();
  /**
    @var array Type de ressource
    package / source /
  */
  public static $type_data='package';
  /**
    @var obj enfant specific type
  */
  private static $objChild;
  /**
    @var string key pck  xxx_stable
  */
  public static $pckID;
  /**
    class constructor
  */
  public function __construct() {
    self::GetConf();

   include_once(DIR_WS_FUNCTIONS.'lib.cip_manager.php');
   include_once(DIR_WS_FUNCTIONS.'lib.configuration.php');
  }


  /**
    @brief Load , adjust and define var environement exe for module
	Is use in module and class abstract for init value config this module
  */
  public static function GetConf(){
    global $languages_id;

    self::$code=__CLASS__;

    self::$action=(isset($_REQUEST['action'])? $_REQUEST['action'] : 'listing' );
    self::$type_data=(isset($_GET['type_data'])?$_GET['type_data']:'package');
    $mode=(isset($_GET['mode'])?$_GET['mode']:'');



    /**
      @remarks not load if not first init
    */
    if(defined('JSONSTATMENT')) return;

    switch(self::$type_data){
      case 'source':
	$class=__CLASS__.'Repository';
	if(!tep_class_exists('exts_'.__CLASS__.'_'.$class)) die('class no found '.$class);
	self::$objChild=new $class;
      break;
      case 'package':
      default:
	//! detail item in ajax
	define('AJAXSTATMENTDETAIL', 'mod=page&type='.__CLASS__.'&type_data='.self::$type_data.'&mode='.$mode);


	$class=__CLASS__.'Utility';
	if(!tep_class_exists('exts_'.__CLASS__.'_'.$class)) die('class no found '.$class);
	self::$objChild=new $class;
    }

    //! active datatable in ajax, precise les GET necessaire
     define('JSONSTATMENT', 'mod=page&type='.__CLASS__.'&type_data='.self::$type_data.'&mode='.$mode);


  }


  public function check_action($actions){
    global $messageStack;

    switch(self::$action){
      case 'source_update':
	if(self::$objChild->SourceUpdate()==true) tep_redirect(tep_href_link(self::FILENAME));
      break;
      case 'download':
	$class=self::$code.'Installer';
	if(!tep_class_exists('exts_'.self::$code.'_'.$class)) return false;
	$obj=new $class;
	$obj->download_exts((string)$_GET['pkgID']);

// 		self::load_db_values(self::REPOSITORY_OFFICIAL,'action=view');
      break;

      case 'upload_confirm':
	if ( !empty($_FILES['new_package']['tmp_name']) ) {
	  $categories_image = new upload('new_package', DIR_FS_CIP);
	}
	tep_redirect(tep_href_link(self::FILENAME, 'type_data=source&action=source_update'));
      break;

      case 'setflag':
	$t=$ts=array();
	$module=$_GET['set'];
	$tclass=$_GET['class'];
	$flag=$_GET['flag'];
	$core=(!isset($_GET['core']))? '' :'_'.$_GET['core'];
	$t=(tep_not_null(self::$code_inistalletd_array[$module]['value'.$core])? explode(';',self::$code_inistalletd_array[$module]['value'.$core]) : array() );
	if($flag ==0) {
	  foreach($t as $v){
	    if(!empty($v) && $tclass.'.php' != $v)$ts[]=$v;
	  }
	}
	else {
	  $ts=((count($t)>0)?$t:array());
	  $ts[]=$tclass.'.php';
	}
	if(count($ts)==1)$ts[]='';
	$check_query = tep_db_query("select configuration_value from " . TABLE_CONFIGURATION . " where configuration_key = '" . self::$code_inistalletd_array[$module]['key'].$core . "'");
	if (tep_db_num_rows($check_query)) {
	  $check = tep_db_fetch_array($check_query);
	  tep_db_query($sql="update " . TABLE_CONFIGURATION . " set configuration_value = '" . implode(';', $ts) . "', last_modified = now() where configuration_key = '" . self::$code_inistalletd_array[$module]['key'].$core . "'");

	} else {
	  tep_db_query($sql="insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Installed Modules ".$type."', '" . self::$code_inistalletd_array[$module]['key'].$core . "', '" .$ts . ";', 'This is automatically updated. No need to edit.', '6', '0', now())");
	}

	tep_redirect(tep_href_link(self::FILENAME, 'set=' . self::$set.'&class='.strtoupper($_GET['class']).'&action=config' ));

      break;
      case 'save':
	while (list($key, $value) = each($_POST['configuration'])) {
	  tep_db_query("update " . TABLE_CONFIGURATION . " set configuration_value = '" . $value . "' where configuration_key = '" . $key . "'");
	}
	tep_redirect(tep_href_link(self::FILENAME, 'set=' . self::$set .'&class='.$_GET['class'].'&core='.@$_GET['core'].'&action=edit' ));
      break;
      default:
	self::load_repository();
    }

  }

  public function get_header(){
  }


  public static function load_db_values($pkg_code){
    global $messageStack;

    self::load_repository();

    //! recup element pkg
    foreach(self::$FeedItem as $item){
      if((int)$pkg_code == (int)$item->internalID)$ObjPkg =$item;
    }

    //! recup depot, si != local ; local pas info supp
    if((string)$ObjPkg->sourceTitle !='local') {

	$class=__CLASS__.'Repository';
	if(!class_exists($class) && !tep_class_exists('exts_'.__CLASS__.'_'.$class)) return false;

	$obj=new $class;
	$ObjDepot=call_user_func(array($obj, 'SourceLoadByKey'),(string)$ObjPkg->sourceKey);
	try{
	  //! load xml file
	  if(!$Parser = @simplexml_load_file((string)$ObjDepot->repository.(string)$ObjDepot->rep_detail.'&pid='.(int)$ObjPkg->pid) ) throw new Exception('Flux introuvable');
	  $FeedItem = $Parser->xpath('channel');

	  return $FeedItem;
	}
	catch(Exception $e){
	  $messageStack->add($e->getMessage(),'error' );
	}
    }
    //! local depot
    elseif((string)$ObjPkg->sourceTitle =='local')
      return array(new objectInfo(array('item'=>$ObjPkg)));
  }


  /**
    @p string $mode (global/installed/updatable/notinstall)
  */
  public static function load_repository($mode='global'){
    global  $messageStack;
    $FeedI=array();
    $DB=Database::getInstance();

    $osCSS_Cache = new osCSS_Cache;

    $res=$DB->query("select cip_id, cip_installed, cip_folder_name from ".TABLE_CIP. " ");
    self::$in_table=$res->fetchAllAssoc();

    try{
      if ($osCSS_Cache->read(self::REPOSITORY_CACHE,0,true) ) {
	//! recup info cache
	$var_file = $osCSS_Cache->getCache();
	//! load xml file

	if(!$Parser = simplexml_load_file(HTTP_SERVER.DIR_WS_ADMIN.DIR_WS_INCLUDES.'data/'.self::REPOSITORY_DATA)) throw new Exception('Flux introuvable');

	$Feed = $Parser->xpath('channel/item');

	/**
	  Mise à jour cache paquet  installed / updatable / non install
	*/
	foreach($Feed as $item){

	  $item->etat=(self::pkg_is_installed($item->ident.'_'.$item->level)? 1 : 0);

	  switch($mode){
	    case 'notinstall':
	      if($item->etat==0)$FeedI[]=$item;
	    break;
	    case 'installed':
	      if($item->etat==1)$FeedI[]=$item;
	    break;
	    default:
	      $FeedI[]=$item;
	  }
	}
// 	$osCSS_Cache->writeBuffer($var_file);

	self::$FeedItem=$FeedI;
      }
//       else tep_redirect(tep_href_link(self::FILENAME, 'type_data=source&action=source_update'));

    }
    catch(Exception $e){
       $messageStack->add_session($e->getMessage(),'error' );
    }
  }





  public function display_view(){

    $action=self::$action;

    switch(self::$action){
    //! source repository
      case 'source_update':
      break;
      case 'source_add':
	$action='edit';
      break;

    //! paquets
      case 'upload':
      break;

      case 'view':
      case 'detail':
	$action='detail';
	$class=self::$code.'Installer';
	if(!tep_class_exists('exts_'.self::$code.'_'.$class)) return false;
	$obj=new $class;

	self::$list=$obj->view_exts((string)$_GET['pkgID']);
      break;

      case 'install':
	$action='detail';
	$class=self::$code.'Installer';
	if(!tep_class_exists('exts_'.self::$code.'_'.$class)) return false;
	$obj=new $class;

	self::$list=$obj->install_exts((string)$_GET['pkgID']);
      break;

      case 'remove':
	$action='detail';
	$class=self::$code.'Installer';
	if(!tep_class_exists('exts_'.self::$code.'_'.$class))return false;
	$obj=new $class;

	self::$list=$obj->remove_exts((string)$_GET['pkgID']);
      break;

      case 'edit':
      case 'config':
	$action='config';
	call_user_func(array(self::$objChild, 'load_config_value'));
      break;

      default:

    }

	/// use master gabarit
	return MGabCont::CallGab(self::$type_data.'.'.$action,__FUNCTION__,__CLASS__);
  }




  /** public static InterfacedTJsonS */

  private static function get_item_status($pkg, $pkgobj){

    $s= '';
    if($pkgobj->etat==1)  $s .=tep_image(DIR_WS_ICONS . 'install.gif', __('icon remove'))."\n";
    else  $s .=tep_image(DIR_WS_ICONS . 'remove.gif', __('icon install'))."\n";

    if(!is_dir(DIR_FS_CIP.$pkg)) $s .=tep_image(DIR_WS_ICONS . 'unpack.gif', __('icon unzip'))."\n";
    if(file_exists(DIR_FS_CIP.$pkg.'.zip'))  $s .=tep_image(DIR_WS_ICONS . 'pack.gif', __('icon install'))."\n";

//     else  $s .=tep_image(DIR_WS_ICONS . 'remove.gif', ICON_INSTALL)."\n";

    $s .= '';

    return $s;
  }

  private static function get_item_action($pkg, $pkg_full, $url_pck, $pkgobj){
    return  sprintf(
		  CsrtAction::getFormat('row_action'),
		  '' ,
		  (($pkgobj->etat==1)
		    ?
		    sprintf(CsrtAction::getLink('row_action_right', __('icon remove'), 'install'), '',  tep_href_link(self::FILENAME,'action=remove&amp;pkgID='.urlencode($pkg_full)) ,'' ).
		    sprintf(CsrtAction::getLink('row_action_right', __('image edit'), 'edit'), '',  tep_href_link(self::FILENAME,'action=config&amp;class='.$pkg) ,'' )
		    :
		    sprintf(CsrtAction::getLink('row_action_right', __('icon install'), 'remove'), '',  tep_href_link(self::FILENAME,'action=download&amp;pkgID='.urlencode($pkg_full)) ,'' )
		  )
	      );
  }

  public static function tep_get_modele(){

    switch(self::$type_data){
      case 'source':
	return array(
		      'key'=>false,
		      'title'=>false,
		      'last_update'=>false,
		      'action'=>false,
		    );
      break;
      case 'package':
      default:
	return array( 0 =>false,
		      'title'=>true,
		      'description'=>true,
		      'level'=>true,
		      'sourceTitle'=>true,
		      'status'=>false,
		      'action'=>false,
		    );
    }
  }


  public static function tep_get_list($page=1,$rowbyp=10,$sOrder='',$sWhere='',$options=''){
    global $query_numrows;

    self::GetConf();

    switch(self::$type_data){
      case 'source':
	call_user_func(array(self::$objChild, 'SourceLoad'));
	$res=self::$FeedItem;
      break;
      default:
      $mode=(isset($_GET['mode'])?$_GET['mode']:'');

      self::load_repository($mode);
      $res=self::$FeedItem;
    }


    /**
      @brief Search
      @remarks limit in one input string
    */
    if(!empty($sWhere)){
      $li=array();
      $match=explode('%',$sWhere);
      foreach($res as $item){
	$etat=array();
	foreach(self::tep_get_modele() as $k=>$v)
	  if( strpos( strtoupper((string)$item->$k),strtoupper(trim($match[1])) )===false) $etat[]=false;
	  else $etat[]=true;

	if(in_array(true,$etat )) $li[]=$item;
      }
    }
    else $li=self::$FeedItem;

    //! sort_order
    $ord=explode(' ',$sOrder);
    if(class_exists('multiSort') && $ord[0] !=0){
      $multiSort=new multiSort;
      $li= $multiSort->sortArray($li,(string)$ord[0],$ord[1]);
    }

    //! num rows
    $query_numrows=count($li);

    /// force recalcul page, via sql default =1, via xml default =0
    $page=$_REQUEST['iDisplayStart'] / $_REQUEST['iDisplayLength'];

    //! split
    self::$list=array_slice($li,($page*$rowbyp), $rowbyp );

    $li=$res=array();

    switch(self::$type_data){
      case 'source':
	foreach(self::$list as $item){
	  foreach(self::tep_get_modele() as $k=>$v) $li[$k]=(tep_not_null((string)$item->$k)? (string)$item->$k : '&nbsp');
	  $li['action']='&nbsp;';
	  $res[]=$li;
	}
      break;
      default:
	foreach(self::$list as $item){
	  foreach(self::tep_get_modele() as $k=>$v) $li[$k]=(string)$item->$k;
	  $li[0]=(int)$item->internalID;
	  $li['status']=self::get_item_status((string)$item->ident.'_'.(string)$item->level, $item);
	  $li['action']=self::get_item_action($item->ident,(int)$item->internalID,$item->url_src ,$item);
	  $res[]=$li;
	}
    }

    return $res;
  }

 /** static InterfacedInnerHtml */

  /**
    @param $id string key pck
  */
  public static function detail_row_page($id){
    self::$pckID=(string)$id;
    $obj=self::load_db_values((string)$id);
    self::$list=$obj[0];
    self::$Rightlist=$obj[0]->item;
    return tep_get_include_contents(__CLASS__.'.inline');
  }

/** Interface module */

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

/** Specific module */



  public static function status_flag($cond,$get){
    if($cond) {
      return tep_image(DIR_WS_ICONS . 'icon_status_green.gif', IMAGE_ICON_STATUS_GREEN) . ' <a href="' . tep_href_link(self::FILENAME, $get.'&flag=0' ) . '">' . tep_image(DIR_WS_ICONS . 'icon_status_red_light.gif', IMAGE_ICON_STATUS_RED_LIGHT) . '</a>';
    } else {
      return '<a href="' . tep_href_link(self::FILENAME, $get.'&flag=1') . '">' . tep_image(DIR_WS_ICONS . 'icon_status_green_light.gif', IMAGE_ICON_STATUS_GREEN_LIGHT) . '</a> ' . tep_image(DIR_WS_ICONS . 'icon_status_red.gif', IMAGE_ICON_STATUS_RED);
    }
  }

  /**
    Precise si le paqiet est installé
    @param string $pkg_name ident_level du paquet
    @return boolean
  */
  public static function pkg_is_installed($pkg_name){
   foreach(self::$in_table as $item)
    if($item['cip_folder_name']==$pkg_name && $item['cip_installed']==1) return true;
    return false;
  }




  /**
  */
  public static function get_right_bar(){
    global $language,$heading,$contents;
    $heading = array();
    $contents = array();
    self::GetConf();

    self::$objChild->right_bar();

    if ( (tep_not_null($heading)) && (tep_not_null($contents)) ) {
      $box = new box;
      return $box->infoBox($heading, $contents);
    }
  }


}

?>