Basic HTML5 Page Layout Structure And Notes

The basic structure is…

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
Hello World
</body>
</html>

Notes:

HTML5 assumes all script types are “text/javaScript” and all stylesheet types are “text/css”.

So...
<script type="text/javascript" src="foo.js"></script>
<link rel="stylesheet" type="text/css" href="bar.css">
Is the same as...
<script src="foo.js"></script>
<link rel="stylesheet" href="bar.css">

Posted in HTML5, Uncategorized | Leave a comment

Freestyle Disk Frisbee: “Touch Free Hovering” Trick

Here is a trick I invented. As far as I know, I am the first and only person to do this…

Posted in Frisbee Disk | Leave a comment

Henderson State Park Time Lapse Videos (Destin FL)

Here are a few time lapse videos I made using my Droid Bionic phone.

Posted in Weather | Tagged | Leave a comment

Waterspout over Choctawhatchee Bay

Posted in Weather | Leave a comment

PHP POP3MAIL Email Telnet Class (without php_imap.dll)

I needed a POP3 client that would retrieve mail from POP3 server to a shared hosting account on Godaddy. As you may know, godaddy disables the php_imap.dll for php. This effectively makes the retrieval of email very difficult. Until now… :) I have mashed up some scripts from phpclasses.com and come up with a POP3MAIL class that retrieves emails and parses the email structure into a php object. The magic is done with Telnet commands sent over a fsockopen() connection. The code is not perfect but it serves the purpose I needed (to retrieve all images in emails). I have posted it here to help anyone who might need POP3 access from Goddady shared hosting. Please see the POP3MAIL.TEST.PHP file for a working example of the script.

POP3MAIL.TEST.PHP:

<?php
 
        //  EDIT THE FOLLOWING 4 VARS....
	$pop3ServerAddress = "";
	$pop3ServerPort = "";
	$pop3UserName = "";
	$pop3UserPass = "";
 
	error_reporting(E_ALL ^ E_DEPRECATED);
	$time_start = microtime(true);		
	include_once("POP3MAIL.CLASS.PHP");
	set_time_limit(120);
 
	$left = "";
	$right = "";
	$footer = "";	
	$footer .= "<br>Max Execution Time: " . ini_get('max_execution_time');
 
	$pop3 = new POP3MAIL();
 
	//////////////////////////////////////////////////////////////////////////
	// OPEN CONNECTION
	if($pop3->open($pop3ServerAddress, $pop3ServerPort))
	{
		$left .= "<br>Connection Opened";
	}
	else
	{
		$left .= "<br>Problem Opening Connection: " . $pop3->getError();
		exit;
	} 
 
	//////////////////////////////////////////////////////////////////////////
	// LOG IN
	if ($pop3->login($pop3UserName, $pop3UserPass))
	{
		$left .= "<br>Log In Successful";
	}
	else
	{
		$left .= "<br>Problem Logging In<br>" . $pop3->error;
		exit;
	}
 
	//////////////////////////////////////////////////////////////////////////
	// MESSAGE COUNT
	$msgCount=$pop3->getEmailCount();
	$left .= "<br>Message Count: " . $msgCount;
	$left .= $pop3->getError();	
 
	//////////////////////////////////////////////////////////////////////////
	// DELETE EMAIL
	if (isset($_GET["delete_msg"]))
	{
		$response = $pop3->deleteMessage($_GET["delete_msg"]);
 
		if ($response != false)
			$right .= "<script>alert('Message Deleted');</script>";
		else
			$right .= "<br>".$pop3->getError();
	}	
 
	//////////////////////////////////////////////////////////////////////////
	// NOOP
	//$response=$pop3->noop();
	//$right .= "<hr>NOOP: ".$response;
	//$right .= $pop3->getError();
 
	//////////////////////////////////////////////////////////////////////////
	// STATUS
	//$response=$pop3->getStatus();
	//$right .= "<hr>STAT: ".$response;
	//$right .= $pop3->getError();
 
	//////////////////////////////////////////////////////////////////////////
	// LIST
	//$response=$pop3->getList();
	//$right .= "<hr>LIST: ".$response;
	//$right .= $pop3->getError();
 
	//////////////////////////////////////////////////////////////////////////
	// MAKE EMAILS CLICKABLE
	$response=$pop3->getList();
	$res_arr = explode("\n", $response);
 
	for ($i = 1; $i < count($res_arr) - 2; $i++)
	{
		$bytes = explode(" " ,trim($res_arr[$i]));
		$left .= "<br><a href='?delete_msg=$i' onclick='return confirm(\"Delete Email #$i?\");'>Delete</a>";
		$left .= " <a href='?view_msg=$i'>View Email #$i (".formatBytes($bytes[1]).")</a> ";
	}
 
	//////////////////////////////////////////////////////////////////////////
	// GET EMAIL
	if (isset($_GET["view_msg"]))
	{
		if ($response = $pop3->getEmail($_GET["view_msg"]))
		{		
			$right .= "<hr><b>Email #: ".$_GET["view_msg"]."</b>";				
			//$right .= "<br><textarea cols=80 rows=10>$response</textarea><br>";
 
			$mimedecoder=new MIMEDECODE($response);								
			//$right .= "<br><textarea cols=80 rows=10>".print_r($mimedecoder, true)."</textarea><br>";
 
			$right .= "<br><b>To:</b> ".$mimedecoder->get_header("to");
			$right .= "<br><b>From:</b> ".$mimedecoder->get_header("from");
			$right .= "<br><b>From Email:</b> ".$mimedecoder->getFromEmail();
			$right .= "<br><b>Date:</b> ".$mimedecoder->get_header("date");
			$right .= "<br><b>Subject:</b> ".$mimedecoder->get_header("subject");
			$right .= "<br><b>Body:</b><br> ".$mimedecoder->getBody();
 
			$right .= "<br><b>Images:</b>";
 
			$image_arr = $mimedecoder->getImageObjects();			
 
			foreach($image_arr as $obj)
			{				
				$right .= "<br>".formatImageName($mimedecoder->getImageName($obj));
				$right .= "<br>".$mimedecoder->saveImageToDisk($obj, createRandomString(8) . "__" . formatImageName($mimedecoder->getImageName($obj)));
			}		
 
			//$right .= "<br><textarea cols='80' rows='10'>";
			//$right .= var_dump($image_arr);
			//$right .= "</textarea>";							
		}
		else
		{
			echo $pop3->getError();
			exit;
		}
	}
 
	if (!$pop3->close())
		$right .= "<hr>ERROR: Problem Closing Connection!!";
 
 
 
	////////////////////////////////////////////////////////////////////
	// FUNCTIONS
 
	function formatBytes($bytes, $precision = 2) { 
		$units = array('B', 'KB', 'MB', 'GB', 'TB'); 
 
		$bytes = max($bytes, 0); 
		$pow = floor(($bytes ? log($bytes) : 0) / log(1024)); 
		$pow = min($pow, count($units) - 1); 
 
		// Uncomment one of the following alternatives
		$bytes /= pow(1024, $pow);
		//$bytes /= (1 << (10 * $pow)); 
 
		return round($bytes, $precision) . ' ' . $units[$pow]; 
	} 
 
	function createRandomString($length) 
	{ 	
		$chars = "abcdefghijkmnopqrstuvwxyz023456789"; 
		srand((double)microtime()*1000000); 
		$i = 0; 
		$str = '' ; 
 
		while ($i < $length) 
		{ 
			$num = rand() % 33; 
			$tmp = substr($chars, $num, 1); 
			$str .= $tmp; 
			$i++; 
		} 
		return $str; 
	}	
 
	function formatImageName($name)
	{
		return preg_replace('@[^0-9a-z\.]+@i', '_', $name);
	}	
 
	$time_end = microtime(true);
	$time = $time_end - $time_start;
	$footer .= "<br>Execution Time: $time seconds\n";
