block_evaluation_graph.class.php 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. use CpChart\Cache as pCache;
  4. use CpChart\Data as pData;
  5. use CpChart\Image as pImage;
  6. /**
  7. * Class BlockEvaluationGraph
  8. * This class is used like controller for this evaluations graph block plugin,
  9. * the class name must be registered inside path.info file
  10. * (e.g: controller = "BlockEvaluationGraph"),
  11. * so dashboard controller will be instantiate it.
  12. *
  13. * This file is part of evaluation graph block plugin for dashboard,
  14. * it should be required inside dashboard controller for showing it
  15. * into dashboard interface from platform
  16. *
  17. * @package chamilo.dashboard
  18. *
  19. * @author Christian Fasanando
  20. */
  21. class BlockEvaluationGraph extends Block
  22. {
  23. private $user_id;
  24. private $courses;
  25. private $sessions;
  26. private $path;
  27. private $permission = [DRH, SESSIONADMIN];
  28. /**
  29. * Constructor.
  30. */
  31. public function __construct($user_id)
  32. {
  33. $this->path = 'block_evaluation_graph';
  34. $this->user_id = $user_id;
  35. $this->bg_width = 450;
  36. $this->bg_height = 350;
  37. if ($this->is_block_visible_for_user($user_id)) {
  38. if (!api_is_session_admin()) {
  39. $this->courses = CourseManager::get_courses_followed_by_drh($user_id);
  40. }
  41. $this->sessions = SessionManager::get_sessions_followed_by_drh($user_id);
  42. }
  43. }
  44. /**
  45. * This method check if a user is allowed to see the block inside dashboard interface.
  46. *
  47. * @param int User id
  48. *
  49. * @return bool Is block visible for user
  50. */
  51. public function is_block_visible_for_user($user_id)
  52. {
  53. $user_info = api_get_user_info($user_id);
  54. $user_status = $user_info['status'];
  55. $is_block_visible_for_user = false;
  56. if (UserManager::is_admin($user_id) || in_array($user_status, $this->permission)) {
  57. $is_block_visible_for_user = true;
  58. }
  59. return $is_block_visible_for_user;
  60. }
  61. /**
  62. * This method return content html containing
  63. * information about sessions and its position for showing it inside dashboard interface
  64. * it's important to use the name 'get_block' for beeing used from dashboard controller.
  65. *
  66. * @return array column and content html
  67. */
  68. public function get_block()
  69. {
  70. global $charset;
  71. $column = 1;
  72. $data = [];
  73. $evaluations_base_courses_graph = $this->get_evaluations_base_courses_graph();
  74. $evaluations_courses_in_sessions_graph = $this->get_evaluations_courses_in_sessions_graph();
  75. $html = '<div class="panel panel-default" id="intro">
  76. <div class="panel-heading">
  77. '.get_lang('EvaluationsGraph').'
  78. <div class="pull-right"><a class="btn btn-danger btn-xs" onclick="javascript:if(!confirm(\''.addslashes(api_htmlentities(get_lang('ConfirmYourChoice'), ENT_QUOTES, $charset)).'\')) return false;" href="index.php?action=disable_block&path='.$this->path.'">
  79. <em class="fa fa-times"></em>
  80. </a></div>
  81. </div>
  82. <div class="panel-body">';
  83. if (empty($evaluations_base_courses_graph) && empty($evaluations_courses_in_sessions_graph)) {
  84. $html .= '<p>'.api_convert_encoding(get_lang('GraphicNotAvailable'), 'UTF-8').'</p>';
  85. } else {
  86. // display evaluations base courses graph
  87. if (!empty($evaluations_base_courses_graph)) {
  88. foreach ($evaluations_base_courses_graph as $course_code => $img_html) {
  89. $html .= '<div><strong>'.$course_code.'</strong></div>';
  90. $html .= $img_html;
  91. }
  92. }
  93. // display evaluations base courses graph
  94. if (!empty($evaluations_courses_in_sessions_graph)) {
  95. foreach ($evaluations_courses_in_sessions_graph as $session_id => $courses) {
  96. $session_name = api_get_session_name($session_id);
  97. $html .= '<div><strong>'.$session_name.':'.get_lang('Evaluations').'</strong></div>';
  98. foreach ($courses as $course_code => $img_html) {
  99. $html .= '<div><strong>'.$course_code.'</strong></div>';
  100. $html .= $img_html;
  101. }
  102. }
  103. }
  104. }
  105. $html .= '</div>
  106. </div>';
  107. $data['column'] = $column;
  108. $data['content_html'] = $html;
  109. return $data;
  110. }
  111. /**
  112. * This method return a graph containing informations about evaluations
  113. * inside base courses, it's used inside get_block method for showing
  114. * it inside dashboard interface.
  115. *
  116. * @return string img html
  117. */
  118. public function get_evaluations_base_courses_graph()
  119. {
  120. $graphs = [];
  121. if (!empty($this->courses)) {
  122. $courses_code = array_keys($this->courses);
  123. foreach ($courses_code as $course_code) {
  124. $cats = Category::load(
  125. null,
  126. null,
  127. $course_code,
  128. null,
  129. null,
  130. null,
  131. false
  132. );
  133. if (isset($cats) && isset($cats[0])) {
  134. $alleval = $cats[0]->get_evaluations(null, true, $course_code);
  135. $alllinks = $cats[0]->get_links(null, true);
  136. $users = GradebookUtils::get_all_users($alleval, $alllinks);
  137. $datagen = new FlatViewDataGenerator($users, $alleval, $alllinks);
  138. $evaluation_sumary = $datagen->getEvaluationSummaryResults();
  139. if (!empty($evaluation_sumary)) {
  140. $items = array_keys($evaluation_sumary);
  141. $max = $min = $avg = [];
  142. foreach ($evaluation_sumary as $evaluation) {
  143. $max[] = $evaluation['max'];
  144. $min[] = !empty($evaluation['min']) ? $evaluation['min'] : 0;
  145. $avg[] = $evaluation['avg'];
  146. }
  147. // Dataset definition
  148. $dataSet = new pData();
  149. $dataSet->addPoints($min, 'Serie3');
  150. $dataSet->addPoints($avg, 'Serie2');
  151. $dataSet->addPoints($max, 'Serie1');
  152. $dataSet->addPoints($items, 'Labels');
  153. $dataSet->setSerieDescription('Serie1', get_lang('Max'));
  154. $dataSet->setSerieDescription('Serie2', get_lang('Avg'));
  155. $dataSet->setSerieDescription('Serie3', get_lang('Min'));
  156. $dataSet->setAbscissa('Labels');
  157. $dataSet->setAbscissaName(get_lang('EvaluationName'));
  158. $dataSet->normalize(100, '%');
  159. $dataSet->loadPalette(api_get_path(SYS_CODE_PATH).'palettes/pchart/default.color', true);
  160. // Cache definition
  161. $cachePath = api_get_path(SYS_ARCHIVE_PATH);
  162. $myCache = new pCache(['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 = $this->bg_width;
  171. $heightSize = $this->bg_height;
  172. $fontSize = 8;
  173. $angle = 50;
  174. $myPicture = new pImage($widthSize, $heightSize, $dataSet);
  175. /* Turn of Antialiasing */
  176. $myPicture->Antialias = false;
  177. /* Add a border to the picture */
  178. $myPicture->drawRectangle(
  179. 0,
  180. 0,
  181. $widthSize - 1,
  182. $heightSize - 1,
  183. [
  184. 'R' => 0,
  185. 'G' => 0,
  186. 'B' => 0,
  187. ]
  188. );
  189. /* Set the default font */
  190. $myPicture->setFontProperties(
  191. [
  192. 'FontName' => api_get_path(SYS_FONTS_PATH).'opensans/OpenSans-Regular.ttf',
  193. 'FontSize' => 10,
  194. ]
  195. );
  196. /* Do NOT Write the chart title */
  197. /* Define the chart area */
  198. $myPicture->setGraphArea(
  199. 50,
  200. 30,
  201. $widthSize - 20,
  202. $heightSize - 100
  203. );
  204. /* Draw the scale */
  205. $scaleSettings = [
  206. 'GridR' => 200,
  207. 'GridG' => 200,
  208. 'GridB' => 200,
  209. 'DrawSubTicks' => true,
  210. 'CycleBackground' => true,
  211. 'Mode' => SCALE_MODE_MANUAL,
  212. 'ManualScale' => [
  213. '0' => [
  214. 'Min' => 0,
  215. 'Max' => 100,
  216. ],
  217. ],
  218. 'LabelRotation' => $angle,
  219. ];
  220. $myPicture->drawScale($scaleSettings);
  221. /* Turn on shadow computing */
  222. $myPicture->setShadow(
  223. true,
  224. [
  225. 'X' => 1,
  226. 'Y' => 1,
  227. 'R' => 0,
  228. 'G' => 0,
  229. 'B' => 0,
  230. 'Alpha' => 10,
  231. ]
  232. );
  233. /* Draw the chart */
  234. $myPicture->setShadow(
  235. true,
  236. [
  237. 'X' => 1,
  238. 'Y' => 1,
  239. 'R' => 0,
  240. 'G' => 0,
  241. 'B' => 0,
  242. 'Alpha' => 10,
  243. ]
  244. );
  245. $settings = [
  246. 'DisplayValues' => true,
  247. 'DisplaySize' => $fontSize,
  248. 'DisplayR' => 0,
  249. 'DisplayG' => 0,
  250. 'DisplayB' => 0,
  251. 'DisplayOrientation' => ORIENTATION_HORIZONTAL,
  252. 'Gradient' => false,
  253. 'Surrounding' => 30,
  254. 'InnerSurrounding' => 25,
  255. ];
  256. $myPicture->drawStackedBarChart($settings);
  257. $legendSettings = [
  258. 'Mode' => LEGEND_HORIZONTAL,
  259. 'Style' => LEGEND_NOBORDER,
  260. ];
  261. $myPicture->drawLegend($widthSize / 2, 15, $legendSettings);
  262. /* Write and save into cache */
  263. $myCache->writeToCache($chartHash, $myPicture);
  264. $imgPath = api_get_path(SYS_ARCHIVE_PATH).$chartHash;
  265. $myCache->saveFromCache($chartHash, $imgPath);
  266. $imgPath = api_get_path(WEB_ARCHIVE_PATH).$chartHash;
  267. }
  268. if (!empty($imgPath)) {
  269. $courses_graph[$course_code] = '<img src="'.$imgPath.'">';
  270. }
  271. }
  272. }
  273. } // end for
  274. }
  275. return $graphs;
  276. }
  277. /**
  278. * This method return a graph containing information about evaluations
  279. * inside courses in sessions, it's used inside get_block method for
  280. * showing it inside dashboard interface.
  281. *
  282. * @return string img html
  283. */
  284. public function get_evaluations_courses_in_sessions_graph()
  285. {
  286. $graphs = [];
  287. if (!empty($this->sessions)) {
  288. $session_ids = array_keys($this->sessions);
  289. foreach ($session_ids as $session_id) {
  290. $courses_code = array_keys(Tracking::get_courses_list_from_session($session_id));
  291. $courses_graph = [];
  292. foreach ($courses_code as $course_code) {
  293. $cats = Category::load(null, null, $course_code, null, null, $session_id);
  294. if (isset($cats) && isset($cats[0])) {
  295. $alleval = $cats[0]->get_evaluations(null, true, $course_code);
  296. $alllinks = $cats[0]->get_links(null, true);
  297. $users = GradebookUtils::get_all_users($alleval, $alllinks);
  298. $datagen = new FlatViewDataGenerator($users, $alleval, $alllinks);
  299. $evaluation_sumary = $datagen->getEvaluationSummaryResults();
  300. if (!empty($evaluation_sumary)) {
  301. $items = array_keys($evaluation_sumary);
  302. $max = $min = $avg = [];
  303. foreach ($evaluation_sumary as $evaluation) {
  304. $max[] = $evaluation['max'];
  305. $min[] = $evaluation['min'];
  306. $avg[] = $evaluation['avg'];
  307. }
  308. // Dataset definition
  309. $dataSet = new pData();
  310. $dataSet->addPoints($min, 'Serie3');
  311. $dataSet->addPoints($avg, 'Serie2');
  312. $dataSet->addPoints($max, 'Serie1');
  313. $dataSet->addPoints($items, 'Labels');
  314. $dataSet->setSerieDescription('Serie1', get_lang('Max'));
  315. $dataSet->setSerieDescription('Serie2', get_lang('Avg'));
  316. $dataSet->setSerieDescription('Serie3', get_lang('Min'));
  317. $dataSet->setAbscissa('Labels');
  318. $dataSet->setAbscissaName(get_lang('EvaluationName'));
  319. $dataSet->normalize(100, '%');
  320. $dataSet->loadPalette(api_get_path(SYS_CODE_PATH).'palettes/pchart/default.color', true);
  321. // Cache definition
  322. $cachePath = api_get_path(SYS_ARCHIVE_PATH);
  323. $myCache = new pCache(
  324. [
  325. 'CacheFolder' => substr(
  326. $cachePath,
  327. 0,
  328. strlen($cachePath) - 1
  329. ),
  330. ]
  331. );
  332. $chartHash = $myCache->getHash($dataSet);
  333. if ($myCache->isInCache($chartHash)) {
  334. $imgPath = api_get_path(SYS_ARCHIVE_PATH).$chartHash;
  335. $myCache->saveFromCache($chartHash, $imgPath);
  336. $imgPath = api_get_path(WEB_ARCHIVE_PATH).$chartHash;
  337. } else {
  338. /* Create the pChart object */
  339. $widthSize = $this->bg_width;
  340. $heightSize = $this->bg_height;
  341. $fontSize = 8;
  342. $angle = 50;
  343. $myPicture = new pImage($widthSize, $heightSize, $dataSet);
  344. /* Turn of Antialiasing */
  345. $myPicture->Antialias = false;
  346. /* Add a border to the picture */
  347. $myPicture->drawRectangle(
  348. 0,
  349. 0,
  350. $widthSize - 1,
  351. $heightSize - 1,
  352. [
  353. 'R' => 0,
  354. 'G' => 0,
  355. 'B' => 0,
  356. ]
  357. );
  358. /* Set the default font */
  359. $myPicture->setFontProperties(
  360. [
  361. 'FontName' => api_get_path(SYS_FONTS_PATH).'opensans/OpenSans-Regular.ttf',
  362. 'FontSize' => 10,
  363. ]
  364. );
  365. /* Do NOT Write the chart title */
  366. /* Define the chart area */
  367. $myPicture->setGraphArea(50, 30, $widthSize - 20, $heightSize - 100);
  368. /* Draw the scale */
  369. $scaleSettings = [
  370. 'GridR' => 200,
  371. 'GridG' => 200,
  372. 'GridB' => 200,
  373. 'DrawSubTicks' => true,
  374. 'CycleBackground' => true,
  375. 'Mode' => SCALE_MODE_MANUAL,
  376. 'ManualScale' => [
  377. '0' => [
  378. 'Min' => 0,
  379. 'Max' => 100,
  380. ],
  381. ],
  382. 'LabelRotation' => $angle,
  383. ];
  384. $myPicture->drawScale($scaleSettings);
  385. /* Turn on shadow computing */
  386. $myPicture->setShadow(
  387. true,
  388. [
  389. 'X' => 1,
  390. 'Y' => 1,
  391. 'R' => 0,
  392. 'G' => 0,
  393. 'B' => 0,
  394. 'Alpha' => 10,
  395. ]
  396. );
  397. /* Draw the chart */
  398. $myPicture->setShadow(
  399. true,
  400. [
  401. 'X' => 1,
  402. 'Y' => 1,
  403. 'R' => 0,
  404. 'G' => 0,
  405. 'B' => 0,
  406. 'Alpha' => 10,
  407. ]
  408. );
  409. $settings = [
  410. 'DisplayValues' => true,
  411. 'DisplaySize' => $fontSize,
  412. 'DisplayR' => 0,
  413. 'DisplayG' => 0,
  414. 'DisplayB' => 0,
  415. 'DisplayOrientation' => ORIENTATION_HORIZONTAL,
  416. 'Gradient' => false,
  417. 'Surrounding' => 30,
  418. 'InnerSurrounding' => 25,
  419. ];
  420. $myPicture->drawStackedBarChart($settings);
  421. $legendSettings = [
  422. 'Mode' => LEGEND_HORIZONTAL,
  423. 'Style' => LEGEND_NOBORDER,
  424. ];
  425. $myPicture->drawLegend($widthSize / 2, 15, $legendSettings);
  426. /* Write and save into cache */
  427. $myCache->writeToCache($chartHash, $myPicture);
  428. $imgPath = api_get_path(SYS_ARCHIVE_PATH).$chartHash;
  429. $myCache->saveFromCache($chartHash, $imgPath);
  430. $imgPath = api_get_path(WEB_ARCHIVE_PATH).$chartHash;
  431. }
  432. if (!empty($imgPath)) {
  433. $courses_graph[$course_code] = '<img src="'.$imgPath.'">';
  434. }
  435. }
  436. }
  437. }
  438. if (!empty($courses_graph)) {
  439. $graphs[$session_id] = $courses_graph;
  440. }
  441. }
  442. }
  443. return $graphs;
  444. }
  445. }