<?php
/*
+--------------------------------------------------------------------------
|   TanyaCMS - Question and Answer Sofware
|   -----------------------------------------------------------------------
|   by fbschool dev team
|   (c) 2011 - 2012 FBSCHOOL
|   http://www.fbschool.com/tanyacms
|   -----------------------------------------------------------------------
|   This is NOT a freeware, use is subject to license terms
|   Support: 13455n@gmail.com
+--------------------------------------------------------------------------
*/

class HTTP
{

	/**
	 * NO CACHE File Header
	 * 
	 * @param string  $type
	 * @param string $charset
	 */
	public static function no_cache_header($type = 'text/html', $charset = 'utf-8')
	{
		header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
		header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); // always modified
		header('Cache-Control: no-cache, must-revalidate'); // HTTP/1.1
		header('Pragma: no-cache');
		header('Content-Type: ' . $type . '; charset=' . $charset . '');
	}

	/**
	 * Get COOKIE
	 * 
	 * @param string $name
	 */
	public static function get_cookie($name)
	{
		if (isset($_COOKIE[GET_COOKIE_PREFIX . $name]))
		{
			return $_COOKIE[GET_COOKIE_PREFIX . $name];
		}
		
		return false;
	}

	/**
	 * Settings COOKIE
	 * @param string $name
	 * @param string $value
	 * @param int $expire
	 * @param string $path
	 * @param string $domain
	 * @param string $secure
	 */
	public static function set_cookie($name, $value = '', $expire = null, $path = '/', $domain = null, $secure = false)
	{
		if (! $domain and GET_COOKIE_DOMAIN)
		{
			$domain = GET_COOKIE_DOMAIN;
		}
		
		return setcookie(GET_COOKIE_PREFIX . $name, $value, $expire, $path, $domain, $secure);
	}

	public static function error_404()
	{
		header('HTTP/1.1 404 Not Found');
		
		TPL::output('global/error_404');
		die();
	}

	/**
	 * Validate IP Address
	 *
	 * Updated version suggested by Geert De Deckere
	 * 
	 * @access	public
	 * @param	string
	 * @return	string
	 */
	public static function valid_ip($ip)
	{
		$ip_segments = explode('.', $ip);
		
		// Always 4 segments needed
		if (count($ip_segments) != 4)
		{
			return FALSE;
		}
		// IP can not start with 0
		if (substr($ip_segments[0], 0, 1) == '0')
		{
			return FALSE;
		}
		// Check each segment
		foreach ($ip_segments as $segment)
		{
			// IP segments must be digits and can not be 
			// longer than 3 digits or greater then 255
			if (preg_match("/[^0-9]/", $segment) or $segment > 255 or strlen($segment) > 3)
			{
				return FALSE;
			}
		}
		
		return TRUE;
	}

	public static function parse_redirect_url($url)
	{
		$url = trim($url);
		
		if (substr($url, 0, 1) == '?')
		{
			$url = get_setting('base_url') . $url;
		}
		else if (substr($url, 0, 1) == '/')
		{
			$url = get_js_url($url);
		}
		
		return $url;
	}

	/**
	 * Redirect URL
	 * 
	 * @param string $url
	 */
	public static function redirect($url)
	{
		if ($url = HTTP::parse_redirect_url($url))
		{
			header('Location: ' . $url);
			die();
		}
	}
	
	static function download_filename_header($filename)
	{
		if (preg_match('~&#([0-9]+);~', $filename))
		{
			//if (function_exists('iconv'))
			//{
				$filename_conv = @iconv('utf-8', 'UTF-8//IGNORE', $filename);
				
				if ($filename_conv !== false)
				{
					$filename = $filename_conv;
				}
			//}
		
			$filename = preg_replace(
				'~&#([0-9]+);~e',
				"convert_int_to_utf8('\\1')",
				$filename
			);
		}
		
		$filename_charset = 'utf-8';
		
		$filename = preg_replace('#[\r\n]#', '', $filename);
		
		// Opera and IE have not a clue about this, mozilla puts on incorrect extensions.
		if (self::IsBrowser('mozilla'))
		{
			$filename = "filename*=" . $filename_charset . "''" . rawurlencode($filename);
			//$filename = "filename==?'utf-8'?B?" . base64_encode($filename) . "?=";
		}
		else
		{
			// other browsers seem to want names in UTF-8
			if ($filename_charset != 'utf-8' AND function_exists('iconv'))
			{
				$filename_conv = iconv($filename_charset, 'UTF-8//IGNORE', $filename);
				
				if ($filename_conv !== false)
				{
					$filename = $filename_conv;
				}
			}
		
			if (self::IsBrowser('opera') OR self::IsBrowser('konqueror') OR self::IsBrowser('safari'))
			{
				// Opera / Konqueror does not support encoded file names
				$filename = 'filename="' . str_replace('"', '', $filename) . '"';
			}
			else if (self::IsBrowser('ie'))
			{
				$filename = 'filename="' . str_replace('+', ' ', urlencode($filename)) . '"';
			}
			else
			{
				// encode the filename to stay within spec
				$filename = 'filename="' . rawurlencode($filename) . '"';
			}
		}
		
		return $filename;
	}
	
	static function force_download_header($filename, $filesize = 0, $modifytime = 0)
	{
		$range = 0;
		
		if (!empty($_SERVER['HTTP_RANGE'])) {
			list($range) = explode('-',(str_replace('bytes=', '', $_SERVER['HTTP_RANGE'])));
		}
		
		ob_end_clean();
		
		header("Cache-Control: no-cache, must-revalidate");
		header("Pragma: no-cache");
		header('Date: ' . gmdate('D, d M Y H:i:s', $modifytime) . ' GMT');
		header('Content-Disposition: attachment; ' . self::download_filename_header($filename));
		//header("Content-Type: application/octet-stream");	// has bug with IE
		header('HTTP/1.1 206 Partial Content');
		header('Accept-Ranges: bytes');
		
		if ($filesize)
		{
			if (!empty($_SERVER['HTTP_RANGE']))
			{
				$rangesize = ($filesize - $range) > 0 ?  ($filesize - $range) : 0;
			
				header('Content-Length: ' . $rangesize);
				header('Content-Range: bytes ' . $range . '-' . ($filesize - 1) . '/' . ($filesize));
			}
			else
			{			
				header('Content-Length: ' . $filesize);
			}
		}
	}

	/**
	 * Browser detection system - returns whether or not the visiting browser is the one specified
	 *
	 * @param	string	Browser name (opera, ie, mozilla, firebord, firefox... etc. - see $is array)
	 * @param	float	Minimum acceptable version for true result (optional)
	 *
	 * @return	boolean
	 */
	public static function IsBrowser($browser, $version = 0)
	{
		static $is;
		
		if (! is_array($is))
		{
			$useragent = strtolower($_SERVER['HTTP_USER_AGENT']);
			
			$is = array(
				'opera' => 0, 
				'ie' => 0, 
				'mozilla' => 0, 
				'firebird' => 0, 
				'firefox' => 0, 
				'camino' => 0, 
				'konqueror' => 0, 
				'safari' => 0, 
				'webkit' => 0, 
				'webtv' => 0, 
				'netscape' => 0, 
				'mac' => 0
			);
			
			// detect opera
			# Opera/7.11 (Windows NT 5.1; U) [en]
			# Mozilla/4.0 (compatible; MSIE 6.0; MSIE 5.5; Windows NT 5.0) Opera 7.02 Bork-edition [en]
			# Mozilla/4.0 (compatible; MSIE 6.0; MSIE 5.5; Windows NT 4.0) Opera 7.0 [en]
			# Mozilla/4.0 (compatible; MSIE 5.0; Windows 2000) Opera 6.0 [en]
			# Mozilla/4.0 (compatible; MSIE 5.0; Mac_PowerPC) Opera 5.0 [en]
			if (strpos($useragent, 'opera') !== false)
			{
				preg_match('#opera(/| )([0-9\.]+)#', $useragent, $regs);
				$is['opera'] = $regs[2];
			}
			
			// detect internet explorer
			# Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; Q312461)
			# Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3705)
			# Mozilla/4.0 (compatible; MSIE 5.22; Mac_PowerPC)
			# Mozilla/4.0 (compatible; MSIE 5.0; Mac_PowerPC; e504460WanadooNL)
			if (strpos($useragent, 'msie ') !== false and ! $is['opera'])
			{
				preg_match('#msie ([0-9\.]+)#', $useragent, $regs);
				$is['ie'] = $regs[1];
			}
			
			// detect macintosh
			if (strpos($useragent, 'mac') !== false)
			{
				$is['mac'] = 1;
			}
			
			// detect safari
			# Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en-us) AppleWebKit/74 (KHTML, like Gecko) Safari/74
			# Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/51 (like Gecko) Safari/51
			if (strpos($useragent, 'applewebkit') !== false and $is['mac'])
			{
				preg_match('#applewebkit/(\d+)#', $useragent, $regs);
				$is['webkit'] = $regs[1];
				
				if (strpos($useragent, 'safari') !== false)
				{
					preg_match('#safari/([0-9\.]+)#', $useragent, $regs);
					$is['safari'] = $regs[1];
				}
			}
			
			// detect konqueror
			# Mozilla/5.0 (compatible; Konqueror/3.1; Linux; X11; i686)
			# Mozilla/5.0 (compatible; Konqueror/3.1; Linux 2.4.19-32mdkenterprise; X11; i686; ar, en_US)
			# Mozilla/5.0 (compatible; Konqueror/2.1.1; X11)
			if (strpos($useragent, 'konqueror') !== false)
			{
				preg_match('#konqueror/([0-9\.-]+)#', $useragent, $regs);
				$is['konqueror'] = $regs[1];
			}
			
			// detect mozilla
			# Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.4b) Gecko/20030504 Mozilla
			# Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.2a) Gecko/20020910
			# Mozilla/5.0 (X11; U; Linux 2.4.3-20mdk i586; en-US; rv:0.9.1) Gecko/20010611
			if (strpos($useragent, 'gecko') !== false and ! $is['safari'] and ! $is['konqueror'])
			{
				preg_match('#gecko/(\d+)#', $useragent, $regs);
				$is['mozilla'] = $regs[1];
				
				// detect firebird / firefox
				# Mozilla/5.0 (Windows; U; WinNT4.0; en-US; rv:1.3a) Gecko/20021207 Phoenix/0.5
				# Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.4b) Gecko/20030516 Mozilla Firebird/0.6
				# Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.4a) Gecko/20030423 Firebird Browser/0.6
				# Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.6) Gecko/20040206 Firefox/0.8
				if (strpos($useragent, 'firefox') !== false or strpos($useragent, 'firebird') !== false or strpos($useragent, 'phoenix') !== false)
				{
					preg_match('#(phoenix|firebird|firefox)( browser)?/([0-9\.]+)#', $useragent, $regs);
					$is['firebird'] = $regs[3];
					
					if ($regs[1] == 'firefox')
					{
						$is['firefox'] = $regs[3];
					}
				}
				
				// detect camino
				# Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en-US; rv:1.0.1) Gecko/20021104 Chimera/0.6
				if (strpos($useragent, 'chimera') !== false or strpos($useragent, 'camino') !== false)
				{
					preg_match('#(chimera|camino)/([0-9\.]+)#', $useragent, $regs);
					$is['camino'] = $regs[2];
				}
			}
			
			// detect web tv
			if (strpos($useragent, 'webtv') !== false)
			{
				preg_match('#webtv/([0-9\.]+)#', $useragent, $regs);
				$is['webtv'] = $regs[1];
			}
			
			// detect pre-gecko netscape
			if (preg_match('#mozilla/([1-4]{1})\.([0-9]{2}|[1-8]{1})#', $useragent, $regs))
			{
				$is['netscape'] = "$regs[1].$regs[2]";
			}
		}
		
		// sanitize the incoming browser name
		$browser = strtolower($browser);
		if (substr($browser, 0, 3) == 'is_')
		{
			$browser = substr($browser, 3);
		}
		
		// return the version number of the detected browser if it is the same as $browser
		if ($is["$browser"])
		{
			// $version was specified - only return version number if detected version is >= to specified $version
			if ($version)
			{
				if ($is["$browser"] >= $version)
				{
					return $is["$browser"];
				}
			}
			else
			{
				return $is["$browser"];
			}
		}
		
		// if we got this far, we are not the specified browser, or the version number is too low
		return 0;
	}

	/**
	 * Make an HTTP request
	 *
	 * @return string API results
	 * @ignore
	 */
	public static function request($url, $method, $postfields = NULL, $headers = array())
	{
		$ci = curl_init();
		
		curl_setopt($ci, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
		curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, 30);
		curl_setopt($ci, CURLOPT_TIMEOUT, 30);
		curl_setopt($ci, CURLOPT_RETURNTRANSFER, TRUE);
		curl_setopt($ci, CURLOPT_ENCODING, "");
		curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, false);
		curl_setopt($ci, CURLOPT_HEADER, FALSE);
		
		switch ($method)
		{
			case 'POST' :
				curl_setopt($ci, CURLOPT_POST, TRUE);
				if (! empty($postfields))
				{
					curl_setopt($ci, CURLOPT_POSTFIELDS, $postfields);
					$this->postdata = $postfields;
				}
				break;
			case 'DELETE' :
				curl_setopt($ci, CURLOPT_CUSTOMREQUEST, 'DELETE');
				if (! empty($postfields))
				{
					$url = "{$url}?{$postfields}";
				}
		}
		
		$headers[] = "API-RemoteIP: " . $_SERVER['REMOTE_ADDR'];
		
		curl_setopt($ci, CURLOPT_URL, $url);
		curl_setopt($ci, CURLOPT_HTTPHEADER, $headers);
		curl_setopt($ci, CURLINFO_HEADER_OUT, TRUE);
		$response = curl_exec($ci);
		curl_close($ci);
		
		return $response;
	}
}