<?php
#G
#=
/****************************************************************************
Copyright 2002, Daniel Deycard, Jacques Messines, Alain Pomirol
(CATICE Académie de Bordeaux)

This file is part of Gibii.

Gibii is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

Gibii is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Gibii; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

****************************************************************************/

include_once('../include/get.inc.php');

function creer_table_divers() {
$sql="CREATE TABLE IF NOT EXISTS divers (
		divers_id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
		motcle VARCHAR( 50 ) NULL ,
		id INT NULL ,
		etab_id INT NULL,
		vrac BLOB NULL ,
		INDEX ( motcle , id )
		) ";
$v=mysql_get_server_info();
if ($v[0]=='5') $sql.=" ENGINE = MYISAM ";
query($sql);
}


function garderVrac(&$nouveau) {
global $modele,$champactif,
	   $logfournis,$mdpfournis,$razmdp,$logprioanc,$mdpenclair;
$nouveau->vrac=array();
foreach(array('modele','champactif','logfournis','mdpfournis','razmdp','logprioanc','mdpenclair') as $idx) {
	$nouveau->vrac[$idx]= $$idx;
	}
$blob=addslashes(serialize($nouveau));
creer_table_divers();
query("INSERT INTO divers SET motcle='$nouveau->table', id=$nouveau->id, etab_id=$nouveau->etab_id, vrac='$blob'");
return mysql_insert_id();
}		

function garderIncertain(&$nouveau) {
global $modele,$champactif,
	   $logfournis,$mdpfournis,$razmdp,$logprioanc,$mdpenclair;
$nouveau->ajoutertable(1);   //ajoute avec tag=1; affecte $this->id
return garderVrac($nouveau);
}


