flatview_data_generator.class.php 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. /**
  4. * Class FlatViewDataGenerator
  5. * Class to select, sort and transform object data into array data,
  6. * used for the teacher's flat view.
  7. *
  8. * @author Bert Steppé
  9. *
  10. * @package chamilo.gradebook
  11. */
  12. class FlatViewDataGenerator
  13. {
  14. // Sorting types constants
  15. const FVDG_SORT_LASTNAME = 1;
  16. const FVDG_SORT_FIRSTNAME = 2;
  17. const FVDG_SORT_ASC = 4;
  18. const FVDG_SORT_DESC = 8;
  19. public $params;
  20. /** @var Category */
  21. public $category;
  22. private $users;
  23. private $evals;
  24. private $links;
  25. private $evals_links;
  26. private $mainCourseCategory;
  27. /**
  28. * @param array $users
  29. * @param array $evals
  30. * @param array $links
  31. * @param array $params
  32. * @param Category|null $mainCourseCategory
  33. */
  34. public function __construct(
  35. $users = [],
  36. $evals = [],
  37. $links = [],
  38. $params = [],
  39. $mainCourseCategory = null
  40. ) {
  41. $this->users = isset($users) ? $users : [];
  42. $this->evals = isset($evals) ? $evals : [];
  43. $this->links = isset($links) ? $links : [];
  44. $this->evals_links = array_merge($this->evals, $this->links);
  45. $this->params = $params;
  46. $this->mainCourseCategory = $mainCourseCategory;
  47. }
  48. /**
  49. * @return Category
  50. */
  51. public function getMainCourseCategory()
  52. {
  53. return $this->mainCourseCategory;
  54. }
  55. /**
  56. * Get total number of users (rows).
  57. *
  58. * @return int
  59. */
  60. public function get_total_users_count()
  61. {
  62. return count($this->users);
  63. }
  64. /**
  65. * Get total number of evaluations/links (columns) (the 2 users columns not included).
  66. *
  67. * @return int
  68. */
  69. public function get_total_items_count()
  70. {
  71. return count($this->evals_links);
  72. }
  73. /**
  74. * Get array containing column header names (incl user columns).
  75. *
  76. * @param int $items_start Start item offset
  77. * @param int $items_count Number of items to get
  78. * @param bool $show_detail whether to show the details or not
  79. *
  80. * @return array List of headers
  81. */
  82. public function get_header_names($items_start = 0, $items_count = null, $show_detail = false)
  83. {
  84. $headers = [];
  85. if (isset($this->params['show_official_code']) && $this->params['show_official_code']) {
  86. $headers[] = get_lang('Code');
  87. }
  88. if (isset($this->params['join_firstname_lastname']) && $this->params['join_firstname_lastname']) {
  89. if (api_is_western_name_order()) {
  90. $headers[] = get_lang('First Name and Last Name');
  91. } else {
  92. $headers[] = get_lang('Last Name and First Name');
  93. }
  94. } else {
  95. if (api_is_western_name_order()) {
  96. $headers[] = get_lang('First name');
  97. $headers[] = get_lang('Last name');
  98. } else {
  99. $headers[] = get_lang('Last name');
  100. $headers[] = get_lang('First name');
  101. }
  102. }
  103. $headers[] = get_lang('Username');
  104. $this->addExtraFieldColumnsHeaders($headers);
  105. if (!isset($items_count)) {
  106. $items_count = count($this->evals_links) - $items_start;
  107. }
  108. $parent_id = $this->category->get_parent_id();
  109. if ($parent_id == 0 ||
  110. isset($this->params['only_subcat']) &&
  111. $this->params['only_subcat'] == $this->category->get_id()
  112. ) {
  113. $main_weight = $this->category->get_weight();
  114. } else {
  115. $main_cat = Category::load($parent_id, null, null);
  116. $main_weight = $main_cat[0]->get_weight();
  117. }
  118. //@todo move these in a function
  119. $sum_categories_weight_array = [];
  120. $mainCategoryId = null;
  121. $mainCourseCategory = $this->getMainCourseCategory();
  122. if (!empty($mainCourseCategory)) {
  123. $mainCategoryId = $mainCourseCategory->get_id();
  124. }
  125. // No category was added
  126. $course_code = api_get_course_id();
  127. $session_id = api_get_session_id();
  128. $model = ExerciseLib::getCourseScoreModel();
  129. $allcat = $this->category->get_subcategories(
  130. null,
  131. $course_code,
  132. $session_id,
  133. 'ORDER BY id'
  134. );
  135. $evaluationsAdded = [];
  136. if ($parent_id == 0 && !empty($allcat)) {
  137. // Means there are any subcategory
  138. /** @var Category $sub_cat */
  139. foreach ($allcat as $sub_cat) {
  140. $sub_cat_weight = round(100 * $sub_cat->get_weight() / $main_weight, 1);
  141. $add_weight = " $sub_cat_weight %";
  142. $mainHeader = Display::url(
  143. $sub_cat->get_name(),
  144. api_get_self().'?selectcat='.$sub_cat->get_id().'&'.api_get_cidreq()
  145. ).$add_weight;
  146. if (api_get_setting('gradebook_detailed_admin_view') === 'true') {
  147. $links = $sub_cat->get_links();
  148. $evaluations = $sub_cat->get_evaluations();
  149. /** @var ExerciseLink $link */
  150. $linkNameList = [];
  151. foreach ($links as $link) {
  152. $linkNameList[] = $link->get_name();
  153. }
  154. $evalNameList = [];
  155. foreach ($evaluations as $evaluation) {
  156. $evalNameList[] = $evaluation->get_name();
  157. }
  158. $finalList = array_merge($linkNameList, $evalNameList);
  159. if (!empty($finalList)) {
  160. $finalList[] = get_lang('Average');
  161. }
  162. $list = [];
  163. $list['items'] = $finalList;
  164. $list['header'] = '<span class="text-center">'.$mainHeader.'</span>';
  165. $headers[] = $list;
  166. } else {
  167. $headers[] = '<span class="text-center">'.$mainHeader.'</span>';
  168. }
  169. }
  170. } else {
  171. if (!isset($this->params['only_total_category']) ||
  172. (isset($this->params['only_total_category']) &&
  173. $this->params['only_total_category'] == false)
  174. ) {
  175. for ($count = 0; ($count < $items_count) && ($items_start + $count < count($this->evals_links)); $count++) {
  176. /** @var AbstractLink $item */
  177. $item = $this->evals_links[$count + $items_start];
  178. $weight = round(100 * $item->get_weight() / $main_weight, 1);
  179. $label = $item->get_name().' '.$weight.' % ';
  180. if (!empty($model)) {
  181. $label = $item->get_name();
  182. }
  183. $headers[] = $label;
  184. $evaluationsAdded[] = $item->get_id();
  185. }
  186. }
  187. }
  188. if (!empty($mainCategoryId)) {
  189. for ($count = 0; ($count < $items_count) && ($items_start + $count < count($this->evals_links)); $count++) {
  190. /** @var AbstractLink $item */
  191. $item = $this->evals_links[$count + $items_start];
  192. if ($mainCategoryId == $item->get_category_id() &&
  193. !in_array($item->get_id(), $evaluationsAdded)
  194. ) {
  195. $weight = round(100 * $item->get_weight() / $main_weight, 1);
  196. $label = $item->get_name().' '.$weight.' % ';
  197. if (!empty($model)) {
  198. $label = $item->get_name();
  199. }
  200. $headers[] = $label;
  201. }
  202. }
  203. }
  204. $headers[] = '<span class="text-center">'.api_strtoupper(get_lang('Total')).'</span>';
  205. return $headers;
  206. }
  207. /**
  208. * @param int $id
  209. *
  210. * @return int
  211. */
  212. public function get_max_result_by_link($id)
  213. {
  214. $max = 0;
  215. foreach ($this->users as $user) {
  216. $item = $this->evals_links[$id];
  217. $score = $item->calc_score($user[0]);
  218. if ($score[0] > $max) {
  219. $max = $score[0];
  220. }
  221. }
  222. return $max;
  223. }
  224. /**
  225. * Get array containing evaluation items.
  226. *
  227. * @return array
  228. */
  229. public function get_evaluation_items($items_start = 0, $items_count = null)
  230. {
  231. $headers = [];
  232. if (!isset($items_count)) {
  233. $items_count = count($this->evals_links) - $items_start;
  234. }
  235. for ($count = 0; ($count < $items_count) && ($items_start + $count < count($this->evals_links)); $count++) {
  236. $item = $this->evals_links[$count + $items_start];
  237. $headers[] = $item->get_name();
  238. }
  239. return $headers;
  240. }
  241. /**
  242. * Get actual array data.
  243. *
  244. * @param int $users_sorting
  245. * @param int $users_start
  246. * @param null $users_count
  247. * @param int $items_start
  248. * @param null $items_count
  249. * @param bool $ignore_score_color
  250. * @param bool $show_all
  251. *
  252. * @return array 2-dimensional array - each array contains the elements:
  253. * 0: user id
  254. * 1: user lastname
  255. * 2: user firstname
  256. * 3+: evaluation/link scores
  257. */
  258. public function get_data(
  259. $users_sorting = 0,
  260. $users_start = 0,
  261. $users_count = null,
  262. $items_start = 0,
  263. $items_count = null,
  264. $ignore_score_color = false,
  265. $show_all = false
  266. ) {
  267. // Do some checks on users/items counts, redefine if invalid values
  268. if (!isset($users_count)) {
  269. $users_count = count($this->users) - $users_start;
  270. }
  271. if ($users_count < 0) {
  272. $users_count = 0;
  273. }
  274. if (!isset($items_count)) {
  275. $items_count = count($this->evals) + count($this->links) - $items_start;
  276. }
  277. if ($items_count < 0) {
  278. $items_count = 0;
  279. }
  280. $userTable = [];
  281. foreach ($this->users as $user) {
  282. $userTable[] = $user;
  283. }
  284. // sort users array
  285. if ($users_sorting & self::FVDG_SORT_LASTNAME) {
  286. usort($userTable, ['FlatViewDataGenerator', 'sort_by_last_name']);
  287. } elseif ($users_sorting & self::FVDG_SORT_FIRSTNAME) {
  288. usort($userTable, ['FlatViewDataGenerator', 'sort_by_first_name']);
  289. }
  290. if ($users_sorting & self::FVDG_SORT_DESC) {
  291. $userTable = array_reverse($userTable);
  292. }
  293. // Select the requested users
  294. $selected_users = array_slice($userTable, $users_start, $users_count);
  295. // Generate actual data array
  296. $scoreDisplay = ScoreDisplay::instance();
  297. $data = [];
  298. //@todo move these in a function
  299. $sum_categories_weight_array = [];
  300. $mainCategoryId = null;
  301. $mainCourseCategory = $this->getMainCourseCategory();
  302. if (!empty($mainCourseCategory)) {
  303. $mainCategoryId = $mainCourseCategory->get_id();
  304. }
  305. if (isset($this->category) && !empty($this->category)) {
  306. $categories = Category::load(
  307. null,
  308. null,
  309. null,
  310. $this->category->get_id()
  311. );
  312. if (!empty($categories)) {
  313. foreach ($categories as $category) {
  314. $sum_categories_weight_array[$category->get_id()] = $category->get_weight();
  315. }
  316. } else {
  317. $sum_categories_weight_array[$this->category->get_id()] = $this->category->get_weight();
  318. }
  319. }
  320. $parent_id = $this->category->get_parent_id();
  321. if ($parent_id == 0 ||
  322. (isset($this->params['only_subcat']) && $this->params['only_subcat'] == $this->category->get_id())
  323. ) {
  324. $main_weight = $this->category->get_weight();
  325. } else {
  326. $main_cat = Category::load($parent_id, null, null);
  327. $main_weight = $main_cat[0]->get_weight();
  328. }
  329. $export_to_pdf = false;
  330. if (isset($this->params['export_pdf']) && $this->params['export_pdf']) {
  331. $export_to_pdf = true;
  332. }
  333. $course_code = api_get_course_id();
  334. $session_id = api_get_session_id();
  335. $model = ExerciseLib::getCourseScoreModel();
  336. foreach ($selected_users as $user) {
  337. $row = [];
  338. // User id
  339. if ($export_to_pdf) {
  340. $row['user_id'] = $user_id = $user[0];
  341. } else {
  342. $row[] = $user_id = $user[0];
  343. }
  344. // Official code
  345. if (isset($this->params['show_official_code']) &&
  346. $this->params['show_official_code']
  347. ) {
  348. if ($export_to_pdf) {
  349. $row['official_code'] = $user[4];
  350. } else {
  351. $row[] = $user[4];
  352. }
  353. }
  354. // Last name
  355. if (isset($this->params['join_firstname_lastname']) &&
  356. $this->params['join_firstname_lastname']
  357. ) {
  358. if ($export_to_pdf) {
  359. $row['name'] = api_get_person_name($user[3], $user[2]);
  360. } else {
  361. $row[] = api_get_person_name($user[3], $user[2]);
  362. }
  363. } else {
  364. if ($export_to_pdf) {
  365. if (api_is_western_name_order()) {
  366. $row['firstname'] = $user[3];
  367. $row['lastname'] = $user[2];
  368. } else {
  369. $row['lastname'] = $user[2];
  370. $row['firstname'] = $user[3];
  371. }
  372. } else {
  373. if (api_is_western_name_order()) {
  374. $row[] = $user[3]; //first name
  375. $row[] = $user[2]; //last name
  376. } else {
  377. $row[] = $user[2]; //last name
  378. $row[] = $user[3]; //first name
  379. }
  380. }
  381. }
  382. $row[] = $user[1];
  383. $this->addExtraFieldColumnsData($row, $user[0]);
  384. $item_value_total = 0;
  385. $item_total = 0;
  386. $allcat = $this->category->get_subcategories(
  387. null,
  388. $course_code,
  389. $session_id,
  390. 'ORDER BY id'
  391. );
  392. $evaluationsAdded = [];
  393. if ($parent_id == 0 && !empty($allcat)) {
  394. /** @var Category $sub_cat */
  395. foreach ($allcat as $sub_cat) {
  396. $score = $sub_cat->calc_score($user_id);
  397. if (api_get_setting('gradebook_detailed_admin_view') === 'true') {
  398. $links = $sub_cat->get_links();
  399. /** @var ExerciseLink $link */
  400. $linkScoreList = [];
  401. foreach ($links as $link) {
  402. $linkScore = $link->calc_score($user_id);
  403. $linkScoreList[] = $scoreDisplay->display_score(
  404. $linkScore,
  405. SCORE_SIMPLE
  406. );
  407. }
  408. $evaluations = $sub_cat->get_evaluations();
  409. $evalScoreList = [];
  410. /** @var Evaluation $evaluation */
  411. foreach ($evaluations as $evaluation) {
  412. $evalScore = $evaluation->calc_score($user_id);
  413. $evalScoreList[] = $scoreDisplay->display_score(
  414. $evalScore,
  415. SCORE_SIMPLE
  416. );
  417. }
  418. }
  419. $real_score = $score;
  420. $divide = $score[1] == 0 ? 1 : $score[1];
  421. $sub_cat_percentage = $sum_categories_weight_array[$sub_cat->get_id()];
  422. $item_value = $score[0] / $divide * $main_weight;
  423. // Fixing total when using one or multiple gradebooks
  424. $percentage = $sub_cat->get_weight() / ($sub_cat_percentage) * $sub_cat_percentage / $this->category->get_weight();
  425. $item_value = $percentage * $item_value;
  426. $item_total += $sub_cat->get_weight();
  427. $style = api_get_configuration_value('gradebook_report_score_style');
  428. $defaultStyle = SCORE_DIV_SIMPLE_WITH_CUSTOM;
  429. if (!empty($style)) {
  430. $defaultStyle = (int) $style;
  431. }
  432. if (api_get_setting('gradebook_show_percentage_in_reports') === 'false') {
  433. $defaultShowPercentageValue = SCORE_SIMPLE;
  434. if (!empty($style)) {
  435. $defaultShowPercentageValue = $style;
  436. }
  437. $real_score = $scoreDisplay->display_score(
  438. $real_score,
  439. $defaultShowPercentageValue,
  440. true
  441. );
  442. $temp_score = $scoreDisplay->display_score(
  443. $score,
  444. SCORE_DIV_SIMPLE_WITH_CUSTOM,
  445. null
  446. );
  447. $temp_score = Display::tip($real_score, $temp_score);
  448. } else {
  449. $real_score = $scoreDisplay->display_score(
  450. $real_score,
  451. SCORE_DIV_PERCENT,
  452. SCORE_ONLY_SCORE
  453. );
  454. $temp_score = $scoreDisplay->display_score(
  455. $score,
  456. $defaultStyle,
  457. null
  458. );
  459. $temp_score = Display::tip($temp_score, $real_score);
  460. }
  461. if (!isset($this->params['only_total_category']) ||
  462. (isset($this->params['only_total_category']) &&
  463. $this->params['only_total_category'] == false)
  464. ) {
  465. if (!$show_all) {
  466. if (api_get_setting('gradebook_detailed_admin_view') === 'true') {
  467. $finalList = array_merge($linkScoreList, $evalScoreList);
  468. if (empty($finalList)) {
  469. $average = 0;
  470. } else {
  471. $average = array_sum($finalList) / count($finalList);
  472. }
  473. $finalList[] = round($average, 2);
  474. foreach ($finalList as $finalValue) {
  475. $row[] = '<span class="text-center">'.$finalValue.'</span>';
  476. }
  477. } else {
  478. $row[] = $temp_score.' ';
  479. }
  480. } else {
  481. $row[] = $temp_score;
  482. }
  483. }
  484. $item_value_total += $item_value;
  485. }
  486. } else {
  487. // All evaluations
  488. $result = $this->parseEvaluations(
  489. $user_id,
  490. $sum_categories_weight_array,
  491. $items_count,
  492. $items_start,
  493. $show_all,
  494. $row
  495. );
  496. $item_value_total += $result['item_value_total'];
  497. $evaluationsAdded = $result['evaluations_added'];
  498. $item_total = $main_weight;
  499. }
  500. // All evaluations
  501. $result = $this->parseEvaluations(
  502. $user_id,
  503. $sum_categories_weight_array,
  504. $items_count,
  505. $items_start,
  506. $show_all,
  507. $row,
  508. $mainCategoryId,
  509. $evaluationsAdded
  510. );
  511. $item_total += $result['item_total'];
  512. $item_value_total += $result['item_value_total'];
  513. $total_score = [$item_value_total, $item_total];
  514. $style = api_get_configuration_value('gradebook_report_score_style');
  515. if (!$show_all) {
  516. $defaultStyle = empty($style) ? SCORE_DIV_PERCENT : (int) $style;
  517. $displayScore = $scoreDisplay->display_score($total_score, $defaultStyle);
  518. if (!empty($model)) {
  519. $displayScore = ExerciseLib::show_score($total_score[0], $total_score[1]);
  520. }
  521. if ($export_to_pdf) {
  522. $row['total'] = $displayScore;
  523. } else {
  524. $row[] = $displayScore;
  525. }
  526. } else {
  527. $defaultStyle = empty($style) ? SCORE_DIV_SIMPLE_WITH_CUSTOM_LETTERS : (int) $style;
  528. $displayScore = $scoreDisplay->display_score($total_score, $defaultStyle);
  529. if (!empty($model)) {
  530. $displayScore = ExerciseLib::show_score($total_score[0], $total_score[1]);
  531. }
  532. if ($export_to_pdf) {
  533. $row['total'] = $displayScore;
  534. } else {
  535. $row[] = $displayScore;
  536. }
  537. }
  538. unset($score);
  539. $data[] = $row;
  540. }
  541. return $data;
  542. }
  543. /**
  544. * Parse evaluations.
  545. *
  546. * @param int $user_id
  547. * @param array $sum_categories_weight_array
  548. * @param int $items_count
  549. * @param int $items_start
  550. * @param int $show_all
  551. * @param int $parentCategoryIdFilter filter by category id if set
  552. *
  553. * @return array
  554. */
  555. public function parseEvaluations(
  556. $user_id,
  557. $sum_categories_weight_array,
  558. $items_count,
  559. $items_start,
  560. $show_all,
  561. &$row,
  562. $parentCategoryIdFilter = null,
  563. $evaluationsAlreadyAdded = []
  564. ) {
  565. // Generate actual data array
  566. $scoreDisplay = ScoreDisplay::instance();
  567. $item_total = 0;
  568. $item_value_total = 0;
  569. $evaluationsAdded = [];
  570. $model = ExerciseLib::getCourseScoreModel();
  571. for ($count = 0; $count < $items_count && ($items_start + $count < count($this->evals_links)); $count++) {
  572. /** @var AbstractLink $item */
  573. $item = $this->evals_links[$count + $items_start];
  574. if (!empty($evaluationsAlreadyAdded)) {
  575. if (in_array($item->get_id(), $evaluationsAlreadyAdded)) {
  576. continue;
  577. }
  578. }
  579. if (!empty($parentCategoryIdFilter)) {
  580. if ($item->get_category_id() != $parentCategoryIdFilter) {
  581. continue;
  582. }
  583. }
  584. $evaluationsAdded[] = $item->get_id();
  585. $score = $item->calc_score($user_id);
  586. $real_score = $score;
  587. $divide = isset($score[1]) && !empty($score[1]) && $score[1] > 0 ? $score[1] : 1;
  588. // Sub cat weight
  589. $item_value = isset($score[0]) ? $score[0] / $divide : 0;
  590. // Fixing total when using one or multiple gradebooks.
  591. if (empty($parentCategoryIdFilter)) {
  592. if ($this->category->get_parent_id() == 0) {
  593. if (isset($score[0])) {
  594. $item_value = $score[0] / $divide * $item->get_weight();
  595. } else {
  596. $item_value = 0;
  597. }
  598. } else {
  599. $item_value = $item_value * $item->get_weight();
  600. }
  601. } else {
  602. $item_value = $score[0] / $divide * $item->get_weight();
  603. }
  604. $item_total += $item->get_weight();
  605. $style = api_get_configuration_value('gradebook_report_score_style');
  606. $defaultStyle = SCORE_DIV_SIMPLE_WITH_CUSTOM;
  607. if (!empty($style)) {
  608. $defaultStyle = (int) $style;
  609. }
  610. $complete_score = $scoreDisplay->display_score(
  611. $score,
  612. SCORE_DIV_PERCENT,
  613. SCORE_ONLY_SCORE
  614. );
  615. if (api_get_setting('gradebook_show_percentage_in_reports') == 'false') {
  616. $defaultShowPercentageValue = SCORE_SIMPLE;
  617. if (!empty($style)) {
  618. $defaultShowPercentageValue = $style;
  619. }
  620. $real_score = $scoreDisplay->display_score(
  621. $real_score,
  622. $defaultShowPercentageValue
  623. );
  624. $temp_score = $scoreDisplay->display_score(
  625. [$item_value, null],
  626. SCORE_DIV_SIMPLE_WITH_CUSTOM
  627. );
  628. $temp_score = Display::tip($real_score, $temp_score);
  629. } else {
  630. $temp_score = $scoreDisplay->display_score(
  631. $real_score,
  632. $defaultStyle
  633. );
  634. $temp_score = Display::tip($temp_score, $complete_score);
  635. }
  636. if (!empty($model)) {
  637. $scoreToShow = '';
  638. if (isset($score[0]) && isset($score[1])) {
  639. $scoreToShow = ExerciseLib::show_score($score[0], $score[1]);
  640. }
  641. $temp_score = $scoreToShow;
  642. }
  643. if (!isset($this->params['only_total_category']) ||
  644. (isset($this->params['only_total_category']) && $this->params['only_total_category'] == false)
  645. ) {
  646. if (!$show_all) {
  647. if (in_array(
  648. $item->get_type(),
  649. [
  650. LINK_EXERCISE,
  651. LINK_DROPBOX,
  652. LINK_STUDENTPUBLICATION,
  653. LINK_LEARNPATH,
  654. LINK_FORUM_THREAD,
  655. LINK_ATTENDANCE,
  656. LINK_SURVEY,
  657. LINK_HOTPOTATOES,
  658. ]
  659. )
  660. ) {
  661. if (!empty($score[0])) {
  662. $row[] = $temp_score.' ';
  663. } else {
  664. $row[] = '';
  665. }
  666. } else {
  667. $row[] = $temp_score.' ';
  668. }
  669. } else {
  670. $row[] = $temp_score;
  671. }
  672. }
  673. $item_value_total += $item_value;
  674. }
  675. return [
  676. 'item_total' => $item_total,
  677. 'item_value_total' => $item_value_total,
  678. 'evaluations_added' => $evaluationsAdded,
  679. ];
  680. }
  681. /**
  682. * Get actual array data evaluation/link scores.
  683. *
  684. * @param int $session_id
  685. *
  686. * @return array
  687. */
  688. public function getEvaluationSummaryResults($session_id = null)
  689. {
  690. $usertable = [];
  691. foreach ($this->users as $user) {
  692. $usertable[] = $user;
  693. }
  694. $selected_users = $usertable;
  695. // generate actual data array for all selected users
  696. $data = [];
  697. foreach ($selected_users as $user) {
  698. $row = [];
  699. for ($count = 0; $count < count($this->evals_links); $count++) {
  700. $item = $this->evals_links[$count];
  701. $score = $item->calc_score($user[0]);
  702. $porcent_score = isset($score[1]) && $score[1] > 0 ? ($score[0] * 100) / $score[1] : 0;
  703. $row[$item->get_name()] = $porcent_score;
  704. }
  705. $data[$user[0]] = $row;
  706. }
  707. // get evaluations for every user by item
  708. $data_by_item = [];
  709. foreach ($data as $uid => $items) {
  710. $tmp = [];
  711. foreach ($items as $item => $value) {
  712. $tmp[] = $item;
  713. if (in_array($item, $tmp)) {
  714. $data_by_item[$item][$uid] = $value;
  715. }
  716. }
  717. }
  718. /* Get evaluation summary results
  719. (maximum, minimum and average of evaluations for all students)
  720. */
  721. $result = [];
  722. foreach ($data_by_item as $k => $v) {
  723. $average = round(array_sum($v) / count($v));
  724. arsort($v);
  725. $maximum = array_shift($v);
  726. $minimum = array_pop($v);
  727. if (is_null($minimum)) {
  728. $minimum = 0;
  729. }
  730. $summary = [
  731. 'max' => $maximum,
  732. 'min' => $minimum,
  733. 'avg' => $average,
  734. ];
  735. $result[$k] = $summary;
  736. }
  737. return $result;
  738. }
  739. /**
  740. * @return array
  741. */
  742. public function get_data_to_graph()
  743. {
  744. // do some checks on users/items counts, redefine if invalid values
  745. $usertable = [];
  746. foreach ($this->users as $user) {
  747. $usertable[] = $user;
  748. }
  749. // sort users array
  750. usort($usertable, ['FlatViewDataGenerator', 'sort_by_first_name']);
  751. $data = [];
  752. $selected_users = $usertable;
  753. foreach ($selected_users as $user) {
  754. $row = [];
  755. $row[] = $user[0]; // user id
  756. $item_value = 0;
  757. $item_total = 0;
  758. for ($count = 0; $count < count($this->evals_links); $count++) {
  759. $item = $this->evals_links[$count];
  760. $score = $item->calc_score($user[0]);
  761. $divide = (($score[1]) == 0) ? 1 : $score[1];
  762. $item_value += $score[0] / $divide * $item->get_weight();
  763. $item_total += $item->get_weight();
  764. $score_denom = ($score[1] == 0) ? 1 : $score[1];
  765. $score_final = ($score[0] / $score_denom) * 100;
  766. $row[] = $score_final;
  767. }
  768. $score_final = ($item_value / $item_total) * 100;
  769. $row[] = $score_final;
  770. $data[] = $row;
  771. }
  772. return $data;
  773. }
  774. /**
  775. * This is a function to show the generated data.
  776. *
  777. * @param bool $displayWarning
  778. *
  779. * @return array
  780. */
  781. public function get_data_to_graph2($displayWarning = true)
  782. {
  783. $course_code = api_get_course_id();
  784. $session_id = api_get_session_id();
  785. // do some checks on users/items counts, redefine if invalid values
  786. $usertable = [];
  787. foreach ($this->users as $user) {
  788. $usertable[] = $user;
  789. }
  790. // sort users array
  791. usort($usertable, ['FlatViewDataGenerator', 'sort_by_first_name']);
  792. // generate actual data array
  793. $scoreDisplay = ScoreDisplay::instance();
  794. $data = [];
  795. $selected_users = $usertable;
  796. foreach ($selected_users as $user) {
  797. $row = [];
  798. $row[] = $user[0]; // user id
  799. $item_value = 0;
  800. $item_total = 0;
  801. $final_score = 0;
  802. $item_value_total = 0;
  803. $allcat = $this->category->get_subcategories(
  804. null,
  805. $course_code,
  806. $session_id,
  807. 'ORDER BY id'
  808. );
  809. $parent_id = $this->category->get_parent_id();
  810. if ($parent_id == 0 && !empty($allcat)) {
  811. foreach ($allcat as $sub_cat) {
  812. $score = $sub_cat->calc_score($user[0]);
  813. $real_score = $score;
  814. $main_weight = $this->category->get_weight();
  815. $divide = $score[1] == 0 ? 1 : $score[1];
  816. //$sub_cat_percentage = $sum_categories_weight_array[$sub_cat->get_id()];
  817. $item_value = $score[0] / $divide * $main_weight;
  818. $item_total += $sub_cat->get_weight();
  819. $row[] = [
  820. $item_value,
  821. trim(
  822. $scoreDisplay->display_score(
  823. $real_score,
  824. SCORE_CUSTOM,
  825. null,
  826. true
  827. )
  828. ),
  829. ];
  830. $item_value_total += $item_value;
  831. $final_score += $score[0];
  832. //$final_score = ($final_score / $item_total) * 100;
  833. }
  834. $total_score = [$final_score, $item_total];
  835. $row[] = [
  836. $final_score,
  837. trim(
  838. $scoreDisplay->display_score(
  839. $total_score,
  840. SCORE_CUSTOM,
  841. null,
  842. true
  843. )
  844. ),
  845. ];
  846. } else {
  847. for ($count = 0; $count < count($this->evals_links); $count++) {
  848. $item = $this->evals_links[$count];
  849. $score = $item->calc_score($user[0]);
  850. $divide = $score[1] == 0 ? 1 : $score[1];
  851. $item_value += $score[0] / $divide * $item->get_weight();
  852. $item_total += $item->get_weight();
  853. $score_denom = ($score[1] == 0) ? 1 : $score[1];
  854. $score_final = ($score[0] / $score_denom) * 100;
  855. $row[] = [
  856. $score_final,
  857. trim(
  858. $scoreDisplay->display_score(
  859. $score,
  860. SCORE_CUSTOM,
  861. null,
  862. true
  863. )
  864. ),
  865. ];
  866. }
  867. $total_score = [$item_value, $item_total];
  868. $score_final = ($item_value / $item_total) * 100;
  869. if ($displayWarning) {
  870. echo Display::return_message($total_score[1], 'warning');
  871. }
  872. $row[] = [
  873. $score_final,
  874. trim(
  875. $scoreDisplay->display_score(
  876. $total_score,
  877. SCORE_CUSTOM,
  878. null,
  879. true
  880. )
  881. ),
  882. ];
  883. }
  884. $data[] = $row;
  885. }
  886. return $data;
  887. }
  888. /**
  889. * @param $item1
  890. * @param $item2
  891. *
  892. * @return int
  893. */
  894. public function sort_by_last_name($item1, $item2)
  895. {
  896. return api_strcmp($item1[2], $item2[2]);
  897. }
  898. /**
  899. * @param $item1
  900. * @param $item2
  901. *
  902. * @return int
  903. */
  904. public function sort_by_first_name($item1, $item2)
  905. {
  906. return api_strcmp($item1[3], $item2[3]);
  907. }
  908. /**
  909. * Add columns heders according to gradebook_flatview_extrafields_columns conf setting.
  910. *
  911. * @param array $headers
  912. */
  913. private function addExtraFieldColumnsHeaders(array &$headers)
  914. {
  915. $extraFieldColumns = api_get_configuration_value('gradebook_flatview_extrafields_columns');
  916. if (!$extraFieldColumns || !is_array($extraFieldColumns)) {
  917. return;
  918. }
  919. foreach ($extraFieldColumns['variables'] as $extraFieldVariable) {
  920. $extraField = new ExtraField('user');
  921. $extraFieldInfo = $extraField->get_handler_field_info_by_field_variable($extraFieldVariable);
  922. $headers[] = $extraFieldInfo['display_text'];
  923. }
  924. }
  925. /**
  926. * Add columns data according to gradebook_flatview_extrafields_columns conf setting.
  927. *
  928. * @param array $row
  929. * @param int $userId
  930. */
  931. private function addExtraFieldColumnsData(array &$row, $userId)
  932. {
  933. $extraFieldColumns = api_get_configuration_value('gradebook_flatview_extrafields_columns');
  934. if (!$extraFieldColumns || !is_array($extraFieldColumns)) {
  935. return;
  936. }
  937. foreach ($extraFieldColumns['variables'] as $extraFieldVariable) {
  938. $extraFieldValue = new ExtraFieldValue('user');
  939. $extraFieldValueInfo = $extraFieldValue->get_values_by_handler_and_field_variable(
  940. $userId,
  941. $extraFieldVariable
  942. );
  943. $row[] = $extraFieldValueInfo ? $extraFieldValueInfo['value'] : null;
  944. }
  945. }
  946. }