category.class.php 75 KB

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