Version 16.44

This commit is contained in:
Antonio Cañas Vargas 2016-10-27 01:30:14 +02:00
parent fc2906daa4
commit 638703d9e8
8 changed files with 545 additions and 234 deletions

View File

@ -145,17 +145,20 @@
// TODO: Writing a message to several recipients: include message to indicate that list of nicknames must be comma separated // TODO: Writing a message to several recipients: include message to indicate that list of nicknames must be comma separated
// TODO: When requesting inscription, I can not click in the photo of my record. Change the form? // TODO: When requesting inscription, I can not click in the photo of my record. Change the form?
// TODO: Cuando se crea una cuenta nueva, debería ponerse a 0 las estadísticas del perfil del usuario
/*****************************************************************************/ /*****************************************************************************/
/****************************** Public constants *****************************/ /****************************** Public constants *****************************/
/*****************************************************************************/ /*****************************************************************************/
#define Log_PLATFORM_VERSION "SWAD 16.43 (2016-10-26)" #define Log_PLATFORM_VERSION "SWAD 16.44 (2016-10-27)"
#define CSS_FILE "swad16.32.1.css" #define CSS_FILE "swad16.32.1.css"
#define JS_FILE "swad15.238.1.js" #define JS_FILE "swad15.238.1.js"
// Number of lines (includes comments but not blank lines) has been got with the following command: // 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 // nl swad*.c swad*.h css/swad*.css py/swad*.py js/swad*.js soap/swad*.h sql/swad*.sql | tail -1
/* /*
Version 16.44: Oct 27, 2016 New scopes (centre, institution, country) of surveys. Not finished. (205826 lines)
Version 16.43: Oct 26, 2016 Fixed bugs and code refactoring in scope of surveys. (205537 lines) Version 16.43: Oct 26, 2016 Fixed bugs and code refactoring in scope of surveys. (205537 lines)
Version 16.42.1: Oct 25, 2016 Added button "New question" in survey when the survey has no questions. Version 16.42.1: Oct 25, 2016 Added button "New question" in survey when the survey has no questions.
Change in layout of survey questions. (205485 lines) Change in layout of survey questions. (205485 lines)

View File

@ -41,6 +41,8 @@
#define Cty_MAX_LENGTH_COUNTRY_WWW 255 #define Cty_MAX_LENGTH_COUNTRY_WWW 255
#define Cty_MAX_LENGTH_MAP_ATTRIBUTION (4*1024) #define Cty_MAX_LENGTH_MAP_ATTRIBUTION (4*1024)
#define Cty_MAX_COUNTRIES_PER_USR 10 // Used in list of my countries
struct Country struct Country
{ {
long CtyCod; long CtyCod;

View File

@ -301,6 +301,16 @@ struct Globals
char PhotoURL[PATH_MAX+1]; char PhotoURL[PATH_MAX+1];
time_t TimeLastAccToThisFileBrowser; time_t TimeLastAccToThisFileBrowser;
bool ConfirmEmailJustSent; // An e-mail to confirm my e-mail address has just been sent bool ConfirmEmailJustSent; // An e-mail to confirm my e-mail address has just been sent
struct
{
bool Filled; // My institutions are already filled?
unsigned Num;
struct
{
long CtyCod;
Rol_Role_t MaxRole;
} Ctys[Cty_MAX_COUNTRIES_PER_USR];
} MyCountries;
struct struct
{ {
bool Filled; // My institutions are already filled? bool Filled; // My institutions are already filled?

View File

@ -41,13 +41,13 @@
#define Sco_NUM_SCOPES 7 #define Sco_NUM_SCOPES 7
typedef enum typedef enum
{ {
Sco_SCOPE_UNK, // Unknown Sco_SCOPE_UNK = 0, // Unknown
Sco_SCOPE_SYS, // System Sco_SCOPE_SYS = 1, // System
Sco_SCOPE_CTY, // Country Sco_SCOPE_CTY = 2, // Country
Sco_SCOPE_INS, // Institution Sco_SCOPE_INS = 3, // Institution
Sco_SCOPE_CTR, // Centre Sco_SCOPE_CTR = 4, // Centre
Sco_SCOPE_DEG, // Degree Sco_SCOPE_DEG = 5, // Degree
Sco_SCOPE_CRS, // Course Sco_SCOPE_CRS = 6, // Course
} Sco_Scope_t; } Sco_Scope_t;
/*****************************************************************************/ /*****************************************************************************/

View File

