#include #include #include #include #include #include "ClearSilver.h" #include "sqlite3.h" #include "global.h" #include "custom.h" /* for date FORMAT strings */ #include "grade.h" /* for date FORMAT strings */ #include "manhat-lib/shared_util.h" #include "manhat-lib/shared_grade_book_menu.h" #include "manhat-lib/shared_grade_book_util.h" #include "manhat-lib/shared_grade_book_db.h" void read_parameters ( char *course, char *key, int *save_option, int *cat_id) { char temp[MAX_KEY]; char *ptr; cs_get_required_parameter("crs", course, MAX_PATH); cs_get_required_parameter("id", key, MAX_KEY); cs_get_required_parameter("save_option", temp, MAX_KEY); if(strcmp(temp, "save") == 0) *save_option = 1; else if(strcmp(temp, "no") == 0) *save_option = 0; else { ptr = strstr(temp, "delete"); if(!ptr) cs_critical_error(ERR_PARAM_MISSING, "delete"); ptr = strchr(temp, ':'); if(!ptr) cs_critical_error(ERR_PARAM_MISSING, "delete"); *ptr = '\0'; ptr++; *save_option = 2; *cat_id = atoi(ptr); } } int check_name(char *cat_name, CATEGORY *dest) { if(!strlen(cat_name)) { *(dest->cat_name) = '\0'; return 0; } strncpy(dest->cat_name, cat_name, MAX_CAT_LEN +1); if(!check_spe_char(cat_name)) return 0; return 1; } int check_weight(const char *weight, char *ungraded, CATEGORY *ptr) { double value; if(!strlen(weight)) { ptr->weight = 0; return 0; } if(!check_float_number(weight)) { ptr->weight = 0; return 0; } value = atof(weight); if(!strcmp(ungraded, "yes")) { if(value > 0) { ptr->weight = value; return 0; } } ptr->weight = value; return 1; } CATEGORY_LIST * check_all_categories(int *error, double *total, int *no_id) { #define MAX_TMP 40 CATEGORY_LIST *cat_list; CATEGORY *ptr; char name[MAX_TMP]; int number_categories =0, i =0; char *weight = 0, *cat_name = 0, *cat_id =0, *ungraded =0, *drop =0; int error_count = 0; double total_weight = 0; int no_id_count =0; number_categories = hdf_get_int_value(global_cgi->hdf, "Query.number_categories", 0); if(number_categories == 0) cs_critical_error(ERR_PARAM_MISSING, "check_all_categories"); cs_set_int_value("number_categories", number_categories); cat_list = ( CATEGORY_LIST *)malloc(sizeof(CATEGORY_LIST)); if(!cat_list) cs_critical_error(ERR_MALLOC_FAILED, "check_all_categories"); cat_list->head =0; cat_list->current =0; for (i = 1; i<=number_categories; i++) { snprintf(name, MAX_TMP, "Query.cat_name_%d", i); cat_name = hdf_get_value(global_cgi->hdf, name, ""); snprintf(name, MAX_TMP, "categories.%d.cat_name", i); cs_set_value(name, cat_name); snprintf(name, MAX_TMP, "Query.cat_id_%d", i); cat_id = hdf_get_value(global_cgi->hdf, name, ""); snprintf(name, MAX_TMP, "categories.%d.cat_id", i); cs_set_value(name, cat_id); snprintf(name, MAX_TMP, "Query.cat_weight_%d", i); weight = hdf_get_value(global_cgi->hdf, name, ""); snprintf(name, MAX_TMP, "categories.%d.cat_weight", i); cs_set_value(name, weight); snprintf(name, MAX_TMP, "Query.cat_ungraded_%d", i); ungraded = hdf_get_value(global_cgi->hdf, name, ""); snprintf(name, MAX_TMP, "categories.%d.cat_ungraded", i); cs_set_value(name, ungraded); snprintf(name, MAX_TMP, "Query.cat_drop_%d", i); drop = hdf_get_value(global_cgi->hdf, name, ""); snprintf(name, MAX_TMP, "categories.%d.cat_drop", i); cs_set_value(name, drop); if( strlen(cat_name) || strlen(weight) || strlen(ungraded)) { ptr = (CATEGORY *)malloc(sizeof(CATEGORY)); if(!ptr) cs_critical_error(ERR_MALLOC_FAILED, "check_all_categories"); ptr->next = 0; if(!check_name(cat_name, ptr)) error_count++; if(!check_weight(weight, ungraded, ptr)) error_count++; else total_weight = total_weight + ptr->weight; if(strlen(cat_id)) ptr->cat_id = atoi(cat_id); else { ptr->cat_id = -1; no_id_count++; } ptr->drop_lowest = atoi(drop); if(!cat_list->head) cat_list->head = ptr; else cat_list->current->next = ptr; cat_list->current = ptr; } } *error = error_count; *total = total_weight; *no_id = no_id_count; return cat_list; #undef MAX_TMP } int get_count(CATEGORY_LIST *cat_list) { int count = 0; CATEGORY *ptr; for( ptr = cat_list->head; ptr; ptr = ptr->next) { if(ptr->cat_id != -1) count++; } return count; } int check_conflict(CATEGORY_LIST *category_list, int no_id, CONFIG_STRUCT *conf) { int g_count =0; int new_count =0; if(!no_id) return 1; get_categories(conf, GRADE_BOOK_DB); /* shared_grade_book_db.h */ if(global_cat_list && global_cat_list->head) { g_count = get_count(global_cat_list); new_count = get_count(category_list); if(g_count == new_count) return 1; else return 0; } else return 1; } void save_categories( CATEGORY_LIST *category_list, CONFIG_STRUCT *conf, int no_id) { char path[MAX_PATH +1]; int ret = 0; sqlite3 *db; char *stmt; CATEGORY *ptr; if(check_conflict(category_list, no_id, conf)) { snprintf(path, MAX_PATH +1, "%s%s/%s", conf->course_path, GRADE_BOOK_DIR, GRADE_BOOK_DB); ret = sqlite3_open(path, &db); if(ret) cs_critical_error(ERR_GRADES_DB, "save categories function"); ret = sqlite3_exec(db, "Begin transaction insert_update_category", 0, 0, 0); if(ret) { cs_critical_error(ERR_GRADES_DB, "begin insert categories function"); sqlite3_close(db); } for(ptr = category_list->head; ptr; ptr = ptr->next) { if(ptr->cat_id == -1) stmt = sqlite3_mprintf("insert into Categories values(NULL, '%q', %4.2f, %d)", ptr->cat_name, ptr->weight, ptr->drop_lowest); else stmt = sqlite3_mprintf("update Categories set catName='%q', weight=%4.2f, dropLowest=%d where catId=%d", ptr->cat_name, ptr->weight, ptr->drop_lowest, ptr->cat_id); if(stmt) { ret = sqlite3_exec(db, stmt, 0,0,0); if(ret) { sqlite3_free(stmt); sqlite3_close(db); cs_critical_error(ERR_GRADES_DB, "error insert/update categories function"); } sqlite3_free(stmt); } } ret = sqlite3_exec(db, "commit transaction insert_update_category", 0, 0, 0); ret = sqlite3_exec(db, "end transaction insert_update_category", 0, 0, 0); sqlite3_close(db); } } void delete_category(int cat_id, CONFIG_STRUCT *conf) { char path[MAX_PATH +1]; int ret = 0; sqlite3 *db; char *stmt; snprintf(path, MAX_PATH +1, "%s%s/%s", conf->course_path, GRADE_BOOK_DIR, GRADE_BOOK_DB); ret = sqlite3_open(path, &db); if(ret) cs_critical_error(ERR_GRADES_DB, "delete category function"); stmt = sqlite3_mprintf("delete from Categories where catId=%d ", cat_id); if(stmt) { ret = sqlite3_exec(db, stmt, 0,0,0); if(ret) { sqlite3_free(stmt); sqlite3_close(db); cs_critical_error(ERR_GRADES_DB, "error delete category function"); } sqlite3_free(stmt); } sqlite3_close(db); } void do_action(const char *course, const char *key, int save_opt, CONFIG_STRUCT *conf, int cat_id) { char *next_url =0; int error = 0; double total = 0; int no_id = 0; CATEGORY_LIST *category_list; next_url = hdf_get_value(global_cgi->hdf, "Query.nextUrl", ""); if(strlen(next_url) == 0) cs_critical_error(ERR_PARAM_MISSING, "grade_book_categories_save, do action function"); if(save_opt == 0) /* do not save anything */ printf("Location: %s\n\n", next_url); else if(save_opt == 1) /* save changes or new categories */ { category_list = check_all_categories(&error, &total, &no_id); if(error || total > 100 || total < 100) { cs_critical_error(ERR_GENERAL_ERROR,"There is a problem with one or more values on this page. Does the sum of your weights equal 100? Did you use anything but A-Z, a-z, 0-9, in category names?"); } else { if(category_list->head) save_categories(category_list, conf, no_id); free_category_list(category_list); printf("Location: %s\n\n", next_url); } } else if(save_opt == 2) { delete_category(cat_id, conf); printf("Location: %s\n\n", next_url); } } int main () { char course[MAX_PATH +1]; char key[MAX_KEY +1]; int save_option = 0, cat_id; SESSION user; CONFIG_STRUCT conf; cs_cgi_init(); /* shared_cs_util.h */ read_parameters ( course, key, &save_option, &cat_id); read_configuration_file (course, &conf); validate_key (key, &user, &conf); if(user.group != FACULTY) cs_critical_error(ERR_REQUEST_DENIED, ""); do_action(course, key, save_option, &conf, cat_id); cs_cgi_destroy(); return 0; }