tests_category.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. /**
  4. hubert.borderiou
  5. Manage tests category page
  6. */
  7. // name of the language file that needs to be included
  8. $language_file = 'exercice';
  9. $nameTools = "";
  10. require_once '../inc/global.inc.php';
  11. require_once 'question.class.php';
  12. $this_section = SECTION_COURSES;
  13. if (!(api_is_allowed_to_edit() || api_is_question_manager())) {
  14. api_not_allowed(true);
  15. }
  16. $type = isset($_GET['type']) ? Security::remove_XSS($_GET['type']) : 'simple';
  17. if ($type == 'global' && !(api_is_platform_admin() || api_is_question_manager())) {
  18. api_not_allowed(true);
  19. }
  20. $url = api_get_path(WEB_AJAX_PATH).'exercise.ajax.php?type='.$type;
  21. $htmlHeadXtra[] = '
  22. <script>
  23. function confirmDelete(in_txt, in_id) {
  24. var oldbgcolor = document.getElementById(in_id).style.backgroundColor;
  25. document.getElementById(in_id).style.backgroundColor="#AAFFB0";
  26. if (confirm(in_txt)) {
  27. return true;
  28. }
  29. else {
  30. document.getElementById(in_id).style.backgroundColor = oldbgcolor;
  31. return false;
  32. }
  33. }
  34. function check() {
  35. $("#parent_id option:selected").each(function() {
  36. var id = $(this).val();
  37. var name = $(this).text();
  38. if (id != "" ) {
  39. $.ajax({
  40. async: false,
  41. url: "'.$url.'&a=exercise_category_exists",
  42. data: "id="+id,
  43. success: function(return_value) {
  44. if (return_value == 0 ) {
  45. alert("'.get_lang('CategoryDoesNotExists').'");
  46. //Deleting select option tag
  47. $("#parent_id").find("option").remove();
  48. $(".holder li").each(function () {
  49. if ($(this).attr("rel") == id) {
  50. $(this).remove();
  51. }
  52. });
  53. }
  54. }
  55. });
  56. }
  57. });
  58. }
  59. $(function() {
  60. $("#parent_id").fcbkcomplete({
  61. json_url: "'.$url.'&a=search_category_parent",
  62. maxitems: 1,
  63. addontab: false,
  64. input_min_size: 1,
  65. cache: false,
  66. complete_text:"'.get_lang('StartToType').'",
  67. firstselected: false,
  68. onselect: check,
  69. filter_selected: true,
  70. newel: true
  71. });
  72. });
  73. </script>';
  74. $htmlHeadXtra[] = '<script src="'.api_get_path(WEB_LIBRARY_PATH).'javascript/tag/jquery.fcbkcomplete.js" type="text/javascript" language="javascript"></script>';
  75. $htmlHeadXtra[] = '<link href="'.api_get_path(WEB_LIBRARY_PATH).'javascript/tag/style.css" rel="stylesheet" type="text/css" />';
  76. // Breadcrumbs
  77. $interbreadcrumb[] = array("url" => "exercice.php", "name" => get_lang('Exercices'));
  78. Display::display_header(get_lang('Category'));
  79. // Action handling: add, edit and remove
  80. if (isset($_GET['action']) && $_GET['action'] == 'addcategory') {
  81. add_category_form($_GET['action'], $type);
  82. } else if (isset($_GET['action']) && $_GET['action'] == 'addcategoryglobal') {
  83. add_category_form($_GET['action'], $type);
  84. } else if (isset($_GET['action']) && $_GET['action'] == 'editcategory') {
  85. edit_category_form($_GET['action'], $type);
  86. } else if (isset($_GET['action']) && $_GET['action'] == 'deletecategory') {
  87. delete_category_form($_GET['action'], $type);
  88. } else {
  89. display_add_category($type);
  90. display_categories($type);
  91. }
  92. Display::display_footer();
  93. // FUNCTIONS
  94. // form to edit a category
  95. function edit_category_form($in_action, $type = 'simple') {
  96. $in_action = Security::remove_XSS($in_action);
  97. if (isset($_GET['category_id']) && is_numeric($_GET['category_id'])) {
  98. $category_id = Security::remove_XSS($_GET['category_id']);
  99. $objcat = new Testcategory($category_id);
  100. // initiate the object
  101. $form = new FormValidator('note', 'post', api_get_self().'?'.api_get_cidreq().'&action='.$in_action.'&category_id='.$category_id."&type=".$type);
  102. $objcat->getForm($form, 'edit');
  103. // The validation or display
  104. if ($form->validate()) {
  105. $check = Security::check_token('post');
  106. if ($check) {
  107. $values = $form->getSubmitValues();
  108. $v_id = $values['category_id'];
  109. $v_name = $values['category_name'];
  110. $v_description = $values['category_description'];
  111. $parent_id = isset($values['parent_id']) ? $values['parent_id'] : null;
  112. $visibility = isset($values['visibility']) ? $values['visibility'] : 1;
  113. $objcat = new Testcategory($v_id, $v_name, $v_description, $parent_id, $type, null, $visibility);
  114. if ($objcat->modifyCategory()) {
  115. Display::display_confirmation_message(get_lang('MofidfyCategoryDone'));
  116. } else {
  117. Display::display_confirmation_message(get_lang('ModifyCategoryError'));
  118. }
  119. }
  120. Security::clear_token();
  121. display_add_category($type);
  122. display_categories($type);
  123. } else {
  124. display_goback($type);
  125. $token = Security::get_token();
  126. $form->addElement('hidden', 'sec_token');
  127. $form->setConstants(array('sec_token' => $token));
  128. $form->display();
  129. display_categories($type);
  130. }
  131. } else {
  132. Display::display_error_message(get_lang('CannotEditCategory'));
  133. }
  134. }
  135. // process to delete a category
  136. function delete_category_form($in_action, $type = 'simple')
  137. {
  138. $in_action = Security::remove_XSS($in_action);
  139. if (isset($_GET['category_id']) && is_numeric($_GET['category_id'])) {
  140. $category_id = Security::remove_XSS($_GET['category_id']);
  141. $catobject = new Testcategory($category_id);
  142. if ($catobject->getCategoryQuestionsNumber() == 0) {
  143. if ($catobject->removeCategory()) {
  144. Display::display_confirmation_message(get_lang('DeleteCategoryDone'));
  145. } else {
  146. Display::display_error_message(get_lang('CannotDeleteCategoryError'));
  147. }
  148. } else {
  149. Display::display_error_message(get_lang('CannotDeleteCategory'));
  150. }
  151. } else {
  152. Display::display_error_message(get_lang('CannotDeleteCategoryError'));
  153. }
  154. display_add_category($type);
  155. display_categories($type);
  156. }
  157. // Form to add a category
  158. function add_category_form($in_action, $type = 'simple')
  159. {
  160. $in_action = Security::remove_XSS($in_action);
  161. // Initiate the object
  162. $form = new FormValidator('note', 'post', api_get_self().'?'.api_get_cidreq().'&action='.$in_action."&type=".$type);
  163. // Setting the form elements
  164. $form->addElement('header', get_lang('AddACategory'));
  165. $form->addElement('text', 'category_name', get_lang('CategoryName'), array('class' => 'span6'));
  166. $form->add_html_editor('category_description', get_lang('CategoryDescription'), false, false, array('ToolbarSet' => 'test_category', 'Width' => '90%', 'Height' => '200'));
  167. $form->addElement('select', 'parent_id', get_lang('Parent'), array(), array('id' => 'parent_id'));
  168. $form->addElement('style_submit_button', 'SubmitNote', get_lang('AddTestCategory'), 'class="add"');
  169. // Setting the rules
  170. $form->addRule('category_name', get_lang('ThisFieldIsRequired'), 'required');
  171. // The validation or display
  172. if ($form->validate()) {
  173. $check = Security::check_token('post');
  174. if ($check) {
  175. $values = $form->getSubmitValues();
  176. $parent_id = isset($values['parent_id']) && isset($values['parent_id'][0]) ? $values['parent_id'][0] : null;
  177. $objcat = new Testcategory(0, $values['category_name'], $values['category_description'], $parent_id, $type, api_get_course_int_id());
  178. if ($objcat->addCategoryInBDD()) {
  179. Display::display_confirmation_message(get_lang('AddCategoryDone'));
  180. } else {
  181. Display::display_confirmation_message(get_lang('AddCategoryNameAlreadyExists'));
  182. }
  183. }
  184. Security::clear_token();
  185. display_add_category($type);
  186. display_categories($type);
  187. } else {
  188. display_goback($type);
  189. $token = Security::get_token();
  190. $form->addElement('hidden', 'sec_token');
  191. $form->setConstants(array('sec_token' => $token));
  192. $form->display();
  193. }
  194. }
  195. // Display add category button
  196. function display_add_category($type) {
  197. echo '<div class="actions">';
  198. echo '<a href="exercice.php?' . api_get_cidreq() . '">' . Display::return_icon('back.png', get_lang('GoBackToQuestionList'), '', ICON_SIZE_MEDIUM) . '</a>';
  199. $icon = "question_category.gif";
  200. if ($type == 'global') {
  201. $icon = "folder_global_category_new.png";
  202. }
  203. echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&action=addcategory&type='.$type.'">'.Display::return_icon($icon, get_lang('AddACategory'), array(), ICON_SIZE_MEDIUM).'</a>';
  204. echo '</div>';
  205. echo "<br/>";
  206. if ($type == 'simple') {
  207. echo "<fieldset><legend>" . get_lang('QuestionCategory') . "</legend></fieldset>";
  208. } else {
  209. echo "<fieldset><legend>".get_lang('QuestionGlobalCategory')."</legend></fieldset>";
  210. }
  211. }
  212. // Display category list
  213. function display_categories($type = 'simple') {
  214. global $app;
  215. $options = array(
  216. 'decorate' => true,
  217. 'rootOpen' => '<ul>',
  218. 'rootClose' => '</ul>',
  219. 'childOpen' => '<li>',
  220. 'childClose' => '</li>',
  221. 'nodeDecorator' => function($row) use ($type) {
  222. $category_id = $row['iid'];
  223. $courseId = $row['cId'];
  224. $tmpobj = new Testcategory($category_id);
  225. $nb_question = $tmpobj->getCategoryQuestionsNumber();
  226. $nb_question_label = $nb_question == 1 ? $nb_question . ' ' . get_lang('Question') : $nb_question . ' ' . get_lang('Questions');
  227. $nb_question_label = Display::label($nb_question_label, 'info');
  228. $actions = null;
  229. if ($courseId == 0 && $type == 'simple') {
  230. $actions .= Display::return_icon('edit_na.png', get_lang('Edit'), array(), ICON_SIZE_SMALL);
  231. } else {
  232. $actions .= '<a href="'.api_get_self().'?action=editcategory&category_id='.$category_id.'&type='.$type.'">'.Display::return_icon('edit.png', get_lang('Edit'), array(), ICON_SIZE_SMALL).'</a>';
  233. }
  234. if ($nb_question > 0 && $courseId == 0 && $type == 'simple') {
  235. $actions .= '<a href="javascript:void(0)" onclick="alert(\'' . protectJSDialogQuote(get_lang('CannotDeleteCategory')) . '\')">';
  236. $actions .= Display::return_icon('delete_na.png', get_lang('CannotDeleteCategory'), array(), ICON_SIZE_SMALL);
  237. $actions .='</a>';
  238. } else {
  239. $rowname = protectJSDialogQuote($row['title']);
  240. $actions .= ' <a href="'.api_get_self().'?action=deletecategory&amp;category_id='.$category_id.'&type='.$type.'"';
  241. $actions .= 'onclick="return confirmDelete(\''.protectJSDialogQuote(get_lang('DeleteCategoryAreYouSure').'['.$rowname).'] ?\', \'id_cat'.$category_id.'\');">';
  242. $actions .= Display::return_icon('delete.png', get_lang('Delete'), array(), ICON_SIZE_SMALL) . '</a>';
  243. }
  244. return $row['title'].' '.$nb_question_label.' '.$actions;
  245. }
  246. //'representationField' => 'slug',
  247. //'html' => true
  248. );
  249. // @todo put this in a function
  250. $repo = $app['orm.em']->getRepository('Entity\CQuizCategory');
  251. $query = null;
  252. if ($type == 'global') {
  253. $query = $app['orm.em']
  254. ->createQueryBuilder()
  255. ->select('node')
  256. ->from('Entity\CQuizCategory', 'node')
  257. ->where('node.cId = 0')
  258. ->orderBy('node.root, node.lft', 'ASC')
  259. ->getQuery();
  260. } else {
  261. $query = $app['orm.em']
  262. ->createQueryBuilder()
  263. ->select('node')
  264. ->from('Entity\CQuizCategory', 'node')
  265. ->where('node.cId = :courseId')
  266. //->add('orderBy', 'node.title ASC')
  267. ->orderBy('node.root, node.lft', 'ASC')
  268. ->setParameter('courseId', api_get_course_int_id())
  269. ->getQuery();
  270. }
  271. $htmlTree = $repo->buildTree($query->getArrayResult(), $options);
  272. /*
  273. $htmlTree = $repo->childrenHierarchy(
  274. null, //starting from root nodes
  275. false, //load all children, not only direct
  276. $options
  277. );*/
  278. echo $htmlTree;
  279. return true;
  280. }
  281. // display goback to category list page link
  282. function display_goback($type) {
  283. $type = Security::remove_XSS($type);
  284. echo '<div class="actions">';
  285. echo '<a href="'.api_get_self().'?type='.$type.'">'.Display::return_icon('back.png', get_lang('BackToCategoryList'), array(), 32).'</a>';
  286. echo '</div>';
  287. }
  288. // To allowed " in javascript dialog box without bad surprises
  289. // replace " with two '
  290. function protectJSDialogQuote($in_txt) {
  291. $res = $in_txt;
  292. $res = str_replace("'", "\'", $res);
  293. $res = str_replace('"', "\'\'", $res); // super astuce pour afficher les " dans les boite de dialogue
  294. return $res;
  295. }