made a copy
[atutor.git] / include / lib / course.inc.php
1 <?php
2 /************************************************************************/
3 /* ATutor                                                                                                                               */
4 /************************************************************************/
5 /* Copyright (c) 2002-2008 by Greg Gay, Joel Kronenberg & Heidi Hazelton*/
6 /* Adaptive Technology Resource Centre / University of Toronto                  */
7 /* http://atutor.ca                                                                                                             */
8 /*                                                                                                                                              */
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 /************************************************************************/
13 // $Id$
14 if (!defined('AT_INCLUDE_PATH')) { exit; }
15
16 /**
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
26  */
27 function resize_image($src, $dest, $src_h, $src_w, $dest_h, $dest_w, $type) {
28         $thumbnail_img = imagecreatetruecolor($dest_w, $dest_h);
29         if ($type == 'gif') {
30                 $source = imagecreatefromgif($src);
31         } else if ($type == 'jpg') {
32                 $source = imagecreatefromjpeg($src);
33         } else {
34                 $source = imagecreatefrompng($src);
35         }
36         
37         $result = imagecopyresampled($thumbnail_img, $source, 0, 0, 0, 0, $dest_w, $dest_h, $src_w, $src_h);
38
39         if ($type == 'gif') {
40                 $result &= imagegif($thumbnail_img, $dest);
41         } else if ($type == 'jpg') {
42                 $result &= imagejpeg($thumbnail_img, $dest, 75);
43         } else {
44                 $result &= imagepng($thumbnail_img, $dest, 7);
45         }
46         return $result;
47 }
48
49 function add_update_course($_POST, $isadmin = FALSE) {
50         require(AT_INCLUDE_PATH.'lib/filemanager.inc.php');
51
52         global $addslashes;
53         global $db;
54         global $system_courses;
55         global $MaxCourseSize;
56         global $msg;
57         global $_config;
58         global $_config_defaults;
59         global $stripslashes;
60
61         $Backup = new Backup($db);
62         $missing_fields = array();
63
64         if ($_POST['title'] == '') {
65                 $missing_fields[] = _AT('title');
66         } 
67         if (!$_POST['instructor']) {
68                 $missing_fields[] = _AT('instructor');
69         }
70
71         if ($missing_fields) {
72                 $missing_fields = implode(', ', $missing_fields);
73                 $msg->addError(array('EMPTY_FIELDS', $missing_fields));
74         }
75
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']);
86
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']);
93
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');
99                 }
100
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');
107                 }               
108         }
109
110         // Custom icon
111         if ($_FILES['customicon']['name'] != ''){
112                 // Use custom icon instead if it exists
113                 $_POST['icon']    = $addslashes($_FILES['customicon']['name']);
114         } 
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')));
118         }
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']);
125
126                 if (!checkdate($month_release, $day_release, $year_release)) { //or date is in the past
127                         $msg->addError('RELEASE_DATE_INVALID');
128                 }
129
130                 if (strlen($month_release) == 1){
131                         $month_release = "0$month_release";
132                 }
133                 if (strlen($day_release) == 1){
134                         $day_release = "0$day_release";
135                 }
136                 if (strlen($hour_release) == 1){
137                         $hour_release = "0$hour_release";
138                 }
139                 if (strlen($min_release) == 1){
140                         $min_release = "0$min_release";
141                 }
142                 $release_date = "$year_release-$month_release-$day_release $hour_release:$min_release:00";
143         } else {
144                 $release_date = "0000-00-00 00:00:00";
145         }
146
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']);
153
154                 if (!checkdate($month_end, $day_end, $year_end)) { //or date is in the past
155                         $msg->addError('END_DATE_INVALID');
156                 }
157
158                 if (strlen($month_end) == 1){
159                         $month_end = "0$month_end";
160                 }
161                 if (strlen($day_end) == 1){
162                         $day_end = "0$day_end";
163                 }
164                 if (strlen($hour_end) == 1){
165                         $hour_end = "0$hour_end";
166                 }
167                 if (strlen($min_end) == 1){
168                         $min_end = "0$min_end";
169                 }
170                 $end_date = "$year_end-$month_end-$day_end $hour_end:$min_end:00";
171         } else {
172                 $end_date = "0000-00-00 00:00:00";
173         }
174
175         $initial_content_info = explode('_', $_POST['initial_content'], 2);
176         //admin
177         $course_quotas = '';
178         if ($isadmin) {
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']);
184
185                 //if they checked 'other', set quota=entered value, if it is empty or negative, set to default (-2)
186                 if ($quota == '2') {
187                         if ($quota_entered=='' || empty($quota_entered) || $quota_entered<0 ) {
188                                 $quota = AT_COURSESIZE_DEFAULT;                         
189                         } else {
190                                 $quota = floatval($quota_entered);
191                                 $quota = megabytes_to_bytes($quota);
192                         }
193                 }
194
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');
200                         } else {
201                                 $filesize = floatval($filesize_entered);
202                                 $filesize = megabytes_to_bytes($filesize);
203                         }
204                 }
205
206                 $course_quotas  =  "max_quota='$quota', max_file_size='$filesize',";
207
208         } else {
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]);
213
214                         if ((count($initial_content_info) == 2) 
215                                 && ($system_courses[$initial_content_info[1]]['member_id'] == $_SESSION['member_id'])) {
216                                 
217                                         if ($MaxCourseSize < $row['contents']['file_manager']) {
218                                                 $msg->addError('RESTORE_TOO_BIG');      
219                                         }
220                         } else {
221                                 $initial_content_info = intval($_POST['initial_content']);
222                         }
223
224                 } else {
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]}',";
227                 }
228         }
229
230         if ($msg->containsErrors()) {
231                 return FALSE;
232         }
233
234         //display defaults
235         if (!$_POST['course']) {
236                 $menu_defaults = ",home_links='$_config[home_defaults]', main_links='$_config[main_defaults]', side_menu='$_config[side_defaults]'";
237         } else {
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'].'\'';
239         }
240
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";
242
243         $result = mysql_query($sql, $db);
244         if (!$result) {
245                 echo mysql_error($db);
246                 echo 'DB Error';
247                 exit;
248         }
249         $_SESSION['is_admin'] = 1;
250         $new_course_id = $_SESSION['course_id'] = mysql_insert_id($db);
251         if ($isadmin) {
252                 write_to_log(AT_ADMIN_LOG_REPLACE, 'courses', mysql_affected_rows($db), $sql);
253         }
254
255         if ($isadmin) {
256                 //get current instructor and unenroll from course if different from POST instructor     
257                 $old_instructor = $system_courses[$_POST['course']]['member_id'];
258                 
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);
264                 } 
265         }
266
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);
270         if ($isadmin) {
271                 write_to_log(AT_ADMIN_LOG_REPLACE, 'course_enrollment', mysql_affected_rows($db), $sql);
272         }
273
274         // create the course content directory
275         $path = AT_CONTENT_DIR . $new_course_id . '/';
276         @mkdir($path, 0700);
277         @copy(AT_CONTENT_DIR . 'index.html', AT_CONTENT_DIR . $new_course_id . '/index.html');
278
279         // create the course backup directory
280         $path = AT_BACKUP_DIR . $new_course_id . '/';
281         @mkdir($path, 0700);
282         @copy(AT_CONTENT_DIR . 'index.html', AT_BACKUP_DIR . $new_course_id . '/index.html');
283
284         /* insert some default content: */
285
286         if (!$_POST['course_id'] && ($_POST['initial_content'] == '1')) {
287                 $contentManager = new ContentManager($db, $new_course_id);
288                 $contentManager->initContent( );
289
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'));
293
294                 $announcement = _AT('default_announcement');
295                 
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);
298                 
299                 if ($isadmin) {
300                         write_to_log(AT_ADMIN_LOG_INSERT, 'news', mysql_affected_rows($db), $sql);
301                 }
302
303                 /**
304                  * removed - #3098
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);
308
309                 if ($isadmin) {
310                         write_to_log(AT_ADMIN_LOG_INSERT, 'forums', mysql_affected_rows($db), $sql);
311                 }
312
313                 $sql = "INSERT INTO ".TABLE_PREFIX."forums_courses VALUES (LAST_INSERT_ID(), $new_course_id)";
314                 $result = mysql_query($sql,$db);
315
316                 if ($isadmin) {
317                         write_to_log(AT_ADMIN_LOG_INSERT, 'forums_courses', mysql_affected_rows($db), $sql);
318                 }
319                 ***/
320
321         } else if (!$_POST['course'] && (count($initial_content_info) == 2)){
322
323                 $Backup->setCourseID($new_course_id);
324                 $Backup->restore($material = TRUE, 'append', $initial_content_info[0], $initial_content_info[1]);
325         }
326  
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']);
331
332         $owner_id = $_SESSION['course_id'];
333         $owner_type = "1";
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');
338
339         } else if ($_FILES['customicon']['error'] || !is_uploaded_file($_FILES['customicon']['tmp_name'])) {
340             $msg->addError('FILE_NOT_SAVED');
341         }
342         
343         if (!$msg->containsErrors()) {
344             $_POST['description'] = $addslashes(trim($_POST['description']));
345             $_FILES['customicon']['name'] = addslashes($_FILES['customicon']['name']);
346
347             if ($_POST['comments']) {
348                 $num_comments = 1;
349             } else {
350                 $num_comments = 0;
351             }
352             
353             $path = AT_CONTENT_DIR.$owner_id."/custom_icons/";
354                 
355             if (!is_dir($path)) {
356                 @mkdir($path);
357             }
358                         
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';
364                         }
365                         if ($gd_info['JPG Support']) {
366                                 $supported_images[] = 'jpg';
367                         }
368                         if ($gd_info['PNG Support']) {
369                                 $supported_images[] = 'png';
370                         }
371
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']);
377
378                         if ($extension == 'jpeg') {
379                                 $extension = 'jpg';
380                         }
381
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'];
387
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');
393                                 }
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');
399                                 }
400                         } else {
401                                 // no resizing, just copy the image.
402                                 // it's too small to resize.
403                                 copy($original_img, $thumbnail_img);
404                         }
405
406         } else {
407             $msg->addError('FILE_NOT_SAVED');
408             
409         }
410         //header('Location: index.php'.$owner_arg_prefix.'folder='.$parent_folder_id);
411         //exit;
412     }
413     //----------------------------------------
414
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');
418         }
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');
421         }
422
423         if ($isadmin) {
424                 $_SESSION['course_id'] = -1;
425         }
426
427         $_SESSION['course_title'] = $stripslashes($_POST['title']);
428         return $new_course_id;
429 }
430
431 ?>