<?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/>.
 *
 */
 
// Extension de classe qui étend DB (pour permettre l’autoload)

// Ces méthodes ne concernent qu’une base STRUCTURE.
// Ces méthodes concernent des actions en lien avec les demandes d’évaluations.

class DB_STRUCTURE_DEMANDE
{

/**
 * Lister les demandes d’évaluation d’un élève donné
 *
 * @param int   $eleve_id   id de l’élève
 * @return array
 */
public static function DB_lister_demandes_eleve_encours($eleve_id)
{
  $DB_SQL = 'SELECT sacoche_demande.*, '
          . 'CONCAT(niveau_ref,".",domaine_code,theme_ordre,item_ordre) AS ref_auto , '
          . 'CONCAT(domaine_ref,theme_ref,item_ref) AS ref_perso , '
          . 'item_id , item_nom , item_lien , sacoche_matiere.matiere_id AS matiere_id  , matiere_nom , '
          . 'prof_id , user_genre , user_nom , user_prenom '
          . 'FROM sacoche_demande '
          . 'LEFT JOIN sacoche_referentiel_item USING (item_id) '
          . 'LEFT JOIN sacoche_referentiel_theme USING (theme_id) '
          . 'LEFT JOIN sacoche_referentiel_domaine USING (domaine_id) '
          . 'LEFT JOIN sacoche_niveau USING (niveau_id) '
          . 'LEFT JOIN sacoche_matiere ON sacoche_referentiel_domaine.matiere_id=sacoche_matiere.matiere_id '
          . 'LEFT JOIN sacoche_user ON sacoche_demande.prof_id=sacoche_user.user_id '
          . 'WHERE eleve_id=:eleve_id AND demande_statut != :not_statut '
          . 'ORDER BY sacoche_demande.matiere_id ASC, niveau_ref ASC, domaine_code ASC, theme_ordre ASC, item_ordre ASC ';
  $DB_VAR = array(
    ':eleve_id'   => $eleve_id,
    ':not_statut' => 'done',
  );
  return DB::queryTab(SACOCHE_STRUCTURE_BD_NAME , $DB_SQL , $DB_VAR);
}

/**
 * lister_demandes_prof
 *
 * @param int    $prof_id           id du prof ; si 0 alors chercher les demandes pour tous les profs
 * @param int    $matiere_id        id de la matière du prof ; si 0 alors chercher parmi toutes les matières du prof
 * @param string $listing_user_id   id des élèves du prof séparés par des virgules
 * @param bool   $is_en_cours       demandes en cours ou demandes archivées
 * @param string $date_debut_sql    date de début au format sql (facultatif : obligatoire uniquement si $is_en_cours=FALSE)
 * @param string $date_fin_sql      date de fin au format sql (facultatif : obligatoire uniquement si $is_en_cours=FALSE)
 * @return array
 */
public static function DB_lister_demandes_prof( $prof_id , $matiere_id , $listing_user_id , $is_en_cours , $date_debut_sql , $date_fin_sql )
{
  $select_references = ($is_en_cours) ? 'CONCAT(niveau_ref,".",domaine_code,theme_ordre,item_ordre) AS ref_auto , CONCAT(domaine_ref,theme_ref,item_ref) AS ref_perso , item_nom, ' : '';
  $select_matiere    = ($matiere_id)  ? '' : 'matiere_nom, ';
  $join_user_matiere = ($matiere_id)  ? '' : 'LEFT JOIN sacoche_jointure_user_matiere ON sacoche_demande.matiere_id=sacoche_jointure_user_matiere.matiere_id ' ;
  $join_matiere      = ($matiere_id)  ? '' : 'LEFT JOIN sacoche_matiere ON sacoche_jointure_user_matiere.matiere_id=sacoche_matiere.matiere_id ' ;
  $where_prof        = ($prof_id)     ? 'AND prof_id IN(0,'.$prof_id.') ' : '' ;
  $where_matiere     = ($matiere_id)  ? 'AND sacoche_demande.matiere_id=:matiere_id ' : ( ($prof_id) ? 'AND sacoche_jointure_user_matiere.user_id=:prof_id ' : '' ) ;
  $where_date        = ($is_en_cours) ? '' : 'AND demande_date>=:date_debut AND demande_date<=:date_fin ' ;
  $order_matiere     = ($matiere_id)  ? '' : 'matiere_nom ASC, ';
  $order_references  = ($is_en_cours) ? 'niveau_ref ASC, domaine_code ASC, theme_ordre ASC, item_ordre ASC ' : 'user_nom ASC, user_prenom ASC ';
  $group_by          = ($prof_id)     ? '' : 'GROUP BY demande_id ';
  $test_statut_done  = ($is_en_cours) ? '!=' : '=' ;
  $DB_SQL = 'SELECT sacoche_demande.*, '.$select_matiere.$select_references
          . 'user_nom, user_prenom, prof_id '
          . 'FROM sacoche_demande '
          . 'LEFT JOIN sacoche_referentiel_item USING (item_id) '
          . 'LEFT JOIN sacoche_referentiel_theme USING (theme_id) '
          . 'LEFT JOIN sacoche_referentiel_domaine USING (domaine_id) '
          . 'LEFT JOIN sacoche_niveau USING (niveau_id) '
          . 'LEFT JOIN sacoche_user ON sacoche_demande.prof_id=sacoche_user.user_id '
          . $join_user_matiere
          . $join_matiere
          . 'WHERE eleve_id IN('.$listing_user_id.') '.$where_prof.$where_matiere.$where_date.' AND demande_statut '.$test_statut_done.' :statut '
          . $group_by
          . 'ORDER BY '.$order_matiere.$order_references;
  $DB_VAR = array(
    ':matiere_id' => $matiere_id,
    ':prof_id'    => $prof_id,
    ':statut'     => 'done',
    ':date_debut' => $date_debut_sql,
    ':date_fin'   => $date_fin_sql,
  );
  return DB::queryTab(SACOCHE_STRUCTURE_BD_NAME , $DB_SQL , $DB_VAR);
}

/**
 * recuperer_demandes_informations
 *
 * @param string $listing_demande_id   id des demandes séparés par des virgules
 * @return array
 */
public static function DB_recuperer_demandes_informations( $listing_demande_id )
{
  $DB_SQL = 'SELECT item_id, item_nom, item_module, matiere_ref, user_id, user_nom, user_prenom, '
          . 'CONCAT(niveau_ref,".",domaine_code,theme_ordre,item_ordre) AS ref_auto , '
          . 'CONCAT(domaine_ref,theme_ref,item_ref) AS ref_perso '
          . 'FROM sacoche_demande '
          . 'LEFT JOIN sacoche_referentiel_item USING (item_id) '
          . 'LEFT JOIN sacoche_referentiel_theme USING (theme_id) '
          . 'LEFT JOIN sacoche_referentiel_domaine USING (domaine_id) '
          . 'LEFT JOIN sacoche_niveau USING (niveau_id) '
          . 'LEFT JOIN sacoche_matiere ON sacoche_demande.matiere_id = sacoche_matiere.matiere_id '
          . 'LEFT JOIN sacoche_user ON sacoche_demande.eleve_id = sacoche_user.user_id '
          . 'WHERE demande_id IN('.$listing_demande_id.') ';
  return DB::queryTab(SACOCHE_STRUCTURE_BD_NAME , $DB_SQL);
}

/**
 * Retourner les résultats pour 1 élève donné, pour 1 item matière donné
 *
 * @param int    $eleve_id
 * @param int    $item_id
 * @param string $date_sql_debut
 * @param bool   $with_saisie_info
 * @return array
 */
public static function DB_lister_result_eleve_item( $eleve_id , $item_id , $date_sql_debut , $with_saisie_info )
{
  $sql_debut   = ($date_sql_debut)   ? 'AND saisie_date>=:date_debut ' : '';
  $saisie_info = ($with_saisie_info) ? 'saisie_info , ' : '';
  $DB_SQL = 'SELECT prof_id, devoir_id , saisie_note AS note , saisie_date AS date , '.$saisie_info
          . 'referentiel_calcul_methode AS calcul_methode , referentiel_calcul_limite AS calcul_limite , referentiel_calcul_retroactif AS calcul_retroactif '
          . 'FROM sacoche_saisie '
          . 'LEFT JOIN sacoche_devoir USING (devoir_id) ' // Pas d’INNER JOIN pour les évals des années antérieures
          . 'LEFT JOIN sacoche_referentiel_item USING (item_id) '
          . 'LEFT JOIN sacoche_referentiel_theme USING (theme_id) '
          . 'LEFT JOIN sacoche_referentiel_domaine USING (domaine_id) '
          . 'LEFT JOIN sacoche_referentiel USING (matiere_id,niveau_id) '
          . 'WHERE eleve_id=:eleve_id AND item_id=:item_id AND saisie_note!="PA" '.$sql_debut
          . 'AND ( devoir_diagnostic = 0 OR devoir_diagnostic IS NULL ) ' // Pas d’évaluations diagnostiques ici
          . 'ORDER BY saisie_date ASC, devoir_id ASC '; // ordre sur devoir_id ajouté à cause des items évalués plusieurs fois le même jour
  $DB_VAR = array(
    ':eleve_id'   => $eleve_id,
    ':item_id'    => $item_id,
    ':date_debut' => $date_sql_debut,
  );
  return DB::queryTab(SACOCHE_STRUCTURE_BD_NAME , $DB_SQL , $DB_VAR);
}

/**
 * recuperer_item_popularite
 * Calculer pour chaque item sa popularité, i.e. le nb de demandes pour les élèves concernés.
 *
 * @param string $listing_demande_id   id des demandes séparés par des virgules
 * @param string $listing_user_id      id des élèves séparés par des virgules
 * @return array   [i]=>array('item_id','popularite')
 */
public static function DB_recuperer_item_popularite( $listing_demande_id , $listing_user_id )
{
  $DB_SQL = 'SELECT item_id , COUNT(item_id) AS popularite '
          . 'FROM sacoche_demande '
          . 'WHERE demande_id IN('.$listing_demande_id.') AND eleve_id IN('.$listing_user_id.') AND demande_statut != "done" '
          . 'GROUP BY item_id ';
  return DB::queryTab(SACOCHE_STRUCTURE_BD_NAME , $DB_SQL);
}

/**
 * Retourner une liste de professeurs attachés à un élève identifié et une matière donnée.
 *
 * @param int $eleve_id
 * @param int $eleve_classe_id
 * @param int $matiere_id
 * @return array
 */
public static function DB_recuperer_professeurs_eleve_matiere( $eleve_id , $eleve_classe_id , $matiere_id )
{
  // Lever si besoin une limitation de GROUP_CONCAT (group_concat_max_len est par défaut limité à une chaîne de 1024 caractères) ; éviter plus de 8096 (http://www.glpi-project.org/forum/viewtopic.php?id=23767).
  DB::query(SACOCHE_STRUCTURE_BD_NAME , 'SET group_concat_max_len = 8096');
  // On connait la classe ($eleve_classe_id), donc on commence par récupérer les groupes éventuels associés à l’élève
  $DB_SQL = 'SELECT GROUP_CONCAT(DISTINCT groupe_id SEPARATOR ",") AS sacoche_liste_groupe_id '
          . 'FROM sacoche_jointure_user_groupe '
          . 'LEFT JOIN sacoche_groupe USING (groupe_id) '
          . 'WHERE user_id=:user_id AND groupe_type=:type2 '
          . 'GROUP BY user_id ';
  $DB_VAR = array(
    ':user_id' => $eleve_id,
    ':type2'   => 'groupe',
  );
  $liste_groupe_id = DB::queryOne(SACOCHE_STRUCTURE_BD_NAME , $DB_SQL , $DB_VAR);
  if( (!$eleve_classe_id) && (!$liste_groupe_id) )
  {
    // élève sans classe et sans groupe
    return FALSE;
  }
  if(!$liste_groupe_id)
  {
    $liste_groupes = $eleve_classe_id;
  }
  elseif(!$eleve_classe_id)
  {
    $liste_groupes = $liste_groupe_id;
  }
  else
  {
    $liste_groupes = $eleve_classe_id.','.$liste_groupe_id;
  }
  // Maintenant qu’on a la matière et la classe / les groupes, on cherche les profs à la fois dans sacoche_jointure_user_matiere et sacoche_jointure_user_groupe .
  // On part de sacoche_jointure_user_matiere qui ne contient que des profs.
  $DB_SQL = 'SELECT DISTINCT(user_id), user_genre, user_nom, user_prenom '
          . 'FROM sacoche_jointure_user_matiere '
          . 'LEFT JOIN sacoche_user USING (user_id) '
          . 'LEFT JOIN sacoche_jointure_user_groupe USING (user_id) '
          . 'WHERE matiere_id=:matiere_id AND groupe_id IN('.$liste_groupes.') AND user_sortie_date>NOW() '
          . 'ORDER BY user_nom ASC, user_prenom ASC';
  $DB_VAR = array(':matiere_id'=>$matiere_id);
  return DB::queryTab(SACOCHE_STRUCTURE_BD_NAME , $DB_SQL , $DB_VAR);
}

/**
 * Récupérer le nombre de demandes d’évaluations autorisées par matière
 *
 * @param int   $matiere_id
 * @return int
 */
public static function DB_recuperer_demandes_autorisees_matiere($matiere_id)
{
  $DB_SQL = 'SELECT matiere_nb_demandes '
          . 'FROM sacoche_matiere '
          . 'WHERE matiere_id=:matiere_id ';
  $DB_VAR = array(':matiere_id'=>$matiere_id);
  return DB::queryOne(SACOCHE_STRUCTURE_BD_NAME , $DB_SQL , $DB_VAR);
}

/**
 * Récupérer les informations relatives à un item donné
 *
 * @param int   $item_id
 * @return array
 */
public static function DB_recuperer_item_infos($item_id)
{
  $DB_SQL = 'SELECT item_nom, item_cart, '
          . 'CONCAT(niveau_ref,".",domaine_code,theme_ordre,item_ordre) AS ref_auto , '
          . 'CONCAT(domaine_ref,theme_ref,item_ref) AS ref_perso , '
          . 'matiere_ref '
          . 'FROM sacoche_referentiel_item '
          . 'LEFT JOIN sacoche_referentiel_theme USING (theme_id) '
          . 'LEFT JOIN sacoche_referentiel_domaine USING (domaine_id) '
          . 'LEFT JOIN sacoche_matiere USING (matiere_id) '
          . 'LEFT JOIN sacoche_niveau USING (niveau_id) '
          . 'WHERE item_id=:item_id ';
  $DB_VAR = array(':item_id'=>$item_id);
  return DB::queryRow(SACOCHE_STRUCTURE_BD_NAME , $DB_SQL , $DB_VAR);
}

/**
 * modifier_demandes_statut
 *
 * @param string $listing_demande_id   id des demandes séparées par des virgules
 * @param string $statut               'request' | 'aggree' | 'ready' | 'done'
 * @param string $message              facultatif
 * @return void
 */
public static function DB_modifier_demandes_statut( $listing_demande_id , $statut , $message )
{
  $message_complementaire = ($message) ? "\r\n\r\n".To::texte_genre_identite($_SESSION['USER_NOM'],FALSE,$_SESSION['USER_PRENOM'],TRUE,$_SESSION['USER_GENRE'])."\r\n".$message : '' ;
  $DB_SQL = 'UPDATE sacoche_demande '
          . 'SET demande_statut=:demande_statut, demande_messages=CONCAT(demande_messages,:message_complementaire) '
          . 'WHERE demande_id IN('.$listing_demande_id.') ';
  $DB_VAR = array(
    ':demande_statut'         => $statut,
    ':message_complementaire' => $message_complementaire
  );
  DB::query(SACOCHE_STRUCTURE_BD_NAME , $DB_SQL , $DB_VAR);
}

/**
 * archiver_demande_precise_eleve_item
 *
 * @param int   $eleve_id
 * @param int   $item_id
 * @return void
 */
public static function DB_archiver_demande_precise_eleve_item($eleve_id,$item_id)
{
  $DB_SQL = 'UPDATE sacoche_demande '
          . 'SET demande_statut=:new_statut '
          . 'WHERE eleve_id=:eleve_id AND item_id=:item_id AND demande_statut != :not_statut ';
  $DB_VAR = array(
    ':new_statut' => 'done',
    ':not_statut' => 'done',
    ':eleve_id'   => $eleve_id,
    ':item_id'    => $item_id,
  );
  DB::query(SACOCHE_STRUCTURE_BD_NAME , $DB_SQL , $DB_VAR);
}

/**
 * modifier_demande_score
 *
 * @param int      $demande_id
 * @param int|null $demande_score
 * @return void
 */
public static function DB_modifier_demande_score( $demande_id , $demande_score )
{
  $DB_SQL = 'UPDATE sacoche_demande '
          . 'SET demande_score=:demande_score '
          . 'WHERE demande_id=:demande_id ';
  $DB_VAR = array(
    ':demande_id'    => $demande_id,
    ':demande_score' => $demande_score
  );
  DB::query(SACOCHE_STRUCTURE_BD_NAME , $DB_SQL , $DB_VAR);
}

/**
 * Compter le nombre de demandes d’évaluations en cours par un élève pour chaque matière
 *
 * @param int   $eleve_id
 * @param int   $matiere_id
 * @return int
 */
public static function DB_compter_demandes_encours_eleve_matiere( $eleve_id , $matiere_id )
{
  $DB_SQL = 'SELECT COUNT(*) AS nombre '
          . 'FROM sacoche_demande '
          . 'WHERE eleve_id=:eleve_id AND matiere_id=:matiere_id AND demande_statut != :not_statut '
          . 'GROUP BY matiere_id';
  $DB_VAR = array(
    ':eleve_id'   => $eleve_id,
    ':matiere_id' => $matiere_id,
    ':not_statut' => 'done',
  );
  return DB::queryOne(SACOCHE_STRUCTURE_BD_NAME , $DB_SQL , $DB_VAR);
}

/**
 * Tester si un élève a déjà formulé une demande d’évaluation pour un item donné
 *
 * @param int    $eleve_id
 * @param int    $matiere_id
 * @param int    $item_id
 * @return int
 */
public static function DB_tester_demande_encours_existante( $eleve_id , $matiere_id , $item_id )
{
  $DB_SQL = 'SELECT demande_id '
          . 'FROM sacoche_demande '
          . 'WHERE eleve_id=:eleve_id AND matiere_id=:matiere_id AND item_id=:item_id AND demande_statut != :not_statut ';
  $DB_VAR = array(
    ':eleve_id'   => $eleve_id,
    ':matiere_id' => $matiere_id,
    ':item_id'    => $item_id,
    ':not_statut' => 'done',
  );
  return (int)DB::queryOne(SACOCHE_STRUCTURE_BD_NAME , $DB_SQL , $DB_VAR);
}

/**
 * Ajouter une demande d’évaluation
 *
 * @param int      $eleve_id
 * @param int      $matiere_id
 * @param int      $item_id
 * @param int      $prof_id
 * @param string   $debut_date
 * @param int|null $demande_score
 * @param string   $demande_statut (forcément 'request')
 * @param string   $message
 * @param string   $demande_doc
 * @return int
 */
public static function DB_ajouter_demande( $eleve_id , $matiere_id , $item_id , $prof_id , $debut_date , $demande_score , $demande_statut , $message , $demande_doc )
{
  $demande_messages = ($message) ? To::texte_genre_identite($_SESSION['USER_NOM'],FALSE,$_SESSION['USER_PRENOM'],TRUE)."\r\n".$message : '' ;
  $DB_SQL = 'INSERT INTO sacoche_demande( eleve_id, matiere_id, item_id, prof_id, periode_debut_date, demande_date, demande_score, demande_statut, demande_messages, demande_doc) '
          . 'VALUES                     (:eleve_id,:matiere_id,:item_id,:prof_id,:periode_debut_date,        NOW(),:demande_score,:demande_statut,:demande_messages,:demande_doc)';
  $DB_VAR = array(
    ':eleve_id'           => $eleve_id,
    ':matiere_id'         => $matiere_id,
    ':item_id'            => $item_id,
    ':prof_id'            => $prof_id,
    ':periode_debut_date' => $debut_date,
    ':demande_score'      => $demande_score,
    ':demande_statut'     => $demande_statut,
    ':demande_messages'   => $demande_messages,
    ':demande_doc'        => $demande_doc,
  );
  DB::query(SACOCHE_STRUCTURE_BD_NAME , $DB_SQL , $DB_VAR);
  return DB::getLastOid(SACOCHE_STRUCTURE_BD_NAME);
}

/**
 * supprimer_demande_precise_id
 *
 * @param int   $demande_id
 * @return int
 */
public static function DB_supprimer_demande_precise_id($demande_id)
{
  $DB_SQL = 'DELETE FROM sacoche_demande '
          . 'WHERE demande_id=:demande_id ';
  $DB_VAR = array(':demande_id'=>$demande_id);
  DB::query(SACOCHE_STRUCTURE_BD_NAME , $DB_SQL , $DB_VAR);
  return DB::rowCount(SACOCHE_STRUCTURE_BD_NAME);
}

/**
 * Supprimer les demandes d’évaluations listées (correspondant à une évaluation)
 *
 * @param string   $listing_demande_id   id des demandes séparées par des virgules
 * @return void
 */
public static function DB_supprimer_demandes_devoir($listing_demande_id)
{
  $DB_SQL = 'DELETE FROM sacoche_demande '
          . 'WHERE demande_id IN('.$listing_demande_id.') ';
  DB::query(SACOCHE_STRUCTURE_BD_NAME , $DB_SQL);
}

}
?>