Files correlati :check_answers.cgi Ricompilazione Demo : [ ] Commento :reso speciale il modulo 1; non serve eseguire alcun test ma solo submittare con un tasto (in realtá é un test in bianco mascherato) git-svn-id: svn://10.65.10.50/trunk@9462 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			329 lines
		
	
	
		
			9.6 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			329 lines
		
	
	
		
			9.6 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
// check_answers.cgi: applicazione per controllare i punteggi e memorizzare le risposte 
 | 
						||
// dei test.
 | 
						||
 | 
						||
#include <libpq++.h>
 | 
						||
#include "applicat.h"
 | 
						||
#include "questionnaire.h"
 | 
						||
 | 
						||
class Check_answers_Application : public Application
 | 
						||
{
 | 
						||
private:
 | 
						||
 | 
						||
  String     _dbname;
 | 
						||
  String     _utente;   // Utente corrente
 | 
						||
  String     _modulo;   // Numero del modulo del quale controllare le risposte
 | 
						||
  String     _testnum;  // Numero del test del quale controllare le risposte
 | 
						||
  PgEnv      _environment;
 | 
						||
  bool       _blank_test;
 | 
						||
  String     _user_answers;
 | 
						||
  Questionnaire _questionario;
 | 
						||
  PgTransaction *_db;
 | 
						||
  
 | 
						||
protected:
 | 
						||
  virtual bool create();
 | 
						||
  virtual bool destroy();
 | 
						||
  virtual void main_func();
 | 
						||
  void check_answers();
 | 
						||
  void print_access_error();
 | 
						||
  bool load_corrector();
 | 
						||
public:
 | 
						||
  Check_answers_Application() 
 | 
						||
  {
 | 
						||
  	_db = NULL;
 | 
						||
  }
 | 
						||
  virtual ~Check_answers_Application() {};
 | 
						||
};
 | 
						||
 | 
						||
 | 
						||
bool Check_answers_Application::create()
 | 
						||
{
 | 
						||
  String separator, ws;
 | 
						||
  String qs[3];
 | 
						||
  char answers[MAXQUESTIONS][MAXANSWERS];
 | 
						||
 | 
						||
  for (int i=0; i<MAXQUESTIONS; i++)
 | 
						||
    for (int j=0; j<MAXANSWERS; j++)
 | 
						||
      answers[i][j] = 'F';
 | 
						||
 | 
						||
  _user_answers = "";
 | 
						||
  separator = "_";
 | 
						||
  _dbname = POSTGRES_DB;
 | 
						||
  _environment.Port(POSTGRES_PORT);
 | 
						||
  _environment.Host(POSTGRES_HOST);
 | 
						||
  print_header("Controllo punteggi");
 | 
						||
  _utente = getenv("REMOTE_USER");
 | 
						||
  _blank_test = FALSE;
 | 
						||
  char *t1, *t2;
 | 
						||
  char *ccc = getenv("CONTENT_LENGTH");
 | 
						||
  int cl = ccc != NULL ? atoi(ccc) : 0;
 | 
						||
 | 
						||
#ifdef DBG
 | 
						||
  cout << "<BR>Lunghezza del buffer: " << cl << "<BR>" << endl;
 | 
						||
#endif
 | 
						||
 | 
						||
  if (cl < 8192) { // Evita di ricevere troppa roba sullo stdin (8kb sono abbastanza??)
 | 
						||
    for (int x = 0; cl && (!feof(stdin)); x++) {
 | 
						||
      t1 = fmakeword(stdin, '&', &cl);
 | 
						||
      t2 = makeword(t1, '=');
 | 
						||
      unescape_url(t1);
 | 
						||
      unescape_url(t2);
 | 
						||
      if (!strcmp(t2,"MODULO"))
 | 
						||
	_modulo = t1;
 | 
						||
      if (!strcmp(t2,"TESTNUM"))
 | 
						||
	_testnum = t1;
 | 
						||
      if (!strcmp(t2,"BLANK_TEST"))
 | 
						||
	_blank_test = !strcmp(t1,"ON");
 | 
						||
      // Carica le risposte fornite
 | 
						||
      if (t2[0] == 'Q') { // Si tratta di una risposta del test; formato Q_<numero_domanda>_<numero_risposta>
 | 
						||
	// Estrae il numero relativo alla domanda ed il numero della risposta
 | 
						||
        ws = t2;
 | 
						||
	const int e = split(ws, qs, 3, separator);
 | 
						||
	if (e == 3) {
 | 
						||
	  const int qnum = atoi(qs[1]) - 1; // riferimento alla domanda
 | 
						||
	  const int anum = atoi(qs[2]) - 1; // riferimento alla risposta
 | 
						||
	  if (qnum < MAXQUESTIONS && anum < MAXANSWERS)
 | 
						||
	    if (!strcmp(t1,"ON"))
 | 
						||
	      answers[qnum][anum] = 'V';
 | 
						||
	}
 | 
						||
      }
 | 
						||
    }
 | 
						||
 | 
						||
    
 | 
						||
    // Compone _user_answers
 | 
						||
    for (int i=0; i<MAXQUESTIONS; i++) {
 | 
						||
      _user_answers += "Q_";
 | 
						||
      _user_answers += itoa(i+1);
 | 
						||
      _user_answers += "=";
 | 
						||
      for (int j=0; j<MAXANSWERS; j++)
 | 
						||
	_user_answers += answers[i][j];
 | 
						||
      _user_answers += ";";
 | 
						||
    }
 | 
						||
 | 
						||
 | 
						||
    // Debug stuff, useful in many wayz
 | 
						||
#ifdef DBG
 | 
						||
    cout << "<H2>Risposte fornite</H2><BR><BR>" << endl;
 | 
						||
    for (int j = 0; j < MAXQUESTIONS; j++) {
 | 
						||
      cout << "Domanda " << j+1 << ":<BR>";
 | 
						||
      for (int k = 0; k < MAXANSWERS; k++)
 | 
						||
	if (answers[j][k] == 'V')
 | 
						||
	  cout << "VERO ";
 | 
						||
	else
 | 
						||
	  cout << "FALSO ";
 | 
						||
      cout << "<BR>" << endl;
 | 
						||
    }
 | 
						||
    return FALSE;
 | 
						||
#endif
 | 
						||
  }
 | 
						||
  else {
 | 
						||
    cout << "<H2>Troppi dati inviati</H2><BR><BR>" << endl;
 | 
						||
    cout << "<P>L'applicazione ha ricevuto troppi dati sul buffer d'ingresso.</P><BR>" << endl;
 | 
						||
    return FALSE;
 | 
						||
  } 
 | 
						||
  return TRUE;
 | 
						||
}
 | 
						||
 | 
						||
