<?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 !');}

$action     = Clean::post('f_action'    , 'texte');
$motif      = Clean::post('f_motif'     , 'texte');
$webservice = Clean::post('f_webservice', 'texte');
$step_maj   = Clean::post('step_maj'    , 'entier'); // Numéro de l’étape
$step_clean = Clean::post('step_clean'  , 'entier'); // Numéro de l’étape


$file_memo = CHEMIN_DOSSIER_EXPORT.'webmestre_maintenance_'.session_id().'.txt';

$tab_ext_webservices = array('php','png');

// ////////////////////////////////////////////////////////////////////////////////////////////////////
// Bloquer ou débloquer l’application
// ////////////////////////////////////////////////////////////////////////////////////////////////////

if( ($action=='bloquer') && !is_null($motif) )
{
  Outil::ajouter_log_PHP( 'Maintenance' /*log_objet*/ , 'Application fermée.' /*log_contenu*/ , __FILE__ /*log_fichier*/ , __LINE__ /*log_ligne*/ , FALSE /*only_sesamath*/ );
  LockAcces::bloquer_application( $_SESSION['USER_PROFIL_TYPE'] , 0 , $motif );
  Json::end( TRUE , '<label class="erreur">Application fermée : '.html($motif).'</label>' );
}

if($action=='debloquer')
{
  Outil::ajouter_log_PHP( 'Maintenance' /*log_objet*/ , 'Application accessible.' /*log_contenu*/ , __FILE__ /*log_fichier*/ , __LINE__ /*log_ligne*/ , FALSE /*only_sesamath*/ );
  LockAcces::debloquer_application( $_SESSION['USER_PROFIL_TYPE'] , 0 );
  Json::end( TRUE , '<label class="valide">Application accessible.</label>' );
}

// ////////////////////////////////////////////////////////////////////////////////////////////////////
// Contenu du ul avec la liste des webservices disponibles
// ////////////////////////////////////////////////////////////////////////////////////////////////////

if($action=='listing_webservices')
{
  $tab_files = FileSystem::lister_contenu_dossier(CHEMIN_DOSSIER_WEBSERVICES);
  $li_webservices = '';
  foreach($tab_files as $file)
  {
    $extension = FileSystem::extension($file);
    if(in_array($extension,$tab_ext_webservices))
    {
      $li_webservices .= '<li><code>'.html($file).'</code><q class="supprimer"'.infobulle('Supprimer ce fichier du serveur (aucune confirmation ne sera demandée).').'></q></li>';
    }
  }
  $li_webservices = ($li_webservices) ? $li_webservices : '<li>Aucun fichier trouvé !</li>';
  Json::end( TRUE , $li_webservices );
}

// ////////////////////////////////////////////////////////////////////////////////////////////////////
// Uploader un fichier de webservice
// ////////////////////////////////////////////////////////////////////////////////////////////////////

if($action=='upload_webservice')
{
  // Récupération du fichier
  $result = FileSystem::recuperer_upload( CHEMIN_DOSSIER_WEBSERVICES /*fichier_chemin*/ , NULL /*fichier_nom*/ , $tab_ext_webservices /*tab_extensions_autorisees*/ , NULL /*tab_extensions_interdites*/ , 500 /*taille_maxi*/ , NULL /*filename_in_zip*/ , FALSE /*lower*/ );
  if($result!==TRUE)
  {
    Json::end( FALSE , $result );
  }
  // pas de vérification du fichier, à partir du moment où on autorise l’upload d’un fichier php tout est permis de toutes façons
  // le compte webmestre permet de supprimer toutes les bases des inscriptions, il est donc par nature déjà extrêmement sensible
  Json::end( TRUE );
}

// ////////////////////////////////////////////////////////////////////////////////////////////////////
// Supprimer un fichier de webservice
// ////////////////////////////////////////////////////////////////////////////////////////////////////

if( ($action=='delete_webservice') && $webservice )
{
  FileSystem::supprimer_fichier( CHEMIN_DOSSIER_WEBSERVICES.$webservice , TRUE /*verif_exist*/ );
  Json::end( TRUE );
}