?>
<html>
<head>
<title>POP3MAIL for PHP</title>
<style>
	body{margin:3px;padding:0px;}
	hr{margin:2px;padding:0px;border:0px;border-top:1px solid black;margin-left:0px;margin-right:0px;}
	div#wrap{width:1000px;border:2px solid black;position:relative;left:50%;margin-left:-504px;margin-top:5px;}
	div#header{width:100%;text-align:center;border:0px;border-bottom:1px solid black;}
	div#left{position:relative;float:left;width:200px;border:0px;padding:3px;}
	div#right{position:relative;float:right;width:787px;min-height:500px;padding:3px;border-left:1px solid black;}
	div#footer{clear:both;border:0px;border-top:1px solid black;text-align:center;}
</style>
</head>
<body style='font-size:12px;'>
<div id="wrap">
	<div id="header">
		<p>
			<h3 style='padding:4px;margin:0px;'>POP3MAIL for PHP</h3>
			(without php_imap.dll)
		</p>
	</div>
	<div id="left">
		<a href='?'>Home</a>
		<? echo $left; ?>
	</div>
	<div id="right">	
		<? echo $right; ?>
	</div>
	<div id="footer">
		<p>
			POP3MAIL by <a href='http://www.kevincornwell.com'>Kevin Cornwell</a>
			<? echo $footer; ?>
		</p>	
	</div>
</div>
TODO:
-body is returning the text twice
-handle pdf and other non image attachments
-render html emails as such	
</body>
</html>

POP3MAIL.CLASS.PHP

<?php
 
//  This class is based upon telnet protocols to pop3 server.
//  http://techhelp.santovec.us/pop3telnet.htm
 
	class POP3MAIL
	{
		var $host;  		// host like 127.0.0.1 or mail.yoursite.com
		var $port;  		// port default is 110 or 143
		var $user;  		// user for logon
		var $password;  	// user paswword
		var $state;   		// variable define diffrent state of connection
		var $connection; 	// handle to a open connection
		var $error;  		// error string
 
		############################################################################
		function POP3MAIL()
		{
			$this->host=NULL;
			$this->port=110;
			$this->user="";
			$this->password="";
			$this->state="DISCONNECTED";
			$this->connection=null;
			$this->error="";
		}
 
		############################################################################
		// Set host.  example: setHost("pop.yoursite.com") */	
		function setHost($host)
		{
			$this->host=$host;
		}
 
		############################################################################
		// This function set the portt example setPort(110)
		function setPort($port)
		{
			$this->port=$port;
		}
 
		############################################################################
		////This function is to retrieve the error of last operation 
		////example popmail::getError()
		function getError()
		{
			if($this->error)
				return $this->error;
		}
 
		############################################################################
		////This function is to retrieve the state of connection. 
		function getState()
		{
			return $this->state;
		}
 
		############################################################################
		///Function is used to open connection
		function open($host="",$port="")
		{
			if(!empty($host))
				$this->host=$host;
			if(!empty($port))
				$this->port=$port;
			return $this->openConnection();
		}
 
		############################################################################
		// Close the active connection
		function close()
		{
			$this->logout();
			@fclose($this->connection);
			$this->connection=null;
			$this->state="DISCONNECTED";
			return true;
		}
 
		############################################################################
		////This function is to open the connection to the server 
		function openConnection()
		{
			if($this->state!="DISCONNECTED")
			{
				$this->error = "Error: Already Connected.";
				return false;
			}
			if(empty($this->host) || empty($this->port))			
			{
				$this->error = "Error: Either HOST or PORT is undifined.";
				return false;
			}
			$this->connection = fsockopen($this->host,$this->port,$errno,$errstr);
			if(!$this->connection)
			{
				$this->error= "Could not make a connection to server , Error : $errstr ($errno)";
				return false;
			}
			$respone=$this->getLine();	
			$this->state = "AUTHORIZATION";
			return true;
		}			
 
		############################################################################
		// Send telnet command and return response string 
		// else on -ERR from server, set error message 
		// and return false.
		function SendCommand($cmd, $delimiter="\r\n")
		{	
			if($this->state=="DISCONNECTED")
			{
				$this->error= "Error(0): No Connection Found.";
				return false;
			}		
			if($this->state=="AUTHORIZATION")
			{
				$this->error = "SendCommand Error(1): User is not authorised or logged in.";
				return false;
			}
			if($this->putLine($cmd))
			{
				$response=$this->getServerResponse($delimiter);
 
				if(!$this->isOK($response))
				{
					$this->error= "SendCommand Error(2) with '$cmd': $response";
					return false;
				}
			}
			else
			{
				$this->error= "SendCommand Error(3) with '$cmd': Could not send request.";
				return false;
			}
			return $response;			
		}
 
		############################################################################
		////This function is to send the command to server
		function putLine($msg)
		{
			return @fputs($this->connection,"$msg\r\n");
		}
 
		############################################################################
		////This function is to retrieve the full response message from server
		function getServerResponse($delimeter="\r\n")
		{
			$response = "";			
			$i = 0;
 
			while($i++ < 10000000) // limit to prevent infinite loop (could be a problem for insainly large emails.
			{
				$response.=$this->getLine();
				if (strpos($response, $delimeter)>0)  //if(substr($response,strpos($response,$this->tag),strlen($this->tag))==$this->tag)
					break;
			}
			return $response;
		}
 
		############################################################################
		// This function is used to get response line from server
		function getLine()
		{
			$line = "";
 
			while(!feof($this->connection))
			{
				$line.=fgets($this->connection);
				if(strlen($line)>=2 && substr($line,-2)=="\r\n")
					return $line; //return(substr($line,0,-2));
			}
		}
 
		############################################################################
		// Function to check for "+OK" response code.	
		function isOK($rsp)
		{
			//note that we are checking against OK and not +OK
			$pos = strpos($rsp, "OK");			
 
			if ($pos === 1)  // OK must be at index position 1.
				return true;
			else
				return false;
		}
 
		############################################################################
		// Login into server
		function login($user,$pwd)
		{
			if($this->state=="DISCONNECTED")
			{
				$this->error= "Error Login(1): No Connection Found.";
				return false;
			}
 
			if($this->state=="AUTHENTICATED")
			{
				$this->error= "Error Login(2): Already Authenticated.";
				return false;
			}
			// Send USER
			if($this->putLine("USER $user"))
			{
				$response=$this->getServerResponse();
 
				if(!$this->isOK($response))
				{
					$this->error = "Error Login(3): in USER command: $response";
					return false;
				}
			}
			else
			{
				$this->error= "Error Login(4): Could not send User request.";
				return false;
			}			
			// Send PASS
			if($this->putLine("PASS $pwd"))
			{
				$response=$this->getServerResponse();
 
				if(!$this->isOK($response))
				{
					$this->error= "Error Login(5):in PASS command: $response";
					return false;
				}
			}
			else
			{
				$this->error= "Error Login(6): Could not send User request.";
				return false;
			}			
			$this->state="AUTHENTICATED";
			return true;
		}
 
		############################################################################
		/* The logout function informs the server that the client is done with the connection. */
		function logout()
		{
			return $this->SendCommand("QUIT", "\r\n");
		}
 
		############################################################################
		// Gets total number of messages on pop3 server and bytes.
		function getStatus()
		{
			return $this->SendCommand("STAT", "\r\n");
		}	
 
		############################################################################
		// Returns the list of emails and size.
		function getList()
		{
			return $this->SendCommand("LIST", "\r\n.\r\n");
		}
 
		############################################################################
		// Periodic poll.  Only return +OK if connection is still valid.
		function getEmailCount()
		{
			$rsp = $this->SendCommand("STAT", "\r\n");
			$arr = explode(" ", $rsp);
			return trim($arr[1]);
		}		
 
		############################################################################
		// Periodic poll command.  Returns "+OK" if connection is still valid.
		function noop()
		{
			return $this->SendCommand("NOOP", "\r\n");
		}		
 
		############################################################################
		//	Returns a raw email by number.
		function getEmail($msgno)
		{
			return $this->SendCommand("RETR $msgno", "\r\n.\r\n");
		}
 
		############################################################################
		// Delete message.
		function deleteMessage($msgno)
		{
			return $this->SendCommand("DELE $msgno", "\r\n");
		}	
	}
