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

<channel>
	<title>{5} Setfive - Talking to the World &#187; open source</title>
	<atom:link href="http://shout.setfive.com/tag/open-source/feed/" rel="self" type="application/rss+xml" />
	<link>http://shout.setfive.com</link>
	<description></description>
	<lastBuildDate>Mon, 19 Jul 2010 19:09:55 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>UPDATED: New Facebook Phonebook Script</title>
		<link>http://shout.setfive.com/2010/07/19/updated-new-facebook-phonebook-script/</link>
		<comments>http://shout.setfive.com/2010/07/19/updated-new-facebook-phonebook-script/#comments</comments>
		<pubDate>Mon, 19 Jul 2010 19:05:24 +0000</pubDate>
		<dc:creator>Ashish Datta</dc:creator>
				<category><![CDATA[open source]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[fun stuff]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://shout.setfive.com/?p=382</guid>
		<description><![CDATA[I realized this morning that Anonymous Coward&#8217;s Facebook Phonebook Greasemonkey script broke awhile back so I decided to rewrite it from scratch. The original instructions for how to install the script are available here. I updated the original Userscripts page with the new script so you can download it here. Once again, this probably breaks [...]]]></description>
			<content:encoded><![CDATA[<p>I realized this morning that Anonymous Coward&#8217;s Facebook Phonebook Greasemonkey script broke awhile back so I decided to rewrite it from scratch.</p>
<p>The original instructions for how to install the script are available <a target="_blank" href="http://shout.setfive.com/2009/03/06/use-greasemonkey-to-extract-your-facebook-phonebook/">here</a>.</p>
<p>I updated the original Userscripts page with the new script so you can download it <a target="_blank" href="http://userscripts.org/scripts/show/43681">here</a>.</p>
<div style="font-size: 18px; font-weight: bold">
Once again, this probably breaks your Facebook TOS so I can&#8217;t vouch for the safety of your account if you do decide to do this.
</div>
]]></content:encoded>
			<wfw:commentRss>http://shout.setfive.com/2010/07/19/updated-new-facebook-phonebook-script/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>jQuery.trigger weirdness</title>
		<link>http://shout.setfive.com/2010/06/10/jquery-trigger-weirdness/</link>
		<comments>http://shout.setfive.com/2010/06/10/jquery-trigger-weirdness/#comments</comments>
		<pubDate>Fri, 11 Jun 2010 03:44:42 +0000</pubDate>
		<dc:creator>Ashish Datta</dc:creator>
				<category><![CDATA[open source]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://shout.setfive.com/?p=369</guid>
		<description><![CDATA[Earlier today, I was trying to use jQuery to trigger the submission of a form after a radio button was clicked. The form tag looked something like: ...form.. function saysomething(){ alert("Hello world from saysomething()"); } So for a regular submit button: Everything works fine, you&#8217;ll see the alert() and the form won&#8217;t submit because of [...]]]></description>
			<content:encoded><![CDATA[<p>Earlier today, I was trying to use jQuery to trigger the submission of a form after a radio button was clicked. The form tag looked something like:</p>
<pre name="code" class="html">
<form action="" id="someForm" method="GET" onsubmit="saysomething(); return false">
   ...form..
   </form>

    <script type="text/javascript">

    function saysomething(){
      alert("Hello world from saysomething()");
    }

   </script>
</pre>
<p>So for a regular submit button:</p>
<pre name="code" class="html">
<input type="submit" value="Submit Form" />
</pre>
<p>Everything works fine, you&#8217;ll see the alert() and the form won&#8217;t submit because of the return false.</p>
<p>I ran into issues when I tried to trigger() the submit event with jQuery. I was trying to trigger the submit() event on the form via jQuery. The problem I ran into, was that the saysomething() function was getting called, but the &#8220;return false&#8221; seemed to have no effect.</p>
<p>The final form looked something like:</p>
<pre name="code" class="html">
<form action="" id="someForm"
          method="GET" onsubmit="saysomething(); return false">
<input type="text" name="someshit" />
<input type="submit" value="Submit Form" />
<input type="button" value="jQuery.submit()" id="clickIt" />
    </form>

    <script type="text/javascript">

    function saysomething(){
      alert("Hello world from saysomething()");
    }

    $(document).ready( function(){
      $("#clickIt").click( function(){ $("#someForm").submit(); });
    });

    </script>
</pre>
<p>For some reason, if you submit the form via a jQuery trigger the form submits even though saysomething() gets called. I&#8217;m not sure if this is the expected behavior but it was certainly something of a shock. Anyway, a live version of the form is running <a href="http://code.setfive.com/shout/formsubmit.html" target="_blank">here</a>. </p>
]]></content:encoded>
			<wfw:commentRss>http://shout.setfive.com/2010/06/10/jquery-trigger-weirdness/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>jQuery blank() modified for password fields</title>
		<link>http://shout.setfive.com/2010/04/28/jquery-blank-modified-for-password-fields/</link>
		<comments>http://shout.setfive.com/2010/04/28/jquery-blank-modified-for-password-fields/#comments</comments>
		<pubDate>Thu, 29 Apr 2010 04:58:20 +0000</pubDate>
		<dc:creator>Ashish Datta</dc:creator>
				<category><![CDATA[open source]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://shout.setfive.com/?p=353</guid>
		<description><![CDATA[We&#8217;ve been using Jeff Hui&#8217;s very awesome jquery.blank plugin for sometime over at Setfive HQ. What blank() is allow you to basically move the labels for text inputs into the input themselves (to save space). We use this technique frequently for login boxes in headers since it&#8217;s easier not to have to stick in labels [...]]]></description>
			<content:encoded><![CDATA[<p>We&#8217;ve been using Jeff Hui&#8217;s very awesome <a target="_blank" href="http://blog.jeffhui.net/work/jquery-blank/">jquery.blank</a> plugin for sometime over at Setfive HQ. What blank() is allow you to basically move the labels for text inputs into the input themselves (to save space). We use this technique frequently for login boxes in headers since it&#8217;s easier not to have to stick in labels next to text boxes.</p>
<p>The problem is, you can&#8217;t use blank() on a password field since a password field won&#8217;t display clear text (obviously). To get around this, I&#8217;ve always manually stuck in a &#8220;shadow&#8221; text box next to the password field and toggled the text box or password box in order to make blank() work correctly.</p>
<p>Anyway, I finally got tired of doing this so I decided to patch the plugin to do this automatically. Jeff incorporated the code back into blank() and it&#8217;s available on GitHub <a target="_blank" href="http://github.com/jeffh/jquery.blank">here</a>. </p>
<p>Happy coding. </p>
]]></content:encoded>
			<wfw:commentRss>http://shout.setfive.com/2010/04/28/jquery-blank-modified-for-password-fields/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Adding ORDER BY FIELD to Propel Criterias</title>
		<link>http://shout.setfive.com/2009/10/13/adding-order-by-field-to-propel-criterias/</link>
		<comments>http://shout.setfive.com/2009/10/13/adding-order-by-field-to-propel-criterias/#comments</comments>
		<pubDate>Tue, 13 Oct 2009 23:22:49 +0000</pubDate>
		<dc:creator>Ashish Datta</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[Propel]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://shout.setfive.com/?p=313</guid>
		<description><![CDATA[Every now and then, we use Sphinx to provide full text searching in MySQL InnoDB tables. Sphinx is pretty solid. It&#8217;s easy to set up, pretty fast, and easy to deploy. My one big issue with Sphinx has always been making it play nice with Symfony, specifically Propel. The way Sphinx returns a result set [...]]]></description>
			<content:encoded><![CDATA[<p>Every now and then, we use <a href="http://www.sphinxsearch.com/" target="_blank">Sphinx</a> to provide full text searching in MySQL InnoDB tables. Sphinx is pretty solid. It&#8217;s easy to set up, pretty fast, and easy to deploy. </p>
<p>My one big issue with Sphinx has always been making it play nice with Symfony, specifically Propel. The way Sphinx returns a result set is as an ordered list of [id, weight] for each document it matched. As outlined <a href="http://www.sphinxsearch.com/faq.html#row-storage" target="_blank">here</a> the idea is to then hit your MySQL server to return the actual documents and use &#8220;ORDER BY FIELD(id, [id list])&#8221; to keep them in the right order that you received the list.</p>
<p>The problem is, Propel Criteria objects provide no mechanism to set an ORDER BY FIELD. This is an issue because if you drop Criterias you loose Propel Pagers which generally adds to a lot of duplicated code and is honestly just not very elegant.</p>
<p>Anyway, after some thought I came up with this solution.</p>
<p>If you read through the definition of &#8220;Criteria::addDescendingOrderByColumn()&#8221;:</p>
<pre class="php" name="code">
	/**
	 * Add order by column name, explicitly specifying descending.
	 *
	 * @param      string $name The name of the column to order by.
	 * @return     Criteria Modified Criteria object (for fluent API)
	 */
	public function addDescendingOrderByColumn($name)
	{
		$this->orderByColumns[] = $name . ' ' . self::DESC;
		return $this;
	}
</pre>
<p>All it really does is add the second part of the ORDER BY clause to an array which then gets joined up to build the final SQL. Because of this, you can actually just add an element onto the orderByColumns array which will cause Propel to execute an ORDER BY FIELD SQL statement.</p>
<p>To make the magic happen, I sub-classed Criteria and then added a addOrderByField() function to let me add a field to order by as well as a list to order by.</p>
<pre class="php" name="code">

class sfCriteria extends Criteria {

  private $myOrderByColumns = array();

  /**
   * Add an ORDER BY FIELD clause.
   *
   * @param String $name The field to order by.
   * @param Array $elements A list to order the elements by.
   * @return unknown
   */
  public function addOrderByField($name, $elements)
  {
    $this->myOrderByColumns[] = ' FIELD(' . $name . ', ' . join(", ", $elements) . ')';
    return $this;
  }

  public function getOrderByColumns(){
    return array_merge( $this->myOrderByColumns, parent::getOrderByColumns() );
  }
}
</pre>
<p>To use it, do something like this:</p>
<pre class="php" name="code">
$ids = array(1, 3, 7);
$c = new sfCriteria();
$c->add( SomeModelPeer::ID, $ids, Criteria::IN);
$c->addOrderByField( SomeModelPeer::ID, $ids);
$results = SomeModelPeer::doSelect( $c );
</pre>
<p>And thats about it. Since sfCriteria is a sub-class of Criteria the code works seamlessly with existing PropelPagers and anything else that expects a Propel Criteria. </p>
]]></content:encoded>
			<wfw:commentRss>http://shout.setfive.com/2009/10/13/adding-order-by-field-to-propel-criterias/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>FOSS Saturday: sfFbConnectGuardPlugin &#8211; sfGuard meets FB Connect</title>
		<link>http://shout.setfive.com/2009/09/12/foss-saturday-sffbconnectguardplugin/</link>
		<comments>http://shout.setfive.com/2009/09/12/foss-saturday-sffbconnectguardplugin/#comments</comments>
		<pubDate>Sat, 12 Sep 2009 22:44:17 +0000</pubDate>
		<dc:creator>Ashish Datta</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[facebook connect]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://shout.setfive.com/?p=275</guid>
		<description><![CDATA[I was slaving over a hot keyboard all Friday! But at last it is done &#8211; FBConnect for sfGuard. Get it here http://www.symfony-project.org/plugins/sfFbConnectGuardPlugin A detailed explanation of how to install it and use it is on the Symfony site. Anyway, the plugin basically just introduces a new table to keep track of Facebook IDs sfGuardUserIds [...]]]></description>
			<content:encoded><![CDATA[<p>I was slaving over a hot keyboard all Friday! </p>
<p>But at last it is done &#8211; FBConnect for sfGuard.</p>
<p>Get it here <a href="http://www.symfony-project.org/plugins/sfFbConnectGuardPlugin" target="_blank">http://www.symfony-project.org/plugins/sfFbConnectGuardPlugin</a></p>
<p>A detailed explanation of how to install it and use it is on the Symfony site. </p>
<p>Anyway, the plugin basically just introduces a new table to keep track of Facebook IDs <---> sfGuardUserIds</p>
<p>Here&#8217;s a fun nugget. One of the problems with using FB Connect is that you can&#8217;t mug a user&#8217;s email address from Facebook. Obviously this is a smart move on Facebook&#8217;s part but it makes life hard for my Nigerian spammer friends. If you want to snag a user&#8217;s email address (or anything else for that matter) while still using Facebook Connect here&#8217;s a sketch of how to do it.</p>
<p>Everything is the same except you can&#8217;t use Facebook&#8217;s FBML to render the FB Connect button. What you want to do instead is trigger the &#8220;connect&#8221; event by hand.  Here is basically how we do it:</p>
<ol>
<li>The user requests to sign up.</li>
<li>We pop up a Lightbox using <a href="http://jquery.com/demo/thickbox/" target="_blank">Thickbox</a></li>
<li>We ask the user for their email address and verify that is valid and unique via AJAX in the background.</li>
<li>The validation routing sets an attribute on the user using setAttribute() that contains the entered email address.</li>
<li>We close the Lightbox and initiate a Facebook Connect request with <a target="_blank" href="http://wiki.developers.facebook.com/index.php/JS_API_M_FB.Connect.RequireSession">FB.Connect.requireSession</a></li>
<li>In our createFbUser() method we get the attribute back and save it with the new user</li>
</ol>
<p>Bam. Got the user&#8217;s email address and logged them in via FB Connect. </p>
]]></content:encoded>
			<wfw:commentRss>http://shout.setfive.com/2009/09/12/foss-saturday-sffbconnectguardplugin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FOSS Fridays: MacGyvered Key/Value in Symfony</title>
		<link>http://shout.setfive.com/2009/08/07/foss-fridays-macgyvered-keyvalue-in-symfony/</link>
		<comments>http://shout.setfive.com/2009/08/07/foss-fridays-macgyvered-keyvalue-in-symfony/#comments</comments>
		<pubDate>Fri, 07 Aug 2009 16:29:47 +0000</pubDate>
		<dc:creator>Ashish Datta</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://shout.setfive.com/?p=232</guid>
		<description><![CDATA[On a project we&#8217;re currently working on, we arrived at a situation where our client had a loose and very fluid idea of the information he wanted to store about certain objects in his application. We didn&#8217;t specifically know the number of fields or the format of the data. Continually modifying the schema would of [...]]]></description>
			<content:encoded><![CDATA[<p>On a project we&#8217;re currently working on, we arrived at a situation where our client had a loose and very fluid idea of the information he wanted to store about certain objects in his application. We didn&#8217;t specifically know the number of fields or the format of the data. Continually modifying the schema would of been painful so I wanted to try something different. </p>
<p>Since the data is more or less non-relational (it only relates to the object that owns it), what I really wanted was an ad-hoc key/value store. But I didn&#8217;t want to break Propel&#8217;s ORM abstractions. I still wanted to be able to do:</p>
<pre class="php" name="code">$company-&gt;getMission();</pre>
<p>With the new system.</p>
<p>Turns out you basically can. Here&#8217;s how it works:</p>
<ol>
<li>Add a &#8220;dynamic_field&#8221; table to your schema. (definition is below)</li>
<li>Override the __call(), hydrate(), and save() functions in Propel model file that you want to MacGyver.</li>
<li>Pray.</li>
</ol>
<p>Definition of the dynamic_field table:</p>
<pre class="xml" name="code">
<table name="dynamic_field">
<column name="id" type="INTEGER" primaryKey="true" required="true" autoIncrement="true"/>
<column name="model" type="VARCHAR" size="128"/>
<column name="model_id" type="INTEGER" />
<column name="field_name" type="VARCHAR" size="128"/>
<column name="field_value" type="LONGVARCHAR" />
  </table>
</pre>
<p>So the idea is we want to basically build a Propel Behaviour to capture any undefined get/set calls and &#8220;get&#8221; the data out of the dynamic_field table or &#8220;set&#8221; the data by storing the value into the table. Since the table stores the model class and model id, the &#8220;keys&#8221; only have to be unique by model (just like Propel normally works).</p>
<p>Here is the code you need to add to the model file:</p>
<pre class="php" name="code">
public function __call($method, $arguments){

  // snag the dynamic setters
  if(strpos($method, "set") !== false
      &amp;&amp; $method[3] === strtoupper($method[3])){
	  $name = strtolower( substr($method, 3) );
	  $this-&gt;dynamicFields[ $name ] = array_pop( $arguments );
	  return true;
  }

  // snag the dynamic getters
  if(strpos($method, "get") !== false
      &amp;&amp; $method[3] === strtoupper($method[3])){
        $name = strtolower( substr($method, 3) );

      if( array_key_exists($name, $this-&gt;hydratedFields) ){
        	return $this-&gt;hydratedFields[$name];
      }

       if( array_key_exists($name, $this-&gt;dynamicFields) ){
        	return $this-&gt;dynamicFields[ $name ];
        }

      	return null;
    }

    return parent::__call($method, $arguments);
}

public function hydrate($row, $startcol = 0, $rehydrate = false)
{
  parent::hydrate($row, $startcol, $rehydrate);
  // pull in our dynamic fields while we're at it
  $c = new Criteria();
  $c-&gt;add( DynamicFieldPeer::MODEL, get_class($this) );
  $c-&gt;add( DynamicFieldPeer::MODEL_ID, $this-&gt;getId() );
  $dynamic = DynamicFieldPeer::doSelect( $c );

  foreach($dynamic as $d){
     $this-&gt;hydratedFields[ $d-&gt;getFieldName() ] = unserialize( $d-&gt;getFieldValue() );
  }

  return true;
}

  public function save(PropelPDO $con = null){

	  // save the dyanmic ones
    if( count($this-&gt;dynamicFields) ){

    	// grab the old ones and update stuff
      $keys = array_keys($this-&gt;dynamicFields);
      $c = new Criteria();
      $c-&gt;add( DynamicFieldPeer::MODEL, get_class($this) );
      $c-&gt;add( DynamicFieldPeer::MODEL_ID, $this-&gt;getId() );
      $c-&gt;add( DynamicFieldPeer::FIELD_NAME, $keys, Criteria::IN );
      $savedFields = DynamicFieldPeer::doSelect( $c );

      foreach($savedFields as $sf){
      	$sf-&gt;setFieldValue( serialize( $this-&gt;dynamicFields[$sf-&gt;getFieldName()] ) );
      	$sf-&gt;save();
      	unset( $this-&gt;dynamicFields[$sf-&gt;getFieldName()] );
      }

		  foreach( $this-&gt;dynamicFields as $key =&gt; $val ){
			  $df = new DynamicField();
			  $df-&gt;setModel( get_class($this) );
			  $df-&gt;setModelId( $this-&gt;getId() );
			  $df-&gt;setFieldName( $key );
			  $df-&gt;setFieldValue( serialize( $val ) );
			  $df-&gt;save();
		  }

	  }

	  return parent::save($con);
  }</pre>
<p>The code captures any undefined get/set calls and then deals with them appropriately. It won&#8217;t serialize the fields until the save() call (just like regular Propel objects). I also overloaded the hydrate() function so that the object will fetch all of its dynamic fields in one shot, as opposed one query per get.</p>
<p>Using the modified objects is exactly like regular Propel objects, the changes are entirely transparent except that you can get/set anything you want.</p>
<p>For example:</p>
<pre class="php" name="code">$company = CompanyPeer::retrieveByPK( 5 );
$company-&gt;setVision( "this is my vision" );
echo $company-&gt;getVision();</pre>
<p>Will work even though there is no &#8220;vision&#8221; column on the company table. Magic.</p>
<p>There is one big problem with this trick though. Because of the Propel class hierarchy, there isn&#8217;t any way to introduce this code in one file and have other objects inherit the changes. You have to manually copy it to any model file that you want to enable it for. </p>
]]></content:encoded>
			<wfw:commentRss>http://shout.setfive.com/2009/08/07/foss-fridays-macgyvered-keyvalue-in-symfony/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Google Calender embed missing events</title>
		<link>http://shout.setfive.com/2009/08/04/google-calender-embed-missing-events/</link>
		<comments>http://shout.setfive.com/2009/08/04/google-calender-embed-missing-events/#comments</comments>
		<pubDate>Tue, 04 Aug 2009 18:14:16 +0000</pubDate>
		<dc:creator>Ashish Datta</dc:creator>
				<category><![CDATA[Free Advice]]></category>
		<category><![CDATA[dumb]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[php code]]></category>

		<guid isPermaLink="false">http://shout.setfive.com/?p=230</guid>
		<description><![CDATA[So we decided to use the Google Calendar API in one of our applications to allow users to easily view and export events from outside the app. In general, the API was working well &#8211; I was using the Zend library to interact with Google and things seemed fine. That was until I tried to [...]]]></description>
			<content:encoded><![CDATA[<p>So we decided to use the Google Calendar API in one of our applications to allow users to easily view and export events from outside the app. In general, the API was working well &#8211; I was using the Zend library to interact with Google and things seemed fine.</p>
<p>That was until I tried to embed the calendar using Google&#8217;s iframe embed code. For some reason, events weren&#8217;t showing up in the embeded iframe calendar even though they were showing up in the actual calendar on calendar.google.com. Even stranger, the events were present in a JSON object on the embeded page and they were showing up in the RSS feed for the calendar.</p>
<p>After literally days of debugging and experimenting I finally found out the culprit.</p>
<p>For some reason, events created via the API that start and end at exactly the same time &#8211; say a start date of 08-05-2009 10:00:00 and an end date of 08-05-2009 10:00:00 don&#8217;t render on the embeded iframe calendar.</p>
<p>What is even more bizarre is that if you create an event via the web interface that starts and ends at the same time, it will render correctly on an embeded calendar.</p>
<p>Anyway, that was weird. All the events without explicit start and end times now last a grand total of one minute.</p>
<p>PS. Kudos to Daum for finding a constant for PHP&#8217;s date() function to generate RFC3339 timestamps.</p>
<p>Use like so:</p>
<pre class="php" name="code">
  $date = date(DATE_RFC3339, $timestamp);
</pre>
<p>To get back a valid RFC3339 for the Google Calendar API. </p>
]]></content:encoded>
			<wfw:commentRss>http://shout.setfive.com/2009/08/04/google-calender-embed-missing-events/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FOSS Fridays: OpenSSL in PHP</title>
		<link>http://shout.setfive.com/2009/07/31/foss-fridays-openssl-in-php/</link>
		<comments>http://shout.setfive.com/2009/07/31/foss-fridays-openssl-in-php/#comments</comments>
		<pubDate>Fri, 31 Jul 2009 21:14:48 +0000</pubDate>
		<dc:creator>Ashish Datta</dc:creator>
				<category><![CDATA[open source]]></category>
		<category><![CDATA[openssl]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[php code]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://shout.setfive.com/?p=202</guid>
		<description><![CDATA[Well Twitter has “Follow Fridays” so I thought we should do FOSS Fridays. I don’t really have a plan for this and it might not last but let’s see where it goes. In the last few days a couple of people have asked for tips on how to use OpenSSL from PHP. So here is [...]]]></description>
			<content:encoded><![CDATA[<p>Well Twitter has “Follow Fridays” so I thought we should do FOSS Fridays. I don’t really have a plan for this and it might not last but let’s see where it goes.</p>
<p>In the last few days a couple of people have asked for tips on how to use OpenSSL from PHP. So here is a snippet on how to do it. This comes out of an application that provides a shared authentication system between our client’s LDAP system and their partner’s systems.</p>
<p>It works like so:</p>
<ol>
<li>Users login to the application using their LDAP credentials.</li>
<li>When the users request to visit the partner site, our system packages up their login information, encrypts it, signs it, and shoots it along with the user to the partner site.</li>
<li>Next, the partner checks if the user has an account and if they do it logs them in. Otherwise, it creates them a new account and logs them in.</li>
</ol>
<p>All of this is done transparently so that the user doesn’t know they’ve actually left the original site.</p>
<p>Here is the code to do it. PS. it’s from a Symfony application.</p>
<pre class="php" name="code">
$user = $this-&gt;getUser();

$profile = $user-&gt;getProfile();

if(is_null($profile)){ die("Could not get user profile?"); }

$email = $profile-&gt;getEmail();

$firstName = $profile-&gt;getFirstName();

$lastName = $profile-&gt;getLastName();

$password = $request-&gt;getParameter("password");

$keyText = file_get_contents(sfConfig::get("sf_root_dir") . "/" . sfConfig::get("app_their_public_key"));

$theirPublicKey = openssl_pkey_get_public($keyText);

$keyText = file_get_contents(sfConfig::get("sf_root_dir") . "/" . sfConfig::get("app_our_private_key"));

$outPrivateKey = openssl_pkey_get_private($keyText);

$arr = array();

$arr["U_EMAIL"] = $email;

$arr["U_PASSWORD"] = $password;

$arr["U_FIRST_NAME"] = $firstName;

$arr["U_LAST_NAME"] = $lastName;

$arr["RL_E"] = $this-&gt;generateUrl("ps_error", array(), true);

$arr["RL_S"] = "PRIVATE URL";

$arr["ETIME"] = time() + 60;

$queryString = http_build_query($arr);

$res = openssl_sign($queryString, $signature, $outPrivateKey);

if(!$res){ throw new sfException("Could not sign the payload!", 1); }

$t = openssl_pkey_get_details($theirPublicKey);

$t = (int) ($t['bits'] / 8 ) - 11;

$l=strlen($queryString);

$cryptPayload = '';

for ($i=0; $i&lt;$l; $i+= $t) {

  $block = substr($queryString, $i, $t);

  if (!openssl_public_encrypt($block,$tS, $theirPublicKey)){
    throw new sfException('failed encrypt', 1);
   }

  $cryptPayload .= $tS;
}

$this-&gt;encodedSignature = base64_encode($signature);

$this-&gt;encodedData = base64_encode($cryptPayload);
</pre>
<p>The net result of all of this is an encrypted payload with the user’s credentials and a signature of the payload. The payload is encrypted with “their” public key and then signed with “our” private key. This ensures that only they can open the package and only we can generate valid signatures.</p>
<p>Happy Friday! </p>
]]></content:encoded>
			<wfw:commentRss>http://shout.setfive.com/2009/07/31/foss-fridays-openssl-in-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Extracting text from PDFs without pdftotext</title>
		<link>http://shout.setfive.com/2009/06/16/extracting-text-from-pdfs-without-pdftotext/</link>
		<comments>http://shout.setfive.com/2009/06/16/extracting-text-from-pdfs-without-pdftotext/#comments</comments>
		<pubDate>Tue, 16 Jun 2009 06:39:26 +0000</pubDate>
		<dc:creator>Ashish Datta</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[pdftotext]]></category>

		<guid isPermaLink="false">http://shout.setfive.com/?p=179</guid>
		<description><![CDATA[For a recent project, I had to extract the text out of a PDF so that I could save it into a database table. Normally, I would of used the popular pdftotext program but it wasn&#8217;t available in the particular environment I was working in. I contact support and they advised that the XPDF package [...]]]></description>
			<content:encoded><![CDATA[<p>For a recent project, I had to extract the text out of a PDF so that I could save it into a database table.</p>
<p>Normally, I would of used the popular pdftotext program but it wasn&#8217;t available in the particular environment I was working in. I contact support and they advised that the <a href="http://www.foolabs.com/xpdf/">XPDF</a> package has several X windows dependencies and that&#8217;s why they had not installed it. Fair enough.</p>
<p>I poked around a bit and found Apache&#8217;s <a href="http://incubator.apache.org/pdfbox/">PDFBox</a> library. I downloaded the package and looked at the examples. Sure enough there was a program called &#8220;ExtractText&#8221; that did exactly what I wanted.</p>
<p>Using ExtractText is similar to pdftotext &#8211; just pass in the PDF file and the text comes back. Awesome.</p>
<p>Anyway, hats off to <a href="mailto:ben@benlitchfield.com">Ben Litchfield</a> who wrote the ExtractText example. I rebuilt the ExtactText.java file as a standalone project and packaged it as a JAR.</p>
<p>I&#8217;ve attached the JAR and Eclipse project if anyone wants a copy of either.</p>
<p><a href="http://shout.setfive.com/wp-content/uploads/2009/06/ExtractTextSF.jar">The JAR</a></p>
<p><a href="http://shout.setfive.com/wp-content/uploads/2009/06/ExtractText.rar">The Eclipse Project</a> </p>
]]></content:encoded>
			<wfw:commentRss>http://shout.setfive.com/2009/06/16/extracting-text-from-pdfs-without-pdftotext/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>sfWidgetjQueryTimepickr &#8211; Symfony timepickr widget</title>
		<link>http://shout.setfive.com/2009/04/06/sfwidgetjquerytimepickr-symfony-timepickr-widget/</link>
		<comments>http://shout.setfive.com/2009/04/06/sfwidgetjquerytimepickr-symfony-timepickr-widget/#comments</comments>
		<pubDate>Mon, 06 Apr 2009 06:26:29 +0000</pubDate>
		<dc:creator>Ashish Datta</dc:creator>
				<category><![CDATA[open source]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://shout.setfive.com/?p=148</guid>
		<description><![CDATA[The component is a jQuery plugin called <a href="http://haineault.com/media/jquery/ui-timepickr/page/" target="_new">timepickr</a> and I thought it was particularly neat. Anyway, I finally needed to write a form which had a time component so I figured I'd drop in the timepickr jQuery plugin.

It didn't look like there was a Symfony Forms widget for it so I whipped one up. You can grab it <a href='http://shout.setfive.com/wp-content/uploads/2009/04/sfwidgetjquerytimepickr.php'>here</a>.]]></description>
			<content:encoded><![CDATA[<p>A couple of months ago <a target="_new" href="http://en.wikipedia.org/wiki/John_Resig">John Resig</a> posted on his <a target="_new" href="http://ejohn.org/blog/picking-time/">blog</a> about a &#8220;new&#8221; way for users to pick time.</p>
<p>The component is a jQuery plugin called <a href="http://haineault.com/media/jquery/ui-timepickr/page/" target="_new">timepickr</a> and I thought it was particularly neat. Anyway, I finally needed to write a form which had a time component so I figured I&#8217;d drop in the timepickr jQuery plugin.</p>
<p>It didn&#8217;t look like there was a Symfony Forms widget for it so I whipped one up. You can grab it <a href='http://shout.setfive.com/wp-content/uploads/2009/04/sfwidgetjquerytimepickrphp.txt'>here</a>.</p>
<p>The only issue with timepickr is that it introduces a ton of dependencies. It requires jQuery, jQuery-ui, jQuery.utils, jQuery.string, and ui.dropslide. Additionally, it needs the dropslide css as well as the timepickr css.</p>
<p>The form widget assumes that you will include jquery-ui by yourself since everyone usually has different naming conventions. It will include the other JS files and CSS files for you.</p>
<p>You can download a package with all of the JS and CSS you need <a href='http://shout.setfive.com/wp-content/uploads/2009/04/timepickr_js_ad_css.zip'>here</a>. Again this DOES NOT include the jQuery-ui stuff. YOU have to include that yourself in your Symfony project as well as on the page that you deploy this widget.</p>
<p>To use it, just drop it in your Symfony project somewhere where classes get autoloaded (projectdir/lib works) and then instantiate a widget with new sfWidgetjQueryTimepickr() . It currently will support all of the timepickr options passed in as widget options (on the constructor). Full documentation for timepickr is <a target="_new" href="http://code.google.com/p/jquery-utils/wiki/UiTimepickr">here</a>.</p>
<p>Have fun picking time. </p>
]]></content:encoded>
			<wfw:commentRss>http://shout.setfive.com/2009/04/06/sfwidgetjquerytimepickr-symfony-timepickr-widget/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
