diff --git a/swad_API.c b/swad_API.c index f150f6e8..7e944d64 100644 --- a/swad_API.c +++ b/swad_API.c @@ -109,6 +109,7 @@ cp -f /home/acanas/swad/swad/swad /var/www/cgi-bin/ #include "swad_browser_database.h" #include "swad_course_database.h" #include "swad_database.h" +#include "swad_enrolment_database.h" #include "swad_error.h" #include "swad_forum.h" #include "swad_global.h" @@ -843,7 +844,6 @@ int swad__loginBySessionKey (struct soap *soap, int ReturnCode; MYSQL_RES *mysql_res; MYSQL_ROW row; - unsigned NumRows; char PhotoURL[Cns_MAX_BYTES_WWW + 1]; bool UsrFound; @@ -895,15 +895,7 @@ int swad__loginBySessionKey (struct soap *soap, // Now, we know that sessionID is a valid session identifier /***** Query data of the session from database *****/ - NumRows = (unsigned) - DB_QuerySELECT (&mysql_res,"can not get session data", - "SELECT UsrCod," // row[0] - "DegCod," // row[1] - "CrsCod" // row[2] - " FROM ses_sessions" - " WHERE SessionId='%s'", - sessionID); - if (NumRows == 1) // Session found in table of sessions + if (Ses_DB_GetSomeSessionData (&mysql_res,sessionID)) // Session found in table of sessions { row = mysql_fetch_row (mysql_res); @@ -1052,20 +1044,11 @@ int swad__getNewPassword (struct soap *soap, Str_RemoveLeadingArrobas (UsrIDNickOrEmail); /* User has typed a nickname */ - Gbl.Usrs.Me.UsrDat.UsrCod = DB_QuerySELECTCode ("can not get user's data", - "SELECT UsrCod" - " FROM usr_nicknames" - " WHERE Nickname='%s'", - UsrIDNickOrEmail); + Gbl.Usrs.Me.UsrDat.UsrCod = Usr_DB_GetUsrCodFromNick (UsrIDNickOrEmail); } else if (Mai_CheckIfEmailIsValid (Gbl.Usrs.Me.UsrIdLogin)) // 2: It's an email /* User has typed an email */ - // TODO: Get only if email confirmed? - Gbl.Usrs.Me.UsrDat.UsrCod = DB_QuerySELECTCode ("can not get user's data", - "SELECT UsrCod" - " FROM usr_emails" - " WHERE E_mail='%s'", - UsrIDNickOrEmail); + Gbl.Usrs.Me.UsrDat.UsrCod = Usr_DB_GetUsrCodFromEmail (UsrIDNickOrEmail); else // 3: It's not a nickname nor email { // Users' IDs are always stored internally in capitals and without leading zeros @@ -1073,12 +1056,7 @@ int swad__getNewPassword (struct soap *soap, Str_ConvertToUpperText (UsrIDNickOrEmail); if (ID_CheckIfUsrIDIsValid (UsrIDNickOrEmail)) /* User has typed a valid user's ID (existing or not) */ - // TODO: Get only if ID confirmed? - Gbl.Usrs.Me.UsrDat.UsrCod = DB_QuerySELECTCode ("can not get user's data", - "SELECT UsrCod" - " FROM usr_ids" - " WHERE UsrID='%s'", - UsrIDNickOrEmail); + Gbl.Usrs.Me.UsrDat.UsrCod = Usr_DB_GetUsrCodFromID (UsrIDNickOrEmail); else // String is not a valid user's nickname, email or ID return soap_receiver_fault (soap, "Bad log in", @@ -1114,8 +1092,8 @@ int swad__getCourses (struct soap *soap, int ReturnCode; MYSQL_RES *mysql_res; MYSQL_ROW row; - unsigned NumRow; - unsigned NumRows; + unsigned NumCrs; + unsigned NumCrss; Rol_Role_t Role; /***** Initializations *****/ @@ -1139,23 +1117,12 @@ int swad__getCourses (struct soap *soap, Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs; /***** Query my courses from database *****/ - NumRows = (unsigned) - DB_QuerySELECT (&mysql_res,"can not get user's courses", - "SELECT crs_courses.CrsCod," // row[0] - "crs_courses.ShortName," // row[1] - "crs_courses.FullName," // row[2] - "crs_users.Role" // row[3] - " FROM crs_users," - "crs_courses" - " WHERE crs_users.UsrCod=%ld" - " AND crs_users.CrsCod=crs_courses.CrsCod" - " ORDER BY crs_courses.FullName", - Gbl.Usrs.Me.UsrDat.UsrCod); + NumCrss = Enr_DB_GetMyCoursesNames (&mysql_res); - getCoursesOut->numCourses = (int) NumRows; - getCoursesOut->coursesArray.__size = (int) NumRows; + getCoursesOut->numCourses = + getCoursesOut->coursesArray.__size = (int) NumCrss; - if (NumRows == 0) + if (NumCrss == 0) getCoursesOut->coursesArray.__ptr = NULL; else // Courses found { @@ -1163,32 +1130,31 @@ int swad__getCourses (struct soap *soap, (getCoursesOut->coursesArray.__size) * sizeof (*(getCoursesOut->coursesArray.__ptr))); - for (NumRow = 0; - NumRow < NumRows; - NumRow++) + for (NumCrs = 0; + NumCrs < NumCrss; + NumCrs++) { /* Get next course */ row = mysql_fetch_row (mysql_res); /* Get course code (row[0]) */ - getCoursesOut->coursesArray.__ptr[NumRow].courseCode = (int) Str_ConvertStrCodToLongCod (row[0]); + getCoursesOut->coursesArray.__ptr[NumCrs].courseCode = (int) Str_ConvertStrCodToLongCod (row[0]); - /* Get course short name (row[1]) */ - getCoursesOut->coursesArray.__ptr[NumRow].courseShortName = + /* Get course short name (row[1]) + and course full name (row[2]) */ + getCoursesOut->coursesArray.__ptr[NumCrs].courseShortName = soap_malloc (soap,Cns_HIERARCHY_MAX_BYTES_SHRT_NAME + 1); - Str_Copy (getCoursesOut->coursesArray.__ptr[NumRow].courseShortName, - row[1],Cns_HIERARCHY_MAX_BYTES_SHRT_NAME); - - /* Get course full name (row[2]) */ - getCoursesOut->coursesArray.__ptr[NumRow].courseFullName = + getCoursesOut->coursesArray.__ptr[NumCrs].courseFullName = soap_malloc (soap,Cns_HIERARCHY_MAX_BYTES_FULL_NAME + 1); - Str_Copy (getCoursesOut->coursesArray.__ptr[NumRow].courseFullName, + Str_Copy (getCoursesOut->coursesArray.__ptr[NumCrs].courseShortName, + row[1],Cns_HIERARCHY_MAX_BYTES_SHRT_NAME); + Str_Copy (getCoursesOut->coursesArray.__ptr[NumCrs].courseFullName, row[2],Cns_HIERARCHY_MAX_BYTES_FULL_NAME); /* Get role (row[3]) */ if (sscanf (row[3],"%u",&Role) != 1) // Role in this course Role = Rol_UNK; - getCoursesOut->coursesArray.__ptr[NumRow].userRole = API_RolRole_to_SvcRole[Role]; + getCoursesOut->coursesArray.__ptr[NumCrs].userRole = API_RolRole_to_SvcRole[Role]; } } @@ -1629,7 +1595,7 @@ int swad__getUsers (struct soap *soap, API_GetLstGrpsSel (groups); if (Gbl.Crs.Grps.LstGrpsSel.NumGrps) /***** Get list of groups types and groups in current course *****/ - Grp_GetListGrpTypesInThisCrs (Grp_ONLY_GROUP_TYPES_WITH_GROUPS); + Grp_GetListGrpTypesInCurrentCrs (Grp_ONLY_GROUP_TYPES_WITH_GROUPS); /***** Get list of users *****/ Usr_GetListUsrs (HieLvl_CRS,Role); @@ -1817,8 +1783,8 @@ int swad__getGroupTypes (struct soap *soap, int ReturnCode; MYSQL_RES *mysql_res; MYSQL_ROW row; - unsigned NumRow; - unsigned NumRows; + unsigned NumGrpTyp; + unsigned NumGrpTypes; long OpenTime; /***** Initializations *****/ @@ -1864,22 +1830,12 @@ int swad__getGroupTypes (struct soap *soap, "Requester must belong to course"); /***** Query group types in a course from database *****/ - NumRows = (unsigned) - DB_QuerySELECT (&mysql_res,"can not get group types", - "SELECT GrpTypCod," // row[0] - "GrpTypName," // row[1] - "Mandatory," // row[2] - "Multiple," // row[3] - "UNIX_TIMESTAMP(OpenTime)" // row[4] - " FROM grp_types" - " WHERE CrsCod=%d" - " ORDER BY GrpTypName", - courseCode); + NumGrpTypes = Grp_DB_GetAllGrpTypesInCrs (&mysql_res,courseCode); - getGroupTypesOut->numGroupTypes = (int) NumRows; - getGroupTypesOut->groupTypesArray.__size = (int) NumRows; + getGroupTypesOut->numGroupTypes = (int) NumGrpTypes; + getGroupTypesOut->groupTypesArray.__size = (int) NumGrpTypes; - if (NumRows == 0) + if (NumGrpTypes == 0) getGroupTypesOut->groupTypesArray.__ptr = NULL; else // Groups found { @@ -1887,35 +1843,39 @@ int swad__getGroupTypes (struct soap *soap, (getGroupTypesOut->groupTypesArray.__size) * sizeof (*(getGroupTypesOut->groupTypesArray.__ptr))); - for (NumRow = 0; - NumRow < NumRows; - NumRow++) + for (NumGrpTyp = 0; + NumGrpTyp < NumGrpTypes; + NumGrpTyp++) { /* Get next group */ row = mysql_fetch_row (mysql_res); /* Get group type code (row[0]) */ - getGroupTypesOut->groupTypesArray.__ptr[NumRow].groupTypeCode = (int) Str_ConvertStrCodToLongCod (row[0]); + getGroupTypesOut->groupTypesArray.__ptr[NumGrpTyp].groupTypeCode = (int) Str_ConvertStrCodToLongCod (row[0]); /* Get group type name (row[1]) */ - getGroupTypesOut->groupTypesArray.__ptr[NumRow].groupTypeName = + getGroupTypesOut->groupTypesArray.__ptr[NumGrpTyp].groupTypeName = soap_malloc (soap,Grp_MAX_BYTES_GROUP_TYPE_NAME + 1); - Str_Copy (getGroupTypesOut->groupTypesArray.__ptr[NumRow].groupTypeName, + Str_Copy (getGroupTypesOut->groupTypesArray.__ptr[NumGrpTyp].groupTypeName, row[1],Grp_MAX_BYTES_GROUP_TYPE_NAME); /* Get whether enrolment is mandatory ('Y') or voluntary ('N') (row[2]) */ - getGroupTypesOut->groupTypesArray.__ptr[NumRow].mandatory = (row[2][0] == 'Y') ? 1 : + getGroupTypesOut->groupTypesArray.__ptr[NumGrpTyp].mandatory = (row[2][0] == 'Y') ? 1 : 0; /* Get whether user can enrol in multiple groups ('Y') or only in one group ('N') (row[3]) */ - getGroupTypesOut->groupTypesArray.__ptr[NumRow].multiple = (row[3][0] == 'Y') ? 1 : + getGroupTypesOut->groupTypesArray.__ptr[NumGrpTyp].multiple = (row[3][0] == 'Y') ? 1 : 0; - /* Get time of opening (row[4]) */ + // Whether groups of this type must be opened (row[4]) ignored here + + /* Get time of opening (row[5]) */ OpenTime = 0L; - if (row[4]) - sscanf (row[4],"%ld",&OpenTime); - getGroupTypesOut->groupTypesArray.__ptr[NumRow].openTime = OpenTime; + if (row[5]) + sscanf (row[5],"%ld",&OpenTime); + getGroupTypesOut->groupTypesArray.__ptr[NumGrpTyp].openTime = OpenTime; + + // Number of groups of this type (row[6]) ignored here } } @@ -1936,7 +1896,8 @@ int swad__getGroups (struct soap *soap, int ReturnCode; MYSQL_RES *mysql_res; MYSQL_ROW row; - unsigned NumRow,NumRows; + unsigned NumGrps; + unsigned NumGrp; long GrpCod; unsigned MaxStudents; @@ -1983,27 +1944,12 @@ int swad__getGroups (struct soap *soap, "Requester must belong to course"); /***** Query groups in a course from database *****/ - NumRows = (unsigned) - DB_QuerySELECT (&mysql_res,"can not get user's groups", - "SELECT grp_types.GrpTypCod," // row[0] - "grp_types.GrpTypName," // row[1] - "grp_groups.GrpCod," // row[2] - "grp_groups.GrpName," // row[3] - "grp_groups.MaxStudents," // row[4] - "grp_groups.Open, " // row[5] - "grp_groups.FileZones" // row[6] - " FROM grp_types," - "grp_groups" - " WHERE grp_types.CrsCod=%d" - " AND grp_types.GrpTypCod=grp_groups.GrpTypCod" - " ORDER BY grp_types.GrpTypName," - "grp_groups.GrpName", - courseCode); + NumGrps = Grp_DB_GetGrpsInCrs (&mysql_res,courseCode); - getGroupsOut->numGroups = (int) NumRows; - getGroupsOut->groupsArray.__size = (int) NumRows; + getGroupsOut->numGroups = (int) NumGrps; + getGroupsOut->groupsArray.__size = (int) NumGrps; - if (NumRows == 0) + if (NumGrps == 0) getGroupsOut->groupsArray.__ptr = NULL; else // Groups found { @@ -2011,50 +1957,50 @@ int swad__getGroups (struct soap *soap, (getGroupsOut->groupsArray.__size) * sizeof (*(getGroupsOut->groupsArray.__ptr))); - for (NumRow = 0; - NumRow < NumRows; - NumRow++) + for (NumGrp = 0; + NumGrp < NumGrps; + NumGrp++) { /* Get next group */ row = mysql_fetch_row (mysql_res); /* Get group type code (row[0]) */ - getGroupsOut->groupsArray.__ptr[NumRow].groupTypeCode = (int) Str_ConvertStrCodToLongCod (row[0]); + getGroupsOut->groupsArray.__ptr[NumGrp].groupTypeCode = (int) Str_ConvertStrCodToLongCod (row[0]); /* Get group type name (row[1]) */ - getGroupsOut->groupsArray.__ptr[NumRow].groupTypeName = + getGroupsOut->groupsArray.__ptr[NumGrp].groupTypeName = soap_malloc (soap,Grp_MAX_BYTES_GROUP_TYPE_NAME + 1); - Str_Copy (getGroupsOut->groupsArray.__ptr[NumRow].groupTypeName,row[1], + Str_Copy (getGroupsOut->groupsArray.__ptr[NumGrp].groupTypeName,row[1], Grp_MAX_BYTES_GROUP_TYPE_NAME); /* Get group code (row[2]) */ GrpCod = Str_ConvertStrCodToLongCod (row[2]); - getGroupsOut->groupsArray.__ptr[NumRow].groupCode = (int) GrpCod; + getGroupsOut->groupsArray.__ptr[NumGrp].groupCode = (int) GrpCod; /* Get group name (row[3]) */ - getGroupsOut->groupsArray.__ptr[NumRow].groupName = + getGroupsOut->groupsArray.__ptr[NumGrp].groupName = soap_malloc (soap,Grp_MAX_BYTES_GROUP_NAME + 1); - Str_Copy (getGroupsOut->groupsArray.__ptr[NumRow].groupName,row[3], + Str_Copy (getGroupsOut->groupsArray.__ptr[NumGrp].groupName,row[3], Grp_MAX_BYTES_GROUP_NAME); /* Get max number of students of group (row[4]) and number of current students */ MaxStudents = Grp_ConvertToNumMaxStdsGrp (row[4]); - getGroupsOut->groupsArray.__ptr[NumRow].maxStudents = (MaxStudents > Grp_MAX_STUDENTS_IN_A_GROUP) ? -1 : + getGroupsOut->groupsArray.__ptr[NumGrp].maxStudents = (MaxStudents > Grp_MAX_STUDENTS_IN_A_GROUP) ? -1 : (int) MaxStudents; /* Get number of current students */ - getGroupsOut->groupsArray.__ptr[NumRow].numStudents = (int) Grp_DB_CountNumUsrsInGrp (Rol_STD,GrpCod); + getGroupsOut->groupsArray.__ptr[NumGrp].numStudents = (int) Grp_DB_CountNumUsrsInGrp (Rol_STD,GrpCod); /* Get whether group is open ('Y') or closed ('N') (row[5]) */ - getGroupsOut->groupsArray.__ptr[NumRow].open = (row[5][0] == 'Y') ? 1 : + getGroupsOut->groupsArray.__ptr[NumGrp].open = (row[5][0] == 'Y') ? 1 : 0; /* Get whether group have file zones ('Y') or not ('N') (row[6]) */ - getGroupsOut->groupsArray.__ptr[NumRow].fileZones = (row[6][0] == 'Y') ? 1 : + getGroupsOut->groupsArray.__ptr[NumGrp].fileZones = (row[6][0] == 'Y') ? 1 : 0; /* Get whether I belong to this group or not */ - getGroupsOut->groupsArray.__ptr[NumRow].member = Grp_GetIfIBelongToGrp (GrpCod) ? 1 : + getGroupsOut->groupsArray.__ptr[NumGrp].member = Grp_GetIfIBelongToGrp (GrpCod) ? 1 : 0; } } @@ -2077,11 +2023,10 @@ int swad__sendMyGroups (struct soap *soap, struct ListCodGrps LstGrpsIWant; const char *Ptr; char LongStr[Cns_MAX_DECIMAL_DIGITS_LONG + 1]; + unsigned NumGrps; unsigned NumGrp; MYSQL_RES *mysql_res; MYSQL_ROW row; - unsigned NumRow; - unsigned NumRows; long GrpCod; unsigned MaxStudents; @@ -2157,27 +2102,12 @@ int swad__sendMyGroups (struct soap *soap, Grp_FreeListCodGrp (&LstGrpsIWant); /***** Query groups in a course from database *****/ - NumRows = (unsigned) - DB_QuerySELECT (&mysql_res,"can not get user's groups", - "SELECT grp_types.GrpTypCod," // row[0] - "grp_types.GrpTypName," // row[1] - "grp_groups.GrpCod," // row[2] - "grp_groups.GrpName," // row[3] - "grp_groups.MaxStudents," // row[4] - "grp_groups.Open," // row[5] - "grp_groups.FileZones" // row[6] - " FROM grp_types," - "grp_groups" - " WHERE grp_types.CrsCod=%d" - " AND grp_types.GrpTypCod=grp_groups.GrpTypCod" - " ORDER BY grp_types.GrpTypName," - "grp_groups.GrpName", - courseCode); + NumGrps = Grp_DB_GetGrpsInCrs (&mysql_res,courseCode); - SendMyGroupsOut->numGroups = (int) NumRows; - SendMyGroupsOut->groupsArray.__size = (int) NumRows; + SendMyGroupsOut->numGroups = (int) NumGrps; + SendMyGroupsOut->groupsArray.__size = (int) NumGrps; - if (NumRows == 0) + if (NumGrps == 0) SendMyGroupsOut->groupsArray.__ptr = NULL; else // Groups found { @@ -2185,50 +2115,49 @@ int swad__sendMyGroups (struct soap *soap, (SendMyGroupsOut->groupsArray.__size) * sizeof (*(SendMyGroupsOut->groupsArray.__ptr))); - for (NumRow = 0; - NumRow < NumRows; - NumRow++) + for (NumGrp = 0; + NumGrp < NumGrps; + NumGrp++) { /* Get next group */ row = mysql_fetch_row (mysql_res); /* Get group type code (row[0]) */ - SendMyGroupsOut->groupsArray.__ptr[NumRow].groupTypeCode = (int) Str_ConvertStrCodToLongCod (row[0]); + SendMyGroupsOut->groupsArray.__ptr[NumGrp].groupTypeCode = (int) Str_ConvertStrCodToLongCod (row[0]); /* Get group type name (row[1]) */ - SendMyGroupsOut->groupsArray.__ptr[NumRow].groupTypeName = + SendMyGroupsOut->groupsArray.__ptr[NumGrp].groupTypeName = soap_malloc (soap,Grp_MAX_BYTES_GROUP_TYPE_NAME + 1); - Str_Copy (SendMyGroupsOut->groupsArray.__ptr[NumRow].groupTypeName,row[1], + Str_Copy (SendMyGroupsOut->groupsArray.__ptr[NumGrp].groupTypeName,row[1], Grp_MAX_BYTES_GROUP_TYPE_NAME); /* Get group code (row[2]) */ GrpCod = Str_ConvertStrCodToLongCod (row[2]); - SendMyGroupsOut->groupsArray.__ptr[NumRow].groupCode = (int) GrpCod; + SendMyGroupsOut->groupsArray.__ptr[NumGrp].groupCode = (int) GrpCod; /* Get group name (row[3]) */ - SendMyGroupsOut->groupsArray.__ptr[NumRow].groupName = + SendMyGroupsOut->groupsArray.__ptr[NumGrp].groupName = soap_malloc (soap,Grp_MAX_BYTES_GROUP_NAME + 1); - Str_Copy (SendMyGroupsOut->groupsArray.__ptr[NumRow].groupName,row[3], + Str_Copy (SendMyGroupsOut->groupsArray.__ptr[NumGrp].groupName,row[3], Grp_MAX_BYTES_GROUP_NAME); /* Get max number of students of group (row[4]) and number of current students */ MaxStudents = Grp_ConvertToNumMaxStdsGrp (row[4]); - SendMyGroupsOut->groupsArray.__ptr[NumRow].maxStudents = (MaxStudents > Grp_MAX_STUDENTS_IN_A_GROUP) ? -1 : + SendMyGroupsOut->groupsArray.__ptr[NumGrp].maxStudents = (MaxStudents > Grp_MAX_STUDENTS_IN_A_GROUP) ? -1 : (int) MaxStudents; /* Get number of current students */ - SendMyGroupsOut->groupsArray.__ptr[NumRow].numStudents = (int) Grp_DB_CountNumUsrsInGrp (Rol_STD,GrpCod); + SendMyGroupsOut->groupsArray.__ptr[NumGrp].numStudents = (int) Grp_DB_CountNumUsrsInGrp (Rol_STD,GrpCod); - /* Get whether group is open ('Y') or closed ('N') (row[5]) */ - SendMyGroupsOut->groupsArray.__ptr[NumRow].open = (row[5][0] == 'Y') ? 1 : - 0; - - /* Get whether group have file zones ('Y') or not ('N') (row[6]) */ - SendMyGroupsOut->groupsArray.__ptr[NumRow].fileZones = (row[6][0] == 'Y') ? 1 : + /* Get whether group is open ('Y') or closed ('N') (row[5]) + and whether group have file zones ('Y') or not ('N') (row[6]) */ + SendMyGroupsOut->groupsArray.__ptr[NumGrp].open = (row[5][0] == 'Y') ? 1 : + 0; + SendMyGroupsOut->groupsArray.__ptr[NumGrp].fileZones = (row[6][0] == 'Y') ? 1 : 0; /* Get whether I belong to this group or not */ - SendMyGroupsOut->groupsArray.__ptr[NumRow].member = Grp_GetIfIBelongToGrp (GrpCod) ? 1 : + SendMyGroupsOut->groupsArray.__ptr[NumGrp].member = Grp_GetIfIBelongToGrp (GrpCod) ? 1 : 0; } } @@ -2301,8 +2230,8 @@ int swad__getAttendanceEvents (struct soap *soap, int ReturnCode; MYSQL_RES *mysql_res; MYSQL_ROW row; - unsigned NumRows; - int NumAttEvent; + unsigned NumAttEvents; + unsigned NumAttEvent; long AttCod; char PhotoURL[Cns_MAX_BYTES_WWW + 1]; long StartTime; @@ -2343,25 +2272,10 @@ int swad__getAttendanceEvents (struct soap *soap, "Requester must be a teacher"); /***** Query list of attendance events *****/ - NumRows = (unsigned) - DB_QuerySELECT (&mysql_res,"can not get attendance events", - "SELECT AttCod," // row[0] - "Hidden," // row[1] - "UsrCod," // row[2] - "UNIX_TIMESTAMP(StartTime) AS ST," // row[3] - "UNIX_TIMESTAMP(EndTime) AS ET," // row[4] - "CommentTchVisible," // row[5] - "Title," // row[6] - "Txt" // row[7] - " FROM att_events" - " WHERE CrsCod=%d" - " ORDER BY ST DESC," - "ET DESC," - "Title DESC", - courseCode); + NumAttEvents = Att_DB_GetDataOfAllAttEvents (&mysql_res,courseCode); getAttendanceEventsOut->eventsArray.__size = - getAttendanceEventsOut->numEvents = (int) NumRows; + getAttendanceEventsOut->numEvents = (int) NumAttEvents; if (getAttendanceEventsOut->numEvents == 0) getAttendanceEventsOut->eventsArray.__ptr = NULL; @@ -2372,7 +2286,7 @@ int swad__getAttendanceEvents (struct soap *soap, sizeof (*(getAttendanceEventsOut->eventsArray.__ptr))); for (NumAttEvent = 0; - NumAttEvent < getAttendanceEventsOut->numEvents; + NumAttEvent < NumAttEvents; NumAttEvent++) { /* Get next group */ @@ -2481,15 +2395,7 @@ static void API_GetListGrpsInAttendanceEventFromDB (struct soap *soap, size_t Length; /***** Get list of groups *****/ - NumGrps = (unsigned) - DB_QuerySELECT (&mysql_res,"can not get groups of an attendance event", - "SELECT GrpCod" - " FROM att_groups" - " WHERE AttCod=%ld", - AttCod); - if (NumGrps == 0) - *ListGroups = NULL; - else // Events found + if ((NumGrps = Att_DB_GetGrpCodsAssociatedToEvent (&mysql_res,AttCod))) // Events found { Length = NumGrps * (10 + 1) - 1; *ListGroups = soap_malloc (soap,Length + 1); @@ -2507,6 +2413,8 @@ static void API_GetListGrpsInAttendanceEventFromDB (struct soap *soap, Str_Concat (*ListGroups,GrpCodStr,Length); } } + else + *ListGroups = NULL; /***** Free structure that stores the query result *****/ DB_FreeMySQLResult (&mysql_res); diff --git a/swad_API_database.c b/swad_API_database.c index f772f354..c51f4411 100644 --- a/swad_API_database.c +++ b/swad_API_database.c @@ -27,46 +27,10 @@ /********************************* Headers ***********************************/ /*****************************************************************************/ -// #include // For scandir, etc. -// #include // For PATH_MAX -// #include // For NULL -// #include -// #include -// #include // For lstat - -// #include "soap/soapH.h" // gSOAP header -// #include "soap/swad.nsmap" // Namespaces map used - -// #include "swad_account.h" #include "swad_API_database.h" -// #include "swad_attendance_database.h" -// #include "swad_browser.h" -// #include "swad_browser_database.h" #include "swad_config.h" #include "swad_database.h" -// #include "swad_error.h" -// #include "swad_forum.h" // #include "swad_global.h" -// #include "swad_group_database.h" -// #include "swad_hierarchy.h" -// #include "swad_hierarchy_level.h" -// #include "swad_ID.h" -// #include "swad_match.h" -// #include "swad_nickname_database.h" -// #include "swad_notice.h" -// #include "swad_notification.h" -// #include "swad_password.h" -// #include "swad_plugin_database.h" -// #include "swad_question_database.h" -// #include "swad_role.h" -// #include "swad_room_database.h" -// #include "swad_search.h" -// #include "swad_session_database.h" -// #include "swad_test_config.h" -// #include "swad_test_visibility.h" -// #include "swad_user.h" -// #include "swad_user_database.h" -// #include "swad_xml.h" /*****************************************************************************/ /************** External global variables from others modules ****************/ diff --git a/swad_attendance_database.c b/swad_attendance_database.c index 89ac2a70..a136730e 100644 --- a/swad_attendance_database.c +++ b/swad_attendance_database.c @@ -144,6 +144,30 @@ unsigned Att_DB_GetListAttEventsAllGrps (MYSQL_RES **mysql_res, Att_DB_OrderBySubQuery[SelectedOrder][OrderNewestOldest]); } +/*****************************************************************************/ +/********************* Get list of all attendance events *********************/ +/*****************************************************************************/ + +unsigned Att_DB_GetDataOfAllAttEvents (MYSQL_RES **mysql_res,long CrsCod) + { + return (unsigned) + DB_QuerySELECT (mysql_res,"can not get attendance events", + "SELECT AttCod," // row[0] + "Hidden," // row[1] + "UsrCod," // row[2] + "UNIX_TIMESTAMP(StartTime) AS ST," // row[3] + "UNIX_TIMESTAMP(EndTime) AS ET," // row[4] + "CommentTchVisible," // row[5] + "Title," // row[6] + "Txt" // row[7] + " FROM att_events" + " WHERE CrsCod=%d" + " ORDER BY ST DESC," + "ET DESC," + "Title DESC", + CrsCod); + } + /*****************************************************************************/ /**************** Get attendance event data using its code *******************/ /*****************************************************************************/ @@ -299,7 +323,7 @@ unsigned Att_DB_GetGrpCodsAssociatedToEvent (MYSQL_RES **mysql_res,long AttCod) DB_QuerySELECT (mysql_res,"can not get groups of an attendance event", "SELECT GrpCod" // row[0] " FROM att_groups" - " WHERE att_groups.AttCod=%ld", + " WHERE AttCod=%ld", AttCod); } diff --git a/swad_attendance_database.h b/swad_attendance_database.h index 83682104..79aea02c 100644 --- a/swad_attendance_database.h +++ b/swad_attendance_database.h @@ -46,7 +46,7 @@ unsigned Att_DB_GetListAttEventsMyGrps (MYSQL_RES **mysql_res, unsigned Att_DB_GetListAttEventsAllGrps (MYSQL_RES **mysql_res, Dat_StartEndTime_t SelectedOrder, Att_OrderNewestOldest_t OrderNewestOldest); - +unsigned Att_DB_GetDataOfAllAttEvents (MYSQL_RES **mysql_res,long CrsCod); unsigned Att_DB_GetDataOfAttEventByCod (MYSQL_RES **mysql_res,long AttCod); void Att_DB_GetAttEventDescription (long AttCod,char Description[Cns_MAX_BYTES_TEXT + 1]); diff --git a/swad_changelog.h b/swad_changelog.h index b24ae7c7..edb05d77 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -602,13 +602,14 @@ TODO: FIX BUG, URGENT! En las fechas como par TODO: En las encuestas, que los estudiantes no puedan ver los resultados hasta que no finalice el plazo. */ -#define Log_PLATFORM_VERSION "SWAD 21.54.1 (2021-11-08)" +#define Log_PLATFORM_VERSION "SWAD 21.54.2 (2021-11-08)" #define CSS_FILE "swad20.45.css" #define JS_FILE "swad20.69.1.js" /* TODO: Rename CENTRE to CENTER in help wiki. TODO: Rename ASSESSMENT.Announcements to ASSESSMENT.Calls_for_exams + Version 21.54.2: Nov 08, 2021 Queries moved to module swad_user_database and other modules. (322054 lines) Version 21.54.1: Nov 08, 2021 Queries moved to module swad_user_database. (322060 lines) Version 21.54: Nov 07, 2021 New module swad_API_database for database queries related to API. (322001 lines) Version 21.53.1: Nov 07, 2021 Queries moved to module swad_room_database. (321879 lines) diff --git a/swad_enrolment_database.c b/swad_enrolment_database.c index 21e3752c..3c5a2880 100644 --- a/swad_enrolment_database.c +++ b/swad_enrolment_database.c @@ -142,6 +142,26 @@ void Enr_DB_DropTmpTableMyCourses (void) "DROP TEMPORARY TABLE IF EXISTS my_courses_tmp"); } +/*****************************************************************************/ +/************************* Get my courses from database **********************/ +/*****************************************************************************/ + +unsigned Enr_DB_GetMyCoursesNames (MYSQL_RES **mysql_res) + { + return (unsigned) + DB_QuerySELECT (mysql_res,"can not get user's courses", + "SELECT crs_courses.CrsCod," // row[0] + "crs_courses.ShortName," // row[1] + "crs_courses.FullName," // row[2] + "crs_users.Role" // row[3] + " FROM crs_users," + "crs_courses" + " WHERE crs_users.UsrCod=%ld" + " AND crs_users.CrsCod=crs_courses.CrsCod" + " ORDER BY crs_courses.FullName", + Gbl.Usrs.Me.UsrDat.UsrCod); + } + /*****************************************************************************/ /******************** Check if a user belongs to a course ********************/ /*****************************************************************************/ diff --git a/swad_enrolment_database.h b/swad_enrolment_database.h index 6def49a2..24b59dde 100644 --- a/swad_enrolment_database.h +++ b/swad_enrolment_database.h @@ -50,6 +50,7 @@ void Enr_DB_AcceptUsrInCrs (long UsrCod,long CrsCod); void Enr_DB_CreateTmpTableMyCourses (void); unsigned Enr_DB_GetMyCourses (MYSQL_RES **mysql_res); void Enr_DB_DropTmpTableMyCourses (void); +unsigned Enr_DB_GetMyCoursesNames (MYSQL_RES **mysql_res); bool Enr_DB_CheckIfUsrBelongsToCrs (long UsrCod,long CrsCod, bool CountOnlyAcceptedCourses); diff --git a/swad_group.c b/swad_group.c index a37ffb54..2044d0ae 100644 --- a/swad_group.c +++ b/swad_group.c @@ -2644,15 +2644,15 @@ static void Grp_PutFormToCreateGroup (const struct Roo_Rooms *Rooms) /*********** Create a list with current group types in this course ***********/ /*****************************************************************************/ -void Grp_GetListGrpTypesInThisCrs (Grp_WhichGroupTypes_t WhichGroupTypes) +void Grp_GetListGrpTypesInCurrentCrs (Grp_WhichGroupTypes_t WhichGroupTypes) { MYSQL_RES *mysql_res; MYSQL_ROW row; unsigned long NumGrpTyp; - static unsigned (*Grp_DB_GetGrpTypesInCurrentCrs[Grp_NUM_WHICH_GROUP_TYPES]) (MYSQL_RES **mysql_res) = + static unsigned (*Grp_DB_GetGrpTypesInCurrentCrs[Grp_NUM_WHICH_GROUP_TYPES]) (MYSQL_RES **mysql_res,long CrsCod) = { - [Grp_ONLY_GROUP_TYPES_WITH_GROUPS] = Grp_DB_GetGrpTypesWithGrpsInCurrentCrs, - [Grp_ALL_GROUP_TYPES ] = Grp_DB_GetAllGrpTypesInCurrentCrs, + [Grp_ONLY_GROUP_TYPES_WITH_GROUPS] = Grp_DB_GetGrpTypesWithGrpsInCrs, + [Grp_ALL_GROUP_TYPES ] = Grp_DB_GetAllGrpTypesInCrs, }; if (++Gbl.Crs.Grps.GrpTypes.NestedCalls > 1) // If list is created yet, there's nothing to do @@ -2663,7 +2663,7 @@ void Grp_GetListGrpTypesInThisCrs (Grp_WhichGroupTypes_t WhichGroupTypes) Grp_OpenGroupsAutomatically (); /***** Get group types from database *****/ - Gbl.Crs.Grps.GrpTypes.NumGrpTypes = Grp_DB_GetGrpTypesInCurrentCrs[WhichGroupTypes] (&mysql_res); + Gbl.Crs.Grps.GrpTypes.NumGrpTypes = Grp_DB_GetGrpTypesInCurrentCrs[WhichGroupTypes] (&mysql_res,Gbl.Hierarchy.Crs.CrsCod); /***** Get group types *****/ Gbl.Crs.Grps.GrpTypes.NumGrpsTotal = 0; @@ -2768,7 +2768,7 @@ void Grp_GetListGrpTypesAndGrpsInThisCrs (Grp_WhichGroupTypes_t WhichGroupTypes) Rol_Role_t Role; /***** First we get the list of group types *****/ - Grp_GetListGrpTypesInThisCrs (WhichGroupTypes); + Grp_GetListGrpTypesInCurrentCrs (WhichGroupTypes); /***** Then we get the list of groups for each group type *****/ for (NumGrpTyp = 0; diff --git a/swad_group.h b/swad_group.h index 04676ced..178ed9bb 100644 --- a/swad_group.h +++ b/swad_group.h @@ -189,7 +189,7 @@ void Grp_ReqRegisterInGrps (void); void Grp_ShowLstGrpsToChgMyGrps (void); void Grp_ShowLstGrpsToChgOtherUsrsGrps (long UsrCod); -void Grp_GetListGrpTypesInThisCrs (Grp_WhichGroupTypes_t WhichGroupTypes); +void Grp_GetListGrpTypesInCurrentCrs (Grp_WhichGroupTypes_t WhichGroupTypes); void Grp_FreeListGrpTypesAndGrps (void); void Grp_OpenGroupsAutomatically (void); void Grp_GetListGrpTypesAndGrpsInThisCrs (Grp_WhichGroupTypes_t WhichGroupTypes); diff --git a/swad_group_database.c b/swad_group_database.c index f8a7b8d0..dedce43b 100644 --- a/swad_group_database.c +++ b/swad_group_database.c @@ -434,10 +434,10 @@ bool Grp_DB_CheckIfUsrSharesAnyOfMyGrpsInCurrentCrs (long UsrCod) } /*****************************************************************************/ -/************** Get group types with groups in current course ****************/ +/***************** Get group types with groups in a course *******************/ /*****************************************************************************/ -unsigned Grp_DB_GetGrpTypesWithGrpsInCurrentCrs (MYSQL_RES **mysql_res) +unsigned Grp_DB_GetGrpTypesWithGrpsInCrs (MYSQL_RES **mysql_res,long CrsCod) { return (unsigned) DB_QuerySELECT (mysql_res,"can not get types of group of a course", @@ -454,14 +454,14 @@ unsigned Grp_DB_GetGrpTypesWithGrpsInCurrentCrs (MYSQL_RES **mysql_res) " AND grp_types.GrpTypCod=grp_groups.GrpTypCod" " GROUP BY grp_types.GrpTypCod" " ORDER BY grp_types.GrpTypName", - Gbl.Hierarchy.Crs.CrsCod); + CrsCod); } /*****************************************************************************/ -/********** Get group types with or without groups in current course *********/ +/************ Get group types with or without groups in a course *************/ /*****************************************************************************/ -unsigned Grp_DB_GetAllGrpTypesInCurrentCrs (MYSQL_RES **mysql_res) +unsigned Grp_DB_GetAllGrpTypesInCrs (MYSQL_RES **mysql_res,long CrsCod) { // The tables in the second part of the UNION requires ALIAS in order to LOCK TABLES when registering in groups return (unsigned) @@ -492,8 +492,8 @@ unsigned Grp_DB_GetAllGrpTypesInCurrentCrs (MYSQL_RES **mysql_res) " (SELECT GrpTypCod" " FROM grp_groups))" " ORDER BY GrpTypName", - Gbl.Hierarchy.Crs.CrsCod, - Gbl.Hierarchy.Crs.CrsCod); + CrsCod, + CrsCod); } /*****************************************************************************/ @@ -544,13 +544,36 @@ unsigned Grp_DB_CountNumGrpsInThisCrsOfType (long GrpTypCod) GrpTypCod); } +/*****************************************************************************/ +/******************** Get groups in a course ********************/ +/*****************************************************************************/ + +unsigned Grp_DB_GetGrpsInCrs (MYSQL_RES **mysql_res,long CrsCod) + { + return (unsigned) + DB_QuerySELECT (mysql_res,"can not get user's groups", + "SELECT grp_types.GrpTypCod," // row[0] + "grp_types.GrpTypName," // row[1] + "grp_groups.GrpCod," // row[2] + "grp_groups.GrpName," // row[3] + "grp_groups.MaxStudents," // row[4] + "grp_groups.Open, " // row[5] + "grp_groups.FileZones" // row[6] + " FROM grp_types," + "grp_groups" + " WHERE grp_types.CrsCod=%d" + " AND grp_types.GrpTypCod=grp_groups.GrpTypCod" + " ORDER BY grp_types.GrpTypName," + "grp_groups.GrpName", + CrsCod); + } + /*****************************************************************************/ /******************** Get groups of a type in this course ********************/ /*****************************************************************************/ unsigned Grp_DB_GetGrpsOfType (MYSQL_RES **mysql_res,long GrpTypCod) { - /***** Get groups of a type from database *****/ // Don't use INNER JOIN because there are groups without assigned room return (unsigned) DB_QuerySELECT (mysql_res,"can not get groups of a type", diff --git a/swad_group_database.h b/swad_group_database.h index 67f73409..7568376b 100644 --- a/swad_group_database.h +++ b/swad_group_database.h @@ -67,13 +67,14 @@ bool Grp_DB_CheckIfIBelongToGrpsOfType (long GrpTypCod); bool Grp_DB_CheckIfIBelongToGrp (long GrpCod); bool Grp_DB_CheckIfUsrSharesAnyOfMyGrpsInCurrentCrs (long UsrCod); -unsigned Grp_DB_GetGrpTypesWithGrpsInCurrentCrs (MYSQL_RES **mysql_res); -unsigned Grp_DB_GetAllGrpTypesInCurrentCrs (MYSQL_RES **mysql_res); +unsigned Grp_DB_GetGrpTypesWithGrpsInCrs (MYSQL_RES **mysql_res,long CrsCod); +unsigned Grp_DB_GetAllGrpTypesInCrs (MYSQL_RES **mysql_res,long CrsCod); unsigned Grp_DB_GetGrpTypesInCurrentCrsToBeOpened (MYSQL_RES **mysql_res); unsigned Grp_DB_CountNumGrpsInCurrentCrs (void); unsigned Grp_DB_CountNumGrpsInThisCrsOfType (long GrpTypCod); +unsigned Grp_DB_GetGrpsInCrs (MYSQL_RES **mysql_res,long CrsCod); unsigned Grp_DB_GetGrpsOfType (MYSQL_RES **mysql_res,long GrpTypCod); unsigned Grp_DB_GetLstCodGrpsInAllCrssUsrBelongs (MYSQL_RES **mysql_res,long UsrCod); diff --git a/swad_session_database.c b/swad_session_database.c index c44987f5..b0a46682 100644 --- a/swad_session_database.c +++ b/swad_session_database.c @@ -171,7 +171,7 @@ bool Ses_DB_CheckIfSessionExists (const char *IdSes) unsigned Ses_DB_GetSessionData (MYSQL_RES **mysql_res) { return (unsigned) - DB_QuerySELECT (mysql_res,"can not get data of session", + DB_QuerySELECT (mysql_res,"can not get session data", "SELECT UsrCod," // row[0] "Password," // row[1] "Role," // row[2] @@ -187,6 +187,22 @@ unsigned Ses_DB_GetSessionData (MYSQL_RES **mysql_res) Gbl.Session.Id); } +/*****************************************************************************/ +/************************* Get some data of a session ************************/ +/*****************************************************************************/ + +unsigned Ses_DB_GetSomeSessionData (MYSQL_RES **mysql_res,const char *SessionId) + { + return (unsigned) + DB_QuerySELECT (mysql_res,"can not get session data", + "SELECT UsrCod," // row[0] + "DegCod," // row[1] + "CrsCod" // row[2] + " FROM ses_sessions" + " WHERE SessionId='%s'", + SessionId); + } + /*****************************************************************************/ /********* Get last page of received/sent messages stored in session *********/ /*****************************************************************************/ diff --git a/swad_session_database.h b/swad_session_database.h index 0f5195e6..b6a4ac40 100644 --- a/swad_session_database.h +++ b/swad_session_database.h @@ -45,6 +45,7 @@ void Ses_DB_UpdateSessionLastRefresh (void); bool Ses_DB_CheckIfSessionExists (const char *IdSes); unsigned Ses_DB_GetSessionData (MYSQL_RES **mysql_res); +unsigned Ses_DB_GetSomeSessionData (MYSQL_RES **mysql_res,const char *SessionId); unsigned Ses_DB_GetLastPageMsgFromSession (Pag_WhatPaginate_t WhatPaginate); void Ses_DB_RemoveExpiredSessions (void); diff --git a/swad_user.c b/swad_user.c index 9d991206..170c4ecf 100644 --- a/swad_user.c +++ b/swad_user.c @@ -4369,7 +4369,7 @@ void Usr_ListAllDataStds (void) { /* Get list of groups types and groups in current course This is necessary to show columns with group selection */ - Grp_GetListGrpTypesInThisCrs (Grp_ONLY_GROUP_TYPES_WITH_GROUPS); + Grp_GetListGrpTypesInCurrentCrs (Grp_ONLY_GROUP_TYPES_WITH_GROUPS); /* Get groups to show */ Grp_GetParCodsSeveralGrpsToShowUsrs (); diff --git a/swad_user_database.c b/swad_user_database.c index 75cbffdd..1453be49 100644 --- a/swad_user_database.c +++ b/swad_user_database.c @@ -119,6 +119,20 @@ long Usr_DB_GetUsrCodFromEncryptedUsrCod (const char EncryptedUsrCod[Cry_BYTES_E EncryptedUsrCod); } +/*****************************************************************************/ +/***************** Get user's code from database using nickname **************/ +/*****************************************************************************/ + +long Usr_DB_GetUsrCodFromNick (const char *NickWithoutArr) + { + return + DB_QuerySELECTCode ("can not get user's code", + "SELECT UsrCod" + " FROM usr_nicknames" + " WHERE Nickname='%s'", + NickWithoutArr); + } + /*****************************************************************************/ /******** Get user's code from database using nickname and password **********/ /*****************************************************************************/ @@ -137,6 +151,20 @@ long Usr_DB_GetUsrCodFromNickPwd (const char *NickWithoutArr,const char *Passwor Password); } +/*****************************************************************************/ +/**************** Get user's code from database using email ******************/ +/*****************************************************************************/ + +long Usr_DB_GetUsrCodFromEmail (const char *Email) + { + return + DB_QuerySELECTCode ("can not get user's code", + "SELECT UsrCod" + " FROM usr_emails" + " WHERE E_mail='%s'", // TODO: Get only if email confirmed? + Email); + } + /*****************************************************************************/ /********** Get user's code from database using email and password ***********/ /*****************************************************************************/ @@ -146,7 +174,8 @@ long Usr_DB_GetUsrCodFromEmailPwd (const char *Email,const char *Password) return DB_QuerySELECTCode ("can not get user's code", "SELECT usr_emails.UsrCod" - " FROM usr_emails,usr_data" + " FROM usr_emails," + "usr_data" " WHERE usr_emails.E_mail='%s'" // TODO: Get only if email confirmed? " AND usr_emails.UsrCod=usr_data.UsrCod" " AND usr_data.Password='%s'", @@ -154,6 +183,20 @@ long Usr_DB_GetUsrCodFromEmailPwd (const char *Email,const char *Password) Password); } +/*****************************************************************************/ +/**************** Get user's code from database using ID *********************/ +/*****************************************************************************/ + +long Usr_DB_GetUsrCodFromID (const char *ID) + { + return + DB_QuerySELECTCode ("can not get user's code", + "SELECT UsrCod" + " FROM usr_ids" + " WHERE UsrID='%s'", // TODO: Get only if ID confirmed? + ID); + } + /*****************************************************************************/ /*********** Get user's code from database using ID and password *************/ /*****************************************************************************/ @@ -528,7 +571,7 @@ void Usr_DB_BuildQueryToGetUsrsLstCrs (char **Query,Rol_Role_t Role) if (!Gbl.Usrs.ClassPhoto.AllGroups) { /***** Get list of groups types in current course *****/ - Grp_GetListGrpTypesInThisCrs (Grp_ONLY_GROUP_TYPES_WITH_GROUPS); + Grp_GetListGrpTypesInCurrentCrs (Grp_ONLY_GROUP_TYPES_WITH_GROUPS); /***** Allocate memory for list of booleans AddStdsWithoutGroupOf *****/ if ((AddStdsWithoutGroupOf = calloc (Gbl.Crs.Grps.GrpTypes.NumGrpTypes, diff --git a/swad_user_database.h b/swad_user_database.h index dfbee9d3..ce5e55dd 100644 --- a/swad_user_database.h +++ b/swad_user_database.h @@ -52,8 +52,11 @@ void Usr_DB_UpdateMyOfficePhone (void); bool Usr_DB_ChkIfUsrCodExists (long UsrCod); long Usr_DB_GetUsrCodFromEncryptedUsrCod (const char EncryptedUsrCod[Cry_BYTES_ENCRYPTED_STR_SHA256_BASE64 + 1]); +long Usr_DB_GetUsrCodFromNick (const char *NickWithoutArr); long Usr_DB_GetUsrCodFromNickPwd (const char *NickWithoutArr,const char *Password); +long Usr_DB_GetUsrCodFromEmail (const char *Email); long Usr_DB_GetUsrCodFromEmailPwd (const char *Email,const char *Password); +long Usr_DB_GetUsrCodFromID (const char *ID); long Usr_DB_GetUsrCodFromIDPwd (const char *ID,const char *Password); unsigned Usr_DB_GetUsrDataFromUsrCod (MYSQL_RES **mysql_res,long UsrCod, Usr_GetPrefs_t GetPrefs);