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

$f_action                     = Clean::post('f_action'                    , 'texte');
$f_objet                      = Clean::post('f_objet'                     , 'texte');
$f_annee                      = Clean::post('f_annee'                     , 'entier');
$f_convention_id              = Clean::post('f_convention_id'             , 'entier');
$f_connexion_mode             = Clean::post('f_connexion_mode'            , 'texte');
$f_connexion_ref              = Clean::post('f_connexion_ref'             , 'texte');
$cas_serveur_host             = Clean::post('cas_serveur_host'            , 'texte');
$cas_serveur_port             = Clean::post('cas_serveur_port'            , 'entier');
$cas_serveur_root             = Clean::post('cas_serveur_root'            , 'texte');
$cas_serveur_url_login        = Clean::post('cas_serveur_url_login'       , 'texte');
$cas_serveur_url_logout       = Clean::post('cas_serveur_url_logout'      , 'texte');
$cas_serveur_url_validate     = Clean::post('cas_serveur_url_validate'    , 'texte');
$cas_serveur_verif_certif_ssl = Clean::post('cas_serveur_verif_certif_ssl', 'entier');
$serveur_host_subdomain       = Clean::post('serveur_host_subdomain'      , 'texte');
$serveur_host_domain          = Clean::post('serveur_host_domain'         , 'texte');
$serveur_port                 = Clean::post('serveur_port'                , 'entier');
$f_chorus_envoi_automatique   = Clean::post('f_chorus_envoi_automatique'  , 'bool');
$f_chorus_code_service        = Clean::post('f_chorus_code_service'       , 'texte');
$f_chorus_numero_engagement   = Clean::post('f_chorus_numero_engagement'  , 'texte');

require(CHEMIN_DOSSIER_INCLUDE.'tableau_sso.php');

// ////////////////////////////////////////////////////////////////////////////////////////////////////
// Mode de connexion (normal, SSO...)
// ////////////////////////////////////////////////////////////////////////////////////////////////////

