<?php

class aloesBK implements sigb {
    
    const version = "1.5.17";
    const nameClass = "aloes";
    
    public $hostData;
    public $databaseName;
    public $databaseID;

    private $sessionID;

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

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

    static function fullInfos() {
        return 'SIGB : Aloes<br />Agent SIGB : '.self::infos().' (version : '.self::version().')';
    }
    
    private function callWsdl() {
        try {
            return new SoapClient($this->hostData.'?WSDL');
        }
        catch (Exception $e) {
            exit('<p style="color:#FF0000;"><em>Client : </em>login '.self::nameClass.' >> Erreur : '.$e->getMessage().'</p>');
        }
    }
    
    private function openSessionAloes() {
        list($server, $posteClient) = explode('\\', $this->databaseName, 2);
        $BaseSession = new BaseSession($this->databaseID);
        $ArrayOfBaseSession = array($BaseSession);
        $ServeurSession = new ServeurSession($ArrayOfBaseSession, $server);
        $ArrayOfServeurSession = array($ServeurSession);
        $EntOuvrirSession = new EntOuvrirSession($posteClient, $ArrayOfServeurSession);
        $params = array('Param' => $EntOuvrirSession);
        $result = $this->callWsdl()->OuvrirSession($params);
        try {
            if ($result->OuvrirSessionResult->GUIDSession == '') throw new Exception('Impossible d\'ouvrir une session Aloes');
            $this->sessionID = $result->OuvrirSessionResult->GUIDSession;
        }
        catch (Exception $e) {
            exit('<p style="color:#FF0000;"><em>Client : </em>login '.self::nameClass.' >> Erreur : '.$e->getMessage().'</p>');
        }
    }

    public function login($user, $pass, $ldap=false) {
        try {
            $this->openSessionAloes();
            $EntEmprAuthentifier = new EntEmprAuthentifier($this->sessionID, $user, $pass);
            $params = array('Param' => $EntEmprAuthentifier);
            $result = $this->callWsdl()->EmprAuthentifier($params);
            if ($result === false) throw new Exception('Impossible d\'appeler la méthode Aloes EmprAuthentifier');
        }
        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="";
        return $date_serveur;
    }

