diff --git a/main/css/base.css b/main/css/base.css index 68c136f218..97aaaaab45 100644 --- a/main/css/base.css +++ b/main/css/base.css @@ -2246,4 +2246,13 @@ div.admin_section h4 { .thematic_advance_actions { width:100px; +} + +.document_preview_container { + background-color: #ccc; + position: absolute; + z-index: 20; + margin:5px; + padding:5px; + } \ No newline at end of file diff --git a/main/document/upload.php b/main/document/upload.php index 92603d0166..71a63c559a 100755 --- a/main/document/upload.php +++ b/main/document/upload.php @@ -286,7 +286,7 @@ echo ''; -$url = api_get_path(WEB_AJAX_PATH).'document.ajax.php'; +$url = api_get_path(WEB_AJAX_PATH).'document.ajax.php?a=upload_file'; $multiple_form = get_lang('ClickToSelectOrDragAndDropMultipleFilesOnTheUploadField').'
'; //Adding icon replace the
'.get_lang('UploadFiles').'
with this: //
'.Display::div(Display::return_icon('folder_document.png', '', array(), 64), array('style'=>'float:left')).' '.get_lang('UploadFiles').'
diff --git a/main/inc/ajax/document.ajax.php b/main/inc/ajax/document.ajax.php index 19136355be..ca73925637 100644 --- a/main/inc/ajax/document.ajax.php +++ b/main/inc/ajax/document.ajax.php @@ -5,36 +5,46 @@ */ require_once '../global.inc.php'; -api_protect_course_script(true); +require_once api_get_path(LIBRARY_PATH).'document.lib.php'; -//User access same as upload.php -$is_allowed_to_edit = api_is_allowed_to_edit(null, true); - -// This needs cleaning! -if (api_get_group_id()) { - if ($is_allowed_to_edit || GroupManager::is_user_in_group(api_get_user_id(), api_get_group_id())) { // Only courseadmin or group members allowed - } else { - exit; - } -} elseif ($is_allowed_to_edit || is_my_shared_folder(api_get_user_id(), $_POST['curdirpath'], api_get_session_id())) { -} else { // No course admin and no group member... - exit; -} - -if (!empty($_FILES)) { - require_once api_get_path(LIBRARY_PATH).'document.lib.php'; - require_once api_get_path(LIBRARY_PATH).'fileDisplay.lib.php'; - $result = DocumentManager::upload_document($_FILES, $_POST['curdirpath'], '', '', 0, 'overwrite', false, false); - $file = $_FILES['file']; - $json = array(); - $json['name'] = Display::url(api_htmlentities($file['name']), api_htmlentities($result['url']), array('target'=>'_blank')); - $json['type'] = api_htmlentities($file['type']); - $json['size'] = format_file_size($file['size']); - if (!empty($result) && is_array($result)) { - $json['result'] = Display::return_icon('accept.png', get_lang('Uploaded')); - } else { - $json['result'] = Display::return_icon('exclamation.png', get_lang('Error')); - } - echo json_encode($json); -} +$action = $_REQUEST['a']; +switch($action) { + case 'upload_file': + api_protect_course_script(true); + + //User access same as upload.php + $is_allowed_to_edit = api_is_allowed_to_edit(null, true); + + // This needs cleaning! + if (api_get_group_id()) { + if ($is_allowed_to_edit || GroupManager::is_user_in_group(api_get_user_id(), api_get_group_id())) { // Only courseadmin or group members allowed + } else { + exit; + } + } elseif ($is_allowed_to_edit || is_my_shared_folder(api_get_user_id(), $_POST['curdirpath'], api_get_session_id())) { + } else { // No course admin and no group member... + exit; + } + + if (!empty($_FILES)) { + require_once api_get_path(LIBRARY_PATH).'fileDisplay.lib.php'; + $result = DocumentManager::upload_document($_FILES, $_POST['curdirpath'], '', '', 0, 'overwrite', false, false); + $file = $_FILES['file']; + $json = array(); + $json['name'] = Display::url(api_htmlentities($file['name']), api_htmlentities($result['url']), array('target'=>'_blank')); + $json['type'] = api_htmlentities($file['type']); + $json['size'] = format_file_size($file['size']); + if (!empty($result) && is_array($result)) { + $json['result'] = Display::return_icon('accept.png', get_lang('Uploaded')); + } else { + $json['result'] = Display::return_icon('exclamation.png', get_lang('Error')); + } + echo json_encode($json); + } + break; + case 'document_preview': + $course_info = api_get_course_info_by_id($_REQUEST['course_id']); + echo DocumentManager::get_document_preview($course_info); + break; +} exit; \ No newline at end of file diff --git a/main/inc/header.inc.php b/main/inc/header.inc.php index 7937b4e5ee..4308c0e0b6 100755 --- a/main/inc/header.inc.php +++ b/main/inc/header.inc.php @@ -90,9 +90,10 @@ global $show_learn_path; if ($show_learn_path) { $htmlHeadXtra[] = ''; - $htmlHeadXtra[] = ''; //will be moved - $htmlHeadXtra[] = ''; //will be moved } +$htmlHeadXtra[] = ''; //will be moved +$htmlHeadXtra[] = ''; //will be moved + //Base CSS echo '@import "'.api_get_path(WEB_CSS_PATH).'base.css";'; //Default CSS diff --git a/main/inc/lib/course.lib.php b/main/inc/lib/course.lib.php index 4883fb9bac..1ff0909ce9 100755 --- a/main/inc/lib/course.lib.php +++ b/main/inc/lib/course.lib.php @@ -2677,7 +2677,7 @@ class CourseManager { $without_special_courses = ' AND course.code NOT IN ("'.implode('","',$special_course_list).'")'; } - $sql_select_courses = "SELECT course.code, course.visual_code, course.subscribe subscr, course.unsubscribe unsubscr, + $sql_select_courses = "SELECT course.id, course.code, course.visual_code, course.subscribe subscr, course.unsubscribe unsubscr, course.title title, course.tutor_name tutor, course.db_name, course.directory, course_rel_user.status status, course_rel_user.sort sort, course_rel_user.user_course_cat user_course_cat, course.visibility FROM $TABLECOURS course, @@ -2715,7 +2715,13 @@ class CourseManager { echo '
'; if (api_is_platform_admin()) { - echo '
'.Display::return_icon('edit.png', get_lang('Edit'), array('align' => 'absmiddle'),22).''; + echo '
'; + + echo ''.Display::return_icon('folder.png', get_lang('Documents'), array('align' => 'absmiddle'),22).''; + echo ''.Display::return_icon('edit.png', get_lang('Edit'), array('align' => 'absmiddle'),22).''; + echo '
'; + echo Display::div('', array('id' => 'document_result_'.$course['id'], 'class'=>'document_preview_container')); + if ($course['status'] == COURSEMANAGER) { //echo Display::return_icon('teachers.gif', get_lang('Status').': '.get_lang('Teacher'), array('style'=>'width: 11px; height: 11px;')); } diff --git a/main/inc/lib/document.lib.php b/main/inc/lib/document.lib.php index 81f9339866..6fecb10460 100755 --- a/main/inc/lib/document.lib.php +++ b/main/inc/lib/document.lib.php @@ -2472,5 +2472,162 @@ return 'application/octet-stream';
'; return $html; } + + function get_document_preview($course_info, $lp_id = false) { + + if (!isset($course_info['dbName'])) { + $course_info = api_get_course_info($course_info['code']); + } + + $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE); + $tbl_doc = Database::get_course_table(TABLE_DOCUMENT, $course_info['dbName']); + $tbl_item_prop = Database::get_course_table(TABLE_ITEM_PROPERTY, $course_info['dbName']); + + $path = '/'; + $path = Database::escape_string(str_replace('_', '\_', $path)); + $added_slash = ($path == '/') ? '' : '/'; + + //condition for the session + $current_session_id = api_get_session_id(); + $condition_session = " AND (id_session = '$current_session_id' OR (id_session = '0' AND insert_date <= (SELECT creation_date FROM $tbl_course WHERE code = '".$course_info['code']."' )))"; + + $sql_doc = "SELECT docs.* + FROM $tbl_item_prop AS last, $tbl_doc AS docs + WHERE docs.id = last.ref + AND docs.path LIKE '".$path.$added_slash."%' + AND docs.path NOT LIKE '%_DELETED_%' + AND last.tool = '".TOOL_DOCUMENT."' $condition_session ORDER BY docs.path ASC"; + + $res_doc = Database::query($sql_doc); + + $return = '
'; + $resources = Database::store_result($res_doc); + + $resources_sorted = array(); + + if ($lp_id) { + $return .= '
'; + $return .= Display::return_icon('new_doc.gif', '', array(), 22); + $return .= Display::url(get_lang('NewDocument') , api_get_self().'?'.api_get_cidreq().'&action=add_item&type='.TOOL_DOCUMENT.'&lp_id='.$_SESSION['oLP']->lp_id); + $return .= '
'; + } + + // If you want to debug it, I advise you to do "echo" on the eval statements. + + foreach ($resources as $resource) { + $resource_paths = explode('/', $resource['path']); + array_shift($resource_paths); + $path_to_eval = $last_path = ''; + $is_file = false; + foreach ($resource_paths as $key => $resource_path) { + if (strpos($resource_path, '.') === false && $key != count($resource_paths) - 1) { + // It's a folder. + $path_to_eval .= '["' . $resource_path . '"]["files"]'; + } else + if (strpos($resource_path, '.') !== false) + $is_file = true; + $last_path = $resource_path; + } + + if ($is_file) { + //for backward compatibility + if (empty($resource['title'])) { + $resource['title'] = basename($resource['path']); + } + eval ('$resources_sorted' . $path_to_eval . '[' . $resource['id'] . '] = "' .$resource['title']."/". $last_path. '";'); + } else { + eval ('$resources_sorted' . $path_to_eval . '["' . $last_path . '"]["id"]=' . $resource['id'] . ';'); + } + } + + $label = get_lang('Documents'); + $new_array[$label] = array('id' => 0, 'files' => $resources_sorted); + $return .= self::write_resources_tree($course_info, $new_array, 0, $lp_id); + $return .= '
'; + return $return; + + } + + /** + * Generate and return an HTML list of resources based on a given array. + * This list is used to show the course creator a list of available resources to choose from + * when creating a learning path. + * @param array Array of elements to add to the list + * @param integer Enables the tree display by shifting the new elements a certain distance to the right + * @return string The HTML list + */ + public function write_resources_tree($course_info, $resources_sorted, $num = 0, $lp_id = false) { + require_once api_get_path(LIBRARY_PATH).'fileDisplay.lib.php'; + $return = ''; + if (count($resources_sorted) > 0) { + foreach ($resources_sorted as $key => $resource) { + if (isset($resource['id']) && is_int($resource['id'])) { + // It's a folder. + //hide some folders + if (in_array($key, array('shared_folder','chat_files', 'HotPotatoes_files', 'css', 'certificates'))){ + continue; + } elseif(preg_match('/_groupdocs/', $key)){ + continue; + } elseif(preg_match('/sf_user_/', $key)){ + continue; + } elseif(preg_match('/shared_folder_session_/', $key)){ + continue; + } + + //trad some titles + if ($key=='images') { + $key=get_lang('Images'); + } elseif($key=='gallery') { + $key=get_lang('Gallery'); + } elseif($key=='flash') { + $key=get_lang('Flash'); + } elseif($key=='audio'){ + $key=get_lang('Audio'); + } elseif($key=='video') { + $key=get_lang('Video'); + } + + $return .= '
'; + $return .= '
'; + + $return .= '  + ' . $key . ' +
'; + } else { + if (!is_array($resource)) { + + // It's a file. + $icon = choose_image($resource); + $position = strrpos($icon, '.'); + $icon = substr($icon, 0, $position) . '_small.gif'; + $file_info = explode('/', $resource); + $my_file_title = $file_info[0]; + $my_file_name = $file_info[1]; + + // Show the "image name" not the filename of the image. + if ($lp_id) { + $lp_id = $this->lp_id; + $url = api_get_self() . '?cidReq=' . Security::remove_XSS($_GET['cidReq']) . '&action=add_item&type=' . TOOL_DOCUMENT . '&file=' . $key . '&lp_id=' .$lp_id; + } else { + $url = api_get_path(WEB_CODE_PATH).'document/document.php?cidReq='.$course_info['code'].'&id='.$key; + } + + $link = Display::url(' ' . $my_file_title, $url); + + $return .= '
'; + $return .= $link; + $return .= '
'; + } + } + } + } + return $return; + } + } //end class DocumentManager \ No newline at end of file diff --git a/main/inc/lib/javascript/dtree/dtree.css b/main/inc/lib/javascript/dtree/dtree.css new file mode 100755 index 0000000000..2c1cf1abdd --- /dev/null +++ b/main/inc/lib/javascript/dtree/dtree.css @@ -0,0 +1,17 @@ +/*--------------------------------------------------| +| dTree 2.05 | www.destroydrop.com/javascript/tree/ | +|---------------------------------------------------| +| Copyright (c) 2002-2003 Geir Landr� | +|--------------------------------------------------*/ + +.dtree{color:#000000; font-size:12px; white-space:nowrap;} + +.dtree img{border:0; margin-right:5px; vertical-align:middle;} + +.dtree a{color:#000000; font-weight:normal; text-decoration:none;} + .dtree a.node, + .dtree a.nodeSel{padding:1px 2px 1px 2px; white-space: nowrap;} + .dtree a.node:hover, .dtree a.nodeSel:hover{color:#000000; text-decoration:none;} + .dtree a.nodeSel{background:#F8F8F8; border:1px dashed #999999;} + +.dtree .clip{overflow:hidden;} \ No newline at end of file diff --git a/main/inc/lib/javascript/dtree/dtree.js b/main/inc/lib/javascript/dtree/dtree.js new file mode 100755 index 0000000000..576ff159ca --- /dev/null +++ b/main/inc/lib/javascript/dtree/dtree.js @@ -0,0 +1,707 @@ +/*--------------------------------------------------| + +| dTree 2.05 | www.destroydrop.com/javascript/tree/ | + +|---------------------------------------------------| + +| Copyright (c) 2002-2003 Geir Landr� | + +| | + +| This script can be used freely as long as all | + +| copyright messages are intact. | + +| | + +| Updated: 17.04.2003 | + +|--------------------------------------------------*/ + + + +// Node object + +function Node(id, pid, name, url, title, target, icon, iconOpen, open) { + + this.id = id; + + this.pid = pid; + + this.name = name; + + this.url = url; + + this.title = title; + + this.target = target; + + this.icon = icon; + + this.iconOpen = iconOpen; + + this._io = open || true; + + this._is = false; + + this._ls = false; + + this._hc = false; + + this._ai = 0; + + this._p; + +}; + + + +// Tree object + +function dTree(objName) { + + this.config = { + + target : null, + + folderLinks : true, + + useSelection : true, + + useCookies : true, + + useLines : true, + + useIcons : true, + + useStatusText : false, + + closeSameLevel : false, + + inOrder : false + + } + + this.icon = { + + root : '../img/icons/22/learnpath.png', + + folder : '../img/folder.gif', + + folderOpen : '../img/folderopen.gif', + + node : '../img/page.gif', + + empty : '../img/empty2.gif', + + line : '../img/line.gif', + + join : '../img/join.gif', + + joinBottom : '../img/joinbottom.gif', + + plus : '../img/plus.gif', + + plusBottom : '../img/plusbottom.gif', + + minus : '../img/minus.gif', + + minusBottom : '../img/minusbottom.gif', + + nlPlus : '../img/nolines_plus.gif', + + nlMinus : '../img/nolines_minus.gif' + + }; + + this.obj = objName; + + this.aNodes = []; + + this.aIndent = []; + + this.root = new Node(-1); + + this.selectedNode = null; + + this.selectedFound = false; + + this.completed = false; + +}; + + + +// Adds a new node to the node array + +dTree.prototype.add = function(id, pid, name, url, title, target, icon, iconOpen, open) { + + this.aNodes[this.aNodes.length] = new Node(id, pid, name, url, title, target, icon, iconOpen, open); + +}; + + + +// Open/close all nodes + +dTree.prototype.openAll = function() { + + this.oAll(true); + +}; + +dTree.prototype.closeAll = function() { + + this.oAll(false); + +}; + + + +// Outputs the tree to the page + +dTree.prototype.toString = function() { + + var str = '
\n'; + + if (document.getElementById) { + + if (this.config.useCookies) this.selectedNode = this.getSelected(); + + str += this.addNode(this.root); + + } else str += 'Browser not supported.'; + + str += '
'; + + if (!this.selectedFound) this.selectedNode = null; + + this.completed = true; + + return str; + +}; + + + +// Creates the tree structure + +dTree.prototype.addNode = function(pNode) { + + var str = ''; + + var n=0; + + if (this.config.inOrder) n = pNode._ai; + + for (n; n'; + + } + + if (node.url) { + + str += ''; + + str += node.name; + + if (node.url || ((!this.config.folderLinks || !node.url) && node._hc)) str += ''; + + str += '
'; + + if (node._hc) { + + str += '
'; + + str += this.addNode(node); + + str += '
'; + + } + + this.aIndent.pop(); + + return str; + +}; + + + +// Adds the empty and line icons + +dTree.prototype.indent = function(node, nodeId) { + + var str = ''; + + if (this.root.id != node.pid) { + + for (var n=0; n'; + + (node._ls) ? this.aIndent.push(0) : this.aIndent.push(1); + + if (node._hc) { + + str += ''; + + } else str += ''; + + } + + return str; + +}; + + + +// Checks if a node has any children and if it is the last sibling + +dTree.prototype.setCS = function(node) { + + var lastId; + + for (var n=0; n'.Display::return_icon('folder_document.gif',get_lang('Documents'),array('style'=>'margin-right:5px;', 'height' => '16px')).' '. get_lang('Documents') . '
'; - $return = '
'; - $resources = Database::store_result($res_doc); - $resources_sorted = array(); - - - $return .= '
'; - $return .= Display::return_icon('new_doc.gif', '', array(), 22); - $return .= Display::url(get_lang('NewDocument') , api_get_self().'?'.api_get_cidreq().'&action=add_item&type='.TOOL_DOCUMENT.'&lp_id='.$_SESSION['oLP']->lp_id); - $return .= '
'; - - // If you want to debug it, I advise you to do "echo" on the eval statements. - - foreach ($resources as $resource) { - $resource_paths = explode('/', $resource['path']); - array_shift($resource_paths); - $path_to_eval = $last_path = ''; - $is_file = false; - foreach ($resource_paths as $key => $resource_path) { - if (strpos($resource_path, '.') === false && $key != count($resource_paths) - 1) { // It's a folder. - $path_to_eval .= '["' . $resource_path . '"]["files"]'; - } else - if (strpos($resource_path, '.') !== false) - $is_file = true; - - $last_path = $resource_path; - } - if ($is_file) { - //eval ('$resources_sorted' . $path_to_eval . '[' . $resource['id'] . '] = "' . $last_path . '";'); - //for backward compatibility - if (empty($resource['title'])) { - $resource['title'] = basename($resource['path']); - } - eval ('$resources_sorted' . $path_to_eval . '[' . $resource['id'] . '] = "' .$resource['title']."/". $last_path. '";'); - } else { - eval ('$resources_sorted' . $path_to_eval . '["' . $last_path . '"]["id"]=' . $resource['id'] . ';'); - } - } - $label = get_lang('Documents'); - $new_array[$label] = array('id' => 0, 'files'=>$resources_sorted); - $return .= $this->write_resources_tree($new_array); - /*if (Database :: num_rows($res_doc) == 0) { - $return .= '
' . get_lang('NoDocuments') . '
'; - }*/ - $return .= '
'; - return $return; - } - - /** - * Generate and return an HTML list of resources based on a given array. - * This list is used to show the course creator a list of available resources to choose from - * when creating a learning path. - * @param array Array of elements to add to the list - * @param integer Enables the tree display by shifting the new elements a certain distance to the right - * @return string The HTML list - */ - public function write_resources_tree($resources_sorted, $num = 0) { - require_once api_get_path(LIBRARY_PATH).'fileDisplay.lib.php'; - $return = ''; - if (count($resources_sorted) > 0) { - foreach ($resources_sorted as $key => $resource) { - if (isset($resource['id']) && is_int($resource['id'])) { - // It's a folder. - //hide some folders - if (in_array($key, array('shared_folder','chat_files', 'HotPotatoes_files', 'css', 'certificates'))){ - continue; - } elseif(preg_match('/_groupdocs/', $key)){ - continue; - } elseif(preg_match('/sf_user_/', $key)){ - continue; - } elseif(preg_match('/shared_folder_session_/', $key)){ - continue; - } - - //trad some titles - if ($key=='images') { - $key=get_lang('Images'); - } elseif($key=='gallery') { - $key=get_lang('Gallery'); - } elseif($key=='flash') { - $key=get_lang('Flash'); - } elseif($key=='audio'){ - $key=get_lang('Audio'); - } elseif($key=='video') { - $key=get_lang('Video'); - } - - $return .= '
'; - $return .= '
 ' . $key . '
'; - } else { - if (!is_array($resource)) { - // It's a file. - $icon = choose_image($resource); - $position = strrpos($icon, '.'); - $icon = substr($icon, 0, $position) . '_small.gif'; - $file_info = explode('/', $resource); - $my_file_title = $file_info[0]; - $my_file_name = $file_info[1]; - //$return .= '
 ' . $resource .'
'; - // Show the "image name" not the filename of the image. - $return .= '
 ' . $my_file_title . "
\r\n"; } - } - } - } - return $return; + $course_info = api_get_course_info(); + require_once api_get_path(LIBRARY_PATH).'document.lib.php'; + $document_tree = DocumentManager::get_document_preview($course_info, $this->lp_id); + return $document_tree; } /** diff --git a/user_portal.php b/user_portal.php index e8aa65a023..fd68b55e47 100755 --- a/user_portal.php +++ b/user_portal.php @@ -193,6 +193,30 @@ if (CONFVAL_showExtractInfo != SCRIPTVAL_UnderCourseList and $orderKey[0] != 'ke Header Include the HTTP, HTML headers plus the top banner. */ +$url = api_get_path(WEB_AJAX_PATH).'document.ajax.php?a=document_preview'; + +$htmlHeadXtra[] = ''; + + Display :: display_header($nameTools); /* MAIN CODE */ @@ -426,7 +450,8 @@ if (is_array($courses_tree)) { //} echo Display::tag('span',$session_link. ' '.$extra_info); if (api_is_platform_admin()) { - echo '
'.Display::return_icon('edit.png', get_lang('Edit'), array('align' => 'absmiddle'),22).'
'; + echo '
'. + Display::return_icon('edit.png', get_lang('Edit'), array('align' => 'absmiddle'),22).'
'; } echo ''; if (api_get_setting('hide_courses_in_sessions') == 'false') {