<?php
defined('WikyBlog') or die('Not an entry point...');


/*

To Do
	Check the amount of disk space used by pageowner
		- there could be a field in all_files for the size!
	
*/

class uploadFiles{
	var $path;
	var $path_thumb = false;
	var $thumbnails = false;
	
	function uploadFiles(){
		global $rootDir,$pageOwner;
		
		wbData::loadFileFunctions();
		includeFile('tool/SavePage.php',false); //false because we don't want to do anything yet
		
		
		$this->path = $rootDir.'/userfiles/'.toStorage($pageOwner['username'],true).'/uploaded';
		
		if(  isset($GLOBALS['wbConfig']['thumbs']) && ($GLOBALS['wbConfig']['thumbs'] == 'On') ){
			includeFile('tool/Thumbnail.php',false);
			$this->path_thumb = $rootDir.'/userfiles/'.toStorage($pageOwner['username'],true).'/thumbnails';
			$this->thumbnails = true;	
		}
		
		if( !$this->checkDirs() ){
			return;
		}
		
		globalFromPost();
		$this->foreachFile();
		
	}
	
	function checkDirs(){
		
		//image directory	
		if( !checkPath($this->path,'userfiles') ){
			trigger_error('Invalid Directory 1');
			return false;
		}
		
		if( !makeDir($this->path) ){
			trigger_error('Couldnt make directory');
			return false;
		}
		
		if( $this->thumbnails ){
			//thumbnail directory
			if( !checkPath($this->path_thumb,'userfiles') ){
				trigger_error('Invalid Directory 2');
				return false;
			}
			
			if( !makeDir($this->path_thumb) ){
				trigger_error('Couldnt make directory');
				return false;
			}
			
			//minimum for some sites
			if( !is_writable($this->path_thumb) ){
				wbChmod($this->path_thumb,0777);
			}
		}
		
		return true;
	}
	
	function foreachFile(){
		global $wbNow;
		if( empty($_FILES['userfile']) ){
			message('empty');
			return;
		}
		
		$numFiles = 0;
		foreach($_FILES['userfile']['name'] as $key => $name){
			if( empty($name) ){
				continue;
			}
			
			if( !$this->addFile($key) ){
				continue;
			}
			$wbNow = date('Y-m-d H:i:s');

			$numFiles++;
		}
	}
	
	
	function uploadFailed($name){
		message('UPLOAD_FAILED',str_replace('.wb~','.',$name));
	}
	
	
	function addFile($filesKey){
		global $page, $max_upload, $pageOwner,$wbFTP,$dbObject;
		
		$fName = $_FILES['userfile']['name'][$filesKey];
		$tempFullPath = $_FILES['userfile']['tmp_name'][$filesKey];
		$data = false;
		
			
		
		//
		//	Check Upload Errors
		//	$_FILES['userfile']['error'] NOT ADDED TILL PHP 4.2
		//
		if( isset($_FILES['userfile']['error'][$filesKey]) ){
			
			// not available till 4.3.1 and 5.0.3
			if( !defined('UPLOAD_ERR_NO_TMP_DIR') ){
				define('UPLOAD_ERR_NO_TMP_DIR',6);
			}
			
			// not available till 5.1.0
			if( !defined('UPLOAD_ERR_CANT_WRITE') ){
				define('UPLOAD_ERR_CANT_WRITE',7);
			}
			
			// not available till 5.2.0
			if( !defined('UPLOAD_ERR_EXTENSION') ){
				define('UPLOAD_ERR_EXTENSION',8);
			}
			
			switch( (int)$_FILES['userfile']['error'][$filesKey]){
				
				case UPLOAD_ERR_OK:
				break;
				
				case UPLOAD_ERR_FORM_SIZE:
				case UPLOAD_ERR_INI_SIZE: //this shouldn't happen
					message('CANNOT_UPLOAD_2',$fName,$max_upload);
				return false;
				

				case UPLOAD_ERR_NO_FILE:
				case UPLOAD_ERR_PARTIAL:
					message('UPLOAD_ERR_PARTIAL', $fName);
				return false;
				
				case UPLOAD_ERR_NO_TMP_DIR:
					$this->uploadFailed($fName);
					trigger_error('Missing a temporary folder for file uploads.');
				return false;
				
				case UPLOAD_ERR_CANT_WRITE:
					$this->uploadFailed($fName);
					trigger_error('PHP couldn\'t write to the temporary directory: '.$fName);
				return false;
				
				case UPLOAD_ERR_EXTENSION:
					$this->uploadFailed($fName);
					trigger_error('File upload stopped by extension: '.$fName);
				return false;
				
			}
			
		}
		
		
		
		//
		//	Check
		//
			//won't upload if the size was too big and php caught it
			if( empty($tempFullPath) ){
				$this->uploadFailed($fName);
				return false;
			}
			
			$stats = @stat($tempFullPath);
			if( !$stats ){
				$this->uploadFailed($fName);
				return false;
			}
			$fileSize = $stats['size'];
			
			if($fileSize > $max_upload){
				message('CANNOT_UPLOAD_2',$fName,$max_upload);
				return false;
			}
			
			if( !$this->addFile2($fName, $tempFullPath, $fileSize) ){
				return;
			}
			
	}
	
