<?php
/**
  @licence GPL 2005-2010  The osCSS developers - osCSS Open Source E-commerce
  @package osCSS-2 <www http://www.oscss.org>
  @version 2.0.1
  @date  14/01/11, 18:06
  @author oscim <mail aurelien@oscim.fr> <www http://www.oscim.fr>
  @encode UTF-8
  @class SvnUpdate

  Mise a jour version, tools SourceForge, utilise viewSVN, trac
  apres install renseigne correctement cip manage, et prepare les element du zip d'install via cip

  NOTE:
    Require config php
    @par set_time_limit(0)
    @par file_get_contents(url)
*/

class SvnUpdate implements InterfaceModule{

  /// Configuration
  /// -> Settings you *must* adjust
  const URL_OSCSS_ORG_TRAC = 'http://sourceforge.net/apps/trac/oscss/changeset/?format=zip&new=SVN_REV_MAX&old=SVN_REV&new_path=branches%2F2.1.0%2Fcatalog&old_path=branches%2F2.1.0%2Fcatalog';
  const URL_OSCSS_GET_REV = 'http://oscss.svn.sourceforge.net/viewvc/oscss?view=revision';
  const PATH_SVN_BRANCHE = 'branches/2.1.0/catalog/';
  const FILEPATH_SVN_CORE = 'common/oscss.version.xml';

  //! page de redirection apres exec
  const REDIRECT = FILENAME_PACKAGE;

  /// version module
  var $version='2.0.1';

  public static  $code;
  var $title;
  var $description;
  var $sort_order;
  var $enabled;
  /**

  */
  public static $actu_rev;
  public static $current_rev;

  /**
    class constructor
    @author oscim <mail oscim@oscss.org> <www http://www.oscim.fr>
  */
  function __construct() {

    self::$code = __CLASS__;
    $this->type='generic';
    $this->enabled = true;
    $this->sort_order = (defined('MODULE_GENERIC_SVNUPDATE_SORT_ORDER'))?MODULE_GENERIC_SVNUPDATE_SORT_ORDER : 0;

    $this->title = __('Synchro Svn');
    $this->description = __('Synchronisation Svn');

    global $languages_id, $messageStack;
    $this->language_id = $languages_id;

    $svnupdate=0;
    if(!tep_session_is_registered('svnupdate')) {
      self::$actu_rev=$this->get_info_core(DIR_FS_CATALOG.self::FILEPATH_SVN_CORE);
      self::$current_rev=$this->get_current_rev(self::URL_OSCSS_GET_REV);
      if(self::$actu_rev!=self::$current_rev)$svnupdate=1;
      $_SESSION['svnupdate']=$svnupdate;
    }
    else $svnupdate=(int)$_SESSION['svnupdate'];

    if($svnupdate==1) {
      $messageStack->add( __("mise a jour disponible ").'<a href="'.tep_href_link(FILENAME_ACA,'action_type='.$this->type.'&amp;action_class='.self::$code.'&amp;action_method=draw_form').'">'.__('detail').'</a>', 'info' ) ;
    }

  }


  function check_action($actions){
    return $actions;
  }

//=====================================
// Functions for modules specific
//=====================================

  /**
    Ajout menu
    @author oscim <mail oscim@oscss.org> <www http://www.oscim.fr>
  */
  public function _add_menu() {
    return('<a href="'.tep_href_link(FILENAME_ACA,'action_type='.$this->type.'&amp;action_class='.self::$code.'&amp;action_method=draw_form').'">'.__('Svn synchro').'</a>');
  }

  /**
    @author oscim <mail oscim@oscss.org> <www http://www.oscim.fr>
  */
  public function draw_form(){
    if((int)self::$actu_rev==0) self::$actu_rev=$this->get_info_core(DIR_FS_CATALOG.self::FILEPATH_SVN_CORE);
    if((int)self::$current_rev==0) self::$current_rev=$this->get_current_rev(self::URL_OSCSS_GET_REV);

    if(isset($_POST['ACTU_REV']))$S=$this->exe_update($_POST['ACTU_REV'],$_POST['CURENT_REV']);
    else {
      if(self::$actu_rev==self::$current_rev) $S='<p>'. __('Pas de nouvelle revisions, actuel:').' '.self::$actu_rev.'</p>';
      else $S=tep_get_include_contents(self::$code.'.form');
    }
    return $S;
  }

  /**
    @author oscim <mail oscim@oscss.org> <www http://www.oscim.fr>
  */
  static private function write_dest($str, &$dest) {
    if (is_resource($dest)) fwrite($dest, $str);
    else $dest .= $str;
  }

