2 /************************************************************************/
4 /************************************************************************/
5 /* Copyright (c) 2002-2008 by Greg Gay, Joel Kronenberg & Heidi Hazelton*/
6 /* Adaptive Technology Resource Centre / University of Toronto */
9 /* This program is free software. You can redistribute it and/or */
10 /* modify it under the terms of the GNU General Public License */
11 /* as published by the Free Software Foundation. */
12 /************************************************************************/
14 if (!defined('AT_INCLUDE_PATH')) { exit; }
17 * To resize course_icon images
18 * @param uploaded image source path
19 * @param uploaded image path to be saved as
20 * @param uploaded image's height
21 * @param uploaded image width
22 * @param save file with this height
23 * @param save file with this width
24 * @param file extension type
25 * @return true if successful, false otherwise
27 function resize_image($src, $dest, $src_h, $src_w, $dest_h, $dest_w, $type) {
28 $thumbnail_img = imagecreatetruecolor($dest_w, $dest_h);
30 $source = imagecreatefromgif($src);
31 } else if ($type == 'jpg') {
32 $source = imagecreatefromjpeg($src);
34 $source = imagecreatefrompng($src);
37 $result = imagecopyresampled($thumbnail_img, $source, 0, 0, 0, 0, $dest_w, $dest_h, $src_w, $src_h);
40 $result &= imagegif($thumbnail_img, $dest);
41 } else if ($type == 'jpg') {
42 $result &= imagejpeg($thumbnail_img, $dest, 75);
44 $result &= imagepng($thumbnail_img, $dest, 7);
49 function add_update_course($_POST, $isadmin = FALSE) {
50 require(AT_INCLUDE_PATH.'lib/filemanager.inc.php');
54 global $system_courses;
55 global $MaxCourseSize;
58 global $_config_defaults;
61 $Backup = new Backup($db);
62 $missing_fields = array();
64 if ($_POST['title'] == '') {
65 $missing_fields[] = _AT('title');
67 if (!$_POST['instructor']) {
68 $missing_fields[] = _AT('instructor');
71 if ($missing_fields) {
72 $missing_fields = implode(', ', $missing_fields);
73 $msg->addError(array('EMPTY_FIELDS', $missing_fields));
76 $_POST['access'] = $addslashes($_POST['access']);
77 $_POST['title'] = $addslashes($_POST['title']);
78 $_POST['description'] = $addslashes($_POST['description']);
79 $_POST['hide'] = $addslashes($_POST['hide']);
80 $_POST['pri_lang'] = $addslashes($_POST['pri_lang']);
81 $_POST['created_date'] = $addslashes($_POST['created_date']);
82 $_POST['copyright'] = $addslashes($_POST['copyright']);
83 $_POST['icon'] = $addslashes($_POST['icon']);
84 $_POST['banner'] = $addslashes($_POST['banner']);
85 $_POST['course_dir_name'] = $addslashes($_POST['course_dir_name']);
87 $_POST['course'] = intval($_POST['course']);
88 $_POST['notify'] = intval($_POST['notify']);
89 $_POST['hide'] = intval($_POST['hide']);
90 $_POST['instructor']= intval($_POST['instructor']);
91 $_POST['category_parent'] = intval($_POST['category_parent']);
92 $_POST['rss'] = intval($_POST['rss']);
94 // Course directory name (aka course slug)
95 if ($_POST['course_dir_name'] != ''){
96 //validate the course_dir_name, allow only alphanumeric, dash, underscore.
97 if (preg_match('/^[\w][\w\d\-\_]+$/', $_POST['course_dir_name'])==0){
98 $msg->addError('COURSE_DIR_NAME_INVALID');
101 //check if the course_dir_name is already being used
102 $sql = 'SELECT COUNT(course_id) as cnt FROM '.TABLE_PREFIX."courses WHERE course_id!=$_POST[course] AND course_dir_name='$_POST[course_dir_name]'";
103 $result = mysql_query($sql);
104 $num_of_dir = mysql_fetch_assoc($result);
105 if (intval($num_of_dir['cnt']) > 0){
106 $msg->addError('COURSE_DIR_NAME_IN_USE');
111 if ($_FILES['customicon']['name'] != ''){
112 // Use custom icon instead if it exists
113 $_POST['icon'] = $addslashes($_FILES['customicon']['name']);
115 if ($_FILES['customicon']['error'] == UPLOAD_ERR_FORM_SIZE){
116 // Check if filesize is too large for a POST
117 $msg->addError(array('FILE_MAX_SIZE', $_config['prof_pic_max_file_size'] . ' ' . _AT('bytes')));
119 if ($_POST['release_date']) {
120 $day_release = intval($_POST['day_release']);
121 $month_release = intval($_POST['month_release']);
122 $year_release = intval($_POST['year_release']);
123 $hour_release = intval($_POST['hour_release']);
124 $min_release = intval($_POST['min_release']);
126 if (!checkdate($month_release, $day_release, $year_release)) { //or date is in the past
127 $msg->addError('RELEASE_DATE_INVALID');
130 if (strlen($month_release) == 1){
131 $month_release = "0$month_release";
133 if (strlen($day_release) == 1){
134 $day_release = "0$day_release";
136 if (strlen($hour_release) == 1){
137 $hour_release = "0$hour_release";
139 if (strlen($min_release) == 1){
140 $min_release = "0$min_release";
142 $release_date = "$year_release-$month_release-$day_release $hour_release:$min_release:00";
144 $release_date = "0000-00-00 00:00:00";
147 if ($_POST['end_date']) {
148 $day_end = intval($_POST['day_end']);
149 $month_end = intval($_POST['month_end']);
150 $year_end = intval($_POST['year_end']);
151 $hour_end = intval($_POST['hour_end']);
152 $min_end = intval($_POST['min_end']);
154 if (!checkdate($month_end, $day_end, $year_end)) { //or date is in the past
155 $msg->addError('END_DATE_INVALID');
158 if (strlen($month_end) == 1){
159 $month_end = "0$month_end";
161 if (strlen($day_end) == 1){
162 $day_end = "0$day_end";
164 if (strlen($hour_end) == 1){
165 $hour_end = "0$hour_end";
167 if (strlen($min_end) == 1){
168 $min_end = "0$min_end";
170 $end_date = "$year_end-$month_end-$day_end $hour_end:$min_end:00";
172 $end_date = "0000-00-00 00:00:00";
175 $initial_content_info = explode('_', $_POST['initial_content'], 2);
179 $instructor = $_POST['instructor'];
180 $quota = intval($_POST['quota']);
181 $quota_entered = intval($_POST['quota_entered']);
182 $filesize = intval($_POST['filesize']);
183 $filesize_entered= intval($_POST['filesize_entered']);
185 //if they checked 'other', set quota=entered value, if it is empty or negative, set to default (-2)
187 if ($quota_entered=='' || empty($quota_entered) || $quota_entered<0 ) {
188 $quota = AT_COURSESIZE_DEFAULT;
190 $quota = floatval($quota_entered);
191 $quota = megabytes_to_bytes($quota);
195 //if they checked 'other', set filesize=entered value, if it is empty or negative, set to default
196 if ($filesize=='2') {
197 if ($filesize_entered=='' || empty($filesize_entered) || $filesize_entered<0 ) {
198 $filesize = AT_FILESIZE_DEFAULT;
199 $msg->addFeedback('COURSE_DEFAULT_FSIZE');
201 $filesize = floatval($filesize_entered);
202 $filesize = megabytes_to_bytes($filesize);
206 $course_quotas = "max_quota='$quota', max_file_size='$filesize',";
209 $instructor = $_SESSION['member_id'];
210 if (!$_POST['course']) {
211 $course_quotas = "max_quota=".AT_COURSESIZE_DEFAULT.", max_file_size=".AT_FILESIZE_DEFAULT.",";
212 $row = $Backup->getRow($initial_content_info[0], $initial_content_info[1]);
214 if ((count($initial_content_info) == 2)
215 && ($system_courses[$initial_content_info[1]]['member_id'] == $_SESSION['member_id'])) {
217 if ($MaxCourseSize < $row['contents']['file_manager']) {
218 $msg->addError('RESTORE_TOO_BIG');
221 $initial_content_info = intval($_POST['initial_content']);
225 unset($initial_content_info);
226 $course_quotas = "max_quota='{$system_courses[$_POST[course]][max_quota]}', max_file_size='{$system_courses[$_POST[course]][max_file_size]}',";
230 if ($msg->containsErrors()) {
235 if (!$_POST['course']) {
236 $menu_defaults = ",home_links='$_config[home_defaults]', main_links='$_config[main_defaults]', side_menu='$_config[side_defaults]'";
238 $menu_defaults = ',home_links=\''.$system_courses[$_POST['course']]['home_links'].'\', main_links=\''.$system_courses[$_POST['course']]['main_links'].'\', side_menu=\''.$system_courses[$_POST['course']]['side_menu'].'\'';
241 $sql = "REPLACE INTO ".TABLE_PREFIX."courses SET course_id=$_POST[course], member_id='$_POST[instructor]', access='$_POST[access]', title='$_POST[title]', description='$_POST[description]', course_dir_name='$_POST[course_dir_name]', cat_id='$_POST[category_parent]', content_packaging='$_POST[content_packaging]', notify=$_POST[notify], hide=$_POST[hide], $course_quotas primary_language='$_POST[pri_lang]', created_date='$_POST[created_date]', rss=$_POST[rss], copyright='$_POST[copyright]', icon='$_POST[icon]', banner='$_POST[banner]', release_date='$release_date', end_date='$end_date' $menu_defaults";
243 $result = mysql_query($sql, $db);
245 echo mysql_error($db);
249 $_SESSION['is_admin'] = 1;
250 $new_course_id = $_SESSION['course_id'] = mysql_insert_id($db);
252 write_to_log(AT_ADMIN_LOG_REPLACE, 'courses', mysql_affected_rows($db), $sql);
256 //get current instructor and unenroll from course if different from POST instructor
257 $old_instructor = $system_courses[$_POST['course']]['member_id'];
259 if ($old_instructor != $_POST['instructor']) {
260 //remove old from course enrollment
261 $sql = "DELETE FROM ".TABLE_PREFIX."course_enrollment WHERE course_id=".$_POST['course']." AND member_id=".$old_instructor;
262 $result = mysql_query($sql, $db);
263 write_to_log(AT_ADMIN_LOG_DELETE, 'course_enrollment', mysql_affected_rows($db), $sql);
267 //enroll new instructor
268 $sql = "INSERT INTO ".TABLE_PREFIX."course_enrollment VALUES ($_POST[instructor], $new_course_id, 'y', 0, '"._AT('instructor')."', 0)";
269 $result = mysql_query($sql, $db);
271 write_to_log(AT_ADMIN_LOG_REPLACE, 'course_enrollment', mysql_affected_rows($db), $sql);
274 // create the course content directory
275 $path = AT_CONTENT_DIR . $new_course_id . '/';
277 @copy(AT_CONTENT_DIR . 'index.html', AT_CONTENT_DIR . $new_course_id . '/index.html');
279 // create the course backup directory
280 $path = AT_BACKUP_DIR . $new_course_id . '/';
282 @copy(AT_CONTENT_DIR . 'index.html', AT_BACKUP_DIR . $new_course_id . '/index.html');
284 /* insert some default content: */
286 if (!$_POST['course_id'] && ($_POST['initial_content'] == '1')) {
287 $contentManager = new ContentManager($db, $new_course_id);
288 $contentManager->initContent( );
290 $cid = $contentManager->addContent($new_course_id, 0, 1,_AT('welcome_to_atutor'),
291 addslashes(_AT('this_is_content')),
292 '', '', 1, date('Y-m-d H:00:00'));
294 $announcement = _AT('default_announcement');
296 $sql = "INSERT INTO ".TABLE_PREFIX."news VALUES (NULL, $new_course_id, $instructor, NOW(), 1, '"._AT('welcome_to_atutor')."', '$announcement')";
297 $result = mysql_query($sql,$db);
300 write_to_log(AT_ADMIN_LOG_INSERT, 'news', mysql_affected_rows($db), $sql);
305 // create forum for Welcome Course
306 $sql = "INSERT INTO ".TABLE_PREFIX."forums VALUES (NULL, '"._AT('forum_general_discussion')."', '', 0, 0, NOW())";
307 $result = mysql_query($sql,$db);
310 write_to_log(AT_ADMIN_LOG_INSERT, 'forums', mysql_affected_rows($db), $sql);
313 $sql = "INSERT INTO ".TABLE_PREFIX."forums_courses VALUES (LAST_INSERT_ID(), $new_course_id)";
314 $result = mysql_query($sql,$db);
317 write_to_log(AT_ADMIN_LOG_INSERT, 'forums_courses', mysql_affected_rows($db), $sql);
321 } else if (!$_POST['course'] && (count($initial_content_info) == 2)){
323 $Backup->setCourseID($new_course_id);
324 $Backup->restore($material = TRUE, 'append', $initial_content_info[0], $initial_content_info[1]);
327 // custom icon, have to be after directory is created
328 // $_FILES['customicon'] = $_POST['customicon']; //copy to $_FILES.
329 if($_FILES['customicon']['tmp_name'] != ''){
330 $_POST['comments'] = trim($_POST['comments']);
332 $owner_id = $_SESSION['course_id'];
334 if ($_FILES['customicon']['error'] == UPLOAD_ERR_INI_SIZE) {
335 $msg->addError(array('FILE_TOO_BIG', get_human_size(megabytes_to_bytes(substr(ini_get('upload_max_filesize'), 0, -1)))));
336 } else if (!isset($_FILES['customicon']['name']) || ($_FILES['customicon']['error'] == UPLOAD_ERR_NO_FILE) || ($_FILES['customicon']['size'] == 0)) {
337 $msg->addError('FILE_NOT_SELECTED');
339 } else if ($_FILES['customicon']['error'] || !is_uploaded_file($_FILES['customicon']['tmp_name'])) {
340 $msg->addError('FILE_NOT_SAVED');
343 if (!$msg->containsErrors()) {
344 $_POST['description'] = $addslashes(trim($_POST['description']));
345 $_FILES['customicon']['name'] = addslashes($_FILES['customicon']['name']);
347 if ($_POST['comments']) {
353 $path = AT_CONTENT_DIR.$owner_id."/custom_icons/";
355 if (!is_dir($path)) {
359 // if we can upload custom course icon, it means GD is enabled, no need to check extension again.
360 $gd_info = gd_info();
361 $supported_images = array();
362 if ($gd_info['GIF Create Support']) {
363 $supported_images[] = 'gif';
365 if ($gd_info['JPG Support']) {
366 $supported_images[] = 'jpg';
368 if ($gd_info['PNG Support']) {
369 $supported_images[] = 'png';
372 // check if this is a supported file type
373 $filename = $stripslashes($_FILES['customicon']['name']);
374 $path_parts = pathinfo($filename);
375 $extension = strtolower($path_parts['extension']);
376 $image_attributes = getimagesize($_FILES['customicon']['tmp_name']);
378 if ($extension == 'jpeg') {
382 // resize the original but don't backup a copy.
383 $width = $image_attributes[0];
384 $height = $image_attributes[1];
385 $original_img = $_FILES['customicon']['tmp_name'];
386 $thumbnail_img = $path . $_FILES['customicon']['name'];
388 if ($width > $height && $width>79) {
389 $thumbnail_height = intval(79 * $height / $width);
390 $thumbnail_width = 79;
391 if (!resize_image($original_img, $thumbnail_img, $height, $width, $thumbnail_height, $thumbnail_width, $extension)){
392 $msg->addError('FILE_NOT_SAVED');
394 } else if ($width <= $height && $height > 79) {
395 $thumbnail_height= 100;
396 $thumbnail_width = intval(100 * $width / $height);
397 if (!resize_image($original_img, $thumbnail_img, $height, $width, $thumbnail_height, $thumbnail_width, $extension)){
398 $msg->addError('FILE_NOT_SAVED');
401 // no resizing, just copy the image.
402 // it's too small to resize.
403 copy($original_img, $thumbnail_img);
407 $msg->addError('FILE_NOT_SAVED');
410 //header('Location: index.php'.$owner_arg_prefix.'folder='.$parent_folder_id);
413 //----------------------------------------
415 /* delete the RSS feeds just in case: */
416 if (file_exists(AT_CONTENT_DIR . 'feeds/' . $new_course_id . '/RSS1.0.xml')) {
417 @unlink(AT_CONTENT_DIR . 'feeds/' . $_POST['course'] . '/RSS1.0.xml');
419 if (file_exists(AT_CONTENT_DIR . 'feeds/' . $new_course_id . '/RSS2.0.xml')) {
420 @unlink(AT_CONTENT_DIR . 'feeds/' . $new_course_id . '/RSS2.0.xml');
424 $_SESSION['course_id'] = -1;
427 $_SESSION['course_title'] = $stripslashes($_POST['title']);
428 return $new_course_id;