?>
 
<?php
 
	class MIMEDECODE 
	{
		//kevin
		var $_mailObjectDecoded;
	    /**
	     * The raw email to decode
	     * @var    string
	     */
	    var $_input;
 
	    /**
	     * The header part of the input
	     * @var    string
	     */
	    var $_header;
 
	    /**
	     * The body part of the input
	     * @var    string
	     */
	    var $_body;
 
	    /**
	     * If an error occurs, this is used to store the message
	     * @var    string
	     */
	    var $_error;
 
	    /**
	     * Flag to determine whether to include bodies in the
	     * returned object.
	     * @var    boolean
	     */
	    var $_include_bodies;
 
	    /**
	     * Flag to determine whether to decode bodies
	     * @var    boolean
	     */
	    var $_decode_bodies;
 
	    /**
	     * Flag to determine whether to decode headers
	     * @var    boolean
	     */
	    var $_decode_headers;
 
	    /**
	    * If invoked from a class, $this will be set. This has problematic
	    * connotations for calling decode() statically. Hence this variable
	    * is used to determine if we are indeed being called statically or
	    * via an object.
	    */
	    var $mailMimeDecode;
 
	    /**
	     * Constructor.
	     *
	     * Sets up the object, initialise the variables, and splits and
	     * stores the header and body of the input.
	     *
	     * @param string The input to decode
	     * @access public
	     */
	    function MIMEDECODE($input)
	    {
	        list($header, $body)   = $this->_split_body_header($input);
 
	        $this->_input          = $input;
	        $this->_header         = $header;
	        $this->_body           = $body;
	        $this->_decode_bodies  = true;
	        $this->_include_bodies = true;
 
	        $this->mailMimeDecode  = true;
			//kevin edit
			$this->_mailObjectDecoded = $this->decode();
	    }
 
	    /**
	     * Begins the decoding process. If called statically
	     * it will create an object and call the decode() method
	     * of it.
	     *
	     * @param array An array of various parameters that determine
	     *              various things:
	     *              include_bodies - Whether to include the body in the returned
	     *                               object.
	     *              decode_bodies  - Whether to decode the bodies
	     *                               of the parts. (Transfer encoding)
	     *              decode_headers - Whether to decode headers
	     *              input          - If called statically, this will be treated
	     *                               as the input
	     * @return object Decoded results
	     * @access public
	     */
	    function decode($params = null)
	    {
 
	        // Have we been called statically? If so, create an object and pass details to that.
	        if (!isset($this->mailMimeDecode) AND isset($params['input'])) {
 
	            $obj = new MIMEDECODE($params['input']);
	            $structure = $obj->decode($params);
 
	        // Called statically but no input
	        } elseif (!isset($this->mailMimeDecode)) {
	            return $this->_error='Called statically and no input given';
 
	        // Called via an object
	        } else {
 
	            //$this->_include_bodies = isset($params['include_bodies'])  ? $params['include_bodies']  : false;
	            //$this->_decode_bodies  = isset($params['decode_bodies'])   ? $params['decode_bodies']   : false;
	            //$this->_decode_headers = isset($params['decode_headers'])  ? $params['decode_headers']  : false;
 
	            $structure = $this->_decode($this->_header, $this->_body);
	            if ($structure === false) {
	                $structure = $this->_error;
	            }
	        }
	        return $structure;
	    }
 
	    /**
	     * Performs the decoding. Decodes the body string passed to it
	     * If it finds certain content-types it will call itself in a
	     * recursive fashion
	     *
	     * @param string Header section
	     * @param string Body section
	     * @return object Results of decoding process
	     * @access private
	     */
	    function _decode($headers, $body, $default_ctype = 'text/plain')
	    {
	        $return = new stdClass;
	        $headers = $this->_parseHeaders($headers);
 
	        foreach ($headers as $value) {
	            if (isset($return->headers[strtolower($value['name'])]) AND !is_array($return->headers[strtolower($value['name'])])) {
	                $return->headers[strtolower($value['name'])]   = array($return->headers[strtolower($value['name'])]);
	                $return->headers[strtolower($value['name'])][] = $value['value'];
 
	            } elseif (isset($return->headers[strtolower($value['name'])])) {
	                $return->headers[strtolower($value['name'])][] = $value['value'];
 
	            } else {
	                $return->headers[strtolower($value['name'])] = $value['value'];
	            }
	        }
 
	        reset($headers);
	        while (list($key, $value) = each($headers)) {
	            $headers[$key]['name'] = strtolower($headers[$key]['name']);
	            switch ($headers[$key]['name']) {
 
	                case 'content-type':
	                    $content_type = $this->_parseHeaderValue($headers[$key]['value']);
 
	                    if (preg_match('/([0-9a-z+.-]+)\/([0-9a-z+.-]+)/i', $content_type['value'], $regs)) {
	                        $return->ctype_primary   = $regs[1];
	                        $return->ctype_secondary = $regs[2];
	                    }
 
	                    if (isset($content_type['other'])) {
	                        while (list($p_name, $p_value) = each($content_type['other'])) {
	                            $return->ctype_parameters[$p_name] = $p_value;
	                        }
	                    }
	                    break;
 
	                case 'content-disposition';
	                    $content_disposition = $this->_parseHeaderValue($headers[$key]['value']);
	                    $return->disposition   = $content_disposition['value'];
	                    if (isset($content_disposition['other'])) {
	                        while (list($p_name, $p_value) = each($content_disposition['other'])) {
	                            $return->d_parameters[$p_name] = $p_value;
	                        }
	                    }
	                    break;
 
	                case 'content-transfer-encoding':
	                    $content_transfer_encoding = $this->_parseHeaderValue($headers[$key]['value']);
	                    break;
	            }
	        }
 
	        if (isset($content_type)) {
	            switch (trim(strtolower($content_type['value']))) {
	                case 'text/plain':
	                    $encoding = isset($content_transfer_encoding) ? $content_transfer_encoding['value'] : '7bit';
	                    $this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $encoding) : $body) : null;
	                    break;
	                case 'text/html':
	                    $encoding = isset($content_transfer_encoding) ? $content_transfer_encoding['value'] : '7bit';
	                    $this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $encoding) : $body) : null;
					    break;
 
	                case 'multipart/parallel':
	                case 'multipart/report': // RFC1892
	                case 'multipart/signed': // PGP
	                case 'multipart/digest':
	                case 'multipart/alternative':
	                case 'multipart/related':
	                case 'multipart/mixed':
	                    if(!isset($content_type['other']['boundary'])){
	                        $this->_error = 'No boundary found for ' . $content_type['value'] . ' part';
	                        return false;
	                    }
 
	                    $default_ctype = (strtolower($content_type['value']) === 'multipart/digest') ? 'message/rfc822' : 'text/plain';
 
	                    $parts = $this->_boundarySplit($body, $content_type['other']['boundary']);
	                    for ($i = 0; $i < count($parts); $i++) {
	                        list($part_header, $part_body) = $this->_split_body_header($parts[$i]);
	                        $part = $this->_decode($part_header, $part_body, $default_ctype);
	                        if($part === false)
	                            $part = $this->raiseError($this->_error);
	                        $return->parts[] = $part;
	                    }
	                    break;
 
	                case 'message/rfc822':
	                    $obj = &new MIMEDECODE($body);
	                    $return->parts[] = $obj->decode(array('include_bodies' => $this->_include_bodies));
	                    unset($obj);
	                    break;
 
	                default:
	                    if(!isset($content_transfer_encoding['value']))
	                        $content_transfer_encoding['value'] = '7bit';
	                    $this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $content_transfer_encoding['value']) : $body) : null;
	                    break;
	            }
 
	        } else {
	            $ctype = explode('/', $default_ctype);
	            $return->ctype_primary   = $ctype[0];
	            $return->ctype_secondary = $ctype[1];
	            $this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body) : $body) : null;
	        }
 
	        return $return;
	    }
 
	    /**
	     * Given the output of the above function, this will return an
	     * array of references to the parts, indexed by mime number.
	     *
	     * @param  object $structure   The structure to go through
	     * @param  string $mime_number Internal use only.
	     * @return array               Mime numbers
	     */
	    function &getMimeNumbers(&$structure, $no_refs = false, $mime_number = '', $prepend = '')
	    {
	        $return = array();
	        if (!empty($structure->parts)) {
	            if ($mime_number != '') {
	                $structure->mime_id = $prepend . $mime_number;
	                $return[$prepend . $mime_number] = &$structure;
	            }
	            for ($i = 0; $i < count($structure->parts); $i++) {
 
 
	                if (!empty($structure->headers['content-type']) AND substr(strtolower($structure->headers['content-type']), 0, 8) == 'message/') {
	                    $prepend      = $prepend . $mime_number . '.';
	                    $_mime_number = '';
	                } else {
	                    $_mime_number = ($mime_number == '' ? $i + 1 : sprintf('%s.%s', $mime_number, $i + 1));
	                }
 
	                $arr = &MIMEDECODE::getMimeNumbers($structure->parts[$i], $no_refs, $_mime_number, $prepend);
	                foreach ($arr as $key => $val) {
	                    $no_refs ? $return[$key] = '' : $return[$key] = &$arr[$key];
	                }
	            }
	        } else {
	            if ($mime_number == '') {
	                $mime_number = '1';
	            }
	            $structure->mime_id = $prepend . $mime_number;
	            $no_refs ? $return[$prepend . $mime_number] = '' : $return[$prepend . $mime_number] = &$structure;
	        }
 
	        return $return;
	    }
 
	    /**
	     * Given a string containing a header and body
	     * section, this function will split them (at the first
	     * blank line) and return them.
	     *
	     * @param string Input to split apart
	     * @return array Contains header and body section
	     * @access private
	     */
	    function _split_body_header($input)
	    {
	        if (preg_match("/^(.*?)\r?\n\r?\n(.*)/s", $input, $match)) {
	            return array($match[1], $match[2]);
	        }
	        $this->_error = 'Could not split header and body';
	        return false;
	    }
 
	    /**
	     * Parse headers given in $input and return
	     * as assoc array.
	     *
	     * @param string Headers to parse
	     * @return array Contains parsed headers
	     * @access private
	     */
	    function _parseHeaders($input)
	    {
 
	        if ($input !== '') {
	            // Unfold the input
	            $input   = preg_replace("/\r?\n/", "\r\n", $input);
	            $input   = preg_replace("/\r\n(\t| )+/", ' ', $input);
	            $headers = explode("\r\n", trim($input));
 
	            foreach ($headers as $value) {
	                $hdr_name = substr($value, 0, $pos = strpos($value, ':'));
	                $hdr_value = substr($value, $pos+1);
	                if($hdr_value[0] == ' ')
	                    $hdr_value = substr($hdr_value, 1);
 
	                $return[] = array(
	                                  'name'  => $hdr_name,
	                                  'value' => $this->_decode_headers ? $this->_decodeHeader($hdr_value) : $hdr_value
	                                 );
	            }
	        } else {
	            $return = array();
	        }
 
	        return $return;
	    }
 
	    /**
	     * Function to parse a header value,
	     * extract first part, and any secondary
	     * parts (after ;) This function is not as
	     * robust as it could be. Eg. header comments
	     * in the wrong place will probably break it.
	     *
	     * @param string Header value to parse
	     * @return array Contains parsed result
	     * @access private
	     */
	    function _parseHeaderValue($input)
	    {
 
	        if (($pos = strpos($input, ';')) !== false) {
 
	            $return['value'] = trim(substr($input, 0, $pos));
	            $input = trim(substr($input, $pos+1));
 
	            if (strlen($input) > 0) {
 
	                // This splits on a semi-colon, if there's no preceeding backslash
	                // Can't handle if it's in double quotes however. (Of course anyone
	                // sending that needs a good slap).
	                $parameters = preg_split('/\s*(?<!\\\\);\s*/i', $input);
 
	                for ($i = 0; $i < count($parameters); $i++) {
	                    $param_name  = substr($parameters[$i], 0, $pos = strpos($parameters[$i], '='));
	                    $param_value = substr($parameters[$i], $pos + 1);
	                    if ($param_value[0] == '"') {
	                        $param_value = substr($param_value, 1, -1);
	                    }
	                    $return['other'][$param_name] = $param_value;
	                    $return['other'][strtolower($param_name)] = $param_value;
	                }
	            }
	        } else {
	            $return['value'] = trim($input);
	        }
 
	        return $return;
	    }
 
	    /**
	     * This function splits the input based
	     * on the given boundary
	     *
	     * @param string Input to parse
	     * @return array Contains array of resulting mime parts
	     * @access private
	     */
	    function _boundarySplit($input, $boundary)
	    {
			$boundary=trim($boundary);
			if(substr($boundary,-1)=='"')
		     	$boundary=substr_replace($boundary,"" ,-1 );
			if(substr($boundary,0,1)=='"')
		     	$boundary=substr_replace($boundary,"" ,0,1);
			$boundary=trim($boundary);
		    $tmp = explode('--'.$boundary,$input);//boundary
	        for ($i=1; $i<count($tmp)-1; $i++) {
	            $parts[] = $tmp[$i];
	        }
 
	        return $parts;
	    }
 
	    /**
	     * Given a header, this function will decode it
	     * according to RFC2047. Probably not *exactly*
	     * conformant, but it does pass all the given
	     * examples (in RFC2047).
	     *
	     * @param string Input header value to decode
	     * @return string Decoded header value
	     * @access private
	     */
	    function _decodeHeader($input)
	    {
	        // Remove white space between encoded-words
	        $input = preg_replace('/(=\?[^?]+\?(q|b)\?[^?]*\?=)(\s)+=\?/i', '\1=?', $input);
 
	        // For each encoded-word...
	        while (preg_match('/(=\?([^?]+)\?(q|b)\?([^?]*)\?=)/i', $input, $matches)) {
 
	            $encoded  = $matches[1];
	            $charset  = $matches[2];
	            $encoding = $matches[3];
	            $text     = $matches[4];
 
	            switch (strtolower($encoding)) {
	                case 'b':
	                    $text = base64_decode($text);  //base64_decode_fix()
	                    break;
 
	                case 'q':
	                    $text = str_replace('_', ' ', $text);
	                    preg_match_all('/=([a-f0-9]{2})/i', $text, $matches);
	                    foreach($matches[1] as $value)
	                        $text = str_replace('='.$value, chr(hexdec($value)), $text);
	                    break;
	            }
 
	            $input = str_replace($encoded, $text, $input);
	        }
 
	        return $input;
	    }
 
	    /**
	     * Given a body string and an encoding type,
	     * this function will decode and return it.
	     *
	     * @param  string Input body to decode
	     * @param  string Encoding type to use.
	     * @return string Decoded body
	     * @access private
	     */
	    function _decodeBody($input, $encoding = '7bit')
	    {
			//echo "<hr>Encoding:$encoding";
 
	        switch (strtolower($encoding)) {
	            case '7bit':
	                return $input;
	                break;
 
	            case 'quoted-printable':
	                return $this->_quotedPrintableDecode($input);
	                break;
 
	            case 'base64':
	                $temp = base64_decode($input, true);  //base64_decode_fix()  // use this?
					// Kevin note: some weird things happen here.  some are already base64 decoded and as such we will get false returned from certain emails.
					if ($temp != false)
						return $temp;
					else
						return $input;
	                break;
 
	            default:
	                return $input;
	        }
	    }
 
		// TODO: not in use at the moment.  Placed in code for people with other less recent versions of PHP.
		// This is a workaround for bug in php 4.3.11 through 4.4.7, 5.1.2 through 5.2.4 and perhaps others (http://bugs.php.net/bug.php?id=37244) 
		function  base64_decode_fix( $data, $strict = false ) 
		{ 
			if( $strict ) 
				if( preg_match( '![^a-zA-Z0-9/+=]!', $data ) ) 
					return( false ); 
 
			return( base64_decode( $data ) ); 
		}		
 
	    /**
	     * Given a quoted-printable string, this
	     * function will decode and return it.
	     *
	     * @param  string Input body to decode
	     * @return string Decoded body
	     * @access private
	     */
	    function _quotedPrintableDecode($input)
	    {
	        // Remove soft line breaks
	        $input = preg_replace("/=\r?\n/", '', $input);
 
	        // Replace encoded characters
			$input = preg_replace('/=([a-f0-9]{2})/ie', "chr(hexdec('\\1'))", $input);
 
	        return $input;
	    }
 
	    /**
	     * Checks the input for uuencoded files and returns
	     * an array of them. Can be called statically, eg:
	     *
	     * $files =& MIMEDECODE::uudecode($some_text);
	     *
	     * It will check for the begin 666 ... end syntax
	     * however and won't just blindly decode whatever you
	     * pass it.
	     *
	     * @param  string Input body to look for attahcments in
	     * @return array  Decoded bodies, filenames and permissions
	     * @access public
	     * @author Unknown
	     */
	    function &uudecode($input)
	    {
	        // Find all uuencoded sections
	        preg_match_all("/begin ([0-7]{3}) (.+)\r?\n(.+)\r?\nend/Us", $input, $matches);
 
	        for ($j = 0; $j < count($matches[3]); $j++) {
 
	            $str      = $matches[3][$j];
	            $filename = $matches[2][$j];
	            $fileperm = $matches[1][$j];
 
	            $file = '';
	            $str = preg_split("/\r?\n/", trim($str));
	            $strlen = count($str);
 
	            for ($i = 0; $i < $strlen; $i++) {
	                $pos = 1;
	                $d = 0;
	                $len=(int)(((ord(substr($str[$i],0,1)) -32) - ' ') & 077);
 
	                while (($d + 3 <= $len) AND ($pos + 4 <= strlen($str[$i]))) {
	                    $c0 = (ord(substr($str[$i],$pos,1)) ^ 0x20);
	                    $c1 = (ord(substr($str[$i],$pos+1,1)) ^ 0x20);
	                    $c2 = (ord(substr($str[$i],$pos+2,1)) ^ 0x20);
	                    $c3 = (ord(substr($str[$i],$pos+3,1)) ^ 0x20);
	                    $file .= chr(((($c0 - ' ') & 077) << 2) | ((($c1 - ' ') & 077) >> 4));
 
	                    $file .= chr(((($c1 - ' ') & 077) << 4) | ((($c2 - ' ') & 077) >> 2));
 
	                    $file .= chr(((($c2 - ' ') & 077) << 6) |  (($c3 - ' ') & 077));
 
	                    $pos += 4;
	                    $d += 3;
	                }
 
	                if (($d + 2 <= $len) && ($pos + 3 <= strlen($str[$i]))) {
	                    $c0 = (ord(substr($str[$i],$pos,1)) ^ 0x20);
	                    $c1 = (ord(substr($str[$i],$pos+1,1)) ^ 0x20);
	                    $c2 = (ord(substr($str[$i],$pos+2,1)) ^ 0x20);
	                    $file .= chr(((($c0 - ' ') & 077) << 2) | ((($c1 - ' ') & 077) >> 4));
 
	                    $file .= chr(((($c1 - ' ') & 077) << 4) | ((($c2 - ' ') & 077) >> 2));
 
	                    $pos += 3;
	                    $d += 2;
	                }
 
	                if (($d + 1 <= $len) && ($pos + 2 <= strlen($str[$i]))) {
	                    $c0 = (ord(substr($str[$i],$pos,1)) ^ 0x20);
	                    $c1 = (ord(substr($str[$i],$pos+1,1)) ^ 0x20);
	                    $file .= chr(((($c0 - ' ') & 077) << 2) | ((($c1 - ' ') & 077) >> 4));
 
	                }
	            }
	            $files[] = array('filename' => $filename, 'fileperm' => $fileperm, 'filedata' => $file);
	        }
 
	        return $files;
	    }
 
	    /**
	     * getSendArray() returns the arguments required for Mail::send()
	     * used to build the arguments for a mail::send() call 
	     *
	     * Usage:
	     * $mailtext = Full email (for example generated by a template)
	     * $decoder = new MIMEDECODE($mailtext);
	     * $parts =  $decoder->getSendArray();
	     * if (!PEAR::isError($parts) {
	     *     list($recipents,$headers,$body) = $parts;
	     *     $mail = Mail::factory('smtp');
	     *     $mail->send($recipents,$headers,$body);
	     * } else {
	     *     echo $parts->message;
	     * }
	     * @return mixed   array of recipeint, headers,body or Pear_Error
	     * @access public
	     * @author Alan Knowles <alan@akbkhome.com>
	     */
	    function getSendArray()
	    {
	        // prevent warning if this is not set
	        $this->_decode_headers = FALSE;
	        $headerlist =$this->_parseHeaders($this->_header);
	        $to = "";
	        if (!$headerlist) {
	            return $this->raiseError("Message did not contain headers");
	        }
	        foreach($headerlist as $item) {
	            $header[$item['name']] = $item['value'];
	            switch (strtolower($item['name'])) {
	                case "to":
	                case "cc":
	                case "bcc":
	                    $to = ",".$item['value'];
	                default:
	                   break;
	            }
	        }
	        if ($to == "") {
	            return $this->raiseError("Message did not contain any recipents");
	        }
	        $to = substr($to,1);
	        return array($to,$header,$this->_body);
	    } 
 
	    /**
	     * Returns a xml copy of the output of
	     * MIMEDECODE::decode. Pass the output in as the
	     * argument. This function can be called statically. Eg:
	     *
	     * $output = $obj->decode();
	     * $xml    = MIMEDECODE::getXML($output);
	     *
	     * The DTD used for this should have been in the package. Or
	     * alternatively you can get it from cvs, or here:
	     * http://www.phpguru.org/xmail/xmail.dtd.
	     *
	     * @param  object Input to convert to xml. This should be the
	     *                output of the MIMEDECODE::decode function
	     * @return string XML version of input
	     * @access public
	     */
	    function getXML($input)
	    {
	        $crlf    =  "\r\n";
	        $output  = '<?xml version=\'1.0\'?>' . $crlf .
	                   '<!DOCTYPE email SYSTEM "http://www.phpguru.org/xmail/xmail.dtd">' . $crlf .
	                   '<email>' . $crlf .
	                   MIMEDECODE::_getXML($input) .
	                   '</email>';
 
	        return $output;
	    }
 
	    /**
	     * Function that does the actual conversion to xml. Does a single
	     * mimepart at a time.
	     *
	     * @param  object  Input to convert to xml. This is a mimepart object.
	     *                 It may or may not contain subparts.
	     * @param  integer Number of tabs to indent
	     * @return string  XML version of input
	     * @access private
	     */
	    function _getXML($input, $indent = 1)
	    {
	        $htab    =  "\t";
	        $crlf    =  "\r\n";
	        $output  =  '';
	        $headers = @(array)$input->headers;
 
	        foreach ($headers as $hdr_name => $hdr_value) {
 
	            // Multiple headers with this name
	            if (is_array($headers[$hdr_name])) {
	                for ($i = 0; $i < count($hdr_value); $i++) {
	                    $output .= MIMEDECODE::_getXML_helper($hdr_name, $hdr_value[$i], $indent);
	                }
 
	            // Only one header of this sort
	            } else {
	                $output .= MIMEDECODE::_getXML_helper($hdr_name, $hdr_value, $indent);
	            }
	        }
 
	        if (!empty($input->parts)) {
	            for ($i = 0; $i < count($input->parts); $i++) {
	                $output .= $crlf . str_repeat($htab, $indent) . '<mimepart>' . $crlf .
	                           MIMEDECODE::_getXML($input->parts[$i], $indent+1) .
	                           str_repeat($htab, $indent) . '</mimepart>' . $crlf;
	            }
	        } elseif (isset($input->body)) {
	            $output .= $crlf . str_repeat($htab, $indent) . '<body><![CDATA[' .
	                       $input->body . ']]></body>' . $crlf;
	        }
 
	        return $output;
	    }
 
	    /**
	     * Helper function to _getXML(). Returns xml of a header.
	     *
	     * @param  string  Name of header
	     * @param  string  Value of header
	     * @param  integer Number of tabs to indent
	     * @return string  XML version of input
	     * @access private
	     */
	    function _getXML_helper($hdr_name, $hdr_value, $indent)
	    {
	        $htab   = "\t";
	        $crlf   = "\r\n";
	        $return = '';
 
	        $new_hdr_value = ($hdr_name != 'received') ? MIMEDECODE::_parseHeaderValue($hdr_value) : array('value' => $hdr_value);
	        $new_hdr_name  = str_replace(' ', '-', ucwords(str_replace('-', ' ', $hdr_name)));
 
	        // Sort out any parameters
	        if (!empty($new_hdr_value['other'])) {
	            foreach ($new_hdr_value['other'] as $paramname => $paramvalue) {
	                $params[] = str_repeat($htab, $indent) . $htab . '<parameter>' . $crlf .
	                            str_repeat($htab, $indent) . $htab . $htab . '<paramname>' . htmlspecialchars($paramname) . '</paramname>' . $crlf .
	                            str_repeat($htab, $indent) . $htab . $htab . '<paramvalue>' . htmlspecialchars($paramvalue) . '</paramvalue>' . $crlf .
	                            str_repeat($htab, $indent) . $htab . '</parameter>' . $crlf;
	            }
 
	            $params = implode('', $params);
	        } else {
	            $params = '';
	        }
 
	        $return = str_repeat($htab, $indent) . '<header>' . $crlf .
	                  str_repeat($htab, $indent) . $htab . '<headername>' . htmlspecialchars($new_hdr_name) . '</headername>' . $crlf .
	                  str_repeat($htab, $indent) . $htab . '<headervalue>' . htmlspecialchars($new_hdr_value['value']) . '</headervalue>' . $crlf .
	                  $params .
	                  str_repeat($htab, $indent) . '</header>' . $crlf;
 
	        return $return;
	    }
 
		/*this function is used to get the parsed message  or you shoud say fineal message
		/////arguments [in]$object = object returned by get_message function defined above
		/////arguments [in]$msg = a pointer to messgae
		///// this function returns message string
		*/
		function get_parsed_message()
		{
			$msg = "";
			// kevin edit (moved to mimedecode function 
			//$this->_mailObjectDecoded = $this->decode();
 
			$msg.="<b>To : </b>".$this->_mailObjectDecoded->headers["to"]."<br>";
			$msg.="<b>From : </b>".$this->_mailObjectDecoded->headers["from"]."<br>";
			$msg.="<b>Subject : </b>".$this->_mailObjectDecoded->headers["subject"]."<br>";
			$msg.="<b>Date : </b>".$this->_mailObjectDecoded->headers["date"]."<br><br>";
			$main_content_type=trim($this->_mailObjectDecoded->ctype_primary)."/".trim($this->_mailObjectDecoded->ctype_secondary);
			//trim(strtok($object->headers['content-type'],";"));
			$msg.=$this->walk(&$this->_mailObjectDecoded,"",$main_content_type);
			return $msg;
		}
 
		function walk($object,$msg="",$main_content_type="")
		{			
			//echo "===============\r\nWalkcount: ".$this->walkcount++."\r\n";			
 
			if(!isset($object->parts))
			{
				//$ctype=trim(strtok($object->headers['content-type'],";"));
				$ctype=trim($object->ctype_primary)."/".trim($object->ctype_secondary);
 
				switch($ctype)
				{
					case "text/html":
						$msg.=$object->body;
						break;
					case "text/plain":
						$enc=$object->headers['content-transfer-encoding'];
						if($enc!="quoted-printable")
							$msg.=nl2br($object->body);
						break;
					case "image/jpeg":
					case "image/gif":
 
						// todo: fix the appending of .gif?
						$name=isset($object->headers['name'])? trim($object->headers['name']) : "NoName_.gif";		
 
						$cid=trim($object->headers['content-id']);		
						$cid=str_replace("<","",$cid);
						$cid=str_replace(">","",$cid);
						if(empty($name))
							 trim(strtok($object->headers['content-type'],"="));
						//$name=trim(strtok("=\""));
						$temp="pop3_temp/";
						@mkdir($temp,0777);
						$tmpfile=$temp.$name;
						//$tmpfile=realpath($tmpfile);
						//echo "\r\ntmpfile:$tmpfile\r\n";
						$fp=fopen($tmpfile,"w");
						fwrite($fp,$object->body);
						fclose($fp);
						if($main_content_type=="multipart/mixed")
						{
							$msg.="<hr>";
							$msg.="<a href='$tmpfile' target='_blank'>$name</a>";
							$msg.="<hr>";
							$msg.="<img src='$tmpfile'>";			
						}
						$msg=str_replace("cid:$cid",$tmpfile,$msg);
						//@unlink($tmpfile);
						break;
					default:
						$name=trim($object->headers['name']);		
						if(empty($name))
							 trim(strtok($object->headers['content-type'],"="));
						$name=trim(strtok("=\""));
						$temp="pop3_temp/";
						@mkdir($temp,777);
						$tmpfile=$temp.$name;
						//$tmpfile=realpath($tmpfile);
						$fp=fopen($tmpfile,"w");
						fwrite($fp,$object->body);
						fclose($fp);
						$msg.="<hr>";
						$msg.="<a href='$tmpfile' target='_blank'>$name</a>";
						break;
				}
			}
			else
			{
				foreach($object->parts as $obj)
					$this->walk($obj,&$msg,$main_content_type);
			}
			return $msg;
		}
 
 
	#########################################################################
	# BEGIN KEVIN'S FUNCTIONS
	########################################################################			
 
		function get_header($name)
		{
			$name = strtolower($name);
			$str = (isset($this->_mailObjectDecoded->headers[$name]))? $this->_mailObjectDecoded->headers[$name] : "";
			return $str;
		}
 
		function getFromEmail()
		{			
			$string = (isset($this->_mailObjectDecoded->headers["from"]))? $this->_mailObjectDecoded->headers["from"] : "";			
			$out = "";
			foreach(preg_split('/\s/', $string) as $token) 
			{
				$email = filter_var(filter_var($token, FILTER_SANITIZE_EMAIL), FILTER_VALIDATE_EMAIL);
				if ($email !== false) 
				{
					$out .= $email;
				}
			}
			return $out;			
		}	
 
		function getBody()
		{
			$body = "";
			$arr = $this->getObjects($this->_mailObjectDecoded, array(), "ctype_primary", "text");
			//return print_r($arr, true);
 
			foreach($arr as $obj)
			{
				$body = $obj->body;
			}
			return $body;
		}
 
		function getImageObjects()
		{
			//// SAMPLE OBJECT STRUCTURE...
			/*  
			Email 3...
			[0] => stdClass Object
					(
						[headers] => Array
							(
								[content-type] => image/jpeg; Name=JJ_Grey_and_MOFRO!!.jpg
								[content-id] => <JJ_Grey_and_MOFRO!!.jpg>
								[content-location] => JJ_Grey_and_MOFRO!!.jpg
								[content-transfer-encoding] => BASE64
								[content-disposition] => attachment; filename=JJ_Grey_and_MOFRO!!.jpg
							)
 
						[ctype_primary] => image
						[ctype_secondary] => jpeg
						[ctype_parameters] => Array
							(
								[Name] => JJ_Grey_and_MOFRO!!.jpg
								[name] => JJ_Grey_and_MOFRO!!.jpg
							)
 
						[disposition] => attachment
						[d_parameters] => Array
							(
								[filename] => JJ_Grey_and_MOFRO!!.jpg
							)
 
						[body] =>
 
 
 
 
			*/		
 
			$arr = $this->getObjects($this->_mailObjectDecoded, array(), "ctype_primary", "image");
			return $arr;
		}
 
		// todo: finish...
		function getAttachmentObjects($ctype_primary)
		{
			$arr = $this->getObjects($this->_mailObjectDecoded, array(), "ctype_primary", $ctype_primary);
			return $arr;
		}
 
		function saveImageToDisk($object,$name)
		{	
			$msg = "Error Saving Image '$name' To Disk";
			//$ctype=trim(strtok($object->headers['content-type'],";"));
			$ctype = strtolower(trim($object->ctype_primary)."/".trim($object->ctype_secondary));
			//echo "<br>ctype: $ctype";
 
			switch($ctype)
			{
				case ("image/png" || "image/jpeg" || "image/gif"):
					$temp="pop3_temp/";
					@mkdir($temp,0777);
					$tmpfile = $temp.$name;
					//$tmpfile=realpath($tmpfile);
					//echo "\r\ntmpfile:$tmpfile\r\n";
					$fp=fopen($tmpfile,"w");					
					fwrite($fp,$object->body);										
					fclose($fp);
					$msg = "<a href='$tmpfile' target='_blank'><img style='width:150px;' src='$tmpfile'></a>";						
					break;
				default:
					// todo: handle other types of attachments
					$temp="pop3_temp/";
					@mkdir($temp,777);
					$tmpfile=$temp.$name;
					//$tmpfile=realpath($tmpfile);
					$fp=fopen($tmpfile,"w");
					fwrite($fp,$object->body);
					fclose($fp);
					$msg = "<a href='$tmpfile' target='_blank'>$name</a>";
					break;
			}
			return $msg;
		}
 
		function getImageName($o)
		{
			if (isset($o->ctype_parameters["name"]))
				return trim($o->ctype_parameters["name"]);
			if (isset($o->d_parameters["filename"]))
				return trim($o->d_parameters["filename"]);			
 
			return "UnknownFileName";
		}
 
		function getObjects($object, $array=array(), $keyName, $valueName)
		{							
			foreach($object as $obj)
			{								
				if (isset($obj[$keyName]))
				{
					if ($obj === $valueName)
					{
						array_push($array, $object);
						//echo "<hr style='border:1px solid green;'>";																												
						//print_r($array);
						//echo "ctype_primary: '".$obj."'";
						//echo "<br>";
						//print_r($object);
					}
				}
 
				// Seek nested objects in arrays...
				if (gettype($obj) === "array")
				{
					foreach($obj as $key => $value) 
					{																
						if (gettype($value) === "object")
						{
							//echo "<hr style='border:1px solid blue;'>";	
							$array = $this->getObjects($value, $array, $keyName, $valueName);
						}
					}
				}
				else if (gettype($obj) === "object")  // Seek nested objects in object...
				{				
					$array = $this->getObjects($obj, $array, $keyName, $valueName);
				}
			}
			return $array;
		}		
 
	}
