<?php

	Class PHPRC_UPLOAD
	{   	
	    Private Static $UPLOADED_MOVE_FILES = [];
		Private Static $UPLOADED_TEMP_FILES = [];
		Private Static $UPLOADED_OVERWRITE = [];
		
		
		/**
		 * Check if uploaded file array contains nothing
		 * @param String $FILE_ITEM <br />Array retrieved from $_FILE[]<br />
		 * @throws Exception
		 * @return Boolean
		 */
		Public Static Function REF_IS_NULL($FILE_ITEM)
		{
			Try
			{
				// Is null
				// _______________________________________________________________________
				if
				(
						isset($FILE_ITEM['tmp_name']) === false ||
						isset($FILE_ITEM['size']) === false ||
						isset($FILE_ITEM['error']) === false
				)
				{
					return true;
				}
				
				// Check if valid array
				// _______________________________________________________________________
				if(is_array($FILE_ITEM['tmp_name']) === true)
				{
					$ARRAY_CTR = 0;
					while($ARRAY_CTR < Count($FILE_ITEM['tmp_name']))
					{
						if ($FILE_ITEM['size'][$ARRAY_CTR] > 0)
						{
							return false;
						}
						$ARRAY_CTR ++;
					}
					return true;
				}
				else
				{
					if ($FILE_ITEM['size'] > 0)
					{
						return false;
					}
					return true;
				}
			}
			Catch(Exception $ERR)
			{
				PHPVC_LOG::VAR_REPORT_ERROR($ERR, 0);
				Throw $ERR;
			}
		}
		
		
		
		/**
		 * Call Move_Uploaded_File with transaction monitoring, 
		 * where it allows to rollback all the monitored uploads with 
		 * CUS_UPLOAD_TRANSACTION_ROLLBACK().
		 * @param String $TEMP_PATH <br />Temp directory of uploaded file<br />
		 * @param String $MOVE_PATH <br />Moved directory of uploaded file<br />
		 * @param Bool $OVERWRITE_EXISTING <br />Currently not supported<br />
		 * @throws Exception
		 */
		Public Static Function REF_UPLOAD_TRANSACTION_MOVEFILE($TEMP_PATH, $MOVE_PATH, $OVERWRITE_EXISTING = false)
		{
			Try
			{
			    array_push(self::$UPLOADED_TEMP_FILES, $TEMP_PATH);
			    array_push(self::$UPLOADED_MOVE_FILES, $MOVE_PATH);
			    array_push(self::$UPLOADED_OVERWRITE, $OVERWRITE_EXISTING);
			}
			Catch(Exception $ERR)
			{
				PHPVC_LOG::VAR_REPORT_ERROR($ERR, 0);
				Throw $ERR;
			}
		}
		
		
		
		/**
		 * Commits all the monitored uploads in current transaction
		 * @throws Exception
		 */
		Public Static Function REF_UPLOAD_TRANSACTION_COMMIT()
		{
			Try
			{
			    // Initialize
			    // _______________________________________________________________________
			    $FILE_PATH = '';
			    $FILE_EXTENSION = '';
			    
			    // Loop Transacted Items
			    // _______________________________________________________________________
			    $ARRAY_CTR = 0;
			    while($ARRAY_CTR < count(self::$UPLOADED_TEMP_FILES))
			    {
			        // Get the breakdown of the path
			        // ...........................................
			        $FILE_EXTENSION = PHPVC_STR::VAR_LCASE
			        (
			            PathInfo
			            (
			                self::$UPLOADED_MOVE_FILES[$ARRAY_CTR], 
			                PATHINFO_EXTENSION
			            )
			        );
			        $FILE_PATH = PHPVC_STR::VAR_DRIGHT
			        (
			            self::$UPLOADED_MOVE_FILES[$ARRAY_CTR], 
			            PHPVC_STR::VAR_LEN($FILE_EXTENSION) + 1
			        );
			        

			        // Check for the existing item, if exists delete item (when overwrite is set to true)
			        // ...........................................
			        foreach
			        (
			            glob
			            (
			                $FILE_PATH . '.*'
		                ) AS $DOWNLOAD_FILE
		            )
			        {
			            if(self::$UPLOADED_OVERWRITE[$ARRAY_CTR] == false)
			            {
			                $FILE_PATH = '';
			                continue;
			            }
                        else
                        {
                            unlink($DOWNLOAD_FILE);
                        }
			        }
			        
			        // Skip Current Line
			        if(PHPVC_STR::VAR_IS_BLANK($FILE_PATH))
			        {
			            $ARRAY_CTR ++;
			            continue;
			        }

			        // Move uploaded file to permanent location
			        // ...........................................
			        if
			        (
			            move_uploaded_file
			            (
			                self::$UPLOADED_TEMP_FILES[$ARRAY_CTR], 
			                self::$UPLOADED_MOVE_FILES[$ARRAY_CTR]
			            ) == false
			        )
    			    {
    			        throw New Exception('Failed to process uploaded file');
    			    }
    			    
    			    
    			    // Next Loop
    			    // ...........................................
    			    $ARRAY_CTR ++;
			    }
			    
			    // Clears the list
			    // _______________________________________________________________________
			    self::REF_UPLOAD_TRANSACTION_ROLLBACK();
			}
			Catch(Exception $ERR)
			{
				PHPVC_LOG::VAR_REPORT_ERROR($ERR, 0);
				Throw $ERR;
			}
		}
		
		
		
		/**
		 * Removes changes made during uploads (does not support overwrited uploads)
		 * @throws Exception
		 */
		Public Static Function REF_UPLOAD_TRANSACTION_ROLLBACK()
		{
			Try
			{
				// Clears the list
			    self::$UPLOADED_MOVE_FILES = [];
			    self::$UPLOADED_TEMP_FILES = [];
			    self::$UPLOADED_OVERWRITE = [];
			}
			Catch(Exception $ERR)
			{
				PHPVC_LOG::VAR_REPORT_ERROR($ERR, 0);
				Throw $ERR;
			}
		}
		
		
		
		/**
		 * Suggest path for the uploaded file. Then creates folders if necessary.
		 * Note: Best for controlling the number of files stored in the folder. 
		 * (Too many files in same folder slows down the directory navigation)
		 * @throws Exception
		 */
		Public Static Function REF_SUGGEST_PATH($FILE_PATH, $FILE_ID, $UPLOADED_FILE)
		{
		    // Create Folder Suggestion
		    // _______________________________________________________________________
		    $BASE_PATH = $FILE_PATH . floor($FILE_ID / 5000) . "/";
		    
		    // Prepare Nested Folders
		    // _______________________________________________________________________
		    PHPRC_FSO_DIRECTORY::REF_CREATE_ALL($BASE_PATH); 
		
		    // Adjust for extension
		    // _______________________________________________________________________
		    if(isset($UPLOADED_FILE) && is_string($UPLOADED_FILE))
		    {
		        $BASE_PATH =  $BASE_PATH . $FILE_ID . "." . PHPVC_STR::VAR_LCASE(PathInfo($UPLOADED_FILE, PATHINFO_EXTENSION));
		    }
		    else if(isset($UPLOADED_FILE))
		    {
		        $BASE_PATH =  $BASE_PATH . $FILE_ID . "." . PHPVC_STR::VAR_LCASE(PathInfo($UPLOADED_FILE['name'], PATHINFO_EXTENSION));
		    }
		    else
		    {
		        $BASE_PATH =  $BASE_PATH . $FILE_ID;
		    }
		    
		    // Return result
		    // _______________________________________________________________________
		    return $BASE_PATH;
		}
		
		
		
		/**
		 * Locate the uploaded file stored using REF_SUGGEST_PATH() suggestion.
		 * @throws Exception
		 */
		Public Static Function REF_LOCATE_FILE($FILE_PATH, $FILE_ID)
		{
		    Try
		    {
		        // Add slash to end of the Path
		        if(PHPVC_STR::VAR_CONTAINS_RIGHT($FILE_PATH, "/") == false)
		        {
		            $FILE_PATH = $FILE_PATH . "/";
		        }
		        
		        // Get Suggestion
		        foreach
		        (
		            glob
		            (
		                $FILE_PATH . floor($FILE_ID / 5000) . '/' .
		                $FILE_ID . '.*'
		            ) AS $DOWNLOAD_FILE
		        )
		        {
		            return $DOWNLOAD_FILE;
		            break;
		        }
		    }
		    Catch(Exception $ERR)
		    {
		        PHPVC_LOG::VAR_REPORT_ERROR($ERR, 0);
		        Throw $ERR;
		    }
		}
	}
?>