    public function accountDetails($idSession) {
        try {          
            $xmlAccount = new SimpleXMLElement('<?xml version="1.0" encoding="utf-8" ?><Root></Root>');
            $xmlAccountAbCompte = $xmlAccount->addChild('AbCompte');
            //Infos
            $EntEmprListerEntite = new EntEmprListerEntite($idSession, 'ListeInfo');
            $params = array('Param' => $EntEmprListerEntite);
            $result = $this->callWsdl()->EmprListerEntite($params);
            if ($result === false) {
                throw new Exception('Impossible d\'appeler la méthode Aloes EmprListerEntite (ListeInfo)');
            }
            if (!isset($result->EmprListerEntiteResult->ErreurService)) {
                $xmlAccountF000 = $xmlAccountAbCompte->addChild('F000');
                $xmlAccountF100 = $xmlAccountAbCompte->addChild('F100');
                $xmlAccountF200 = $xmlAccountAbCompte->addChild('F200');
                $enteteDonnees = array_flip($result->EmprListerEntiteResult->Entite->LibelleDonnee->string);
                $xmlAccountF000->addChild('SF3', $result->EmprListerEntiteResult->Entite->Donnees->Lignes->ValeursDonnees->string[$enteteDonnees['CodeBarre']]);
                $xmlAccountF000->addChild('SFd', 5);
                $xmlAccountF000->addChild('SFe', 10);
                $xmlAccountF000->addChild('SFg', $result->EmprListerEntiteResult->Entite->Donnees->Lignes->ValeursDonnees->string[$enteteDonnees['email']]);
                $xmlAccountF000->addChild('SFm', $result->EmprListerEntiteResult->Entite->Donnees->Lignes->ValeursDonnees->string[$enteteDonnees['BibInscription']]);
                $dateNaissance = $result->EmprListerEntiteResult->Entite->Donnees->Lignes->ValeursDonnees->string[$enteteDonnees['DateNaissance']];
                $xmlAccountF000->addChild('SFn', $this->convertDateToYMD($dateNaissance));
                $xmlAccountF100->addChild('SFa', $result->EmprListerEntiteResult->Entite->Donnees->Lignes->ValeursDonnees->string[$enteteDonnees['Nom']].', '.$result->EmprListerEntiteResult->Entite->Donnees->Lignes->ValeursDonnees->string[$enteteDonnees['Prénom']]);
                $xmlAccountF100->addChild('SFc', $result->EmprListerEntiteResult->Entite->Donnees->Lignes->ValeursDonnees->string[$enteteDonnees['BibInscription']]);
                $xmlAccountF100->addChild('SF3', $result->EmprListerEntiteResult->Entite->Donnees->Lignes->ValeursDonnees->string[$enteteDonnees['CodeBarre']]);
                $xmlAccountF200->addChild('SFa', $result->EmprListerEntiteResult->Entite->Donnees->Lignes->ValeursDonnees->string[$enteteDonnees['BibInscription']].' (solde : '.$result->EmprListerEntiteResult->Entite->Donnees->Lignes->ValeursDonnees->string[$enteteDonnees['Solde']].')');
                $dateDebutAbo = $this->convertDateToYMD($result->EmprListerEntiteResult->Entite->Donnees->Lignes->ValeursDonnees->string[$enteteDonnees['Réinscrip.']]);
                $dateFinAbo = $this->convertDateToYMD($result->EmprListerEntiteResult->Entite->Donnees->Lignes->ValeursDonnees->string[$enteteDonnees['Expire le']]);
                $xmlAccountF200->addChild('SFb', $dateDebutAbo);
                $xmlAccountF200->addChild('SFc', $dateFinAbo);
            }
            //Prets
            $EntEmprListerEntite = new EntEmprListerEntite($idSession, 'ListePret');
            $params = array('Param' => $EntEmprListerEntite);
            $result = $this->callWsdl()->EmprListerEntite($params);
            if ($result === false) throw new Exception('Impossible d\'appeler la méthode Aloes EmprListerEntite (ListePret)');
            if (!isset($result->EmprListerEntiteResult->ErreurService)) {
                if ($result->EmprListerEntiteResult->Entite) {
                    $enteteDonnees = array_flip($result->EmprListerEntiteResult->Entite->LibelleDonnee->string);
                    foreach ($result->EmprListerEntiteResult->Entite->Donnees->Lignes as $key => $pret) {
                        if (is_numeric($key)) {
                            $pret = $pret->ValeursDonnees;
                        }
                        $xmlAccountF400 = $xmlAccountAbCompte->addChild('F400');
                        $xmlAccountF400->addChild('SFa', $pret->string[$enteteDonnees['No Notice Mère']]);
                        $xmlAccountF400->addChild('SFb', $this->convertDateToYMD($pret->string[$enteteDonnees['Emprunté le|FILTREDATE']]));
                        $xmlAccountF400->addChild('SFc', $this->convertDateToYMD($pret->string[$enteteDonnees['Retour prévu le']]));
                        $xmlAccountF400->addChild('SFd', $pret->string[$enteteDonnees['Bibliothèque']]);
                        $xmlAccountF400->addChild('SFj', 'T');
                        $xmlAccountF400->addChild('SFk', $pret->string[$enteteDonnees['No Prêt']]);
                    }
                }
            }
            //Prets en retard
            $EntEmprListerEntite = new EntEmprListerEntite($idSession, 'ListeRetard');
            $params = array('Param' => $EntEmprListerEntite);
            $result = $this->callWsdl()->EmprListerEntite($params);
            if ($result === false) throw new Exception('Impossible d\'appeler la méthode Aloes EmprListerEntite (ListeRetard)');
            if (!isset($result->EmprListerEntiteResult->ErreurService)) {
                if ($result->EmprListerEntiteResult->Entite) {
                    $enteteDonnees = array_flip($result->EmprListerEntiteResult->Entite->LibelleDonnee->string);
                    foreach ($result->EmprListerEntiteResult->Entite->Donnees->Lignes as $key => $pret) {
                        if (is_numeric($key)) {
                            $pret = $pret->ValeursDonnees;
                        }
                        $xmlAccountF400 = $xmlAccountAbCompte->addChild('F400');
                        $xmlAccountF400->addChild('SFa', $pret->string[$enteteDonnees['No Notice Mère']]);
                        $xmlAccountF400->addChild('SFb', $this->convertDateToYMD($pret->string[$enteteDonnees['Emprunté le|FILTREDATE']]));
                        $xmlAccountF400->addChild('SFc', $this->convertDateToYMD($pret->string[$enteteDonnees['A rendre le|FILTREDATE']]));
                        $xmlAccountF400->addChild('SFd', $pret->string[$enteteDonnees['Bibliothèque']]);
                        $xmlAccountF400->addChild('SFe', 'T');
                        $xmlAccountF400->addChild('SFj', 'F');
                        $xmlAccountF400->addChild('SFk', $pret->string[$enteteDonnees['No Prêt']]);
                    }
                }
            }
            //Resas
            $EntEmprListerEntite = new EntEmprListerEntite($idSession, 'ListeResa');
            $params = array('Param' => $EntEmprListerEntite);
            $result = $this->callWsdl()->EmprListerEntite($params);
            if ($result === false) throw new Exception('Impossible d\'appeler la méthode Aloes EmprListerEntite (ListeResa)');
            if (!isset($result->EmprListerEntiteResult->ErreurService)) {
                if ($result->EmprListerEntiteResult->Entite) {
                    $enteteDonnees = array_flip($result->EmprListerEntiteResult->Entite->LibelleDonnee->string);
                    foreach ($result->EmprListerEntiteResult->Entite->Donnees->Lignes as $key => $resa) {
                        if (is_numeric($key)) {
                            $resa = $resa->ValeursDonnees;
                        }
                        $xmlAccountF500 = $xmlAccountAbCompte->addChild('F500');
                        //ajouter l'id de la résa
                        $xmlAccountF500->addChild('SFa', $resa->string[$enteteDonnees['idmere']]);
                        $xmlAccountF500->addChild('SFb', $this->convertDateToYMD($resa->string[$enteteDonnees['Depuis le']]));
                        $etatPhrase = $resa->string[4];
                        if (strpos($etatPhrase, 'Réservation satisfaite') !== false) {
                            $etat = 'D';
                        }
                        else {
                            $etat = 'A';
                        }
                        $xmlAccountF500->addChild('SFd', $etat);
                        if ($etat == 'D') {
                            $xmlAccountF500->addChild('SFj', substr($etatPhrase, strpos($etatPhrase, 'disponible à') + 14));
                        }
                        if ($etat == 'A') {
                            $xmlAccountF500->addChild('SFh', $resa->string[$enteteDonnees['No réservation']]);
                        }
                        //Rang, nouvelle lettre "l"
                        $xmlAccountF500->addChild('SFl', $resa->string[$enteteDonnees['Rang|LISTETEXTE']]);
                    }
                }
            }
        }
        catch (Exception $e) {
            exit('<p style="color:#FF0000;"><em>Client : </em>accountDetails '.self::nameClass.' >> Erreur : '.$e->getMessage().'</p>');
        }
        return $this->formatResult($xmlAccount, '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 {
            $this->openSessionAloes();
            $AffichageNotice = new AffichageNotice('3');
            $EntRecupererNotice = new EntRecupererNotice($this->sessionID, 0, $noticeid, '', array($AffichageNotice), array(''));
            $params = array('Param' => $EntRecupererNotice);
            $result = $this->callWsdl()->RecupererNotice($params);
            if ($result === false) throw new Exception('Impossible d\'appeler la méthode Aloes RecupererNotice');
        }
        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="") {
        try {
            $tabPrets = array($id);
            $EntEmprProlong = new EntEmprProlong($userid, $tabPrets);
            $params = array('Param' => $EntEmprProlong);
            $result = $this->callWsdl()->EmprProlong($params);
            if ($result === false) throw new Exception('Impossible d\'appeler la méthode Aloes EmprProlong');
            if ($messageRetour = $result->EmprProlongResult->MessageRetour) {
                if (substr($messageRetour, 0, 2) == 'OK') {
                    $error = 0;
                }
                else {
                    $error = $messageRetour;
                }
            }
            else {
                $error = $result->EmprProlongResult->ErreurService->LibelleErreur;
            }
            $xml = new SimpleXMLElement('<?xml version="1.0" encoding="utf-8"?><root></root>');
            $prolong = $xml->addChild('prolongation');
            $prolong->addChild('sigb', self::nameClass);
            $prolong->addChild('id', $id);
            $prolong->addChild('error', $error);
            $prolong->addChild('code', $result->EmprProlongResult->Reussite);
            return $xml->asXML();
        }
        catch (Exception $e) {
            exit('<p style="color:#FF0000;"><em>Client : </em>Exemplaires '.self::nameClass.' >> Erreur : '.$e->getMessage().'</p>');
        }
    }

