Adding jquery multiple uploader script for documents see #2784 (need to be more preatty) the pbar.ani.gif is also very big 250kb need to be replaced

skala
Julio Montoya 15 years ago
parent a5a8f10156
commit 9fb4257162
  1. 339
      main/document/upload.php
  2. 16
      main/inc/ajax/document.ajax.php
  3. 274
      main/inc/lib/document.lib.php
  4. 32
      main/inc/lib/fileUpload.lib.php
  5. 61
      main/inc/lib/javascript/jquery-upload/README.txt
  6. 74
      main/inc/lib/javascript/jquery-upload/jquery.fileupload-ui.css
  7. 308
      main/inc/lib/javascript/jquery-upload/jquery.fileupload-ui.js
  8. 629
      main/inc/lib/javascript/jquery-upload/jquery.fileupload.js
  9. BIN
      main/inc/lib/javascript/jquery-upload/pbar-ani.gif
  10. 10
      main/inc/lib/main_api.lib.php

@ -40,14 +40,13 @@ $language_file = array('document','gradebook');
require_once '../inc/global.inc.php';
// Including additional libraries
require_once api_get_path(LIBRARY_PATH).'fileUpload.lib.php';
require_once api_get_path(LIBRARY_PATH).'document.lib.php';
require_once api_get_path(LIBRARY_PATH).'specific_fields_manager.lib.php';
require_once api_get_path(LIBRARY_PATH).'formvalidator/FormValidator.class.php';
require_once 'document.inc.php';
// Adding extra javascript to the form
$htmlHeadXtra[] = '<script src="../inc/lib/javascript/jquery.js" type="text/javascript" language="javascript"></script>';
$htmlHeadXtra[] = api_get_jquery_libraries_js(array('jquery-ui', 'jquery-upload'));
$htmlHeadXtra[] = '<script type="text/javascript">
function check_unzip() {
@ -71,94 +70,35 @@ function advanced_parameters() {
document.getElementById(\'img_plus_and_minus\').innerHTML=\'&nbsp;<img style="vertical-align:middle;" src="../img/div_show.gif" alt="" />&nbsp;'.get_lang('AdvancedParameters').'\';
}
}
function setFocus(){
$("#title_file").focus();
}
$(document).ready(function () {
setFocus();
});
});
</script>';
/**
* Obtains the text inside the file with the right parser
*/
function get_text_content($doc_path, $doc_mime) {
// TODO: review w$ compatibility
// Use usual exec output lines array to store stdout instead of a temp file
// because we need to store it at RAM anyway before index on DokeosIndexer object
$ret_val = null;
switch ($doc_mime) {
case 'text/plain':
$handle = fopen($doc_path, 'r');
$output = array(fread($handle, filesize($doc_path)));
fclose($handle);
break;
case 'application/pdf':
exec("pdftotext $doc_path -", $output, $ret_val);
break;
case 'application/postscript':
$temp_file = tempnam(sys_get_temp_dir(), 'chamilo');
exec("ps2pdf $doc_path $temp_file", $output, $ret_val);
if ($ret_val !== 0) { // shell fail, probably 127 (command not found)
return false;
}
exec("pdftotext $temp_file -", $output, $ret_val);
unlink($temp_file);
//var_dump($output);
break;
case 'application/msword':
exec("catdoc $doc_path", $output, $ret_val);
//var_dump($output);
break;
case 'text/html':
exec("html2text $doc_path", $output, $ret_val);
break;
case 'text/rtf':
// Note: correct handling of code pages in unrtf
// on debian lenny unrtf v0.19.2 can not, but unrtf v0.20.5 can
exec("unrtf --text $doc_path", $output, $ret_val);
if ($ret_val == 127) { // command not found
return false;
}
// Avoid index unrtf comments
if (is_array($output) && count($output) > 1) {
$parsed_output = array();
foreach ($output as & $line) {
if (!preg_match('/^###/', $line, $matches)) {
if (!empty($line)) {
$parsed_output[] = $line;
}
}
}
$output = $parsed_output;
}
break;
case 'application/vnd.ms-powerpoint':
exec("catppt $doc_path", $output, $ret_val);
break;
case 'application/vnd.ms-excel':
exec("xls2csv -c\" \" $doc_path", $output, $ret_val);
break;
}
$content = '';
if (!is_null($ret_val)) {
if ($ret_val !== 0) { // shell fail, probably 127 (command not found)
return false;
}
}
if (isset($output)) {
foreach ($output as & $line) {
$content .= $line."\n";
}
return $content;
}
else {
return false;
}
}
$htmlHeadXtra[] = "
<script type=\"text/javascript\">
$(function () {
$('#file_upload').fileUploadUI({
uploadTable: $('#files'),
downloadTable: $('#files'),
buildUploadRow: function (files, index) {
return $('<tr><td>' + files[index].name + '<\/td>' +
'<td class=\"file_upload_progress\"><div><\/div><\/td>' +
'<td class=\"file_upload_cancel\">' +
'<button class=\"ui-state-default ui-corner-all\" title=\"".get_lang('Cancel')."\">' +
'<span class=\"ui-icon ui-icon-cancel\">".get_lang('Cancel')."<\/span>' +
'<\/button><\/td><\/tr>');
},
buildDownloadRow: function (file) {
return $('<tr><td>' + file.name + '<\/td><\/tr>');
}
});
$('#tabs').tabs();
});
</script>";
// Variables
@ -184,17 +124,17 @@ if (!DocumentManager::get_document_id($_course, $path)) {
}
// This needs cleaning!
if (isset($_SESSION['_gid']) && $_SESSION['_gid'] != '') { // If the group id is set, check if the user has the right to be here
if (api_get_group_id()) { // If the group id is set, check if the user has the right to be here
// Needed for group related stuff
require_once api_get_path(LIBRARY_PATH).'groupmanager.lib.php';
// Get group info
$group_properties = GroupManager::get_group_properties($_SESSION['_gid']);
$group_properties = GroupManager::get_group_properties(api_get_group_id());
$noPHP_SELF = true;
if ($is_allowed_to_edit || GroupManager::is_user_in_group($_user['user_id'], $_SESSION['_gid'])) { // Only courseadmin or group members allowed
$to_group_id = $_SESSION['_gid'];
$req_gid = '&amp;gidReq='.$_SESSION['_gid'];
$interbreadcrumb[] = array('url' => '../group/group_space.php?gidReq='.$_SESSION['_gid'], 'name' => get_lang('GroupSpace'));
if ($is_allowed_to_edit || GroupManager::is_user_in_group($_user['user_id'], api_get_group_id())) { // Only courseadmin or group members allowed
$to_group_id = api_get_group_id();
$req_gid = '&amp;gidReq='.api_get_group_id();
$interbreadcrumb[] = array('url' => '../group/group_space.php?gidReq='.api_get_group_id(), 'name' => get_lang('GroupSpace'));
} else {
api_not_allowed(true);
}
@ -218,13 +158,8 @@ if ($is_certificate_array[0] == 'certificates') {
$is_certificate_mode = true;
}
// If we want to unzip a file, we need the library
if (isset($_POST['unzip']) && $_POST['unzip'] == 1) {
require_once api_get_path(LIBRARY_PATH).'pclzip/pclzip.lib.php';
}
// Variables
$max_filled_space = DocumentManager::get_course_quota();
//$max_filled_space = DocumentManager::get_course_quota();
// Title of the tool
if ($to_group_id != 0) { // Add group name after for group documents
@ -243,6 +178,7 @@ if ($is_certificate_mode) {
$interbreadcrumb[] = array('url' => './document.php?curdirpath='.urlencode($path).$req_gid, 'name'=> get_lang('Documents'));
}
$this_section = SECTION_COURSES;
// Display the header
@ -251,182 +187,12 @@ Display::display_header($nameTools, 'Doc');
/* Here we do all the work */
// User has submitted a file
if (isset($_FILES['user_upload'])) {
//echo('<pre>');
//print_r($_FILES['user_upload']);
//echo('</pre>');
$upload_ok = process_uploaded_file($_FILES['user_upload']);
if ($upload_ok) {
// File got on the server without problems, now process it
$new_path = handle_uploaded_document($_course, $_FILES['user_upload'], $base_work_dir, $_POST['curdirpath'], $_user['user_id'], $to_group_id, $to_user_id, $max_filled_space, $_POST['unzip'], $_POST['if_exists']);
$new_comment = isset($_POST['comment']) ? trim($_POST['comment']) : '';
$new_title = isset($_POST['title']) ? trim($_POST['title']) : '';
if ($new_path && ($new_comment || $new_title)) {
if (($docid = DocumentManager::get_document_id($_course, $new_path))) {
$table_document = Database::get_course_table(TABLE_DOCUMENT);
$ct = '';
if ($new_comment) $ct .= ", comment='$new_comment'";
if ($new_title) $ct .= ", title='$new_title'";
Database::query("UPDATE $table_document SET".substr($ct, 1)." WHERE id = '$docid'");
}
}
// Showing message when sending zip files
if ($new_path === true && $_POST['unzip'] == 1) {
Display::display_confirmation_message(get_lang('UplUploadSucceeded').'<br />', false);
}
if ((api_get_setting('search_enabled') == 'true') && ($docid = DocumentManager::get_document_id($_course, $new_path))) {
$table_document = Database::get_course_table(TABLE_DOCUMENT);
$result = Database::query("SELECT * FROM $table_document WHERE id = '$docid' LIMIT 1");
if (Database::num_rows($result) == 1) {
$row = Database::fetch_array($result);
$doc_path = api_get_path(SYS_COURSE_PATH).$courseDir.$row['path'];
//TODO: mime_content_type is deprecated, fileinfo php extension is enabled by default as of PHP 5.3.0
// now versions of PHP on Debian testing(5.2.6-5) and Ubuntu(5.2.6-2ubuntu) are lower, so wait for a while
$doc_mime = mime_content_type($doc_path);
//echo $doc_mime;
//TODO: more mime types
$allowed_mime_types = array('text/plain', 'application/pdf', 'application/postscript', 'application/msword', 'text/html', 'text/rtf', 'application/vnd.ms-powerpoint', 'application/vnd.ms-excel');
// mime_content_type does not detect correctly some formats that are going to be supported for index, so an extensions array is used by the moment
if (empty($doc_mime)) {
$allowed_extensions = array('ppt', 'pps', 'xls');
$extensions = preg_split("/[\/\\.]/", $doc_path) ;
$doc_ext = strtolower($extensions[count($extensions) - 1]);
if (in_array($doc_ext, $allowed_extensions)) {
switch ($doc_ext) {
case 'ppt':
case 'pps':
$doc_mime = 'application/vnd.ms-powerpoint';
break;
case 'xls':
$doc_mime = 'application/vnd.ms-excel';
break;
}
}
}
if (in_array($doc_mime, $allowed_mime_types) && isset($_POST['index_document']) && $_POST['index_document']) {
$file_title = $row['title'];
$file_content = get_text_content($doc_path, $doc_mime);
$courseid = api_get_course_id();
$lang = isset($_POST['language']) ? Database::escape_string($_POST['language']) : 'english';
require_once api_get_path(LIBRARY_PATH).'search/DokeosIndexer.class.php';
require_once api_get_path(LIBRARY_PATH).'search/IndexableChunk.class.php';
$ic_slide = new IndexableChunk();
$ic_slide->addValue('title', $file_title);
$ic_slide->addCourseId($courseid);
$ic_slide->addToolId(TOOL_DOCUMENT);
$xapian_data = array(
SE_COURSE_ID => $courseid,
SE_TOOL_ID => TOOL_DOCUMENT,
SE_DATA => array('doc_id' => (int)$docid),
SE_USER => (int)api_get_user_id(),
);
$ic_slide->xapian_data = serialize($xapian_data);
$di = new DokeosIndexer();
$di->connectDb(null, null, $lang);
$specific_fields = get_specific_field_list();
// process different depending on what to do if file exists
/**
* FIXME: Find a way to really verify if the file had been
* overwriten. Now all work is done at
* handle_uploaded_document() and it's difficult to verify it
*/
if (!empty($_POST['if_exists']) && $_POST['if_exists'] == 'overwrite') {
// overwrite the file on search engine
// actually, it consists on delete terms from db, insert new ones, create a new search engine document, and remove the old one
// Get search_did
$tbl_se_ref = Database::get_main_table(TABLE_MAIN_SEARCH_ENGINE_REF);
$sql = 'SELECT * FROM %s WHERE course_code=\'%s\' AND tool_id=\'%s\' AND ref_id_high_level=%s LIMIT 1';
$sql = sprintf($sql, $tbl_se_ref, $courseid, TOOL_DOCUMENT, $docid);
$res = Database::query($sql);
if (Database::num_rows($res) > 0) {
$se_ref = Database::fetch_array($res);
$di->remove_document((int)$se_ref['search_did']);
$all_specific_terms = '';
foreach ($specific_fields as $specific_field) {
delete_all_specific_field_value($courseid, $specific_field['id'], TOOL_DOCUMENT, $docid);
// Update search engine
$sterms = trim($_REQUEST[$specific_field['code']]);
$all_specific_terms .= ' '. $sterms;
$sterms = explode(',', $sterms);
foreach ($sterms as $sterm) {
$sterm = trim($sterm);
if (!empty($sterm)) {
$ic_slide->addTerm($sterm, $specific_field['code']);
add_specific_field_value($specific_field['id'], $courseid, TOOL_DOCUMENT, $docid, $value);
}
}
}
// Add terms also to content to make terms findable by probabilistic search
$file_content = $all_specific_terms .' '. $file_content;
$ic_slide->addValue('content', $file_content);
$di->addChunk($ic_slide);
// Index and return a new search engine document id
$did = $di->index();
if ($did) {
// update the search_did on db
$tbl_se_ref = Database::get_main_table(TABLE_MAIN_SEARCH_ENGINE_REF);
$sql = 'UPDATE %s SET search_did=%d WHERE id=%d LIMIT 1';
$sql = sprintf($sql, $tbl_se_ref, (int)$did, (int)$se_ref['id']);
Database::query($sql);
}
}
} else {
// Add all terms
$all_specific_terms = '';
foreach ($specific_fields as $specific_field) {
if (isset($_REQUEST[$specific_field['code']])) {
$sterms = trim($_REQUEST[$specific_field['code']]);
$all_specific_terms .= ' '. $sterms;
if (!empty($sterms)) {
$sterms = explode(',', $sterms);
foreach ($sterms as $sterm) {
$ic_slide->addTerm(trim($sterm), $specific_field['code']);
add_specific_field_value($specific_field['id'], $courseid, TOOL_DOCUMENT, $docid, $sterm);
}
}
}
}
// Add terms also to content to make terms findable by probabilistic search
$file_content = $all_specific_terms .' '. $file_content;
$ic_slide->addValue('content', $file_content);
$di->addChunk($ic_slide);
// Index and return search engine document id
$did = $di->index();
if ($did) {
// Save it to db
$tbl_se_ref = Database::get_main_table(TABLE_MAIN_SEARCH_ENGINE_REF);
$sql = 'INSERT INTO %s (id, course_code, tool_id, ref_id_high_level, search_did)
VALUES (NULL , \'%s\', \'%s\', %s, %s)';
$sql = sprintf($sql, $tbl_se_ref, $courseid, TOOL_DOCUMENT, $docid, $did);
Database::query($sql);
}
}
}
}
}
// Check for missing images in html files
$missing_files = check_for_missing_files($base_work_dir.$new_path);
if ($missing_files) {
// Show a form to upload the missing files
Display::display_normal_message(build_missing_files_form($missing_files, $_POST['curdirpath'], $_FILES['user_upload']['name']), false);
}
}
if (!empty($_FILES)) {
DocumentManager::upload_document($_FILES, $_POST['curdirpath'], $_POST['title'], $_POST['comment'], $_POST['unzip'], $_POST['if_exists'], $_POST['index_document'], true);
}
// @todo remove this submit_image ???
/*
// Missing images are submitted
if (isset($_POST['submit_image'])) {
$number_of_uploaded_images = count($_FILES['img_file']['name']);
@ -444,7 +210,9 @@ if (isset($_POST['submit_image'])) {
item_property_update_on_folder($_course, $_POST['curdirpath'], $_user['user_id']);
}
}
*/
//@todo keep it simple this page should only upload files!
/*
// They want to create a directory
if (isset($_POST['create_dir']) && $_POST['dirname'] != '') {
$added_slash = ($path=='/') ? '' : '/';
@ -456,13 +224,13 @@ if (isset($_POST['create_dir']) && $_POST['dirname'] != '') {
} else {
display_error(get_lang('CannotCreateDir'));
}
}
}*/
// Tracking not needed here?
//event_access_tool(TOOL_DOCUMENT);
/* They want to create a new directory */
/*
if (isset($_GET['createdir'])) {
// create the form that asks for the directory name
$new_folder_text = '<form action="'.api_get_self().'" method="POST">';
@ -475,7 +243,7 @@ if (isset($_GET['createdir'])) {
//Display::display_normal_message($new_folder_text, false);
echo create_dir_form();
}
}*/
// Actions
echo '<div class="actions">';
@ -488,9 +256,10 @@ if ($is_certificate_mode) {
}
// Link to create a folder
/*
if (!isset($_GET['createdir']) && !is_my_shared_folder($_user['user_id'], $path, api_get_session_id()) && !$is_certificate_mode) {
echo '<a href="'.api_get_self().'?path='.$path.'&amp;createdir=1">'.Display::return_icon('new_folder.png', get_lang('CreateDir'),'','32').'</a>';
}
}*/
echo '</div>';
// Form to select directory
@ -501,9 +270,8 @@ if (!$is_certificate_mode) {
$form = new FormValidator('upload', 'POST', api_get_self(), '', 'enctype="multipart/form-data"');
$form->addElement('hidden', 'curdirpath', $path);
$form->addElement('file', 'user_upload', get_lang('File'), 'id="user_upload" size="45"');
$form->addElement('file', 'file', get_lang('File'), 'id="user_upload" size="45"');
$form->addElement('html', '<div class="row" style="font-size:smaller;font-style:italic;"><div class="label">&nbsp;</div><div class="formw">'.get_lang('MaxFileSize').': '.ini_get('upload_max_filesize').'<br/>'.get_lang('DocumentQuota').': '.(round(DocumentManager::get_course_quota()/1000000)-round(documents_total_space($_course)/1000000)).' M</div></div>');
if (api_get_setting('use_document_title') == 'true') {
$form->addElement('text', 'title', get_lang('Title'), array('size' => '20', 'style' => 'width:300px', 'id' => 'title_file'));
$form->addElement('textarea', 'comment', get_lang('Comment'), 'wrap="virtual" style="width:300px;"');
@ -542,6 +310,7 @@ $form->addElement('radio', 'if_exists', '', get_lang('UplRenameLong'), 'rename')
// Close the java script and avoid the footer up
$form -> addElement('html', '</div>');
// Button send document
$form->addElement('style_submit_button', 'submitDocument', get_lang('SendDocument'), 'class="upload"');
$form->add_real_progress_bar('DocumentUpload', 'user_upload');
@ -550,7 +319,19 @@ $defaults = array('index_document' => 'checked="checked"');
$form->setDefaults($defaults);
$form->display();
$simple_form = $form->return_form();
// Multiple uploads
$url = api_get_path(WEB_AJAX_PATH).'document.ajax.php';
$multiple_form = get_lang('ClickToSelectOrDragAndDropMultipleFilesOnTheUploadField').'<br />';
$multiple_form .= '<form id="file_upload" action="'.$url.'" method="POST" enctype="multipart/form-data">
<input type="hidden" name="curdirpath" value="'.$path.'" />
<input type="file" name="file" multiple>
<button>Upload</button>
<div>'.get_lang('UploadFiles').'</div>
</form>';
$multiple_form .='<table id="files"></table>';
$headers = array(get_lang('Simple') , get_lang('Multiple'));
echo Display::tabs($headers, array($simple_form, $multiple_form ),'tabs');
// Footer
Display::display_footer();
Display::display_footer();

@ -0,0 +1,16 @@
<?php
/* For licensing terms, see /license.txt */
/**
* Responses to AJAX calls for the document upload
*/
require_once '../global.inc.php';
if (api_is_anonymous()){
exit;
}
if(!empty($_FILES)) {
require_once api_get_path(LIBRARY_PATH).'document.lib.php';
DocumentManager::upload_document($_FILES, $_POST['curdirpath'], '', '', 0);
$file = $_FILES['file'];
echo '{"name":"'.$file['name'].'","type":"'.$file['type'].'","size":"'.$file['size'].'"}';
}
exit;

@ -1800,5 +1800,279 @@ class DocumentManager {
$pdf = new PDF();
$pdf->html_to_pdf($file_path, $document_data['title'], $course_code);
}
public function upload_document($files, $path, $title = '', $comment = '', $unzip = 0, $if_exists = '', $index_document = false, $show_output = false) {
require_once api_get_path(LIBRARY_PATH).'fileUpload.lib.php';
//If we want to unzip a file, we need the library
if (isset($unzip) && $unzip == 1) {
require_once api_get_path(LIBRARY_PATH).'pclzip/pclzip.lib.php';
}
$max_filled_space = self::get_course_quota();
$course_info = api_get_course_info();
$courseDir = $course_info['path'].'/document';
$sys_course_path = api_get_path(SYS_COURSE_PATH);
$base_work_dir = $sys_course_path.$courseDir;
if (isset($files['file'])) {
//echo('<pre>');
//echo('</pre>');
$upload_ok = process_uploaded_file($files['file']);
if ($upload_ok) {
// File got on the server without problems, now process it
$new_path = handle_uploaded_document($course_info, $files['file'], $base_work_dir, $path, api_get_user_id(), api_get_group_id(), null, $max_filled_space, $unzip, $if_exists, $show_output);
$new_comment = isset($title) ? trim($comment) : '';
$new_title = isset($title) ? trim($title) : '';
if ($new_path && ($new_comment || $new_title)) {
if (($docid = DocumentManager::get_document_id($course_info, $new_path))) {
$table_document = Database::get_course_table(TABLE_DOCUMENT);
$ct = '';
if ($new_comment) $ct .= ", comment='$new_comment'";
if ($new_title) $ct .= ", title='$new_title'";
Database::query("UPDATE $table_document SET ".substr($ct, 1)." WHERE id = $docid");
}
}
// Showing message when sending zip files
if ($new_path === true && $unzip == 1) {
//Display::display_confirmation_message(get_lang('UplUploadSucceeded').'<br />', false);
}
if ((api_get_setting('search_enabled') == 'true') && ($docid = DocumentManager::get_document_id($course_info, $new_path))) {
$table_document = Database::get_course_table(TABLE_DOCUMENT);
$result = Database::query("SELECT * FROM $table_document WHERE id = '$docid' LIMIT 1");
if (Database::num_rows($result) == 1) {
$row = Database::fetch_array($result);
$doc_path = api_get_path(SYS_COURSE_PATH).$courseDir.$row['path'];
//TODO: mime_content_type is deprecated, fileinfo php extension is enabled by default as of PHP 5.3.0
// now versions of PHP on Debian testing(5.2.6-5) and Ubuntu(5.2.6-2ubuntu) are lower, so wait for a while
$doc_mime = mime_content_type($doc_path);
//echo $doc_mime;
//TODO: more mime types
$allowed_mime_types = array('text/plain', 'application/pdf', 'application/postscript', 'application/msword', 'text/html', 'text/rtf', 'application/vnd.ms-powerpoint', 'application/vnd.ms-excel');
// mime_content_type does not detect correctly some formats that are going to be supported for index, so an extensions array is used by the moment
if (empty($doc_mime)) {
$allowed_extensions = array('ppt', 'pps', 'xls');
$extensions = preg_split("/[\/\\.]/", $doc_path) ;
$doc_ext = strtolower($extensions[count($extensions) - 1]);
if (in_array($doc_ext, $allowed_extensions)) {
switch ($doc_ext) {
case 'ppt':
case 'pps':
$doc_mime = 'application/vnd.ms-powerpoint';
break;
case 'xls':
$doc_mime = 'application/vnd.ms-excel';
break;
}
}
}
//@todo move this nightmare in a search controller or something like that!!! J.M
if (in_array($doc_mime, $allowed_mime_types) && isset($index_document) && $index_document) {
$file_title = $row['title'];
$file_content = self::get_text_content($doc_path, $doc_mime);
$courseid = api_get_course_id();
$lang = isset($_POST['language']) ? Database::escape_string($_POST['language']) : 'english';
require_once api_get_path(LIBRARY_PATH).'search/DokeosIndexer.class.php';
require_once api_get_path(LIBRARY_PATH).'search/IndexableChunk.class.php';
$ic_slide = new IndexableChunk();
$ic_slide->addValue('title', $file_title);
$ic_slide->addCourseId($courseid);
$ic_slide->addToolId(TOOL_DOCUMENT);
$xapian_data = array(
SE_COURSE_ID => $courseid,
SE_TOOL_ID => TOOL_DOCUMENT,
SE_DATA => array('doc_id' => (int)$docid),
SE_USER => (int)api_get_user_id(),
);
$ic_slide->xapian_data = serialize($xapian_data);
$di = new DokeosIndexer();
$di->connectDb(null, null, $lang);
$specific_fields = get_specific_field_list();
// process different depending on what to do if file exists
/**
* FIXME: Find a way to really verify if the file had been
* overwriten. Now all work is done at
* handle_uploaded_document() and it's difficult to verify it
*/
if (!empty($if_exists) && $if_exists == 'overwrite') {
// overwrite the file on search engine
// actually, it consists on delete terms from db, insert new ones, create a new search engine document, and remove the old one
// Get search_did
$tbl_se_ref = Database::get_main_table(TABLE_MAIN_SEARCH_ENGINE_REF);
$sql = 'SELECT * FROM %s WHERE course_code=\'%s\' AND tool_id=\'%s\' AND ref_id_high_level=%s LIMIT 1';
$sql = sprintf($sql, $tbl_se_ref, $courseid, TOOL_DOCUMENT, $docid);
$res = Database::query($sql);
if (Database::num_rows($res) > 0) {
$se_ref = Database::fetch_array($res);
$di->remove_document((int)$se_ref['search_did']);
$all_specific_terms = '';
foreach ($specific_fields as $specific_field) {
delete_all_specific_field_value($courseid, $specific_field['id'], TOOL_DOCUMENT, $docid);
// Update search engine
$sterms = trim($_REQUEST[$specific_field['code']]);
$all_specific_terms .= ' '. $sterms;
$sterms = explode(',', $sterms);
foreach ($sterms as $sterm) {
$sterm = trim($sterm);
if (!empty($sterm)) {
$ic_slide->addTerm($sterm, $specific_field['code']);
add_specific_field_value($specific_field['id'], $courseid, TOOL_DOCUMENT, $docid, $value);
}
}
}
// Add terms also to content to make terms findable by probabilistic search
$file_content = $all_specific_terms .' '. $file_content;
$ic_slide->addValue('content', $file_content);
$di->addChunk($ic_slide);
// Index and return a new search engine document id
$did = $di->index();
if ($did) {
// update the search_did on db
$tbl_se_ref = Database::get_main_table(TABLE_MAIN_SEARCH_ENGINE_REF);
$sql = 'UPDATE %s SET search_did=%d WHERE id=%d LIMIT 1';
$sql = sprintf($sql, $tbl_se_ref, (int)$did, (int)$se_ref['id']);
Database::query($sql);
}
}
} else {
// Add all terms
$all_specific_terms = '';
foreach ($specific_fields as $specific_field) {
if (isset($_REQUEST[$specific_field['code']])) {
$sterms = trim($_REQUEST[$specific_field['code']]);
$all_specific_terms .= ' '. $sterms;
if (!empty($sterms)) {
$sterms = explode(',', $sterms);
foreach ($sterms as $sterm) {
$ic_slide->addTerm(trim($sterm), $specific_field['code']);
add_specific_field_value($specific_field['id'], $courseid, TOOL_DOCUMENT, $docid, $sterm);
}
}
}
}
// Add terms also to content to make terms findable by probabilistic search
$file_content = $all_specific_terms .' '. $file_content;
$ic_slide->addValue('content', $file_content);
$di->addChunk($ic_slide);
// Index and return search engine document id
$did = $di->index();
if ($did) {
// Save it to db
$tbl_se_ref = Database::get_main_table(TABLE_MAIN_SEARCH_ENGINE_REF);
$sql = 'INSERT INTO %s (id, course_code, tool_id, ref_id_high_level, search_did)
VALUES (NULL , \'%s\', \'%s\', %s, %s)';
$sql = sprintf($sql, $tbl_se_ref, $courseid, TOOL_DOCUMENT, $docid, $did);
Database::query($sql);
}
}
}
}
}
// Check for missing images in html files
$missing_files = check_for_missing_files($base_work_dir.$new_path);
if ($missing_files) {
// Show a form to upload the missing files
//Display::display_normal_message(build_missing_files_form($missing_files, $path, $files['file']['name']), false);
}
}
}
}
/**
* Obtains the text inside the file with the right parser
*/
function get_text_content($doc_path, $doc_mime) {
// TODO: review w$ compatibility
// Use usual exec output lines array to store stdout instead of a temp file
// because we need to store it at RAM anyway before index on DokeosIndexer object
$ret_val = null;
switch ($doc_mime) {
case 'text/plain':
$handle = fopen($doc_path, 'r');
$output = array(fread($handle, filesize($doc_path)));
fclose($handle);
break;
case 'application/pdf':
exec("pdftotext $doc_path -", $output, $ret_val);
break;
case 'application/postscript':
$temp_file = tempnam(sys_get_temp_dir(), 'chamilo');
exec("ps2pdf $doc_path $temp_file", $output, $ret_val);
if ($ret_val !== 0) { // shell fail, probably 127 (command not found)
return false;
}
exec("pdftotext $temp_file -", $output, $ret_val);
unlink($temp_file);
//var_dump($output);
break;
case 'application/msword':
exec("catdoc $doc_path", $output, $ret_val);
//var_dump($output);
break;
case 'text/html':
exec("html2text $doc_path", $output, $ret_val);
break;
case 'text/rtf':
// Note: correct handling of code pages in unrtf
// on debian lenny unrtf v0.19.2 can not, but unrtf v0.20.5 can
exec("unrtf --text $doc_path", $output, $ret_val);
if ($ret_val == 127) { // command not found
return false;
}
// Avoid index unrtf comments
if (is_array($output) && count($output) > 1) {
$parsed_output = array();
foreach ($output as & $line) {
if (!preg_match('/^###/', $line, $matches)) {
if (!empty($line)) {
$parsed_output[] = $line;
}
}
}
$output = $parsed_output;
}
break;
case 'application/vnd.ms-powerpoint':
exec("catppt $doc_path", $output, $ret_val);
break;
case 'application/vnd.ms-excel':
exec("xls2csv -c\" \" $doc_path", $output, $ret_val);
break;
}
$content = '';
if (!is_null($ret_val)) {
if ($ret_val !== 0) { // shell fail, probably 127 (command not found)
return false;
}
}
if (isset($output)) {
foreach ($output as & $line) {
$content .= $line."\n";
}
return $content;
}
else {
return false;
}
}
}
//end class DocumentManager

@ -139,7 +139,9 @@ function handle_uploaded_document($_course, $uploaded_file, $base_work_dir, $upl
$current_session_id = api_get_session_id();
// Check if there is enough space to save the file
if (!enough_space($uploaded_file['size'], $maxFilledSpace)) {
Display::display_error_message(get_lang('UplNotEnoughSpace'));
if ($output){
Display::display_error_message(get_lang('UplNotEnoughSpace'));
}
return false;
}
@ -150,7 +152,9 @@ function handle_uploaded_document($_course, $uploaded_file, $base_work_dir, $upl
}
// We can only unzip ZIP files (no gz, tar,...)
elseif ($unzip == 1 && !preg_match('/.zip$/', strtolower($uploaded_file['name']))) {
Display::display_error_message(get_lang('UplNotAZip')." ".get_lang('PleaseTryAgain'));
if ($output) {
Display::display_error_message(get_lang('UplNotAZip')." ".get_lang('PleaseTryAgain'));
}
return false;
} else {
// Clean up the name, only ASCII characters should stay. (and strict)
@ -158,7 +162,9 @@ function handle_uploaded_document($_course, $uploaded_file, $base_work_dir, $upl
// No "dangerous" files
$clean_name = disable_dangerous_file($clean_name);
if (!filter_extension($clean_name)) {
Display::display_error_message(get_lang('UplUnableToSaveFileFilteredExtension'));
if ($output){
Display::display_error_message(get_lang('UplUnableToSaveFileFilteredExtension'));
}
return false;
} else {
// Extension is good
@ -175,7 +181,9 @@ function handle_uploaded_document($_course, $uploaded_file, $base_work_dir, $upl
$where_to_save = $base_work_dir.$upload_path;
// At least if the directory doesn't exist, tell so
if (!is_dir($where_to_save)) {
Display::display_error_message(get_lang('DestDirectoryDoesntExist').' ('.$upload_path.')');
if ($output){
Display::display_error_message(get_lang('DestDirectoryDoesntExist').' ('.$upload_path.')');
}
return false;
}
//echo '<br />where to save = '.$where_to_save;
@ -223,11 +231,15 @@ function handle_uploaded_document($_course, $uploaded_file, $base_work_dir, $upl
// If the file is in a folder, we need to update all parent folders
item_property_update_on_folder($_course, $upload_path, $user_id);
// Display success message to user
Display::display_confirmation_message(get_lang('UplUploadSucceeded').'<br />'.$file_path, false);
if ($output){
Display::display_confirmation_message(get_lang('UplUploadSucceeded').'<br />'.$file_path, false);
}
return $file_path;
}
} else {
Display::display_error_message(get_lang('UplUnableToSaveFile'));
if ($output){
Display::display_error_message(get_lang('UplUnableToSaveFile'));
}
return false;
}
break;
@ -264,7 +276,9 @@ function handle_uploaded_document($_course, $uploaded_file, $base_work_dir, $upl
// Only save the file if it doesn't exist or warn user if it does exist
default:
if (file_exists($store_path)) {
Display::display_error_message($clean_name.' '.get_lang('UplAlreadyExists'));
if ($output){
Display::display_error_message($clean_name.' '.get_lang('UplAlreadyExists'));
}
} else {
if (@move_uploaded_file($uploaded_file['tmp_name'], $store_path)) {
chmod($store_path, $files_perm);
@ -283,7 +297,9 @@ function handle_uploaded_document($_course, $uploaded_file, $base_work_dir, $upl
}
return $file_path;
} else {
Display::display_error_message(get_lang('UplUnableToSaveFile'));
if ($output){
Display::display_error_message(get_lang('UplUnableToSaveFile'));
}
return false;
}
}

@ -0,0 +1,61 @@
jQuery File Upload Plugin
=========================
Demo
----
http://aquantum-demo.appspot.com/file-upload
Features
--------
- Multiple file upload:
Allows to select multiple files at once and upload them simultaneously.
- Drag & Drop support:
Allows to upload files by dragging them from your desktop or filemanager and dropping them on your browser window.
- Upload progress bar:
Shows a progress bar indicating the upload progress for individual files.
- Cancelable uploads:
Individual file uploads can be canceled to stop the upload progress.
- No browser plugins (e.g. Adobe Flash) required:
The implementation is based on open standards like HTML5 and JavaScript and requires no additional browser plugins.
- Graceful fallback for legacy browsers:
Uploads files via XMLHttpRequests if supported and uses iframes as fallback for legacy browsers.
- HTML file upload form fallback:
Shows a standard HTML file upload form if JavaScript is disabled.
- Cross-site file uploads:
Supports uploading files to a different domain with Cross-site XMLHttpRequests.
- Multiple plugin instances:
Allows to use multiple plugin instances on the same webpage.
- Customizable and extensible:
Provides an API to set individual options and define callBack methods for various upload events.
- Multipart and file contents stream uploads:
Files can be uploaded as standard "multipart/form-data" or file contents stream (HTTP PUT file upload).
- Compatible with any server-side application platform:
Works with Google App Engine (Python, Java), Ruby on Rails, PHP and any other platform that supports HTTP file uploads.
Requirements
------------
- jQuery v. 1.4+
- jQuery UI v. 1.8+ (optional)
Browser Support (tested versions)
---------------------------------
- Google Chrome - 7.0, 8.0, 9.0
- Apple Safari - 5.0 ¹
- Mozilla Firefox - 3.6
- Opera - 10.60 ², 11.00 ²
- Microsoft Internet Explorer 6.0 ², 7.0 ², 8.0 ², 9.0 ²
¹ Drag & Drop is not supported on the Windows version of Safari.
² MSIE and Opera have no support for Drag & Drop, multiple file selection or upload progress indication.
License
-------
Released under the MIT license:
http://creativecommons.org/licenses/MIT/
Source Code & Download
----------------------
https://github.com/blueimp/jQuery-File-Upload
Documentation
-------------
https://github.com/blueimp/jQuery-File-Upload/wiki

@ -0,0 +1,74 @@
.file_upload {
position: relative;
overflow: hidden;
direction: ltr;
cursor: pointer;
text-align: center;
color: #333;
font-weight: bold;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
border-radius: 10px;
width: 200px;
height: 30px;
line-height: 30px;
background: palegreen;
border: 1px solid limegreen;
}
.file_upload_small {
width: 200px;
height: 30px;
line-height: 30px;
font-size: auto;
background: palegreen;
border: 1px solid limegreen;
}
.file_upload_large {
width: 100%;
height: 150px;
line-height: 150px;
font-size: 20px;
background: palegreen;
border: 1px solid limegreen;
}
.file_upload_highlight {
background: lawngreen;
}
.file_upload input {
position: absolute;
top: 0;
right: 0;
margin: 0;
border: 300px solid transparent;
opacity: 0;
-ms-filter: 'alpha(opacity=0)';
filter: alpha(opacity=0);
-o-transform: translate(-300px, -300px) scale(10);
-moz-transform: translate(-800px, 0) scale(10);
cursor: pointer;
}
.file_upload iframe, .file_upload button {
display: none;
}
.file_upload_preview img {
width: 80px;
}
.file_upload_progress .ui-progressbar-value {
background: url(pbar-ani.gif);
}
.file_upload_progress div {
width: 150px;
height: 15px;
}
.file_upload_cancel button {
cursor: pointer;
}

@ -0,0 +1,308 @@
/*
* jQuery File Upload User Interface Plugin 3.6
*
* Copyright 2010, Sebastian Tschan, AQUANTUM
* Licensed under the MIT license:
* http://creativecommons.org/licenses/MIT/
*
* https://blueimp.net
* http://www.aquantum.de
*/
/*jslint browser: true */
/*global jQuery, FileReader, URL */
(function ($) {
var undef = 'undefined',
func = 'function',
UploadHandler,
methods,
LocalImage = function (file, imageTypes) {
var img,
fileReader;
if (!imageTypes.test(file.type)) {
return null;
}
img = document.createElement('img');
if (typeof URL !== undef && typeof URL.createObjectURL === func) {
img.src = URL.createObjectURL(file);
img.onload = function () {
URL.revokeObjectURL(this.src);
};
return img;
}
if (typeof FileReader !== undef) {
fileReader = new FileReader();
if (typeof fileReader.readAsDataURL === func) {
fileReader.onload = function (e) {
img.src = e.target.result;
};
fileReader.readAsDataURL(file);
return img;
}
}
return null;
};
UploadHandler = function (container, options) {
var uploadHandler = this,
dragOverTimeout,
isDropZoneEnlarged;
this.dropZone = container;
this.imageTypes = /^image\/(gif|jpeg|png)$/;
this.previewSelector = '.file_upload_preview';
this.progressSelector = '.file_upload_progress div';
this.cancelSelector = '.file_upload_cancel button';
this.cssClassSmall = 'file_upload_small';
this.cssClassLarge = 'file_upload_large';
this.cssClassHighlight = 'file_upload_highlight';
this.dropEffect = 'highlight';
this.uploadTable = this.downloadTable = null;
this.buildUploadRow = this.buildDownloadRow = function () {
return null;
};
this.addNode = function (parentNode, node, callBack) {
if (node) {
node.css('display', 'none').appendTo(parentNode).fadeIn(function () {
if (typeof callBack === func) {
try {
callBack();
} catch (e) {
// Fix endless exception loop:
$(this).stop();
throw e;
}
}
});
} else if (typeof callBack === func) {
callBack();
}
};
this.removeNode = function (node, callBack) {
if (node) {
node.fadeOut(function () {
$(this).remove();
if (typeof callBack === func) {
try {
callBack();
} catch (e) {
// Fix endless exception loop:
$(this).stop();
throw e;
}
}
});
} else if (typeof callBack === func) {
callBack();
}
};
this.onAbort = function (event, files, index, xhr, handler) {
handler.removeNode(handler.uploadRow);
};
this.cancelUpload = function (event, files, index, xhr, handler) {
var readyState = xhr.readyState;
xhr.abort();
// If readyState is below 2, abort() has no effect:
if (isNaN(readyState) || readyState < 2) {
handler.onAbort(event, files, index, xhr, handler);
}
};
this.initProgressBar = function (node, value) {
if (typeof node.progressbar === func) {
return node.progressbar({
value: value
});
} else {
var progressbar = $('<progress value="' + value + '" max="100"/>').appendTo(node);
progressbar.progressbar = function (key, value) {
progressbar.attr('value', value);
};
return progressbar;
}
};
this.initUploadRow = function (event, files, index, xhr, handler, callBack) {
var uploadRow = handler.uploadRow = handler.buildUploadRow(files, index, handler);
if (uploadRow) {
handler.progressbar = handler.initProgressBar(
uploadRow.find(handler.progressSelector),
(xhr.upload ? 0 : 100)
);
uploadRow.find(handler.cancelSelector).click(function (e) {
handler.cancelUpload(e, files, index, xhr, handler);
});
uploadRow.find(handler.previewSelector).each(function () {
$(this).append(new LocalImage(files[index], handler.imageTypes));
});
}
handler.addNode(
(typeof handler.uploadTable === func ? handler.uploadTable(handler) : handler.uploadTable),
uploadRow,
callBack
);
};
this.initUpload = function (event, files, index, xhr, handler, callBack) {
handler.initUploadRow(event, files, index, xhr, handler, function () {
if (typeof handler.beforeSend === func) {
handler.beforeSend(event, files, index, xhr, handler, callBack);
} else {
callBack();
}
});
};
this.onProgress = function (event, files, index, xhr, handler) {
if (handler.progressbar) {
handler.progressbar.progressbar(
'value',
parseInt(event.loaded / event.total * 100, 10)
);
}
};
this.parseResponse = function (xhr) {
if (typeof xhr.responseText !== undef) {
return $.parseJSON(xhr.responseText);
} else {
// Instead of an XHR object, an iframe is used for legacy browsers:
return $.parseJSON(xhr.contents().text());
}
};
this.initDownloadRow = function (event, files, index, xhr, handler, callBack) {
var json, downloadRow;
try {
json = handler.response = handler.parseResponse(xhr);
downloadRow = handler.downloadRow = handler.buildDownloadRow(json, handler);
handler.addNode(
(typeof handler.downloadTable === func ? handler.downloadTable(handler) : handler.downloadTable),
downloadRow,
callBack
);
} catch (e) {
if (typeof handler.onError === func) {
handler.originalEvent = event;
handler.onError(e, files, index, xhr, handler);
} else {
throw e;
}
}
};
this.onLoad = function (event, files, index, xhr, handler) {
handler.removeNode(handler.uploadRow, function () {
handler.initDownloadRow(event, files, index, xhr, handler, function () {
if (typeof handler.onComplete === func) {
handler.onComplete(event, files, index, xhr, handler);
}
});
});
};
this.dropZoneEnlarge = function () {
if (!isDropZoneEnlarged) {
if (typeof uploadHandler.dropZone.switchClass === func) {
uploadHandler.dropZone.switchClass(
uploadHandler.cssClassSmall,
uploadHandler.cssClassLarge
);
} else {
uploadHandler.dropZone.addClass(uploadHandler.cssClassLarge);
uploadHandler.dropZone.removeClass(uploadHandler.cssClassSmall);
}
isDropZoneEnlarged = true;
}
};
this.dropZoneReduce = function () {
if (typeof uploadHandler.dropZone.switchClass === func) {
uploadHandler.dropZone.switchClass(
uploadHandler.cssClassLarge,
uploadHandler.cssClassSmall
);
} else {
uploadHandler.dropZone.addClass(uploadHandler.cssClassSmall);
uploadHandler.dropZone.removeClass(uploadHandler.cssClassLarge);
}
isDropZoneEnlarged = false;
};
this.onDocumentDragEnter = function (event) {
uploadHandler.dropZoneEnlarge();
};
this.onDocumentDragOver = function (event) {
if (dragOverTimeout) {
clearTimeout(dragOverTimeout);
}
dragOverTimeout = setTimeout(function () {
uploadHandler.dropZoneReduce();
}, 200);
};
this.onDragEnter = this.onDragLeave = function (event) {
uploadHandler.dropZone.toggleClass(uploadHandler.cssClassHighlight);
};
this.onDrop = function (event) {
if (dragOverTimeout) {
clearTimeout(dragOverTimeout);
}
if (uploadHandler.dropEffect && typeof uploadHandler.dropZone.effect === func) {
uploadHandler.dropZone.effect(uploadHandler.dropEffect, function () {
uploadHandler.dropZone.removeClass(uploadHandler.cssClassHighlight);
uploadHandler.dropZoneReduce();
});
} else {
uploadHandler.dropZone.removeClass(uploadHandler.cssClassHighlight);
uploadHandler.dropZoneReduce();
}
};
$.extend(this, options);
};
methods = {
init : function (options) {
return this.each(function () {
$(this).fileUpload(new UploadHandler($(this), options));
});
},
option: function (option, value, namespace) {
if (typeof option === undef || (typeof option === 'string' && typeof value === undef)) {
return $(this).fileUpload('option', option, value, namespace);
}
return this.each(function () {
$(this).fileUpload('option', option, value, namespace);
});
},
destroy : function (namespace) {
return this.each(function () {
$(this).fileUpload('destroy', namespace);
});
}
};
$.fn.fileUploadUI = function (method) {
if (methods[method]) {
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
} else if (typeof method === 'object' || !method) {
return methods.init.apply(this, arguments);
} else {
$.error('Method ' + method + ' does not exist on jQuery.fileUploadUI');
}
};
}(jQuery));

@ -0,0 +1,629 @@
/*
* jQuery File Upload Plugin 3.7.1
*
* Copyright 2010, Sebastian Tschan, AQUANTUM
* Licensed under the MIT license:
* http://creativecommons.org/licenses/MIT/
*
* https://blueimp.net
* http://www.aquantum.de
*/
/*jslint browser: true */
/*global File, FileReader, FormData, unescape, jQuery */
(function ($) {
var defaultNamespace = 'file_upload',
undef = 'undefined',
func = 'function',
num = 'number',
FileUpload,
methods,
MultiLoader = function (callBack, numberComplete) {
var loaded = 0;
this.complete = function () {
loaded += 1;
if (loaded === numberComplete) {
callBack();
}
};
};
FileUpload = function (container) {
var fileUpload = this,
uploadForm,
fileInput,
settings = {
namespace: defaultNamespace,
uploadFormFilter: function (index) {
return true;
},
fileInputFilter: function (index) {
return true;
},
cssClass: defaultNamespace,
dragDropSupport: true,
dropZone: container,
url: function (form) {
return form.attr('action');
},
method: function (form) {
return form.attr('method');
},
fieldName: function (input) {
return input.attr('name');
},
formData: function (form) {
return form.serializeArray();
},
multipart: true,
multiFileRequest: false,
withCredentials: false,
forceIframeUpload: false
},
documentListeners = {},
dropZoneListeners = {},
protocolRegExp = /^http(s)?:\/\//,
optionsReference,
isXHRUploadCapable = function () {
return typeof XMLHttpRequest !== undef && typeof File !== undef && (
!settings.multipart || typeof FormData !== undef || typeof FileReader !== undef
);
},
initEventHandlers = function () {
if (settings.dragDropSupport) {
if (typeof settings.onDocumentDragEnter === func) {
documentListeners['dragenter.' + settings.namespace] = function (e) {
settings.onDocumentDragEnter(e);
};
}
if (typeof settings.onDocumentDragLeave === func) {
documentListeners['dragleave.' + settings.namespace] = function (e) {
settings.onDocumentDragLeave(e);
};
}
documentListeners['dragover.' + settings.namespace] = fileUpload.onDocumentDragOver;
documentListeners['drop.' + settings.namespace] = fileUpload.onDocumentDrop;
$(document).bind(documentListeners);
if (typeof settings.onDragEnter === func) {
dropZoneListeners['dragenter.' + settings.namespace] = function (e) {
settings.onDragEnter(e);
};
}
if (typeof settings.onDragLeave === func) {
dropZoneListeners['dragleave.' + settings.namespace] = function (e) {
settings.onDragLeave(e);
};
}
dropZoneListeners['dragover.' + settings.namespace] = fileUpload.onDragOver;
dropZoneListeners['drop.' + settings.namespace] = fileUpload.onDrop;
settings.dropZone.bind(dropZoneListeners);
}
fileInput.bind('change.' + settings.namespace, fileUpload.onChange);
},
removeEventHandlers = function () {
$.each(documentListeners, function (key, value) {
$(document).unbind(key, value);
});
$.each(dropZoneListeners, function (key, value) {
settings.dropZone.unbind(key, value);
});
fileInput.unbind('change.' + settings.namespace);
},
initUploadEventHandlers = function (files, index, xhr, settings) {
if (typeof settings.onProgress === func) {
xhr.upload.onprogress = function (e) {
settings.onProgress(e, files, index, xhr, settings);
};
}
if (typeof settings.onLoad === func) {
xhr.onload = function (e) {
settings.onLoad(e, files, index, xhr, settings);
};
}
if (typeof settings.onAbort === func) {
xhr.onabort = function (e) {
settings.onAbort(e, files, index, xhr, settings);
};
}
if (typeof settings.onError === func) {
xhr.onerror = function (e) {
settings.onError(e, files, index, xhr, settings);
};
}
},
getUrl = function (settings) {
if (typeof settings.url === func) {
return settings.url(settings.uploadForm || uploadForm);
}
return settings.url;
},
getMethod = function (settings) {
if (typeof settings.method === func) {
return settings.method(settings.uploadForm || uploadForm);
}
return settings.method;
},
getFieldName = function (settings) {
if (typeof settings.fieldName === func) {
return settings.fieldName(settings.fileInput || fileInput);
}
return settings.fieldName;
},
getFormData = function (settings) {
var formData;
if (typeof settings.formData === func) {
return settings.formData(settings.uploadForm || uploadForm);
} else if ($.isArray(settings.formData)) {
return settings.formData;
} else if (settings.formData) {
formData = [];
$.each(settings.formData, function (name, value) {
formData.push({name: name, value: value});
});
return formData;
}
return [];
},
isSameDomain = function (url) {
if (protocolRegExp.test(url)) {
var host = location.host,
indexStart = location.protocol.length + 2,
index = url.indexOf(host, indexStart),
pathIndex = index + host.length;
if ((index === indexStart || index === url.indexOf('@', indexStart) + 1) &&
(url.length === pathIndex || $.inArray(url.charAt(pathIndex), ['/', '?', '#']) !== -1)) {
return true;
}
return false;
}
return true;
},
nonMultipartUpload = function (file, xhr, sameDomain) {
if (sameDomain) {
xhr.setRequestHeader('X-File-Name', unescape(encodeURIComponent(file.name)));
}
xhr.setRequestHeader('Content-Type', file.type);
xhr.send(file);
},
formDataUpload = function (files, xhr, settings) {
var formData = new FormData(),
i;
$.each(getFormData(settings), function (index, field) {
formData.append(field.name, field.value);
});
for (i = 0; i < files.length; i += 1) {
formData.append(getFieldName(settings), files[i]);
}
xhr.send(formData);
},
loadFileContent = function (file, callBack) {
var fileReader = new FileReader();
fileReader.onload = function (e) {
file.content = e.target.result;
callBack();
};
fileReader.readAsBinaryString(file);
},
buildMultiPartFormData = function (boundary, files, filesFieldName, fields) {
var doubleDash = '--',
crlf = '\r\n',
formData = '';
$.each(fields, function (index, field) {
formData += doubleDash + boundary + crlf +
'Content-Disposition: form-data; name="' +
unescape(encodeURIComponent(field.name)) +
'"' + crlf + crlf +
unescape(encodeURIComponent(field.value)) + crlf;
});
$.each(files, function (index, file) {
formData += doubleDash + boundary + crlf +
'Content-Disposition: form-data; name="' +
unescape(encodeURIComponent(filesFieldName)) +
'"; filename="' + unescape(encodeURIComponent(file.name)) + '"' + crlf +
'Content-Type: ' + file.type + crlf + crlf +
file.content + crlf;
});
formData += doubleDash + boundary + doubleDash + crlf;
return formData;
},
fileReaderUpload = function (files, xhr, settings) {
var boundary = '----MultiPartFormBoundary' + (new Date()).getTime(),
loader,
i;
xhr.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' + boundary);
loader = new MultiLoader(function () {
xhr.sendAsBinary(buildMultiPartFormData(
boundary,
files,
getFieldName(settings),
getFormData(settings)
));
}, files.length);
for (i = 0; i < files.length; i += 1) {
loadFileContent(files[i], loader.complete);
}
},
upload = function (files, index, xhr, settings) {
var url = getUrl(settings),
sameDomain = isSameDomain(url),
filesToUpload;
initUploadEventHandlers(files, index, xhr, settings);
xhr.open(getMethod(settings), url, true);
if (sameDomain) {
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
} else if (settings.withCredentials) {
xhr.withCredentials = true;
}
if (!settings.multipart) {
nonMultipartUpload(files[index], xhr, sameDomain);
} else {
if (typeof index === num) {
filesToUpload = [files[index]];
} else {
filesToUpload = files;
}
if (typeof FormData !== undef) {
formDataUpload(filesToUpload, xhr, settings);
} else if (typeof FileReader !== undef) {
fileReaderUpload(filesToUpload, xhr, settings);
} else {
$.error('Browser does neither support FormData nor FileReader interface');
}
}
},
handleUpload = function (event, files, input, form, index) {
var xhr = new XMLHttpRequest(),
uploadSettings = $.extend({}, settings);
uploadSettings.fileInput = input;
uploadSettings.uploadForm = form;
if (typeof uploadSettings.initUpload === func) {
uploadSettings.initUpload(
event,
files,
index,
xhr,
uploadSettings,
function () {
upload(files, index, xhr, uploadSettings);
}
);
} else {
upload(files, index, xhr, uploadSettings);
}
},
handleFiles = function (event, files, input, form) {
var i;
if (settings.multiFileRequest) {
handleUpload(event, files, input, form);
} else {
for (i = 0; i < files.length; i += 1) {
handleUpload(event, files, input, form, i);
}
}
},
legacyUploadFormDataInit = function (input, form, settings) {
var formData = getFormData(settings);
form.find(':input').not(':disabled')
.attr('disabled', true)
.addClass(settings.namespace + '_disabled');
$.each(formData, function (index, field) {
$('<input type="hidden"/>')
.attr('name', field.name)
.val(field.value)
.addClass(settings.namespace + '_form_data')
.appendTo(form);
});
input
.attr('name', getFieldName(settings))
.appendTo(form);
},
legacyUploadFormDataReset = function (input, form, settings) {
input.detach();
form.find('.' + settings.namespace + '_disabled')
.removeAttr('disabled')
.removeClass(settings.namespace + '_disabled');
form.find('.' + settings.namespace + '_form_data').remove();
},
legacyUpload = function (input, form, iframe, settings) {
var originalAction = form.attr('action'),
originalMethod = form.attr('method'),
originalTarget = form.attr('target');
iframe
.unbind('abort')
.bind('abort', function (e) {
iframe.readyState = 0;
// javascript:false as iframe src prevents warning popups on HTTPS in IE6
// concat is used here to prevent the "Script URL" JSLint error:
iframe.unbind('load').attr('src', 'javascript'.concat(':false;'));
if (typeof settings.onAbort === func) {
settings.onAbort(e, [{name: input.val(), type: null, size: null}], 0, iframe, settings);
}
})
.unbind('load')
.bind('load', function (e) {
iframe.readyState = 4;
if (typeof settings.onLoad === func) {
settings.onLoad(e, [{name: input.val(), type: null, size: null}], 0, iframe, settings);
}
// Fix for IE endless progress bar activity bug (happens on form submits to iframe targets):
$('<iframe src="javascript:false;" style="display:none"></iframe>').appendTo(form).remove();
});
form
.attr('action', getUrl(settings))
.attr('method', getMethod(settings))
.attr('target', iframe.attr('name'));
legacyUploadFormDataInit(input, form, settings);
iframe.readyState = 2;
form.get(0).submit();
legacyUploadFormDataReset(input, form, settings);
form
.attr('action', originalAction)
.attr('method', originalMethod)
.attr('target', originalTarget);
},
handleLegacyUpload = function (event, input, form) {
// javascript:false as iframe src prevents warning popups on HTTPS in IE6:
var iframe = $('<iframe src="javascript:false;" style="display:none" name="iframe_' +
settings.namespace + '_' + (new Date()).getTime() + '"></iframe>'),
uploadSettings = $.extend({}, settings);
uploadSettings.fileInput = input;
uploadSettings.uploadForm = form;
iframe.readyState = 0;
iframe.abort = function () {
iframe.trigger('abort');
};
iframe.bind('load', function () {
iframe.unbind('load');
if (typeof uploadSettings.initUpload === func) {
uploadSettings.initUpload(
event,
[{name: input.val(), type: null, size: null}],
0,
iframe,
uploadSettings,
function () {
legacyUpload(input, form, iframe, uploadSettings);
}
);
} else {
legacyUpload(input, form, iframe, uploadSettings);
}
}).appendTo(form);
},
initUploadForm = function () {
uploadForm = (container.is('form') ? container : container.find('form'))
.filter(settings.uploadFormFilter);
},
initFileInput = function () {
fileInput = uploadForm.find('input:file')
.filter(settings.fileInputFilter);
},
replaceFileInput = function (input) {
var inputClone = input.clone(true);
$('<form/>').append(inputClone).get(0).reset();
input.after(inputClone).detach();
initFileInput();
};
this.onDocumentDragOver = function (e) {
if (typeof settings.onDocumentDragOver === func &&
settings.onDocumentDragOver(e) === false) {
return false;
}
e.preventDefault();
};
this.onDocumentDrop = function (e) {
if (typeof settings.onDocumentDrop === func &&
settings.onDocumentDrop(e) === false) {
return false;
}
e.preventDefault();
};
this.onDragOver = function (e) {
if (typeof settings.onDragOver === func &&
settings.onDragOver(e) === false) {
return false;
}
var dataTransfer = e.originalEvent.dataTransfer;
if (dataTransfer) {
dataTransfer.dropEffect = dataTransfer.effectAllowed = 'copy';
}
e.preventDefault();
};
this.onDrop = function (e) {
if (typeof settings.onDrop === func &&
settings.onDrop(e) === false) {
return false;
}
var dataTransfer = e.originalEvent.dataTransfer;
if (dataTransfer && dataTransfer.files && isXHRUploadCapable()) {
handleFiles(e, dataTransfer.files);
}
e.preventDefault();
};
this.onChange = function (e) {
if (typeof settings.onChange === func &&
settings.onChange(e) === false) {
return false;
}
var input = $(e.target),
form = $(e.target.form);
if (form.length === 1) {
input.data(defaultNamespace + '_form', form);
replaceFileInput(input);
} else {
form = input.data(defaultNamespace + '_form');
}
if (!settings.forceIframeUpload && e.target.files && isXHRUploadCapable()) {
handleFiles(e, e.target.files, input, form);
} else {
handleLegacyUpload(e, input, form);
}
};
this.init = function (options) {
if (options) {
$.extend(settings, options);
optionsReference = options;
}
initUploadForm();
initFileInput();
if (container.data(settings.namespace)) {
$.error('FileUpload with namespace "' + settings.namespace + '" already assigned to this element');
return;
}
container
.data(settings.namespace, fileUpload)
.addClass(settings.cssClass);
settings.dropZone.not(container).addClass(settings.cssClass);
initEventHandlers();
};
this.options = function (options) {
var oldCssClass,
oldDropZone,
uploadFormFilterUpdate,
fileInputFilterUpdate;
if (typeof options === undef) {
return $.extend({}, settings);
}
if (optionsReference) {
$.extend(optionsReference, options);
}
removeEventHandlers();
$.each(options, function (name, value) {
switch (name) {
case 'namespace':
$.error('The FileUpload namespace cannot be updated.');
return;
case 'uploadFormFilter':
uploadFormFilterUpdate = true;
fileInputFilterUpdate = true;
break;
case 'fileInputFilter':
fileInputFilterUpdate = true;
break;
case 'cssClass':
oldCssClass = settings.cssClass;
break;
case 'dropZone':
oldDropZone = settings.dropZone;
break;
}
settings[name] = value;
});
if (uploadFormFilterUpdate) {
initUploadForm();
}
if (fileInputFilterUpdate) {
initFileInput();
}
if (typeof oldCssClass !== undef) {
container
.removeClass(oldCssClass)
.addClass(settings.cssClass);
(oldDropZone ? oldDropZone : settings.dropZone).not(container)
.removeClass(oldCssClass);
settings.dropZone.not(container).addClass(settings.cssClass);
} else if (oldDropZone) {
oldDropZone.not(container).removeClass(settings.cssClass);
settings.dropZone.not(container).addClass(settings.cssClass);
}
initEventHandlers();
};
this.option = function (name, value) {
var options;
if (typeof value === undef) {
return settings[name];
}
options = {};
options[name] = value;
fileUpload.options(options);
};
this.destroy = function () {
removeEventHandlers();
container
.removeData(settings.namespace)
.removeClass(settings.cssClass);
settings.dropZone.not(container).removeClass(settings.cssClass);
};
};
methods = {
init : function (options) {
return this.each(function () {
(new FileUpload($(this))).init(options);
});
},
option: function (option, value, namespace) {
namespace = namespace ? namespace : defaultNamespace;
var fileUpload = $(this).data(namespace);
if (fileUpload) {
if (typeof option === 'string') {
return fileUpload.option(option, value);
}
return fileUpload.options(option);
} else {
$.error('No FileUpload with namespace "' + namespace + '" assigned to this element');
}
},
destroy : function (namespace) {
namespace = namespace ? namespace : defaultNamespace;
return this.each(function () {
var fileUpload = $(this).data(namespace);
if (fileUpload) {
fileUpload.destroy();
} else {
$.error('No FileUpload with namespace "' + namespace + '" assigned to this element');
}
});
}
};
$.fn.fileUpload = function (method) {
if (methods[method]) {
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
} else if (typeof method === 'object' || !method) {
return methods.init.apply(this, arguments);
} else {
$.error('Method ' + method + ' does not exist on jQuery.fileUpload');
}
};
}(jQuery));

Binary file not shown.

After

Width:  |  Height:  |  Size: 297 KiB

@ -4839,12 +4839,12 @@ function api_get_jquery_libraries_js($libraries, $include_jquery = true) {
$js .= '<script src="'.$js_path.'jqgrid/js/i18n/grid.locale-'.$languaje.'.js" type="text/javascript" language="javascript"></script>';
$js .= '<script src="'.$js_path.'jqgrid/js/jquery.jqGrid.min.js" type="text/javascript" language="javascript"></script>';
}
if (in_array('jquery-ui',$libraries)) {
if (in_array('jquery-upload',$libraries)) {
//Adding default CSS changes of the jquery-ui themes for Chamilo in order to preserve the original jquery-ui css
$js .= '<link rel="stylesheet" href="'.$js_path.'jquery-ui/default.css" type="text/css">';
$js .= '<script src="'.$js_path.'jquery-upload/jquery.fileupload.js" type="text/javascript" language="javascript"></script>';
$js .= '<script src="'.$js_path.'jquery-upload/jquery.fileupload-ui.js" type="text/javascript" language="javascript"></script>';
$js .= '<link rel="stylesheet" href="'.$js_path.'jquery-upload/jquery.fileupload-ui.css" type="text/css">';
}
return $js;
}

Loading…
Cancel
Save