evalform.class.php 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. /**
  4. * Class EvalForm
  5. *
  6. * Extends FormValidator with add&edit forms for evaluations
  7. * @author Stijn Konings
  8. * @package chamilo.gradebook
  9. */
  10. class EvalForm extends FormValidator
  11. {
  12. const TYPE_ADD = 1;
  13. const TYPE_EDIT = 2;
  14. const TYPE_MOVE = 3;
  15. const TYPE_RESULT_ADD = 4;
  16. const TYPE_RESULT_EDIT = 5;
  17. const TYPE_ALL_RESULTS_EDIT = 6;
  18. const TYPE_ADD_USERS_TO_EVAL = 7;
  19. private $evaluation_object;
  20. private $result_object;
  21. private $extra;
  22. /**
  23. * Builds a form containing form items based on a given parameter
  24. * @param int $form_type 1=add, 2=edit,3=move,4=result_add
  25. * @param Evaluation $evaluation_object the category object
  26. * @param obj $result_object the result object
  27. * @param string $form_name
  28. * @param string $method
  29. * @param string $action
  30. */
  31. public function __construct(
  32. $form_type,
  33. $evaluation_object,
  34. $result_object,
  35. $form_name,
  36. $method = 'post',
  37. $action = null,
  38. $extra1 = null,
  39. $extra2 = null
  40. ) {
  41. parent::__construct($form_name, $method, $action);
  42. if (isset($evaluation_object)) {
  43. $this->evaluation_object = $evaluation_object;
  44. }
  45. if (isset($result_object)) {
  46. $this->result_object = $result_object;
  47. }
  48. if (isset($extra1)) {
  49. $this->extra = $extra1;
  50. }
  51. switch ($form_type) {
  52. case self::TYPE_EDIT:
  53. $this->build_editing_form();
  54. break;
  55. case self::TYPE_ADD:
  56. $this->build_add_form();
  57. break;
  58. case self::TYPE_MOVE:
  59. $this->build_editing_form();
  60. break;
  61. case self::TYPE_RESULT_ADD:
  62. $this->build_result_add_form();
  63. break;
  64. case self::TYPE_RESULT_EDIT:
  65. $this->build_result_edit_form();
  66. break;
  67. case self::TYPE_ALL_RESULTS_EDIT:
  68. $this->build_all_results_edit_form();
  69. break;
  70. case self::TYPE_ADD_USERS_TO_EVAL:
  71. $this->build_add_user_to_eval();
  72. break;
  73. }
  74. $this->setDefaults();
  75. }
  76. /**
  77. * This form will build a form to add users to an evaluation
  78. */
  79. protected function build_add_user_to_eval()
  80. {
  81. $this->addElement('header', get_lang('ChooseUser'));
  82. $select = $this->addElement(
  83. 'select',
  84. 'firstLetterUser',
  85. get_lang('FirstLetter'),
  86. null,
  87. array(
  88. 'onchange' => 'document.add_users_to_evaluation.submit()',
  89. )
  90. );
  91. $select->addOption('', '');
  92. for ($i = 65; $i <= 90; $i++) {
  93. $letter = chr($i);
  94. if (isset($this->extra) && $this->extra == $letter) {
  95. $select->addOption($letter, $letter, 'selected');
  96. } else {
  97. $select->addOption($letter, $letter);
  98. }
  99. }
  100. $select = $this->addElement(
  101. 'select',
  102. 'add_users',
  103. null,
  104. null,
  105. array(
  106. 'multiple' => 'multiple',
  107. 'size' => '15',
  108. 'style' => 'width:250px',
  109. )
  110. );
  111. foreach ($this->evaluation_object->get_not_subscribed_students() as $user) {
  112. if ((!isset($this->extra)) || empty($this->extra) || api_strtoupper(api_substr($user[1], 0, 1)) == $this->extra
  113. ) {
  114. $select->addoption($user[1].' '.$user[2].' ('.$user[3].')', $user[0]);
  115. }
  116. }
  117. $this->addButtonCreate(get_lang('AddUserToEval'), 'submit_button');
  118. }
  119. /**
  120. * This function builds a form to edit all results in an evaluation
  121. */
  122. protected function build_all_results_edit_form()
  123. {
  124. //extra field for check on maxvalue
  125. $this->addElement('header', get_lang('EditResult'));
  126. $renderer = &$this->defaultRenderer();
  127. // set new form template
  128. $form_template = '<form{attributes}>
  129. <table class="data_table" border="0" cellpadding="5" cellspacing="5">{content}
  130. </table>
  131. </form>';
  132. $renderer->setFormTemplate($form_template);
  133. if (api_is_western_name_order()) {
  134. $renderer->setHeaderTemplate(
  135. '<tr>
  136. <th>'.get_lang('OfficialCode').'</th>
  137. <th>'.get_lang('UserName').'</th>
  138. <th>'.get_lang('FirstName').'</th>
  139. <th>'.get_lang('LastName').'</th>
  140. <th>'.get_lang('Qualify').'</th>
  141. </tr>'
  142. );
  143. } else {
  144. $renderer->setHeaderTemplate(
  145. '<tr>
  146. <th>'.get_lang('OfficialCode').'</th>
  147. <th>'.get_lang('UserName').'</th>
  148. <th>'.get_lang('LastName').'</th>
  149. <th>'.get_lang('FirstName').'</th>
  150. <th>'.get_lang('Qualify').'</th>
  151. </tr>'
  152. );
  153. }
  154. $template_submit = '<tr>
  155. <td colspan="4" ></td>
  156. <td>
  157. {element}
  158. <!-- BEGIN error --><br /><span style="color: #ff0000;font-size:10px">{error}</span><!-- END error -->
  159. </td>
  160. </tr>';
  161. $results_and_users = array();
  162. foreach ($this->result_object as $result) {
  163. $user = api_get_user_info($result->get_user_id());
  164. $results_and_users[] = array('result' => $result, 'user' => $user);
  165. }
  166. usort($results_and_users, array('EvalForm', 'sort_by_user'));
  167. $defaults = array();
  168. foreach ($results_and_users as $result_and_user) {
  169. $user = $result_and_user['user'];
  170. $result = $result_and_user['result'];
  171. $renderer = &$this->defaultRenderer();
  172. $this->addFloat(
  173. 'score['.$result->get_id().']',
  174. $this->build_stud_label($user['user_id'], $user['username'], $user['lastname'], $user['firstname']),
  175. false,
  176. array(
  177. 'maxlength' => 5
  178. ),
  179. false,
  180. 0,
  181. $this->evaluation_object->get_max()
  182. );
  183. $defaults['score['.$result->get_id().']'] = $result->get_score();
  184. if (api_is_western_name_order()) {
  185. $user_info = '<td align="left" >'.$user['firstname'].'</td>';
  186. $user_info .= '<td align="left" >'.$user['lastname'].'</td>';
  187. } else {
  188. $user_info = '<td align="left" >'.$user['lastname'].'</td>';
  189. $user_info .= '<td align="left" >'.$user['firstname'].'</td>';
  190. }
  191. $template = '<tr>
  192. <td align="left" >'.$user['official_code'].'</td>
  193. <td align="left" >'.$user['username'].'</td>
  194. '.$user_info.'
  195. <td align="left">{element} / '.$this->evaluation_object->get_max().'
  196. <!-- BEGIN error --><br /><span style="color: #ff0000;font-size:10px">{error}</span><!-- END error -->
  197. </td>
  198. </tr>';
  199. $renderer->setElementTemplate($template, 'score['.$result->get_id().']');
  200. }
  201. $this->setDefaults($defaults);
  202. $this->addButtonSave(get_lang('EditResult'), 'submit');
  203. $renderer->setElementTemplate($template_submit, 'submit');
  204. }
  205. /**
  206. * This function builds a form to move an item to another category
  207. *
  208. */
  209. protected function build_move_form()
  210. {
  211. $renderer = &$this->defaultRenderer();
  212. $renderer->setCustomElementTemplate('<span>{element}</span> ');
  213. $this->addElement('static', null, null, '"'.$this->evaluation_object->get_name().'" ');
  214. $this->addElement('static', null, null, get_lang('MoveTo').' : ');
  215. $select = $this->addElement('select', 'move_cat', null, null);
  216. $line = '';
  217. foreach ($this->evaluation_object->get_target_categories() as $cat) {
  218. for ($i = 0; $i < $cat[2]; $i++) {
  219. $line .= '&mdash;';
  220. }
  221. $select->addoption($line.' '.$cat[1], $cat[0]);
  222. $line = '';
  223. }
  224. $this->addButtonSave(get_lang('Ok'), 'submit');
  225. }
  226. /**
  227. * Builds a result form containing inputs for all students with a given course_code
  228. */
  229. protected function build_result_add_form()
  230. {
  231. $renderer = &$this->defaultRenderer();
  232. $renderer->setFormTemplate(
  233. '<form{attributes}>
  234. <table class="data_table">
  235. {content}
  236. </table>
  237. </form>'
  238. );
  239. $tblusers = GradebookUtils::get_users_in_course($this->evaluation_object->get_course_code());
  240. $nr_users = 0;
  241. //extra field for check on maxvalue
  242. $this->addElement('hidden', 'maxvalue', $this->evaluation_object->get_max());
  243. $this->addElement('hidden', 'minvalue', 0);
  244. $this->addElement('header', get_lang('AddResult'));
  245. if (api_is_western_name_order()) {
  246. $renderer->setHeaderTemplate(
  247. '<tr>
  248. <th>'.get_lang('OfficialCode').'</th>
  249. <th>'.get_lang('UserName').'</th>
  250. <th>'.get_lang('FirstName').'</th>
  251. <th>'.get_lang('LastName').'</th>
  252. <th>'.get_lang('Qualify').'</th>
  253. </tr>'
  254. );
  255. } else {
  256. $renderer->setHeaderTemplate(
  257. '<tr>
  258. <th>'.get_lang('OfficialCode').'</th>
  259. <th>'.get_lang('UserName').'</th>
  260. <th>'.get_lang('LastName').'</th>
  261. <th>'.get_lang('FirstName').'</th>
  262. <th>'.get_lang('Qualify').'</th>
  263. </tr>'
  264. );
  265. }
  266. $firstUser = true;
  267. foreach ($tblusers as $user) {
  268. $element_name = 'score['.$user[0].']';
  269. $scoreColumnProperties = array('maxlength' => 5);
  270. if ($firstUser) {
  271. $scoreColumnProperties['autofocus'] = '';
  272. $firstUser = false;
  273. }
  274. //user_id, user.username, lastname, firstname
  275. $this->addFloat(
  276. $element_name,
  277. $this->build_stud_label($user[0], $user[1], $user[2], $user[3]),
  278. false,
  279. $scoreColumnProperties,
  280. false,
  281. 0,
  282. $this->evaluation_object->get_max()
  283. );
  284. if (api_is_western_name_order()) {
  285. $user_info = '<td align="left" >'.$user[3].'</td>';
  286. $user_info .= '<td align="left" >'.$user[2].'</td>';
  287. } else {
  288. $user_info = '<td align="left" >'.$user[2].'</td>';
  289. $user_info .= '<td align="left" >'.$user[3].'</td>';
  290. }
  291. $nr_users++;
  292. $template = '<tr>
  293. <td align="left" >'.$user[4].'</td>
  294. <td align="left" >'.$user[1].'</td>
  295. '.$user_info.'
  296. <td align="left">{element} / '.$this->evaluation_object->get_max().'
  297. <!-- BEGIN error --><br /><span style="color: #ff0000;font-size:10px">{error}</span><!-- END error -->
  298. </td>
  299. </tr>';
  300. $renderer->setElementTemplate($template, $element_name);
  301. }
  302. $this->addElement('hidden', 'nr_users', $nr_users);
  303. $this->addElement('hidden', 'evaluation_id', $this->result_object->get_evaluation_id());
  304. $this->addButtonSave(get_lang('AddResult'), 'submit');
  305. $template_submit = '<tr>
  306. <td colspan="4" ></td>
  307. <td >
  308. {element}
  309. <!-- BEGIN error --><br /><span style="color: #ff0000;font-size:10px">{error}</span><!-- END error -->
  310. </td>
  311. </tr>';
  312. $renderer->setElementTemplate($template_submit, 'submit');
  313. }
  314. /**
  315. * Builds a form to edit a result
  316. */
  317. protected function build_result_edit_form()
  318. {
  319. $this->setDefaults(
  320. array(
  321. 'score' => $this->result_object->get_score(),
  322. 'maximum' => $this->evaluation_object->get_max(),
  323. )
  324. );
  325. $userInfo = api_get_user_info($this->result_object->get_user_id());
  326. $this->addHeader(get_lang('User').': '.$userInfo['complete_name']);
  327. $this->addFloat(
  328. 'score',
  329. array(
  330. get_lang('Score'),
  331. null,
  332. '/ '.$this->evaluation_object->get_max(),
  333. ),
  334. false,
  335. array(
  336. 'size' => '4',
  337. 'maxlength' => '5',
  338. ),
  339. false,
  340. 0,
  341. $this->evaluation_object->get_max()
  342. );
  343. $this->addButtonSave(get_lang('Edit'), 'submit');
  344. $this->addElement('hidden', 'hid_user_id', $this->result_object->get_user_id());
  345. }
  346. /**
  347. * Builds a form to add an evaluation
  348. */
  349. protected function build_add_form()
  350. {
  351. $this->setDefaults(
  352. array(
  353. 'hid_user_id' => $this->evaluation_object->get_user_id(),
  354. 'hid_category_id' => $this->evaluation_object->get_category_id(),
  355. 'hid_course_code' => $this->evaluation_object->get_course_code(),
  356. 'created_at' => api_get_utc_datetime(),
  357. )
  358. );
  359. $this->build_basic_form(0);
  360. if ($this->evaluation_object->get_course_code() == null) {
  361. $this->addElement('checkbox', 'adduser', null, get_lang('AddUserToEval'));
  362. } else {
  363. $this->addElement('checkbox', 'addresult', null, get_lang('AddResult'));
  364. }
  365. $this->addButtonCreate(get_lang('AddAssessment'), 'submit');
  366. }
  367. /**
  368. * Builds a form to edit an evaluation
  369. */
  370. protected function build_editing_form()
  371. {
  372. $parent_cat = Category::load($this->evaluation_object->get_category_id());
  373. //@TODO $weight_mask is replaced?
  374. if ($parent_cat[0]->get_parent_id() == 0) {
  375. $weight_mask = $this->evaluation_object->get_weight();
  376. } else {
  377. $cat = Category::load($parent_cat[0]->get_parent_id());
  378. $global_weight = $cat[0]->get_weight();
  379. $weight_mask = $global_weight * $this->evaluation_object->get_weight() / $parent_cat[0]->get_weight();
  380. }
  381. $weight = $weight_mask = $this->evaluation_object->get_weight();
  382. $this->setDefaults(array(
  383. 'hid_id' => $this->evaluation_object->get_id(),
  384. 'name' => $this->evaluation_object->get_name(),
  385. 'description' => $this->evaluation_object->get_description(),
  386. 'hid_user_id' => $this->evaluation_object->get_user_id(),
  387. 'hid_course_code' => $this->evaluation_object->get_course_code(),
  388. 'hid_category_id' => $this->evaluation_object->get_category_id(),
  389. 'created_at' => api_get_utc_datetime($this->evaluation_object->get_date()),
  390. 'weight' => $weight,
  391. 'weight_mask' => $weight_mask,
  392. 'max' => $this->evaluation_object->get_max(),
  393. 'visible' => $this->evaluation_object->is_visible()
  394. ));
  395. $id_current = isset($this->id) ? $this->id : null;
  396. $this->addElement('hidden', 'hid_id', $id_current);
  397. $this->build_basic_form(1);
  398. $this->addButtonSave(get_lang('ModifyEvaluation'), 'submit');
  399. }
  400. /**
  401. * Builds a basic form that is used in add and edit
  402. */
  403. private function build_basic_form($edit = 0)
  404. {
  405. $form_title = get_lang('NewEvaluation');
  406. if (!empty($_GET['editeval']) && $_GET['editeval'] == 1) {
  407. $form_title = get_lang('EditEvaluation');
  408. }
  409. $this->addElement('header', $form_title);
  410. $this->addElement('hidden', 'hid_user_id');
  411. $this->addElement('hidden', 'hid_course_code');
  412. $this->addText(
  413. 'name',
  414. get_lang('EvaluationName'),
  415. true,
  416. array(
  417. 'maxlength' => '50',
  418. 'id' => 'evaluation_title',
  419. )
  420. );
  421. $cat_id = $this->evaluation_object->get_category_id();
  422. $session_id = api_get_session_id();
  423. $course_code = api_get_course_id();
  424. $all_categories = Category:: load(
  425. null,
  426. null,
  427. $course_code,
  428. null,
  429. null,
  430. $session_id,
  431. false
  432. );
  433. if (count($all_categories) == 1) {
  434. $this->addElement('hidden', 'hid_category_id', $cat_id);
  435. } else {
  436. $select_gradebook = $this->addElement(
  437. 'select',
  438. 'hid_category_id',
  439. get_lang('SelectGradebook'),
  440. array(),
  441. array('id' => 'hid_category_id')
  442. );
  443. $this->addRule('hid_category_id', get_lang('ThisFieldIsRequired'), 'nonzero');
  444. $default_weight = 0;
  445. if (!empty($all_categories)) {
  446. foreach ($all_categories as $my_cat) {
  447. if ($my_cat->get_course_code() == api_get_course_id()) {
  448. $grade_model_id = $my_cat->get_grade_model_id();
  449. if (empty($grade_model_id)) {
  450. if ($my_cat->get_parent_id() == 0) {
  451. $default_weight = $my_cat->get_weight();
  452. $select_gradebook->addoption(get_lang('Default'), $my_cat->get_id());
  453. $cats_added[] = $my_cat->get_id();
  454. } else {
  455. $select_gradebook->addoption($my_cat->get_name(), $my_cat->get_id());
  456. $cats_added[] = $my_cat->get_id();
  457. }
  458. } else {
  459. $select_gradebook->addoption(get_lang('Select'), 0);
  460. }
  461. if ($this->evaluation_object->get_category_id() == $my_cat->get_id()) {
  462. $default_weight = $my_cat->get_weight();
  463. }
  464. }
  465. }
  466. }
  467. }
  468. $this->addFloat(
  469. 'weight_mask',
  470. array(
  471. get_lang('Weight'),
  472. null,
  473. ' [0 .. <span id="max_weight">'.$all_categories[0]->get_weight().'</span>] ',
  474. ),
  475. true,
  476. array(
  477. 'size' => '4',
  478. 'maxlength' => '5'
  479. )
  480. );
  481. if ($edit) {
  482. if (!$this->evaluation_object->has_results()) {
  483. $this->addText(
  484. 'max',
  485. get_lang('QualificationNumeric'),
  486. true,
  487. array(
  488. 'maxlength' => '5'
  489. )
  490. );
  491. } else {
  492. $this->addText(
  493. 'max',
  494. array(get_lang('QualificationNumeric'), get_lang('CannotChangeTheMaxNote')),
  495. false,
  496. array(
  497. 'maxlength' => '5',
  498. 'disabled' => 'disabled'
  499. )
  500. );
  501. }
  502. } else {
  503. $this->addText(
  504. 'max',
  505. get_lang('QualificationNumeric'),
  506. true,
  507. array(
  508. 'maxlength' => '5',
  509. )
  510. );
  511. $default_max = api_get_setting('gradebook_default_weight');
  512. $defaults['max'] = isset($default_max) ? $default_max : 100;
  513. $this->setDefaults($defaults);
  514. }
  515. $this->addElement('textarea', 'description', get_lang('Description'));
  516. $this->addRule('hid_category_id', get_lang('ThisFieldIsRequired'), 'required');
  517. $this->addElement('checkbox', 'visible', null, get_lang('Visible'));
  518. $this->addRule('max', get_lang('OnlyNumbers'), 'numeric');
  519. $this->addRule(
  520. 'max',
  521. get_lang('NegativeValue'),
  522. 'compare',
  523. '>=',
  524. 'server',
  525. false,
  526. false,
  527. 0
  528. );
  529. $setting = api_get_setting('tool_visible_by_default_at_creation');
  530. $visibility_default = 1;
  531. if (isset($setting['gradebook']) && $setting['gradebook'] == 'false') {
  532. $visibility_default = 0;
  533. }
  534. $this->setDefaults(array('visible' => $visibility_default));
  535. }
  536. function display()
  537. {
  538. parent::display();
  539. }
  540. function setDefaults($defaults = array(), $filter = null)
  541. {
  542. parent::setDefaults($defaults, $filter);
  543. }
  544. /**
  545. * @param $id
  546. * @param $username
  547. * @param $lastname
  548. * @param $firstname
  549. * @return string
  550. */
  551. private function build_stud_label($id, $username, $lastname, $firstname)
  552. {
  553. $opendocurl_start = '';
  554. $opendocurl_end = '';
  555. // evaluation's origin is a link
  556. if ($this->evaluation_object->get_category_id() < 0) {
  557. $link = LinkFactory::get_evaluation_link($this->evaluation_object->get_id());
  558. $doc_url = $link->get_view_url($id);
  559. if ($doc_url != null) {
  560. $opendocurl_start .= '<a href="'.$doc_url.'" target="_blank">';
  561. $opendocurl_end = '</a>';
  562. }
  563. }
  564. return $opendocurl_start.api_get_person_name($firstname, $lastname).' ('.$username.')'.$opendocurl_end;
  565. }
  566. public function sort_by_user($item1, $item2)
  567. {
  568. $user1 = $item1['user'];
  569. $user2 = $item2['user'];
  570. if (api_sort_by_first_name()) {
  571. $result = api_strcmp($user1['firstname'], $user2['firstname']);
  572. if ($result == 0) {
  573. return api_strcmp($user1['lastname'], $user2['lastname']);
  574. }
  575. } else {
  576. $result = api_strcmp($user1['lastname'], $user2['lastname']);
  577. if ($result == 0) {
  578. return api_strcmp($user1['firstname'], $user2['firstname']);
  579. }
  580. }
  581. return $result;
  582. }
  583. }