<?php
/**
 * @version $Id$
 * @author Thomas Crespin <thomas.crespin@sesamath.net>
 * @copyright Thomas Crespin 2009-2022
 * 
 * ****************************************************************************************************
 * SACoche <https://sacoche.sesamath.net> - Suivi d’Acquisitions de Compétences
 * © Thomas Crespin pour Sésamath <https://www.sesamath.net> - Tous droits réservés.
 * Logiciel placé sous la licence libre Affero GPL 3 <https://www.gnu.org/licenses/agpl-3.0.html>.
 * ****************************************************************************************************
 * 
 * Ce fichier est une partie de SACoche.
 * 
 * SACoche est un logiciel libre ; vous pouvez le redistribuer ou le modifier suivant les termes 
 * de la “GNU Affero General Public License” telle que publiée par la Free Software Foundation :
 * soit la version 3 de cette licence, soit (à votre gré) toute version ultérieure.
 * 
 * SACoche est distribué dans l’espoir qu’il vous sera utile, mais SANS AUCUNE GARANTIE :
 * sans même la garantie implicite de COMMERCIALISABILITÉ ni d’ADÉQUATION À UN OBJECTIF PARTICULIER.
 * Consultez la Licence Publique Générale GNU Affero pour plus de détails.
 * 
 * Vous devriez avoir reçu une copie de la Licence Publique Générale GNU Affero avec SACoche ;
 * si ce n’est pas le cas, consultez : <http://www.gnu.org/licenses/>.
 * 
 */

if(!defined('SACoche')) {exit('Ce fichier ne peut être appelé directement !');}
if($_SESSION['SESAMATH_ID']==ID_DEMO){Json::end( FALSE , 'Action désactivée pour la démo.' );}

$action  = Clean::post('f_action' , 'texte');
$section = Clean::post('f_section', 'texte');
$objet   = Clean::post('f_objet'  , 'texte');

// ////////////////////////////////////////////////////////////////////////////////////////////////////
// Voir le contenu d’un fichier déjà importé
// ////////////////////////////////////////////////////////////////////////////////////////////////////

if( ($action=='voir_import') && $objet )
{
  $tab_fichier = DB_STRUCTURE_SIECLE::DB_recuperer_import_contenu($objet);
  if(empty($tab_fichier))
  {
    Json::end( FALSE , 'Fichier introuvable ! Objet transmis ("'.html($objet).'") correct ?' );
  }
  Json::end( TRUE , print_r($tab_fichier,TRUE) );
}

// ////////////////////////////////////////////////////////////////////////////////////////////////////
// Récupération des autres valeurs transmises sinon
// ////////////////////////////////////////////////////////////////////////////////////////////////////

if( ($action!='recolter') && ($action!='generer_export') )
{
  Json::end( FALSE , 'Erreur avec les données transmises !' );
}

$PAGE_REF   = Clean::post('f_page_ref'  , 'texte');
$periode    = Clean::post('f_periode'   , 'texte');
$classe_id  = Clean::post('f_classe'    , 'entier');
$groupe_nom = Clean::post('f_groupe_nom', 'texte');
$version    = Clean::post('f_version'   , 'texte');
$tab_eleve  = Clean::post('f_eleve'   , array('array',','));
$tab_eleve  = array_filter( Clean::map('entier',$tab_eleve) , 'positif' );

// Tableaux communs utiles

$tab_periode_livret = array(
  'periode21' => 'Semestre 1/2' ,
  'periode22' => 'Semestre 2/2' ,
  'periode31' => 'Trimestre 1/3',
  'periode32' => 'Trimestre 2/3',
  'periode33' => 'Trimestre 3/3',
  'periode41' => 'Bimestre 1/4' ,
  'periode42' => 'Bimestre 2/4' ,
  'periode43' => 'Bimestre 3/4' ,
  'periode44' => 'Bimestre 4/4' ,
  'periode51' => 'Période 1/5'  ,
  'periode52' => 'Période 2/5'  ,
  'periode53' => 'Période 3/5'  ,
  'periode54' => 'Période 4/5'  ,
  'periode55' => 'Période 5/5'  ,
  'cycle0'    => 'Fin de cycle' ,
  'annuel0'  => 'Moyennes annuelles 3e' ,
);

$tab_export_type = array(
  'cycle1' => 'maternelle',
  'cp'     => 'ecole',
  'ce1'    => 'ecole',
  'ce2'    => 'ecole',
  'cycle2' => 'ecole',
  'cm1'    => 'ecole',
  'cm2'    => 'ecole',
  '6e'     => 'college',
  'cycle3' => 'college',
  '5e'     => 'college',
  '4e'     => 'college',
  '3e'     => 'college',
  'cycle4' => 'college',
  'dnb'    => 'college',
);

// Vérification version

if($action=='generer_export')
{
  $tab_xsd_version = array('9.0','11.0','12.0','13.0');
  if(empty($version))
  {
    Json::end( FALSE , 'Version de LSU non transmise !' );
  }
  if(!in_array($version,$tab_xsd_version))
  {
    Json::end( FALSE , 'Version de LSU "'.html($version).'" inconnue !' );
  }

  // $xsd_schema_version_ecole   = (version_compare(TODAY_SQL,'2024-09-01','>=')) ? '7.0' : '6.0' ;
  // $xsd_schema_version_college = (version_compare(TODAY_SQL,'2024-09-01','>=')) ? '8.0' : '7.0' ;
  $xsd_schema_version_ecole   = '9.0' ;
  $xsd_schema_version_college = ($version=='9.0') ? '12.0' : $version ;

  $tab_xml_param = array(
    'ecole' => array(
      'schema'   => 'xsi:schemaLocation="urn:fr:edu:scolarite:lsun:bilans:import import-bilan-1d.xsd" schemaVersion="'.$xsd_schema_version_ecole.'"',
      'file_xsd' => 'livret-scolaire_1d_schema_'.$xsd_schema_version_ecole.'.xsd',
    ),
    'college' => array(
      'schema'   => 'xsi:schemaLocation="urn:fr:edu:scolarite:lsun:bilans:import import-bilan-complet.xsd" schemaVersion="'.$xsd_schema_version_college.'"',
      'file_xsd' => 'livret-scolaire_2d_schema_'.$xsd_schema_version_college.'.xsd',
    ),
  );
}


// Vérification période

if( !isset($tab_periode_livret[$periode]) && ( ($action=='recolter') || !empty($periode) ) )
{
  Json::end( FALSE , 'Période "'.html($periode).'" inconnue !' );
}