// ////////////////////////////////////////////////////////////////////////////////////////////////////
// Mise à jour automatique des fichiers
// ////////////////////////////////////////////////////////////////////////////////////////////////////

$fichier_import  = CHEMIN_DOSSIER_IMPORT.'telechargement.zip';
$dossier_dezip   = CHEMIN_DOSSIER_IMPORT.'SACoche'.DS;
$dossier_install = CHEMIN_DOSSIER_SACOCHE;

//
// 1. Récupération de l’archive <em>ZIP</em>...
//
if($action=='maj_etape1')
{
  if(IS_HEBERGEMENT_SESAMATH)
  {
    Json::end( FALSE , 'La mise à jour de SACoche sur le serveur Sésamath doit s’effectuer en déployant le dépôt (SVN, GIT, &hellip;) !' );
  }
  if(is_file(CHEMIN_FICHIER_WS_LCS))
  {
    Json::end( FALSE , 'La mise à jour du module LCS-SACoche doit s’effectuer via le LCS !' );
  }
  $contenu_zip = cURL::get_contents( SERVEUR_TELECHARGEMENT , array() /*tab_post*/ , 90 /*timeout*/ );
  if(substr($contenu_zip,0,6)=='Erreur')
  {
    Json::end( FALSE , $contenu_zip );
  }
  FileSystem::ecrire_fichier($fichier_import,$contenu_zip);
  Json::end( TRUE , 'Décompression de l’archive&hellip;' );
}

//
// 2. Décompression de l’archive...
//
if($action=='maj_etape2')
{
  if(is_dir($dossier_dezip))
  {
    FileSystem::supprimer_dossier($dossier_dezip);
  }
  // Dezipper dans le dossier temporaire
  $code_erreur = FileSystem::unzip( $fichier_import , CHEMIN_DOSSIER_IMPORT );
  if($code_erreur)
  {
    Json::end( FALSE , 'Erreur d’extraction du contenu ('.FileSystem::$tab_zip_error[$code_erreur].') !' );
  }
  Json::end( TRUE , 'Analyse des fichiers et recensement des dossiers&hellip;' );
}

//
// 3. Analyse des fichiers et recensement des dossiers...
//
if($action=='maj_etape3')
{
  FileSystem::analyser_dossier( $dossier_install , strlen($dossier_install) , 'avant' , FALSE /*with_first_dir*/ );
  FileSystem::analyser_dossier( $dossier_dezip   , strlen($dossier_dezip)   , 'apres' , FALSE /*with_first_dir*/ );
  // Il est arrivé, une unique fois sur un seul serveur, que malgré un dezippage correct et complet, aucun fichier ne soit recensé.
  // Cette situation assez incompréhensible a entraîné la suppression de tout le contenu présent !!!
  // D’où ce test en plus...
  if(!strpos( serialize(FileSystem::$tab_analyse) , '"apres"' ))
  {
    Json::end( FALSE , 'Arrêt de la procédure car aucun contenu recensé par l’analyse des données extraites !' );
  }
  // Enregistrer ces informations
  FileSystem::enregistrer_fichier_infos_serializees( $file_memo , FileSystem::$tab_analyse );
  // Retour
  Json::end( TRUE , 'Analyse et répercussion des modifications&hellip;' );
}

