skill.lib.php 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. /**
  4. * This class provides methods for the notebook management.
  5. * Include/require it in your code to use its features.
  6. * @package chamilo.library
  7. */
  8. /**
  9. * Code
  10. */
  11. /**
  12. * @package chamilo.library
  13. */
  14. define ('SKILL_TYPE_REQUIREMENT', 'required');
  15. define ('SKILL_TYPE_ACQUIRED', 'acquired');
  16. define ('SKILL_TYPE_BOTH', 'both');
  17. class SkillProfile extends Model {
  18. var $columns = array('id', 'name','description');
  19. public function __construct() {
  20. $this->table = Database::get_main_table(TABLE_MAIN_SKILL_PROFILE);
  21. $this->table_rel_profile = Database::get_main_table(TABLE_MAIN_SKILL_REL_PROFILE);
  22. }
  23. public function get_profiles() {
  24. $sql = "SELECT * FROM $this->table p INNER JOIN $this->table_rel_profile sp ON(p.id = sp.profile_id) ";
  25. $result = Database::query($sql);
  26. $profiles = Database::store_result($result,'ASSOC');
  27. return $profiles;
  28. }
  29. public function save($params) {
  30. if (!empty($params)) {
  31. $profile_id = parent::save($params);
  32. if ($profile_id) {
  33. $skill_rel_profile = new SkillRelProfile();
  34. if (isset($params['skills'])) {
  35. foreach($params['skills'] as $skill_id) {
  36. $attributes = array('skill_id' => $skill_id, 'profile_id'=>$profile_id);
  37. $skill_rel_profile->save($attributes);
  38. }
  39. }
  40. return $profile_id;
  41. }
  42. }
  43. return false;
  44. }
  45. }
  46. class SkillRelProfile extends Model {
  47. var $columns = array('id', 'skill_id', 'profile_id');
  48. public function __construct() {
  49. $this->table = Database::get_main_table(TABLE_MAIN_SKILL_REL_PROFILE);
  50. }
  51. public function get_skills_by_profile($profile_id) {
  52. $skills = $this->get_all(array('where'=>array('profile_id = ? ' => $profile_id)));
  53. $return_array = array();
  54. if (!empty($skills)) {
  55. foreach($skills as $skill_data) {
  56. $return_array[] = $skill_data['skill_id'];
  57. }
  58. }
  59. return $return_array;
  60. }
  61. }
  62. class SkillRelSkill extends Model {
  63. var $columns = array('skill_id', 'parent_id','relation_type', 'level');
  64. public function __construct() {
  65. $this->table = Database::get_main_table(TABLE_MAIN_SKILL_REL_SKILL);
  66. }
  67. /**
  68. * Gets an element
  69. */
  70. public function get_skill_info($id) {
  71. if (empty($id)) { return array(); }
  72. $result = Database::select('*',$this->table, array('where'=>array('skill_id = ?'=>intval($id))), 'first');
  73. return $result;
  74. }
  75. public function get_skill_parents($skill_id, $add_child_info = true) {
  76. $skill_id = intval($skill_id);
  77. $sql = 'SELECT child.* FROM '.$this->table.' child LEFT JOIN '.$this->table.' parent
  78. ON child.parent_id = parent.skill_id
  79. WHERE child.skill_id = '.$skill_id.' ';
  80. $result = Database::query($sql);
  81. $skill = Database::store_result($result,'ASSOC');
  82. $skill = isset($skill[0]) ? $skill[0] : null;
  83. $parents = array();
  84. if (!empty($skill)) {
  85. if ($skill['parent_id'] != null) {
  86. $parents = self::get_skill_parents($skill['parent_id']);
  87. }
  88. if ($add_child_info) {
  89. $parents[] = $skill;
  90. }
  91. }
  92. return $parents;
  93. }
  94. public function get_direct_parents($skill_id) {
  95. $skill_id = intval($skill_id);
  96. $sql = 'SELECT parent_id as skill_id FROM '.$this->table.'
  97. WHERE skill_id = '.$skill_id.' ';
  98. $result = Database::query($sql);
  99. $skill = Database::store_result($result,'ASSOC');
  100. $skill = isset($skill[0]) ? $skill[0] : null;
  101. $parents = array();
  102. if (!empty($skill)) {
  103. $parents[] = $skill;
  104. }
  105. return $parents;
  106. }
  107. public function get_children($skill_id, $load_user_data = false, $user_id = false) {
  108. $skills = $this->find('all', array('where'=> array('parent_id = ? '=> $skill_id)));
  109. $skill_obj = new Skill();
  110. $skill_rel_user = new SkillRelUser();
  111. if ($load_user_data) {
  112. $passed_skills = $skill_rel_user->get_user_skills($user_id);
  113. $done_skills = array();
  114. foreach($passed_skills as $done_skill) {
  115. $done_skills[] = $done_skill['skill_id'];
  116. }
  117. }
  118. if (!empty($skills)) {
  119. foreach ($skills as &$skill) {
  120. $skill['data'] = $skill_obj->get($skill['skill_id']);
  121. if (!empty($done_skills)) {
  122. $skill['data']['passed'] = 0;
  123. if (in_array($skill['skill_id'], $done_skills)) {
  124. $skill['data']['passed'] = 1;
  125. }
  126. }
  127. }
  128. }
  129. return $skills;
  130. }
  131. function update_by_skill($params) {
  132. $result = Database::update($this->table, $params, array('skill_id = ? '=> $params['skill_id']));
  133. if ($result) {
  134. return true;
  135. }
  136. return false;
  137. }
  138. function relation_exists($skill_id, $parent_id) {
  139. $result = $this->find('all', array('where'=>array('skill_id = ? AND parent_id = ?' => array($skill_id, $parent_id))));
  140. if (!empty($result)) {
  141. return true;
  142. }
  143. return false;
  144. }
  145. }
  146. /**
  147. * @package chamilo.library
  148. */
  149. class SkillRelGradebook extends Model {
  150. var $columns = array('id', 'gradebook_id','skill_id');
  151. public function __construct() {
  152. $this->table = Database::get_main_table(TABLE_MAIN_SKILL_REL_GRADEBOOK);
  153. }
  154. public function exists_gradebook_skill($gradebook_id, $skill_id) {
  155. $result = $this->find('all', array('where'=>array('gradebook_id = ? AND skill_id = ?' => array($gradebook_id, $skill_id))));
  156. if (!empty($result)) {
  157. return true;
  158. }
  159. return false;
  160. }
  161. /**
  162. * Gets an element
  163. */
  164. public function get_skill_info($skill_id, $gradebook_id) {
  165. if (empty($skill_id)) { return array(); }
  166. $result = Database::select('*',$this->table, array('where'=>array('skill_id = ? AND gradebook_id = ? '=>array($skill_id, $gradebook_id))),'first');
  167. return $result;
  168. }
  169. public function update_gradebooks_by_skill($skill_id, $gradebook_list) {
  170. $original_gradebook_list = $this->find('all', array('where'=>array('skill_id = ?' => array($skill_id))));
  171. $gradebooks_to_remove = array();
  172. $gradebooks_to_add = array();
  173. $original_gradebook_list_ids = array();
  174. if (!empty($original_gradebook_list)) {
  175. foreach ($original_gradebook_list as $gradebook) {
  176. if (!in_array($gradebook['gradebook_id'], $gradebook_list)) {
  177. $gradebooks_to_remove[] = $gradebook['id'];
  178. }
  179. }
  180. foreach($original_gradebook_list as $gradebook_item) {
  181. $original_gradebook_list_ids[] = $gradebook_item['gradebook_id'];
  182. }
  183. }
  184. if (!empty($gradebook_list))
  185. foreach($gradebook_list as $gradebook_id) {
  186. if (!in_array($gradebook_id, $original_gradebook_list_ids)) {
  187. $gradebooks_to_add[] = $gradebook_id;
  188. }
  189. }
  190. //var_dump($gradebooks_to_add, $gradebooks_to_remove);
  191. if (!empty($gradebooks_to_remove)) {
  192. foreach($gradebooks_to_remove as $id) {
  193. $this->delete($id);
  194. }
  195. }
  196. if (!empty($gradebooks_to_add)) {
  197. foreach($gradebooks_to_add as $gradebook_id) {
  198. $attributes = array('skill_id' => $skill_id, 'gradebook_id' => $gradebook_id);
  199. $this->save($attributes);
  200. }
  201. }
  202. }
  203. function update_by_skill($params) {
  204. $skill_info = $this->exists_gradebook_skill($params['gradebook_id'], $params['skill_id']);
  205. if ($skill_info) {
  206. return;
  207. } else {
  208. $result = $this->save($params);
  209. }
  210. if ($result) {
  211. return true;
  212. }
  213. return false;
  214. }
  215. }
  216. /**
  217. * @package chamilo.library
  218. */
  219. class SkillRelUser extends Model {
  220. var $columns = array('id', 'user_id','skill_id','acquired_skill_at','assigned_by');
  221. public function __construct() {
  222. $this->table = Database::get_main_table(TABLE_MAIN_SKILL_REL_USER);
  223. //$this->table_user = Database::get_main_table(TABLE_MAIN_USER);
  224. }
  225. public function get_user_by_skills($skill_list) {
  226. $users = array();
  227. if (!empty($skill_list)) {
  228. $skill_list = array_map('intval', $skill_list);
  229. $skill_list = implode("', '", $skill_list);
  230. $sql = "SELECT user_id FROM {$this->table} WHERE skill_id IN ('$skill_list') ";
  231. $result = Database::query($sql);
  232. $users = Database::store_result($result, 'ASSOC');
  233. }
  234. return $users;
  235. }
  236. public function get_user_skills($user_id) {
  237. if (empty($user_id)) { return array(); }
  238. $result = Database::select('skill_id',$this->table, array('where'=>array('user_id = ?'=>intval($user_id))), 'all');
  239. return $result;
  240. }
  241. }
  242. class Skill extends Model {
  243. var $columns = array('id', 'name','description', 'access_url_id');
  244. var $required = array('name');
  245. public function __construct() {
  246. $this->table = Database::get_main_table(TABLE_MAIN_SKILL);
  247. $this->table_skill_rel_gradebook = Database::get_main_table(TABLE_MAIN_SKILL_REL_GRADEBOOK);
  248. $this->table_skill_rel_user = Database::get_main_table(TABLE_MAIN_SKILL_REL_USER);
  249. $this->table_course = Database::get_main_table(TABLE_MAIN_COURSE);
  250. $this->table_skill_rel_skill = Database::get_main_table(TABLE_MAIN_SKILL_REL_SKILL);
  251. $this->table_gradebook = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
  252. }
  253. function get_skill_info($id) {
  254. $skill_rel_skill = new SkillRelSkill();
  255. $skill_info = $this->get($id);
  256. if (!empty($skill_info)) {
  257. $skill_info['extra'] = $skill_rel_skill->get_skill_info($id);
  258. $skill_info['gradebooks'] = self::get_gradebooks_by_skill($id);
  259. }
  260. return $skill_info;
  261. }
  262. function get_skills_info($skill_list) {
  263. $skill_list = array_map('intval', $skill_list);
  264. $skill_list = implode("', '", $skill_list);
  265. $sql = "SELECT * FROM {$this->table} WHERE id IN ('$skill_list') ";
  266. $result = Database::query($sql);
  267. $users = Database::store_result($result, 'ASSOC');
  268. return $users;
  269. }
  270. function get_all($load_user_data = false, $user_id = false) {
  271. $sql = "SELECT id, name, description, parent_id, relation_type
  272. FROM {$this->table} s INNER JOIN {$this->table_skill_rel_skill} ss ON (s.id = ss.skill_id) ";
  273. $result = Database::query($sql);
  274. $skills = array();
  275. if (Database::num_rows($result)) {
  276. while ($row = Database::fetch_array($result, 'ASSOC')) {
  277. $skill_rel_skill = new SkillRelSkill();
  278. $a = $skill_rel_skill->get_skill_parents($row['id']);
  279. $row['level'] = count($a)-1;
  280. $row['gradebooks'] = self::get_gradebooks_by_skill($row['id']);
  281. $skills[$row['id']] = $row;
  282. }
  283. }
  284. if ($load_user_data && $user_id) {
  285. $passed_skills = $this->get_user_skills($user_id);
  286. foreach ($skills as &$skill) {
  287. $skill['done_by_user'] = 0;
  288. if (in_array($skill['id'], $passed_skills)) {
  289. $skill['done_by_user'] = 1;
  290. }
  291. }
  292. }
  293. return $skills;
  294. }
  295. function get_gradebooks_by_skill($skill_id) {
  296. $skill_id = intval($skill_id);
  297. $sql = "SELECT g.* FROM {$this->table_gradebook} g INNER JOIN {$this->table_skill_rel_gradebook} sg
  298. ON g.id = sg.gradebook_id
  299. WHERE sg.skill_id = $skill_id";
  300. $result = Database::query($sql);
  301. $result = Database::store_result($result,'ASSOC');
  302. return $result;
  303. }
  304. function get_children($skill_id) {
  305. $skill_rel_skill = new SkillRelSkill();
  306. $user_id = api_get_user_id();
  307. $skills = $skill_rel_skill->get_children($skill_id, true, $user_id);
  308. return $skills;
  309. }
  310. /**
  311. * All parents from root to n
  312. */
  313. function get_parents($skill_id) {
  314. $skill_rel_skill = new SkillRelSkill();
  315. $skills = $skill_rel_skill->get_skill_parents($skill_id, true);
  316. foreach($skills as &$skill) {
  317. $skill['data'] = self::get($skill['skill_id']);
  318. }
  319. return $skills;
  320. }
  321. /**
  322. * All direct parents
  323. */
  324. function get_direct_parents($skill_id) {
  325. $skill_rel_skill = new SkillRelSkill();
  326. $skills = $skill_rel_skill->get_direct_parents($skill_id, true);
  327. foreach($skills as &$skill) {
  328. $skill['data'] = self::get($skill['skill_id']);
  329. $skill_info2 = $skill_rel_skill->get_skill_info($skill['skill_id']);
  330. $skill['data']['parent_id'] = $skill_info2['parent_id'];
  331. }
  332. return $skills;
  333. }
  334. public function add($params) {
  335. if (!isset($params['parent_id'])) {
  336. $params['parent_id'] = 1;
  337. }
  338. $skill_rel_skill = new SkillRelSkill();
  339. $skill_rel_gradebook = new SkillRelGradebook();
  340. //Saving name, description
  341. $skill_id = $this->save($params);
  342. if ($skill_id) {
  343. //Saving skill_rel_skill (parent_id, relation_type)
  344. $attributes = array(
  345. 'skill_id' => $skill_id,
  346. 'parent_id' => $params['parent_id'],
  347. 'relation_type' => $params['relation_type'],
  348. //'level' => $params['level'],
  349. );
  350. $skill_rel_skill->save($attributes);
  351. if (!empty($params['gradebook_id'])) {
  352. foreach ($params['gradebook_id'] as $gradebook_id) {
  353. $attributes = array();
  354. $attributes['gradebook_id'] = $gradebook_id;
  355. $attributes['skill_id'] = $skill_id;
  356. $skill_rel_gradebook->save($attributes);
  357. }
  358. }
  359. }
  360. }
  361. public function edit($params) {
  362. if (!isset($params['parent_id'])) {
  363. $params['parent_id'] = 1;
  364. }
  365. $skill_rel_skill = new SkillRelSkill();
  366. $skill_rel_gradebook = new SkillRelGradebook();
  367. //Saving name, description
  368. $this->update($params);
  369. $skill_id = $params['id'];
  370. if ($skill_id) {
  371. //Saving skill_rel_skill (parent_id, relation_type)
  372. $attributes = array(
  373. 'skill_id' => $skill_id,
  374. 'parent_id' => $params['parent_id'],
  375. 'relation_type' => $params['relation_type'],
  376. //'level' => $params['level'],
  377. );
  378. $skill_rel_skill->update_by_skill($attributes);
  379. $skill_rel_gradebook->update_gradebooks_by_skill($skill_id, $params['gradebook_id']);
  380. }
  381. }
  382. /**
  383. * Return true if the user has the skill
  384. *
  385. * @param int $userId User's id
  386. * @param int $skillId Skill's id
  387. * @param int $checkInParents if true, function will search also in parents of the given skill id
  388. *
  389. * @return bool
  390. */
  391. public function user_has_skill($user_id, $skill_id) {
  392. $skills = $this->get_user_skills($user_id);
  393. foreach($skills as $my_skill_id) {
  394. if ($my_skill_id == $skill_id) {
  395. return true;
  396. }
  397. }
  398. return false;
  399. }
  400. public function add_skill_to_user($user_id, $gradebook_id) {
  401. $skill_gradebook = new SkillRelGradebook();
  402. $skill_rel_user = new SkillRelUser();
  403. $skill_gradebooks = $skill_gradebook->get_all(array('where'=>array('gradebook_id = ?' =>$gradebook_id)));
  404. if (!empty($skill_gradebooks)) {
  405. foreach ($skill_gradebooks as $skill_gradebook) {
  406. $user_has_skill = $this->user_has_skill($user_id, $skill_gradebook['skill_id']);
  407. if (!$user_has_skill) {
  408. $params = array( 'user_id' => $user_id,
  409. 'skill_id' => $skill_gradebook['skill_id'],
  410. 'acquired_skill_at' => api_get_utc_datetime(),
  411. );
  412. $skill_rel_user->save($params);
  413. }
  414. }
  415. }
  416. }
  417. /**
  418. * Get user's skills
  419. *
  420. * @param int $userId User's id
  421. */
  422. public function get_user_skills($user_id, $get_skill_data = false) {
  423. $user_id = intval($user_id);
  424. //$sql = 'SELECT skill.*, user.* FROM '.$this->table_skill_rel_user.' user INNER JOIN '.$this->table_skill.' skill
  425. $sql = 'SELECT DISTINCT s.id, s.name FROM '.$this->table_skill_rel_user.' u INNER JOIN '.$this->table.' s
  426. ON u.skill_id = s.id
  427. WHERE user_id = '.$user_id;
  428. $result = Database::query($sql);
  429. $skills = Database::store_result($result, 'ASSOC');
  430. $clean_skill = array();
  431. if (!empty($skills)) {
  432. foreach ($skills as $skill) {
  433. if ($get_skill_data) {
  434. $clean_skill[$skill['id']] = $skill;
  435. } else {
  436. $clean_skill[$skill['id']] = $skill['id'];
  437. }
  438. }
  439. }
  440. return $clean_skill;
  441. }
  442. public function get_skills_tree($user_id = null, $return_flat_array = false) {
  443. if (isset($user_id) && !empty($user_id)) {
  444. $skills = $this->get_all(true, $user_id);
  445. } else {
  446. $skills = $this->get_all();
  447. }
  448. $refs = array();
  449. $skills_tree = null;
  450. // Create references for all nodes
  451. $flat_array = array();
  452. if (!empty($skills)) {
  453. foreach($skills as &$skill) {
  454. if ($skill['parent_id'] == 0) {
  455. $skill['parent_id'] = 'root';
  456. }
  457. $skill['data'] = array('parent_id' => $skill['parent_id']); // because except main keys (id, name, children) others keys are not saved while in the space tree
  458. if ($user_id) {
  459. $skill['data']['achieved'] = $this->user_has_skill($user_id, $skill['id']);
  460. }
  461. $refs[$skill['id']] = &$skill;
  462. $flat_array[$skill['id']] = &$skill;
  463. }
  464. // Moving node to the children index of their parents
  465. foreach($skills as $skillInd => &$skill) {
  466. $refs[$skill['parent_id']]['children'][] = &$skill;
  467. $flat_array[$skillInd] = $skill;
  468. }
  469. $skills_tree = array(
  470. 'name' => get_lang('SkillRootName'),
  471. 'id' => 'root',
  472. 'children' => $refs['root']['children'],
  473. 'data' => array()
  474. );
  475. }
  476. //var_dump($flat_array);exit;
  477. if ($return_flat_array) {
  478. return $flat_array;
  479. }
  480. unset($skills);
  481. return $skills_tree;
  482. }
  483. }