// ////////////////////////////////////////////////////////////////////////////////////////////////////
// Récolter les données pour les élèves d’une classes et d’une période
// ////////////////////////////////////////////////////////////////////////////////////////////////////

if($action=='recolter')
{
  $periode_nom = $tab_periode_livret[$periode];
  require(CHEMIN_DOSSIER_INCLUDE.'code_livret_recolter.php');
  // Normalement, on est stoppé avant.
  Json::end( FALSE , 'Problème de code : point d’arrêt manquant !' );
}

// ////////////////////////////////////////////////////////////////////////////////////////////////////
// Générer le fichier d’export en fonction des critères sélectionnés
// ////////////////////////////////////////////////////////////////////////////////////////////////////

// Fermeture de session (mais pas destruction, juste écriture et libération des données pour éviter un verrouillage en écriture)
Session::write_close();

// Elèves
if( empty($tab_eleve) )
{
  Json::end( FALSE , 'Erreur avec les données transmises !' );
}
$liste_eleve_id = implode(',',$tab_eleve);

// Période
if(substr($periode,0,7)=='periode')
{
  $PAGE_PERIODICITE = 'periode';
  $JOINTURE_PERIODE = substr($periode,7);
}
else if(substr($periode,0,5)=='cycle')
{
  $PAGE_PERIODICITE = 'cycle';
  $JOINTURE_PERIODE = '0';
}
else if(substr($periode,0,6)=='annuel')
{
  $PAGE_PERIODICITE = 'annuel';
  $JOINTURE_PERIODE = '0';
}
else
{
  $PAGE_PERIODICITE = '';
  $JOINTURE_PERIODE = '0';
}

// Au cas où...
Erreur500::prevention_et_gestion_erreurs_fatales( TRUE /*memory*/ , TRUE /*time*/ );

// Données
$DB_TAB = DB_STRUCTURE_LIVRET::DB_lister_livret_export_eleves( $liste_eleve_id , $PAGE_PERIODICITE , $JOINTURE_PERIODE );
if(empty($DB_TAB))
{
  Json::end( FALSE , 'Aucun bilan trouvé selon les critères transmis !' );
}

// On extrait les données élèves et on mutualise les données communes
$tab_export_objet   = array();
$tab_export_eleve   = array();
$tab_export_donnees = array();
$tab_export_commun  = array(
  'periode'          => array(),
  'directeur'        => array(), // 1D
  'classe'           => array(), // 1D
  'responsable-etab' => array(), // 2D
  'discipline'       => array(), // 2D
  'enseignant'       => array(),
  'element'          => array(),
  'crcn'             => array(),
  'epi-thematique'   => array(), // 2D
  'epi'              => array(), // 2D
  'ap'               => array(), // 2D
  'parcours'         => array(),
  'viesco'           => array(), // 2D
);

foreach($DB_TAB as $key => $DB_ROW)
{
  $export_objet = $tab_export_type[$DB_ROW['livret_page_ref']];
  $tab_export_objet[ $export_objet ] = TRUE;
  $tab_export_donnees[$key] = json_decode($DB_ROW['export_contenu'], TRUE);
  $tab_export_eleve[$DB_ROW['user_id']] = $tab_export_donnees[$key]['eleve'];
  if($export_objet=='college')
  {
    $tab_export_commun['responsable-etab'] = array_merge( $tab_export_commun['responsable-etab'] , $tab_export_donnees[$key]['commun']['responsable-etab'] );
    $tab_export_commun['epi']              = array_merge( $tab_export_commun['epi']              , $tab_export_donnees[$key]['commun']['epi']              );
    $tab_export_commun['ap']               = array_merge( $tab_export_commun['ap']               , $tab_export_donnees[$key]['commun']['ap']               );
    $tab_export_commun['viesco']           = array_merge( $tab_export_commun['viesco']           , $tab_export_donnees[$key]['commun']['viesco']           );
    $tab_export_commun['discipline']       = array_merge( $tab_export_commun['discipline']       , $tab_export_donnees[$key]['commun']['discipline']       );
  }
  if($export_objet=='ecole')
  {
    $tab_export_commun['directeur']        = array_merge( $tab_export_commun['directeur']        , $tab_export_donnees[$key]['commun']['directeur']        );
    $tab_export_commun['classe']           = array_merge( $tab_export_commun['classe']           , $tab_export_donnees[$key]['commun']['classe']           );
  }
  $tab_export_commun['periode']            = array_merge( $tab_export_commun['periode']          , $tab_export_donnees[$key]['commun']['periode']          );
  $tab_export_commun['enseignant']         = array_merge( $tab_export_commun['enseignant']       , $tab_export_donnees[$key]['commun']['enseignant']       );
  $tab_export_commun['element']            = array_merge( $tab_export_commun['element']          , $tab_export_donnees[$key]['commun']['element']          );
  $tab_export_commun['crcn']               = array_merge( $tab_export_commun['crcn']             , $tab_export_donnees[$key]['commun']['crcn']             );
  $tab_export_commun['parcours']           = array_merge( $tab_export_commun['parcours']         , $tab_export_donnees[$key]['commun']['parcours']         );
  unset( $tab_export_donnees[$key]['eleve'] , $tab_export_donnees[$key]['commun'] );
}

if( isset($tab_export_objet['cycle_maternelle']) )
{
  Json::end( FALSE , 'L’application nationale ne gère pas le bilan de maternelle (qui ne fait pas partie du Livret Scolaire) !' );
}

if( count($tab_export_objet) > 1 )
{
  Json::end( FALSE , 'Il est impossible d’exporter dans un fichier unique des bilans de différents formats('.implode(' / ',array_keys($tab_export_objet)).') !' );
}

$export_objet = key($tab_export_objet);

// ////////////////////////////////////////////////////////////////////////////////////////////////////
/* 
 * Libérer de la place mémoire car les scripts de bilans sont assez gourmands.
 * Supprimer $DB_TAB ne fonctionne pas si on ne force pas auparavant la fermeture de la connexion.
 * SebR devrait peut-être envisager d’ajouter une méthode qui libère cette mémoire, si c’est possible...
 */
// ////////////////////////////////////////////////////////////////////////////////////////////////////

DB::close(SACOCHE_STRUCTURE_BD_NAME);
unset($DB_TAB);

// On attaque le XML : prologue + élément racine

