<?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>AdSpeed.org</title>
	<atom:link href="http://adspeed.org/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://adspeed.org</link>
	<description>Giving IT Back - Knowledge Sharing Repository from AdSpeed Ad Server</description>
	<lastBuildDate>Wed, 15 Dec 2010 00:48:24 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.4.2</generator>
		<item>
		<title>String rotation method for simple encoding</title>
		<link>http://adspeed.org/?p=23</link>
		<comments>http://adspeed.org/?p=23#comments</comments>
		<pubDate>Fri, 19 Dec 2008 17:34:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://adspeed.org/?p=23</guid>
		<description><![CDATA[/** rotate a string, use for simple encoding */ function rotateString($pInput,$pRotateNum=0) { $vOutput = &#8221;; $vStr = &#8216;abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890&#124;&#8217;; $vLen = strlen($vStr); for ($i=0;$i0?$vIndex%$vLen:($vLen+$vIndex)%$vLen; $vOutput .= $vStr{$vIndex}; } // fi } // rof //var_dump($vOutput); return $vOutput; } Usage $a = rotateString($b,19); // encode $b = rotateString($a,-19); // decode]]></description>
			<content:encoded><![CDATA[<p><textarea name="code" class="php"><br />
/** rotate a string, use for simple encoding  */<br />
 function rotateString($pInput,$pRotateNum=0) {<br />
  $vOutput = &#8221;;<br />
  $vStr = &#8216;abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890|&#8217;;<br />
  $vLen = strlen($vStr);<br />
  for ($i=0;$i<strlen($pInput);$i++) {<br />
   $vIndex = strpos($vStr,$pInput{$i});<br />
   if ($vIndex===FALSE) { // non-encode chars, leave these alone<br />
    $vOutput .= $pInput{$i};<br />
   } else {<br />
    $vIndex = $vIndex+$pRotateNum;<br />
    $vIndex = $vIndex>0?$vIndex%$vLen:($vLen+$vIndex)%$vLen;<br />
    $vOutput .= $vStr{$vIndex};<br />
   } // fi<br />
  } // rof<br />
  //var_dump($vOutput);<br />
  return $vOutput;<br />
 }<br />
</textarea></p>
<h4>Usage</h4>
<pre>
$a = rotateString($b,19); // encode
$b = rotateString($a,-19); // decode
</pre>
]]></content:encoded>
			<wfw:commentRss>http://adspeed.org/?feed=rss2&#038;p=23</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Popup</title>
		<link>http://adspeed.org/?p=22</link>
		<comments>http://adspeed.org/?p=22#comments</comments>
		<pubDate>Mon, 27 Oct 2008 23:08:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://adspeed.org/?p=22</guid>
		<description><![CDATA[This scripts show the content of a div when clicked on an opener. if (typeof(document.createElement(&#8216;div&#8217;).contains) == &#8216;undefined&#8217;) { /** overwrite this function to avoid firing child event inside a parent */ HTMLElement.prototype.contains = function(node) { if (node == null) return false; if (node == this) return true; else return this.contains(node.parentNode); } } // fi var [...]]]></description>
			<content:encoded><![CDATA[<p>This scripts show the content of a div when clicked on an opener.</p>
<p><textarea name="code" class="js"><br />
if (typeof(document.createElement(&#8216;div&#8217;).contains) == &#8216;undefined&#8217;) {<br />
  /** overwrite this function to avoid firing child event inside a parent */<br />
  HTMLElement.prototype.contains = function(node) {<br />
    if (node == null) return false;<br />
    if (node == this) return true;<br />
    else return this.contains(node.parentNode);<br />
 }<br />
} // fi</p>
<p>var $globInPopup = false;<br />
var $globTarget;<br />
var $globTimerID;</p>
<p>function signalMouseIn($pPopID,$pEvt) {<br />
  $globInPopup = true;<br />
  window.clearTimeout($globTimerID);<br />
}<br />
function closePop($pPopID,$pEvt) {<br />
 var $vPop = $as($pPopID);<br />
 if (!$vPop.contains(getTarget($pEvt))) {<br />
  $globTarget = getTarget($pEvt);<br />
  $globTimerID = window.setTimeout(&#8220;mouseOutPopup(&#8216;&#8221;+$pPopID+&#8221;&#8216;)&#8221;,600);<br />
 } // if<br />
}<br />
function mouseOutPopup($pPopID) {<br />
 var $vPop = $as($pPopID);<br />
 if (!$vPop.contains($globTarget)) {<br />
  hidePopup($vPop);<br />
 } // fi<br />
}<br />
function trigOpenerOut($pPopID,$pEvt) {<br />
 $globTarget = getTarget($pEvt);<br />
 $globTimerID = window.setTimeout(&#8220;mouseOutOpener(&#8216;&#8221;+$pPopID+&#8221;&#8216;)&#8221;,600);<br />
}<br />
function mouseOutOpener($pPopID) {<br />
 var $vPop = $as($pPopID);<br />
 if (!$globInPopup &#038;&#038; !$vPop.contains($globTarget)) {<br />
  hidePopup($vPop);<br />
 } // fi<br />
}</p>
<p>function hidePopup($pPop) {<br />
 $pPop.style.visibility = &#8216;hidden&#8217;;<br />
 $globInPopup = false;<br />
}</p>
<p>function getTarget($pEvent) {<br />
 if (typeof($pEvent.relatedTarget)!=&#8217;undefined&#8217;) {<br />
  return $pEvent.relatedTarget;<br />
 } else if (typeof($pEvent.toElement)!=&#8217;undefined&#8217;) {<br />
  return $pEvent.toElement;<br />
 } // fi<br />
 return false;<br />
}</p>
<p>function showRelPop($pPopID) {<br />
 $as($pPopID).style.visibility = &#8216;visible&#8217;;<br />
}<br />
</textarea></p>
]]></content:encoded>
			<wfw:commentRss>http://adspeed.org/?feed=rss2&#038;p=22</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>jQuery &#8211; Extend tablesorter plugin</title>
		<link>http://adspeed.org/?p=21</link>
		<comments>http://adspeed.org/?p=21#comments</comments>
		<pubDate>Thu, 16 Oct 2008 17:59:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://adspeed.org/?p=21</guid>
		<description><![CDATA[This js code extends the tablesorter plugin in jQuery: Parser for sorting values like &#8220;$1,300.50&#8243; Parser for sorting values like &#8220;2 months ago&#8221;,&#8221;3 years ago&#8221; (actual timestamp hide in the comment) Parser for sorting values like &#8220;SMALLER&#8221;,&#8221;SMALL&#8221; (actual text value hide in comment) Widget to highlight a row when mouse hovers it Widget to highlight [...]]]></description>
			<content:encoded><![CDATA[<p>This js code extends the tablesorter plugin in jQuery:</p>
<ol>
<li>Parser for sorting values like &#8220;$1,300.50&#8243;</li>
<li>Parser for sorting values like &#8220;2 months ago&#8221;,&#8221;3 years ago&#8221; (actual timestamp hide in the comment)</li>
<li>Parser for sorting values like &#8220;SMALLER&#8221;,&#8221;SMALL&#8221; (actual text value hide in comment)</li>
<li>Widget to highlight a row when mouse hovers it</li>
<li>Widget to highlight a header when mouse hovers it</li>
<li>Widget to save/memorize sort order via AJAX</li>
</ol>
<p>Let&#8217;s get right into the code:</p>
</ol>
<p><textarea name="code" class="js"><br />
/** define custom sorter and widgets for tablesorter plugin for jQuery<br />
* @since 10/4/2008<br />
* @author Son Nguyen<br />
*/</p>
<p>// add sorting by 1,300,000 (with commas)<br />
$.tablesorter.addParser({<br />
 id: &#8220;fwnumber&#8221;,<br />
 is: function(s) {<br />
  return false;<br />
 },<br />
 format: function(s) {<br />
  return $.tablesorter.formatFloat(s.replace(/(\,|\%)/g,&#8221;"));<br />
 },<br />
 type: &#8220;numeric&#8221;<br />
});</p>
<p>// only look for value in the comment, eg: <!--text--><img>,<br />
$.tablesorter.addParser({<br />
 id: &#8220;commenttxt&#8221;,<br />
 is: function(s) {<br />
  return /^<!--([a-z]+)-->/.test($.trim(s));<br />
 },<br />
 format: function(s) {<br />
  return s.replace(/^<!--([a-z]+)-->.*/g,&#8221;$1&#8243;);<br />
 },<br />
 type: &#8220;text&#8221;<br />
});</p>
<p>// only look for value in the comment, eg: <!--21928--><date><br />
$.tablesorter.addParser({<br />
 id: &#8220;commentnum&#8221;,<br />
 is: function(s) {<br />
  return /^<!--([0-9]+)-->/.test($.trim(s));<br />
 },<br />
 format: function(s) {<br />
  return s.replace(/^<!--([0-9]+)-->.*/g,&#8221;$1&#8243;);<br />
 },<br />
 type: &#8220;numeric&#8221;<br />
});</p>
<p>// show the hover row different than other rows<br />
$.tablesorter.addWidget({<br />
 id: &#8220;rowHover&#8221;,<br />
 format: function(table) {<br />
  $(&#8220;tr:visible&#8221;,table.tBodies[0]).hover(<br />
   function () { $(this).addClass(table.config.widgetRowHover.css); },<br />
   function () { $(this).removeClass(table.config.widgetRowHover.css); }<br />
  );<br />
 }<br />
}); </p>
<p>// apply CSS to the sortable header when mouse hovers it<br />
$.tablesorter.addWidget({<br />
 id: &#8220;headerHover&#8221;,<br />
 format: function(table) {<br />
  $(&#8220;thead th:visible&#8221;,table).hover(<br />
   function () { if (!table.config.headerList[$("thead th:visible",table).index(this)].sortDisabled) $(this).addClass(table.config.widgetHeaderHover.css); },<br />
   function () { $(this).removeClass(table.config.widgetHeaderHover.css); }<br />
  );<br />
 }<br />
}); </p>
<p>// call a link via AJAX to save/memorize the sort order<br />
$.tablesorter.addWidget({<br />
 id: &#8220;memorizeSortOrder&#8221;,<br />
 format: function(table) {<br />
  if (!table.config.widgetMemorizeSortOrder.isBinded) { // only bind if not already binded<br />
   table.config.widgetMemorizeSortOrder.isBinded = true;<br />
   $(&#8220;thead th:visible&#8221;,table).click(function() {<br />
    var i = $(&#8220;thead th:visible&#8221;,table).index(this);<br />
    $.get(table.config.widgetMemorizeSortOrder.url+i+&#8217;|'+table.config.headerList[i].order);<br />
   });<br />
  } // fi<br />
 }<br />
});<br />
</textarea></p>
<p>Demo HTML file</p>
<p><textarea name="code" class="html"><br />
<html><br />
 <head></p>
<p>	<script src="jquery-1.2.6.min.js"></script><br />
	<script src="jquery.tablesorter.min.js"></script><br />
	<script src="tablesorter.extend.js"></script></p>
<style>
		.rowhover {background:green}
		.headerhover {background:blue}
		.even2 {background:#CCC}
		.odd {background:#DDD}
	</style>
<p> </head></p>
<p> <body></p>
<h1>This table is sortable, click on the headings to sort</h1>
<table id="myGrid" cellpadding="0" cellspacing="0">
<thead>
<tr>
<th>Number</th>
<th>String</th>
<th>Currency</th>
<th>Embedded</th>
<th>Time</th>
</tr>
</thead>
<tbody>
<tr>
<td>120</td>
<td>ABC</td>
<td>$123.50</td>
<td><!--d-->MEDIUM</td>
<td><!--3-->1 month</td>
</tr>
<tr>
<td>0</td>
<td>XYZ</td>
<td>$99</td>
<td><!--c-->SMALL</td>
<td><!--4-->1 week</td>
</tr>
<tr>
<td>1</td>
<td>Member</td>
<td>$932,329</td>
<td><!--b-->SMALLER</td>
<td><!--2-->2 month</td>
</tr>
<tr>
<td>678</td>
<td>John Doe</td>
<td>$323.23</td>
<td><!--a-->SMALLEST</td>
<td><!--1-->1 year</td>
</tr>
<tr>
<td>4,342</td>
<td>O&#8217;Ryan</td>
<td>$1,223.50</td>
<td><!--e-->LARGE</td>
<td><!--5-->2 day</td>
</tr>
</tbody>
</table>
<p><script type="text/javascript">
	$("#myGrid").tablesorter({
		//debug:true,
		headers:{0:{sorter:'fwnumber'}},
		widgets:['zebra','headerHover','rowHover','memorizeSortOrder'],
		widgetZebra:{css:["even","odd"]},
		widgetRowHover:{css:'rowhover'},
		widgetHeaderHover:{css:'headerhover'},
		widgetMemorizeSortOrder:{url:'http://example.com/ajax.php?update='},
		cssHeader:'',
		cssAsc:'',
		cssDesc:''		
	}); 
</script></p>
<p> </body><br />
</html></p>
<p></textarea></p>
]]></content:encoded>
			<wfw:commentRss>http://adspeed.org/?feed=rss2&#038;p=21</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Time-Series Forecasting with PHP</title>
		<link>http://adspeed.org/?p=20</link>
		<comments>http://adspeed.org/?p=20#comments</comments>
		<pubDate>Thu, 02 Oct 2008 03:22:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://adspeed.org/?p=20</guid>
		<description><![CDATA[This PHP 5 class forecasts future values from past data. It takes into account the growth trend, seasonality and irregularity (noise) in input data. This class uses an external class: linear regression analysis]]></description>
			<content:encoded><![CDATA[<p>This PHP 5 class forecasts future values from past data. It takes into account the growth trend, seasonality and irregularity (noise) in input data. This class uses an external class: <a href="http://blog.trungson.com/2005/11/linear-regression-php-class.html">linear regression analysis</a></p>
<p><textarea name="code" class="php"><br />
<?php<br />
/** A time-series forcasting, given a series of data (w/ seasonal data), predict future data<br />
* Src: http://home.ubalt.edu/ntsbarsh/stat-data/Forecast.htm &#038; BUS264 (Oliver Yu's coursenote)<br />
* @author Son Nguyen<br />
* @since 10/1/2008<br />
* @package Framework<br />
* @subpackage Math<br />
*/<br />
class CMathForecasting {<br />
   private $mPastDatas; // array of data (eg: x1,x2,x3,x4...)<br />
   private $mNumSeasons; // the number of seasons to consider (eg: 4 quarters/year, 7 days/week, 24 hours/day)<br />
   /** constructor */<br />
   function __construct($pPastDatas,$pNumSeasons) {<br />
      $this->mPastDatas = $pPastDatas;<br />
      $this->mNumSeasons = $pNumSeasons;<br />
   }</p>
<p>   /** compute the n-season moving average */<br />
   function computeSMA() {<br />
      $vSMA = array();<br />
      for ($i=0;$i<count($this->mPastDatas);$i++) {<br />
         if ($i+$this->mNumSeasons-1>=count($this->mPastDatas)) { // out of bound, done<br />
            break;<br />
         } // fi</p>
<p>         $vSum = 0;<br />
         for ($j=0;$j<$this->mNumSeasons;$j++) {<br />
            $vSum += $this->mPastDatas[$i+$j];<br />
         } // rof<br />
         $vSMA[] = $vSum/$this->mNumSeasons;<br />
      } // rof<br />
      return $vSMA;<br />
   }</p>
<p>   /** compute centered moving average from the n-season moving average */<br />
   function computeCMA($pSMA) {<br />
      $vCMA = array();<br />
      for ($i=0;$i<count($pSMA);$i++) {<br />
         if ($i+1>=count($pSMA)) { // out of bound, done<br />
            break;<br />
         } // fi<br />
         $vCMA[] = ($pSMA[$i]+$pSMA[$i+1])/2;<br />
      } // rof<br />
      return $vCMA;<br />
   }</p>
<p>   /** season irregularity */<br />
   function computeNoises($pCMA) {<br />
      $vNoises = array();<br />
      for ($i=0;$i<count($pCMA);$i++) {<br />
         $vStarting = floor($this->mNumSeasons/2);<br />
         $vNoises[] = $this->mPastDatas[$i+$vStarting]/$pCMA[$i];<br />
      } // rof<br />
      return $vNoises;<br />
   }</p>
<p>   /** comment */<br />
   function computeSeasonIndices($pNoises) {<br />
      $vIndices = array();<br />
      for ($i=0;$i<$this->mNumSeasons;$i++) {<br />
         $vSum = array();<br />
         for ($j=$i;$j<count($pNoises);$j+=$this->mNumSeasons) {<br />
            $vSum[] = $pNoises[$j];<br />
         } // rof<br />
         $vStarting = (floor($this->mNumSeasons/2)+$i)%$this->mNumSeasons;<br />
         $vIndices[$vStarting] = array_sum($vSum)/count($vSum);<br />
      } // rof</p>
<p>      ksort($vIndices);</p>
<p>      // also adjust these season indices<br />
      $vSum = array_sum($vIndices);<br />
      for ($i=0;$i<count($vIndices);$i++) {<br />
         $vIndices[$i] = $vIndices[$i]*$this->mNumSeasons/$vSum;<br />
      } // rof<br />
      return $vIndices;<br />
   }</p>
<p>   /** comment */<br />
   function computeDeSeasonalized($pSeasonIndex) {<br />
      $vDatas = array();</p>
<p>      for ($i=0;$i<count($this->mPastDatas);$i++) {<br />
         $vDatas[] = $this->mPastDatas[$i]/$pSeasonIndex[$i%$this->mNumSeasons];<br />
      } // rof<br />
      return $vDatas;<br />
   }</p>
<p>   /** how many future periods to predict */<br />
   function predict($pNumFuturePeriods) {<br />
      $vSMA = $this->computeSMA();<br />
      if ($this->mNumSeasons%2==0) { // even<br />
         $vCMA = $this->computeCMA($vSMA);<br />
      } else { // odd, nSMA=CMA<br />
         $vCMA = $vSMA;<br />
      } // fi</p>
<p>      $vNoises = $this->computeNoises($vCMA);<br />
      $vIndices = $this->computeSeasonIndices($vNoises);</p>
<p>      $vDeSeasonalized = $this->computeDeSeasonalized($vIndices);</p>
<p>      // perform regression to get the trend line<br />
      $vRegression = new CRegressionLinear($vDeSeasonalized);<br />
      list($vXVar,$vIntercept) = $vRegression->calculate();</p>
<p>      $vForecast = array();<br />
      for ($i=0;$i<$pNumFuturePeriods;$i++) {<br />
         $vForecast[] = $vIntercept + $vXVar*(count($this->mPastDatas)+$i);<br />
      } // rof</p>
<p>      // have to re-seasonalized these values<br />
      for ($i=0;$i<count($vForecast);$i++) {<br />
         $vForecast[$i] = $vForecast[$i]*$vIndices[(count($this->mPastDatas)+$i)%$this->mNumSeasons];<br />
      } // rof</p>
<p>      return $vForecast;</p>
<p>   }<br />
}<br />
?><br />
</textarea></p>
<h3>Sample Usage</h3>
<p><textarea name="code" class="php"><br />
<?php<br />
include('math.reg.linear.class.php');<br />
include('math.forecasting.class.php');</p>
<p>// Example #1: daily sales number for the past 30 days<br />
$vSales = array(<br />
   637381,700986,641305,660285,604474,565316,598734,688690,723406,697358,<br />
   669910,605636,526655,555165,625800,579405,588317,634433,628443,570597,<br />
   662584,763516,742150,703209,669883,586504,489240,648875,692212,586509<br />
);</p>
<p>$vForecast = new CMathForecasting($vSales,7); // sales pattern is weekly<br />
$vResult = $vForecast->predict(7); // predict the next 7 days<br />
var_dump($vResult);</p>
<p>// Example #2: quarterly demand number (x1000 units)<br />
$vSales = array(<br />
   3,9,6,2,<br />
   4,11,8,3,<br />
   5,15,11,3<br />
);</p>
<p>$vForecast = new CMathForecasting($vSales,4); // sales pattern is quarterly<br />
$vResult = $vForecast->predict(4); // predict the next 4 quarters<br />
var_dump($vResult);<br />
?><br />
</textarea></p>
]]></content:encoded>
			<wfw:commentRss>http://adspeed.org/?feed=rss2&#038;p=20</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>JSON with Padding = JSONP</title>
		<link>http://adspeed.org/?p=19</link>
		<comments>http://adspeed.org/?p=19#comments</comments>
		<pubDate>Tue, 19 Aug 2008 17:15:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[ajax]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://adspeed.org/?p=19</guid>
		<description><![CDATA[With JSONP, you can avoid the &#8220;Access is Denied&#8221; problem when loading a remote AJAX request. jQuery 1.2.x now supports JSONP, you can use that or this simple code snippet. In this example, let&#8217;s assume you&#8217;re on a page with a remote javascript loaded, now you only want this remote script to reload, not the [...]]]></description>
			<content:encoded><![CDATA[<p>With JSONP, you can avoid the &#8220;Access is Denied&#8221; problem when loading a remote AJAX request. jQuery 1.2.x now supports JSONP, you can use that or this simple code snippet. In this example, let&#8217;s assume you&#8217;re on a page with a remote javascript loaded, now you only want this remote script to reload, not the whole page.</p>
<p><textarea name="code" class="js"><br />
function reloadJS() {<br />
  var url = &#8216;http://example.com/getJSON.php?id=1234&#8242;;<br />
  var js = document.createElement(&#8220;script&#8221;);<br />
  js.setAttribute(&#8220;src&#8221;,url+&#8221;&#038;CacheBuster=&#8221;+Math.random());<br />
  js.setAttribute(&#8220;type&#8221;,&#8221;text/javascript&#8221;);<br />
  document.body.appendChild(js);<br />
}</p>
<p>function ajaxJSONCallback(data) {<br />
  document.getElementById(&#8220;SomeDivID&#8221;).innerHTML = data.SomeData;<br />
}</p>
<p>window.setInterval(&#8220;reloadJS()&#8221;,10000);</p>
<p></textarea></p>
<p>And the result of getJSON.php:<br />
<textarea name="code" class="js"><br />
ajaxJSONCallback({&#8220;SomeData&#8221;:&#8221;
<p>Test Output</p>
<p>&#8220;});<br />
</textarea></p>
]]></content:encoded>
			<wfw:commentRss>http://adspeed.org/?feed=rss2&#038;p=19</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Reloading partial page content with JavaScript</title>
		<link>http://adspeed.org/?p=18</link>
		<comments>http://adspeed.org/?p=18#comments</comments>
		<pubDate>Wed, 06 Aug 2008 17:56:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://adspeed.org/?p=18</guid>
		<description><![CDATA[If you need to reload a partial content (not the whole page) with JavaScript, you can easily use AJAX (jQuery is the simplest). But if the content is also from another website (eg: some API), then you can use JSONP (JSON with Padding) to get around the security protection of AJAX requests. document.write(&#8220; &#8220;); document.write(&#8220;Initial [...]]]></description>
			<content:encoded><![CDATA[<p>If you need to reload a partial content (not the whole page) with JavaScript, you can easily use AJAX (jQuery is the simplest). But if the content is also from another website (eg: some API), then you can use JSONP (JSON with Padding) to get around the security protection of AJAX requests. </p>
<p><textarea name="code" class="js"><br />
document.write(&#8220;
<div id=\"MyContent\">&#8220;);<br />
document.write(&#8220;Initial Contents&#8221;);<br />
document.write(&#8220;</div>
<p>&#8220;);</p>
<p>function reloadJS() {<br />
 var js = document.createElement(&#8220;script&#8221;);<br />
 js.setAttribute(&#8220;src&#8221;,&#8221;http://example.com/javascript.php?output=jsonp&#038;random=&#8221;+Math.random());<br />
 js.setAttribute(&#8220;type&#8221;,&#8221;text/javascript&#8221;);<br />
 document.body.appendChild(js);<br />
}</p>
<p>function ajaxJSONCallback(data) {<br />
 document.getElementById(&#8220;MyContent&#8221;).innerHTML = data.FullHTML;<br />
}<br />
window.setInterval(&#8220;reloadJS()&#8221;,{ASJSRefreshSec});<br />
</textarea></p>
<p>And in the server-side javascript.php, you would return:<br />
<textarea name="code" class="js"><br />
ajaxJSONCallback({&#8216;FullHTML&#8217;:'New Content&#8217;})<br />
</textarea></p>
]]></content:encoded>
			<wfw:commentRss>http://adspeed.org/?feed=rss2&#038;p=18</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Javascript table grid sort</title>
		<link>http://adspeed.org/?p=17</link>
		<comments>http://adspeed.org/?p=17#comments</comments>
		<pubDate>Mon, 31 Mar 2008 23:22:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://adspeed.org/?p=17</guid>
		<description><![CDATA[/** grid sorting class * @since 3/29/2005 * @author Son Nguyen * @package Scripts * @subpackage Grid */ function CGridSort($pTableID) { this.mTable = $($pTableID); this.mSortOrder = null; // asc=0, desc=1 this.mColumnIndex = null; // which is the actively sorted col this.mShouldBeOrder = null; // the correct order after sorted this.mCurrentOrder = null; // the current [...]]]></description>
			<content:encoded><![CDATA[<p><textarea name="code" class="js"><br />
/** grid sorting class<br />
* @since 3/29/2005<br />
* @author Son Nguyen<br />
* @package Scripts<br />
* @subpackage Grid<br />
*/<br />
function CGridSort($pTableID) {<br />
	this.mTable = $($pTableID);<br />
	this.mSortOrder = null; // asc=0, desc=1<br />
	this.mColumnIndex = null; // which is the actively sorted col<br />
	this.mShouldBeOrder = null; // the correct order after sorted<br />
	this.mCurrentOrder = null; // the current row order</p>
<p>	this.mBodyOnClass = null; // mouse over row style<br />
	this.mBodyOffClass = null;<br />
	this.mHeaderOnClass = null; // mouse over header style<br />
	this.mHeaderOffClass = null;<br />
	this.mHeaderUpClass = null; // header sorted up<br />
	this.mHeaderDownClass = null; </p>
<p>	var $vRows = this.mTable.rows;<br />
	for (var $i=1;$i<$vRows.length;$i++) { // assumption: 1st row is header! Skip!<br />
		if ($vRows[$i].nodeName == 'TR') {<br />
			var oThis = this;<br />
			$vRows[$i].onmouseover = function () { oThis.highLiteRow(this) };<br />
			$vRows[$i].onmouseout = function () { oThis.highLiteRow(this) };<br />
		} // fi<br />
	} // rof<br />
}</p>
<p>CGridSort.prototype.setBodyClass = function($pOn,$pOff) {<br />
	this.mBodyOnClass = $pOn;<br />
	this.mBodyOffClass = $pOff;<br />
}</p>
<p>CGridSort.prototype.setHeaderClass = function($pOn,$pOff,$pUp,$pDown) {<br />
	this.mHeaderOnClass = $pOn;<br />
	this.mHeaderOffClass = $pOff;<br />
	this.mHeaderUpClass = $pUp;<br />
	this.mHeaderDownClass = $pDown;<br />
}</p>
<p>CGridSort.prototype.highLiteRow = function($pRowObj) {<br />
	var $vCSS = new CElementCSS($pRowObj);<br />
	if ($vCSS.hasStyle(this.mBodyOnClass)) {<br />
		$vCSS.removeStyle(this.mBodyOnClass);<br />
		$vCSS.appendStyle(this.mBodyOffClass);<br />
	} else {<br />
		$vCSS.removeStyle(this.mBodyOffClass);<br />
		$vCSS.appendStyle(this.mBodyOnClass);<br />
	} // fi<br />
}</p>
<p>CGridSort.prototype.showSrtOrd = function($pHeaderCell,$pIsHeaderOn) {<br />
	this.clearOrders($pHeaderCell);<br />
	var $pPrimary = ($pIsHeaderOn==true)?this.mHeaderOnClass:this.mHeaderOffClass;</p>
<p>	if ($pHeaderCell.cellIndex==this.mColumnIndex &#038;&#038; this.mSortOrder==0) {<br />
		$pHeaderCell.className = $pPrimary+' '+this.mHeaderUpClass;<br />
	} else if ($pHeaderCell.cellIndex==this.mColumnIndex &#038;&#038; this.mSortOrder==1) {<br />
		$pHeaderCell.className = $pPrimary+' '+this.mHeaderDownClass;<br />
	} else {<br />
		$pHeaderCell.className = $pPrimary;<br />
	} // fi<br />
}<br />
/** clear orders for other headers */<br />
CGridSort.prototype.clearOrders = function($pHeaderCell) {<br />
	var $vHeaders = $pHeaderCell.parentNode.childNodes;<br />
	for (var $i=0;$i<$vHeaders.length;$i++) {<br />
		if ($vHeaders[$i].nodeName=='TH' &#038;&#038; $i!=this.mColumnIndex &#038;&#038; $vHeaders[$i] != $pHeaderCell) {<br />
			$vHeaders[$i].className = this.mHeaderOffClass;<br />
		} // fi<br />
	} // rof<br />
}</p>
<p>/** actually do the sorting */<br />
CGridSort.prototype.sortCol = function($pColumnIndex) {<br />
	this.mSortOrder = (this.mSortOrder!=null &#038;&#038; $pColumnIndex==this.mColumnIndex)?(this.mSortOrder+1)%2:0;<br />
	this.mColumnIndex = $pColumnIndex;</p>
<p>	this.initSort();</p>
<p>	// swap those not in place<br />
	for (var $i=0;$i
<this.mCurrentOrder.length;$i++) {<br />
		if (this.mCurrentOrder[$i]!=this.mShouldBeOrder[this.mColumnIndex][$i]) {<br />
			this.swapRow(this.mCurrentOrder[$i],this.mShouldBeOrder[this.mColumnIndex][$i]);<br />
		} // fi<br />
	} // rof</p>
<p>	// reverse the order array<br />
	this.mShouldBeOrder[this.mColumnIndex].reverse();<br />
}</p>
<p>/** init the global vars, done for every col for the first time */<br />
CGridSort.prototype.initSort = function() {<br />
	// init gRows for this table if not done outside already<br />
	if (this.mCurrentOrder==null) {<br />
		this.mCurrentOrder = new Array();<br />
		var $vLength = 0;<br />
		var $vCnt = 0;<br />
		var $vRows = this.mTable.rows;<br />
		for (var $i=1;$i<$vRows.length;$i++) { // assumption: 1st row is header! Skip!<br />
			if ($vRows[$i].nodeName == 'TR') {<br />
				this.mCurrentOrder[this.mCurrentOrder.length] = $vRows[$i].id;<br />
			} // fi<br />
		} // rof<br />
	} // fi</p>
<p>	// init order-by array<br />
	if (this.mShouldBeOrder==null) { this.mShouldBeOrder = new Array(); }<br />
	if (typeof(this.mShouldBeOrder[this.mColumnIndex])=='undefined') {<br />
		this.mShouldBeOrder[this.mColumnIndex] = new Array();<br />
		var $vTmpAry = new Array();<br />
		var $vTmpAry2 = new Array();<br />
		var $vCellValue = null;<br />
		var $vKey = null;<br />
		var $vSampleValue = null;<br />
		for (var $i=0;$i<this.mCurrentOrder.length;$i++) {<br />
			$vCellValue = this.processSortValue($(this.mCurrentOrder[$i]).cells[this.mColumnIndex].innerHTML);<br />
			if ($vCellValue!='') {<br />
				$vSampleValue = $vCellValue;<br />
			} // if<br />
			$vTmpAry[$i] = $vCellValue;</p>
<p>			$vKey = $vCellValue;<br />
			while (typeof($vTmpAry2[$vKey])!='undefined') {<br />
				$vKey = $vKey+'x';<br />
			} // rof<br />
			$vTmpAry2[$vKey] = this.mCurrentOrder[$i];<br />
		} // rof</p>
<p>		// determine sort algorithm and sorting<br />
		var $vSortFn = null; // this.sortCaseInsen; // default, use the internally supported, the other give IE "Number Expected" err<br />
		if ($vSampleValue.match(/^\d\d[\/-]\d\d[\/-]\d\d\d\d$/)) $vSortFn = this.sortDate;<br />
	    if ($vSampleValue.match(/^\d\d[\/-]\d\d[\/-]\d\d$/)) $vSortFn = this.sortDate;<br />
		if ($vSampleValue.match(/^[£$]/)) $vSortFn = this.sortCur;<br />
	    if ($vSampleValue.match(/^[\d\.\,\%]+$/)) $vSortFn = this.sortNum;<br />
		//alert($vSortFn);<br />
		if ($vSortFn!=null) {<br />
			$vTmpAry.sort($vSortFn);<br />
		} else {<br />
			$vTmpAry.sort();<br />
		} // fi</p>
<p>		//alert('pass sorting');</p>
<p>		// correct the duplicate rows<br />
		for (var $i=0;$i<$vTmpAry.length;$i++) {<br />
			for (var $j=$i+1;$j<$vTmpAry.length;$j++) {<br />
				if ($vTmpAry[$i]==$vTmpAry[$j]) {<br />
					$vTmpAry[$j] = $vTmpAry[$j]+'x';<br />
				} else { // break out of the first loop now, save some time<br />
					break;<br />
				} // fi<br />
			} // rof<br />
		} // rof</p>
<p>		var $vRowID = null;<br />
		for (var $i=0;$i<$vTmpAry.length;$i++) {<br />
			$vRowID = $vTmpAry2[$vTmpAry[$i]];<br />
			this.mShouldBeOrder[this.mColumnIndex][$i] = $vRowID;<br />
		} // rof<br />
	} // fi<br />
}</p>
<p>/** swapping data and index */<br />
CGridSort.prototype.swapRow = function($pRowA,$pRowB) {<br />
	var $vOne = $($pRowA);<br />
	var $vTwo = $($pRowB);<br />
	var $vTmp;</p>
<p>	// 1.3 swap the data<br />
	for (var $k=0;$k<$vOne.cells.length;$k++) {<br />
		$vTmp = $vOne.cells[$k].innerHTML;<br />
		$vOne.cells[$k].innerHTML = $vTwo.cells[$k].innerHTML;<br />
		$vTwo.cells[$k].innerHTML = $vTmp;<br />
	} // for</p>
<p>	// 2.3 also swap index<br />
	for (var $k=0;$k<this.mCurrentOrder.length;$k++) {<br />
		if (this.mCurrentOrder[$k] == $pRowA) {<br />
			this.mCurrentOrder[$k] = $pRowB;<br />
		} else if (this.mCurrentOrder[$k] == $pRowB) {<br />
			this.mCurrentOrder[$k] = $pRowA;<br />
		} // else<br />
	} // for</p>
<p>	// 3.3 also swap id<br />
	$vOne.id = $pRowB;<br />
	$vTwo.id = $pRowA;<br />
}</p>
<p>/** strip tags, process special comment for timestamp/other special cases */<br />
CGridSort.prototype.processSortValue = function($pValue) {<br />
	var $vResult = $pValue.match(/<!--([^-]+)-->/g);<br />
	if ($vResult) { // comment stores the real value, ignore the outside<br />
		$pValue = $vResult[0];<br />
		$pValue = $pValue.substring(4,$pValue.length-4);<br />
		$pValue = $pValue.replace(/ /g,&#8221;);<br />
	} else { // strip tags or everything within tags<br />
		var $vBkup = $pValue;<br />
		// first try to strip everything between a pair of tags<br />
		$pValue = $pValue.replace(/<[^>]+>/g,&#8217;<>&#8216;); // anything in <><br />
		$pValue = $pValue.replace(/<>.*<>/g,&#8221;);<br />
		$pValue = $pValue.replace(/<>/g,&#8221;);<br />
		if ($pValue==&#8221;) { // then only strip tags, leave everything in between<br />
			$pValue = $vBkup.replace(/<[^>]+>/g,&#8221;);<br />
		} // fi<br />
		$pValue = $pValue.replace(/^\s*|\s*$/g,&#8221;);	// whitespaces<br />
		$pValue = $pValue.replace(/ /g,&#8221;);<br />
		$pValue = $pValue.replace(/&nbsp;/g,&#8221;);<br />
		$pValue = $pValue.replace(/\n/g,&#8221;);<br />
	} // fi<br />
	return $pValue;<br />
}</p>
<p>/** HELPER, SORT FUNCTIONS */</p>
<p>/** sort case insensitive */<br />
CGridSort.prototype.sortCaseInsen = function($pValueA,$pValueB) {<br />
	$pValueA = $pValueA.toLowerCase();<br />
	$pValueB = $pValueB.toLowerCase();</p>
<p>    if ($pValueA>$pValueB) return 1;<br />
    if ($pValueA<$pValueB) return -1;<br />
    return 0;<br />
}</p>
<p>CGridSort.prototype.sortNum = function($pValueA,$pValueB) {<br />
	$pValueA = parseFloat($pValueA.replace(/[^0-9.]/g,''));<br />
    $pValueB = parseFloat($pValueB.replace(/[^0-9.]/g,''));</p>
<p>	if (isNaN($pValueA)) $pValueA = 0;<br />
	if (isNaN($pValueB)) $pValueB = 0;</p>
<p>	return $pValueA-$pValueB;<br />
}</p>
<p>/** sort on date */<br />
CGridSort.prototype.sortDate = function($pValueA,$pValueB) {<br />
    if ($pValueA.length == 10) {<br />
        $dt1 = $pValueA.substr(6,4)+$pValueA.substr(3,2)+$pValueA.substr(0,2);<br />
    } else {<br />
        $yr = $pValueA.substr(6,2);<br />
        if (parseInt($yr) < 50) { $yr = '20'+$yr; } else { $yr = '19'+$yr; }<br />
        $dt1 = $yr+$pValueA.substr(3,2)+$pValueA.substr(0,2);<br />
    } // if</p>
<p>    if ($pValueB.length == 10) {<br />
        $dt2 = $pValueB.substr(6,4)+$pValueB.substr(3,2)+$pValueB.substr(0,2);<br />
    } else {<br />
        $yr = $pValueB.substr(6,2);<br />
        if (parseInt($yr) < 50) { $yr = '20'+$yr; } else { $yr = '19'+$yr; }<br />
        $dt2 = $yr+$pValueB.substr(3,2)+$pValueB.substr(0,2);<br />
    }<br />
    if ($dt1==$dt2) return 0;<br />
    if ($dt1<$dt2) return -1;<br />
    return 1;<br />
}</p>
<p>/** sort currency */<br />
CGridSort.prototype.sortCur = function($pValueA,$pValueB) {<br />
	$pValueA = $pValueA.replace(/[^0-9.]/g,'');<br />
    $pValueB = $pValueB.replace(/[^0-9.]/g,'');<br />
    return parseFloat($pValueA) - parseFloat($pValueB);<br />
}<br />
</textarea></p>
]]></content:encoded>
			<wfw:commentRss>http://adspeed.org/?feed=rss2&#038;p=17</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP5 Class for Yahoo Term Extractor API</title>
		<link>http://adspeed.org/?p=16</link>
		<comments>http://adspeed.org/?p=16#comments</comments>
		<pubDate>Sun, 03 Feb 2008 00:34:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[code]]></category>

		<guid isPermaLink="false">http://adspeed.org/?p=16</guid>
		<description><![CDATA[Given a content string, this class uses Yahoo Term Extraction API to generate a list of keywords/phrases that you can use for things like META tags or other SEO objectives. Result AS $vOne) { $vTmp[] = (string)$vOne; } // rof return $vTmp; // an array of tags } /** comment */ function display() { $vTags [...]]]></description>
			<content:encoded><![CDATA[<p>Given a content string, this class uses Yahoo Term Extraction API to generate a list of keywords/phrases that you can use for things like META tags or other SEO objectives.</p>
<p><textarea name="code" class="php"><br />
<?php<br />
/**<br />
* @author Son Nguyen<br />
* @since 2/13/2006<br />
* @package Framework<br />
* @subpackage WebServices<br />
*/<br />
class CYahooTermExtraction extends CYahooAPI {<br />
 private $mContext; // string, get main keywords from this text<br />
 /** constructor */<br />
 function __construct($pContext) {<br />
  $this->mServiceURL = &#8216;http://api.search.yahoo.com/ContentAnalysisService/V1/termExtraction&#8217;;<br />
  $this->mContext = $pContext;<br />
 }</p>
<p> /** get the tags/keywords through Yahoo API */<br />
 function fetchTags() {<br />
  $vReq = new CHTTPRequest($this->mServiceURL);<br />
  $vReq->addQueryString(&#8216;appid&#8217;,$this->mAppID);<br />
  $vReq->addQueryString(&#8216;context&#8217;,$this->mContext);<br />
  list($vHeader,$vBody) = $vReq->sendPOST();<br />
  //var_dump($vHeader,$vBody);die;<br />
  $vXML = simplexml_load_string($vBody);<br />
  $vTmp = array();<br />
  foreach ($vXML->Result AS $vOne) {<br />
   $vTmp[] = (string)$vOne;<br />
  } // rof<br />
  return $vTmp; // an array of tags<br />
 }</p>
<p> /** comment */<br />
 function display() {<br />
  $vTags = $this->fetchTags();<br />
  return implode(&#8216;, &#8216;,$vTags);<br />
 }<br />
}<br />
?></p>
<p><?php<br />
/**<br />
* @author Son Nguyen<br />
* @since 3/21/2006<br />
* @package Framework<br />
* @subpackage WebServices<br />
*/<br />
class CYahooAPI {<br />
 protected $mAppID = 'YourYahooApplicationID';<br />
 protected $mServiceURL;</p>
<p> /** constructor */<br />
 function __construct() {</p>
<p> }<br />
}<br />
?></p>
<p></textarea></p>
]]></content:encoded>
			<wfw:commentRss>http://adspeed.org/?feed=rss2&#038;p=16</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Fix php_browscap.ini for PHP</title>
		<link>http://adspeed.org/?p=14</link>
		<comments>http://adspeed.org/?p=14#comments</comments>
		<pubDate>Sat, 19 Jan 2008 18:18:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[code]]></category>

		<guid isPermaLink="false">http://adspeed.org/?p=14</guid>
		<description><![CDATA[This class parses, fixes and prepares php_browscap.ini into browscap.ini for PHP. It also detects if the latest version needed to download.]]></description>
			<content:encoded><![CDATA[<p>This class parses, fixes and prepares php_browscap.ini into browscap.ini for PHP. It also detects if the latest version needed to download.</p>
<p><textarea name="code" class="php"><br />
<?php<br />
/** from localhost to fetch and prepare the browscap.ini file<br />
* @author Son Nguyen<br />
* @since 8/25/2006<br />
* @package Framework<br />
* @subpackage Lookup<br />
*/<br />
class CBrowsCap {<br />
 private $mTmpFileName = 'php_browscap.ini'; // tmp file before fixing<br />
 private $mDownloadURL = 'http://browsers.garykeith.com/stream.asp?PHP_BrowsCapINI';<br />
 /** constructor */<br />
 function __construct() {}</p>
<p> /** get the version string from the file */<br />
 function getVersion($pFile,$pCheckExisted) {<br />
  $vVersion = NULL;<br />
  if ($pCheckExisted &#038;&#038; !file_exists($pFile)) {<br />
   return NULL;<br />
  } // fi</p>
<p>  $vContent = file_get_contents($pFile,FALSE,NULL,0,500);<br />
  if (preg_match('/version=(.*)/i',$vContent,$vMatches)) {<br />
   $vVersion = trim($vMatches[1]);<br />
  } // fi<br />
  return $vVersion;<br />
 }</p>
<p> /** comment */<br />
 function getLatestVersion() {<br />
  return $this->getVersion($this->mDownloadURL,FALSE);<br />
 }</p>
<p> /** get the current I&#8217;m currently use */<br />
 function getMyVersion() {<br />
  return $this->getVersion($this->mTmpFileName,TRUE);<br />
 }</p>
<p> /** if need to update */<br />
 function checkUpdate() {<br />
  $vMy = $this->getMyVersion();<br />
  $vLatest = $this->getLatestVersion();<br />
  if (!file_exists($this->mTmpFileName) || $vMy<$vLatest) { // should update<br />
   $vContent = file_get_contents($this->mDownloadURL);<br />
   file_put_contents($this->mTmpFileName,$vContent);<br />
   return &#8216;Updated to version #&#8217;.$vLatest.&#8217; from #&#8217;.$vMy; // yes, do update<br />
  } // fi</p>
<p>  return &#8216;Already at the latest version #&#8217;.$vLatest; // latest, don&#8217;t update<br />
 }</p>
<p> /** fix the browsecap.ini for php */<br />
 function fix() {<br />
  $vOutput = $this->checkUpdate();</p>
<p>  $vContent = file_get_contents($this->mTmpFileName);<br />
  $vContent = preg_replace(&#8220;/\r/&#8221;,&#8221;",$vContent);<br />
  $vContent = preg_replace(&#8216;/=&#8221;(.*)&#8221;/i&#8217;,'=\\1&#8242;,$vContent);<br />
  $vContent = preg_replace(&#8220;/platform=(.*)/i&#8221;,&#8221;platform=\&#8221;\\1\&#8221;",$vContent);<br />
  $vContent = preg_replace(&#8220;/parent=(.*)/i&#8221;,&#8221;parent=\&#8221;\\1\&#8221;",$vContent);<br />
  $vContent = preg_replace(&#8220;/minorver=(.*)/i&#8221;,&#8221;minorver=\&#8221;\\1\&#8221;",$vContent);<br />
  $vContent = preg_replace(&#8220;/majorver=(.*)/i&#8221;,&#8221;majorver=\&#8221;\\1\&#8221;",$vContent);<br />
  $vContent = preg_replace(&#8220;/version=(.*)/i&#8221;,&#8221;version=\&#8221;\\1\&#8221;",$vContent);<br />
  $vContent = preg_replace(&#8220;/browser=(.*)/i&#8221;,&#8221;browser=\&#8221;\\1\&#8221;",$vContent);<br />
  $vContent = str_replace(&#8220;[*]&#8220;,&#8221;*&#8221;,$vContent);<br />
  file_put_contents(&#8216;browscap.ini&#8217;,$vContent);</p>
<p>  return $vOutput;<br />
 }<br />
}<br />
?><br />
</textarea></p>
]]></content:encoded>
			<wfw:commentRss>http://adspeed.org/?feed=rss2&#038;p=14</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Simple &amp; fast spider detection</title>
		<link>http://adspeed.org/?p=13</link>
		<comments>http://adspeed.org/?p=13#comments</comments>
		<pubDate>Sat, 19 Jan 2008 18:09:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[code]]></category>

		<guid isPermaLink="false">http://adspeed.org/?p=13</guid>
		<description><![CDATA[Developers can use the browscap.ini to detect if the User-Agent is a search engine or data collection spider or not. However, that file is rather large and will be expensive on resources. If you need a faster, simpler (albeit less accurate) method, this class can be useful.]]></description>
			<content:encoded><![CDATA[<p>Developers can use the browscap.ini to detect if the User-Agent is a search engine or data collection spider or not. However, that file is rather large and will be expensive on resources. If you need a faster, simpler (albeit less accurate) method, this class can be useful.</p>
<p><textarea name="code" class="php"><br />
<?php<br />
/** a quick/less resource intensive browser detection<br />
* @author Son Nguyen<br />
* @since 1/29/2007<br />
* @package Framework<br />
* @subpackage Misc<br />
*/<br />
class CBrowserDetect {<br />
 private $mUA;<br />
 /** constructor */<br />
 function __construct($pUA=NULL) {<br />
  $this->setUA($pUA);<br />
 }</p>
<p> /** comment */<br />
 function setUA($pUA=NULL) {<br />
  if (is_null($pUA) &#038;&#038; isset($_SERVER['HTTP_USER_AGENT'])) {<br />
   $this->mUA = $_SERVER['HTTP_USER_AGENT'];<br />
  } else {<br />
   $this->mUA = $pUA;<br />
  } // fi<br />
 }</p>
<p> /** if this is a spider/crawler */<br />
 function isSpider($pUA=NULL) {<br />
  $this->setUA($pUA);<br />
  $vBots = array(<br />
   &#8216;AdsBot-Google&#8217;,<br />
   &#8216;alexa&#8217;,<br />
   &#8216;appie&#8217;,<br />
   &#8216;Ask Jeeves&#8217;,<br />
   &#8216;Baiduspider&#8217;,<br />
   &#8216;crawler&#8217;,<br />
   &#8216;FAST&#8217;,<br />
   &#8216;Firefly&#8217;,<br />
   &#8216;froogle&#8217;,<br />
   &#8216;girafabot&#8217;,<br />
   &#8216;Googlebot&#8217;,<br />
   &#8216;ia_archiver&#8217;,<br />
   &#8216;InfoSeek&#8217;,<br />
   &#8216;inktomi&#8217;,<br />
   &#8216;Java/&#8217;,<br />
   &#8216;looksmart&#8217;,<br />
   &#8216;msnbot&#8217;,<br />
   &#8216;NationalDirectory&#8217;,<br />
   &#8216;rabaz&#8217;,<br />
   &#8216;Scooter&#8217;,<br />
   &#8216;Slurp&#8217;,<br />
   &#8216;Spade&#8217;,<br />
   &#8216;TECNOSEEK&#8217;,<br />
   &#8216;Teoma&#8217;,<br />
   &#8216;URL_Spider_SQL&#8217;,<br />
   &#8216;WebBug&#8217;,<br />
   &#8216;WebCapture&#8217;,<br />
   &#8216;WebFindBot&#8217;,<br />
   &#8216;Wget/&#8217;,<br />
   &#8216;ZyBorg&#8217;,<br />
   &#8216;libwww-perl/&#8217;,<br />
   &#8216;httpunit/&#8217;,<br />
   &#8216;WebZIP/&#8217;,<br />
  );<br />
  foreach ($vBots AS $vPat) {<br />
   if (stripos($this->mUA,$vPat)!==FALSE) {<br />
    return TRUE;<br />
   } // fi<br />
  } // rof<br />
  return FALSE;<br />
 }<br />
}<br />
?><br />
</textarea></p>
]]></content:encoded>
			<wfw:commentRss>http://adspeed.org/?feed=rss2&#038;p=13</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