@ -104,6 +104,10 @@ static void Svy_GetParamSvyOrderType (void);
static void Svy_PutFormsToRemEditOneSvy (long SvyCod,bool Visible); static void Svy_PutFormsToRemEditOneSvy (long SvyCod,bool Visible);
static void Svy_PutParams (void); static void Svy_PutParams (void);
static void Svy_SetAllowedAndHiddenScopes (unsigned *ScopesAllowed,
unsigned *HiddenAllowed);
static void Svy_GetSurveyTxtFromDB (long SvyCod,char *Txt); static void Svy_GetSurveyTxtFromDB (long SvyCod,char *Txt);
static void Svy_PutParamSvyCod (long SvyCod); static void Svy_PutParamSvyCod (long SvyCod);
static long Svy_GetParamSvyCod (void); static long Svy_GetParamSvyCod (void);
@ -189,10 +193,6 @@ static void Svy_ListAllSurveys (struct SurveyQuestion *SvyQst)
unsigned NumSvy; unsigned NumSvy;
bool ICanEdit = Svy_CheckIfICanCreateSvy (); bool ICanEdit = Svy_CheckIfICanCreateSvy ();
/***** Get number of groups in current course *****/
if (!Gbl.CurrentCrs.Grps.NumGrps)
Gbl.CurrentCrs.Grps.WhichGrps = Grp_ALL_GROUPS;
/***** Get list of surveys *****/ /***** Get list of surveys *****/
Svy_GetListSurveys (); Svy_GetListSurveys ();
@ -386,6 +386,9 @@ static void Svy_ShowOneSurvey (long SvyCod,struct SurveyQuestion *SvyQst,
extern const char *Txt_No_of_questions; extern const char *Txt_No_of_questions;
extern const char *Txt_No_of_users; extern const char *Txt_No_of_users;
extern const char *Txt_Scope; extern const char *Txt_Scope;
extern const char *Txt_Country;
extern const char *Txt_Institution;
extern const char *Txt_Centre;
extern const char *Txt_Degree; extern const char *Txt_Degree;
extern const char *Txt_Course; extern const char *Txt_Course;
extern const char *Txt_Users; extern const char *Txt_Users;
@ -535,14 +538,36 @@ static void Svy_ShowOneSurvey (long SvyCod,struct SurveyQuestion *SvyQst,
Svy.Status.Visible ? "ASG_GRP" : Svy.Status.Visible ? "ASG_GRP" :
"ASG_GRP_LIGHT", "ASG_GRP_LIGHT",
Txt_Scope); Txt_Scope);
if (Svy.CrsCod > 0) switch (Svy.Scope)
fprintf (Gbl.F.Out,"%s %s", {
Txt_Course,Gbl.CurrentCrs.Crs.ShortName); case Sco_SCOPE_UNK: // Unknown
else if (Svy.DegCod > 0) Lay_ShowErrorAndExit ("Wrong survey scope.");
fprintf (Gbl.F.Out,"%s %s", break;
Txt_Degree,Gbl.CurrentDeg.Deg.ShortName); case Sco_SCOPE_SYS: // System
else fprintf (Gbl.F.Out,"%s",
fprintf (Gbl.F.Out,"%s",Cfg_PLATFORM_SHORT_NAME); Cfg_PLATFORM_SHORT_NAME);
break;
case Sco_SCOPE_CTY: // Country
fprintf (Gbl.F.Out,"%s %s",
Txt_Country,Gbl.CurrentCty.Cty.Name[Gbl.Prefs.Language]);
break;
case Sco_SCOPE_INS: // Institution
fprintf (Gbl.F.Out,"%s %s",
Txt_Institution,Gbl.CurrentIns.Ins.ShortName);
break;
case Sco_SCOPE_CTR: // Centre
fprintf (Gbl.F.Out,"%s %s",
Txt_Centre,Gbl.CurrentCtr.Ctr.ShortName);
break;
case Sco_SCOPE_DEG: // Degree
fprintf (Gbl.F.Out,"%s %s",
Txt_Degree,Gbl.CurrentDeg.Deg.ShortName);
break;
case Sco_SCOPE_CRS: // Course
fprintf (Gbl.F.Out,"%s %s",
Txt_Course,Gbl.CurrentCrs.Crs.ShortName);
break;
}
fprintf (Gbl.F.Out,"</div>"); fprintf (Gbl.F.Out,"</div>");
/* Users' roles who can answer the survey */ /* Users' roles who can answer the survey */
@ -557,7 +582,7 @@ static void Svy_ShowOneSurvey (long SvyCod,struct SurveyQuestion *SvyQst,
fprintf (Gbl.F.Out,"</div>"); fprintf (Gbl.F.Out,"</div>");
/* Groups whose users can answer this survey */ /* Groups whose users can answer this survey */
if (Svy.CrsCod > 0) if (Svy.Scope == Sco_SCOPE_CRS)
if (Gbl.CurrentCrs.Grps.NumGrps) if (Gbl.CurrentCrs.Grps.NumGrps)
Svy_GetAndWriteNamesOfGrpsAssociatedToSvy (&Svy); Svy_GetAndWriteNamesOfGrpsAssociatedToSvy (&Svy);
@ -588,10 +613,10 @@ static void Svy_ShowOneSurvey (long SvyCod,struct SurveyQuestion *SvyQst,
Gbl.RowEvenOdd = 1 - Gbl.RowEvenOdd; Gbl.RowEvenOdd = 1 - Gbl.RowEvenOdd;
/***** Mark possible notification as seen *****/ /***** Mark possible notification as seen *****/
if (Svy.CrsCod > 0) // Only course surveys are notified if (Svy.Scope == Sco_SCOPE_CRS) // Only course surveys are notified
Ntf_MarkNotifAsSeen (Ntf_EVENT_SURVEY, Ntf_MarkNotifAsSeen (Ntf_EVENT_SURVEY,
SvyCod,Svy.CrsCod, SvyCod,Svy.Cod,
Gbl.Usrs.Me.UsrDat.UsrCod); Gbl.Usrs.Me.UsrDat.UsrCod);
/***** End frame *****/ /***** End frame *****/
if (ShowOnlyThisSvyComplete) if (ShowOnlyThisSvyComplete)
@ -695,7 +720,7 @@ static void Svy_WriteStatus (struct Survey *Svy)
Txt_SURVEY_Type_of_user_not_allowed); Txt_SURVEY_Type_of_user_not_allowed);
/* Write whether survey can be answered by me or not depending on groups */ /* Write whether survey can be answered by me or not depending on groups */
if (Svy->Status.IBelongToDegCrsGrps) if (Svy->Status.IBelongToScope)
fprintf (Gbl.F.Out,"<li class=\"%s\">%s</li>", fprintf (Gbl.F.Out,"<li class=\"%s\">%s</li>",
Svy->Status.Visible ? "STATUS_GREEN" : Svy->Status.Visible ? "STATUS_GREEN" :
"STATUS_GREEN_LIGHT", "STATUS_GREEN_LIGHT",
@ -818,105 +843,73 @@ static void Svy_PutParams (void)
void Svy_GetListSurveys (void) void Svy_GetListSurveys (void)
{ {
char HiddenSubQuery[256]; char SubQuery[Sco_NUM_SCOPES][128];
char OrderBySubQuery[256]; char OrderBySubQuery[256];
char Query[2048]; char Query[2048];
MYSQL_RES *mysql_res; MYSQL_RES *mysql_res;
MYSQL_ROW row; MYSQL_ROW row;
unsigned long NumRows; unsigned long NumRows;
unsigned NumSvy; unsigned NumSvy;
unsigned ScopesAllowed = 0;
unsigned HiddenAllowed = 0;
long Cods[Sco_NUM_SCOPES];
Sco_Scope_t Scope;
bool SubQueryFilled;
/***** Free list of surveys *****/
if (Gbl.Svys.LstIsRead) if (Gbl.Svys.LstIsRead)
Svy_FreeListSurveys (); Svy_FreeListSurveys ();
/***** Get list of surveys from database *****/ /***** Set allowed and hidden scopes to get list depending on my user's role *****/
switch (Gbl.Svys.SelectedOrderType) Svy_SetAllowedAndHiddenScopes (&ScopesAllowed,&HiddenAllowed);
{
case Svy_ORDER_BY_START_DATE:
sprintf (OrderBySubQuery,"StartTime DESC,EndTime DESC,Title DESC");
break;
case Svy_ORDER_BY_END_DATE:
sprintf (OrderBySubQuery,"EndTime DESC,StartTime DESC,Title DESC");
break;
}
if (Gbl.CurrentDeg.Deg.DegCod < 0) // If no degree selected /***** Get list of surveys from database *****/
Cods[Sco_SCOPE_SYS] = -1L; // System
Cods[Sco_SCOPE_CTY] = Gbl.CurrentCty.Cty.CtyCod; // Country
Cods[Sco_SCOPE_INS] = Gbl.CurrentIns.Ins.InsCod; // Institution
Cods[Sco_SCOPE_CTR] = Gbl.CurrentCtr.Ctr.CtrCod; // Centre
Cods[Sco_SCOPE_DEG] = Gbl.CurrentDeg.Deg.DegCod; // Degree
Cods[Sco_SCOPE_CRS] = Gbl.CurrentCrs.Crs.CrsCod; // Course
for (Scope = Sco_SCOPE_SYS, SubQueryFilled = false;
Scope < Sco_SCOPE_CRS;
Scope++)
if (ScopesAllowed & 1 << Scope)
{
sprintf (SubQuery[Scope],"%s(Scope='%u' AND Cod='%ld'%s)",
SubQueryFilled ? " OR " :
"",
(unsigned) Scope,Cods[Scope],
(ScopesAllowed & 1 << Sco_SCOPE_SYS) ? "" :
" AND Hidden='N'");
SubQueryFilled = true;
}
else
SubQuery[Scope][0] = '\0';
if (SubQueryFilled)
{ {
switch (Gbl.Usrs.Me.LoggedRole) switch (Gbl.Svys.SelectedOrderType)
{ {
case Rol_SYS_ADM: case Svy_ORDER_BY_START_DATE:
HiddenSubQuery[0] = '\0'; // Show all surveys, visible or hidden sprintf (OrderBySubQuery,"StartTime DESC,EndTime DESC,Title DESC");
break; break;
default: case Svy_ORDER_BY_END_DATE:
sprintf (HiddenSubQuery," AND Hidden='N'"); // Show only visible surveys sprintf (OrderBySubQuery,"EndTime DESC,StartTime DESC,Title DESC");
break; break;
} }
sprintf (Query,"SELECT SvyCod" sprintf (Query,"SELECT SvyCod"
" FROM surveys" " FROM surveys"
" WHERE DegCod='-1' AND CrsCod='-1'%s" " WHERE %s%s%s%s%s%s"
" ORDER BY %s", " ORDER BY %s",
HiddenSubQuery, SubQuery[Sco_SCOPE_SYS],
OrderBySubQuery); SubQuery[Sco_SCOPE_CTY],
} SubQuery[Sco_SCOPE_INS],
else if ((Gbl.CurrentDeg.Deg.DegCod > 0 && Gbl.CurrentCrs.Crs.CrsCod < 0) || // If degree selected, but no course selected SubQuery[Sco_SCOPE_CTR],
Gbl.Usrs.Me.LoggedRole == Rol_DEG_ADM) // or if I am a degree administrator SubQuery[Sco_SCOPE_DEG],
{ SubQuery[Sco_SCOPE_CRS],
switch (Gbl.Usrs.Me.LoggedRole) OrderBySubQuery);
{
case Rol_DEG_ADM:
case Rol_SYS_ADM:
HiddenSubQuery[0] = '\0'; // Show all surveys, visible or hidden
break;
default:
sprintf (HiddenSubQuery," AND Hidden='N'"); // Show only visible surveys
break;
}
sprintf (Query,"SELECT SvyCod"
" FROM surveys"
" WHERE ((DegCod='-1' AND CrsCod='-1')"
" OR (DegCod='%ld' AND CrsCod='-1'))%s"
" ORDER BY %s",
Gbl.CurrentDeg.Deg.DegCod,
HiddenSubQuery,
OrderBySubQuery);
}
else if (Gbl.CurrentCrs.Crs.CrsCod > 0 &&
Gbl.Usrs.Me.LoggedRole != Rol_DEG_ADM)
{
switch (Gbl.Usrs.Me.LoggedRole)
{
case Rol_TEACHER:
case Rol_SYS_ADM:
HiddenSubQuery[0] = '\0'; // Show all surveys, visible or hidden
break;
default:
sprintf (HiddenSubQuery," AND Hidden='N'"); // Show only visible surveys
break;
}
if (Gbl.CurrentCrs.Grps.WhichGrps == Grp_ONLY_MY_GROUPS)
sprintf (Query,"SELECT SvyCod"
" FROM surveys"
" WHERE ((DegCod='-1' AND CrsCod='-1')"
" OR (DegCod='%ld' AND CrsCod='-1')"
" OR (CrsCod='%ld'"
" AND (SvyCod NOT IN (SELECT SvyCod FROM svy_grp) OR"
" SvyCod IN (SELECT svy_grp.SvyCod FROM svy_grp,crs_grp_usr"
" WHERE crs_grp_usr.UsrCod='%ld' AND svy_grp.GrpCod=crs_grp_usr.GrpCod))))%s"
" ORDER BY %s",
Gbl.CurrentDeg.Deg.DegCod,
Gbl.CurrentCrs.Crs.CrsCod,
Gbl.Usrs.Me.UsrDat.UsrCod,
HiddenSubQuery,OrderBySubQuery);
else // Gbl.CurrentCrs.Grps.WhichGrps == Grp_ALL_GROUPS
sprintf (Query,"SELECT SvyCod"
" FROM surveys"
" WHERE ((DegCod='-1' AND CrsCod='-1')"
" OR (DegCod='%ld' AND CrsCod='-1')"
" OR CrsCod='%ld')%s"
" ORDER BY %s",
Gbl.CurrentDeg.Deg.DegCod,
Gbl.CurrentCrs.Crs.CrsCod,
HiddenSubQuery,OrderBySubQuery);
} }
else else
Lay_ShowErrorAndExit ("Can not get list of surveys."); Lay_ShowErrorAndExit ("Can not get list of surveys.");
@ -951,6 +944,172 @@ void Svy_GetListSurveys (void)
Gbl.Svys.LstIsRead = true; Gbl.Svys.LstIsRead = true;
} }
/*****************************************************************************/
/*** Set allowed and hidden scopes to get list depending on my user's role ***/
/*****************************************************************************/
static void Svy_SetAllowedAndHiddenScopes (unsigned *ScopesAllowed,
unsigned *HiddenAllowed)
{
switch (Gbl.Usrs.Me.LoggedRole)
{
case Rol_UNKNOWN: // User not logged in *********************************
*ScopesAllowed = 0;
*HiddenAllowed = 0;
break;
case Rol__GUEST_: // User not belonging to any course *******************
*ScopesAllowed = 1 << Sco_SCOPE_SYS;
*HiddenAllowed = 0;
break;
case Rol_VISITOR: // Student or teacher in other courses...
// ...but not belonging to the current course *********
*ScopesAllowed = 1 << Sco_SCOPE_SYS;
*HiddenAllowed = 0;
if (Usr_CheckIfIBelongToCty (Gbl.CurrentCty.Cty.CtyCod))
{
*ScopesAllowed |= 1 << Sco_SCOPE_CTY;
if (Usr_CheckIfIBelongToIns (Gbl.CurrentIns.Ins.InsCod))
{
*ScopesAllowed |= 1 << Sco_SCOPE_INS;
if (Usr_CheckIfIBelongToCtr (Gbl.CurrentCtr.Ctr.CtrCod))
{
*ScopesAllowed |= 1 << Sco_SCOPE_CTR;
if (Usr_CheckIfIBelongToDeg (Gbl.CurrentDeg.Deg.DegCod))
*ScopesAllowed |= 1 << Sco_SCOPE_DEG;
}
}
}
break;
case Rol_STUDENT: // Student in current course **************************
*ScopesAllowed = 1 << Sco_SCOPE_SYS;
*HiddenAllowed = 0;
if (Usr_CheckIfIBelongToCty (Gbl.CurrentCty.Cty.CtyCod))
{
*ScopesAllowed |= 1 << Sco_SCOPE_CTY;
if (Usr_CheckIfIBelongToIns (Gbl.CurrentIns.Ins.InsCod))
{
*ScopesAllowed |= 1 << Sco_SCOPE_INS;
if (Usr_CheckIfIBelongToCtr (Gbl.CurrentCtr.Ctr.CtrCod))
{
*ScopesAllowed |= 1 << Sco_SCOPE_CTR;
if (Usr_CheckIfIBelongToDeg (Gbl.CurrentDeg.Deg.DegCod))
{
*ScopesAllowed |= 1 << Sco_SCOPE_DEG;
if (Usr_CheckIfIBelongToCrs (Gbl.CurrentCrs.Crs.CrsCod))
*ScopesAllowed |= 1 << Sco_SCOPE_CRS;
}
}
}
}
break;
case Rol_TEACHER: // Teacher in current course **************************
*ScopesAllowed = 1 << Sco_SCOPE_SYS;
*HiddenAllowed = 0;
if (Usr_CheckIfIBelongToCty (Gbl.CurrentCty.Cty.CtyCod))
{
*ScopesAllowed |= 1 << Sco_SCOPE_CTY;
if (Usr_CheckIfIBelongToIns (Gbl.CurrentIns.Ins.InsCod))
{
*ScopesAllowed |= 1 << Sco_SCOPE_INS;
if (Usr_CheckIfIBelongToCtr (Gbl.CurrentCtr.Ctr.CtrCod))
{
*ScopesAllowed |= 1 << Sco_SCOPE_CTR;
if (Usr_CheckIfIBelongToDeg (Gbl.CurrentDeg.Deg.DegCod))
{
*ScopesAllowed |= 1 << Sco_SCOPE_DEG;
if (Usr_CheckIfIBelongToCrs (Gbl.CurrentCrs.Crs.CrsCod))
{
*ScopesAllowed |= 1 << Sco_SCOPE_CRS;
*HiddenAllowed |= 1 << Sco_SCOPE_CRS; // A teacher can view hidden course surveys
}
}
}
}
}
break;
case Rol_DEG_ADM: // Degree administrator *******************************
*ScopesAllowed = 1 << Sco_SCOPE_SYS;
*HiddenAllowed = 0;
if (Gbl.CurrentCty.Cty.CtyCod > 0) // Country selected
{
*ScopesAllowed |= 1 << Sco_SCOPE_CTY;
if (Gbl.CurrentIns.Ins.InsCod > 0) // Institution selected
{
*ScopesAllowed |= 1 << Sco_SCOPE_INS;
if (Gbl.CurrentCtr.Ctr.CtrCod > 0) // Centre selected
{
*ScopesAllowed |= 1 << Sco_SCOPE_CTR;
if (Gbl.CurrentDeg.Deg.DegCod > 0) // Degree selected
{
*ScopesAllowed |= 1 << Sco_SCOPE_DEG;
*HiddenAllowed |= 1 << Sco_SCOPE_DEG; // A degree admin can view hidden degree surveys
}
}
}
}
break;
case Rol_CTR_ADM: // Centre administrator *******************************
*ScopesAllowed = 1 << Sco_SCOPE_SYS;
*HiddenAllowed = 0;
if (Gbl.CurrentCty.Cty.CtyCod > 0) // Country selected
{
*ScopesAllowed |= 1 << Sco_SCOPE_CTY;
if (Gbl.CurrentIns.Ins.InsCod > 0) // Institution selected
{
*ScopesAllowed |= 1 << Sco_SCOPE_INS;
if (Gbl.CurrentCtr.Ctr.CtrCod > 0) // Centre selected
{
*ScopesAllowed |= 1 << Sco_SCOPE_CTR;
*HiddenAllowed |= 1 << Sco_SCOPE_CTR; // A centre admin can view hidden centre surveys
}
}
}
break;
case Rol_INS_ADM: // Institution administrator **************************
*ScopesAllowed = 1 << Sco_SCOPE_SYS;
*HiddenAllowed = 0;
if (Gbl.CurrentCty.Cty.CtyCod > 0) // Country selected
{
*ScopesAllowed |= 1 << Sco_SCOPE_CTY;
if (Gbl.CurrentIns.Ins.InsCod > 0) // Institution selected
{
*ScopesAllowed |= 1 << Sco_SCOPE_INS;
*HiddenAllowed |= 1 << Sco_SCOPE_INS; // An institution admin can view hidden institution surveys
}
}
break;
case Rol_SYS_ADM: // System administrator (superuser) *******************
*ScopesAllowed = 1 << Sco_SCOPE_SYS;
*HiddenAllowed = 1 << Sco_SCOPE_SYS; // A system admin can view hidden system surveys
if (Gbl.CurrentCty.Cty.CtyCod > 0) // Country selected
{
*ScopesAllowed |= 1 << Sco_SCOPE_CTY;
*HiddenAllowed |= 1 << Sco_SCOPE_CTY; // A system admin can view hidden country surveys
if (Gbl.CurrentIns.Ins.InsCod > 0) // Institution selected
{
*ScopesAllowed |= 1 << Sco_SCOPE_INS;
*HiddenAllowed |= 1 << Sco_SCOPE_INS; // A system admin can view hidden institution surveys
if (Gbl.CurrentCtr.Ctr.CtrCod > 0) // Centre selected
{
*ScopesAllowed |= 1 << Sco_SCOPE_CTR;
*HiddenAllowed |= 1 << Sco_SCOPE_CTR; // A system admin can view hidden centre surveys
if (Gbl.CurrentDeg.Deg.DegCod > 0) // Degree selected
{
*ScopesAllowed |= 1 << Sco_SCOPE_DEG;
*HiddenAllowed |= 1 << Sco_SCOPE_DEG; // A system admin can view hidden degree surveys
if (Gbl.CurrentCrs.Crs.CrsCod > 0) // Course selected
{
*ScopesAllowed |= 1 << Sco_SCOPE_CRS;
*HiddenAllowed |= 1 << Sco_SCOPE_CRS; // A system admin can view hidden course surveys
}
}
}
}
}
break;
}
}
/*****************************************************************************/ /*****************************************************************************/
/********************* Get survey data using its code ************************/ /********************* Get survey data using its code ************************/
/*****************************************************************************/ /*****************************************************************************/
@ -963,7 +1122,7 @@ void Svy_GetDataOfSurveyByCod (struct Survey *Svy)
unsigned long NumRows; unsigned long NumRows;
/***** Build query *****/ /***** Build query *****/
sprintf (Query,"SELECT SvyCod,DegCod,CrsCod,Hidden,Roles,UsrCod," sprintf (Query,"SELECT SvyCod,Scope,Cod,Hidden,Roles,UsrCod,"
"UNIX_TIMESTAMP(StartTime)," "UNIX_TIMESTAMP(StartTime),"
"UNIX_TIMESTAMP(EndTime)," "UNIX_TIMESTAMP(EndTime),"
"NOW() BETWEEN StartTime AND EndTime," "NOW() BETWEEN StartTime AND EndTime,"
@ -983,25 +1142,12 @@ void Svy_GetDataOfSurveyByCod (struct Survey *Svy)
/* Get code of the survey (row[0]) */ /* Get code of the survey (row[0]) */
Svy->SvyCod = Str_ConvertStrCodToLongCod (row[0]); Svy->SvyCod = Str_ConvertStrCodToLongCod (row[0]);
/* Get code of the degree (row[1]) */ /* Get survey scope (row[1]) */
Svy->DegCod = Str_ConvertStrCodToLongCod (row[1]); if ((Svy->Scope = Sco_GetScopeFromUnsignedStr (row[1])) == Sco_SCOPE_UNK)
if (Svy->DegCod > 0) Lay_ShowErrorAndExit ("Wrong survey scope.");
if (Svy->DegCod != Gbl.CurrentDeg.Deg.DegCod)
Lay_ShowErrorAndExit ("Wrong survey degree.");
/* Get code of the course (row[2]) */ /* Get code of the country, institution, centre, degree or course (row[2]) */
Svy->CrsCod = Str_ConvertStrCodToLongCod (row[2]); Svy->Cod = Str_ConvertStrCodToLongCod (row[2]);
if (Svy->CrsCod > 0)
if (Svy->CrsCod != Gbl.CurrentCrs.Crs.CrsCod)
Lay_ShowErrorAndExit ("Wrong survey course.");
/* Set survey scope */
if (Svy->CrsCod > 0)
Svy->Scope = Sco_SCOPE_CRS;
else if (Svy->DegCod > 0)
Svy->Scope = Sco_SCOPE_DEG;
else
Svy->Scope = Sco_SCOPE_SYS;
/* Get whether the survey is hidden (row[3]) */ /* Get whether the survey is hidden (row[3]) */
Svy->Status.Visible = (row[3][0] == 'N'); Svy->Status.Visible = (row[3][0] == 'N');
@ -1033,15 +1179,31 @@ void Svy_GetDataOfSurveyByCod (struct Survey *Svy)
Svy->Status.IAmLoggedWithAValidRoleToAnswer = (Svy->Roles & (1 << Gbl.Usrs.Me.LoggedRole)); Svy->Status.IAmLoggedWithAValidRoleToAnswer = (Svy->Roles & (1 << Gbl.Usrs.Me.LoggedRole));
/* Do I belong to valid groups to answer this survey? */ /* Do I belong to valid groups to answer this survey? */
if (Svy->DegCod < 0 && Svy->CrsCod < 0) switch (Svy->Scope)
Svy->Status.IBelongToDegCrsGrps = Gbl.Usrs.Me.Logged; {
else if (Svy->DegCod > 0 && Svy->CrsCod < 0) case Sco_SCOPE_UNK: // Unknown
Svy->Status.IBelongToDegCrsGrps = Usr_CheckIfIBelongToDeg (Svy->DegCod); Lay_ShowErrorAndExit ("Wrong survey scope.");
else if (Svy->CrsCod > 0) break;
Svy->Status.IBelongToDegCrsGrps = Usr_CheckIfIBelongToCrs (Svy->CrsCod) && case Sco_SCOPE_SYS: // System
Svy_CheckIfICanDoThisSurveyBasedOnGrps (Svy->SvyCod); Svy->Status.IBelongToScope = Gbl.Usrs.Me.Logged;
else break;
Lay_ShowErrorAndExit ("Wrong survey scope."); case Sco_SCOPE_CTY: // Country
Svy->Status.IBelongToScope = Usr_CheckIfIBelongToCty (Svy->Cod);
break;
case Sco_SCOPE_INS: // Institution
Svy->Status.IBelongToScope = Usr_CheckIfIBelongToIns (Svy->Cod);
break;
case Sco_SCOPE_CTR: // Centre
Svy->Status.IBelongToScope = Usr_CheckIfIBelongToCtr (Svy->Cod);
break;
case Sco_SCOPE_DEG: // Degree
Svy->Status.IBelongToScope = Usr_CheckIfIBelongToDeg (Svy->Cod);
break;
case Sco_SCOPE_CRS: // Course
Svy->Status.IBelongToScope = Usr_CheckIfIBelongToCrs (Svy->Cod) &&
Svy_CheckIfICanDoThisSurveyBasedOnGrps (Svy->SvyCod);
break;
}
/* Have I answered this survey? */ /* Have I answered this survey? */
Svy->Status.IHaveAnswered = Svy_CheckIfIHaveAnsweredSvy (Svy->SvyCod); Svy->Status.IHaveAnswered = Svy_CheckIfIHaveAnsweredSvy (Svy->SvyCod);
@ -1051,7 +1213,7 @@ void Svy_GetDataOfSurveyByCod (struct Survey *Svy)
Svy->Status.Visible && Svy->Status.Visible &&
Svy->Status.Open && Svy->Status.Open &&
Svy->Status.IAmLoggedWithAValidRoleToAnswer && Svy->Status.IAmLoggedWithAValidRoleToAnswer &&
Svy->Status.IBelongToDegCrsGrps && Svy->Status.IBelongToScope &&
!Svy->Status.IHaveAnswered; !Svy->Status.IHaveAnswered;
/* Can I view results of the survey? /* Can I view results of the survey?
@ -1059,56 +1221,92 @@ void Svy_GetDataOfSurveyByCod (struct Survey *Svy)
switch (Gbl.Usrs.Me.LoggedRole) switch (Gbl.Usrs.Me.LoggedRole)
{ {
case Rol_STUDENT: case Rol_STUDENT:
Svy->Status.ICanViewResults = (Svy->NumQsts != 0) && Svy->Status.ICanViewResults = (Svy->Scope == Sco_SCOPE_CRS ||
Svy->Status.Visible && Svy->Scope == Sco_SCOPE_DEG ||
Svy->Status.Open && Svy->Scope == Sco_SCOPE_CTR ||
Svy->Status.IAmLoggedWithAValidRoleToAnswer && Svy->Scope == Sco_SCOPE_INS ||
Svy->Status.IBelongToDegCrsGrps && Svy->Scope == Sco_SCOPE_CTY ||
Svy->Status.IHaveAnswered; Svy->Scope == Sco_SCOPE_SYS) &&
Svy->Status.ICanEdit = false; (Svy->NumQsts != 0) &&
Svy->Status.Visible &&
Svy->Status.Open &&
Svy->Status.IAmLoggedWithAValidRoleToAnswer &&
Svy->Status.IBelongToScope &&
Svy->Status.IHaveAnswered;
Svy->Status.ICanEdit = false;
break; break;
case Rol_TEACHER: case Rol_TEACHER:
Svy->Status.ICanViewResults = (Svy->NumQsts != 0) && Svy->Status.ICanViewResults = (Svy->Scope == Sco_SCOPE_CRS ||
Svy->Scope == Sco_SCOPE_DEG ||
Svy->Scope == Sco_SCOPE_CTR ||
Svy->Scope == Sco_SCOPE_INS ||
Svy->Scope == Sco_SCOPE_CTY ||
Svy->Scope == Sco_SCOPE_SYS) &&
Svy->NumQsts != 0 &&
!Svy->Status.ICanAnswer; !Svy->Status.ICanAnswer;
Svy->Status.ICanEdit = Svy->Scope == Sco_SCOPE_CRS && Svy->Status.ICanEdit = Svy->Scope == Sco_SCOPE_CRS &&
Svy->Status.IBelongToDegCrsGrps; Svy->Status.IBelongToScope;
break; break;
case Rol_DEG_ADM: case Rol_DEG_ADM:
Svy->Status.ICanViewResults = false; Svy->Status.ICanViewResults = (Svy->Scope == Sco_SCOPE_DEG ||
Svy->Status.ICanEdit = Svy->Scope == Sco_SCOPE_DEG && Svy->Scope == Sco_SCOPE_CTR ||
Svy->Status.IBelongToDegCrsGrps; Svy->Scope == Sco_SCOPE_INS ||
Svy->Scope == Sco_SCOPE_CTY ||
Svy->Scope == Sco_SCOPE_SYS) &&
(Svy->NumQsts != 0) &&
!Svy->Status.ICanAnswer;
Svy->Status.ICanEdit = Svy->Scope == Sco_SCOPE_DEG &&
Svy->Status.IBelongToScope;
break;
case Rol_CTR_ADM:
Svy->Status.ICanViewResults = (Svy->Scope == Sco_SCOPE_CTR ||
Svy->Scope == Sco_SCOPE_INS ||
Svy->Scope == Sco_SCOPE_CTY ||
Svy->Scope == Sco_SCOPE_SYS) &&
(Svy->NumQsts != 0) &&
!Svy->Status.ICanAnswer;
Svy->Status.ICanEdit = Svy->Scope == Sco_SCOPE_CTR &&
Svy->Status.IBelongToScope;
break;
case Rol_INS_ADM:
Svy->Status.ICanViewResults = (Svy->Scope == Sco_SCOPE_INS ||
Svy->Scope == Sco_SCOPE_CTY ||
Svy->Scope == Sco_SCOPE_SYS) &&
(Svy->NumQsts != 0) &&
!Svy->Status.ICanAnswer;
Svy->Status.ICanEdit = Svy->Scope == Sco_SCOPE_INS &&
Svy->Status.IBelongToScope;
break; break;
// TODO: Add Rol_CTR_ADM
// TODO: Add Rol_INS_ADM
case Rol_SYS_ADM: case Rol_SYS_ADM:
Svy->Status.ICanViewResults = (Svy->NumQsts != 0); Svy->Status.ICanViewResults = (Svy->NumQsts != 0);
Svy->Status.ICanEdit = true; Svy->Status.ICanEdit = true;
break; break;
default: default:
Svy->Status.ICanViewResults = false; Svy->Status.ICanViewResults = false;
Svy->Status.ICanEdit = false; Svy->Status.ICanEdit = false;
break; break;
} }
} }
else else
{ {
/* Initialize to empty survey */ /* Initialize to empty survey */
Svy->SvyCod = -1L; Svy->SvyCod = -1L;
Svy->Scope = Sco_SCOPE_UNK; Svy->Scope = Sco_SCOPE_UNK;
Svy->Roles = 0; Svy->Roles = 0;
Svy->UsrCod = -1L; Svy->UsrCod = -1L;
Svy->TimeUTC[Svy_START_TIME] = Svy->TimeUTC[Svy_START_TIME] =
Svy->TimeUTC[Svy_END_TIME ] = (time_t) 0; Svy->TimeUTC[Svy_END_TIME ] = (time_t) 0;
Svy->Title[0] = '\0'; Svy->Title[0] = '\0';
Svy->NumQsts = 0; Svy->NumQsts = 0;
Svy->NumUsrs = 0; Svy->NumUsrs = 0;
Svy->Status.Visible = true; Svy->Status.Visible = true;
Svy->Status.Open = false; Svy->Status.Open = false;
Svy->Status.IAmLoggedWithAValidRoleToAnswer = false; Svy->Status.IAmLoggedWithAValidRoleToAnswer = false;
Svy->Status.IBelongToDegCrsGrps = false; Svy->Status.IBelongToScope = false;
Svy->Status.IHaveAnswered = false; Svy->Status.IHaveAnswered = false;
Svy->Status.ICanAnswer = false; Svy->Status.ICanAnswer = false;
Svy->Status.ICanViewResults = false; Svy->Status.ICanViewResults = false;
Svy->Status.ICanEdit = false;
} }
/***** Free structure that stores the query result *****/ /***** Free structure that stores the query result *****/
@ -1495,8 +1693,8 @@ static bool Svy_CheckIfSimilarSurveyExists (struct Survey *Svy)
/***** Get number of surveys with a field value from database *****/ /***** Get number of surveys with a field value from database *****/
sprintf (Query,"SELECT COUNT(*) FROM surveys" sprintf (Query,"SELECT COUNT(*) FROM surveys"
" WHERE DegCod='%ld' AND CrsCod='%ld' AND Title='%s' AND SvyCod<>'%ld'", " WHERE Scope='%u' AND Cod='%ld' AND Title='%s' AND SvyCod<>'%ld'",
Svy->DegCod,Svy->CrsCod,Svy->Title,Svy->SvyCod); (unsigned) Svy->Scope,Svy->Cod,Svy->Title,Svy->SvyCod);
return (DB_QueryCOUNT (Query,"can not get similar surveys") != 0); return (DB_QueryCOUNT (Query,"can not get similar surveys") != 0);
} }
@ -1548,7 +1746,7 @@ void Svy_RequestCreatOrEditSvy (void)
Svy.Status.Visible = true; Svy.Status.Visible = true;
Svy.Status.Open = true; Svy.Status.Open = true;
Svy.Status.IAmLoggedWithAValidRoleToAnswer = false; Svy.Status.IAmLoggedWithAValidRoleToAnswer = false;
Svy.Status.IBelongToDegCrsGrps = false; Svy.Status.IBelongToScope = false;
Svy.Status.IHaveAnswered = false; Svy.Status.IHaveAnswered = false;
Svy.Status.ICanAnswer = false; Svy.Status.ICanAnswer = false;
Svy.Status.ICanViewResults = false; Svy.Status.ICanViewResults = false;
@ -1653,10 +1851,8 @@ void Svy_RequestCreatOrEditSvy (void)
} }
/*****************************************************************************/ /*****************************************************************************/
/*** Set default and allowed location ranges depending on logged user type ***/ /****** Set default and allowed scopes depending on logged user's role *******/
/*****************************************************************************/ /*****************************************************************************/
// Return true if user can edit survey
// Return false if user can not edit survey
static void Svy_SetDefaultAndAllowedScope (struct Survey *Svy) static void Svy_SetDefaultAndAllowedScope (struct Survey *Svy)
{ {
@ -1668,7 +1864,7 @@ static void Svy_SetDefaultAndAllowedScope (struct Survey *Svy)
switch (Gbl.Usrs.Me.LoggedRole) switch (Gbl.Usrs.Me.LoggedRole)
{ {
case Rol_TEACHER: case Rol_TEACHER: // Teachers only can edit course surveys
if (Gbl.CurrentCrs.Crs.CrsCod > 0) if (Gbl.CurrentCrs.Crs.CrsCod > 0)
{ {
if (Svy->Scope == Sco_SCOPE_UNK) // Scope not defined if (Svy->Scope == Sco_SCOPE_UNK) // Scope not defined
@ -1681,7 +1877,7 @@ static void Svy_SetDefaultAndAllowedScope (struct Survey *Svy)
} }
} }
break; break;
case Rol_DEG_ADM: case Rol_DEG_ADM: // Degree admins only can edit degree surveys
if (Svy->Scope == Sco_SCOPE_UNK) // Scope not defined if (Svy->Scope == Sco_SCOPE_UNK) // Scope not defined
Svy->Scope = Sco_SCOPE_DEG; Svy->Scope = Sco_SCOPE_DEG;
if (Svy->Scope == Sco_SCOPE_DEG) if (Svy->Scope == Sco_SCOPE_DEG)
@ -1691,27 +1887,48 @@ static void Svy_SetDefaultAndAllowedScope (struct Survey *Svy)
ICanEdit = true; ICanEdit = true;
} }
break; break;
// TODO: Add Rol_CTR_ADM case Rol_CTR_ADM: // Centre admins only can edit centre surveys
// TODO: Add Rol_INS_ADM if (Svy->Scope == Sco_SCOPE_UNK) // Scope not defined
case Rol_SYS_ADM: Svy->Scope = Sco_SCOPE_CTR;
if (Svy->Scope == Sco_SCOPE_UNK) if (Svy->Scope == Sco_SCOPE_CTR)
{ {
if (Gbl.CurrentCrs.Crs.CrsCod > 0) Gbl.Scope.Default = Svy->Scope;
Gbl.Scope.Allowed = 1 << Sco_SCOPE_CTR;
ICanEdit = true;
}
break;
case Rol_INS_ADM: // Institution admins only can edit institution surveys
if (Svy->Scope == Sco_SCOPE_UNK) // Scope not defined
Svy->Scope = Sco_SCOPE_INS;
if (Svy->Scope == Sco_SCOPE_INS)
{
Gbl.Scope.Default = Svy->Scope;
Gbl.Scope.Allowed = 1 << Sco_SCOPE_INS;
ICanEdit = true;
}
break;
case Rol_SYS_ADM:// System admins can edit any survey
if (Svy->Scope == Sco_SCOPE_UNK) // Scope not defined
{
if (Gbl.CurrentCrs.Crs.CrsCod > 0)
Svy->Scope = Sco_SCOPE_CRS; Svy->Scope = Sco_SCOPE_CRS;
else if (Gbl.CurrentDeg.Deg.DegCod > 0) else if (Gbl.CurrentDeg.Deg.DegCod > 0)
Svy->Scope = Sco_SCOPE_DEG; Svy->Scope = Sco_SCOPE_DEG;
// TODO: Add Sco_SCOPE_CTR else if (Gbl.CurrentCtr.Ctr.CtrCod > 0)
// TODO: Add Sco_SCOPE_INS Svy->Scope = Sco_SCOPE_CTR;
// TODO: Add Sco_SCOPE_CTY else if (Gbl.CurrentIns.Ins.InsCod > 0)
Svy->Scope = Sco_SCOPE_INS;
else if (Gbl.CurrentCty.Cty.CtyCod > 0)
Svy->Scope = Sco_SCOPE_CTY;
else else
Svy->Scope = Sco_SCOPE_SYS; Svy->Scope = Sco_SCOPE_SYS;
} }
Gbl.Scope.Default = Svy->Scope; Gbl.Scope.Default = Svy->Scope;
Gbl.Scope.Allowed = 1 << Sco_SCOPE_SYS | Gbl.Scope.Allowed = 1 << Sco_SCOPE_SYS |
// 1 << Sco_SCOPE_CTY | // TODO: Add this scope 1 << Sco_SCOPE_CTY |
// 1 << Sco_SCOPE_INS | // TODO: Add this scope 1 << Sco_SCOPE_INS |
// 1 << Sco_SCOPE_CTR | // TODO: Add this scope 1 << Sco_SCOPE_CTR |
1 << Sco_SCOPE_DEG | 1 << Sco_SCOPE_DEG |
1 << Sco_SCOPE_CRS; 1 << Sco_SCOPE_CRS;
ICanEdit = true; ICanEdit = true;
break; break;
@ -1785,7 +2002,8 @@ void Svy_RecFormSurvey (void)
{ {
extern const char *Txt_Already_existed_a_survey_with_the_title_X; extern const char *Txt_Already_existed_a_survey_with_the_title_X;
extern const char *Txt_You_must_specify_the_title_of_the_survey; extern const char *Txt_You_must_specify_the_title_of_the_survey;
struct Survey OldSvy,NewSvy; struct Survey OldSvy;
struct Survey NewSvy;
struct SurveyQuestion SvyQst; struct SurveyQuestion SvyQst;
bool ItsANewSurvey; bool ItsANewSurvey;
bool NewSurveyIsCorrect = true; bool NewSurveyIsCorrect = true;
@ -1795,51 +2013,62 @@ void Svy_RecFormSurvey (void)
/***** Get the code of the survey *****/ /***** Get the code of the survey *****/
ItsANewSurvey = ((NewSvy.SvyCod = Svy_GetParamSvyCod ()) == -1L); ItsANewSurvey = ((NewSvy.SvyCod = Svy_GetParamSvyCod ()) == -1L);
if (!ItsANewSurvey) if (ItsANewSurvey)
NewSvy.Scope = Sco_SCOPE_UNK;
else
{ {
/* Get data of the old (current) survey from database */ /* Get data of the old (current) survey from database */
OldSvy.SvyCod = NewSvy.SvyCod; OldSvy.SvyCod = NewSvy.SvyCod;
Svy_GetDataOfSurveyByCod (&OldSvy); Svy_GetDataOfSurveyByCod (&OldSvy);
if (!OldSvy.Status.ICanEdit) if (!OldSvy.Status.ICanEdit)
Lay_ShowErrorAndExit ("You can not update this survey."); Lay_ShowErrorAndExit ("You can not update this survey.");
NewSvy.Scope = OldSvy.Scope;
} }
/***** Get scope *****/ /***** Get scope *****/
Gbl.Scope.Allowed = 1 << Sco_SCOPE_SYS | Svy_SetDefaultAndAllowedScope (&NewSvy);
// 1 << Sco_SCOPE_CTY | // TODO: Add this scope
// 1 << Sco_SCOPE_INS | // TODO: Add this scope
// 1 << Sco_SCOPE_CTR | // TODO: Add this scope
1 << Sco_SCOPE_DEG |
1 << Sco_SCOPE_CRS;
Gbl.Scope.Default = Sco_SCOPE_SYS;
Sco_GetScope ("ScopeSvy"); Sco_GetScope ("ScopeSvy");
switch (Gbl.Scope.Current) switch (Gbl.Scope.Current)
{ {
case Sco_SCOPE_SYS: case Sco_SCOPE_SYS:
NewSvy.DegCod = -1L; if (Gbl.Usrs.Me.LoggedRole != Rol_SYS_ADM)
NewSvy.CrsCod = -1L; Lay_ShowErrorAndExit ("Wrong survey scope.");
NewSvy.Scope = Sco_SCOPE_SYS; NewSvy.Scope = Sco_SCOPE_SYS;
NewSvy.Cod = -1L;
break;
case Sco_SCOPE_CTY:
if (Gbl.Usrs.Me.LoggedRole != Rol_SYS_ADM)
Lay_ShowErrorAndExit ("Wrong survey scope.");
NewSvy.Scope = Sco_SCOPE_CTY;
NewSvy.Cod = Gbl.CurrentCty.Cty.CtyCod;
break;
case Sco_SCOPE_INS:
if (Gbl.Usrs.Me.LoggedRole != Rol_SYS_ADM &&
Gbl.Usrs.Me.LoggedRole != Rol_INS_ADM)
Lay_ShowErrorAndExit ("Wrong survey scope.");
NewSvy.Scope = Sco_SCOPE_INS;
NewSvy.Cod = Gbl.CurrentIns.Ins.InsCod;
break;
case Sco_SCOPE_CTR:
if (Gbl.Usrs.Me.LoggedRole != Rol_SYS_ADM &&
Gbl.Usrs.Me.LoggedRole != Rol_CTR_ADM)
Lay_ShowErrorAndExit ("Wrong survey scope.");
NewSvy.Scope = Sco_SCOPE_CTR;
NewSvy.Cod = Gbl.CurrentCtr.Ctr.CtrCod;
break; break;
case Sco_SCOPE_DEG: case Sco_SCOPE_DEG:
if (Gbl.CurrentDeg.Deg.DegCod > 0) if (Gbl.Usrs.Me.LoggedRole != Rol_SYS_ADM &&
{ Gbl.Usrs.Me.LoggedRole != Rol_DEG_ADM)
NewSvy.DegCod = Gbl.CurrentDeg.Deg.DegCod; Lay_ShowErrorAndExit ("Wrong survey scope.");
NewSvy.CrsCod = -1L; NewSvy.Scope = Sco_SCOPE_DEG;
NewSvy.Scope = Sco_SCOPE_DEG; NewSvy.Cod = Gbl.CurrentDeg.Deg.DegCod;
}
else
Lay_ShowErrorAndExit ("Wrong survey location.");
break; break;
case Sco_SCOPE_CRS: case Sco_SCOPE_CRS:
if (Gbl.CurrentCrs.Crs.CrsCod > 0) if (Gbl.Usrs.Me.LoggedRole != Rol_SYS_ADM &&
{ Gbl.Usrs.Me.LoggedRole != Rol_TEACHER)
NewSvy.DegCod = -1L; // DegCod doen't mind when CrsCod > 0 Lay_ShowErrorAndExit ("Wrong survey scope.");
NewSvy.CrsCod = Gbl.CurrentCrs.Crs.CrsCod; NewSvy.Scope = Sco_SCOPE_CRS;
NewSvy.Scope = Sco_SCOPE_CRS; NewSvy.Cod = Gbl.CurrentCrs.Crs.CrsCod;
}
else
Lay_ShowErrorAndExit ("Wrong survey location.");
break; break;
default: default:
Lay_ShowErrorAndExit ("Wrong scope."); Lay_ShowErrorAndExit ("Wrong scope.");
@ -1900,8 +2129,8 @@ void Svy_RecFormSurvey (void)
else else
Svy_RequestCreatOrEditSvy (); Svy_RequestCreatOrEditSvy ();
/***** Notify by e-mail about the new assignment *****/ /***** Notify by e-mail about the new survey *****/
if (NewSvy.CrsCod > 0) // Notify only the surveys for a course, not for a degree or global if (NewSvy.Scope == Sco_SCOPE_CRS) // Notify only the surveys for a course, not for a degree or global
{ {
if ((NumUsrsToBeNotifiedByEMail = Ntf_StoreNotifyEventsToAllUsrs (Ntf_EVENT_SURVEY,NewSvy.SvyCod))) if ((NumUsrsToBeNotifiedByEMail = Ntf_StoreNotifyEventsToAllUsrs (Ntf_EVENT_SURVEY,NewSvy.SvyCod)))
Svy_UpdateNumUsrsNotifiedByEMailAboutSurvey (NewSvy.SvyCod,NumUsrsToBeNotifiedByEMail); Svy_UpdateNumUsrsNotifiedByEMailAboutSurvey (NewSvy.SvyCod,NumUsrsToBeNotifiedByEMail);
@ -1939,12 +2168,12 @@ static void Svy_CreateSurvey (struct Survey *Svy,const char *Txt)
/***** Create a new survey *****/ /***** Create a new survey *****/
sprintf (Query,"INSERT INTO surveys" sprintf (Query,"INSERT INTO surveys"
" (DegCod,CrsCod,Hidden,Roles,UsrCod,StartTime,EndTime,Title,Txt)" " (Scope,Cod,Hidden,Roles,UsrCod,StartTime,EndTime,Title,Txt)"
" VALUES ('%ld','%ld','N','%u','%ld'," " VALUES ('%u','%ld','N','%u','%ld',"
"FROM_UNIXTIME('%ld'),FROM_UNIXTIME('%ld')," "FROM_UNIXTIME('%ld'),FROM_UNIXTIME('%ld'),"
"'%s','%s')", "'%s','%s')",
Svy->DegCod, (unsigned) Svy->Scope,
Svy->CrsCod, Svy->Cod,
Svy->Roles, Svy->Roles,
Gbl.Usrs.Me.UsrDat.UsrCod, Gbl.Usrs.Me.UsrDat.UsrCod,
Svy->TimeUTC[Svy_START_TIME], Svy->TimeUTC[Svy_START_TIME],
@ -1974,12 +2203,12 @@ static void Svy_UpdateSurvey (struct Survey *Svy,const char *Txt)
/***** Update the data of the survey *****/ /***** Update the data of the survey *****/
sprintf (Query,"UPDATE surveys" sprintf (Query,"UPDATE surveys"
" SET DegCod='%ld',CrsCod='%ld',Roles='%u'," " SET Scope='%u',Cod='%ld',Roles='%u',"
"StartTime=FROM_UNIXTIME('%ld')," "StartTime=FROM_UNIXTIME('%ld'),"
"EndTime=FROM_UNIXTIME('%ld')," "EndTime=FROM_UNIXTIME('%ld'),"
"Title='%s',Txt='%s'" "Title='%s',Txt='%s'"
" WHERE SvyCod='%ld'", " WHERE SvyCod='%ld'",
Svy->DegCod,Svy->CrsCod, (unsigned) Svy->Scope,Svy->Cod,
Svy->Roles, Svy->Roles,
Svy->TimeUTC[Svy_START_TIME], Svy->TimeUTC[Svy_START_TIME],
Svy->TimeUTC[Svy_END_TIME ], Svy->TimeUTC[Svy_END_TIME ],

View File

@ -45,9 +45,8 @@ typedef enum
struct Survey struct Survey
{ {
long SvyCod; long SvyCod;
long DegCod;
long CrsCod;
Sco_Scope_t Scope; Sco_Scope_t Scope;
long Cod; // Country, institution, centre, degree or course code
unsigned Roles; // Example: if survey can be made by students and teachers, Roles == (1 << Rol_ROLE_STUDENT) | (1 << Rol_ROLE_TEACHER) unsigned Roles; // Example: if survey can be made by students and teachers, Roles == (1 << Rol_ROLE_STUDENT) | (1 << Rol_ROLE_TEACHER)
long UsrCod; long UsrCod;
char Title[Svy_MAX_LENGTH_SURVEY_TITLE+1]; char Title[Svy_MAX_LENGTH_SURVEY_TITLE+1];
@ -59,7 +58,7 @@ struct Survey
bool Visible; // Survey is not hidden bool Visible; // Survey is not hidden
bool Open; // Start date <= now <= end date bool Open; // Start date <= now <= end date
bool IAmLoggedWithAValidRoleToAnswer; // I am logged with a valid role to answer this survey bool IAmLoggedWithAValidRoleToAnswer; // I am logged with a valid role to answer this survey
bool IBelongToDegCrsGrps; // I can answer this survey (it is associated to no groups or (if associated to groups) I belong to any of the groups bool IBelongToScope; // I belong to the scope of this survey
bool IHaveAnswered; // I have already answered this survey bool IHaveAnswered; // I have already answered this survey
bool ICanAnswer; bool ICanAnswer;
bool ICanViewResults; bool ICanViewResults;

View File

@ -938,6 +938,53 @@ bool Usr_CheckIfUsrSharesAnyOfMyCrsWithDifferentRole (long UsrCod)
return UsrSharesAnyOfMyCrsWithDifferentRole; return UsrSharesAnyOfMyCrsWithDifferentRole;
} }
/*****************************************************************************/
/**** Get all my countries (those of my courses) and store them in a list ****/
/*****************************************************************************/
void Usr_GetMyCountries (void)
{
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned NumCty;
unsigned NumCtys;
long CtyCod;
/***** If my countries are yet filled, there's nothing to do *****/
if (!Gbl.Usrs.Me.MyCountries.Filled)
{
Gbl.Usrs.Me.MyCountries.Num = 0;
/***** Get my institutions from database *****/
if ((NumCtys = (unsigned) Usr_GetCtysFromUsr (Gbl.Usrs.Me.UsrDat.UsrCod,&mysql_res)) > 0) // Countries found
for (NumCty = 0;
NumCty < NumCtys;
NumCty++)
{
/* Get next country */
row = mysql_fetch_row (mysql_res);
/* Get country code */
if ((CtyCod = Str_ConvertStrCodToLongCod (row[0])) > 0)
{
if (Gbl.Usrs.Me.MyCountries.Num == Cty_MAX_COUNTRIES_PER_USR)
Lay_ShowErrorAndExit ("Maximum number of countries of a user exceeded.");
Gbl.Usrs.Me.MyCountries.Ctys[Gbl.Usrs.Me.MyCountries.Num].CtyCod = CtyCod;
Gbl.Usrs.Me.MyCountries.Ctys[Gbl.Usrs.Me.MyCountries.Num].MaxRole = Rol_ConvertUnsignedStrToRole (row[1]);
Gbl.Usrs.Me.MyCountries.Num++;
}
}
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
/***** Set boolean that indicates that my institutions are yet filled *****/
Gbl.Usrs.Me.MyCountries.Filled = true;
}
}
/*****************************************************************************/ /*****************************************************************************/
/** Get all my institutions (those of my courses) and store them in a list ***/ /** Get all my institutions (those of my courses) and store them in a list ***/
/*****************************************************************************/ /*****************************************************************************/
@ -1295,10 +1342,29 @@ bool Usr_CheckIfUsrBelongsToCrs (long UsrCod,
return (DB_QueryCOUNT (Query,"can not check if a user belongs to a course") != 0); return (DB_QueryCOUNT (Query,"can not check if a user belongs to a course") != 0);
} }
/*****************************************************************************/
/********************** Check if I belong to a country **********************/
/*****************************************************************************/
bool Usr_CheckIfIBelongToCty (long CtyCod)
{
unsigned NumMyCty;
/***** Fill the list with the institutions I belong to *****/
Usr_GetMyCountries ();
/***** Check if the country passed as parameter is any of my countries *****/
for (NumMyCty = 0;
NumMyCty < Gbl.Usrs.Me.MyCountries.Num;
NumMyCty++)
if (Gbl.Usrs.Me.MyCountries.Ctys[NumMyCty].CtyCod == CtyCod)
return true;
return false;
}
/*****************************************************************************/ /*****************************************************************************/
/******************** Check if I belong to an institution ********************/ /******************** Check if I belong to an institution ********************/
/*****************************************************************************/ /*****************************************************************************/
// The list of my institutions must be filled before calling this function
bool Usr_CheckIfIBelongToIns (long InsCod) bool Usr_CheckIfIBelongToIns (long InsCod)
{ {
@ -1319,7 +1385,6 @@ bool Usr_CheckIfIBelongToIns (long InsCod)
/*****************************************************************************/ /*****************************************************************************/
/*********************** Check if I belong to a centre ***********************/ /*********************** Check if I belong to a centre ***********************/
/*****************************************************************************/ /*****************************************************************************/
// The list of my centres must be filled before calling this function
bool Usr_CheckIfIBelongToCtr (long CtrCod) bool Usr_CheckIfIBelongToCtr (long CtrCod)
{ {
@ -1340,7 +1405,6 @@ bool Usr_CheckIfIBelongToCtr (long CtrCod)
/*****************************************************************************/ /*****************************************************************************/
/*********************** Check if I belong to a degree ***********************/ /*********************** Check if I belong to a degree ***********************/
/*****************************************************************************/ /*****************************************************************************/
// The list of my degrees must be filled before calling this function
bool Usr_CheckIfIBelongToDeg (long DegCod) bool Usr_CheckIfIBelongToDeg (long DegCod)
{ {
@ -1361,7 +1425,6 @@ bool Usr_CheckIfIBelongToDeg (long DegCod)
/*****************************************************************************/ /*****************************************************************************/
/*********************** Check if I belong to a course ***********************/ /*********************** Check if I belong to a course ***********************/
/*****************************************************************************/ /*****************************************************************************/
// The list of my courses must be filled before calling this function
bool Usr_CheckIfIBelongToCrs (long CrsCod) bool Usr_CheckIfIBelongToCrs (long CrsCod)
{ {

View File

@ -234,11 +234,14 @@ unsigned Usr_GetNumUsrsInCrssOfAUsr (long UsrCod,Rol_Role_t UsrRole,
Rol_Role_t OthersRole); Rol_Role_t OthersRole);
bool Usr_CheckIfUsrSharesAnyOfMyCrs (long UsrCod); bool Usr_CheckIfUsrSharesAnyOfMyCrs (long UsrCod);
bool Usr_CheckIfUsrSharesAnyOfMyCrsWithDifferentRole (long UsrCod); bool Usr_CheckIfUsrSharesAnyOfMyCrsWithDifferentRole (long UsrCod);
void Usr_GetMyCountries (void);
void Usr_GetMyInstitutions (void); void Usr_GetMyInstitutions (void);
void Usr_GetMyCentres (void); void Usr_GetMyCentres (void);
void Usr_GetMyDegrees (void); void Usr_GetMyDegrees (void);
void Usr_GetMyCourses (void); void Usr_GetMyCourses (void);
void Usr_FreeMyCourses (void); void Usr_FreeMyCourses (void);
bool Usr_CheckIfUsrBelongsToIns (long UsrCod, bool Usr_CheckIfUsrBelongsToIns (long UsrCod,
long InsCod, long InsCod,
bool CountOnlyAcceptedCourses); bool CountOnlyAcceptedCourses);
@ -251,6 +254,8 @@ bool Usr_CheckIfUsrBelongsToDeg (long UsrCod,
bool Usr_CheckIfUsrBelongsToCrs (long UsrCod, bool Usr_CheckIfUsrBelongsToCrs (long UsrCod,
long CrsCod, long CrsCod,
bool CountOnlyAcceptedCourses); bool CountOnlyAcceptedCourses);
bool Usr_CheckIfIBelongToCty (long CtyCod);
bool Usr_CheckIfIBelongToIns (long InsCod); bool Usr_CheckIfIBelongToIns (long InsCod);
bool Usr_CheckIfIBelongToCtr (long CtrCod); bool Usr_CheckIfIBelongToCtr (long CtrCod);
bool Usr_CheckIfIBelongToDeg (long DegCod); bool Usr_CheckIfIBelongToDeg (long DegCod);