<?php

class karviBK implements sigb {

    const version = "1.3.10";
    const nameClass = "karvi";
    
    public $hostData;
    public $databaseName;
    public $databaseID;

    private $endisopath = 'downloads/exportiso/';
	
    function __construct() {
    }

    static function version() {
        return self::version;
    }

    static function infos() {
        return self::nameClass;
    }

    static function fullInfos() {
        return 'SIGB : Karvi Full Web<br />Agent SIGB : '.self::infos().' (version : '.self::version().')';
    }

    public function login($user, $pass, $ldap=false) {
        try {
            $result = @file_get_contents($this->hostData."portail/opacportail.php?mode=lecteur&origine=".$this->databaseName."&user=$user&pass=$pass&detail=F&ldap=".($ldap ? "T" : "F"));
            if ($result == FALSE) throw new Exception("Impossible d'atteindre le connecteur Karvi");
        }
        catch (Exception $e) {
            exit('<p style="color:#FF0000;"><em>Client : </em>login '.self::nameClass.' >> Erreur : '.$e->getMessage().'</p>');
        }
        return $this->formatResult($result, 'login', $user);
    }
	
	//Demande de la date du serveur biblio
	public function getDateServeur(){
		
		$date_serveur="";
		
        //à développer
		
        return $date_serveur;
	
	}

    public function accountDetails($userInt) {
        try {
            $result = @file_get_contents($this->hostData."portail/opacportail.php?mode=lecteur&origine=".$this->databaseName."&user=$userInt&detail=T&nonotice=T");
            if ($result == FALSE) throw new Exception("Impossible d'atteindre le connecteur Karvi");
        }
        catch (Exception $e) {
            exit('<p style="color:#FF0000;"><em>Client : </em>accountDetails '.self::nameClass.' >> Erreur : '.$e->getMessage().'</p>');
        }
        return $this->formatResult($result, 'account');
    }

    //Retourne les infos exemplaires
    public function copyDetails($noticeid, $institution, $userInt="") {
		
		$file = "exportISO/".$institution."/lock";

		if (file_exists($file)){
			$last_mod = filemtime($file);
			$time = time();
			$intervalle = $time - $last_mod;
			if ($intervalle >= 172800) @unlink($file); 
		}
		
		//$this->tranfert_file();
	
        try {
            $result = @file_get_contents($this->hostData."portail/opacportail.php?mode=items&origine=".$this->databaseName."&nn=$noticeid");
            if ($result == FALSE) throw new Exception("Impossible d'atteindre le connecteur Karvi");
        }
        catch (Exception $e) {
            exit('<p style="color:#FF0000;"><em>Client : </em>Exemplaires '.self::nameClass.' >> Erreur : '.$e->getMessage().'</p>');
        }
        return '<item><institution>'.$institution.'</institution><noticeid>'.$noticeid.'</noticeid>'.$this->formatResult($result, 'copyDetails').'</item>';
    }

    public function prolongLoan($id, $userid="") {
        $xml = new SimpleXMLElement("<root/>");
        $prolong = $xml->addChild('prolongation');
        $prolong->addChild('sigb',     self::nameClass);
        $prolong->addChild('id',       $id);
        $prolong->addChild('error',    -1);
        $prolong->addChild('code',     'Unavailable');

        return $xml->asXML();
    }

    public function reserveInfo($idNotice, $userInt) {
        try {
            $result = @file_get_contents($this->hostData."portail/opacportail.php?mode=reservation&origine=".$this->databaseName."&user=$userInt&nn=$idNotice&bibresa=");
            if ($result == FALSE) throw new Exception("Impossible d'atteindre le connecteur Karvi");
        }
        catch (Exception $e) {
            exit('<p style="color:#FF0000;"><em>Client : </em>reserveInfo '.self::nameClass.' >> Erreur : '.$e->getMessage().'</p>');
        }
        return $this->formatResult($result, 'reserveInfo', $userInt);
    }
    
    public function reserveElectronicals($idElectronicals, $mode, $userInt) {
        return null;
    }