    public function reserveInfo($idNotice, $idSession) {
        try {
            $AffichageNotice = new AffichageNotice('3');
            $EntRecupererNotice = new EntRecupererNotice($idSession, 0, $idNotice, '', array($AffichageNotice), array(''));
            $params = array('Param' => $EntRecupererNotice);
            $result = $this->callWsdl()->RecupererNotice($params);
            if ($result === false) throw new Exception('Impossible d\'appeler la méthode Aloes RecupererNotice');
        }
        catch (Exception $e) {
            exit('<p style="color:#FF0000;"><em>Client : </em>Exemplaires '.self::nameClass.' >> Erreur : '.$e->getMessage().'</p>');
        }
        return $this->formatResult($result, 'reserveInfo', array('notice' => $idNotice, 'user' => $userInt));
    }

    public function reserveDocument($idNotice, $idSession, $site) {
        try {
            if (strpos($site, "|") !== false) {
                list ($idNotice, $site) = explode("|", $site, 2);
            }
            $tabNotices = array($idNotice);
            $EntEmprReserver = new EntEmprReserver($idSession, $tabNotices);
            $params = array('Param' => $EntEmprReserver, 'CodeLieu' => $site);
            $result = $this->callWsdl()->EmprReserver($params);
            if ($result === false) throw new Exception('Impossible d\'appeler la méthode Aloes EmprReserver');
        }
        catch (Exception $e) {
            exit('<p style="color:#FF0000;"><em>Client : </em>reserveDocument '.self::nameClass.' >> Erreur : '.$e->getMessage().'</p>');
        }
        return $this->formatResult($result, 'reserveDocument', array('user' => $idSession, 'site' => $site));
    }

