<?php
/* PageCookery Framework
*
* Author: Explon
*
* Copyright (C) 2008 Explon <http://pagecookery.com>
*/

class Helper
{	
	static function NoCacheHeader($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 . '');
	}
	
	static function ForceDownloadHeader($filename, $filesize, $modifytime = 0)
	{
		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) . '"';
			}
		}
		
		$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; ' . $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);
			}
		}
	}
	
	static function BakeCookie($name, $value = '', $expire = 0, $path = '', $domain = '', $secure = false)
	{
		if (!$domain)
		{
			// Don't use a cfg value for the domain, will break mirrored sites
			$currentDomain = preg_replace('/(^www\.|:\d+$)/', '', (!empty($_SERVER["HTTP_HOST"]) AND $_SERVER["HTTP_HOST"] != $_SERVER['SERVER_NAME']) ? $_SERVER["HTTP_HOST"] : $_SERVER['SERVER_NAME']);
		
			if (!preg_match('/(?:\d{1,3}\.){3}\d{1,3}/', $currentDomain) AND $currentDomain != 'localhost' AND !self::ValidIP($currentDomain))
			{
				$domain = '.' . $currentDomain; // add . to allow subdomains of this domain to share this cookie
			}
		}
		
		return setcookie(COOKIE_PREFIX . $name, $value, $expire, $path, $domain, $secure);
	}
	
	static function GetCookie($name)
	{
		if (isset($_COOKIE[COOKIE_PREFIX . $name]))
		{
			return Format::Safe($_COOKIE[COOKIE_PREFIX . $name]);
		}
		
		return false;
	}
		
	// #############################################################################
	/**
	* 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
	*/
	static function IsBrowser($browser, $version = 0)
	{
		static $is;
		
		if (!is_array($is))
		{
			$useragent = strtolower(self::UserAgent());
			
			$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;
	}
	
	// --------------------------------------------------------------------
	/**
		 * Fetch the IP Address
		 *
		 * @access	public
		 * @return	string
	*/
	static function FetchIP()
	{
		if ($_SERVER['HTTP_X_FORWARDED_FOR'] AND self::ValidIP($_SERVER['HTTP_X_FORWARDED_FOR']))
		{
			$ip_address = $_SERVER['HTTP_X_FORWARDED_FOR'];
		}
		else if ($_SERVER['REMOTE_ADDR'] AND $_SERVER['HTTP_CLIENT_IP'])
		{
			$ip_address = $_SERVER['HTTP_CLIENT_IP'];
		}
		else if ($_SERVER['REMOTE_ADDR'])
		{
			$ip_address = $_SERVER['REMOTE_ADDR'];
		}
		else if ($_SERVER['HTTP_CLIENT_IP'])
		{
			$ip_address = $_SERVER['HTTP_CLIENT_IP'];
		}
	
		if ($ip_address === FALSE)
		{
			$ip_address = '0.0.0.0';
			
			return $ip_address;
		}
	
		if (strstr($ip_address, ','))
		{
			$x = explode(',', $ip_address);
			$ip_address = end($x);
		}
	
		return $ip_address;
	}
	
	// --------------------------------------------------------------------
	/**
		 * User Agent
		 *
		 * @access	public
		 * @return	string
	*/
	
	static function UserAgent()
	{
		$user_agent = ( ! isset($_SERVER['HTTP_USER_AGENT'])) ? FALSE : $_SERVER['HTTP_USER_AGENT'];
	
		return $user_agent;
	}
	
	static function RemoveDir($dir)
	{
	    $result = false;
	    
	    if (!is_dir($dir))
	    {
	        return false;
	    }
	    
	    $handle = opendir($dir);
	    
	    while (($file = readdir($handle)) !== false)
	    {
	        if ($file != '.' AND $file != '..')
	        {
	            $location = $dir . DIRECTORY_SEPARATOR . $file;
	            is_dir($location) ? self::RemoveDir($location) : unlink($location);
	        }
	    }
	    
	    closedir($handle);
	    
	    return rmdir($dir) ? true : false;
	}
	
	static function PrintJavaScript($script, $return = false)
	{
		if ($return)
		{
			return script_tag($script, TRUE);
		}
		else
		{
			header('Content-Type: text/html; charset=utf-8');
			
			echo script_tag($script, TRUE);
			exit;
		}
	}
	
	static function ValidEmail($address)
	{
		return (!preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $address)) ? FALSE : TRUE;
	}
	
	// --------------------------------------------------------------------

	/**
	 * Valid Base64
	 *
	 * Tests a string for characters outside of the Base64 alphabet
	 * as defined by RFC 2045 http://www.faqs.org/rfcs/rfc2045
	 *
	 * @access	public
	 * @param	string
	 * @return	bool
	 */
	static function ValidBase64($str)
	{
		return (bool) ! preg_match('/[^a-zA-Z0-9\/\+=]/', $str);
	}
	
	static function SwfUploadError($message)
	{
		//set_status_header(500);
		echo '<b style="color:red">' . $message . '</b>';
		exit;
	}
	
	static function SendMail($sendto, $subject, $message, $name = 'PageCookery', $from = 'noreply@mail.com', $replyto = '')
	{		
		//date_default_timezone_set(date_default_timezone_get());
		
		require_once(COOKERY_FRAMEWORK_DIR . 'lib/phpMailer/class.phpmailer.php');
		
		$PHPMail = new PHPMailer();
		
		if (MAIL_SMTP === TRUE)
		{
			$PHPMail->IsSMTP();
			
			if (MAIL_SMTP_SSL === TRUE)
			{
				$PHPMail->SMTPSecure = 'ssl';
			}
			
			$PHPMail->Host = MAIL_SMTP_HOST;
			$PHPMail->Port = MAIL_SMTP_PORT;
			
			if (defined('MAIL_SMTP_USER'))
			{
				$PHPMail->SMTPAuth = TRUE;
				
				$PHPMail->Username = MAIL_SMTP_USER;
				$PHPMail->Password = MAIL_SMTP_PASSWORD;
			}
		}
		
		$PHPMail->CharSet = 'UTF-8';
		$PHPMail->Encoding = 'base64';
		$PHPMail->FromName = $name;
		$PHPMail->From = strtolower($from);
		
		$PHPMail->AddAddress(strtolower($sendto));
		
		if ($replyto AND $from != $replyto)
		{
			$PHPMail->AddReplyTo(strtolower($replyto));
		}
		
		$PHPMail->IsHTML(TRUE);
		
		$PHPMail->Subject = MAIL_SUBJECT_PREFIX . $subject;
		
		$PHPMail->AltBody = strip_tags(str_ireplace(array('<br>', '<br />'), "\n", $message));
		
		if (!strstr($message, '<br />') AND !strstr($message, '<p>'))
		{
			$message = nl2br($message);
		}
		
		if (defined('EMAIL_TEMPLATE'))
		{
			$message = str_replace('{$mail_content}', $message, file_get_contents(EMAIL_TEMPLATE));
		}
		
		$PHPMail->MsgHTML($message);
				
		return $PHPMail->Send();
	}
		
	static function ValidURL($url)
	{
		if (trim($url) == '')
		{
			return false;
		}
		
		$url = strtolower($url);
		
		if (substr($url, 0, 7) != 'http://' AND substr($url, 0, 8) != 'https://')
		{
			return 'http://' . $url;
		}
		
		return $url;
	}
	
	/**
	 * Validate IP Address
	 *
	 * Updated version suggested by Geert De Deckere
	 * 
	 * @access	public
	 * @param	string
	 * @return	string
	 */
	static function ValidIP($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;
	}
	
	static function GetFileExt($filename)
	{
		$filename = explode('.', $filename);
		
		$ext_count = sizeof($filename) - 1;
		
		if ($filename[$ext_count] == 'jpeg' OR $filename[$ext_count] == 'jpe')
		{
			$filename[$ext_count] = 'jpg';
		}
		
		if ($filename[$ext_count] == 'htm')
		{
			$filename[$ext_count] = 'html';
		}
		
		return strtolower($filename[$ext_count]);
	}
	
	static function ArraySearch($needle, $haystack)
	{
		$length = strlen($needle);
		
	    foreach($haystack AS $key => $value)
		{
			if (is_array($value))
			{
				foreach($value AS $_key => $_value)
				{
					if (substr(strtolower($_value), 0, $length) == substr(strtolower($needle), 0, $length))
					{
						$found[] = $_value;
			        }
					else if (strstr(substr(strtolower($_value), 0, $length * 2), $needle))
					{
						$found[] = $_value; 
					}
				}
			}
			else
			{
				if (substr(strtolower($value), 0, $length) == substr(strtolower($needle), 0, $length))
				//if (similar_text(substr(strtolower($value), 0, $length), substr(strtolower($needle), 0, $length)) > 9)
				{
					$found[] = $value;
		        }
				else if (strstr(substr(strtolower($value), 0, $length * 2), $needle))
				{
					$found[] = $value; 
				}
			}
	    } 
	    
		if (is_array($found))
		{
			return $found;
		}
		
		return false;
	}
	
	static function IsSearchBot()
	{
		$user_agent = strtolower(self::UserAgent());
		
		$identify = array(
			'googlebot',
			'adsbot-google',
			'gsa-crawler',
			'mediapartners-google',
			'baiduspider',
			'yahoo! slurp',
			'inktomi',
			'msnbot',
			'yodaobot',
			'outfoxbot',
			'sogou spider',
			'sosospider',
			'iaskspider',
			'naverrobot'
		);
		
		foreach ($identify AS $key => $tag)
		{
			if (strstr($user_agent, $tag))
			{
				return true;
			}
		}
		
		return false;
	}
}
