flatviewtable.class.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. require_once dirname(__FILE__) . '/../../../inc/global.inc.php';
  4. require_once dirname(__FILE__) . '/../be.inc.php';
  5. set_time_limit(0);
  6. use CpChart\Classes\pData as pData;
  7. use CpChart\Classes\pImage as pImage;
  8. use CpChart\Classes\pCache as pCache;
  9. /**
  10. * Class FlatViewTable
  11. * Table to display flat view (all evaluations and links for all students)
  12. * @author Stijn Konings
  13. * @author Bert Steppé - (refactored, optimised)
  14. * @author Julio Montoya Armas - Gradebook Graphics
  15. *
  16. * @package chamilo.gradebook
  17. */
  18. class FlatViewTable extends SortableTable
  19. {
  20. public $datagen;
  21. private $selectcat;
  22. private $limit_enabled;
  23. private $offset;
  24. private $mainCourseCategory;
  25. /**
  26. * @param Category $selectcat
  27. * @param array $users
  28. * @param array $evals
  29. * @param array $links
  30. * @param bool $limit_enabled
  31. * @param int $offset
  32. * @param null $addparams
  33. * @param Category $mainCourseCategory
  34. */
  35. public function FlatViewTable(
  36. $selectcat,
  37. $users = array(),
  38. $evals = array(),
  39. $links = array(),
  40. $limit_enabled = false,
  41. $offset = 0,
  42. $addparams = null,
  43. $mainCourseCategory = null
  44. ) {
  45. parent :: __construct('flatviewlist', null, null, (api_is_western_name_order() xor api_sort_by_first_name()) ? 1 : 0);
  46. $this->selectcat = $selectcat;
  47. $this->datagen = new FlatViewDataGenerator(
  48. $users,
  49. $evals,
  50. $links,
  51. array('only_subcat' => $this->selectcat->get_id()),
  52. $mainCourseCategory
  53. );
  54. $this->limit_enabled = $limit_enabled;
  55. $this->offset = $offset;
  56. if (isset($addparams)) {
  57. $this->set_additional_parameters($addparams);
  58. }
  59. // step 2: generate rows: students
  60. $this->datagen->category = $this->selectcat;
  61. $this->mainCourseCategory = $mainCourseCategory;
  62. }
  63. /**
  64. * @param bool $value
  65. */
  66. public function setLimitEnabled($value)
  67. {
  68. $this->limit_enabled = (bool) $value;
  69. }
  70. /**
  71. * @return Category
  72. */
  73. public function getMainCourseCategory()
  74. {
  75. return $this->mainCourseCategory;
  76. }
  77. /**
  78. *
  79. */
  80. public function display_graph_by_resource()
  81. {
  82. $headerName = $this->datagen->get_header_names();
  83. $total_users = $this->datagen->get_total_users_count();
  84. if ($this->datagen->get_total_items_count() > 0 && $total_users > 0) {
  85. //Removing first name
  86. array_shift($headerName);
  87. //Removing last name
  88. array_shift($headerName);
  89. $displayscore = ScoreDisplay::instance();
  90. $customdisplays = $displayscore->get_custom_score_display_settings();
  91. if (is_array($customdisplays) && count(($customdisplays))) {
  92. $user_results = $this->datagen->get_data_to_graph2(false);
  93. $pre_result = $new_result = array();
  94. foreach ($user_results as $result) {
  95. for ($i = 0; $i < count($headerName); $i++) {
  96. $pre_result[$i + 3][] = $result[$i + 1];
  97. }
  98. }
  99. $i = 0;
  100. $show_draw = false;
  101. $resource_list = array();
  102. $pre_result2 = array();
  103. foreach ($pre_result as $key => $res_array) {
  104. rsort($res_array);
  105. $pre_result2[] = $res_array;
  106. }
  107. //@todo when a display custom does not exist the order of the color does not match
  108. //filling all the answer that are not responded with 0
  109. rsort($customdisplays);
  110. if ($total_users > 0) {
  111. foreach ($pre_result2 as $key => $res_array) {
  112. $key_list = array();
  113. foreach ($res_array as $user_result) {
  114. $resource_list[$key][$user_result[1]] += 1;
  115. $key_list[] = $user_result[1];
  116. }
  117. foreach ($customdisplays as $display) {
  118. if (!in_array($display['display'], $key_list))
  119. $resource_list[$key][$display['display']] = 0;
  120. }
  121. $i++;
  122. }
  123. }
  124. //fixing $resource_list
  125. $max = 0;
  126. $new_list = array();
  127. foreach ($resource_list as $key => $value) {
  128. $new_value = array();
  129. foreach ($customdisplays as $item) {
  130. if ($value[$item['display']] > $max) {
  131. $max = $value[$item['display']];
  132. }
  133. $new_value[$item['display']] = strip_tags($value[$item['display']]);
  134. }
  135. $new_list[] = $new_value;
  136. }
  137. $resource_list = $new_list;
  138. $i = 1;
  139. foreach ($resource_list as $key => $resource) {
  140. // Reverse array, otherwise we get highest values first
  141. $resource = array_reverse($resource, true);
  142. $dataSet = new pData();
  143. $dataSet->addPoints($resource, 'Serie');
  144. $dataSet->addPoints(array_keys($resource), 'Labels');
  145. $dataSet->setSerieDescription('Labels', strip_tags($headerName[$i - 1]));
  146. $dataSet->setAbscissa('Labels');
  147. $dataSet->setAbscissaName(get_lang('GradebookSkillsRanking'));
  148. $dataSet->setAxisName(0, get_lang('Students'));
  149. $palette = array(
  150. '0' => array('R' => 186, 'G' => 206, 'B' => 151, 'Alpha' => 100),
  151. '1' => array('R' => 210, 'G' => 148, 'B' => 147, 'Alpha' => 100),
  152. '2' => array('R' => 148, 'G' => 170, 'B' => 208, 'Alpha' => 100),
  153. '3' => array('R' => 221, 'G' => 133, 'B' => 61, 'Alpha' => 100),
  154. '4' => array('R' => 65, 'G' => 153, 'B' => 176, 'Alpha' => 100),
  155. '5' => array('R' => 114, 'G' => 88, 'B' => 144, 'Alpha' => 100),
  156. '6' => array('R' => 138, 'G' => 166, 'B' => 78, 'Alpha' => 100),
  157. '7' => array('R' => 171, 'G' => 70, 'B' => 67, 'Alpha' => 100),
  158. '8' => array('R' => 69, 'G' => 115, 'B' => 168, 'Alpha' => 100),
  159. );
  160. // Cache definition
  161. $cachePath = api_get_path(SYS_ARCHIVE_PATH);
  162. $myCache = new pCache(array('CacheFolder' => substr($cachePath, 0, strlen($cachePath) - 1)));
  163. $chartHash = $myCache->getHash($dataSet);
  164. if ($myCache->isInCache($chartHash)) {
  165. $imgPath = api_get_path(SYS_ARCHIVE_PATH) . $chartHash;
  166. $myCache->saveFromCache($chartHash, $imgPath);
  167. $imgPath = api_get_path(WEB_ARCHIVE_PATH) . $chartHash;
  168. } else {
  169. /* Create the pChart object */
  170. $widthSize = 480;
  171. $heightSize = 250;
  172. $myPicture = new pImage($widthSize, $heightSize, $dataSet);
  173. /* Turn of Antialiasing */
  174. $myPicture->Antialias = false;
  175. /* Add a border to the picture */
  176. $myPicture->drawRectangle(
  177. 0,
  178. 0,
  179. $widthSize - 1,
  180. $heightSize - 1,
  181. array(
  182. 'R' => 0,
  183. 'G' => 0,
  184. 'B' => 0
  185. )
  186. );
  187. /* Set the default font */
  188. $myPicture->setFontProperties(
  189. array(
  190. 'FontName' => api_get_path(SYS_FONTS_PATH) . 'opensans/OpenSans-Regular.ttf',
  191. 'FontSize' => 10
  192. )
  193. );
  194. /* Write the chart title */
  195. $myPicture->drawText(
  196. 250,
  197. 30,
  198. strip_tags($headerName[$i - 1]),
  199. array(
  200. 'FontSize' => 12,
  201. 'Align' => TEXT_ALIGN_BOTTOMMIDDLE
  202. )
  203. );
  204. /* Define the chart area */
  205. $myPicture->setGraphArea(50, 40, $widthSize - 20, $heightSize - 50);
  206. /* Draw the scale */
  207. $scaleSettings = array(
  208. 'GridR' => 200,
  209. 'GridG' => 200,
  210. 'GridB' => 200,
  211. 'DrawSubTicks' => true,
  212. 'CycleBackground' => true,
  213. 'Mode' => SCALE_MODE_START0
  214. );
  215. $myPicture->drawScale($scaleSettings);
  216. /* Turn on shadow computing */
  217. $myPicture->setShadow(
  218. true,
  219. array(
  220. 'X' => 1,
  221. 'Y' => 1,
  222. 'R' => 0,
  223. 'G' => 0,
  224. 'B' => 0,
  225. 'Alpha' => 10
  226. )
  227. );
  228. /* Draw the chart */
  229. $myPicture->setShadow(
  230. true,
  231. array(
  232. 'X' => 1,
  233. 'Y' => 1,
  234. 'R' => 0,
  235. 'G' => 0,
  236. 'B' => 0,
  237. 'Alpha' => 10
  238. )
  239. );
  240. $settings = array(
  241. 'OverrideColors' => $palette,
  242. 'Gradient' => false,
  243. 'GradientMode' => GRADIENT_SIMPLE,
  244. 'DisplayPos' => LABEL_POS_TOP,
  245. 'DisplayValues' => true,
  246. 'DisplayR' => 0,
  247. 'DisplayG' => 0,
  248. 'DisplayB' => 0,
  249. 'DisplayShadow' => true,
  250. 'Surrounding' => 10,
  251. );
  252. $myPicture->drawBarChart($settings);
  253. /* Render the picture (choose the best way) */
  254. $myCache->writeToCache($chartHash, $myPicture);
  255. $imgPath = api_get_path(SYS_ARCHIVE_PATH) . $chartHash;
  256. $myCache->saveFromCache($chartHash, $imgPath);
  257. $imgPath = api_get_path(WEB_ARCHIVE_PATH) . $chartHash;
  258. }
  259. echo '<img src="' . $imgPath . '" >';
  260. if ($i % 2 == 0 && $i != 0) {
  261. echo '<br /><br />';
  262. } else {
  263. echo '&nbsp;&nbsp;&nbsp;';
  264. }
  265. $i++;
  266. }
  267. } //end foreach
  268. } else {
  269. echo get_lang('ToViewGraphScoreRuleMustBeEnabled');
  270. }
  271. }
  272. /**
  273. * Function used by SortableTable to get total number of items in the table
  274. */
  275. public function get_total_number_of_items()
  276. {
  277. return $this->datagen->get_total_users_count();
  278. }
  279. /**
  280. * Function used by SortableTable to generate the data to display
  281. */
  282. public function get_table_data($from = 1, $per_page = null, $column = null, $direction = null, $sort = null)
  283. {
  284. $is_western_name_order = api_is_western_name_order();
  285. // create page navigation if needed
  286. $totalitems = $this->datagen->get_total_items_count();
  287. if ($this->limit_enabled && $totalitems > LIMIT) {
  288. $selectlimit = LIMIT;
  289. } else {
  290. $selectlimit = $totalitems;
  291. }
  292. $header = null;
  293. if ($this->limit_enabled && $totalitems > LIMIT) {
  294. $header .= '<table style="width: 100%; text-align: right; margin-left: auto; margin-right: auto;" border="0" cellpadding="2">'
  295. . '<tbody>'
  296. . '<tr>';
  297. // previous X
  298. $header .= '<td style="width:100%;">';
  299. if ($this->offset >= LIMIT) {
  300. $header .= '<a href="' . api_get_self()
  301. . '?selectcat=' . Security::remove_XSS($_GET['selectcat'])
  302. . '&offset=' . (($this->offset) - LIMIT)
  303. . (isset($_GET['search']) ? '&search=' . Security::remove_XSS($_GET['search']) : '') . '">'
  304. . Display::return_icon('action_prev.png', get_lang('PreviousPage'), array(), 32)
  305. . '</a>';
  306. } else {
  307. $header .= Display::return_icon('action_prev_na.png', get_lang('PreviousPage'), array(), 32);
  308. }
  309. $header .= ' ';
  310. // next X
  311. $calcnext = (($this->offset + (2 * LIMIT)) > $totalitems) ?
  312. ($totalitems - (LIMIT + $this->offset)) : LIMIT;
  313. if ($calcnext > 0) {
  314. $header .= '<a href="' . api_get_self()
  315. . '?selectcat=' . Security::remove_XSS($_GET['selectcat'])
  316. . '&offset=' . ($this->offset + LIMIT)
  317. . (isset($_GET['search']) ? '&search=' . Security::remove_XSS($_GET['search']) : '') . '">'
  318. . Display::return_icon('action_next.png', get_lang('NextPage'), array(), 32)
  319. . '</a>';
  320. } else {
  321. $header .= Display::return_icon('action_next_na.png', get_lang('NextPage'), array(), 32);
  322. }
  323. $header .= '</td>';
  324. $header .= '</tbody></table>';
  325. echo $header;
  326. }
  327. // retrieve sorting type
  328. if ($is_western_name_order) {
  329. //$users_sorting = ($this->column == 0 ? FlatViewDataGenerator :: FVDG_SORT_FIRSTNAME : FlatViewDataGenerator :: FVDG_SORT_LASTNAME);
  330. $users_sorting = FlatViewDataGenerator :: FVDG_SORT_FIRSTNAME;
  331. } else {
  332. //$users_sorting = ($this->column == 0 ? FlatViewDataGenerator :: FVDG_SORT_LASTNAME : FlatViewDataGenerator :: FVDG_SORT_FIRSTNAME);
  333. $users_sorting = FlatViewDataGenerator :: FVDG_SORT_LASTNAME;
  334. }
  335. if ($this->direction == 'DESC') {
  336. $users_sorting |= FlatViewDataGenerator :: FVDG_SORT_DESC;
  337. } else {
  338. $users_sorting |= FlatViewDataGenerator :: FVDG_SORT_ASC;
  339. }
  340. // step 1: generate columns: evaluations and links
  341. $header_names = $this->datagen->get_header_names($this->offset, $selectlimit);
  342. if ($is_western_name_order) {
  343. $this->set_header(0, $header_names[1]);
  344. $this->set_header(1, $header_names[0]);
  345. } else {
  346. $this->set_header(0, $header_names[0]);
  347. $this->set_header(1, $header_names[1]);
  348. }
  349. $column = 2;
  350. while ($column < count($header_names)) {
  351. $this->set_header($column, $header_names[$column], false);
  352. $column++;
  353. }
  354. $data_array = $this->datagen->get_data(
  355. $users_sorting,
  356. $from,
  357. $this->per_page,
  358. $this->offset,
  359. $selectlimit
  360. );
  361. $table_data = array();
  362. foreach ($data_array as $user_row) {
  363. $table_row = array();
  364. $count = 0;
  365. $user_id = $user_row[$count++];
  366. $lastname = $user_row[$count++];
  367. $firstname = $user_row[$count++];
  368. if ($is_western_name_order) {
  369. $table_row[] = $this->build_name_link($user_id, $firstname);
  370. $table_row[] = $this->build_name_link($user_id, $lastname);
  371. } else {
  372. $table_row[] = $this->build_name_link($user_id, $lastname);
  373. $table_row[] = $this->build_name_link($user_id, $firstname);
  374. }
  375. while ($count < count($user_row)) {
  376. $table_row[] = $user_row[$count++];
  377. }
  378. $table_data[] = $table_row;
  379. }
  380. return $table_data;
  381. }
  382. /**
  383. * @param $user_id
  384. * @param $name
  385. *
  386. * @return string
  387. */
  388. private function build_name_link($user_id, $name)
  389. {
  390. return '<a href="user_stats.php?userid=' . $user_id . '&selectcat=' . $this->selectcat->get_id() . '&'.api_get_cidreq().'">' . $name . '</a>';
  391. }
  392. }