gradebooktable.class.php 40 KB

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