diff --git a/sql/swad.sql b/sql/swad.sql index 2caf94168..9ad8583bc 100644 --- a/sql/swad.sql +++ b/sql/swad.sql @@ -603,13 +603,11 @@ CREATE TABLE IF NOT EXISTS gam_grp ( -- Table gam_questions: stores the questions in the games -- CREATE TABLE IF NOT EXISTS gam_questions ( - QstCod INT NOT NULL AUTO_INCREMENT, GamCod INT NOT NULL, + QstCod INT NOT NULL, QstInd INT NOT NULL DEFAULT 0, - AnsType ENUM('unique_choice','multiple_choice') NOT NULL, - Stem TEXT NOT NULL, - UNIQUE INDEX(QstCod), - INDEX(GamCod)); + INDEX(GamCod), + INDEX(QstCod)); -- -- Table gam_users: stores the users who have answer the games -- diff --git a/swad_changelog.h b/swad_changelog.h index e157fa00f..7d14d6cb2 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -232,17 +232,24 @@ // TODO: Cuando sólo se cambian los grupos y no el rol de un profesor ya existente, no sale ningún mensaje. se haga lo que se haga en la edición debería salir un mensaje del tipo "Cambios realizados" +// TODO: "Solicitar inscripción" como superusuario: "Usted no tiene permiso para realizar esta acción" + /*****************************************************************************/ /****************************** Public constants *****************************/ /*****************************************************************************/ -#define Log_PLATFORM_VERSION "SWAD 16.251.3 (2017-07-18)" +#define Log_PLATFORM_VERSION "SWAD 16.251.4 (2017-09-01)" #define CSS_FILE "swad16.235.1.css" #define JS_FILE "swad16.206.3.js" // Number of lines (includes comments but not blank lines) has been got with the following command: // nl swad*.c swad*.h css/swad*.css py/swad*.py js/swad*.js soap/swad*?.h sql/swad*.sql | tail -1 /* +// TODO: "Error when getting answers of a question" + Version 16.251.4: Sep 01, 2017 Listing games for remote control. Not finished. (? lines) +DROP TABLE IF EXISTS gam_questions; +CREATE TABLE IF NOT EXISTS gam_questions (GamCod INT NOT NULL,QstCod INT NOT NULL,QstInd INT NOT NULL DEFAULT 0,INDEX(GamCod),INDEX(QstCod)); + Version 16.251.3: Jul 18, 2017 Listing games for remote control. Not finished. (227148 lines) Version 16.251.2: Jul 16, 2017 Listing games for remote control. Not finished. (227062 lines) 1 change necessary in database: diff --git a/swad_database.c b/swad_database.c index d27f801cf..2a7bc3641 100644 --- a/swad_database.c +++ b/swad_database.c @@ -1311,25 +1311,21 @@ mysql> DESCRIBE gam_grp; /***** Table gam_questions *****/ /* mysql> DESCRIBE gam_questions; -+---------+-----------------------------------------+------+-----+---------+----------------+ -| Field | Type | Null | Key | Default | Extra | -+---------+-----------------------------------------+------+-----+---------+----------------+ -| QstCod | int(11) | NO | PRI | NULL | auto_increment | -| SvyCod | int(11) | NO | MUL | NULL | | -| QstInd | int(11) | NO | | 0 | | -| AnsType | enum('unique_choice','multiple_choice') | NO | | NULL | | -| Stem | text | NO | | NULL | | -+---------+-----------------------------------------+------+-----+---------+----------------+ -5 rows in set (0.00 sec) ++--------+---------+------+-----+---------+-------+ +| Field | Type | Null | Key | Default | Extra | ++--------+---------+------+-----+---------+-------+ +| GamCod | int(11) | NO | MUL | NULL | | +| QstCod | int(11) | NO | MUL | NULL | | +| QstInd | int(11) | NO | | 0 | | ++--------+---------+------+-----+---------+-------+ +3 rows in set (0,00 sec) */ DB_CreateTable ("CREATE TABLE IF NOT EXISTS gam_questions (" - "QstCod INT NOT NULL AUTO_INCREMENT," "GamCod INT NOT NULL," + "QstCod INT NOT NULL," "QstInd INT NOT NULL DEFAULT 0," - "AnsType ENUM ('unique_choice','multiple_choice') NOT NULL," - "Stem TEXT NOT NULL," // Cns_MAX_BYTES_TEXT - "UNIQUE INDEX(QstCod)," - "INDEX(GamCod))"); + "INDEX(GamCod)," + "INDEX(QstCod))"); /***** Table gam_users *****/ /* diff --git a/swad_remote_control.c b/swad_remote_control.c index 2947d2487..d0a2ca7e1 100644 --- a/swad_remote_control.c +++ b/swad_remote_control.c @@ -2557,14 +2557,14 @@ static unsigned Rmt_GetNumQstsGame (long GamCod) void Rmt_RequestEditQuestion (void) { - long GamCod; + struct Game Game; struct GameQuestion GameQst; /***** Initialize question to zero *****/ Rmt_InitQst (&GameQst); /***** Get game code *****/ - if ((GamCod = Rmt_GetParamGameCod ()) == -1L) + if ((Game.GamCod = Rmt_GetParamGameCod ()) == -1L) Lay_ShowErrorAndExit ("Code of game is missing."); /* Get the question code */ @@ -2576,10 +2576,10 @@ void Rmt_RequestEditQuestion (void) Gbl.Games.CurrentPage = Pag_GetParamPagNum (Pag_SURVEYS); /***** Show form to create a new question in this game *****/ - Tst_ShowFormAskSelectTstsForGame (GamCod); + Tst_ShowFormAskSelectTstsForGame (Game.GamCod); /***** Show current game *****/ - Rmt_ShowOneGame (GamCod,&GameQst,true); + Rmt_ShowOneGame (Game.GamCod,&GameQst,true); } /*****************************************************************************/ @@ -2741,7 +2741,7 @@ void Rmt_ReceiveQst (void) extern const char *Txt_The_game_has_been_modified; char Txt[Cns_MAX_BYTES_TEXT + 1]; char Query[512 + Cns_MAX_BYTES_TEXT]; - long GamCod; + struct Game Game; struct GameQuestion GameQst; unsigned NumAns; char AnsStr[8 + 10 + 1]; @@ -2754,7 +2754,7 @@ void Rmt_ReceiveQst (void) /***** Get parameters from form *****/ /* Get game code */ - if ((GamCod = Rmt_GetParamGameCod ()) == -1L) + if ((Game.GamCod = Rmt_GetParamGameCod ()) == -1L) Lay_ShowErrorAndExit ("Code of game is missing."); /* Get question code */ @@ -2823,20 +2823,20 @@ void Rmt_ReceiveQst (void) } if (Error) - Tst_ShowFormAskSelectTstsForGame (GamCod); + Tst_ShowFormAskSelectTstsForGame (Game.GamCod); else { /***** Form is received OK ==> insert question and answer in the database *****/ if (GameQst.QstCod < 0) // It's a new question { - GameQst.QstInd = Rmt_GetNextQuestionIndexInGame (GamCod); + GameQst.QstInd = Rmt_GetNextQuestionIndexInGame (Game.GamCod); /* Insert question in the table of questions */ sprintf (Query,"INSERT INTO gam_questions" " (GamCod,QstInd,AnsType,Stem)" " VALUES" " (%ld,%u,'%s','%s')", - GamCod,GameQst.QstInd,Rmt_StrAnswerTypesDB[GameQst.AnswerType],Txt); + Game.GamCod,GameQst.QstInd,Rmt_StrAnswerTypesDB[GameQst.AnswerType],Txt); GameQst.QstCod = DB_QueryINSERTandReturnCode (Query,"can not create question"); } else // It's an existing question @@ -2845,7 +2845,7 @@ void Rmt_ReceiveQst (void) sprintf (Query,"UPDATE gam_questions SET Stem='%s',AnsType='%s'" " WHERE QstCod=%ld AND GamCod=%ld", Txt,Rmt_StrAnswerTypesDB[GameQst.AnswerType], - GameQst.QstCod,GamCod); + GameQst.QstCod,Game.GamCod); DB_QueryUPDATE (Query,"can not update question"); } @@ -2894,7 +2894,7 @@ void Rmt_ReceiveQst (void) Rmt_FreeTextChoiceAnswers (&GameQst,Rmt_MAX_ANSWERS_PER_QUESTION); /***** Show current game *****/ - Rmt_ShowOneGame (GamCod,&GameQst,true); + Rmt_ShowOneGame (Game.GamCod,&GameQst,true); } /*****************************************************************************/ @@ -2976,7 +2976,7 @@ static void Rmt_ListGameQuestions (struct Game *Game,struct GameQuestion *GameQs extern const char *Txt_This_game_has_no_questions; extern const char *Txt_Done; extern const char *Txt_Edit_question; - char Query[256]; + char Query[512]; MYSQL_RES *mysql_res; MYSQL_ROW row; unsigned NumQsts; @@ -2987,8 +2987,12 @@ static void Rmt_ListGameQuestions (struct Game *Game,struct GameQuestion *GameQs bool PutFormAnswerGame = Game->Status.ICanAnswer && !Editing; /***** Get data of questions from database *****/ - sprintf (Query,"SELECT QstCod,QstInd,AnsType,Stem" - " FROM gam_questions WHERE GamCod=%ld ORDER BY QstInd", + sprintf (Query,"SELECT gam_questions.QstCod,gam_questions.QstInd," + "tst_questions.AnsType,tst_questions.Stem" + " FROM gam_questions,tst_questions" + " WHERE gam_questions.GamCod=%ld" + " AND gam_questions.QstCod=tst_questions.QstCod" + " ORDER BY gam_questions.QstInd", Game->GamCod); NumQsts = (unsigned) DB_QuerySELECT (Query,&mysql_res,"can not get data of a question"); @@ -3155,6 +3159,15 @@ static void Rmt_PutButtonToAddNewQuestions (void) void Rmt_AddTstQuestionsToGame (void) { extern const char *Txt_You_must_select_one_ore_more_questions; + struct Game Game; + const char *Ptr; + char LongStr[1 + 10 + 1]; + struct GameQuestion GameQst; + char Query[256]; + + /***** Get game code *****/ + if ((Game.GamCod = Rmt_GetParamGameCod ()) == -1L) + Lay_ShowErrorAndExit ("Code of game is missing."); /***** Get selected questions *****/ /* Allocate space for selected question codes */ @@ -3172,7 +3185,28 @@ void Rmt_AddTstQuestionsToGame (void) // TODO: Show form again!!! } - /* Free space for selected question codes */ + /***** Insert questions in database *****/ + Ptr = Gbl.Games.ListQuestions; + while (*Ptr) + { + /* Get next code */ + Par_GetNextStrUntilSeparParamMult (&Ptr,LongStr,1 + 10); + if (sscanf (LongStr,"%ld",&GameQst.QstCod) != 1) + Lay_ShowErrorAndExit ("Wrong question code."); + + /* Get next index */ + GameQst.QstInd = Rmt_GetNextQuestionIndexInGame (Game.GamCod); + + /* Insert question in the table of questions */ + sprintf (Query,"INSERT INTO gam_questions" + " (GamCod,QstCod,QstInd)" + " VALUES" + " (%ld,%ld,%u)", + Game.GamCod,GameQst.QstCod,GameQst.QstInd); + DB_QueryINSERT (Query,"can not create question"); + } + + /***** Free space for selected question codes *****/ Rmt_FreeListsSelectedQuestions (); } @@ -3211,7 +3245,7 @@ static unsigned Rmt_CountNumQuestionsInList (void) { const char *Ptr; unsigned NumQuestions = 0; - char LongStr[1+ 10 + 1]; + char LongStr[1 + 10 + 1]; long QstCod; /***** Go over the list Gbl.Test.ListAnsTypes counting the number of types of answer *****/ @@ -3417,12 +3451,12 @@ void Rmt_RequestRemoveQst (void) { extern const char *Txt_Do_you_really_want_to_remove_the_question_X; extern const char *Txt_Remove_question; - long GamCod; + struct Game Game; struct GameQuestion GameQst; /***** Get parameters from form *****/ /* Get game code */ - if ((GamCod = Rmt_GetParamGameCod ()) == -1L) + if ((Game.GamCod = Rmt_GetParamGameCod ()) == -1L) Lay_ShowErrorAndExit ("Code of game is missing."); /* Get question code */ @@ -3433,7 +3467,7 @@ void Rmt_RequestRemoveQst (void) GameQst.QstInd = Rmt_GetQstIndFromQstCod (GameQst.QstCod); /***** Show question and button to remove question *****/ - Gbl.Games.GamCodToEdit = GamCod; + Gbl.Games.GamCodToEdit = Game.GamCod; Gbl.Games.GamQstCodToEdit = GameQst.QstCod; sprintf (Gbl.Alert.Txt,Txt_Do_you_really_want_to_remove_the_question_X, (unsigned long) (GameQst.QstInd + 1)); @@ -3442,7 +3476,7 @@ void Rmt_RequestRemoveQst (void) Btn_REMOVE_BUTTON,Txt_Remove_question); /***** Show current game *****/ - Rmt_ShowOneGame (GamCod,&GameQst,true); + Rmt_ShowOneGame (Game.GamCod,&GameQst,true); } /*****************************************************************************/ @@ -3453,12 +3487,12 @@ void Rmt_RemoveQst (void) { extern const char *Txt_Question_removed; char Query[512]; - long GamCod; + struct Game Game; struct GameQuestion GameQst; /***** Get parameters from form *****/ /* Get game code */ - if ((GamCod = Rmt_GetParamGameCod ()) == -1L) + if ((Game.GamCod = Rmt_GetParamGameCod ()) == -1L) Lay_ShowErrorAndExit ("Code of game is missing."); /* Get question code */ @@ -3482,7 +3516,7 @@ void Rmt_RemoveQst (void) /* Change index of questions greater than this */ sprintf (Query,"UPDATE gam_questions SET QstInd=QstInd-1" " WHERE GamCod=%ld AND QstInd>%u", - GamCod,GameQst.QstInd); + Game.GamCod,GameQst.QstInd); DB_QueryUPDATE (Query,"can not update indexes of questions"); /***** Write message *****/ @@ -3490,7 +3524,7 @@ void Rmt_RemoveQst (void) Ale_ShowAlert (Ale_SUCCESS,Gbl.Alert.Txt); /***** Show current game *****/ - Rmt_ShowOneGame (GamCod,&GameQst,true); + Rmt_ShowOneGame (Game.GamCod,&GameQst,true); } /*****************************************************************************/ diff --git a/swad_test.c b/swad_test.c index 4342a47b7..a30532b45 100644 --- a/swad_test.c +++ b/swad_test.c @@ -194,8 +194,11 @@ static unsigned long Tst_GetQuestions (MYSQL_RES **mysql_res); static unsigned long Tst_GetQuestionsForTest (MYSQL_RES **mysql_res); static void Tst_ListOneQstToEdit (void); static bool Tst_GetOneQuestionByCod (long QstCod,MYSQL_RES **mysql_res); -static void Tst_ListOneOrMoreQuestionsForEdition (unsigned long NumRows,MYSQL_RES *mysql_res); -static void Tst_ListOneOrMoreQuestionsForSelection (unsigned long NumRows,MYSQL_RES *mysql_res); +static void Tst_ListOneOrMoreQuestionsForEdition (unsigned long NumRows, + MYSQL_RES *mysql_res); +static void Tst_ListOneOrMoreQuestionsForSelection (long GamCod, + unsigned long NumRows, + MYSQL_RES *mysql_res); static void Tst_WriteAnswersOfAQstEdit (long QstCod); static void Tst_WriteAnswersOfAQstViewTest (unsigned NumQst,long QstCod,bool Shuffle); @@ -2632,7 +2635,7 @@ void Tst_ListQuestionsToSelect (void) { if ((NumRows = Tst_GetQuestions (&mysql_res)) != 0) // Query database /* Show the table with the questions */ - Tst_ListOneOrMoreQuestionsForSelection (NumRows,mysql_res); + Tst_ListOneOrMoreQuestionsForSelection (GamCod,NumRows,mysql_res); /***** Free structure that stores the query result *****/ DB_FreeMySQLResult (&mysql_res); @@ -2998,7 +3001,8 @@ static bool Tst_GetOneQuestionByCod (long QstCod,MYSQL_RES **mysql_res) /****************** List for edition one or more test questions **************/ /*****************************************************************************/ -static void Tst_ListOneOrMoreQuestionsForEdition (unsigned long NumRows,MYSQL_RES *mysql_res) +static void Tst_ListOneOrMoreQuestionsForEdition (unsigned long NumRows, + MYSQL_RES *mysql_res) { extern const char *Hlp_ASSESSMENT_Tests; extern const char *Txt_Questions; @@ -3286,7 +3290,9 @@ static void Tst_ListOneOrMoreQuestionsForEdition (unsigned long NumRows,MYSQL_RE /****************** List for edition one or more test questions **************/ /*****************************************************************************/ -static void Tst_ListOneOrMoreQuestionsForSelection (unsigned long NumRows,MYSQL_RES *mysql_res) +static void Tst_ListOneOrMoreQuestionsForSelection (long GamCod, + unsigned long NumRows, + MYSQL_RES *mysql_res) { extern const char *Hlp_ASSESSMENT_Tests; extern const char *Txt_Questions; @@ -3311,6 +3317,7 @@ static void Tst_ListOneOrMoreQuestionsForSelection (unsigned long NumRows,MYSQL_ /***** Start form *****/ Act_FormStart (ActAddTstQstToGam); + Rmt_PutParamGameCod (GamCod); /***** Write the heading *****/ Tbl_StartTableWideMargin (2);