$tab_xml = array();
$tab_xml[] = '<?xml version="1.0" encoding="UTF-8"?>';
$tab_xml[] = '<lsun-bilans xmlns="urn:fr:edu:scolarite:lsun:bilans:import" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" '.$tab_xml_param[$export_objet]['schema'].'>';
// entête
$tab_xml[] = ' <entete>';
$tab_xml[] = '  <editeur>Sésamath</editeur>';
$tab_xml[] = '  <application>SACoche</application>';
$tab_xml[] = '  <appliVersion>'.VERSION_PROG.'</appliVersion>';
$tab_xml[] = '  <etablissement>'.html($_SESSION['WEBMESTRE_UAI']).'</etablissement>';
$tab_xml[] = ' </entete>';
$tab_xml[] = ' <donnees>';

// Attention, pour la conformité du XML, l’odre est important (j'aurais bien mis <eleves> en premier mais ce n’est pas permis).

$key_classe        = ($export_objet=='college') ? 'code-division'        : 'classe-ref' ;
$key_profs_eleve   = ($export_objet=='college') ? 'prof-princ-refs'      : 'enseignant-refs' ;
$key_chef_etabl    = ($export_objet=='college') ? 'responsable-etab-ref' : 'directeur-ref' ;
$key_appr_synthese = ($export_objet=='college') ? 'acquis-conseils'      : 'appreciation-generale' ;

// responsables-etab (2D, sauf si uniquement moyennes annuelles... ah bah non, le le DTD l'exige...)
if( ($export_objet=='college') && !empty($tab_export_commun['responsable-etab']) )
{
  $tab_xml[] = '  <responsables-etab>';
  foreach($tab_export_commun['responsable-etab'] as $id => $tab)
  {
    $tab_xml[] = '   <responsable-etab id="'.$id.'" libelle="'.html($tab['libelle']).'" />';
  }
  $tab_xml[] = '  </responsables-etab>';
}

// directeurs & classes (1D)
if($export_objet=='ecole')
{
  $tab_xml[] = '  <directeurs>';
  foreach($tab_export_commun['directeur'] as $id => $tab)
  {
    $tab_xml[] = '   <directeur id="'.$id.'" civilite="'.$tab['civilite'].'" nom="'.html($tab['nom']).'" prenom="'.html($tab['prenom']).'" />';
  }
  $tab_xml[] = '  </directeurs>';
  $tab_xml[] = '  <classes>';
  foreach($tab_export_commun['classe'] as $id => $tab)
  {
    $tab_xml[] = '   <classe id="'.$id.'" id-be="'.$tab['id-be'].'" libelle="'.html($tab['libelle']).'" />';
  }
  $tab_xml[] = '  </classes>';
}

// eleves
$nb_eleves = count($tab_export_eleve);
$tab_xml[] = '  <eleves>';
foreach($tab_export_eleve as $eleve_id => $tab)
{
  switch($export_objet)
  {
    case 'college' : $tab_xml[] = '   <eleve id="'.$tab['id'].'" id-be="'.$tab['id-be'].'" nom="'.html($tab['nom']).'" prenom="'.html($tab['prenom']).'" '.$key_classe.'="'.html($tab[$key_classe]).'" />'; break;
    case 'ecole'   : $tab_xml[] = '   <eleve id="'.$tab['id'].'" ine="'.$tab['ine'].'" '.$key_classe.'="'.html($tab[$key_classe]).'" nom="'.html($tab['nom']).'" prenom="'.html($tab['prenom']).'" />'; break;
  }
}
$tab_xml[] = '  </eleves>';
unset( $tab_export_eleve );

// periodes (uniquement si présence de bilans périodiques)
if(!empty($tab_export_commun['periode']))
{
  $tab_xml[] = '  <periodes>';
  foreach($tab_export_commun['periode'] as $id => $tab)
  {
    $date_debut = ($export_objet=='college') ? '' : ' date-debut="'.$tab['date-debut'].'"' ;
    $date_fin   = ($export_objet=='college') ? '' : ' date-fin="'.$tab['date-fin'].'"' ;
    $tab_xml[] = '   <periode id="'.$id.'" millesime="'.$tab['millesime'].'" indice="'.$tab['indice'].'" nb-periodes="'.$tab['nb-periodes'].'"'.$date_debut.$date_fin.' />';
  }
  $tab_xml[] = '  </periodes>';
}

// disciplines (2D & uniquement si présence de bilans périodiques ou de moyennes annuelles)
if(!empty($tab_export_commun['discipline']))
{
  $tab_xml[] = '  <disciplines>';
  foreach($tab_export_commun['discipline'] as $id => $tab)
  {
    /*
    Pour l’année scolaire 2025‑2026, il est demandé 
    - uniquement pour les élèves de niveau 3IEME, et uniquement pour les matières attendues (celles figurant dans le fichier de nomenclatures) - 
    qu’au moment de la génération du fichier d’export, 
    votre solution logicielle convertisse le code des matières avec modalité d’éloignement en leur matière équivalente sans modalité d’éloignement.
    À titre d’exemple : les matières 030211 ANGLAIS LV1 A DISTANCE ou 030221 ANGLAIS LV1 HORS ÉTABLISSEMENT seront converties en 030201 ANGLAIS LV1.
    ...
    Ici je ne sais pas si c’est une matière DNB, ni pour des élèves de 3e... 
    Et il y a risque de conflit avec une autre matière sans modalité d’éloignement... même si a priori c’est qu’elle n’est pas enseignée dans l’établissement...
    Mais bon, pas le choix, je retire la modalité d’éloignement...
    Attention aux matières spécifiques où le code n’a rien à voir (d’où le premier test).
    */
    $code = ( ($tab['code'][0]=='x') || ($tab['code'][4]=='0') ) ? $tab['code'] : substr($tab['code'],0,4).'0'.$tab['code'][5];
    $id_lv = empty($tab['id-lv']) ? '' : ' id-lv="'.$tab['id-lv'].'"' ;
    $tab_xml[] = '   <discipline id="'.$id.'" code="'.$code.'" modalite-election="'.$tab['modalite-election'].'" libelle="'.html($tab['libelle']).'"'.$id_lv.' />';
  }
  $tab_xml[] = '  </disciplines>';
}

// enseignants (sauf si uniquement moyennes annuelles)
if(!empty($tab_export_commun['enseignant']))
{
  $tab_xml[] = '  <enseignants>';
  foreach($tab_export_commun['enseignant'] as $id => $tab)
  {
    $civilite = $tab['civilite'] ? ' civilite="'.$tab['civilite'].'"' : '' ;
    switch($export_objet)
    {
      case 'college' : $tab_xml[] = '   <enseignant id="'.$id.'" type="'.$tab['type'].'" id-sts="'.$tab['id-sts'].'"'.$civilite.' nom="'.html($tab['nom']).'" prenom="'.html($tab['prenom']).'" />'; break;
      case 'ecole'   : $tab_xml[] = '   <enseignant id="'.$id.'"'.$civilite.' nom="'.html($tab['nom']).'" prenom="'.html($tab['prenom']).'" />'; break;
    }
  }
  $tab_xml[] = '  </enseignants>';
}

