assign.php 14 KB

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