diff --git a/htdocs/core/ajax/flowjs-server.php b/htdocs/core/ajax/flowjs-server.php new file mode 100644 index 00000000000..e1f5feaaf10 --- /dev/null +++ b/htdocs/core/ajax/flowjs-server.php @@ -0,0 +1,161 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/ajax/bankconciliate.php + * \brief File to set data for bank concilation + */ + +if (!defined('NOTOKENRENEWAL')) { + define('NOTOKENRENEWAL', '1'); // Disables token renewal +} +if (!defined('NOREQUIREMENU')) { + define('NOREQUIREMENU', '1'); +} +if (!defined('NOREQUIREHTML')) { + define('NOREQUIREHTML', '1'); +} +if (!defined('NOREQUIREAJAX')) { + define('NOREQUIREAJAX', '1'); +} +if (!defined('NOREQUIRESOC')) { + define('NOREQUIRESOC', '1'); +} +// If there is no need to load and show top and left menu +if (!defined("NOLOGIN")) { + define("NOLOGIN", '1'); +} +//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); // Required to know date format for dol_print_date + +// Load Dolibarr environment +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + +$action = GETPOST('action', 'aZ09'); +$module = GETPOST('module', 'aZ09'); +$upload_dir = GETPOST('upload_dir', 'alpha'); +$flowFilename = GETPOST('flowFilename', 'alpha'); +$flowIdentifier = GETPOST('flowIdentifier', 'alpha'); +$flowChunkNumber = GETPOST('flowChunkNumber', 'alpha'); +$flowChunkSize = GETPOST('flowChunkSize', 'alpha'); +$flowTotalSize = GETPOST('flowTotalSize', 'alpha'); + +/* + * Action + */ + + +top_httphead(); +dol_syslog(join(',', $_GET)); + +$result = true; + +if (!empty($upload_dir)) { + $temp_dir = $upload_dir.'/'.$flowIdentifier; +} else { + $temp_dir = DOL_DATA_ROOT.'/'.$module.'/temp/'.$flowIdentifier; + $upload_dir = $temp_dir; +} + +if ($_SERVER['REQUEST_METHOD'] === 'GET') { + $chunk_file = $temp_dir.'/'.$flowFilename.'.part'.$flowChunkNumber; + if (file_exists($chunk_file)) { + header("HTTP/1.0 200 Ok"); + } else { + header("HTTP/1.0 404 Not Found"); + } +} else { + // loop through files and move the chunks to a temporarily created directory + if (file_exists($upload_dir.'/'.$flowFilename)) { + echo json_encode('File '.$flowIdentifier.' was already uploaded'); + header("HTTP/1.0 200 Ok"); + } elseif (!empty($_FILES)) foreach ($_FILES as $file) { + // check the error status + if ($file['error'] != 0) { + dol_syslog('error '.$file['error'].' in file '.$flowFilename); + continue; + } + + // init the destination file (format .part<#chunk> + // the file is stored in a temporary directory + $dest_file = $temp_dir.'/'.$flowFilename.'.part'.$flowChunkNumber; + + // create the temporary directory + if (!dol_is_dir($temp_dir)) { + dol_mkdir($temp_dir); + } + + // move the temporary file + if (!dol_move_uploaded_file($file['tmp_name'], $dest_file, 0)) { + dol_syslog('Error saving (move_uploaded_file) chunk '.$flowChunkNumber.' for file '.$flowFilename); + } else { + // check if all the parts present, and create the final destination file + $result = createFileFromChunks($temp_dir, $upload_dir, $flowFilename, $flowChunkSize, $flowTotalSize); + } + } +} +if ($result) { + echo json_encode('File '.$flowIdentifier.' uploaded'); +} else { + echo json_encode('Error while uploading file '.$flowIdentifier); +} + + +/** + * Check if all the parts exist, and + * gather all the parts of the file together + * @param string $temp_dir - the temporary directory holding all the parts of the file + * @param string $upload_dir - the temporary directory to create file + * @param string $fileName - the original file name + * @param string $chunkSize - each chunk size (in bytes) + * @param string $totalSize - original file size (in bytes) + * @return bool true if Ok false else + */ +function createFileFromChunks($temp_dir, $upload_dir, $fileName, $chunkSize, $totalSize) +{ + + dol_syslog(__METHOD__, LOG_DEBUG); + // count all the parts of this file + $total_files = 0; + $files = dol_dir_list($temp_dir, 'files'); + foreach ($files as $file) { + if (stripos($file, $fileName) !== false) { + $total_files++; + } + } + + // check that all the parts are present + // the size of the last part is between chunkSize and 2*$chunkSize + if ($total_files * $chunkSize >= ($totalSize - $chunkSize + 1)) { + // create the final destination file + if (($fp = fopen($upload_dir.'/'.$fileName, 'w')) !== false) { + for ($i=1; $i<=$total_files; $i++) { + fwrite($fp, file_get_contents($temp_dir.'/'.$fileName.'.part'.$i)); + dol_syslog('writing chunk '.$i); + } + fclose($fp); + } else { + dol_syslog('cannot create the destination file'); + return false; + } + + // rename the temporary directory (to avoid access from other + // concurrent chunks uploads) + @rename($temp_dir, $temp_dir.'_UNUSED'); + } + return true; +}