category.class.php 54 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. /**
  4. * Defines a gradebook Category object
  5. * @package chamilo.gradebook
  6. */
  7. /**
  8. * Init
  9. */
  10. /**
  11. * Class
  12. * @package chamilo.gradebook
  13. */
  14. class Category implements GradebookItem
  15. {
  16. private $id;
  17. private $name;
  18. private $description;
  19. private $user_id;
  20. private $course_code;
  21. private $parent;
  22. private $weight;
  23. private $visible;
  24. private $certificate_min_score;
  25. private $session_id;
  26. private $skills = array();
  27. private $grade_model_id;
  28. public function __construct()
  29. {
  30. }
  31. // GETTERS AND SETTERS
  32. public function get_id()
  33. {
  34. return $this->id;
  35. }
  36. public function get_name()
  37. {
  38. return $this->name;
  39. }
  40. public function get_description()
  41. {
  42. return $this->description;
  43. }
  44. public function get_user_id()
  45. {
  46. return $this->user_id;
  47. }
  48. public function get_certificate_min_score()
  49. {
  50. if (!empty($this->certificate_min_score)) {
  51. return $this->certificate_min_score;
  52. } else {
  53. return null;
  54. }
  55. }
  56. public function get_course_code()
  57. {
  58. return $this->course_code;
  59. }
  60. public function get_parent_id()
  61. {
  62. return $this->parent;
  63. }
  64. public function get_weight()
  65. {
  66. return $this->weight;
  67. }
  68. public function is_locked()
  69. {
  70. return isset($this->locked) && $this->locked == 1 ? true : false;
  71. }
  72. public function is_visible()
  73. {
  74. return $this->visible;
  75. }
  76. public function set_id($id)
  77. {
  78. $this->id = $id;
  79. }
  80. public function set_name($name)
  81. {
  82. $this->name = $name;
  83. }
  84. public function set_description($description)
  85. {
  86. $this->description = $description;
  87. }
  88. public function set_user_id($user_id)
  89. {
  90. $this->user_id = $user_id;
  91. }
  92. public function set_course_code($course_code)
  93. {
  94. $this->course_code = $course_code;
  95. $courseInfo = api_get_course_info($course_code);
  96. $this->course_id = $courseInfo['real_id'];
  97. }
  98. public function set_course_id($courseId)
  99. {
  100. $this->course_id = $courseId;
  101. }
  102. public function get_course_id()
  103. {
  104. return $this->course_id;
  105. }
  106. public function set_certificate_min_score($min_score = null)
  107. {
  108. $this->certificate_min_score = $min_score;
  109. }
  110. public function set_parent_id($parent)
  111. {
  112. $this->parent = intval($parent);
  113. }
  114. /**
  115. * Filters to int and sets the session ID
  116. * @param int The session ID from the Dokeos course session
  117. */
  118. public function set_session_id($session_id = 0)
  119. {
  120. $this->session_id = (int)$session_id;
  121. }
  122. public function set_weight($weight)
  123. {
  124. $this->weight = $weight;
  125. }
  126. public function set_visible($visible)
  127. {
  128. $this->visible = $visible;
  129. }
  130. public function set_grade_model_id($id)
  131. {
  132. $this->grade_model_id = $id;
  133. }
  134. public function set_locked($locked)
  135. {
  136. $this->locked = $locked;
  137. }
  138. public function get_grade_model_id()
  139. {
  140. return $this->grade_model_id;
  141. }
  142. public function get_type()
  143. {
  144. return 'category';
  145. }
  146. public function get_skills($from_db = true)
  147. {
  148. if ($from_db) {
  149. $cat_id = $this->get_id();
  150. $gradebook = new Gradebook();
  151. $skills = $gradebook->get_skills_by_gradebook($cat_id);
  152. } else {
  153. $skills = $this->skills;
  154. }
  155. return $skills;
  156. }
  157. public function get_skills_for_select()
  158. {
  159. $skills = $this->get_skills();
  160. $skill_select = array();
  161. if (!empty($skills)) {
  162. foreach ($skills as $skill) {
  163. $skill_select[$skill['id']] = $skill['name'];
  164. }
  165. }
  166. return $skill_select;
  167. }
  168. // CRUD FUNCTIONS
  169. /**
  170. * Retrieve categories and return them as an array of Category objects
  171. * @param int category id
  172. * @param int user id (category owner)
  173. * @param string course code
  174. * @param int parent category
  175. * @param bool visible
  176. * @param int session id (in case we are in a session)
  177. * @param bool Whether to show all "session" categories (true) or hide them (false) in case there is no session id
  178. */
  179. public static function load(
  180. $id = null,
  181. $user_id = null,
  182. $course_code = null,
  183. $parent_id = null,
  184. $visible = null,
  185. $session_id = null,
  186. $order_by = null
  187. ) {
  188. //if the category given is explicitly 0 (not null), then create
  189. // a root category object (in memory)
  190. if (isset($id) && (int)$id === 0) {
  191. $cats = array();
  192. $cats[] = Category::create_root_category();
  193. return $cats;
  194. }
  195. $tbl_grade_categories = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
  196. $sql = 'SELECT * FROM '.$tbl_grade_categories;
  197. $paramcount = 0;
  198. if (isset($id)) {
  199. $id = Database::escape_string($id);
  200. $sql .= ' WHERE id = '.intval($id);
  201. $paramcount++;
  202. }
  203. if (isset($user_id)) {
  204. $user_id = intval($user_id);
  205. if ($paramcount != 0) {
  206. $sql .= ' AND';
  207. } else {
  208. $sql .= ' WHERE';
  209. }
  210. $sql .= ' user_id = '.intval($user_id);
  211. $paramcount++;
  212. }
  213. if (isset($course_code)) {
  214. $course_code = Database::escape_string($course_code);
  215. if ($paramcount != 0) {
  216. $sql .= ' AND';
  217. } else {
  218. $sql .= ' WHERE';
  219. }
  220. if ($course_code == '0') {
  221. $sql .= ' course_code is null ';
  222. } else {
  223. $sql .= " course_code = '".Database::escape_string($course_code)."'";
  224. }
  225. /*if ($show_session_categories !== true) {
  226. // a query on the course should show all
  227. // the categories inside sessions for this course
  228. // otherwise a special parameter is given to ask explicitely
  229. $sql .= " AND (session_id IS NULL OR session_id = 0) ";
  230. } else {*/
  231. if (empty($session_id)) {
  232. $sql .= ' AND (session_id IS NULL OR session_id = 0) ';
  233. } else {
  234. $sql .= ' AND session_id = '.(int)$session_id.' ';
  235. }
  236. //}
  237. $paramcount++;
  238. }
  239. if (isset($parent_id)) {
  240. $parent_id = Database::escape_string($parent_id);
  241. if ($paramcount != 0) {
  242. $sql .= ' AND ';
  243. } else {
  244. $sql .= ' WHERE ';
  245. }
  246. $sql .= ' parent_id = '.intval($parent_id);
  247. $paramcount++;
  248. }
  249. if (isset($visible)) {
  250. $visible = Database::escape_string($visible);
  251. if ($paramcount != 0) {
  252. $sql .= ' AND';
  253. } else {
  254. $sql .= ' WHERE';
  255. }
  256. $sql .= ' visible = '.intval($visible);
  257. $paramcount++;
  258. }
  259. if (!empty($order_by)) {
  260. if (!empty($order_by) && $order_by != '') {
  261. $sql .= ' '.$order_by;
  262. }
  263. }
  264. $result = Database::query($sql);
  265. $allcat = array();
  266. if (Database::num_rows($result) > 0) {
  267. $allcat = Category::create_category_objects_from_sql_result($result);
  268. }
  269. return $allcat;
  270. }
  271. private function create_root_category()
  272. {
  273. $cat = new Category();
  274. $cat->set_id(0);
  275. $cat->set_name(get_lang('RootCat'));
  276. $cat->set_description(null);
  277. $cat->set_user_id(0);
  278. $cat->set_course_code(null);
  279. $cat->set_parent_id(null);
  280. $cat->set_weight(0);
  281. $cat->set_visible(1);
  282. return $cat;
  283. }
  284. private static function create_category_objects_from_sql_result($result)
  285. {
  286. $allcat = array();
  287. while ($data = Database::fetch_array($result)) {
  288. $cat = new Category();
  289. $cat->set_id($data['id']);
  290. $cat->set_name($data['name']);
  291. $cat->set_description($data['description']);
  292. $cat->set_user_id($data['user_id']);
  293. $cat->set_course_code($data['course_code']);
  294. $cat->set_parent_id($data['parent_id']);
  295. $cat->set_weight($data['weight']);
  296. $cat->set_visible($data['visible']);
  297. $cat->set_session_id($data['session_id']);
  298. $cat->set_certificate_min_score($data['certif_min_score']);
  299. $cat->set_grade_model_id($data['grade_model_id']);
  300. $cat->set_locked($data['locked']);
  301. $allcat[] = $cat;
  302. }
  303. return $allcat;
  304. }
  305. /**
  306. * Insert this category into the database
  307. */
  308. public function add()
  309. {
  310. if (isset($this->name) && '-1' == $this->name) {
  311. return false;
  312. }
  313. if (isset($this->name) && isset($this->user_id)) {
  314. $tbl_grade_categories = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
  315. $sql = 'INSERT INTO '.$tbl_grade_categories.' (name,user_id,weight,visible';
  316. if (isset($this->description)) {
  317. $sql .= ',description';
  318. }
  319. if (isset($this->course_code)) {
  320. $sql .= ',course_code';
  321. }
  322. if (isset($this->parent)) {
  323. $sql .= ',parent_id';
  324. }
  325. if (!empty($this->session_id)) {
  326. $sql .= ', session_id';
  327. }
  328. if (isset($this->grade_model_id)) {
  329. $sql .= ', grade_model_id ';
  330. }
  331. if (isset($this->certificate_min_score) && !empty($this->certificate_min_score)) {
  332. $sql .= ', certif_min_score ';
  333. }
  334. /*
  335. $setting = api_get_setting('tool_visible_by_default_at_creation');
  336. $visible = 1;
  337. if (isset($setting['gradebook'])) {
  338. if ($setting['gradebook'] == 'false') {
  339. $visible = 0;
  340. }
  341. }*/
  342. $visible = intval($this->is_visible());
  343. $sql .= ") VALUES ('".Database::escape_string($this->get_name())."'"
  344. .','.intval($this->get_user_id())
  345. .','.Database::escape_string($this->get_weight())
  346. .','.$visible;
  347. if (isset($this->description)) {
  348. $sql .= ",'".Database::escape_string($this->get_description())."'";
  349. }
  350. if (isset($this->course_code)) {
  351. $sql .= ",'".Database::escape_string($this->get_course_code())."'";
  352. }
  353. if (isset($this->parent)) {
  354. $sql .= ','.intval($this->get_parent_id());
  355. }
  356. if (!empty($this->session_id)) {
  357. $sql .= ', '.intval($this->get_session_id());
  358. }
  359. if (isset($this->grade_model_id)) {
  360. $sql .= ', '.intval($this->get_grade_model_id());
  361. }
  362. if (isset($this->certificate_min_score) && !empty($this->certificate_min_score)) {
  363. $sql .= ', '.Database::escape_string($this->get_certificate_min_score());
  364. }
  365. $sql .= ')';
  366. Database::query($sql);
  367. $id = Database::insert_id();
  368. $this->set_id($id);
  369. if (!empty($id)) {
  370. $parent_id = $this->get_parent_id();
  371. $grade_model_id = $this->get_grade_model_id();
  372. if ($parent_id == 0) {
  373. //do something
  374. if (isset($grade_model_id) && !empty($grade_model_id) && $grade_model_id != '-1') {
  375. $obj = new GradeModel();
  376. $components = $obj->get_components($grade_model_id);
  377. $default_weight_setting = api_get_setting('gradebook_default_weight');
  378. $default_weight = 100;
  379. if (isset($default_weight_setting)) {
  380. $default_weight = $default_weight_setting;
  381. }
  382. foreach ($components as $component) {
  383. $gradebook = new Gradebook();
  384. $params = array();
  385. $params['name'] = $component['acronym'];
  386. $params['description'] = $component['title'];
  387. $params['user_id'] = api_get_user_id();
  388. $params['parent_id'] = $id;
  389. $params['weight'] = $component['percentage'] / 100 * $default_weight;
  390. $params['session_id'] = api_get_session_id();
  391. $params['course_code'] = $this->get_course_code();
  392. $gradebook->save($params);
  393. }
  394. }
  395. }
  396. }
  397. $gradebook = new Gradebook();
  398. $gradebook->update_skills_to_gradebook($this->id, $this->get_skills(false));
  399. return $id;
  400. }
  401. }
  402. /**
  403. * Update the properties of this category in the database
  404. * @todo fix me
  405. */
  406. public function save()
  407. {
  408. $tbl_grade_categories = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
  409. $sql = 'UPDATE '.$tbl_grade_categories." SET name = '".Database::escape_string(
  410. $this->get_name()
  411. )."'".', description = ';
  412. if (isset($this->description)) {
  413. $sql .= "'".Database::escape_string($this->get_description())."'";
  414. } else {
  415. $sql .= 'null';
  416. }
  417. $sql .= ', user_id = '.intval($this->get_user_id())
  418. .', course_code = ';
  419. if (isset($this->course_code)) {
  420. $sql .= "'".Database::escape_string($this->get_course_code())."'";
  421. } else {
  422. $sql .= 'null';
  423. }
  424. $sql .= ', parent_id = ';
  425. if (isset($this->parent)) {
  426. $sql .= intval($this->get_parent_id());
  427. } else {
  428. $sql .= 'null';
  429. }
  430. $sql .= ', certif_min_score = ';
  431. if (isset($this->certificate_min_score) && !empty($this->certificate_min_score)) {
  432. $sql .= Database::escape_string($this->get_certificate_min_score());
  433. } else {
  434. $sql .= 'null';
  435. }
  436. if (isset($this->grade_model_id)) {
  437. $sql .= ', grade_model_id = '.intval($this->get_grade_model_id());
  438. }
  439. $sql .= ', weight = '.Database::escape_string($this->get_weight())
  440. .', visible = '.intval($this->is_visible())
  441. .' WHERE id = '.intval($this->id);
  442. Database::query($sql);
  443. if (!empty($this->id)) {
  444. $parent_id = $this->get_parent_id();
  445. $grade_model_id = $this->get_grade_model_id();
  446. if ($parent_id == 0) {
  447. if (isset($grade_model_id) && !empty($grade_model_id) && $grade_model_id != '-1') {
  448. $obj = new GradeModel();
  449. $components = $obj->get_components($grade_model_id);
  450. $default_weight_setting = api_get_setting('gradebook_default_weight');
  451. $default_weight = 100;
  452. if (isset($default_weight_setting)) {
  453. $default_weight = $default_weight_setting;
  454. }
  455. $final_weight = $this->get_weight();
  456. if (!empty($final_weight)) {
  457. $default_weight = $this->get_weight();
  458. }
  459. foreach ($components as $component) {
  460. $gradebook = new Gradebook();
  461. $params = array();
  462. $params['name'] = $component['acronym'];
  463. $params['description'] = $component['title'];
  464. $params['user_id'] = api_get_user_id();
  465. $params['parent_id'] = $this->id;
  466. $params['weight'] = $component['percentage'] / 100 * $default_weight;
  467. $params['session_id'] = api_get_session_id();
  468. $params['course_code'] = $this->get_course_code();
  469. $gradebook->save($params);
  470. }
  471. }
  472. }
  473. }
  474. $gradebook = new Gradebook();
  475. $gradebook->update_skills_to_gradebook($this->id, $this->get_skills(false));
  476. }
  477. /**
  478. * Update link weights see #5168
  479. * @param type $new_weight
  480. */
  481. function update_children_weight($new_weight)
  482. {
  483. //$evals = $this->get_evaluations();
  484. $links = $this->get_links();
  485. $old_weight = $this->get_weight();
  486. if (!empty($links)) {
  487. foreach ($links as $link_item) {
  488. if (isset($link_item)) {
  489. $new_item_weight = $new_weight * $link_item->get_weight() / $old_weight;
  490. $link_item->set_weight($new_item_weight);
  491. $link_item->save();
  492. }
  493. }
  494. }
  495. }
  496. /**
  497. * Delete this evaluation from the database
  498. */
  499. public function delete()
  500. {
  501. $tbl_grade_categories = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
  502. $sql = 'DELETE FROM '.$tbl_grade_categories.' WHERE id = '.intval($this->id);
  503. Database::query($sql);
  504. }
  505. /**
  506. * Not delete this category from the database,when visible=3 is category eliminated
  507. */
  508. public function update_category_delete($course_id)
  509. {
  510. $tbl_grade_categories = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
  511. $sql = 'UPDATE '.$tbl_grade_categories.' SET visible=3 WHERE course_code ="'.Database::escape_string(
  512. $course_id
  513. ).'"';
  514. Database::query($sql);
  515. }
  516. /**
  517. * Show message resource delete
  518. */
  519. public function show_message_resource_delete($course_id)
  520. {
  521. $tbl_grade_categories = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
  522. $sql = 'SELECT count(*) AS num from '.$tbl_grade_categories.' WHERE course_code ="'.Database::escape_string(
  523. $course_id
  524. ).'" AND visible=3';
  525. $res = Database::query($sql);
  526. $option = Database::fetch_array($res, 'ASSOC');
  527. if ($option['num'] >= 1) {
  528. return '&nbsp;&nbsp;<span class="resource-deleted">(&nbsp;'.get_lang('ResourceDeleted').'&nbsp;)</span>';
  529. } else {
  530. return false;
  531. }
  532. }
  533. /**
  534. * Shows all information of an category
  535. */
  536. public function shows_all_information_an_category($selectcat = '')
  537. {
  538. if ($selectcat == '') {
  539. return null;
  540. } else {
  541. $tbl_category = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
  542. $sql = 'SELECT name,description,user_id,course_code,parent_id,weight,visible,certif_min_score,session_id
  543. FROM '.$tbl_category.' c
  544. WHERE c.id = '.intval($selectcat);
  545. $result = Database::query($sql);
  546. $row = Database::fetch_array($result, 'ASSOC');
  547. return $row;
  548. }
  549. }
  550. // OTHER FUNCTIONS
  551. /**
  552. * Check if a category name (with the same parent category) already exists
  553. * @param $name name to check (if not given, the name property of this object will be checked)
  554. * @param $parent parent category
  555. */
  556. public function does_name_exist($name, $parent)
  557. {
  558. if (!isset ($name)) {
  559. $name = $this->name;
  560. $parent = $this->parent;
  561. }
  562. $tbl_grade_categories = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
  563. $sql = 'SELECT count(id) AS number'
  564. .' FROM '.$tbl_grade_categories
  565. ." WHERE name = '".Database::escape_string($name)."'";
  566. if (api_is_allowed_to_edit()) {
  567. $parent = Category::load($parent);
  568. $courseId = $parent[0]->get_course_id();
  569. if (isset($courseId) && !empty($courseId)) {
  570. $main_course_user_table = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
  571. $sql .= ' AND user_id IN ('
  572. .' SELECT user_id FROM '.$main_course_user_table
  573. ." WHERE c_id = '".Database::escape_string($courseId)."'"
  574. .' AND status = '.COURSEMANAGER
  575. .')';
  576. } else {
  577. $sql .= ' AND user_id = '.api_get_user_id();
  578. }
  579. } else {
  580. $sql .= ' AND user_id = '.api_get_user_id();
  581. }
  582. if (!isset ($parent)) {
  583. $sql .= ' AND parent_id is null';
  584. } else {
  585. $sql .= ' AND parent_id = '.intval($parent);
  586. }
  587. $result = Database::query($sql);
  588. $number = Database::fetch_row($result);
  589. return ($number[0] != 0);
  590. }
  591. /**
  592. * Checks if the certificate is available for the given user in this category
  593. * @param integer User ID
  594. * @return boolean True if conditions match, false if fails
  595. */
  596. public function is_certificate_available($user_id)
  597. {
  598. $score = $this->calc_score($user_id, $this->course_code);
  599. if (isset($score)) {
  600. $certification_score = ($score[0] / $score[1]) * 100; //get a percentage score to compare to minimum certificate score
  601. if ($certification_score >= $this->certificate_min_score) {
  602. return true;
  603. }
  604. }
  605. return false;
  606. }
  607. /**
  608. * Is this category a course ?
  609. * A category is a course if it has a course code and no parent category.
  610. */
  611. public function is_course()
  612. {
  613. return (isset($this->course_code) && !empty($this->course_code)
  614. && (!isset($this->parent) || $this->parent == 0));
  615. }
  616. /**
  617. * Calculate the score of this category
  618. * @param $stud_id student id (default: all students - then the average is returned)
  619. * @return array (score sum, weight sum)
  620. * or null if no scores available
  621. */
  622. public function calc_score($stud_id = null, $course_code = '', $session_id = null)
  623. {
  624. // get appropriate subcategories, evaluations and links
  625. if (!empty($course_code)) {
  626. $cats = $this->get_subcategories($stud_id, $course_code, $session_id);
  627. $evals = $this->get_evaluations($stud_id, false, $course_code);
  628. $links = $this->get_links($stud_id, false, $course_code);
  629. } else {
  630. $cats = $this->get_subcategories($stud_id);
  631. $evals = $this->get_evaluations($stud_id);
  632. $links = $this->get_links($stud_id);
  633. }
  634. // calculate score
  635. $rescount = 0;
  636. $ressum = 0;
  637. $weightsum = 0;
  638. if (!empty($cats)) {
  639. foreach ($cats as $cat) {
  640. $catres = $cat->calc_score($stud_id, $course_code, $session_id); // recursive call
  641. if ($cat->get_weight() != 0) {
  642. $catweight = $cat->get_weight();
  643. $rescount++;
  644. $weightsum += $catweight;
  645. }
  646. if (isset($catres)) {
  647. $ressum += (($catres[0] / $catres[1]) * $catweight);
  648. }
  649. }
  650. }
  651. if (!empty($evals)) {
  652. foreach ($evals as $eval) {
  653. $evalres = $eval->calc_score($stud_id);
  654. if (isset($evalres) && $eval->get_weight() != 0) {
  655. $evalweight = $eval->get_weight();
  656. $rescount++;
  657. $weightsum += $evalweight;
  658. $ressum += (($evalres[0] / $evalres[1]) * $evalweight);
  659. } else {
  660. }
  661. }
  662. }
  663. if (!empty($links)) {
  664. foreach ($links as $link) {
  665. $linkres = $link->calc_score($stud_id);
  666. if (isset($linkres) && $link->get_weight() != 0) {
  667. $linkweight = $link->get_weight();
  668. $link_res_denom = ($linkres[1] == 0) ? 1 : $linkres[1];
  669. $rescount++;
  670. $weightsum += $linkweight;
  671. $ressum += (($linkres[0] / $link_res_denom) * $linkweight);
  672. } else {
  673. //adding if result does not exists
  674. if ($link->get_weight() != 0) {
  675. $linkweight = $link->get_weight();
  676. $weightsum += $linkweight;
  677. }
  678. }
  679. }
  680. }
  681. if ($rescount == 0) {
  682. return null;
  683. } else {
  684. return array($ressum, $weightsum);
  685. }
  686. }
  687. /**
  688. * Delete this category and every subcategory, evaluation and result inside
  689. */
  690. public function delete_all()
  691. {
  692. $cats = Category::load(null, null, $this->course_code, $this->id, null);
  693. $evals = Evaluation::load(null, null, $this->course_code, $this->id, null);
  694. $links = LinkFactory::load(null, null, null, null, $this->course_code, $this->id, null);
  695. if (!empty($cats)) {
  696. foreach ($cats as $cat) {
  697. $cat->delete_all();
  698. $cat->delete();
  699. }
  700. }
  701. if (!empty($evals)) {
  702. foreach ($evals as $eval) {
  703. $eval->delete_with_results();
  704. }
  705. }
  706. if (!empty($links)) {
  707. foreach ($links as $link) {
  708. $link->delete();
  709. }
  710. }
  711. $this->delete();
  712. }
  713. /**
  714. * Return array of Category objects where a student is subscribed to.
  715. * @param int student id
  716. * @param string Course code
  717. * @param int Session id
  718. */
  719. public function get_root_categories_for_student($stud_id, $course_code = null, $session_id = null)
  720. {
  721. // courses
  722. $main_course_user_table = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
  723. $course_table = Database :: get_main_table(TABLE_MAIN_COURSE);
  724. $tbl_grade_categories = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
  725. $sql = 'SELECT * FROM '.$tbl_grade_categories.' WHERE parent_id = 0';
  726. if (!api_is_allowed_to_edit()) {
  727. $sql .= ' AND visible = 1';
  728. //proceed with checks on optional parameters course & session
  729. if (!empty($course_code)) {
  730. // TODO: considering it highly improbable that a user would get here
  731. // if he doesn't have the rights to view this course and this
  732. // session, we don't check his registration to these, but this
  733. // could be an improvement
  734. if (!empty($session_id)) {
  735. $sql .= " AND course_code = '".Database::escape_string($course_code)."'"
  736. ." AND session_id = ".(int)$session_id;
  737. } else {
  738. $sql .= " AND course_code = '".Database::escape_string(
  739. $course_code
  740. )."' AND session_id is null OR session_id=0";
  741. }
  742. } else {
  743. //no optional parameter, proceed as usual
  744. $sql .= ' AND course_code IN
  745. (
  746. SELECT course.code
  747. FROM '.$main_course_user_table.' course_user
  748. INNER JOIN '.$course_table.' course ON (course.id AND course_user.c_id)
  749. WHERE user_id = '.intval($stud_id).' AND status = '.STUDENT
  750. .')';
  751. }
  752. } elseif (api_is_allowed_to_edit() && !api_is_platform_admin()) {
  753. //proceed with checks on optional parameters course & session
  754. if (!empty($course_code)) {
  755. // TODO: considering it highly improbable that a user would get here
  756. // if he doesn't have the rights to view this course and this
  757. // session, we don't check his registration to these, but this
  758. // could be an improvement
  759. $sql .= " AND course_code = '".Database::escape_string($course_code)."'";
  760. if (!empty($session_id)) {
  761. $sql .= " AND session_id = ".(int)$session_id;
  762. } else {
  763. $sql .= "AND session_id IS NULL OR session_id=0";
  764. }
  765. } else {
  766. $sql .= ' AND course_code in'
  767. .' (SELECT course_code FROM '.$main_course_user_table
  768. .' WHERE user_id = '.api_get_user_id()
  769. .' AND status = '.COURSEMANAGER
  770. .')';
  771. }
  772. } elseif (api_is_platform_admin()) {
  773. if (isset($session_id) && $session_id != 0) {
  774. $sql .= ' AND session_id='.intval($session_id);
  775. } else {
  776. $sql .= ' AND coalesce(session_id,0)=0';
  777. }
  778. }
  779. $result = Database::query($sql);
  780. $cats = Category::create_category_objects_from_sql_result($result);
  781. // Course independent categories
  782. if (empty($course_code)) {
  783. $cats = Category::get_independent_categories_with_result_for_student(0, $stud_id, $cats);
  784. }
  785. return $cats;
  786. }
  787. /**
  788. * Return array of Category objects where a teacher is admin for.
  789. * @param int user id (to return everything, use 'null' here)
  790. * @param string course code (optional)
  791. * @param int session id (optional)
  792. */
  793. public function get_root_categories_for_teacher($user_id, $course_code = null, $session_id = null)
  794. {
  795. if ($user_id == null) {
  796. return Category::load(null, null, $course_code, 0, null, $session_id);
  797. }
  798. // Courses
  799. $main_course_user_table = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
  800. $tbl_grade_categories = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
  801. $course_table = Database :: get_main_table(TABLE_MAIN_COURSE);
  802. $sql = 'SELECT * FROM '.$tbl_grade_categories.' WHERE parent_id = 0';
  803. if (!empty($course_code)) {
  804. $sql .= " AND course_code = '".Database::escape_string($course_code)."' ";
  805. if (!empty($session_id)) {
  806. $sql .= " AND session_id = ".(int)$session_id;
  807. }
  808. } else {
  809. $sql .= ' AND course_code IN
  810. (
  811. SELECT course.code
  812. FROM '.$main_course_user_table.' course_user
  813. INNER JOIN '.$course_table.' course ON (course.id AND course_user.c_id)
  814. WHERE user_id = '.intval($stud_id).' AND status = '.STUDENT
  815. .')';
  816. }
  817. $result = Database::query($sql);
  818. $cats = Category::create_category_objects_from_sql_result($result);
  819. // course independent categories
  820. if (isset($course_code)) {
  821. $indcats = Category::load(null, $user_id, $course_code, 0, null, $session_id);
  822. $cats = array_merge($cats, $indcats);
  823. }
  824. return $cats;
  825. }
  826. /**
  827. * Can this category be moved to somewhere else ?
  828. * The root and courses cannot be moved.
  829. */
  830. public function is_movable()
  831. {
  832. return (!(!isset ($this->id) || $this->id == 0 || $this->is_course()));
  833. }
  834. /**
  835. * Generate an array of possible categories where this category can be moved to.
  836. * Notice: its own parent will be included in the list: it's up to the frontend
  837. * to disable this element.
  838. * @return array 2-dimensional array - every element contains 3 subelements (id, name, level)
  839. */
  840. public function get_target_categories()
  841. {
  842. // the root or a course -> not movable
  843. if (!$this->is_movable()) {
  844. return null;
  845. } // otherwise:
  846. // - course independent category
  847. // -> movable to root or other independent categories
  848. // - category inside a course
  849. // -> movable to root, independent categories or categories inside the course
  850. else {
  851. $user = (api_is_platform_admin() ? null : api_get_user_id());
  852. $targets = array();
  853. $level = 0;
  854. $root = array(0, get_lang('RootCat'), $level);
  855. $targets[] = $root;
  856. if (isset($this->course_code) && !empty($this->course_code)) {
  857. $crscats = Category::load(null, null, $this->course_code, 0);
  858. foreach ($crscats as $cat) {
  859. if ($this->can_be_moved_to_cat($cat)) {
  860. $targets[] = array($cat->get_id(), $cat->get_name(), $level + 1);
  861. $targets = $this->add_target_subcategories($targets, $level + 1, $cat->get_id());
  862. }
  863. }
  864. }
  865. $indcats = Category::load(null, $user, 0, 0);
  866. foreach ($indcats as $cat) {
  867. if ($this->can_be_moved_to_cat($cat)) {
  868. $targets[] = array($cat->get_id(), $cat->get_name(), $level + 1);
  869. $targets = $this->add_target_subcategories($targets, $level + 1, $cat->get_id());
  870. }
  871. }
  872. return $targets;
  873. }
  874. }
  875. /**
  876. * Internal function used by get_target_categories()
  877. */
  878. private function add_target_subcategories($targets, $level, $catid)
  879. {
  880. $subcats = Category::load(null, null, null, $catid);
  881. foreach ($subcats as $cat) {
  882. if ($this->can_be_moved_to_cat($cat)) {
  883. $targets[] = array($cat->get_id(), $cat->get_name(), $level + 1);
  884. $targets = $this->add_target_subcategories($targets, $level + 1, $cat->get_id());
  885. }
  886. }
  887. return $targets;
  888. }
  889. /**
  890. * Internal function used by get_target_categories() and add_target_subcategories()
  891. * Can this category be moved to the given category ?
  892. * Impossible when origin and target are the same... children won't be processed
  893. * either. (a category can't be moved to one of its own children)
  894. */
  895. private function can_be_moved_to_cat($cat)
  896. {
  897. return ($cat->get_id() != $this->get_id());
  898. }
  899. /**
  900. * Move this category to the given category.
  901. * If this category moves from inside a course to outside,
  902. * its course code must be changed, as well as the course code
  903. * of all underlying categories and evaluations. All links will
  904. * be deleted as well !
  905. */
  906. public function move_to_cat($cat)
  907. {
  908. $this->set_parent_id($cat->get_id());
  909. if ($this->get_course_code() != $cat->get_course_code()) {
  910. $this->set_course_code($cat->get_course_code());
  911. $this->apply_course_code_to_children();
  912. }
  913. $this->save();
  914. }
  915. /**
  916. * Internal function used by move_to_cat()
  917. */
  918. private function apply_course_code_to_children()
  919. {
  920. $cats = Category::load(null, null, null, $this->id, null);
  921. $evals = Evaluation::load(null, null, null, $this->id, null);
  922. $links = LinkFactory::load(null, null, null, null, null, $this->id, null);
  923. foreach ($cats as $cat) {
  924. $cat->set_course_code($this->get_course_code());
  925. $cat->save();
  926. $cat->apply_course_code_to_children();
  927. }
  928. foreach ($evals as $eval) {
  929. $eval->set_course_code($this->get_course_code());
  930. $eval->save();
  931. }
  932. foreach ($links as $link) {
  933. $link->delete();
  934. }
  935. }
  936. /**
  937. * Generate an array of all categories the user can navigate to
  938. */
  939. public function get_tree()
  940. {
  941. $targets = array();
  942. $level = 0;
  943. $root = array(0, get_lang('RootCat'), $level);
  944. $targets[] = $root;
  945. // course or platform admin
  946. if (api_is_allowed_to_edit()) {
  947. $user = (api_is_platform_admin() ? null : api_get_user_id());
  948. $cats = Category::get_root_categories_for_teacher($user);
  949. foreach ($cats as $cat) {
  950. $targets[] = array($cat->get_id(), $cat->get_name(), $level + 1);
  951. $targets = Category::add_subtree($targets, $level + 1, $cat->get_id(), null);
  952. }
  953. } else { // student
  954. $cats = Category::get_root_categories_for_student(api_get_user_id());
  955. foreach ($cats as $cat) {
  956. $targets[] = array($cat->get_id(), $cat->get_name(), $level + 1);
  957. $targets = Category::add_subtree($targets, $level + 1, $cat->get_id(), 1);
  958. }
  959. }
  960. return $targets;
  961. }
  962. /**
  963. * Internal function used by get_tree()
  964. */
  965. private function add_subtree($targets, $level, $catid, $visible)
  966. {
  967. $subcats = Category::load(null, null, null, $catid, $visible);
  968. if (!empty($subcats)) {
  969. foreach ($subcats as $cat) {
  970. $targets[] = array($cat->get_id(), $cat->get_name(), $level + 1);
  971. $targets = Category::add_subtree($targets, $level + 1, $cat->get_id(), $visible);
  972. }
  973. }
  974. return $targets;
  975. }
  976. /**
  977. * Generate an array of courses that a teacher hasn't created a category for.
  978. * @return array 2-dimensional array - every element contains 2 subelements (code, title)
  979. */
  980. public function get_not_created_course_categories($user_id)
  981. {
  982. $tbl_main_courses = Database :: get_main_table(TABLE_MAIN_COURSE);
  983. $tbl_main_course_user = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
  984. $tbl_grade_categories = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
  985. $sql = 'SELECT DISTINCT(code), title
  986. FROM '.$tbl_main_courses.' cc, '.$tbl_main_course_user.' cu
  987. WHERE cc.c_id = cu.id AND cu.status = '.COURSEMANAGER;
  988. if (!api_is_platform_admin()) {
  989. $sql .= ' AND cu.user_id = '.$user_id;
  990. }
  991. $sql .= ' AND cc.code NOT IN
  992. (
  993. SELECT course_code FROM '.$tbl_grade_categories.'
  994. WHERE parent_id = 0 AND course_code IS NOT null
  995. )';
  996. $result = Database::query($sql);
  997. $cats = array();
  998. while ($data = Database::fetch_array($result)) {
  999. $cats[] = array($data['code'], $data['title']);
  1000. }
  1001. return $cats;
  1002. }
  1003. /**
  1004. * Generate an array of all courses that a teacher is admin of.
  1005. * @return array 2-dimensional array - every element contains 2 subelements (code, title)
  1006. */
  1007. public function get_all_courses($user_id)
  1008. {
  1009. $tbl_main_courses = Database :: get_main_table(TABLE_MAIN_COURSE);
  1010. $tbl_main_course_user = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
  1011. $tbl_grade_categories = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
  1012. $sql = 'SELECT DISTINCT(code), title FROM '.$tbl_main_courses.' cc, '.$tbl_main_course_user.' cu'
  1013. .' WHERE cc.id = cu.c_id'
  1014. .' AND cu.status = '.COURSEMANAGER;
  1015. if (!api_is_platform_admin()) {
  1016. $sql .= ' AND cu.user_id = '.intval($user_id);
  1017. }
  1018. $result = Database::query($sql);
  1019. $cats = array();
  1020. while ($data = Database::fetch_array($result)) {
  1021. $cats[] = array($data['code'], $data['title']);
  1022. }
  1023. return $cats;
  1024. }
  1025. /**
  1026. * Apply the same visibility to every subcategory, evaluation and link
  1027. */
  1028. public function apply_visibility_to_children()
  1029. {
  1030. $cats = Category::load(null, null, null, $this->id, null);
  1031. $evals = Evaluation::load(null, null, null, $this->id, null);
  1032. $links = LinkFactory::load(null, null, null, null, null, $this->id, null);
  1033. if (!empty($cats)) {
  1034. foreach ($cats as $cat) {
  1035. $cat->set_visible($this->is_visible());
  1036. $cat->save();
  1037. $cat->apply_visibility_to_children();
  1038. }
  1039. }
  1040. if (!empty($evals)) {
  1041. foreach ($evals as $eval) {
  1042. $eval->set_visible($this->is_visible());
  1043. $eval->save();
  1044. }
  1045. }
  1046. if (!empty($links)) {
  1047. foreach ($links as $link) {
  1048. $link->set_visible($this->is_visible());
  1049. $link->save();
  1050. }
  1051. }
  1052. }
  1053. /**
  1054. * Check if a category contains evaluations with a result for a given student
  1055. */
  1056. public function has_evaluations_with_results_for_student($stud_id)
  1057. {
  1058. $evals = Evaluation::get_evaluations_with_result_for_student($this->id, $stud_id);
  1059. if (count($evals) != 0) {
  1060. return true;
  1061. } else {
  1062. $cats = Category::load(
  1063. null,
  1064. null,
  1065. null,
  1066. $this->id,
  1067. api_is_allowed_to_edit() ? null : 1
  1068. );
  1069. foreach ($cats as $cat) {
  1070. if ($cat->has_evaluations_with_results_for_student($stud_id)) {
  1071. return true;
  1072. }
  1073. }
  1074. return false;
  1075. }
  1076. }
  1077. /**
  1078. * Retrieve all categories inside a course independent category
  1079. * that should be visible to a student.
  1080. * @param $cat_id parent category
  1081. * @param $stud_id student id
  1082. * @param $cats optional: if defined, the categories will be added to this array
  1083. */
  1084. public function get_independent_categories_with_result_for_student($cat_id, $stud_id, $cats = array())
  1085. {
  1086. $creator = (api_is_allowed_to_edit() && !api_is_platform_admin()) ? api_get_user_id() : null;
  1087. $crsindcats = Category::load(
  1088. null,
  1089. $creator,
  1090. '0',
  1091. $cat_id,
  1092. api_is_allowed_to_edit() ? null : 1
  1093. );
  1094. if (!empty($crsindcats)) {
  1095. foreach ($crsindcats as $crsindcat) {
  1096. if ($crsindcat->has_evaluations_with_results_for_student($stud_id)) {
  1097. $cats[] = $crsindcat;
  1098. }
  1099. }
  1100. }
  1101. return $cats;
  1102. }
  1103. /**
  1104. * Return the session id (in any case, even if it's null or 0)
  1105. * @return int Session id (can be null)
  1106. */
  1107. public function get_session_id()
  1108. {
  1109. return $this->session_id;
  1110. }
  1111. /**
  1112. * Get appropriate subcategories visible for the user (and optionally the course and session)
  1113. * @param int $stud_id student id (default: all students)
  1114. * @param string Course code (optional)
  1115. * @param int Session ID (optional)
  1116. * @return array Array of subcategories
  1117. */
  1118. public function get_subcategories($stud_id = null, $course_code = null, $session_id = null, $order = null)
  1119. {
  1120. // 1 student
  1121. if (isset($stud_id)) {
  1122. // special case: this is the root
  1123. if ($this->id == 0) {
  1124. return Category::get_root_categories_for_student($stud_id, $course_code, $session_id);
  1125. } else {
  1126. return Category::load(
  1127. null,
  1128. null,
  1129. $course_code,
  1130. $this->id,
  1131. api_is_allowed_to_edit() ? null : 1,
  1132. $session_id,
  1133. $order
  1134. );
  1135. }
  1136. } else { // all students
  1137. // course admin
  1138. if (api_is_allowed_to_edit() && !api_is_platform_admin()) {
  1139. // root
  1140. if ($this->id == 0) {
  1141. return $this->get_root_categories_for_teacher(api_get_user_id(), $course_code, $session_id, false);
  1142. // inside a course
  1143. } elseif (!empty($this->course_code)) {
  1144. return Category::load(null, null, $this->course_code, $this->id, null, $session_id, $order);
  1145. } elseif (!empty($course_code)) {
  1146. return Category::load(null, null, $course_code, $this->id, null, $session_id, $order);
  1147. // course independent
  1148. } else {
  1149. return Category::load(null, api_get_user_id(), 0, $this->id, null);
  1150. }
  1151. } elseif (api_is_platform_admin()) {
  1152. // platform admin
  1153. //we explicitly avoid listing subcats from another session
  1154. return Category::load(null, null, $course_code, $this->id, null, $session_id, $order);
  1155. }
  1156. }
  1157. return array();
  1158. }
  1159. /**
  1160. * Get appropriate evaluations visible for the user
  1161. * @param int $stud_id student id (default: all students)
  1162. * @param boolean $recursive process subcategories (default: no recursion)
  1163. */
  1164. public function get_evaluations($stud_id = null, $recursive = false, $course_code = '')
  1165. {
  1166. $evals = array();
  1167. if (empty($course_code)) {
  1168. $course_code = api_get_course_id();
  1169. }
  1170. // 1 student
  1171. if (isset($stud_id) && !empty($stud_id)) {
  1172. // special case: this is the root
  1173. if ($this->id == 0) {
  1174. $evals = Evaluation::get_evaluations_with_result_for_student(0, $stud_id);
  1175. } else {
  1176. $evals = Evaluation::load(null, null, $course_code, $this->id, api_is_allowed_to_edit() ? null : 1);
  1177. }
  1178. } else { // all students
  1179. // course admin
  1180. if ((api_is_allowed_to_edit() || api_is_drh() || api_is_session_admin()) && !api_is_platform_admin()) {
  1181. // root
  1182. if ($this->id == 0) {
  1183. $evals = Evaluation::load(null, api_get_user_id(), null, $this->id, null);
  1184. } elseif (isset($this->course_code) && !empty($this->course_code)) {
  1185. // inside a course
  1186. $evals = Evaluation::load(null, null, $course_code, $this->id, null);
  1187. } else {
  1188. // course independent
  1189. $evals = Evaluation::load(null, api_get_user_id(), null, $this->id, null);
  1190. }
  1191. } elseif (api_is_platform_admin()) {
  1192. //platform admin
  1193. $evals = Evaluation::load(null, null, $course_code, $this->id, null);
  1194. }
  1195. }
  1196. if ($recursive) {
  1197. $subcats = $this->get_subcategories($stud_id, $course_code);
  1198. if (!empty($subcats)) {
  1199. foreach ($subcats as $subcat) {
  1200. $subevals = $subcat->get_evaluations($stud_id, true, $course_code);
  1201. //$this->debugprint($subevals);
  1202. $evals = array_merge($evals, $subevals);
  1203. }
  1204. }
  1205. }
  1206. return $evals;
  1207. }
  1208. /**
  1209. * Get appropriate links visible for the user
  1210. * @param int $stud_id student id (default: all students)
  1211. * @param boolean $recursive process subcategories (default: no recursion)
  1212. */
  1213. public function get_links($stud_id = null, $recursive = false, $course_code = '')
  1214. {
  1215. $links = array();
  1216. if (empty($course_code)) {
  1217. $course_code = api_get_course_id();
  1218. }
  1219. // no links in root or course independent categories
  1220. if ($this->id == 0) {
  1221. } elseif (isset($stud_id)) {
  1222. // 1 student $stud_id
  1223. $links = LinkFactory::load(
  1224. null,
  1225. null,
  1226. null,
  1227. null,
  1228. empty($this->course_code) ? null : $course_code,
  1229. $this->id,
  1230. api_is_allowed_to_edit() ? null : 1
  1231. );
  1232. } elseif (api_is_allowed_to_edit() || api_is_drh() || api_is_session_admin()) {
  1233. // all students -> only for course/platform admin
  1234. $links = LinkFactory::load(
  1235. null,
  1236. null,
  1237. null,
  1238. null,
  1239. empty($this->course_code) ? null : $this->course_code,
  1240. $this->id,
  1241. null
  1242. );
  1243. }
  1244. if ($recursive) {
  1245. $subcats = $this->get_subcategories($stud_id, $course_code);
  1246. if (!empty($subcats)) {
  1247. foreach ($subcats as $subcat) {
  1248. $sublinks = $subcat->get_links($stud_id, false, $course_code);
  1249. $links = array_merge($links, $sublinks);
  1250. }
  1251. }
  1252. }
  1253. return $links;
  1254. }
  1255. // Other methods implementing GradebookItem
  1256. public function get_item_type()
  1257. {
  1258. return 'C';
  1259. }
  1260. public function set_skills($skills)
  1261. {
  1262. $this->skills = $skills;
  1263. }
  1264. public function get_date()
  1265. {
  1266. return null;
  1267. }
  1268. public function get_icon_name()
  1269. {
  1270. return 'cat';
  1271. }
  1272. /**
  1273. * Find category by name
  1274. * @param string $name_mask search string
  1275. * @return array category objects matching the search criterium
  1276. */
  1277. public function find_category($name_mask, $allcat)
  1278. {
  1279. $foundcats = array();
  1280. foreach ($allcat as $search_cat) {
  1281. if (!(strpos(strtolower($search_cat->get_name()), strtolower($name_mask)) === false)) {
  1282. $foundcats[] = $search_cat;
  1283. }
  1284. }
  1285. return $foundcats;
  1286. }
  1287. /**
  1288. * This function, locks a category , only one who can unlock it is the platform administrator.
  1289. * @param int locked 1 or unlocked 0
  1290. * @return bool
  1291. *
  1292. * */
  1293. function lock($locked)
  1294. {
  1295. $table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
  1296. $sql = "UPDATE $table SET locked = '".intval($locked)."' WHERE id='".intval($this->id)."'";
  1297. Database::query($sql);
  1298. }
  1299. function lock_all_items($locked)
  1300. {
  1301. if (api_get_setting('gradebook_locking_enabled') == 'true') {
  1302. $this->lock($locked);
  1303. $evals_to_lock = $this->get_evaluations();
  1304. if (!empty($evals_to_lock)) {
  1305. foreach ($evals_to_lock as $item) {
  1306. $item->lock($locked);
  1307. }
  1308. }
  1309. $link_to_lock = $this->get_links();
  1310. if (!empty($link_to_lock)) {
  1311. foreach ($link_to_lock as $item) {
  1312. $item->lock($locked);
  1313. }
  1314. }
  1315. $event_type = LOG_GRADEBOOK_UNLOCKED;
  1316. if ($locked == 1) {
  1317. $event_type = LOG_GRADEBOOK_LOCKED;
  1318. }
  1319. event_system($event_type, LOG_GRADEBOOK_ID, $this->id);
  1320. }
  1321. }
  1322. static function register_user_certificate($category_id, $user_id)
  1323. {
  1324. // generating the total score for a course
  1325. $cats_course = Category :: load($category_id, null, null, null, null, null, false);
  1326. $alleval_course = $cats_course[0]->get_evaluations($user_id, true);
  1327. $alllink_course = $cats_course[0]->get_links($user_id, true);
  1328. $evals_links = array_merge($alleval_course, $alllink_course);
  1329. $item_total = 0;
  1330. //@todo move these in a function
  1331. $sum_categories_weight_array = array();
  1332. if (isset($cats_course) && !empty($cats_course)) {
  1333. $categories = Category::load(null, null, null, $category_id);
  1334. if (!empty($categories)) {
  1335. foreach ($categories as $category) {
  1336. $sum_categories_weight_array[$category->get_id()] = $category->get_weight();
  1337. }
  1338. } else {
  1339. $sum_categories_weight_array[$category_id] = $cats_course[0]->get_weight();
  1340. }
  1341. }
  1342. $main_weight = $cats_course[0]->get_weight();
  1343. $item_total_value = 0;
  1344. $item_value = 0;
  1345. for ($count = 0; $count < count($evals_links); $count++) {
  1346. $item = $evals_links[$count];
  1347. $score = $item->calc_score($user_id);
  1348. $divide = (($score[1]) == 0) ? 1 : $score[1];
  1349. $sub_cat_percentage = $sum_categories_weight_array[$item->get_category_id()];
  1350. $item_value = $score[0] / $divide * $item->get_weight() * $sub_cat_percentage / $main_weight;
  1351. $item_total_value += $item_value;
  1352. }
  1353. $item_total_value = (float)$item_total_value;
  1354. $cattotal = Category :: load($category_id);
  1355. $scoretotal = $cattotal[0]->calc_score($user_id);
  1356. //Do not remove this the gradebook/lib/fe/gradebooktable.class.php file load this variable as a global
  1357. $scoredisplay = ScoreDisplay :: instance();
  1358. $my_score_in_gradebook = $scoredisplay->display_score($scoretotal, SCORE_SIMPLE);
  1359. //Show certificate
  1360. $certificate_min_score = $cats_course[0]->get_certificate_min_score();
  1361. $scoretotal_display = $scoredisplay->display_score(
  1362. $scoretotal,
  1363. SCORE_DIV_PERCENT
  1364. ); //a student always sees only the teacher's repartition
  1365. if (isset($certificate_min_score) && $item_total_value >= $certificate_min_score) {
  1366. $my_certificate = get_certificate_by_user_id($cats_course[0]->get_id(), $user_id);
  1367. if (empty($my_certificate)) {
  1368. register_user_info_about_certificate(
  1369. $category_id,
  1370. $user_id,
  1371. $my_score_in_gradebook,
  1372. api_get_utc_datetime()
  1373. );
  1374. $my_certificate = get_certificate_by_user_id($cats_course[0]->get_id(), $user_id);
  1375. }
  1376. if (!empty($my_certificate)) {
  1377. $certificate_obj = new Certificate($my_certificate['id']);
  1378. $url = Certificate::getCertificatePublicURL($my_certificate['id']);
  1379. $certificates = Display::url(
  1380. Display::return_icon('certificate.png', get_lang('Certificates'), array(), 32),
  1381. $url,
  1382. array('target' => '_blank')
  1383. );
  1384. $html = '<div class="actions" align="right">';
  1385. $html .= Display::url($url, $url, array('target' => '_blank'));
  1386. $html .= $certificates;
  1387. $html .= '</div>';
  1388. return $html;
  1389. }
  1390. } else {
  1391. return false;
  1392. }
  1393. }
  1394. }