if($f_action=='enregistrer_mode_identification')
{

  if(!isset($tab_connexion_info[$f_connexion_mode][$f_connexion_ref]))
  {
    Json::end( FALSE , 'Erreur avec les données transmises !<br>'.pathinfo(__FILE__,PATHINFO_FILENAME).':'.__LINE__ );
  }

  if( ($f_connexion_mode=='cas') && ($tab_connexion_info[$f_connexion_mode][$f_connexion_ref]['serveur_host_subdomain']=='*') && !$serveur_host_subdomain )
  {
    Json::end( FALSE , 'Sous-domaine manquant !' );
  }

  if( ($f_connexion_mode=='cas') && ($tab_connexion_info[$f_connexion_mode][$f_connexion_ref]['serveur_port']=='*') && !$serveur_port )
  {
    Json::end( FALSE , 'Port manquant !' );
  }

  list($f_connexion_departement,$f_connexion_nom) = explode('|',$f_connexion_ref);

  if( ($f_connexion_mode=='normal') || ($f_connexion_mode=='shibboleth') )
  {
    DB_STRUCTURE_PARAMETRE::DB_modifier_parametres( array('connexion_mode'=>$f_connexion_mode,'connexion_nom'=>$f_connexion_nom,'connexion_departement'=>$f_connexion_departement) );
    // ne pas oublier de mettre aussi à jour la session (normalement faudrait pas car connecté avec l’ancien mode, mais sinon pb d’initalisation du formulaire)
    Session::_set('CONNEXION_MODE'        , $f_connexion_mode);
    Session::_set('CONNEXION_NOM'         , $f_connexion_nom);
    Session::_set('CONNEXION_DEPARTEMENT' , $f_connexion_departement);
    Json::end( TRUE );
  }

  if($f_connexion_mode=='cas')
  {
    // Soit le host est saisi manuellement, soit il faut le recomposer si sous-domaine saisi (dans la situation majoritaire où il n’y a pas de sous-domaine variable, le résultat est le même)
    $cas_serveur_host = ($f_connexion_nom=='perso') ? $cas_serveur_host : ( ($serveur_host_subdomain!='') ? ( (substr($serveur_host_subdomain,-1)!='.') ? $serveur_host_subdomain.'.'.$serveur_host_domain : $serveur_host_subdomain.$serveur_host_domain ) : $serveur_host_domain ) ;
    // Cas du port
    $cas_serveur_port = ($tab_connexion_info[$f_connexion_mode][$f_connexion_ref]['serveur_port']!='*') ? $cas_serveur_port : $serveur_port ;
    // Vérifier les paramètres CAS en reprenant le code de phpCAS
    if ( empty($cas_serveur_host) || !preg_match('/[\.\d\-abcdefghijklmnopqrstuvwxyz]*/',$cas_serveur_host) )
    {
      Json::end( FALSE , 'Syntaxe du domaine incorrecte !' );
    }
    if ( ($cas_serveur_port == 0) || !is_int($cas_serveur_port) )
    {
      Json::end( FALSE , 'Numéro du port incorrect !' );
    }
    if ( !preg_match('/[\.\d\-_abcdefghijklmnopqrstuvwxyz\/]*/',$cas_serveur_root) )
    {
      Json::end( FALSE , 'Syntaxe du chemin incorrecte !' );
    }
    // Expression régulière pour tester une URL (pas trop compliquée)
    $masque = '#^http(s)?://[\w-]+[\w.-]+\.[a-zA-Z]{2,6}(:[0-9]+)?#';
    if ( $cas_serveur_url_login && !preg_match($masque,$cas_serveur_url_login) )
    {
      Json::end( FALSE , 'Syntaxe URL login incorrecte !' );
    }
    if ( $cas_serveur_url_logout && !preg_match($masque,$cas_serveur_url_logout) )
    {
      Json::end( FALSE , 'Syntaxe URL logout incorrecte !' );
    }
    if ( $cas_serveur_url_validate && !preg_match($masque,$cas_serveur_url_validate) )
    {
      Json::end( FALSE , 'Syntaxe URL validate incorrecte !' );
    }
    if( is_null($cas_serveur_verif_certif_ssl) )
    {
      Json::end( FALSE , 'Paramètre vérif. certificat SSL manquant !' );
    }
    // Deux tests sauf pour les établissements destinés à tester les connecteurs ENT
    if( !IS_HEBERGEMENT_SESAMATH || ($_SESSION['BASE']<CONVENTION_ENT_ID_ETABL_MAXI) )
    {
      // Ne pas dupliquer en paramétrage CAS-perso un paramétrage CAS-ENT existant (utiliser la connexion CAS officielle)
      if($f_connexion_nom=='perso')
      {
        foreach($tab_serveur_cas as $cas_nom => $tab_cas_param)
        {
          if($cas_nom)
          {
            $is_param_defaut_identiques = ( (strpos($cas_serveur_host,$tab_cas_param['serveur_host_domain'])!==FALSE) && ($cas_serveur_root==$tab_cas_param['serveur_root']) ) ? TRUE : FALSE ; // Pas de test sur le sous-domaine ni le port car ils peuvent varier
            $is_param_force_identiques  = ( ($cas_serveur_url_login!='') && ( ($cas_serveur_url_login==$tab_cas_param['serveur_url_login']) || (strpos($cas_serveur_url_login,$tab_cas_param['serveur_host_domain'].':'.$tab_cas_param['serveur_port'].'/'.$tab_cas_param['serveur_root'])!==FALSE) ) ) ? TRUE : FALSE ;
            if( $is_param_defaut_identiques || $is_param_force_identiques )
            {
              Json::end( FALSE , 'Paramètres d’un ENT référencé : sélectionnez-le !' );
            }
          }
        }
      }
      // Sur le serveur Sésamath, ne pas autoriser un paramétrage CAS correspondant à un hébergement académique (ne devrait pas se produire, Sésamath n’hébergeant pas ces établissements).
      else if(IS_HEBERGEMENT_SESAMATH)
      {
        activeSesamathLoader();
        if( isset(EntConventions::$tab_connecteurs_hebergement[$f_connexion_ref]) )
        {
          Json::end( FALSE , 'Paramètres d’un serveur CAS à utiliser sur l’hébergement académique dédié !' );
        }
      }
    }
    // C’est ok
    $tab_parametres = array(
      'connexion_mode'               => $f_connexion_mode,
      'connexion_nom'                => $f_connexion_nom,
      'connexion_departement'        => $f_connexion_departement,
      'cas_serveur_host'             => $cas_serveur_host,
      'cas_serveur_port'             => $cas_serveur_port,
      'cas_serveur_root'             => $cas_serveur_root,
      'cas_serveur_url_login'        => $cas_serveur_url_login,
      'cas_serveur_url_logout'       => $cas_serveur_url_logout,
      'cas_serveur_url_validate'     => $cas_serveur_url_validate,
      'cas_serveur_verif_certif_ssl' => $cas_serveur_verif_certif_ssl,
    );
    DB_STRUCTURE_PARAMETRE::DB_modifier_parametres( $tab_parametres );
    // ne pas oublier de mettre aussi à jour la session (normalement faudrait pas car connecté avec l’ancien mode, mais sinon pb d’initalisation du formulaire)
    Session::_set('CONNEXION_MODE'                 , $f_connexion_mode);
    Session::_set('CONNEXION_NOM'                  , $f_connexion_nom);
    Session::_set('CONNEXION_DEPARTEMENT'          , $f_connexion_departement);
    Session::_set('CAS_SERVEUR','HOST'             , $cas_serveur_host);
    Session::_set('CAS_SERVEUR','PORT'             , $cas_serveur_port);
    Session::_set('CAS_SERVEUR','ROOT'             , $cas_serveur_root);
    Session::_set('CAS_SERVEUR','URL_LOGIN'        , $cas_serveur_url_login);
    Session::_set('CAS_SERVEUR','URL_LOGOUT'       , $cas_serveur_url_logout);
    Session::_set('CAS_SERVEUR','URL_VALIDATE'     , $cas_serveur_url_validate);
    Session::_set('CAS_SERVEUR','VERIF_CERTIF_SSL' , $cas_serveur_verif_certif_ssl);
    Json::end( TRUE );
  }

}

