flatviewtable.class.php 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618
  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. /**
  7. * Class FlatViewTable
  8. * Table to display flat view (all evaluations and links for all students)
  9. * @author Stijn Konings
  10. * @author Bert Steppé - (refactored, optimised)
  11. * @author Julio Montoya Armas - Gradebook Graphics
  12. *
  13. * @package chamilo.gradebook
  14. */
  15. class FlatViewTable extends SortableTable
  16. {
  17. public $datagen;
  18. private $selectcat;
  19. private $limit_enabled;
  20. private $offset;
  21. private $mainCourseCategory;
  22. /**
  23. * @param Category $selectcat
  24. * @param array $users
  25. * @param array $evals
  26. * @param array $links
  27. * @param bool $limit_enabled
  28. * @param int $offset
  29. * @param null $addparams
  30. * @param Category $mainCourseCategory
  31. */
  32. public function FlatViewTable(
  33. $selectcat,
  34. $users = array(),
  35. $evals = array(),
  36. $links = array(),
  37. $limit_enabled = false,
  38. $offset = 0,
  39. $addparams = null,
  40. $mainCourseCategory = null
  41. ) {
  42. parent :: __construct('flatviewlist', null, null, api_is_western_name_order() ? 1 : 0);
  43. $this->selectcat = $selectcat;
  44. $this->datagen = new FlatViewDataGenerator(
  45. $users,
  46. $evals,
  47. $links,
  48. array('only_subcat' => $this->selectcat->get_id()),
  49. $mainCourseCategory
  50. );
  51. $this->limit_enabled = $limit_enabled;
  52. $this->offset = $offset;
  53. if (isset($addparams)) {
  54. $this->set_additional_parameters($addparams);
  55. }
  56. // step 2: generate rows: students
  57. $this->datagen->category = $this->selectcat;
  58. $this->mainCourseCategory = $mainCourseCategory;
  59. }
  60. /**
  61. * @param bool $value
  62. */
  63. public function setLimitEnabled($value)
  64. {
  65. $this->limit_enabled = (bool) $value;
  66. }
  67. /**
  68. * @return Category
  69. */
  70. public function getMainCourseCategory()
  71. {
  72. return $this->mainCourseCategory;
  73. }
  74. /**
  75. * Display the graph of the total results of all students
  76. * */
  77. public function display_graph()
  78. {
  79. include_once api_get_path(LIBRARY_PATH) . 'pchart/pData.class.php';
  80. include_once api_get_path(LIBRARY_PATH) . 'pchart/pChart.class.php';
  81. include_once api_get_path(LIBRARY_PATH) . 'pchart/pCache.class.php';
  82. $header_name = $this->datagen->get_header_names();
  83. $total_users = $this->datagen->get_total_users_count();
  84. $img_file = '';
  85. if ($this->datagen->get_total_items_count() > 0 && $total_users > 0) {
  86. // Removing user names and total
  87. array_shift($header_name);
  88. array_shift($header_name);
  89. array_pop($header_name);
  90. $user_results = $this->datagen->get_data_to_graph();
  91. $pre_result = $new_result = array();
  92. $DataSet = new pData();
  93. //$pre_result total score of students
  94. //filling the Dataset
  95. foreach ($user_results as $result) {
  96. for ($i = 0; $i < count($header_name); $i++) {
  97. $pre_result[$i + 3]+= $result[$i + 1];
  98. }
  99. }
  100. $i = 1;
  101. $show_draw = false;
  102. if ($total_users > 0) {
  103. foreach ($pre_result as $res) {
  104. $total = $res / ($total_users);
  105. if ($total != 0) {
  106. $show_draw = true;
  107. }
  108. $DataSet->AddPoint($total, "Serie" . $i);
  109. $DataSet->SetSerieName(strip_tags($header_name[$i - 1]), "Serie" . $i);
  110. // Dataset definition
  111. $DataSet->AddAllSeries();
  112. $DataSet->SetAbsciseLabelSerie();
  113. $i++;
  114. }
  115. }
  116. // Cache definition
  117. $Cache = new pCache();
  118. // the graph id
  119. $gradebook_id = intval($_GET['selectcat']);
  120. $graph_id = api_get_user_id() . 'AverageResultsVsResource' . $gradebook_id . api_get_course_id();
  121. $data = $DataSet->GetData();
  122. if ($show_draw) {
  123. if ($Cache->IsInCache($graph_id, $DataSet->GetData())) {
  124. //if (0) {
  125. //if we already created the img
  126. //echo 'in cache';
  127. $img_file = $Cache->GetHash($graph_id, $DataSet->GetData());
  128. } else {
  129. // if the image does not exist in the archive/ folder
  130. // Initialise the graph
  131. $angle = -30;
  132. $Test = new pChart(760, 360);
  133. // set font of the axes
  134. $Test->setFontProperties(api_get_path(LIBRARY_PATH) . "pchart/fonts/tahoma.ttf", 8);
  135. $Test = $Test->fixHeightByRotation($DataSet->GetData(), $DataSet->GetDataDescription(), $angle);
  136. //which schema of color will be used
  137. $quant_resources = count($data[0]) - 1;
  138. // Adding the color schemma
  139. if ($quant_resources < 8) {
  140. $Test->loadColorPalette(api_get_path(LIBRARY_PATH) . "pchart/palette/reduced.txt");
  141. } else {
  142. $Test->loadColorPalette(api_get_path(LIBRARY_PATH) . "pchart/palette/default.txt");
  143. }
  144. $Test->setGraphArea(50, 30, 610, 300);
  145. $Test->drawFilledRoundedRectangle(7, 7, $Test->XSize + 20, $Test->YSize - 30, 5, 240, 240, 240);
  146. //$Test->drawRoundedRectangle(5,5,790,330,5,230,230,230);
  147. //background color area & stripe or not
  148. $Test->drawGraphArea(255, 255, 255, TRUE);
  149. $Test->drawScale($DataSet->GetData(), $DataSet->GetDataDescription(), SCALE_START0, 150, 150, 150, TRUE, 0, 1, FALSE);
  150. //background grid
  151. $Test->drawGrid(4, TRUE, 230, 230, 230, 50);
  152. // Draw the 0 line
  153. //$Test->setFontProperties(api_get_path(LIBRARY_PATH)."pchart/fonts/tahoma.ttf",6);
  154. //$Test->drawTreshold(0,143,55,72,TRUE,TRUE);
  155. // Draw the bar graph
  156. $Test->drawBarGraph($DataSet->GetData(), $DataSet->GetDataDescription(), TRUE);
  157. //Set legend properties: width, height and text color and font
  158. $Test->setFontProperties(api_get_path(LIBRARY_PATH) . "pchart/fonts/tahoma.ttf", 9);
  159. $Test->drawLegend(620, 70, $DataSet->GetDataDescription(), 255, 255, 255);
  160. //Set title properties
  161. $Test->setFontProperties(api_get_path(LIBRARY_PATH) . "pchart/fonts/tahoma.ttf", 10);
  162. $Test->drawTitle(50, 22, get_lang('AverageResultsVsResource'), 50, 50, 80, 620);
  163. //------------------
  164. //echo 'not in cache';
  165. $Cache->WriteToCache($graph_id, $DataSet->GetData(), $Test);
  166. ob_start();
  167. $Test->Stroke();
  168. ob_end_clean();
  169. $img_file = $Cache->GetHash($graph_id, $DataSet->GetData());
  170. }
  171. }
  172. }
  173. return api_get_path(WEB_ARCHIVE_PATH) . $img_file;
  174. }
  175. /**
  176. *
  177. */
  178. public function display_graph_by_resource()
  179. {
  180. require_once api_get_path(LIBRARY_PATH) . 'pchart/pData.class.php';
  181. require_once api_get_path(LIBRARY_PATH) . 'pchart/pChart.class.php';
  182. require_once api_get_path(LIBRARY_PATH) . 'pchart/pCache.class.php';
  183. $header_name = $this->datagen->get_header_names();
  184. $total_users = $this->datagen->get_total_users_count();
  185. $img_file = '';
  186. if ($this->datagen->get_total_items_count() > 0 && $total_users > 0) {
  187. //Removing first name
  188. array_shift($header_name);
  189. //Removing last name
  190. array_shift($header_name);
  191. $displayscore = ScoreDisplay :: instance();
  192. $customdisplays = $displayscore->get_custom_score_display_settings();
  193. if (is_array($customdisplays) && count(($customdisplays))) {
  194. $user_results = $this->datagen->get_data_to_graph2(false);
  195. $pre_result = $new_result = array();
  196. $DataSet = new pData();
  197. //filling the Dataset
  198. foreach ($user_results as $result) {
  199. //print_r($result);
  200. for ($i = 0; $i < count($header_name); $i++) {
  201. $pre_result[$i + 3][] = $result[$i + 1];
  202. }
  203. }
  204. $i = 0;
  205. $show_draw = false;
  206. $resource_list = array();
  207. $pre_result2 = array();
  208. foreach ($pre_result as $key => $res_array) {
  209. rsort($res_array);
  210. $pre_result2[] = $res_array;
  211. }
  212. //@todo when a display custom does not exist the order of the color does not match
  213. //filling all the answer that are not responded with 0
  214. rsort($customdisplays);
  215. if ($total_users > 0) {
  216. foreach ($pre_result2 as $key => $res_array) {
  217. $key_list = array();
  218. foreach ($res_array as $user_result) {
  219. $resource_list[$key][$user_result[1]] += 1;
  220. $key_list[] = $user_result[1];
  221. }
  222. foreach ($customdisplays as $display) {
  223. if (!in_array($display['display'], $key_list))
  224. $resource_list[$key][$display['display']] = 0;
  225. }
  226. $i++;
  227. }
  228. }
  229. //fixing $resource_list
  230. $max = 0;
  231. $new_list = array();
  232. foreach ($resource_list as $key => $value) {
  233. $new_value = array();
  234. foreach ($customdisplays as $item) {
  235. if ($value[$item['display']] > $max) {
  236. $max = $value[$item['display']];
  237. }
  238. $new_value[$item['display']] = strip_tags($value[$item['display']]);
  239. }
  240. $new_list[] = $new_value;
  241. }
  242. $resource_list = $new_list;
  243. $i = 1;
  244. $j = 0;
  245. foreach ($resource_list as $key => $resource) {
  246. $new_resource_list = $new_resource_list_name = array();
  247. $DataSet = new pData();
  248. // Reverse array, otherwise we get highest values first
  249. $resource = array_reverse($resource, true);
  250. foreach ($resource as $name => $cant) {
  251. $DataSet->AddPoint($cant, "Serie" . $j);
  252. $DataSet->SetSerieName(strip_tags($name), "Serie" . $j);
  253. $j++;
  254. }
  255. //print_r($pre_result); print_r($header_name);
  256. // Dataset definition
  257. $DataSet->AddAllSeries();
  258. $DataSet->SetAbsciseLabelSerie('');
  259. $DataSet->SetXAxisName(get_lang('GradebookSkillsRanking'));
  260. $DataSet->SetYAxisName(get_lang('Students'));
  261. $show_draw = true;
  262. // Cache definition
  263. $Cache = new pCache();
  264. // the graph id
  265. $gradebook_id = intval($_GET['selectcat']);
  266. $graph_id = api_get_user_id() . 'ByResource' . $gradebook_id . api_get_course_id() . api_get_session_id();
  267. if ($show_draw) {
  268. //if ($Cache->IsInCache($graph_id, $DataSet->GetData())) {
  269. if (0) {
  270. //if we already created the img we get the img file id
  271. //echo 'in cache';
  272. $img_file = $Cache->GetHash($graph_id, $DataSet->GetData());
  273. } else {
  274. // if the image does not exist in the archive/ folder
  275. // Initialise the graph
  276. $chart_size_w = 480;
  277. $chart_size_h = 250;
  278. $angle = -30;
  279. $Test = new pChart($chart_size_w, $chart_size_h);
  280. // set font of the axes
  281. $Test->setFontProperties(api_get_path(LIBRARY_PATH) . "pchart/fonts/tahoma.ttf", 8);
  282. $Test = $Test->fixHeightByRotation(
  283. $DataSet->GetData(),
  284. $DataSet->GetDataDescription(),
  285. $angle
  286. );
  287. // Adding the color schemma
  288. $Test->loadColorPalette(api_get_path(LIBRARY_PATH) . "pchart/palette/pastel.txt");
  289. $area_graph_w = $chart_size_w - 130;
  290. $Test->setGraphArea(50, 30, $area_graph_w, $chart_size_h - 50);
  291. $Test->drawFilledRoundedRectangle(
  292. 5,
  293. 5,
  294. $chart_size_w - 1,
  295. $Test->YSize - 20,
  296. 5,
  297. 240,
  298. 240,
  299. 240
  300. );
  301. //$Test->drawRoundedRectangle(5,5,790,330,5,230,230,230);
  302. //background color area & stripe or not
  303. $Test->drawGraphArea(255, 255, 255, TRUE);
  304. //Setting max height by default see #3296
  305. if (!empty($max)) {
  306. if (is_int($max)) {
  307. $Test->setFixedScale(0, $max + 1, $max + 1);
  308. } else {
  309. $Test->setFixedScale(0, $max);
  310. }
  311. }
  312. $Test->drawScale(
  313. $DataSet->GetData(),
  314. $DataSet->GetDataDescription(),
  315. SCALE_ADDALLSTART0,
  316. 150,
  317. 150,
  318. 150,
  319. TRUE,
  320. 0,
  321. 1,
  322. FALSE
  323. );
  324. //background grid
  325. $Test->drawGrid(4, TRUE, 230, 230, 230, 50);
  326. // Draw the 0 line
  327. //$Test->setFontProperties(api_get_path(LIBRARY_PATH)."pchart/fonts/tahoma.ttf",6);
  328. //$Test->drawTreshold(0,143,55,72,TRUE,TRUE);
  329. // Draw the bar graph
  330. $Test->setFontProperties(api_get_path(LIBRARY_PATH) . "pchart/fonts/tahoma.ttf", 11);
  331. $Test->drawBarGraph($DataSet->GetData(), $DataSet->GetDataDescription(), TRUE);
  332. //Set legend properties: width, height and text color and font
  333. $Test->setFontProperties(api_get_path(LIBRARY_PATH) . "pchart/fonts/tahoma.ttf", 9);
  334. $Test->drawLegend($area_graph_w + 10, 50, $DataSet->GetDataDescription(), 255, 255, 255);
  335. //Set title properties
  336. $Test->setFontProperties(api_get_path(LIBRARY_PATH) . "pchart/fonts/tahoma.ttf", 10);
  337. $Test->drawTitle(50, 22, strip_tags($header_name[$i - 1]), 50, 50, 80, $chart_size_w - 50);
  338. //------------------
  339. //echo 'not in cache';
  340. $Cache->WriteToCache($graph_id, $DataSet->GetData(), $Test);
  341. //ob_start();
  342. //$Test->Stroke();
  343. //ob_end_clean();
  344. $img_file = $Cache->GetHash($graph_id, $DataSet->GetData());
  345. }
  346. echo '<img src="' . api_get_path(WEB_ARCHIVE_PATH) . $img_file . '" >';
  347. if ($i % 2 == 0 && $i != 0) {
  348. echo '<br />';
  349. }
  350. $i++;
  351. }
  352. } //end foreach
  353. } else {
  354. echo get_lang('ToViewGraphScoreRuleMustBeEnabled');
  355. }
  356. // Pie charts
  357. /*
  358. $show_draw = false;
  359. $resource_list = array();
  360. //print_r($pre_result_pie);
  361. if ($total_users>0) {
  362. foreach($pre_result_pie as $key=>$res_array) {
  363. //$resource_list
  364. foreach($res_array as $user_result) {
  365. $total+= $user_result / ($total_users*100);
  366. }
  367. echo $total;
  368. //echo $total = $res / ($total_users*100);
  369. echo '<br>';
  370. //$DataSet->AddPoint($total,"Serie".$i);
  371. //$DataSet->SetSerieName($header_name[$i-1],"Serie".$i);
  372. }
  373. }
  374. //here--------------
  375. foreach($resource_list as $key=>$resource) {
  376. $new_resource_list = $new_resource_list_name = array();
  377. foreach($resource as $name=>$cant) {
  378. $new_resource_list[]=$cant;
  379. $new_resource_list_name[]=$name;
  380. }
  381. //Pie chart
  382. $DataSet = new pData;
  383. $DataSet->AddPoint($new_resource_list,"Serie1");
  384. $DataSet->AddPoint($new_resource_list_name,"Serie2");
  385. $DataSet->AddAllSeries();
  386. $DataSet->SetAbsciseLabelSerie("Serie2");
  387. $Test = new pChart(400,300);
  388. $Test->loadColorPalette(api_get_path(LIBRARY_PATH)."pchart/palette/soft_tones.txt");
  389. // background
  390. //$Test->drawFilledRoundedRectangle(7,7,293,193,5,240,240,240);
  391. // border color
  392. $Test->drawRoundedRectangle(5,5,295,195,5,230,230,230);
  393. // This will draw a shadow under the pie chart
  394. //$Test->drawFilledCircle(122,102,70,200,200,200);
  395. //Draw the pie chart
  396. $Test->setFontProperties(api_get_path(LIBRARY_PATH)."pchart/fonts/tahoma.ttf",8);
  397. $Test->drawBarGraph($DataSet->GetData(),$DataSet->GetDataDescription(),TRUE);
  398. $tmp_path = api_get_path(SYS_ARCHIVE_PATH);
  399. $Test->drawBasicPieGraph($DataSet->GetData(),$DataSet->GetDataDescription(),120,100,70,PIE_PERCENTAGE,255,255,218);
  400. $Test->drawPieLegend(230,15,$DataSet->GetData(),$DataSet->GetDataDescription(),250,250,250);
  401. $user_id = api_get_user_id();
  402. $img_file_generated_name = $key.uniqid('').'gradebook.png';
  403. $Test->Render($tmp_path.$img_file_generated_name);
  404. chmod($tmp_path.$img_file_generated_name, api_get_permissions_for_new_files());
  405. if ($i % 2 == 0 && $i!= 0) {
  406. echo '<br>';
  407. }
  408. echo '<img src="'.api_get_path(WEB_ARCHIVE_PATH).$img_file_generated_name.'">';
  409. }
  410. */
  411. }
  412. }
  413. /**
  414. * Function used by SortableTable to get total number of items in the table
  415. */
  416. public function get_total_number_of_items()
  417. {
  418. return $this->datagen->get_total_users_count();
  419. }
  420. /**
  421. * Function used by SortableTable to generate the data to display
  422. */
  423. public function get_table_data($from = 1, $per_page = null, $column = null, $direction = null, $sort = null)
  424. {
  425. $is_western_name_order = api_is_western_name_order();
  426. // create page navigation if needed
  427. $totalitems = $this->datagen->get_total_items_count();
  428. if ($this->limit_enabled && $totalitems > LIMIT) {
  429. $selectlimit = LIMIT;
  430. } else {
  431. $selectlimit = $totalitems;
  432. }
  433. $header = null;
  434. if ($this->limit_enabled && $totalitems > LIMIT) {
  435. $header .= '<table style="width: 100%; text-align: right; margin-left: auto; margin-right: auto;" border="0" cellpadding="2">'
  436. . '<tbody>'
  437. . '<tr>';
  438. // previous X
  439. $header .= '<td style="width:100%;">';
  440. if ($this->offset >= LIMIT) {
  441. $header .= '<a href="' . api_get_self()
  442. . '?selectcat=' . Security::remove_XSS($_GET['selectcat'])
  443. . '&offset=' . (($this->offset) - LIMIT)
  444. . (isset($_GET['search']) ? '&search=' . Security::remove_XSS($_GET['search']) : '') . '">'
  445. . Display::return_icon('action_prev.png', get_lang('PreviousPage'), array(), 32)
  446. . '</a>';
  447. } else {
  448. $header .= Display::return_icon('action_prev_na.png', get_lang('PreviousPage'), array(), 32);
  449. }
  450. $header .= ' ';
  451. // next X
  452. $calcnext = (($this->offset + (2 * LIMIT)) > $totalitems) ?
  453. ($totalitems - (LIMIT + $this->offset)) : LIMIT;
  454. if ($calcnext > 0) {
  455. $header .= '<a href="' . api_get_self()
  456. . '?selectcat=' . Security::remove_XSS($_GET['selectcat'])
  457. . '&offset=' . ($this->offset + LIMIT)
  458. . (isset($_GET['search']) ? '&search=' . Security::remove_XSS($_GET['search']) : '') . '">'
  459. . Display::return_icon('action_next.png', get_lang('NextPage'), array(), 32)
  460. . '</a>';
  461. } else {
  462. $header .= Display::return_icon('action_next_na.png', get_lang('NextPage'), array(), 32);
  463. }
  464. $header .= '</td>';
  465. $header .= '</tbody></table>';
  466. echo $header;
  467. }
  468. // retrieve sorting type
  469. if ($is_western_name_order) {
  470. //$users_sorting = ($this->column == 0 ? FlatViewDataGenerator :: FVDG_SORT_FIRSTNAME : FlatViewDataGenerator :: FVDG_SORT_LASTNAME);
  471. $users_sorting = FlatViewDataGenerator :: FVDG_SORT_FIRSTNAME;
  472. } else {
  473. //$users_sorting = ($this->column == 0 ? FlatViewDataGenerator :: FVDG_SORT_LASTNAME : FlatViewDataGenerator :: FVDG_SORT_FIRSTNAME);
  474. $users_sorting = FlatViewDataGenerator :: FVDG_SORT_LASTNAME;
  475. }
  476. if ($this->direction == 'DESC') {
  477. $users_sorting |= FlatViewDataGenerator :: FVDG_SORT_DESC;
  478. } else {
  479. $users_sorting |= FlatViewDataGenerator :: FVDG_SORT_ASC;
  480. }
  481. // step 1: generate columns: evaluations and links
  482. $header_names = $this->datagen->get_header_names($this->offset, $selectlimit);
  483. if ($is_western_name_order) {
  484. $this->set_header(0, $header_names[1]);
  485. $this->set_header(1, $header_names[0]);
  486. } else {
  487. $this->set_header(0, $header_names[0]);
  488. $this->set_header(1, $header_names[1]);
  489. }
  490. $column = 2;
  491. while ($column < count($header_names)) {
  492. $this->set_header($column, $header_names[$column], false);
  493. $column++;
  494. }
  495. $data_array = $this->datagen->get_data(
  496. $users_sorting,
  497. $from,
  498. $this->per_page,
  499. $this->offset,
  500. $selectlimit
  501. );
  502. $table_data = array();
  503. foreach ($data_array as $user_row) {
  504. $table_row = array();
  505. $count = 0;
  506. $user_id = $user_row[$count++];
  507. $lastname = $user_row[$count++];
  508. $firstname = $user_row[$count++];
  509. if ($is_western_name_order) {
  510. $table_row[] = $this->build_name_link($user_id, $firstname);
  511. $table_row[] = $this->build_name_link($user_id, $lastname);
  512. } else {
  513. $table_row[] = $this->build_name_link($user_id, $lastname);
  514. $table_row[] = $this->build_name_link($user_id, $firstname);
  515. }
  516. while ($count < count($user_row)) {
  517. $table_row[] = $user_row[$count++];
  518. }
  519. $table_data[] = $table_row;
  520. }
  521. return $table_data;
  522. }
  523. /**
  524. * @param $user_id
  525. * @param $name
  526. *
  527. * @return string
  528. */
  529. private function build_name_link($user_id, $name)
  530. {
  531. return '<a href="user_stats.php?userid=' . $user_id . '&selectcat=' . $this->selectcat->get_id() . '&'.api_get_cidreq().'">' . $name . '</a>';
  532. }
  533. }