//
// 4. Analyse et répercussion des modifications... (tout en bloquant l’appli)
//
if($action=='maj_etape4')
{
  $thead = '<tr><td colspan="2">Mise à jour automatique - '.date('d/m/Y H:i:s').'</td></tr>';
  $tbody = '';
  // Bloquer l’application
  Outil::ajouter_log_PHP( 'Mise à jour des fichiers' /*log_objet*/ , 'Application fermée.' /*log_contenu*/ , __FILE__ /*log_fichier*/ , __LINE__ /*log_ligne*/ , FALSE /*only_sesamath*/ );
  LockAcces::bloquer_application( 'automate' , 0 , 'Mise à jour des fichiers en cours.' );
  // Récupérer les informations
  $tab_memo = FileSystem::recuperer_fichier_infos_serializees( $file_memo );
  // Dossiers : ordre croissant pour commencer par ceux les moins imbriqués : obligatoire pour l’ajout, et pour la suppression on teste si pas déjà supprimé.
  ksort($tab_memo['dossier']);
  foreach($tab_memo['dossier'] as $dossier => $tab)
  {
    if( (isset($tab['avant'])) && (isset($tab['apres'])) )
    {
      // Dossier inchangé (cas le plus fréquent donc testé en premier).
    }
    elseif(!isset($tab['avant']))
    {
      // Dossier à ajouter
      $tbody .= '<tr><td class="v">Dossier ajouté</td><td>'.$dossier.'</td></tr>';
      if( !FileSystem::creer_dossier($dossier_install.$dossier) )
      {
        Outil::ajouter_log_PHP( 'Mise à jour des fichiers' /*log_objet*/ , 'Application accessible.' /*log_contenu*/ , __FILE__ /*log_fichier*/ , __LINE__ /*log_ligne*/ , FALSE /*only_sesamath*/ );
        LockAcces::debloquer_application( 'automate' , 0 );
        Json::end( FALSE , 'Dossier "'.$dossier.'" non créé ou inaccessible en écriture !' );
      }
    }
    elseif(!isset($tab['apres'])) // (forcément)
    {
      // Dossier à supprimer
      $tbody .= '<tr><td class="r">Dossier supprimé</td><td>'.$dossier.'</td></tr>';
      if(is_dir($dossier_install.$dossier))
      {
        FileSystem::supprimer_dossier($dossier_install.$dossier);
      }
    }
  }
  // Fichiers : ordre décroissant pour avoir VERSION.txt en dernier (majuscules avant dans la table ASCII).
  krsort($tab_memo['fichier']);
  foreach($tab_memo['fichier'] as $fichier => $tab)
  {
    if( (isset($tab['avant'])) && (isset($tab['apres'])) )
    {
      if( ($tab['avant']!=$tab['apres']) && (substr($fichier,-9)!='.htaccess') )
      {
        // Fichier changé => maj (si le .htaccess a été changé, c’est sans doute volontaire, ne pas y toucher)
        if( !copy( $dossier_dezip.$fichier , $dossier_install.$fichier ) )
        {
          Outil::ajouter_log_PHP( 'Mise à jour des fichiers' /*log_objet*/ , 'Application accessible.' /*log_contenu*/ , __FILE__ /*log_fichier*/ , __LINE__ /*log_ligne*/ , FALSE /*only_sesamath*/ );
          LockAcces::debloquer_application( 'automate' , 0 );
          Json::end( FALSE , 'Erreur lors de l’écriture du fichier "'.$fichier.'" !' );
        }
        $tbody .= '<tr><td class="b">Fichier modifié</td><td>'.$fichier.'</td></tr>';
      }
    }
    elseif( (!isset($tab['avant'])) && (substr($fichier,-9)!='.htaccess') )
    {
      // Fichier à ajouter (si le .htaccess n’y est pas, c’est sans doute volontaire, ne pas l’y remettre)
      if( !copy( $dossier_dezip.$fichier , $dossier_install.$fichier ) )
      {
        Outil::ajouter_log_PHP( 'Mise à jour des fichiers' /*log_objet*/ , 'Application accessible.' /*log_contenu*/ , __FILE__ /*log_fichier*/ , __LINE__ /*log_ligne*/ , FALSE /*only_sesamath*/ );
        LockAcces::debloquer_application( 'automate' , 0 );
        Json::end( FALSE , 'Erreur lors de l’écriture du fichier "'.$fichier.'" !' );
      }
      $tbody .= '<tr><td class="v">Fichier ajouté</td><td>'.$fichier.'</td></tr>';
    }
    elseif(!isset($tab['apres'])) // (forcément)
    {
      // Fichier à supprimer
      FileSystem::supprimer_fichier($dossier_install.$fichier , TRUE /*verif_exist*/ );
      $tbody .= '<tr><td class="r">Fichier supprimé</td><td>'.$fichier.'</td></tr>';
    }
  }
  // Débloquer l’application
  Outil::ajouter_log_PHP( 'Mise à jour des fichiers' /*log_objet*/ , 'Application accessible.' /*log_contenu*/ , __FILE__ /*log_fichier*/ , __LINE__ /*log_ligne*/ , FALSE /*only_sesamath*/ );
  LockAcces::debloquer_application( 'automate' , 0 );
  // Enregistrement du rapport
  Session::_set('tmp','rapport_filename' , 'rapport_maj_'.FileSystem::generer_fin_nom_fichier__date_et_alea().'.html' );
  FileSystem::fabriquer_fichier_rapport( $_SESSION['tmp']['rapport_filename'] , $thead , $tbody );
  // Retour
  Json::end( TRUE , 'Rapport des modifications apportées et nettoyage&hellip;' );
}