// ////////////////////////////////////////////////////////////////////////////////////////////////////
// Ajouter une convention
// ////////////////////////////////////////////////////////////////////////////////////////////////////

if( IS_HEBERGEMENT_SESAMATH && ($f_action=='ajouter_convention') && $f_connexion_mode && $f_connexion_ref && in_array($f_annee,array(0,1)) )
{
  if( ($f_connexion_mode!='cas') || (!isset($tab_connexion_info['cas'][$f_connexion_ref])) )
  {
    Json::end( FALSE , 'Erreur avec les données transmises !<br>'.pathinfo(__FILE__,PATHINFO_FILENAME).':'.__LINE__ );
  }
  activeSesamathLoader();
  // Extraire les infos
  list($f_connexion_departement,$f_connexion_nom) = explode('|',$f_connexion_ref);
  $date_debut_sql = To::jour_debut_annee_scolaire('sql',$f_annee);
  $date_fin_sql   = To::jour_fin_annee_scolaire(  'sql',$f_annee);
  // Vérifier que la convention n’existe pas déjà
  DBextra::charger_parametres_sql_supplementaires( 0 /*BASE*/ );
  if(DB_WEBMESTRE_ADMINISTRATEUR::DB_tester_convention_precise( $_SESSION['BASE'] , $f_connexion_nom , $date_debut_sql ))
  {
    Json::end( FALSE , 'Convention déjà existante pour ce service sur cette période !' );
  }
  // Insérer l’enregistrement
  $convention_id = DB_WEBMESTRE_ADMINISTRATEUR::DB_ajouter_convention( $_SESSION['BASE'] , $f_connexion_nom , $date_debut_sql , $date_fin_sql );
  // Infos utiles
  $montant = EntConventions::is_moratoire($date_debut_sql) ? 0 : FACTURE_MONTANT ;
  $is_gestion_v2 = EntConventions::is_gestion_v2($convention_id);
  $is_modele_v2  = EntConventions::is_modele_v2( $convention_id);
  $tab_convention = array(
    'connexion_nom'         => $f_connexion_nom,
    'convention_creation'   => TODAY_SQL,
    'convention_date_debut' => $date_debut_sql,
    'convention_date_fin'   => $date_fin_sql,
  );
  // Coordonnées de l’établissement et du contact référent
  $DB_ROW_contact = DB_WEBMESTRE_ADMINISTRATEUR::DB_recuperer_contact_infos($_SESSION['BASE']);
  $convention_PDF = new PDF_convention( NULL /*officiel*/ , 'A4' /*page_size*/ , 'portrait' /*orientation*/ , 15 /*marge_gauche*/ , 15 /*marge_droite*/ , 7.5 /*marge_haut*/ , 10 /*marge_bas*/ , 'oui' /*couleur*/ );
  $convention_PDF->etabl_coords( 'session' , $_SESSION['ETABLISSEMENT'] );
  $convention_PDF->contact_coords( $DB_ROW_contact );
  // Imprimer la convention
  $convention_PDF->generer( 'convention' , $is_gestion_v2 , $is_modele_v2 , $_SESSION['BASE'] , $convention_id , $f_connexion_nom , $montant , $tab_convention , CHEMIN_DOSSIER_OFFICIEL );
  // Envoyer un courriel au contact.
  $courriel_bilan = CourrielConvention::generation( $DB_ROW_contact , $_SESSION['BASE'] , $convention_id , $f_connexion_nom , $_SESSION['ETABLISSEMENT']['DENOMINATION'] , $date_debut_sql , $date_fin_sql , $convention_PDF );
  if(!$courriel_bilan)
  {
    Json::end( FALSE , 'Envoi du courriel infructueux !' );
  }
  // Afficher le retour
  $texte_paiement = ($montant) ? 'Sans objet pour l’instant' : 'Sans objet (moratoire)' ;
  if( ($date_debut_sql>TODAY_SQL) || ($date_fin_sql<TODAY_SQL) )
  {
    $texte_activation = 'Non (hors période)';
    $class_activation = 'br';
  }
  else
  {
    $texte_activation = 'Provisoirement';
    $class_activation = 'bj';
  }
  $tr = '<tr data-id="'.$convention_id.'" class="new">'
      .   '<td>'.html($f_connexion_nom).'</td>'
      .   '<td>du '.To::date_sql_to_french($date_debut_sql).'<br>au '.To::date_sql_to_french($date_fin_sql).'</td>'
      .   '<td>le '.TODAY_FR.'</td>'
      .   '<td class="br"><a href="#convention"><span class="file file_pdf">Convention</span></a><br>Non réceptionnée</td>'
      .   '<td class="bj">'.$texte_paiement.'</td>'
      .   '<td class="'.$class_activation.'">'.$texte_activation.'</td>'
      . '</tr>';
  Json::end( TRUE , $tr );
}