  /**
    Recuperation des element de svn basé sur le fichier oscss.version.xml
    @package oscss-2 <www http://www.oscss.org>
    @date  15/05/10, 16:19
    @author oscim <mail oscim@oscss.org> <www http://www.oscim.fr>
  */
  private function get_info_core($file,$name='svn'){
    global $messageStack;
    if(!file_exists($file)) return $messageStack->add( __("Erreur récupération fichier"), 'error' );
    $SimpleParser = @simplexml_load_file($file);
    if(!isset($SimpleParser->$name)) $messageStack->add( __("Erreur récupération n° révision courant"), 'error' );
    else return $SimpleParser->$name;
  }


  /**
    Recup current version svn, basé sur ViewVC fournis pas Sourceforge , vieVC 1.0.5
    @author oscim <mail oscim@oscss.org> <www http://www.oscim.fr>
  */
  private function get_current_rev($src) {
    $content=fileUtility::url_fopen($src);
    if ($content !== false){
      preg_match("#.oscss..Revision.([0-9]*).*#i",strip_tags($content),$val );
      if(isset($val[1]) && is_numeric($val[1])) return $val[1];
    }
    else return false;
  }


  /**
    Execution synhro
    @author oscim <mail oscim@oscss.org> <www http://www.oscim.fr>
  */
  private function exe_update($corre_rev,$curent_rev){
    global $messageStack;

    //! bloque delai
    @set_time_limit(0);
    $folder_admin=substr(DIR_WS_ADMIN, strlen(DIR_WS_CATALOG) );
    $name='old'.$corre_rev.'new'.$curent_rev.'_patch.zip';
    $file=DIR_FS_ADMIN.'contributions/'.$name;

    //! recup zip fournis par trac SF
      $oscss_zip = @fopen($file,'wb');
      // recup zip
      $tp=@file_get_contents/*fileUtility::url_fopen*/(str_replace( array('SVN_REV_MAX', 'SVN_REV'), array($curent_rev, $corre_rev), self::URL_OSCSS_ORG_TRAC));
      fputs( $oscss_zip,$tp);
      fclose($oscss_zip);
      if ($file!=false)  $messageStack->add( __("Le fichier à été enregistré"),'succes' ) ;
      else  $messageStack->add( __("Le fichier n'as pas été enregistré"), 'error' ) ;
    //! dezipp
      sleep(1);
      tep_zip_extractto( $file,DIR_FS_CATALOG);
    //! mode admin folder
    // report branche dans le core
    if(file_exists(DIR_FS_CATALOG.self::PATH_SVN_BRANCHE)){
      $this->recurse_copy(DIR_FS_CATALOG.self::PATH_SVN_BRANCHE,DIR_FS_CATALOG);
      $this->recurse_delete(DIR_FS_CATALOG.'branches/');
    }
    // deplacement admin
    if(file_exists(DIR_FS_CATALOG.'admin')){
      $this->recurse_copy(DIR_FS_CATALOG.'admin',DIR_FS_ADMIN);
      if($folder_admin !='admin/') $this->recurse_delete(DIR_FS_CATALOG.'admin/');
    }
    //! update core.xml
      $this->new_version_xml($curent_rev, $corre_rev);
    //! db recup merge

    //! exe db update


    //! bascule en cip.zip
      $this->gener_install($name,$curent_rev, $corre_rev);

    //! reset alert messageStack
    $_SESSION['svnupdate']=0;

    tep_redirect(tep_href_link(self::REDIRECT, 'cip='.$name));
  }

  /**
    Ecriture fichier version moteur
    @author oscim <mail oscim@oscss.org> <www http://www.oscim.fr>
    @param
      @a int $curent_rev version courante
      @a int $corre_rev n° revision patch
  */
  private function new_version_xml($curent_rev, $corre_rev){
    $tmp='<?xml version="1.0" encoding="utf-8"?>'."\n".
      '<core>'."\n".
	'<version>'.get_info_core(DIR_FS_CATALOG. DIR_WS_COMMON.'oscss.version.xml','version').'</version>'."\n".
	'<svn>'.$curent_rev.'</svn>'."\n".
      '</core>'."\n";
    $file_vers= @fopen(DIR_FS_CATALOG.self::FILEPATH_SVN_CORE,'w');
    fputs( $file_vers,$tmp);
    fclose($file_vers);
  }

