skill.lib.php 20 KB

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