diff --git a/main/work/work.lib.php b/main/work/work.lib.php index 4f1bd62cc1..3b09594224 100644 --- a/main/work/work.lib.php +++ b/main/work/work.lib.php @@ -22,17 +22,23 @@ * @author * @version $Id$ */ - -function display_action_links($always_show_tool_options, $always_show_upload_form) +/** + * Displays action links (for admins, authorized groups members and authorized students) + * @param string Current dir + * @param integer Whether to show tool options + * @param integer Whether to show upload form option + * @return void + */ +function display_action_links($cur_dir_path, $always_show_tool_options, $always_show_upload_form) { $display_output = ""; if (! $always_show_upload_form ) { - $display_output .= "".Display::return_icon('submit_file.gif')." ". get_lang("UploadADocument") . " "; + $display_output .= "".Display::return_icon('submit_file.gif')." ". get_lang("UploadADocument") . " "; } if (! $always_show_tool_options && api_is_allowed_to_edit() ) { - $display_output .= "".Display::return_icon('acces_tool.gif').' ' . get_lang("EditToolOptions") . " "; + $display_output .= "".Display::return_icon('acces_tool.gif').' ' . get_lang("EditToolOptions") . " "; } if ($display_output != "") @@ -66,7 +72,7 @@ function display_tool_options($uploadvisibledisabled, $origin) "\n", "", get_lang('AllFiles')." : ", - "", "\"".get_lang('Delete')."\"", "", @@ -81,13 +87,13 @@ function display_tool_options($uploadvisibledisabled, $origin) if ($columnStatus['Default'] == 1) { - echo "", + echo "", "\"".get_lang('Invisible')."\"", "\n"; } else { - echo "", + echo "", "\"".get_lang('Visible')."\"", "\n"; } @@ -97,9 +103,31 @@ function display_tool_options($uploadvisibledisabled, $origin) display_default_visibility_form($uploadvisibledisabled, $origin); - echo ""; - echo ""; - echo ""; + echo ''; + echo ''; + /* + ============================================================================== + Display directories list + ============================================================================== + */ + //$folders = DocumentManager::get_all_document_folders($_course,$to_group_id,$is_allowed_to_edit || $group_member_with_upload_rights); + if($cur_dir_path=='/'){$my_cur_dir_path='';}else{$my_cur_dir_path=$cur_dir_path;} + $folders = get_subdirs_list($base_work_dir,1); + echo '
'; + echo(build_directory_selector($folders,$cur_dir_path,'')); + echo '
'; + echo ''; + if ($cur_dir_path!= '/' && $cur_dir_path!=$group_properties['directory']) + { + echo ''. + ''. + get_lang("Up").' '."\n"; +} + echo '' . + ''. + ''.get_lang("CreateDir").' '."\n"; + + echo ""; } /** @@ -135,7 +163,7 @@ function display_default_visibility_form($uploadvisibledisabled, $origin) * @param $dateFormatLong - date format * @param $origin - typically empty or 'learnpath' */ -function display_student_publications_list($currentCourseRepositoryWeb, $link_target_parameter, $dateFormatLong, $origin) +function display_student_publications_list($work_dir,$sub_course_dir,$currentCourseRepositoryWeb, $link_target_parameter, $dateFormatLong, $origin) { //init $work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION); @@ -162,17 +190,32 @@ function display_student_publications_list($currentCourseRepositoryWeb, $link_ta } $sort_params = implode('&',$sort_params); + if(substr($sub_course_dir,-1,1)!='/' && !empty($sub_course_dir)){$sub_course_dir = $sub_course_dir.'/';} + if($sub_course_dir == '/'){$sub_course_dir='';} + //Get list from database - if (!empty($_SESSION['toolgroup'])){ - $group_query = " WHERE post_group_id = '".$_SESSION['toolgroup']."' "; // set to select only messages posted by the user's group + if($is_allowed_to_edit) + { + $sql_get_publications_list = "SELECT * " . + "FROM ".$work_table." " . + "WHERE url LIKE '$sub_course_dir%' " . + "AND url NOT LIKE '$sub_course_dir%/%' " . + "ORDER BY id"; } - else { - $group_query = ''; + else + { + if (!empty($_SESSION['toolgroup'])) + { + $group_query = " WHERE post_group_id = '".$_SESSION['toolgroup']."' "; // set to select only messages posted by the user's group + } + else { + $group_query = ''; } - $sql_get_publications_list = "SELECT * " . + $sql_get_publications_list = "SELECT * " . "FROM ".$work_table." " . $group_query. "ORDER BY id"; + } //echo $sql_get_publications_list; $sql_result = api_sql_query($sql_get_publications_list,__FILE__,__LINE__); @@ -180,11 +223,43 @@ function display_student_publications_list($currentCourseRepositoryWeb, $link_ta $table_header[] = array(get_lang('Description'),true); $table_header[] = array(get_lang('Authors'),true); $table_header[] = array(get_lang('Date'),true); + //if( $is_allowed_to_edit) + //{ + $table_header[] = array(get_lang('Modify'),true); + //} + $table_data = array(); + + $dirs_list = get_subdirs_list($work_dir); + + $my_sub_dir = str_replace('work/','',$sub_course_dir); + foreach($dirs_list as $dir) + { + $mydir = $my_sub_dir.$dir; + $action = ''; + //display info depending on the permissions if( $is_allowed_to_edit) { - $table_header[] = array(get_lang('Modify'),true); + $row = array(); + $class = ''; + $url = implode("/", array_map("rawurlencode", explode("/", $work->url))); + $row[] = 'dir'.$dir.''; + $row[] = ''; + $row[] = ''; + $row[] = ''; + if( $is_allowed_to_edit) + { + //$action .= ''.get_lang('Modify').''; + $action .= ''.get_lang('DirDelete').''; + $row[] = $action; + }else{ + $row[] = ""; + } + $table_data[] = $row; + } } - $table_data = array(); while( $work = mysql_fetch_object($sql_result)) { //Get the author ID for that document from the item_property table @@ -214,13 +289,17 @@ function display_student_publications_list($currentCourseRepositoryWeb, $link_ta $row[] = $work->sent_date; if( $is_allowed_to_edit) { + $action = ''; + $action .= ''.get_lang('Modify').''; + $action .= ''.get_lang('WorkDelete').''; + $action .= ''; if($work->accepted == '1') { - $action = ''.get_lang('Invisible').''; + $action .= ''.get_lang('Invisible').''; } else { - $action = ''.get_lang('Visible').''; + $action .= ''.get_lang('Visible').''; } $action .= ''.get_lang('Modify').''; $action .= ''.get_lang('WorkDelete').''; @@ -228,8 +307,8 @@ function display_student_publications_list($currentCourseRepositoryWeb, $link_ta $row[] = $action; }elseif($is_author){ $action = ''; - $action .= ''.get_lang('Modify').''; - $action .= ''.get_lang('WorkDelete').''; + $action .= ''.get_lang('Modify').''; + $action .= ''.get_lang('WorkDelete').''; $row[] = $action; }else{ @@ -243,3 +322,244 @@ function display_student_publications_list($currentCourseRepositoryWeb, $link_ta Display::display_sortable_table($table_header,$table_data); } } +/** + * Returns a list of subdirectories found in the given directory. + * + * The list return starts from the given base directory. + * If you require the subdirs of /var/www/ (or /var/www), you will get 'abc/', 'def/', but not '/var/www/abc/'... + * @param string Base dir + * @param integer 0 if we only want dirs from this level, 1 if we want to recurse into subdirs + * @return strings_array The list of subdirs in 'abc/' form, -1 on error, and 0 if none found + * @todo Add a session check to see if subdirs_list doesn't exist yet (cached copy) + */ +function get_subdirs_list($basedir='',$recurse=0){ + //echo "Looking for subdirs of $basedir"; + if(empty($basedir) or !is_dir($basedir)){return -1;} + if(substr($basedir,-1,1)!='/'){$basedir = $basedir.'/';} + $dirs_list = array(); + $dh = opendir($basedir); + while($entry = readdir($dh)){ + if(is_dir($basedir.$entry) && $entry!='..' && $entry!='.'){ + $dirs_list[] = $entry; + if($recurse==1){ + foreach(get_subdirs_list($basedir.$entry) as $subdir){ + $dirs_list[] = $entry.'/'.$subdir; + } + } + } + } + closedir($dh); + return $dirs_list; +} +/** + * Builds the form thats enables the user to + * select a directory to browse/upload in + * This function has been copied from the document/document.inc.php library + * + * @param array $folders + * @param string $curdirpath + * @param string $group_dir + * @return string html form + */ +function build_directory_selector($folders,$curdirpath,$group_dir='') +{ + $form = '
'."\n"; + $form .= get_lang('CurrentDirectory').' '."\n"; + $form .= ''."\n"; + $form .= '
'; + + return $form; +} +/** + * Builds the form thats enables the user to + * move a document from one directory to another + * This function has been copied from the document/document.inc.php library + * + * @param array $folders + * @param string $curdirpath + * @param string $move_file + * @return string html form + */ +function build_move_to_selector($folders,$curdirpath,$move_file,$group_dir='') +{ + $form = '
'."\n"; + $form .= ''."\n"; + $form .= get_lang('MoveTo').' '."\n"; + $form .= ''."\n"; + $form .= '
'; + + return $form; +} +/** + * Checks if the first given directory exists as a subdir of the second given directory + * @param string Subdir + * @param string Base dir + * @return integer -1 on error, 0 if not subdir, 1 if subdir + */ +function is_subdir_of($subdir,$basedir){ + if(empty($subdir) or empty($basedir)){return -1;} + if(substr($basedir,-1,1)!='/'){$basedir=$basedir.'/';} + if(substr($subdir,0,1)=='/'){$subdir = substr($subdir,1);} + if(is_dir($basedir.$subdir)){ + return 1; + }else{ + return 0; + } +} +/** + * creates a new directory trying to find a directory name + * that doesn't already exist + * (we could use unique_name() here...) + * + * @author Hugues Peeters + * @author Bert Vanderkimpen + * @author Yannick Warnier Adaptation for work tool + * @param string Base work dir (.../work) + * @param string $desiredDirName complete path of the desired name + * @return string actual directory name if it succeeds, + * boolean false otherwise + */ + +function create_unexisting_work_directory($base_work_dir,$desired_dir_name) +{ + $nb = ''; + $base_work_dir = (substr($base_work_dir,-1,1)=='/'?$base_work_dir:$base_work_dir.'/'); + while ( file_exists($base_work_dir.$desired_dir_name.$nb) ) + { + $nb += 1; + } + //echo "creating ".$base_work_dir.$desired_dir_name.$nb."#..."; + if ( mkdir($base_work_dir.$desired_dir_name.$nb, 0777)) + { + return $desired_dir_name.$nb; + } + else + { + return false; + } +} +/** + * Delete a work-tool directory + * @param string Base "work" directory for this course as /var/www/dokeos/courses/ABCD/work/ + * @param string The directory name as the bit after "work/", without trailing slash + * @return integer -1 on error + */ +function del_dir($base_work_dir,$dir){ + if(empty($dir) or $dir=='/'){return -1;}//not authorized + //escape hacks + $dir = str_replace('../','',$dir); + $dir = str_replace('..','',$dir); + $dir = str_replace('./','',$dir); + $dir = str_replace('.','',$dir); + if(!is_dir($base_work_dir.$dir)) {return -1;} + $table = Database::get_course_table(STUDENT_PUBLICATION_TABLE); + $sql = "DELETE FROM $table WHERE url LIKE 'work/".$dir."/%'"; + $res = api_sql_query($sql,__FILE__,__LINE__); + require_once(api_get_library_path().'/fileManage.lib.php'); + my_delete($base_work_dir.$dir); +} +/** + * Get the path of a document in the student_publication table (path relative to the course directory) + * @param integer Element ID + * @return string Path (or -1 on error) + */ +function get_work_path($id){ + $table = Database::get_course_table(STUDENT_PUBLICATION_TABLE); + $sql = "SELECT * FROM $table WHERE id=$id"; + $res = api_sql_query($sql); + if(Database::num_rows($res)!=1){ + return -1; + }else{ + $row = Database::fetch_array($res); + return $row['url']; + } +} +/** + * Update the url of a work in the student_publication table + * @param integer ID of the work to update + * @param string Destination directory where the work has been moved (must end with a '/') + * @return -1 on error, sql query result on success + */ +function update_work_url($id,$new_path){ + if(empty($id)) return -1; + $table = Database::get_course_table(STUDENT_PUBLICATION_TABLE); + $sql = "SELECT * FROM $table WHERE id=$id"; + $res = api_sql_query($sql); + if(Database::num_rows($res)!=1){ + return -1; + }else{ + $row = Database::fetch_array($res); + $filename = basename($row['url']); + $new_url = $new_path.$filename; + $sql2 = "UPDATE $table SET url = '$new_url' WHERE id=$id"; + $res2 = api_sql_query($sql2); + return $res2; + } +} +?> \ No newline at end of file diff --git a/main/work/work.php b/main/work/work.php index e542fa4648..e2061c3f5b 100644 --- a/main/work/work.php +++ b/main/work/work.php @@ -22,7 +22,7 @@ * @author Thomas, Hugues, Christophe - original version * @author Patrick Cool , Ghent University - ability for course admins to specify wether uploaded documents are visible or invisible by default. * @author Roan Embrechts, code refactoring and virtual course support -* @version $Id: work.php 10418 2006-12-07 15:48:25Z pcool $ +* @version $Id: work.php 10568 2006-12-29 13:51:42Z fvauthier $ * * @todo refactor more code into functions, use quickforms, coding standards, ... */ @@ -79,7 +79,8 @@ */ // name of the language file that needs to be included -$language_file = "work"; +$language_file[] = "work"; +$language_file[] = "document"; // Section (for the tabs) $this_section=SECTION_COURSES; @@ -142,6 +143,38 @@ $title = $_REQUEST['title']; $uploadvisibledisabled = $_REQUEST['uploadvisibledisabled']; $id = (int) $_REQUEST['id']; +//directories management +$sys_course_path = api_get_path(SYS_COURSE_PATH); +$course_dir = $sys_course_path.$_course['path']; +$base_work_dir = $course_dir.'/work'; +$http_www = api_get_path('WEB_COURSE_PATH').$_course['path'].'/work'; + +if(isset($_GET['curdirpath']) && $_GET['curdirpath']!='') +{ + $cur_dir_path = preg_replace('#/\.\./#','/',$_GET['curdirpath']); //escape '..' hack attempts +} +elseif (isset($_POST['curdirpath']) && $_POST['curdirpath']!='') +{ + $cur_dir_path = preg_replace('#/\.\./#','/',$_POST['curdirpath']); //escape '..' hack attempts +} +else +{ + $cur_dir_path = '/'; +} +if (!is_subdir_of($cur_dir_path,$base_work_dir) or ($cur_dir_path == '.')) +{ + $cur_dir_path='/'; +} +$cur_dir_path_url = urlencode($cur_dir_path); + + +//prepare a form of path that can easily be added at the end of any url ending with "work/" +$my_cur_dir_path = $cur_dir_path; +if($my_cur_dir_path == '/'){ + $my_cur_dir_path = ''; +}elseif(substr($my_cur_dir_path,-1,1)!='/'){ + $my_cur_dir_path = $my_cur_dir_path.'/'; +} /* ----------------------------------------------------------- Configuration settings @@ -290,10 +323,10 @@ if ($is_allowed_to_edit) { // check the url really points to a file in the work area // (some work links can come from groups area...) - - if (substr (dirname($thisUrl['url']), -4) == "work") + //if (substr (dirname($thisUrl['url']), -4) == "work") + if(strstr($thisUrl['url'],"work/$my_cur_dir_path")!==false) { - @unlink($currentCourseRepositorySys."work/".$thisWork); + @unlink($currentCourseRepositorySys.$thisUrl['url']); } } } @@ -305,7 +338,7 @@ if ($is_allowed_to_edit) if ($edit) { - $sql = "SELECT * FROM ".$work_table." WHERE id='".$edit."'"; + $sql = "SELECT * FROM ".$work_table." WHERE id='".mysql_real_escape_string($edit)."'"; $result = api_sql_query($sql,__FILE__,__LINE__); if ($result) @@ -379,7 +412,152 @@ if ($is_allowed_to_edit) api_sql_query($sql,__FILE__,__LINE__); } } + /*-------------------- + * Create dir command + ---------------------*/ + if(!empty($_REQUEST['create_dir']) && !empty($_REQUEST['new_dir'])){ + //create the directory + //needed for directory creation + include_once(api_get_path(LIBRARY_PATH) . "fileUpload.lib.php"); + $added_slash = (substr($cur_dir_path,-1,1)=='/')?'':'/'; + $dir_name = $cur_dir_path.$added_slash.replace_dangerous_char($_POST['new_dir']); + $created_dir = create_unexisting_work_directory($base_work_dir,$dir_name); + if($created_dir) + { + //Display::display_normal_message("".$created_dir." was created!"); + Display::display_normal_message(''.get_lang('DirCr').''); + //uncomment if you want to enter the created dir + //$curdirpath = $created_dir; + //$curdirpathurl = urlencode($curdirpath); + } + else + { + Display::display_error_message(get_lang('CannotCreateDir')); + } + } + /* ------------------- + * Delete dir command + --------------------*/ + if(!empty($_REQUEST['delete_dir'])){ + //TODO implement + del_dir($base_work_dir.'/',$_REQUEST['delete_dir']); + Display::display_normal_message($_REQUEST['delete_dir'].' '.get_lang('DirDeleted')); + } + /* ---------------------- + * Move file form request + ----------------------- */ + if(!empty($_REQUEST['move'])){ + $folders = get_subdirs_list($base_work_dir,1); + Display::display_normal_message(build_move_to_selector($folders,$cur_dir_path,$_REQUEST['move'])); + } + /* ------------------ + * Move file command + ------------------- */ + if (isset($_POST['move_to']) && isset($_POST['move_file'])) + { + include_once(api_get_path(LIBRARY_PATH) . "/fileManage.lib.php"); + $move_to = $_POST['move_to']; + if($move_to == '/' or empty($move_to)) + { + $move_to = ''; + }elseif(substr($move_to,-1,1)!='/') + { + $move_to = $move_to.'/'; + } + //security fix: make sure they can't move files that are not in the document table + if($path = get_work_path($_POST['move_file'])) + { + //echo "got path $path"; + //Display::display_normal_message('We want to move '.$_POST['move_file'].' to '.$_POST['move_to']); + if ( move($course_dir.'/'.$path,$base_work_dir.'/'.$move_to) ) + { + //update db + update_work_url($_POST['move_file'],'work/'.$move_to); + //set the current path + $cur_dir_path = $move_to; + $cur_dir_path_url = urlencode($move_to); + Display::display_normal_message(get_lang('DirMv')); +} + else + { + Display::display_error_message(get_lang('Impossible')); + } + } + else + { + Display::display_error_message(get_lang('Impossible')); + } + } +} +/* +----------------------------------------------------------- + COMMANDS SECTION (reserved for others - check they're authors each time) +----------------------------------------------------------- +*/ +else{ + $iprop_table = Database::get_course_table(ITEM_PROPERTY_TABLE); + $user_id = api_get_user_id(); + /*------------------------------------------- + DELETE WORK COMMAND + -----------------------------------------*/ + if ($delete) + { + if ($delete == "all"){/*not authorized to this user */} + else + { + //Get the author ID for that document from the item_property table + $author_sql = "SELECT * FROM $iprop_table WHERE tool = 'work' AND insert_user_id='$user_id' AND ref=".mysql_real_escape_string($delete); + $author_qry = api_sql_query($author_sql,__FILE__,__LINE__); + if(Database::num_rows($author_qry)==1) + { + //we found the current user is the author + $queryString1 = "SELECT url FROM ".$work_table." WHERE id = '$delete'"; + $queryString2 = "DELETE FROM ".$work_table." WHERE id='$delete'"; + $result1 = api_sql_query($queryString1,__FILE__,__LINE__); + $result2 = api_sql_query($queryString2,__FILE__,__LINE__); + if ($result1) + { + item_property_update($_course,'work',$delete,get_lang('DocumentDeleted'),$user_id); + while ($thisUrl = mysql_fetch_array($result1)) + { + // check the url really points to a file in the work area + // (some work links can come from groups area...) + if (substr (dirname($thisUrl['url']), -4) == "work") + { + @unlink($currentCourseRepositorySys."work/".$thisWork); + } + } + } + } + } + } + /*------------------------------------------- + EDIT COMMAND WORK COMMAND + -----------------------------------------*/ + + if ($edit) + { + //Get the author ID for that document from the item_property table + $author_sql = "SELECT * FROM $iprop_table WHERE tool = 'work' AND insert_user_id='$user_id' AND ref=".mysql_real_escape_string($edit); + $author_qry = api_sql_query($author_sql,__FILE__,__LINE__); + if(Database::num_rows($author_qry)==1) + { + //we found the current user is the author + $sql = "SELECT * FROM ".$work_table." WHERE id='".$edit."'"; + $result = api_sql_query($sql,__FILE__,__LINE__); + + if ($result) + { + $row = mysql_fetch_array($result); + + $workTitle = $row ['title' ]; + $workAuthor = $row ['author' ]; + $workDescription = $row ['description']; + $workUrl = $row ['url' ]; + } + } + } } /* @@ -426,10 +604,9 @@ if($submitWork && $is_course_member) else{$post_group_id = '0';} //if we come from the group tools the groupid will be saved in $work_table - move_uploaded_file($_FILES['file']['tmp_name'],$updir.$new_file_name); - - $url = "work/".$new_file_name; + move_uploaded_file($_FILES['file']['tmp_name'],$updir.$my_cur_dir_path.$new_file_name); + $url = "work/".$my_cur_dir_path.$new_file_name; $result = api_sql_query("SHOW FIELDS FROM ".$work_table." LIKE 'sent_date'",__FILE__,__LINE__); if(!mysql_num_rows($result)) @@ -580,7 +757,7 @@ if ($submitWork && $succeed &&!$id) //last value is to check this is not "just" Display links to upload form and tool options =======================================*/ - display_action_links($always_show_tool_options, $always_show_upload_form); + display_action_links($cur_dir_path,$always_show_tool_options, $always_show_upload_form); /*======================================= Display form to upload document @@ -601,8 +778,7 @@ if ($submitWork && $succeed &&!$id) //last value is to check this is not "just" } } - echo "
\n", - + echo "\n", "\n"; if(!empty($error_message)) Display::display_error_message($error_message); @@ -722,6 +898,19 @@ if ($submitWork && $succeed &&!$id) //last value is to check this is not "just" "

 

"; } + //show them the form for the directory name + if(isset($_REQUEST['createdir']) && $is_allowed_to_edit) + { + //create the form that asks for the directory name + $new_folder_text = ''; + $new_folder_text .= ''; + $new_folder_text .= get_lang('NewDir') .' '; + $new_folder_text .= ''; + $new_folder_text .= ''; + $new_folder_text .= ''; + //show the form + echo $new_folder_text; + } } else { @@ -737,7 +926,7 @@ if ($submitWork && $succeed &&!$id) //last value is to check this is not "just" if ($display_tool_options) { - display_tool_options($uploadvisibledisabled, $origin); + display_tool_options($uploadvisibledisabled, $origin,$base_work_dir,$cur_dir_path,$cur_dir_path_url); } /* @@ -745,8 +934,8 @@ if ($submitWork && $succeed &&!$id) //last value is to check this is not "just" Display list of student publications ============================================================================== */ - - /*if ( ! $id )*/ display_student_publications_list($currentCourseRepositoryWeb, $link_target_parameter, $dateFormatLong, $origin); + if($cur_dir_path =='/'){$my_cur_dir_path = '';}else{$my_cur_dir_path = $cur_dir_path;} + display_student_publications_list($base_work_dir.'/'.$my_cur_dir_path,'work/'.$my_cur_dir_path,$currentCourseRepositoryWeb, $link_target_parameter, $dateFormatLong, $origin); //} /*