//
// 5. Nettoyage...
//
if($action=='maj_etape5')
{
  $fichier_chemin = URL_DIR_EXPORT.$_SESSION['tmp']['rapport_filename'];
  // Supprimer toutes les données provisoires
  FileSystem::supprimer_dossier($dossier_dezip);
  FileSystem::supprimer_fichier( $file_memo );
  Session::_unset('tmp');
  // Retour
  Json::end( TRUE , array( 'version' => VERSION_PROG , 'fichier' => $fichier_chemin ) );
}

// ////////////////////////////////////////////////////////////////////////////////////////////////////
// Vérification des fichiers de l’application en place
// ////////////////////////////////////////////////////////////////////////////////////////////////////

$fichier_import  = CHEMIN_DOSSIER_IMPORT.'verification.zip';
$dossier_dezip   = CHEMIN_DOSSIER_IMPORT.'SACoche'.DS;
$dossier_install = '.'.DS;

//
// 1. Récupération de l’archive <em>ZIP</em>...
//
if($action=='verif_file_appli_etape1')
{
  $tab_post = array();
  $tab_post['verification'] = 1;
  $tab_post['version'] = VERSION_PROG;
  $contenu_zip = cURL::get_contents( SERVEUR_TELECHARGEMENT , $tab_post , 60 /*timeout*/ );
  if(substr($contenu_zip,0,6)=='Erreur')
  {
    Json::end( FALSE , $contenu_zip );
  }
  FileSystem::ecrire_fichier($fichier_import,$contenu_zip);
  Json::end( TRUE , 'Décompression de l’archive&hellip;' );
}

//
// 2. Décompression de l’archive...
//
if($action=='verif_file_appli_etape2')
{
  if(is_dir($dossier_dezip))
  {
    FileSystem::supprimer_dossier($dossier_dezip);
  }
  // Dezipper dans le dossier temporaire
  $code_erreur = FileSystem::unzip( $fichier_import , CHEMIN_DOSSIER_IMPORT );
  if($code_erreur)
  {
    Json::end( FALSE , 'Erreur d’extraction du contenu ('.FileSystem::$tab_zip_error[$code_erreur].') !' );
  }
  Json::end( TRUE , 'Analyse des fichiers et recensement des dossiers&hellip;' );
}

//
// 3. Analyse des fichiers et recensement des dossiers...
//
if($action=='verif_file_appli_etape3')
{
  FileSystem::analyser_dossier( $dossier_install , strlen($dossier_install) , 'avant' , FALSE /*with_first_dir*/ );
  FileSystem::analyser_dossier( $dossier_dezip   , strlen($dossier_dezip)   , 'apres' , FALSE /*with_first_dir*/ , FALSE );
  // Enregistrer ces informations
  FileSystem::enregistrer_fichier_infos_serializees( $file_memo , FileSystem::$tab_analyse );
  // Retour
  Json::end( TRUE , 'Comparaison des données&hellip;' );
}