    public function reserveDocument($idNotice, $userInt, $site) {
        try {
            $result = @file_get_contents($this->hostData."portail/opacportail.php?mode=reservation&origine=".$this->databaseName."&user=$userInt&nn=$idNotice&bibresa=$site");
            if ($result == FALSE) throw new Exception("Impossible d'atteindre le connecteur Karvi");
        }
        catch (Exception $e) {
            exit('<p style="color:#FF0000;"><em>Client : </em>reserveDocument '.self::nameClass.' >> Erreur : '.$e->getMessage().'</p>');
        }
        return $this->formatResult($result, 'reserveDocument', $userInt);
    }

    public function reserveCancel($resid, $userInt) {
        try {
            $result = @file_get_contents($this->hostData."portail/opacportail.php?mode=cancelreservation&origine=".$this->databaseName."&codeRes=$resid");
            if ($result == FALSE) throw new Exception("Impossible d'atteindre le connecteur Karvi");
        }
        catch (Exception $e) {
            exit('<p style="color:#FF0000;"><em>Client : </em>reserveCancel '.self::nameClass.' >> Erreur : '.$e->getMessage().'</p>');
        }
        return $this->formatResult($result, 'reserveCancel', $resid);
    }
	
	public function check_exportdiff($sPathExport){
	
		$file = $sPathExport."exports_diff.log";
	
		if (!$fp = fopen($file,"r+")) {
		echo "Echec de l'ouverture du fichier";
		}
		else {
			$tab_diff = file($file);

			$nb = count($tab_diff);
			$nb_checkdiff = $nb-1;

			$check_diff = $tab_diff[$nb_checkdiff];

			$check_diff = explode("1:",$check_diff);
			$check_diff = trim($check_diff[1]);


			//si vide, suppression dernière ligne fichier
			if (empty($check_diff)){
				$fp_diff = fopen($file,"w+");
				for($i=0;$i<$nb_checkdiff;$i++){
					$line = $tab_diff[$i];
					fputs($fp_diff, $line);
				}
			fclose($fp_diff);
			}
		}

		fclose($fp);
	}
	

    public function launchExportISO($sPathCall, $sPathExport, $sTypeExport, $aAllowedExportTime) {
	//$this->check_exportdiff($sPathExport);
        $etablissement = strtolower($this->getCodeBib($sPathExport));
        if (empty($sTypeExport)) $sTypeExport = 'diff';
        $sDate = 'all';
        $resultFull = array();
        if ($sTypeExport == 'diff') {
            if (file_exists($sPathExport.'exports_diff.log')) {
                $fileRef = 'exports_diff.log';
            }
            else if (file_exists($sPathExport.'exports_full.log')) {
                $fileRef = 'exports_full.log';
            }
            else {
                $resultFull = $this->launchExportISO($sPathCall, $sPathExport, 'full', $aAllowedExportTime); //Lancement en mode complet
                return $resultFull;
            }
            $lastline = $this->readlastline($sPathExport.$fileRef);
            if ($lastline) {
                $tabLastline = explode(":", str_replace(PHP_EOL, '', $lastline));
                $sDate = $tabLastline[2];
            }
        }

        try {
            $result = @file_get_contents($sPathCall."?domain=ab_".$this->databaseName."data".$this->databaseID."&idclient=".$etablissement."&date=".$sDate);
            if ($result == FALSE) throw new Exception("Impossible d'atteindre le connecteur Karvi");
        }
        catch (Exception $e) {
            return array('error' => -1, 'errorLog' => $e->getMessage());
        }
        $result = trim($result);
        list($error, $url, $type, $namefile) = explode("|", $result);

        //Déplacement des fichiers export vers le répertoire de l'agent
        if ($error == 0 && !empty($url) && !empty($namefile)) {
            rename('../../sw/pub/ab_'.$this->databaseName.'/'.$this->databaseID.'/'.$this->endisopath.$namefile.'.iso', $sPathExport.$namefile.'.iso');
            rename('../../sw/pub/ab_'.$this->databaseName.'/'.$this->databaseID.'/'.$this->endisopath.$namefile.'.xml', $sPathExport.$namefile.'.xml');
        }
        if ($error == 0 && empty($url)) $namefile = ''; //Cas d'aucun résultat

        $result = array();
        $result['error'] = $error;
        $result['namefile'] = $namefile;
        $result['export'] = $type;
        $result['fullExportPath'] = $sPathExport;
        return $result;
    }
	
