Timeline

Using Zend Framework To Iterate Through Your Gmail Mailbox

I was asked to research the most popular techniques to pull emails from a Gmail / Google Apps account. I figured that using Zend can be much easier than working with the built in imap_open function that comes with your PHP parser. Here are the steps to get it to work:

1. Download Zend Framework.

You have to choose the right version for your operating system. Then you have to choose if you want to Minimal Functionality Zend Framework or the Zend Framework Full Package. I chose the second one, since you never know what you may need in the future. If you do the same, you will be asked to register first on the Zend website and then download the framework.

Here is  the link: Zend Framework

2. Installation

You don’t really need to install anything. Just copy the library folder somewhere within your www server and add the right path to your php file. We are going to use the Mail functions:

<?
include(“Zend/Mail.php”);
include(“Zend/Mail/Storage/Imap.php”);
?>

You should change your path accordingly.

3. Add your php code

The only thing left is to add your code and play around with your email messages. Here is my code that you can use as an example:

<?
include(“Zend/Mail.php”);
include(“Zend/Mail/Storage/Imap.php”);
$mail = new Zend_Mail();
$mail = new Zend_Mail_Storage_Imap(array(‘host’ => ‘imap.gmail.com’,
‘port’ => ’993′,
‘user’ => ‘michael@xyz.com’,
‘password’ => ’12345′,
‘folder’ => ‘[Gmail]/All Mail’,
‘ssl’ => ‘SSL’));

$maxMessage = $mail->countMessages();
$time_generated1 = strtotime(date(“Y-m-d H:i:s”));

$n = 0;
$m = 0;
foreach ($mail as $messageNum => $message) {
if (isset($message->subject)) {
echo $n . ” ” .$message->subject . “<br>”;
$n++;
}
$m++;
if ($n == 10000) {
break;
}
}
echo “n: ” . $n . “<br>”;
echo “m: ” . $m . “<br>”;

$time_generated2 = strtotime(date(“Y-m-d H:i:s”));
$difference = $time_generated1 – $time_generated2;
echo(“Page generated in ” . $difference . ” seconds. “);
?>

You have to remember to check if the subject property exists. Apparently if the subject of the message is empty, it doesn’t exist and the framework throws the error:

Fatal error: Uncaught exception ‘Zend_Mail_Storage_Exception’ with message ‘cannot login, user or password wrong’ in C:\xampplite\htdocs\testing\Zend\Mail\Storage\Imap.php:279 Stack trace: #0 C:\xampplite\htdocs\testing\index.php(11): Zend_Mail_Storage_Imap->__construct(Array) #1 {main} thrown in C:\xampplite\htdocs\testing\Zend\Mail\Storage\Imap.php on line 279