    public function reserveCancel($resid, $idSession) {
        try {
            $resa = new ResaIdType($resid, 'Reservation');
            $ArrayOfResaIdType = array($resa);
            $EntEmprSupprResa = new EntEmprSupprResa($idSession, $ArrayOfResaIdType);
            $params = array('Param' => $EntEmprSupprResa);
            $result = $this->callWsdl()->EmprSupprResa($params);
            if ($result === false) throw new Exception('Impossible d\'appeler la méthode Aloes EmprSupprResa');
        }
        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) {
        $etablissement = strtolower($this->getCodeBib($sPathExport));
        if (empty($sTypeExport)) $sTypeExport = 'diff';
        if (file_exists($sPathCall.'EXPORTDIFFBIB')) {
            $pathNamefile = $sPathCall.'EXPORTDIFFBIB';
            $namefile = 'EXPORTDIFFBIB';
        }
        else if (file_exists($sPathCall.'EXPORTCOMPLETBIB')) {
            $sTypeExport = 'full';
            $pathNamefile = $sPathCall.'EXPORTCOMPLETBIB';
            $namefile = 'EXPORTCOMPLETBIB';
        }
        else {
            $error = 0;
            $namefile = '';
        }
        
        if ($error == 0 && !empty($namefile)) {
            $namefile = date("Ymd-His");
            //Vérification que le fichier n'est pas en train d'arriver
            $fileSize = filesize($pathNamefile);
            sleep(2);
            $newFileSize = filesize($pathNamefile);
            if ($newFileSize == $fileSize) {
                rename($pathNamefile, $sPathExport.$namefile.'.iso');
                $this->createXMLExport($sPathExport, $namefile, $etablissement, $fileSize);
            }
            else {
                $namefile = '';
            }
        }

        $result = array();
        $result['error'] = $error;
        $result['namefile'] = $namefile;
        $result['export'] = $sTypeExport;
        $result['fullExportPath'] = $sPathExport;
        return $result;
    }