//
// 4. Comparaison des données...
//
if($action=='verif_file_appli_etape4')
{
  $thead = '<tr><td colspan="2">Vérification des fichiers de l’application en place - '.date('d/m/Y H:i:s').'</td></tr>';
  $tbody_ok = '';
  $tbody_pb = '';
  // Récupérer les informations
  $tab_memo = FileSystem::recuperer_fichier_infos_serializees( $file_memo );
  // Dossiers : ordre croissant pour commencer par ceux les moins imbriqués : obligatoire pour l’ajout, et pour la suppression on teste si pas déjà supprimé.
  ksort($tab_memo['dossier']);
  foreach($tab_memo['dossier'] as $dossier => $tab)
  {
    if( (isset($tab['avant'])) && (isset($tab['apres'])) )
    {
      // Dossier inchangé (cas le plus fréquent donc testé en premier).
      $tbody_ok .= '<tr class="v"><td>Dossier présent</td><td>'.$dossier.'</td></tr>';
    }
    elseif(!isset($tab['avant']))
    {
      // Dossier manquant
      $tbody_pb .= '<tr class="r"><td>Dossier manquant</td><td>'.$dossier.'</td></tr>';
    }
    elseif(!isset($tab['apres'])) // (forcément)
    {
      // Dossier en trop
      $tbody_pb .= '<tr class="r"><td>Dossier en trop</td><td>'.$dossier.'</td></tr>';
    }
  }
  // Fichiers : ordre décroissant pour avoir VERSION.txt en dernier (majuscules avant dans la table ASCII).
  krsort($tab_memo['fichier']);
  foreach($tab_memo['fichier'] as $fichier => $tab)
  {
    if( (isset($tab['avant'])) && (isset($tab['apres'])) )
    {
      if( ($tab['avant']==$tab['apres']) || (substr($fichier,-9)=='.htaccess') )
      {
        // Fichier identique (si le .htaccess a été changé, c’est sans doute volontaire, ne pas y toucher)
        $tbody_ok .= '<tr class="v"><td>Fichier identique</td><td>'.$fichier.'</td></tr>';
      }
      else
      {
        // Fichier différent
        $tbody_pb .= '<tr class="r"><td>Fichier différent</td><td>'.$fichier.'</td></tr>';
      }
    }
    elseif( (!isset($tab['avant'])) && (substr($fichier,-9)!='.htaccess') )
    {
      // Fichier manquant
      $tbody_pb .= '<tr class="r"><td>Fichier manquant</td><td>'.$fichier.'</td></tr>';
    }
    elseif(!isset($tab['apres'])) // (forcément)
    {
      $tbody_pb .= '<tr class="r"><td>Fichier en trop</td><td>'.$fichier.'</td></tr>';
    }
  }
  // Enregistrement du rapport
  Session::_set('tmp','rapport_filename' , 'rapport_verif_file_appli_'.FileSystem::generer_fin_nom_fichier__date_et_alea().'.html' );
  FileSystem::fabriquer_fichier_rapport( $_SESSION['tmp']['rapport_filename'] , $thead , $tbody_pb.$tbody_ok );
  // Retour
  Json::end( TRUE , 'Rapport des différences trouvées et nettoyage&hellip;' );
}

//
// 5. Nettoyage...
//
if($action=='verif_file_appli_etape5')
{
  $fichier_chemin = URL_DIR_EXPORT.$_SESSION['tmp']['rapport_filename'];
  // Supprimer toutes les données provisoires
  FileSystem::supprimer_dossier($dossier_dezip);
  FileSystem::supprimer_fichier( $file_memo );
  Session::_unset('tmp');
  // Retour
  Json::end( TRUE , $fichier_chemin );
}

// ////////////////////////////////////////////////////////////////////////////////////////////////////
// Étape de mise à jour forcée des bases des établissements
// ////////////////////////////////////////////////////////////////////////////////////////////////////