However if you use the “if (isset($message->subject)) {” you should be good.

Share

Adding Multiple Custom jquery datepicker Fields On One Page

Those who are not familiar with the datepicker plugin for jquery, it’s basically a module that allows to easily display a custom calendar within your HTML form. The plugin allows developers to play around with its options that allow to modify many feautures of the calendar. For the full list and description of all options please visit the jQuery page. The most important feature in my case was the beforeShowDay option which allows to turn off (grey out) some specific dates that you don’t want user to select, for example weekends. This is the basic use of the datepicker plugin with the beforeShowDay with the start date set for the next business day:

<script type="text/javascript">
var disabledDays = ["1-15-2012"];
function nationalDays(date) {
var m = date.getMonth(), d = date.getDate(), y = date.getFullYear();
for (i = 0; i < disabledDays.length; i++) { if($.inArray((m+1) + '-' + d + '-' + y,disabledDays) != -1 || new Date() > date) {
return [false];
}
}
return [true];
}
function noWeekendsOrHolidays(date) {
var noWeekend = jQuery.datepicker.noWeekends(date);
return noWeekend[0] ? nationalDays(date) : noWeekend;
}
$.ajaxSetup ({
cache: false
});

$('.datepicker:not(.ui-datepicker)').live('click',function(){
$(this).datepicker({
minDate: new Date(),
maxDate: new Date('', '', ''),
dateFormat: 'yy-mm-dd',
constrainInput: true,
beforeShowDay: noWeekendsOrHolidays
}).focus();
return false;
});
</script>

It works smoothly. If I want to have just one calendar on the page I can use PHP to create a custom calendar and paste the dates here: var disabledDays = [<? echo $my_disabled_dates?>];.

However, what if  we want to display multiple date fields, each with our calendar plugin and each with different disabled days? It becomes a problem because our javascript code runs only once and we don’t modify anything on the fly using ajax or php in this case.
My idea to solve this issue is very easy. I decided to use simple php code to prepopulate the values. At first I need to pass some values from the input field  to one of the functions. I decided to use the jquery call back and names of the fields:

$('.datepicker:not(.ui-datepicker)').live('click',function(){
$(this).datepicker({
minDate: new Date(),
maxDate: new Date('', '', ''),
dateFormat: 'yy-mm-dd',
constrainInput: true,
beforeShowDay: function(date) { return noWeekendsOrHolidays(date,this.name); }
}).focus();
return false;
});

So, our noWeekendsOrHolidays will pass the name of the field. Next, the noWeekendsOrHolidays looks like this:

function noWeekendsOrHolidays(date, arg1) {
var noWeekend = jQuery.datepicker.noWeekends(date);
return noWeekend[0] ? nationalDays(date,arg1) : noWeekend;
}

So, I just passed the arg1 (name of the field) to the nationalDays which will handle our requests:

function nationalDays(date,type) {
if (type == 'EXM_trial_implementation_date') {
var disabledDays = ["1-15-2012","1-16-2012"];
} else if (type == 'one_trial_implementation_date'){
var disabledDays = ["1-19-2012","1-20-2012"];
} else if (type == 'two_trial_implementation_date'){
var disabledDays = ["1-30-2012","1-31-2012"];
} else if (type == 'three_trial_implementation_date'){
var disabledDays = ["2-15-2012","2-16-2012"];
} else if (type == 'four_trial_implementation_date'){
var disabledDays = ["3-15-2012","3-16-2012"];
}
var m = date.getMonth(), d = date.getDate(), y = date.getFullYear();
for (i = 0; i < disabledDays.length; i++) {
if($.inArray((m+1) + '-' + d + '-' + y,disabledDays) != -1 || new Date() > date) {
return [false];
}
}
return [true];
}

and of course, the var disabledDays = ["3-15-2012","3-16-2012"]; we can pre-populate using php.

Good luck!

Share

Troubleshooting connectivity problems in SQL Server 2008 with the Connectivity Ring Buffer

Few days ago we started having problems with our system based on PHP 5 and MSSQL 2008. The problem is intermittent and it doesn’t seem to be any logical explanation for it but this is what happens:

Few times a day when using our PHP system we get the following error:

Warning: mssql_connect() [function.mssql-connect]: Unable to connect
to server: 192.168.0.22 in D:\xampp\htdocs\_PROD\BE\_config
\database.connection.php on line 7
Cannot Connect To Server

In most cases, refreshing the page helps, and problem goes away. In order to to troubleshoot this problem with SQL Server 2008 we can use the new functionality that hasn’t been available in former versions of SQL Server called Connectivity Ring Buffer.

In order to do this, open a new query window and run the following command:
SELECT CAST(record AS XML) FROM sys.dm_os_ring_buffers
WHERE ring_buffer_type = ‘RING_BUFFER_CONNECTIVITY’

In my case it returns two records:

<Record id="0" type="RING_BUFFER_CONNECTIVITY" time="18230162">
 <ConnectivityTraceRecord>
  <RecordType>Error</RecordType>
  <RecordSource>Tds</RecordSource>
  <Spid>51</Spid>
  <SniConnectionId>55D5EE76-3898-4D75-94B9-58CC5E90E4D5</SniConnectionId>
  <OSError>0</OSError>
  <SniConsumerError>18456</SniConsumerError>
  <SniProvider>4</SniProvider>
  <State>38</State>
  <RemoteHost>&lt;local machine&gt;</RemoteHost>
  <RemotePort>0</RemotePort>
  <LocalHost />
  <LocalPort>0</LocalPort>
  <RecordTime>5/17/2011 20:39:34.921</RecordTime>
  <TdsBuffersInformation>
   <TdsInputBufferError>0</TdsInputBufferError>
   <TdsOutputBufferError>0</TdsOutputBufferError>
   <TdsInputBufferBytes>96</TdsInputBufferBytes>
  </TdsBuffersInformation>
  <TdsDisconnectFlags>
   <PhysicalConnectionIsKilled>0</PhysicalConnectionIsKilled>
   <DisconnectDueToReadError>0</DisconnectDueToReadError>
   <NetworkErrorFoundInInputStream>0</NetworkErrorFoundInInputStream>
   <ErrorFoundBeforeLogin>0</ErrorFoundBeforeLogin>
   <SessionIsKilled>0</SessionIsKilled>
   <NormalDisconnect>0</NormalDisconnect>
  </TdsDisconnectFlags>
 </ConnectivityTraceRecord>
 <Stack>
  <frame id="0">0X00000000013CC34B</frame>
  <frame id="1">0X00000000013C8FDD</frame>
  <frame id="2">0X00000000020E1001</frame>
  <frame id="3">0X00000000008C7E98</frame>
  <frame id="4">0X00000000004815AD</frame>
  <frame id="5">0X0000000000481492</frame>
  <frame id="6">0X000000000004BBD8</frame>
  <frame id="7">0X000000000004B8BA</frame>
  <frame id="8">0X000000000004B6FF</frame>
  <frame id="9">0X0000000000568FB6</frame>
  <frame id="10">0X0000000000569175</frame>
  <frame id="11">0X0000000000569839</frame>
  <frame id="12">0X0000000000569502</frame>
  <frame id="13">0X00000000753337D7</frame>
  <frame id="14">0X0000000075333894</frame>
  <frame id="15">0X00000000775EF56D</frame>
 </Stack>
</Record>
<Record id="1" type="RING_BUFFER_CONNECTIVITY" time="18230162">
 <ConnectivityTraceRecord>
  <RecordType>ConnectionClose</RecordType>
  <RecordSource>Tds</RecordSource>
  <Spid>51</Spid>
  <SniConnectionId>55D5EE76-3898-4D75-94B9-58CC5E90E4D5</SniConnectionId>
  <SniProvider>4</SniProvider>
  <RemoteHost>&lt;local machine&gt;</RemoteHost>
  <RemotePort>0</RemotePort>
  <LocalHost />
  <LocalPort>0</LocalPort>
  <RecordTime>5/17/2011 20:39:34.921</RecordTime>
  <TdsBuffersInformation>
   <TdsInputBufferError>0</TdsInputBufferError>
   <TdsOutputBufferError>0</TdsOutputBufferError>
   <TdsInputBufferBytes>96</TdsInputBufferBytes>
  </TdsBuffersInformation>
  <TdsDisconnectFlags>
   <PhysicalConnectionIsKilled>0</PhysicalConnectionIsKilled>
   <DisconnectDueToReadError>0</DisconnectDueToReadError>
   <NetworkErrorFoundInInputStream>0</NetworkErrorFoundInInputStream>
   <ErrorFoundBeforeLogin>0</ErrorFoundBeforeLogin>
   <SessionIsKilled>0</SessionIsKilled>
   <NormalDisconnect>0</NormalDisconnect>
   <NormalLogout>0</NormalLogout>
  </TdsDisconnectFlags>
 </ConnectivityTraceRecord>
 <Stack>
  <frame id="0">0X00000000013CC34B</frame>
  <frame id="1">0X00000000013C925E</frame>
  <frame id="2">0X000000000068C099</frame>
  <frame id="3">0X000000000004BBD8</frame>
  <frame id="4">0X000000000004B8BA</frame>
  <frame id="5">0X000000000004B6FF</frame>
  <frame id="6">0X0000000000568FB6</frame>
  <frame id="7">0X0000000000569175</frame>
  <frame id="8">0X0000000000569839</frame>
  <frame id="9">0X0000000000569502</frame>
  <frame id="10">0X00000000753337D7</frame>
  <frame id="11">0X0000000075333894</frame>
  <frame id="12">0X00000000775EF56D</frame>
  <frame id="13">0X0000000077723281</frame>
 </Stack>
</Record>

In my case, the first record returns 18456 error which can be further diagnosed here: http://www.eraofdata.com/blog/sql-18456-login-failures/

Share