category.class.php 60 KB

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