gradebooktable.class.php 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983
  1. <?php
  2. /* For licensing terms, see license.txt */
  3. use CpChart\Classes\pCache as pCache;
  4. use CpChart\Classes\pData as pData;
  5. use CpChart\Classes\pImage as pImage;
  6. /**
  7. * GradebookTable Class
  8. * Table to display categories, evaluations and links
  9. * @author Stijn Konings
  10. * @author Bert Steppé (refactored, optimised)
  11. * @package chamilo.gradebook
  12. */
  13. class GradebookTable extends SortableTable
  14. {
  15. private $currentcat;
  16. private $datagen;
  17. private $evals_links;
  18. public $cats;
  19. private $dataForGraph;
  20. public $exportToPdf;
  21. public $teacherView;
  22. public $userId;
  23. /**
  24. * Constructor
  25. * @param Category $currentcat
  26. * @param array $cats
  27. * @param array $evals
  28. * @param array $links
  29. * @param null $addparams
  30. */
  31. public function __construct(
  32. $currentcat,
  33. $cats = array(),
  34. $evals = array(),
  35. $links = array(),
  36. $addparams = null,
  37. $exportToPdf = false,
  38. $showTeacherView = null,
  39. $userId = null
  40. ) {
  41. $this->teacherView = is_null($showTeacherView) ? api_is_allowed_to_edit(null, true) : $showTeacherView;
  42. $this->userId = is_null($userId) ? api_get_user_id() : $userId;
  43. $this->exportToPdf = $exportToPdf;
  44. parent::__construct(
  45. 'gradebooklist',
  46. null,
  47. null,
  48. api_is_allowed_to_edit() ? 1 : 0,
  49. 20,
  50. 'ASC',
  51. 'gradebook_list'
  52. );
  53. $this->evals_links = array_merge($evals, $links);
  54. $this->currentcat = $currentcat;
  55. $this->cats = $cats;
  56. $this->datagen = new GradebookDataGenerator($cats, $evals, $links);
  57. if (!empty($userId)) {
  58. $this->datagen->userId = $userId;
  59. }
  60. if (isset($addparams)) {
  61. $this->set_additional_parameters($addparams);
  62. }
  63. $column= 0;
  64. if ($this->teacherView) {
  65. if ($this->exportToPdf == false) {
  66. $this->set_header($column++, '', '', 'width="25px"');
  67. }
  68. }
  69. $this->set_header($column++, get_lang('Type'), '', 'width="35px"');
  70. $this->set_header($column++, get_lang('Name'), false);
  71. if ($this->exportToPdf == false) {
  72. $this->set_header($column++, get_lang('Description'), false);
  73. }
  74. if ($this->teacherView) {
  75. $this->set_header(
  76. $column++,
  77. get_lang('Weight'),
  78. '',
  79. 'width="100px"'
  80. );
  81. } else {
  82. $this->set_header($column++, get_lang('Weight'), false);
  83. $this->set_header($column++, get_lang('Result'), false);
  84. $this->set_header($column++, get_lang('Ranking'), false);
  85. $this->set_header($column++, get_lang('Best'), false);
  86. $this->set_header($column++, get_lang('Average'), false);
  87. if (!empty($cats)) {
  88. if ($this->exportToPdf == false) {
  89. $this->set_header($column++, get_lang('Actions'), false);
  90. }
  91. }
  92. }
  93. // Deactivates the odd/even alt rows in order that the +/- buttons work see #4047
  94. $this->odd_even_rows_enabled = false;
  95. // Admins get an edit column.
  96. if ($this->teacherView) {
  97. $this->set_header($column++, get_lang('Modify'), false, 'width="195px"');
  98. // Actions on multiple selected documents.
  99. $this->set_form_actions(array(
  100. 'setvisible' => get_lang('SetVisible'),
  101. 'setinvisible' => get_lang('SetInvisible'),
  102. 'deleted' => get_lang('DeleteSelected')
  103. )
  104. );
  105. } else {
  106. if (empty($_GET['selectcat']) && !$this->teacherView) {
  107. if ($this->exportToPdf == false) {
  108. $this->set_header(
  109. $column++,
  110. get_lang('Certificates'),
  111. false
  112. );
  113. }
  114. }
  115. }
  116. }
  117. /**
  118. * @return GradebookDataGenerator
  119. */
  120. public function get_data()
  121. {
  122. return $this->datagen;
  123. }
  124. /**
  125. * Function used by SortableTable to get total number of items in the table
  126. * @return int
  127. */
  128. public function get_total_number_of_items()
  129. {
  130. return $this->datagen->get_total_items_count();
  131. }
  132. /**
  133. * Function used by SortableTable to generate the data to display
  134. * @param int $from
  135. * @param int $per_page
  136. * @param int $column
  137. * @param string $direction
  138. * @param int $sort
  139. * @return array|mixed
  140. */
  141. public function get_table_data($from = 1, $per_page = null, $column = null, $direction = null, $sort = null)
  142. {
  143. //variables load in index.php
  144. global $certificate_min_score;
  145. // determine sorting type
  146. $col_adjust = api_is_allowed_to_edit() ? 1 : 0;
  147. // By id
  148. $this->column = 5;
  149. switch ($this->column) {
  150. // Type
  151. case (0 + $col_adjust) :
  152. $sorting = GradebookDataGenerator :: GDG_SORT_TYPE;
  153. break;
  154. case (1 + $col_adjust) :
  155. $sorting = GradebookDataGenerator :: GDG_SORT_NAME;
  156. break;
  157. case (2 + $col_adjust) :
  158. $sorting = GradebookDataGenerator :: GDG_SORT_DESCRIPTION;
  159. break;
  160. case (3 + $col_adjust) :
  161. $sorting = GradebookDataGenerator :: GDG_SORT_WEIGHT;
  162. break;
  163. case (4 + $col_adjust) :
  164. $sorting = GradebookDataGenerator :: GDG_SORT_DATE;
  165. case (5 + $col_adjust) :
  166. $sorting = GradebookDataGenerator :: GDG_SORT_ID;
  167. break;
  168. }
  169. if ($this->direction == 'DESC') {
  170. $sorting |= GradebookDataGenerator :: GDG_SORT_DESC;
  171. } else {
  172. $sorting |= GradebookDataGenerator :: GDG_SORT_ASC;
  173. }
  174. // Status of user in course.
  175. //$user_id = api_get_user_id();
  176. $user_id = $this->userId;
  177. $course_code = api_get_course_id();
  178. $session_id = api_get_session_id();
  179. $status_user = api_get_status_of_user_in_course(
  180. api_get_user_id(),
  181. api_get_course_int_id()
  182. );
  183. if (empty($session_id)) {
  184. $statusToFilter = STUDENT;
  185. } else {
  186. $statusToFilter = 0;
  187. }
  188. $studentList = CourseManager::get_user_list_from_course_code(
  189. $course_code,
  190. $session_id,
  191. null,
  192. null,
  193. $statusToFilter
  194. );
  195. $this->datagen->userId = $this->userId;
  196. $data_array = $this->datagen->get_data(
  197. $sorting,
  198. $from,
  199. $this->per_page,
  200. false,
  201. $studentList
  202. );
  203. // generate the data to display
  204. $sortable_data = array();
  205. $weight_total_links = 0;
  206. $main_categories = array();
  207. $main_cat = Category::load(
  208. null,
  209. null,
  210. $course_code,
  211. null,
  212. null,
  213. $session_id,
  214. false
  215. );
  216. $total_categories_weight = 0;
  217. $scoredisplay = ScoreDisplay :: instance();
  218. $totalResult = [0, 0];
  219. $totalBest = [0, 0];
  220. $totalAverage = [0, 0];
  221. // Categories.
  222. foreach ($data_array as $data) {
  223. // list of items inside the gradebook (exercises, lps, forums, etc)
  224. $row = array();
  225. /** @var AbstractLink $item */
  226. $item = $mainCategory = $data[0];
  227. //if the item is invisible, wrap it in a span with class invisible
  228. $invisibility_span_open = api_is_allowed_to_edit() && $item->is_visible() == '0' ? '<span class="invisible">' : '';
  229. $invisibility_span_close = api_is_allowed_to_edit() && $item->is_visible() == '0' ? '</span>' : '';
  230. // Id
  231. if ($this->teacherView) {
  232. if ($this->exportToPdf == false) {
  233. $row[] = $this->build_id_column($item);
  234. }
  235. }
  236. // Type.
  237. $row[] = $this->build_type_column($item);
  238. // Name.
  239. if (get_class($item) == 'Category') {
  240. $row[] = $invisibility_span_open.'<h3>'.$item->get_name().'</h3>'.$invisibility_span_close;
  241. $main_categories[$item->get_id()]['name'] = $item->get_name();
  242. } else {
  243. $row[] = $invisibility_span_open.$this->build_name_link($item) . $invisibility_span_close;
  244. $main_categories[$item->get_id()]['name'] = $this->build_name_link($item);
  245. }
  246. $this->dataForGraph['categories'][] = $item->get_name();
  247. $main_categories[$item->get_id()]['weight']= $item->get_weight();
  248. $total_categories_weight += $item->get_weight();
  249. // Description.
  250. if ($this->exportToPdf == false) {
  251. $row[] = $invisibility_span_open.$data[2].$invisibility_span_close;
  252. }
  253. // Weight.
  254. $weight = $scoredisplay->display_score(
  255. array(
  256. $data['3'],
  257. $this->currentcat->get_weight()
  258. ),
  259. SCORE_SIMPLE,
  260. SCORE_BOTH,
  261. true
  262. );
  263. if ($this->teacherView) {
  264. $row[] = $invisibility_span_open .Display::tag('h4', $weight).$invisibility_span_close;
  265. } else {
  266. $row[] = $invisibility_span_open .$weight.$invisibility_span_close;
  267. }
  268. $category_weight = $item->get_weight();
  269. $mainCategoryWeight = $main_cat[0]->get_weight();
  270. if ($this->teacherView) {
  271. $weight_total_links += $data[3];
  272. } else {
  273. $cattotal = Category::load($_GET['selectcat']);
  274. $scoretotal = $cattotal[0]->calc_score($this->userId);
  275. $item_value = $scoredisplay->display_score($scoretotal, SCORE_SIMPLE);
  276. }
  277. // Edit (for admins).
  278. if ($this->teacherView) {
  279. $cat = new Category();
  280. $show_message = $cat->show_message_resource_delete($item->get_course_code());
  281. if ($show_message === false) {
  282. $row[] = $this->build_edit_column($item);
  283. }
  284. } else {
  285. $score = $item->calc_score($this->userId);
  286. if (!empty($score[1])) {
  287. $completeScore = $scoredisplay->display_score($score, SCORE_DIV_PERCENT);
  288. $score = $score[0]/$score[1]*$item->get_weight();
  289. $score = $scoredisplay->display_score(array($score, null), SCORE_SIMPLE);
  290. $scoreToDisplay = Display::tip($score, $completeScore);
  291. } else {
  292. $scoreToDisplay = '-';
  293. $categoryScore = null;
  294. }
  295. // Students get the results and certificates columns
  296. //if (count($this->evals_links) > 0 && $status_user != 1) {
  297. if ($status_user != 1) {
  298. $value_data = isset($data[4]) ? $data[4] : null;
  299. $best = isset($data['best']) ? $data['best'] : null;
  300. $average = isset($data['average']) ? $data['average'] : null;
  301. $ranking = isset($data['ranking']) ? $data['ranking'] : null;
  302. $totalResult = [
  303. $totalResult[0] + $data['result_score_weight'][0],
  304. $totalResult[1] + $data['result_score_weight'][1]
  305. ];
  306. $totalBest = [
  307. $totalBest[0] + $data['best_score'][0],
  308. $totalBest[1] + $data['best_score'][1],
  309. ];
  310. $totalAverage = [
  311. $totalAverage[0] + $data['average_score'][0],
  312. $totalAverage[1] + $data['average_score'][1],
  313. ];
  314. $this->dataForGraph['my_result'][] = (float) $scoredisplay->display_score($totalResult, SCORE_AVERAGE);
  315. $this->dataForGraph['average'][] = (float) $scoredisplay->display_score($totalAverage, SCORE_AVERAGE);
  316. // Student result
  317. $row[] = $value_data;
  318. // Ranking
  319. $row[] = $ranking;
  320. // Best
  321. $row[] = $best;
  322. // Average
  323. $row[] = $average;
  324. if (get_class($item) == 'Category') {
  325. if ($this->exportToPdf == false) {
  326. $row[] = $this->build_edit_column($item);
  327. }
  328. }
  329. } else {
  330. $row[] = $scoreToDisplay;
  331. if (!empty($this->cats)) {
  332. if ($this->exportToPdf == false) {
  333. $row[] = $this->build_edit_column($item);
  334. }
  335. }
  336. }
  337. }
  338. // Category added.
  339. $sortable_data[] = $row;
  340. // Loading children
  341. if (get_class($item) == 'Category') {
  342. $course_code = api_get_course_id();
  343. $session_id = api_get_session_id();
  344. $parent_id = $item->get_id();
  345. $cats = Category::load(
  346. $parent_id,
  347. null,
  348. null,
  349. null,
  350. null,
  351. null
  352. );
  353. if (isset($cats[0])) {
  354. $allcat = $cats[0]->get_subcategories($this->userId, $course_code, $session_id);
  355. $alleval = $cats[0]->get_evaluations($this->userId);
  356. $alllink = $cats[0]->get_links($this->userId);
  357. $sub_cat_info = new GradebookDataGenerator($allcat, $alleval, $alllink);
  358. $sub_cat_info->userId = $user_id;
  359. $data_array = $sub_cat_info->get_data($sorting, $from, $this->per_page);
  360. $total_weight = 0;
  361. // Links.
  362. foreach ($data_array as $data) {
  363. $row = array();
  364. $item = $data[0];
  365. //if the item is invisible, wrap it in a span with class invisible
  366. $invisibility_span_open = api_is_allowed_to_edit() && $item->is_visible() == '0' ? '<span class="invisible">' : '';
  367. $invisibility_span_close = api_is_allowed_to_edit() && $item->is_visible() == '0' ? '</span>' : '';
  368. if (isset($item)) {
  369. $main_categories[$parent_id]['children'][$item->get_id()]['name'] = $item->get_name();
  370. $main_categories[$parent_id]['children'][$item->get_id()]['weight'] = $item->get_weight();
  371. }
  372. if ($this->teacherView) {
  373. if ($this->exportToPdf == false) {
  374. $row[] = $this->build_id_column($item);
  375. }
  376. }
  377. // Type
  378. $row[] = $this->build_type_column($item, array('style' => 'padding-left:5px'));
  379. // Name.
  380. $row[] = $invisibility_span_open."&nbsp;&nbsp;&nbsp; ".$this->build_name_link($item) . $invisibility_span_close;
  381. // Description.
  382. if ($this->exportToPdf == false) {
  383. $row[] = $invisibility_span_open.$data[2].$invisibility_span_close;
  384. }
  385. $weight = $data[3];
  386. $total_weight += $weight;
  387. // Weight
  388. $row[] = $invisibility_span_open.$weight.$invisibility_span_close;
  389. if ($this->teacherView) {
  390. //$weight_total_links += intval($data[3]);
  391. } else {
  392. $cattotal = Category::load($_GET['selectcat']);
  393. $scoretotal = $cattotal[0]->calc_score($this->userId);
  394. $item_value = $scoretotal[0];
  395. }
  396. // Admins get an edit column.
  397. if (api_is_allowed_to_edit(null, true) &&
  398. isset($_GET['user_id']) == false &&
  399. (isset($_GET['action']) && $_GET['action'] != 'export_all' || !isset($_GET['action'])
  400. )
  401. ) {
  402. $cat = new Category();
  403. $show_message = $cat->show_message_resource_delete($item->get_course_code());
  404. if ($show_message === false) {
  405. if ($this->exportToPdf == false) {
  406. $row[] = $this->build_edit_column($item);
  407. }
  408. }
  409. } else {
  410. // Students get the results and certificates columns
  411. $eval_n_links = array_merge($alleval, $alllink);
  412. if (count($eval_n_links)> 0) {
  413. $value_data = isset($data[4]) ? $data[4] : null;
  414. if (!is_null($value_data)) {
  415. //$score = $item->calc_score(api_get_user_id());
  416. //$new_score = $data[3] * $score[0] / $score[1];
  417. //$new_score = floatval(number_format($new_score, api_get_setting('gradebook_number_decimals')));
  418. // Result
  419. $row[] = $value_data;
  420. $best = isset($data['best']) ? $data['best'] : null;
  421. $average = isset($data['average']) ? $data['average'] : null;
  422. $ranking = isset($data['ranking']) ? $data['ranking'] : null;
  423. // Ranking
  424. $row[] = $ranking;
  425. // Best
  426. $row[] = $best;
  427. // Average
  428. $row[] = $average;
  429. }
  430. }
  431. if (!empty($cats)) {
  432. if ($this->exportToPdf == false) {
  433. $row[] = null;
  434. }
  435. }
  436. }
  437. if ($this->exportToPdf == false) {
  438. $row['child_of'] = $parent_id;
  439. }
  440. $sortable_data[] = $row;
  441. }
  442. // "Warning row"
  443. if (!empty($data_array)) {
  444. if ($this->teacherView) {
  445. // Compare the category weight to the sum of all weights inside the category
  446. if (intval($total_weight) == $category_weight) {
  447. $label = null;
  448. $total = GradebookUtils::score_badges(
  449. array(
  450. $total_weight.' / '.$category_weight,
  451. '100'
  452. )
  453. );
  454. } else {
  455. $label = Display::return_icon(
  456. 'warning.png',
  457. sprintf(get_lang('TotalWeightMustBeX'), $category_weight)
  458. );
  459. $total = Display::badge($total_weight.' / '.$category_weight, 'warning');
  460. }
  461. $row = array(
  462. null,
  463. null,
  464. "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<h5>".get_lang('SubTotal').'</h5>',
  465. null,
  466. $total.' '.$label,
  467. 'child_of' => $parent_id
  468. );
  469. $sortable_data[] = $row;
  470. }
  471. }
  472. }
  473. }
  474. } //end looping categories
  475. if ($this->teacherView) {
  476. // Total for teacher.
  477. if (count($main_cat) > 1) {
  478. $main_weight = intval($main_cat[0]->get_weight());
  479. if (intval($total_categories_weight) == $main_weight) {
  480. $total = GradebookUtils::score_badges(
  481. array($total_categories_weight.' / '.$main_weight, '100')
  482. );
  483. } else {
  484. $total = Display::badge($total_categories_weight.' / '.$main_weight, 'warning');
  485. }
  486. $row = array(
  487. null,
  488. null,
  489. '<h3>' . get_lang('Total') . '</h3>',
  490. null,
  491. $total
  492. );
  493. $sortable_data[] = $row;
  494. }
  495. } else {
  496. // Total for student.
  497. if (count($main_cat) > 1) {
  498. $main_weight = intval($main_cat[0]->get_weight());
  499. $global = null;
  500. $average = null;
  501. // Overwrite main weight
  502. $totalResult[1] = $main_weight;
  503. $totalResult = $scoredisplay->display_score(
  504. $totalResult,
  505. SCORE_DIV
  506. );
  507. $totalRanking = array();
  508. foreach ($studentList as $student) {
  509. $score = $main_cat[0]->calc_score($student['user_id']);
  510. $totalRanking[$student['user_id']] = $score[0];
  511. }
  512. $totalRanking = AbstractLink::getCurrentUserRanking($user_id, $totalRanking);
  513. $totalRanking = $scoredisplay->display_score(
  514. $totalRanking,
  515. SCORE_DIV
  516. );
  517. $totalBest = $scoredisplay->display_score(
  518. $totalBest,
  519. SCORE_DIV
  520. );
  521. $totalAverage = $scoredisplay->display_score(
  522. $totalAverage,
  523. SCORE_DIV
  524. );
  525. if ($this->exportToPdf) {
  526. $row = array(
  527. null,
  528. '<h3>' . get_lang('Total') . '</h3>',
  529. $main_weight,
  530. $totalResult,
  531. $totalRanking,
  532. $totalBest,
  533. $totalAverage,
  534. );
  535. } else {
  536. $row = array(
  537. null,
  538. '<h3>' . get_lang('Total') . '</h3>',
  539. null,
  540. $main_weight,
  541. $totalResult,
  542. $totalRanking,
  543. $totalBest,
  544. $totalAverage,
  545. );
  546. }
  547. $sortable_data[] = $row;
  548. }
  549. }
  550. // Warning messages
  551. $view = isset($_GET['view']) ? $_GET['view']: null;
  552. if ($this->teacherView) {
  553. if (isset($_GET['selectcat']) &&
  554. $_GET['selectcat'] > 0 &&
  555. $view <> 'presence'
  556. ) {
  557. $id_cat = intval($_GET['selectcat']);
  558. $category = Category::load($id_cat);
  559. $weight_category = intval($this->build_weight($category[0]));
  560. $course_code = $this->build_course_code($category[0]);
  561. $weight_total_links = round($weight_total_links);
  562. if ($weight_total_links > $weight_category ||
  563. $weight_total_links < $weight_category ||
  564. $weight_total_links > $weight_category
  565. ) {
  566. $warning_message = sprintf(get_lang('TotalWeightMustBeX'), $weight_category);
  567. $modify_icons = '<a class="right_link" href="gradebook_edit_cat.php?editcat='.$id_cat.'&cidReq='.$course_code.'&id_session='.api_get_session_id().'">'.
  568. Display::return_icon('edit.png', $warning_message, array(), ICON_SIZE_SMALL).'</a>';
  569. $warning_message .= $modify_icons;
  570. Display::display_warning_message($warning_message, false);
  571. }
  572. $content_html = DocumentManager::replace_user_info_into_html(
  573. api_get_user_id(),
  574. $course_code
  575. );
  576. if (!empty($content_html)) {
  577. $new_content = explode('</head>',$content_html['content']);
  578. }
  579. if (empty($new_content[0])) {
  580. // Set default certificate
  581. $courseData = api_get_course_info($course_code);
  582. DocumentManager::generateDefaultCertificate($courseData);
  583. }
  584. }
  585. if (empty($_GET['selectcat'])) {
  586. $categories = Category :: load();
  587. $weight_categories = $certificate_min_scores = $course_codes = array();
  588. foreach ($categories as $category) {
  589. $course_code_category = $this->build_course_code($category);
  590. if (!empty($course_code)) {
  591. if ($course_code_category == $course_code) {
  592. $weight_categories[] = intval($this->build_weight($category));
  593. $certificate_min_scores[] = intval($this->build_certificate_min_score($category));
  594. $course_codes[] = $course_code;
  595. break;
  596. }
  597. } else {
  598. $weight_categories[] = intval($this->build_weight($category));
  599. $certificate_min_scores[] = intval($this->build_certificate_min_score($category));
  600. $course_codes[] = $course_code_category;
  601. }
  602. }
  603. if (is_array($weight_categories) &&
  604. is_array($certificate_min_scores) &&
  605. is_array($course_codes)
  606. ) {
  607. $warning_message = '';
  608. for ($x = 0; $x<count($weight_categories);$x++) {
  609. $weight_category = intval($weight_categories[$x]);
  610. $certificate_min_score = intval($certificate_min_scores[$x]);
  611. $course_code = $course_codes[$x];
  612. if (empty($certificate_min_score) ||
  613. ($certificate_min_score > $weight_category)
  614. ) {
  615. $warning_message .= $course_code .'&nbsp;-&nbsp;'.get_lang('CertificateMinimunScoreIsRequiredAndMustNotBeMoreThan').'&nbsp;'.$weight_category.'<br />';
  616. }
  617. }
  618. if (!empty($warning_message)) {
  619. Display::display_warning_message($warning_message,false);
  620. }
  621. }
  622. }
  623. }
  624. return $sortable_data;
  625. }
  626. /**
  627. * @return array
  628. */
  629. private function getDataForGraph()
  630. {
  631. return $this->dataForGraph;
  632. }
  633. /**
  634. * @return string
  635. */
  636. public function getGraph()
  637. {
  638. $data = $this->getDataForGraph();
  639. if (!empty($data) &&
  640. isset($data['categories']) &&
  641. isset($data['my_result']) &&
  642. isset($data['average'])
  643. ) {
  644. $dataSet = new pData();
  645. $dataSet->addPoints($data['my_result'], get_lang('Me'));
  646. // In order to generate random values
  647. // $data['average'] = array(rand(0,50), rand(0,50));
  648. $dataSet->addPoints($data['average'], get_lang('Average'));
  649. $dataSet->addPoints($data['categories'], 'categories');
  650. $dataSet->setAbscissa("categories");
  651. $xSize = 600;
  652. $ySize = 400;
  653. $pChart = new pImage($xSize, $ySize, $dataSet);
  654. /* Turn of Antialiasing */
  655. $pChart->Antialias = FALSE;
  656. /* Add a border to the picture */
  657. $pChart->drawRectangle(0,0,$xSize-10,$ySize-10,array("R"=>0,"G"=>0,"B"=>0));
  658. $pChart->drawText(10,16,get_lang('Results'),array("FontSize"=>11,"Align"=>TEXT_ALIGN_BOTTOMLEFT));
  659. $pChart->setGraphArea(50, 30, $xSize-50, $ySize-50);
  660. $pChart->setFontProperties(
  661. array(
  662. 'FontName' => api_get_path(SYS_FONTS_PATH) . 'opensans/OpenSans-Regular.ttf',
  663. 'FontSize' => 10
  664. )
  665. );
  666. /* Draw the scale */
  667. $scaleSettings = array(
  668. "XMargin" => 10,
  669. "YMargin" => 10,
  670. "Floating" => true,
  671. "GridR" => 200,
  672. "GridG" => 200,
  673. "GridB" => 200,
  674. "DrawSubTicks" => true,
  675. "CycleBackground" => true,
  676. );
  677. $pChart->drawScale($scaleSettings);
  678. /* Draw the line chart */
  679. $pChart->drawLineChart();
  680. $pChart->drawPlotChart(array("DisplayValues"=>TRUE,"PlotBorder"=>TRUE,"BorderSize"=>2,"Surrounding"=>-60,"BorderAlpha"=>80));
  681. /* Write the chart legend */
  682. $pChart->drawLegend(
  683. $xSize - 180,
  684. 9,
  685. array(
  686. "Style" => LEGEND_NOBORDER,
  687. "Mode" => LEGEND_HORIZONTAL,
  688. "FontR" => 0,
  689. "FontG" => 0,
  690. "FontB" => 0,
  691. )
  692. );
  693. $cachePath = api_get_path(SYS_ARCHIVE_PATH);
  694. $myCache = new pCache(array('CacheFolder' => substr($cachePath, 0, strlen($cachePath) - 1)));
  695. $chartHash = $myCache->getHash($dataSet);
  696. $myCache->writeToCache($chartHash, $pChart);
  697. $imgSysPath = api_get_path(SYS_ARCHIVE_PATH) . $chartHash;
  698. $myCache->saveFromCache($chartHash, $imgSysPath);
  699. $imgWebPath = api_get_path(WEB_ARCHIVE_PATH) . $chartHash;
  700. if (file_exists($imgSysPath)) {
  701. $result = '<div id="contentArea" style="text-align: center;" >';
  702. $result .= '<img src="' . $imgWebPath.'" >';
  703. $result .= '</div>';
  704. return $result;
  705. }
  706. }
  707. return '';
  708. }
  709. /**
  710. * @param $item
  711. * @return mixed
  712. */
  713. private function build_certificate_min_score($item)
  714. {
  715. return $item->get_certificate_min_score();
  716. }
  717. /**
  718. * @param $item
  719. * @return mixed
  720. */
  721. private function build_weight($item)
  722. {
  723. return $item->get_weight();
  724. }
  725. /**
  726. * @param $item
  727. * @return mixed
  728. */
  729. private function build_course_code($item)
  730. {
  731. return $item->get_course_code();
  732. }
  733. /**
  734. * @param $item
  735. * @return string
  736. */
  737. private function build_id_column($item)
  738. {
  739. switch ($item->get_item_type()) {
  740. // category
  741. case 'C' :
  742. return 'CATE' . $item->get_id();
  743. // evaluation
  744. case 'E' :
  745. return 'EVAL' . $item->get_id();
  746. // link
  747. case 'L' :
  748. return 'LINK' . $item->get_id();
  749. }
  750. }
  751. /**
  752. * @param $item
  753. * @param array $attributes
  754. * @return string
  755. */
  756. private function build_type_column($item, $attributes = array())
  757. {
  758. return GradebookUtils::build_type_icon_tag($item->get_icon_name(), $attributes);
  759. }
  760. /**
  761. * Generate name column
  762. * @param unknown_type $item
  763. * @return string
  764. */
  765. private function build_name_link($item)
  766. {
  767. $view = isset($_GET['view']) ? Security::remove_XSS($_GET['view']) : null;
  768. switch ($item->get_item_type()) {
  769. // category
  770. case 'C' :
  771. $prms_uri='?selectcat=' . $item->get_id() . '&view='.$view;
  772. if (isset($_GET['isStudentView'])) {
  773. if ( isset($is_student) || ( isset($_SESSION['studentview']) && $_SESSION['studentview']=='studentview') ) {
  774. $prms_uri=$prms_uri.'&isStudentView='.Security::remove_XSS($_GET['isStudentView']);
  775. }
  776. }
  777. $cat = new Category();
  778. $show_message=$cat->show_message_resource_delete($item->get_course_code());
  779. return '&nbsp;<a href="'.Security::remove_XSS($_SESSION['gradebook_dest']).$prms_uri.'">'
  780. . $item->get_name()
  781. . '</a>'
  782. . ($item->is_course() ? ' &nbsp;[' . $item->get_course_code() . ']'.$show_message : '');
  783. // evaluation
  784. case 'E' :
  785. $cat = new Category();
  786. $show_message = false;
  787. $course_id = 0;
  788. if (isset($_GET['selectcat'])) {
  789. $course_id = CourseManager::get_course_by_category(
  790. $_GET['selectcat']
  791. );
  792. $show_message = $cat->show_message_resource_delete($course_id);
  793. }
  794. // course/platform admin can go to the view_results page
  795. if (api_is_allowed_to_edit() && $show_message===false) {
  796. if ($item->get_type() == 'presence') {
  797. return '&nbsp;'
  798. . '<a href="gradebook_view_result.php?cidReq='.$course_id.'&selecteval=' . $item->get_id() . '">'
  799. . $item->get_name()
  800. . '</a>';
  801. } else {
  802. return '&nbsp;'
  803. . '<a href="gradebook_view_result.php?cidReq='.$course_id.'&selecteval=' . $item->get_id() . '">'
  804. . $item->get_name()
  805. . '</a>&nbsp;'.Display::label(get_lang('Evaluation'));
  806. }
  807. } elseif (ScoreDisplay :: instance()->is_custom() && $show_message===false) {
  808. // students can go to the statistics page (if custom display enabled)
  809. return '&nbsp;'
  810. . '<a href="gradebook_statistics.php?selecteval=' . $item->get_id() . '">'
  811. . $item->get_name()
  812. . '</a>';
  813. } elseif ($show_message === false && !api_is_allowed_to_edit() && !ScoreDisplay :: instance()->is_custom()) {
  814. return '&nbsp;'
  815. . '<a href="gradebook_statistics.php?selecteval=' . $item->get_id() . '">'
  816. . $item->get_name()
  817. . '</a>';
  818. } else {
  819. return '['.get_lang('Evaluation').']&nbsp;&nbsp;'.$item->get_name().$show_message;
  820. }
  821. case 'L':
  822. // link
  823. $cat = new Category();
  824. $course_id = CourseManager::get_course_by_category($_GET['selectcat']);
  825. $show_message = $cat->show_message_resource_delete($course_id);
  826. $url = $item->get_link();
  827. if (isset($url) && $show_message === false) {
  828. $text = '&nbsp;<a href="' . $item->get_link() . '">'
  829. . $item->get_name()
  830. . '</a>';
  831. } else {
  832. $text = $item->get_name();
  833. }
  834. $text .= "&nbsp;".Display::label($item->get_type_name(), 'info').$show_message;
  835. $cc = $this->currentcat->get_course_code();
  836. if (empty($cc)) {
  837. $text .= '&nbsp;[<a href="'.api_get_path(REL_COURSE_PATH).$item->get_course_code().'/">'.$item->get_course_code().'</a>]';
  838. }
  839. return $text;
  840. }
  841. }
  842. /**
  843. * @param $item
  844. * @return null|string
  845. */
  846. private function build_edit_column($item)
  847. {
  848. switch ($item->get_item_type()) {
  849. // category
  850. case 'C' :
  851. return GradebookUtils::build_edit_icons_cat($item, $this->currentcat);
  852. // evaluation
  853. case 'E' :
  854. return GradebookUtils::build_edit_icons_eval($item, $this->currentcat->get_id());
  855. // link
  856. case 'L' :
  857. return GradebookUtils::build_edit_icons_link($item, $this->currentcat->get_id());
  858. }
  859. }
  860. }