// ////////////////////////////////////////////////////////////////////////////////////////////////////
// Imprimer une convention ou une facture
// ////////////////////////////////////////////////////////////////////////////////////////////////////

if( IS_HEBERGEMENT_SESAMATH && ($f_action=='imprimer_document') && $f_convention_id && in_array($f_objet,array('convention','facture')) )
{
  // Récupération et vérification des infos de la convention
  DBextra::charger_parametres_sql_supplementaires( 0 /*BASE*/ );
  $DB_ROW = DB_WEBMESTRE_ADMINISTRATEUR::DB_recuperer_convention($f_convention_id);
  if(empty($DB_ROW))
  {
    Json::end( FALSE , 'Convention non trouvée !' );
  }
  if( $DB_ROW['sacoche_base'] != $_SESSION['BASE'] )
  {
    Json::end( FALSE , 'Convention d’une autre structure !' );
  }

  // Infos utiles

  activeSesamathLoader();
  if ($f_objet == 'facture') {
    // c’est une facture
    $facture = new SacFacture($_SESSION['BASE'], $f_convention_id, true);
    $pdf = new SacFacturePdf($facture);
    $pdf->save(CHEMIN_DOSSIER_TMP);
  } else {
    // c’est une convention
    $montant = EntConventions::is_moratoire($DB_ROW['convention_date_debut']) ? 0 : FACTURE_MONTANT;
    $is_gestion_v2 = EntConventions::is_gestion_v2($f_convention_id);
    $is_modele_v2 = EntConventions::is_modele_v2($f_convention_id);
    // Coordonnées de l’établissement et du contact référent
    $DB_ROW_contact = DB_WEBMESTRE_ADMINISTRATEUR::DB_recuperer_contact_infos($_SESSION['BASE']);
    $pdf = new PDF_convention(NULL /*officiel*/, 'A4' /*page_size*/, 'portrait' /*orientation*/, 15 /*marge_gauche*/, 15 /*marge_droite*/, 7.5 /*marge_haut*/, 10 /*marge_bas*/, 'oui' /*couleur*/);
    $pdf->etabl_coords('session', $_SESSION['ETABLISSEMENT']);
    $pdf->contact_coords($DB_ROW_contact);
    // Imprimer la convention ou la facture
    $pdf->generer($f_objet, $is_gestion_v2, $is_modele_v2, $_SESSION['BASE'], $f_convention_id, $DB_ROW['connexion_nom'], $montant, $DB_ROW, CHEMIN_DOSSIER_TMP);
  }
  // Retour des informations.
  Json::end( TRUE , URL_DIR_TMP.$pdf->fichier_nom );
}