?>
Posted in Uncategorized | Leave a comment

PHP Function List For Notepad++ v6.x

Find functionList.xml in the Notepad++ install directory and add the following line to the associationMap section…

    <association langID = "1" id="php_function"/>

and in the parsers section add…

<parser id="php_function" displayName="PHP" commentExpr="((/\*.*?\*)/|(//.*?$))">
	<function
		mainExpr="((^|[\s]+|[;\}\.])([_A-Za-z][\w_]*\.)*[_A-Za-z][\w_]*[\s]*=|^|[\s;\}]+)[\s]*function([\s]+[_A-Za-z]?[\w_]*\([^\)\(]*\)|\([^\)\(]*\))[\n\s]*\{"
		displayMode="$className->$functionName">
		<functionName>
			<nameExpr expr="[_A-Za-z][\w_]*[\s]*=|[_A-Za-z]?[\w_]*[\s]*\("/>
			<nameExpr expr="[_A-Za-z]?[\w_]*"/>
		</functionName>
		<className>
			<nameExpr expr="([_A-Za-z][\w_]*\.)*[_A-Za-z][\w_]*\."/>
			<nameExpr expr="([_A-Za-z][\w_]*\.)*[_A-Za-z][\w_]*"/>
		</className>
	</function>			
</parser>