	function addFile2($fName,$tempFullPath,$fileSize){
		global $page, $max_upload, $pageOwner,$wbFTP,$dbObject;
			
		//
		// Compression Type
		//
			$compressType = '';
			if( isset($_POST['compress']) ){
				switch($_POST['compress']){
					case 'gz':
						if( function_exists('gzencode') ){
							$compressType = '.gz';
						}
					break;
					case 'bz':
						if( function_exists('bzcompress') ){
							$compressType = '.bz';
						}
					break;
				}
				$fName .= $compressType;
			}
			
		//
		//	Secure names of image files
		//
			$isImage = $dbObject->isImage($fName);
			if( $isImage ){
				$nameParts = explode('.',$fName); 
				$file_type = array_pop($nameParts);
				$fName = implode('_',$nameParts).'.'.$file_type;
			}
				
			
		//
		//	Check for existing files
		//
			
			$fName = toStorage($fName);
			$originalName = $fName;
			$fName = $this->checkFileName($fName);
			if( $fName === false ){
				$this->uploadFailed($originalName);
				return false;
			}
			
			$upName = $fName;
			if( !$isImage ){
				$upName = str_replace('.','.wb~',$upName);
			}
			$destinationFile = $this->path.'/'.$upName;
			
			
		//
		//	Save the file to disk
		//
			if( $destinationFile != $tempFullPath ){ //because upgrade to WikyBlog V1.6 will have the same path
			
				if( !empty($compressType) ){
					
					if( !$this->saveCompressed($tempFullPath, $destinationFile, $compressType)){
						$this->uploadFailed($fName);
						return false;
					}
					$fileSize = fileSize($destinationFile); //get a new filesize for a compressed file
					
				}elseif( !wbMove_uploaded_file($tempFullPath, $destinationFile)) {
					$this->uploadFailed($fName);
					return false;
				}
			}
			
		//
		//	Save gz version for content negotiation
		//
			if( empty($compresstype) && !$isImage && function_exists('gzencode') ){
				$this->saveCompressed($destinationFile, $destinationFile.'.gz', '.gz');
			}

	
		//
		//	Thumbnail		
		//
			if( $this->thumbnails && $isImage ){
				$dest_thumb = $this->path_thumb.'/'.$upName;
				thumbnail::createSquare($destinationFile,$dest_thumb,50);
			}
			
			
		//
		//	Save the file to database
		//
			
			$newValues = array();
			$newValues['height'] = 0;
			$newValues['width'] = 0;
			$newValues['keywords'] = $_POST['keywords'];
			if( $isImage ){
				$data = @getimagesize($destinationFile);
				if( $data ){
					$newValues['width'] = $data[0];
					$newValues['height'] = $data[1];
				}
			}
			
			
			$dbObject->exists = false;
			$oldObject = php4_clone($dbObject);
			$oldObject->title = toStorage($fName);
			$oldObject->filesize = $fileSize;
			$oldObject->setFileLocations();
			//$oldObject->flags = 'safe';

			if( !objectSave::saveControl($oldObject,$newValues) ){
				return false;
			}
			
			
			
			message('UPLOADED',$fName);
			return true;
	}
	
	//
	//	Save the file with compression
	//
	function saveCompressed($tempFullPath,$destination,$compressType){
		
		$contents = file_get_contents($tempFullPath); //should be ok in safe mode because it's an uploaded file
		return wbSaveCompressed($destination,$contents,$compressType);
	}
	
	
	//checks database for file name
	function checkFileName($name){
		global $dbObject;
		
		$nameParts = explode('.',$name); 
		$file_type = array_pop($nameParts);
		$tempName = implode('.',$nameParts);
		$i = 1;
		
		//max length of 40.. shorten
		if( wbStrlen($name) > 37 ){
			$remove = 3; //2 for "_1" and 1 for "."
			$remove += wbStrlen($file_type);
			$tempName = wbSubstr($tempName,0,(40-$remove));
			$name = $tempName.'.'.$file_type; //rebuild $name
		}
		
		do{
			
			//Check The Database
			$query = 'SELECT 1 FROM ';
			$query .= $dbObject->dbInfo['dbTable'];
			$query .= ' WHERE `owner` = "'.wbDB::escape($dbObject->owner).'" ';
			$query .= ' AND `title` = "'.wbDB::escape($name).'" ';
			$result = wbDB::runQuery($query);
			if( mysql_num_rows($result) === 0 ){
				return $name;
			}
			
			//increment name
			$name = $tempName.'_'.$i.'.'.$file_type;
			$i++;
			
		}while($i < 20);
		
		return false;
	}
}