function loginPourNouveau(&$nouveau) {
global $logfournis, $logprioanc, $modele;
if ($logfournis && !empty($nouveau->login)) {
	$txtlog=$nouveau->login; //car modifié par creerL...
	$newlog=$nouveau->creerloginunique($modele); //$nouveau->login est aussi affecté
    if ($logprioanc) {
        //on cherche à créer le login fourni et on garde le résultat, même s'il est suffixé
		if ($txtlog==$newlog) $nouveau->addmess("- le login du fichier texte ($txtlog) a été attribué");
		else $nouveau->addmess("- le login fourni a dû être suffixé ($newlog au lieu de $txtlog)");
		}
    elseif ($newlog!=$txtlog) {
        //il existe un user dont il faut modifier le login
    	query("UPDATE comptes SET login='".secs($newlog)."'
    			WHERE login='".secs($txtlog)."' AND etab_id=$nouveau->etab_id");
        $nouveau->addmess("- <span class=\"warning\"><b>Attention</b></span>
        					Le login d'un ancien utilisateur a dû être modifié ; son nouveau est $newlog");
        $nouveau->login=$txtlog;
        $nouveau->addmess("- login de l'utilisateur courant : $txtlog");
    	}
    else {
        $nouveau->addmess("- login : celui du fichier texte ($txtlog)");
        }
    }
else {
    $nouveau->creerloginunique($modele);
    $nouveau->addmess("- login créé : $nouveau->login");
	}
}

function mdpPourNouveau(&$nouveau) {
global $mdpfournis,$mdpenclair;
if ($mdpfournis) {
    if ($mdpenclair) {
        $nouveau->mdp=md5($nouveau->mdp);
        $nouveau->addmess("- mdp transformé par MD5 à partir du fichier texte");
        }
    else $nouveau->addmess("- mdp fourni tel quel depuis le fichier texte");
    }
else {
    $nouveau->mdp=md5($nouveau->dnaiss);
    $nouveau->addmess("- mdp crypté à partir de dnaiss");
    }
}

//----------------------------------------------------------
function majAncienMemeEtab(&$ancien,&$nouveau) {
global $modele,$champactif,$etab_id,
	   $logfournis,$mdpfournis,$razmdp,$logprioanc,$mdpenclair;
if ($logfournis && $nouveau->login) {
    if ($ancien->login!=$nouveau->login) {
        //l'ancien a xy, le nouveau a zt
        $txtlog=$nouveau->login;
        $newlog=$nouveau->creerloginunique($modele); //$nouveau->login est affecté dans la fonction
        $nouveau->addmess("txt login=$txtlog - nouveau login=$newlog - ancien login=$ancien->login");
        //si on trouve zt, c'est bon pour zt dans tous les cas
        if ($newlog!=$txtlog) {
            if ($logprioanc) {
            	//un user DOIT changer de login
                query("UPDATE comptes SET login='".secs($newlog)."'
                        WHERE login='".secs($txtlog)."' AND etab_id=$nouveau->etab_id");
                $nouveau->login=$txtlog;
                $nouveau->addmess("- <span class=\"warning\"><b>Attention</b></span>
                                    Le login $txtlog d'un ancien utilisateur a dû être modifié
                                    et son nouveau login est maintenant $newlog");
                $nouveau->addmess("- le login de l'utilisateur courant ($nouveau->nom, $nouveau->prenom, $nouveau->dnaiss)
                					est bien maintenant $txtlog");
                }
            else $nouveau->addmess("- le login attribué est $newlog car le login demandé ($txtlog) existait déjà");
            }
        else $nouveau->addmess("- l'ancien login ($ancien->login) a été remplacé par celui du fichier texte ($txtlog)");
        $loginquot=addslashes($nouveau->login);
        $set[]="login='$loginquot' ";
        }
    else $nouveau->addmess("- l'ancien login ($ancien->login) a été conservé (identique à celui du fichier texte)");
    }
else {
	//les logins ne sont pas fournis dans le fichier texte (ou l'admin s'est planté de bouton)
	$nouveau->login=$ancien->login;
	$nouveau->addmess("- l'ancien login a été conservé");
	}
if ($nouveau->login!=$ancien->login)
	$nouveau->addmess("<span class=\"attention\">- le login a été modifié.</span>");
}

//----------------------------------------------------------
function majAncienChangementEtab(&$ancien,&$nouveau) {
global $modele,$champactif,$etab_id,
	   $logfournis,$mdpfournis,$razmdp,$logprioanc,$mdpenclair;
if ($logfournis && $nouveau->login) {
    $txtlog=$nouveau->login;
	//tester si le login fourni dans le fichier texte n'est pas déjà utilisé (creerloginunique en retournera un autre)
    $newlog=$nouveau->creerloginunique($modele); //$nouveau->login est affecté dans la fonction
    $nouveau->addmess("txt login=$txtlog - nouveau login=$newlog - ancien login=$ancien->login");
    if ($newlog!=$txtlog) {
        if ($logprioanc) {
        	//un user DOIT changer de login
            query("UPDATE comptes SET login='".secs($newlog)."' WHERE login='".secs($txtlog)."' AND etab_id=$nouveau->etab_id");
            $nouveau->login=$txtlog;
            $nouveau->addmess("- <span class=\"warning\"><b>Attention</b></span>
                                Le login $txtlog d'un ancien utilisateur a dû être modifié
                                et son nouveau login est maintenant $newlog");
            $nouveau->addmess("- le login de l'utilisateur courant ($nouveau->nom, $nouveau->prenom, $nouveau->dnaiss)
            					est bien maintenant $txtlog comme prévu par les options choisies");
            }
        else $nouveau->addmess("- le login attribué est $newlog car le login demandé ($txtlog) existait déjà");
        }

    else $nouveau->addmess("- le login du fichier texte $txtlog convient dans l'établissement");
    }
else {
	//les logins ne sont pas fournis dans le fichier texte mais il y a eu changement d'établissement
	//tester si le login fourni dans le fichier texte n'est pas déjà utilisé (creerloginunique en retournera un autre)
	$nouveau->login=$ancien->login; //a priori
    $newlog=$nouveau->creerloginunique($modele); //$nouveau->login est affecté dans la fonction
	if ($nouveau->login==$ancien->login)
		$nouveau->addmess("- le login de l'ancien établissement a été conservé");
	else 
		$nouveau->addmess("<span class=\"attention\">- le login de l'ancien établissement ($ancien->login) 
							 a été dû être modifié ($nouveau->login) pour éviter un conflit.</span>");
	}
}

function majMotDePasse(&$ancien,&$nouveau) {
global $modele,$champactif,$etab_id,
	   $logfournis,$mdpfournis,$razmdp,$logprioanc,$mdpenclair;

if ($mdpfournis) {
    if ($mdpenclair) {
        $nouveau->mdp=md5($nouveau->mdp);
        $nouveau->addmess("- mdp transformé par MD5 à partir du fichier texte");
        }
    else $nouveau->addmess("- mdp fourni écrit tel quel dans la base (il est déjà crypté dans le fichier texte");
    }
else {
    if ($razmdp) {        
    	  //demande de réinitialisation
        $nouveau->mdp=md5($nouveau->dnaiss);
		    $nouveau->addmess("- mdp réinitialisé (cryptage de la dnaiss)");
        }
    else {
    	  $nouveau->mdp=$ancien->mdp;
        }
    }

if ($nouveau->mdp!=$ancien->mdp) 
    $nouveau->addmess("<span class=\"attention\">- le mot de passe a été modifié.</span>");
else $nouveau->addmess("- le mot de passe est le même que l'ancien");
}
	

//==========================================================	
function majancien(&$ancien,&$nouveau) {
global $modele,$champactif,$etab_id,
	   $logfournis,$mdpfournis,$razmdp,$logprioanc,$mdpenclair;

$nouveau->updatetable($ancien);      //met à jour eleves ou profs et l'id de nouveau
$nouveau->updateoptions();          //langues (élève) ou classes (prof)
$nouveau->updategroupe_en_lien($ancien);
$set=array();
if ($nouveau->etab_id==$ancien->etab_id) 
	majAncienMemeEtab($ancien,$nouveau);
else 
	majAncienChangementEtab($ancien,$nouveau);
majMotDePasse($ancien,$nouveau);

//mettre éventuellement la table comptes à jour
//---------------------------------------------
$set=array();
if ($nouveau->login!=$ancien->login) {
	$set[]=" login='".addslashes($nouveau->login)."' ";
	}
if ($nouveau->mdp!=$ancien->mdp) {
    $set[]=" mdp='$nouveau->mdp' ";
	}
if ($nouveau->etab_id!=$ancien->etab_id) {
    $set[]=" etab_id=$nouveau->etab_id ";
    }
if (count($set)) {
	$chset=implode(', ',$set);
	$nouveau->addmess("- table `comptes` modifiée");
    query("UPDATE comptes SET $chset WHERE $ancien->champ_id=$ancien->id"); 
    }
}


//==========================================================
function maj_ancien_nouveau(&$ancien,&$nouveau) {
global $champactif,$modele,$etab_id,$sess_ascol,
	   $logfournis,$mdpfournis,$razmdp,$logprioanc,$mdpenclair;

$res=query("SELECT login,mdp FROM comptes WHERE compte_id=$ancien->compte_id;");
if (empty($ancien->compte_id) || $ancien->compte_id==NULL || $ancien->compte_id==0 || mysql_num_rows($res)==0)  {
    //cas exceptionnel : pas d'enregistrement dans la table compte
    $nouveau->updatetable($ancien);      //met à jour eleves ou profs et l'id de nouveau
	$nouveau->updategroupe_en_lien($ancien);
    $nouveau->updateoptions();              //langues (élève) ou classes (prof)
    $nouveau->addmess("- existait dans la table $nouveau->table mais sans compte");
    $nouveau->addmess("- un nouveau compte a été créé, avec login=$nouveau->login");
    loginPourNouveau($nouveau);
    mdpPourNouveau($nouveau);
    $nouveau->insertcompte($champactif);
    return;
    }

list($ancien->login,$ancien->mdp)=mysql_fetch_array($res);
$metab=$ancien->etab_id==$etab_id;          //champs non vides
$mannee=$ancien->annee==$sess_ascol;        //champs non vides

if ($mannee &&  $metab)  {           //repasse ------------------------------------------------------------
    $nouveau->addmess("- déjà présent dans la base (même année et même étab) ; mis à jour");
    majancien($ancien,$nouveau);
    return ;
    }

if (!$mannee &&  $metab)  {          //ancien du même étab-------------------------------------------------
    $nouveau->addmess("- ancien du même établissement");
    majancien($ancien,$nouveau);
    return ;
    }

$oldetab=getetab($ancien->etab_id);
$oldetabaff=$oldetab['nom'].' - '.$oldetab['ville'];

if (!$mannee && !$metab)  {          //ancien d'un étab différent OU à cheval sur 2 -----------------------
    //si c'est un cas "à cheval" l'autre étab n'a pas fait la bascule donc
    //il tombera dans le cas ($mannee && !$metab) ci-dessous et il créera un clone
    $nouveau->addmess("- ancien d'un autre établissement ($oldetabaff)");
    majancien($ancien,$nouveau);
    return ;
    }

//ici on a ($mannee && !$metab)      //chgt étab en cours d'année OU à cheval sur 2 -----------------------
if ($ancien->statut=='Eleve') {         //un élève ne peut pas être à cheval
    $nouveau->addmess("- changement d'établissement en cours d'année (vient de $oldetabaff)");
    majancien($ancien,$nouveau);
    return ;
    }
else {                               //type n°3/3 d'incertain  -------------------------------------------------
    $nouveau->addmess("- prof ayant changé d'étab en cours d'année (ancien = $oldetabaff) ou à cheval sur 2 étabs (il faudra créer un clone)");
    $nouveau->addmess('- Cas ambigu : à déterminer ultérieurement (traitement des incertains).','red');
	garderIncertain($nouveau);
    //Le compte n'est pas créé
    return ;
    }
}


function engranger(&$nouveau) {
global $champactif,$modele,
	    $logfournis,$mdpfournis,$razmdp,$logprioanc,$mdpenclair,
		$etab_id,$sess_ascol,$MODULE,$etab_niveau;
//recherche les homonymes "bruts" dans la table d'origine (noms, prénoms identiques)
$result=$nouveau->qhomo();
if (is_object($result)) {
	$nbhomo=1;
	$ancien=$result;
	$certain=true;
	}
else {
	$nbhomo=$result;
	$ancien=NULL;
	$certain=false;
	}
$nouveau->addmess("nombre d'homonymes : $nbhomo");
$trouve=0;
switch ($nbhomo) {
	case 0 :
        $nouveau->addmess("- nouveau");
        $nouveau->ajoutertable(0);  //tag=0 : vrai nouveau
		$nouveau->ajoutgroupe_en_lien(); 
        loginPourNouveau($nouveau);
        mdpPourNouveau($nouveau);
        $nouveau->insertcompte($champactif);
        if ('Melia'==$MODULE || 'prof_id'==$nouveau->champ_id)
            $nouveau->ajouteroptions(0); //sinon, la table restera vide (lien_eleves_disciplines) sous GiBii
        if ('Melia'==$MODULE && 'prof_id'==$nouveau->champ_id)
            $nouveau->cochercompetences($etab_niveau);
        $trouve=1;
    	break;
	case 1 :
        if ($certain) {            
        	if ($ancien->etab_id==$etab_id) {
        		$etabaff='(le même)';
        		}
            else {
                $etab=getetab($ancien->etab_id);
                $etabaff=$etab['nom'].' - '.$etab['ville'];
                }
        	$mess="<font color=\"navy\"><strong>$ancien->nom, $ancien->prenom, $ancien->civil, $ancien->dnaiss, année=$ancien->annee, étab=$etabaff";
            if (!empty($ancien->ident_nat)) $mess.=", $ancien->ident_nat ";
            $mess.="</strong></font>";
            $nouveau->addmess($mess);
            if (!empty($nouveau->ident_nat) && $nouveau->ident_nat==$ancien->ident_nat) 
				$nouveau->addmess('- mêmes ident_nat');
			if (!empty($nouveau->uid) && $nouveau->uid==$ancien->uid) 
				$nouveau->addmess("- égalité des identificateurs nationaux (INE pour l'élève)");
			
            maj_ancien_nouveau($ancien,$nouveau); //true sauf cas particulier rare
            $trouve=1;
            }
		else {  //type n°1/3 d'incertain
			$nouveau->addmess("- cas ambigu (un homonyme à déterminer ultérieurement (traitement des incertains).",'red');
			garderIncertain($nouveau);
            }
      	break;
	default : // type n°2/3 d'incertain
        $nouveau->addmess("- cas ambigu : trop d'homonymes. A déterminer ultérieurement (traitement des incertains).",'red');
		garderIncertain($nouveau);
	}
unset($ancien);
$nouveau->findclose();
return $trouve; //0 ou 1
}


//----------------------------
function afficher(&$nouveau,$tout=true) {
global $MODULE;
print "<h2>";
print "$nouveau->nom, $nouveau->prenom, $nouveau->civil, $nouveau->dnaiss, $nouveau->uid, ";
if ($nouveau->statut=='Prof') {
        print "$nouveau->discipline";
        $listecl='';
        foreach($nouveau->classes as $classe_id) $listecl.= "'".getclasse($classe_id)."' ";
        if ($listecl) print ", classes=[ $listecl]";
    }
else {
        print "$nouveau->divcod";
        if ($MODULE=='Melia') {
           print ", langues=[ ";
           foreach($nouveau->lv as $ind=>$langue_id) print " LV$ind:".getlangue($langue_id)." ";
           print "]";
           }
}
if ($tout) {							//affichage détaillé
	print "</h2>\n";
	$espaces=str_repeat("&nbsp;",10);
	for ($i=0; $i<count($nouveau->messages);$i++) {
	        $mess=$nouveau->messages[$i];
	        echo $espaces,$mess,'<br />';
		}
	}
else print ", $nouveau->login</h2>\n"; //affichage restreint pour la résolution d'un incertain
}


//----------------------------
function affichererreur($chligne,$nouveau,$batch) {
if ($batch) {
	logf($chligne."\n");
	logf("  ".$nouveau->messages[0]."\n");
	}
else {
	print "<h3><font color=\"orange\">$chligne</font></h3>";
	print "<p>";
	print "<font color=\"orange\">".$nouveau->messages[0]."</font>";
	print "</p>\n";
	print "<p>";print_r($nouveau->messages);print "</p>";
	}
}


//utilisée dans txt2tables et dans batch_incorporation
//----------------------------------------
function get_errmsg($errcode) {
$msg="";
switch ($errcode) {
	case -1 : $msg= "Pas de séparateur trouvé";break;
	case -2 : $msg= "Un des libellés de champ est absent";break;
	case -3 : $msg= "Un des champs doublonne";break;
	case -4 : $msg= "L'un des champs est inconnu";break;
	}
return $msg;
}

function getprotomap($elvprof,$fichier) {
global $etab_id,$sess_ascol;
$nouveau=new $elvprof();
$nouveau->etab_id=$etab_id;
$nouveau->annee=$sess_ascol;
$nouveau->maptxt($fichier); 	//affecte $nouveau->sep, $nouveau->entete et $nouveau->map
return $nouveau;
}


function balayer_txt($elvprof,$fichier,$batch=false,$verbose=true) {
//l'en-tête éventuel a été vérifié. On le recalcule afin de tomber sur les données,
//ce qui est certainement moins coûteux que de le stocker en session à la fin de la vérification.
global $champactif,$sess_ascol,$etab_id,
	   $logfournis,$mdpfournis,$razlog,$razmdp,$logprioanc,$mdpenclair;
	   
$nouveau=getprotomap($elvprof,$fichier);
if ($nouveau->codemap<0) return array($nouveau->codemap,$nouveau->entete);
	
$sep=$nouveau->sep;
$fp = fopen($fichier, "r");

//chercher et sauter la ligne d'en-tête
if ($nouveau->codemap>0) { //il y a un en-tête (code=1)
	while($buffer=fgets($fp,1024)) {
		if (strpos($buffer,$sep)!==false) break; //on saute les 1ères lignes sans en-tête
	    }
	//le pointeur de fichier est juste après la ligne d'en-tête
	}

unset($nouveau->exemples,$nouveau->entete); //on libère un peu de place...

$nbincertains=0;$nbtraites=0;
while ($ligne = fgetcsv ($fp, 1024,$sep)) {
	$chligne=implode($ligne," ");
	if (!trim($chligne)) continue;
	if ($chligne[0]=="#") continue;
	if ($nouveau->setbytxt($ligne,$mdpenclair))  { 
		//print "<br><br>après setbytxt : nouveau = ";print_r($nouveau);print "<br><br>";
		$nouveau->verbose=$verbose;         
		if (!engranger($nouveau)) $nbincertains++;
		$nbtraites++;
		if ($verbose) {
			afficher($nouveau);
			print "<br /><br />";         
			}
		}
	else affichererreur($chligne,$nouveau,$batch); //verbose ou pas on affiche les erreurs
	$nouveau->vider();// c'est le même qui sert ; le nettoyer, sauf sa table, etab_id et annee
	}
return array($nbincertains,$nbtraites);
}
?>