// elements-programme (facultatif + uniquement si présence de bilans périodiques)
if(!empty($tab_export_commun['element']))
{
  $tab_xml[] = '  <elements-programme>';
  foreach($tab_export_commun['element'] as $id => $libelle)
  {
    $tab_xml[] = '   <element-programme id="'.$id.'" libelle="'.html($libelle).'" />';
  }
  $tab_xml[] = '  </elements-programme>';
}

// competences-numeriques-communs (appréciation sur la classe) (facultatif + uniquement si dernier bilan périodique de cm2 ou 6e)
if(!empty($tab_export_commun['crcn']))
{
  $tab_xml[] = '  <competences-numeriques-communs>';
  foreach($tab_export_commun['crcn'] as $key => $tab)
  {
    $classe_structure = ($export_objet=='college') ? ' code-structure="'.html($tab['code-structure']).'" type-structure="'.$tab['type-structure'].'"' : '' ;
    $tab_xml[] = '   <competences-numeriques-commun id="'.$key.'"'.$classe_structure.'>'.html($tab['appreciation']).'</competences-numeriques-commun>';
  }
  $tab_xml[] = '  </competences-numeriques-communs>';
}

// parcours-communs (appréciation sur la classe) (facultatif + uniquement si présence de bilans périodiques)
if(!empty($tab_export_commun['parcours']))
{
  $tab_parcours = array();
  foreach($tab_export_commun['parcours'] as $key => $tab)
  {
    $tab_parcours[$tab['periode-ref'].'¤'.$tab[$key_classe]][] = $tab;
  }
  $tab_xml[] = '  <parcours-communs>';
  foreach($tab_parcours as $key => $tab_ensemble)
  {
    list( $periode_ref , $champ_classe ) = explode('¤',$key,2);
    $tab_xml[] = '   <parcours-commun periode-ref="'.$periode_ref.'" '.$key_classe.'="'.html($champ_classe).'">';
    foreach($tab_ensemble as $tab)
    {
      $tab_xml[] = '    <parcours code="'.$tab['code'].'">'.html($tab['projet']).'</parcours>';
    }
    $tab_xml[] = '   </parcours-commun>';
  }
  $tab_xml[] = '  </parcours-communs>';
}

// vies-scolaires-communs (appréciation sur la classe) (facultatif + uniquement si présence de bilans périodiques)
// --> pas de saisie proposée dans SACoche


// epi-thematique (2D & uniquement si présence de thématiques personnalisées dans des bilans périodiques)
if(!empty($tab_export_commun['epi-thematique']))
{
  $tab_xml[] = '  <epis-thematiques>';
  foreach($tab_export_commun['epi-thematique'] as $code => $libelle)
  {
    $tab_xml[] = '   <epi-thematique code="'.$code.'" libelle="'.html($libelle).'" />';
  }
  $tab_xml[] = '  </epis-thematiques>';
}

// epis & epis-groupes (facultatif + uniquement si présence de bilans périodiques)
if(!empty($tab_export_commun['epi']))
{
  $tab_xml[] = '  <epis>';
  foreach($tab_export_commun['epi'] as $key => $tab)
  {
    $tab_xml[] = '   <epi id="'.$tab['id'].'" intitule="'.html($tab['intitule']).'" thematique="'.$tab['thematique'].'" discipline-refs="'.implode(' ',array_unique($tab['discipline-refs'])).'">';
    if($tab['description'])
    {
      $tab_xml[] = '    <description>'.html($tab['description']).'</description>';
    }
    $tab_xml[] = '   </epi>';
  }
  $tab_xml[] = '  </epis>';
    // Pas de sous-groupes gérés dans SACoche, l’EPI est défini sur une classe...
  $tab_xml[] = '  <epis-groupes>';
  foreach($tab_export_commun['epi'] as $key => $tab)
  {
    $tab_xml[] = '   <epi-groupe id="'.$key.'GR" intitule="'.html($tab['intitule']).'" epi-ref="'.$tab['id'].'">';
    // Pour le commentaire sur le groupe, on reporte la description (c’est ce que veut LSU de toutes façons).
    if($tab['description'])
    {
      $tab_xml[] = '    <commentaire>'.html($tab['description']).'</commentaire>';
    }
    $tab_xml[] = '    <enseignants-disciplines>';
    foreach($tab['discipline-refs'] as $key => $discipline_ref)
    {
      $enseignant_ref = $tab['enseignant-refs'][$key];
      $tab_xml[] = '     <enseignant-discipline discipline-ref="'.$discipline_ref.'" enseignant-ref="'.$enseignant_ref.'" />';
    }
    $tab_xml[] = '    </enseignants-disciplines>';
    $tab_xml[] = '   </epi-groupe>';
  }
  $tab_xml[] = '  </epis-groupes>';
}

// acc-persos & acc-persos-groupes (facultatif + uniquement si présence de bilans périodiques)
// AP supprimés à compter de LSU 25.5.0 diffusée aux académies le 19/01/2026 !!!
if( !empty($tab_export_commun['ap']) && version_compare($xsd_schema_version_college,'12.0','<') )
{
  $tab_xml[] = '  <acc-persos>';
  foreach($tab_export_commun['ap'] as $key => $tab)
  {
    $tab_xml[] = '   <acc-perso id="'.$tab['id'].'" intitule="'.html($tab['intitule']).'" discipline-refs="'.implode(' ',array_unique($tab['discipline-refs'])).'">';
    // EDIT 2019-02-02 : retiré, car sinon LSU l’affiche maintenant en double avec le commentaire sur le groupe (voir juste en dessous)...
    // if($tab['description'])
    // {
    //   $tab_xml[] = '    <description>'.html($tab['description']).'</description>';
    // }
    $tab_xml[] = '   </acc-perso>';
  }
  $tab_xml[] = '  </acc-persos>';
    // Pas de sous-groupes gérés dans SACoche, l’AP est défini sur une classe...
  $tab_xml[] = '  <acc-persos-groupes>';
  foreach($tab_export_commun['ap'] as $key => $tab)
  {
    $tab_xml[] = '   <acc-perso-groupe id="'.$key.'GR" intitule="'.html($tab['intitule']).'" acc-perso-ref="'.$tab['id'].'">';
    // Pour le commentaire sur le groupe, on reporte la description (c’est ce que veut LSU de toutes façons).
    if($tab['description'])
    {
      $tab_xml[] = '    <commentaire>'.html($tab['description']).'</commentaire>';
    }
    $tab_xml[] = '    <enseignants-disciplines>';
    foreach($tab['discipline-refs'] as $key => $discipline_ref)
    {
      $enseignant_ref = $tab['enseignant-refs'][$key];
      $tab_xml[] = '     <enseignant-discipline discipline-ref="'.$discipline_ref.'" enseignant-ref="'.$enseignant_ref.'" />';
    }
    $tab_xml[] = '    </enseignants-disciplines>';
    $tab_xml[] = '   </acc-perso-groupe>';
  }
  $tab_xml[] = '  </acc-persos-groupes>';
}

