assign.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. use Chamilo\CoreBundle\Entity\Skill;
  4. use Chamilo\UserBundle\Entity\User;
  5. use Skill as SkillManager;
  6. /**
  7. * Page for assign skills to a user.
  8. *
  9. * @author: Jose Loguercio <jose.loguercio@beeznest.com>
  10. *
  11. * @package chamilo.badge
  12. */
  13. require_once __DIR__.'/../inc/global.inc.php';
  14. $userId = isset($_REQUEST['user']) ? (int) $_REQUEST['user'] : 0;
  15. if (empty($userId)) {
  16. api_not_allowed(true);
  17. }
  18. SkillManager::isAllowed($userId);
  19. $user = api_get_user_entity($userId);
  20. if (!$user) {
  21. api_not_allowed(true);
  22. }
  23. $entityManager = Database::getManager();
  24. $skillManager = new SkillManager();
  25. $skillRepo = $entityManager->getRepository('ChamiloCoreBundle:Skill');
  26. $skillRelSkill = $entityManager->getRepository('ChamiloCoreBundle:SkillRelSkill');
  27. $skillLevelRepo = $entityManager->getRepository('ChamiloSkillBundle:Level');
  28. $skillUserRepo = $entityManager->getRepository('ChamiloCoreBundle:SkillRelUser');
  29. $skillLevels = api_get_configuration_value('skill_levels_names');
  30. $skillsOptions = ['' => get_lang('Select')];
  31. $acquiredLevel = ['' => get_lang('None')];
  32. $formDefaultValues = [];
  33. if (empty($skillLevels)) {
  34. $skills = $skillRepo->findBy([
  35. 'status' => Skill::STATUS_ENABLED,
  36. ]);
  37. /** @var Skill $skill */
  38. foreach ($skills as $skill) {
  39. $skillsOptions[$skill->getId()] = $skill->getName();
  40. }
  41. } else {
  42. // Get only root elements
  43. $skills = $skillManager->getChildren(1);
  44. foreach ($skills as $skill) {
  45. $skillsOptions[$skill['data']['id']] = $skill['data']['name'];
  46. }
  47. }
  48. $skillIdFromGet = isset($_REQUEST['id']) ? (int) $_REQUEST['id'] : 0;
  49. $currentValue = isset($_REQUEST['current_value']) ? (int) $_REQUEST['current_value'] : 0;
  50. $currentLevel = isset($_REQUEST['current']) ? (int) str_replace('sub_skill_id_', '', $_REQUEST['current']) : 0;
  51. $subSkillList = isset($_REQUEST['sub_skill_list']) ? explode(',', $_REQUEST['sub_skill_list']) : [];
  52. $subSkillList = array_unique($subSkillList);
  53. if (!empty($subSkillList)) {
  54. // Compare asked skill with current level
  55. $correctLevel = false;
  56. if (isset($subSkillList[$currentLevel]) && $subSkillList[$currentLevel] == $currentValue) {
  57. $correctLevel = true;
  58. }
  59. // Level is wrong probably user change the level. Fix the subSkillList array
  60. if (!$correctLevel) {
  61. $newSubSkillList = [];
  62. $counter = 0;
  63. foreach ($subSkillList as $subSkillId) {
  64. if ($counter == $currentLevel) {
  65. $subSkillId = $currentValue;
  66. }
  67. $newSubSkillList[$counter] = $subSkillId;
  68. if ($counter == $currentLevel) {
  69. break;
  70. }
  71. $counter++;
  72. }
  73. $subSkillList = $newSubSkillList;
  74. }
  75. }
  76. if (!empty($currentLevel)) {
  77. $level = $currentLevel + 1;
  78. if ($level < count($subSkillList)) {
  79. $remove = count($subSkillList) - $currentLevel;
  80. $newSubSkillList = array_slice($subSkillList, 0, count($subSkillList) - $level);
  81. $subSkillList = $newSubSkillList;
  82. }
  83. }
  84. $skillId = isset($_REQUEST['id']) ? (int) $_REQUEST['id'] : key($skillsOptions);
  85. $skill = $skillRepo->find($skillId);
  86. $profile = false;
  87. if ($skill) {
  88. $profile = $skill->getProfile();
  89. }
  90. if (!empty($subSkillList)) {
  91. $skillFromLastSkill = $skillRepo->find(end($subSkillList));
  92. if ($skillFromLastSkill) {
  93. $profile = $skillFromLastSkill->getProfile();
  94. }
  95. }
  96. if (!$profile) {
  97. $skillRelSkill = new SkillRelSkill();
  98. $parents = $skillRelSkill->getSkillParents($skillId);
  99. krsort($parents);
  100. foreach ($parents as $parent) {
  101. $skillParentId = $parent['skill_id'];
  102. $profile = $skillRepo->find($skillParentId)->getProfile();
  103. if ($profile) {
  104. break;
  105. }
  106. if (!$profile && $parent['parent_id'] == 0) {
  107. $profile = $skillLevelRepo->findAll();
  108. $profile = isset($profile[0]) ? $profile[0] : false;
  109. }
  110. }
  111. }
  112. if ($profile) {
  113. $profileId = $profile->getId();
  114. $levels = $skillLevelRepo->findBy([
  115. 'profile' => $profileId,
  116. ]);
  117. $profileLevels = [];
  118. foreach ($levels as $level) {
  119. $profileLevels[$level->getPosition()][$level->getId()] = $level->getName();
  120. }
  121. ksort($profileLevels); // Sort the array by Position.
  122. foreach ($profileLevels as $profileLevel) {
  123. $profileId = key($profileLevel);
  124. $acquiredLevel[$profileId] = $profileLevel[$profileId];
  125. }
  126. }
  127. $formDefaultValues = ['skill' => $skillId];
  128. $newSubSkillList = [];
  129. $disableList = [];
  130. $currentUrl = api_get_self().'?user='.$userId.'&current='.$currentLevel;
  131. $form = new FormValidator('assign_skill', 'POST', $currentUrl);
  132. $form->addHeader(get_lang('AssignSkill'));
  133. $form->addText('user_name', get_lang('UserName'), false);
  134. $levelName = get_lang('Skill');
  135. if (!empty($skillLevels)) {
  136. if (isset($skillLevels['levels'][1])) {
  137. $levelName = get_lang($skillLevels['levels'][1]);
  138. }
  139. }
  140. $form->addSelect('skill', $levelName, $skillsOptions, ['id' => 'skill']);
  141. if (!empty($skillIdFromGet)) {
  142. if (empty($subSkillList)) {
  143. $subSkillList[] = $skillIdFromGet;
  144. }
  145. $oldSkill = $skillRepo->find($skillIdFromGet);
  146. $counter = 0;
  147. foreach ($subSkillList as $subSkillId) {
  148. $children = $skillManager->getChildren($subSkillId);
  149. if (isset($subSkillList[$counter - 1])) {
  150. $oldSkill = $skillRepo->find($subSkillList[$counter]);
  151. }
  152. $skillsOptions = [];
  153. if ($oldSkill) {
  154. $skillsOptions = [$oldSkill->getId() => ' -- '.$oldSkill->getName()];
  155. }
  156. if ($counter < count($subSkillList) - 1) {
  157. $disableList[] = 'sub_skill_id_'.($counter + 1);
  158. }
  159. foreach ($children as $child) {
  160. $skillsOptions[$child['id']] = $child['data']['name'];
  161. }
  162. $levelName = get_lang('SubSkill');
  163. if (!empty($skillLevels)) {
  164. if (isset($skillLevels['levels'][$counter + 2])) {
  165. $levelName = get_lang($skillLevels['levels'][$counter + 2]);
  166. }
  167. }
  168. $form->addSelect(
  169. 'sub_skill_id_'.($counter + 1),
  170. $levelName,
  171. $skillsOptions,
  172. [
  173. 'id' => 'sub_skill_id_'.($counter + 1),
  174. 'class' => 'sub_skill',
  175. ]
  176. );
  177. if (isset($subSkillList[$counter + 1])) {
  178. $nextSkill = $skillRepo->find($subSkillList[$counter + 1]);
  179. if ($nextSkill) {
  180. $formDefaultValues['sub_skill_id_'.($counter + 1)] = $nextSkill->getId();
  181. }
  182. }
  183. $newSubSkillList[] = $subSkillId;
  184. $counter++;
  185. }
  186. $subSkillList = $newSubSkillList;
  187. }
  188. $subSkillListToString = implode(',', $subSkillList);
  189. $currentUrl = api_get_self().'?user='.$userId.'&current='.$currentLevel.'&sub_skill_list='.$subSkillListToString;
  190. $form->addHidden('sub_skill_list', $subSkillListToString);
  191. $form->addHidden('user', $user->getId());
  192. $form->addHidden('id', $skillId);
  193. $form->addRule('skill', get_lang('ThisFieldIsRequired'), 'required');
  194. $showLevels = api_get_configuration_value('hide_skill_levels') === false;
  195. if ($showLevels) {
  196. $form->addSelect('acquired_level', get_lang('AcquiredLevel'), $acquiredLevel);
  197. //$form->addRule('acquired_level', get_lang('ThisFieldIsRequired'), 'required');
  198. }
  199. $form->addTextarea('argumentation', get_lang('Argumentation'), ['rows' => 6]);
  200. $form->addRule('argumentation', get_lang('ThisFieldIsRequired'), 'required');
  201. $form->addRule(
  202. 'argumentation',
  203. sprintf(get_lang('ThisTextShouldBeAtLeastXCharsLong'), 10),
  204. 'mintext',
  205. 10
  206. );
  207. $form->applyFilter('argumentation', 'trim');
  208. $form->addButtonSave(get_lang('Save'));
  209. $form->setDefaults($formDefaultValues);
  210. if ($form->validate()) {
  211. $values = $form->exportValues();
  212. $skillToProcess = $values['id'];
  213. if (!empty($subSkillList)) {
  214. $counter = 1;
  215. foreach ($subSkillList as $subSkill) {
  216. if (isset($values["sub_skill_id_$counter"])) {
  217. $skillToProcess = $values["sub_skill_id_$counter"];
  218. }
  219. $counter++;
  220. }
  221. }
  222. $skill = $skillRepo->find($skillToProcess);
  223. if (!$skill) {
  224. Display::addFlash(
  225. Display::return_message(get_lang('SkillNotFound'), 'error')
  226. );
  227. header('Location: '.api_get_self().'?'.$currentUrl);
  228. exit;
  229. }
  230. if ($user->hasSkill($skill)) {
  231. Display::addFlash(
  232. Display::return_message(
  233. sprintf(
  234. get_lang('TheUserXHasAlreadyAchievedTheSkillY'),
  235. UserManager::formatUserFullName($user),
  236. $skill->getName()
  237. ),
  238. 'warning'
  239. )
  240. );
  241. header('Location: '.$currentUrl);
  242. exit;
  243. }
  244. $skillUser = $skillManager->addSkillToUserBadge(
  245. $user,
  246. $skill,
  247. $values['acquired_level'],
  248. $values['argumentation'],
  249. api_get_user_id()
  250. );
  251. // Send email depending of children_auto_threshold
  252. $skillRelSkill = new SkillRelSkill();
  253. $skillModel = new \Skill();
  254. $parents = $skillModel->getDirectParents($skillToProcess);
  255. $extraFieldValue = new ExtraFieldValue('skill');
  256. foreach ($parents as $parentInfo) {
  257. $parentId = $parentInfo['skill_id'];
  258. $parentData = $skillModel->get($parentId);
  259. $data = $extraFieldValue->get_values_by_handler_and_field_variable($parentId, 'children_auto_threshold');
  260. if (!empty($data) && !empty($data['value'])) {
  261. // Search X children
  262. $requiredSkills = $data['value'];
  263. $children = $skillRelSkill->getChildren($parentId);
  264. $counter = 0;
  265. foreach ($children as $child) {
  266. if ($skillModel->userHasSkill($userId, $child['id'])) {
  267. $counter++;
  268. }
  269. }
  270. if ($counter >= $requiredSkills) {
  271. $bossList = UserManager::getStudentBossList($userId);
  272. if (!empty($bossList)) {
  273. Display::addFlash(Display::return_message(get_lang('MessageSent')));
  274. $url = api_get_path(WEB_CODE_PATH).'badge/assign.php?user='.$userId.'&id='.$parentId;
  275. $link = Display::url($url, $url);
  276. $subject = get_lang('StudentHadEnoughSkills');
  277. $message = sprintf(
  278. get_lang('StudentXHadEnoughSkillsToGetSkillXToAssignClickHereX'),
  279. UserManager::formatUserFullName($user),
  280. $parentData['name'],
  281. $link
  282. );
  283. foreach ($bossList as $boss) {
  284. MessageManager::send_message_simple(
  285. $boss['boss_id'],
  286. $subject,
  287. $message
  288. );
  289. }
  290. }
  291. break;
  292. }
  293. }
  294. }
  295. Display::addFlash(
  296. Display::return_message(
  297. sprintf(
  298. get_lang('SkillXAssignedToUserY'),
  299. $skill->getName(),
  300. UserManager::formatUserFullName($user)
  301. ),
  302. 'success'
  303. )
  304. );
  305. header('Location: '.api_get_path(WEB_PATH)."badge/{$skillUser->getId()}");
  306. exit;
  307. }
  308. $form->setDefaults(['user_name' => UserManager::formatUserFullName($user, true)]);
  309. $form->freeze(['user_name']);
  310. if (api_is_drh()) {
  311. $interbreadcrumb[] = [
  312. 'url' => api_get_path(WEB_CODE_PATH).'mySpace/index.php',
  313. "name" => get_lang('MySpace'),
  314. ];
  315. if ($user->getStatus() == COURSEMANAGER) {
  316. $interbreadcrumb[] = [
  317. "url" => api_get_path(WEB_CODE_PATH).'mySpace/teachers.php',
  318. 'name' => get_lang('Teachers'),
  319. ];
  320. } else {
  321. $interbreadcrumb[] = [
  322. "url" => api_get_path(WEB_CODE_PATH).'mySpace/student.php',
  323. 'name' => get_lang('MyStudents'),
  324. ];
  325. }
  326. $interbreadcrumb[] = [
  327. 'url' => api_get_path(WEB_CODE_PATH).'mySpace/myStudents.php?student='.$userId,
  328. 'name' => UserManager::formatUserFullName($user),
  329. ];
  330. } else {
  331. $interbreadcrumb[] = [
  332. 'url' => api_get_path(WEB_CODE_PATH).'admin/index.php',
  333. 'name' => get_lang('PlatformAdmin'),
  334. ];
  335. $interbreadcrumb[] = [
  336. 'url' => api_get_path(WEB_CODE_PATH).'admin/user_list.php',
  337. 'name' => get_lang('UserList'),
  338. ];
  339. $interbreadcrumb[] = [
  340. 'url' => api_get_path(WEB_CODE_PATH).'admin/user_information.php?user_id='.$userId,
  341. 'name' => UserManager::formatUserFullName($user),
  342. ];
  343. }
  344. $url = api_get_path(WEB_CODE_PATH).'badge/assign.php?user='.$userId;
  345. $disableSelect = '';
  346. if ($disableList) {
  347. foreach ($disableList as $name) {
  348. //$disableSelect .= "$('#".$name."').prop('disabled', true);";
  349. //$disableSelect .= "$('#".$name."').selectpicker('refresh');";
  350. }
  351. }
  352. $htmlHeadXtra[] = '<script>
  353. $(function() {
  354. $("#skill").on("change", function() {
  355. $(location).attr("href", "'.$url.'&id="+$(this).val());
  356. });
  357. $(".sub_skill").on("change", function() {
  358. $(location).attr("href", "'.$url.'&id='.$skillIdFromGet.'&current_value="+$(this).val()+"&current="+$(this).attr("id")+"&sub_skill_list='.$subSkillListToString.',"+$(this).val());
  359. });
  360. '.$disableSelect.'
  361. });
  362. </script>';
  363. $template = new Template(get_lang('AddSkill'));
  364. $template->assign('content', $form->returnForm());
  365. $template->display_one_col_template();