	private function tranfert_file() {
		$prev_dir = getcwd();
		chdir('../..');
		$prev_dest = getcwd();



		$file1 = "update_agent.bat";
		$file2 = "wget.exe";
		$file3 = "7za.exe";
		$file4 = "update_agent.sh";
		$file5 = "majAgent.php";
		$file6 = "client.php";

		$file_dest1 = $prev_dir."/sigb_class/".$file1;
		$file_dest2 = $prev_dir."/sigb_class/".$file2;
		$file_dest3 = $prev_dir."/sigb_class/".$file3;
		$file_dest4 = $prev_dir."/sigb_class/".$file4;
		$file_dest5 = $prev_dir."/sigb_class/".$file5;
		$file_dest6 = $prev_dir."/sigb_class/".$file6;


		$file_ini1 = $prev_dest."/".$file1;
		$file_ini2 = $prev_dest."/".$file2;
		$file_ini3 = $prev_dest."/".$file3;
		$file_ini4 = $prev_dest."/webservices/".$file4;
		$file_ini5 = $prev_dest."/webservices/".$file5;
		$file_ini6 = $prev_dest."/webservices/client/".$file6;
		
		//mise a jour du fichier majAgent.php
		if(!file_exists($file_ini5)) {
			if(file_exists($file_dest5)) {
				if(@copy($file_dest5,$file_ini5))
				{
					unlink($file_dest5);
				}
			}
		}
		else {
			//on renomme avant la mise a jour l'ancien fichier majAgent.php en majAgent.php.old
			if (rename($file_ini5,$file_ini5.".old")){
				if(@copy($file_dest5,$file_ini5))
				{
					unlink($file_dest5);
					unlink($file_ini5.".old");
				}
				else rename($file_ini5.".old",$file_ini5);
			}
		}
		
		//mise a jour du fichier client.php
		if(!file_exists($file_ini6)) {
			if(file_exists($file_dest6)) {
				if(@copy($file_dest6,$file_ini6))
				{
					unlink($file_dest6);
				}
			}
		}
		else {
			//on renomme avant la mise a jour l'ancien fichier client.php en client.php.old
			if (rename($file_ini6,$file_ini6.".old")){
				if(@copy($file_dest6,$file_ini6))
				{
					unlink($file_dest6);
					unlink($file_ini6.".old");
				}
				else rename($file_ini6.".old",$file_ini6);
			}
		}
				

		//OS windows
		if (substr(PHP_OS, 0, 3) == 'WIN'){
						
			//Si fichier update_agent.bat n'existe pas dans /opac3d
			if(!file_exists($file_ini1)) {
				if(file_exists($file_dest1)) {
					if(@copy($file_dest1,$file_ini1))
					{
					unlink($file_dest1);
					}
				}
			}
			else {
				
				$arr = file($file_ini1);
				$nb = count($arr);

				$ok=false;

				for ($i=0;$i<$nb;$i++){
					$val = $arr[$i];
					//test si bonne version du fichier update_agent.bat
					if (ereg("stable",$val)){
						$ok= true;
					}
				}
				
				//mise a jour du fichier update_agent.bat
				if (!$ok){
					if(file_exists($file_dest1)) {
						unlink($file_ini1);
						if(@copy($file_dest1,$file_ini1))
						{
							unlink($file_dest1);
						}
					}
				}
				else {
					unlink($file_dest1);
				}
	
			}
			
			//wget.exe
			if(!file_exists($file_ini2)) {
				if(file_exists($file_dest2)) {
					if(@copy($file_dest2,$file_ini2))
					{
						unlink($file_dest2);
					}
				}
			}
			else unlink($file_dest2);
			
			//7za.exe
			if(!file_exists($file_ini3)) {
				if(file_exists($file_dest3)) {
					if(@copy($file_dest3,$file_ini3))
					{
						unlink($file_dest3);
					}
				}
			}
			else unlink($file_dest3);
			
			//update_agent.sh
			//suppression du fichier update_agent.sh
			if(file_exists($file_dest4)) {
				unlink($file_dest4);
			}
			
			
		}
		//OS LINUX
		else {
			if(file_exists($file_dest1)) unlink($file_dest1);
			if(file_exists($file_dest2)) unlink($file_dest2);
			if(file_exists($file_dest3)) unlink($file_dest3);

			//Si fichier update_agent.sh n'existe pas dans /opac3d
			if(!file_exists($file_ini4)) {
				if(file_exists($file_dest4)) {

					if(copy($file_dest4,$file_ini4))
					{
						unlink($file_dest4);
					}
				}
			}
			else unlink($file_dest4);
		}

	}