Restart Notepadd++, you are done.

More info on FunctionList parser setup.

FunctionList Wiki

Posted in Uncategorized | 4 Comments

Session Timeout in IIS, ASP.NET

Boss had me look into how we can keep sessions alive (IIS server/client)
without having to “stay-alive-ping” the server (in our website asp.net code)
from client browsers. The main consideration is that a user must reenter
their CAC pin when the ping occurs and if the user is away from his/her
machine during the ping request the ping will not complete and return a 403
status because the client certificate will become invalid. If a user was in
the middle of a long form or taking a training course, all data would be
lost. This is bad.

I have done some research and have found out the following:

We can extend the session out by extended the session timeout on the server.
This requires the following 3 settings:

Set Session Timeout for website:

IIS –> [website] –> Properties –> Directory Tab –> Configuration Button –>
Options Tab –> Session timout (currently 120 minutes for most sites, default
IIS value: 20)

Set ASP.NET Authentication Cookie Timout:

IIS –> [website] –> Properties –> ASP.NET Tab –> Edit Configuration Button –>
Authentication Tab –> Cookie timeout (currently 120 minutes for most sites,
default asp.net value: 30)

Set Idle timeout in App Pool:

IIS –> [app pool] –> Properties –> Performance Tab –> Idle Timeout (currently 20
for most sites, default IIS value: 20)

