<?php

	Class PHPRC_HTTP
	{
		// ============================================================================
		// 						SEND HTTP REQUEST
		// ============================================================================
		Public Static Function REF_REQUEST($REQUEST_URL, $REQUEST_PARAMETER, $TIMEOUT = 10, $CONNECTION_TIMEOUT = 10)
		{
			// Validate Parameters
			// ------------------------------------------------
			if(PHPVC_STR::VAR_IS_BLANK($REQUEST_URL) === TRUE)
			{
				Throw PHPVC_ERROR::VAR_RAISERROR(New Exception(PHPVC_ERROR::VAR_ARGUMENT_EXCEPTION_NULL("REQUEST_URL", False)));
			}
			if($CONNECTION_TIMEOUT > $TIMEOUT)
			{
				Throw PHPVC_ERROR::VAR_RAISERROR(New Exception(PHPVC_ERROR::VAR_ARGUMENT_EXCEPTION_INVALID_RANGE("CONNECTION_TIMEOUT", $TIMEOUT, 60, False)));
			}
			if($TIMEOUT <= 0 || $TIMEOUT > 60)
			{
				Throw PHPVC_ERROR::VAR_RAISERROR(New Exception(PHPVC_ERROR::VAR_ARGUMENT_EXCEPTION_INVALID_RANGE("TIMEOUT", 1, 60, False)));
			}
			// ------------------------------------------------
			
			
			// Actual Function
			// ------------------------------------------------
			try
			{
				$C_URL = curl_init();
				curl_setopt($C_URL, CURLOPT_RETURNTRANSFER, true);
				curl_setopt($C_URL, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);	
				if
				(
				    function_exists('curl_file_create') == false && 
				    defined('CURLOPT_SAFE_UPLOAD')
				) 
				{
					curl_setopt($C_URL, CURLOPT_SAFE_UPLOAD, false);
				}
		
				// SESSION
				curl_setopt($C_URL, CURLOPT_COOKIESESSION, true);
				curl_setopt($C_URL, CURLOPT_COOKIE, Session_name() . '=' . Session_id() . '; path=/');

				// SSL
				curl_setopt($C_URL, CURLOPT_SSL_VERIFYPEER, false);
				curl_setopt($C_URL, CURLOPT_SSL_VERIFYHOST, false);
				
				// HTTP
				curl_setopt($C_URL, CURLOPT_URL, $REQUEST_URL);
				curl_setopt($C_URL, CURLOPT_POST, 1);
				curl_setopt($C_URL, CURLOPT_TIMEOUT, $TIMEOUT);
				curl_setopt($C_URL, CURLOPT_CONNECTTIMEOUT, $CONNECTION_TIMEOUT);

				
				// Add Parameters
				if
				(
					is_string($REQUEST_PARAMETER) &&
					is_array($REQUEST_PARAMETER) == false &&
					PHPVC_STR::VAR_IS_BLANK($REQUEST_PARAMETER) == false
				)
				{
					curl_setopt($C_URL, CURLOPT_POSTFIELDS, $REQUEST_PARAMETER);
				}
				else if
				(
				 	isset($REQUEST_PARAMETER) && 
					(
						is_array($REQUEST_PARAMETER) &&
						count($REQUEST_PARAMETER) > 0
					)
				)
				{
					if(PHPVC_ARRAY::VAR_IS_STRING($REQUEST_PARAMETER))
					{
						curl_setopt($C_URL, CURLOPT_POSTFIELDS, http_build_query($REQUEST_PARAMETER));
					}
					else
					{
						curl_setopt($C_URL, CURLOPT_POSTFIELDS, $REQUEST_PARAMETER);
					}
				}
				else
				{
					curl_setopt($C_URL, CURLOPT_POSTFIELDS, null);
				}
				
				PHPVC_SESSION::VAR_STOP();
				$C_URL_REQUEST = curl_exec($C_URL);
				PHPVC_SESSION::VAR_BEGIN();
				
				if(curl_error($C_URL))
				{
					$CURL_ERR = curl_error($C_URL);
					curl_close($C_URL);
					Throw New Exception('CURL:' . $CURL_ERR);
				}
				else
				{
					curl_close($C_URL);
					return $C_URL_REQUEST;
				}
			}
			catch(Exception $ERR)
			{
				PHPVC_LOG::VAR_REPORT_ERROR($ERR, 0);
				Throw $ERR;
			}
			// ------------------------------------------------
		}
		
		/**
		 * Check if the given URL is using SSL or not
		 * @param String $TARGET_URL <br />URL to check<br />
		 * @return boolean
		 */
		function REF_IS_HTTPS($TARGET_URL)
		{
			// Validate Parameters
			// ------------------------------------------------
			if(PHPVC_STR::VAR_IS_URL($TARGET_URL) === false)
			{
				Throw PHPVC_ERROR::VAR_RAISERROR(New Exception(PHPVC_ERROR::VAR_ARGUMENT_EXCEPTION_INVALID_VALUE("TARGET_URL", False)));
			}
			// ------------------------------------------------
			
			
			// Actual Function
			// ------------------------------------------------
			Try
			{
				if(StrLen($TARGET_URL) < StrLen('https://'))
				{
					return false;
				}
				else 
				{
					if(StrToLower(PHPVC_STR::VAR_LEFT($TARGET_URL, StrLen('https://'))) == 'https://')
					{
						return true;
					}
					else
					{
						return false;
					}
				}
			}
			Catch(Exception $ERR)
			{
				PHPVC_LOG::VAR_REPORT_ERROR($ERR, 0);
				Throw $ERR;
			}
			// ------------------------------------------------
		}
		
		// ============================================================================
		// 						RETURNS SERVER BUSY STATUS
		// ============================================================================
		function REF_SERVER_BUSY()
		{
			header('HTTP/1.1 503 Service Temporarily Unavailable');
			header('Status: 503 Service Temporarily Unavailable');
			header('Retry-After: 30'); //30 seconds
			exit;
		}
	}

	
	Class PHPRC_HTTP_PARAM
	{
	    /**
	     * Suggest Parameter Key, if array '[]'.
	     * @param unknown $PARAMETER_SET Current Parameter Set.
	     * @param unknown $PARAMETER_NAME Parameter name you are currently assign.
	     * @return string Suggested Parameter Name.
	     */
	    Private Static Function REF_SUGGEST_KEY($PARAMETER_SET, $PARAMETER_NAME)
	    {
	        Try
	        {
	            // Check if array
	            // _______________________________________________________________________
	            if(PHPVC_STR::VAR_CONTAINS_RIGHT($PARAMETER_NAME, '[]'))
	            {
	                $PARAMETER_NAME = PHPVC_STR::VAR_DRIGHT($PARAMETER_NAME, 2);
	                $ARRAY_INDEX = 0;

	                // Is already exists (add indexes)
	                // ...........................................
	                if(PHPVC_ARRAY::VAR_KEY_EXISTS($PARAMETER_SET, $PARAMETER_NAME . '[0]'))
	                {
	                    while(PHPVC_ARRAY::VAR_KEY_EXISTS($PARAMETER_SET, $PARAMETER_NAME . '[' . $ARRAY_INDEX . ']'))
	                    {
	                        $ARRAY_INDEX ++;
	                    }
	                    $PARAMETER_NAME = $PARAMETER_NAME . '[' . $ARRAY_INDEX . ']';
	                }
	                
	                // Not yet added, add as index of 0
	                // ...........................................
	                else
	                {
	                    $PARAMETER_NAME = $PARAMETER_NAME . '[0]';
	                }
	            }
	            
	            // Return Result
	            // _______________________________________________________________________
	            return $PARAMETER_NAME;
	        }
	        Catch(Exception $ERR)
	        {
	            PHPVC_LOG::VAR_REPORT_ERROR($ERR, 0);
	            Throw $ERR;
	        }
	    }
	    
	    
		/**
		 * Add item to HTTP request parameters
		 * @param String[] $PARAMETER_SET <br />Parameter set. To start new parameter collection, pass NULL.<br />
		 * @param String $PARAMETER_NAME <br />Name of parameter to add. If already exists in the Parameter set, it will replace the old data.<br />
		 * @param String $PARAMETER_VALUE <br />Value to add.<br />
		 * @return String[] <br />Result parameter collection.<br />
		 */
		Public Static Function REF_ADD($PARAMETER_SET, $PARAMETER_NAME, $PARAMETER_VALUE)
		{
			Try
			{
			    // Initialize
			    // _______________________________________________________________________
			    if($PARAMETER_SET == NULL)
			    {
			        $PARAMETER_SET = [];
			    }
			    $PARAMETER_NAME = self::REF_SUGGEST_KEY($PARAMETER_SET, $PARAMETER_NAME);
				
				// if DateTime class, convert to string
				// _______________________________________________________________________
				if($PARAMETER_VALUE instanceof DateTime)
				{
					$PARAMETER_VALUE = PHPVC_DATETIME::VAR_TO_STRING($PARAMETER_VALUE);
				}
				
				// Set to Param Set
				// _______________________________________________________________________
				$PARAMETER_SET[$PARAMETER_NAME] = $PARAMETER_VALUE; //urlencode($PARAMETER_VALUE);
				return $PARAMETER_SET;
			}
			Catch(Exception $ERR)
			{
				PHPVC_LOG::VAR_REPORT_ERROR($ERR, 0);
				Throw $ERR;
			}
		}
		
		
		/**
		 * Add File into the HTTP Parameter
		 * @param unknown $PARAMETER_SET Parameter Set. If not yet initialized, you can pass NULL or empty string [].
		 * @param unknown $PARAMETER_NAME Name of the parameter.
		 * @param unknown $FILE_PATH local path of the file. 
		 * @return Array Returns Parameter Set
		 */
		Public Static Function REF_ADD_FILE($PARAMETER_SET, $PARAMETER_NAME, $FILE_PATH)
		{
			// Validate Parameters
			// ------------------------------------------------------
			if(PHPVC_STR::VAR_IS_BLANK($PARAMETER_NAME) === True)
			{
				Throw PHPVC_ERROR::VAR_RAISERROR(New Exception(PHPVC_ERROR::VAR_ARGUMENT_EXCEPTION_NULL("PARAMETER_NAME", False)));
			}
			if(PHPVC_STR::VAR_IS_BLANK($FILE_PATH) === True)
			{
				Throw PHPVC_ERROR::VAR_RAISERROR(New Exception(PHPVC_ERROR::VAR_ARGUMENT_EXCEPTION_NULL("FILE_PATH", False)));
			}
			if(PHPRC_FSO_FILE::REF_EXISTS('', $FILE_PATH) === false)
			{
				Throw PHPVC_ERROR::VAR_RAISERROR(New Exception(PHPVC_ERROR::VAR_ARGUMENT_EXCEPTION_ITEM_NOT_FOUND("FILE : " . $FILE_PATH, "Directory", False)));
			}
			// ------------------------------------------------------
			
			// Actual Function
			// ------------------------------------------------------
			Try
			{
			    // Initialize
			    // _______________________________________________________________________
			    if($PARAMETER_SET == NULL)
			    {
			        $PARAMETER_SET = [];
			    }
			    $PARAMETER_NAME = self::REF_SUGGEST_KEY($PARAMETER_SET, $PARAMETER_NAME);
			    
				// php 5.6+
				// _______________________________________________________________________
				if(function_exists('curl_file_create')) 
				{ 
					$ADD_FILE = curl_file_create($FILE_PATH);
				} 
				
				// php 5.5 and older
				// _______________________________________________________________________
				else 
				{
					$ADD_FILE = '@' . realpath($FILE_PATH);
				}
				
				// Set to Param Set
				// _______________________________________________________________________
				$PARAMETER_SET[$PARAMETER_NAME] = $ADD_FILE;
				return $PARAMETER_SET;
			}
			Catch(Exception $ERR)
			{
				PHPVC_LOG::VAR_REPORT_ERROR($ERR, 0);
				Throw $ERR;
			}
			// ------------------------------------------------------
		}
		
		
		/**
		 * Checks if the parameter exists in either POST/GET request. 
		 * @param String $PARAMETER_NAME <br />Name of parameter to locate.<br />
		 * @return Boolean <br />Returns TRUE if exists.<br />
		 */
		Public Static Function REF_ISSET($PARAMETER_NAME)
		{
			// Validate Parameters
			// ------------------------------------------------
			if(PHPVC_STR::VAR_IS_BLANK($PARAMETER_NAME) === TRUE)
			{
				Throw PHPVC_ERROR::VAR_RAISERROR(New Exception(PHPVC_ERROR::VAR_ARGUMENT_EXCEPTION_NULL("PARAMETER_NAME", False)));
			}
			// ------------------------------------------------
				
			// Actual Function
			// ------------------------------------------------
			try
			{
				if
				(
					isset($_GET[$PARAMETER_NAME]) ||
					isset($_POST[$PARAMETER_NAME]) ||
					(
						isset($_FILES[$PARAMETER_NAME]) &&
						PHPVC_STR::VAR_IS_BLANK($_FILES[$PARAMETER_NAME]["tmp_name"]) === false
					)
				)
				{
					return true;
				}
				else
				{
					return false;
				}
			}
			catch(Exception $ERR)
			{
				PHPVC_LOG::VAR_REPORT_ERROR($ERR, 0);
				Throw $ERR;
			}
			// ------------------------------------------------
		}
		
		
		/**
		 * Checks if the parameters exist in either POST/GET request.
		 * @param String[] $PARAMETER_SET <br />Collection of parameter names to locate.<br />
		 * @param Boolean $RETRUN_TRUE_ON_ANY_MATCHES [Optional]<br />If TRUE, returns TRUE on any matches found. [Default: FALSE]<br />
		 * @return Boolean <br />Returns TRUE if match(es) found.<br />
		 */
		Public Static Function REF_ISSET_IN_ARRAY(array $PARAMETER_SET, $RETRUN_TRUE_ON_ANY_MATCHES = false)
		{
			// Validate Parameters
			// ------------------------------------------------
			if($PARAMETER_SET == NULL)
			{
				Throw PHPVC_ERROR::VAR_RAISERROR(New Exception(PHPVC_ERROR::VAR_ARGUMENT_EXCEPTION_NULL("PARAMETER_SET", False)));
			}
			// ------------------------------------------------
			
			
			// Actual Function
			// ------------------------------------------------
			try
			{
				$ARR_CTR = 0;
				while($ARR_CTR < Count($PARAMETER_SET))
				{
					if
					(
						isset($_GET[$PARAMETER_SET[$ARR_CTR]]) ||
						isset($_POST[$PARAMETER_SET[$ARR_CTR]]) ||
						(
							isset($_FILES[$PARAMETER_SET[$ARR_CTR]]) &&
							PHPVC_STR::VAR_IS_BLANK($_FILES[$PARAMETER_SET[$ARR_CTR]]["tmp_name"]) === false
						)
					)
					{
						if($RETRUN_TRUE_ON_ANY_MATCHES === true)
						{
							return true;
						}
					}
					else
					{
						if($RETRUN_TRUE_ON_ANY_MATCHES === false)
						{
							return false;
						}
					}
					$ARR_CTR ++;
				}
		
				if($RETRUN_TRUE_ON_ANY_MATCHES === True || Count($PARAMETER_SET) <= 0)
				{
					Return False;
				}
				else
				{
					Return True;
				}
			}
			Catch(Exception $ERR)
			{
				PHPVC_LOG::VAR_REPORT_ERROR($ERR, 0);
				Throw $ERR;
			}
			// ------------------------------------------------
		}
		
		
		/**
		 * Read the value of [$_GET, $_POST, $_FILES]parameter exists or not. If not, returns NULL.
		 * @param String $PARAMETER_SET <br />Name of the parameter to read.<br />
		 * @param Boolean $AUTO_TRIM [Optional]<br />If TRUE, it trims the value. Will not work on $_FILES parameter. [Default : TRUE]<br />
		 * @return String or String() <br />Returns the value of parameter.<br />
		 */
		Public Static Function REF_READ($PARAMETER_NAME, $AUTO_TRIM = True)
		{
			try
			{
				if(isset($_GET[$PARAMETER_NAME]))
				{
					if($AUTO_TRIM === TRUE)
					{
						if(is_array($_GET[$PARAMETER_NAME]))
						{
							Return PHPVC_STR::VAR_FIX_ARRAY($_GET[$PARAMETER_NAME]);
						}
						else
						{
							Return PHPVC_STR::VAR_FIX($_GET[$PARAMETER_NAME]);
						}
					}
					else
					{
						Return $_GET[$PARAMETER_NAME];
					}
				}
				
				// ..........................................
				
				else if(isset($_POST[$PARAMETER_NAME]))
				{
					if($AUTO_TRIM === TRUE)
					{
						if(is_array($_POST[$PARAMETER_NAME]))
						{
							Return PHPVC_STR::VAR_FIX_ARRAY($_POST[$PARAMETER_NAME]);
						}
						else
						{
							Return PHPVC_STR::VAR_FIX($_POST[$PARAMETER_NAME]);
						}
					}
					else
					{
						Return $_POST[$PARAMETER_NAME];
					}
				}
				else if(isset($_FILES[$PARAMETER_NAME]))
				{
					return $_FILES[$PARAMETER_NAME];
				}
				else
				{
					Return NULL;
				}
			}
			catch(Exception $ERR)
			{
				PHPVC_LOG::VAR_REPORT_ERROR($ERR, 0);
				Throw $ERR;
			}
		}
		
		
		/**
		 * Checks if the forwarded parameter is consists of an array or not.
		 * @return boolean <br />Returns TRUE if ANY of the array item contains an array.
		 */
		Public Static Function REF_IS_ARRAY()
		{
			Try
			{
				$ARRAY_KEY = '';
				$ARRAY_CTR = 0;
				
				if(isset($_GET) && is_array($_GET))
				{
					while($ARRAY_CTR < count($_GET))
					{
						$ARRAY_KEY = array_keys($_GET)[$ARRAY_CTR];
						if(isset($_GET[$ARRAY_KEY]) && is_array($_GET[$ARRAY_KEY]))
						{
							return true;
						}
						$ARRAY_CTR += 1;
					}
				}
				
				$ARRAY_CTR = 0;
				if(isset($_POST) && is_array($_POST))
				{
					while($ARRAY_CTR < count($_POST))
					{
						$ARRAY_KEY = array_keys($_POST)[$ARRAY_CTR];
						if(isset($_POST[$ARRAY_KEY]) && is_array($_POST[$ARRAY_KEY]))
						{
							return true;
						}
						$ARRAY_CTR += 1;
					}
				}
				
				return false;
			}
			Catch(Exception $ERR)
			{
				PHPVC_LOG::VAR_REPORT_ERROR($ERR, 0);
				Throw $ERR;
			}
		}
		
		/**
		 * Returns the maximum count of request value array (up to 30k limit)
		 * @return integer <br />Array count.
		 */
		Public Static Function REF_ARRAY_COUNT()
		{
			Try
			{
				$ARRAY_KEY = '';
				$MAX_INDEX = 0;
				$ARRAY_CTR = 0;
				
				if(isset($_GET) && is_array($_GET))
				{
					while($ARRAY_CTR < count($_GET) && $ARRAY_CTR <= 30000)
					{
						$ARRAY_KEY = array_keys($_GET)[$ARRAY_CTR];
						if(isset($_GET[$ARRAY_KEY]) && is_array($_GET[$ARRAY_KEY]))
						{
							if(count($_GET[$ARRAY_KEY]) > $MAX_INDEX)
							{
								$MAX_INDEX = count($_GET[$ARRAY_KEY]);
							}
						}
						$ARRAY_CTR += 1;
					}
				}
			
				// ................................
				
				$ARRAY_CTR = 0;
				if(isset($_POST) && is_array($_POST))
				{
					while($ARRAY_CTR < count($_POST) && $ARRAY_CTR <= 30000)
					{
						$ARRAY_KEY = array_keys($_POST)[$ARRAY_CTR];
						if(isset($_POST[$ARRAY_KEY]) && is_array($_POST[$ARRAY_KEY]))
						{
							if(count($_POST[$ARRAY_KEY]) > $MAX_INDEX)
							{
								$MAX_INDEX = count($_POST[$ARRAY_KEY]);
							}
						}
						$ARRAY_CTR += 1;
					}
				}
			
				return $MAX_INDEX;
			}
			Catch(Exception $ERR)
			{
				PHPVC_LOG::VAR_REPORT_ERROR($ERR, 0);
				Throw $ERR;
			}
		}
	}
?>