    private function createXMLExport($pathExport, $nameFile, $idClient, $fileSize) {
        list($date, $heure) = explode("-", $nameFile);
        $nbNotices = ceil($fileSize/1000); //calcul environ du nombre de notices
        $xmlExport = new SimpleXMLElement('<?xml version="1.0" encoding="utf8"?><Root></Root>');
        $xmlExport->addChild('Etablissement', $idClient);
        $debutNode = $xmlExport->addChild('Debut');
        $debutNode->addChild('Date', $date);
        $debutNode->addChild('Heure', $heure);
        $finNode = $xmlExport->addChild('Fin');
        $finNode->addChild('Date', $date);
        $finNode->addChild('Heure', $heure);
        $contenuNode = $xmlExport->addChild('Contenu');
        $contenuNode->addChild('Nb_Notices', $nbNotices);
        $xmlExport->saveXML($pathExport.$nameFile.'.xml');
    }
    
    //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);
        if (!isset($dateserveur) || empty($dateserveur)) $dateserveur = $xmlResult->Fin->Date.$xmlResult->Fin->Heure;
        $xmlResultImport = $xmlResult->addChild('Import');
        $xmlResultImport->addChild('Format', 'iso2709aloes');
        $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', 'iso2709aloes: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;
    }

    public function nextCompleteExportISO($sPath) {
        return null;
    }

    //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;
    }

    private function checkExemplaireReservable($exemplaireObj) {
        return preg_match('/\d{2}\/\d{2}\/\d{4}/', $exemplaireObj->DonneesFille->DonneeFille[8]->ValeurDonnee) && strtolower($this->replaceAccentedChars($exemplaireObj->DonneesFille->DonneeFille[11]->ValeurDonnee)) != 'non reservable';
    }
    
    private function replaceAccentedChars($string) {
        return utf8_encode(strtr(utf8_decode($string), utf8_decode('ÀÁÂÃÄÅàáâãäåÒÓÔÕÖØòóôõöøÈÉÊËéèêëÇçÌÍÎÏìíîïÙÚÛÜùúûüÿÑñ'), 'AAAAAAaaaaaaOOOOOOooooooEEEEeeeeCcIIIIiiiiUUUUuuuuyNno'));
    }
    
    //Formatage de la réponse pour le serveur
    private function formatResult($oResult, $sAction, $sTempVar = '') {
        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', $oResult->EmprAuthentifierResult->IDEmprunteur);
                                     $oXMLreturnLogin->addChild('id', $oResult->EmprAuthentifierResult->GUIDSession); //Pour les appels suivants, seule l'id session suffit
                                     $oXMLreturnLogin->addChild('fullname', $oResult->EmprAuthentifierResult->IdentiteEmpr);
                                     $oXMLreturnLogin->addChild('error', $oResult->EmprAuthentifierResult->ErreurService->CodeErreur == '0' ? 1 : 0);
                                     $oXMLreturnLogin->addChild('code', 0);
                                     break;
            case 'account'         : $oXMLreturn = '<?xml version="1.0" encoding="utf-8"?><root>'.$oResult->AbCompte->asXML().'</root>';
                                     $oXMLreturn = simplexml_load_string($oXMLreturn);
                                     break;
            case 'copyDetails'     : $oXMLreturn = new SimpleXMLElement('<?xml version="1.0" encoding="utf-8"?><root></root>');
                                     $noticeNode = $oXMLreturn->addChild('Notice');
                                     $unimarcNode = $noticeNode->addChild('Unimarc');
                                     $atLeastReservable = false;
                                     if (!is_array($oResult->RecupererNoticeResult->Notice->Exemplaires->NoticesFilles->NoticeFille)) {
                                         $oResult->RecupererNoticeResult->Notice->Exemplaires->NoticesFilles->NoticeFille = array($oResult->RecupererNoticeResult->Notice->Exemplaires->NoticesFilles->NoticeFille);
                                     }
                                     $tabCodesEtatAloes = array(
                                        1 => 'Exemplaire disponible',
                                        2 => 'Mis à disposition d\'une réservation',
                                        3 => 'Non disponible (en prêt)',
                                        4 => 'Rendu ce jour',
                                        5 => 'Exclu définitivement',
                                        6 => 'Exclu temporairement',
                                        7 => 'En transit',
                                        8 => 'Consultation sur place'
                                     );
                                     foreach ($oResult->RecupererNoticeResult->Notice->Exemplaires->NoticesFilles->NoticeFille as $exemplaire) {
                                         $numInterne = $exemplaire->NumFille;
                                         if ($numInterne != '') {
                                            //Disponibilité
                                            $state = intval($exemplaire->DonneesFille->DonneeFille[17]->ValeurDonnee);
                                            switch ($state) {
                                                case 3:
                                                    if (preg_match('/\d{2}\/\d{2}\/\d{4}/', $exemplaire->DonneesFille->DonneeFille[8]->ValeurDonnee)) {
                                                        $dispo = 4;
                                                    }
                                                    else {
                                                        $dispo = 6;
                                                    }
                                                    break;
                                                case 1:
                                                case 4:
                                                case 8:
                                                    $dispo = 1;
                                                    break;
                                                case 2:
                                                    $dispo = 3;
                                                    break;
                                                default:
                                                    $dispo = 6;
                                            }
                                            //Reservable
                                            if ($this->checkExemplaireReservable($exemplaire)) {
                                                $atLeastReservable = true;
                                            }
                                            $F941Node = $unimarcNode->addChild('F941');
                                            $F941Node->addChild('SFh', $numInterne);
                                            $F941Node->addChild('SFa', $exemplaire->DonneesFille->DonneeFille[9]->ValeurDonnee);
                                            //$F941Node->addChild('SFz', $exemplaire->DonneesFille->DonneeFille[3]->ValeurDonnee);
                                            $F941Node->addChild('SFc', $exemplaire->DonneesFille->DonneeFille[6]->ValeurDonnee);
                                            $F941Node->addChild('SFv', $exemplaire->DonneesFille->DonneeFille[0]->ValeurDonnee);
                                            $F941Node->addChild('SFo', $dispo);
                                            if ($dispo == 4) {
                                                $F941Node->addChild('SFq', $this->convertDateToYMD($exemplaire->DonneesFille->DonneeFille[8]->ValeurDonnee));
                                            }
                                            if ($dispo == 3 && $exemplaire->DonneesFille->DonneeFille[15]->ValeurDonnee) {
                                                $F941Node->addChild('SFn', 'Rang : '.$exemplaire->DonneesFille->DonneeFille[15]->ValeurDonnee);
                                            }
                                            if ($dispo == 6) {
                                                $F941Node->addChild('SFn', 'Indisponible ('.$tabCodesEtatAloes[$state].')');
                                            }
                                            if ($state == 8) {
                                                $F941Node->addChild('SFn', $tabCodesEtatAloes[$state]);
                                            }
                                            $F941fields = $F941Node->addChild('fields');
                                            if ($exemplaire->DonneesFille->DonneeFille[0]->ValeurDonnee) {
                                                $F941fields->addChild('site', $exemplaire->DonneesFille->DonneeFille[0]->ValeurDonnee);
                                            }
                                            if ($exemplaire->DonneesFille->DonneeFille[5]->ValeurDonnee) {
                                                $F941fields->addChild('local', $exemplaire->DonneesFille->DonneeFille[5]->ValeurDonnee);
                                            }
                                            if ($exemplaire->DonneesFille->DonneeFille[18]->ValeurDonnee) {
                                                $F941fields->addChild('sublocal', $exemplaire->DonneesFille->DonneeFille[18]->ValeurDonnee);
                                            }
                                            $F941fieldsOthers = $F941fields->addChild('others');
                                            if ($exemplaire->DonneesFille->DonneeFille[10]->ValeurDonnee) {
                                                $F941fieldsOthersOther = $F941fieldsOthers->addChild('other');
                                                $F941fieldsOthersOther->addChild('label', 'Droit d\'emprunt');
                                                $F941fieldsOthersOther->addChild('data', $exemplaire->DonneesFille->DonneeFille[10]->ValeurDonnee);
                                                // Exemple pour rebond : $F941fieldsOthersOther->addChild('searchField', 'champSolr');
                                            }
                                            if ($exemplaire->DonneesFille->DonneeFille[2]->ValeurDonnee) {
                                                $F941fieldsOthersOther = $F941fieldsOthers->addChild('other');
                                                $F941fieldsOthersOther->addChild('label', $exemplaire->DonneesFille->DonneeFille[2]->NomDonnee);
                                                $F941fieldsOthersOther->addChild('data', $exemplaire->DonneesFille->DonneeFille[2]->ValeurDonnee);
                                            }
                                            if ($exemplaire->DonneesFille->DonneeFille[19]->ValeurDonnee) {
                                                $F941fieldsOthersOther = $F941fieldsOthers->addChild('other');
                                                $F941fieldsOthersOther->addChild('label', 'Localisation');
                                                $F941fieldsOthersOther->addChild('data', $exemplaire->DonneesFille->DonneeFille[19]->ValeurDonnee);
                                            }
                                            if ($exemplaire->DonneesFille->DonneeFille[12]->ValeurDonnee) {
                                                $F941fieldsOthersOther = $F941fieldsOthers->addChild('other');
                                                //$F941fieldsOthersOther->addChild('label', 'Piège 2');
                                                $F941fieldsOthersOther->addChild('data', $exemplaire->DonneesFille->DonneeFille[12]->ValeurDonnee);
                                            }
                                            if ($exemplaire->DonneesFille->DonneeFille[13]->ValeurDonnee) {
                                                $F941fieldsOthersOther = $F941fieldsOthers->addChild('other');
                                                //$F941fieldsOthersOther->addChild('label', 'Piège 3');
                                                $F941fieldsOthersOther->addChild('data', $exemplaire->DonneesFille->DonneeFille[13]->ValeurDonnee);
                                            }
                                            if ($exemplaire->DonneesFille->DonneeFille[14]->ValeurDonnee) {
                                                $F941fieldsOthersOther = $F941fieldsOthers->addChild('other');
                                                //$F941fieldsOthersOther->addChild('label', 'En transit');
                                                $F941fieldsOthersOther->addChild('data', $exemplaire->DonneesFille->DonneeFille[14]->ValeurDonnee);
                                            }
                                            if ($exemplaire->DonneesFille->DonneeFille[15]->ValeurDonnee) {
                                                $F941fieldsOthersOther = $F941fieldsOthers->addChild('other');
                                                $F941fieldsOthersOther->addChild('label', 'Rang de réservation');
                                                $F941fieldsOthersOther->addChild('data', $exemplaire->DonneesFille->DonneeFille[15]->ValeurDonnee);
                                            }
                                         }
                                     }
                                     $noticeNode->addChild('Reservation', $atLeastReservable ? 'T' : 'F');
                                     $resCode = 1;
                                     if (!$atLeastReservable) {
                                         $resCode = 301;
                                     }
                                     $noticeNode->addChild('ReservationCode', $resCode);
                                     return $oXMLreturn->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['user']);
                                     $oXMLreturnResInfo->addChild('nn', $sTempVar['notice']);
                                     $codeError = 0;
                                     $atLeastReservable = false;
                                     if (!is_array($oResult->RecupererNoticeResult->Notice->Exemplaires->NoticesFilles->NoticeFille)) {
                                         $oResult->RecupererNoticeResult->Notice->Exemplaires->NoticesFilles->NoticeFille = array($oResult->RecupererNoticeResult->Notice->Exemplaires->NoticesFilles->NoticeFille);
                                     }
                                     foreach ($oResult->RecupererNoticeResult->Notice->Exemplaires->NoticesFilles->NoticeFille as $keyEx => $exemplaire) {
                                        if ($this->checkExemplaireReservable($exemplaire)) {
                                            $atLeastReservable = true;
                                            $oXMLreturnResInfoSite = $oXMLreturnResInfo->addChild('site', $exemplaire->DonneesFille->DonneeFille[0]->ValeurDonnee);
                                            $oXMLreturnResInfoSite->addAttribute('id', $exemplaire->NumFille.'|'.$exemplaire->DonneesFille->DonneeFille[1]->ValeurDonnee);
                                            $oXMLreturnResInfoSite->addAttribute('coche', $keyEx == 0 ? 'T' : 'F');
                                        }
                                     }
                                     if (!$atLeastReservable) {
                                         $codeError = 301;
                                     }
                                     $oXMLreturnResInfo->addChild('error', 0);
                                     $oXMLreturnResInfo->addChild('code', $codeError);
                                     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['user']);
                                     $errorCode = 1;
                                     $errorMessage = 1;
                                     if ($oResult->EmprReserverResult->Reussite == '1') {
                                        $oXMLreturnResDoc->addChild('infosres', $sTempVar['site']);
                                     }
                                     else {
                                         $errorCode = 2;
                                         //$errorMessage = $oResult->EmprReserverResult->ErreurService->LibelleErreur;
                                         $errorMessage = 101;
                                         //Attention, il faut la liste de leurs codes d'erreur et mapper sur nos codes existants errorCodes.xml
                                     }
                                     $oXMLreturnResDoc->addChild('error', $errorCode);
                                     $oXMLreturnResDoc->addChild('code', $errorMessage);
                                     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', ($oResult->EmprSupprResaResult->Reussite == '1' ? 0 : -1));
                                     $oXMLreturnResCancel->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) {
        return null;
    }
    
    public function updateGroupAccount($formDatas) {
        return null;
    }

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

    public function sendMessage($userInt, $mailId, $action, $objet, $text, $suggTitle, $suggAuthor, $suggEditor, $suggDocType) {
        return null;
    }

    public function reserveElectronicals($idElectronicals, $mode, $userInt) {
        return null;
    }
    
    private function convertDateToYMD($date) {
        $dateTab = explode("/", $date, 3);
        return $dateTab[2].$dateTab[1].$dateTab[0];
    }

    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);
        }
    }
    
}