if( ($action=='maj_bases_etabl') && $step_maj )
{
  // 1. Liste des bases
  if($step_maj==1)
  {
    // Récupérer les ids des structures
    $tab_memo = array(
      'base_id' => array_keys( DB_WEBMESTRE_WEBMESTRE::DB_lister_structures_id() ),
      'rapport' => array(),
    );
    // Enregistrer ces informations
    FileSystem::enregistrer_fichier_infos_serializees( $file_memo , $tab_memo );
    // Retour
    Json::end( TRUE , 'continuer' );
  }
  else
  {
    // Récupérer les informations
    $tab_memo = FileSystem::recuperer_fichier_infos_serializees( $file_memo );
    // n. Étape suivante
    if(!empty($tab_memo['base_id']))
    {
      $base_id = current($tab_memo['base_id']);
      DBextra::charger_parametres_sql_supplementaires($base_id);
      $version_base = DB_STRUCTURE_MAJ_BASE::DB_version_base();
      if(empty($tab_memo['rapport'][$base_id]))
      {
        $tab_memo['rapport'][$base_id] = $version_base;
      }
      // base déjà à jour
      if($tab_memo['rapport'][$base_id] == VERSION_BASE_STRUCTURE)
      {
        array_shift($tab_memo['base_id']);
        // Enregistrer ces informations
        FileSystem::enregistrer_fichier_infos_serializees( $file_memo , $tab_memo );
        // Retour
        Json::end( TRUE , 'continuer' );
      }
      // on lance la maj "classique"
      if($version_base != VERSION_BASE_STRUCTURE)
      {
        $maj_classique = TRUE;
        // Bloquer l’application
        LockAcces::bloquer_application( 'automate' , $base_id , 'Mise à jour de la base en cours.' );
        // Lancer une mise à jour de la base
        Session::_set('BASE',$base_id); // Valeur sinon inconnue quand MAJ lancée par le webmestre
        DB_STRUCTURE_MAJ_BASE::DB_maj_base($version_base);
        Session::_set('BASE',0); // On remet la valeur attendue pour une connexion du webmestre
      }
      else
      {
        $maj_classique = FALSE;
      }
      // test si cela nécessite une mise à jour complémentaire
      Session::_set('VERSION_BASE_MAJ_COMPLEMENTAIRE' , DB_STRUCTURE_MAJ_BASE::DB_version_base_maj_complementaire() );
      if(!$_SESSION['VERSION_BASE_MAJ_COMPLEMENTAIRE'])
      {
        // Débloquer l’application
        LockAcces::debloquer_application( 'automate' , $base_id );
        array_shift($tab_memo['base_id']);
        // Enregistrer ces informations
        FileSystem::enregistrer_fichier_infos_serializees( $file_memo , $tab_memo );
        // Retour
        Json::end( TRUE , 'continuer' );
      }
      elseif($maj_classique)
      {
        // on fera la maj complémentaire au prochain coup
        Json::end( TRUE , 'continuer' );
      }
      else
      {
        // on lance une étape de la maj complémentaire
        DB_STRUCTURE_MAJ_BASE::DB_maj_base_complement();
        if(!$_SESSION['VERSION_BASE_MAJ_COMPLEMENTAIRE'])
        {
          LockAcces::debloquer_application( 'automate' , $base_id );
          array_shift($tab_memo['base_id']);
        }
        // Enregistrer ces informations
        FileSystem::enregistrer_fichier_infos_serializees( $file_memo , $tab_memo );
        // Retour
        Json::end( TRUE , 'continuer' );
      }
    }
    // n. Dernière étape
    else
    {
      // Rapport
      $thead = '<tr><td>Mise à jour forcée des bases - '.date('d/m/Y H:i:s').'</td></tr>';
      $tbody = '';
      foreach($tab_memo['rapport'] as $base_id => $version_base)
      {
        $tbody .= ($version_base==VERSION_BASE_STRUCTURE) ? '<tr><td class="b">Base n°'.$base_id.' déjà à jour.</td></tr>' : '<tr><td class="v">Base n°'.$base_id.' mise à jour depuis la version '.$version_base.'.</td></tr>' ;
      }
      // Enregistrement du rapport
      $fichier_rapport = 'rapport_maj_bases_etabl_'.FileSystem::generer_fin_nom_fichier__date_et_alea().'.html';
      FileSystem::fabriquer_fichier_rapport( $fichier_rapport , $thead , $tbody );
      $fichier_chemin = URL_DIR_EXPORT.$fichier_rapport;
      // Supprimer les informations provisoires
      FileSystem::supprimer_fichier( $file_memo );
      // Retour
      Json::end( TRUE , $fichier_chemin );
    }
  }
}

