<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Cogito, ergo sum</title>
	<atom:link href="http://mnshankar.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://mnshankar.wordpress.com</link>
	<description>Here&#039;s hoping my musings can help you out!</description>
	<lastBuildDate>Wed, 18 Jan 2012 19:31:34 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='mnshankar.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Cogito, ergo sum</title>
		<link>http://mnshankar.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://mnshankar.wordpress.com/osd.xml" title="Cogito, ergo sum" />
	<atom:link rel='hub' href='http://mnshankar.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Custom Zend Form Slider Element</title>
		<link>http://mnshankar.wordpress.com/2011/10/21/custom-zend-form-slider-element/</link>
		<comments>http://mnshankar.wordpress.com/2011/10/21/custom-zend-form-slider-element/#comments</comments>
		<pubDate>Fri, 21 Oct 2011 23:34:42 +0000</pubDate>
		<dc:creator>mnshankar</dc:creator>
				<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[Custom form element]]></category>
		<category><![CDATA[slider]]></category>
		<category><![CDATA[Zend form]]></category>

		<guid isPermaLink="false">https://mnshankar.wordpress.com/2011/10/21/custom-zend-form-slider-element/</guid>
		<description><![CDATA[In one of my web projects, I had a need for a slider UI element. I use Zend framework extensively in all my projects, and my initial approach was to use pure JQuery coupled with $_POST variables to interact with a JQueryUI slider. The validation criterion was that a slider HAD to be selected: If [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mnshankar.wordpress.com&amp;blog=8005313&amp;post=10639&amp;subd=mnshankar&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In one of my web projects, I had a need for a slider UI element. I use <a href="http://framework.zend.com/" target="_blank">Zend framework</a> extensively in all my projects, and my initial approach was to use pure JQuery coupled with $_POST variables to interact with a <a href="http://jqueryui.it/demos/slider" target="_blank">JQueryUI</a> slider.</p>
<p>The validation criterion was that a slider HAD to be selected: If the user wanted to indicate a zero value, the slider had to be dragged and brought back to zero.</p>
<p>Very soon, I realized that while the JQuery/php code worked well, it required increasing amounts of code in the controller and view to handle form validation. Also, maintaining the state across form submissions became a laborious process. Error highlighting/reporting became difficult, and all these mundane activities took up lots of space and time. Of course, the problems only grew worse with increasing number of sliders on the page.</p>
<p>I recently refactored my code and arrived at a much better solution: Create a custom zend form element named &#8220;slider&#8221;, and let the Zend framework handle the grunt work of state persistence and error management &#8211; things it was designed to do in the first place.</p>
<p><strong>Requirements</strong>: The main requirements of the slider element are summarized below:</p>
<p>1. The ability to create and work with sliders in a way similar to other standard form controls (text/radio etc). For example:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:0609a932-8bc8-41df-af3a-7eb5b7aceaea" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: php;">
$slider1 = $this-&gt;createElement('slider', 'clinical_experience');
$slider1-&gt;setLabel('How do you rate your clinical experience?');
$slider1-&gt;setRequired();
$this-&gt;addElement($slider1);
</pre>
</pre>
</div>
<p>2. The setRequired() validation should be performed by the framework, and slider state should be retained between form postings.</p>
<p>3. It should be possible to customize left and right anchors of the sliders to reflect varying end points(default least-most).</p>
<p>4. It should be possible to customize the min and max values of each slider (default range from 0-100).</p>
<p>Now that our requirements are clearly defined, we move on to coding the form element. In order to work with the slider, we actually create a combination of a slider div AND a hidden form element. The hidden element will help us get the posted value easily and also help maintain state.</p>
<p>We establish a simple naming convention for associated hidden fields – give their name attribute a value of “<i>controlname</i>-text”</p>
<p>For instance the slider above named “clinical_experience” will have a hidden field named “clinical_experience-text” that holds the value of the slider selection (the numerical value of the slider is set via javascript)</p>
<p>The slider class extends Zend_From_Element_Xhtml. This gives our custom slider element access to all of Zend frameworks’ support for form elements. We also create setter methods for the left and right anchor and the min/max slider values. The init() method sets appropriate defaults (should the user choose not to use the setters while creating the form).</p>
<p>Note that the form helper element (bolded in the code below) is set to ‘SliderElement’ – This will be defined by us next. The framework takes care of passing the control name, value, attribs array and options array to the helper.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:9194ecad-00b5-4fe2-ba2d-66be18131707" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: php; pad-line-numbers: true;">
&lt;?php
class ZF_Slider extends Zend_Form_Element_Xhtml
{
    public $helper = 'sliderElement';
    public $options = array();
    public function init()
    {
        $this-&gt;setMinValue(0);
        $this-&gt;setMaxValue(100);
        $this-&gt;setLeftAnchor('Least');
        $this-&gt;setRightAnchor('Most');
    }
    public function setLeftAnchor($left)
    {
        $this-&gt;options['left'] = $left;
    }
    public function setRightAnchor($right)
    {
        $this-&gt;options['right'] = $right;
    }
    public function setMinValue($min=0)
    {
        $this-&gt;options['min']=$min;
    }
    public function setMaxValue($max=100)
    {
        $this-&gt;options['max']=$max;
    }
    public function isValid($value, $context = null)
    {
        //We have named our hidden text field name-text.. get its value
        $field = $this-&gt;_name.&quot;-text&quot;;       
        
        $value = $context[$field];
        $this-&gt;setValue($value);
        if (($value === null) or ($value==-1))
        {
            $value=null;
        }
        return parent::isValid($value, $context);
    }

}
?&gt;
</pre>
</pre>
</div>
<p>The control name is available via $this-&gt;_name. Therefore the corresponding hidden element can be retrieved using $this-&gt;_name.”-text”</p>
<p>The isValid() method is overridden as shown in the code above. It gets passed a value and a context (which comprises all the posted form values). We extract the hidden field value (based on our naming convention) and assign it to the value of our control ($this-&gt;setValue()).</p>
<p>If the value is null or -1, we set the value to null. Finally we make a call to the parent’s isValid() method. This takes care of responding appropriately to missing/null values.</p>
<p>The view helper for our newly created form element is displayed below (SliderElement.php). The “Sliderelement” helper takes care of “visually” displaying our custom control. First, a set of div tags is established. The first div tag establishes the left anchor, followed by a placeholder for the slider (rendered by jquery), followed by the div for the right anchor (I use <a href="http://blueprintcss.org/" target="_blank">Blueprint css</a> for positioning)</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:16c29f36-cbdf-40ab-abc6-1cbc0cee915e" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: php;">
&lt;?php
class Zend_View_Helper_SliderElement extends Zend_View_Helper_FormElement
{
    //all these input parameters are passed by the Zend_Form_Element
    public function SliderElement($name, $value=null, $attribs=null, $options=null)
    {
        $str ='&lt;div class=&quot;box&quot;&gt;
            &lt;div class=&quot;span-3&quot;&gt;' . $options['left'] . '&lt;/div&gt;
            &lt;div class=&quot;span-9&quot; id=&quot;' . $name . '&quot;&gt;&lt;/div&gt;
            &lt;div class=&quot;span-3&quot;&gt;' . $options['right'] . '&lt;/div&gt;
                &lt;input type=&quot;hidden&quot; value=&quot;' . $value . '&quot; id=&quot;' .
                $name . '-text&quot; name=&quot;' . $name . '-text&quot;/&gt;
            &lt;/div&gt;';
        //$value is injected into the javascript.. passing null will result in js error!
        $value=($value == null)?-1:$value;
        $str.=$this-&gt;SliderGen($name, $value,$options['min'],$options['max']);
        return $str;
    }

    //return a javscript string that renders the slider using 
    //jquery ui..
    private function SliderGen($id, $value,$min,$max)
    {
        $str = '&lt;script&gt;
    $(document).ready(function(){';
        $str.=&quot;
            \$(\&quot;#$id\&quot;).slider({
    animate: true ,
    range: \&quot;min\&quot;,
    value: $value,
    min: $min,
    max: $max,
    slide: function(event, ui) {\$(\&quot;#$id-text\&quot;).val(ui.value)}
    });&quot;;
        $str.= &quot;\$(\&quot;#$id\&quot;).css('cursor', 'pointer');&quot;;
        $str.='});
        &lt;/script&gt;';
        return $str;
    }
}
?&gt;
</pre>
</pre>
</div>
<p>The internal (private) method SliderGen() emits javascript code to render the slider using JQuery. The “slide” function/callback populates the hidden text box with the slider selection.</p>
<p>Please look up the <a href="http://jqueryui.it/demos/slider" target="_blank">JQueryUI</a> site if you need more information regarding the syntax for displaying the slider component on a web page.</p>
<p>Finally, we are ready to create our Zend form. The code is as shown below (forms/slider.php):</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:863b4c9a-0fb7-4a23-ba3f-f33b933b9ec2" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: php;">
&lt;?php
class Form_Slider extends Zend_Form
{
    public function init()
    {
        //tell this form where to find our slider element
        $this-&gt;addPrefixPath('ZF', 'ZF','element');
        
        $slider1 = $this-&gt;createElement('slider', 'clinical_experience');
        $slider1-&gt;setLabel('How do you rate your clinical experience?');
        $slider1-&gt;setRequired();
        $slider1-&gt;setLeftAnchor('Poor');
        $slider1-&gt;setRightAnchor('Excellent');
        $slider1-&gt;setMinValue(100);
        $slider1-&gt;setMaxValue(500);
        $this-&gt;addElement($slider1);
        
        $slider2 = $this-&gt;createElement('slider', 'teaching_experience');
        $slider2-&gt;setRequired();
        $slider2-&gt;setLabel('How do you rate your teaching experience?');
        $slider2-&gt;setLeftAnchor('Poor');
        $slider2-&gt;setRightAnchor('Excellent');
        $this-&gt;addElement($slider2);
            
        $submit = $this-&gt;createElement('submit', 'next');
        $submit-&gt;setIgnore(true);
        $submit-&gt;setLabel('Next');
        $this-&gt;addElement($submit);
    }
}
?&gt;
</pre>
</pre>
</div>
<p>The “addPrefixPath()” command is used to instruct set the actual location of our ‘slider’ component (plugin). This class is named “ZF_Slider” and is in the path /library/ZF/slider.php</p>
<p>We create two sliders using the “slider” component that we just created.. Set all the required values and add it to Form_Slider.</p>
<p>Finally, to tie it all together and generate some output, we create an indexController. It simply initiates our form class, passes it on to the view and dumps the response when the form is submitted:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:9a32ea3a-cb8a-48c5-a0ce-82c3be3d9a88" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: php;">
&lt;?php
class IndexController extends Zend_Controller_Action
{
    public function indexAction()
    {
       $form = new Form_Slider();
       $this-&gt;view-&gt;form = $form;
       if ($this-&gt;_request-&gt;isPost())
       {
           if ($form-&gt;isValid($_POST))
           {
               var_dump($form-&gt;getValues());
           }
       }
    }
}
?&gt;
</pre>
</pre>
</div>
<p>Since all the heavy weight lifting has been delegated to the Zend form, the view (index.phtml) is a simple one-liner:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:5eed7bc7-1615-4107-b4c1-9cb165e44723" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: php;">
&lt;?php
echo $this-&gt;form;
?&gt;
</pre>
</pre>
</div>
<p>That’s it! No additional javascript coding and messing with posted values (Note that a reference to both JQuery and JQueryUI is necessary to make this function.. I setup all this in my bootstrap and render it on my layout.phtml)</p>
<p>This is what the rendered form looks like (note that I use <a href="http://blueprintcss.org/" target="_blank">blueprint css</a> for positioning):</p>
<p>&nbsp;</p>
<p><a href="http://mnshankar.files.wordpress.com/2011/10/clip_image002.jpg"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border-width:0;" title="clip_image002" border="0" alt="clip_image002" src="http://mnshankar.files.wordpress.com/2011/10/clip_image002_thumb.jpg?w=644&#038;h=188" width="644" height="188"></a></p>
<p>When the form is submitted without interacting with either of the sliders, the standard error messages (setRequired())are displayed underneath the appropriate controls.</p>
<p><a href="http://mnshankar.files.wordpress.com/2011/10/clip_image004.jpg"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border-width:0;" title="clip_image004" border="0" alt="clip_image004" src="http://mnshankar.files.wordpress.com/2011/10/clip_image004_thumb.jpg?w=644&#038;h=256" width="644" height="256"></a></p>
<p>When selections are made and the “Next” button is hit, the posted values are displayed as expected:</p>
<p><a href="http://mnshankar.files.wordpress.com/2011/10/clip_image006.jpg"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border-width:0;" title="clip_image006" border="0" alt="clip_image006" src="http://mnshankar.files.wordpress.com/2011/10/clip_image006_thumb.jpg?w=644&#038;h=262" width="644" height="262"></a></p>
<p>Note that when we initialized the “clinical_experience” slider, we had min and max set at 100 and 500 respectively. The posted value reflects that. Notice also how the state of the slider is maintained after post back.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mnshankar.wordpress.com/10639/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mnshankar.wordpress.com/10639/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mnshankar.wordpress.com/10639/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mnshankar.wordpress.com/10639/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/mnshankar.wordpress.com/10639/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/mnshankar.wordpress.com/10639/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/mnshankar.wordpress.com/10639/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/mnshankar.wordpress.com/10639/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mnshankar.wordpress.com/10639/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mnshankar.wordpress.com/10639/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mnshankar.wordpress.com/10639/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mnshankar.wordpress.com/10639/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mnshankar.wordpress.com/10639/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mnshankar.wordpress.com/10639/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mnshankar.wordpress.com&amp;blog=8005313&amp;post=10639&amp;subd=mnshankar&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mnshankar.wordpress.com/2011/10/21/custom-zend-form-slider-element/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/54eaf4a8492ddeea93a0d826041b3b7b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mnshankar</media:title>
		</media:content>

		<media:content url="http://mnshankar.files.wordpress.com/2011/10/clip_image002_thumb.jpg" medium="image">
			<media:title type="html">clip_image002</media:title>
		</media:content>

		<media:content url="http://mnshankar.files.wordpress.com/2011/10/clip_image004_thumb.jpg" medium="image">
			<media:title type="html">clip_image004</media:title>
		</media:content>

		<media:content url="http://mnshankar.files.wordpress.com/2011/10/clip_image006_thumb.jpg" medium="image">
			<media:title type="html">clip_image006</media:title>
		</media:content>
	</item>
		<item>
		<title>ASUS Transformer TF101</title>
		<link>http://mnshankar.wordpress.com/2011/08/28/asus-transformer-tf101/</link>
		<comments>http://mnshankar.wordpress.com/2011/08/28/asus-transformer-tf101/#comments</comments>
		<pubDate>Sun, 28 Aug 2011 09:56:53 +0000</pubDate>
		<dc:creator>mnshankar</dc:creator>
				<category><![CDATA[Computers and Internet]]></category>

		<guid isPermaLink="false">https://mnshankar.wordpress.com/2011/08/28/asus-transformer-tf101/</guid>
		<description><![CDATA[Last week, in the midst of the HP Touchpad frenzy (which I could not get in on, by the way), I decided to pull the trigger on an ASUS Transformer (TF101). After having played with it sufficiently, I am really happy and excited about my purchase! If Apple has taught us anything, it is that [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mnshankar.wordpress.com&amp;blog=8005313&amp;post=10622&amp;subd=mnshankar&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Last week, in the midst of the HP Touchpad frenzy (which I could not get in on, by the way), I decided to pull the trigger on an <a href="http://www.amazon.com/Transformer-TF101-A1-10-1-Inch-Tablet-Computer/dp/B004U78J1G" target="_blank">ASUS Transformer (TF101)</a>. After having played with it sufficiently, I am really happy and excited about my purchase!</p>
<p>If Apple has taught us anything, it is that the hardware and software go hand in hand towards a great user experience, and Asus definitely followed this. Out of the box, people want to surf the web, listen to music, watch movies, play games, buy apps, and read books &#8211; The transformer really excels in ALL these areas as an extremely user-friendly tablet.</p>
<p>If you are on the fence about buying a TF101, hopefully, this blog should help you make up your mind!</p>
<p><a href="http://googlemobile.blogspot.com/2011/01/sneak-peak-of-android-30-honeycomb.html" target="_blank">Android 3.0/Honeycomb</a> is a glorious OS, and the Transformer has the right hardware to make everything extremely fluid and fast. Asus has also paid close attention to customizing the software for the Transformer. Oh.. and the screen on the Transformer is gorgeous! 10.1 inch, 1280*800 pixels of super-responsive real estate.</p>
<p>Most software that you require to be productive has already been included on the Transformer(or available as a free download). The Android market is literally littered with apps. Writing “good” software that plays well with the available hardware is hard.. So, I am extremely cautious about downloading stuff off the market. I always prefer apps that have been tried and tested.</p>
<p>Connecting the Transformer to a computer to transfer data is also a cinch.. Just use the USB cord shipped along with the unit. The transformer shows up as a drive (Windows 7 automatically recognizes and installs the required drivers).</p>
<p>Here’s what my home screen looks like – with my most commonly used apps lined up at the bottom:</p>
<p><a href="http://mnshankar.files.wordpress.com/2011/08/p20110827210023.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border:0;" title="P20110827210023" src="http://mnshankar.files.wordpress.com/2011/08/p20110827210023_thumb.png?w=644&#038;h=404" alt="P20110827210023" width="644" height="404" border="0" /></a></p>
<p>Here is a list of apps that I use regularly (and I strongly recommend each one of them):</p>
<p>1. <strong>Browser</strong> : A version of Chrome. Very snappy and full featured (You will be prompted to download Flash on first use). There is really no reason to download another browser.</p>
<p>2. <strong>YouTube</strong> : Great app customized for tablets. Makes flipping through videos a joy!</p>
<p>3. <strong>File Manager</strong> : Folder manager app created by ASUS. I actually prefer this to the highly acclaimed “Astro” file manager.</p>
<p>4. <strong>Polaris Office</strong>: Included by Asus. Lets users easily read and edit various office document formats (.docx, .xlsx, .pdf etc). I prefer this to “Documents to go”. (Although this reads pdf files, the Adobe reader does a much better job of rendering pages)</p>
<p>5. <strong>Amazon Kindle</strong>: Enough said!</p>
<p>6. <strong>2X Client</strong> : This is a free remote desktop client. 2X actually designs and develops load balancing servers (which we use for our terminal services at work).. So, I have absolutely no qualms in recommending their RDP client. Works flawlessly with minimal resources.</p>
<p>7. <strong>Repligo PDF Reader</strong>: The most feature rich PDF reader available for android (The feature that I absolutely love about Repligo is that it remembers the last page read. The Day/Night mode is also very helpful). The official PDF reader by Adobe is not yet there in terms of required features.. but is a close 2nd choice.</p>
<p>8. <strong>MX Video Player</strong> : An awesome media player for Android.. It uses custom codecs to take advantage of processor specific features(H/W acceleration). It allows me to play a wide variety of video files on my android (The full-featured free version displays ads only when you pause.. not at all obtrusive).</p>
<p>9. <strong>Due Today</strong> : A full featured task management/reminder system with a very good UI. It also syncs with <a href="http://www.toodledo.com/" target="_blank">ToodleDo </a>when online.. so you have your tasks securely backed up. There is another highly acclaimed app named &#8220;Beautiful Notes&#8221; that competes in the same category. I personally chose &#8220;Due Today&#8221; because 1. it is more structured and captures data in numerous fields 2. It is much more light weight (500KB) vs Beautiful Notes (8.5 MB)</p>
<p>10. <strong>Windows 8 Notepad:</strong> A very functional notepad replacement. I love its clean and minimalistic design. Available for free from the Android market.</p>
<h4><span style="text-decoration:underline;">Configuring the Keyboard (Setting-&gt;Language &amp; input)</span></h4>
<p>The ASUS keyboard is vastly superior to the stock android keyboard.. But it can be further enhanced using the configuration options available:</p>
<p><a href="http://mnshankar.files.wordpress.com/2011/08/image.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border:0;" title="image" src="http://mnshankar.files.wordpress.com/2011/08/image_thumb.png?w=644&#038;h=404" alt="image" width="644" height="404" border="0" /></a></p>
<p><a href="http://mnshankar.files.wordpress.com/2011/08/image1.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border:0;" title="image" src="http://mnshankar.files.wordpress.com/2011/08/image_thumb1.png?w=644&#038;h=404" alt="image" width="644" height="404" border="0" /></a></p>
<p>I checked ALL available options on mine.. Note that the <a href="http://www.youtube.com/watch?v=SJ-RAefCG_c&amp;feature=player_embedded" target="_blank">Swype style</a> functionality is built into the ASUS keyboard app. This is really handy and works great (not to mention the &#8216;cool&#8217; factor!).</p>
<p><a href="http://mnshankar.files.wordpress.com/2011/08/image2.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border:0;" title="image" src="http://mnshankar.files.wordpress.com/2011/08/image_thumb2.png?w=644&#038;h=404" alt="image" width="644" height="404" border="0" /></a></p>
<h4><span style="text-decoration:underline;">Setting up VPN (Settings-&gt;Wireless &amp; networks)</span></h4>
<p>Honeycomb also has built in support for VPN -  Click on the “VPN Settings” option:</p>
<p><a href="http://mnshankar.files.wordpress.com/2011/08/image3.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border:0;" title="image" src="http://mnshankar.files.wordpress.com/2011/08/image_thumb3.png?w=644&#038;h=404" alt="image" width="644" height="404" border="0" /></a></p>
<p>Next, select the type of VPN (L2TP is the easiest to set up)</p>
<p><a href="http://mnshankar.files.wordpress.com/2011/08/image4.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border:0;" title="image" src="http://mnshankar.files.wordpress.com/2011/08/image_thumb4.png?w=644&#038;h=404" alt="image" width="644" height="404" border="0" /></a></p>
<p>Enter your values for VPN Name, Server, and pre-shared key.. Yes.. its that easy!</p>
<p><a href="http://mnshankar.files.wordpress.com/2011/08/image5.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border:0;" title="image" src="http://mnshankar.files.wordpress.com/2011/08/image_thumb5.png?w=644&#038;h=404" alt="image" width="644" height="404" border="0" /></a></p>
<p>And for those of you curious about how I did these awesome screen captures – No.. it is not an app! The feature is built right into the Honeycomb OS (Settings-&gt;Screen-&gt;Screenshot). This takes a screenshot if you keep the “Recent apps” key pressed for about 3 seconds (this is the icon next to the “Home” icon at the bottom of the screen. The pictures are saved in the “Screenshot” folder of your main SD card  (you can get there using the File Manager app)</p>
<p><a href="http://mnshankar.files.wordpress.com/2011/08/p20110827203742.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border:0;margin:0;" title="P20110827203742" src="http://mnshankar.files.wordpress.com/2011/08/p20110827203742_thumb.png?w=644&#038;h=404" alt="P20110827203742" width="644" height="404" border="0" /></a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mnshankar.wordpress.com/10622/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mnshankar.wordpress.com/10622/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mnshankar.wordpress.com/10622/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mnshankar.wordpress.com/10622/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/mnshankar.wordpress.com/10622/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/mnshankar.wordpress.com/10622/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/mnshankar.wordpress.com/10622/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/mnshankar.wordpress.com/10622/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mnshankar.wordpress.com/10622/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mnshankar.wordpress.com/10622/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mnshankar.wordpress.com/10622/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mnshankar.wordpress.com/10622/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mnshankar.wordpress.com/10622/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mnshankar.wordpress.com/10622/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mnshankar.wordpress.com&amp;blog=8005313&amp;post=10622&amp;subd=mnshankar&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mnshankar.wordpress.com/2011/08/28/asus-transformer-tf101/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/54eaf4a8492ddeea93a0d826041b3b7b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mnshankar</media:title>
		</media:content>

		<media:content url="http://mnshankar.files.wordpress.com/2011/08/p20110827210023_thumb.png" medium="image">
			<media:title type="html">P20110827210023</media:title>
		</media:content>

		<media:content url="http://mnshankar.files.wordpress.com/2011/08/image_thumb.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://mnshankar.files.wordpress.com/2011/08/image_thumb1.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://mnshankar.files.wordpress.com/2011/08/image_thumb2.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://mnshankar.files.wordpress.com/2011/08/image_thumb3.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://mnshankar.files.wordpress.com/2011/08/image_thumb4.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://mnshankar.files.wordpress.com/2011/08/image_thumb5.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://mnshankar.files.wordpress.com/2011/08/p20110827203742_thumb.png" medium="image">
			<media:title type="html">P20110827203742</media:title>
		</media:content>
	</item>
		<item>
		<title>Regression Analysis Using PHP</title>
		<link>http://mnshankar.wordpress.com/2011/05/01/regression-analysis-using-php/</link>
		<comments>http://mnshankar.wordpress.com/2011/05/01/regression-analysis-using-php/#comments</comments>
		<pubDate>Sun, 01 May 2011 23:07:38 +0000</pubDate>
		<dc:creator>mnshankar</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Regression by hand;multiple regression;matrix class;linear regression]]></category>

		<guid isPermaLink="false">https://mnshankar.wordpress.com/?p=10552</guid>
		<description><![CDATA[Introduction: Regression analysis is one of the core tools of statistics that helps investigate relationships between variables. If there is only a single explanatory variable, it is termed “Simple Regression” (It is often difficult to come across such situations in real life). Computing a simple regression involves fitting a straight line through the scatter graph [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mnshankar.wordpress.com&amp;blog=8005313&amp;post=10552&amp;subd=mnshankar&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><strong>Introduction: </strong></p>
<p>Regression analysis is one of the core tools of statistics that helps investigate relationships between variables. If there is only a single explanatory variable, it is termed “Simple Regression” (It is often difficult to come across such situations in real life). Computing a simple regression involves fitting a straight line through the scatter graph obtained from the sample. From coordinate geometry basics, recall that a straight line has the equation:</p>
<blockquote><p>y=c + mx</p>
<p>where m = slope of the line, and c is the y intercept.</p></blockquote>
<p>There can of course be many straight lines through a scatter plot.. Regression analysis picks ONE line in particular – The criteria used is to <a href="http://mathworld.wolfram.com/LeastSquaresFitting.html" target="_blank">minimize the sum of squares of the errors (distance from the points in the scatter plot to the line constructed).</a></p>
<p>If there is more than one variable on which the prediction depends, it is called “Multiple Regression” – It accounts for multiple additional factors (separately) so that the effect of each (independent) variable on the dependent variable can be assessed.</p>
<p>The equation for a (linear) multiple regression can be expressed as:</p>
<blockquote><p>y = a+bx1+cx2+…</p></blockquote>
<p>Mathematically, it is identical to “Simple Regression”. For example, in solving a 2 parameter regression, we need 3 dimensions – so, instead of estimating a straight line, we select a single “plane” &#8211; again such that the sum of squares of errors is minimum.</p>
<p>We can in fact, extrapolate this to an arbitrarily large number of independent variables. Fortunately, Computers have no problems crunching the numbers using matrix algebra to solve numerous simultaneous equations to arrive at the results.</p>
<p><strong>Using Matrix Algebra to Solve Multiple Regression:</strong></p>
<p>Let X be the data matrix of the predictor (independent) variables.<br />
Let Y be the data vector representing the criterion (dependent) variable.<br />
and, Let ‘b’ be the data vector representing the regression coefficients.</p>
<p>The formula for computing b (coefficient matrix) using Matrix algebra is given by the following formula:</p>
<blockquote><p>b = (X&#8217;X)<sup>-1</sup>X&#8217;Y</p></blockquote>
<p>The proof of this equation is quite simple:</p>
<ol>
<li>The simplified equation for a (simple) linear regression in matrix terms is Y=Xb+e</li>
<li>Assume that the average error (e) will equal 0. The equation becomes Y=Xb and we need to find the value of ‘b’</li>
<li>Multiply both sides of the equation by X&#8217; (transpose of X) : X&#8217;Y = X&#8217;Xb</li>
<li>We are trying to get rid of X&#8217;X on the RHS.. so multiply both sides of the equation with (X&#8217;X)<sup>-1</sup> – the inverse of X&#8217;X:<br />
(X&#8217;X)<sup>-1</sup>X&#8217;Y = (X&#8217;X)<sup>-1</sup>(X&#8217;X)b</li>
<li>Any matrix multiplied by its inverse is the identity matrix I:<br />
(X&#8217;X)<sup>-1</sup>X&#8217;Y = Ib</li>
<li>Ib =<strong> b = (X&#8217;X)<sup>-1</sup>X&#8217;Y</strong></li>
</ol>
<blockquote><p>[Note: the above equation contains the <a href="http://mathworld.wolfram.com/Moore-PenroseMatrixInverse.html" target="_blank">Moore-Penrose pseudoinverse</a> matrix which ensures that inverses take place on SQUARE matrices. A <sup>pseudo-1</sup>=(A'A)<sup>-1</sup> *A'</p>
<p>To solve equation Y = Xb, a naive approach would be to multiply both sides by X<sup>-1 </sup>and immediately simplify the resulting equation like so:</p>
<p>X<sup>-1</sup>Y = X<sup>-1</sup>Xb, and thus<br />
X<sup>-1</sup>Y = b (because X<sup>-1</sup>X =I)</p>
<p>However, recall that matrix inverses are only defined on Square matrices. We cannot guarantee that the matrix of independent variables will be a square matrix..in fact, it never is! the sample size needs to be reasonable to ensure correct results. The use of a pseudoinverse matrix solves this problem nicely.]</p></blockquote>
<p><strong>Example:</strong></p>
<p>A typical workflow involving regression analysis goes like this:</p>
<ol>
<li>Formulate a hypothesis about the relationship between variables of interest</li>
<li>Gather data from a representative sample</li>
<li>Compute regression parameters and prove (or disprove) the hypothesis</li>
</ol>
<p>A common example of multiple regression analysis is in college Student Admissions. The admissions committee bases its decision on numerous factors that it believes will influence the students GPA.</p>
<p>For example, a college could hypothesize that the GPA that will be attained by the admitted student is dependent on his/her High school GPA, SAT score (V+Q) and Letters of recommendation (The strength of recommendation letters will of course need to be quantified)</p>
<p>A sample of students currently attending the college is then surveyed for their current college GPA, high school GPA, SAT scores and Recommendation letter strength.</p>
<p>The predictor equation for college GPA (dependent variable) is :</p>
<blockquote><p>Y = a+b1X1+b2X2+b3X3</p></blockquote>
<p>where Y = Predicted GPA<br />
{b1, b2, b3} = Regression coefficients<br />
a = Intercept<br />
X1 = HS GPA, X2 = SAT Score and X3 = Strength of Recommendation letters</p>
<p>So, once the coefficients and intercept are determined, it is quite easy to plug in values for X1, X2, X3 and “predict” the future GPA of a student.</p>
<p><strong>Implementation in PHP:</strong></p>
<p>Although there are numerical statistical packages that can easily compute regression parameters, they are all geared towards “offline” computation. That is, data is collected first, and then the numbers are aggregated and crunched to arrive at the result. I was interested in using regression in an online survey – i.e., display the relevant regression parameters at the end of an online survey. I decided to write my own PHP library for this purpose (complete source code is attached at the end of this blog).</p>
<p>Each observation can be written as an algebraic equation as follows:</p>
<p><img src="http://www.geog.ucsb.edu/~joel/g210_w07/lecture_notes/lect09/mult_nbyk_eqn.gif" alt="" /></p>
<p>Our goal then, is to solve these simultaneous equations to find the value of b0..bk. For explanatory purposes, consider a simple linear regression (one independent variable). In matrix terms, the solution to this equation looks like:</p>
<p><a href="http://mnshankar.files.wordpress.com/2011/05/image.png"><img style="display:inline;border-width:0;" title="image" src="http://mnshankar.files.wordpress.com/2011/05/image_thumb.png?w=383&#038;h=246" alt="image" width="383" height="246" border="0" /></a></p>
<p>We can then solve for {b0,b1}… Note how the X matrix needs to be <strong>filled with 1’s in the first column</strong>. The exact same approach works for multiple regression too &#8211; We just use larger matrices!</p>
<p><img src="http://www.geog.ucsb.edu/~joel/g210_w07/lecture_notes/lect09/mult_xmat_eqn.gif" alt="" width="241" height="127" /></p>
<p><a href="http://mnshankar.files.wordpress.com/2011/05/image5.png"><img style="display:inline;border:0;" title="image" src="http://mnshankar.files.wordpress.com/2011/05/image5_thumb.png?w=161&#038;h=129" alt="image" width="161" height="129" border="0" /></a></p>
<p>‘n’ is the sample size (number of observations)</p>
<p>The various formulae used/computed by the regression class are:</p>
<table width="655" border="1" cellspacing="0" cellpadding="2">
<tbody>
<tr>
<td valign="top" width="133"><strong>Parameter</strong></td>
<td valign="top" width="166"><strong>Formula</strong></td>
<td valign="top" width="354"><strong>Explanation</strong></td>
</tr>
<tr>
<td valign="top" width="133">b</td>
<td valign="top" width="166">(X&#8217;X)<sup>-1</sup>X&#8217;Y</td>
<td valign="top" width="354">Regression coefficients. This is an n X 1 array</td>
</tr>
<tr>
<td valign="top" width="133">SSR</td>
<td valign="top" width="166">b&#8217;X'Y – (1/n) (Y&#8217;UU&#8217;Y)</td>
<td valign="top" width="354">Sum of squares due to regression – this is a scalar. U is a unit vector of dimensions n X 1</td>
</tr>
<tr>
<td valign="top" width="133">SSE</td>
<td valign="top" width="166">Y&#8217;Y-b&#8217;X'Y</td>
<td valign="top" width="354">Sum of squares due to errors – scalar</td>
</tr>
<tr>
<td valign="top" width="133">SSTO</td>
<td valign="top" width="166">SSR+SSE</td>
<td valign="top" width="354">Total sum of squares – scalar</td>
</tr>
<tr>
<td valign="top" width="133">dfTotal</td>
<td valign="top" width="166">sample_size – 1</td>
<td valign="top" width="354">Total degrees of freedom</td>
</tr>
<tr>
<td valign="top" width="133">dfModel</td>
<td valign="top" width="166">num_independent – 1</td>
<td valign="top" width="354">Model degrees of freedom</td>
</tr>
<tr>
<td valign="top" width="133">dfResidual</td>
<td valign="top" width="166">dfTotal – dfModel</td>
<td valign="top" width="354">Residual degrees of freedom</td>
</tr>
<tr>
<td valign="top" width="133">MSE</td>
<td valign="top" width="166">SSE/dfResidual</td>
<td valign="top" width="354">Mean square error – scalar</td>
</tr>
<tr>
<td valign="top" width="133">SE</td>
<td valign="top" width="166">(X&#8217;X)<sup>-1</sup> *(MSE)<br />
then take Square Root of elements on the diagonal</td>
<td valign="top" width="354">Standard error array</td>
</tr>
<tr>
<td valign="top" width="133">t-stat</td>
<td valign="top" width="166">b[i][j]/SE[i][j]</td>
<td valign="top" width="354">t-statistic</td>
</tr>
<tr>
<td valign="top" width="133">R<sup>2</sup></td>
<td valign="top" width="166">SSR/SSTO</td>
<td valign="top" width="354">R Square of regression</td>
</tr>
<tr>
<td valign="top" width="133">F</td>
<td valign="top" width="166">(SSR/dfModel)/(SSE/dfResidual)</td>
<td valign="top" width="354">F Value</td>
</tr>
</tbody>
</table>
<p>The heart of the library is the Lib_Matrix class. It handles all required matrix manipulation operations. A fluent interface has been provided where possible to make code more intuitive and readable. The Regression computation is performed in the “Lib_Regression” class. I have also attached the complete Unit test suite (100% code coverage) to help you better understand the API. The attached ZIP file contains the following files:</p>
<table width="650" border="1" cellspacing="0" cellpadding="2">
<tbody>
<tr>
<td valign="top" width="199"><strong>File Name</strong></td>
<td valign="top" width="449"><strong>Purpose</strong></td>
</tr>
<tr>
<td valign="top" width="219">Matrix.php</td>
<td valign="top" width="449">Core Matrix Manipulation</td>
</tr>
<tr>
<td valign="top" width="223">Regression.php</td>
<td valign="top" width="449">Compute various regression parameters</td>
</tr>
<tr>
<td valign="top" width="223">MatrixTest.php</td>
<td valign="top" width="449">Complete unit test suite for both matrix and regression classes</td>
</tr>
<tr>
<td valign="top" width="222">Excel Regression.xlsx</td>
<td valign="top" width="449">Regression performed on the test case testRegressionPassingArrays() using MS excel</td>
</tr>
<tr>
<td valign="top" width="222">MyReg.csv</td>
<td valign="top" width="449">Sample CSV file used by function testRegressionUsingCSV()</td>
</tr>
</tbody>
</table>
<blockquote>
<h3></h3>
<h3>Click here to download the <a href="http://cid-c30873a82c051135.office.live.com/self.aspx/Public/Code/Regression.rar" target="_blank">Regression library</a>.</h3>
</blockquote>
<p><strong>References:</strong></p>
<p><a href="http://marketing.byu.edu/htmlpages/books/pcmds/REGRESS.html">http://marketing.byu.edu/htmlpages/books/pcmds/REGRESS.html<br />
</a><a href="http://davidmlane.com/hyperstat/prediction.html">http://davidmlane.com/hyperstat/prediction.html<br />
</a><a href="http://luna.cas.usf.edu/~mbrannic/files/regression/regma.htm">http://luna.cas.usf.edu/~mbrannic/files/regression/regma.htm<br />
</a><a href="http://home.ubalt.edu/ntsbarsh/Business-stat/otherapplets/pvalues.htm#rtdist">http://home.ubalt.edu/ntsbarsh/Business-stat/otherapplets/pvalues.htm#rtdist</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mnshankar.wordpress.com/10552/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mnshankar.wordpress.com/10552/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mnshankar.wordpress.com/10552/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mnshankar.wordpress.com/10552/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/mnshankar.wordpress.com/10552/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/mnshankar.wordpress.com/10552/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/mnshankar.wordpress.com/10552/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/mnshankar.wordpress.com/10552/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mnshankar.wordpress.com/10552/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mnshankar.wordpress.com/10552/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mnshankar.wordpress.com/10552/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mnshankar.wordpress.com/10552/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mnshankar.wordpress.com/10552/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mnshankar.wordpress.com/10552/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mnshankar.wordpress.com&amp;blog=8005313&amp;post=10552&amp;subd=mnshankar&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mnshankar.wordpress.com/2011/05/01/regression-analysis-using-php/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/54eaf4a8492ddeea93a0d826041b3b7b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mnshankar</media:title>
		</media:content>

		<media:content url="http://www.geog.ucsb.edu/~joel/g210_w07/lecture_notes/lect09/mult_nbyk_eqn.gif" medium="image" />

		<media:content url="http://mnshankar.files.wordpress.com/2011/05/image_thumb.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://www.geog.ucsb.edu/~joel/g210_w07/lecture_notes/lect09/mult_xmat_eqn.gif" medium="image" />

		<media:content url="http://mnshankar.files.wordpress.com/2011/05/image5_thumb.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>
	</item>
		<item>
		<title>Handling Static Files in Zend Framework</title>
		<link>http://mnshankar.wordpress.com/2011/04/16/handling-static-files-in-zend-framework/</link>
		<comments>http://mnshankar.wordpress.com/2011/04/16/handling-static-files-in-zend-framework/#comments</comments>
		<pubDate>Sat, 16 Apr 2011 09:10:40 +0000</pubDate>
		<dc:creator>mnshankar</dc:creator>
				<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">https://mnshankar.wordpress.com/2011/04/16/handling-static-files-in-zend-framework/</guid>
		<description><![CDATA[There are a couple of alternatives when you need to render static files in your Zend Framework MVC application: 1. Completely bypass the framework The easiest solution is to move such content into a subfolder in the “public” directory. The default .htaccess file already setup to serve any physical file that is web-accessible. For example, [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mnshankar.wordpress.com&amp;blog=8005313&amp;post=10543&amp;subd=mnshankar&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>There are a couple of alternatives when you need to render static files in your Zend Framework MVC application:</p>
<p><strong>1. Completely bypass the framework</strong></p>
<p>The easiest solution is to move such content into a subfolder in the “public” directory. The default .htaccess file already setup to serve any physical file that is web-accessible. For example, <a href="http://localhost/ZFApp/public/static/myfile.html">http://localhost/ZFApp/public/static/myfile.html</a> would display myfile.html contained in the “static” subfolder.</p>
<p><strong>Advantage</strong>: minimum overhead imposed by the framework</p>
<p><strong>Disadvantage</strong>: You lose out on all the great features provided by the framework such as Caching, Layouts, Error Handling and Security – This approach is therefore not recommended and is reserved for the simplest of apps.</p>
<p><strong>2. Create a “custom route” specifically to handle static pages:</strong></p>
<p>Add the following route definitions to your application.ini</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:fefc68e0-d369-4233-8000-c0208228ef50" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: powershell; pad-line-numbers: true;">
resources.router.routes.staticpage.route = /statics/:filename
resources.router.routes.staticpage.defaults.controller =
staticcontent
resources.router.routes.staticpage.defaults.action = display
</pre>
</pre>
</div>
<p>This staticpage custom route defined above will take a url of the form “/statics/about”, store “about” as a parameter named “filename”, open a controller named “staticcontentController” and execute an action named “displayAction” in it. The displayAction can then render the file about.phtml (stored in views/scripts/staticcontent)like so:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:e6c1249e-368c-44b0-9957-02fe9aac67a4" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: php;">
class StaticcontentController extends Zend_Controller_Action
{
// action to handle ALL static pages
public function displayAction()
{
$page = $this-&gt;getRequest()-&gt;getParam('filename');
$this-&gt;render($page);
}
}
</pre>
</pre>
</div>
<p><strong>3. Empty action stubs</strong> : The ViewRenderer (builtin) helper automatically renders foo/foo.phtml after executing “fooAction”. So just creating empty action blocks, and copying the static content into the desired .phtml file would accomplish what we want. On the downside, your code may get&nbsp; peppered with empty actions over time (not that there is anything inherently wrong with this.. I resort to doing this for the occasional static file).</p>
<p>4. <strong>Overload the php magic function “__call”</strong> to intercept calls to non-extant actions and render them. This technique allows you to totally omit defining empty action stubs and relies on the php magic method to hande them.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:fd8b1269-88dd-4dda-b03f-539cd034b58a" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: php;">
class StaticcontentController extends Zend_Controller_Action 
{
public function __call($method, $args) 
{
if ('Action' == substr($method, -6)) 
{
$action = $this-&gt;getRequest()-&gt;getActionName();
return $this-&gt;render($actionName);
}
}
}
</pre>
</pre>
</div>
<p>Now, your controllers (with lots of statics) should extend StaticcontentController (instead of Zend_Controlller_Action). When the framework tries to invoke aboutAction, it will fail to find the method, get trapped by the __call method and then render the about.phtml page.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mnshankar.wordpress.com/10543/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mnshankar.wordpress.com/10543/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mnshankar.wordpress.com/10543/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mnshankar.wordpress.com/10543/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/mnshankar.wordpress.com/10543/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/mnshankar.wordpress.com/10543/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/mnshankar.wordpress.com/10543/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/mnshankar.wordpress.com/10543/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mnshankar.wordpress.com/10543/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mnshankar.wordpress.com/10543/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mnshankar.wordpress.com/10543/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mnshankar.wordpress.com/10543/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mnshankar.wordpress.com/10543/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mnshankar.wordpress.com/10543/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mnshankar.wordpress.com&amp;blog=8005313&amp;post=10543&amp;subd=mnshankar&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mnshankar.wordpress.com/2011/04/16/handling-static-files-in-zend-framework/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/54eaf4a8492ddeea93a0d826041b3b7b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mnshankar</media:title>
		</media:content>
	</item>
		<item>
		<title>memcached on 64 bit Windows</title>
		<link>http://mnshankar.wordpress.com/2011/03/25/memcached-on-64-bit-windows/</link>
		<comments>http://mnshankar.wordpress.com/2011/03/25/memcached-on-64-bit-windows/#comments</comments>
		<pubDate>Sat, 26 Mar 2011 01:34:20 +0000</pubDate>
		<dc:creator>mnshankar</dc:creator>
				<category><![CDATA[Computers and Internet]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">https://mnshankar.wordpress.com/2011/03/25/memcached-on-64-bit-windows/</guid>
		<description><![CDATA[Download memcached 1.4.4-14 from here (note that later versions of memcached have been modifed and DO NOT work as windows services). Unzip to a folder on your computer (say d:\memcached) Open an ADMINISTRATOR command window, and navigate to the memcached folder: Typing “memcached –h” will display all the available options 1. Install memcached service on [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mnshankar.wordpress.com&amp;blog=8005313&amp;post=10527&amp;subd=mnshankar&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Download memcached 1.4.4-14 from <a href="http://s3.amazonaws.com/downloads.northscale.com/memcached-win64-1.4.4-14.zip" target="_blank">here</a> (note that later versions of memcached have been modifed and DO NOT work as windows services).</p>
<p>Unzip to a folder on your computer (say d:\memcached)</p>
<p>Open an ADMINISTRATOR command window, and navigate to the memcached folder:</p>
<p><a href="http://mnshankar.files.wordpress.com/2011/03/image.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:inline;border-top:0;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://mnshankar.files.wordpress.com/2011/03/image_thumb.png?w=644&#038;h=325" width="644" height="325"></a></p>
<p>Typing “memcached –h” will display all the available options </p>
<p>1. Install memcached service on your system by typing </p>
<blockquote><p>memcached.exe –d install</p>
</blockquote>
<p><em>2. </em>Tell memcached to start</p>
<blockquote><p>memcached.exe –d start</p>
</blockquote>
<p>You are done.. When you view your taskmanager, you will notice memcached service running:</p>
<p><a href="http://mnshankar.files.wordpress.com/2011/03/image1.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:inline;border-top:0;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://mnshankar.files.wordpress.com/2011/03/image_thumb1.png?w=444&#038;h=484" width="444" height="484"></a></p>
<p>This service is setup to autostart with windows so you will not need to repeat the above.</p>
<p>Now, if you want to access/use memcached via php (or Zend Framework), you need to install&nbsp; php_memcache extension.</p>
<p>php_memcache.dll comes bundled in a zip file available <a href="http://www.anindya.com/category/windows/" target="_blank">here</a> (Many thanks to Anindya for making this available). Extract and save the dll file in your php ext directory.</p>
<p>Edit your php.ini and add this line:</p>
<blockquote><p>extension=php_memcache.dll</p>
</blockquote>
<p>Restart Apache.. Navigate to your phpinfo and you should see a section for memcache.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mnshankar.wordpress.com/10527/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mnshankar.wordpress.com/10527/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mnshankar.wordpress.com/10527/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mnshankar.wordpress.com/10527/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/mnshankar.wordpress.com/10527/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/mnshankar.wordpress.com/10527/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/mnshankar.wordpress.com/10527/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/mnshankar.wordpress.com/10527/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mnshankar.wordpress.com/10527/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mnshankar.wordpress.com/10527/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mnshankar.wordpress.com/10527/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mnshankar.wordpress.com/10527/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mnshankar.wordpress.com/10527/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mnshankar.wordpress.com/10527/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mnshankar.wordpress.com&amp;blog=8005313&amp;post=10527&amp;subd=mnshankar&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mnshankar.wordpress.com/2011/03/25/memcached-on-64-bit-windows/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/54eaf4a8492ddeea93a0d826041b3b7b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mnshankar</media:title>
		</media:content>

		<media:content url="http://mnshankar.files.wordpress.com/2011/03/image_thumb.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://mnshankar.files.wordpress.com/2011/03/image_thumb1.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>
	</item>
		<item>
		<title>Installing APC (3.1.6) on WAMP (64 bit)</title>
		<link>http://mnshankar.wordpress.com/2011/03/25/installing-apc-3-1-6-on-wamp-64-bit/</link>
		<comments>http://mnshankar.wordpress.com/2011/03/25/installing-apc-3-1-6-on-wamp-64-bit/#comments</comments>
		<pubDate>Sat, 26 Mar 2011 00:41:11 +0000</pubDate>
		<dc:creator>mnshankar</dc:creator>
				<category><![CDATA[Computers and Internet]]></category>
		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">https://mnshankar.wordpress.com/2011/03/25/installing-apc-3-1-6-on-wamp-64-bit/</guid>
		<description><![CDATA[My dev machine has 64bit wampserver installed on windows 7 (MSVC9 (Visual C++ 2008) , Thread Safe, x64). I wanted a caching solution that works well with this setup – As of this writing, APC is the only 64 bit option available. Get the precompiled TS dll from here (In the comments posted on this [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mnshankar.wordpress.com&amp;blog=8005313&amp;post=10521&amp;subd=mnshankar&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>My dev machine has 64bit <a href="http://www.wampserver.com/en/download.php" target="_blank">wampserver</a> installed on windows 7 (MSVC9 (Visual C++ 2008) , Thread Safe, x64). I wanted a caching solution that works well with this setup – As of this writing, APC is the <strong>only</strong> 64 bit option available.</p>
<p>Get the precompiled TS dll from <a href="http://www.anindya.com/php-5-3-4-x64-64-bit-for-windows/" target="_blank">here</a> (In the comments posted on this page, you will find a link to php_apc.dll <strong>without memprotect</strong>). Save it in your php “ext” directory.</p>
<p>Add the following line to your php.ini file :</p>
<blockquote><p>extension=php_apc.dll </p>
</blockquote>
<p>Restart apache web server..browse your phpinfo page, and it should have a section for APC – The defaults work fine for a test server setup.</p>
<p>Next, setup the admin page – this will help you view/clear your variable cache(s):</p>
<ul>
<li>Download apc.php from <a href="http://svn.php.net/viewvc/pecl/apc/trunk/apc.php?revision=307048&amp;view=markup" target="_blank">here</a></li>
<li>Save it in your webfolder as apc.php</li>
<li>Edit apc.php. Change the admin password (from the default ‘password’ to any string of your liking):</li>
</ul>
<blockquote><p>defaults(&#8216;ADMIN_USERNAME&#8217;,'apc&#8217;);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Admin Username<br />defaults(&#8216;ADMIN_PASSWORD&#8217;,'pAssW0rd&#8217;);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Admin Password &#8211; CHANGE THIS TO ENABLE!!!</p>
</blockquote>
<ul>
<li>Navigate to <a href="http://localhost/apc.php">http://localhost/apc.php</a> and you should see a nicely formatted page displaying the status of your cache.</li>
</ul>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mnshankar.wordpress.com/10521/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mnshankar.wordpress.com/10521/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mnshankar.wordpress.com/10521/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mnshankar.wordpress.com/10521/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/mnshankar.wordpress.com/10521/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/mnshankar.wordpress.com/10521/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/mnshankar.wordpress.com/10521/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/mnshankar.wordpress.com/10521/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mnshankar.wordpress.com/10521/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mnshankar.wordpress.com/10521/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mnshankar.wordpress.com/10521/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mnshankar.wordpress.com/10521/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mnshankar.wordpress.com/10521/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mnshankar.wordpress.com/10521/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mnshankar.wordpress.com&amp;blog=8005313&amp;post=10521&amp;subd=mnshankar&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mnshankar.wordpress.com/2011/03/25/installing-apc-3-1-6-on-wamp-64-bit/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/54eaf4a8492ddeea93a0d826041b3b7b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mnshankar</media:title>
		</media:content>
	</item>
		<item>
		<title>Search Implementation Using Zend_Search_Lucene</title>
		<link>http://mnshankar.wordpress.com/2011/03/16/search-implementatio-using-zend_search_lucene/</link>
		<comments>http://mnshankar.wordpress.com/2011/03/16/search-implementatio-using-zend_search_lucene/#comments</comments>
		<pubDate>Thu, 17 Mar 2011 01:12:04 +0000</pubDate>
		<dc:creator>mnshankar</dc:creator>
				<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[search example]]></category>
		<category><![CDATA[Zend lucene example]]></category>

		<guid isPermaLink="false">https://mnshankar.wordpress.com/2011/03/16/search-solution-using-zend_search_lucene/</guid>
		<description><![CDATA[Zend_Search_Lucene is a comprehensive Information Retrieval component written entirely in PHP (the index is completely file system based). It can be employed in most medium to mid-range websites to provide full-text search capabilities. In this blog, we will look at a practical implementation of the same. From the outside, the API makes Lucene seem obscenely [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mnshankar.wordpress.com&amp;blog=8005313&amp;post=10501&amp;subd=mnshankar&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p id="codeSnippetWrapper"><a href="http://framework.zend.com/manual/en/zend.search.lucene.html" target="_blank">Zend_Search_Lucene</a> is a comprehensive Information Retrieval component written entirely in PHP (the index is completely file system based). It can be employed in most medium to mid-range websites to provide full-text search capabilities. In this blog, we will look at a practical implementation of the same. From the outside, the API makes Lucene seem obscenely simplistic. But it is in fact quite a complex data analysis, storage and retrieval engine. It masterfully encompasses many major aspects of computer theory like Data structures, File systems,&nbsp; Indexes and Parsing. For the technically inclined who wish to learn more about Lucene internals, I would strongly recommend <a href="http://www.manning.com/hatcher2/" target="_blank">Lucene In Action </a>(The entire PHP source code is also available under the Zend/Search folder. You can easily insert a break point and explore it line by line using a good IDE like <a href="http://netbeans.org/" target="_blank">Netbeans</a>!)</p>
<p><strong>Credit where it is due</strong>: The code has been inspired by a chapter from the book “<a href="http://www.zendframeworkinaction.com/" target="_blank">Zend Framework in Action</a>” by Rob Allen. Although coding a Lucene search solution that “works” is quite trivial to accomplish with the Zend_Search_Lucene API, this book/chapter looks at a “well-engineered” solution using the Observer design pattern that scales beautifully.</p>
<h3>Note:</h3>
<ol>
<li>The PHP implementation of Lucene is slower than its pure <a href="http://lucene.apache.org/java/docs/index.html" target="_blank">Java counterpart</a>. This is especially true when the size of data to be indexed increases. (Understandably so &#8211; PHP, an interpreted language, comes no where close to java in runtime efficiency)
<li>The max size of a Lucene index on a 32 bit OS is 2GB. On a 64 bit server OS, there is no limit.
<li>The binary index structure created by PHP and Java are identical and can be used interchangeably
<li>The next step in scaling your search solution would be migrating to <a href="http://lucene.apache.org/solr/" target="_blank">SOLR</a>. SOLR is a pure java server-side indexing engine (built on Lucene) which does not have any of the bottlenecks of Lucene. It is truly enterprise-ready with the ability to scale to multiple servers, and index millions of documents. It runs in a Tomcat container and provides a web service which can be easily queried by PHP. So, once you migrate to SOLR, your search query will be submitted to SOLR via a web service call which in turn returns formatted HTML. The SOLR API provides similar mechanisms to add/modify/delete from your index. </li>
</ol>
<p>The following framework is built on the Zend Framework and helps us to ‘instantaneously’ index fresh content so that it is available for search. This is a core requirement for dynamic websites (like facebook and twitter).</p>
<p>We will be building a search solution for a web app for the infamous ‘bugs’ database – although the example is quite contrived, you will see that the solution can easily be extended to any model type.</p>
<p>Our simple model has the following (self explanatory) fields: bug_id, bug_description, reported_by. In order to search, we must first have an “index” of terms in place. The index comprises one or more “documents” that are in turn made up of “field” objects. We will add to the index when new books are “inserted” into the system (to get reacquainted with the basics of Zend_Search_Lucene, <a title="Searching with Zend&nbsp;(Zend_Lucene)" href="http://mnshankar.wordpress.com/2009/05/29/searching-with-zend-lucene/" target="_blank">please refer to my earlier blog</a>).</p>
<p>The following describes the lucene field types that will be used in our index:</p>
<table border="1" cellspacing="0" cellpadding="2" width="913">
<tbody>
<tr>
<td valign="top" width="133"><strong>Lucene Field Name </strong></td>
<td valign="top" width="133"><strong>Lucene Field Type </strong></td>
<td valign="top" width="645"><strong>Description</strong></td>
</tr>
<tr>
<td valign="top" width="133">classname</td>
<td valign="top" width="133">Unindexed</td>
<td valign="top" width="645">For now, we are indexing “bugs”.. As our application grows, we may need to store data from various other models Storing the classname will help us construct links to pages that contain the full data</td>
</tr>
<tr>
<td valign="top" width="133">key</td>
<td valign="top" width="133">Unindexed</td>
<td valign="top" width="645">The id that uniquely identifies the record in the table. Again used for creating the URL to link to the full data</td>
</tr>
<tr>
<td valign="top" width="133">docRef</td>
<td valign="top" width="133">Keyword</td>
<td valign="top" width="645">Unique id in the index – We will concatenate the “class” and “internal id” fields and store it so we can accurately locate the document. This is especially useful for updates (Lucene does not permit updates.. so document will need to be deleted and a fresh document inserted). We would like this field to be indexed -we can use Zend_Search_Lucene_Search_Query_Term to search for this exact term and delete the documents returned!</td>
</tr>
<tr>
<td valign="top" width="133">description</td>
<td valign="top" width="133">text</td>
<td valign="top" width="645">bug description. Needs to be indexed, tokenized and stored.</td>
</tr>
<tr>
<td valign="top" width="133">reported_by</td>
<td valign="top" width="133">keyword</td>
<td valign="top" width="645">name (we don’t want this to be tokenized.. A name is a name is a name!)</td>
</tr>
</tbody>
</table>
<p>The code for creating an index is the same irrespective of the data model:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:a43e9129-2661-4bfb-91c0-7bc5f6320612" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: php; pad-line-numbers: true;">
//open the index directory
$index = Zend_Search_Lucene::open(APPLICATION_PATH . &quot;\searchindex&quot;);
//declare the search document structure
$doc = new Zend_Search_Lucene_Document(field1, field2, field3…);
//insert the document into the index
$index-&gt;addDocument($doc);
</pre>
</pre>
</div>
<div id="codeSnippetWrapper">
<p>The naive solution is to repeat the above 3 lines whenever/wherever we have data to be indexed. However, as our application (and the number of data models) grows, we would run into code maintenance issues. We would also like to make all the models searchable (if required) – automatically.</p>
</div>
<p>To a mind attuned to design patterns, hints of the “observer” pattern begin to emerge. The data/model rows in our case are the “subjects” and the SearchIndexer class is the “observer”. The SearchIndexer class registers with models to be notified of any updates – conveniently for us, the Zend_Db_Table_Row_Abstract class triggers&nbsp; _postInsert(), _postUpdate() and _postDelete() function/events AFTER insert, update and delete respectively on the data model. This design pattern can be effectively used to decouple the model from the search.</p>
<p>Advantages of a “lightly coupled” search solution:</p>
<ol>
<li>It is scalable. It can grow easily with our application and not require major work to make additions searchable
<li>We could swap out our search solution tomorrow with another without impacting any other business logic code (you know this is coming!) </li>
</ol>
<p>We create the interfaces required to implement the observer design pattern in our code (an in-depth treatment of the actual design pattern is beyond the scope of this article. If you are new to design patterns, <a href="http://oreilly.com/catalog/9780596007126" target="_blank">Head First Design Patterns</a> is an exceptional read):</p>
<p>We start off by creating the cornerstones of the Observer design pattern namely the Observer and Subject interfaces as shown below. The “Subject” raises the event and the “Observer” responds to it. In our case, the subject is the model row (that is inserted, updated or deleted) and the observer is the SearchIndexer that modifies the Lucene index files accordingly.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:2a622286-2a5f-4938-9283-17b1f875d295" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: php;">
&lt;?php
interface ZF_ISubject {
public static function  Register(ZF_IObserver $o);
public function Notify($flag);
}
?&gt;
</pre>
</pre>
</div>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:f81a362c-bfc9-4608-bea4-00cea8519b87" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: php;">
&lt;?php
interface ZF_IObserver {
public function update($flag, $row);
}
?&gt;
</pre>
</pre>
</div>
<p>Looking at the target Use Cases will give you a high-level view of what we are aiming for:</p>
<p><strong>1. Registering the Observer</strong></p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:ea6a33c9-3ac7-4ca6-8dfe-744c1ec06b94" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: php;">
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
public function _initSearchListeners()
{
	$search = new ZF_SearchIndexer(APPLICATION_PATH . '/index');
	ZF_SearchableRow::Register($search);
	Zend_Registry::set('search', $search);
}
}

</pre>
</pre>
</div>
<p>The SearchIndexer object registers itself with SearchableRow using the static “Register” function. This is typically done in the Bootstrap process.</p>
<p><strong></p>
<p>2. Trigger an insert into the index by updating a row and then search for the newly inserted term</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:7573c6ec-b5e8-40c7-ac6a-e73b0601e737" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: php;">
//retrieve search indexer from Zend Registry
$search = Zend_Registry::get('search');
//Use a plain old object to create a bug
$data = new Model_Bugs();
$data-&gt;bug_id=1;
$data-&gt;bug_description = &quot;Button click does not work!&quot;;
$obj-&gt;update($data);    //this automatically indexes the data!
//search for the data in the index
$index = Zend_Search_Lucene::open($search-&gt;getIndexDirectory());
$hits = $index-&gt;find('Button');
Zend_Debug::dump($hits);
</pre>
</pre>
</div>
<p></strong></p>
<div><strong>3. Rebuild the whole index</strong></div>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:12fc58b4-3200-40eb-96c6-5eee22c09c7b" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: php;">
//retrieve search indexer from registry
$search = Zend_Registry::get('search');
//loop through all our model rows and index!
$obj = new Model_BugsDAL();
$rows = $obj-&gt;fetchAll();
foreach ($rows as $row)
{
$search-&gt;update('insert', $obj-&gt;getRow($row));
}
</pre>
</pre>
</div>
<div id="codeSnippetWrapper"><strong><br /></strong></div>
<p>See how easy it is to extend the indexing to the whole site (and possibly all models) once we have the search infrastructure setup ?</p>
<p>The ZF_SearchableRow class is defined below. As you may notice from its definition, it extends the Zend_Db_Table_Row_Abstract class and implements the ISubject interface. Additionally, this class is defined as abstract (no instances can be created) further, it defines two abstract methods – ModelType() and getSearchFields() that its concrete class must implement.</p>
<p>The $_observers[] array, and the Register function are marked as static (so that they can be accessed from the bootstrapper without the need to instantiate an object). The _postInsert(), _postUpdate() and _postDelete() events are caught and the notify() function is triggered with the type of event and the entire row ($this) as parameter.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:2417c1f2-e3a8-4355-a740-cc90a8cd8192" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: php;">
&lt;?php
abstract class ZF_SearchableRow extends Zend_Db_Table_Row_Abstract implements ZF_ISubject
{
protected static $_observers = array();
//all classes that inherit this must provide implementation for
//the following:
//Return the name of the model.
abstract public function ModelType();
//Return the index fields. This is best known to the individual models.
abstract public function getSearchFields();

public static function Register(ZF_IObserver $o)
{
self::$_observers[] = $o;
}
public function Notify($flag)
{
foreach (self::$_observers as $observer)
{
$observer-&gt;update($flag, $this);
}
}
protected function  _postInsert()
{
$this-&gt;Notify(&quot;insert&quot;);
parent::_postInsert();
}
protected function  _postUpdate()
{
$this-&gt;Notify(&quot;update&quot;);
parent::_postUpdate();
}
protected function  _postDelete()
{
$this-&gt;Notify('delete');
parent::_postDelete();
}
}
?&gt;

</pre>
</pre>
</div>
<p>We next implement the model classes. I wont go into too much detail &#8211; I follow the <a href="http://framework.zend.com/manual/en/learning.quickstart.create-model.html" target="_blank">Zend framework recommended documentation</a> for creating models (If you are new to this, please also take time to view this informative presentation on data models by Matthew Weier O&#8217;Phinney: <a href="http://mtadata.s3.amazonaws.com/webcasts/20090724-playdoh.wmv">http://mtadata.s3.amazonaws.com/webcasts/20090724-playdoh.wmv</a>)</p>
<p>We create three classes for the Bugs model layer</p>
<ul>
<li><strong>Bugs</strong>: business logic
<li><strong>BugsDAL</strong>: Data abstraction layer
<li><strong>BugsDB</strong>: data source model; in our example we extend Zend_Db_Table_Abstract. Additionally, we create BugsRow.php that extends ZF_SearchableRow above (and set the _rowClass variable in BugsDB to refer to this class) </li>
</ul>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:93490c18-9f92-4830-8950-bcac8a147f8b" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: php;">
&lt;?php
/*
* override the __get and __set magic methods to provide base functionality for models.
*/
class ZF_BaseGetSet
{
protected $_data=array();
/**
*Automatically invoked when a non existant property is read
* @param &lt;type&gt; $name
*/
public function __get($name)
{
if (array_key_exists($name, $this-&gt;_data))
return $this-&gt;_data[$name];
}
/**
*Automatically invoked when a non existant property is written
* @param &lt;type&gt; $name
* @param &lt;type&gt; $value
*/
public function  __set($name, $value)
{
$this-&gt;_data[$name]=$value;
}
}
?&gt;
</pre>
</pre>
</div>
</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:f212d62d-e14a-4cbb-b43b-81a130d2dabe" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: php;">
&lt;?php
class Model_Bugs extends ZF_BaseGetSet
{
//this model now has default getter and setter
//inherited from ZF_BaseGetSet
}
?&gt;
</pre>
</pre>
</div>
</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:f562d527-fec4-4f21-bb82-6f5851fc0e04" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: php;">
&lt;?php
class Model_BugsDB extends Zend_Db_Table_Abstract
{
protected $_name=&quot;zfbugs&quot;;
protected $_rowClass = &quot;Model_BugsRow&quot;;
}
?&gt;
</pre>
</pre>
</div>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:58503abe-88d8-4634-ac6f-426aca352bbb" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: php;">
&lt;?php
class Model_BugsRow extends ZF_SearchableRow
{
public function getSearchFields()
{
$fields=array();
$fields['class']=$this-&gt;ModelType();
$fields['key']=$this-&gt;bug_id;
$fields['description']=$this-&gt;bug_description;
$fields['reportedBy']=$this-&gt;reported_by;
return $fields;
}
/**
*Each model row exposes what type it is.. This helps make our search
* more generic.
* @return &lt;type&gt;
*/
public function ModelType()
{
return &quot;Bugs&quot;;
}
}
?&gt;
</pre>
</pre>
</div>
<p>&nbsp;</p>
<p>So far, we have handled the models and “Subjects”. Let us now move on to implementing the SearchIndexer class (the observer)</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:d9d5bb32-fbe9-436b-a9bc-6558469dd308" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: php;">
&lt;?php
class ZF_SearchIndexer implements ZF_IObserver
{
protected $_indexDirectory;
public function __construct($indexDirectory)
{
$this-&gt;_indexDirectory = $indexDirectory;
try
{
$index = Zend_Search_Lucene::open($this-&gt;_indexDirectory);
} catch (Exception $e)
{
$index = Zend_Search_Lucene::create($this-&gt;_indexDirectory);
}
}
public function setIndexDirectory($directory)
{
$this-&gt;_indexDirectory = $directory;
}
public function getIndexDirectory()
{
return $this-&gt;_indexDirectory;
}
protected function getDocument($row)
{
//use factory design pattern to figure out the
//appropriate zend lucene document type and field structure
$doc = ZF_SearchIndexFactory::getDocument($row);
return $doc;
}
//this is the function invoked by the subject (Observer pattern)
public function update($flag, $row)
{
$doc = $this-&gt;getDocument($row);
$this-&gt;_modifyIndex($flag, $doc);
}
protected function _modifyIndex($flag, Zend_Search_Lucene_Document $doc)
{
$docRef = $doc-&gt;docRef;
$index = Zend_Search_Lucene::open($this-&gt;_indexDirectory);
if ($flag != 'insert')
{
$term = new Zend_Search_Lucene_Index_Term($docRef, 'docRef');
$query = new Zend_Search_Lucene_Search_Query_Term($term);
$hits = $index-&gt;find($query);
if (count($hits) &gt; 0)
{
foreach ($hits as $hit)
{
$index-&gt;delete($hit-&gt;id);
}
}
}
if ($flag != &quot;delete&quot;)
{
$index-&gt;addDocument($doc);
$index-&gt;optimize();
}
}
}
?&gt;
</pre>
</pre>
</div>
<p>The constructor checks if the index is present in the directory.. if not, it goes ahead and creates a new index.</p>
<p>Notice how the the above class handles “updates” (_modifyIndex() method) – The index is first searched for the ‘docRef’ –this is guaranteed to be unique in the index : If found, the document is first deleted (Unfortunately, this is the only way to handle updates in Lucene).</p>
<p>The “<strong>Factory</strong>” design pattern is used to create Zend_Search_Lucene_Document instances confirming to particular models:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:d65b18e1-bae2-4526-b83d-9f00f8ebcfba" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: php;">
&lt;?php
class ZF_SearchIndexFactory
{
//returns a lucene document for indexing
public static function getDocument($row)
{
//return a Zend_Lucene_Document corresponding to the
//model passed in as parameter.
if ($row-&gt;modelType() == 'Bugs')
{
$fields = $row-&gt;getSearchFields();
$doc = new ZF_BugsLuceneDocument($fields['class'], $fields['key'],
$fields['description'], $fields['reportedBy']);
}
//if you have more types, add them here...
return $doc;
}
}
?&gt;
</pre>
</pre>
</div>
<p>And, finally here is the ZF_BugsLuceneDocument that simply extends Zend_Search_Lucene_Document and adds the fields that are passed to its constructor. The ‘docRef’ field is created as a concatenation of the class and key fields.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:61da11e7-ac58-42b7-8746-9c61a16a9211" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: php;">
&lt;?php
class ZF_BugsLuceneDocument extends Zend_Search_Lucene_Document
{

public function __construct($class, $key, $description, $reportedBy)
{
$this-&gt;addField(Zend_Search_Lucene_Field::Keyword(
'docRef', &quot;$class:$key&quot;));
$this-&gt;addField(Zend_Search_Lucene_Field::UnIndexed(
'class', $class));
$this-&gt;addField(Zend_Search_Lucene_Field::UnIndexed(
'key', $key));
$this-&gt;addField(Zend_Search_Lucene_Field::text(
'description', $description));
$this-&gt;addField(Zend_Search_Lucene_Field::Keyword(
'reportedBy', $reportedBy));
}
}
?&gt;

</pre>
</pre>
</div>
<p>Down the line, if we need ‘Blogs’ to be indexed, we create the appropriate models (inheriting and implementing the required classes), make sure that its ModelType returns “Blogs” , and its getSearchFields() returns an array containing appropriate fields to be indexed from the Blogs model, and finally tweak the ZF_SearchIndexFactory to return instances of ZF_BlogsLuceneDocument &#8211; See how elegant the code is?</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mnshankar.wordpress.com/10501/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mnshankar.wordpress.com/10501/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mnshankar.wordpress.com/10501/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mnshankar.wordpress.com/10501/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/mnshankar.wordpress.com/10501/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/mnshankar.wordpress.com/10501/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/mnshankar.wordpress.com/10501/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/mnshankar.wordpress.com/10501/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mnshankar.wordpress.com/10501/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mnshankar.wordpress.com/10501/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mnshankar.wordpress.com/10501/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mnshankar.wordpress.com/10501/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mnshankar.wordpress.com/10501/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mnshankar.wordpress.com/10501/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mnshankar.wordpress.com&amp;blog=8005313&amp;post=10501&amp;subd=mnshankar&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mnshankar.wordpress.com/2011/03/16/search-implementatio-using-zend_search_lucene/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
<enclosure url="http://mtadata.s3.amazonaws.com/webcasts/20090724-playdoh.wmv" length="59063715" type="video/asf" />
	
		<media:content url="http://1.gravatar.com/avatar/54eaf4a8492ddeea93a0d826041b3b7b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mnshankar</media:title>
		</media:content>
	</item>
		<item>
		<title>Installing PEAR on WAMP</title>
		<link>http://mnshankar.wordpress.com/2011/02/26/installing-pear-on-wamp/</link>
		<comments>http://mnshankar.wordpress.com/2011/02/26/installing-pear-on-wamp/#comments</comments>
		<pubDate>Sat, 26 Feb 2011 21:14:52 +0000</pubDate>
		<dc:creator>mnshankar</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">https://mnshankar.wordpress.com/2011/02/26/installing-pear-on-wamp/</guid>
		<description><![CDATA[I do most of my php development on Windows (using Wampserver on Windows 7).  Unfortunately, the default wampserver installation does NOT provide PHPUnit &#8211; the unit testing tool for PHP. PHPUnit is distributed via PEAR repositories. While installing the PEAR repository is a cinch on Linux, I am honestly surprised about how convoluted it is on [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mnshankar.wordpress.com&amp;blog=8005313&amp;post=10486&amp;subd=mnshankar&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I do most of my php development on Windows (using Wampserver on Windows 7).  Unfortunately, the default wampserver installation does NOT provide PHPUnit &#8211; the unit testing tool for PHP.</p>
<p>PHPUnit is distributed via PEAR repositories. While installing the PEAR repository is a cinch on Linux, I am honestly surprised about how convoluted it is on a WAMP setup (actually, it is the lack of accurate documentation that is troubling. I tried the process some time ago and faced a similar problem. At the time, <a href="https://mnshankar.wordpress.com/2010/10/30/setting-up-phpunit-on-wamp/" target="_blank">I wrote a blog about setting up PHPUnit manually</a>).</p>
<p>So, here is my attempt at detailing the (fully working!) PEAR and PHPUnit install process step-by-step with all the gory details:</p>
<p>1. Right click on the following link: <a href="http://pear.php.net/go-pear.phar">http://pear.php.net/go-pear.phar</a> and save as go-pear.phar in your wamp/bin/php directory (C:\wamp\bin\php\php5.3.4 in my case)</p>
<p>(<strong>Note</strong> that there are many online resources pointing to download <a href="http://pear.php.net/go-pear">http://pear.php.net/go-pear</a>, save the file as go-pear.php, and then execute it using php. However, that approach did not work for me)</p>
<p>2. Open an ADMIN command window, navigate to the folder where go-pear.phar was downloaded and type in</p>
<blockquote><p>php go-pear.phar</p></blockquote>
<p><a href="http://mnshankar.files.wordpress.com/2011/02/image10.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border-width:0;" title="image" src="http://mnshankar.files.wordpress.com/2011/02/image_thumb10.png?w=644&#038;h=424" border="0" alt="image" width="644" height="424" /></a></p>
<p>3. You will be prompted for install locations.. Accept ALL defaults, and proceed with the setup:</p>
<p><a href="http://mnshankar.files.wordpress.com/2011/02/image11.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border-width:0;" title="image" src="http://mnshankar.files.wordpress.com/2011/02/image_thumb11.png?w=644&#038;h=424" border="0" alt="image" width="644" height="424" /></a></p>
<p>4. When the install is complete, the pear installer creates a registry file to help us set the correct paths:</p>
<p><a href="http://mnshankar.files.wordpress.com/2011/02/image12.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border-width:0;" title="image" src="http://mnshankar.files.wordpress.com/2011/02/image_thumb12.png?w=644&#038;h=424" border="0" alt="image" width="644" height="424" /></a></p>
<p>5. The PEAR_ENV.reg file is generated as shown in the explorer window below.. Double click to launch and update your registry (it merely sets up path variables and global constants so that the pear files are accessible from the command line)</p>
<p><a href="http://mnshankar.files.wordpress.com/2011/02/image13.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border-width:0;" title="image" src="http://mnshankar.files.wordpress.com/2011/02/image_thumb13.png?w=587&#038;h=484" border="0" alt="image" width="587" height="484" /></a></p>
<p>6. Now, you should have PEAR installed on your computer. The next step is to register the channels that we require to download PHPUnit. Three repositories are required. Run the following commands in sequence:</p>
<p><span style="color:#ff0000;">(Make sure you have both <strong>openssl</strong> and <strong>curl</strong> support in your php installation. You may need to uncomment the corresponding .dll load commands in your php.ini&#8230; Remember the CLI&#8217;s php.ini NOT your apache&#8217;s)</span></p>
<blockquote><p>C:\wamp\bin\php\php5.3.4&gt;pear channel-discover pear.phpunit.de</p>
<p>C:\wamp\bin\php\php5.3.4&gt;pear channel-discover pear.symfony-project.com</p>
<p>C:\wamp\bin\php\php5.3.4&gt;pear channel-discover components.ez.no</p></blockquote>
<p><a href="http://mnshankar.files.wordpress.com/2011/02/image14.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border-width:0;" title="image" src="http://mnshankar.files.wordpress.com/2011/02/image_thumb14.png?w=644&#038;h=424" border="0" alt="image" width="644" height="424" /></a></p>
<p>7. Now that we have all sources established, issue the command to install the phpunit files. The ‘- &#8211; alldeps’ parameter is REQUIRED to install the command line tools for PHPUnit</p>
<blockquote><p>pear install &#8211; -alldeps phpunit/PHPUnit</p></blockquote>
<p>(NOTE: If you are copying and pasting the above line into your command window, the &#8220;alldeps&#8221; keyword is preceeded by TWO HYPHENS.. For some reason, wordpress is creating a weird character there)</p>
<p><a href="http://mnshankar.files.wordpress.com/2011/02/image15.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border-width:0;" title="image" src="http://mnshankar.files.wordpress.com/2011/02/image_thumb15.png?w=644&#038;h=424" border="0" alt="image" width="644" height="424" /></a></p>
<p>You should now have all the required components for phpUnit to function normally. Happy testing!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mnshankar.wordpress.com/10486/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mnshankar.wordpress.com/10486/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mnshankar.wordpress.com/10486/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mnshankar.wordpress.com/10486/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/mnshankar.wordpress.com/10486/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/mnshankar.wordpress.com/10486/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/mnshankar.wordpress.com/10486/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/mnshankar.wordpress.com/10486/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mnshankar.wordpress.com/10486/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mnshankar.wordpress.com/10486/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mnshankar.wordpress.com/10486/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mnshankar.wordpress.com/10486/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mnshankar.wordpress.com/10486/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mnshankar.wordpress.com/10486/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mnshankar.wordpress.com&amp;blog=8005313&amp;post=10486&amp;subd=mnshankar&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mnshankar.wordpress.com/2011/02/26/installing-pear-on-wamp/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/54eaf4a8492ddeea93a0d826041b3b7b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mnshankar</media:title>
		</media:content>

		<media:content url="http://mnshankar.files.wordpress.com/2011/02/image_thumb10.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://mnshankar.files.wordpress.com/2011/02/image_thumb11.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://mnshankar.files.wordpress.com/2011/02/image_thumb12.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://mnshankar.files.wordpress.com/2011/02/image_thumb13.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://mnshankar.files.wordpress.com/2011/02/image_thumb14.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://mnshankar.files.wordpress.com/2011/02/image_thumb15.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>
	</item>
		<item>
		<title>Recaptcha With Zend Form Element</title>
		<link>http://mnshankar.wordpress.com/2011/02/25/recaptcha-with-zend-form-element/</link>
		<comments>http://mnshankar.wordpress.com/2011/02/25/recaptcha-with-zend-form-element/#comments</comments>
		<pubDate>Fri, 25 Feb 2011 10:51:20 +0000</pubDate>
		<dc:creator>mnshankar</dc:creator>
				<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">https://mnshankar.wordpress.com/?p=10471</guid>
		<description><![CDATA[In an earlier blog, I had written about how Zend_Form_Element_Captcha can be used to easily generate CAPTCHA’s for your website. I have since embraced “Recaptcha” as the defacto captcha adapter. The same Zend_Form_Element_Captcha can be repurposed to easily deliver it on your site with minimal effort. Advantages of Recaptcha: Endorsed (and owned) by Google. It [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mnshankar.wordpress.com&amp;blog=8005313&amp;post=10471&amp;subd=mnshankar&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><font size="2" face="Calibri">In an </font><a href="https://mnshankar.wordpress.com/2010/06/01/zend-form-element-captcha/" target="_blank"><font size="2" face="Calibri">earlier blog</font></a><font size="2" face="Calibri">, I had written about how Zend_Form_Element_Captcha can be used to easily generate CAPTCHA’s for your website. I have since embraced “</font><a href="http://www.google.com/recaptcha" target="_blank"><font size="2" face="Calibri">Recaptcha</font></a><font size="2" face="Calibri">” as the defacto captcha adapter. The same Zend_Form_Element_Captcha can be repurposed to easily deliver it on your site with minimal effort.</font></p>
<p><font size="2" face="Calibri">Advantages of Recaptcha:</font></p>
<ul>
<li><font size="2" face="Calibri">Endorsed (and owned) by Google. </font></li>
<li><font size="2" face="Calibri">It is a webservice.. No more expensive GDI operations performed on your webserver. The captcha generation is done on google servers and delivered to your webpage as Html. </font></li>
<li><font size="2" face="Calibri">Provides Accessibility support. </font></li>
<li><font size="2" face="Calibri">Has a lot of “fuzzy” logic going on.. Notice that you don&#8217;t have to type the “recaptcha” word verbatim. Missing an illegible word will not invalidate your response. Captcha generated by you will not be so forgiving. </font></li>
<li><font size="2" face="Calibri">Why reinvent the wheel? </font></li>
<p>   <font size="2" face="Calibri"></font></ul>
<ul><font size="2" face="Calibri"></font></ul>
<p><font size="2" face="Calibri">The first step towards getting started is to go on the </font><a href="http://www.google.com/recaptcha"><font size="2" face="Calibri">Recaptcha</font></a><font size="2" face="Calibri"> website and create a key pair (You need a google account to log in).</font></p>
<p><font size="2" face="Calibri">I prefer creating a “global key”.. The keys can then be used on any website (and you can type in any domain in the provided space as shown below:</font></p>
<p><a href="http://mnshankar.files.wordpress.com/2011/02/image9.png"><font size="2" face="Calibri"><img style="display:inline;border-width:0;" title="image" border="0" alt="image" src="http://mnshankar.files.wordpress.com/2011/02/image_thumb9.png?w=644&#038;h=393" width="644" height="393" /></font></a></p>
<p><font size="2" face="Calibri">Click on the “Create Key” button at the bottom of the page. You will be presented with a public key and private key. You will require these when you make your webservice calls.</font></p>
<p><font size="2" face="Calibri">Ok.. onto our form class:</font></p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:203695f0-5406-49b2-9d25-27583aaffc02" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: php;">
class Form_Recaptcha extends Zend_Form
{
    public function init()
    {
        $recaptcha = new Zend_Service_ReCaptcha(&quot;sdfgdsfgdfgzGsA5WwGrLW4dq&quot;,
                        &quot;sdfgdfgsdfgsdfgsdfgfdfDT8lumPZ&quot;);
        $captcha = $this-&gt;createElement('Captcha', 'ReCaptcha',
                array('captcha'=&gt;array('captcha'=&gt;'ReCaptcha',
                                        'service'=&gt;$recaptcha)));

        $captcha-&gt;setLabel('Enter CAPTCHA');
        $this-&gt;addElement($captcha);

        $submit = $this-&gt;createElement('submit', 'submit');
        $submit-&gt;setLabel('Submit');
        $this-&gt;addElement($submit);
    }
}
</pre>
</pre>
</div>
<p><font size="2" face="Calibri">(Note that I have mangled my keys.. so please do not attempt to use the values in the code above!)</font></p>
<p><font size="2" face="Calibri">First, a Zend_Service_Recaptcha instance is created with our public and private key as parameters. This is passed in as an option to the “createElement” call.</font></p>
<p><font size="2" face="Calibri">One caveat though is that you MUST provide the options array when you create the captcha element.</font></p>
<p><font size="2" face="Calibri">For example, creating the captcha element like so:</font></p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:e815c90e-2df7-49f5-9d83-cc29b5d22695" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: php;">
$captcha = $this-&gt;createElement('Captcha', 'ReCaptcha');
$captcha-&gt;setOptions(
               array('captcha'=&gt;array('captcha'=&gt;'ReCaptcha',
                                      'service'=&gt;$recaptcha)));
</pre>
</pre>
</div>
<p><font size="2" face="Calibri">Although Syntactically and Semantically correct, will result in the following error message:</font></p>
<blockquote>
<p><font face="Calibri"><font size="2"><b>Message:</b> Invalid validator provided to addValidator; must be string or Zend_Validate_Interface</font></font></p>
</blockquote>
<p><font size="2" face="Calibri">The indexcontroller code that exercises the above form is shown below:</font></p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:ea4dd7c7-017f-458b-a86f-6a43aaac0879" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: php;">
class IndexController extends Zend_Controller_Action
{
    public function indexAction()
    {
        // action body
        $form = new Form_Recaptcha();
        $this-&gt;view-&gt;form = $form;
        if ($this-&gt;_request-&gt;isPost())
        {
            if ($form-&gt;isValid($_POST))
            {
               //Checks Everything! Captcha included :-)
                echo &quot;Valid!&quot;;

            }
        }
    }
}
</pre>
</pre>
</div>
<p><font size="2" face="Calibri">As shown above, the isValid() call checks all form elements including the recaptcha. Could not be simpler!</font></p>
<p><font size="2" face="Calibri"></font></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mnshankar.wordpress.com/10471/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mnshankar.wordpress.com/10471/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mnshankar.wordpress.com/10471/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mnshankar.wordpress.com/10471/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/mnshankar.wordpress.com/10471/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/mnshankar.wordpress.com/10471/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/mnshankar.wordpress.com/10471/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/mnshankar.wordpress.com/10471/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mnshankar.wordpress.com/10471/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mnshankar.wordpress.com/10471/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mnshankar.wordpress.com/10471/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mnshankar.wordpress.com/10471/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mnshankar.wordpress.com/10471/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mnshankar.wordpress.com/10471/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mnshankar.wordpress.com&amp;blog=8005313&amp;post=10471&amp;subd=mnshankar&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mnshankar.wordpress.com/2011/02/25/recaptcha-with-zend-form-element/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/54eaf4a8492ddeea93a0d826041b3b7b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mnshankar</media:title>
		</media:content>

		<media:content url="http://mnshankar.files.wordpress.com/2011/02/image_thumb9.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>
	</item>
		<item>
		<title>Sync files with your NAS</title>
		<link>http://mnshankar.wordpress.com/2011/02/05/sync-files-with-your-nas/</link>
		<comments>http://mnshankar.wordpress.com/2011/02/05/sync-files-with-your-nas/#comments</comments>
		<pubDate>Sat, 05 Feb 2011 17:16:12 +0000</pubDate>
		<dc:creator>mnshankar</dc:creator>
				<category><![CDATA[Computers and Internet]]></category>
		<category><![CDATA[NAS]]></category>
		<category><![CDATA[Sync]]></category>
		<category><![CDATA[SyncToy]]></category>
		<category><![CDATA[Windows7]]></category>

		<guid isPermaLink="false">https://mnshankar.wordpress.com/2011/02/05/sync-files-with-your-nas/</guid>
		<description><![CDATA[I have my main workstation (Windows 7 64 bit) connected to a USB hub having connecting cables for my scanner, camera, webcam, handycam etc. All these external devices deliver content into my “Users” folder. The goal then is to have content in the “Pictures”, “Videos” and “Documents” folder in my main workstation transferred automatically to [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mnshankar.wordpress.com&amp;blog=8005313&amp;post=10463&amp;subd=mnshankar&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I have my main workstation (Windows 7 64 bit) connected to a USB hub having connecting cables for my scanner, camera, webcam, handycam etc. All these external devices deliver content into my “Users” folder. The goal then is to have content in the “Pictures”, “Videos” and “Documents” folder in my main workstation transferred automatically to my DNS-323 NAS so that</p>
<ol>
<li>Files are backed up</li>
<li>Files are easily accessible from any computer in my network</li>
</ol>
<p>&#8220;Sync&#8221; and &#8220;Backup&#8221; are two commonly used (or misused) terms to describe the above. Here are the important differences between the two:</p>
<ul>
<li>A “Backup” file is not usually human readable.. it needs to be “Restored” using the software that created the backup</li>
<li>Sync is 2-Way while Backup is 1-Way (although, depending on the software employed, you could set “master-slave” rules that mimic a backup plan)</li>
<li>While both Sync and Backup are incremental in nature, Backup additionally employs some compression on your files in order to reduce storage space. Sync utilizes exactly the same space on the source and destination.</li>
</ul>
<p>Having decided that “Sync” was the better option for me, I found that a tool named <a href="http://www.microsoft.com/downloads/en/details.aspx?familyid=c26efa36-98e0-4ee9-a7c5-98d0592d8c52&amp;displaylang=en" target="_blank">“SyncToy” from Microsoft</a> satisfied my requirements exactly. I just love the simplicity of its user interface!  Whats more, it is FREE, works exactly as advertised,  has a small footprint (~1 MB), and works natively on 64 bit windows (As an aside, I really think Microsoft should have incorporated this into “Live Mesh” – another sync tool offered by MS that syncs with its cloud based storage).</p>
<p>One shortcoming (if you want to call it that), is that SyncToy does not offer “automatic or scheduled syncing”. It is however pretty trivial to set this up using the built in Task Scheduler in Windows 7 (described below).</p>
<p>Here’s how I setup SyncToy on my main desktop:</p>
<p><a href="http://mnshankar.files.wordpress.com/2011/02/image.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border-width:0;" title="image" src="http://mnshankar.files.wordpress.com/2011/02/image_thumb.png?w=551&#038;h=484" border="0" alt="image" width="551" height="484" /></a></p>
<p>Note that I use the static IP address assigned to my NAS in the “Right Folder”. Please refer to my <a href="https://mnshankar.wordpress.com/2010/07/17/setting-up-my-dns-323-nas/" target="_blank">blog on how I setup my NAS</a> for additional information.</p>
<p>Pay particular attention to the options presented on the next screen.. This forms the core of your sync strategy. “Echo” works nicely for my setup.. but you might want to select “Contribute” if you do not want to propagate deletes.</p>
<p><a href="http://mnshankar.files.wordpress.com/2011/02/image1.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border-width:0;" title="image" src="http://mnshankar.files.wordpress.com/2011/02/image_thumb1.png?w=551&#038;h=484" border="0" alt="image" width="551" height="484" /></a></p>
<p><a href="http://mnshankar.files.wordpress.com/2011/02/image2.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border-width:0;" title="image" src="http://mnshankar.files.wordpress.com/2011/02/image_thumb2.png?w=551&#038;h=484" border="0" alt="image" width="551" height="484" /></a></p>
<p>Repeat the process for all folders on your workstation that you want to sync to your NAS. You are done setting up the sync rules at this point. You can click on the “Preview button” to view all the files/actions.</p>
<h2>Using Task Scheduler to schedule the sync:</h2>
<p>Although SyncToy can be run on demand anytime, Automating the process gives you the confidence that your invaluble docs, pics etc are safely synced on a regular basis (I strongly recommend you check the logs the first couple of times just to ensure that all went well).</p>
<p>Click on the <strong>Start</strong> menu, then select <strong>All Programs</strong> –&gt; <strong>Accessories</strong> &gt; <strong>System Tools</strong> –&gt;<strong>Task Scheduler </strong></p>
<p>(Alternatively, you can simply search for “Scheduler” in the win 7 search box).</p>
<p>Click on “Create Basic Task”:</p>
<p><a href="http://mnshankar.files.wordpress.com/2011/02/image3.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border-width:0;" title="image" src="http://mnshankar.files.wordpress.com/2011/02/image_thumb3.png?w=644&#038;h=416" border="0" alt="image" width="644" height="416" /></a></p>
<p>Enter a name for your job.. and a brief description:</p>
<p><a href="http://mnshankar.files.wordpress.com/2011/02/image4.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border-width:0;" title="image" src="http://mnshankar.files.wordpress.com/2011/02/image_thumb4.png?w=601&#038;h=484" border="0" alt="image" width="601" height="484" /></a></p>
<p>Next up, the trigger event. I setup mine to sync every week. You may want to tweak this depending on your circumstance… You can get REALLY granular ..Feel free to explore the available options.</p>
<p><a href="http://mnshankar.files.wordpress.com/2011/02/image5.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border:0;" title="image" src="http://mnshankar.files.wordpress.com/2011/02/image_thumb5.png?w=601&#038;h=484" border="0" alt="image" width="601" height="484" /></a></p>
<p>(Note that you <strong>SHOULD NOT </strong>select &#8220;When the computer starts&#8221; because it fires prior to login.. so neither your security credentials nor your LAN connection is ready at the time)</p>
<p><a href="http://mnshankar.files.wordpress.com/2011/02/image6.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border:0;" title="image" src="http://mnshankar.files.wordpress.com/2011/02/image_thumb6.png?w=601&#038;h=484" border="0" alt="image" width="601" height="484" /></a></p>
<p><a href="http://mnshankar.files.wordpress.com/2011/02/image7.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border-width:0;" title="image" src="http://mnshankar.files.wordpress.com/2011/02/image_thumb7.png?w=601&#038;h=484" border="0" alt="image" width="601" height="484" /></a></p>
<p>Under “Program/Script”, click on <strong>Browse</strong> button and locate the <strong>SyncToyCmd.exe – Note: </strong>Select SyncToyCmd (command line version) and NOT SyncToy(GUI). In the “Arguments” field, enter “-R” (for running all the sync folders setup).</p>
<p><a href="http://mnshankar.files.wordpress.com/2011/02/image8.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border:0;" title="image" src="http://mnshankar.files.wordpress.com/2011/02/image_thumb8.png?w=601&#038;h=484" border="0" alt="image" width="601" height="484" /></a></p>
<p>Finish up.. and you are done with the scheduling process.</p>
<h2>Hiding the command window:</h2>
<p>When the scheduled process runs, it brings up a DOS command window (&#8220;taskeng.exe&#8221;) displaying the progress of the sync operation. This may not be acceptable to some. Here’s how you can suppress it:</p>
<p>1. Create a file named “Auto.vbs” (Ofcourse you can call it anything, I chose &#8220;Auto&#8221;) in your SyncToy folder with the following contents:</p>
<blockquote><p>Set WshShell = CreateObject(&#8220;WScript.Shell&#8221;)<br />
WshShell.Run Chr(34) &amp; &#8220;C:\Program Files\SyncToy 2.1\SyncToyCmd&#8221; &amp; Chr(34) &amp; &#8221; -R&#8221;, 0<br />
Set WshShell = Nothing</p></blockquote>
<p>2. Edit the scheduler script that was setup earlier to execute “Auto.vbs” instead of &#8220;SyncToyCmd.exe&#8221; (Remember to remove the –R switch from the arguments field as it is already included in the script)</p>
<p>Editing an existing scheduled operation using the task scheduler is actually a little convoluted.. You have to double click on the task.. then, select &#8220;Properties&#8221; from the right side action pane. This opens up the task for edits.</p>
<p>Note that once you have the basic scheduling in place, you can add any number of folders to SyncToy and it will be handled automatically during the next Sync!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mnshankar.wordpress.com/10463/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mnshankar.wordpress.com/10463/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mnshankar.wordpress.com/10463/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mnshankar.wordpress.com/10463/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/mnshankar.wordpress.com/10463/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/mnshankar.wordpress.com/10463/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/mnshankar.wordpress.com/10463/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/mnshankar.wordpress.com/10463/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mnshankar.wordpress.com/10463/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mnshankar.wordpress.com/10463/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mnshankar.wordpress.com/10463/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mnshankar.wordpress.com/10463/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mnshankar.wordpress.com/10463/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mnshankar.wordpress.com/10463/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mnshankar.wordpress.com&amp;blog=8005313&amp;post=10463&amp;subd=mnshankar&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mnshankar.wordpress.com/2011/02/05/sync-files-with-your-nas/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/54eaf4a8492ddeea93a0d826041b3b7b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mnshankar</media:title>
		</media:content>

		<media:content url="http://mnshankar.files.wordpress.com/2011/02/image_thumb.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://mnshankar.files.wordpress.com/2011/02/image_thumb1.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://mnshankar.files.wordpress.com/2011/02/image_thumb2.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://mnshankar.files.wordpress.com/2011/02/image_thumb3.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://mnshankar.files.wordpress.com/2011/02/image_thumb4.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://mnshankar.files.wordpress.com/2011/02/image_thumb5.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://mnshankar.files.wordpress.com/2011/02/image_thumb6.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://mnshankar.files.wordpress.com/2011/02/image_thumb7.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://mnshankar.files.wordpress.com/2011/02/image_thumb8.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>
	</item>
	</channel>
</rss>