class EntOuvrirSession {
    private $NomMachine;
    private $ListeServeurs;

    function __construct($NomMachine, $ListeServeurs) {
        $this->NomMachine = $NomMachine;
        $this->ListeServeurs = $ListeServeurs;
    }
}

class ServeurSession {
    private $BasesServeurs;
    private $NomServeur;

    function __construct($BasesServeurs, $NomServeur) {
        $this->BasesServeurs = $BasesServeurs;
        $this->NomServeur = $NomServeur;
    }
}

class BaseSession {
    private $NomBase;

    function __construct($NomBase) {
        $this->NomBase = $NomBase;
    }
}

class EntRecupererNotice {
    private $Catalogue = 'C';
    private $GUIDSession;
    private $RangNotice;
    private $NumNotice;
    private $IDEtape;
    private $Affichage;
    private $Restricteurs;
    private $FondsEnPret = false;

    function __construct($GUIDSession, $RangNotice, $NumNotice, $IDEtape, $Affichage, $Restricteurs) {
        $this->GUIDSession = $GUIDSession;
        $this->RangNotice = $RangNotice;
        $this->NumNotice = $NumNotice;
        $this->IDEtape = $IDEtape;
        $this->Affichage = $Affichage;
        $this->Restricteurs = $Restricteurs;
    }
}