unset( $tab_export_commun );

// responsables (dans une fonction car commun aux bilans périodiques et de fin de cycle)
function xml_responsables($tab_donnee_bilan_responsables)
{
  $tab_xml = array();
  $tab_xml[] = '    <responsables>';
  // A compter de LSU 18.4 on utilise un unique champ 'dénomination' et on fusionne les responsables de même adresse
  $tab_xml_responsable_adresse = array();
  foreach($tab_donnee_bilan_responsables as $resp_num => $tab)
  {
    $ligne2 = $tab['ligne2']   ? ' ligne2="'.html($tab['ligne2']).'"' : '' ;
    $ligne3 = $tab['ligne3']   ? ' ligne3="'.html($tab['ligne3']).'"' : '' ;
    $ligne4 = $tab['ligne4']   ? ' ligne4="'.html($tab['ligne4']).'"' : '' ;
    $adresse = '<adresse ligne1="'.html($tab['ligne1']).'"'.$ligne2.$ligne3.$ligne4.' code-postal="'.html($tab['code-postal']).'" commune="'.html($tab['commune']).'" />';
    $md5 = md5($adresse);
    if(!isset($tab_xml_responsable_adresse[$md5]))
    {
      $tab_xml_responsable_adresse[$md5] = array(
        'denomination' => $tab['nom'].' '.$tab['prenom'],
        'adresse'      => $adresse,
      );
    }
    else
    {
      $tab_xml_responsable_adresse[$md5]['denomination'] .= ', '.$tab['prenom'];
    }
  }
  foreach($tab_xml_responsable_adresse as $md5 => $tab)
  {
    $tab_xml[] = '     <responsable denomination="'.html($tab['denomination']).'">'; // lien-parente non géré (facultatif) ; legal peu compatible avec ce format
    $tab_xml[] = '      '.$tab['adresse'];
    $tab_xml[] = '     </responsable>';
  }
  $tab_xml[] = '    </responsables>';
  return $tab_xml;
}