  /**
    Ajout element table cip suivi pkg
    @author oscim <mail oscim@oscss.org> <www http://www.oscim.fr>
    @param
      @a string $name le nom sans ext
  */
  private function insert_db_cip($name){
    $DB=Database::getInstance();
    $DB->query("INSERT INTO ".TABLE_CIP." (cip_folder_name,cip_installed)  VALUES ('".$name."','1')");
  }

  /**
    Tranformation du zip en paquet pour cip, ajout rep + construction file install.xml
    @author oscim <mail oscim@oscss.org> <www http://www.oscim.fr>
    @param
      @a string $name_zip le nom du zip existant
      @a int $curent_rev version courante
      @a int $corre_rev n° revision patch
  */
  private function gener_install($name_zip,$curent_rev, $corre_rev){

    $folder=substr($name_zip, 0, strlen($name_zip)-4);

    $file='<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'."\n".
	'<contrib>'."\n".
	  '<description><!-- Description of the contribution -->'."\n".
		  '<details contrib_ref="" forum_ref="" contrib_type="upgrade" status="0" last_update="'.date("Y-m-d").'" />'."\n".
		  '<author_pkg>www.oscim.fr</author_pkg>'."\n".
		  '<comments>'.sprintf(__("installation automatisé patch mise à jour, generer par le module SvnUpdate;  Vou permet de reappliquer ou recuprer les elements de mise à jour entre ces version : avant patch %s, revision patch %s"), $corre_rev,$curent_rev) .'</comments>'."\n".
		  '<credits>'.self::$code.'</credits>'."\n".
		  '<version>'.$this->version.'</version>'."\n".
		  '<post_install_notes><![CDATA['."\n".
		      __("fichier creer dynamiquement. les mises à jour ne concerne que les fichier, la base de donnée n'est pas modifié")."\n".
		  ']]></post_install_notes>'."\n".
	  '</description>'."\n".
	  '<extractzip>'."\n".
	    '<zip name="'.$name_zip.'" />'."\n".
	    '<path name="catalog/" />'."\n".
	  '</extractzip>'."\n".
	'</contrib>'."\n";

      mkdir(DIR_FS_ADMIN.'contributions/'.$folder.'/');
      copy(DIR_FS_ADMIN.'contributions/'.$name_zip,DIR_FS_ADMIN.'contributions/'.$folder.'/'.$name_zip);
      //! ne pas supp le zip, sert a être traité par cip
//       unlink(DIR_FS_ADMIN.'contributions/'.$name_zip);
      $this->insert_db_cip($folder);

      $file_vers= @fopen(DIR_FS_ADMIN.'contributions/'.$folder.'/install.xml','w');
      fputs( $file_vers,$file);
      fclose($file_vers);
  }

  /**
    Delete repertoire recursif
    @author oscim <mail oscim@oscss.org> <www http://www.oscim.fr>
  */
  static  function recurse_delete($src){
    $dir = opendir($src);
    @mkdir($dst);
    while(false !== ( $file = readdir($dir)) ) {
    if (( $file != '.' ) && ( $file != '..' )) {
        if ( is_dir($src . '/' . $file) ) {
        SvnUpdate::recurse_delete($src . '/' . $file);
        }
        else {
        @unlink($src . '/' . $file);
        }
    }
    }
    closedir($dir);
    rmdir($src);
  }

  /**
    Copy repertoire recursif
    @author oscim <mail oscim@oscss.org> <www http://www.oscim.fr>
  */
  static function recurse_copy($src,$dst){
    $dir = opendir($src);
    @mkdir($dst);
    while(false !== ( $file = readdir($dir)) ) {
    if (( $file != '.' ) && ( $file != '..' )) {
        if ( is_dir($src . '/' . $file) ) {
        SvnUpdate::recurse_copy($src . '/' . $file,$dst . '/' . $file);
        }
        else {
        @copy($src . '/' . $file,$dst . '/' . $file);
        }
    }
    }
    closedir($dir);
  }


//=====================================
// Functions for modules administration
//=====================================

    function check() {
      if (!isset($this->_check)) {
	$check_query = tep_db_query("select configuration_value from " . TABLE_CONFIGURATION . " where configuration_key = 'MODULE_GENERIC_SVNUPDATE_SORT_ORDER'");
	$this->_check = tep_db_num_rows($check_query);
      }
      return $this->_check;
    }

    function install() {
      tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added,configuration_type) values ('".addslashes(__("Ordre de tri"))."', 'MODULE_GENERIC_SVNUPDATE_SORT_ORDER', '0', '".addslashes(__("Ordre de tri, dans l'affichage"))."', '1', '0', now(),1)");
    }

    function remove() { return false;    }

    function keys() {
      return array();
    }

}
?>