class AffichageNotice {
    private $CodeAffichage = 'ISBDSTAND';
    private $NiveauAffichage;
    private $LibelleAffichage = '';

    function __construct($NiveauAffichage) {
        $this->NiveauAffichage = $NiveauAffichage;
    }
}

class EntEmprAuthentifier {
    private $IDEmprunteur;
    private $MotDePasse;
    private $Place = '';
    private $GUIDSession;
    
    function __construct($GUIDSession, $IDEmprunteur, $MotDePasse) {
        $this->GUIDSession = $GUIDSession;
        $this->IDEmprunteur = $IDEmprunteur;
        $this->MotDePasse = $MotDePasse;
    }
}

class EntEmprListerEntite {
    private $GUIDSession;
    private $IdEntite;
    
    function __construct($GUIDSession, $IdEntite) {
        $this->GUIDSession = $GUIDSession;
        $this->IdEntite = $IdEntite;
    }
}

class EntEmprReserver {
    private $GUIDSession;
    private $NumNotices;
        
    function __construct($GUIDSession, $NumNotices) {
        $this->GUIDSession = $GUIDSession;
        $this->NumNotices = $NumNotices;
    }
}

class EntEmprSupprResa {
    private $GUIDSession;
    private $ListeResa;
    
    function __construct($GUIDSession, $ListeResa) {
        $this->GUIDSession = $GUIDSession;
        $this->ListeResa = $ListeResa;
    }
}

class ResaIdType {
    private $IDResa;
    private $TypeResa;
    
    function __construct($IDResa, $TypeResa) {
        $this->IDResa = $IDResa;
        $this->TypeResa = $TypeResa;
    }
}

class EntEmprProlong {
    private $GUIDSession;
    private $ListeProlong;
    
    function __construct($GUIDSession, $ListeProlong) {
        $this->GUIDSession = $GUIDSession;
        $this->ListeProlong = $ListeProlong;
    }
}

class EntEmprEnvoyerMessage {
    private $GUIDSession;
    private $Destinataire;
    private $Message;
    
    function __construct($GUIDSession, $Destinataire, $Message) {
        $this->GUIDSession = $GUIDSession;
        $this->Destinataire = $Destinataire;
        $this->Message = $Message;
    }
}