// bilans périodiques ou de fin de cycle ou moyennes annuelles
$nb_bilans = count($tab_export_donnees);
$tab_xml_bilans = array ( 'periodique' => array() , 'cycle' => array() );
$rubrique_sans_element = FALSE ;
foreach($tab_export_donnees as $key => $tab_donnee_bilan)
{
  $tab_bilan = $tab_donnee_bilan['bilan'];
  // [1] BILAN PÉRIODIQUE
  if($tab_bilan['type']=='periode')
  {
    $date_bilan  = ($export_objet=='college') ? 'date-conseil-classe="'.$tab_bilan['date-conseil-classe'].'"' : 'date-creation="'.$tab_bilan['date-creation'].'"' ;
    $profs_eleve_refs = !empty($tab_bilan[$key_profs_eleve]) ? ' '.$key_profs_eleve.'="'.$tab_bilan[$key_profs_eleve].'"' : '' ;
    $tab_xml_bilans['periodique'][] = '   <bilan-periodique'.$profs_eleve_refs.' eleve-ref="'.$tab_bilan['eleve-ref'].'" periode-ref="'.$tab_bilan['periode-ref'].'" '.$date_bilan.' date-scolarite="'.$tab_bilan['date-scolarite'].'" '.$key_chef_etabl.'="'.$tab_bilan[$key_chef_etabl].'">';
    $champ_position = $tab_bilan['position'];
    // liste-acquis
    $tab_xml_bilans['periodique'][] = '    <liste-acquis>';
    // 2D
    if($export_objet=='college')
    {
      foreach($tab_donnee_bilan['acquis'] as $discipline_ref => $tab)
      {
        // élément de prg travaillé obligatoire
        $element_programme_refs = !empty($tab['elements']) ? implode(' ',$tab['elements']) : 'EL0' ;
        // positionnement
        // si élève avec positionnement manquant transmettre :
        // 1 = "non noté" hors MEF 3e
        // 2 = "en attente" pour le niveau 3e (sauf dispensé)
        // 3 = "dispensé" pour le niveau 3e EPS ou LV2 uniquement
        if( is_null($tab[$champ_position]) )
        {
          $position_eleve = ' statut-evaluation-eleve="'.( ($tab_bilan['page_ref']!='3e') ? '1' : '2' ).'"';
        }
        else if($tab[$champ_position]==='DI') // sur les vieilles versions de PHP le test ( 0 == 'blablabla' ) renvoie TRUE !
        {
          $position_eleve = ' statut-evaluation-eleve="3"';
        }
        else
        {
          $position_eleve = ' '.$champ_position.'="'.$tab[$champ_position].'"';
        }
        // classe sans positionnement par paramétrage ou car positionnement élève non chiffré
        if( !$tab_bilan['moyenne_classe'] || ($champ_position=='positionnement') )
        {
          $position_classe = '';
        }
        // classe paramétrée avec positionnement mais manquant : transmettre 1 = "non noté" ou 2 = "en attente" pour le niveau 3e
        else if( is_null($tab['moyenne-structure']))
        {
          $position_classe = ' statut-evaluation-structure="'.( ($tab_bilan['page_ref']!='3e') ? '1' : '2' ).'"';
        }
        // classe paramétrée avec un positionnement qui a bien été déterminé
        else
        {
          $position_classe = ' moyenne-structure="'.$tab['moyenne-structure'].'"';
        }
        $tab_xml_bilans['periodique'][] = '     <acquis discipline-ref="'.$discipline_ref.'" enseignant-refs="'.implode(' ',$tab['profs']).'" element-programme-refs="'.$element_programme_refs.'"'.$position_eleve.$position_classe.' >';
        // appréciation obligatoire sauf si élève non noté
        if( $tab['appreciation'] || ( !is_null($tab[$champ_position]) && ($tab[$champ_position]!='DI') ) )
        {
          $tab['appreciation'] = !empty($tab['appreciation']) ? $tab['appreciation'] : '-' ;
          $tab_xml_bilans['periodique'][] = '      <appreciation>'.html($tab['appreciation']).'</appreciation>';
        }
        $rubrique_sans_element = $rubrique_sans_element || ($element_programme_refs=='EL0') ;
        $tab_xml_bilans['periodique'][] = '     </acquis>';
      }
    }
    // 1D
    if($export_objet=='ecole')
    {
      // on fait 2 passages parce que c’est compliqué sinon
      $tab_acquis_domaine = array();
      foreach($tab_donnee_bilan['acquis'] as $code => $tab)
      {
        list( $domaine , $sous_domaine ) = explode('-',$code);
        $element_programme_refs = !empty($tab['elements']) ? ' element-programme-refs="'.implode(' ',$tab['elements']).'"' : '' ;
        $positionnement = ($tab['positionnement']) ? ' positionnement="'.$tab['positionnement'].'"' : ' non-evalue="true"' ;
        if( $sous_domaine == 'RAC' )
        {
          $tab_acquis_domaine[$domaine] = array(
            'nb_sous_domaine'        => 0,
            'element_programme_refs' => $element_programme_refs,
            'positionnement'         => $positionnement,
            'appreciation'           => $tab['appreciation'],
          );
        }
        else
        {
          if(!isset($tab_acquis_domaine[$domaine]))
          {
            $tab_acquis_domaine[$domaine]['nb_sous_domaine'] = 1;
            $tab_acquis_domaine[$domaine]['nb_sous_domaine_avec_infos'] = 0;
            $tab_acquis_domaine[$domaine]['appreciation'] = $tab['appreciation'];
          }
          else
          {
            $tab_acquis_domaine[$domaine]['nb_sous_domaine'] += 1;
            $tab_acquis_domaine[$domaine]['appreciation'] .= $tab['appreciation'];
          }
          $tab_acquis_domaine[$domaine]['sous_domaine'][$sous_domaine] = array(
            'element_programme_refs' => $element_programme_refs,
            'positionnement'         => $positionnement,
          );
          if( $element_programme_refs || strpos($positionnement,'positionnement') )
          {
            $tab_acquis_domaine[$domaine]['nb_sous_domaine_avec_infos'] += 1;
          }
        }
      }
      foreach($tab_acquis_domaine as $code_domaine => $tab_info_domaine)
      {
        if($tab_info_domaine['nb_sous_domaine']==0)
        {
          $tab_xml_bilans['periodique'][] = '     <acquis code-domaine="'.$code_domaine.'-RAC"'.$tab_info_domaine['element_programme_refs'].$tab_info_domaine['positionnement'].'>';
          if($tab_info_domaine['appreciation'])
          {
            $tab_xml_bilans['periodique'][] = '      <appreciation>'.html($tab_info_domaine['appreciation']).'</appreciation>';
          }
          $tab_xml_bilans['periodique'][] = '     </acquis>';
        }
        else
        {
          $tab_xml_bilans['periodique'][] = '     <acquis code-domaine="'.$code_domaine.'-RAC">';
          if($tab_info_domaine['appreciation'])
          {
            $tab_xml_bilans['periodique'][] = '      <appreciation>'.html($tab_info_domaine['appreciation']).'</appreciation>';
          }
          if($tab_info_domaine['nb_sous_domaine'])
          {
            $tab_xml_bilans['periodique'][] = '      <sous-domaines>';
            foreach($tab_info_domaine['sous_domaine'] as $code_sous_domaine => $tab_info_sous_domaine)
            {
              // test pour éviter de passer ici en cas de domaine avec en théorie des sous-domaines mais en réalité seulement une appréciation transmise rattachée au 1er élément bien qu’il n’apparaisse pas
              // attention, il peut aussi s’agir d’un sous-domaine unique sans positionnement ni éléments de prg travaillés donc avec seulement une appréciation !
              if( $tab_info_sous_domaine['element_programme_refs'] || strpos($tab_info_sous_domaine['positionnement'],'positionnement') || ($tab_info_domaine['nb_sous_domaine']==1) || ($tab_info_domaine['nb_sous_domaine_avec_infos']==0) )
              {
                $tab_xml_bilans['periodique'][] = '       <sous-domaine code-domaine="'.$code_domaine.'-'.$code_sous_domaine.'"'.$tab_info_sous_domaine['element_programme_refs'].$tab_info_sous_domaine['positionnement'].' />';            }
            }
            $tab_xml_bilans['periodique'][] = '      </sous-domaines>';
          }
          $tab_xml_bilans['periodique'][] = '     </acquis>';
        }
      }
    }
    $tab_xml_bilans['periodique'][] = '    </liste-acquis>';
    // competences-numeriques
    if(!empty($tab_donnee_bilan['crcn']))
    {
      $tab_crcn = $tab_donnee_bilan['crcn'];
      $comp_num_commun_refs = !empty($tab_crcn['comp-num-commun-refs']) ? ' comp-num-commun-refs="'.$tab_crcn['comp-num-commun-refs'].'"' : '' ;
      $tab_xml_bilans['periodique'][] = '    <competences-numeriques'.$comp_num_commun_refs.'>';
      if(!empty($tab_crcn['appreciation']))
      {
        $tab_xml_bilans['periodique'][] = '     <appreciation-num>'.html($tab_crcn['appreciation']).'</appreciation-num>';
      }
      if(!empty($tab_crcn['niveau']))
      {
        foreach($tab_crcn['niveau'] as $code => $niveau)
        {
          // Pour l’instant obligatoire que pour la fin de cycle 3, avec un niveau compris entre 1 et 3 uniquement.
          $niveau = min($niveau,3);
          $tab_xml_bilans['periodique'][] = '     <competence-num code="'.$code.'" niveau="'.$niveau.'" />';
        }
      }
      $tab_xml_bilans['periodique'][] = '    </competences-numeriques>';
    }
    // epis-eleve (2D)
    if(!empty($tab_donnee_bilan['epi']))
    {
      $tab_xml_bilans['periodique'][] = '    <epis-eleve>';
      foreach($tab_donnee_bilan['epi'] as $id => $tab)
      {
        $tab_xml_bilans['periodique'][] = '     <epi-eleve epi-groupe-ref="'.$id.'GR">';
        if(!empty($tab['appreciation']))
        {
          $tab_xml_bilans['periodique'][] = '      <commentaire>'.html($tab['appreciation']).'</commentaire>';
        }
        $tab_xml_bilans['periodique'][] = '     </epi-eleve>';
      }
      $tab_xml_bilans['periodique'][] = '    </epis-eleve>';
    }
    // acc-persos-eleve (2D)
    // AP supprimés à compter de LSU 25.5.0 diffusée aux académies le 19/01/2026 !!!
    if( !empty($tab_export_commun['ap']) && version_compare($xsd_schema_version_college,'12.0','<') )
    {
      $tab_xml_bilans['periodique'][] = '    <acc-persos-eleve>';
      foreach($tab_donnee_bilan['ap'] as $id => $tab)
      {
        $tab_xml_bilans['periodique'][] = '     <acc-perso-eleve acc-perso-groupe-ref="'.$id.'GR">';
        if(!empty($tab['appreciation']))
        {
          $tab_xml_bilans['periodique'][] = '      <commentaire>'.html($tab['appreciation']).'</commentaire>';
        }
        $tab_xml_bilans['periodique'][] = '     </acc-perso-eleve>';
      }
      $tab_xml_bilans['periodique'][] = '    </acc-persos-eleve>';
    }
    // parcours
    if(!empty($tab_donnee_bilan['parcours']))
    {
      $tab_xml_bilans['periodique'][] = '    <liste-parcours>';
      foreach($tab_donnee_bilan['parcours'] as $id => $tab)
      {
        $tab['appreciation'] = !empty($tab['appreciation']) ? $tab['appreciation'] : '-' ;
        $tab_xml_bilans['periodique'][] = '     <parcours code="'.$tab['code'].'">'.html($tab['appreciation']).'</parcours>';
      }
      $tab_xml_bilans['periodique'][] = '    </liste-parcours>';
    }
    // modalites-accompagnement (2D)
    if(!empty($tab_donnee_bilan['modaccomp']))
    {
      $tab_xml_bilans['periodique'][] = '    <modalites-accompagnement>';
      foreach($tab_donnee_bilan['modaccomp'] as $code => $info_complement)
      {
        if( ($code!='PPRE') || !$info_complement )
        {
          $tab_xml_bilans['periodique'][] = '     <modalite-accompagnement code="'.$code.'" />';
        }
        else
        {
          $tab_xml_bilans['periodique'][] = '     <modalite-accompagnement code="'.$code.'"><complement-ppre>'.html($info_complement).'</complement-ppre></modalite-accompagnement>';
        }
      }
      $tab_xml_bilans['periodique'][] = '    </modalites-accompagnement>';
    }
    // acquis-conseils (2D) | appreciation-generale (1D)
    $tab_synthese = $tab_donnee_bilan['synthese'];
    $tab_xml_bilans['periodique'][] = '    <'.$key_appr_synthese.'>'.html($tab_synthese['appreciation']).'</'.$key_appr_synthese.'>';
    // devoirs-faits
    if(!empty($tab_donnee_bilan['devoirsfaits']))
    {
      $tab_xml_bilans['periodique'][] = '    <devoirs-faits>Élève inscrit au dispositif.</devoirs-faits>';
    }
    // vie-scolaire (2D)
    if(!empty($tab_donnee_bilan['viesco']))
    {
      $tab_viesco = $tab_donnee_bilan['viesco'];
      $tab_xml_bilans['periodique'][] = '    <vie-scolaire nb-retards="'.$tab_viesco['nb-retards'].'" nb-abs-justifiees="'.$tab_viesco['nb-abs-justifiees'].'" nb-abs-injustifiees="'.$tab_viesco['nb-abs-injustifiees'].'">'; // nb-heures-manquees non géré
      if(!empty($tab_viesco['appreciation']))
      {
        $tab_xml_bilans['periodique'][] = '     <commentaire>'.html($tab_viesco['appreciation']).'</commentaire>';
      }
      $tab_xml_bilans['periodique'][] = '    </vie-scolaire>';
    }
    // socle
    // --> pas géré pour l’instant
    // responsables
    if(!empty($tab_donnee_bilan['responsables']))
    {
      $tab_xml_bilans['periodique'] = array_merge( $tab_xml_bilans['periodique'] , xml_responsables($tab_donnee_bilan['responsables']) );
    }
    $tab_xml_bilans['periodique'][] = '   </bilan-periodique>';
  }
  // [2] MOYENNE ANNUELLE
  if( ($tab_bilan['type']=='annuel') && version_compare($xsd_schema_version_college,'13.0','>=') )
  {
    $tab_xml_bilans['moyennes-annuelles'][] = '   <moyennes-annuelles-eleve eleve-ref="'.$tab_bilan['eleve-ref'].'" millesime="'.$tab_bilan['millesime'].'">';
    foreach($tab_donnee_bilan['moyennes-annuelles'] as $discipline_ref => $moyenne)
    {
      // transmettre :
      // 1 = la moyenne
      // 2 = "en attente" si NULL
      // 3 = "dispensé" si DI (EPS ou LV2 uniquement)
      if( is_null($moyenne) )
      {
        $moyenne_eleve = ' statut-evaluation-eleve="2"';
      }
      else if($moyenne==='DI') // sur les vieilles versions de PHP le test ( 0 == 'blablabla' ) renvoie TRUE !
      {
        $moyenne_eleve = ' statut-evaluation-eleve="3"';
      }
      else
      {
        $moyenne_eleve = ' moyenne="'.$moyenne.'"';
      }
      $tab_xml_bilans['moyennes-annuelles'][] = '    <moyenne-annuelle discipline-ref="'.$discipline_ref.'"'.$moyenne_eleve.' />';
    }
    $tab_xml_bilans['moyennes-annuelles'][] = '   </moyennes-annuelles-eleve>';
  }
  // [3] BILAN DE FIN DE CYCLE
  else if($tab_bilan['type']=='cycle')
  {
    $profs_eleve_refs = !empty($tab_bilan[$key_profs_eleve]) ? ' '.$key_profs_eleve.'="'.$tab_bilan[$key_profs_eleve].'"' : '' ;
    $tab_xml_bilans['cycle'][] = '   <bilan-cycle'.$profs_eleve_refs.' eleve-ref="'.$tab_bilan['eleve-ref'].'" cycle="'.$tab_bilan['cycle'].'" millesime="'.$tab_bilan['millesime'].'" date-creation="'.$tab_bilan['date-creation'].'" '.$key_chef_etabl.'="'.$tab_bilan[$key_chef_etabl].'">';
    // domaines du socle
    $tab_xml_bilans['cycle'][] = '    <socle>';
    foreach($tab_donnee_bilan['socle'] as $id => $tab)
    {
      $tab_xml_bilans['cycle'][] = '     <domaine code="'.$tab['code'].'" positionnement="'.$tab['positionnement'].'" />';
    }
    $tab_xml_bilans['cycle'][] = '    </socle>';
    // synthèse
    $tab_synthese = $tab_donnee_bilan['synthese'];
    $tab_xml_bilans['cycle'][] = '    <synthese>'.html($tab_synthese['appreciation']).'</synthese>';
    // responsables
    if(!empty($tab_donnee_bilan['responsables']))
    {
      $tab_xml_bilans['cycle'] = array_merge( $tab_xml_bilans['cycle'] , xml_responsables($tab_donnee_bilan['responsables']) );
    }
    // langue de culture régionale (cycle 4 uniquement)
    if(!empty($tab_donnee_bilan['langcultregion']))
    {
      $tab_langcultregion = $tab_donnee_bilan['langcultregion'];
      $positionnement = ($tab_langcultregion['code']=='AUC') ? '' : ' positionnement="'.$tab_langcultregion['positionnement'].'"' ;
      $tab_xml_bilans['cycle'][] = '    <langue-culture-regionale code="'.$tab_langcultregion['code'].'"'.$positionnement.' />';
    }
    $tab_xml_bilans['cycle'][] = '   </bilan-cycle>';
  }
  unset($tab_export_donnees[$key]);
}
// assemblage
if(!empty($tab_xml_bilans['moyennes-annuelles']))
{
  $tab_xml[] = '  <moyennes-annuelles>';
  $tab_xml[] = implode(NL,$tab_xml_bilans['moyennes-annuelles']);
  $tab_xml[] = '  </moyennes-annuelles>';
}
if(!empty($tab_xml_bilans['periodique']))
{
  $tab_xml[] = '  <bilans-periodiques>';
  $tab_xml[] = implode(NL,$tab_xml_bilans['periodique']);
  $tab_xml[] = '  </bilans-periodiques>';
}
if(!empty($tab_xml_bilans['cycle']))
{
  $tab_xml[] = '  <bilans-cycle>';
  $tab_xml[] = implode(NL,$tab_xml_bilans['cycle']);
  $tab_xml[] = '  </bilans-cycle>';
}