// ////////////////////////////////////////////////////////////////////////////////////////////////////
// Chorus : enregistrement des choix / paramètres
// ////////////////////////////////////////////////////////////////////////////////////////////////////

$f_chorus_envoi_automatique   = Clean::post('f_chorus_envoi_automatique'  , 'bool');
$f_chorus_code_service        = Clean::post('f_chorus_code_service'       , 'texte');
$f_chorus_numero_engagement   = Clean::post('f_chorus_numero_engagement'  , 'texte');
if( ($f_action=='chorus_enregistrer_configuration') && !is_null($f_chorus_code_service) && !is_null($f_chorus_numero_engagement) )
{
  $tab_parametres = array();
  $tab_parametres['chorus_envoi_automatique'] = $f_chorus_envoi_automatique;
  $tab_parametres['chorus_code_service']      = $f_chorus_code_service;
  $tab_parametres['chorus_numero_engagement'] = $f_chorus_numero_engagement;
  DB_STRUCTURE_PARAMETRE::DB_modifier_parametres($tab_parametres);
  // On modifie aussi la session
  Session::_set('CHORUS_ENVOI_AUTOMATIQUE' , $f_chorus_envoi_automatique );
  Session::_set('CHORUS_CODE_SERVICE'      , $f_chorus_code_service );
  Session::_set('CHORUS_NUMERO_ENGAGEMENT' , $f_chorus_numero_engagement );
  Json::end( TRUE );
}

// ////////////////////////////////////////////////////////////////////////////////////////////////////
// Chorus : envoi de la facture
// ////////////////////////////////////////////////////////////////////////////////////////////////////

if( IS_HEBERGEMENT_SESAMATH && ($f_action=='chorus_envoyer_facture') && $f_convention_id )
{
  if( !$_SESSION['WEBMESTRE_UAI'] )
  {
    Json::end( FALSE , 'Pas d’envoi possible vers Chorus en l’absence de numéro UAI !' );
  }
  // Récupération et vérification des infos de la convention faites à la génération de la facture
  DBextra::charger_parametres_sql_supplementaires( 0 /*BASE*/ );
  activeSesamathLoader();
  try
  {
    $chorus = new Chorus();
    $facture = new SacFacture($_SESSION['BASE'], $f_convention_id, TRUE);
    $pdf = new SacFacturePdf($facture);
    $chorusId = $chorus->sendFacture($pdf, $_SESSION['CHORUS_CODE_SERVICE'], $_SESSION['CHORUS_NUMERO_ENGAGEMENT']);
    Json::end(TRUE, 'La facture a bien été transmise à Chorus (identifiant '.$chorusId.').');
  }
  catch (Exception $e)
  {
    if (!is_a($e, 'Sesamath\Common\UserException')) {
      trigger_error($e, E_USER_WARNING);
    }
    Json::end(FALSE, $e->getMessage());
  }
}

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

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

?>