bool Check_answers_Application::destroy()
 | 
						||
{
 | 
						||
  print_footer();
 | 
						||
  return TRUE;
 | 
						||
}
 | 
						||
 | 
						||
bool Check_answers_Application::load_corrector()
 | 
						||
{
 | 
						||
  bool loaded = FALSE;
 | 
						||
  String command, correct_answers, separator;
 | 
						||
 | 
						||
  separator = ";";
 | 
						||
  command = "SELECT * FROM CORRETTORI WHERE modulo=";
 | 
						||
  command += _modulo;
 | 
						||
  command += " AND testnum='";
 | 
						||
  command += _testnum;
 | 
						||
  command += "'";
 | 
						||
  _db->ExecCommandOk(command);
 | 
						||
  const int tuples = _db->Tuples();
 | 
						||
 | 
						||
 | 
						||
  if (tuples > 0) {
 | 
						||
    correct_answers = _db->GetValue(0, "risposte");
 | 
						||
    loaded = _questionario.load(correct_answers, _user_answers);
 | 
						||
  }
 | 
						||
 
 | 
						||
  return loaded;
 | 
						||
}
 | 
						||
 | 
						||
void Check_answers_Application::check_answers()
 | 
						||
{
 | 
						||
  if (!load_corrector()) {
 | 
						||
    cout << "<H2>Correttore inesistente</H2><BR><BR>" << endl;
 | 
						||
    cout << "<P>Impossibile caricare il correttore per il test immesso.</P>";
 | 
						||
    cout << "<P>Rivolgersi al docente della lezione odierna.</P>";
 | 
						||
    return;
 | 
						||
  }
 | 
						||
  
 | 
						||
  // 1 of theze dayz I'll fall to pieces anywayz
 | 
						||
  String command, verifiche, corso;
 | 
						||
  // Compone la stringa di selezione utente. 
 | 
						||
  command = "SELECT * FROM UTENTI WHERE loginname='";
 | 
						||
  command += _utente;
 | 
						||
  command += "' AND logged='t'";
 | 
						||
  // Esegue il comando SQL, dovrebbe venir ritornata una sola tupla
 | 
						||
  // al limite se ne vengono ritornate piu' di una verranno ignorate
 | 
						||
  _db->ExecCommandOk(command);
 | 
						||
  const int tuples = _db->Tuples();
 | 
						||
  if (tuples > 0) {
 | 
						||
    // Aggiorna lo stato dei test effettuati per modulo sulla tabella UTENTI
 | 
						||
    verifiche = _db->GetValue(0, "verifiche");
 | 
						||
    corso     = _db->GetValue(0, "course");
 | 
						||
    trim(corso);
 | 
						||
 | 
						||
    const unsigned int mod_int = atoi(_modulo);
 | 
						||
    const unsigned int l       = verifiche.length();
 | 
						||
    if ((l < mod_int || verifiche[mod_int-1] != _testnum[0]) && mod_int <= MAXMODULES) {
 | 
						||
      if (l< mod_int)
 | 
						||
	for (unsigned int j=l; j < mod_int; j++)
 | 
						||
	  verifiche += ' ';
 | 
						||
      verifiche[mod_int-1] = _testnum[0];
 | 
						||
      command = "UPDATE UTENTI SET verifiche='";
 | 
						||
      command += verifiche;
 | 
						||
      command += "' WHERE loginname='";
 | 
						||
      command += _utente;
 | 
						||
      command += "'";
 | 
						||
      _db->ExecCommandOk(command);
 | 
						||
      
 | 
						||
      // Controlla i punteggi inseriti nella matrice con quelli memorizzati nel correttore
 | 
						||
      // Compone le risposte fornite da memorizzare sulla tabella VERIFICHE in un formato pi<70> "umano"
 | 
						||
      Rational punteggio;
 | 
						||
      punteggio = _blank_test ? ZERO : _questionario.calc_score();
 | 
						||
      
 | 
						||
      long progressivo = 0L;
 | 
						||
      // Blocca la tabella dei progressivi e prende il progressivo 
 | 
						||
      command = "LOCK PROGRESSIVI";
 | 
						||
      _db->ExecCommandOk(command);
 | 
						||
      
 | 
						||
      command = "SELECT * FROM PROGRESSIVI";
 | 
						||
      if (_db->ExecTuplesOk(command) && _db->Tuples() > 0){
 | 
						||
	progressivo = atol(_db->GetValue(0, "progverifiche"));
 | 
						||
      }
 | 
						||
      else { // Se non c'<27> nessuna riga viene aggiunta
 | 
						||
	command = "INSERT INTO PROGRESSIVI VALUES(0,0)";
 | 
						||
	_db->ExecCommandOk(command);	  
 | 
						||
      }
 | 
						||
      progressivo++;
 | 
						||
      command = "UPDATE PROGRESSIVI SET progverifiche=progverifiche+1"; // Incrementa il progressivo
 | 
						||
      _db->ExecCommandOk(command); // Aggiorna la tabella PROGRESSIVI
 | 
						||
      // Memorizza il punteggio e le risposte fornite sulla tabella VERIFICHE
 | 
						||
      command = "INSERT INTO VERIFICHE VALUES (";
 | 
						||
      command += ltoa(progressivo);
 | 
						||
      command += ",'";
 | 
						||
      command += _utente;
 | 
						||
      command += "',current_timestamp,";
 | 
						||
      command += _modulo;
 | 
						||
      command += ",'";
 | 
						||
      command += _testnum;
 | 
						||
      command += "','";
 | 
						||
      if (_blank_test)
 | 
						||
        command +=  " " ;
 | 
						||
      else
 | 
						||
        command += _user_answers; // Risposte fornite in formato "umano"
 | 
						||
      command += "',";
 | 
						||
      command += dtoa((double) punteggio); // Punteggio sottoforma di double
 | 
						||
      command += ")";
 | 
						||
      _db->ExecCommandOk(command);
 | 
						||
 | 
						||
      if (_modulo=="1")		// (23/01/01) Il modulo 1 <20> "speciale" in quanto non ha alcun test; <20> il modulo di
 | 
						||
		cout << "" << endl;	// formazione del tecnico contabile di Eurocampo
 | 
						||
	  else
 | 
						||
      cout << "<H2>Risultato del test</H2><BR><BR>" << endl;
 | 
						||
      if (!_blank_test)
 | 
						||
        _questionario.dump_html(corso, atoi(_modulo), _testnum[0]);
 | 
						||
      else
 | 
						||
		{
 | 
						||
		  if(_modulo=="1")	// (23/01/01) solito modulo 1 speciale
 | 
						||
			cout << "<P><STRONG><H3>Benvenuti nel modulo per la formazione del TECNICO CONTABILE</H3></STRONG><BR><BR><BR>";
 | 
						||
		  else
 | 
						||
			cout << "<P>Test consegnato <STRONG> in bianco </STRONG><BR><BR><BR>";
 | 
						||
		}
 | 
						||
      cout << "<TABLE><TR><TD><FORM METHOD=\"POST\" ACTION=";
 | 
						||
      cout << GET_MODULE_CGI << ">";
 | 
						||
      cout << "Cliccate sull'icona sottostante per ritornare all'area formativa del modulo.";
 | 
						||
      cout << "<BR><BR><INPUT TYPE=HIDDEN NAME=\"MODULO\" VALUE=\"" << _modulo << "\">";
 | 
						||
      cout << "<INPUT TYPE=\"IMAGE\" SRC=\"/images/area_" << mod_int;
 | 
						||
      cout << ".gif\" ALIGN=top ALT=\"Accesso al modulo\" BORDER=0>";
 | 
						||
      cout << "</FORM></TD></TR></TABLE></P>" << endl;
 | 
						||
 | 
						||
    }
 | 
						||
    else { // Se il test <20> gi<67> stato eseguito, nega l'aggiornamento il calcolo punteggio e tutto il resto
 | 
						||
      cout << "<H2>Test gi<67> eseguito</H2><BR><BR>" << endl;
 | 
						||
      cout << "<P>Il test selezionato risulta gi<67> eseguito.</P>";
 | 
						||
      cout << "<P>Si prega di riselezionare l'area corretta dalla pagina di <A HREF=\"";
 | 
						||
      cout << LOGIN_CGI << "\">selezione moduli.</A></P>";
 | 
						||
  }
 | 
						||
 | 
						||
  }
 | 
						||
  else { // Se non trova i dati dell'utente indicato 
 | 
						||
         // visualizza la mancanza di informazioni per completare la pagina.
 | 
						||
    cout << "<H2>Mancanza di informazioni</H2><BR><BR>" << endl;
 | 
						||
    cout << "<P>Impossibile reperire le informazioni relative al percorso formativo dell'utente " << _utente;
 | 
						||
    cout << ".</P><P>Controllare l'esattezza delle informazioni inserite.</P>";
 | 
						||
  }
 | 
						||
  return;
 | 
						||
}
 | 
						||
 | 
						||