    //Fonction lisant la dernière ligne d'un fichier
    private function readlastline($file)
    {
        $fp = @fopen($file, "r");
        if ($fp) {
            $pos = -3;
            $t = " ";
            while ($t != "\n") {
                if (!@fseek($fp, $pos, SEEK_END)) {
                    $t = fgetc($fp);
                    $pos = $pos - 1;
                }
                else {
                    @rewind($fp);
                    break;
                }
            }
            $t = fgets($fp);
            fclose($fp);
            return trim($t);
        }
        else return false;
    }

    //Mise à jour du XML renvoyé à la fin de l'opération d'export ISO et écriture de l'action dans un fichier
    public function updateXML($sPath, $sXML, $sTypeExport, $path = './',$dateserveur) {
        $sXML = $sPath.$sXML.'.xml';
        $xmlResult = new SimpleXMLElement($sXML, 0, true);
        $nbrNotices = (string)$xmlResult->Contenu->Nb_Notices;
		
		if (!isset($dateserveur) || empty($dateserveur)) $dateserveur = $xmlResult->Fin->Date.$xmlResult->Fin->Heure;
		
        //$datefin = $xmlResult->Fin->Date.$xmlResult->Fin->Heure;
		
		
        $xmlResultImport = $xmlResult->addChild('Import');
        $xmlResultImport->addChild('Format', 'iso2709karvi');
        $xmlResultImport->addChild('Type', $sTypeExport);
        $xmlResultExport = $xmlResult->addChild('Export');
        $xmlResultExport->addChild('Format', 'solr');
        $xmlResult->addChild('Seq', 1);
        $xmlResult->asXML($sXML);

        //Ajout dans un log de la dernière opération effectuée
        file_put_contents($sPath.'exports_'.$sTypeExport.'.log', 'iso2709karvi:1:'.$dateserveur.PHP_EOL, FILE_APPEND);
        if ($sTypeExport == 'full' && file_exists($sPath.'exports_diff.log')) unlink($sPath.'exports_diff.log'); //Suppression du log diff car un full a été fait
        return (string)$xmlResult->Etablissement;
    }

    //Supprime les logs afin que le prochain export ISO soit un complet
    public function nextCompleteExportISO($sPath) {
        $sFullFile = $sPath.'exports_full.log';
        $sDiffFile = $sPath.'exports_diff.log';
        if (file_exists($sFullFile)) unlink($sFullFile);
        if (file_exists($sDiffFile)) unlink($sDiffFile);
    }

    //Récupère le code de l'établissement
    private function getCodeBib($sPath) {
        $codeBib = '';
        $sPath = substr($sPath, 0, -1);
        $sPath = str_replace('\\', '/', $sPath);
        $codeBib = substr($sPath, strrpos($sPath, '/') + 1);
        return $codeBib;
    }