// fermeture des balises
$tab_xml[] = ' </donnees>';
$tab_xml[] = '</lsun-bilans>';

// Le xml
$export_xml = implode(NL,$tab_xml);
if($rubrique_sans_element)
{
  $export_xml = str_replace( '<elements-programme>' , '<elements-programme>'.NL.'   <element-programme id="EL0" libelle="-" />' , $export_xml );
}

// Vérification XML valide

// @see http://php.net/manual/fr/domdocument.schemavalidate.php#62032
function libxml_display_error($error)
{
  $return = '<p>';
  switch ($error->level)
  {
    case LIBXML_ERR_WARNING:
      $return .= "<b>Warning $error->code</b> : ";
      break;
    case LIBXML_ERR_ERROR:
      $return .= "<b>Error $error->code</b> : ";
      break;
    case LIBXML_ERR_FATAL:
      $return .= "<b>Fatal Error $error->code</b> : ";
      break;
  }
  $return .= trim($error->message);
  /*
  if ($error->file) {
    $return .=    " in <b>$error->file</b>";
  }
  $return .= " on line <b>$error->line</b>\n";
  */
  $return .= '</p>'.NL;
  return $return;
}

libxml_use_internal_errors(TRUE);
$dom_xml= new DOMDocument();
$dom_xml->loadXML($export_xml);
if(!$dom_xml->schemaValidate(CHEMIN_DOSSIER_XSD.$tab_xml_param[$export_objet]['file_xsd']))
{
  $errors = libxml_get_errors();
  Json::add_str( '<p><label class="erreur">Fichier XML obtenu détecté invalide ; utilisez le lien [assistance] en haut de page en précisant la classe ou l’élève concerné et le message d’erreur.</label></p>' );
  foreach ($errors as $error)
  {
    Json::add_str( libxml_display_error($error) );
  }
  libxml_clear_errors();
  // En PROD on ne donne pas ce fichier qui de toutes façons sera rejeté par LSU.
  // Hors PROD on laisse la possibilité de récupérer le fichier pour l’analyser.
  if(SERVEUR_TYPE == 'PROD')
  {
    Json::end( FALSE );
  }
}