void Check_answers_Application::print_access_error()
 | 
						||
{ 
 | 
						||
 
 | 
						||
  cout << "<H2>Errore di accesso</H2><BR><BR>";
 | 
						||
  cout << "<P>Utilizzare la normale procedura di <A HREF=\"";
 | 
						||
  cout << LOGIN_CGI << "\">accesso</A> ai corsi.</P><BR>";
 | 
						||
}
 | 
						||
 | 
						||
void Check_answers_Application::main_func()
 | 
						||
{ 
 | 
						||
  // Controllo utente: se il CGI viene chiamato senza tutte le indicazioni necessarie
 | 
						||
  // visualizza l'errore
 | 
						||
  if (_utente.empty() || _modulo.empty() || _testnum.empty() || _user_answers.empty()) {
 | 
						||
    print_access_error();
 | 
						||
    return;
 | 
						||
  }
 | 
						||
  // Se tutto <20> OK...
 | 
						||
  // Inizia la transazione
 | 
						||
  _db = new PgTransaction(_environment, _dbname);
 | 
						||
  if ( _db->ConnectionBad() ) 
 | 
						||
    print_database_error();
 | 
						||
  else
 | 
						||
    check_answers();
 | 
						||
  delete _db; // Termina la transazione
 | 
						||
  return;
 | 
						||
}
 | 
						||
 | 
						||
int main(int argc, char* argv[])
 | 
						||
{
 | 
						||
  Check_answers_Application* a = new Check_answers_Application();
 | 
						||
 
 | 
						||
  a->run(argc, argv);
 | 
						||
 | 
						||
  delete a;
 | 
						||
  
 | 
						||
  exit(0);
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 |