category.class.php 74 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. use Chamilo\CoreBundle\Entity\GradebookCategory;
  4. /**
  5. * Class Category
  6. * Defines a gradebook Category object
  7. * @package chamilo.gradebook
  8. */
  9. class Category implements GradebookItem
  10. {
  11. private $id;
  12. private $name;
  13. private $description;
  14. private $user_id;
  15. private $course_code;
  16. private $parent;
  17. private $weight;
  18. private $visible;
  19. private $certificate_min_score;
  20. private $session_id;
  21. private $skills = array();
  22. private $grade_model_id;
  23. private $generateCertificates;
  24. private $isRequirement;
  25. public $studentList;
  26. /**
  27. * Consctructor
  28. */
  29. public function __construct()
  30. {
  31. $this->id = 0;
  32. $this->name = null;
  33. $this->description = null;
  34. $this->user_id = 0;
  35. $this->course_code = null;
  36. $this->parent = 0;
  37. $this->weight = 0;
  38. $this->visible = false;
  39. $this->certificate_min_score = 0;
  40. $this->session_id = 0;
  41. $this->grade_model_id = 0;
  42. $this->generateCertificates = false;
  43. $this->isRequirement = false;
  44. }
  45. /**
  46. * @return int
  47. */
  48. public function get_id()
  49. {
  50. return $this->id;
  51. }
  52. /**
  53. * @return string
  54. */
  55. public function get_name()
  56. {
  57. return $this->name;
  58. }
  59. /**
  60. * @return string
  61. */
  62. public function get_description()
  63. {
  64. return $this->description;
  65. }
  66. /**
  67. * @return int
  68. */
  69. public function get_user_id()
  70. {
  71. return $this->user_id;
  72. }
  73. /**
  74. * @return integer|null
  75. */
  76. public function get_certificate_min_score()
  77. {
  78. if (!empty($this->certificate_min_score)) {
  79. return $this->certificate_min_score;
  80. } else {
  81. return null;
  82. }
  83. }
  84. /**
  85. * @return string
  86. */
  87. public function get_course_code()
  88. {
  89. return $this->course_code;
  90. }
  91. /**
  92. * @return integer
  93. */
  94. public function get_parent_id()
  95. {
  96. return $this->parent;
  97. }
  98. /**
  99. * @return integer
  100. */
  101. public function get_weight()
  102. {
  103. return $this->weight;
  104. }
  105. /**
  106. * @return bool
  107. */
  108. public function is_locked()
  109. {
  110. return isset($this->locked) && $this->locked == 1 ? true : false;
  111. }
  112. /**
  113. * @return boolean
  114. */
  115. public function is_visible()
  116. {
  117. return $this->visible;
  118. }
  119. /**
  120. * Get $isRequirement
  121. * @return int
  122. */
  123. public function getIsRequirement()
  124. {
  125. return $this->isRequirement;
  126. }
  127. /**
  128. * @param int $id
  129. */
  130. public function set_id($id)
  131. {
  132. $this->id = $id;
  133. }
  134. /**
  135. * @param string $name
  136. */
  137. public function set_name($name)
  138. {
  139. $this->name = $name;
  140. }
  141. /**
  142. * @param string $description
  143. */
  144. public function set_description($description)
  145. {
  146. $this->description = $description;
  147. }
  148. /**
  149. * @param int $user_id
  150. */
  151. public function set_user_id($user_id)
  152. {
  153. $this->user_id = $user_id;
  154. }
  155. /**
  156. * @param string $course_code
  157. */
  158. public function set_course_code($course_code)
  159. {
  160. $this->course_code = $course_code;
  161. }
  162. /**
  163. * @param float $min_score
  164. */
  165. public function set_certificate_min_score($min_score = null)
  166. {
  167. $this->certificate_min_score = $min_score;
  168. }
  169. /**
  170. * @param int $parent
  171. */
  172. public function set_parent_id($parent)
  173. {
  174. $this->parent = intval($parent);
  175. }
  176. /**
  177. * Filters to int and sets the session ID
  178. * @param int The session ID from the Dokeos course session
  179. */
  180. public function set_session_id($session_id = 0)
  181. {
  182. $this->session_id = (int)$session_id;
  183. }
  184. /**
  185. * @param $weight
  186. */
  187. public function set_weight($weight)
  188. {
  189. $this->weight = $weight;
  190. }
  191. /**
  192. * @param $visible
  193. */
  194. public function set_visible($visible)
  195. {
  196. $this->visible = $visible;
  197. }
  198. /**
  199. * @param int $id
  200. */
  201. public function set_grade_model_id($id)
  202. {
  203. $this->grade_model_id = $id;
  204. }
  205. /**
  206. * @param $locked
  207. */
  208. public function set_locked($locked)
  209. {
  210. $this->locked = $locked;
  211. }
  212. /**
  213. * Set $isRequirement
  214. * @param int $isRequirement
  215. */
  216. public function setIsRequirement($isRequirement)
  217. {
  218. $this->isRequirement = $isRequirement;
  219. }
  220. /**
  221. * @return null|integer
  222. */
  223. public function get_grade_model_id()
  224. {
  225. if ($this->grade_model_id < 0) {
  226. return null;
  227. }
  228. return $this->grade_model_id;
  229. }
  230. /**
  231. * @return string
  232. */
  233. public function get_type()
  234. {
  235. return 'category';
  236. }
  237. /**
  238. * @param bool $from_db
  239. * @return array|resource
  240. */
  241. public function get_skills($from_db = true)
  242. {
  243. if ($from_db) {
  244. $cat_id = $this->get_id();
  245. $gradebook = new Gradebook();
  246. $skills = $gradebook->get_skills_by_gradebook($cat_id);
  247. } else {
  248. $skills = $this->skills;
  249. }
  250. return $skills;
  251. }
  252. /**
  253. * @return array
  254. */
  255. public function get_skills_for_select()
  256. {
  257. $skills = $this->get_skills();
  258. $skill_select = array();
  259. if (!empty($skills)) {
  260. foreach($skills as $skill) {
  261. $skill_select[$skill['id']] = $skill['name'];
  262. }
  263. }
  264. return $skill_select;
  265. }
  266. /**
  267. * Set the generate_certificates value
  268. * @param int $generateCertificates
  269. */
  270. public function setGenerateCertificates($generateCertificates)
  271. {
  272. $this->generateCertificates = $generateCertificates;
  273. }
  274. /**
  275. * Get the generate_certificates value
  276. * @return int
  277. */
  278. public function getGenerateCertificates()
  279. {
  280. return $this->generateCertificates;
  281. }
  282. /**
  283. * @param int $id
  284. * @param int $session_id
  285. *
  286. * @return array
  287. */
  288. public static function load_session_categories($id = null, $session_id = null)
  289. {
  290. if (isset($id) && (int)$id === 0) {
  291. $cats = array();
  292. $cats[] = Category::create_root_category();
  293. return $cats;
  294. }
  295. $courseCode = api_get_course_info_by_id(api_get_course_int_id());
  296. $courseCode = $courseCode['code'];
  297. $session_id = intval($session_id);
  298. if (!empty($session_id)) {
  299. $tbl_grade_categories = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
  300. $sql = 'SELECT id, course_code
  301. FROM '.$tbl_grade_categories. '
  302. WHERE session_id = '.$session_id;
  303. $result_session = Database::query($sql);
  304. if (Database::num_rows($result_session) > 0) {
  305. $categoryList = array();
  306. while ($data_session = Database::fetch_array($result_session)) {
  307. $parent_id = $data_session['id'];
  308. if ($data_session['course_code'] == $courseCode) {
  309. $categories = Category::load($parent_id);
  310. $categoryList = array_merge($categoryList, $categories);
  311. }
  312. }
  313. return $categoryList;
  314. }
  315. }
  316. }
  317. /**
  318. * Retrieve categories and return them as an array of Category objects
  319. * @param int $id category id
  320. * @param int $user_id (category owner)
  321. * @param string $course_code
  322. * @param int $parent_id parent category
  323. * @param bool $visible
  324. * @param int $session_id (in case we are in a session)
  325. * @param bool $order_by Whether to show all "session"
  326. * categories (true) or hide them (false) in case there is no session id
  327. */
  328. public static function load(
  329. $id = null,
  330. $user_id = null,
  331. $course_code = null,
  332. $parent_id = null,
  333. $visible = null,
  334. $session_id = null,
  335. $order_by = null
  336. ) {
  337. //if the category given is explicitly 0 (not null), then create
  338. // a root category object (in memory)
  339. if (isset($id) && (int)$id === 0) {
  340. $cats = array();
  341. $cats[] = Category::create_root_category();
  342. return $cats;
  343. }
  344. $tbl_grade_categories = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
  345. $sql = 'SELECT * FROM '.$tbl_grade_categories;
  346. $paramcount = 0;
  347. if (isset($id)) {
  348. $sql.= ' WHERE id = '.intval($id);
  349. $paramcount ++;
  350. }
  351. if (isset($user_id)) {
  352. $user_id = intval($user_id);
  353. if ($paramcount != 0) {
  354. $sql .= ' AND';
  355. } else {
  356. $sql .= ' WHERE';
  357. }
  358. $sql .= ' user_id = '.intval($user_id);
  359. $paramcount++;
  360. }
  361. if (isset($course_code)) {
  362. if ($paramcount != 0) {
  363. $sql .= ' AND';
  364. } else {
  365. $sql .= ' WHERE';
  366. }
  367. if ($course_code == '0') {
  368. $sql .= ' course_code is null ';
  369. } else {
  370. $sql .= " course_code = '".Database::escape_string($course_code)."'";
  371. }
  372. /*if ($show_session_categories !== true) {
  373. // a query on the course should show all
  374. // the categories inside sessions for this course
  375. // otherwise a special parameter is given to ask explicitely
  376. $sql .= " AND (session_id IS NULL OR session_id = 0) ";
  377. } else {*/
  378. if (empty($session_id)) {
  379. $sql .= ' AND (session_id IS NULL OR session_id = 0) ';
  380. } else {
  381. $sql .= ' AND session_id = '.(int)$session_id.' ';
  382. }
  383. //}
  384. $paramcount ++;
  385. }
  386. if (isset($parent_id)) {
  387. if ($paramcount != 0) {
  388. $sql .= ' AND ';
  389. } else {
  390. $sql .= ' WHERE ';
  391. }
  392. $sql .= ' parent_id = '.intval($parent_id);
  393. $paramcount++;
  394. }
  395. if (isset($visible)) {
  396. if ($paramcount != 0) {
  397. $sql .= ' AND';
  398. } else {
  399. $sql .= ' WHERE';
  400. }
  401. $sql .= ' visible = '.intval($visible);
  402. }
  403. if (!empty($order_by)) {
  404. if (!empty($order_by) && $order_by != '') {
  405. $sql .= ' '.$order_by;
  406. }
  407. }
  408. $result = Database::query($sql);
  409. $categories = array();
  410. if (Database::num_rows($result) > 0) {
  411. $categories = Category::create_category_objects_from_sql_result(
  412. $result
  413. );
  414. }
  415. return $categories;
  416. }
  417. /**
  418. * @return Category
  419. */
  420. private static function create_root_category()
  421. {
  422. $cat = new Category();
  423. $cat->set_id(0);
  424. $cat->set_name(get_lang('RootCat'));
  425. $cat->set_description(null);
  426. $cat->set_user_id(0);
  427. $cat->set_course_code(null);
  428. $cat->set_parent_id(null);
  429. $cat->set_weight(0);
  430. $cat->set_visible(1);
  431. $cat->setGenerateCertificates(0);
  432. $cat->setIsRequirement(false);
  433. return $cat;
  434. }
  435. /**
  436. * @param Doctrine\DBAL\Driver\Statement|null $result
  437. *
  438. * @return array
  439. */
  440. private static function create_category_objects_from_sql_result($result)
  441. {
  442. $categories = array();
  443. while ($data = Database::fetch_array($result)) {
  444. $cat = new Category();
  445. $cat->set_id($data['id']);
  446. $cat->set_name($data['name']);
  447. $cat->set_description($data['description']);
  448. $cat->set_user_id($data['user_id']);
  449. $cat->set_course_code($data['course_code']);
  450. $cat->set_parent_id($data['parent_id']);
  451. $cat->set_weight($data['weight']);
  452. $cat->set_visible($data['visible']);
  453. $cat->set_session_id($data['session_id']);
  454. $cat->set_certificate_min_score($data['certif_min_score']);
  455. $cat->set_grade_model_id($data['grade_model_id']);
  456. $cat->set_locked($data['locked']);
  457. $cat->setGenerateCertificates($data['generate_certificates']);
  458. $cat->setIsRequirement($data['is_requirement']);
  459. $categories[] = $cat;
  460. }
  461. return $categories;
  462. }
  463. /**
  464. * Create a category object from a GradebookCategory entity
  465. * @param GradebookCategory $gradebookCategory The entity
  466. * @return \Category
  467. */
  468. public static function createCategoryObjectFromEntity(GradebookCategory $gradebookCategory)
  469. {
  470. $category = new Category();
  471. $category->set_id($gradebookCategory->getId());
  472. $category->set_name($gradebookCategory->getName());
  473. $category->set_description($gradebookCategory->getDescription());
  474. $category->set_user_id($gradebookCategory->getUserId());
  475. $category->set_course_code($gradebookCategory->getCourseCode());
  476. $category->set_parent_id($gradebookCategory->getParentId());
  477. $category->set_weight($gradebookCategory->getWeight());
  478. $category->set_visible($gradebookCategory->getVisible());
  479. $category->set_session_id($gradebookCategory->getSessionId());
  480. $category->set_certificate_min_score(
  481. $gradebookCategory->getCertifMinScore()
  482. );
  483. $category->set_grade_model_id($gradebookCategory->getGradeModelId());
  484. $category->set_locked($gradebookCategory->getLocked());
  485. $category->setGenerateCertificates(
  486. $gradebookCategory->getGenerateCertificates()
  487. );
  488. $category->setIsRequirement($gradebookCategory->getIsRequirement());
  489. return $category;
  490. }
  491. /**
  492. * Insert this category into the database
  493. */
  494. public function add()
  495. {
  496. if (isset($this->name) && '-1' == $this->name) {
  497. return false;
  498. }
  499. if (isset($this->name) && isset($this->user_id)) {
  500. $em = Database::getManager();
  501. $category = new GradebookCategory();
  502. $category->setName($this->name);
  503. $category->setDescription($this->description);
  504. $category->setUserId($this->user_id);
  505. $category->setCourseCode($this->course_code);
  506. $category->setParentId($this->parent);
  507. $category->setWeight($this->weight);
  508. $category->setVisible($this->visible);
  509. $category->setCertifMinScore($this->certificate_min_score);
  510. $category->setSessionId($this->session_id);
  511. $category->setGenerateCertificates($this->generateCertificates);
  512. $category->setGradeModelId($this->grade_model_id);
  513. $category->setIsRequirement($this->isRequirement);
  514. $category->setLocked(false);
  515. $em->persist($category);
  516. $em->flush();
  517. $id = $category->getId();
  518. $this->set_id($id);
  519. if (!empty($id)) {
  520. $parent_id = $this->get_parent_id();
  521. $grade_model_id = $this->get_grade_model_id();
  522. if ($parent_id == 0) {
  523. //do something
  524. if (isset($grade_model_id) && !empty($grade_model_id) && $grade_model_id != '-1') {
  525. $obj = new GradeModel();
  526. $components = $obj->get_components($grade_model_id);
  527. $default_weight_setting = api_get_setting('gradebook_default_weight');
  528. $default_weight = 100;
  529. if (isset($default_weight_setting)) {
  530. $default_weight = $default_weight_setting;
  531. }
  532. foreach ($components as $component) {
  533. $gradebook = new Gradebook();
  534. $params = array();
  535. $params['name'] = $component['acronym'];
  536. $params['description'] = $component['title'];
  537. $params['user_id'] = api_get_user_id();
  538. $params['parent_id'] = $id;
  539. $params['weight'] = $component['percentage'] / 100 * $default_weight;
  540. $params['session_id'] = api_get_session_id();
  541. $params['course_code'] = $this->get_course_code();
  542. $gradebook->save($params);
  543. }
  544. }
  545. }
  546. }
  547. $gradebook= new Gradebook();
  548. $gradebook->update_skills_to_gradebook($this->id, $this->get_skills(false));
  549. return $id;
  550. }
  551. }
  552. /**
  553. * Update the properties of this category in the database
  554. * @todo fix me
  555. */
  556. public function save()
  557. {
  558. $em = Database::getManager();
  559. $gradebookCategory = $em
  560. ->getRepository('ChamiloCoreBundle:GradebookCategory')
  561. ->find($this->id);
  562. if (empty($gradebookCategory)) {
  563. return false;
  564. }
  565. $gradebookCategory->setName($this->name);
  566. $gradebookCategory->setDescription($this->description);
  567. $gradebookCategory->setUserId($this->user_id);
  568. $gradebookCategory->setCourseCode($this->course_code);
  569. $gradebookCategory->setParentId($this->parent);
  570. $gradebookCategory->setWeight($this->weight);
  571. $gradebookCategory->setVisible($this->visible);
  572. $gradebookCategory->setCertifMinScore($this->certificate_min_score);
  573. $gradebookCategory->setGenerateCertificates(
  574. $this->generateCertificates
  575. );
  576. $gradebookCategory->setGradeModelId($this->grade_model_id);
  577. $gradebookCategory->setIsRequirement($this->isRequirement);
  578. $em->merge($gradebookCategory);
  579. $em->flush();
  580. if (!empty($this->id)) {
  581. $parent_id = $this->get_parent_id();
  582. $grade_model_id = $this->get_grade_model_id();
  583. if ($parent_id == 0) {
  584. if (isset($grade_model_id) && !empty($grade_model_id) && $grade_model_id != '-1') {
  585. $obj = new GradeModel();
  586. $components = $obj->get_components($grade_model_id);
  587. $default_weight_setting = api_get_setting('gradebook_default_weight');
  588. $default_weight = 100;
  589. if (isset($default_weight_setting)) {
  590. $default_weight = $default_weight_setting;
  591. }
  592. $final_weight = $this->get_weight();
  593. if (!empty($final_weight)) {
  594. $default_weight = $this->get_weight();
  595. }
  596. foreach ($components as $component) {
  597. $gradebook = new Gradebook();
  598. $params = array();
  599. $params['name'] = $component['acronym'];
  600. $params['description'] = $component['title'];
  601. $params['user_id'] = api_get_user_id();
  602. $params['parent_id'] = $this->id;
  603. $params['weight'] = $component['percentage']/100*$default_weight;
  604. $params['session_id'] = api_get_session_id();
  605. $params['course_code'] = $this->get_course_code();
  606. $gradebook->save($params);
  607. }
  608. }
  609. }
  610. }
  611. $gradebook= new Gradebook();
  612. $gradebook->update_skills_to_gradebook(
  613. $this->id,
  614. $this->get_skills(false),
  615. true
  616. );
  617. }
  618. /**
  619. * Update link weights see #5168
  620. * @param type $new_weight
  621. */
  622. public function update_children_weight($new_weight)
  623. {
  624. $links = $this->get_links();
  625. $old_weight = $this->get_weight();
  626. if (!empty($links)) {
  627. foreach ($links as $link_item) {
  628. if (isset($link_item)) {
  629. $new_item_weight = $new_weight * $link_item->get_weight() / $old_weight;
  630. $link_item->set_weight($new_item_weight);
  631. $link_item->save();
  632. }
  633. }
  634. }
  635. }
  636. /**
  637. * Delete this evaluation from the database
  638. */
  639. public function delete()
  640. {
  641. $tbl_grade_categories = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
  642. $sql = 'DELETE FROM '.$tbl_grade_categories.' WHERE id = '.intval($this->id);
  643. Database::query($sql);
  644. }
  645. /**
  646. * Not delete this category from the database,when visible=3 is category eliminated
  647. */
  648. public function update_category_delete($course_id)
  649. {
  650. $tbl_grade_categories = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
  651. $sql = 'UPDATE '.$tbl_grade_categories.' SET visible=3
  652. WHERE course_code ="'.Database::escape_string($course_id).'"';
  653. Database::query($sql);
  654. }
  655. /**
  656. * Show message resource delete
  657. */
  658. public function show_message_resource_delete($course_id)
  659. {
  660. $tbl_grade_categories = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
  661. $sql = 'SELECT count(*) AS num from '.$tbl_grade_categories.'
  662. WHERE
  663. course_code = "'.Database::escape_string($course_id).'" AND
  664. visible=3';
  665. $res = Database::query($sql);
  666. $option = Database::fetch_array($res, 'ASSOC');
  667. if ($option['num']>=1) {
  668. return '&nbsp;&nbsp;<span class="resource-deleted">(&nbsp;'.get_lang('ResourceDeleted').'&nbsp;)</span>';
  669. } else {
  670. return false;
  671. }
  672. }
  673. /**
  674. * Shows all information of an category
  675. */
  676. public function shows_all_information_an_category($selectcat = '')
  677. {
  678. if ($selectcat == '') {
  679. return null;
  680. } else {
  681. $tbl_category = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
  682. $sql = 'SELECT name,description,user_id,course_code,parent_id,weight,visible,certif_min_score,session_id, generate_certificates, is_requirement
  683. FROM '.$tbl_category.' c
  684. WHERE c.id='.intval($selectcat);
  685. $result = Database::query($sql);
  686. $row = Database::fetch_array($result, 'ASSOC');
  687. return $row;
  688. }
  689. }
  690. /**
  691. * Check if a category name (with the same parent category) already exists
  692. * @param $name name to check (if not given, the name property of this object will be checked)
  693. * @param $parent parent category
  694. */
  695. public function does_name_exist($name, $parent)
  696. {
  697. if (!isset ($name)) {
  698. $name = $this->name;
  699. $parent = $this->parent;
  700. }
  701. $tbl_grade_categories = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
  702. $sql = 'SELECT count(id) AS number'
  703. .' FROM '.$tbl_grade_categories
  704. ." WHERE name = '".Database::escape_string($name)."'";
  705. if (api_is_allowed_to_edit()) {
  706. $parent = Category::load($parent);
  707. $code = $parent[0]->get_course_code();
  708. $courseInfo = api_get_course_info($code);
  709. $courseId = $courseInfo['real_id'];
  710. if (isset($code) && $code != '0') {
  711. $main_course_user_table = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
  712. $sql .= ' AND user_id IN (
  713. SELECT user_id FROM '.$main_course_user_table.'
  714. WHERE c_id = '.$courseId.' AND status = '.COURSEMANAGER.'
  715. )';
  716. } else {
  717. $sql .= ' AND user_id = '.api_get_user_id();
  718. }
  719. } else {
  720. $sql .= ' AND user_id = '.api_get_user_id();
  721. }
  722. if (!isset ($parent)) {
  723. $sql.= ' AND parent_id is null';
  724. } else {
  725. $sql.= ' AND parent_id = '.intval($parent);
  726. }
  727. $result = Database::query($sql);
  728. $number = Database::fetch_row($result);
  729. return ($number[0] != 0);
  730. }
  731. /**
  732. * Checks if the certificate is available for the given user in this category
  733. * @param integer $user_id User ID
  734. * @return boolean True if conditions match, false if fails
  735. */
  736. public function is_certificate_available($user_id)
  737. {
  738. $score = $this->calc_score(
  739. $user_id,
  740. null,
  741. $this->course_code,
  742. $this->session_id
  743. );
  744. if (isset($score) && isset($score[0])) {
  745. // Get a percentage score to compare to minimum certificate score
  746. //$certification_score = $score[0] / $score[1] * 100;
  747. // Get real score not a percentage.
  748. $certification_score = $score[0];
  749. if ($certification_score >= $this->certificate_min_score) {
  750. return true;
  751. }
  752. }
  753. return false;
  754. }
  755. /**
  756. * Is this category a course ?
  757. * A category is a course if it has a course code and no parent category.
  758. */
  759. public function is_course()
  760. {
  761. return (isset($this->course_code) && !empty($this->course_code)
  762. && (!isset($this->parent) || $this->parent == 0));
  763. }
  764. /**
  765. * Calculate the score of this category
  766. * @param integer $stud_id student id (default: all students - then the average is returned)
  767. * @param integer $session_id
  768. * @return array (score sum, weight sum)
  769. * or null if no scores available
  770. */
  771. public function calc_score(
  772. $stud_id = null,
  773. $type = null,
  774. $course_code = '',
  775. $session_id = null
  776. ) {
  777. // Classic
  778. if (!empty($stud_id) && $type == '') {
  779. if (!empty($course_code)) {
  780. $cats = $this->get_subcategories(
  781. $stud_id,
  782. $course_code,
  783. $session_id
  784. );
  785. $evals = $this->get_evaluations($stud_id, false, $course_code);
  786. $links = $this->get_links($stud_id, false, $course_code);
  787. } else {
  788. $cats = $this->get_subcategories($stud_id);
  789. $evals = $this->get_evaluations($stud_id);
  790. $links = $this->get_links($stud_id);
  791. }
  792. // Calculate score
  793. $count = 0;
  794. $ressum = 0;
  795. $weightsum = 0;
  796. if (!empty($cats)) {
  797. /** @var Category $cat */
  798. foreach ($cats as $cat) {
  799. $cat->set_session_id($session_id);
  800. $cat->set_course_code($course_code);
  801. $cat->setStudentList($this->getStudentList());
  802. $score = $cat->calc_score(
  803. $stud_id,
  804. null,
  805. $course_code,
  806. $session_id
  807. );
  808. $catweight = 0;
  809. if ($cat->get_weight() != 0) {
  810. $catweight = $cat->get_weight();
  811. $weightsum += $catweight;
  812. }
  813. if (isset($score) && !empty($score[1]) && !empty($catweight)) {
  814. $ressum += $score[0]/$score[1] * $catweight;
  815. }
  816. }
  817. }
  818. $students = array();
  819. if (!empty($evals)) {
  820. /** @var Evaluation $eval */
  821. foreach ($evals as $eval) {
  822. $eval->setStudentList($this->getStudentList());
  823. $evalres = $eval->calc_score($stud_id, null);
  824. if (isset($evalres) && $eval->get_weight() != 0) {
  825. $evalweight = $eval->get_weight();
  826. $weightsum += $evalweight;
  827. $count++;
  828. if (!empty($evalres[1])) {
  829. $ressum += $evalres[0] / $evalres[1] * $evalweight;
  830. }
  831. } else {
  832. if ($eval->get_weight() != 0) {
  833. $evalweight = $eval->get_weight();
  834. $weightsum += $evalweight;
  835. }
  836. }
  837. }
  838. }
  839. if (!empty($links)) {
  840. /** @var EvalLink|ExerciseLink $link */
  841. foreach ($links as $link) {
  842. $link->setStudentList($this->getStudentList());
  843. $linkres = $link->calc_score($stud_id, null);
  844. if (!empty($linkres) && $link->get_weight() != 0) {
  845. $students[$stud_id] = $linkres[0];
  846. $linkweight = $link->get_weight();
  847. $link_res_denom = $linkres[1] == 0 ? 1 : $linkres[1];
  848. $count++;
  849. $weightsum += $linkweight;
  850. $ressum += $linkres[0] / $link_res_denom * $linkweight;
  851. } else {
  852. // Adding if result does not exists
  853. if ($link->get_weight() != 0) {
  854. $linkweight = $link->get_weight();
  855. $weightsum += $linkweight;
  856. }
  857. }
  858. }
  859. }
  860. } else {
  861. if (!empty($course_code)) {
  862. $cats = $this->get_subcategories(
  863. null,
  864. $course_code,
  865. $session_id
  866. );
  867. $evals = $this->get_evaluations(null, false, $course_code);
  868. $links = $this->get_links(null, false, $course_code);
  869. } else {
  870. $cats = $this->get_subcategories(null);
  871. $evals = $this->get_evaluations(null);
  872. $links = $this->get_links(null);
  873. }
  874. // Calculate score
  875. $count = 0;
  876. $ressum = 0;
  877. $weightsum = 0;
  878. $bestResult = 0;
  879. if (!empty($cats)) {
  880. /** @var Category $cat */
  881. foreach ($cats as $cat) {
  882. $cat->setStudentList($this->getStudentList());
  883. $score = $cat->calc_score(
  884. null,
  885. $type,
  886. $course_code,
  887. $session_id
  888. );
  889. $catweight = 0;
  890. if ($cat->get_weight() != 0) {
  891. $catweight = $cat->get_weight();
  892. $weightsum += $catweight;
  893. }
  894. if (isset($score) && !empty($score[1]) && !empty($catweight)) {
  895. $ressum += $score[0]/$score[1] * $catweight;
  896. if ($ressum > $bestResult) {
  897. $bestResult = $ressum;
  898. }
  899. }
  900. }
  901. }
  902. if (!empty($evals)) {
  903. /** @var Evaluation $eval */
  904. foreach ($evals as $eval) {
  905. $evalres = $eval->calc_score(null, $type);
  906. $eval->setStudentList($this->getStudentList());
  907. if (isset($evalres) && $eval->get_weight() != 0) {
  908. $evalweight = $eval->get_weight();
  909. $weightsum += $evalweight;
  910. $count++;
  911. if (!empty($evalres[1])) {
  912. $ressum += $evalres[0] / $evalres[1] * $evalweight;
  913. }
  914. if ($ressum > $bestResult) {
  915. $bestResult = $ressum;
  916. }
  917. } else {
  918. if ($eval->get_weight() != 0) {
  919. $evalweight = $eval->get_weight();
  920. $weightsum += $evalweight;
  921. }
  922. }
  923. }
  924. }
  925. if (!empty($links)) {
  926. /** @var EvalLink|ExerciseLink $link */
  927. foreach ($links as $link) {
  928. $link->setStudentList($this->getStudentList());
  929. $linkres = $link->calc_score($stud_id, $type);
  930. if (!empty($linkres) && $link->get_weight() != 0) {
  931. $students[$stud_id] = $linkres[0];
  932. $linkweight = $link->get_weight();
  933. $link_res_denom = $linkres[1] == 0 ? 1 : $linkres[1];
  934. $count++;
  935. $weightsum += $linkweight;
  936. $ressum += $linkres[0] / $link_res_denom * $linkweight;
  937. if ($ressum > $bestResult) {
  938. $bestResult = $ressum;
  939. }
  940. } else {
  941. // Adding if result does not exists
  942. if ($link->get_weight() != 0) {
  943. $linkweight = $link->get_weight();
  944. $weightsum += $linkweight;
  945. }
  946. }
  947. }
  948. }
  949. }
  950. switch ($type) {
  951. case 'best':
  952. if (empty($bestResult)) {
  953. return null;
  954. }
  955. return array($bestResult, $weightsum);
  956. break;
  957. case 'average':
  958. if (empty($ressum)) {
  959. return null;
  960. }
  961. return array($ressum, $weightsum);
  962. break;
  963. case 'ranking':
  964. // category ranking is calculated in gradebook_data_generator.class.php
  965. // function get_data
  966. return null;
  967. return AbstractLink::getCurrentUserRanking($stud_id, array());
  968. break;
  969. default:
  970. return array($ressum, $weightsum);
  971. break;
  972. }
  973. }
  974. /**
  975. * Delete this category and every subcategory, evaluation and result inside
  976. */
  977. public function delete_all()
  978. {
  979. $cats = Category::load(null, null, $this->course_code, $this->id, null);
  980. $evals = Evaluation::load(null, null, $this->course_code, $this->id, null);
  981. $links = LinkFactory::load(null, null, null, null, $this->course_code, $this->id, null);
  982. if (!empty($cats)) {
  983. foreach ($cats as $cat) {
  984. $cat->delete_all();
  985. $cat->delete();
  986. }
  987. }
  988. if (!empty($evals)) {
  989. foreach ($evals as $eval) {
  990. $eval->delete_with_results();
  991. }
  992. }
  993. if (!empty($links)) {
  994. foreach ($links as $link) {
  995. $link->delete();
  996. }
  997. }
  998. $this->delete();
  999. }
  1000. /**
  1001. * Return array of Category objects where a student is subscribed to.
  1002. * @param int student id
  1003. * @param string Course code
  1004. * @param int Session id
  1005. * @param integer $stud_id
  1006. * @param string $course_code
  1007. * @param integer $session_id
  1008. */
  1009. public function get_root_categories_for_student($stud_id, $course_code = null, $session_id = null)
  1010. {
  1011. $main_course_user_table = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
  1012. $courseTable = Database :: get_main_table(TABLE_MAIN_COURSE);
  1013. $tbl_grade_categories = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
  1014. $sql = "SELECT * FROM $tbl_grade_categories WHERE parent_id = 0";
  1015. if (!api_is_allowed_to_edit()) {
  1016. $sql .= ' AND visible = 1';
  1017. //proceed with checks on optional parameters course & session
  1018. if (!empty($course_code)) {
  1019. // TODO: considering it highly improbable that a user would get here
  1020. // if he doesn't have the rights to view this course and this
  1021. // session, we don't check his registration to these, but this
  1022. // could be an improvement
  1023. if (!empty($session_id)) {
  1024. $sql .= " AND course_code = '".Database::escape_string($course_code)."' AND session_id = ".(int)$session_id;
  1025. } else {
  1026. $sql .= " AND course_code = '".Database::escape_string($course_code)."' AND session_id is null OR session_id=0";
  1027. }
  1028. } else {
  1029. //no optional parameter, proceed as usual
  1030. $sql .= ' AND course_code in
  1031. (
  1032. SELECT c.code
  1033. FROM '.$main_course_user_table.' cu INNER JOIN '.$courseTable.' c
  1034. ON (cu.c_id = c.id)
  1035. WHERE cu.user_id = '.intval($stud_id).'
  1036. AND cu.status = '.STUDENT.'
  1037. )';
  1038. }
  1039. } elseif (api_is_allowed_to_edit() && !api_is_platform_admin()) {
  1040. //proceed with checks on optional parameters course & session
  1041. if (!empty($course_code)) {
  1042. // TODO: considering it highly improbable that a user would get here
  1043. // if he doesn't have the rights to view this course and this
  1044. // session, we don't check his registration to these, but this
  1045. // could be an improvement
  1046. $sql .= " AND course_code = '".Database::escape_string($course_code)."'";
  1047. if (!empty($session_id)) {
  1048. $sql .= " AND session_id = ".(int)$session_id;
  1049. } else {
  1050. $sql .="AND session_id IS NULL OR session_id=0";
  1051. }
  1052. } else {
  1053. $sql .= ' AND course_code IN
  1054. (
  1055. SELECT c.code
  1056. FROM '.$main_course_user_table.' cu INNER JOIN '.$courseTable.' c
  1057. ON (cu.c_id = c.id)
  1058. WHERE
  1059. cu.user_id = '.api_get_user_id().' AND
  1060. cu.status = '.COURSEMANAGER.'
  1061. )';
  1062. }
  1063. }elseif (api_is_platform_admin()) {
  1064. if (isset($session_id) && $session_id!=0) {
  1065. $sql.=' AND session_id='.intval($session_id);
  1066. } else {
  1067. $sql.=' AND coalesce(session_id,0)=0';
  1068. }
  1069. }
  1070. $result = Database::query($sql);
  1071. $cats = Category::create_category_objects_from_sql_result($result);
  1072. // course independent categories
  1073. if (empty($course_code)) {
  1074. $cats = Category::get_independent_categories_with_result_for_student (0, $stud_id, $cats);
  1075. }
  1076. return $cats;
  1077. }
  1078. /**
  1079. * Return array of Category objects where a teacher is admin for.
  1080. * @param int user id (to return everything, use 'null' here)
  1081. * @param string course code (optional)
  1082. * @param int session id (optional)
  1083. * @param integer $user_id
  1084. * @param string $course_code
  1085. * @param integer $session_id
  1086. */
  1087. public function get_root_categories_for_teacher($user_id, $course_code = null, $session_id = null)
  1088. {
  1089. if ($user_id == null) {
  1090. return Category::load(null,null,$course_code,0,null,$session_id);
  1091. }
  1092. $courseTable = Database :: get_main_table(TABLE_MAIN_COURSE);
  1093. $main_course_user_table = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
  1094. $tbl_grade_categories = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
  1095. $sql = 'SELECT * FROM '.$tbl_grade_categories.'
  1096. WHERE parent_id = 0';
  1097. if (!empty($course_code)) {
  1098. $sql .= " AND course_code = '".Database::escape_string($course_code)."' ";
  1099. if (!empty($session_id)) {
  1100. $sql .= " AND session_id = ".(int)$session_id;
  1101. }
  1102. } else {
  1103. $sql .= ' AND course_code in
  1104. (
  1105. SELECT c.code
  1106. FROM '.$main_course_user_table.' cu
  1107. INNER JOIN '.$courseTable.' c
  1108. ON (cu.c_id = c.id)
  1109. WHERE user_id = '.intval($user_id).'
  1110. )';
  1111. }
  1112. $result = Database::query($sql);
  1113. $cats = Category::create_category_objects_from_sql_result($result);
  1114. // course independent categories
  1115. if (isset($course_code)) {
  1116. $indcats = Category::load(null,$user_id,$course_code,0,null,$session_id);
  1117. $cats = array_merge($cats, $indcats);
  1118. }
  1119. return $cats;
  1120. }
  1121. /**
  1122. * Can this category be moved to somewhere else ?
  1123. * The root and courses cannot be moved.
  1124. */
  1125. public function is_movable()
  1126. {
  1127. return (!(!isset ($this->id) || $this->id == 0 || $this->is_course()));
  1128. }
  1129. /**
  1130. * Generate an array of possible categories where this category can be moved to.
  1131. * Notice: its own parent will be included in the list: it's up to the frontend
  1132. * to disable this element.
  1133. * @return array 2-dimensional array - every element contains 3 subelements (id, name, level)
  1134. */
  1135. public function get_target_categories()
  1136. {
  1137. // the root or a course -> not movable
  1138. if (!$this->is_movable()) {
  1139. return null;
  1140. } else {
  1141. // otherwise:
  1142. // - course independent category
  1143. // -> movable to root or other independent categories
  1144. // - category inside a course
  1145. // -> movable to root, independent categories or categories inside the course
  1146. $user = (api_is_platform_admin() ? null : api_get_user_id());
  1147. $targets = array();
  1148. $level = 0;
  1149. $root = array(0, get_lang('RootCat'), $level);
  1150. $targets[] = $root;
  1151. if (isset($this->course_code) && !empty($this->course_code)) {
  1152. $crscats = Category::load(null,null,$this->course_code,0);
  1153. foreach ($crscats as $cat) {
  1154. if ($this->can_be_moved_to_cat($cat)) {
  1155. $targets[] = array ($cat->get_id(), $cat->get_name(), $level+1);
  1156. $targets = $this->add_target_subcategories($targets, $level+1, $cat->get_id());
  1157. }
  1158. }
  1159. }
  1160. $indcats = Category::load(null,$user,0,0);
  1161. foreach ($indcats as $cat) {
  1162. if ($this->can_be_moved_to_cat($cat)) {
  1163. $targets[] = array ($cat->get_id(), $cat->get_name(), $level+1);
  1164. $targets = $this->add_target_subcategories($targets, $level+1, $cat->get_id());
  1165. }
  1166. }
  1167. return $targets;
  1168. }
  1169. }
  1170. /**
  1171. * Internal function used by get_target_categories()
  1172. * @param integer $level
  1173. */
  1174. private function add_target_subcategories($targets, $level, $catid)
  1175. {
  1176. $subcats = Category::load(null,null,null,$catid);
  1177. foreach ($subcats as $cat) {
  1178. if ($this->can_be_moved_to_cat($cat)) {
  1179. $targets[] = array ($cat->get_id(), $cat->get_name(), $level+1);
  1180. $targets = $this->add_target_subcategories($targets, $level+1, $cat->get_id());
  1181. }
  1182. }
  1183. return $targets;
  1184. }
  1185. /**
  1186. * Internal function used by get_target_categories() and add_target_subcategories()
  1187. * Can this category be moved to the given category ?
  1188. * Impossible when origin and target are the same... children won't be processed
  1189. * either. (a category can't be moved to one of its own children)
  1190. */
  1191. private function can_be_moved_to_cat ($cat)
  1192. {
  1193. return $cat->get_id() != $this->get_id();
  1194. }
  1195. /**
  1196. * Move this category to the given category.
  1197. * If this category moves from inside a course to outside,
  1198. * its course code must be changed, as well as the course code
  1199. * of all underlying categories and evaluations. All links will
  1200. * be deleted as well !
  1201. */
  1202. public function move_to_cat($cat)
  1203. {
  1204. $this->set_parent_id($cat->get_id());
  1205. if ($this->get_course_code() != $cat->get_course_code()) {
  1206. $this->set_course_code($cat->get_course_code());
  1207. $this->apply_course_code_to_children();
  1208. }
  1209. $this->save();
  1210. }
  1211. /**
  1212. * Internal function used by move_to_cat()
  1213. */
  1214. private function apply_course_code_to_children()
  1215. {
  1216. $cats = Category::load(null, null, null, $this->id, null);
  1217. $evals = Evaluation::load(null, null, null, $this->id, null);
  1218. $links = LinkFactory::load(null,null,null,null,null,$this->id,null);
  1219. foreach ($cats as $cat) {
  1220. $cat->set_course_code($this->get_course_code());
  1221. $cat->save();
  1222. $cat->apply_course_code_to_children();
  1223. }
  1224. foreach ($evals as $eval) {
  1225. $eval->set_course_code($this->get_course_code());
  1226. $eval->save();
  1227. }
  1228. foreach ($links as $link) {
  1229. $link->delete();
  1230. }
  1231. }
  1232. /**
  1233. * Generate an array of all categories the user can navigate to
  1234. */
  1235. public function get_tree()
  1236. {
  1237. $targets = array();
  1238. $level = 0;
  1239. $root = array(0, get_lang('RootCat'), $level);
  1240. $targets[] = $root;
  1241. // course or platform admin
  1242. if (api_is_allowed_to_edit()) {
  1243. $user = (api_is_platform_admin() ? null : api_get_user_id());
  1244. $cats = Category::get_root_categories_for_teacher($user);
  1245. foreach ($cats as $cat) {
  1246. $targets[] = array ($cat->get_id(), $cat->get_name(), $level+1);
  1247. $targets = Category::add_subtree($targets, $level+1, $cat->get_id(),null);
  1248. }
  1249. } else {
  1250. // student
  1251. $cats = Category::get_root_categories_for_student(api_get_user_id());
  1252. foreach ($cats as $cat) {
  1253. $targets[] = array ($cat->get_id(), $cat->get_name(), $level+1);
  1254. $targets = Category::add_subtree($targets, $level+1, $cat->get_id(), 1);
  1255. }
  1256. }
  1257. return $targets;
  1258. }
  1259. /**
  1260. * Internal function used by get_tree()
  1261. * @param integer $level
  1262. * @param null|integer $visible
  1263. */
  1264. private function add_subtree ($targets, $level, $catid, $visible)
  1265. {
  1266. $subcats = Category::load(null,null,null,$catid,$visible);
  1267. if (!empty($subcats)) {
  1268. foreach ($subcats as $cat) {
  1269. $targets[] = array ($cat->get_id(), $cat->get_name(), $level+1);
  1270. $targets = Category::add_subtree($targets, $level+1, $cat->get_id(),$visible);
  1271. }
  1272. }
  1273. return $targets;
  1274. }
  1275. /**
  1276. * Generate an array of courses that a teacher hasn't created a category for.
  1277. * @param integer $user_id
  1278. * @return array 2-dimensional array - every element contains 2 subelements (code, title)
  1279. */
  1280. public function get_not_created_course_categories ($user_id)
  1281. {
  1282. $tbl_main_courses = Database :: get_main_table(TABLE_MAIN_COURSE);
  1283. $tbl_main_course_user = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
  1284. $tbl_grade_categories = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
  1285. $sql = 'SELECT DISTINCT(code), title
  1286. FROM '.$tbl_main_courses.' cc, '.$tbl_main_course_user.' cu'
  1287. .' WHERE cc.id = cu.c_id '
  1288. .' AND cu.status = '.COURSEMANAGER;
  1289. if (!api_is_platform_admin()) {
  1290. $sql .= ' AND cu.user_id = '.$user_id;
  1291. }
  1292. $sql .= ' AND cc.code NOT IN
  1293. (
  1294. SELECT course_code FROM '.$tbl_grade_categories.'
  1295. WHERE
  1296. parent_id = 0 AND
  1297. course_code IS NOT NULL
  1298. )';
  1299. $result = Database::query($sql);
  1300. $cats=array();
  1301. while ($data=Database::fetch_array($result)) {
  1302. $cats[] = array ($data['code'], $data['title']);
  1303. }
  1304. return $cats;
  1305. }
  1306. /**
  1307. * Generate an array of all courses that a teacher is admin of.
  1308. * @param integer $user_id
  1309. * @return array 2-dimensional array - every element contains 2 subelements (code, title)
  1310. */
  1311. public function get_all_courses ($user_id)
  1312. {
  1313. $tbl_main_courses = Database :: get_main_table(TABLE_MAIN_COURSE);
  1314. $tbl_main_course_user = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
  1315. $sql = 'SELECT DISTINCT(code), title
  1316. FROM '.$tbl_main_courses.' cc, '.$tbl_main_course_user.' cu
  1317. WHERE cc.id = cu.c_id AND cu.status = '.COURSEMANAGER;
  1318. if (!api_is_platform_admin()) {
  1319. $sql .= ' AND cu.user_id = '.intval($user_id);
  1320. }
  1321. $result = Database::query($sql);
  1322. $cats = array();
  1323. while ($data = Database::fetch_array($result)) {
  1324. $cats[] = array ($data['code'], $data['title']);
  1325. }
  1326. return $cats;
  1327. }
  1328. /**
  1329. * Apply the same visibility to every subcategory, evaluation and link
  1330. */
  1331. public function apply_visibility_to_children()
  1332. {
  1333. $cats = Category::load(null, null, null, $this->id, null);
  1334. $evals = Evaluation::load(null, null, null, $this->id, null);
  1335. $links = LinkFactory::load(null,null,null,null,null,$this->id,null);
  1336. if (!empty($cats)) {
  1337. foreach ($cats as $cat) {
  1338. $cat->set_visible($this->is_visible());
  1339. $cat->save();
  1340. $cat->apply_visibility_to_children();
  1341. }
  1342. }
  1343. if (!empty($evals)) {
  1344. foreach ($evals as $eval) {
  1345. $eval->set_visible($this->is_visible());
  1346. $eval->save();
  1347. }
  1348. }
  1349. if (!empty($links)) {
  1350. foreach ($links as $link) {
  1351. $link->set_visible($this->is_visible());
  1352. $link->save();
  1353. }
  1354. }
  1355. }
  1356. /**
  1357. * Check if a category contains evaluations with a result for a given student
  1358. */
  1359. public function has_evaluations_with_results_for_student($stud_id)
  1360. {
  1361. $evals = Evaluation::get_evaluations_with_result_for_student($this->id, $stud_id);
  1362. if (count($evals) != 0) {
  1363. return true;
  1364. } else {
  1365. $cats = Category::load(
  1366. null,
  1367. null,
  1368. null,
  1369. $this->id,
  1370. api_is_allowed_to_edit() ? null : 1
  1371. );
  1372. foreach ($cats as $cat) {
  1373. if ($cat->has_evaluations_with_results_for_student($stud_id)) {
  1374. return true;
  1375. }
  1376. }
  1377. return false;
  1378. }
  1379. }
  1380. /**
  1381. * Retrieve all categories inside a course independent category
  1382. * that should be visible to a student.
  1383. * @param integer $cat_id parent category
  1384. * @param $stud_id student id
  1385. * @param $cats optional: if defined, the categories will be added to this array
  1386. */
  1387. public function get_independent_categories_with_result_for_student($cat_id, $stud_id, $cats = array())
  1388. {
  1389. $creator = api_is_allowed_to_edit() && !api_is_platform_admin() ? api_get_user_id() : null;
  1390. $crsindcats = Category::load(
  1391. null,
  1392. $creator,
  1393. '0',
  1394. $cat_id,
  1395. api_is_allowed_to_edit() ? null : 1
  1396. );
  1397. if (!empty($crsindcats)) {
  1398. foreach ($crsindcats as $crsindcat) {
  1399. if ($crsindcat->has_evaluations_with_results_for_student($stud_id)) {
  1400. $cats[] = $crsindcat;
  1401. }
  1402. }
  1403. }
  1404. return $cats;
  1405. }
  1406. /**
  1407. * Return the session id (in any case, even if it's null or 0)
  1408. * @return int Session id (can be null)
  1409. */
  1410. public function get_session_id()
  1411. {
  1412. return $this->session_id;
  1413. }
  1414. /**
  1415. * Get appropriate subcategories visible for the user (and optionally the course and session)
  1416. * @param int $stud_id student id (default: all students)
  1417. * @param string $course_code Course code (optional)
  1418. * @param int $session_id Session ID (optional)
  1419. * @param bool $order
  1420. * @return array Array of subcategories
  1421. */
  1422. public function get_subcategories($stud_id = null, $course_code = null, $session_id = null, $order = null)
  1423. {
  1424. if (!empty($session_id)) {
  1425. /*$tbl_grade_categories = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
  1426. $sql = 'SELECT id FROM '.$tbl_grade_categories. ' WHERE session_id = '.$session_id;
  1427. $result_session = Database::query($sql);
  1428. if (Database::num_rows($result_session) > 0) {
  1429. $data_session = Database::fetch_array($result_session);
  1430. $parent_id = $data_session['id'];
  1431. return Category::load(null, null, null, $parent_id, null, null, $order);
  1432. }*/
  1433. }
  1434. // 1 student
  1435. if (isset($stud_id)) {
  1436. // Special case: this is the root
  1437. if ($this->id == 0) {
  1438. return Category::get_root_categories_for_student($stud_id, $course_code, $session_id);
  1439. } else {
  1440. return Category::load(
  1441. null,
  1442. null,
  1443. $course_code,
  1444. $this->id,
  1445. api_is_allowed_to_edit() ? null : 1,
  1446. $session_id,
  1447. $order
  1448. );
  1449. }
  1450. } else {
  1451. // All students
  1452. // Course admin
  1453. if (api_is_allowed_to_edit() && !api_is_platform_admin()) {
  1454. // root
  1455. if ($this->id == 0) {
  1456. return $this->get_root_categories_for_teacher(api_get_user_id(), $course_code, $session_id, false);
  1457. // inside a course
  1458. } elseif (!empty($this->course_code)) {
  1459. return Category::load(null, null, $this->course_code, $this->id, null, $session_id, $order);
  1460. } elseif (!empty($course_code)) {
  1461. return Category::load(null, null, $course_code, $this->id, null, $session_id, $order);
  1462. // course independent
  1463. } else {
  1464. return Category::load(null, api_get_user_id(), 0, $this->id, null);
  1465. }
  1466. } elseif (api_is_platform_admin()) {
  1467. // platform admin
  1468. // we explicitly avoid listing subcats from another session
  1469. return Category::load(null, null, $course_code, $this->id, null, $session_id, $order);
  1470. }
  1471. }
  1472. return array();
  1473. }
  1474. /**
  1475. * Get appropriate evaluations visible for the user
  1476. * @param int $stud_id student id (default: all students)
  1477. * @param boolean $recursive process subcategories (default: no recursion)
  1478. * @param string $course_code
  1479. * @param int $sessionId
  1480. *
  1481. * @return array
  1482. */
  1483. public function get_evaluations(
  1484. $stud_id = null,
  1485. $recursive = false,
  1486. $course_code = '',
  1487. $sessionId = 0
  1488. ) {
  1489. $evals = array();
  1490. if (empty($course_code)) {
  1491. $course_code = api_get_course_id();
  1492. }
  1493. if (empty($sessionId)) {
  1494. $sessionId = api_get_session_id();
  1495. }
  1496. // 1 student
  1497. if (isset($stud_id) && !empty($stud_id)) {
  1498. // Special case: this is the root
  1499. if ($this->id == 0) {
  1500. $evals = Evaluation::get_evaluations_with_result_for_student(0, $stud_id);
  1501. } else {
  1502. $evals = Evaluation::load(
  1503. null,
  1504. null,
  1505. $course_code,
  1506. $this->id,
  1507. api_is_allowed_to_edit() ? null : 1
  1508. );
  1509. }
  1510. } else {
  1511. // All students
  1512. // course admin
  1513. if ((api_is_allowed_to_edit() || api_is_drh() || api_is_session_admin()) &&
  1514. !api_is_platform_admin()
  1515. ) {
  1516. // root
  1517. if ($this->id == 0) {
  1518. $evals = Evaluation::load(null, api_get_user_id(), null, $this->id, null);
  1519. } elseif (isset($this->course_code) && !empty($this->course_code)) {
  1520. // inside a course
  1521. $evals = Evaluation::load(null, null, $course_code, $this->id, null);
  1522. } else {
  1523. // course independent
  1524. $evals = Evaluation::load(null, api_get_user_id(), null, $this->id, null);
  1525. }
  1526. } else {
  1527. $evals = Evaluation::load(null, null, $course_code, $this->id, null);
  1528. }
  1529. }
  1530. if ($recursive) {
  1531. $subcats = $this->get_subcategories($stud_id, $course_code, $sessionId);
  1532. if (!empty($subcats)) {
  1533. foreach ($subcats as $subcat) {
  1534. $subevals = $subcat->get_evaluations($stud_id, true, $course_code);
  1535. $evals = array_merge($evals, $subevals);
  1536. }
  1537. }
  1538. }
  1539. return $evals;
  1540. }
  1541. /**
  1542. * Get appropriate links visible for the user
  1543. * @param int $stud_id student id (default: all students)
  1544. * @param boolean $recursive process subcategories (default: no recursion)
  1545. * @param string $course_code
  1546. * @param int $sessionId
  1547. *
  1548. * @return array
  1549. */
  1550. public function get_links(
  1551. $stud_id = null,
  1552. $recursive = false,
  1553. $course_code = '',
  1554. $sessionId = 0
  1555. ) {
  1556. $links = array();
  1557. if (empty($course_code)) {
  1558. $course_code = api_get_course_id();
  1559. }
  1560. if (empty($sessionId)) {
  1561. $sessionId = api_get_session_id();
  1562. }
  1563. // no links in root or course independent categories
  1564. if ($this->id == 0) {
  1565. } elseif (isset($stud_id)) {
  1566. // 1 student $stud_id
  1567. $links = LinkFactory::load(
  1568. null,
  1569. null,
  1570. null,
  1571. null,
  1572. empty($this->course_code) ? null : $course_code,
  1573. $this->id,
  1574. api_is_allowed_to_edit() ? null : 1
  1575. );
  1576. //} elseif (api_is_allowed_to_edit() || api_is_drh() || api_is_session_admin()) {
  1577. } else {
  1578. // All students -> only for course/platform admin
  1579. $links = LinkFactory::load(
  1580. null,
  1581. null,
  1582. null,
  1583. null,
  1584. empty($this->course_code) ? null : $this->course_code,
  1585. $this->id,
  1586. null
  1587. );
  1588. }
  1589. if ($recursive) {
  1590. $subcats = $this->get_subcategories(
  1591. $stud_id,
  1592. $course_code,
  1593. $sessionId
  1594. );
  1595. if (!empty($subcats)) {
  1596. /** @var Category $subcat */
  1597. foreach ($subcats as $subcat) {
  1598. $sublinks = $subcat->get_links(
  1599. $stud_id,
  1600. false,
  1601. $course_code,
  1602. $sessionId
  1603. );
  1604. $links = array_merge($links, $sublinks);
  1605. }
  1606. }
  1607. }
  1608. return $links;
  1609. }
  1610. /**
  1611. * Get all the categories from with the same given direct parent
  1612. * @param int $catId Category parent ID
  1613. * @return array Array of Category objects
  1614. */
  1615. public function getCategories($catId)
  1616. {
  1617. $tblGradeCategories = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
  1618. $sql = 'SELECT * FROM '.$tblGradeCategories.'
  1619. WHERE parent_id = '.intval($catId);
  1620. $result = Database::query($sql);
  1621. $allcats = Category::create_category_objects_from_sql_result($result);
  1622. return $allcats;
  1623. }
  1624. /**
  1625. * Gets the type for the current object
  1626. * @return string 'C' to represent "Category" object type
  1627. */
  1628. public function get_item_type()
  1629. {
  1630. return 'C';
  1631. }
  1632. /**
  1633. * @param array $skills
  1634. */
  1635. public function set_skills($skills)
  1636. {
  1637. $this->skills = $skills;
  1638. }
  1639. /**
  1640. * @return null
  1641. */
  1642. public function get_date()
  1643. {
  1644. return null;
  1645. }
  1646. /**
  1647. * @return string
  1648. */
  1649. public function get_icon_name()
  1650. {
  1651. return 'cat';
  1652. }
  1653. /**
  1654. * Find category by name
  1655. * @param string $name_mask search string
  1656. * @return array category objects matching the search criterium
  1657. */
  1658. public function find_category($name_mask,$allcat)
  1659. {
  1660. $foundcats = array();
  1661. foreach ($allcat as $search_cat) {
  1662. if (!(strpos(strtolower($search_cat->get_name()), strtolower($name_mask)) === false)) {
  1663. $foundcats[] = $search_cat;
  1664. }
  1665. }
  1666. return $foundcats;
  1667. }
  1668. /**
  1669. * This function, locks a category , only one who can unlock it is
  1670. * the platform administrator.
  1671. * @param int locked 1 or unlocked 0
  1672. * @return boolean|null
  1673. * */
  1674. public function lock($locked)
  1675. {
  1676. $table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
  1677. $sql = "UPDATE $table SET locked = '".intval($locked)."'
  1678. WHERE id='".intval($this->id)."'";
  1679. Database::query($sql);
  1680. }
  1681. /**
  1682. * @param $locked
  1683. */
  1684. public function lock_all_items($locked)
  1685. {
  1686. if (api_get_setting('gradebook_locking_enabled') == 'true') {
  1687. $this->lock($locked);
  1688. $evals_to_lock = $this->get_evaluations();
  1689. if (!empty($evals_to_lock)) {
  1690. foreach ($evals_to_lock as $item) {
  1691. $item->lock($locked);
  1692. }
  1693. }
  1694. $link_to_lock= $this->get_links();
  1695. if (!empty($link_to_lock)) {
  1696. foreach ($link_to_lock as $item ) {
  1697. $item->lock($locked);
  1698. }
  1699. }
  1700. $event_type = LOG_GRADEBOOK_UNLOCKED;
  1701. if ($locked == 1) {
  1702. $event_type = LOG_GRADEBOOK_LOCKED;
  1703. }
  1704. Event::addEvent($event_type, LOG_GRADEBOOK_ID, $this->id);
  1705. }
  1706. }
  1707. /**
  1708. * Generates a certificate for this user if everything matches
  1709. * @param int $category_id
  1710. * @param int $user_id
  1711. * @return bool|string
  1712. */
  1713. public static function register_user_certificate($category_id, $user_id)
  1714. {
  1715. $courseId = api_get_course_int_id();
  1716. $courseCode = api_get_course_id();
  1717. $sessionId = api_get_session_id();
  1718. // Generating the total score for a course
  1719. $cats_course = Category::load(
  1720. $category_id,
  1721. null,
  1722. null,
  1723. null,
  1724. null,
  1725. $sessionId,
  1726. false
  1727. );
  1728. /** @var Category $category */
  1729. $category = $cats_course[0];
  1730. //@todo move these in a function
  1731. $sum_categories_weight_array = array();
  1732. if (isset($cats_course) && !empty($cats_course)) {
  1733. $categories = Category::load(null, null, null, $category_id);
  1734. if (!empty($categories)) {
  1735. foreach ($categories as $subCategory) {
  1736. $sum_categories_weight_array[$subCategory->get_id()] = $subCategory->get_weight();
  1737. }
  1738. } else {
  1739. $sum_categories_weight_array[$category_id] = $cats_course[0]->get_weight();
  1740. }
  1741. }
  1742. $main_weight = $cats_course[0]->get_weight();
  1743. $cattotal = Category::load($category_id);
  1744. $scoretotal = $cattotal[0]->calc_score($user_id);
  1745. // Do not remove this the gradebook/lib/fe/gradebooktable.class.php
  1746. // file load this variable as a global
  1747. $scoredisplay = ScoreDisplay::instance();
  1748. $my_score_in_gradebook = $scoredisplay->display_score($scoretotal, SCORE_SIMPLE);
  1749. // A student always sees only the teacher's repartition
  1750. $scoretotal_display = $scoredisplay->display_score($scoretotal, SCORE_DIV_PERCENT);
  1751. if (!self::userFinishedCourse($user_id, $cats_course[0], 0, $courseCode, $sessionId, true)) {
  1752. return false;
  1753. }
  1754. $skillToolEnabled = api_get_setting('allow_skills_tool') == 'true';
  1755. $userHasSkills = false;
  1756. if ($skillToolEnabled) {
  1757. $skill = new Skill();
  1758. $skill->add_skill_to_user(
  1759. $user_id,
  1760. $category_id,
  1761. $courseId,
  1762. $sessionId
  1763. );
  1764. $objSkillRelUser = new SkillRelUser();
  1765. $userSkills = $objSkillRelUser->get_user_skills($user_id, $courseId, $sessionId);
  1766. $userHasSkills = !empty($userSkills);
  1767. if (!$category->getGenerateCertificates() && $userHasSkills) {
  1768. return [
  1769. 'badge_link' => Display::toolbarButton(
  1770. get_lang('ExportBadges'),
  1771. api_get_path(WEB_CODE_PATH) . "gradebook/get_badges.php?user=$user_id",
  1772. 'external-link'
  1773. )
  1774. ];
  1775. }
  1776. }
  1777. $my_certificate = GradebookUtils::get_certificate_by_user_id(
  1778. $cats_course[0]->get_id(),
  1779. $user_id
  1780. );
  1781. if (empty($my_certificate)) {
  1782. GradebookUtils::register_user_info_about_certificate(
  1783. $category_id,
  1784. $user_id,
  1785. $my_score_in_gradebook,
  1786. api_get_utc_datetime()
  1787. );
  1788. $my_certificate = GradebookUtils::get_certificate_by_user_id(
  1789. $cats_course[0]->get_id(),
  1790. $user_id
  1791. );
  1792. }
  1793. $html = array();
  1794. if (!empty($my_certificate)) {
  1795. $certificate_obj = new Certificate($my_certificate['id']);
  1796. $fileWasGenerated = $certificate_obj->html_file_is_generated();
  1797. if (!empty($fileWasGenerated)) {
  1798. $url = api_get_path(WEB_PATH) . 'certificates/index.php?id=' . $my_certificate['id'];
  1799. $certificates = Display::toolbarButton(get_lang('DisplayCertificate'), $url, 'eye', 'primary');
  1800. $exportToPDF = Display::url(
  1801. Display::return_icon(
  1802. 'pdf.png',
  1803. get_lang('ExportToPDF'),
  1804. array(),
  1805. ICON_SIZE_MEDIUM
  1806. ),
  1807. "$url&action=export"
  1808. );
  1809. $hideExportLink = api_get_setting('hide_certificate_export_link');
  1810. $hideExportLinkStudent = api_get_setting('hide_certificate_export_link_students');
  1811. if ($hideExportLink === 'true' || (api_is_student() && $hideExportLinkStudent === 'true') ) {
  1812. $exportToPDF = null;
  1813. }
  1814. $html = array(
  1815. 'certificate_link' => $certificates,
  1816. 'pdf_link' => $exportToPDF,
  1817. 'pdf_url' => "$url&action=export"
  1818. );
  1819. if ($skillToolEnabled && $userHasSkills) {
  1820. $html['badge_link'] = Display::toolbarButton(
  1821. get_lang('ExportBadges'),
  1822. api_get_path(WEB_CODE_PATH) . "gradebook/get_badges.php?user=$user_id",
  1823. 'external-link'
  1824. );
  1825. }
  1826. }
  1827. return $html;
  1828. }
  1829. }
  1830. /**
  1831. * @param int $catId
  1832. * @param array $userList
  1833. */
  1834. public static function generateCertificatesInUserList($catId, $userList)
  1835. {
  1836. if (!empty($userList)) {
  1837. foreach ($userList as $userInfo) {
  1838. self::register_user_certificate($catId, $userInfo['user_id']);
  1839. }
  1840. }
  1841. }
  1842. /**
  1843. * @param int $catId
  1844. * @param array $userList
  1845. */
  1846. public static function exportAllCertificates(
  1847. $catId,
  1848. $userList = array()
  1849. ) {
  1850. $orientation = api_get_configuration_value('certificate_pdf_orientation');
  1851. $params['orientation'] = 'landscape';
  1852. if (!empty($orientation)) {
  1853. $params['orientation'] = $orientation;
  1854. }
  1855. $params['left'] = 0;
  1856. $params['right'] = 0;
  1857. $params['top'] = 0;
  1858. $params['bottom'] = 0;
  1859. $page_format = $params['orientation'] == 'landscape' ? 'A4-L' : 'A4';
  1860. $pdf = new PDF($page_format, $params['orientation'], $params);
  1861. $certificate_list = GradebookUtils::get_list_users_certificates($catId, $userList);
  1862. $certificate_path_list = array();
  1863. if (!empty($certificate_list)) {
  1864. foreach ($certificate_list as $index=>$value) {
  1865. $list_certificate = GradebookUtils::get_list_gradebook_certificates_by_user_id(
  1866. $value['user_id'],
  1867. $catId
  1868. );
  1869. foreach ($list_certificate as $value_certificate) {
  1870. $certificate_obj = new Certificate($value_certificate['id']);
  1871. $certificate_obj->generate(array('hide_print_button' => true));
  1872. if ($certificate_obj->html_file_is_generated()) {
  1873. $certificate_path_list[]= $certificate_obj->html_file;
  1874. }
  1875. }
  1876. }
  1877. }
  1878. if (!empty($certificate_path_list)) {
  1879. // Print certificates (without the common header/footer/watermark
  1880. // stuff) and return as one multiple-pages PDF
  1881. $pdf->html_to_pdf(
  1882. $certificate_path_list,
  1883. get_lang('Certificates'),
  1884. null,
  1885. false,
  1886. false
  1887. );
  1888. }
  1889. }
  1890. /**
  1891. * @param int $catId
  1892. */
  1893. public static function deleteAllCertificates($catId)
  1894. {
  1895. $certificate_list = GradebookUtils::get_list_users_certificates($catId);
  1896. if (!empty($certificate_list)) {
  1897. foreach ($certificate_list as $index=>$value) {
  1898. $list_certificate = GradebookUtils::get_list_gradebook_certificates_by_user_id($value['user_id'], $catId);
  1899. foreach ($list_certificate as $value_certificate) {
  1900. $certificate_obj = new Certificate($value_certificate['id']);
  1901. $certificate_obj->delete(true);
  1902. }
  1903. }
  1904. }
  1905. }
  1906. /**
  1907. * Check whether a user has finished a course by its gradebook
  1908. * @param int $userId The user ID
  1909. * @param \Category $category Optional. The gradebook category.
  1910. * To check by the gradebook category
  1911. * @param int $categoryId Optional. The gradebook category ID.
  1912. * To check by the category ID
  1913. * @param string $courseCode Optional. The course code
  1914. * @param int $sessionId Optional. The session ID
  1915. * @param boolean $recalcutateScore Whether recalculate the score
  1916. * @return boolean
  1917. */
  1918. public static function userFinishedCourse(
  1919. $userId,
  1920. \Category $category = null,
  1921. $categoryId = 0,
  1922. $courseCode = null,
  1923. $sessionId = 0,
  1924. $recalcutateScore = false
  1925. ) {
  1926. if (is_null($category) && empty($categoryId)) {
  1927. return false;
  1928. }
  1929. $courseCode = empty($courseCode) ? api_get_course_id() : $courseCode;
  1930. $sessionId = empty($sessionId) ? api_get_session_id() : $sessionId;
  1931. if (is_null($category) && !empty($categoryId)) {
  1932. $cats_course = Category::load(
  1933. $categoryId,
  1934. null,
  1935. $courseCode,
  1936. null,
  1937. null,
  1938. $sessionId,
  1939. false
  1940. );
  1941. if (empty($cats_course)) {
  1942. return false;
  1943. }
  1944. $category = $cats_course[0];
  1945. }
  1946. $currentScore = self::getCurrentScore(
  1947. $userId,
  1948. $category->get_id(),
  1949. $courseCode,
  1950. $sessionId,
  1951. $recalcutateScore
  1952. );
  1953. $minCertificateScore = $category->get_certificate_min_score();
  1954. return !empty($minCertificateScore) && $currentScore >= $minCertificateScore;
  1955. }
  1956. /**
  1957. * Get the current score (as percentage) on a gradebook category for a user
  1958. * @param int $userId The user id
  1959. * @param int $categoryId The gradebook category
  1960. * @param int $courseCode The course code
  1961. * @param int $sessionId Optional. The session id
  1962. * @param bool $recalculate
  1963. *
  1964. * @return float The score
  1965. */
  1966. public static function getCurrentScore($userId, $categoryId, $courseCode, $sessionId = 0, $recalculate = false)
  1967. {
  1968. if ($recalculate) {
  1969. return self::calculateCurrentScore($userId, $categoryId, $courseCode, $sessionId);
  1970. }
  1971. $resultData = Database::select(
  1972. '*',
  1973. Database::get_main_table(TABLE_MAIN_GRADEBOOK_SCORE_LOG),
  1974. [
  1975. 'where' => [
  1976. 'category_id = ? AND user_id = ?' => [$categoryId, $userId],
  1977. ],
  1978. 'order' => 'registered_at DESC',
  1979. 'limit' => '1'
  1980. ],
  1981. 'first'
  1982. );
  1983. if (empty($resultData)) {
  1984. return 0;
  1985. }
  1986. return $resultData['score'];
  1987. }
  1988. /**
  1989. * Calculate the current score on a gradebook category for a user
  1990. * @param int $userId The user id
  1991. * @param int $categoryId The gradebook category
  1992. * @param int $courseCode The course code
  1993. * @param int $sessionId Optional. The session id
  1994. * @return float The score
  1995. */
  1996. private static function calculateCurrentScore($userId, $categoryId, $courseCode, $sessionId)
  1997. {
  1998. $cats_course = Category::load(
  1999. $categoryId,
  2000. null,
  2001. $courseCode,
  2002. null,
  2003. null,
  2004. $sessionId,
  2005. false
  2006. );
  2007. if (empty($cats_course)) {
  2008. return 0;
  2009. }
  2010. $category = $cats_course[0];
  2011. $courseEvaluations = $category->get_evaluations($userId, true);
  2012. $courseLinks = $category->get_links($userId, true);
  2013. $evaluationsAndLinks = array_merge($courseEvaluations, $courseLinks);
  2014. $categoryScore = 0;
  2015. for ($i = 0; $i < count($evaluationsAndLinks); $i++) {
  2016. $item = $evaluationsAndLinks[$i];
  2017. $score = $item->calc_score($userId);
  2018. $itemValue = 0;
  2019. if (!empty($score)) {
  2020. $divider = $score[1] == 0 ? 1 : $score[1];
  2021. $itemValue = $score[0] / $divider * $item->get_weight();
  2022. }
  2023. $categoryScore += $itemValue;
  2024. }
  2025. return floatval($categoryScore);
  2026. }
  2027. /**
  2028. * Register the current score for a user on a category gradebook
  2029. * @param float $score The achieved score
  2030. * @param int $userId The user id
  2031. * @param int $categoryId The gradebook category
  2032. * @return false|string The insert id
  2033. */
  2034. public static function registerCurrentScore($score, $userId, $categoryId)
  2035. {
  2036. return Database::insert(
  2037. Database::get_main_table(TABLE_MAIN_GRADEBOOK_SCORE_LOG),
  2038. [
  2039. 'category_id' => intval($categoryId),
  2040. 'user_id' => intval($userId),
  2041. 'score' => floatval($score),
  2042. 'registered_at' => api_get_utc_datetime()
  2043. ]
  2044. );
  2045. }
  2046. /**
  2047. * @return array
  2048. */
  2049. public function getStudentList()
  2050. {
  2051. return $this->studentList;
  2052. }
  2053. /**
  2054. * @param array $list
  2055. */
  2056. public function setStudentList($list)
  2057. {
  2058. $this->studentList = $list;
  2059. }
  2060. }