// à compter de LSU 19.2 une vérification est effectuée sur la taille du fichier, limité à 100 Mo
if( mb_strlen($export_xml) > 100000000 )
{
  Json::end( FALSE , 'Fichier dépassant la taille limite de 100 Mo autorisée par LSU !<br>Sélectionner moins d’élèves ou moins de périodes.' );
}

// Enregistrement du fichier
$periode_nom = ($periode) ? $tab_periode_livret[$periode] : 'Toutes périodes' ;
$xsd_version = ($export_objet=='ecole') ? $xsd_schema_version_ecole : $xsd_schema_version_college ;

$fichier_extension = 'xml';
$fichier_nom = 'import-lsun-'.$xsd_version.'_'.Clean::fichier($_SESSION['WEBMESTRE_UAI'].'_'.$periode_nom.'_'.$groupe_nom).'_'.FileSystem::generer_fin_nom_fichier__date_et_alea().'.'.$fichier_extension; // LSU recommande le modèle "import-lsun-{timestamp}.xml"
FileSystem::ecrire_fichier( CHEMIN_DOSSIER_EXPORT.$fichier_nom , $export_xml );
$fichier_lien = './force_download.php?fichier='.$fichier_nom;

// Retour
$sb = ($nb_bilans>1) ? 's' : '' ;
$se = ($nb_eleves>1) ? 's' : '' ;
Json::add_str('<p><label class="valide">Fichier d’export généré : '.$nb_bilans.' bilan'.$sb.' concernant '.$nb_eleves.' élève'.$se.'.</label></p>'.NL);
Json::add_str('<p><a target="_blank" rel="noopener noreferrer" href="'.$fichier_lien.'"><span class="file file_'.$fichier_extension.'">Récupérer le fichier au format <em>'.$fichier_extension.'</em>.</span></a></p>'.NL);
Json::add_str('<p><label class="alerte">Pour des raisons de sécurité et de confidentialité, ce fichier sera effacé du serveur dans 1h.</label></p>'.NL);
Json::end( TRUE );

?>