The botton line is that the session will timeout at the lowest of these
three settings… Which is 20 minutes in the App Pool objects. Currently we
are doing asp.net “stay-alive-ping” at some interval less than 20 minutes
from our pages to extend this limit indefinitely. If we were to change
our app pool to 120 minutes (matching the other two settings), we could then
extend the “stay alive pinging” to say… 115 minutes. Thus the CAC Pins
would only be requested when a user post/get occurs (and the cac software
requires a revalidation) or at the 115 minutes since the last user post/get,
which ever comes first.

Posted in Uncategorized | Leave a comment

DATE DIMENTION TABLE FOR ORACLE

--CREATE DATE DIMENTION TABLE
CREATE TABLE DATES AS
SELECT
n AS Date_ID,
CurrDate AS FULL_DATE,
(TO_NUMBER(TO_CHAR(CurrDate,'MM')) || '/' || TO_NUMBER(TO_CHAR(CurrDate,'DD')) || '/' || TO_CHAR(CurrDate,'YYYY')) AS DOT_NET_DATE, --3/23/2012
TO_NUMBER(TO_CHAR(CurrDate,'DD')) AS DAY_OF_MONTH,
TO_NUMBER(TO_CHAR(CurrDate, 'DDD')) AS DAY_OF_YEAR,
TO_NUMBER(TO_CHAR(CurrDate, 'D')) AS DAY_OF_WEEK,
TO_CHAR(CurrDate,'Day') AS DAY_LONG,
TO_CHAR(CurrDate, 'DY') AS DAY_SHORT,
TO_NUMBER(TO_CHAR(CurrDate, 'W')) AS WEEK_OF_MONTH,
TO_NUMBER(TO_CHAR(CurrDate, 'IW')) AS WEEK_OF_YEAR,
TO_NUMBER(TO_CHAR(CurrDate,'Q')) AS QUARTER,
TO_NUMBER(TO_CHAR(CurrDate,'MM')) AS MONTH_OF_YEAR,
TO_CHAR(CurrDate,'Mon') AS MONTH_SHORT,
TO_CHAR(CurrDate,'Month') AS MONTH_LONG,
TO_NUMBER(TO_CHAR(CurrDate,'YYYY')) AS YEAR,
CASE
    WHEN TO_NUMBER(TO_CHAR(CurrDate, 'MM')) IN (10,11,12) THEN 'FY' || TO_NUMBER(TO_CHAR(ADD_MONTHS(CurrDate, 3), 'YY')) || ' Q1'
    WHEN TO_NUMBER(TO_CHAR(CurrDate, 'MM')) IN (1,2,3) THEN 'FY' || TO_NUMBER(TO_CHAR(ADD_MONTHS(CurrDate, 3), 'YY')) || ' Q2'
    WHEN TO_NUMBER(TO_CHAR(CurrDate, 'MM')) IN (4,5,6) THEN 'FY' || TO_NUMBER(TO_CHAR(ADD_MONTHS(CurrDate, 3), 'YY')) || ' Q3'
    WHEN TO_NUMBER(TO_CHAR(CurrDate, 'MM')) IN (7,8,9) THEN 'FY' || TO_NUMBER(TO_CHAR(ADD_MONTHS(CurrDate, 3), 'YY')) || ' Q4'
