uploadFile.php 11.7 KB
<?php
 /**
 * @file uploadFile
 * @brief
 * @author Elena
 * @version $Id: uploadFile.php 2905 2015-05-18 10:08:24Z elena $
 *
 */

	function file_upload_error_message($error_code) 
	{	
		switch ($error_code) 
		{
			case UPLOAD_ERR_INI_SIZE:
				return 'The uploaded file exceeds the upload_max_filesize directive in php.ini';
			case UPLOAD_ERR_FORM_SIZE:
				return 'The uploaded file exceeds max file size of '.maxSize;
			case UPLOAD_ERR_PARTIAL:
				return 'The uploaded file was only partially uploaded';
			case UPLOAD_ERR_NO_FILE:
				return 'No file was uploaded';
			case UPLOAD_ERR_NO_TMP_DIR:
				return 'Missing a temporary folder';
			case UPLOAD_ERR_CANT_WRITE:
				return 'Failed to write file to disk';
			case UPLOAD_ERR_EXTENSION:
				return 'File upload stopped by extension';
			case UPLOAD_ERR_EMPTY: 
				return 'File is empty';
			default:
				return 'Unknown upload error';
		}
	} 

	function getUrlFileSize($URL) 
	{
		$ch = curl_init($URL);
		curl_setopt($ch, CURLOPT_NOBODY, true);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($ch, CURLOPT_HEADER, true);
		curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
		// BRE - Add proxy host if exists
                ProxyUtils::addProxyForCurl($ch);
		$data = curl_exec($ch);
		curl_close($ch);

		$ContentLength = 1000000000000000000;
		if (preg_match('/Content-Length: (\d+)/', $data, $matches)) {
			$ContentLength = (int)$matches[1];
		}
				
		return $ContentLength;
	}
	
	function return_bytes($val) {
		$val = trim($val);
		$last = strtolower($val[strlen($val)-1]);
		switch($last) {
			// Le modifieur 'G' est disponible depuis PHP 5.1.0
			case 'g':
				$val *= 1024;
			case 'm':
				$val *= 1024;
			case 'k':
				$val *= 1024;
		}

		return $val;
	}
	
	/**
	*  Main
	*/ 
	define("UPLOAD_ERR_EMPTY",5);

	require_once 'config.php';

	// error_reporting(E_ERROR | E_WARNING | E_PARSE);

	if (!isset($_POST['sessionID'])) {
		$response = array( 'success' => false, 'error' => ': Check that uploaded file size is less than '.ini_get('upload_max_filesize')); 
		die(json_encode($response));           
	}

	define('USERDATADIR', USERPATH."/".$_POST['sessionID']."/DATA/");
	define('USERTTDIR', USERPATH."/".$_POST['sessionID']."/TT/");
	define('USERTEMPDIR', USERPATH."/".$_POST['sessionID']."/TEMP/");
	define('USERWSDIR', USERPATH."/".$_POST['sessionID']."/WS/"); 
	define('USERWORKINGDIR', USERPATH."/".$_POST['sessionID']."/RES/");
	define('ATTACHMENTDIR', DATAPATH."/Feedback/Attach/");

	$upload_max_filesize = return_bytes(ini_get('upload_max_filesize'));
	
	if ($upload_max_filesize  > $_POST['MAX_FILE_SIZE'])
			define('maxSize',$_POST['MAX_FILE_SIZE']);
	else 
			define('maxSize',$upload_max_filesize); // NEVER !
			
	if (!is_dir(USERTEMPDIR)) mkdir(USERTEMPDIR.'/', 0755, true);
	if (!is_dir(ATTACHMENTDIR)) mkdir(ATTACHMENTDIR.'/', 0755, true);

	if (!isset($_FILES['attachment']) && !isset($_FILES['localFileName']) && !isset($_FILES['localTTName']) && !isset($_FILES['localCatName']) && 
		!isset($_POST['remoteFile']) && !isset($_POST['remoteTT']) && !isset($_POST['remoteCat'])) 
	{
		$response = array( 'success' => false, 'error' => 'UNDEFINED ACTION'); 
		die(json_encode($response));
	}
 
	$fileFrmt = $_POST['filefrmt'];
	$timeFrmt = $_POST['timefrmt'] ?  $_POST['timefrmt'] : null;
	$timeSmplg = $_POST['timesmpl'] ?  $_POST['timesmpl'] : null;
	$nonStd = $_POST['nonstd'] ?  $_POST['nonstd'] : null;
	$timeLength = $_POST['timelength'] ?  $_POST['timelength'] : null;
	$doy = isset($_POST['doy']) ?  $_POST['doy'] : null;
	$sampling =  isset($_POST['smpl']) ?  $_POST['smpl'] : null;
	$min_sampling = isset($_POST['min_manual_sampling']) ?  $_POST['min_manual_sampling'] : null;
	$max_sampling = isset($_POST['max_manual_sampling']) ?  $_POST['max_manual_sampling'] : null;
	
	if ($sampling == "auto" && $timeSmplg == "variable" 
				&&  (strtolower($fileFrmt) == "cdf" || strtolower($fileFrmt) == "nc")) {	
				$response = array('success' => false, 'error' => " : Auto-definition of variable sampling for $fileFrmt isn't implemented yet. 
				Use manual sampling definition");
				die(json_encode($response));
	}
	
	$sampData = isset($_POST['sampData']) ? $_POST['sampData'] : null;
	$sampFileName = isset($_POST['sampFileName']) ? $_POST['sampFileName'] : null;

	$allFormats = array('fileFormat' => $fileFrmt, 'timeFormat' => $timeFrmt, 'doy' => $doy,
								'timeSampling' => $timeSmplg, 'nonStandard' => $nonStd, 'timeLength' => $timeLength,
								'samplingType' => $sampling, 'min_sampling' => $min_sampling, 'max_sampling' => $max_sampling);

	if ($_POST['filesrc'] == 'URL') $fromURL = true;  
	else  $fromURL = false;

	// to check ws size
	$wsMgr = new UserMgr($_POST['sessionID']);
	$wsMgr->setSpecialSettings();


 	if (isset($sampData) && !empty($sampData)) {
		$fileMgr = new FilesMgr();
		$fileName = date("Y-m-d\TH:i:s").'_samp.vot';
		$tmpFilePath = USERTEMPDIR.$fileName;
		file_put_contents($tmpFilePath, $sampData);
		$fileSize = filesize($tmpFilePath);

		if ($wsMgr->getWsSize() + $fileSize > DISK_QUOTA)
                {
			$response = array( 'success' => false, 'error' => 'Please clean up you workspace. You are about to exceed available disk space');
			unlink($tmpFilePath);
			die(json_encode($response));
		}

		if ($fileSize > maxSize)
		{
			$maxMB = maxSize/1000000;
			$response = array( 'success' => false, 'error' => 'The uploaded file exceeds '.$maxMB.'MB');
			unlink($tmpFilePath);
			die(json_encode($response));
		}

		$dataFilePath = USERDATADIR.$fileName;
		rename($tmpFilePath,$dataFilePath);
	}
	else if ($fromURL) 
	{
	// url files check
		if ($_POST['remoteFile']) 
		{
			$remoteName = $_POST['remoteFile'];
			$fileName = substr(strrchr($remoteName,"/"),1);
			$localName = USERDATADIR.$fileName; 		 
			$isFile = true;
		}
		else 
		{
			$isTimeTable =  $_POST['remoteTT'] ? true : false;
			$remoteName = $isTimeTable ? $_POST['remoteTT'] : $_POST['remoteCat'];
			$fileName = substr(strrchr($remoteName,"/"),1);
			$localName = USERTEMPDIR.$fileName; 		 		 	     
			$isFile = false;
		}
      
		$url = null;
		
		if (substr($remoteName,0,5) == 'https') 
		{
			$response = array( 'success' => false, 'error' => ' : Sorry, https protocol is no implemented yet'); 
			die(json_encode($response));
		}
		
		if (substr($remoteName,0,4) == 'http')  $url = 'http';
		if (substr($remoteName,0,3) == 'ftp')   $url = 'ftp';

		if (!$url) 
		{
			$response = array( 'success' => false, 'error' => 'Unknown net protocol'); 
			die(json_encode($response));
		}

		if (file_exists($localName) && $isFile) 
		{
			$response = array( 'success' => false, 'error' => 'File  '.$fileName.' exists'); 
			die(json_encode($response));		 
		}

		if ($url == 'ftp') $fileSize = filesize($remoteName);
		else $fileSize = getUrlFileSize($remoteName);

		if (!$fileSize) 
		{
			$response = array( 'success' => false, 'error' => 'Can\'t estimate file size '.$fileName); 
			die(json_encode($response));
		}
               
		if (isset($file['size']) && ($file['size'] > DISK_QUOTA)) 
		{
			$response = array( 'success' => false, 'error' => 'The file you selected is too big for allowed disk quota'); 
			die(json_encode($response));
		}
		
		if ($wsMgr->getWsSize() + $fileSize > DISK_QUOTA && $isFile) 
		{
			$response = array( 'success' => false, 'error' => 'Please clean up you workspace. You are about to exceed available disk space'); 
			die(json_encode($response));
		}

		if ($fileSize > maxSize) 
		{
			$maxMB = maxSize/1000000;
			$response = array( 'success' => false, 'error' => 'The uploaded file exceeds '.$maxMB.'MB'); 
			die(json_encode($response));
		}


		// BRE - Add proxy host if exists
		$result = FALSE;
		$context = ProxyUtils::getStreamContextWithProxy();
		if (isset($context)) {
			$result = copy($remoteName, $localName, $context);
		}
		else {
			$result = copy($remoteName, $localName);
		}

		if (!$result) 
		{
			$response = array( 'success' => false, 'error' => 'Can\'t copy '.$fileName); 
			die(json_encode($response));
		}

		if (is_executable($localName))
		{
			$response = array( 'success' => false, 'error' => 'File '.$fileName.' is executable');		   
			unlink($localName);
			die(json_encode($response));		   
		}

		if ($isFile) 
		{
			$fileMgr = new FilesMgr();
			$amdaStat = new AmdaStats($_POST['sessionID']);
			if ($amdaStat->success) $amdaStat->addTask('upload', $_POST['sessionID'], null);
		}
		// Time Table
		else if ($isTimeTable)
		{
			$response = array( 'success'=>true, 'file'=>$fileName, 'format'=>$_POST['ttfrmt'] );	  	     
			die(json_encode($response)); 
		} 
		else
		{
			$response = array( 'success'=>true, 'file'=>$fileName, 'format'=>$_POST['catfrmt'] );	  	     
			die(json_encode($response)); 
		}
	}
	else 
	{
		// local files check
		if ($_FILES['localFileName']) 
		{
				$file = $_FILES['localFileName']; 
				$localName = USERDATADIR.$file['name'];
				$isFile = true;
		}
		else if ($_FILES['attachment']) 
		{
			if (!is_dir(ATTACHMENTDIR)) mkdir(ATTACHMENTDIR,755);
			
			$file = $_FILES['attachment'];
			$file['name'] = str_replace(" ","_",$file['name']);
			$file['name'] = $_POST['sessionID'].'_'.date("Y-m-d\TH:i:s").'_'.$file['name'];
			$localName = ATTACHMENTDIR.$file['name'];
			$isFile = false;
		}
		else 
		{
			$isTimeTable = $_FILES['localTTName'] ? true : false;
			$file = $isTimeTable ? $_FILES['localTTName'] : $_FILES['localCatName'];
			$localName = USERTEMPDIR.$file['name'];		     
			$isFile = false;
		}
 	
		if($file['size'] === 0 && $file['error'] === 0)
		{
			$file['error'] = 5;
		}
	
		if ($file['error'] !== 0) 
		{
			$response = array( 'success'=>false, 'error'=>file_upload_error_message($file['error'])); 		   
			die(json_encode($response));
		}

		if (file_exists($localName) && $isFile) 
		{
			$response = array( 'success'=>false, 'error'=>'File  '.$file['name'].' exists'); 		  
			die(json_encode($response));
		}
      
		if (is_executable($file['tmp_name']))
		{
			$response = array( 'success'=>false, 'error'=>'File '.$file['name'].' is executable'); 		  
			unlink($file['tmp_name']);
			die(json_encode($response));		   
		}

		if (!is_uploaded_file($file['tmp_name'])) 
		{
			$response = array( 'success'=>false, 'error'=>'File '.$file['name'].' WASN\'T UPLOADED');		   
			unlink($file['tmp_name']);
			die(json_encode($response));		    
		}	 
                
		if ($file['size'] > DISK_QUOTA) 
		{
			$response = array( 'success'=>false, 'error'=>'The file you selected is too big for allowed disk quota'); 
			die(json_encode($response));
		}

		if ($wsMgr->getWsSize() + $file['size'] > DISK_QUOTA) 
		{
			$response = array( 'success'=>false, 'error'=>'Please clean up your workspace. You are about to exceed available disk space'); 
			die(json_encode($response));
		}
                    
		if (!rename($file['tmp_name'], $localName)) 
		{          
			$response = array( 'success'=>false, 'error'=>'Cannot copy file '.$file['name']);		    
			unlink($file['tmp_name']);
			die(json_encode($response));		    
		}
 	  
		if (file_exists($localName) && !$isFile) 
		{
			if ($_POST['ttfrmt'] == 'VOT' || $_POST['catfrmt'] == 'VOT') 
			{
				$votMgr = new VOTableMgr();
				if (!$votMgr->load($localName) || !$votMgr->isValidSchema())
				{	   	
					$response = array( 'success'=>false, 'error'=>'File  '.$file['name'].' is not valid'); 			   
					unlink($localName);
					die(json_encode($response));
				} 
			}  
		}

		$fileName = $file['name'];

		if ($isFile) 
		{
			$fileMgr = new FilesMgr();
		//	$amdaStat = new AmdaStats($_POST['sessionID']);
		//	if ($amdaStat->success) $amdaStat->addTask('upload', $_POST['sessionID'], null);
		}
		// Time Table or Catalog
		else 
		{
		      $format = $isTimeTable ? $_POST['ttfrmt'] : $_POST['catfrmt'];
				$response = array( 'success'=>true, 'file'=>$fileName, 'format'=>$format );	  	    
				die(json_encode($response)); 
		} 
	}
 	 
	$response = $fileMgr->addFile($fileName, $allFormats);
 	         
	echo json_encode($response);
?>