gradebooktable.class.php 39 KB

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