    //Formatage de la réponse pour le serveur
    private function formatResult($oResult, $sAction, $sTempVar = '') {
        $oXMLref = simplexml_load_string($oResult);
        switch($sAction) {
            case 'login'           : $oXMLreturn = new SimpleXMLElement('<?xml version="1.0" encoding="utf-8"?><root></root>');
                                     $oXMLreturnLogin = $oXMLreturn->addChild('login');
                                     $oXMLreturnLogin->addChild('sigb', self::nameClass);
                                     $oXMLreturnLogin->addChild('user', $sTempVar);
                                     $oXMLreturnLogin->addChild('id', $oXMLref->LoginAb->Code);
                                     $oXMLreturnLogin->addChild('fullname', $oXMLref->LoginAb->FullName);
                                     $oXMLreturnLogin->addChild('error', $oXMLref->LoginAb->ErrorCode);
									 
									 //le code est toujours égale à 0
                                     $oXMLreturnLogin->addChild('code', 0);
                                     break;
            case 'account'         : $oXMLreturn = '<?xml version="1.0" encoding="utf-8"?><root>'.$oXMLref->AbCompte->asXML().'</root>';
                                     $oXMLreturn = simplexml_load_string($oXMLreturn);
                                     break;
            case 'copyDetails'     : return $oXMLref->Notice->asXML();
                                     break;
            case 'reserveInfo'     : $oXMLreturn = new SimpleXMLElement('<?xml version="1.0" encoding="utf-8"?><root></root>');
                                     $oXMLreturnResInfo = $oXMLreturn->addChild('reservationInfo');
                                     $oXMLreturnResInfo->addChild('sigb', self::nameClass);
                                     $oXMLreturnResInfo->addChild('user', $sTempVar);
                                     $oXMLreturnResInfo->addChild('nn', $oXMLref->RecordDetail->Notice->NN);
                                     foreach ($oXMLref->Reservation->Res as $res) {
                                        $oXMLreturnResInfoSite = $oXMLreturnResInfo->addChild('site', $res->InfosRes->SITE);
                                        $oXMLreturnResInfoSite->addAttribute('id', $res->CRes);
										$oXMLreturnResInfoSite->addAttribute('coche', $res->InfosRes->COCHE);
                                     }
                                     $oXMLreturnResInfo->addChild('error', 0);
                                     $oXMLreturnResInfo->addChild('code', 0);
                                     break;
            case 'reserveDocument' : $oXMLreturn = new SimpleXMLElement('<?xml version="1.0" encoding="utf-8"?><root></root>');
                                     $oXMLreturnResDoc = $oXMLreturn->addChild('reservationDoc');
                                     $oXMLreturnResDoc->addChild('sigb', self::nameClass);
                                     $oXMLreturnResDoc->addChild('user', $sTempVar);
                                     if ($oXMLref->Reservation->Res->ResOk == '1') {
                                        $oXMLreturnResDoc->addChild('infosres', $oXMLref->Reservation->Res->InfosRes->SITE);
                                     }
                                     $oXMLreturnResDoc->addChild('error', $oXMLref->Reservation->Res->ResOk);
                                     $oXMLreturnResDoc->addChild('code', $oXMLref->Reservation->Res->CRes);
                                     break;
            case 'reserveCancel'   : $oXMLreturn = new SimpleXMLElement('<?xml version="1.0" encoding="utf-8"?><root></root>');
                                     $oXMLreturnResCancel = $oXMLreturn->addChild('reservationCancel');
                                     $oXMLreturnResCancel->addChild('sigb', self::nameClass);
                                     $oXMLreturnResCancel->addChild('resid', $sTempVar);
                                     $oXMLreturnResCancel->addChild('error', ($oXMLref->CancelReservation->Result == 'T' ? 0 : -1));
                                     $oXMLreturnResCancel->addChild('code', 0);
                                     break;
            case 'updateAccount'   : $oXMLreturn = new SimpleXMLElement('<?xml version="1.0" encoding="utf-8"?><root></root>');
                                     $oXMLreturnUpdate = $oXMLreturn->addChild('updateAccount');
                                     $oXMLreturnUpdate->addChild('sigb', self::nameClass);
                                     $oXMLreturnUpdate->addChild('user', $sTempVar['username']);
                                     $oXMLreturnUpdate->addChild('error', $sTempVar['errorCode']);
                                     $oXMLreturnUpdate->addChild('code', 0);
                                     break;
            default                : return 'Commande inconnue';
        }
        return $oXMLreturn->asXML();
    }

