<?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>Phillip Napieralski &#187; PHP</title>
	<atom:link href="http://blog.pnapieralski.com/tag/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.pnapieralski.com</link>
	<description>Programmer, Engineer, Researcher.</description>
	<lastBuildDate>Tue, 20 Dec 2011 16:41:18 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>How to Setup MongoDB PHP Extension on Shared Hosting</title>
		<link>http://blog.pnapieralski.com/mongodb/how-to-setup-mongodb-php-extension-on-shared-hosting/</link>
		<comments>http://blog.pnapieralski.com/mongodb/how-to-setup-mongodb-php-extension-on-shared-hosting/#comments</comments>
		<pubDate>Wed, 07 Jul 2010 21:38:04 +0000</pubDate>
		<dc:creator>Phillip Napieralski</dc:creator>
				<category><![CDATA[MongoDB]]></category>
		<category><![CDATA[Shared hosting]]></category>
		<category><![CDATA[Dreamhost]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[PHP Extensions]]></category>

		<guid isPermaLink="false">http://blog.pnapieralski.com/?p=57</guid>
		<description><![CDATA[Want to use MongoDB but don't want to switch to a more expensive hosting plan? This is a great alternative that I got working on Dreamhost in less than an hour!]]></description>
			<content:encoded><![CDATA[<p>Want to use MongoDB but don&#8217;t want to switch to a more expensive hosting plan? This is a great alternative that I got working on Dreamhost in less than an hour!</p>
<h2>Setup your external MongoDB</h2>
<p>I use <a href="https://mongohq.com/home">MongoHQ</a> to host my database (your first 16MB database is free). Make sure to take note of your connection string for later.</p>
<h2>Custom PHP.ini</h2>
<p>This part is somewhat tricky. Luckily, if you are using dreamhost, it is well documented on <a href="http://wiki.dreamhost.com/index.php/PHP.ini#Custom_php.ini_for_a_Single_domain">their wiki</a>. Thus, I won&#8217;t go into detail of that here. Follow the directions and proceed to the next step (or leave a comment asking for help if you have issues).</p>
<p>After setting up your custom ini file for your domain, add the following lines to the very end of your php.ini:</p>
<pre class="brush: php; title: ; notranslate">
extension_dir = &quot;/home/YOUR_USERNAME/bin&quot;
extension = mongo.so
</pre>
<p><strong>NOTE:</strong> This step loads the MongoDB extension but, we don&#8217;t have it yet! The next steps will fix that.</p>
<h2>Compile MongoDB: Part 1</h2>
<p>Using SSH, cd into your home folder (/home/YOUR_USERNAME) and type the following:</p>
<pre class="brush: bash; title: ; notranslate">
mkdir bin
cd bin/
wget http://download.github.com/mongodb-mongo-php-driver-1.0.6-0-gd261d7a.tar.gz
tar zxvf mongodb-mongo-php-driver-1.0.6-0-gd261d7a.tar.gz
cd mongodb-mongo-php-driver-gd261d7a/
phpize
</pre>
<p>If you receive the error <em>Cannot find autoconf</em> after running the command <em>phpize</em>, follow the next section. Otherwise, skip it!</p>
<h2>Compile/install autoconf</h2>
<pre class="brush: bash; title: ; notranslate">
wget http://ftp.gnu.org/gnu/autoconf/autoconf-2.66.tar.gz
tar -zvxf autoconf-2.66.tar.gz
cd autoconf-2.66/
./configure &quot;--prefix=$HOME&quot;
make
make install
</pre>
<p>The <em>configure</em> line will tell <em>make install</em> to put the library (.so) file into our home/bin directory (eg, /home/YOUR_USERNAME/bin). Quickly check that you have a few autoconf folders in your bin directory and continue on.</p>
<p><strong>IMPORTANT:</strong> You must now tell linux to look for libraries in your home/bin directory. To do this, you must change the PATH as follows:</p>
<pre class="brush: bash; title: ; notranslate">
EXPORT PATH=$HOME/bin:$PATH
</pre>
<h2>Compile MongoDB: Part 2</h2>
<p>Remember that <em>phpize</em> function? Yea, try it again:</p>
<pre class="brush: bash; title: ; notranslate">
cd $HOME/bin/mongodb-mongo-php-driver-gd261d7a/
phpize
</pre>
<p>This time, you should not receive an autoconf error. Now, we actually compile the extension.</p>
<pre class="brush: bash; title: ; notranslate">
./configure &quot;--prefix=$HOME&quot;
make
</pre>
<p>And, for some reason, the <em>make install</em> commands ignores our prefix&#8230; so we can just manually copy the needed (.so) file to our bin folder:</p>
<pre class="brush: bash; title: ; notranslate">
cp modules/mongo.so $HOME/bin/
</pre>
<p>Now double check that Mongo.so exists in your home/bin directory (eg, /home/YOUR_USERNAME/bin/mongo.so)</p>
<h2>Test it</h2>
<p>Now, here&#8217;s a simple script to test if you can insert something into your external Mongo database.</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php
   $m = new Mongo(&quot;mongodb://YOUR_USERNAME:YOUR_PASSWORD@YOUR_SERVER:27046/YOUR_DATABASE&quot;);
   $m-&gt;connect();
   $db = $m-&gt;YOUR_DATABASE
   $collection = $db-&gt;YOUR_COLLECTION;

   $collection-&gt;insert(array('name' =&gt; 'super test 5000'));
</pre>
<p>There! You should have just inserted a new record into your database collection. Test by changing the insert line to the following:</p>
<pre class="brush: php; title: ; notranslate">
$cursor = $collection-&gt;find();

echo $cursor-&gt;count() . ' documents found. &lt;br/&gt;';
foreach ($cursor as $obj) {
   var_dump($obj);
   echo '&lt;br/&gt;';
}
</pre>
<p>Now when you run that last script, you should see at least the one record you JUST added! </p>
<h2>Conclusion</h2>
<p>This is the approach I am currently using for one of my smaller pet projects. I&#8217;m going to be doing a lot of testing on my local machine using XAMPP, then going live with it using Dreamhost. It is also unfortunate that I&#8217;m forced to use an external DB. But, considering the first 16MB of database from MongoHQ is free, I&#8217;m totally satisfied with this for now.</p>


<div class="shr-bookmarks shr-bookmarks-expand shr-bookmarks-center">
<ul class="socials">
		<li class="shr-twitter">
			<a href="http://www.shareaholic.com/api/share/?title=How+to+Setup+MongoDB+PHP+Extension+on+Shared+Hosting&amp;link=http://blog.pnapieralski.com/mongodb/how-to-setup-mongodb-php-extension-on-shared-hosting/&amp;notes=Want%20to%20use%20MongoDB%20but%20don%27t%20want%20to%20switch%20to%20a%20more%20expensive%20hosting%20plan%3F%20This%20is%20a%20great%20alternative%20that%20I%20got%20working%20on%20Dreamhost%20in%20less%20than%20an%20hour%21&amp;short_link=&amp;shortener=google&amp;shortener_key=&amp;v=1&amp;apitype=1&amp;apikey=8afa39428933be41f8afdb8ea21a495c&amp;source=Shareaholic&amp;template=%2524%257Btitle%257D%2B-%2B%2524%257Bshort_link%257D&amp;service=7&amp;tags=&amp;ctype=" rel="nofollow" class="external" title="Tweet This!">Tweet This!</a>
		</li>
		<li class="shr-digg">
			<a href="http://www.shareaholic.com/api/share/?title=How+to+Setup+MongoDB+PHP+Extension+on+Shared+Hosting&amp;link=http://blog.pnapieralski.com/mongodb/how-to-setup-mongodb-php-extension-on-shared-hosting/&amp;notes=Want%20to%20use%20MongoDB%20but%20don%27t%20want%20to%20switch%20to%20a%20more%20expensive%20hosting%20plan%3F%20This%20is%20a%20great%20alternative%20that%20I%20got%20working%20on%20Dreamhost%20in%20less%20than%20an%20hour%21&amp;short_link=&amp;shortener=google&amp;shortener_key=&amp;v=1&amp;apitype=1&amp;apikey=8afa39428933be41f8afdb8ea21a495c&amp;source=Shareaholic&amp;template=&amp;service=3&amp;tags=&amp;ctype=" rel="nofollow" class="external" title="Digg this!">Digg this!</a>
		</li>
		<li class="shr-reddit">
			<a href="http://www.shareaholic.com/api/share/?title=How+to+Setup+MongoDB+PHP+Extension+on+Shared+Hosting&amp;link=http://blog.pnapieralski.com/mongodb/how-to-setup-mongodb-php-extension-on-shared-hosting/&amp;notes=Want%20to%20use%20MongoDB%20but%20don%27t%20want%20to%20switch%20to%20a%20more%20expensive%20hosting%20plan%3F%20This%20is%20a%20great%20alternative%20that%20I%20got%20working%20on%20Dreamhost%20in%20less%20than%20an%20hour%21&amp;short_link=&amp;shortener=google&amp;shortener_key=&amp;v=1&amp;apitype=1&amp;apikey=8afa39428933be41f8afdb8ea21a495c&amp;source=Shareaholic&amp;template=&amp;service=40&amp;tags=&amp;ctype=" rel="nofollow" class="external" title="Share this on Reddit">Share this on Reddit</a>
		</li>
		<li class="shr-technorati">
			<a href="http://www.shareaholic.com/api/share/?title=How+to+Setup+MongoDB+PHP+Extension+on+Shared+Hosting&amp;link=http://blog.pnapieralski.com/mongodb/how-to-setup-mongodb-php-extension-on-shared-hosting/&amp;notes=Want%20to%20use%20MongoDB%20but%20don%27t%20want%20to%20switch%20to%20a%20more%20expensive%20hosting%20plan%3F%20This%20is%20a%20great%20alternative%20that%20I%20got%20working%20on%20Dreamhost%20in%20less%20than%20an%20hour%21&amp;short_link=&amp;shortener=google&amp;shortener_key=&amp;v=1&amp;apitype=1&amp;apikey=8afa39428933be41f8afdb8ea21a495c&amp;source=Shareaholic&amp;template=&amp;service=10&amp;tags=&amp;ctype=" rel="nofollow" class="external" title="Share this on Technorati">Share this on Technorati</a>
		</li>
		<li class="shr-facebook">
			<a href="http://www.shareaholic.com/api/share/?title=How+to+Setup+MongoDB+PHP+Extension+on+Shared+Hosting&amp;link=http://blog.pnapieralski.com/mongodb/how-to-setup-mongodb-php-extension-on-shared-hosting/&amp;notes=Want%20to%20use%20MongoDB%20but%20don%27t%20want%20to%20switch%20to%20a%20more%20expensive%20hosting%20plan%3F%20This%20is%20a%20great%20alternative%20that%20I%20got%20working%20on%20Dreamhost%20in%20less%20than%20an%20hour%21&amp;short_link=&amp;shortener=google&amp;shortener_key=&amp;v=1&amp;apitype=1&amp;apikey=8afa39428933be41f8afdb8ea21a495c&amp;source=Shareaholic&amp;template=&amp;service=5&amp;tags=&amp;ctype=" rel="nofollow" title="Share this on Facebook">Share this on Facebook</a>
		</li>
		<li class="shr-stumbleupon">
			<a href="http://www.shareaholic.com/api/share/?title=How+to+Setup+MongoDB+PHP+Extension+on+Shared+Hosting&amp;link=http://blog.pnapieralski.com/mongodb/how-to-setup-mongodb-php-extension-on-shared-hosting/&amp;notes=Want%20to%20use%20MongoDB%20but%20don%27t%20want%20to%20switch%20to%20a%20more%20expensive%20hosting%20plan%3F%20This%20is%20a%20great%20alternative%20that%20I%20got%20working%20on%20Dreamhost%20in%20less%20than%20an%20hour%21&amp;short_link=&amp;shortener=google&amp;shortener_key=&amp;v=1&amp;apitype=1&amp;apikey=8afa39428933be41f8afdb8ea21a495c&amp;source=Shareaholic&amp;template=&amp;service=38&amp;tags=&amp;ctype=" rel="nofollow" class="external" title="Stumble upon something good? Share it on StumbleUpon">Stumble upon something good? Share it on StumbleUpon</a>
		</li>
</ul><div style="clear: both;"></div><div class="shr-getshr" style="visibility:hidden;font-size:10px !important"><a target="_blank" href="http://www.shareaholic.com/?src=pub">Get Shareaholic</a></div><div style="clear: both;"></div></div>

]]></content:encoded>
			<wfw:commentRss>http://blog.pnapieralski.com/mongodb/how-to-setup-mongodb-php-extension-on-shared-hosting/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>User Account Class in PHP 2</title>
		<link>http://blog.pnapieralski.com/php/user-account-class-in-php-2/</link>
		<comments>http://blog.pnapieralski.com/php/user-account-class-in-php-2/#comments</comments>
		<pubDate>Wed, 10 Feb 2010 16:10:00 +0000</pubDate>
		<dc:creator>Phillip Napieralski</dc:creator>
				<category><![CDATA[mysqli]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Happy Polack]]></category>

		<guid isPermaLink="false">http://blog.pnapieralski.com/?p=18</guid>
		<description><![CDATA[I started up an account class in my previous post, but I left out a way for the user to authenticate! Let's fix that...]]></description>
			<content:encoded><![CDATA[<p>I started up an account class in my previous post, but I left out a way for the user to authenticate! Let&#8217;s fix that&#8230;</p>
<h2>Authenticate</h2>
<pre class="brush: php; title: ; notranslate">
	public function authenticate($group_id = 0) {
		$dbconn = @Database::grab();

		// They must have ALL three cookies set from the login function, otherwise something went wrong!
		if( !isset($_COOKIE['id']) &amp;&amp; !isset($_COOKIE['cookie']) &amp;&amp; !isset($_COOKIE['name']) )
		{
			return false;
		}

		// Sanitize
		$id = safe($dbconn, $_COOKIE['id']);
		$cookie = safe($dbconn, $_COOKIE['cookie']);
		$username = safe($dbconn, $_COOKIE['name']);

		// Make sure they have a valid cookie value first! (64 characters long in our case)
		if( strlen($cookie) &gt; 63 )
		{
			// Check the values in the DB with a quick query
			$query = &quot;SELECT id, username, cookie, group_id FROM users WHERE
					id = &quot;.$id.&quot; AND
					cookie = '&quot;.$cookie.&quot;' AND username = '&quot;.$username.&quot;' AND group_id &gt;= $group_id LIMIT 1&quot;;
			$queryData = $dbconn-&gt;query($query);
		}
		if( $queryData )
		{
			if( $queryData-&gt;num_rows &gt; 0) {
				$data = $queryData-&gt;fetch_object();
				$this-&gt;group_id = $data-&gt;group_id;
				$this-&gt;user_id = $data-&gt;id;
				$this-&gt;username = $data-&gt;username;
				return true;
			}
		}

		// They failed to authenticate! Wrong username/pass?
		$this-&gt;logout();
		return false;
	}
</pre>
<p>There you have it. Basically, check to make sure they have all the cookies you set in your login function. If any are missing, fail. Then, we write a query to check the credentials from the cookies to see if they match what&#8217;s in the database. If not, clean up their cookies with $this->logout() and return false. That reminds me, here&#8217;s the code for logout:</p>
<h2>Logout</h2>
<pre class="brush: php; title: ; notranslate">
	public function logout() {
		$dbconn = @Database::grab();

		if(isset($_COOKIE[&quot;id&quot;]) &amp;&amp; isset($_COOKIE[&quot;cookie&quot;]))
		{
			$id = safe($dbconn, $_COOKIE['id']);
			$cookie = safe($dbconn, $_COOKIE['cookie']);

			// Set the cookie to null in the database
			$query = &quot;UPDATE users SET cookie = 0 WHERE id = &quot;.$id.&quot; AND cookie = '&quot;.$cookie.&quot;'&quot;;
			$dbconn-&gt;query($query);
		}
		// Expire our cookies by setting the time to 1 second after the EPOCH
		setcookie(&quot;hpname&quot;, &quot;&quot;, 1, &quot;/&quot; );
		setcookie(&quot;hpid&quot;, &quot;&quot;, 1,&quot;/&quot; );
		setcookie(&quot;hpcookie&quot;, &quot;&quot;, 1,&quot;/&quot; );

		// Unset them immediately
		unset($_COOKIE['hpname']);
		unset($_COOKIE['hpid']);
		unset($_COOKIE['hpcookie']);
	}
</pre>
<p>There you go. What&#8217;s missing now? We just need a forgot password function and we&#8217;re good to go.</p>
<p>Lost on this tutorial? Try going back to <a href="http://blog.pnapieralski.com/php/user-account-class-in-php-1/">part 1</a></p>


<div class="shr-bookmarks shr-bookmarks-expand shr-bookmarks-center">
<ul class="socials">
		<li class="shr-twitter">
			<a href="http://www.shareaholic.com/api/share/?title=User+Account+Class+in+PHP+2&amp;link=http://blog.pnapieralski.com/php/user-account-class-in-php-2/&amp;notes=I%20started%20up%20an%20account%20class%20in%20my%20previous%20post%2C%20but%20I%20left%20out%20a%20way%20for%20the%20user%20to%20authenticate%21%20Let%27s%20fix%20that...&amp;short_link=&amp;shortener=google&amp;shortener_key=&amp;v=1&amp;apitype=1&amp;apikey=8afa39428933be41f8afdb8ea21a495c&amp;source=Shareaholic&amp;template=%2524%257Btitle%257D%2B-%2B%2524%257Bshort_link%257D&amp;service=7&amp;tags=&amp;ctype=" rel="nofollow" class="external" title="Tweet This!">Tweet This!</a>
		</li>
		<li class="shr-digg">
			<a href="http://www.shareaholic.com/api/share/?title=User+Account+Class+in+PHP+2&amp;link=http://blog.pnapieralski.com/php/user-account-class-in-php-2/&amp;notes=I%20started%20up%20an%20account%20class%20in%20my%20previous%20post%2C%20but%20I%20left%20out%20a%20way%20for%20the%20user%20to%20authenticate%21%20Let%27s%20fix%20that...&amp;short_link=&amp;shortener=google&amp;shortener_key=&amp;v=1&amp;apitype=1&amp;apikey=8afa39428933be41f8afdb8ea21a495c&amp;source=Shareaholic&amp;template=&amp;service=3&amp;tags=&amp;ctype=" rel="nofollow" class="external" title="Digg this!">Digg this!</a>
		</li>
		<li class="shr-reddit">
			<a href="http://www.shareaholic.com/api/share/?title=User+Account+Class+in+PHP+2&amp;link=http://blog.pnapieralski.com/php/user-account-class-in-php-2/&amp;notes=I%20started%20up%20an%20account%20class%20in%20my%20previous%20post%2C%20but%20I%20left%20out%20a%20way%20for%20the%20user%20to%20authenticate%21%20Let%27s%20fix%20that...&amp;short_link=&amp;shortener=google&amp;shortener_key=&amp;v=1&amp;apitype=1&amp;apikey=8afa39428933be41f8afdb8ea21a495c&amp;source=Shareaholic&amp;template=&amp;service=40&amp;tags=&amp;ctype=" rel="nofollow" class="external" title="Share this on Reddit">Share this on Reddit</a>
		</li>
		<li class="shr-technorati">
			<a href="http://www.shareaholic.com/api/share/?title=User+Account+Class+in+PHP+2&amp;link=http://blog.pnapieralski.com/php/user-account-class-in-php-2/&amp;notes=I%20started%20up%20an%20account%20class%20in%20my%20previous%20post%2C%20but%20I%20left%20out%20a%20way%20for%20the%20user%20to%20authenticate%21%20Let%27s%20fix%20that...&amp;short_link=&amp;shortener=google&amp;shortener_key=&amp;v=1&amp;apitype=1&amp;apikey=8afa39428933be41f8afdb8ea21a495c&amp;source=Shareaholic&amp;template=&amp;service=10&amp;tags=&amp;ctype=" rel="nofollow" class="external" title="Share this on Technorati">Share this on Technorati</a>
		</li>
		<li class="shr-facebook">
			<a href="http://www.shareaholic.com/api/share/?title=User+Account+Class+in+PHP+2&amp;link=http://blog.pnapieralski.com/php/user-account-class-in-php-2/&amp;notes=I%20started%20up%20an%20account%20class%20in%20my%20previous%20post%2C%20but%20I%20left%20out%20a%20way%20for%20the%20user%20to%20authenticate%21%20Let%27s%20fix%20that...&amp;short_link=&amp;shortener=google&amp;shortener_key=&amp;v=1&amp;apitype=1&amp;apikey=8afa39428933be41f8afdb8ea21a495c&amp;source=Shareaholic&amp;template=&amp;service=5&amp;tags=&amp;ctype=" rel="nofollow" title="Share this on Facebook">Share this on Facebook</a>
		</li>
		<li class="shr-stumbleupon">
			<a href="http://www.shareaholic.com/api/share/?title=User+Account+Class+in+PHP+2&amp;link=http://blog.pnapieralski.com/php/user-account-class-in-php-2/&amp;notes=I%20started%20up%20an%20account%20class%20in%20my%20previous%20post%2C%20but%20I%20left%20out%20a%20way%20for%20the%20user%20to%20authenticate%21%20Let%27s%20fix%20that...&amp;short_link=&amp;shortener=google&amp;shortener_key=&amp;v=1&amp;apitype=1&amp;apikey=8afa39428933be41f8afdb8ea21a495c&amp;source=Shareaholic&amp;template=&amp;service=38&amp;tags=&amp;ctype=" rel="nofollow" class="external" title="Stumble upon something good? Share it on StumbleUpon">Stumble upon something good? Share it on StumbleUpon</a>
		</li>
</ul><div style="clear: both;"></div><div class="shr-getshr" style="visibility:hidden;font-size:10px !important"><a target="_blank" href="http://www.shareaholic.com/?src=pub">Get Shareaholic</a></div><div style="clear: both;"></div></div>

]]></content:encoded>
			<wfw:commentRss>http://blog.pnapieralski.com/php/user-account-class-in-php-2/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>User Account Class in PHP 1</title>
		<link>http://blog.pnapieralski.com/php/user-account-class-in-php-1/</link>
		<comments>http://blog.pnapieralski.com/php/user-account-class-in-php-1/#comments</comments>
		<pubDate>Wed, 03 Feb 2010 07:29:48 +0000</pubDate>
		<dc:creator>Phillip Napieralski</dc:creator>
				<category><![CDATA[mysqli]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Happy Polack]]></category>

		<guid isPermaLink="false">http://blog.pnapieralski.com/?p=14</guid>
		<description><![CDATA[I'm going to describe the class I created to handle signup/login/authentication at happypolack.com.

If you'd like a demo, <a title="Happy Polack" href="http://happypolack.com">create an account at Happy Polack :)</a>.

The features in this class are:
<ol>
<li>Signing up with confirmation e-mail</li>
<li>Logging in/out</li>
<li>Authenticate/differentiate regular user and administrators</li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m going to describe the class I created to handle signup/login/authentication at happypolack.com.</p>
<p>If you&#8217;d like a demo, <a title="Happy Polack" href="http://happypolack.com">create an account at Happy Polack <img src='http://blog.pnapieralski.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </a>.</p>
<h2>The Database Structure</h2>
<p>First, what is it going to look like in the database? Well, here&#8217;s what I used:</p>
<div id="attachment_15" class="wp-caption alignnone" style="width: 365px"><a href="http://blog.pnapieralski.com/wp-content/uploads/2010/02/usergroup.png" rel="shadowbox[sbpost-14];player=img;"><img class="size-full wp-image-15" title="usergroup" src="http://blog.pnapieralski.com/wp-content/uploads/2010/02/usergroup.png" alt="" width="355" height="260" /></a><p class="wp-caption-text">Generated using MySQL Workbench</p></div>
<p>Take note of the indexes used. I have a foreign key relating the users and the groups table (1-1 for now). I also have a unique index on the username to prevent the same username. Lastly, I have a regular index on the email address to make searching that field faster (useful if they forgot their password).</p>
<p>The other thing to note is that both <em>password</em> and <em>cookie</em> have a datatype of CHAR(64). This is because I encrypted the password using a SHA256 algorithm, which is WAY stronger than md5, before placing it in the database (this is PHPs <em>hash(&#8220;sha256&#8243;,$unenc_password)</em> function). For the cookie field, I use that algorithm on the uniq_id() function built into PHP. I&#8217;ll get to that in a minute.</p>
<h2>The Class Structure</h2>
<pre class="brush: php; title: ; notranslate">
class AccountController {
        // Initialize variables to something arbitrary
	private $group_id = -1;
	private $user_id = -1;
	private $username = '';

	public function signup($username, $password, $email){...}
	public function login($username, $password){...}
	public function logout(){...}
	public function authenticate($group_id = 0){...}
	public function is_logged_in(){...}
	public function is_admin(){...}
}
</pre>
<p>Excellent! We got the basic functionality out of the way. We are able to signup/login/logout/authenticate. We can even pass a group_id to authenticate to make sure they are part of a specific group.</p>
<h3>Signup</h3>
<pre class="brush: php; title: ; notranslate">
public function signup($username, $password, $email) {
	$dbconn = @Database::grab(); // This WILL be different for you. I use a simple MySQLi wrapper.

	$origpassword =  $password; // store original password to send to them
	$password = hash('sha256', $password);
	if(!$dbconn-&gt;query($query))
		return false;
	else
	{
		// Send a nice email
		$message = '&lt;b&gt;Account Information:&lt;/b&gt;';
		$message .= '&lt;p&gt;Username: '.$username;
		$message .= '&lt;/p&gt;&lt;p&gt;Password: '.$origpassword;
		$message .= '&lt;/p&gt;&lt;p&gt;Your profile: http://happypolack.com/user/'.$username.'&lt;/p&gt;;

		send_mail( $email, &quot;Welcome to Happy Polack!&quot;, &quot;Hello and Welcome to Happy Polack!&quot;, $message );
	}
	return true;
}
</pre>
<p>There you have it! Now we can signup, well&#8230; except for the send_mail piece, let me give you the code for that:</p>
<pre class="brush: php; title: ; notranslate">
function send_mail($to, $subject, $title, $msg)
{
	$headers = 'From: Happy Polack &lt;you@example.com&gt;'. &quot;\r\n&quot;.
			'Reply-To: you@example.com' . &quot;\r\n&quot; .
			'X-Mailer: PHP/' .phpversion(). &quot;\r\n&quot;;

	$headers .= 'MIME-Version: 1.0' . &quot;\r\n&quot;;
	$headers .= 'Content-type: text/html; charset=iso-8859-1' . &quot;\r\n&quot;;

	$message =  '&lt;h1&gt;'. $title.'&lt;/h1&gt;';
	$message .= $msg;

	mail( $to, $subject, $message, $headers);
}
</pre>
<p>Basically, this nifty function automatically sets up the headers so we can use HTML in our e-mails and it automatically formats various features (this implementation could be spruced up with some neat css too).</p>
<h3>Login</h3>
<pre class="brush: php; title: ; notranslate">
public function login($username, $password) {
	$dbconn = @Database::grab();

	$epassword = hash(&quot;sha256&quot;,$password); // Encrypt using SHA256. We could also &quot;salt&quot; the password before hashing for added security.

	$query = &quot;SELECT id, group_id FROM users WHERE username = '$username' AND password = '$epassword' LIMIT 1&quot;;
	$qData = $dbconn-&gt;query($query) ;
	if( $qData-&gt;num_rows &gt; 0 )
	{
		$userData = $qData-&gt;fetch_array();
		$cookie = generate_token();
		$userID = $userData['id'];

		$query = &quot;UPDATE users SET cookie = '$cookie' WHERE username = '$username' AND password = '$epassword'&quot;;

		if($dbconn-&gt;query($Query))
		{
			$this-&gt;user_id = $userID;
			$this-&gt;group_id = $userData['group_id'];
			$expire_time = 60*60*24*7+time(); // About one week
			// When we create the cookies, we pass the cookie's name, the value, the expire time and what piece of the site the cookie is valid on. I specify &quot;/&quot; to allow it to be usable throughout the whole website.
			setcookie(&quot;id&quot;, $userID, $expire_time, &quot;/&quot;);
			setcookie(&quot;cookie&quot;, $cookie, $expire_time, &quot;/&quot;);
			setcookie(&quot;username&quot;, $username, $expire_time, &quot;/&quot;);

			// This piece is so that the COOKIE values are set immediately. When I left this piece out, I noticed it would take an extra page load for the cookies to register. This is because the cookies are generally sent with everyday headers and *it seems* that they are not processed right away.
			$_COOKIE['id'] = $userID;
			$_COOKIE['cookie'] = $cookie;
			$_COOKIE['username'] = $username;

			return true; // SUCCESS, now logged in!
		}
	}
	return false; // Bummer!
}
</pre>
<p>What&#8217;s happening here? Well, let&#8217;s get a pretty picture to clarify the order a little bit:</p>
<div id="attachment_16" class="wp-caption alignnone" style="width: 192px"><a href="http://blog.pnapieralski.com/wp-content/uploads/2010/02/74dc5b69.png" rel="shadowbox[sbpost-14];player=img;"><img class="size-full wp-image-16   " title="74dc5b69" src="http://blog.pnapieralski.com/wp-content/uploads/2010/02/74dc5b69.png" alt="" width="182" height="358" /></a><p class="wp-caption-text">Generated with yUML - Does this help?</p></div>
<p>In easier terms: Check if the user is in the database -> if he is, put a random value into his <em>cookie</em> field for later authentication and set his cookies.</p>
<p>That reminds me, here is one last function, <em>generate_token()</em>, that is pretty essential, and simple, to get a random string of length 64.</p>
<pre class="brush: php; title: ; notranslate">
// Return a random string of length 64
function generate_token() {
	return hash('sha256', uniqid(mt_rand(), true));
}
</pre>
<h2>Next Time</h2>
<p>Wow! Progress has been made. But there&#8217;s more to be had. We still need an authenticate function as well as a way to logout!</p>
<p>Phew.</p>


<div class="shr-bookmarks shr-bookmarks-expand shr-bookmarks-center">
<ul class="socials">
		<li class="shr-twitter">
			<a href="http://www.shareaholic.com/api/share/?title=User+Account+Class+in+PHP+1&amp;link=http://blog.pnapieralski.com/php/user-account-class-in-php-1/&amp;notes=I%27m%20going%20to%20describe%20the%20class%20I%20created%20to%20handle%20signup%2Flogin%2Fauthentication%20at%20happypolack.com.%0D%0A%0D%0AIf%20you%27d%20like%20a%20demo%2C%20create%20an%20account%20at%20Happy%20Polack%20%3A%29.%0D%0A%0D%0AThe%20features%20in%20this%20class%20are%3A%0D%0A%0D%0ASigning%20up%20with%20confirmation%20e-mail%0D%0ALogging%20in%2Fout%0D%0AAuthenticate%2Fdifferentiate%20regular%20user%20and%20administrators%0D%0A&amp;short_link=&amp;shortener=google&amp;shortener_key=&amp;v=1&amp;apitype=1&amp;apikey=8afa39428933be41f8afdb8ea21a495c&amp;source=Shareaholic&amp;template=%2524%257Btitle%257D%2B-%2B%2524%257Bshort_link%257D&amp;service=7&amp;tags=&amp;ctype=" rel="nofollow" class="external" title="Tweet This!">Tweet This!</a>
		</li>
		<li class="shr-digg">
			<a href="http://www.shareaholic.com/api/share/?title=User+Account+Class+in+PHP+1&amp;link=http://blog.pnapieralski.com/php/user-account-class-in-php-1/&amp;notes=I%27m%20going%20to%20describe%20the%20class%20I%20created%20to%20handle%20signup%2Flogin%2Fauthentication%20at%20happypolack.com.%0D%0A%0D%0AIf%20you%27d%20like%20a%20demo%2C%20create%20an%20account%20at%20Happy%20Polack%20%3A%29.%0D%0A%0D%0AThe%20features%20in%20this%20class%20are%3A%0D%0A%0D%0ASigning%20up%20with%20confirmation%20e-mail%0D%0ALogging%20in%2Fout%0D%0AAuthenticate%2Fdifferentiate%20regular%20user%20and%20administrators%0D%0A&amp;short_link=&amp;shortener=google&amp;shortener_key=&amp;v=1&amp;apitype=1&amp;apikey=8afa39428933be41f8afdb8ea21a495c&amp;source=Shareaholic&amp;template=&amp;service=3&amp;tags=&amp;ctype=" rel="nofollow" class="external" title="Digg this!">Digg this!</a>
		</li>
		<li class="shr-reddit">
			<a href="http://www.shareaholic.com/api/share/?title=User+Account+Class+in+PHP+1&amp;link=http://blog.pnapieralski.com/php/user-account-class-in-php-1/&amp;notes=I%27m%20going%20to%20describe%20the%20class%20I%20created%20to%20handle%20signup%2Flogin%2Fauthentication%20at%20happypolack.com.%0D%0A%0D%0AIf%20you%27d%20like%20a%20demo%2C%20create%20an%20account%20at%20Happy%20Polack%20%3A%29.%0D%0A%0D%0AThe%20features%20in%20this%20class%20are%3A%0D%0A%0D%0ASigning%20up%20with%20confirmation%20e-mail%0D%0ALogging%20in%2Fout%0D%0AAuthenticate%2Fdifferentiate%20regular%20user%20and%20administrators%0D%0A&amp;short_link=&amp;shortener=google&amp;shortener_key=&amp;v=1&amp;apitype=1&amp;apikey=8afa39428933be41f8afdb8ea21a495c&amp;source=Shareaholic&amp;template=&amp;service=40&amp;tags=&amp;ctype=" rel="nofollow" class="external" title="Share this on Reddit">Share this on Reddit</a>
		</li>
		<li class="shr-technorati">
			<a href="http://www.shareaholic.com/api/share/?title=User+Account+Class+in+PHP+1&amp;link=http://blog.pnapieralski.com/php/user-account-class-in-php-1/&amp;notes=I%27m%20going%20to%20describe%20the%20class%20I%20created%20to%20handle%20signup%2Flogin%2Fauthentication%20at%20happypolack.com.%0D%0A%0D%0AIf%20you%27d%20like%20a%20demo%2C%20create%20an%20account%20at%20Happy%20Polack%20%3A%29.%0D%0A%0D%0AThe%20features%20in%20this%20class%20are%3A%0D%0A%0D%0ASigning%20up%20with%20confirmation%20e-mail%0D%0ALogging%20in%2Fout%0D%0AAuthenticate%2Fdifferentiate%20regular%20user%20and%20administrators%0D%0A&amp;short_link=&amp;shortener=google&amp;shortener_key=&amp;v=1&amp;apitype=1&amp;apikey=8afa39428933be41f8afdb8ea21a495c&amp;source=Shareaholic&amp;template=&amp;service=10&amp;tags=&amp;ctype=" rel="nofollow" class="external" title="Share this on Technorati">Share this on Technorati</a>
		</li>
		<li class="shr-facebook">
			<a href="http://www.shareaholic.com/api/share/?title=User+Account+Class+in+PHP+1&amp;link=http://blog.pnapieralski.com/php/user-account-class-in-php-1/&amp;notes=I%27m%20going%20to%20describe%20the%20class%20I%20created%20to%20handle%20signup%2Flogin%2Fauthentication%20at%20happypolack.com.%0D%0A%0D%0AIf%20you%27d%20like%20a%20demo%2C%20create%20an%20account%20at%20Happy%20Polack%20%3A%29.%0D%0A%0D%0AThe%20features%20in%20this%20class%20are%3A%0D%0A%0D%0ASigning%20up%20with%20confirmation%20e-mail%0D%0ALogging%20in%2Fout%0D%0AAuthenticate%2Fdifferentiate%20regular%20user%20and%20administrators%0D%0A&amp;short_link=&amp;shortener=google&amp;shortener_key=&amp;v=1&amp;apitype=1&amp;apikey=8afa39428933be41f8afdb8ea21a495c&amp;source=Shareaholic&amp;template=&amp;service=5&amp;tags=&amp;ctype=" rel="nofollow" title="Share this on Facebook">Share this on Facebook</a>
		</li>
		<li class="shr-stumbleupon">
			<a href="http://www.shareaholic.com/api/share/?title=User+Account+Class+in+PHP+1&amp;link=http://blog.pnapieralski.com/php/user-account-class-in-php-1/&amp;notes=I%27m%20going%20to%20describe%20the%20class%20I%20created%20to%20handle%20signup%2Flogin%2Fauthentication%20at%20happypolack.com.%0D%0A%0D%0AIf%20you%27d%20like%20a%20demo%2C%20create%20an%20account%20at%20Happy%20Polack%20%3A%29.%0D%0A%0D%0AThe%20features%20in%20this%20class%20are%3A%0D%0A%0D%0ASigning%20up%20with%20confirmation%20e-mail%0D%0ALogging%20in%2Fout%0D%0AAuthenticate%2Fdifferentiate%20regular%20user%20and%20administrators%0D%0A&amp;short_link=&amp;shortener=google&amp;shortener_key=&amp;v=1&amp;apitype=1&amp;apikey=8afa39428933be41f8afdb8ea21a495c&amp;source=Shareaholic&amp;template=&amp;service=38&amp;tags=&amp;ctype=" rel="nofollow" class="external" title="Stumble upon something good? Share it on StumbleUpon">Stumble upon something good? Share it on StumbleUpon</a>
		</li>
</ul><div style="clear: both;"></div><div class="shr-getshr" style="visibility:hidden;font-size:10px !important"><a target="_blank" href="http://www.shareaholic.com/?src=pub">Get Shareaholic</a></div><div style="clear: both;"></div></div>

]]></content:encoded>
			<wfw:commentRss>http://blog.pnapieralski.com/php/user-account-class-in-php-1/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Inline AJAX Editing</title>
		<link>http://blog.pnapieralski.com/ajax/inline-ajax-editing/</link>
		<comments>http://blog.pnapieralski.com/ajax/inline-ajax-editing/#comments</comments>
		<pubDate>Sat, 23 Jan 2010 16:26:21 +0000</pubDate>
		<dc:creator>Phillip Napieralski</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[Happy Polack]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://blog.pnapieralski.com/uncategorized/6/</guid>
		<description><![CDATA[Happypolack.com is a joke site I created as a side project a little bit ago and it's continually being enhanced. The latest feature I added was a way for admins to edit any joke (eg, fix typos), quickly and easily.

This weirdo typed "Your Mommy" instead of "Yo Mama" on one of the jokes. How distracting! Let's write some code so we can fix this on the fly...]]></description>
			<content:encoded><![CDATA[<p>Happypolack.com is a joke site I created as a side project a little bit ago and it&#8217;s continually being enhanced. The latest feature I added was a way for admins to edit any joke (eg, fix typos), quickly and easily.</p>
<h2>An Example</h2>
<p>This weirdo typed &#8220;Your Mommy&#8221; instead of &#8220;Yo Mama.&#8221; How distracting! Let&#8217;s write some code so we can fix this.</p>
<div id="attachment_21" class="wp-caption alignnone" style="width: 464px"><a href="http://blog.pnapieralski.com/wp-content/uploads/2010/01/edit1.png" rel="shadowbox[sbpost-6];player=img;"><img class="size-full wp-image-21    " title="edit1" src="http://blog.pnapieralski.com/wp-content/uploads/2010/01/edit1.png" alt="" width="454" height="91" /></a><p class="wp-caption-text"> </p></div>
<p>If we click the edit link corresponding to the joke, we get something that looks like the following:</p>
<div id="attachment_22" class="wp-caption alignnone" style="width: 463px"><a href="http://blog.pnapieralski.com/wp-content/uploads/2010/01/edit2.png" rel="shadowbox[sbpost-6];player=img;"><img class="size-full wp-image-22   " title="edit2" src="http://blog.pnapieralski.com/wp-content/uploads/2010/01/edit2.png" alt="" width="453" height="91" /></a><p class="wp-caption-text"> </p></div>
<p>Great! We edited it, now we simply click submit and we can go on with reading jokes and being merry!</p>
<div id="attachment_25" class="wp-caption alignnone" style="width: 464px"><a href="http://blog.pnapieralski.com/wp-content/uploads/2010/01/edit32.png" rel="shadowbox[sbpost-6];player=img;"><img class="size-full wp-image-25 " title="edit3" src="http://blog.pnapieralski.com/wp-content/uploads/2010/01/edit32.png" alt="" width="454" height="91" /></a><p class="wp-caption-text"> </p></div>
<h2>How it works</h2>
<p>When the <em>edit</em> link is clicked, some simple javascript is called.  Here is the PHP code for the <em>edit</em> hyperlink for any joke.</p>
<pre class="brush: php; title: ; notranslate">
echo &quot;&lt;a id=&quot;joke&amp;quot;.$joke_id.&amp;quot;&quot; href=&quot;javascript:edit_joke(&amp;quot;.$joke_id.&amp;quot;);&quot;&gt;;edit&lt;/a&gt;&quot;;
</pre>
<p>We start by assigning each link with a distinct ID (corresponding to the joke&#8217;s ID in the database) and, upon clicking, it calls the javascript function edit_joke.</p>
<h3>The Javascript/jQuery Part</h3>
<p>Inside the edit_joke function, I used jQuery selectors to find the link and text for the joke. I then used the wrapInner() method to place an editable &lt;div&gt; inside our joke text&#8217;s &lt;p&gt; tags (basically, we now have <em>&lt;p id=&#8221;123&#8243;&gt;&lt;div&gt;Your mommy joke hehe haha&lt;/div&gt;&lt;/p&gt;</em> instead of <em>&lt;p id=&#8221;joke123&#8243;&gt;Your mommy joke hehe haha&lt;/p&gt;</em>). After that, change the <em>edit</em> link to <em>submit/cancel</em> using jQuery. Clicking submit will call the javascript function <em>edit_joke_submit(..)</em> and clicking cancel will call the javascript function <em>edit_joke_cancel(..)</em>. I placed those links inside a &lt;span&gt; tag so I could easily reference them later. The magic in this code is the contenteditable=&#8217;true&#8217; part of the div. Here&#8217;s the code:</p>
<pre class="brush: jscript; title: ; notranslate">
function edit_joke(joke_id){
	this_link = $(&quot;a#joke&quot;+joke_id);
	this_joke = $(&quot;p#joke&quot;+joke_id);

	this_joke.wrapInner(&quot;&lt;div contenteditable='true' class='editable_div'&gt;&lt;/div&gt;&quot;);

	this_link.replaceWith(&quot;&lt;span id='submitcancel'&gt;&quot;+
		&quot;&lt;a id='joke&quot;+joke_id+&quot;' href='javascript:edit_joke_submit(&quot;+joke_id+&quot;);'&gt;submit&lt;/a&gt;&quot;+
		&quot;&lt;a id='joke&quot;+joke_id+&quot;' href='javascript:edit_joke_cancel(&quot;+joke_id+&quot;);'&gt;/cancel&lt;/a&gt;&quot; );
}
</pre>
<p>The edit_joke_cancel function is relatively simple. I first found the corresponding <em>submit/cancel</em> link and the joke div using jQuery selectors. After that, I used the html() method to grab the new text that was typed in. I set the text inside the &lt;p&gt; tags equal to the new text so that it would look like <em>&lt;p id=&#8221;123&#8243;&gt;Yo mama joke hehe haha&lt;div&gt;Yo mama joke hehe haha&lt;/div&gt;&lt;/p&gt;</em> instead of <em>&lt;p id=&#8221;joke123&#8243;&gt;Yo mama joke hehe haha&lt;/p&gt;</em>. Then, simply remove the &lt;div&gt; tags (and, consequently, the text inside), and it&#8217;s back to normal.</p>
<pre class="brush: php; title: ; notranslate">
function edit_joke_cancel(joke_id){
	this_link = $(&quot;span#submitcancel&quot;);
	this_joke = $(&quot;p#joke&quot;+joke_id);
	this_joke_div = this_joke.find(&quot;div&quot;);

	joke_text = this_joke_div.html();
	this_joke.html(joke_text);
	this_joke_div.remove();

	this_link.replaceWith(
			&quot;&lt;a id='joke&quot;+joke_id+&quot;' href='javascript:edit_joke(&quot;+joke_id+&quot;);'&gt;edit&lt;/a&gt;&quot;
		);
}
</pre>
<p>To submit the joke changes, we need only send a post request to a server side php script with the joke id and the new joke text. Here&#8217;s the code:</p>
<pre class="brush: jscript; title: ; notranslate">
function edit_joke_submit(joke_id){
	var this_joke = $(&quot;p#joke&quot;+joke_id);
	var joke_text = this_joke.find(&quot;div&quot;).html();

	$.post('/jokes/ajax-edit.php',
			{
				id: joke_id,
				text: joke_text
			},
			function(data){
				alert(data);
			}
		);

	edit_joke_cancel(joke_id); // remove edible div
}
</pre>
<h3>The PHP Part</h3>
<p>All we have to do now is send an update query to the database with the corresponding id and text. The only caveat: editable divs place &lt;br&gt;&#8217;s when you hit enter, so I added the str_replace(..) to turn those into newline characters capable of storage in the database. Check it out:</p>
<pre class="brush: php; title: ; notranslate">
// Include needed files for account verification here.
// Get your database connection and store it in $dbconn HERE. I use mySQLi in my code.
&lt;?php
if( $accounts-&gt;check_admin() )
{
	$id = $dbconn-&gt;escape_string($_POST['id']);    // Prevent sql injection
	$text = $dbconn-&gt;escape_string($_POST['text']);

	$text = str_replace(&quot;&lt;br&gt;&quot;,&quot;\r\n&quot;, $text);    // Swap's out &lt;br&gt;'s

	$query = &quot;UPDATE joke_table SET text='&quot;.$text.&quot;' WHERE id = &quot;.$id;
	$dbconn-&gt;query($query) or die(mysqli_error($dbconn));
	echo &quot;The joke has been edited <img src='http://blog.pnapieralski.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> &quot;;
}
else
{
	echo 'Yea... okay buddy -_-';
}
?&gt;
</pre>


<div class="shr-bookmarks shr-bookmarks-expand shr-bookmarks-center">
<ul class="socials">
		<li class="shr-twitter">
			<a href="http://www.shareaholic.com/api/share/?title=Inline+AJAX+Editing&amp;link=http://blog.pnapieralski.com/ajax/inline-ajax-editing/&amp;notes=Happypolack.com%20is%20a%20joke%20site%20I%20created%20as%20a%20side%20project%20a%20little%20bit%20ago%20and%20it%27s%20continually%20being%20enhanced.%20The%20latest%20feature%20I%20added%20was%20a%20way%20for%20admins%20to%20edit%20any%20joke%20%28eg%2C%20fix%20typos%29%2C%20quickly%20and%20easily.%0D%0A%0D%0AThis%20weirdo%20typed%20%22Your%20Mommy%22%20instead%20of%20%22Yo%20Mama%22%20on%20one%20of%20the%20jokes.%20How%20distracting%21%20Let%27s%20write%20some%20code%20so%20we%20can%20fix%20this%20on%20the%20fly...&amp;short_link=&amp;shortener=google&amp;shortener_key=&amp;v=1&amp;apitype=1&amp;apikey=8afa39428933be41f8afdb8ea21a495c&amp;source=Shareaholic&amp;template=%2524%257Btitle%257D%2B-%2B%2524%257Bshort_link%257D&amp;service=7&amp;tags=&amp;ctype=" rel="nofollow" class="external" title="Tweet This!">Tweet This!</a>
		</li>
		<li class="shr-digg">
			<a href="http://www.shareaholic.com/api/share/?title=Inline+AJAX+Editing&amp;link=http://blog.pnapieralski.com/ajax/inline-ajax-editing/&amp;notes=Happypolack.com%20is%20a%20joke%20site%20I%20created%20as%20a%20side%20project%20a%20little%20bit%20ago%20and%20it%27s%20continually%20being%20enhanced.%20The%20latest%20feature%20I%20added%20was%20a%20way%20for%20admins%20to%20edit%20any%20joke%20%28eg%2C%20fix%20typos%29%2C%20quickly%20and%20easily.%0D%0A%0D%0AThis%20weirdo%20typed%20%22Your%20Mommy%22%20instead%20of%20%22Yo%20Mama%22%20on%20one%20of%20the%20jokes.%20How%20distracting%21%20Let%27s%20write%20some%20code%20so%20we%20can%20fix%20this%20on%20the%20fly...&amp;short_link=&amp;shortener=google&amp;shortener_key=&amp;v=1&amp;apitype=1&amp;apikey=8afa39428933be41f8afdb8ea21a495c&amp;source=Shareaholic&amp;template=&amp;service=3&amp;tags=&amp;ctype=" rel="nofollow" class="external" title="Digg this!">Digg this!</a>
		</li>
		<li class="shr-reddit">
			<a href="http://www.shareaholic.com/api/share/?title=Inline+AJAX+Editing&amp;link=http://blog.pnapieralski.com/ajax/inline-ajax-editing/&amp;notes=Happypolack.com%20is%20a%20joke%20site%20I%20created%20as%20a%20side%20project%20a%20little%20bit%20ago%20and%20it%27s%20continually%20being%20enhanced.%20The%20latest%20feature%20I%20added%20was%20a%20way%20for%20admins%20to%20edit%20any%20joke%20%28eg%2C%20fix%20typos%29%2C%20quickly%20and%20easily.%0D%0A%0D%0AThis%20weirdo%20typed%20%22Your%20Mommy%22%20instead%20of%20%22Yo%20Mama%22%20on%20one%20of%20the%20jokes.%20How%20distracting%21%20Let%27s%20write%20some%20code%20so%20we%20can%20fix%20this%20on%20the%20fly...&amp;short_link=&amp;shortener=google&amp;shortener_key=&amp;v=1&amp;apitype=1&amp;apikey=8afa39428933be41f8afdb8ea21a495c&amp;source=Shareaholic&amp;template=&amp;service=40&amp;tags=&amp;ctype=" rel="nofollow" class="external" title="Share this on Reddit">Share this on Reddit</a>
		</li>
		<li class="shr-technorati">
			<a href="http://www.shareaholic.com/api/share/?title=Inline+AJAX+Editing&amp;link=http://blog.pnapieralski.com/ajax/inline-ajax-editing/&amp;notes=Happypolack.com%20is%20a%20joke%20site%20I%20created%20as%20a%20side%20project%20a%20little%20bit%20ago%20and%20it%27s%20continually%20being%20enhanced.%20The%20latest%20feature%20I%20added%20was%20a%20way%20for%20admins%20to%20edit%20any%20joke%20%28eg%2C%20fix%20typos%29%2C%20quickly%20and%20easily.%0D%0A%0D%0AThis%20weirdo%20typed%20%22Your%20Mommy%22%20instead%20of%20%22Yo%20Mama%22%20on%20one%20of%20the%20jokes.%20How%20distracting%21%20Let%27s%20write%20some%20code%20so%20we%20can%20fix%20this%20on%20the%20fly...&amp;short_link=&amp;shortener=google&amp;shortener_key=&amp;v=1&amp;apitype=1&amp;apikey=8afa39428933be41f8afdb8ea21a495c&amp;source=Shareaholic&amp;template=&amp;service=10&amp;tags=&amp;ctype=" rel="nofollow" class="external" title="Share this on Technorati">Share this on Technorati</a>
		</li>
		<li class="shr-facebook">
			<a href="http://www.shareaholic.com/api/share/?title=Inline+AJAX+Editing&amp;link=http://blog.pnapieralski.com/ajax/inline-ajax-editing/&amp;notes=Happypolack.com%20is%20a%20joke%20site%20I%20created%20as%20a%20side%20project%20a%20little%20bit%20ago%20and%20it%27s%20continually%20being%20enhanced.%20The%20latest%20feature%20I%20added%20was%20a%20way%20for%20admins%20to%20edit%20any%20joke%20%28eg%2C%20fix%20typos%29%2C%20quickly%20and%20easily.%0D%0A%0D%0AThis%20weirdo%20typed%20%22Your%20Mommy%22%20instead%20of%20%22Yo%20Mama%22%20on%20one%20of%20the%20jokes.%20How%20distracting%21%20Let%27s%20write%20some%20code%20so%20we%20can%20fix%20this%20on%20the%20fly...&amp;short_link=&amp;shortener=google&amp;shortener_key=&amp;v=1&amp;apitype=1&amp;apikey=8afa39428933be41f8afdb8ea21a495c&amp;source=Shareaholic&amp;template=&amp;service=5&amp;tags=&amp;ctype=" rel="nofollow" title="Share this on Facebook">Share this on Facebook</a>
		</li>
		<li class="shr-stumbleupon">
			<a href="http://www.shareaholic.com/api/share/?title=Inline+AJAX+Editing&amp;link=http://blog.pnapieralski.com/ajax/inline-ajax-editing/&amp;notes=Happypolack.com%20is%20a%20joke%20site%20I%20created%20as%20a%20side%20project%20a%20little%20bit%20ago%20and%20it%27s%20continually%20being%20enhanced.%20The%20latest%20feature%20I%20added%20was%20a%20way%20for%20admins%20to%20edit%20any%20joke%20%28eg%2C%20fix%20typos%29%2C%20quickly%20and%20easily.%0D%0A%0D%0AThis%20weirdo%20typed%20%22Your%20Mommy%22%20instead%20of%20%22Yo%20Mama%22%20on%20one%20of%20the%20jokes.%20How%20distracting%21%20Let%27s%20write%20some%20code%20so%20we%20can%20fix%20this%20on%20the%20fly...&amp;short_link=&amp;shortener=google&amp;shortener_key=&amp;v=1&amp;apitype=1&amp;apikey=8afa39428933be41f8afdb8ea21a495c&amp;source=Shareaholic&amp;template=&amp;service=38&amp;tags=&amp;ctype=" rel="nofollow" class="external" title="Stumble upon something good? Share it on StumbleUpon">Stumble upon something good? Share it on StumbleUpon</a>
		</li>
</ul><div style="clear: both;"></div><div class="shr-getshr" style="visibility:hidden;font-size:10px !important"><a target="_blank" href="http://www.shareaholic.com/?src=pub">Get Shareaholic</a></div><div style="clear: both;"></div></div>

]]></content:encoded>
			<wfw:commentRss>http://blog.pnapieralski.com/ajax/inline-ajax-editing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