END AS FISCAL_FY_Q,
'FY' || TO_NUMBER(TO_CHAR(ADD_MONTHS(CurrDate, 3), 'YY')) AS FISCAL_FY,
TO_NUMBER(TO_CHAR(ADD_MONTHS(CurrDate, 3), 'YYYY')) AS FISCAL_YEAR,
CASE
    WHEN TO_NUMBER(TO_CHAR(CurrDate, 'MM')) IN (10,11,12) THEN 'Q1'
    WHEN TO_NUMBER(TO_CHAR(CurrDate, 'MM')) IN (1,2,3) THEN 'Q2'
    WHEN TO_NUMBER(TO_CHAR(CurrDate, 'MM')) IN (4,5,6) THEN 'Q3'
    WHEN TO_NUMBER(TO_CHAR(CurrDate, 'MM')) IN (7,8,9) THEN 'Q4'
END AS FISCAL_Q,
CASE
    WHEN TO_NUMBER(TO_CHAR(CurrDate, 'MM')) IN (10,11,12) THEN 1
    WHEN TO_NUMBER(TO_CHAR(CurrDate, 'MM')) IN (1,2,3) THEN 2
    WHEN TO_NUMBER(TO_CHAR(CurrDate, 'MM')) IN (4,5,6) THEN 3
    WHEN TO_NUMBER(TO_CHAR(CurrDate, 'MM')) IN (7,8,9) THEN 4   
