diff --git a/js/swad18.123.js b/js/swad18.123.js index 1fb8a195a..812326879 100644 --- a/js/swad18.123.js +++ b/js/swad18.123.js @@ -86,6 +86,7 @@ function writeLocalDateHMSFromUTC (id,TimeUTC,DateFormat,Separator,StrToday, writeLocalDateHMSFromUTC.lastd = d; // Update last date for the next call /* Set date */ + StrDate = ''; if (WriteDate) { WriteTodayStr = false; if (StrToday != null) @@ -111,7 +112,6 @@ function writeLocalDateHMSFromUTC (id,TimeUTC,DateFormat,Separator,StrToday, StrDate = MonthsShort[Mon - 1] + ' ' + Day.toString() + ', ' + Yea.toString(); break; default: - StrDate = ''; break; } @@ -120,10 +120,10 @@ function writeLocalDateHMSFromUTC (id,TimeUTC,DateFormat,Separator,StrToday, DayOfWeek = (DayOfWeek == 0) ? 6 : DayOfWeek - 1; StrDate = StrDate + Separator + DAYS[DayOfWeek]; } - StrDate = StrDate + Separator; } - else - StrDate = ''; + else if (WriteWeekDay) + StrDate = Separator; + StrDate = StrDate + Separator; /* Set HH:MM:SS */ StrHou = ''; diff --git a/sql/swad.sql b/sql/swad.sql index 6156d98a9..37f04cf97 100644 --- a/sql/swad.sql +++ b/sql/swad.sql @@ -634,23 +634,17 @@ CREATE TABLE IF NOT EXISTS gam_grp ( CREATE TABLE IF NOT EXISTS gam_matches ( MchCod INT NOT NULL AUTO_INCREMENT, GamCod INT NOT NULL, + UsrCod INT NOT NULL, StartTime DATETIME NOT NULL, EndTime DATETIME NOT NULL, - UsrCod INT NOT NULL, Title VARCHAR(2047) NOT NULL, - UNIQUE INDEX(MchCod), - INDEX(GamCod)); --- --- Table gam_playing: stores the matches (game instances) beeing played currently --- -CREATE TABLE IF NOT EXISTS gam_playing ( - MchCod INT NOT NULL, QstInd INT NOT NULL DEFAULT 0, QstCod INT NOT NULL DEFAULT -1, + QstStartTime DATETIME NOT NULL, ShowingAnswers ENUM('N','Y') NOT NULL DEFAULT 'N', - MchStart DATETIME NOT NULL, - QstStart DATETIME NOT NULL, - UNIQUE INDEX(MchCod)); + Finished ENUM('N','Y') NOT NULL DEFAULT 'N', + UNIQUE INDEX(MchCod), + INDEX(GamCod)); -- -- Table gam_questions: stores the questions in the games -- diff --git a/swad_changelog.h b/swad_changelog.h index 54bcbc3b1..3bd0cc04a 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -451,15 +451,19 @@ En OpenSWAD: ps2pdf source.ps destination.pdf */ -#define Log_PLATFORM_VERSION "SWAD 18.124 (2019-05-28)" +#define Log_PLATFORM_VERSION "SWAD 18.125 (2019-05-29)" #define CSS_FILE "swad18.123.css" #define JS_FILE "swad18.123.js" /* + Version 18.125: May 29, 2019 Unification of tables of matches (saved and current) into one table. (243371 lines) + 2 changes necessary in database: +DROP TABLE gam_matches; +CREATE TABLE IF NOT EXISTS gam_matches (MchCod INT NOT NULL AUTO_INCREMENT,GamCod INT NOT NULL,UsrCod INT NOT NULL,StartTime DATETIME NOT NULL,EndTime DATETIME NOT NULL,Title VARCHAR(2047) NOT NULL,QstInd INT NOT NULL DEFAULT 0,QstCod INT NOT NULL DEFAULT -1,QstStartTime DATETIME NOT NULL,ShowingAnswers ENUM('N','Y') NOT NULL DEFAULT 'N',Finished ENUM('N','Y') NOT NULL DEFAULT 'N',UNIQUE INDEX(MchCod),INDEX(GamCod)); + Version 18.124: May 28, 2019 Every game can have several matches (game instances). (243400 lines) - 4 changes necessary in database: -DROP TABLE gam_played,gam_playing,gam_grp; + 3 changes necessary in database: +DROP TABLE gam_played,gam_matches,gam_grp; CREATE TABLE IF NOT EXISTS gam_matches (MchCod INT NOT NULL AUTO_INCREMENT,GamCod INT NOT NULL,StartTime DATETIME NOT NULL,EndTime DATETIME NOT NULL,UsrCod INT NOT NULL,Title VARCHAR(2047) NOT NULL,UNIQUE INDEX(MchCod),INDEX(GamCod)); -CREATE TABLE IF NOT EXISTS gam_playing (MchCod INT NOT NULL,QstInd INT NOT NULL DEFAULT 0,QstCod INT NOT NULL DEFAULT -1,ShowingAnswers ENUM('N','Y') NOT NULL DEFAULT 'N',MchStart DATETIME NOT NULL,QstStart DATETIME NOT NULL,UNIQUE INDEX(MchCod)); CREATE TABLE IF NOT EXISTS gam_grp (MchCod INT NOT NULL,GrpCod INT NOT NULL,UNIQUE INDEX(MchCod,GrpCod)); Version 18.123.2: May 23, 2019 New table with games instances already played. (242829 lines) @@ -481,9 +485,8 @@ sudo cp icon/flag-checkered.svg /var/www/html/swad/icon/ INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1781','es','N','Finalizar juego'); Version 18.122.2: May 20, 2019 New action to show current question (in a game beeing played) to a student. (242378 lines) - 2 changes necessary in database: + 1 change necessary in database: INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1780','es','N','Mostrar juego a estudiante'); -CREATE TABLE IF NOT EXISTS gam_playing (GamCod INT NOT NULL,QstInd INT NOT NULL DEFAULT 0,QstCod INT NOT NULL DEFAULT -1,ShowingAnswers ENUM('N','Y') NOT NULL DEFAULT 'N',GamStart DATETIME NOT NULL,QstStart DATETIME NOT NULL,UNIQUE INDEX(GamCod)); Version 18.122.1: May 20, 2019 New action to play game by a student. (242257 lines) 2 changes necessary in database: diff --git a/swad_database.c b/swad_database.c index 85d02c80b..503aa02de 100644 --- a/swad_database.c +++ b/swad_database.c @@ -1373,51 +1373,37 @@ mysql> DESCRIBE gam_grp; /***** Table gam_matches *****/ /* mysql> DESCRIBE gam_matches; -+-----------+---------------+------+-----+---------+----------------+ -| Field | Type | Null | Key | Default | Extra | -+-----------+---------------+------+-----+---------+----------------+ -| MchCod | int(11) | NO | PRI | NULL | auto_increment | -| GamCod | int(11) | NO | MUL | NULL | | -| StartTime | datetime | NO | | NULL | | -| EndTime | datetime | NO | | NULL | | -| UsrCod | int(11) | NO | | NULL | | -| Title | varchar(2047) | NO | | NULL | | -+-----------+---------------+------+-----+---------+----------------+ -6 rows in set (0.00 sec) ++----------------+---------------+------+-----+---------+----------------+ +| Field | Type | Null | Key | Default | Extra | ++----------------+---------------+------+-----+---------+----------------+ +| MchCod | int(11) | NO | PRI | NULL | auto_increment | +| GamCod | int(11) | NO | MUL | NULL | | +| UsrCod | int(11) | NO | | NULL | | +| StartTime | datetime | NO | | NULL | | +| EndTime | datetime | NO | | NULL | | +| Title | varchar(2047) | NO | | NULL | | +| QstInd | int(11) | NO | | 0 | | +| QstCod | int(11) | NO | | -1 | | +| QstStartTime | datetime | NO | | NULL | | +| ShowingAnswers | enum('N','Y') | NO | | N | | +| Finished | enum('N','Y') | NO | | N | | ++----------------+---------------+------+-----+---------+----------------+ +11 rows in set (0.00 sec) */ DB_CreateTable ("CREATE TABLE IF NOT EXISTS gam_matches (" "MchCod INT NOT NULL AUTO_INCREMENT," "GamCod INT NOT NULL," + "UsrCod INT NOT NULL," "StartTime DATETIME NOT NULL," "EndTime DATETIME NOT NULL," - "UsrCod INT NOT NULL," "Title VARCHAR(2047) NOT NULL," // Gam_MAX_BYTES_TITLE - "UNIQUE INDEX(MchCod)," - "INDEX(GamCod)"); - - /***** Table gam_playing *****/ -/* -mysql> DESCRIBE gam_playing; -+----------------+---------------+------+-----+---------+-------+ -| Field | Type | Null | Key | Default | Extra | -+----------------+---------------+------+-----+---------+-------+ -| MchCod | int(11) | NO | PRI | NULL | | -| QstInd | int(11) | NO | | 0 | | -| QstCod | int(11) | NO | | -1 | | -| ShowingAnswers | enum('N','Y') | NO | | N | | -| MchStart | datetime | NO | | NULL | | -| QstStart | datetime | NO | | NULL | | -+----------------+---------------+------+-----+---------+-------+ -6 rows in set (0.00 sec) -*/ - DB_CreateTable ("CREATE TABLE IF NOT EXISTS gam_playing (" - "MchCod INT NOT NULL," "QstInd INT NOT NULL DEFAULT 0," "QstCod INT NOT NULL DEFAULT -1," + "QstStartTime DATETIME NOT NULL," "ShowingAnswers ENUM('N','Y') NOT NULL DEFAULT 'N'," - "MchStart DATETIME NOT NULL," - "QstStart DATETIME NOT NULL," - "UNIQUE INDEX(MchCod))"); + "Finished ENUM('N','Y') NOT NULL DEFAULT 'N'," + "UNIQUE INDEX(MchCod)," + "INDEX(GamCod)"); /***** Table gam_questions *****/ /* diff --git a/swad_game.c b/swad_game.c index 582af5fa7..42a567437 100644 --- a/swad_game.c +++ b/swad_game.c @@ -84,8 +84,15 @@ struct Match long GamCod; long UsrCod; time_t TimeUTC[2]; - bool Open; char Title[Gam_MAX_BYTES_TITLE + 1]; + struct + { + int QstInd; + long QstCod; + time_t QstStartTimeUTC; + bool ShowAnswers; + bool Finished; + } Status; }; /*****************************************************************************/ @@ -113,7 +120,6 @@ static void Gam_ShowOneGame (long GamCod, bool PutFormNewMatch, bool PutButtonToPlay); static void Gam_WriteAuthor (struct Game *Game); -// static void Gam_WriteStatus (struct Game *Game); static void Gam_GetParamGameOrder (void); static void Gam_PutFormsToRemEditOneGame (const struct Game *Game, @@ -128,8 +134,6 @@ static void Gam_ShowLstGrpsToEditMatch (void); static void Gam_CreateGame (struct Game *Game,const char *Txt); static void Gam_UpdateGame (struct Game *Game,const char *Txt); -// static bool Gam_CheckIfMatchIsAssociatedToGrps (long MchCod); -// Nstatic void Gam_RemoveAllTheGrpsAssociatedToMatchesOfAGame (long GamCod); static void Gam_CreateGrps (long MchCod); static void Gam_GetAndWriteNamesOfGrpsAssociatedToMatch (struct Match *Match); static bool Gam_CheckIfIPlayThisMatchBasedOnGrps (long GamCod); @@ -144,8 +148,8 @@ static void Gam_RemAnswersOfAQuestion (long QstCod); static int Gam_GetQstIndFromQstCod (long GamCod,long QstCod); // TODO: Remove this function because a question code can be repeated static long Gam_GetQstCodFromQstInd (long GamCod,unsigned QstInd); static int Gam_GetMaxQuestionIndexInGame (long GamCod); -static int Gam_GetPrevQuestionIndexInGame (long GamCod,unsigned QstInd); -static int Gam_GetNextQuestionIndexInGame (long GamCod,unsigned QstInd); +static int Gam_GetPrevQuestionIndexInGame (long GamCod,int QstInd); +static int Gam_GetNextQuestionIndexInGame (long GamCod,int QstInd); static void Gam_ListGameQuestions (struct Game *Game); static void Gam_ListOneOrMoreQuestionsForEdition (long GamCod,unsigned NumQsts, MYSQL_RES *mysql_res); @@ -176,9 +180,8 @@ static void Gam_PutBigButtonToPlayMatchTch (struct Game *Game); static void Gam_PutBigButtonToPlayMatchStd (long MchCod); static long Gam_CreateMatch (struct Match *Match); -// static bool Gam_CheckIfGameIsBeingPlayed (long GamCod); -static void Gam_UpdateMatchBeingPlayed (long MchCod,unsigned QstInd,long QstCod,bool ShowingAnswers); -static void Gam_RemoveMatchBeingPlayed (long MchCod); +static void Gam_UpdateMatchBeingPlayed (long MchCod,unsigned QstInd,long QstCod, + bool ShowingAnswers); static void Gam_PlayGameShowQuestionAndAnswers (long MchCod, unsigned QstInd, @@ -187,7 +190,7 @@ static void Gam_PutBigButtonToContinue (Act_Action_t NextAction, long MchCod,unsigned QstInd); static void Gam_PutBigButtonToEnd (long GamCod); -static void Gam_ShowQuestionBeingPlayed (void); +static void Gam_ShowQuestionBeingPlayed (struct Match *Match); static void Gam_ReceiveAndStoreUserAnswersToAGame (long GamCod); static void Gam_IncreaseAnswerInDB (long QstCod,unsigned AnsInd); @@ -1717,23 +1720,10 @@ bool Gam_CheckIfMatchIsAssociatedToGrp (long MchCod,long GrpCod) MchCod,GrpCod) != 0); } -/*****************************************************************************/ -/******************** Remove groups in matches of a game *********************/ -/*****************************************************************************/ -/* -static void Gam_RemoveAllTheGrpsAssociatedToMatchesOfAGame (long GamCod) - { - ***** Remove groups of the game ***** - DB_QueryDELETE ("can not remove the groups associated to matches of a game", - "DELETE FROM gam_grp USING gam_grp,gam_matches" - " WHERE gam_matches.GrpCod=%ld" - " AND gam_matches.MchCod=gam_grp.MchCod", - GamCod); - } -*/ /*****************************************************************************/ /******************** Remove one group from all the games ********************/ /*****************************************************************************/ +// TODO: Check if this function should be called when removing group void Gam_RemoveGroup (long GrpCod) { @@ -1747,6 +1737,7 @@ void Gam_RemoveGroup (long GrpCod) /*****************************************************************************/ /**************** Remove groups of one type from all the games ***************/ /*****************************************************************************/ +// TODO: Check if this function should be called when removing group type void Gam_RemoveGroupsOfType (long GrpTypCod) { @@ -2098,7 +2089,7 @@ static int Gam_GetMaxQuestionIndexInGame (long GamCod) // Question index can be 0, 1, 2,... // Return -1 if no previous question -static int Gam_GetPrevQuestionIndexInGame (long GamCod,unsigned QstInd) +static int Gam_GetPrevQuestionIndexInGame (long GamCod,int QstInd) { MYSQL_RES *mysql_res; MYSQL_ROW row; @@ -2109,7 +2100,7 @@ static int Gam_GetPrevQuestionIndexInGame (long GamCod,unsigned QstInd) // ...this implementation works even with non continuous indexes if (!DB_QuerySELECT (&mysql_res,"can not get previous question index", "SELECT MAX(QstInd) FROM gam_questions" - " WHERE GamCod=%ld AND QstInd<%u", + " WHERE GamCod=%ld AND QstInd<%d", GamCod,QstInd)) Lay_ShowErrorAndExit ("Error: previous question index not found."); @@ -2131,7 +2122,7 @@ static int Gam_GetPrevQuestionIndexInGame (long GamCod,unsigned QstInd) // Question index can be 0, 1, 2,... // Return -1 if no next question -static int Gam_GetNextQuestionIndexInGame (long GamCod,unsigned QstInd) +static int Gam_GetNextQuestionIndexInGame (long GamCod,int QstInd) { MYSQL_RES *mysql_res; MYSQL_ROW row; @@ -2142,7 +2133,7 @@ static int Gam_GetNextQuestionIndexInGame (long GamCod,unsigned QstInd) // ...this implementation works even with non continuous indexes if (!DB_QuerySELECT (&mysql_res,"can not get next question index", "SELECT MIN(QstInd) FROM gam_questions" - " WHERE GamCod=%ld AND QstInd>%u", + " WHERE GamCod=%ld AND QstInd>%d", GamCod,QstInd)) Lay_ShowErrorAndExit ("Error: next question index not found."); @@ -2923,13 +2914,17 @@ static void Gam_ListPlayedMatches (struct Game *Game,bool PutFormNewMatch) /* Make query */ NumMatches = (unsigned) DB_QuerySELECT (&mysql_res,"can not get matches", - "SELECT MchCod," // row[0] - "GamCod," // row[1] - "UNIX_TIMESTAMP(StartTime)," // row[2] - "UNIX_TIMESTAMP(EndTime)," // row[3] - "NOW() BETWEEN StartTime AND EndTime,"// row[4] - "UsrCod," // row[5] - "Title" // row[6] + "SELECT MchCod," // row[ 0] + "GamCod," // row[ 1] + "UsrCod," // row[ 2] + "UNIX_TIMESTAMP(StartTime)," // row[ 3] + "UNIX_TIMESTAMP(EndTime)," // row[ 4] + "Title," // row[ 5] + "QstInd," // row[ 6] + "QstCod," // row[ 7] + "UNIX_TIMESTAMP(QstStartTime)," // row[ 8] + "ShowingAnswers," // row[ 9] + "Finished" // row[10] " FROM gam_matches" " WHERE %s" " ORDER BY MchCod", @@ -2971,13 +2966,17 @@ void Gam_GetDataOfMatchByCod (struct Match *Match) /***** Get data of match from database *****/ NumRows = (unsigned) DB_QuerySELECT (&mysql_res,"can not get matches", - "SELECT MchCod," // row[0] - "GamCod," // row[1] - "UNIX_TIMESTAMP(StartTime)," // row[2] - "UNIX_TIMESTAMP(EndTime)," // row[3] - "NOW() BETWEEN StartTime AND EndTime," // row[4] - "UsrCod," // row[5] - "Title" // row[6] + "SELECT MchCod," // row[ 0] + "GamCod," // row[ 1] + "UsrCod," // row[ 2] + "UNIX_TIMESTAMP(StartTime)," // row[ 3] + "UNIX_TIMESTAMP(EndTime)," // row[ 4] + "Title," // row[ 5] + "QstInd," // row[ 6] + "QstCod," // row[ 7] + "UNIX_TIMESTAMP(QstStartTime)," // row[ 8] + "ShowingAnswers," // row[ 9] + "Finished" // row[10] " FROM gam_matches" " WHERE MchCod=%ld" " AND GamCod IN" // Extra check @@ -2996,8 +2995,12 @@ void Gam_GetDataOfMatchByCod (struct Match *Match) Match->UsrCod = -1L; Match->TimeUTC[Gam_START_TIME] = Match->TimeUTC[Gam_END_TIME ] = (time_t) 0; - Match->Open = false; Match->Title[0] = '\0'; + Match->Status.QstInd = -1; + Match->Status.QstCod = -1L; + Match->Status.QstStartTimeUTC = (time_t) 0; + Match->Status.ShowAnswers = false; + Match->Status.Finished = false; } /***** Free structure that stores the query result *****/ @@ -3028,6 +3031,7 @@ static void Gam_ListOneOrMoreMatchesForEdition (unsigned NumMatches, extern const char *Txt_ROLES_SINGUL_Abc[Rol_NUM_ROLES][Usr_NUM_SEXS]; extern const char *Txt_START_END_TIME[Dat_NUM_START_END_TIME]; extern const char *Txt_Match; + extern const char *Txt_Continue; extern const char *Txt_Today; unsigned NumMatch; unsigned UniqueId; @@ -3037,19 +3041,19 @@ static void Gam_ListOneOrMoreMatchesForEdition (unsigned NumMatches, Tbl_StartTableWideMargin (2); fprintf (Gbl.F.Out,"" "" - "" + "" "%s" "" - "" + "" "%s" "" - "" + "" "%s" "" - "" + "" "%s" "" - "" + "" "%s" "" "", @@ -3079,6 +3083,16 @@ static void Gam_ListOneOrMoreMatchesForEdition (unsigned NumMatches, Ico_PutIconRemove (); Frm_EndForm (); + /* Put icon to continue playing the match */ + if (!Match.Status.Finished) + { + Gam_CurrentMchCod = Match.MchCod; + Lay_PutContextualLinkOnlyIcon (ActGamTchNxtQst,NULL, // TODO: Continue on a new tab!!!! + Gam_PutParamCurrentMchCod, + "play.svg", + Txt_Continue); + } + fprintf (Gbl.F.Out,""); /***** Number of match ******/ @@ -3098,8 +3112,8 @@ static void Gam_ListOneOrMoreMatchesForEdition (unsigned NumMatches, fprintf (Gbl.F.Out,"", UniqueId, - Match.Open ? "DATE_GREEN" : - "DATE_RED", + Match.Status.Finished ? "DATE_RED" : + "DATE_GREEN", Gbl.RowEvenOdd); fprintf (Gbl.F.Out,"