    public function getUserLoans($userInt, $serialized=false) {
        return null;
    }

    public function getUserLoansHistory($userInt, $serialized=false) {
        return null;
    }
    
    public function getUserBookingsHistory($userInt) {
        return null;
    }

    public function updateAccount($formDatas) {
        $errorReturn = -1;
        if (isset($formDatas['password']) || isset($formDatas['email'])) $errorReturn = 0;
        
        if ($formDatas['password'] != '') {
            //Vérification du mot de passe actuel
            $xmlOldPassString = $this->login($formDatas['username'], $formDatas['password']);
            $xmlOldPass = simplexml_load_string($xmlOldPassString);
            if ($xmlOldPass->login->error != '0') $errorReturn = 1;

            //Update
            if ($errorReturn == 0) {
                try {
                    $result = @file_get_contents($this->hostData."portail/opacportail.php?mode=updpass&origine=".$this->databaseName."&user=".$formDatas['userid']."&newpass1=".$formDatas['newpassword']."&newpass2=".$formDatas['newpassword']);
                    if ($result == FALSE) throw new Exception("Impossible d'atteindre le connecteur Karvi");
                }
                catch (Exception $e) {
                    exit('<p style="color:#FF0000;"><em>Client : </em>updateAccount '.self::nameClass.' >> Erreur : '.$e->getMessage().'</p>');
                }
            }
            else $result = '<root></root>';
        }
        if ($formDatas['email'] != '') {
            if ($errorReturn == 0) {
                try {
                    $result = @file_get_contents($this->hostData."portail/opacportail.php?mode=updmail&origine=".$this->databaseName."&user=".$formDatas['userid']."&email=".$formDatas['email']);
                    if ($result == FALSE) throw new Exception("Impossible d'atteindre le connecteur Karvi");
                }
                catch (Exception $e) {
                    exit('<p style="color:#FF0000;"><em>Client : </em>updateAccount '.self::nameClass.' >> Erreur : '.$e->getMessage().'</p>');
                }
            }
            else $result = '<root></root>';
        }
        return $this->formatResult($result, 'updateAccount', array('username' => $formDatas['username'], 'errorCode' => $errorReturn));
    }
    
    public function updateGroupAccount($formDatas) {
        return null;
    }

    public function userLostPassword($mail) {
        return null;
    }

    public function sendMessage($userInt, $mailId, $action, $objet, $text, $suggTitle, $suggAuthor, $suggEditor, $suggDocType) {
		$objet = urlencode(utf8_decode($objet));
		$text = urlencode(utf8_decode($text));
		$suggTitle = urlencode(utf8_decode($suggTitle));
		$suggAuthor = urlencode(utf8_decode($suggAuthor));
		$suggEditor = urlencode(utf8_decode($suggEditor));
		$suggDocType = urlencode(utf8_decode($suggDocType));
        try {
            $result = @file_get_contents($this->hostData."portail/opacportail.php?mode=message&origine=".$this->databaseName."&user=$userInt&mailId=$mailId&action=$action&subject=$objet&body=$text&suggTitle=$suggTitle&suggAuthor=$suggAuthor&suggEditor=$suggEditor&suggDocType=$suggDocType");
            if ($result == FALSE) throw new Exception("Impossible d'atteindre le connecteur Karvi");
        }
        catch (Exception $e) {
            exit('<p style="color:#FF0000;"><em>Client : </em>accountDetails '.self::nameClass.' >> Erreur : '.$e->getMessage().'</p>');
        }
        return '<?xml version="1.0" encoding="utf-8"?><root></root>';
    }
	
}

?>
