add_course.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. use Chamilo\CoreBundle\Entity\CourseCategory;
  4. use Chamilo\CoreBundle\Entity\Repository\CourseCategoryRepository;
  5. /**
  6. * This script allows professors and administrative staff to create course sites.
  7. *
  8. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  9. * @author Roan Embrechts, refactoring
  10. *
  11. * @package chamilo.create_course
  12. * "Course validation" feature:
  13. *
  14. * @author Jose Manuel Abuin Mosquera <chema@cesga.es>, Centro de Supercomputacion de Galicia
  15. * "Course validation" feature, technical adaptation for Chamilo 1.8.8:
  16. * @author Ivan Tcholakov <ivantcholakov@gmail.com>
  17. */
  18. // Flag forcing the "current course" reset.
  19. $cidReset = true;
  20. require_once __DIR__.'/../inc/global.inc.php';
  21. // Check access rights.
  22. if (!api_is_allowed_to_create_course()) {
  23. api_not_allowed(true);
  24. exit;
  25. }
  26. // Section for the tabs.
  27. $this_section = SECTION_COURSES;
  28. $em = Database::getManager();
  29. /** @var CourseCategoryRepository $courseCategoriesRepo */
  30. $courseCategoriesRepo = $em->getRepository('ChamiloCoreBundle:CourseCategory');
  31. // Get all possible teachers.
  32. $accessUrlId = api_get_current_access_url_id();
  33. // "Course validation" feature. This value affects the way of a new course creation:
  34. // true - the new course is requested only and it is created after approval;
  35. // false - the new course is created immediately, after filling this form.
  36. $course_validation_feature = false;
  37. if (api_get_setting('course_validation') === 'true' &&
  38. !api_is_platform_admin()
  39. ) {
  40. $course_validation_feature = true;
  41. }
  42. $htmlHeadXtra[] = '<script>
  43. function setFocus(){
  44. $("#title").focus();
  45. }
  46. $(window).on("load", function () {
  47. setFocus();
  48. });
  49. </script>';
  50. $interbreadcrumb[] = [
  51. 'url' => api_get_path(WEB_PATH).'user_portal.php',
  52. 'name' => get_lang('MyCourses'),
  53. ];
  54. // Displaying the header.
  55. $tool_name = $course_validation_feature ? get_lang('CreateCourseRequest') : get_lang('CreateSite');
  56. $tpl = new Template($tool_name);
  57. // Build the form.
  58. $form = new FormValidator('add_course');
  59. // Form title
  60. $form->addElement('header', $tool_name);
  61. // Title
  62. $form->addElement(
  63. 'text',
  64. 'title',
  65. [
  66. get_lang('CourseName'),
  67. get_lang('Ex'),
  68. ],
  69. [
  70. 'id' => 'title',
  71. ]
  72. );
  73. $form->applyFilter('title', 'html_filter');
  74. $form->addRule('title', get_lang('ThisFieldIsRequired'), 'required');
  75. $form->addButtonAdvancedSettings('advanced_params');
  76. $form->addElement(
  77. 'html',
  78. '<div id="advanced_params_options" style="display:none">'
  79. );
  80. $countCategories = $courseCategoriesRepo->countAllInAccessUrl(
  81. $accessUrlId,
  82. api_get_configuration_value('allow_base_course_category')
  83. );
  84. if ($countCategories >= 100) {
  85. // Category code
  86. $url = api_get_path(WEB_AJAX_PATH).'course.ajax.php?a=search_category';
  87. $form->addElement(
  88. 'select_ajax',
  89. 'category_code',
  90. get_lang('CourseFaculty'),
  91. null,
  92. ['url' => $url]
  93. );
  94. } else {
  95. $categories = $courseCategoriesRepo->findAllInAccessUrl(
  96. $accessUrlId,
  97. api_get_configuration_value('allow_base_course_category')
  98. );
  99. $categoriesOptions = [null => get_lang('None')];
  100. /** @var CourseCategory $category */
  101. foreach ($categories as $category) {
  102. $categoriesOptions[$category->getCode()] = $category->__toString();
  103. }
  104. $form->addSelect(
  105. 'category_code',
  106. get_lang('CourseFaculty'),
  107. $categoriesOptions
  108. );
  109. }
  110. // Course code
  111. $form->addText(
  112. 'wanted_code',
  113. [
  114. get_lang('Code'),
  115. get_lang('OnlyLettersAndNumbers'),
  116. ],
  117. '',
  118. [
  119. 'maxlength' => CourseManager::MAX_COURSE_LENGTH_CODE,
  120. 'pattern' => '[a-zA-Z0-9]+',
  121. 'title' => get_lang('OnlyLettersAndNumbers'),
  122. ]
  123. );
  124. $form->applyFilter('wanted_code', 'html_filter');
  125. $form->addRule(
  126. 'wanted_code',
  127. get_lang('Max'),
  128. 'maxlength',
  129. CourseManager::MAX_COURSE_LENGTH_CODE
  130. );
  131. // The teacher
  132. $titular = &$form->addElement('hidden', 'tutor_name', '');
  133. if ($course_validation_feature) {
  134. // Description of the requested course.
  135. $form->addElement(
  136. 'textarea',
  137. 'description',
  138. get_lang('Description'),
  139. ['rows' => '3']
  140. );
  141. // Objectives of the requested course.
  142. $form->addElement(
  143. 'textarea',
  144. 'objetives',
  145. get_lang('Objectives'),
  146. ['rows' => '3']
  147. );
  148. // Target audience of the requested course.
  149. $form->addElement(
  150. 'textarea',
  151. 'target_audience',
  152. get_lang('TargetAudience'),
  153. ['rows' => '3']
  154. );
  155. }
  156. // Course language.
  157. $languages = api_get_languages();
  158. if (count($languages['name']) === 1) {
  159. // If there's only one language available, there's no point in asking
  160. $form->addElement('hidden', 'course_language', $languages['folder'][0]);
  161. } else {
  162. $form->addSelectLanguage(
  163. 'course_language',
  164. get_lang('Ln'),
  165. [],
  166. ['style' => 'width:150px']
  167. );
  168. }
  169. // Exemplary content checkbox.
  170. $form->addElement(
  171. 'checkbox',
  172. 'exemplary_content',
  173. null,
  174. get_lang('FillWithExemplaryContent')
  175. );
  176. if ($course_validation_feature) {
  177. // A special URL to terms and conditions that is set
  178. // in the platform settings page.
  179. $terms_and_conditions_url = trim(
  180. api_get_setting('course_validation_terms_and_conditions_url')
  181. );
  182. // If the special setting is empty,
  183. // then we may get the URL from Chamilo's module "Terms and conditions",
  184. // if it is activated.
  185. if (empty($terms_and_conditions_url)) {
  186. if (api_get_setting('allow_terms_conditions') === 'true') {
  187. $terms_and_conditions_url = api_get_path(WEB_CODE_PATH).'auth/inscription.php?legal';
  188. }
  189. }
  190. if (!empty($terms_and_conditions_url)) {
  191. // Terms and conditions to be accepted before sending a course request.
  192. $form->addElement(
  193. 'checkbox',
  194. 'legal',
  195. null,
  196. get_lang('IAcceptTermsAndConditions'),
  197. 1
  198. );
  199. $form->addRule(
  200. 'legal',
  201. get_lang('YouHaveToAcceptTermsAndConditions'),
  202. 'required'
  203. );
  204. // Link to terms and conditions.
  205. $link_terms_and_conditions = '
  206. <script>
  207. function MM_openBrWindow(theURL, winName, features) { //v2.0
  208. window.open(theURL,winName,features);
  209. }
  210. </script>
  211. ';
  212. $link_terms_and_conditions .= Display::url(
  213. get_lang('ReadTermsAndConditions'),
  214. '#',
  215. ['onclick' => "javascript:MM_openBrWindow('$terms_and_conditions_url', 'Conditions', 'scrollbars=yes, width=800');"]
  216. );
  217. $form->addElement('label', null, $link_terms_and_conditions);
  218. }
  219. }
  220. $obj = new GradeModel();
  221. $obj->fill_grade_model_select_in_form($form);
  222. if (api_get_setting('teacher_can_select_course_template') === 'true') {
  223. $form->addElement(
  224. 'select_ajax',
  225. 'course_template',
  226. [
  227. get_lang('CourseTemplate'),
  228. get_lang('PickACourseAsATemplateForThisNewCourse'),
  229. ],
  230. null,
  231. ['url' => api_get_path(WEB_AJAX_PATH).'course.ajax.php?a=search_course']
  232. );
  233. }
  234. $form->addElement('html', '</div>');
  235. // Submit button.
  236. $form->addButtonCreate($course_validation_feature ? get_lang('CreateThisCourseRequest') : get_lang('CreateCourseArea'));
  237. // The progress bar of this form.
  238. $form->addProgress();
  239. // Set default values.
  240. if (isset($_user['language']) && $_user['language'] != '') {
  241. $values['course_language'] = $_user['language'];
  242. } else {
  243. $values['course_language'] = api_get_setting('platformLanguage');
  244. }
  245. $form->setDefaults($values);
  246. $message = null;
  247. $content = null;
  248. // Validate the form.
  249. if ($form->validate()) {
  250. $course_values = $form->exportValues();
  251. $wanted_code = $course_values['wanted_code'];
  252. $category_code = isset($course_values['category_code']) ? $course_values['category_code'] : '';
  253. $title = $course_values['title'];
  254. $course_language = $course_values['course_language'];
  255. $exemplary_content = !empty($course_values['exemplary_content']);
  256. if ($course_validation_feature) {
  257. $description = $course_values['description'];
  258. $objetives = $course_values['objetives'];
  259. $target_audience = $course_values['target_audience'];
  260. }
  261. if ($wanted_code == '') {
  262. $wanted_code = CourseManager::generate_course_code(
  263. api_substr($title, 0, CourseManager::MAX_COURSE_LENGTH_CODE)
  264. );
  265. }
  266. // Check whether the requested course code has already been occupied.
  267. if (!$course_validation_feature) {
  268. $course_code_ok = !CourseManager::course_code_exists($wanted_code);
  269. } else {
  270. $course_code_ok = !CourseRequestManager::course_code_exists($wanted_code);
  271. }
  272. if ($course_code_ok) {
  273. if (!$course_validation_feature) {
  274. $params = [];
  275. $params['title'] = $title;
  276. $params['exemplary_content'] = $exemplary_content;
  277. $params['wanted_code'] = $wanted_code;
  278. $params['course_category'] = $category_code;
  279. $params['course_language'] = $course_language;
  280. $params['gradebook_model_id'] = isset($course_values['gradebook_model_id']) ? $course_values['gradebook_model_id'] : null;
  281. $params['course_template'] = isset($course_values['course_template']) ? $course_values['course_template'] : '';
  282. include_once api_get_path(SYS_CODE_PATH).'lang/english/trad4all.inc.php';
  283. $file_to_include = api_get_path(SYS_CODE_PATH).'lang/'.$course_language.'/trad4all.inc.php';
  284. if (file_exists($file_to_include)) {
  285. include $file_to_include;
  286. }
  287. $course_info = CourseManager::create_course($params);
  288. if (!empty($course_info)) {
  289. /*
  290. $directory = $course_info['directory'];
  291. $title = $course_info['title'];
  292. // Preparing a confirmation message.
  293. $link = api_get_path(WEB_COURSE_PATH).$directory.'/';
  294. $tpl->assign('course_url', $link);
  295. $tpl->assign('course_title', Display::url($title, $link));
  296. $tpl->assign('course_id', $course_info['code']);
  297. $add_course_tpl = $tpl->get_template('create_course/add_course.tpl');
  298. $message = $tpl->fetch($add_course_tpl);*/
  299. $splash = api_get_setting('course_creation_splash_screen');
  300. if ($splash === 'true') {
  301. $url = api_get_path(WEB_CODE_PATH);
  302. $url .= 'course_info/start.php?'.api_get_cidreq_params($course_info['code']);
  303. $url .= '&first=1';
  304. header('Location: '.$url);
  305. exit;
  306. } else {
  307. $url = api_get_path(WEB_COURSE_PATH).$course_info['directory'].'/';
  308. header('Location: '.$url);
  309. exit;
  310. }
  311. } else {
  312. $message = Display::return_message(
  313. get_lang('CourseCreationFailed'),
  314. 'error',
  315. false
  316. );
  317. // Display the form.
  318. $content = $form->returnForm();
  319. }
  320. } else {
  321. // Create a request for a new course.
  322. $request_id = CourseRequestManager::create_course_request(
  323. $wanted_code,
  324. $title,
  325. $description,
  326. $category_code,
  327. $course_language,
  328. $objetives,
  329. $target_audience,
  330. api_get_user_id(),
  331. $exemplary_content
  332. );
  333. if ($request_id) {
  334. $course_request_info = CourseRequestManager::get_course_request_info($request_id);
  335. $message = (is_array($course_request_info) ? '<strong>'.$course_request_info['code'].'</strong> : ' : '').get_lang('CourseRequestCreated');
  336. $message = Display::return_message(
  337. $message,
  338. 'confirmation',
  339. false
  340. );
  341. $message .= Display::tag(
  342. 'div',
  343. Display::url(
  344. get_lang('Enter'),
  345. api_get_path(WEB_PATH).'user_portal.php',
  346. ['class' => 'btn btn-default']
  347. ),
  348. ['style' => 'float: left; margin:0px; padding: 0px;']
  349. );
  350. } else {
  351. $message = Display::return_message(
  352. get_lang('CourseRequestCreationFailed'),
  353. 'error',
  354. false
  355. );
  356. // Display the form.
  357. $content = $form->returnForm();
  358. }
  359. }
  360. } else {
  361. $message = Display::return_message(
  362. get_lang('CourseCodeAlreadyExists'),
  363. 'error',
  364. false
  365. );
  366. // Display the form.
  367. $content = $form->returnForm();
  368. }
  369. } else {
  370. if (!$course_validation_feature) {
  371. $message = Display::return_message(get_lang('Explanation'));
  372. }
  373. // Display the form.
  374. $content = $form->returnForm();
  375. }
  376. $tpl->assign('message', $message);
  377. $tpl->assign('content', $content);
  378. $template = $tpl->get_template('layout/layout_1_col.tpl');
  379. $tpl->display($template);