// ////////////////////////////////////////////////////////////////////////////////////////////////////
// Étape de nettoyage des fichiers temporaires des établissements
// ////////////////////////////////////////////////////////////////////////////////////////////////////

if( ($action=='clean_file_temp') && $step_clean )
{
  // 1. Liste des bases
  if($step_clean==1)
  {
    // Récupérer les ids des structures
    $tab_memo = array(
      'base_id' => array_keys( DB_WEBMESTRE_WEBMESTRE::DB_lister_structures_id() ),
      'rapport' => array(),
    );
    // Enregistrer ces informations
    FileSystem::enregistrer_fichier_infos_serializees( $file_memo , $tab_memo );
    // Retour
    Json::end( TRUE , 'continuer' );
  }
  else
  {
    // Récupérer les informations
    $tab_memo = FileSystem::recuperer_fichier_infos_serializees( $file_memo );
    // n. Étape suivante
    if(!empty($tab_memo['base_id']))
    {
      $base_id = current($tab_memo['base_id']);
      $tab_memo['rapport'][$base_id] = FileSystem::nettoyer_fichiers_temporaires_etablissement($base_id);
      array_shift($tab_memo['base_id']);
      // Enregistrer ces informations
      FileSystem::enregistrer_fichier_infos_serializees( $file_memo , $tab_memo );
      // Retour
      Json::end( TRUE , 'continuer' );
    }
    // n. Dernière étape
    else
    {
      // Rapport
      $thead = '<tr><td>Nettoyage forcé des fichiers temporaires - '.date('d/m/Y H:i:s').'</td></tr>';
      $tbody = '';
      $total = 0;
      foreach($tab_memo['rapport'] as $base_id => $nb_suppression)
      {
        $total += $nb_suppression;
        $s = ($nb_suppression>1) ? 's' : '' ;
        $tbody .= ($nb_suppression) ? '<tr><td class="v">Base n°'.$base_id.' &rarr; '.$nb_suppression.' fichier'.$s.' / dossier'.$s.' supprimé'.$s.'.</td></tr>' : '<tr><td class="b">Base n°'.$base_id.' &rarr; rien à signaler.</td></tr>' ;
      }
      $s = ($total>1) ? 's' : '' ;
      $tfoot = '<tr><td>'.$total.' fichier'.$s.' / dossier'.$s.' supprimé'.$s.'</td></tr>';
      // Enregistrement du rapport
      $fichier_rapport = 'rapport_clean_file_temp_'.FileSystem::generer_fin_nom_fichier__date_et_alea().'.html';
      FileSystem::fabriquer_fichier_rapport( $fichier_rapport , $thead , $tbody , $tfoot );
      $fichier_chemin = URL_DIR_EXPORT.$fichier_rapport;
      // Supprimer les informations provisoires
      FileSystem::supprimer_fichier( $file_memo );
        // Retour
      Json::end( TRUE , $fichier_chemin );
    }
  }
}

// ////////////////////////////////////////////////////////////////////////////////////////////////////
// Il se peut que rien n’ait été récupéré à cause de l’upload d’un fichier trop lourd
// ////////////////////////////////////////////////////////////////////////////////////////////////////

if(empty($_POST))
{
  Json::end( FALSE , 'Aucune donnée reçue ! Fichier trop lourd ? '.InfoServeur::minimum_limitations_upload() );
}

// ////////////////////////////////////////////////////////////////////////////////////////////////////
// On ne devrait pas en arriver là...
// ////////////////////////////////////////////////////////////////////////////////////////////////////

Json::end( FALSE , 'Erreur avec les données transmises !<br>'.pathinfo(__FILE__,PATHINFO_FILENAME).':'.__LINE__ );

?>