END AS FISCAL_QUARTER,
-1 AS FISCAL_DAY_NUMBER,
-1 AS FISCAL_WEEK_NUMBER,
TO_NUMBER(TO_CHAR(ADD_MONTHS(CurrDate, 3), 'MM')) AS FISCAL_MONTH_NUMBER,
TO_NUMBER(TO_CHAR(CurrDate, 'J')) AS JULIAN_DAY,
CASE
    WHEN TO_CHAR(CurrDate, 'D') = '1' THEN CurrDate
    WHEN TO_CHAR(CurrDate, 'D') = '2' THEN CurrDate-1
    WHEN TO_CHAR(CurrDate, 'D') = '3' THEN CurrDate-2
    WHEN TO_CHAR(CurrDate, 'D') = '4' THEN CurrDate-3
    WHEN TO_CHAR(CurrDate, 'D') = '5' THEN CurrDate-4
    WHEN TO_CHAR(CurrDate, 'D') = '6' THEN CurrDate-5
    WHEN TO_CHAR(CurrDate, 'D') = '7' THEN CurrDate-6
END AS CAL_BEGIN_WEEK_DT,
CASE
    WHEN TO_CHAR(CurrDate, 'D') = '7' THEN CurrDate
    WHEN TO_CHAR(CurrDate, 'D') = '6' THEN CurrDate+1
    WHEN TO_CHAR(CurrDate, 'D') = '5' THEN CurrDate+2
    WHEN TO_CHAR(CurrDate, 'D') = '4' THEN CurrDate+3
    WHEN TO_CHAR(CurrDate, 'D') = '3' THEN CurrDate+4
    WHEN TO_CHAR(CurrDate, 'D') = '2' THEN CurrDate+5
    WHEN TO_CHAR(CurrDate, 'D') = '1' THEN CurrDate+6
END AS CAL_END_WEEK_DT,
CASE
    WHEN TO_CHAR(CurrDate, 'D') = '2' THEN CurrDate
    WHEN TO_CHAR(CurrDate, 'D') = '3' THEN CurrDate-1
    WHEN TO_CHAR(CurrDate, 'D') = '4' THEN CurrDate-2
    WHEN TO_CHAR(CurrDate, 'D') = '5' THEN CurrDate-3
    WHEN TO_CHAR(CurrDate, 'D') = '6' THEN CurrDate-4
END AS WORKING_WK_BEGIN_DT,
CASE
    WHEN TO_CHAR(CurrDate, 'D') = '6' THEN CurrDate
    WHEN TO_CHAR(CurrDate, 'D') = '5' THEN CurrDate+1
    WHEN TO_CHAR(CurrDate, 'D') = '4' THEN CurrDate+2
    WHEN TO_CHAR(CurrDate, 'D') = '3' THEN CurrDate+3
    WHEN TO_CHAR(CurrDate, 'D') = '2' THEN CurrDate+4
END AS WORKING_WK_END_DT,
DECODE(TO_CHAR(CurrDate, 'D'), '7', 0, '1', 0, 1) AS IS_WORKDAY,
DECODE(TO_CHAR(CurrDate, 'D'), '7', 1, '1', 1, 0) AS IS_WEEKEND,
-1 AS IS_HOLIDAY
FROM (
SELECT level n, TO_DATE('31/12/1989','DD/MM/YYYY') + NUMTODSINTERVAL(level,'day') CurrDate
FROM dual
CONNECT BY level <= 18250)
Posted in Uncategorized | Leave a comment

ASP.NET Add Sub Header Row (Group) To GridView Control

    ''' <summary>
    ''' Insert a sub header in a grid view.
    ''' </summary>
    ''' <param name="gv">The GridView to insert the sub header row into.</param>
    ''' <param name="gvrBeforeRow">The GridViewRow to insert the sub header before.</param>
    ''' <param name="sSubHeaderText">The text to render in the sub header.</param>
    ''' <remarks></remarks>
    Protected Sub insertGroupHeaderToGridView(ByRef gv As GridView, ByVal gvrBeforeRow As GridViewRow, ByVal sSubHeaderText As String)
 
        Dim visibleColumns As Integer = gv.Columns.Count
 
        Dim tbl As Table = gv.Controls(0)
        Dim newRowIndex As Integer = tbl.Rows.GetRowIndex(gvrBeforeRow)
        Dim newRow As GridViewRow = New GridViewRow(newRowIndex, newRowIndex, DataControlRowType.DataRow, DataControlRowState.Normal)
 
        newRow.Cells.Add(New TableCell())
 
        If (visibleColumns > 1) Then
            newRow.Cells(0).ColumnSpan = visibleColumns
            newRow.Cells(0).Text = sSubHeaderText
        End If
 
        tbl.Controls.AddAt(newRowIndex, newRow)
 
    End Sub
Posted in .NET, ASP, microsoft | Leave a comment

Hands Across The Sand – Stop Oil Drilling In Florida

Hands Across The Sand is an organization committed to protecting our coastlines and waterways from near and off shore oil drilling. Join us February 13, 2010!

An organization devoted to protecting our coastlines and waterways from the devastating environmental effects of oil exploration and support industries.

Mission:

1. To raise awareness about pending Florida legislation to drill for oil within 3 to 10 miles of our coast

2. To organize a statewide, coastal movement to protest this legislation. This protest will bring thousands of Florida citizens to our beaches and will draw metaphorical and physical lines in the sand; human lines in the sand against near shore oil drilling in our waters. This event will be held on Saturday February 13, 2010

3. To convince our Legislators and Governor to drop any and all Legislation that would allow this folly.

Hands Across The Sand On Facebook

Posted in Life, Uncategorized | Leave a comment