<?php
#=
function queryplus($s) {
//$s est une requête de type UPDATE ou DELETE
query($s);
$n=mysql_affected_rows();
return $n;
}

function a_cheval() {
//retourne true si une classe (au sens mathématique) de doublons contient des profs de cette année
//et d'étabs différents (ce n'est qu'une condition nécessaire de la présence
//de profs à cheval mais ça permet dans l'affichage d'attiter la vigilence
//du sadmin qui dédoublonne.

global $dan,$detab_id, $individu;
if ($individu=='e') return false; //les élèves ne sont jamais à cheval sur 2 étabs
$ascol=ascol();
$firstetab=0;
for ($i=1; $i<=count($dan); $i++) {
    if ($dan[$i]==$ascol) {
        if (!$firstetab) $firstetab=$detab_id[$i];
        elseif ($detab_id[$i]!=$firstetab) {
            return true;
            }
        }
    }
return false;
}


//Cherche les doublons pour le triplet ($Nom,$Prenom,$Dnaiss)
//==============================================================================
function traiter_doublons() {
global $Nom,$Prenom,$Dnaiss,
       $deid,$dan,$detab_id,$dprecdate,$dident_nat,$dcid,$dlogin,$dcetab_id;
global $ok_eidbl,$ok_cidbl,$ok_login,$ok_items;

/*Méthode :
La meilleure année ($ok_annee) est la dernière. On ne garde que les élèves de cette année-là.
Le meilleur étab est celui de la dernière connexion réussie (sinon, on prend le premier
de la liste).
On obtient ainsi $ok_eidbl, indice dans le tableau des doublons de l'élève qu'on garde.
Grâce à cet indice, on trouvera dans les autres tableaux les autres renseignements, sans
avoir besoin de les retrouver dans la base. On retrouve même ce qui a premis de
calculer $ok_eidbl (l'année, la date de la dernière connexion et l'étab) :
    - l'enregistrement de l'élève dans sa table : $deid[$ok_eidbl],
    - son ident_nat :  $dident_nat[$ok_eidbl],
    - son année : $dan[$ok_eidbl],
    - son étab : $detab_id[$ok_eidbl],

Le meilleur login est celui de la dernière connexion, toutes années et étabs confondus.
S'il n'y a pas eu de connexion, on prend le plus simple des logins (c'est le premier des doublons
du fait de l'ordre imposé dans la requête). S'il a déjà été réutilisé par un autre élève, on prend
le suivant. Si les logins de tous les doublons ont été réutilisés, on en crée un avec l'algorithme
de l'incorporation.

On obtient $ok_login qui permet de déterminer le meilleur compte $ok_ceidbl (dans le cas
où on est obligé d'en fabriquer un neuf, on choisit le premier compte trouvé dans les doublons).
Ce compte permet d'obtenir tous les renseignements de la table comptes sauf les champs
login et eleve_id qui sont remis à jour avec les données trouvées.
Pour le champ precdate, on garde celui trouvé dans le compte (NULL éventuellement)
mais en réalité ce n'est pas une donnée très importante pour la suite.
*/

//----------------------------------
//la dernière année est la meilleure
//----------------------------------
$ok_annee=max($dan);
$mannee=$ok_annee==min($dan);
$ti_ok_annee=array_keys($dan,$ok_annee); //table des indices idbl de la bonne année (la dernière)

//--------------------------------------------
//trouver le meilleur établissement
//--------------------------------------------
/*
Ce tableau $ti_ok_annee à index numériques a pour valeurs les indices
de la bonne année dans les tableaux $deid, $dan,...
Ainsi, par exemple, si on trouve $ti_ok_annee=array(0=>4, 1=>11, 2=>46),
cela signifie que la dernière année ($ok_annee) est trouvée
pour les élèves $deid[4], $deid[11] et $deid[46]

On cherche maintenant le meilleur établissement possible parmi ceux dont
l'année est égale à $ok_annee
Exemple : lignes des tables qui ont l'année égale à 2004
        $idbl  $detab_id  $dan   $dprecdate
          4       8       2004      1000
          11      8       2004      1500
          46      9       2004       600
la colonne $idbl étant rangée dans le tableau $ti_ok_annee (par exemple,
$ti_ok_annee[1]=11). Les 3 lignes ci-dessus sont les lignes 4, 11, 46, extraites
des tableaux $d---. On les balaie par $ti_ok_annee[0..n]

La date de connexion la plus récente est 1500. On estime alors que le meilleur
choix d'étab est celui de la 2e ligne (le 8 avec $idbl=11).
Si l'élève ne s'est jamais connecté (NULL partout dans la dernière colonne),
aucune autre info ne permet de conclure (il aurait faluu stocker la dernière date
d'installation dans la table élève). Donc, si $dprecdate vaut partout NULL,
on prend le premier établissement trouvé (le 8, avec $idbl=4 dans ce cas).
*/

$ok_precdate=0;
foreach ($ti_ok_annee as $idbl)  { //$idbl=indice dans les tableaux $deid,$dan,...
    if ($dprecdate[$idbl]>$ok_precdate) {
        $ok_precdate=$dprecdate[$idbl];
        $ok_eidbl=$idbl;           //on conserve l'indice idbl correct dans la table deid
        }
    }

if ($ok_precdate==0) { //on prend n'importe lequel en commençant par le début de la liste
    for ($i=0;$i<count($ti_ok_annee);$i++) {
        $ok_eidbl=$ti_ok_annee[$i];       //indice suivant dans la liste des doublons
        $ok_etab_id=$detab_id[$ok_eidbl]; //c'est l'eleve_id qui décide de l'etab_id
        if ($ok_etab_id>0) break;
        //on prend l'étab_id trouvé dans comptes
        $ok_etab_id=$dcetab_id[$ok_eidbl];
        if ($ok_etab_id>0) break;
        }
    if (!isset($ok_etab_id) || $ok_etab_id==0) {
        $ok_eidbl=$ti_ok_annee[0];   //on prend le premier
        $ok_etab_id=0;
        $detab_id[$ok_eidbl]=0;
        $dcetab_id[$ok_eidbl]=0;
        }
    }


//-------------------------------
//trouver le meilleur login (et le bon compte_id)
//-------------------------------
//chercher la dernière bonne connexion (pas nécessairement la même que
//$ok_precdate ci-dessus qui ne cherche que dans la dernière année)
$last_connexion=max($dprecdate);
if ($last_connexion==NULL) {
    //jamais connecté !
    $ok_login='';
    //chercher dans les résultats de la requête principale qui les a triés en ordre croissant
    for ($idbl=1;$idbl<=count($deid);$idbl++) { //on cherche parmi les logins des homonymes
        $login=$dlogin[$idbl];
        if (!$login) continue;
        $id=$deid[$idbl];
        $loginquote=addslashes($login);
        $res2=query("SELECT * FROM comptes WHERE etab_id=$ok_etab_id AND login='$loginquote' AND eleve_id<>$id");
        if (mysql_num_rows($res2)==0) {
            $ok_login=$login;
            $ok_cidbl=$idbl;
            break;
            }
        mysql_free_result($res2);
        }
    if ($ok_login=='') {  //aucun des logins actuels ne convient
        //créer login unique à partir du min des logins
        $login=$dlogin[1];
        $loginquote=addslashes($login);
        if (!$login) $login='X'; //né sous X : on ne peut faire mieux, mais c'est exceptionnel
        $res2=query("SELECT login FROM comptes
                        WHERE login LIKE '$loginquote%'
                          AND etab_id=$ok_etab_id");
        $long=strlen($login);
        $tlog=array();
        while (list($loginexistant)=mysql_fetch_array($res2)) {
            $finlogin=substr($loginexistant,$long);
            $tlog[]=$finlogin;
            }
        mysql_free_result($res2);
        $suffixe='';
        if (count($tlog)) while (in_array($suffixe,$tlog)) $suffixe++;
        $ok_login=$login.$suffixe;
        $ok_cidbl=1;
        }
    }
else {
    $idbl_lastdate=array_search($last_connexion,$dprecdate); //un seul non NULL trouvé (avec proba=0.9999999 !)
    $ok_login=$dlogin[$idbl_lastdate];
    $ok_cidbl=$idbl_lastdate;
    }

// On tient le login, l'année, l'étab, ident_nat, la dernière connexion, le compte (sauf cas 0)

//-----------------------------------------
//Cumuler les items des homonymes
//-----------------------------------------
$liste_indiv=implode(',',$deid);
$resitems=query("SELECT DISTINCT item_id FROM resultats WHERE eleve_id IN ($liste_indiv)");
$ok_items=array();
while (list($item_id)=mysql_fetch_array($resitems)) $ok_items[]=$item_id;
mysql_free_result($resitems);
}


//==============================================================================
function recuperer_donnees($id) {
global $table,$champ,
       $Nom,$Prenom,$Dnaiss,
       $deid,$dan,$detab_id,$dtag,$dprecdate,$dident_nat,$dcid,$dlogin,$dcetab_id;
$res1=query("SELECT nom,prenom,dnaiss FROM $table where $champ=$id");
//print "SELECT nom,prenom,dnaiss FROM $table where $champ=$id";exit();
list($Nom,$Prenom,$Dnaiss)=mysql_fetch_array($res1);
$Nom=stripslashes($Nom);
$Prenom=stripslashes($Prenom);
mysql_free_result($res1);
//retrouver le groupe ayant même (m,p,d)
$idoub=0;
$Nomq=addslashes($Nom);
$Prenomq=addslashes($Prenom);
$sql=       "SELECT e.$champ,e.annee,e.etab_id,e.tag,
                    c.precdate,e.ident_nat,
                    c.compte_id,c.login
               FROM $table AS e
          LEFT JOIN comptes AS c
                 ON e.compte_id=c.compte_id
              WHERE e.nom='$Nomq' AND e.prenom='$Prenomq' AND e.dnaiss='$Dnaiss'
           ORDER BY c.login";
$res=query($sql);
$deid=$dan=$detab_id=$dtag=$dprecdate=$dident_nat=$dcid=$dlogin=array();  //on vide
while (list($eid,$an,$etab,$tag,$precdate,$ident_nat,$cid,$login)
        =mysql_fetch_array($res)) {
    $idoub++;
    $deid[$idoub]=$eid;$dan[$idoub]=$an;$detab_id[$idoub]=$etab;$dtag[$idoub]=$tag;
    $dprecdate[$idoub]=$precdate;$dident_nat[$idoub]=$ident_nat;
    $dcid[$idoub]=$cid;$dlogin[$idoub]=stripslashes($login);
    }
mysql_free_result($res);
return $idoub;
}

//==============================================================================
function afficher_lignes() {
global $table,$champ,
       $deid,$dan,$detab_id,$dprecdate,$dident_nat,$dcid,$dlogin,$dcetab_id;
$nbdoublons=count($deid);
for ($i=1;$i<=$nbdoublons;$i++) {
    $eid=$deid[$i];$an=$dan[$i];$etab_id=$detab_id[$i];
    $precdate=$dprecdate[$i];$ident_nat=$dident_nat[$i];
    $cid=$dcid[$i];$login=$dlogin[$i];
    print "<tr>\n";
    print "<td>$eid&nbsp;</td>\n";
    print "<td>$cid&nbsp;</td>\n";
    print "<td>$login&nbsp;</td>\n";
    print "<td>$precdate&nbsp;</td>\n";
    print "<td>$ident_nat&nbsp;</td>\n";
    print "<td>$an&nbsp;</td>\n";
    print "<td>$etab_id&nbsp;</td>\n";
    if ($table=='eleves') {
        print "<td>\n";
        //recherche des items obtenus par $eid
        $res3=query("SELECT item_id FROM resultats WHERE eleve_id=$eid");
        while (list($item_id)=mysql_fetch_array($res3)) print $item_id.' ';
        mysql_free_result($res3);
        $checked="";
        print "&nbsp;</td>\n";
        }
    print "</tr>\n";
    }
}

//==============================================================================
function afficher_en_tete() {
global $individu;
print "<tr><th> id </th><th>compte_id</th><th>login</th><th>préc date</th><th>ident_nat</th>
       <th>année</th><th>etab_id</th>";
if ($individu=='e') print "<th>Items obtenus</th>";
print "</tr>\n";
}

//==============================================================================
function afficher_doublons($passe,$coche=true) {
global $individu,
       $Nom,$Prenom,$Dnaiss,
       $deid,$dan,$detab_id,$dprecdate,$dident_nat,$dcid,$dlogin,$dcetab_id;
global $ok_eidbl,$ok_cidbl,$ok_login,$ok_items;

//l'en-tête du tableau

print "<br />\n";
print "<fieldset>";
print "<legend>";
$triplet="<strong> $Nom, $Prenom, $Dnaiss\n</strong>&nbsp;&nbsp;&nbsp;&nbsp\n";
if ($passe==1) {
    //les cases cochées seront cb[0]=12345 cb[1]=22344  cb[2]=22754, etc.
    //la valeur des checkbox est l'id du premier homonyme. Il permettre de retouver
    //son triplet (n,p,d).
    if ($coche) $checked='checked="checked"'; else $checked='';
    print "<input type=\"checkbox\" name=\"cb[]\" value=\"$deid[1]\" $checked />\n";
    print $triplet;
    print "<a href=\"dedoub_manu.php?id=$deid[1]&individu=$individu\">Traiter manuellement</a>";
    }
else print $triplet;

print "</legend>\n";

print "<table width=\"100%\" border=\"1\">\n";
afficher_en_tete();

//balayer les doublons en les affichant
//-------------------------------------
afficher_lignes();

//afficher le meilleur choix
//--------------------------
print "<tr class=\"meilleurchoix\">\n";
print "<td>".$deid[$ok_eidbl]."</td>\n";
print "<td>".$dcid[$ok_cidbl]."</td>\n";
print "<td>$ok_login&nbsp;</td>\n";
print "<td>".$dprecdate[$ok_cidbl]."&nbsp;</td>\n"; //le precdate du compte choisi
print "<td>".$dident_nat[$ok_eidbl]."&nbsp;</td>\n";
print "<td>".$dan[$ok_eidbl]."&nbsp;</td>\n";
print "<td>".$detab_id[$ok_eidbl]."&nbsp;</td>\n";
print "<td>\n";
if ($individu=='e') {
    foreach ($ok_items as $item) print $item.' ';
    print "&nbsp;</td>\n";
    }
print "</tr>\n";
print "</table>\n";
print "</fieldset>\n";
}

//==============================================================================
function updates() {
global $fpcsv;
global $individu,$table,$champ;
global $deid,$dan,$detab_id,$dprecdate,$dident_nat,$dcid,$dlogin;
global $ok_eidbl,$ok_cidbl,$ok_login,$ok_items;
global $ok_eid,$ok_cid;
global $Nom,$Prenom,$Dnaiss;


//on a besoin de l'étab pour le compte (pas toujours celui associé à l'élève)
$ok_etab_id=$detab_id[$ok_eidbl]; //c'est l'élève qui décide de l'étab
$ligne="$ok_etab_id;$individu;$Nom;$Prenom;$Dnaiss;$ok_login;";

if ($individu=='e') {
    $lindividu="l'élève";
    $lesindividus="les élèves";
    $ligne.=implode(' ',$ok_items);
    }
else {
    $lindividu="le prof";
    $lesindividus="les profs";
    }

fputs($fpcsv,$ligne."\n");

//$deid vaut par exemple (6,15,17,19,25). Si $ok_eid=15, on supprime 15 et on
//obtient (6,17,19,25). Idem pour $dcid.
//Il reste seulement les élèves et les comptes à supprimer vraiment.

$deid=array_diff($deid,array($ok_eid));
$eliste=implode(',',$deid);

$dcid=array_diff($dcid,array($ok_cid));
$cliste='('.implode(',',$dcid).')';


//tableau de formatage pour les résultats concernant un individu
print "<br />";
print "<table border=\"0\" width=\"100%\" ><tr>";
print "<td width=\"10%\">&nbsp;</td><td>";  //marge de 10%
//----

//print "<h4>Mises à jour des tables (UPDATE) pour $Nom $Prenom, $Dnaiss</h4>\n";

$n=queryplus("UPDATE $table SET compte_id=$ok_cid, tag=0 WHERE $champ=$ok_eid");
print "Table $table : mise à jour du champ compte_id de l'enregistrement $ok_eid.<br />\n";

$ok_loginquote=addslashes($ok_login);
$n=queryplus("UPDATE comptes SET $champ=$ok_eid, login='$ok_loginquote', etab_id=$ok_etab_id WHERE compte_id=$ok_cid");
print "Table comptes : mise à jour des champs $champ, login, etab_id de l'enregistrement $ok_cid.<br />\n";

if ($individu=='e' && $eliste) {
    $n=queryplus("UPDATE demandes SET eleve_id=$ok_eid WHERE eleve_id IN ($eliste)");
    $n=queryplus("UPDATE resultats SET eleve_id=$ok_eid WHERE eleve_id IN ($eliste)");
    print "Tables demandes et résultats : mise à jour relative aux doublons supprimés (eleve_id mis à $ok_eid).<br />\n";
    }

//---- fin du tableau de formatage pour les résultats concernant un individu
print "</td></tr></table>\n";
}

//==============================================================================
function suppressions($tabsupeid,$tabsupcid) {
global $individu,$table,$champ;

if ($individu=='e') {
    $lindividu="l'élève";
    $lesindividus="les élèves";
    }
else {
    $lindividu="le prof";
    $lesindividus="les profs";
    }

//on effectue le travail : la suppression peut se faire en une seule requête
print "<p>&nbsp;</p>\n";
print "<h3><font color=\"red\">Suppression d'enregistrements</font></h3>\n";
print "<table border=\"1\" width=\"100%\">\n";
print "<tr><th> Table </th><th> portant sur </th><th> appartenant à </th><th> Enregistrements concernés </th></tr>\n";

$seliste=implode(', ',$tabsupeid);    //, et espace pour casser les lignes affichées

//$tabsupcid vient des champs compte_id de la table eleves et peut contenir valeurs incorrectes
if (count($tabsupcid)) $tabsupcid=array_diff($tabsupcid,array("",NULL,0));
$scliste=implode(', ',$tabsupcid);


if ($seliste) {
    $lienc='lien_'.$table.'_classes';
    $n=queryplus("DELETE FROM $lienc WHERE $champ IN ($seliste)");
    print "<tr><td> $lienc </td><td>les élèves</td><td> $seliste </td><td>$n</td></tr>\n";
    if ($individu=='e') {
        $n=queryplus("DELETE FROM lien_eleves_disciplines WHERE eleve_id IN ($seliste)");
        print "<tr><td> lien_eleves_disciplines </td><td>les élèves</td><td> -- id -- </td><td>$n</td></tr>\n";
        }
    else {
        $n=queryplus("DELETE FROM lpi WHERE prof_id IN ($seliste)");
        print "<tr><td> lpi </td><td>les profs</td><td> -- id -- </td><td>$n</td></tr>\n";
        }

    $n=queryplus("DELETE FROM $table WHERE $champ IN ($seliste)");
    print "<tr><td> $table </td><td>$lesindividus</td><td> -- id -- </td><td>$n</td></tr>\n";
    }

if ($scliste) {
    $n=queryplus("DELETE FROM comptes WHERE compte_id IN ($scliste)");
    print "<tr><td> comptes </td><td>les comptes</td><td> $scliste </td><td>$n</td></tr>\n";
    }

print "</table>";
}

function menu_retour() {
$goto=   array("Revenir à l'affichage des doublons"         => "../sadmin/dedoublonner.php?",
               "Récupérer la liste des individus traités"   => "",
               "Vider la liste des individus traités"       => "../sadmin/dedoub_vide.php",
               ""                                           => "",
               "Revenir au menu &laquo;Vérification&raquo;" => "../sadmin/choix_verif.form.php");

print "<br /><ul type=\"square\">\n";
foreach ($goto as $action => $destination) {
    if (!$action) print "<br />";   //ligne vide
    elseif (!$destination)          //cas particulier
        print  "<li><a href=\"javascript:void(0)\" onClick=\"getpop('../prive/dupdates.csv',600,300,150,50)\">$action</a></li>\n";
    else print "<li><a href=\"$destination\">$action</a></li>\n";
    }
print "</ul>\n";
}


function entete() {
print "<html>
    <head>
    <meta http-equiv=\"content-type\" content=\"text/html; charset=ISO-8859-1\">
      <title>Traitement des doublons</title>
        <style type=\"text/css\" media=\"screen\">
            tr.meilleurchoix {
                background: #CCFFCC;
                color: Red;
                }
            td.eleve {
                background: #CCFFCC;
                color: Red;
                }
            td.compte {
                background: #CCCCFF;
                color: Navy;
                }
        </style>
    <link rel=\"stylesheet\" href=\"../include/general.css\">
    <script language=\"javascript\">
    function getpop(cible,w,h,l,t) {
       var param='width='+w+',height='+h+',left='+l+',top='+t+',status=0,directories=0,toolbar=0,menubar=1,location=0,scrollbars=1,resizable=1';
       fen=window.open(cible,'vasydefonce',param);
       fen_exist=true;
       window.fen.focus();
    }
    </script>
    </head>
    <body class=\"arial_sadmin\" bgcolor=\"white\" text=\"black\" link=\"white\" vlink=\"white\" alink=\"blue\">";
}


function blabla() {
print "
Vous pouvez choisir de visualiser <b>tous</b> les doublons. Vous pouvez aussi utiliser un <b>critère d'affichage</b> à l'aide des éléments de formulaire ci-dessous.<br /><br />
Dans un cas comme dans l'autre, une fois des doublons affichés, vous pourrez les traiter <b>globalement</b> ou <b>un par un</b>.<br />
<ul>
<li>Dans le premier cas, le script choisira les \"<u>meilleures données</u>\" pour l'individu référencé plusieurs fois dans la base.</li>
<li>Dans le second, pour un triplet (nom,prénom,date de naissance) qui a des homonymes, vous pourrez choisir :
    <ul><li>l'individu (élève ou prof) qui fournit <u>le bon établissement et la bonne année scolaire</u></li>
        <li>le compte dont <u>le login</u> vous semble le meilleur.</li>
    </ul>
</li>
</ul>
Enfin, lorsque le traitement sera terminé, vous pourrez récupérer les caractéristiques des individus traités dans un fichier CSV que vous pourrez
modifier à votre goût à l'aide d'un tableur.
Ce fichier sera aussi stocké dans le sous-répertoire b2i/prive.
";
print "<hr>";
}



?>
